Compare commits
4 Commits
mb/cli
...
fixing_sou
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37d15588b8 | ||
|
|
d2bf8321a0 | ||
|
|
781df7ac77 | ||
|
|
1d69a92ea1 |
@@ -5,6 +5,15 @@ All notable changes to **Pipecat** will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Added real-time throttling to the `BaseOutputTransport` when using audio mixer
|
||||||
|
to ensure audio frames (including silence) are emitted at the correct intervals.
|
||||||
|
This prevents unnecessary CPU usage and avoids flooding the output with silent
|
||||||
|
frames when no new audio is available.
|
||||||
|
|
||||||
## [0.0.66] - 2025-05-02
|
## [0.0.66] - 2025-05-02
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -435,6 +435,9 @@ class BaseOutputTransport(FrameProcessor):
|
|||||||
async def with_mixer(vad_stop_secs: float) -> AsyncGenerator[Frame, None]:
|
async def with_mixer(vad_stop_secs: float) -> AsyncGenerator[Frame, None]:
|
||||||
last_frame_time = 0
|
last_frame_time = 0
|
||||||
silence = b"\x00" * self._audio_chunk_size
|
silence = b"\x00" * self._audio_chunk_size
|
||||||
|
# chunk duration in seconds
|
||||||
|
chunk_duration = (10 * self._params.audio_out_10ms_chunks) / 1000.0
|
||||||
|
next_frame_time = time.time()
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
frame = self._audio_queue.get_nowait()
|
frame = self._audio_queue.get_nowait()
|
||||||
@@ -454,6 +457,11 @@ class BaseOutputTransport(FrameProcessor):
|
|||||||
num_channels=self._params.audio_out_channels,
|
num_channels=self._params.audio_out_channels,
|
||||||
)
|
)
|
||||||
yield frame
|
yield frame
|
||||||
|
# Throttle frame generation to maintain real-time pacing and avoid flooding with silence
|
||||||
|
wait = next_frame_time - time.time()
|
||||||
|
if wait > 0:
|
||||||
|
await asyncio.sleep(wait)
|
||||||
|
next_frame_time += chunk_duration
|
||||||
|
|
||||||
if self._mixer:
|
if self._mixer:
|
||||||
return with_mixer(BOT_VAD_STOP_SECS)
|
return with_mixer(BOT_VAD_STOP_SECS)
|
||||||
|
|||||||
@@ -484,9 +484,10 @@ class SmallWebRTCOutputTransport(BaseOutputTransport):
|
|||||||
self._params = params
|
self._params = params
|
||||||
|
|
||||||
async def start(self, frame: StartFrame):
|
async def start(self, frame: StartFrame):
|
||||||
await super().start(frame)
|
|
||||||
await self._client.setup(self._params, frame)
|
await self._client.setup(self._params, frame)
|
||||||
await self._client.connect()
|
await self._client.connect()
|
||||||
|
# Parent start.
|
||||||
|
await super().start(frame)
|
||||||
|
|
||||||
async def stop(self, frame: EndFrame):
|
async def stop(self, frame: EndFrame):
|
||||||
await super().stop(frame)
|
await super().stop(frame)
|
||||||
|
|||||||
Reference in New Issue
Block a user