#!/bin/bash
#-------------------------------------------------------
# burncdda is a shell script for burning audio cd's with
# cdrdao and cdrecord
#
# (C) 2001 by Thorsten Muehlfelder
#-------------------------------------------------------

# catch SIGINT and SIGTERM, remove TEMPFILE
trap 'test -e $TEMPFILE && rm -f $TEMPFILE; exit 0' 2 15

# cleanup
rm -f /tmp/burncdda.??????

# some variables
BACKTITLE="burnCDDA 1.2.9"
TEMPFILE=`mktemp /tmp/burncdda.XXXXXX`
ERROR="An error ocurred:"
STARTDIR=`pwd`
PLAYLIST=""
LINE=""
WAVNAME=""
MAINLEV="0"
LEV1="0"
TYP="mp3"
NORMSET="0"
EXT=""
LL="0"
M3U="m3u"

# sets integer variables
declare -i N=0
declare -i LN=1
declare -i MAXN=0
declare -i MAXLN=1
declare -i FILESIZE=0
declare -i FILETIME=0
declare -i CDTIME=0
declare -i MINUTES=0
declare -i SECONDS=0
declare -i CORRUPTED=0

# read config file
if [ -r /etc/burncdda.conf ]; then
	source /etc/burncdda.conf
else
	dialog --backtitle "$BACKTITLE" --title "$ERROR" \
	       --msgbox "Check your installation! You don't have a config file." 6 60
	clear
	exit 1
fi
if [ -r ~/.burncdda ]; then
	source ~/.burncdda
fi

# is /etc/burncdda.conf configured?
if [ $FIRSTRUN = "1" ]; then
	dialog --backtitle "$BACKTITLE" --title "$ERROR" \
	       --msgbox "Please edit the config file: /etc/burncdda.conf" 6 60
	clear
	exit 1
fi

# create IMGDIR
if [ ! -e "$IMGDIR" ]; then
	echo "Creating '$IMGDIR'"
	mkdir -p "$IMGDIR"
	echo "Press Enter"
	read JUNK
fi

#
# begin functions
#

# decode and normalize
function decodenorm()
{
mkdir "$IMGDIR/$WAVNAME"
N=0
LN=1
while [ $LN -le $MAXLN ]; do
	LINE=`head -$LN "$PLAYLIST" | tail -1`
	LINE=`echo "$LINE" | sed s/$'\r'//`
	EXT=`echo "$LINE" | head -c 1`
	if [ "$EXT" = "#" ]; then
		LN=$LN+1
		continue
	fi
	echo "File: $LINE"
	TYP=`echo "$LINE" | tail -c 4`
	TYP=`echo "$TYP" | tr "A-Z" "a-z"`
	N=$N+1
	LN=$LN+1
	if [ $N -le 9 ]; then
		LL="0"
	else
		LL=""
	fi
	if [ "$TYP" = "mp3" ]; then
		echo "mpg123..."
		mpg123 -r 44100 --stereo -q --wav "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav" "$LINE" || decerror
		echo "--> $WAVNAME.$LL$N.wav"
		if [ $NORMSET = 1 ]; then
			echo "normalize..."
			normalize -q --amplitude=$NORMAMP "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav" || decerror
			echo "--> $WAVNAME.$LL$N.wav was normalized to $NORMAMP"
		fi
		timecount "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav"
	elif [ "$TYP" = "ogg" ]; then
		echo "oggdec..."
		oggdec -Q -o "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav" "$LINE" || decerror
		echo "--> $WAVNAME.$LL$N.wav"
		if [ $NORMSET = 1 ]; then
			echo "normalize..."
			normalize -q --amplitude=$NORMAMP "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav" || decerror
			echo "--> $WAVNAME.$LL$N.wav was normalized to $NORMAMP"
		fi
		timecount "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav"
	elif [ "$TYP" = "mpc" ]; then
		echo "mppdec..."
		mppdec --silent "$LINE" "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav" || decerror
		echo "--> $WAVNAME.$LL$N.wav"
		if [ $NORMSET = 1 ]; then
			echo "normalize..."
			normalize -q --amplitude=$NORMAMP "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav" || decerror
			echo "--> $WAVNAME.$LL$N.wav was normalized to $NORMAMP"
		fi
		timecount "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav"
	elif [ "$TYP" = "wav" ]; then
		echo "sox..."
		sox "$LINE" -r 44100 -c 2 "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav" || decerror
		echo "--> $WAVNAME.$LL$N.wav"
		if [ $NORMSET = 1 ]; then
			echo "normalize..."
			normalize -q --amplitude=$NORMAMP "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav" || decerror
			echo "--> $WAVNAME.$LL$N.wav was normalized to $NORMAMP"
		fi
		timecount "$IMGDIR/$WAVNAME/$WAVNAME.$LL$N.wav"
	else
		echo "Track $LL$N: $TYP is not a supportet format. Skipping!"
		decerror
	fi
	echo ""
	echo ""
done
MINUTES=($CDTIME/60)
SECONDS=`expr $CDTIME % 60`
if [ $SECONDS -le 9 ]; then
	echo "Disc Length: $MINUTES:0$SECONDS"
else
	echo "Disc Length: $MINUTES:$SECONDS"
fi
}

