v2.2 - Small improvement Interface change
This commit is contained in:
@@ -3,6 +3,7 @@ import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
import threading # ALFRED_DUPLEX_BARGE_IN_V1
|
||||
import wave
|
||||
|
||||
from wyoming.audio import AudioChunk, AudioStart, AudioStop
|
||||
@@ -71,10 +72,31 @@ async def synthesize(text, wav_path):
|
||||
await client.disconnect()
|
||||
|
||||
|
||||
# ALFRED_DUPLEX_BARGE_IN_V1: control only this module's aplay process.
|
||||
_playback_lock = threading.RLock()
|
||||
_playback_cancel = threading.Event()
|
||||
_playback_proc = None
|
||||
|
||||
|
||||
def stop_playback():
|
||||
"""Interrupts Piper playback or marks pending synth for cancellation."""
|
||||
global _playback_proc
|
||||
_playback_cancel.set()
|
||||
with _playback_lock:
|
||||
process = _playback_proc
|
||||
if process is not None and process.poll() is None:
|
||||
try:
|
||||
process.terminate()
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def speak(text):
|
||||
if not text or not text.strip():
|
||||
return
|
||||
|
||||
_playback_cancel.clear() # ALFRED_DUPLEX_BARGE_IN_V1
|
||||
|
||||
fd, wav_path = tempfile.mkstemp(
|
||||
prefix="alfred_piper_",
|
||||
suffix=".wav"
|
||||
@@ -90,11 +112,32 @@ def speak(text):
|
||||
|
||||
print("[ALFRED PIPER] Lecture...", flush=True)
|
||||
|
||||
subprocess.run(
|
||||
["aplay", "-q", "-D", AUDIO_DEVICE, wav_path],
|
||||
check=True,
|
||||
timeout=120
|
||||
)
|
||||
# ALFRED_DUPLEX_BARGE_IN_V1: allow a concurrent microphone detector
|
||||
# to terminate playback, without killing Hermes or the entire service.
|
||||
global _playback_proc
|
||||
if _playback_cancel.is_set():
|
||||
print("[ALFRED PIPER] Annulé avant lecture", flush=True)
|
||||
return
|
||||
proc = subprocess.Popen(["aplay", "-q", "-D", AUDIO_DEVICE, wav_path])
|
||||
with _playback_lock:
|
||||
_playback_proc = proc
|
||||
if _playback_cancel.is_set() and proc.poll() is None:
|
||||
proc.terminate()
|
||||
try:
|
||||
result = proc.wait(timeout=120)
|
||||
except subprocess.TimeoutExpired:
|
||||
proc.kill()
|
||||
proc.wait()
|
||||
raise
|
||||
finally:
|
||||
with _playback_lock:
|
||||
if _playback_proc is proc:
|
||||
_playback_proc = None
|
||||
if _playback_cancel.is_set():
|
||||
print("[ALFRED PIPER] Lecture interrompue par la voix", flush=True)
|
||||
return
|
||||
if result:
|
||||
raise subprocess.CalledProcessError(result, proc.args)
|
||||
|
||||
print(
|
||||
f"[ALFRED PIPER] Terminé en {time.monotonic() - start:.2f}s",
|
||||
|
||||
Reference in New Issue
Block a user