Skip to content

Instantly share code, notes, and snippets.

@vijinho
Last active January 7, 2025 11:24
Show Gist options
  • Save vijinho/b23cdf6d94a49468cf5351f08396b762 to your computer and use it in GitHub Desktop.
Save vijinho/b23cdf6d94a49468cf5351f08396b762 to your computer and use it in GitHub Desktop.
Uses mimic https://github.com/MycroftAI/mimic1?tab=readme-ov-file to speak text or output wav or mp3 file
#!/bin/bash
# Uses mimic https://github.com/MycroftAI/mimic1?tab=readme-ov-file to speak
# optionally uses aplay https://linux.die.net/man/1/aplay to speak then delete the output file
# Set default values
VOICE='slt_hts'
WAVFILE="$TEMP/$(date "+%Y%m%d.%H%M%S")-tts.wav"
TEXT=''
TEXTFILE=''
PITCH=110
SPEED=1.25
PLAY=false
CONVERT_TO=""
BITRATE=""
# Function to print usage message and exit
print_usage_and_exit() {
echo "Usage: $0 -v <voice> -f <textfile> -w <$WAVEFILE> -t <text> -p <pitch> -s <speed> [-l] [-m | -a]"
echo "If -l is specified, the output file is piped into aplay, then DELETED afterwards"
echo "Example to speak the date/time to the current user: $0 -t "\"Attention \$USER, \$\(date +\"the date is %A, %B %d, %Y and the time is %I:%M %p.\"\)"\" -l 1"
echo "Example to read output from fortune and output mp3 file: $0 -t \"\`fortune -a\`\" -w $HOME/Desktop/fortune.wav -m 64"
echo "Example to read a file and speak into a wav file: $0 -f text.txt -w $HOME/Desktop/text.wav"
echo "Optional conversion options:"
echo " -m <bitrate> Convert the WAV file to MP3"
exit 1
}
# Parse command-line options using getopts for better syntax and robustness
while getopts ':v:f:w:t:p:s:l:m:a' opt; do
case ${opt} in
v )
VOICE=$OPTARG
;;
f )
TEXTFILE=$OPTARG
;;
w )
WAVFILE=$OPTARG
;;
t )
TEXT=$OPTARG
;;
p )
PITCH=$OPTARG
;;
s )
SPEED=$OPTARG
;;
l )
PLAY=true
;;
m )
CONVERT_TO="mp3"
BITRATE=$OPTARG
;;
\? )
print_usage_and_exit
;;
: )
echo "Invalid option: -$OPTARG requires an argument" 1>&2
print_usage_and_exit
;;
esac
done
shift $((OPTIND -1))
# Check if required arguments are provided
if [[ -z "$TEXT" && -z "$TEXTFILE" ]]; then
echo "Error: Either -t or -f is a required argument." >&2
print_usage_and_exit
fi
# If TEXT is not provided but TEXTFILE is, read the text from the file
if [[ -z "$TEXT" ]]; then
if [[ -f "$TEXTFILE" ]]; then
TEXT=$(<"$TEXTFILE")
else
echo "Error: The specified file $TEXTFILE does not exist." >&2
print_usage_and_exit
fi
fi
# Validate numeric input for PITCH and SPEED
if ! [[ "$PITCH" =~ ^[0-9]+$ ]] || ! [[ "$SPEED" =~ ^[0-9]+([.][0-9]+)?$ ]]; then
echo "Error: PITCH and SPEED must be valid numbers." >&2
print_usage_and_exit
fi
# Run the mimic command with sanitized input
mimic --setf int_f0_target_mean=$PITCH --setf duration_stretch=$SPEED -voice $VOICE -t "$TEXT" -o $WAVFILE
echo "Text to speech conversion completed. Output file: $WAVFILE"
# If play option is specified, play the audio and delete the file
if [ "$PLAY" = true ]; then
if command -v aplay &> /dev/null; then
aplay "$WAVFILE"
rm "$WAVFILE"
echo "Audio played and output file deleted."
else
echo "Error: 'aplay' is not installed. Please install it to play the audio." >&2
fi
fi
# Convert the WAV file if conversion option is specified
if [[ -n "$CONVERT_TO" ]]; then
if ! command -v ffmpeg &> /dev/null; then
echo "Error: 'ffmpeg' is not installed. Please install it to convert the audio." >&2
exit 1
fi
OUTPUT_FILE="${WAVFILE%.*}.${CONVERT_TO}"
ffmpeg -i $WAVFILE -b:a $BITRATE $OUTPUT_FILE
rm $WAVFILE
echo "File converted and original WAV file deleted. Output file: $OUTPUT_FILE"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment