Files
gaming-image-files/usr/bin/espeak

228 lines
7.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Initialize variables for spd-say options
rate=""
pitch=""
pitch_range=""
punctuation_mode=""
wait_flag=""
ssml_mode=""
application_name="espeak-ng-wrapper"
# Function to check if a string is numeric
is_numeric() {
[[ "$1" =~ ^-?[0-9]+$ ]]
}
# Process arguments
while [[ $# -gt 0 ]]; do
case "$1" in
# Handle speed parameter (can be -s 100 or -s100)
-s*)
if [[ "$1" == "-s" && -n "$2" && $(is_numeric "$2") ]]; then
# Format: -s 100
espeak_speed="$2"
shift 2
elif [[ "$1" =~ ^-s([0-9]+)$ ]]; then
# Format: -s100
espeak_speed="${BASH_REMATCH[1]}"
shift
else
# Invalid format, skip
shift
continue
fi
# Convert espeak-ng speed to spd-say rate
spd_rate=$(( (($espeak_speed - 175) * 200) / 420 ))
# Clamp to spd-say's allowed range
if (( spd_rate > 100 )); then
spd_rate=100
elif (( spd_rate < -100 )); then
spd_rate=-100
fi
rate="-r $spd_rate"
;;
# Handle pitch parameter (can be -p 50 or -p50)
-p*)
if [[ "$1" == "-p" && -n "$2" && $(is_numeric "$2") ]]; then
# Format: -p 50
espeak_pitch="$2"
shift 2
elif [[ "$1" =~ ^-p([0-9]+)$ ]]; then
# Format: -p50
espeak_pitch="${BASH_REMATCH[1]}"
shift
else
# Invalid format, skip
shift
continue
fi
# Convert espeak-ng pitch to spd-say pitch
spd_pitch=$(( (($espeak_pitch - 50) * 200) / 99 ))
# Clamp to spd-say's allowed range
if (( spd_pitch > 100 )); then
spd_pitch=100
elif (( spd_pitch < -100 )); then
spd_pitch=-100
fi
pitch="-p $spd_pitch"
;;
# Handle pitch range parameter (can be -P 50 or -P50)
-P*)
if [[ "$1" == "-P" && -n "$2" && $(is_numeric "$2") ]]; then
# Format: -P 50
espeak_pitch_range="$2"
shift 2
elif [[ "$1" =~ ^-P([0-9]+)$ ]]; then
# Format: -P50
espeak_pitch_range="${BASH_REMATCH[1]}"
shift
else
# Invalid format, skip
shift
continue
fi
# Convert espeak-ng pitch range to spd-say pitch range
spd_pitch_range=$(( (($espeak_pitch_range - 50) * 200) / 99 ))
# Clamp to spd-say's allowed range
if (( spd_pitch_range > 100 )); then
spd_pitch_range=100
elif (( spd_pitch_range < -100 )); then
spd_pitch_range=-100
fi
pitch_range="-R $spd_pitch_range"
;;
# Handle punctuation mode parameter (can be -m none or -mnone)
-m*)
if [[ "$1" == "-m" && -n "$2" ]]; then
# Format: -m none
punct_mode="$2"
shift 2
elif [[ "$1" =~ ^-m(.+)$ ]]; then
# Format: -mnone
punct_mode="${BASH_REMATCH[1]}"
shift
else
# Invalid format, skip
shift
continue
fi
# Process the mode
if [[ "$punct_mode" == "ssml" ]]; then
# SSML mode for spd-say
ssml_mode="-x"
else
# Map to punctuation mode if specified
case "$punct_mode" in
none|some|most|all)
punctuation_mode="-m $punct_mode"
;;
esac
fi
;;
# File input parameter (can be -f file.txt or -ffile.txt)
-f*)
if [[ "$1" == "-f" && -n "$2" ]]; then
# Format: -f file.txt
input_file="$2"
shift 2
elif [[ "$1" =~ ^-f(.+)$ ]]; then
# Format: -ffile.txt
input_file="${BASH_REMATCH[1]}"
shift
else
# Invalid format, skip
shift
continue
fi
# Check if file exists
if [[ -f "$input_file" ]]; then
input_from_file="$input_file"
fi
;;
# Wait until speaking is done
-z)
wait_flag="-w"
shift
;;
# Input from stdin
--stdin)
input_from_stdin=1
shift
;;
# Silently discard voice, volume, and other unsupported options with possibly attached values
-v*|-a*|-l*|-d*|-g*|-k*|-b*|-w*|-q*|-x*|-X*|-D*|--compile*|--ipa|--path|--pho|--phonout|--punct*|--sep*|--split*|--stdout|--tie*|--version|--voices*|--load*)
# Skip the option (and its separated value if it exists)
if [[ "$1" =~ ^-[a-zA-Z]$ && -n "$2" && ! "$2" =~ ^- ]]; then
# Format with separate value: -v en-us
shift 2
else
# Format with attached value or no value: -ven-us or just -q
shift
fi
;;
# Any other unrecognized options - silently discard
-*)
# Skip the option (and its separated value if it exists)
if [[ "$1" =~ ^-[a-zA-Z]$ && -n "$2" && ! "$2" =~ ^- ]]; then
# Format with separate value
shift 2
else
# Format with attached value or no value
shift
fi
;;
# Text to speak - anything not starting with -
*)
# Collect all non-option arguments as text to speak
if [[ -z "$text" ]]; then
text="$1"
else
text="$text $1"
fi
shift
;;
esac
done
# Build the spd-say command with only the supported converted options
spd_cmd="spd-say $rate $pitch $pitch_range $punctuation_mode $ssml_mode $wait_flag -N $application_name"
# Handle the input based on what was provided
if [[ -n "$input_from_file" ]]; then
# Input from specified file
spd_cmd="$spd_cmd -e --"
cat "$input_from_file" | $spd_cmd
elif [[ -n "$input_from_stdin" ]]; then
# Input from stdin all at once
spd_cmd="$spd_cmd -e --"
cat | $spd_cmd
elif [[ -n "$text" ]]; then
# Text provided as arguments
$spd_cmd -- "$text"
else
# No text provided, read from stdin line by line
spd_cmd="$spd_cmd -e --"
cat | $spd_cmd
fi
# Exit with success
exit 0