Add wakeword-specific audio cues (detected / captured)
Two optional WAVs in the Hands-free section: "Sound: detected" plays when the wakeword fires (your cue to speak now) and "Sound: captured" plays when the command is taken (silence/stop). For hands-free sessions these take precedence over the general [sounds] cues, falling back to them and then to the built-in system sound. The general cues are relabelled "Audio cues (manual dictation)". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
87eee3f103
commit
8e1419e828
@ -80,6 +80,8 @@ class Config:
|
||||
wakeword_enabled: bool = False
|
||||
wakeword_uri: str = "tcp://127.0.0.1:10400"
|
||||
wakeword_model: str = "okay_computer"
|
||||
wakeword_sound_detected: str = "" # WAV played when the wakeword fires (speak now)
|
||||
wakeword_sound_done: str = "" # WAV played when the command is captured
|
||||
# workflows
|
||||
workflows: list[Workflow] = field(default_factory=list)
|
||||
|
||||
@ -172,6 +174,8 @@ def load(path: Path = CONFIG_PATH) -> Config:
|
||||
wakeword_enabled=bool(ww.get("enabled", False)),
|
||||
wakeword_uri=ww.get("uri", "tcp://127.0.0.1:10400"),
|
||||
wakeword_model=ww.get("model", "okay_computer"),
|
||||
wakeword_sound_detected=ww.get("sound_detected", ""),
|
||||
wakeword_sound_done=ww.get("sound_done", ""),
|
||||
)
|
||||
|
||||
for entry in data.get("workflow", []):
|
||||
@ -279,6 +283,8 @@ def save(cfg: Config, path: Path = CONFIG_PATH) -> None:
|
||||
"enabled": cfg.wakeword_enabled,
|
||||
"uri": cfg.wakeword_uri,
|
||||
"model": cfg.wakeword_model,
|
||||
"sound_detected": cfg.wakeword_sound_detected,
|
||||
"sound_done": cfg.wakeword_sound_done,
|
||||
},
|
||||
"stt": {"active": cfg.stt_active},
|
||||
"stt_engine": [
|
||||
@ -398,6 +404,11 @@ threshold = 0.82 # 0..1 fuzzy-match strictness (higher = stricter)
|
||||
enabled = false
|
||||
uri = "tcp://127.0.0.1:10400"
|
||||
model = "okay_computer"
|
||||
# Optional WAV cues for hands-free use (override the [sounds] cues when the
|
||||
# wakeword triggers): played when the wakeword fires (speak now) and when the
|
||||
# command is captured.
|
||||
sound_detected = ""
|
||||
sound_done = ""
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Speech-to-text engines (presets). The active one is used for transcription.
|
||||
|
||||
@ -147,12 +147,15 @@ class Daemon:
|
||||
sound.play(fallback=sound_name)
|
||||
|
||||
def _play_cue(self, cue: str) -> None:
|
||||
"""Play the user's WAV for 'before'/'after', else a built-in system sound."""
|
||||
"""Play an audio cue. Hands-free (wakeword) sessions prefer the wakeword
|
||||
sounds, then the general [sounds] cues, then a built-in system sound."""
|
||||
from . import sound
|
||||
if cue == "before":
|
||||
sound.play(self.cfg.sound_before, fallback="device-added")
|
||||
custom = (self.cfg.wakeword_sound_detected if self._session_silent else "") or self.cfg.sound_before
|
||||
sound.play(custom, fallback="device-added")
|
||||
else:
|
||||
sound.play(self.cfg.sound_after, fallback="complete")
|
||||
custom = (self.cfg.wakeword_sound_done if self._session_silent else "") or self.cfg.sound_after
|
||||
sound.play(custom, fallback="complete")
|
||||
|
||||
# -- recording control ----------------------------------------------------
|
||||
def start_dictation(self, workflow: Workflow | None = None) -> None:
|
||||
|
||||
@ -765,8 +765,15 @@ class SettingsDialog:
|
||||
box = Gtk.Box(spacing=10); box.pack_start(self.ww_test_btn, False, False, 0); box.pack_start(self.ww_test_lbl, False, False, 0)
|
||||
_labeled(page, "", box)
|
||||
|
||||
self.ww_snd_detected = self._sound_field(
|
||||
page, "Sound: detected", self.cfg.wakeword_sound_detected,
|
||||
"Played right after the wakeword is recognised — your cue that Blitztext is listening, speak now.")
|
||||
self.ww_snd_done = self._sound_field(
|
||||
page, "Sound: captured", self.cfg.wakeword_sound_done,
|
||||
"Played when your command is captured (silence or stop) — confirms your input was taken.")
|
||||
|
||||
page.pack_start(Gtk.Separator(), False, False, 8)
|
||||
page.pack_start(Gtk.Label(label="Audio cues", xalign=0.0), False, False, 2)
|
||||
page.pack_start(Gtk.Label(label="Audio cues (manual dictation)", xalign=0.0), False, False, 2)
|
||||
self.snd_before = self._sound_field(
|
||||
page, "Play before", self.cfg.sound_before,
|
||||
"Sound played when recording starts — your confirmation that Blitztext is listening.")
|
||||
@ -1118,6 +1125,8 @@ class SettingsDialog:
|
||||
c.wakeword_enabled = self.ww_enabled.get_active()
|
||||
c.wakeword_uri = self.ww_uri.get_text().strip()
|
||||
c.wakeword_model = _combo_text(self.ww_model)
|
||||
c.wakeword_sound_detected = self.ww_snd_detected.get_filename() or ""
|
||||
c.wakeword_sound_done = self.ww_snd_done.get_filename() or ""
|
||||
c.mic = self._selected_mic_name()
|
||||
c.output = self.gen_output.get_active_text() or "type"
|
||||
c.language = self.gen_lang.get_text().strip()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user