Tidying up the Hume example and service
This commit is contained in:
@@ -9,9 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added `HumeTTSService` for text-to-speech synthesis using Hume AI's expressive voice models.
|
- Added `HumeTTSService` for text-to-speech synthesis using Hume AI's
|
||||||
Provides high-quality, emotionally expressive speech synthesis with support for various voice models.
|
expressive voice models. Provides high-quality, emotionally expressive speech
|
||||||
Includes example in `examples/foundational/07ad-interruptible-hume.py`.
|
synthesis with support for various voice models. Includes example in
|
||||||
|
`examples/foundational/07ad-interruptible-hume.py`.
|
||||||
|
|
||||||
- Added `hume` optional dependency group for Hume AI TTS integration.
|
- Added `hume` optional dependency group for Hume AI TTS integration.
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,12 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
from pipecat.audio.turn.smart_turn.base_smart_turn import SmartTurnParams
|
||||||
|
from pipecat.audio.turn.smart_turn.local_smart_turn_v3 import LocalSmartTurnAnalyzerV3
|
||||||
|
from pipecat.audio.vad.silero import SileroVADAnalyzer
|
||||||
|
from pipecat.audio.vad.vad_analyzer import VADParams
|
||||||
from pipecat.frames.frames import LLMRunFrame
|
from pipecat.frames.frames import LLMRunFrame
|
||||||
from pipecat.pipeline.pipeline import Pipeline
|
from pipecat.pipeline.pipeline import Pipeline
|
||||||
from pipecat.pipeline.runner import PipelineRunner
|
from pipecat.pipeline.runner import PipelineRunner
|
||||||
@@ -32,14 +37,21 @@ transport_params = {
|
|||||||
"daily": lambda: DailyParams(
|
"daily": lambda: DailyParams(
|
||||||
audio_in_enabled=True,
|
audio_in_enabled=True,
|
||||||
audio_out_enabled=True,
|
audio_out_enabled=True,
|
||||||
vad_analyzer=SileroVADAnalyzer(),
|
vad_analyzer=SileroVADAnalyzer(params=VADParams(stop_secs=0.2)),
|
||||||
|
turn_analyzer=LocalSmartTurnAnalyzerV3(params=SmartTurnParams()),
|
||||||
),
|
),
|
||||||
"twilio": lambda: FastAPIWebsocketParams(
|
"twilio": lambda: FastAPIWebsocketParams(
|
||||||
audio_in_enabled=True,
|
audio_in_enabled=True,
|
||||||
audio_out_enabled=True,
|
audio_out_enabled=True,
|
||||||
vad_analyzer=SileroVADAnalyzer(),
|
vad_analyzer=SileroVADAnalyzer(params=VADParams(stop_secs=0.2)),
|
||||||
|
turn_analyzer=LocalSmartTurnAnalyzerV3(params=SmartTurnParams()),
|
||||||
|
),
|
||||||
|
"webrtc": lambda: TransportParams(
|
||||||
|
audio_in_enabled=True,
|
||||||
|
audio_out_enabled=True,
|
||||||
|
vad_analyzer=SileroVADAnalyzer(params=VADParams(stop_secs=0.2)),
|
||||||
|
turn_analyzer=LocalSmartTurnAnalyzerV3(params=SmartTurnParams()),
|
||||||
),
|
),
|
||||||
"webrtc": lambda: TransportParams(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -108,7 +120,6 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
|
|||||||
async def bot(runner_args: RunnerArguments):
|
async def bot(runner_args: RunnerArguments):
|
||||||
"""Main bot entry point compatible with Pipecat Cloud."""
|
"""Main bot entry point compatible with Pipecat Cloud."""
|
||||||
transport = await create_transport(runner_args, transport_params)
|
transport = await create_transport(runner_args, transport_params)
|
||||||
|
|
||||||
await run_bot(transport, runner_args)
|
await run_bot(transport, runner_args)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -201,12 +201,20 @@ class HumeTTSService(TTSService):
|
|||||||
if len(self._audio_bytes) < self.chunk_size:
|
if len(self._audio_bytes) < self.chunk_size:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
yield TTSAudioRawFrame(self._audio_bytes, self.sample_rate, 1)
|
frame = TTSAudioRawFrame(
|
||||||
|
audio=self._audio_bytes,
|
||||||
|
sample_rate=self.sample_rate,
|
||||||
|
num_channels=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
yield frame
|
||||||
|
|
||||||
self._audio_bytes = b""
|
self._audio_bytes = b""
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f"{self} error generating TTS: {e}")
|
logger.exception(f"{self} error generating TTS: {e}")
|
||||||
yield ErrorFrame(error=str(e))
|
await self.push_error(ErrorFrame(f"Error generating TTS: {e}"))
|
||||||
finally:
|
finally:
|
||||||
# Ensure TTFB timer is stopped even on early failures
|
# Ensure TTFB timer is stopped even on early failures
|
||||||
|
await self.stop_ttfb_metrics()
|
||||||
yield TTSStoppedFrame()
|
yield TTSStoppedFrame()
|
||||||
|
|||||||
Reference in New Issue
Block a user