Merge branch 'main' into sarvam/stt
This commit is contained in:
13
CHANGELOG.md
13
CHANGELOG.md
@@ -12,6 +12,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added supprt for Sarvam Speech-to-Text service (`SarvamSTTService`) with streaming WebSocket
|
- Added supprt for Sarvam Speech-to-Text service (`SarvamSTTService`) with streaming WebSocket
|
||||||
support for `saarika` (STT) and `saaras` (STT-translate) models.
|
support for `saarika` (STT) and `saaras` (STT-translate) models.
|
||||||
|
|
||||||
|
- Add support for `speaking_rate` input parameter in `GoogleHttpTTSService`.
|
||||||
|
|
||||||
|
- Added `enable_speaker_diarization` and `enable_language_identification` to
|
||||||
|
`SonioxSTTService`.
|
||||||
|
|
||||||
|
- Added `SpeechmaticsTTSService`, which uses Speechmatic's TTS API. Updated
|
||||||
|
examples 07a\* to use the new TTS service.
|
||||||
|
|
||||||
- Added support for including images or audio to LLM context messages using
|
- Added support for including images or audio to LLM context messages using
|
||||||
`LLMContext.create_image_message()` or `LLMContext.create_image_url_message()`
|
`LLMContext.create_image_message()` or `LLMContext.create_image_url_message()`
|
||||||
(not all LLMs support URLs) and `LLMContext.create_audio_message()`. For
|
(not all LLMs support URLs) and `LLMContext.create_audio_message()`. For
|
||||||
@@ -223,6 +231,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
- Removed `enable_non_final_tokens` and `max_non_final_tokens_duration_ms` from
|
||||||
|
`SonioxSTTService`.
|
||||||
|
|
||||||
- Removed the `aiohttp_session` arg from `SarvamTTSService` as it's no longer
|
- Removed the `aiohttp_session` arg from `SarvamTTSService` as it's no longer
|
||||||
used.
|
used.
|
||||||
|
|
||||||
@@ -1388,6 +1399,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- Added `SonioxSTTService` using Soniox's STT websocket API.
|
||||||
|
|
||||||
- Added `enable_emulated_vad_interruptions` to `LLMUserAggregatorParams`.
|
- Added `enable_emulated_vad_interruptions` to `LLMUserAggregatorParams`.
|
||||||
When user speech is emulated (e.g. when a transcription is received but
|
When user speech is emulated (e.g. when a transcription is received but
|
||||||
VAD doesn't detect speech), this parameter controls whether the emulated
|
VAD doesn't detect speech), this parameter controls whether the emulated
|
||||||
|
|||||||
26
README.md
26
README.md
@@ -72,19 +72,19 @@ Catch new features, interviews, and how-tos on our [Pipecat TV](https://www.yout
|
|||||||
|
|
||||||
## 🧩 Available services
|
## 🧩 Available services
|
||||||
|
|
||||||
| Category | Services |
|
| Category | Services |
|
||||||
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Speech-to-Text | [AssemblyAI](https://docs.pipecat.ai/server/services/stt/assemblyai), [AWS](https://docs.pipecat.ai/server/services/stt/aws), [Azure](https://docs.pipecat.ai/server/services/stt/azure), [Cartesia](https://docs.pipecat.ai/server/services/stt/cartesia), [Deepgram](https://docs.pipecat.ai/server/services/stt/deepgram), [ElevenLabs](https://docs.pipecat.ai/server/services/stt/elevenlabs), [Fal Wizper](https://docs.pipecat.ai/server/services/stt/fal), [Gladia](https://docs.pipecat.ai/server/services/stt/gladia), [Google](https://docs.pipecat.ai/server/services/stt/google), [Groq (Whisper)](https://docs.pipecat.ai/server/services/stt/groq), [NVIDIA Riva](https://docs.pipecat.ai/server/services/stt/riva), [OpenAI (Whisper)](https://docs.pipecat.ai/server/services/stt/openai), [SambaNova (Whisper)](https://docs.pipecat.ai/server/services/stt/sambanova), [Soniox](https://docs.pipecat.ai/server/services/stt/soniox), [Speechmatics](https://docs.pipecat.ai/server/services/stt/speechmatics), [Ultravox](https://docs.pipecat.ai/server/services/stt/ultravox), [Whisper](https://docs.pipecat.ai/server/services/stt/whisper) |
|
| Speech-to-Text | [AssemblyAI](https://docs.pipecat.ai/server/services/stt/assemblyai), [AWS](https://docs.pipecat.ai/server/services/stt/aws), [Azure](https://docs.pipecat.ai/server/services/stt/azure), [Cartesia](https://docs.pipecat.ai/server/services/stt/cartesia), [Deepgram](https://docs.pipecat.ai/server/services/stt/deepgram), [ElevenLabs](https://docs.pipecat.ai/server/services/stt/elevenlabs), [Fal Wizper](https://docs.pipecat.ai/server/services/stt/fal), [Gladia](https://docs.pipecat.ai/server/services/stt/gladia), [Google](https://docs.pipecat.ai/server/services/stt/google), [Groq (Whisper)](https://docs.pipecat.ai/server/services/stt/groq), [NVIDIA Riva](https://docs.pipecat.ai/server/services/stt/riva), [OpenAI (Whisper)](https://docs.pipecat.ai/server/services/stt/openai), [SambaNova (Whisper)](https://docs.pipecat.ai/server/services/stt/sambanova), [Soniox](https://docs.pipecat.ai/server/services/stt/soniox), [Speechmatics](https://docs.pipecat.ai/server/services/stt/speechmatics), [Ultravox](https://docs.pipecat.ai/server/services/stt/ultravox), [Whisper](https://docs.pipecat.ai/server/services/stt/whisper) |
|
||||||
| LLMs | [Anthropic](https://docs.pipecat.ai/server/services/llm/anthropic), [AWS](https://docs.pipecat.ai/server/services/llm/aws), [Azure](https://docs.pipecat.ai/server/services/llm/azure), [Cerebras](https://docs.pipecat.ai/server/services/llm/cerebras), [DeepSeek](https://docs.pipecat.ai/server/services/llm/deepseek), [Fireworks AI](https://docs.pipecat.ai/server/services/llm/fireworks), [Gemini](https://docs.pipecat.ai/server/services/llm/gemini), [Grok](https://docs.pipecat.ai/server/services/llm/grok), [Groq](https://docs.pipecat.ai/server/services/llm/groq), [Mistral](https://docs.pipecat.ai/server/services/llm/mistral), [NVIDIA NIM](https://docs.pipecat.ai/server/services/llm/nim), [Ollama](https://docs.pipecat.ai/server/services/llm/ollama), [OpenAI](https://docs.pipecat.ai/server/services/llm/openai), [OpenRouter](https://docs.pipecat.ai/server/services/llm/openrouter), [Perplexity](https://docs.pipecat.ai/server/services/llm/perplexity), [Qwen](https://docs.pipecat.ai/server/services/llm/qwen), [SambaNova](https://docs.pipecat.ai/server/services/llm/sambanova) [Together AI](https://docs.pipecat.ai/server/services/llm/together) |
|
| LLMs | [Anthropic](https://docs.pipecat.ai/server/services/llm/anthropic), [AWS](https://docs.pipecat.ai/server/services/llm/aws), [Azure](https://docs.pipecat.ai/server/services/llm/azure), [Cerebras](https://docs.pipecat.ai/server/services/llm/cerebras), [DeepSeek](https://docs.pipecat.ai/server/services/llm/deepseek), [Fireworks AI](https://docs.pipecat.ai/server/services/llm/fireworks), [Gemini](https://docs.pipecat.ai/server/services/llm/gemini), [Grok](https://docs.pipecat.ai/server/services/llm/grok), [Groq](https://docs.pipecat.ai/server/services/llm/groq), [Mistral](https://docs.pipecat.ai/server/services/llm/mistral), [NVIDIA NIM](https://docs.pipecat.ai/server/services/llm/nim), [Ollama](https://docs.pipecat.ai/server/services/llm/ollama), [OpenAI](https://docs.pipecat.ai/server/services/llm/openai), [OpenRouter](https://docs.pipecat.ai/server/services/llm/openrouter), [Perplexity](https://docs.pipecat.ai/server/services/llm/perplexity), [Qwen](https://docs.pipecat.ai/server/services/llm/qwen), [SambaNova](https://docs.pipecat.ai/server/services/llm/sambanova) [Together AI](https://docs.pipecat.ai/server/services/llm/together) |
|
||||||
| Text-to-Speech | [Async](https://docs.pipecat.ai/server/services/tts/asyncai), [AWS](https://docs.pipecat.ai/server/services/tts/aws), [Azure](https://docs.pipecat.ai/server/services/tts/azure), [Cartesia](https://docs.pipecat.ai/server/services/tts/cartesia), [Deepgram](https://docs.pipecat.ai/server/services/tts/deepgram), [ElevenLabs](https://docs.pipecat.ai/server/services/tts/elevenlabs), [Fish](https://docs.pipecat.ai/server/services/tts/fish), [Google](https://docs.pipecat.ai/server/services/tts/google), [Groq](https://docs.pipecat.ai/server/services/tts/groq), [Hume](https://docs.pipecat.ai/server/services/tts/hume), [Inworld](https://docs.pipecat.ai/server/services/tts/inworld), [LMNT](https://docs.pipecat.ai/server/services/tts/lmnt), [MiniMax](https://docs.pipecat.ai/server/services/tts/minimax), [Neuphonic](https://docs.pipecat.ai/server/services/tts/neuphonic), [NVIDIA Riva](https://docs.pipecat.ai/server/services/tts/riva), [OpenAI](https://docs.pipecat.ai/server/services/tts/openai), [Piper](https://docs.pipecat.ai/server/services/tts/piper), [PlayHT](https://docs.pipecat.ai/server/services/tts/playht), [Rime](https://docs.pipecat.ai/server/services/tts/rime), [Sarvam](https://docs.pipecat.ai/server/services/tts/sarvam), [XTTS](https://docs.pipecat.ai/server/services/tts/xtts) |
|
| Text-to-Speech | [Async](https://docs.pipecat.ai/server/services/tts/asyncai), [AWS](https://docs.pipecat.ai/server/services/tts/aws), [Azure](https://docs.pipecat.ai/server/services/tts/azure), [Cartesia](https://docs.pipecat.ai/server/services/tts/cartesia), [Deepgram](https://docs.pipecat.ai/server/services/tts/deepgram), [ElevenLabs](https://docs.pipecat.ai/server/services/tts/elevenlabs), [Fish](https://docs.pipecat.ai/server/services/tts/fish), [Google](https://docs.pipecat.ai/server/services/tts/google), [Groq](https://docs.pipecat.ai/server/services/tts/groq), [Hume](https://docs.pipecat.ai/server/services/tts/hume), [Inworld](https://docs.pipecat.ai/server/services/tts/inworld), [LMNT](https://docs.pipecat.ai/server/services/tts/lmnt), [MiniMax](https://docs.pipecat.ai/server/services/tts/minimax), [Neuphonic](https://docs.pipecat.ai/server/services/tts/neuphonic), [NVIDIA Riva](https://docs.pipecat.ai/server/services/tts/riva), [OpenAI](https://docs.pipecat.ai/server/services/tts/openai), [Piper](https://docs.pipecat.ai/server/services/tts/piper), [PlayHT](https://docs.pipecat.ai/server/services/tts/playht), [Rime](https://docs.pipecat.ai/server/services/tts/rime), [Sarvam](https://docs.pipecat.ai/server/services/tts/sarvam), [Speechmatics](https://docs.pipecat.ai/server/services/tts/speechmatics), [XTTS](https://docs.pipecat.ai/server/services/tts/xtts) |
|
||||||
| Speech-to-Speech | [AWS Nova Sonic](https://docs.pipecat.ai/server/services/s2s/aws), [Gemini Multimodal Live](https://docs.pipecat.ai/server/services/s2s/gemini), [OpenAI Realtime](https://docs.pipecat.ai/server/services/s2s/openai) |
|
| Speech-to-Speech | [AWS Nova Sonic](https://docs.pipecat.ai/server/services/s2s/aws), [Gemini Multimodal Live](https://docs.pipecat.ai/server/services/s2s/gemini), [OpenAI Realtime](https://docs.pipecat.ai/server/services/s2s/openai) |
|
||||||
| Transport | [Daily (WebRTC)](https://docs.pipecat.ai/server/services/transport/daily), [FastAPI Websocket](https://docs.pipecat.ai/server/services/transport/fastapi-websocket), [SmallWebRTCTransport](https://docs.pipecat.ai/server/services/transport/small-webrtc), [WebSocket Server](https://docs.pipecat.ai/server/services/transport/websocket-server), Local |
|
| Transport | [Daily (WebRTC)](https://docs.pipecat.ai/server/services/transport/daily), [FastAPI Websocket](https://docs.pipecat.ai/server/services/transport/fastapi-websocket), [SmallWebRTCTransport](https://docs.pipecat.ai/server/services/transport/small-webrtc), [WebSocket Server](https://docs.pipecat.ai/server/services/transport/websocket-server), Local |
|
||||||
| Serializers | [Plivo](https://docs.pipecat.ai/server/utilities/serializers/plivo), [Twilio](https://docs.pipecat.ai/server/utilities/serializers/twilio), [Telnyx](https://docs.pipecat.ai/server/utilities/serializers/telnyx) |
|
| Serializers | [Plivo](https://docs.pipecat.ai/server/utilities/serializers/plivo), [Twilio](https://docs.pipecat.ai/server/utilities/serializers/twilio), [Telnyx](https://docs.pipecat.ai/server/utilities/serializers/telnyx) |
|
||||||
| Video | [HeyGen](https://docs.pipecat.ai/server/services/video/heygen), [Tavus](https://docs.pipecat.ai/server/services/video/tavus), [Simli](https://docs.pipecat.ai/server/services/video/simli) |
|
| Video | [HeyGen](https://docs.pipecat.ai/server/services/video/heygen), [Tavus](https://docs.pipecat.ai/server/services/video/tavus), [Simli](https://docs.pipecat.ai/server/services/video/simli) |
|
||||||
| Memory | [mem0](https://docs.pipecat.ai/server/services/memory/mem0) |
|
| Memory | [mem0](https://docs.pipecat.ai/server/services/memory/mem0) |
|
||||||
| Vision & Image | [fal](https://docs.pipecat.ai/server/services/image-generation/fal), [Google Imagen](https://docs.pipecat.ai/server/services/image-generation/fal), [Moondream](https://docs.pipecat.ai/server/services/vision/moondream) |
|
| Vision & Image | [fal](https://docs.pipecat.ai/server/services/image-generation/fal), [Google Imagen](https://docs.pipecat.ai/server/services/image-generation/fal), [Moondream](https://docs.pipecat.ai/server/services/vision/moondream) |
|
||||||
| Audio Processing | [Silero VAD](https://docs.pipecat.ai/server/utilities/audio/silero-vad-analyzer), [Krisp](https://docs.pipecat.ai/server/utilities/audio/krisp-filter), [Koala](https://docs.pipecat.ai/server/utilities/audio/koala-filter), [ai-coustics](https://docs.pipecat.ai/server/utilities/audio/aic-filter) |
|
| Audio Processing | [Silero VAD](https://docs.pipecat.ai/server/utilities/audio/silero-vad-analyzer), [Krisp](https://docs.pipecat.ai/server/utilities/audio/krisp-filter), [Koala](https://docs.pipecat.ai/server/utilities/audio/koala-filter), [ai-coustics](https://docs.pipecat.ai/server/utilities/audio/aic-filter) |
|
||||||
| Analytics & Metrics | [OpenTelemetry](https://docs.pipecat.ai/server/utilities/opentelemetry), [Sentry](https://docs.pipecat.ai/server/services/analytics/sentry) |
|
| Analytics & Metrics | [OpenTelemetry](https://docs.pipecat.ai/server/utilities/opentelemetry), [Sentry](https://docs.pipecat.ai/server/services/analytics/sentry) |
|
||||||
|
|
||||||
📚 [View full services documentation →](https://docs.pipecat.ai/server/services/supported-services)
|
📚 [View full services documentation →](https://docs.pipecat.ai/server/services/supported-services)
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ from pipecat.utils.tracing.service_decorators import traced_tts
|
|||||||
# Suppress gRPC fork warnings
|
# Suppress gRPC fork warnings
|
||||||
os.environ["GRPC_ENABLE_FORK_SUPPORT"] = "false"
|
os.environ["GRPC_ENABLE_FORK_SUPPORT"] = "false"
|
||||||
|
|
||||||
from typing import AsyncGenerator, List, Literal, Optional
|
from typing import Any, AsyncGenerator, List, Literal, Mapping, Optional
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
@@ -248,7 +248,8 @@ class GoogleHttpTTSService(TTSService):
|
|||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
pitch: Voice pitch adjustment (e.g., "+2st", "-50%").
|
pitch: Voice pitch adjustment (e.g., "+2st", "-50%").
|
||||||
rate: Speaking rate adjustment (e.g., "slow", "fast", "125%").
|
rate: Speaking rate adjustment (e.g., "slow", "fast", "125%"). Used for SSML prosody tags (non-Chirp voices).
|
||||||
|
speaking_rate: Speaking rate for AudioConfig (Chirp/Journey voices). Range [0.25, 2.0].
|
||||||
volume: Volume adjustment (e.g., "loud", "soft", "+6dB").
|
volume: Volume adjustment (e.g., "loud", "soft", "+6dB").
|
||||||
emphasis: Emphasis level for the text.
|
emphasis: Emphasis level for the text.
|
||||||
language: Language for synthesis. Defaults to English.
|
language: Language for synthesis. Defaults to English.
|
||||||
@@ -258,6 +259,7 @@ class GoogleHttpTTSService(TTSService):
|
|||||||
|
|
||||||
pitch: Optional[str] = None
|
pitch: Optional[str] = None
|
||||||
rate: Optional[str] = None
|
rate: Optional[str] = None
|
||||||
|
speaking_rate: Optional[float] = None
|
||||||
volume: Optional[str] = None
|
volume: Optional[str] = None
|
||||||
emphasis: Optional[Literal["strong", "moderate", "reduced", "none"]] = None
|
emphasis: Optional[Literal["strong", "moderate", "reduced", "none"]] = None
|
||||||
language: Optional[Language] = Language.EN
|
language: Optional[Language] = Language.EN
|
||||||
@@ -291,6 +293,7 @@ class GoogleHttpTTSService(TTSService):
|
|||||||
self._settings = {
|
self._settings = {
|
||||||
"pitch": params.pitch,
|
"pitch": params.pitch,
|
||||||
"rate": params.rate,
|
"rate": params.rate,
|
||||||
|
"speaking_rate": params.speaking_rate,
|
||||||
"volume": params.volume,
|
"volume": params.volume,
|
||||||
"emphasis": params.emphasis,
|
"emphasis": params.emphasis,
|
||||||
"language": self.language_to_service_language(params.language)
|
"language": self.language_to_service_language(params.language)
|
||||||
@@ -360,6 +363,22 @@ class GoogleHttpTTSService(TTSService):
|
|||||||
"""
|
"""
|
||||||
return language_to_google_tts_language(language)
|
return language_to_google_tts_language(language)
|
||||||
|
|
||||||
|
async def _update_settings(self, settings: Mapping[str, Any]):
|
||||||
|
"""Override to handle speaking_rate updates for Chirp/Journey voices.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
settings: Dictionary of settings to update. Can include 'speaking_rate' (float)
|
||||||
|
"""
|
||||||
|
if "speaking_rate" in settings:
|
||||||
|
rate_value = float(settings["speaking_rate"])
|
||||||
|
if 0.25 <= rate_value <= 2.0:
|
||||||
|
self._settings["speaking_rate"] = rate_value
|
||||||
|
else:
|
||||||
|
logger.warning(
|
||||||
|
f"Invalid speaking_rate value: {rate_value}. Must be between 0.25 and 2.0"
|
||||||
|
)
|
||||||
|
await super()._update_settings(settings)
|
||||||
|
|
||||||
def _construct_ssml(self, text: str) -> str:
|
def _construct_ssml(self, text: str) -> str:
|
||||||
ssml = "<speak>"
|
ssml = "<speak>"
|
||||||
|
|
||||||
@@ -436,10 +455,17 @@ class GoogleHttpTTSService(TTSService):
|
|||||||
voice = texttospeech_v1.VoiceSelectionParams(
|
voice = texttospeech_v1.VoiceSelectionParams(
|
||||||
language_code=self._settings["language"], name=self._voice_id
|
language_code=self._settings["language"], name=self._voice_id
|
||||||
)
|
)
|
||||||
audio_config = texttospeech_v1.AudioConfig(
|
# Build audio config with conditional speaking_rate
|
||||||
audio_encoding=texttospeech_v1.AudioEncoding.LINEAR16,
|
audio_config_params = {
|
||||||
sample_rate_hertz=self.sample_rate,
|
"audio_encoding": texttospeech_v1.AudioEncoding.LINEAR16,
|
||||||
)
|
"sample_rate_hertz": self.sample_rate,
|
||||||
|
}
|
||||||
|
|
||||||
|
# For Chirp and Journey voices, include speaking_rate in AudioConfig
|
||||||
|
if (is_chirp_voice or is_journey_voice) and self._settings["speaking_rate"] is not None:
|
||||||
|
audio_config_params["speaking_rate"] = self._settings["speaking_rate"]
|
||||||
|
|
||||||
|
audio_config = texttospeech_v1.AudioConfig(**audio_config_params)
|
||||||
|
|
||||||
request = texttospeech_v1.SynthesizeSpeechRequest(
|
request = texttospeech_v1.SynthesizeSpeechRequest(
|
||||||
input=synthesis_input, voice=voice, audio_config=audio_config
|
input=synthesis_input, voice=voice, audio_config=audio_config
|
||||||
@@ -500,7 +526,7 @@ class GoogleTTSService(TTSService):
|
|||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
language: Language for synthesis. Defaults to English.
|
language: Language for synthesis. Defaults to English.
|
||||||
speaking_rate: The speaking rate, in the range [0.25, 4.0].
|
speaking_rate: The speaking rate, in the range [0.25, 2.0].
|
||||||
"""
|
"""
|
||||||
|
|
||||||
language: Optional[Language] = Language.EN
|
language: Optional[Language] = Language.EN
|
||||||
@@ -591,6 +617,22 @@ class GoogleTTSService(TTSService):
|
|||||||
"""
|
"""
|
||||||
return language_to_google_tts_language(language)
|
return language_to_google_tts_language(language)
|
||||||
|
|
||||||
|
async def _update_settings(self, settings: Mapping[str, Any]):
|
||||||
|
"""Override to handle speaking_rate updates for streaming API.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
settings: Dictionary of settings to update. Can include 'speaking_rate' (float)
|
||||||
|
"""
|
||||||
|
if "speaking_rate" in settings:
|
||||||
|
rate_value = float(settings["speaking_rate"])
|
||||||
|
if 0.25 <= rate_value <= 2.0:
|
||||||
|
self._settings["speaking_rate"] = rate_value
|
||||||
|
else:
|
||||||
|
logger.warning(
|
||||||
|
f"Invalid speaking_rate value: {rate_value}. Must be between 0.25 and 2.0"
|
||||||
|
)
|
||||||
|
await super()._update_settings(settings)
|
||||||
|
|
||||||
@traced_tts
|
@traced_tts
|
||||||
async def run_tts(self, text: str) -> AsyncGenerator[Frame, None]:
|
async def run_tts(self, text: str) -> AsyncGenerator[Frame, None]:
|
||||||
"""Generate streaming speech from text using Google's streaming API.
|
"""Generate streaming speech from text using Google's streaming API.
|
||||||
|
|||||||
Reference in New Issue
Block a user