# counts files in playlist (MAXN), counts lines in playlist (MAXLN)
function filecount()
{
clear
MAXLN=`awk 'END {print FNR}' "$PLAYLIST"`
LN=1
MAXN=0
echo -n "Counting Files in playlist"
while [ $LN -le $MAXLN ]; do
	LINE=`head -$LN "$PLAYLIST" | tail -1`
	EXT=`echo "$LINE" | head -c 1`
	if [ "$EXT" != "#" ]; then
		MAXN=$MAXN+1
	fi
	LN=$LN+1
	echo -n "."
done
echo ""
}

# calculates length of single tracks and adds them to CDTIME
function timecount()
{
FILESIZE=`ls -l "$1" | awk '{print $5}'`
FILETIME=($FILESIZE/176400)
MINUTES=($FILETIME/60)
SECONDS=`expr $FILETIME % 60`
if [ $SECONDS -le 9 ]; then
	echo "Track Length: $MINUTES:0$SECONDS"
else
	echo "Track Length: $MINUTES:$SECONDS"
fi
CDTIME=($CDTIME+$FILETIME)
}

# errormessage of decodenorm
function decerror()
{
echo "WARNING: An error occurred!"
echo "Press Enter"
read JUNK
echo ""
continue
}

# errormessage of checkm3u
function checkerror()
{
CORRUPTED=$CORRUPTED+1
echo ""
echo "This File is corrupted and can cause bad sound quality!"
echo "Press Enter"
read JUNK
echo ""
continue
}

# checks m3u playlist
function checkm3u()
{
N=0
LN=1
CORRUPTED=0
while [ $LN -le $MAXLN ]; do
	LINE=`head -$LN "$PLAYLIST" | tail -1`
	LINE=`echo "$LINE" | sed s/$'\r'//`
	EXT=`echo "$LINE" | head -c 1`
	if [ "$EXT" = "#" ]; then
		LN=$LN+1
		continue
	fi
	echo "File: $LINE"
	TYP=`echo "$LINE" | tail -c 4`
	TYP=`echo "$TYP" | tr "A-Z" "a-z"`
	N=$N+1
	LN=$LN+1
	if [ $TYP = "mp3" ]; then
		echo "mp3_check..."
		mp3_check "$LINE" > /dev/null || checkerror
		echo "OK"
	elif [ $TYP = "ogg" ]; then
		echo "ogginfo..."
		ogginfo "$LINE" | grep Corrupted && checkerror
		echo "OK"
	elif [ $TYP = "mpc" ]; then
		echo "MPC file. Skipping!"
	elif [ $TYP = "wav" ]; then
		echo "WAV file. Skipping!"
	else
		echo "$TYP is not a supported format. Skipping!"
	fi
	echo ""
	echo ""
done
echo ""
echo "mp3_check found $CORRUPTED corrupted files."
}

#
# functions end
#

