#!/usr/bin/env python3 """Genera la misma frase con las cuatro voces britanicas de Kokoro. flatpak run --command=python3 io.github.qwersyk.Newelle//master \ ~/COFRE/CODERS/JARVIS/config/comparar_voces.py Todas salen ya con el tratamiento aplicado, que es como sonaran de verdad. Elegir de oido y fijar la ganadora con set_voice.py. """ import os import subprocess import sys sys.path.insert(0, "/app/share/newelle") sys.path.insert(0, os.path.expanduser( "~/.var/app/io.github.qwersyk.Newelle/config/pip")) from gi.repository import Gio # noqa: E402 from newelle.handlers.tts.kokoro_handler import KokoroTTSHandler # noqa: E402 from newelle.handlers.tts.tts import jarvis_audio_filter # noqa: E402 VOCES = ["bm_george", "bm_daniel", "bm_lewis", "bm_fable"] FRASE = ("Good evening, sir. All systems are running locally. " "The GPU is idle, and you have 846 gigabytes free. " "Shall I run the diagnostics?") SALIDA = os.path.expanduser("~/COFRE/CODERS/JARVIS/muestras/voces") CONFIG = os.path.expanduser("~/.var/app/io.github.qwersyk.Newelle/config") def nivel(path): """mean/max en dB, para confirmar que ninguna sale floja o recortada.""" r = subprocess.run( ["ffmpeg", "-hide_banner", "-i", path, "-af", "volumedetect", "-f", "null", "/dev/null"], capture_output=True, text=True, ) vals = [l.split(":")[-1].strip() for l in r.stderr.splitlines() if "mean_volume:" in l or "max_volume:" in l] return " / ".join(vals) if vals else "?" def main(): os.makedirs(SALIDA, exist_ok=True) settings = Gio.Settings.new("io.github.qwersyk.Newelle") handler = KokoroTTSHandler(settings, os.path.join(CONFIG, "models")) if not handler.is_installed(): print("instalando kokoro...") handler.install() filtro = jarvis_audio_filter() print(f"{'voz':<12} {'fichero':<26} nivel (mean / max)") for voz in VOCES: handler.set_voice(voz) crudo = os.path.join(SALIDA, f"_{voz}_seca.wav") final = os.path.join(SALIDA, f"{voz}.wav") try: handler.save_audio(FRASE, crudo) subprocess.run( ["ffmpeg", "-hide_banner", "-loglevel", "error", "-i", crudo, "-af", filtro, "-y", final], check=True, ) os.remove(crudo) print(f"{voz:<12} {os.path.basename(final):<26} {nivel(final)}") except Exception as e: print(f"{voz:<12} FALLO: {e}") # dejar la voz como estaba, que este script solo compara handler.set_voice(VOCES[0]) print(f"\nvoz restaurada a {VOCES[0]}") print(f"escuchalas en: {SALIDA}") return 0 if __name__ == "__main__": sys.exit(main())