JARVIS: asistente de voz local para Linux
Nucleo propio: oye con whisper.cpp, piensa con un modelo de Ollama, habla con Piper, y hace RAG sobre los apuntes del usuario. 100% local, sin cuentas ni claves. Escrito bajo una restriccion dura, 4 GB de VRAM: el cerebro y whisper comparten tarjeta y solo caben porque estan dimensionados para ello. El RAG usa embeddings estaticos con busqueda hibrida; la voz clonada se sirve de una cache de frases. Incluye instalador (install.sh), requisitos, y documentacion del stack, del manejo de root y de las acciones. Los apuntes indexados y el diario NO se incluyen: son privados y el .gitignore los bloquea.
This commit is contained in:
commit
8e4bc8ad94
125 changed files with 25033 additions and 0 deletions
74
config/set_voz_piper.py
Normal file
74
config/set_voz_piper.py
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Pone la voz de Piper: castellano de España, grave.
|
||||
|
||||
flatpak run --command=python3 io.github.qwersyk.Newelle//master \
|
||||
~/COFRE/CODERS/JARVIS/config/set_voz_piper.py
|
||||
|
||||
Por que no Kokoro: no tiene ni una voz de España. Sus dos masculinas en
|
||||
español, em_alex y em_santa, suenan latinoamericanas. Piper si las tiene, es
|
||||
libre (MIT, voces con licencias abiertas) y corre local.
|
||||
|
||||
Medido con la misma frase:
|
||||
|
||||
em_alex (Kokoro, latino) 129 Hz
|
||||
es_ES-carlfm-x_low 118 Hz calidad baja, 16 kHz
|
||||
es_ES-sharvard-medium 127 Hz
|
||||
es_ES-davefx-medium 128 Hz
|
||||
es_ES-sharvard-medium + tono 106 Hz <- elegida
|
||||
|
||||
106 Hz cae de lleno en el rango de voz masculina grave (85-110). Se llega ahi
|
||||
con rubberband en el envoltorio, no con la cadena de la app: alli el descenso
|
||||
usa asetrate, que depende de la frecuencia de muestreo y esta calculado para
|
||||
los 24 kHz de Kokoro, no para los 22050 de Piper.
|
||||
|
||||
Se apaga por tanto la bajada de tono de la app, para no aplicarla dos veces.
|
||||
El resto del tratamiento (paso alto, ecualizador, compresor, eco) se queda:
|
||||
es independiente de la frecuencia y es lo que da el aire de "voz en la sala".
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
from gi.repository import Gio
|
||||
|
||||
SCHEMA = "io.github.qwersyk.Newelle"
|
||||
ENVOLTORIO = os.path.expanduser(
|
||||
"~/COFRE/CODERS/JARVIS/config/jarvis-piper.sh")
|
||||
|
||||
|
||||
def main():
|
||||
if not os.path.exists(ENVOLTORIO):
|
||||
print(f"FALLO: no esta {ENVOLTORIO}")
|
||||
return 1
|
||||
|
||||
settings = Gio.Settings.new(SCHEMA)
|
||||
|
||||
try:
|
||||
voces = json.loads(settings.get_string("tts-voice") or "{}")
|
||||
except json.JSONDecodeError:
|
||||
voces = {}
|
||||
|
||||
# {0} es el fichero y {1} el texto; el handler los entrecomilla, asi que
|
||||
# aqui van sin comillas alrededor
|
||||
voces["custom_command"] = {"command": f"{ENVOLTORIO} {{0}} {{1}}"}
|
||||
settings.set_string("tts-voice", json.dumps(voces))
|
||||
settings.set_string("tts", "custom_command")
|
||||
Gio.Settings.sync()
|
||||
|
||||
motor = settings.get_string("tts")
|
||||
orden = json.loads(settings.get_string("tts-voice")).get(
|
||||
"custom_command", {}).get("command", "")
|
||||
|
||||
print(f"motor de voz: {motor}")
|
||||
print(f"orden: {orden}")
|
||||
|
||||
ok = motor == "custom_command" and ENVOLTORIO in orden
|
||||
print("verificado" if ok else "FALLO: no quedo como se pidio")
|
||||
if ok:
|
||||
print("\nrecuerda apagar la bajada de tono de la app, que ya la hace el envoltorio:")
|
||||
print(" flatpak override --user --env=JARVIS_TTS_GRAVEDAD=1.0 io.github.qwersyk.Newelle")
|
||||
return 0 if ok else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Loading…
Add table
Add a link
Reference in a new issue