mirror of
https://github.com/home-assistant/core.git
synced 2025-07-08 13:57:10 +00:00
Add minimum command seconds to VAD (#124447)
This commit is contained in:
parent
c506188c13
commit
156e39ebb2
@ -78,6 +78,9 @@ class VoiceCommandSegmenter:
|
|||||||
speech_seconds: float = 0.3
|
speech_seconds: float = 0.3
|
||||||
"""Seconds of speech before voice command has started."""
|
"""Seconds of speech before voice command has started."""
|
||||||
|
|
||||||
|
command_seconds: float = 1.0
|
||||||
|
"""Minimum number of seconds for a voice command."""
|
||||||
|
|
||||||
silence_seconds: float = 0.7
|
silence_seconds: float = 0.7
|
||||||
"""Seconds of silence after voice command has ended."""
|
"""Seconds of silence after voice command has ended."""
|
||||||
|
|
||||||
@ -96,6 +99,9 @@ class VoiceCommandSegmenter:
|
|||||||
_speech_seconds_left: float = 0.0
|
_speech_seconds_left: float = 0.0
|
||||||
"""Seconds left before considering voice command as started."""
|
"""Seconds left before considering voice command as started."""
|
||||||
|
|
||||||
|
_command_seconds_left: float = 0.0
|
||||||
|
"""Seconds left before voice command could stop."""
|
||||||
|
|
||||||
_silence_seconds_left: float = 0.0
|
_silence_seconds_left: float = 0.0
|
||||||
"""Seconds left before considering voice command as stopped."""
|
"""Seconds left before considering voice command as stopped."""
|
||||||
|
|
||||||
@ -112,6 +118,7 @@ class VoiceCommandSegmenter:
|
|||||||
def reset(self) -> None:
|
def reset(self) -> None:
|
||||||
"""Reset all counters and state."""
|
"""Reset all counters and state."""
|
||||||
self._speech_seconds_left = self.speech_seconds
|
self._speech_seconds_left = self.speech_seconds
|
||||||
|
self._command_seconds_left = self.command_seconds - self.speech_seconds
|
||||||
self._silence_seconds_left = self.silence_seconds
|
self._silence_seconds_left = self.silence_seconds
|
||||||
self._timeout_seconds_left = self.timeout_seconds
|
self._timeout_seconds_left = self.timeout_seconds
|
||||||
self._reset_seconds_left = self.reset_seconds
|
self._reset_seconds_left = self.reset_seconds
|
||||||
@ -142,6 +149,9 @@ class VoiceCommandSegmenter:
|
|||||||
if self._speech_seconds_left <= 0:
|
if self._speech_seconds_left <= 0:
|
||||||
# Inside voice command
|
# Inside voice command
|
||||||
self.in_command = True
|
self.in_command = True
|
||||||
|
self._command_seconds_left = (
|
||||||
|
self.command_seconds - self.speech_seconds
|
||||||
|
)
|
||||||
self._silence_seconds_left = self.silence_seconds
|
self._silence_seconds_left = self.silence_seconds
|
||||||
_LOGGER.debug("Voice command started")
|
_LOGGER.debug("Voice command started")
|
||||||
else:
|
else:
|
||||||
@ -154,7 +164,8 @@ class VoiceCommandSegmenter:
|
|||||||
# Silence in command
|
# Silence in command
|
||||||
self._reset_seconds_left = self.reset_seconds
|
self._reset_seconds_left = self.reset_seconds
|
||||||
self._silence_seconds_left -= chunk_seconds
|
self._silence_seconds_left -= chunk_seconds
|
||||||
if self._silence_seconds_left <= 0:
|
self._command_seconds_left -= chunk_seconds
|
||||||
|
if (self._silence_seconds_left <= 0) and (self._command_seconds_left <= 0):
|
||||||
# Command finished successfully
|
# Command finished successfully
|
||||||
self.reset()
|
self.reset()
|
||||||
_LOGGER.debug("Voice command finished")
|
_LOGGER.debug("Voice command finished")
|
||||||
@ -163,6 +174,7 @@ class VoiceCommandSegmenter:
|
|||||||
# Speech in command.
|
# Speech in command.
|
||||||
# Reset silence counter if enough speech.
|
# Reset silence counter if enough speech.
|
||||||
self._reset_seconds_left -= chunk_seconds
|
self._reset_seconds_left -= chunk_seconds
|
||||||
|
self._command_seconds_left -= chunk_seconds
|
||||||
if self._reset_seconds_left <= 0:
|
if self._reset_seconds_left <= 0:
|
||||||
self._silence_seconds_left = self.silence_seconds
|
self._silence_seconds_left = self.silence_seconds
|
||||||
self._reset_seconds_left = self.reset_seconds
|
self._reset_seconds_left = self.reset_seconds
|
||||||
|
@ -206,3 +206,23 @@ def test_timeout() -> None:
|
|||||||
|
|
||||||
assert not segmenter.process(_ONE_SECOND * 0.5, False)
|
assert not segmenter.process(_ONE_SECOND * 0.5, False)
|
||||||
assert segmenter.timed_out
|
assert segmenter.timed_out
|
||||||
|
|
||||||
|
|
||||||
|
def test_command_seconds() -> None:
|
||||||
|
"""Test minimum number of seconds for voice command."""
|
||||||
|
|
||||||
|
segmenter = VoiceCommandSegmenter(
|
||||||
|
command_seconds=3, speech_seconds=1, silence_seconds=1, reset_seconds=1
|
||||||
|
)
|
||||||
|
|
||||||
|
assert segmenter.process(_ONE_SECOND, True)
|
||||||
|
|
||||||
|
# Silence counts towards total command length
|
||||||
|
assert segmenter.process(_ONE_SECOND * 0.5, False)
|
||||||
|
|
||||||
|
# Enough to finish command now
|
||||||
|
assert segmenter.process(_ONE_SECOND, True)
|
||||||
|
assert segmenter.process(_ONE_SECOND * 0.5, False)
|
||||||
|
|
||||||
|
# Silence to finish
|
||||||
|
assert not segmenter.process(_ONE_SECOND * 0.5, False)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user