Forráskód Böngészése

fix(tts): only interrupt TTS on real ASR, filler detection won't stop playback

wenhongquan 3 hete
szülő
commit
d3e2c18286
1 módosított fájl, 10 hozzáadás és 14 törlés
  1. 10 14
      asr_agent/worker.py

+ 10 - 14
asr_agent/worker.py

@@ -521,15 +521,13 @@ class Worker:
         tts_track = rtc.LocalAudioTrack.create_audio_track("tts", tts_src)
         await self.room.local_participant.publish_track(tts_track)
         play_q: "asyncio.Queue[tuple[int, np.ndarray]]" = asyncio.Queue()
-        gen = 0                 # turn generation; bumped to flush in-flight audio
-        cur_gen = {"v": -1}    # generation currently being played by _player
+        cur_gen = {"v": 0}    # generation counter + currently playing gen
 
         async def _player():
             """Drain TTS audio sequentially on the single track."""
             while True:
                 g, audio = await play_q.get()
                 logger.info("PLAY start gen=%d samples=%d", g, len(audio))
-                cur_gen["v"] = g
                 for i in range(0, len(audio), 24000 // 50):
                     if cur_gen["v"] != g:
                         break
@@ -539,13 +537,12 @@ class Worker:
                         num_channels=1, samples_per_channel=len(c),
                     ))
                     await asyncio.sleep(0.018)
-                cur_gen["v"] = -1
                 logger.info("PLAY end gen=%d", g)
 
         player_task = asyncio.create_task(_player())
 
         async def _acc():
-            nonlocal busy, gen
+            nonlocal busy
             stream = rtc.AudioStream(track, sample_rate=sr, num_channels=1)
             fc = 0
             async for ev in stream:
@@ -565,12 +562,9 @@ class Worker:
 
                 if was_speech and vad.should_end() and vad.min_speech_met():
                     logger.info("[%s] VAD END blen=%d", sid, len(buf.buffer))
-                    gen += 1
-                    cur_gen["v"] = -1  # stop current playback immediately
-                    _drain_queue(play_q)
                     busy = True
                     try:
-                        await self._transcribe_and_respond(buf, play_q, gen)
+                        await self._transcribe_and_respond(buf, play_q, cur_gen)
                     except Exception:
                         logger.exception("[%s] transcribe failed", sid)
                     busy = False
@@ -579,12 +573,9 @@ class Worker:
 
                 if vad.in_speech and vad.total_samples >= int(MAX_SPEECH_S * sr):
                     logger.info("[%s] VAD MAX blen=%d", sid, len(buf.buffer))
-                    gen += 1
-                    cur_gen["v"] = -1
-                    _drain_queue(play_q)
                     busy = True
                     try:
-                        await self._transcribe_and_respond(buf, play_q, gen)
+                        await self._transcribe_and_respond(buf, play_q, cur_gen)
                     except Exception:
                         logger.exception("[%s] max failed", sid)
                     busy = False
@@ -606,7 +597,7 @@ class Worker:
             except Exception:
                 pass
 
-    async def _transcribe_and_respond(self, buf: AudioBuffer, play_q, gen: int):
+    async def _transcribe_and_respond(self, buf: AudioBuffer, play_q, cur_gen: dict):
         all_audio = buf.get_all()
         buf.clear()
         if len(all_audio) <= 1600:
@@ -616,6 +607,11 @@ class Worker:
         if not txt:
             return
 
+        # Real utterance — stop previous TTS, start new generation
+        cur_gen["v"] += 1
+        gen = cur_gen["v"]
+        _drain_queue(play_q)
+
         logger.info("ASR: %s", txt[:80])
         await self._send({"type": "utterance", "text": txt, "seq": 0})