Merge pull request #1238 from pipecat-ai/aleix/stt-mute-filter-ignore-input-audio-frames
STTMuteFilter: ignore audio frames so no transcriptions are generated
This commit is contained in:
@@ -5,6 +5,13 @@ 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
|
||||||
|
|
||||||
|
- Fixed a `STTMuteFilter` issue that would not mute user audio frames causing
|
||||||
|
transcriptions to be generated by the STT service.
|
||||||
|
|
||||||
## [0.0.57] - 2025-02-14
|
## [0.0.57] - 2025-02-14
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ from pipecat.frames.frames import (
|
|||||||
Frame,
|
Frame,
|
||||||
FunctionCallInProgressFrame,
|
FunctionCallInProgressFrame,
|
||||||
FunctionCallResultFrame,
|
FunctionCallResultFrame,
|
||||||
|
InputAudioRawFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
StartInterruptionFrame,
|
StartInterruptionFrame,
|
||||||
StopInterruptionFrame,
|
StopInterruptionFrame,
|
||||||
@@ -185,6 +186,7 @@ class STTMuteFilter(FrameProcessor):
|
|||||||
StopInterruptionFrame,
|
StopInterruptionFrame,
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
UserStoppedSpeakingFrame,
|
UserStoppedSpeakingFrame,
|
||||||
|
InputAudioRawFrame,
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
# Only pass VAD-related frames when not muted
|
# Only pass VAD-related frames when not muted
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ from pipecat.frames.frames import (
|
|||||||
BotStoppedSpeakingFrame,
|
BotStoppedSpeakingFrame,
|
||||||
FunctionCallInProgressFrame,
|
FunctionCallInProgressFrame,
|
||||||
FunctionCallResultFrame,
|
FunctionCallResultFrame,
|
||||||
|
InputAudioRawFrame,
|
||||||
STTMuteFrame,
|
STTMuteFrame,
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
UserStoppedSpeakingFrame,
|
UserStoppedSpeakingFrame,
|
||||||
)
|
)
|
||||||
from pipecat.processors.filters.stt_mute_filter import STTMuteConfig, STTMuteFilter, STTMuteStrategy
|
from pipecat.processors.filters.stt_mute_filter import STTMuteConfig, STTMuteFilter, STTMuteStrategy
|
||||||
from pipecat.tests.utils import run_test
|
from pipecat.tests.utils import SleepFrame, run_test
|
||||||
|
|
||||||
|
|
||||||
class TestSTTMuteFilter(unittest.IsolatedAsyncioTestCase):
|
class TestSTTMuteFilter(unittest.IsolatedAsyncioTestCase):
|
||||||
@@ -26,10 +27,14 @@ class TestSTTMuteFilter(unittest.IsolatedAsyncioTestCase):
|
|||||||
frames_to_send = [
|
frames_to_send = [
|
||||||
BotStartedSpeakingFrame(), # First bot speech starts
|
BotStartedSpeakingFrame(), # First bot speech starts
|
||||||
UserStartedSpeakingFrame(), # Should be suppressed
|
UserStartedSpeakingFrame(), # Should be suppressed
|
||||||
|
InputAudioRawFrame(
|
||||||
|
audio=b"", sample_rate=16000, num_channels=1
|
||||||
|
), # Should be suppressed
|
||||||
UserStoppedSpeakingFrame(), # Should be suppressed
|
UserStoppedSpeakingFrame(), # Should be suppressed
|
||||||
BotStoppedSpeakingFrame(), # First bot speech ends
|
BotStoppedSpeakingFrame(), # First bot speech ends
|
||||||
BotStartedSpeakingFrame(), # Second bot speech
|
BotStartedSpeakingFrame(), # Second bot speech
|
||||||
UserStartedSpeakingFrame(), # Should pass through
|
UserStartedSpeakingFrame(), # Should pass through
|
||||||
|
InputAudioRawFrame(audio=b"", sample_rate=16000, num_channels=1), # Should pass through
|
||||||
UserStoppedSpeakingFrame(), # Should pass through
|
UserStoppedSpeakingFrame(), # Should pass through
|
||||||
BotStoppedSpeakingFrame(),
|
BotStoppedSpeakingFrame(),
|
||||||
]
|
]
|
||||||
@@ -41,6 +46,7 @@ class TestSTTMuteFilter(unittest.IsolatedAsyncioTestCase):
|
|||||||
STTMuteFrame, # mute=False
|
STTMuteFrame, # mute=False
|
||||||
BotStartedSpeakingFrame,
|
BotStartedSpeakingFrame,
|
||||||
UserStartedSpeakingFrame, # Now passes through
|
UserStartedSpeakingFrame, # Now passes through
|
||||||
|
InputAudioRawFrame, # Now passes through
|
||||||
UserStoppedSpeakingFrame, # Now passes through
|
UserStoppedSpeakingFrame, # Now passes through
|
||||||
BotStoppedSpeakingFrame,
|
BotStoppedSpeakingFrame,
|
||||||
]
|
]
|
||||||
@@ -57,12 +63,19 @@ class TestSTTMuteFilter(unittest.IsolatedAsyncioTestCase):
|
|||||||
frames_to_send = [
|
frames_to_send = [
|
||||||
BotStartedSpeakingFrame(), # First speech starts
|
BotStartedSpeakingFrame(), # First speech starts
|
||||||
UserStartedSpeakingFrame(), # Should be suppressed
|
UserStartedSpeakingFrame(), # Should be suppressed
|
||||||
|
InputAudioRawFrame(
|
||||||
|
audio=b"", sample_rate=16000, num_channels=1
|
||||||
|
), # Should be suppressed
|
||||||
UserStoppedSpeakingFrame(), # Should be suppressed
|
UserStoppedSpeakingFrame(), # Should be suppressed
|
||||||
BotStoppedSpeakingFrame(), # First speech ends
|
BotStoppedSpeakingFrame(), # First speech ends
|
||||||
UserStartedSpeakingFrame(), # Should pass through
|
UserStartedSpeakingFrame(), # Should pass through
|
||||||
|
InputAudioRawFrame(audio=b"", sample_rate=16000, num_channels=1), # Should pass through
|
||||||
UserStoppedSpeakingFrame(), # Should pass through
|
UserStoppedSpeakingFrame(), # Should pass through
|
||||||
BotStartedSpeakingFrame(), # Second speech starts
|
BotStartedSpeakingFrame(), # Second speech starts
|
||||||
UserStartedSpeakingFrame(), # Should be suppressed again
|
UserStartedSpeakingFrame(), # Should be suppressed again
|
||||||
|
InputAudioRawFrame(
|
||||||
|
audio=b"", sample_rate=16000, num_channels=1
|
||||||
|
), # Should be suppressed again
|
||||||
UserStoppedSpeakingFrame(), # Should be suppressed again
|
UserStoppedSpeakingFrame(), # Should be suppressed again
|
||||||
BotStoppedSpeakingFrame(), # Second speech ends
|
BotStoppedSpeakingFrame(), # Second speech ends
|
||||||
]
|
]
|
||||||
@@ -73,6 +86,7 @@ class TestSTTMuteFilter(unittest.IsolatedAsyncioTestCase):
|
|||||||
BotStoppedSpeakingFrame,
|
BotStoppedSpeakingFrame,
|
||||||
STTMuteFrame, # mute=False
|
STTMuteFrame, # mute=False
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
|
InputAudioRawFrame,
|
||||||
UserStoppedSpeakingFrame,
|
UserStoppedSpeakingFrame,
|
||||||
BotStartedSpeakingFrame,
|
BotStartedSpeakingFrame,
|
||||||
STTMuteFrame, # mute=True
|
STTMuteFrame, # mute=True
|
||||||
@@ -134,15 +148,23 @@ class TestSTTMuteFilter(unittest.IsolatedAsyncioTestCase):
|
|||||||
|
|
||||||
frames_to_send = [
|
frames_to_send = [
|
||||||
UserStartedSpeakingFrame(), # Should be suppressed (starts muted)
|
UserStartedSpeakingFrame(), # Should be suppressed (starts muted)
|
||||||
|
InputAudioRawFrame(
|
||||||
|
audio=b"", sample_rate=16000, num_channels=1
|
||||||
|
), # Should be suppressed
|
||||||
UserStoppedSpeakingFrame(), # Should be suppressed
|
UserStoppedSpeakingFrame(), # Should be suppressed
|
||||||
BotStartedSpeakingFrame(), # First bot speech
|
BotStartedSpeakingFrame(), # First bot speech
|
||||||
UserStartedSpeakingFrame(), # Should be suppressed
|
UserStartedSpeakingFrame(), # Should be suppressed
|
||||||
|
InputAudioRawFrame(
|
||||||
|
audio=b"", sample_rate=16000, num_channels=1
|
||||||
|
), # Should be suppressed
|
||||||
UserStoppedSpeakingFrame(), # Should be suppressed
|
UserStoppedSpeakingFrame(), # Should be suppressed
|
||||||
BotStoppedSpeakingFrame(), # First speech ends, unmutes
|
BotStoppedSpeakingFrame(), # First speech ends, unmutes
|
||||||
UserStartedSpeakingFrame(), # Should pass through
|
UserStartedSpeakingFrame(), # Should pass through
|
||||||
|
InputAudioRawFrame(audio=b"", sample_rate=16000, num_channels=1), # Should pass through
|
||||||
UserStoppedSpeakingFrame(), # Should pass through
|
UserStoppedSpeakingFrame(), # Should pass through
|
||||||
BotStartedSpeakingFrame(), # Second speech
|
BotStartedSpeakingFrame(), # Second speech
|
||||||
UserStartedSpeakingFrame(), # Should pass through
|
UserStartedSpeakingFrame(), # Should pass through
|
||||||
|
InputAudioRawFrame(audio=b"", sample_rate=16000, num_channels=1), # Should pass through
|
||||||
UserStoppedSpeakingFrame(), # Should pass through
|
UserStoppedSpeakingFrame(), # Should pass through
|
||||||
BotStoppedSpeakingFrame(),
|
BotStoppedSpeakingFrame(),
|
||||||
]
|
]
|
||||||
@@ -153,9 +175,11 @@ class TestSTTMuteFilter(unittest.IsolatedAsyncioTestCase):
|
|||||||
BotStoppedSpeakingFrame,
|
BotStoppedSpeakingFrame,
|
||||||
STTMuteFrame, # mute=False after first speech
|
STTMuteFrame, # mute=False after first speech
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
|
InputAudioRawFrame,
|
||||||
UserStoppedSpeakingFrame,
|
UserStoppedSpeakingFrame,
|
||||||
BotStartedSpeakingFrame,
|
BotStartedSpeakingFrame,
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
|
InputAudioRawFrame,
|
||||||
UserStoppedSpeakingFrame,
|
UserStoppedSpeakingFrame,
|
||||||
BotStoppedSpeakingFrame,
|
BotStoppedSpeakingFrame,
|
||||||
]
|
]
|
||||||
@@ -190,23 +214,30 @@ class TestSTTMuteFilter(unittest.IsolatedAsyncioTestCase):
|
|||||||
|
|
||||||
frames_to_send = [
|
frames_to_send = [
|
||||||
UserStartedSpeakingFrame(), # Should pass through
|
UserStartedSpeakingFrame(), # Should pass through
|
||||||
|
InputAudioRawFrame(audio=b"", sample_rate=16000, num_channels=1), # Should pass through
|
||||||
UserStoppedSpeakingFrame(), # Should pass through
|
UserStoppedSpeakingFrame(), # Should pass through
|
||||||
BotStartedSpeakingFrame(), # Bot starts speaking
|
BotStartedSpeakingFrame(), # Bot starts speaking
|
||||||
UserStartedSpeakingFrame(), # Should be suppressed
|
UserStartedSpeakingFrame(), # Should be suppressed
|
||||||
|
InputAudioRawFrame(
|
||||||
|
audio=b"", sample_rate=16000, num_channels=1
|
||||||
|
), # Should be suppressed
|
||||||
UserStoppedSpeakingFrame(), # Should be suppressed
|
UserStoppedSpeakingFrame(), # Should be suppressed
|
||||||
BotStoppedSpeakingFrame(), # Bot stops speaking
|
BotStoppedSpeakingFrame(), # Bot stops speaking
|
||||||
UserStartedSpeakingFrame(), # Should pass through
|
UserStartedSpeakingFrame(), # Should pass through
|
||||||
|
InputAudioRawFrame(audio=b"", sample_rate=16000, num_channels=1), # Should pass through
|
||||||
UserStoppedSpeakingFrame(), # Should pass through
|
UserStoppedSpeakingFrame(), # Should pass through
|
||||||
]
|
]
|
||||||
|
|
||||||
expected_returned_frames = [
|
expected_returned_frames = [
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
|
InputAudioRawFrame,
|
||||||
UserStoppedSpeakingFrame,
|
UserStoppedSpeakingFrame,
|
||||||
BotStartedSpeakingFrame,
|
BotStartedSpeakingFrame,
|
||||||
STTMuteFrame, # mute=True
|
STTMuteFrame, # mute=True
|
||||||
BotStoppedSpeakingFrame,
|
BotStoppedSpeakingFrame,
|
||||||
STTMuteFrame, # mute=False
|
STTMuteFrame, # mute=False
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
|
InputAudioRawFrame,
|
||||||
UserStoppedSpeakingFrame,
|
UserStoppedSpeakingFrame,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user