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
58
config/jarvis-piper.sh
Executable file
58
config/jarvis-piper.sh
Executable file
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env bash
|
||||
# Voz de JARVIS con Piper: castellano de España, no latinoamericano.
|
||||
#
|
||||
# jarvis-piper.sh <fichero.wav> <texto>
|
||||
#
|
||||
# Kokoro, que es lo que trae Newelle, no tiene ni una voz de España: sus dos
|
||||
# masculinas en español (em_alex, em_santa) suenan latinas. Piper si las tiene,
|
||||
# es libre y corre local. Se invoca desde el handler custom_command, que ya
|
||||
# ejecuta en el host.
|
||||
#
|
||||
# El descenso de tono se hace aqui y no en la cadena de la app porque alli se
|
||||
# usa asetrate, que necesita saber la frecuencia de muestreo: esta calculada
|
||||
# para los 24 kHz de Kokoro y Piper saca 22050, asi que aplicaria una bajada
|
||||
# distinta de la pedida. Aqui se usa rubberband, que trabaja en semitonos y le
|
||||
# da igual la frecuencia. Existe en el ffmpeg del sistema pero no en el del
|
||||
# flatpak, y este script ya corre fuera.
|
||||
#
|
||||
# Ajustes por entorno:
|
||||
# JARVIS_PIPER_VOZ es_ES-sharvard-medium (defecto) | es_ES-davefx-medium
|
||||
# | es_ES-carlfm-x_low
|
||||
# JARVIS_PIPER_TONO 0.90 (defecto). 1.0 no toca el tono; por debajo de
|
||||
# 0.85 empieza a sonar artificial.
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
# La raiz se deduce de donde esta este fichero, no del $HOME de nadie: asi el
|
||||
# arbol se puede mover o clonar en otra maquina y sigue funcionando sin editar
|
||||
# rutas. `cd -P` resuelve enlaces simbolicos, que el lanzador de escritorio
|
||||
# puede invocarlo por uno.
|
||||
RAIZ=$(cd -P "$(dirname "${BASH_SOURCE[0]:-$0}")/.." && pwd)
|
||||
BASE=$RAIZ/voz
|
||||
VOZ=${JARVIS_PIPER_VOZ:-es_ES-sharvard-medium}
|
||||
TONO=${JARVIS_PIPER_TONO:-0.90}
|
||||
|
||||
SALIDA=${1:-}
|
||||
TEXTO=${2:-}
|
||||
|
||||
[ -n "$SALIDA" ] || { echo "falta el fichero de salida" >&2; exit 1; }
|
||||
[ -n "$TEXTO" ] || { echo "sin texto que decir" >&2; exit 1; }
|
||||
|
||||
MODELO=$BASE/modelos/$VOZ.onnx
|
||||
[ -f "$MODELO" ] || { echo "no esta el modelo $MODELO" >&2; exit 1; }
|
||||
|
||||
CRUDO=$(mktemp --suffix=.wav)
|
||||
trap 'rm -f "$CRUDO"' EXIT
|
||||
|
||||
printf '%s' "$TEXTO" | "$BASE/piper/piper" \
|
||||
--model "$MODELO" --output_file "$CRUDO" 2>/dev/null
|
||||
|
||||
[ -s "$CRUDO" ] || { echo "piper no genero audio" >&2; exit 1; }
|
||||
|
||||
if [ "$TONO" = "1.0" ] || ! command -v ffmpeg >/dev/null; then
|
||||
cp "$CRUDO" "$SALIDA"
|
||||
else
|
||||
ffmpeg -hide_banner -loglevel error -i "$CRUDO" \
|
||||
-af "rubberband=pitch=$TONO" -y "$SALIDA" 2>/dev/null \
|
||||
|| cp "$CRUDO" "$SALIDA"
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue