v2 - STT via Whisper for more precision and if nor available, twist to Vox
This commit is contained in:
@@ -302,6 +302,12 @@ def listen_once(stop_event: Optional[threading.Event] = None,
|
||||
|
||||
model_path = os.getenv("VOSK_MODEL_PATH", "")
|
||||
sample_rate = int(os.getenv("VOSK_SAMPLE_RATE", "16000"))
|
||||
# ALFRED_WYOMING_WHISPER_STT_V1: Vosk segments the utterance and
|
||||
# provides UI partials. Wyoming Whisper replaces only its final transcript.
|
||||
stt_engine = os.getenv("STT_ENGINE", "vosk").strip().lower()
|
||||
wyoming_enabled = stt_engine in ("wyoming", "wyoming_whisper", "whisper")
|
||||
wyoming_audio = bytearray()
|
||||
wyoming_max_bytes = max(16000, int(os.getenv("STT_MAX_AUDIO_SECONDS", "30")) * sample_rate * 2)
|
||||
if not model_path or not os.path.exists(model_path):
|
||||
return STTResult(error=f"Modèle Vosk introuvable: {model_path}")
|
||||
try:
|
||||
@@ -311,6 +317,9 @@ def listen_once(stop_event: Optional[threading.Event] = None,
|
||||
return STTResult(error=f"Init Vosk: {exc}")
|
||||
|
||||
def process(data: bytes) -> Optional[str]:
|
||||
# ALFRED_WYOMING_WHISPER_STT_V1: retain the exact PCM heard by Vosk.
|
||||
if wyoming_enabled and len(wyoming_audio) < wyoming_max_bytes:
|
||||
wyoming_audio.extend(data[:wyoming_max_bytes - len(wyoming_audio)])
|
||||
if on_level and data:
|
||||
try:
|
||||
a = np.frombuffer(data, dtype=np.int16).astype(np.float32)
|
||||
@@ -321,6 +330,25 @@ def listen_once(stop_event: Optional[threading.Event] = None,
|
||||
if rec.AcceptWaveform(data):
|
||||
text = (json.loads(rec.Result() or "{}").get("text") or "").strip()
|
||||
if text:
|
||||
if wyoming_enabled and wyoming_audio:
|
||||
# ALFRED_WYOMING_WHISPER_STT_V1: remote final STT, local fallback.
|
||||
try:
|
||||
from services.wyoming_stt import transcribe_pcm
|
||||
whisper_text = transcribe_pcm(
|
||||
bytes(wyoming_audio),
|
||||
host=os.getenv("WYOMING_WHISPER_HOST", "192.168.1.13"),
|
||||
port=int(os.getenv("WYOMING_WHISPER_PORT", "10300")),
|
||||
language=os.getenv("WYOMING_WHISPER_LANGUAGE", "fr"),
|
||||
sample_rate=sample_rate,
|
||||
connect_timeout=float(os.getenv("WYOMING_WHISPER_CONNECT_TIMEOUT", "3")),
|
||||
response_timeout=float(os.getenv("WYOMING_WHISPER_TIMEOUT", "20")),
|
||||
)
|
||||
if whisper_text:
|
||||
print(f"[ALFRED STT] Whisper final : {whisper_text!r} (Vosk : {text!r})", flush=True)
|
||||
return whisper_text
|
||||
print("[ALFRED STT] Whisper réponse vide, secours Vosk", flush=True)
|
||||
except Exception as exc:
|
||||
print(f"[ALFRED STT] Whisper indisponible, secours Vosk : {exc}", flush=True)
|
||||
return text
|
||||
elif on_partial:
|
||||
partial = json.loads(rec.PartialResult() or "{}").get("partial", "")
|
||||
|
||||
Reference in New Issue
Block a user