From 9485601e1852c81c8f8158789d8fa849e8f329b0 Mon Sep 17 00:00:00 2001 From: kassam Date: Fri, 24 Apr 2026 15:23:19 +0400 Subject: [PATCH] Update 2026-04-24 15:23:19 --- Config/config_Voice.json | 17 +- .../session_001_2026-04-22/alerts.json | 1 - .../session_001_2026-04-22/commands.json | 8 - .../session_001_2026-04-22/detections.json | 1 - .../session_001_2026-04-22/places.json | 1 - .../session_002_2026-04-22/alerts.json | 1 - .../session_002_2026-04-22/commands.json | 8 - .../session_002_2026-04-22/detections.json | 1 - .../session_002_2026-04-22/places.json | 1 - .../session_003_2026-04-22/alerts.json | 1 - .../session_003_2026-04-22/commands.json | 8 - .../session_003_2026-04-22/detections.json | 1 - .../session_003_2026-04-22/places.json | 1 - .../session_004_2026-04-22/alerts.json | 1 - .../session_004_2026-04-22/commands.json | 8 - .../session_004_2026-04-22/detections.json | 1 - .../session_004_2026-04-22/places.json | 1 - Data/Voice/Recordings/unk_1776999824.wav | Bin 0 -> 96300 bytes Data/Voice/Recordings/unk_1777000093.wav | Bin 0 -> 39340 bytes Voice/marcus_voice.py | 238 +++++++++++++++--- 20 files changed, 214 insertions(+), 85 deletions(-) delete mode 100644 Data/Brain/Sessions/session_001_2026-04-22/alerts.json delete mode 100644 Data/Brain/Sessions/session_001_2026-04-22/commands.json delete mode 100644 Data/Brain/Sessions/session_001_2026-04-22/detections.json delete mode 100644 Data/Brain/Sessions/session_001_2026-04-22/places.json delete mode 100644 Data/Brain/Sessions/session_002_2026-04-22/alerts.json delete mode 100644 Data/Brain/Sessions/session_002_2026-04-22/commands.json delete mode 100644 Data/Brain/Sessions/session_002_2026-04-22/detections.json delete mode 100644 Data/Brain/Sessions/session_002_2026-04-22/places.json delete mode 100644 Data/Brain/Sessions/session_003_2026-04-22/alerts.json delete mode 100644 Data/Brain/Sessions/session_003_2026-04-22/commands.json delete mode 100644 Data/Brain/Sessions/session_003_2026-04-22/detections.json delete mode 100644 Data/Brain/Sessions/session_003_2026-04-22/places.json delete mode 100644 Data/Brain/Sessions/session_004_2026-04-22/alerts.json delete mode 100644 Data/Brain/Sessions/session_004_2026-04-22/commands.json delete mode 100644 Data/Brain/Sessions/session_004_2026-04-22/detections.json delete mode 100644 Data/Brain/Sessions/session_004_2026-04-22/places.json create mode 100644 Data/Voice/Recordings/unk_1776999824.wav create mode 100644 Data/Voice/Recordings/unk_1777000093.wav diff --git a/Config/config_Voice.json b/Config/config_Voice.json index 0332956..ce58843 100644 --- a/Config/config_Voice.json +++ b/Config/config_Voice.json @@ -5,11 +5,14 @@ "target_sample_rate": 16000 }, "stt": { - "backend": "faster_whisper", + "_backend_comment": "'faster_whisper' (Whisper base.en int8 on CPU) or 'moonshine' (useful-sensors Moonshine via onnxruntime). Moonshine has a different error profile — worth trying when Whisper consistently mishears commands as short hallucinations like 'Yes.', 'Bye.', 'It.'. Moonshine requires `pip install moonshine-voice` on the Jetson.", + "backend": "moonshine", + "moonshine_language": "en", "_comment": "Custom energy wake detector (instant, no ML) + faster-whisper base.en int8 on CPU for command transcription. Wake fires on any 0.2-1.5s speech burst; Whisper only runs on the recorded command, so it's ~10x less busy than a Whisper-polling setup.", - "_mode_comment": "Three modes: 'wake_and_command' = instant acoustic wake detector (no ML) hears 'Sanad', THEN records a ~2s command, transcribes once — fastest, most reliable on G1 mic. 'always_on' = continuous VAD → Whisper every utterance, dispatch all (chatty, LLM gets every noise). 'always_on_gated' = continuous transcribe, dispatch only utterances containing 'Sanad' (Sanad-style but Whisper hallucinates commands from TTS echo on G1 mic, creating feedback loops — keep as opt-in, not default).", + "_mode_comment": "Three modes. 'always_on_gated' (default, Sanad-style) = continuously transcribe+log every utterance to logs/transcript.log. Dispatch only when wake word is in the utterance. 'Sanad ' dispatches the cmd. Bare 'Sanad' → speak 'Yes' and treat the NEXT utterance as the command (within await_command_timeout_sec). 'wake_and_command' = classic acoustic wake first, then record a separate command (no always-listen overhead). 'always_on' = transcribe + dispatch everything, no gate (chatty).", "mode": "wake_and_command", + "await_command_timeout_sec": 10.0, "_always_on_comment": "Tunables for always_on mode only. Lower entry threshold catches quieter speech (since there's no wake gate). silence_duration is how long of quiet closes an utterance. idle_log_sec is how often to print an ambient-level summary so you can see what the mic is hearing even when nobody is talking.", "always_on_speech_entry_rms": 150.0, @@ -36,7 +39,7 @@ "_whisper_temp_comment": "Temperature fallback: Whisper first tries greedy (T=0). If the output fails its own confidence gates, it retries at 0.2, then 0.4. On noisy audio this often rescues a bad greedy decode — the small random noise in softmax helps unstick the decoder from a local minimum.", "_whisper_gates_comment": "Looser than faster-whisper defaults (0.6 / -1.0 / 2.4) because G1 far-field mic audio has poor SNR and frequently falls below the default log-prob. A segment is dropped only if (no_speech_prob > 0.85 AND log_prob < -1.8) — lets more shaky-but-real speech through. Hallucination risk is cushioned by the GARBAGE_PATTERNS filter downstream and the fuzzy-match to command_vocab.", "_initial_prompt_comment": "EMPTY BY DEFAULT. Any bias prompt leaks — on unclear/short audio Whisper echoes the prompt verbatim as the transcription (seen repeatedly: 'This is a robot assistant' hallucinated from <1s of ambient). Clean, unbiased decode is worse at recognising 'Sanad' specifically but doesn't produce phantom commands. Set to a single short cue if you want nudging and can tolerate occasional echoes.", - "whisper_initial_prompt": "Robot voice command.", + "whisper_initial_prompt": "Sanad. Turn left. Turn right. Move forward. Move back. Stop. Sit down. Stand up. Wave hello. Follow me. Come here. Go home. Look around. What do you see.", "_vocab_comment": "Tunable vocab lists for voice post-processing. wake_words = fuzzy variants of the wake word 'Sanad' Whisper might produce (used by always_on_gated mode). command_vocab = canonical commands the voice layer fuzzy-matches transcriptions against (e.g. 'Turn right up' → 'turn right' so command_parser's regex catches it). Edit these to add new vocabulary — NO code change required.", "wake_words": [ @@ -85,21 +88,21 @@ "_wake_comment": "Custom energy-based wake detector with adaptive noise floor. speech_threshold is a FLOOR — the effective trigger is max(speech_threshold, ambient_baseline * wake_adaptive_mult). CRITICAL: speech_threshold must be ABOVE your room's ambient RMS, else state stays in SPEAKING forever and baseline can't learn. Check logs — if `baseline=0` and `state=SPEAKING` persist with peak values well below your 'Sanad' peaks, raise this floor. Normal G1 room: 80-150. Noisy room (fans, HVAC): 300-500. Measured-here room ambient ≈ 250-350, so 400 gives margin.", - "speech_threshold": 400.0, + "speech_threshold": 200.0, "min_word_duration": 0.25, "max_word_duration": 2.50, "post_silence": 0.20, "wake_cooldown": 1.00, "wake_chunk_ms": 50, "wake_adaptive_window_n": 50, - "wake_adaptive_mult": 3.0, + "wake_adaptive_mult": 2.0, "wake_diag_log_sec": 3.0, "wake_ack": "tts", "_wake_ack_comment": "tts = spoken 'Yes' via TtsMaker (~1.7s G1 firmware latency). none = silent, relies on terminal print (fast).", - "_wake_verify_comment": "DISABLED for speed. When enabled, runs a ~3s Whisper decode on each wake burst and rejects non-/sa-/ speech — good for filtering coughs/claps, but adds 3s latency per wake. With it off, every acoustic wake fires — faster response, more false wakes from loud noises (but those drop silently at the 'no speech' recording stage, so user impact is near-zero). Set true again if background noise is triggering too many false wakes.", - "wake_verify_enabled": false, + "_wake_verify_comment": "ENABLED — confirm each acoustic wake with a lightweight Whisper decode on the triggering burst BEFORE speaking 'Yes' / opening the record window. Accept if the transcription contains any wake-word variant OR starts with s/sh/z (Whisper's consistent signature for mishearing 'Sanad' as 'Stop', 'Sand', 'Set', etc.). Reject pure noise (empty whisper) and clearly non-/sa-/ speech silently. Cost: ~1-2s extra per wake for the Whisper decode. Trade-off: slower wake response, but no 'Yes' played on stray loud noises. Set false if you prefer speed over false-wake filtering.", + "wake_verify_enabled": true, "_vad_comment": "Hysteretic VAD with adaptive ambient baseline. speech_entry_rms = 'user started talking' floor; silence_exit_rms = 'user stopped' floor (must be < entry). Adaptive: we reuse the wake detector's baseline (measured during idle silence) to bump both up if the room is noisier than the floors. Tune for YOUR ambient: check `command audio: peak=X rms=Y` in voice.log — speech_entry should sit roughly 2× above ambient rms. Room-measured ambient ≈ 250-350 → entry 400 with margin.", diff --git a/Data/Brain/Sessions/session_001_2026-04-22/alerts.json b/Data/Brain/Sessions/session_001_2026-04-22/alerts.json deleted file mode 100644 index 0637a08..0000000 --- a/Data/Brain/Sessions/session_001_2026-04-22/alerts.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_001_2026-04-22/commands.json b/Data/Brain/Sessions/session_001_2026-04-22/commands.json deleted file mode 100644 index a420e30..0000000 --- a/Data/Brain/Sessions/session_001_2026-04-22/commands.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "time": "15:29:59", - "cmd": "hello, can you hear me", - "response": "Hello, can you hear me?", - "duration_s": 4.69 - } -] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_001_2026-04-22/detections.json b/Data/Brain/Sessions/session_001_2026-04-22/detections.json deleted file mode 100644 index 0637a08..0000000 --- a/Data/Brain/Sessions/session_001_2026-04-22/detections.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_001_2026-04-22/places.json b/Data/Brain/Sessions/session_001_2026-04-22/places.json deleted file mode 100644 index 9e26dfe..0000000 --- a/Data/Brain/Sessions/session_001_2026-04-22/places.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/Data/Brain/Sessions/session_002_2026-04-22/alerts.json b/Data/Brain/Sessions/session_002_2026-04-22/alerts.json deleted file mode 100644 index 0637a08..0000000 --- a/Data/Brain/Sessions/session_002_2026-04-22/alerts.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_002_2026-04-22/commands.json b/Data/Brain/Sessions/session_002_2026-04-22/commands.json deleted file mode 100644 index b5aa0ad..0000000 --- a/Data/Brain/Sessions/session_002_2026-04-22/commands.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "time": "15:37:37", - "cmd": "turn left", - "response": "local command", - "duration_s": 0.0 - } -] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_002_2026-04-22/detections.json b/Data/Brain/Sessions/session_002_2026-04-22/detections.json deleted file mode 100644 index 0637a08..0000000 --- a/Data/Brain/Sessions/session_002_2026-04-22/detections.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_002_2026-04-22/places.json b/Data/Brain/Sessions/session_002_2026-04-22/places.json deleted file mode 100644 index 9e26dfe..0000000 --- a/Data/Brain/Sessions/session_002_2026-04-22/places.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/Data/Brain/Sessions/session_003_2026-04-22/alerts.json b/Data/Brain/Sessions/session_003_2026-04-22/alerts.json deleted file mode 100644 index 0637a08..0000000 --- a/Data/Brain/Sessions/session_003_2026-04-22/alerts.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_003_2026-04-22/commands.json b/Data/Brain/Sessions/session_003_2026-04-22/commands.json deleted file mode 100644 index 6f3c242..0000000 --- a/Data/Brain/Sessions/session_003_2026-04-22/commands.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "time": "16:22:54", - "cmd": "hi", - "response": "Hello! I am Sanad. How can I help you?", - "duration_s": 0.0 - } -] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_003_2026-04-22/detections.json b/Data/Brain/Sessions/session_003_2026-04-22/detections.json deleted file mode 100644 index 0637a08..0000000 --- a/Data/Brain/Sessions/session_003_2026-04-22/detections.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_003_2026-04-22/places.json b/Data/Brain/Sessions/session_003_2026-04-22/places.json deleted file mode 100644 index 9e26dfe..0000000 --- a/Data/Brain/Sessions/session_003_2026-04-22/places.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/Data/Brain/Sessions/session_004_2026-04-22/alerts.json b/Data/Brain/Sessions/session_004_2026-04-22/alerts.json deleted file mode 100644 index 0637a08..0000000 --- a/Data/Brain/Sessions/session_004_2026-04-22/alerts.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_004_2026-04-22/commands.json b/Data/Brain/Sessions/session_004_2026-04-22/commands.json deleted file mode 100644 index 67b8bc6..0000000 --- a/Data/Brain/Sessions/session_004_2026-04-22/commands.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "time": "16:24:12", - "cmd": "what do you see", - "response": "I see a man sitting in front of a desk with a backpack and a helmet on it. There is also a red and white object hanging on the wall behind him.", - "duration_s": 0.0 - } -] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_004_2026-04-22/detections.json b/Data/Brain/Sessions/session_004_2026-04-22/detections.json deleted file mode 100644 index 0637a08..0000000 --- a/Data/Brain/Sessions/session_004_2026-04-22/detections.json +++ /dev/null @@ -1 +0,0 @@ -[] \ No newline at end of file diff --git a/Data/Brain/Sessions/session_004_2026-04-22/places.json b/Data/Brain/Sessions/session_004_2026-04-22/places.json deleted file mode 100644 index 9e26dfe..0000000 --- a/Data/Brain/Sessions/session_004_2026-04-22/places.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/Data/Voice/Recordings/unk_1776999824.wav b/Data/Voice/Recordings/unk_1776999824.wav new file mode 100644 index 0000000000000000000000000000000000000000..b2eeef9e4411c0f8a699dbcbb243ed90d409c40f GIT binary patch literal 96300 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 None: + """Write one line to logs/transcript.log. + action: 'HEARD' / 'WAKE' / 'CMD' / 'UNK' / ... + """ + _transcript_log.info("%-5s %s", action, (text or "").strip()) + + # Module-level vocabulary containers. EMPTY on import — populated by # VoiceModule.__init__ from Config/config_Voice.json::stt.{wake_words, # command_vocab, garbage_patterns}. Config is the single source of truth; @@ -248,13 +272,35 @@ class VoiceModule: if self._mic_gain != 1.0: log.info("mic_gain = %.2fx (applied to all mic reads)", self._mic_gain) - # ── faster-whisper (lazy-init on first wake) ── + # ── STT backend selection ── + # "faster_whisper" (default): Whisper base.en int8 on CPU via CTranslate2. + # "moonshine": useful-sensors Moonshine via moonshine-voice + # + onnxruntime. Different training, different + # error profile from Whisper — useful when + # Whisper's hallucinations (short "Yes.", + # "Bye.", "It.") are the failure mode. + self._backend_name = str(self._stt.get("backend", "faster_whisper")).lower() + + # Lazy-init handles — concrete model loads on first wake so startup + # stays light. `False` marks a failed init so we don't keep retrying. self._fw = None + self._moonshine = None + + # ── Two-turn wake state (always_on_gated mode) ── + # self._awaiting_command: False = listening for wake. + # True = wake heard, next utterance is + # the command. Cleared after the + # command dispatches or after + # await_command_timeout_sec seconds + # so a stray "Sanad" doesn't arm + # forever. + self._awaiting_command = False + self._await_deadline = 0.0 self._running = False self._thread = None self._cooldown_until = 0.0 - log.info("VoiceModule initialized (wake=custom, stt=faster-whisper)") + log.info("VoiceModule initialized (wake=custom, stt=%s)", self._backend_name) # ─── gain-applied mic read ──────────────────────────── @@ -299,6 +345,49 @@ class VoiceModule: self._fw = None return self._fw + # ─── lazy moonshine init ────────────────────────────── + + def _get_moonshine(self): + """ + Load Moonshine (useful-sensors) on first use. Requires + `pip install moonshine-voice` on the target. Returns None if + the package isn't available — caller should fall back. + """ + if self._moonshine is not None: + return self._moonshine if self._moonshine is not False else None + lang = self._stt.get("moonshine_language", "en") + log.info("Loading Moonshine: language=%s", lang) + try: + from moonshine_voice import Transcriber + from moonshine_voice.download import download_model + model_path, model_arch = download_model(language=lang) + self._moonshine = Transcriber( + model_path=model_path, model_arch=model_arch, + ) + log.info("Moonshine ready: arch=%s", model_arch) + except Exception as e: + log.error("Moonshine init failed: %s — voice will be wake-only", e) + self._moonshine = False + return None + return self._moonshine + + def _moonshine_decode(self, audio_f32: np.ndarray) -> str: + """Run Moonshine one-shot on a float32 16kHz mono array. Returns ''.""" + m = self._get_moonshine() + if m is None: + return "" + try: + result = m.transcribe_without_streaming( + audio_data=audio_f32, sample_rate=self._sample_rate, + ) + lines = getattr(result, "lines", None) or [] + text = " ".join(getattr(ln, "text", "") for ln in lines).strip() + log.info("moonshine: text=%r", text[:80]) + return text + except Exception as e: + log.error("moonshine transcribe failed: %s", e) + return "" + # ─── command recording ──────────────────────────────── def _record_command(self) -> np.ndarray: @@ -445,7 +534,10 @@ class VoiceModule: # ─── transcription ──────────────────────────────────── def _transcribe(self, audio_i16: np.ndarray) -> str: - """int16 PCM → Whisper transcription. Returns '' on no-speech/noise.""" + """int16 PCM → STT transcription. Returns '' on no-speech/noise.""" + if self._backend_name == "moonshine": + return self._transcribe_moonshine(audio_i16, lenient=False) + fw = self._get_fw() if fw is None: return "" @@ -596,6 +688,9 @@ class VoiceModule: The downside (no Sanad nudge) is fine here because the acoustic detector has already gated out non-speech. """ + if self._backend_name == "moonshine": + return self._transcribe_moonshine(audio_i16, lenient=True) + fw = self._get_fw() if fw is None: return "" @@ -634,6 +729,39 @@ class VoiceModule: log.error("whisper-raw transcribe failed: %s", e) return "" + def _transcribe_moonshine(self, audio_i16: np.ndarray, lenient: bool) -> str: + """ + Moonshine decode path. Light DSP only (DC-removal + peak-normalize); + Moonshine has its own internal feature extraction, and the Whisper- + oriented pre-emphasis / 80 Hz HPF are not helpful here. + + lenient=True mirrors _transcribe_raw: skip the garbage-pattern and + min-length filters so wake verify can see short /s-/ phonetic signals. + lenient=False applies the same rejection pipeline as _transcribe. + """ + if audio_i16.size == 0: + return "" + + audio_f32 = audio_i16.astype(np.float32) / 32768.0 + audio_f32 = audio_f32 - np.mean(audio_f32) + peak = float(np.abs(audio_f32).max()) + if peak > 1e-4 and peak < 0.7: + audio_f32 = audio_f32 * (0.7 / peak) + + text = self._moonshine_decode(audio_f32) + if not text: + return "" + if lenient: + return text + + low = text.lower().strip().rstrip(".!?,") + vocab_exact = {c.lower() for c in COMMAND_VOCAB} + if low in GARBAGE_PATTERNS or len(low) < _MIN_TRANSCRIPTION_LENGTH: + if low not in WAKE_WORDS and low not in vocab_exact: + log.info("Rejecting likely noise transcription: %r", text) + return "" + return text + # ─── command transcription ──────────────────────────── def _transcribe_command(self, audio_i16: np.ndarray) -> str: @@ -925,47 +1053,89 @@ class VoiceModule: text = self._transcribe_command(audio) if audio.size else "" if text: log.info("HEARD: %r", text) - # Gated mode: only dispatch if the wake word was - # spoken. Everything is still logged above so the - # operator has full visibility into what the mic - # is picking up. - if gated and not _has_wake_word(text): - log.info(" (no wake word — not dispatched)") - else: - if gated: - command = _strip_wake_word(text) - if command != text: - log.info(" wake-stripped: %r → %r", - text, command) - # Bare wake word ("Sanad.", "Sanad") → - # speak a "Yes" ack, do NOT call the - # brain (it would hallucinate a random - # response from a 1-word prompt). - if not command: - log.info(" wake-only utterance — speaking ack") - try: - self._audio.speak( - self._messages.get("wake_heard", "Yes") - ) - except Exception as e: - log.warning("wake-ack TTS failed: %s", e) - continue - else: - command = text + _log_transcript("HEARD", text) - # Normalize near-misses ("Turn right up" → - # "turn right") so command_parser's regex - # fast-path can hit without an LLM round-trip. + # ── Two-turn gated flow ──────────────────── + # State A — listening for wake: + # non-wake utterance → log only, do not dispatch + # "Sanad " → strip + dispatch now + # "Sanad" alone → speak "Yes", switch to + # state B ("awaiting command") + # State B — awaiting command (after Yes): + # any utterance → dispatch as the command, + # regardless of wake word. + # Then back to state A. + # + # This matches the SanadVoice/gemini_interact + # pattern: always transcribe + log every word, + # say "yes" on wake, treat the next utterance + # as the command. + # Timeout stale await-command state + if self._awaiting_command and time.time() > self._await_deadline: + log.info(" [awaiting-cmd] timed out — back to wake-listen") + self._awaiting_command = False + + if self._awaiting_command: + # State B — next utterance is the command. + command = _strip_wake_word(text) # drop accidental "Sanad," + if not command: + command = text # safety: never drop to empty command = self._normalize_command(command) - + log.info(" [awaiting-cmd] dispatching: %r", command) + _log_transcript("CMD", command) + self._awaiting_command = False print(f' [Sanad] heard: "{command}"') if self._on_command: try: self._on_command(command, "en") except Exception as e: log.error("on_command: %s", e, exc_info=True) + continue + + # State A — listening for wake. + if gated and not _has_wake_word(text): + log.info(" (no wake word — logged only)") + _log_transcript("IGN", text) + continue + + if gated: + command = _strip_wake_word(text) + if command != text: + log.info(" wake-stripped: %r → %r", + text, command) + if not command: + # Bare "Sanad" — speak "Yes" and arm + # the next-utterance-as-command trigger. + log.info(" wake heard alone — speaking 'Yes', " + "next utterance will be treated as command") + _log_transcript("WAKE", text) + try: + self._audio.speak( + self._messages.get("wake_heard", "Yes") + ) + except Exception as e: + log.warning("wake-ack TTS failed: %s", e) + self._awaiting_command = True + self._await_deadline = time.time() + float( + self._stt.get("await_command_timeout_sec", 10.0) + ) + continue + else: + command = text + + # Sanad + command in one utterance (e.g. + # "Sanad, turn left") → fuzzy-normalize + dispatch. + command = self._normalize_command(command) + _log_transcript("CMD", command) + print(f' [Sanad] heard: "{command}"') + if self._on_command: + try: + self._on_command(command, "en") + except Exception as e: + log.error("on_command: %s", e, exc_info=True) else: log.info("utterance rejected (empty/garbage after Whisper)") + _log_transcript("UNK", "(empty)") else: idle_peak_rms = max(idle_peak_rms, rms) idle_sum_rms += rms