From 5348ea3ac452c03b2aab704b4b84bffe70e1c18b Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sun, 23 Apr 2023 21:28:56 -0500 Subject: [PATCH] Add processing tone (#91931) * Add processing tone * Update homeassistant/components/voip/voip.py Co-authored-by: Paulus Schoutsen * Update homeassistant/components/voip/voip.py Co-authored-by: Paulus Schoutsen * Fix linting * Fix tests --------- Co-authored-by: Paulus Schoutsen --- homeassistant/components/voip/processing.pcm | Bin 0 -> 20938 bytes homeassistant/components/voip/voip.py | 32 ++++++++++++++++--- tests/components/voip/test_voip.py | 3 ++ 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 homeassistant/components/voip/processing.pcm diff --git a/homeassistant/components/voip/processing.pcm b/homeassistant/components/voip/processing.pcm new file mode 100644 index 0000000000000000000000000000000000000000..c76c8787e5c53025f249685ca12ca90f2401af00 GIT binary patch literal 20938 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 BKC}P; literal 0 HcmV?d00001 diff --git a/homeassistant/components/voip/voip.py b/homeassistant/components/voip/voip.py index 6a18ec6696b..67b1fcda7e5 100644 --- a/homeassistant/components/voip/voip.py +++ b/homeassistant/components/voip/voip.py @@ -82,6 +82,7 @@ class PipelineRtpDatagramProtocol(RtpDatagramProtocol): pipeline_timeout: float = 30.0, audio_timeout: float = 2.0, listening_tone_enabled: bool = True, + processing_tone_enabled: bool = True, ) -> None: """Set up pipeline RTP server.""" # STT expects 16Khz mono with 16-bit samples @@ -94,6 +95,7 @@ class PipelineRtpDatagramProtocol(RtpDatagramProtocol): self.pipeline_timeout = pipeline_timeout self.audio_timeout = audio_timeout self.listening_tone_enabled = listening_tone_enabled + self.processing_tone_enabled = processing_tone_enabled self._audio_queue: asyncio.Queue[bytes] = asyncio.Queue() self._context = context @@ -101,6 +103,7 @@ class PipelineRtpDatagramProtocol(RtpDatagramProtocol): self._pipeline_task: asyncio.Task | None = None self._session_id: str | None = None self._tone_bytes: bytes | None = None + self._processing_bytes: bytes | None = None def connection_made(self, transport): """Server is ready.""" @@ -157,6 +160,9 @@ class PipelineRtpDatagramProtocol(RtpDatagramProtocol): chunk_buffer, ): yield chunk + + if self.processing_tone_enabled: + await self._play_processing_tone() except asyncio.TimeoutError: # Expected after caller hangs up _LOGGER.debug("Audio timeout") @@ -289,7 +295,8 @@ class PipelineRtpDatagramProtocol(RtpDatagramProtocol): if self._tone_bytes is None: # Do I/O in executor self._tone_bytes = await self.hass.async_add_executor_job( - self._load_tone, + self._load_pcm, + "tone.pcm", ) await self.hass.async_add_executor_job( @@ -301,9 +308,26 @@ class PipelineRtpDatagramProtocol(RtpDatagramProtocol): ) ) - def _load_tone(self) -> bytes: - """Load raw tone audio (16Khz, 16-bit mono).""" - return (Path(__file__).parent / "tone.pcm").read_bytes() + async def _play_processing_tone(self) -> None: + """Play a tone to indicate that Home Assistant is processing the voice command.""" + if self._processing_bytes is None: + # Do I/O in executor + self._processing_bytes = await self.hass.async_add_executor_job( + self._load_pcm, + "processing.pcm", + ) + + await self.hass.async_add_executor_job( + partial( + self.send_audio, + self._processing_bytes, + **_RTP_AUDIO_SETTINGS, + ) + ) + + def _load_pcm(self, file_name: str) -> bytes: + """Load raw audio (16Khz, 16-bit mono).""" + return (Path(__file__).parent / file_name).read_bytes() class NotConfiguredRtpDatagramProtocol(RtpDatagramProtocol): diff --git a/tests/components/voip/test_voip.py b/tests/components/voip/test_voip.py index fe39fe9f567..c26d9a7a294 100644 --- a/tests/components/voip/test_voip.py +++ b/tests/components/voip/test_voip.py @@ -88,6 +88,7 @@ async def test_pipeline( voip_device, Context(), listening_tone_enabled=False, + processing_tone_enabled=False, ) rtp_protocol.transport = Mock() @@ -137,6 +138,7 @@ async def test_pipeline_timeout(hass: HomeAssistant, voip_device: VoIPDevice) -> Context(), pipeline_timeout=0.001, listening_tone_enabled=False, + processing_tone_enabled=False, ) transport = Mock(spec=["close"]) rtp_protocol.connection_made(transport) @@ -175,6 +177,7 @@ async def test_stt_stream_timeout(hass: HomeAssistant, voip_device: VoIPDevice) Context(), audio_timeout=0.001, listening_tone_enabled=False, + processing_tone_enabled=False, ) transport = Mock(spec=["close"]) rtp_protocol.connection_made(transport)