From 6e06bf97c017ffc16d991a93264afcb5b2b3659f Mon Sep 17 00:00:00 2001 From: Filipi Fuchter Date: Thu, 17 Apr 2025 17:21:29 -0300 Subject: [PATCH] Preventing emitting the UserStartedSpeaking event multiple times. --- src/pipecat/audio/turn/base_smart_turn.py | 4 ++++ src/pipecat/transports/base_input.py | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/pipecat/audio/turn/base_smart_turn.py b/src/pipecat/audio/turn/base_smart_turn.py index cc18b2880..0716d4e7c 100644 --- a/src/pipecat/audio/turn/base_smart_turn.py +++ b/src/pipecat/audio/turn/base_smart_turn.py @@ -57,6 +57,10 @@ class BaseSmartTurn(ABC): def set_sample_rate(self, sample_rate: int): self._sample_rate = sample_rate + @property + def speech_triggered(self) -> bool: + return self._speech_triggered + def append_audio(self, buffer: bytes, is_speech: bool) -> EndOfTurnState: # Convert raw audio to float32 format and append to the buffer audio_int16 = np.frombuffer(buffer, dtype=np.int16) diff --git a/src/pipecat/transports/base_input.py b/src/pipecat/transports/base_input.py index 5ff7723ec..767bc158c 100644 --- a/src/pipecat/transports/base_input.py +++ b/src/pipecat/transports/base_input.py @@ -196,12 +196,18 @@ class BaseInputTransport(FrameProcessor): and new_vad_state != VADState.STOPPING ): frame = None - if new_vad_state == VADState.SPEAKING: - frame = UserStartedSpeakingFrame() - # TODO: need to double check if this is the expected behavior - # Not triggering the UserStoppedSpeakingFrame if the turn analyser is enabled - elif new_vad_state == VADState.QUIET and not self.end_of_turn_analyzer: - frame = UserStoppedSpeakingFrame() + # If the turn analyser is enabled, this will prevent: + # - Creating the UserStoppedSpeakingFrame + # - Creating the UserStartedSpeakingFrame multiple times + can_create_user_frames = ( + self._params.end_of_turn_analyzer is None + or not self._params.end_of_turn_analyzer.speech_triggered + ) + if can_create_user_frames: + if new_vad_state == VADState.SPEAKING: + frame = UserStartedSpeakingFrame() + elif new_vad_state == VADState.QUIET: + frame = UserStoppedSpeakingFrame() if frame: await self._handle_user_interruption(frame)