Files
kefu/deploy/review-voice-20260918/verify_real_offline_asr.py
T
2026-09-21 10:34:06 +08:00

67 lines
3.0 KiB
Python

"""Real inference using ONLY explicitly generated synthetic Chinese speech."""
from pathlib import Path
import hashlib
import io
import json
import socket
import sys
import time
from unittest import mock
sys.dont_write_bytecode = True
sys.path.insert(0, r"C:\wechat_rpa")
import av
import numpy as np
import pysilk
import voice_transcription as voice
root = Path(__file__).resolve().parent
wav = root / "synthetic-chinese.wav"
silk = root / "synthetic-chinese.silk"
amr = root / "synthetic-chinese.amr"
audio = voice._decode_audio(wav.read_bytes())
pcm = (np.clip(audio, -1, 1) * 32767).astype("<i2")
with silk.open("wb") as target:
pysilk.encode(io.BytesIO(pcm.tobytes()), target, 16000, 24000, tencent=True)
with av.open(str(amr), "w", format="amr") as target:
stream = target.add_stream("libopencore_amrnb", rate=8000)
stream.bit_rate = 12200
stream.layout = "mono"
downsampled = pcm[::2]
for offset in range(0, len(downsampled), 160):
samples = downsampled[offset:offset + 160]
if len(samples) < 160:
samples = np.pad(samples, (0, 160 - len(samples)))
frame = av.AudioFrame.from_ndarray(np.ascontiguousarray(samples).reshape(1, -1), format="s16", layout="mono")
frame.sample_rate = 8000
for packet in stream.encode(frame):
target.mux(packet)
for packet in stream.encode(None):
target.mux(packet)
attempts = []
def no_network(*args, **kwargs):
attempts.append("network")
raise AssertionError("Synthetic offline ASR forbids network")
report = {"input_kind": "local Microsoft Huihui Desktop synthetic speech",
"input_text": "这是自动语音识别测试。请问今天下午三点可以预约吗?我想了解预约流程。",
"network_attempts": attempts, "results": []}
recognizer = voice.OfflineRecognizer(Path(r"C:\wechat_rpa\assets\asr\faster-whisper-base"))
with mock.patch.object(socket.socket, "connect", no_network), mock.patch.object(socket.socket, "connect_ex", no_network), mock.patch.object(socket, "getaddrinfo", no_network):
for path in (wav, silk, amr):
started = time.monotonic()
try:
result = voice.transcribe_file(path, allowed_roots=[root], recognizer=recognizer)
result["meaning_verified"] = "预约" in result["text"] and any(value in result["text"] for value in ("三点", "3点"))
except voice.VoiceTranscriptionError as exc:
result = {"status": "error", "error_code": exc.code, "meaning_verified": False}
result["format"] = path.suffix
result["elapsed_seconds"] = round(time.monotonic() - started, 3)
result["input_sha256"] = hashlib.sha256(path.read_bytes()).hexdigest()
report["results"].append(result)
print(json.dumps(result, ensure_ascii=False), flush=True)
report["ok"] = not attempts and all(row["status"] == "ready" and row["meaning_verified"] for row in report["results"])
(root / "real-offline-asr.json").write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
raise SystemExit(0 if report["ok"] else 1)