#
# start command line options
#
case $1 in

	-c)
	PLAYLIST="$2"
	M3U=`echo "$PLAYLIST" | tail -c 4`
	M3U=`echo "$M3U" | tr "A-Z" "a-z"`
	if [ "$M3U" != "m3u" ]; then
		dialog --backtitle "$BACKTITLE" --title "$ERROR" \
		    --msgbox "'$PLAYLIST' is not a M3U file" 6 60
		clear
		exit 1
	fi
	if [ ! -r "$PLAYLIST" ]; then
		dialog --backtitle "$BACKTITLE" --title "$ERROR" \
		    --msgbox "'$PLAYLIST' does not exist or is not readable" 6 60
		clear
		exit 1
	fi
	filecount
	echo "There are $MAXN files in '$PLAYLIST'"
	echo "Press Enter"
	read JUNK
	echo ""
	checkm3u
	echo ""
	exit 0
	;;

	-b)
	PLAYLIST="$2"
	M3U=`echo "$PLAYLIST" | tail -c 4`
	M3U=`echo "$M3U" | tr "A-Z" "a-z"`
	if [ "$M3U" != "m3u" ]; then
		dialog --backtitle "$BACKTITLE" --title "$ERROR" \
		    --msgbox "'$PLAYLIST' is not a M3U file" 6 60
		clear
		exit 1
	fi
	if [ ! -r "$PLAYLIST" ]; then
		dialog --backtitle "$BACKTITLE" --title "$ERROR" \
		    --msgbox "'$PLAYLIST' does not exist or is not readable" 6 60
		clear
		exit 1
	fi
	LEV1="0"
	while [ $LEV1 = "0" ]; do
		# enter wav names
		dialog --backtitle "$BACKTITLE" --title "Burn Audio-CD from playlist" \
		       --inputbox "Enter name of WAV files (without .wav):" 8 60 2> $TEMPFILE
		if [ $? = "1" ]; then
			LEV1="1"
			clear
			continue
		fi
		WAVNAME=`cat $TEMPFILE`
		if [ -e "$IMGDIR/$WAVNAME" ]; then
			dialog --backtitle "$BACKTITLE" --title "$ERROR" \
			    --msgbox "'$WAVNAME' already exists. Choose another name!" 6 60
			continue
		fi
		# abfrage: normalisiern ja/nein
		dialog --backtitle "$BACKTITLE" --title "Burn Audio-CD from playlist" \
		       --yesno "Do you want to normalize the WAVs to $NORMAMP?" 6 60
		if [ $? = "0" ]; then
			NORMSET="1"
		else
			NORMSET="0"
		fi
		# count files
		filecount
		# checks playlist for more than 99 tracks
		if [ $MAXN -gt 99 ]; then
			dialog --backtitle "$BACKTITLE" --title "$ERROR" \
			       --msgbox "There are $MAXN files in '$PLAYLIST' but you cannot burn more than 99 tracks." 6 60
			LEV1="1"
			clear
			continue
		else
		echo "There are $MAXN files in '$PLAYLIST'"
		echo "Press Enter"
		read JUNK
		fi
		echo ""
		# decode and normalize
		decodenorm
		echo ""
		echo "Insert CD-R and press Enter"
		read JUNK
		cdrecord $DEVWREC $SPEEDREC $BURNFREE $OTHERREC "$IMGDIR/$WAVNAME/$WAVNAME".*.wav
		echo ""
		echo "Press Enter"
		read JUNK
		LEV1="1"
	done
	exit 0
	;;

	-*)
	echo "Usage: burncdda [option] file"
	echo "   -b  Burn M3U playlist"
	echo "   -c  Check MP3s in M3U playlist"
	echo ""
	echo "Try 'man burncdda' for more information!"
	exit 0
	;;

esac

#
# end command line options
#

#
# main menu begin
#
clear
while [ $MAINLEV = "0" ]; do
	LEV1="0"
	CDTIME=0
	cd "$STARTDIR"
	dialog --backtitle "$BACKTITLE" --title "Main Menu" --menu "Make your choice" 15 60 8 \
		1 "Read CD image" \
		2 "Burn CD image" \
		3 "Copy CD" \
		4 "Burn M3U playlist" \
		5 "Convert M3U playlist to WAVs" \
		6 "Burn WAVs" \
		7 "Check files in M3U playlist" \
		8 "Exit"	2> $TEMPFILE

	# if cancel exit menu
	if [ $? = "1" ]; then
		MAINLEV="1"
	fi
	WAHL=`cat $TEMPFILE`
	rm -f $TEMPFILE
	# menu end

	case $WAHL in

		1)
		while [ $LEV1 = "0" ]; do
			dialog --backtitle "$BACKTITLE" --title "Read Audio-CD" \
				--inputbox "Enter CD-image filename (without .bin):" 8 60 2> $TEMPFILE
			if [ $? = "1" ]; then
				LEV1="1"
				continue
			fi
			CDNAME=`cat $TEMPFILE`
			cd "$IMGDIR"
			if [ -e "$CDNAME.toc" ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
					--msgbox "'$CDNAME.toc' already exists. Choose another name!" 6 60
				continue
			fi
			dialog --backtitle "$BACKTITLE" --title "Read Audio-CD" \
				--msgbox "\nInsert Audio-CD and press OK to read" 7 40
			clear
			nice -n 14 cdrdao read-cd $DEVRDAO $DRVRDAO $PARANOIA --datafile "$CDNAME.bin" "$CDNAME.toc"
			echo ""
			echo "Press Enter"
			read JUNK
			LEV1="1"
		done
		;;

		2)
		while [ $LEV1 = "0" ]; do
			dialog --backtitle "$BACKTITLE" --title "Burn Audio-CD" \
				--inputbox "Enter CD-image filename (without .bin):" 8 60 2> $TEMPFILE
			if [ $? = "1" ]; then
				LEV1="1"
				continue
			fi
			CDNAME=`cat $TEMPFILE`
			cd "$IMGDIR"
			if [ ! -r "$CDNAME.toc" ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
					--msgbox "'$CDNAME.toc' does not exist or is not readable. Choose another name!" 6 60
				continue
			fi
			dialog --backtitle "$BACKTITLE" --title " Burn Audio-CD " \
				--msgbox "\n  Insert CD-R and press OK to burn" 7 40
			clear
			cdrdao write $DEVWDAO $DRVWDAO $SPEEDDAO "$CDNAME.toc"
			echo ""
			echo "Press Enter"
			read JUNK
			LEV1="1"
		done
		;;

		3)
		while [ $LEV1 = "0" ]; do
			dialog --backtitle "$BACKTITLE" --title "Copy Audio-CD" \
				--inputbox "Enter CD-image filename (without .bin):" 8 60 2> $TEMPFILE
			if [ $? = "1" ]; then
				LEV1="1"
				continue
			fi
			CDNAME=`cat $TEMPFILE`
			cd "$IMGDIR"
			if [ -e "$CDNAME.toc" ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
					--msgbox "'$CDNAME.toc' already exists. Choose another name!" 6 60
				continue
			fi
			dialog --backtitle "$BACKTITLE" --title "Copy Audio-CD" \
				--msgbox "\nInsert Audio-CD and press OK to read" 7 40
			clear
			nice -n 14 cdrdao read-cd $DEVRDAO $DRVRDAO $PARANOIA --datafile "$CDNAME.bin" "$CDNAME.toc"
			echo ""
			echo "Insert CD-R and press Enter to burn"
			read JUNK
			echo ""
			cdrdao write $DEVWDAO $DRVWDAO $SPEEDDAO "$CDNAME.toc"
			echo ""
			echo "Press Enter"
			read JUNK
			LEV1="1"
		done
		;;

		4)
		while [ $LEV1 = "0" ]; do
			# enter playlist filename
			dialog --backtitle "$BACKTITLE" --title "Burn Audio-CD from playlist" \
				--inputbox "Enter playlist filename (without .m3u):" 8 60 2> $TEMPFILE
			if [ $? = "1" ]; then
				LEV1="1"
				continue
			fi
			PLAYLIST="`cat $TEMPFILE`.m3u"
			if [ ! -r "$PLAYLIST" ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
					--msgbox "'$PLAYLIST' does not exist or is not readable" 6 60
				continue
			fi
			# enter wav names
			dialog --backtitle "$BACKTITLE" --title "Burn Audio-CD from playlist" \
				--inputbox "Enter name of WAV files (without .wav):" 8 60 2> $TEMPFILE
			if [ $? = "1" ]; then
				LEV1="1"
				continue
			fi
			WAVNAME=`cat $TEMPFILE`
			if [ -e "$IMGDIR/$WAVNAME" ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
					--msgbox "'$WAVNAME' already exists. Choose another name!" 6 60
				continue
			fi
			# normalize: yes/no
			dialog --backtitle "$BACKTITLE" --title "Burn Audio-CD from playlist" \
				--yesno "Do you want to normalize the WAVs to $NORMAMP?" 6 60
			if [ $? = "0" ]; then
				NORMSET="1"
			else
				NORMSET="0"
			fi
			# count files
			filecount
			# checks playlist for more than 99 tracks
			if [ $MAXN -gt 99 ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
					--msgbox "There are $MAXN files in '$PLAYLIST' but you cannot burn more than 99 tracks." 6 60
				LEV1="1"
				continue
			else
			echo "There are $MAXN files in '$PLAYLIST'"
			echo "Press Enter"
			read JUNK
			fi
			echo ""
			# decode and normalize
			decodenorm
			echo ""
			echo "Insert CD-R and press Enter"
			read JUNK
			cdrecord $DEVWREC $SPEEDREC $BURNFREE $OTHERREC "$IMGDIR/$WAVNAME/$WAVNAME".*.wav
			echo ""
			echo "Press Enter"
			read JUNK
			LEV1="1"
		done
		;;

		5)
		while [ $LEV1 = "0" ]; do
			# enter playlist filename
			dialog --backtitle "$BACKTITLE" --title "Convert M3U playlist to WAVs" \
				--inputbox "Enter playlist filename (without .m3u):" 8 60 2> $TEMPFILE
			if [ $? = "1" ]; then
				LEV1="1"
				continue
			fi
			PLAYLIST="`cat $TEMPFILE`.m3u"
			if [ ! -r "$PLAYLIST" ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
					--msgbox "'$PLAYLIST' does not exist or is not readable" 6 60
				continue
			fi
			# enter wav names
			dialog --backtitle "$BACKTITLE" --title "Convert M3U playlist to WAVs" \
				--inputbox "Enter name of WAV files (without .wav):" 8 60 2> $TEMPFILE
			if [ $? = "1" ]; then
				LEV1="1"
				continue
			fi
			WAVNAME=`cat $TEMPFILE`
			if [ -e "$IMGDIR/$WAVNAME" ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
					--msgbox "'$WAVNAME' already exists. Choose another name!" 6 60
				continue
			fi
			# normalize: yes/no
			dialog --backtitle "$BACKTITLE" --title "Convert M3U playlist to WAVs" \
			       --yesno "Do you want to normalize the WAV to $NORMAMP?" 6 60
			if [ $? = "0" ]; then
				NORMSET="1"
			else
				NORMSET="0"
			fi
			# count files
			filecount
			#  checks playlist for more than 99 tracks
			if [ $MAXN -gt 99 ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
					--msgbox "There are $MAXN files in '$PLAYLIST' but you cannot burn more than 99 tracks." 6 60
				LEV1="1"
				continue
			else
			echo "There are $MAXN files in '$PLAYLIST'"
			echo "Press Enter"
			read JUNK
			fi
			echo ""
			decodenorm
			echo ""
			echo "Press Enter"
			read JUNK
			LEV1="1"
		done
		;;

		6)
		while [ $LEV1 = "0" ]; do
			dialog --backtitle "$BACKTITLE" --title "Burn Audio-CD from WAVs" \
			       --inputbox "Enter name of WAV files (without .XX.wav):" 8 60 2> $TEMPFILE
			if [ $? = "1" ]; then
				LEV1="1"
				continue
			fi
			WAVNAME=`cat $TEMPFILE`
			if [ ! -r "$IMGDIR/$WAVNAME/$WAVNAME.01.wav" ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
					--msgbox "'$WAVNAME.01.wav' does not exist or is not readable" 6 60
				continue
			fi
			echo -e "TRACKLIST:\n" > $TEMPFILE
			find "$IMGDIR/$WAVNAME/$WAVNAME".*.wav -printf "%f\n" >> $TEMPFILE
			echo -e "\nInsert CD-R and press OK to burn" >> $TEMPFILE
			dialog --backtitle "$BACKTITLE" --title "Burn Audio-CD from WAVs" --exit-label "OK" \
				--textbox $TEMPFILE 16 60
			clear
			cdrecord $DEVWREC $SPEEDREC $BURNFREE $OTHERREC "$IMGDIR/$WAVNAME/$WAVNAME".*.wav
			echo ""
			echo "Press Enter"
			read JUNK
			LEV1="1"
		done
		;;

		7)
		while [ $LEV1 = "0" ]; do
			dialog --backtitle "$BACKTITLE" --title "Check MP3s in M3U playlist" \
				--inputbox "Enter playlist filename (without .m3u):" 8 60 2> $TEMPFILE
			if [ $? = "1" ]; then
				LEV1="1"
				continue
			fi
			PLAYLIST="`cat $TEMPFILE`.m3u"
			if [ ! -r "$PLAYLIST" ]; then
				dialog --backtitle "$BACKTITLE" --title "$ERROR" \
				    --msgbox "'$PLAYLIST' does not exist or is not readable" 6 60
				continue
			fi
			filecount
			checkm3u
			echo "Press Enter"
			read JUNK
			LEV1="1"
		done
		;;

		8)
		MAINLEV="1"
		;;
	esac
done
rm -f $TEMPFILE
clear
echo "$BACKTITLE (C) by Thorsten Muehlfelder"
