#!/bin/bash
#
# 'makemusic.sh'
#
# A script to rename and encode WAV files, using a playlist file
#
# Arguments: switches (see below)
#
# -----------------------------------------------------------------
# History:
#   2007-12-31, JHa, first working version
#   2008-01-10, JHa, playlist file can now be specified as argument
#   2008-02-03, JHa, allows varying names for input .wav files
#   2008-03-01, JHa, minor improvements
#   2008-08-13, JHa, cleanup of filenames after run
# -----------------------------------------------------------------
# Copyright (c) 2007, 2008 Joerg Hau <joerg.hau(at)dplanet.ch>.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# -----------------------------------------------------------------

# set defaults
#
PLAYLIST="playlist.txt"
MODE=""

# -----------------------------------------------------------------
# subroutine to check for some required executables
# argument: (list of) programs to test for
# will exit with rc=1 if any program was not found
# -----------------------------------------------------------------
function checkfor()
{
for i in $*; do
    PROG=`which $i`
    if [ $? != 0 ]; then
        echo "'$i' command not found, exiting."
        exit 1
    fi
done
}

# check for some mandatory stuff
#
checkfor grep cut sed awk wc echo seq


# ------------------------------------------------------------
# subroutine to print usage mode
# ------------------------------------------------------------
function usage()
{
cat << eof
${0##*/} - a script to control the conversion of WAV audio files into FLAC, OGG, or MP3 format.

Copyright (c) 2007...2008 Joerg Hau <joerg.hau(at)dplanet.ch>.

This program is free software; you can redistribute it and/or
modify it under the terms of version 2 of the GNU General Public
License as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

Usage: ${0##*/} [-f|--flac] [-o|--ogg] [-m|--mp3] [playlist]

Options:
    -f, --flac      use FLAC encoding (requires flac)
    -o, --ogg       use OGG encoding (requires oggenc)
    -m, --mp3       use MP3 encoding (requires lame)
    playlist        name of file with playlist info (default: $PLAYLIST)
    -h | --help     this help ;-)

    The .wav files must have names according to *.XX.wav, where
    "XX" is always a two-digit number indicating the track number.

    Invoking "${0##*/}" with no options will do nothing.

eof
}

# --------------------------------------------------------------
# parse & handle command line flags
# --------------------------------------------------------------
while true; do
    case $1 in
        -f | --flac )       MODE="FLAC"
                            ;;
        -o | --ogg )        MODE="OGG"
                            ;;
        -m | --mp3 )        MODE="MP3"
                            ;;
        -h | -? | --help )  usage
                            exit 2
                            ;;
        *)                  break
                            ;;
    esac
    shift
done

if [ "$MODE" = "OGG" ] ; then
    echo "OGG conversion requested."
    checkfor oggenc
elif [ "$MODE" = "MP3" ] ; then
    echo "MP3 conversion requested."
    checkfor lame
elif [ "$MODE" = "FLAC" ] ; then
    echo "FLAC conversion requested."
    checkfor flac
else
    usage
    echo "Oups: No (or unknown) conversion requested."
    exit 1
fi

# --------------------------------------------------------------
# if an argument is given, take it as playlist filename
# (any following args are ignored)
# --------------------------------------------------------------
if [ $1 ] ; then
    PLAYLIST="$1"
    echo "Going to read playlist metadata from '$PLAYLIST'."
fi

# --------------------------------------------------------------
# check for existence of playlist file
# --------------------------------------------------------------
if [ ! -r $PLAYLIST ] ; then
    echo "Playlist file '$PLAYLIST' not found! Exiting."
    exit 2
fi

# --------------------------------------------------------------
# parse playlist file and extract info
# The format of this file is as follows (without the '#' character!):
#
# Artist	Al Stewart
# Album	Year of the Cat
# Year	1976
# Genre	Rock
# 01	Lord Grenville
# 02	On the Border
# 03	Midas Shadow
# 04	Sand in Your Shoes
# 05	If it doesn't come naturally, leave it
# 06	Flying Sorcery
# 07	Broadway Hotel
# 08	One Stage Before
# 09	Year of the Cat
#
# (todo: error checking ...)
# I'm invoking sed instead of cut since the file may be composed
# using whitespace instead of tab
# --------------------------------------------------------------
ARTIST=`grep "^Artist" $PLAYLIST | sed 's/^Artist[ \t]*//'`
ALBUM=`grep "^Album" $PLAYLIST | sed 's/^Album[ \t]*//'`
YEAR=`grep "^Year" $PLAYLIST | sed 's/^Year[ \t]*//'`
GENRE=`grep "^Genre" $PLAYLIST | sed 's/^Genre[ \t]*//'`

echo $ARTIST $ALBUM $YEAR $GENRE

# --------------------------------------------------------------
# obtain total number of titles
# --------------------------------------------------------------
NUMTITLES=`grep "^[0-9]" $PLAYLIST | wc -l`

# --------------------------------------------------------------
# parse and save titles into a list
# --------------------------------------------------------------
for i in `seq 1 $NUMTITLES`; do
    NUM=`printf "%02d\n" $i`
    TITLE[$i]=`grep "^$NUM" $PLAYLIST | sed 's/^[0-9][0-9][ \t]*//'`
    # echo ${TITLE[$i]}
done

# --------------------------------------------------------------
# now run the actual conversion
# --------------------------------------------------------------
for i in `seq 1 $NUMTITLES`; do
    NUM=`printf "%02d\n" $i`    # always use 2-digit numbers
    WAV="*.${NUM}.wav"
    # echo "Converting $WAV ..."
    if [ "$MODE" = "OGG" ] ; then
        oggenc -q 6 -o "${NUM}-${TITLE[$i]}.ogg" --artist "$ARTIST" --album "$ALBUM" \
               --title "${TITLE[$i]}" --date "$YEAR" --tracknum $i --genre "$GENRE" $WAV
    elif [ "$MODE" = "MP3" ] ; then
        lame -q 2 -b 160 -m s --add-id3v2 --tt "${TITLE[$i]}" --ta "$ARTIST" --tl "$ALBUM" \
             --ty "$YEAR" --tg "$GENRE" --tn $i $WAV "${NUM}-${TITLE[$i]}.mp3"
    elif [ "$MODE" = "FLAC" ] ; then
        flac --best -o "${NUM}-${TITLE[$i]}.flac" --tag=Artist="$ARTIST" --tag=Album="$ALBUM" \
             --tag=Date="$YEAR" --tag=Title="${TITLE[$i]}" --tag=Tracknumber=$i --tag=Genre="$GENRE" $WAV
    fi
done

# --------------------------------------------------------------
# "clean" the resulting filenames
# --------------------------------------------------------------

for i in *.ogg *.mp3 *.flac; do
  mv "$i" "`echo $i | sed 's/ /_/g'`"
done

exit 0

