| #!/bin/sh |
| # __________ __ ___. |
| # Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| # \/ \/ \/ \/ \/ |
| # $Id$ |
| # |
| # Copyright (c) 2006 Jonas Häggqvist |
| # |
| # All files in this archive are subject to the GNU General Public License. |
| # See the file COPYING in the source tree root for full license agreement. |
| # |
| # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| # KIND, either express or implied. |
| # |
| # A selection of functions common to creating voicefiles for Rockbox. |
| # |
| # You may wish to change some of the settings below. |
| |
| ##################### |
| # Program locations # |
| ##################### |
| |
| # Leave any you're not using untouched, enter full path if the program is |
| # not found |
| |
| # the festival main executable |
| FESTIVAL_BIN=festival |
| # the festival_client binary |
| FESTIVAL_CLIENT=festival_client |
| |
| # The flite executable |
| FLITE_BIN=flite |
| |
| # The eSpeak executable |
| ESPEAK_BIN=speak |
| |
| # The lame executable |
| LAME_BIN=lame |
| |
| # The speexenc executable |
| SPEEX_BIN=speexenc |
| |
| # The oggenc executable |
| VORBIS_BIN=oggenc |
| |
| # The wavtrim executable |
| WAVTRIM=`dirname $0`/wavtrim |
| |
| ##################### |
| # Festival settings # |
| ##################### |
| |
| # If you're not using festival, leave untouched |
| |
| # whether to start the Festival server locally (Y/N) |
| FESTIVAL_START=Y |
| # the host of the Festival server |
| # this is set to localhost automatically when FESTIVAL_START is Y |
| FESTIVAL_HOST=localhost |
| # the port of the Festival server |
| FESTIVAL_PORT=1314 |
| # where to log the Festival client output |
| FESTIVAL_LOG=/dev/null |
| # other options to the festival client |
| FESTIVAL_OPTS="" |
| |
| ################## |
| # Flite settings # |
| ################## |
| |
| # If you're not using flite, leave untouched |
| FLITE_OPTS="" |
| |
| ################### |
| # eSpeak settings # |
| ################### |
| |
| # If you're not using eSpeak, leave untouched |
| ESPEAK_OPTS="" |
| |
| #################### |
| # Wavtrim settings # |
| #################### |
| |
| # The maximum sample value that will be treated as silence by the wavtrim tool. |
| # The value is expressed as an absolute 16 bit integer sample value (0 dB equals |
| # 32767). |
| # |
| # 500 is a good guess - at least for Festival |
| |
| NOISEFLOOR='500' |
| |
| ##################### |
| # Encoding settings # |
| ##################### |
| # where to log the encoder output |
| ENC_LOG=/dev/null |
| |
| # Suggested: --vbr-new -t --nores -S |
| # VBR, independent frames, silent mode |
| LAME_OPTS="--vbr-new -t --nores -S" |
| |
| # Suggested: |
| # XXX: suggest a default |
| SPEEX_OPTS="" |
| |
| # Suggested: -q0 --downmix |
| # Low quality, mono |
| VORBIS_OPTS="-q0 --downmix" |
| |
| ################### |
| # End of settings # |
| ################### |
| |
| # Check if executables exist and perform any necessary initialisation |
| init_tts() { |
| case $TTS_ENGINE in |
| festival) |
| # Check for festival_client |
| if [ ! `which $FESTIVAL_CLIENT` ]; then |
| echo "Error: $FESTIVAL_CLIENT not found" |
| exit 4 |
| fi |
| |
| # Check for, and start festival server if specified |
| if [ X$FESTIVAL_START = XY ]; then |
| if [ ! `which $FESTIVAL_BIN` ]; then |
| echo "Error: $FESTIVAL_BIN not found" |
| exit 3 |
| fi |
| FESTIVAL_HOST='localhost' |
| $FESTIVAL_BIN --server 2>&1 > /dev/null & |
| FESTIVAL_SERVER_PID=$! |
| sleep 3 |
| if [ `ps | grep -c "^\ *$FESTIVAL_SERVER_PID"` -ne 1 ]; then |
| echo "Error: Festival not started" |
| exit 9 |
| fi |
| fi |
| # Test connection to festival server |
| output=`echo -E "Rockbox" | $FESTIVAL_CLIENT --server \ |
| $FESTIVAL_HOST --otype riff --ttw --output \ |
| /dev/null 2>&1` |
| if [ $? -ne 0 ]; then |
| echo "Error: Couldn't connect to festival server at" \ |
| "$FESTIVAL_HOST ($output)" |
| exit 8 |
| fi |
| ;; |
| flite) |
| # Check for flite |
| if [ ! `which $FLITE_BIN` ]; then |
| echo "Error: $FLITE_BIN not found" |
| exit 5 |
| fi |
| ;; |
| espeak) |
| # Check for flite |
| if [ ! `which $ESPEAK_BIN` ]; then |
| echo "Error: $ESPEAK_BIN not found" |
| exit 5 |
| fi |
| ;; |
| *) |
| echo "Error: no valid TTS engine selected: $TTS_ENGINE" |
| exit 2 |
| ;; |
| esac |
| if [ ! -x $WAVTRIM ]; then |
| echo "Error: $WAVTRIM is not available" |
| exit 11 |
| fi |
| } |
| |
| # Perform any necessary shutdown for TTS engine |
| stop_tts() { |
| case $TTS_ENGINE in |
| festival) |
| if [ X$FESTIVAL_START = XY ]; then |
| # XXX: This is probably possible to do using festival_client |
| kill $FESTIVAL_SERVER_PID > /dev/null 2>&1 |
| fi |
| ;; |
| esac |
| } |
| |
| # Check if executables exist and perform any necessary initialisation |
| init_encoder() { |
| case $ENCODER in |
| lame) |
| # Check for lame binary |
| if [ ! `which $LAME_BIN` ]; then |
| echo "Error: $LAME_BIN not found" |
| exit 6 |
| fi |
| ;; |
| speex) |
| # Check for speexenc binary |
| if [ ! `which $SPEEX_BIN` ]; then |
| echo "Error: $SPEEX_BIN not found" |
| exit 7 |
| fi |
| ;; |
| vorbis) |
| # Check for vorbis encoder binary |
| if [ ! `which $VORBIS_BIN` ]; then |
| echo "Error: $VORBIS_BIN not found" |
| exit 10 |
| fi |
| ;; |
| *) |
| echo "Error: no valid encoder selected: $ENCODER" |
| exit 1 |
| ;; |
| esac |
| |
| } |
| |
| # Encode file $1 with ENCODER and save the result in $2, delete $1 if specified |
| encode() { |
| INPUT=$1 |
| OUTPUT=$2 |
| |
| if [ ! -f "$INPUT" ]; then |
| echo "Warning: missing input file: \"$INPUT\"" |
| else |
| echo "Action: Encode $OUTPUT with $ENCODER" |
| case $ENCODER in |
| lame) |
| $LAME_BIN $LAME_OPTS "$WAV_FILE" "$OUTPUT" >>$ENC_LOG 2>&1 |
| ;; |
| speex) |
| $SPEEX_BIN $SPEEX_OPTS "$WAV_FILE" "$OUTPUT" >>$ENC_LOG 2>&1 |
| ;; |
| vorbis) |
| $VORBIS_BIN $VORBIS_OPTS "$WAV_FILE" -o "$OUTPUT" >>$ENC_LOG 2>&1 |
| esac |
| if [ ! -f "$OUTPUT" ]; then |
| echo "Warning: missing output file \"$OUTPUT\"" |
| fi |
| fi |
| } |
| |
| # Generate file $2 containing $1 spoken by TTS_ENGINE, trim silence |
| voice() { |
| TO_SPEAK=$1 |
| WAV_FILE=$2 |
| if [ ! -f "$WAV_FILE" ] || [ X$OVERWRITE_WAV = XY ]; then |
| if [ "${TO_SPEAK}" = "" ]; then |
| touch "$WAV_FILE" |
| else |
| case $TTS_ENGINE in |
| festival) |
| echo "Action: Generate $WAV_FILE with festival" |
| echo -E "$TO_SPEAK" | $FESTIVAL_CLIENT $FESTIVAL_OPTS \ |
| --server $FESTIVAL_HOST \ |
| --otype riff --ttw --output "$WAV_FILE" 2>"$WAV_FILE" |
| ;; |
| espeak) |
| echo "Action: Generate $WAV_FILE with eSpeak" |
| echo $ESPEAK_BIN $ESPEAK_OPTS -w "$WAV_FILE" |
| echo -E "$TO_SPEAK" | $ESPEAK_BIN $ESPEAK_OPTS -w "$WAV_FILE" |
| ;; |
| flite) |
| echo "Action: Generate $WAV_FILE with flite" |
| echo -E "$TO_SPEAK" | $FLITE_BIN $FLITE_OPTS -o "$WAV_FILE" |
| ;; |
| esac |
| fi |
| fi |
| trim "$WAV_FILE" |
| } |
| |
| # Trim wavefile $1 |
| trim() { |
| WAVEFILE="$1" |
| echo "Action: Trim $WAV_FILE" |
| $WAVTRIM "$WAVEFILE" $NOISEFLOOR |
| } |