### Install streaming-tts Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Install the library using pip. For development, use the editable install option. ```bash pip install streaming-tts ``` ```bash pip install -e . ``` -------------------------------- ### Install streaming-tts and optional extras Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Install the core library and optional dependencies for compressed audio export or specific language packs. ```bash pip install streaming-tts # Optional: compressed audio export (MP3, Opus, FLAC, AAC) pip install av # Language packs pip install streaming-tts[jp] # Japanese pip install streaming-tts[zh] # Chinese pip install streaming-tts[ko] # Korean pip install streaming-tts[all] # All extras ``` -------------------------------- ### Install PyAudio on Windows Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Use these commands if you encounter issues installing PyAudio on Windows. This involves installing pipwin first, then PyAudio. ```bash pip install pipwin ``` ```bash pipwin install pyaudio ``` -------------------------------- ### Install Optional Language Support Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Install optional extras for Japanese, Chinese, Korean, or all features. Note that non-English languages require espeak-ng. ```bash # Japanese language support pip install streaming-tts[jp] ``` ```bash # Chinese language support pip install streaming-tts[zh] ``` ```bash # Korean language support pip install streaming-tts[ko] ``` ```bash # All features pip install streaming-tts[all] ``` -------------------------------- ### Initialize TextToAudioStream with callbacks Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Initialize TextToAudioStream with a KokoroEngine and define callback functions for audio stream events like start, stop, word timing, and audio chunks. ```python from streaming_tts import TextToAudioStream, KokoroEngine engine = KokoroEngine(voice="af_heart") # --- Callbacks --- def on_start(): print("Audio started") def on_stop(): print("Audio finished") def on_word(timing): # timing has .word, .start_time, .end_time (in seconds) print(f" word='{timing.word}' at {timing.start_time:.2f}s") def on_chunk(chunk: bytes): # chunk is int16 PCM bytes; forward to WebSocket, file, etc. pass stream = TextToAudioStream( engine, on_audio_stream_start=on_start, on_audio_stream_stop=on_stop, on_word=on_word, on_audio_chunk=on_chunk, muted=False, # True = synthesize silently (no speakers) enable_crossfade=True, # Smooth transitions between chunks crossfade_ms=25.0, enable_diagnostics=False, # Collect timing stats ) ``` -------------------------------- ### StreamingAudioWriter Initialization Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Initializes a writer for streaming audio data into various formats like MP3, WAV, Opus, or FLAC. Requires the `audio` extra to be installed. ```APIDOC ## StreamingAudioWriter ### Description Provides functionality to write audio data chunks into specified formats (e.g., MP3, WAV, Opus, FLAC). This class is useful for exporting synthesized audio. Requires `pip install streaming-tts[audio]`. ### Parameters - **format** (str) - Required - The desired audio format (e.g., "mp3", "wav", "opus", "flac"). - **sample_rate** (int) - Optional - The sample rate for the audio output (default: 24000). ``` -------------------------------- ### Quick Start: Basic TTS Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Initialize the Kokoro engine with a voice and use TextToAudioStream to feed and play text. This is the most basic usage for generating speech. ```python from streaming_tts import TextToAudioStream, KokoroEngine # Initialize the engine engine = KokoroEngine(voice="af_heart") # Create stream and play stream = TextToAudioStream(engine) stream.feed("Hello, world! This is a test of streaming text to speech.").play() ``` -------------------------------- ### TextToAudioStream API Parameters Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Initialize `TextToAudioStream` with an engine instance and optional callbacks for stream start, stop, audio chunks, and word timing. The `muted` parameter can disable speaker output. ```python TextToAudioStream( engine, # KokoroEngine instance on_audio_stream_start=None, # Callback when audio starts on_audio_stream_stop=None, # Callback when audio stops on_audio_chunk=None, # Callback for each audio chunk on_word=None, # Callback for word timing muted=False # Disable speaker output ) ``` -------------------------------- ### StreamingAudioWriter.write_chunk() Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Writes an audio chunk to the writer for encoding into the specified format. Call with `finalize=True` to complete the writing process and get the final data. ```APIDOC ## StreamingAudioWriter.write_chunk() ### Description Encodes and writes a chunk of audio data to the specified format. When `finalize` is set to True, it completes the encoding process and returns the final audio data. ### Parameters - **audio_chunk** (bytes or similar) - Required - The audio data chunk to write. - **finalize** (bool) - Optional - If True, signals the end of the stream and returns the final encoded data (default: False). ### Returns - **bytes**: The encoded audio data. ``` -------------------------------- ### Get KokoroEngine stream information Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Retrieve the audio stream format, channel count, and sample rate from the KokoroEngine. This information is typically used internally by audio playback systems. ```python # Stream info (used internally by TextToAudioStream) fmt, channels, rate = engine.get_stream_info() print(fmt, channels, rate) # pyaudio.paInt16, 1, 24000 ``` -------------------------------- ### Multi-Format Audio Export Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Export synthesized audio to various formats like MP3, WAV, Opus, FLAC, or AAC using `StreamingAudioWriter`. Requires `pip install streaming-tts[audio]`. ```python from streaming_tts import StreamingAudioWriter # Requires: pip install streaming-tts[audio] writer = StreamingAudioWriter("mp3", sample_rate=24000) for audio_chunk in audio_chunks: mp3_data = writer.write_chunk(audio_chunk) # Stream or save mp3_data final_data = writer.write_chunk(finalize=True) writer.close() ``` -------------------------------- ### KokoroEngine Initialization and Usage Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Demonstrates how to initialize and use the KokoroEngine for text-to-speech synthesis, including voice selection, blending, runtime changes, and retrieving available voices. ```APIDOC ## KokoroEngine The `KokoroEngine` class wraps the Kokoro 82M neural TTS model and manages voice selection, speed control, silence trimming, and audio chunk queuing. It is the required engine argument for `TextToAudioStream`. Voices are specified by name (e.g. `"af_heart"`) or as a weighted blend formula. The engine lazily creates per-language `KPipeline` instances and caches blended voice tensors. ```python from streaming_tts import KokoroEngine, KokoroVoice # Basic initialization with a named voice engine = KokoroEngine( voice="af_heart", # American English female default_speed=1.0, # 1.0 = normal speed trim_silence=True, # Remove leading/trailing silence silence_threshold=0.005, # Amplitude threshold for silence detection extra_start_ms=15, # Extra ms to trim from start after silence extra_end_ms=15, # Extra ms to trim from end after silence fade_in_ms=10, # Fade-in at chunk start (ms) fade_out_ms=10, # Fade-out at chunk end (ms) debug=False, ) # Voice blending: weighted mix of two voices blended_engine = KokoroEngine(voice="0.3*af_sarah + 0.7*am_adam") # Use a KokoroVoice object (explicit language code) voice_obj = KokoroVoice(name="bf_emma", language_code="b") # British English engine_brit = KokoroEngine(voice=voice_obj) # Change voice at runtime engine.set_voice("am_michael") # Switch to American English male engine.set_speed(1.25) # Speed up synthesis # List all 54 available voices voices = engine.get_voices() for v in voices[:5]: print(v.name, v.language_code) # af_heart a # af_alloy a # af_aoede a # af_bella a # af_jessica a # Stream info (used internally by TextToAudioStream) fmt, channels, rate = engine.get_stream_info() print(fmt, channels, rate) # pyaudio.paInt16, 1, 24000 ``` ``` -------------------------------- ### play() / play_async() Parameters Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt This section details the various parameters available for the `play()` and `play_async()` methods, which control how text is synthesized and streamed. These parameters allow for fine-tuning aspects like fragment yielding speed, sentence length, buffering, conversational pauses, and audio callbacks. ```APIDOC ## play() / play_async() Parameters This section details the various parameters available for the `play()` and `play_async()` methods, which control how text is synthesized and streamed. These parameters allow for fine-tuning aspects like fragment yielding speed, sentence length, buffering, conversational pauses, and audio callbacks. ### Parameters - **fast_sentence_fragment** (bool) - Optional - Yield first fragment quickly. - **minimum_sentence_length** (int) - Optional - Minimum characters per sentence chunk. - **minimum_first_fragment_length** (int) - Optional - Minimum length for the first fragment. - **buffer_threshold_seconds** (float) - Optional - Pre-buffer before synthesizing the next chunk (0 means off). - **conversational_pauses** (bool) - Optional - Use natural punctuation-based pauses. - **comma_silence_duration** (float) - Optional - Silence duration for commas (only when `conversational_pauses` is False). - **sentence_silence_duration** (float) - Optional - Silence duration for sentences. - **context_size** (int) - Optional - Characters used for sentence boundary detection. - **force_first_fragment_after_words** (int) - Optional - Force the first fragment after a specified number of words. - **log_synthesized_text** (bool) - Optional - Log the synthesized text. - **on_audio_chunk** (callable) - Optional - Callback function executed for each audio chunk. - **on_sentence_synthesized** (callable) - Optional - Callback function executed when a sentence is synthesized. - **muted** (bool) - Optional - Mute the audio output. - **output_wavfile** (str) - Optional - Path to save the output as a WAV file. - **tokenizer** (str) - Optional - The tokenizer to use (e.g., 'nltk'). - **language** (str) - Optional - The language code for synthesis (e.g., 'en'). - **debug** (bool) - Optional - Enable debug logging. ``` -------------------------------- ### Initialize KokoroEngine with voice blending Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Initialize KokoroEngine using a weighted blend formula to combine multiple voices. This allows for custom voice characteristics. ```python # Voice blending: weighted mix of two voices blended_engine = KokoroEngine(voice="0.3*af_sarah + 0.7*am_adam") ``` -------------------------------- ### Initialize KokoroEngine with a named voice Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Basic initialization of KokoroEngine with a specific voice, speed, and silence trimming options. Configure fade in/out durations for audio chunks. ```python from streaming_tts import KokoroEngine, KokoroVoice # Basic initialization with a named voice engine = KokoroEngine( voice="af_heart", # American English female default_speed=1.0, # 1.0 = normal speed trim_silence=True, # Remove leading/trailing silence silence_threshold=0.005, # Amplitude threshold for silence detection extra_start_ms=15, # Extra ms to trim from start after silence extra_end_ms=15, # Extra ms to trim from end after silence fade_in_ms=10, # Fade-in at chunk start (ms) fade_out_ms=10, # Fade-out at chunk end (ms) debug=False, ) ``` -------------------------------- ### Initialize KokoroEngine with KokoroVoice object Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Initialize KokoroEngine using an explicit KokoroVoice object, specifying the voice name and language code. This provides more control over voice selection. ```python # Use a KokoroVoice object (explicit language code) voice_obj = KokoroVoice(name="bf_emma", language_code="b") # British English engine_brit = KokoroEngine(voice=voice_obj) ``` -------------------------------- ### Multi-engine Fallback and Stream Control Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Demonstrates setting up multiple TTS engines for fallback and controlling audio playback with pause and resume functionality. ```python engine1 = KokoroEngine(voice="af_heart") engine2 = KokoroEngine(voice="af_nova") stream_fb = TextToAudioStream([engine1, engine2]) stream_fb.feed("Fallback demo").play() ``` ```python stream.feed("Long text...").play_async() stream.pause() stream.resume() stream.stop() ``` ```python print(stream.text()) ``` -------------------------------- ### KokoroEngine Initialization Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Initializes the Kokoro engine for text-to-speech synthesis. You can specify a single voice or a blend of voices using a weighted formula. Optional parameters control speech speed, silence trimming, and debug output. ```APIDOC ## KokoroEngine ### Description Initializes the Kokoro engine for text-to-speech synthesis. Supports single voices or voice blending with weighted formulas. Allows configuration of default speech speed, silence trimming, and debug mode. ### Parameters - **voice** (string) - Required - Voice name or blend formula (e.g., "af_heart" or "0.3*af_sarah + 0.7*am_adam"). - **default_speed** (float) - Optional - Speech speed multiplier (default: 1.0). - **trim_silence** (bool) - Optional - Remove silence from audio (default: True). - **debug** (bool) - Optional - Enable debug output (default: False). ``` -------------------------------- ### Enable and Analyze Playback Diagnostics Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Pass enable_diagnostics=True to TextToAudioStream to record synthesis and queue timing. Call print_report() on the diagnostics object after playback to analyze timing gaps. ```python from streaming_tts import TextToAudioStream, KokoroEngine engine = KokoroEngine(voice="af_heart") stream = TextToAudioStream(engine, enable_diagnostics=True) stream.feed( "Diagnostics track synthesis and playback timing per sentence chunk." ).play() # Print timing analysis report stream.diagnostics.print_report() # Output example: # === Playback Diagnostics === # Chunk 0: synthesis=0.312s, queue_put=0.313s, audio_dur=1.820s # ... ``` -------------------------------- ### TextToAudioStream Initialization Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Creates a text-to-audio stream instance. This class handles the feeding of text and playback of synthesized audio. It supports various callbacks for stream events and can be muted to prevent direct audio output. ```APIDOC ## TextToAudioStream ### Description Manages the streaming of synthesized audio from text. Accepts an initialized KokoroEngine and provides callbacks for stream start, stop, audio chunks, and word timing. Can operate in a muted mode. ### Parameters - **engine** (KokoroEngine) - Required - An instance of the KokoroEngine. - **on_audio_stream_start** (callable) - Optional - Callback function invoked when the audio stream begins. - **on_audio_stream_stop** (callable) - Optional - Callback function invoked when the audio stream finishes. - **on_audio_chunk** (callable) - Optional - Callback function invoked for each received audio chunk. - **on_word** (callable) - Optional - Callback function invoked with word timing information. - **muted** (bool) - Optional - If True, suppresses direct audio output (default: False). ``` -------------------------------- ### Implement Custom TTS Engine with BaseEngine Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Subclass BaseEngine to integrate custom synthesis backends. Requires implementing get_stream_info and synthesize methods. Use with TextToAudioStream for synthesis. ```python from streaming_tts import BaseEngine, TimingInfo import pyaudio import numpy as np import queue class MyCustomEngine(BaseEngine): def __init__(self): super().__init__() self.engine_name = "custom" self.can_consume_generators = False def get_stream_info(self): # Must return (pyaudio_format, channels, sample_rate) return (pyaudio.paInt16, 1, 24000) def synthesize(self, text: str) -> bool: super().synthesize(text) try: # Generate audio samples (replace with real synthesis) num_samples = 24000 # 1 second of silence as placeholder audio = np.zeros(num_samples, dtype=np.int16) self.queue.put(audio.tobytes()) # Optionally emit word timings self.timings.put(TimingInfo(0.0, 0.5, text.split()[0] if text.split() else "")) self.audio_duration += num_samples / 24000 return True except Exception: return False def get_voices(self): return [] def set_voice(self, voice): pass def set_voice_parameters(self, **kwargs): pass # Use with TextToAudioStream from streaming_tts import TextToAudioStream engine = MyCustomEngine() stream = TextToAudioStream(engine) stream.feed("Test sentence.").play(muted=True) print("Synthesized:", stream.text()) ``` -------------------------------- ### TextToAudioStream Initialization and Usage Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Explains how to use TextToAudioStream to manage the TTS process, including feeding text, playback options (blocking/non-blocking), callbacks for events, and saving audio to a file. ```APIDOC ## TextToAudioStream `TextToAudioStream` is the main orchestrator. It accepts a `KokoroEngine` (or a list for fallback), tokenizes input text into sentence fragments, synthesizes them concurrently, and plays audio via PyAudio with optional crossfade smoothing. Text is fed via `feed()`, then playback is triggered by `play()` (blocking) or `play_async()` (non-blocking). ```python from streaming_tts import TextToAudioStream, KokoroEngine engine = KokoroEngine(voice="af_heart") # --- Callbacks --- def on_start(): print("Audio started") def on_stop(): print("Audio finished") def on_word(timing): # timing has .word, .start_time, .end_time (in seconds) print(f" word='{timing.word}' at {timing.start_time:.2f}s") def on_chunk(chunk: bytes): # chunk is int16 PCM bytes; forward to WebSocket, file, etc. pass stream = TextToAudioStream( engine, on_audio_stream_start=on_start, on_audio_stream_stop=on_stop, on_word=on_word, on_audio_chunk=on_chunk, muted=False, # True = synthesize silently (no speakers) enable_crossfade=True, # Smooth transitions between chunks crossfade_ms=25.0, enable_diagnostics=False, # Collect timing stats ) # --- Blocking playback --- stream.feed("Hello, world! This is a streaming TTS demo.").play() # --- Non-blocking playback --- stream.feed("Playing in background.").play_async() # ... do other work ... while stream.is_playing(): pass # --- Save to WAV file --- stream.feed("Saving this to disk.").play(output_wavfile="output.wav", muted=True) ``` ``` -------------------------------- ### Text Normalization with Custom Options Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Shows how to use the `normalize_text` function with `NormalizationOptions` to prepare raw text for TTS, handling URLs, emails, numbers, and more. ```python from streaming_tts import normalize_text, NormalizationOptions options = NormalizationOptions( normalize=True, url_normalization=True, email_normalization=True, phone_normalization=True, unit_normalization=True, optional_pluralization_normalization=True, replace_remaining_symbols=True, ) examples = [ "Visit https://github.com/project for details.", "Email user@example.com for support.", "The price is $42.50.", "Call (555) 123-4567 anytime.", "The meeting is at 3:30 PM.", "It happened in 1984.", "File size: 2.5gb.", "Speed: 100kph.", ] for text in examples: result = normalize_text(text, options) print(f"{text!r}") print(f" -> {result!r}\n") ``` -------------------------------- ### Advanced play() Parameters for TTS Stream Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Illustrates the various parameters available for the `play()` method to control TTS output, including fragment yielding, sentence length, buffering, and callbacks. ```python stream.feed("Some text.").play( fast_sentence_fragment=True, # Yield first fragment quickly minimum_sentence_length=10, # Min chars per sentence chunk minimum_first_fragment_length=10, buffer_threshold_seconds=0.0, # Pre-buffer before synthesizing next (0=off) conversational_pauses=True, # Natural punctuation-based pauses # comma_silence_duration=0.2, # Only when conversational_pauses=False # sentence_silence_duration=0.5, context_size=12, # Chars for sentence boundary detection force_first_fragment_after_words=30, log_synthesized_text=False, on_audio_chunk=lambda c: None, # Per-chunk callback on_sentence_synthesized=lambda s: print(f"Done: {s}"), muted=False, output_wavfile=None, tokenizer="nltk", language="en", debug=False, ) ``` -------------------------------- ### KokoroEngine API Parameters Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Configure the `KokoroEngine` with parameters like `voice`, `default_speed`, `trim_silence`, and `debug` for customized speech synthesis. ```python KokoroEngine( voice="af_heart", # Voice name or blend formula default_speed=1.0, # Speech speed multiplier trim_silence=True, # Remove silence from audio debug=False # Enable debug output ) ``` -------------------------------- ### Feed text and play audio synchronously Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Feed text into the TextToAudioStream and play the synthesized audio synchronously. The `play()` method blocks until synthesis and playback are complete. ```python # --- Blocking playback --- stream.feed("Hello, world! This is a streaming TTS demo.").play() ``` -------------------------------- ### TextToAudioStream.feed() and TextToAudioStream.play() Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Feeds text into the audio stream for synthesis and initiates playback. The `play` method can be configured with options to mute output and provide a callback for audio chunks. ```APIDOC ## TextToAudioStream.feed() and TextToAudioStream.play() ### Description Feeds text into the audio stream for synthesis and optionally plays it. The `play` method allows for muting output and specifying a callback for processing audio chunks during playback. ### Method - `feed(text: str)`: Feeds the given text into the stream for synthesis. - `play(muted: bool = False, on_audio_chunk: callable = None)`: Initiates playback of the synthesized audio. Can be muted and accept a callback for audio chunks. ### Parameters for play() - **muted** (bool) - Optional - If True, suppresses direct audio output. - **on_audio_chunk** (callable) - Optional - Callback function to process each audio chunk. ``` -------------------------------- ### Text Normalization Options Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Enable text normalization to automatically convert URLs, emails, numbers, and currency into their spoken forms. Customize normalization behavior with NormalizationOptions. ```python from streaming_tts import normalize_text, NormalizationOptions options = NormalizationOptions(normalize=True) # URLs, emails, numbers, money, etc. text = "Visit https://example.com or email user@test.com. Price: $42.50" normalized = normalize_text(text, options) # -> "Visit https example dot com or email user at test dot com. Price: forty-two dollars and fifty cents" ``` -------------------------------- ### Feed text and play audio asynchronously Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Feed text into the TextToAudioStream and play the synthesized audio asynchronously. Use `play_async()` for non-blocking playback and check `is_playing()` to monitor status. ```python # --- Non-blocking playback --- stream.feed("Playing in background.").play_async() # ... do other work ... while stream.is_playing(): pass ``` -------------------------------- ### smart_split() Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Splits a given text into smaller, optimal chunks for text-to-speech synthesis, considering token boundaries for better quality. ```APIDOC ## smart_split() ### Description Splits a long text into smaller, manageable chunks suitable for TTS processing. This function aims to optimize chunking based on tokenization for improved audio quality. ### Parameters - **text** (str) - Required - The input text to be split. ### Returns - **list[str]**: A list of text chunks. ``` -------------------------------- ### Smart Text Chunking Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Utilize `smart_split` and `process_text_with_pauses` to break down long texts into optimal chunks for TTS synthesis, ensuring better quality and handling of pauses. ```python from streaming_tts import smart_split, process_text_with_pauses import time # Process text with pauses for item in process_text_with_pauses(text, normalize=True): if isinstance(item, float): time.sleep(item) # Pause else: stream.feed(item).play() # Speak ``` -------------------------------- ### Usage with Callbacks for Audio Chunks Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Process audio chunks as they are generated using the `on_audio_chunk` callback. This is useful for real-time streaming or processing. The `on_audio_stream_stop` callback is invoked when the stream finishes. ```python from streaming_tts import TextToAudioStream, KokoroEngine def on_audio_chunk(chunk): # Process audio chunk (e.g., send over websocket) pass def on_stream_stop(): print("Audio stream finished") engine = KokoroEngine(voice="af_heart") stream = TextToAudioStream(engine, on_audio_stream_stop=on_stream_stop) stream.feed("Hello world").play(muted=True, on_audio_chunk=on_audio_chunk) ``` -------------------------------- ### List available KokoroEngine voices Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Retrieve and print a list of all available voices supported by the KokoroEngine. This includes voice names and their corresponding language codes. ```python # List all 54 available voices voices = engine.get_voices() for v in voices[:5]: print(v.name, v.language_code) # af_heart a # af_alloy a # af_aoede a # af_bella a # af_jessica a ``` -------------------------------- ### Voice Blending Formula Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Blend multiple voices by providing a weighted formula to the `voice` parameter in `KokoroEngine`. Adjust the weights to control the mix. ```python engine = KokoroEngine(voice="0.3*af_sarah + 0.7*am_adam") ``` -------------------------------- ### Process Text with Pauses Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Use this generator to easily integrate text synthesis and pauses into a feed-and-play loop. It yields strings for synthesis and floats for pause durations. ```python from streaming_tts import TextToAudioStream, KokoroEngine, process_text_with_pauses import time engine = KokoroEngine(voice="af_heart") stream = TextToAudioStream(engine) text = """ Welcome to the streaming TTS demo! [pause:0.5s] Today the price is $99.99. For info, visit https://example.com. [pause:1s] Thank you for listening! """ for item in process_text_with_pauses(text, lang_code="a", normalize=True): if isinstance(item, float): print(f" Pausing {item}s...") time.sleep(item) else: print(f" Speaking: {item[:60]!r}") stream.feed(item).play() # Speaking: 'Welcome to the streaming TTS demo!' # Pausing 0.5s... # Speaking: 'Today the price is ninety-nine dollars and ninety-nine cents...' # Pausing 1.0s... # Speaking: 'Thank you for listening!' ``` -------------------------------- ### Using Pause Tags in Text Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Insert natural pauses into your speech by including tags like `[pause:1s]` or `[pause:500ms]` within the text string. ```python text = "Hello! [pause:1s] How are you? [pause:500ms] I hope you're well." stream.feed(text).play() ``` -------------------------------- ### Parsing Pause Tags in Text Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Demonstrates splitting text into spoken parts and pause durations using the `parse_pause_tags` function, recognizing `[pause:Xs]` and `[pause:Xms]` syntax. ```python from streaming_tts import parse_pause_tags text = "Good morning! [pause:1s] How are you? [pause:500ms] I hope you're well." chunks = parse_pause_tags(text) for chunk in chunks: if chunk.is_pause: print(f"PAUSE: {chunk.pause_duration}s") else: print(f"TEXT: {chunk.text!r}") ``` -------------------------------- ### Smart Text Splitting for TTS Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Utilizes `smart_split` with `ChunkingOptions` to divide long text into optimal chunks for TTS, considering token counts, normalization, and pause tags. ```python from streaming_tts import smart_split, ChunkingOptions, NormalizationOptions long_text = "" Artificial intelligence has transformed many aspects of our daily lives. From virtual assistants to recommendation systems, AI is everywhere. [pause:0.5s] Machine learning, a subset of AI, enables computers to learn from data. Deep learning takes this further with neural networks that mimic the human brain. [pause:1s] The future is both exciting and challenging. The cost is already $1m per training run. " options = ChunkingOptions( target_min_tokens=175, target_max_tokens=250, absolute_max_tokens=450, normalize=True, normalization_options=NormalizationOptions(), ) for chunk in smart_split(long_text, lang_code="a", options=options): if chunk.is_pause: print(f"[PAUSE {chunk.pause_duration}s]") else: est_tokens = len(chunk.text) // 4 print(f"[TEXT ~{est_tokens} tokens] {chunk.text[:80]!r}") ``` -------------------------------- ### Change KokoroEngine voice and speed at runtime Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Dynamically change the voice and synthesis speed of an active KokoroEngine instance. This is useful for adapting speech characteristics during runtime. ```python # Change voice at runtime engine.set_voice("am_michael") # Switch to American English male engine.set_speed(1.25) # Speed up synthesis ``` -------------------------------- ### Streaming Audio Writer for WAV and MP3 Export Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Encode raw PCM audio chunks into WAV, MP3, Opus, FLAC, AAC, or raw PCM. WAV export requires no extra dependencies, while MP3 and other formats require PyAV. This is useful for saving or forwarding audio. ```python from streaming_tts import StreamingAudioWriter, KokoroEngine import numpy as np engine = KokoroEngine(voice="af_heart") # Collect raw audio from the engine queue engine.synthesize("Hello, this is a streaming audio export demo.") chunks = [] while not engine.queue.empty(): chunks.append(engine.queue.get()) # --- WAV export (no extra deps) --- with StreamingAudioWriter("wav", sample_rate=24000, channels=1) as writer: for chunk_bytes in chunks: audio = np.frombuffer(chunk_bytes, dtype=np.int16) writer.write_chunk(audio) wav_data = writer.write_chunk(finalize=True) with open("output.wav", "wb") as f: f.write(wav_data) print(f"WAV: {len(wav_data)} bytes") # --- MP3 export (requires PyAV) --- with StreamingAudioWriter("mp3", sample_rate=24000, bit_rate=128000) as writer: for chunk_bytes in chunks: audio = np.frombuffer(chunk_bytes, dtype=np.int16) mp3_fragment = writer.write_chunk(audio) if mp3_fragment: # Could stream mp3_fragment over WebSocket here pass mp3_data = writer.write_chunk(finalize=True) with open("output.mp3", "wb") as f: f.write(mp3_data) print(f"MP3: {len(mp3_data)} bytes") # --- Silence helper --- from streaming_tts import create_silence silence = create_silence(duration_seconds=0.5, sample_rate=24000) # silence.shape -> (12000,), dtype=int16 ``` -------------------------------- ### Feed text and save audio to WAV file Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Feed text into the TextToAudioStream and save the synthesized audio directly to a WAV file. The `muted=True` option prevents audio from being played through speakers during file export. ```python # --- Save to WAV file --- stream.feed("Saving this to disk.").play(output_wavfile="output.wav", muted=True) ``` -------------------------------- ### Audio Normalizer for Silence Trimming and Padding Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt Use AudioNormalizer to trim silence from audio boundaries and apply punctuation-aware padding for natural-sounding speech assembly. It can also normalize float32 audio to int16. ```python from streaming_tts import AudioNormalizer, create_silence import numpy as np normalizer = AudioNormalizer( sample_rate=24000, gap_trim_ms=1.0, # Trim 1ms from each boundary padding_ms=410.0, # Default inter-chunk padding silence_threshold_db=-45.0, ) # Simulate a chunk of synthesized audio (int16) raw_audio = np.random.randint(-1000, 1000, size=24000, dtype=np.int16) # Trim silence and apply natural padding trimmed = normalizer.trim_audio( raw_audio, chunk_text="Hello, world.", # Used for punctuation-based padding speed=1.0, is_last_chunk=False, ) print(f"Original: {len(raw_audio)} samples, Trimmed: {len(trimmed)} samples") # Normalize float32 -> int16 float_audio = np.random.uniform(-1, 1, size=2400).astype(np.float32) int16_audio = normalizer.normalize(float_audio) print(f"dtype: {int16_audio.dtype}, max: {int16_audio.max()}") # dtype: int16, max: ~32767 # Create silence silence = create_silence(0.25, sample_rate=24000) # 0.25s of zeros print(f"Silence: {len(silence)} samples, dtype={silence.dtype}") # Silence: 6000 samples, dtype=int16 ``` -------------------------------- ### smart_split Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt The `smart_split` generator intelligently divides a given text into `TextChunk` objects, optimizing for TTS quality by targeting a specific token count per chunk (175-250 tokens). It incorporates text normalization and pause tag processing, ensuring that synthesized speech is coherent and natural. ```APIDOC ## smart_split `smart_split` is a generator that splits text (including pause tags) into `TextChunk` objects with token-aware sizing (targeting 175–250 tokens per chunk) for optimal TTS quality, applying text normalization and pause extraction along the way. ### Parameters - **text** (str) - The input text to be split. - **lang_code** (str) - The language code for text processing (e.g., 'en'). - **options** (ChunkingOptions) - Configuration options for chunking. #### ChunkingOptions Parameters - **target_min_tokens** (int) - Optional - The minimum target number of tokens per chunk. - **target_max_tokens** (int) - Optional - The maximum target number of tokens per chunk. - **absolute_max_tokens** (int) - Optional - The absolute maximum number of tokens allowed in a chunk. - **normalize** (bool) - Optional - Whether to apply text normalization before splitting. - **normalization_options** (NormalizationOptions) - Optional - Specific options for text normalization. ### Example Usage ```python from streaming_tts import smart_split, ChunkingOptions, NormalizationOptions long_text = """ Artificial intelligence has transformed many aspects of our daily lives. From virtual assistants to recommendation systems, AI is everywhere. [pause:0.5s] Machine learning, a subset of AI, enables computers to learn from data. Deep learning takes this further with neural networks that mimic the human brain. [pause:1s] The future is both exciting and challenging. The cost is already $1m per training run. """ options = ChunkingOptions( target_min_tokens=175, target_max_tokens=250, absolute_max_tokens=450, normalize=True, normalization_options=NormalizationOptions(), ) for chunk in smart_split(long_text, lang_code="a", options=options): if chunk.is_pause: print(f"[PAUSE {chunk.pause_duration}s]") else: est_tokens = len(chunk.text) // 4 print(f"[TEXT ~{est_tokens} tokens] {chunk.text[:80]!r}") ``` ### Example Output ``` [TEXT ~47 tokens] 'Artificial intelligence has transformed many aspects...' (This is an example, actual token count may vary based on normalization and language) [PAUSE 0.5s] [TEXT ~52 tokens] 'Machine learning, a subset of AI...' (This is an example, actual token count may vary based on normalization and language) [PAUSE 1.0s] [TEXT ~38 tokens] 'The future is both exciting...' (This is an example, actual token count may vary based on normalization and language) ``` ``` -------------------------------- ### normalize_text() Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Normalizes input text by converting numbers, URLs, emails, and currency into their spoken forms. Supports custom normalization options. ```APIDOC ## normalize_text() ### Description Normalizes text for speech synthesis, converting elements like URLs, emails, numbers, and currency into their spoken equivalents. Allows customization through `NormalizationOptions`. ### Parameters - **text** (str) - Required - The input text to normalize. - **options** (NormalizationOptions) - Optional - An object containing normalization settings. ### Returns - **str**: The normalized text. ``` -------------------------------- ### process_text_with_pauses() Source: https://github.com/nikkoxgonzales/streaming-tts/blob/master/README.md Processes text that may contain pause tags, yielding either text segments to be spoken or float values representing pause durations. ```APIDOC ## process_text_with_pauses() ### Description Iterates through text, yielding either speech segments or pause durations (as floats) based on detected pause tags (e.g., `[pause:1s]`). Useful for controlling timing in speech synthesis. ### Parameters - **text** (str) - Required - The input text containing potential pause tags. - **normalize** (bool) - Optional - Whether to apply text normalization before processing pauses. ### Yields - **str or float**: Yields text segments to be spoken or float values representing pause durations in seconds. ``` -------------------------------- ### normalize_text Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt The `normalize_text` function preprocesses raw text to ensure TTS engines can pronounce it naturally. It handles various elements like URLs, emails, phone numbers, currency, numbers, units, and time expressions, converting them into a spoken-friendly format. ```APIDOC ## normalize_text `normalize_text` converts raw text containing URLs, emails, phone numbers, money expressions, numbers, units, and time expressions into a form that TTS engines can pronounce naturally. ### Parameters - **text** (str) - The raw input text to normalize. - **options** (NormalizationOptions) - An object containing various flags to control the normalization process. #### NormalizationOptions Parameters - **normalize** (bool) - Required - Whether to perform normalization. - **url_normalization** (bool) - Optional - Whether to normalize URLs. - **email_normalization** (bool) - Optional - Whether to normalize email addresses. - **phone_normalization** (bool) - Optional - Whether to normalize phone numbers. - **unit_normalization** (bool) - Optional - Whether to normalize units of measurement. - **optional_pluralization_normalization** (bool) - Optional - Whether to normalize optional pluralizations. - **replace_remaining_symbols** (bool) - Optional - Whether to replace remaining symbols. ### Example Usage ```python from streaming_tts import normalize_text, NormalizationOptions options = NormalizationOptions( normalize=True, url_normalization=True, email_normalization=True, phone_normalization=True, unit_normalization=True, optional_pluralization_normalization=True, replace_remaining_symbols=True, ) examples = [ "Visit https://github.com/project for details.", "Email user@example.com for support.", "The price is $42.50.", "Call (555) 123-4567 anytime.", "The meeting is at 3:30 PM.", "It happened in 1984.", "File size: 2.5gb.", "Speed: 100kph.", ] for text in examples: result = normalize_text(text, options) print(f"{text!r}") print(f" -> {result!r}\n") ``` ### Example Output ``` 'Visit https://github.com/project for details.' -> 'Visit https github dot com slash project for details.' 'Email user@example.com for support.' -> 'Email user at example dot com for support.' 'The price is $42.50.' -> 'The price is forty-two dollars and fifty cents.' 'Call (555) 123-4567 anytime.' -> 'Call five five five one two three four five six seven anytime.' 'The meeting is at 3:30 PM.' -> 'The meeting is at three thirty PM.' 'It happened in 1984.' -> 'It happened in nineteen eighty-four.' 'File size: 2.5gb.' -> 'File size: two point 5 gigabytes.' 'Speed: 100kph.' -> 'Speed: one hundred kilometers per hour.' ``` ``` -------------------------------- ### parse_pause_tags Source: https://context7.com/nikkoxgonzales/streaming-tts/llms.txt The `parse_pause_tags` function segments a given text string into a list of `TextChunk` objects. It distinguishes between regular text and pause markers defined in the format `[pause:Xs]` or `[pause:Xms]`, allowing for explicit control over silence durations in the synthesized speech. ```APIDOC ## parse_pause_tags `parse_pause_tags` splits a text string into a list of `TextChunk` objects, separating spoken text from pause markers specified with `[pause:Xs]` or `[pause:Xms]` syntax. ### Parameters - **text** (str) - The input string containing text and potential pause tags. ### Returns - A list of `TextChunk` objects, where each object is either a text segment or a pause segment. #### TextChunk Object - **is_pause** (bool) - True if the chunk represents a pause, False otherwise. - **text** (str) - The text content (if `is_pause` is False). - **pause_duration** (float) - The duration of the pause in seconds (if `is_pause` is True). ### Example Usage ```python from streaming_tts import parse_pause_tags text = "Good morning! [pause:1s] How are you? [pause:500ms] I hope you're well." chunks = parse_pause_tags(text) for chunk in chunks: if chunk.is_pause: print(f"PAUSE: {chunk.pause_duration}s") else: print(f"TEXT: {chunk.text!r}") ``` ### Example Output ``` TEXT: 'Good morning! ' PAUSE: 1.0s TEXT: ' How are you? ' PAUSE: 0.5s TEXT: " I hope you're well." ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.