Skip to content

Instantly share code, notes, and snippets.

@jaggzh
Last active October 10, 2023 21:11
Show Gist options
  • Save jaggzh/040778fe4260f19ad35dce0fa083e523 to your computer and use it in GitHub Desktop.
Save jaggzh/040778fe4260f19ad35dce0fa083e523 to your computer and use it in GitHub Desktop.
#!/bin/bash
# by jaggz.h {who is over at} gmail.com
# CC-BY. Reference my email or Jaggz Tech @ Youtube
# gist-paste -u https://gist.github.com/jaggzh/040778fe4260f19ad35dce0fa083e523
defmodel=e # Default model from models=() array below
blank_line_delay=.3 # Not sure if this works for other systems' sleep commands
# piper=~/opt/voice/tts/piper/piper
piper=~/opt/lib/voice/tts/piper/piper
if [[ ! -x $piper ]]; then
echo "No piper bin at: $piper" >&2
exit
fi
# voicedir=~/models/tts/onyx
# model=~/models/tts/onyx/en_US-ryan-high.onnx
voicedir=~/data/models/tts/onyx
echo "Voices:" >&2
cd "$voicedir" && find . -type d | grep 'onnx$' | sed -e 's/^/ /' >&2
declare -A models
models=( # May be a subdir/path of voicedir
[u]="en_US-ryan-high.onnx"
[e]="en_US-ryan-high.onnx"
)
model=${models[$defmodel]}
echo
echo "Select model during typng by prefixing line with 'm:...'" >&2
for l in "${!models[@]}"; do
echo " $l: ${models[$l]}"; >&2
done
echo
echo "Text me, one per line:" >&2
umask 0177
wavtmp="/tmp/tts-$USER.wav"
# Set up history file. Crop it to keep its size down
HISTFILE="/tmp/vpi_history-$USER"
touch "$HISTFILE"
echo "$txt" >> "$HISTFILE" # Append to history file
history -r "$HISTFILE"
tail -n 50 "$HISTFILE" > "${HISTFILE}.tmp" && mv "${HISTFILE}.tmp" "$HISTFILE"
while read -e txt; do
# txt="${txt// /+}"
printf 'You entered: {{%s}}\n' "$txt" >&2
echo "$txt" >> "$HISTFILE" # Append to history file
history -r "$HISTFILE"
# See if user entered a prefix to select a model:
pfx=''
if [[ $txt =~ ^.: ]]; then
pfx=$(printf "%s" "$txt" | sed -e 's/:.*$//')
if [[ -z "${models[$pfx]}" ]]; then
echo " ERROR. Model '$pfx' seems to have been requested, but models[] array doesn't"
echo " seem to exist. We're not changing anything and will speak it as typed."
else
model="$voicedir/${models[$pfx]}"
echo " MODEL SWITCHED TO: $model"
# Strip prefix off text
txt=$(printf "%s" "$txt" | sed -e 's/^[^:]\+://;')
fi
fi
if [[ -z $txt ]]; then
if [[ -n $pfx ]]; then
pass # We don't say anything if they just changed the model
# with, e.g. "e:", but didn't type anything else
else
echo "Blank text entered. I guess we'll delay briefly in case you intended a pause."
sleep "$blank_line_delay"
fi
else
cat <<-EOT >&2
Running piper:
printf '%s\n' "$txt" | "$piper" \\
--model "$model" \\
--output_file "$wavtmp"
EOT
printf '%s\n' "$txt" | "$piper" \
--model "$model" \
--output_file "$wavtmp"
ls -lgG -- "$wavtmp"
play "$wavtmp"
fi
txt='' # Done. Wipe'em
pfx=''
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment