|
|
@@ -365,36 +365,9 @@ class Worker:
|
|
|
vad = _SileroVAD()
|
|
|
busy = False
|
|
|
play_tasks: list[asyncio.Task] = []
|
|
|
- partial_task: asyncio.Task | None = None
|
|
|
-
|
|
|
- async def _partial_asr():
|
|
|
- """Streaming partial ASR during speech (xiaozhi-style interim)."""
|
|
|
- last_pos = 0
|
|
|
- try:
|
|
|
- while vad.in_speech:
|
|
|
- await asyncio.sleep(1.0)
|
|
|
- if busy or not vad.in_speech:
|
|
|
- continue
|
|
|
- total = len(buf.buffer)
|
|
|
- if total - last_pos < 4800: # 0.3s new audio minimum
|
|
|
- continue
|
|
|
- audio = buf.buffer[last_pos:]
|
|
|
- if len(audio) < 4800:
|
|
|
- continue
|
|
|
- loop = asyncio.get_running_loop()
|
|
|
- result = await loop.run_in_executor(None, self.asr.transcribe_array, audio)
|
|
|
- txt = result.get("text", "").strip()
|
|
|
- if txt:
|
|
|
- logger.info("[%s] partial ASR: %s", sid, txt[:60])
|
|
|
- await self._send({"type": "partial", "text": txt, "seq": 0})
|
|
|
- last_pos = total
|
|
|
- except asyncio.CancelledError:
|
|
|
- pass
|
|
|
- except Exception:
|
|
|
- logger.exception("[%s] partial_asr failed", sid)
|
|
|
|
|
|
async def _acc():
|
|
|
- nonlocal busy, play_tasks, partial_task
|
|
|
+ nonlocal busy, play_tasks
|
|
|
stream = rtc.AudioStream(track, sample_rate=sr, num_channels=1)
|
|
|
fc = 0
|
|
|
async for ev in stream:
|
|
|
@@ -407,12 +380,6 @@ class Worker:
|
|
|
was_speech = vad.in_speech
|
|
|
vad.process(arr)
|
|
|
|
|
|
- # Start partial ASR when speech begins
|
|
|
- if vad.in_speech and not was_speech:
|
|
|
- if partial_task and not partial_task.done():
|
|
|
- partial_task.cancel()
|
|
|
- partial_task = asyncio.create_task(_partial_asr())
|
|
|
-
|
|
|
if fc % 100 == 0:
|
|
|
logger.info("[%s] af#%d e=%.4f vad=%s blen=%d",
|
|
|
sid, fc, float(np.sqrt(np.mean(arr ** 2))),
|
|
|
@@ -420,8 +387,6 @@ 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))
|
|
|
- if partial_task and not partial_task.done():
|
|
|
- partial_task.cancel()
|
|
|
for pt in play_tasks:
|
|
|
if not pt.done():
|
|
|
pt.cancel()
|
|
|
@@ -437,8 +402,6 @@ 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))
|
|
|
- if partial_task and not partial_task.done():
|
|
|
- partial_task.cancel()
|
|
|
for pt in play_tasks:
|
|
|
if not pt.done():
|
|
|
pt.cancel()
|