#!/bin/sh
# mp3ClipGen
#
# Note: You may wish to change some of the settings below.
#
# A script to automatically generate audio clips containing the names of all
# folders in a directory tree for use with the "Talkbox" feature available to
# users of the Rockbox open source firmware for Archos MP3 players and
# recorders. Talkbox permits the Archos device to speak the names of the
# folders as one navigates the directory structure on the device, thus
# permitting "eyes-free" use for those for whom the usual visual navigation is
# difficult or simply inadvisable.
#
# Audio clips are captured and stored in wave format, then converted into MP3
# format by a third party application (lame). If you execute the scripti,
# passing it the top level of your music file hierarchy as an argument while
# your Archos device is connected to your PC, then the resulting audio clips
# will be generated and stored in the correct location for use with the Talkbox
# feature. Alternatively, if you mirror your music folder structure from your
# PC to your Archos device, you can just run the script on the PC and then
# update the files on your Archos with your usual synchronization routine.
#
# A log of all the commands executed by the script is written to the file
# <filename>.log, which can later be executed as a shell script to "replay"
# all the commands
#
# NOTE: If you don't already have them installed, you may obtain the Festival
# text to speech system and several voices at:
#
# http://www.cstr.ed.ac.uk/projects/festival.html
# http://festvox.org/festival/
#
# The most pleasant freely available Festival voice I know of is the slt_arctic
# voice from HST at http://hts.ics.nitech.ac.jp/

# whether to overwrite existing mp3 files or only create missing ones (Y/N)
OVERWRITE_MP3=N
# whether, when overwriting mp3 files, also to regenerate all the wav files
OVERWRITE_WAV=N
# whether to remove the intermediary wav files after creating the mp3 files
REMOVE_WAV=Y

# the directory where the Festival binaries are installed
FESTIVAL_DIR=/home/daniel/speech/festival/bin
# whether to start the Festival server locally (Y/N)
FESTIVAL_START=Y
# the Festival server configuration file
FESTIVAL_CONFIG=$FESTIVAL_DIR/defaults.scm
# 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

# lame encoding options: VBR, independent frames, silent mode
# These may need to be tweaked for smaller size and/or better sound quality.
LAME_OPTS="--vbr-new -t --nores -S"
# where to log the lame output
LAME_LOG=/dev/null

# the file into which all the commands are logged
LOGFILE=`basename $0 sh`log
echo "#!/bin/sh" >> $LOGFILE

if [ X$FESTIVAL_START = XY ]
then
  FESTIVAL_HOST=localhost
  if [ -z "$FESTIVAL_CONFIG" ]
  then
    echo "$FESTIVAL_DIR/festival_server -p $FESTIVAL_PORT $FESTIVAL_DIR/festival &" >> $LOGFILE
    $FESTIVAL_DIR/festival_server -p $FESTIVAL_PORT $FESTIVAL_DIR/festival &
  else
    echo "$FESTIVAL_DIR/festival_server -p $FESTIVAL_PORT -c $FESTIVAL_CONFIG $FESTIVAL_DIR/festival &">> $LOGFILE
    $FESTIVAL_DIR/festival_server -p $FESTIVAL_PORT -c $FESTIVAL_CONFIG $FESTIVAL_DIR/festival &
  fi
  echo sleep 5 >> $LOGFILE
  sleep 5
fi

function dirwalk() {
  for i in "$1"/*
  do
    if [ -d "$i" ]
    then
      TO_SPEAK=`basename "$i"`
      WAV_FILE="$i"/.dirname.wav
      MP3_FILE="$i"/.dirname.mp3
      if [ X$OVERWRITE_MP3 = XY -o ! -f "$MP3_FILE" ]
      then
        if [ X$OVERWRITE_WAV = XY -o ! -f "$WAV_FILE" ]
        then
          echo "echo -E $TO_SPEAK | $FESTIVAL_DIR/festival_client --server $FESTIVAL_HOST --port $FESTIVAL_PORT --otype riff --output \"$WAV_FILE\" --ttw >>$FESTIVAL_LOG 2>&1" >> $LOGFILE
          echo -E $TO_SPEAK | $FESTIVAL_DIR/festival_client \
            --server $FESTIVAL_HOST --port $FESTIVAL_PORT \
            --otype riff --output "$WAV_FILE" --ttw >>$FESTIVAL_LOG 2>&1
        fi
        if [ -f "$WAV_FILE" ]
        then
          echo "lame $LAME_OPTS \"$WAV_FILE\" \"$MP3_FILE\" >>$LAME_LOG 2>&1" >> $LOGFILE
          lame $LAME_OPTS "$WAV_FILE" "$MP3_FILE" >>$LAME_LOG 2>&1
        else
          echo "# warning: missing \"$WAV_FILE\"" >> $LOGFILE
        fi
      fi
      if [ X$REMOVE_WAV = XY -a -f "$WAV_FILE" ]
      then
        echo rm \"$WAV_FILE\" >> $LOGFILE
        rm "$WAV_FILE"
      fi
      dirwalk "$i"
    fi
  done
}

if [ $# -gt 0 ]
then
    dirwalk "$*"
else
  dirwalk .
fi

if [ X$FESTIVAL_START = XY ]
then
  echo $FESTIVAL_DIR/festival_server_control -p $FESTIVAL_PORT exit >> $LOGFILE
  $FESTIVAL_DIR/festival_server_control -p $FESTIVAL_PORT exit
  echo rm festival_wrapper_pid festival_sleep_pid festival_server.scm festival_server.log >> $LOGFILE
  rm festival_wrapper_pid festival_sleep_pid festival_server.scm festival_server.log
fi

