diff --git a/src/pipecat/transports/daily/transport.py b/src/pipecat/transports/daily/transport.py index 2798f6d5e..f33fa79ff 100644 --- a/src/pipecat/transports/daily/transport.py +++ b/src/pipecat/transports/daily/transport.py @@ -676,15 +676,19 @@ class DailyTransportClient(EventHandler): await asyncio.sleep(0.01) return None - async def register_audio_destination(self, destination: str): + async def register_audio_destination( + self, destination: str, auto_silence: Optional[bool] = True + ): """Register a custom audio destination for multi-track output. Args: destination: The destination identifier to register. + auto_silence: If True, the audio source inserts silence when no audio is available. + If False, the source waits for audio data. Defaults to True. """ params = (self._params.custom_audio_track_params or {}).get(destination) self._custom_audio_tracks[destination] = await self.add_custom_audio_track( - destination, params=params + destination, params=params, auto_silence=auto_silence ) publishing: Dict[str, Any] = {"customAudio": {destination: True}} if params and params.send_settings: @@ -831,7 +835,14 @@ class DailyTransportClient(EventHandler): self._camera_track = DailyVideoTrack(source=video_source, track=video_track) if self._params.audio_out_enabled and not self._microphone_track: - audio_source = CustomAudioSource(self._out_sample_rate, self._params.audio_out_channels) + logger.debug( + f"Creating custom audio source, auto silence {self._params.audio_out_insert_silence}" + ) + audio_source = CustomAudioSource( + self._out_sample_rate, + self._params.audio_out_channels, + self._params.audio_out_insert_silence, + ) audio_track = CustomAudioTrack(audio_source) self._microphone_track = DailyAudioTrack(source=audio_source, track=audio_track) @@ -1269,12 +1280,15 @@ class DailyTransportClient(EventHandler): self, track_name: str, params: Optional[DailyCustomAudioTrackParams] = None, + auto_silence: Optional[bool] = True, ) -> DailyAudioTrack: """Add a custom audio track for multi-stream output. Args: track_name: Name for the custom audio track. params: Optional per-track configuration for sample rate, channels, and sendSettings. + auto_silence: If True, the audio source inserts silence when no audio is available. + If False, the source waits for audio data. Defaults to True. Returns: The created DailyAudioTrack instance. @@ -1284,7 +1298,7 @@ class DailyTransportClient(EventHandler): sample_rate = params.sample_rate if params and params.sample_rate else self._out_sample_rate channels = params.channels if params else 1 - audio_source = CustomAudioSource(sample_rate, channels) + audio_source = CustomAudioSource(sample_rate, channels, auto_silence) audio_track = CustomAudioTrack(audio_source) diff --git a/src/pipecat/transports/smallwebrtc/transport.py b/src/pipecat/transports/smallwebrtc/transport.py index cfe2b7f49..b239f3831 100644 --- a/src/pipecat/transports/smallwebrtc/transport.py +++ b/src/pipecat/transports/smallwebrtc/transport.py @@ -126,7 +126,8 @@ class RawAudioTrack(AudioStreamTrack): """Return the next audio frame for WebRTC transmission. Returns: - An AudioFrame containing the next audio data or silence. + An AudioFrame containing the next audio data, or silence if the queue is empty + and ``insert_silence`` is True. """ # Compute required wait time for synchronization if self._timestamp > 0: diff --git a/src/pipecat/transports/tavus/transport.py b/src/pipecat/transports/tavus/transport.py index 872e6eefc..426b7f72c 100644 --- a/src/pipecat/transports/tavus/transport.py +++ b/src/pipecat/transports/tavus/transport.py @@ -417,16 +417,20 @@ class TavusTransportClient: return False return await self._client.write_audio_frame(frame) - async def register_audio_destination(self, destination: str): + async def register_audio_destination( + self, destination: str, auto_silence: Optional[bool] = True + ): """Register an audio destination for output. Args: destination: The destination identifier to register. + auto_silence: If True, the audio source inserts silence when no audio is available. + If False, the source waits for audio data. Defaults to True. """ if not self._client: return - await self._client.register_audio_destination(destination) + await self._client.register_audio_destination(destination, auto_silence=auto_silence) class TavusInputTransport(BaseInputTransport):