File size: 2,210 Bytes
efe917e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"""Ejecuta TTS y STT locales sobre un audio efímero, sin robot ni red.

    python -m scripts.validar_audio_local

Sintetiza una frase con Piper y se la da a transcribir a faster-whisper. Es la
forma de comprobar la voz **sin micrófono**: si lo que vuelve se parece a lo que
salió, las dos mitades del audio funcionan. El audio no toca el disco.
"""

from __future__ import annotations

import json
import time

import numpy as np

from lexia.core.paths import runtime_root
from lexia.legal.local_asr import LocalWhisperTranscriber
from lexia.legal.voice import cargar_voz

PHRASE = "La documentación técnica es obligatoria para los sistemas de inteligencia artificial de alto riesgo."


def main() -> None:
    target = runtime_root() / "reports" / "validacion-audio-local.json"
    target.parent.mkdir(parents=True, exist_ok=True)
    started = time.perf_counter()
    try:
        voice = cargar_voz(descargar=False)
        tts_started = time.perf_counter()
        chunks = list(voice.sintetizar(PHRASE))
        tts_seconds = time.perf_counter() - tts_started
        audio = np.concatenate(chunks) if chunks else np.empty(0, dtype=np.int16)
        if not audio.size:
            raise RuntimeError("Piper no produjo audio")
        stt_started = time.perf_counter()
        transcript = LocalWhisperTranscriber().transcribe(audio)
        payload: dict[str, object] = {
            "outcome": "ok",
            "tts_input": PHRASE,
            "tts_seconds": round(tts_seconds, 3),
            "audio_samples": int(audio.size),
            "audio_seconds": round(audio.size / 16_000, 3),
            "stt_output": transcript,
            "stt_seconds": round(time.perf_counter() - stt_started, 3),
            "total_seconds": round(time.perf_counter() - started, 3),
        }
    except Exception as exc:
        payload = {
            "outcome": "failed",
            "error_type": type(exc).__name__,
            "error": str(exc),
            "total_seconds": round(time.perf_counter() - started, 3),
        }
        raise
    finally:
        target.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
    print(target)


if __name__ == "__main__":
    main()