#!/bin/bash
#    dvd-slideshow
#    Copyright 2003 Scott Dylewski  <scott at dylewski.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    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.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

name='dvd-slideshow'
version='0.5.4'

echo "[dvd-slideshow]            dvd-slideshow $version"
echo "[dvd-slideshow]            Licensed under the GNU GPL"
echo "[dvd-slideshow]            Copyright 2003-2004 by Scott Dylewski"

changes ()
{
echo 'Changes:
0.5.4	
	Added option to re-define background image from text file input.
	Code cleanup (slightly)
	Added support for two audio tracks.  
	Added audio effects:  fadein/fadeout	
	Default command-line audio fadein/fadeout time is 3 seconds.
0.5.2	
	Fixed bug in musictitle Title info parsing.
	Checks to make sure a slidshow name is passed.
	Added low-quality mode (-L) for testing.  Speeds things up about 4x.
	Reduced verbosity.
	Checks for required fonts. Subtitles look much better now.
	Word-wraps long subtitle lines into two lines.
0.5.0	
	Added KenBurns effect!  See docs for usage.
	Added scroll effect!  See docs for usage.
	Added crop effect.  See docs for usage.
	Audio can be started and stoped for multiple files within
		the text file.  See docs for usage.
	Added "musictitle" option for displaying audio info.
	You can now comment out lines in the textfile by using the # character.
	Also ignores blank lines in textfile.
	Fades can now have up to 9999 frames.
	Total slides can now be 9999.  You guys are crazy.
	fixed small bug when no chapters are specified.
	Chapter markers are now rounded up to the next full second due to
		a bug in some versions of dvdauthor.
	Only checks for oggdec or lame if you pass an ogg or mp3 file.
	Changed syntax of command line input for files and audio.
	Passing images on the command line is no longer "public". 
		Use the text file in put instead.
	Fixed audio problem with some mp3 files getting pops in them.
0.4.8   
	Changed audio to process raw (headerless) audio files before 
		joining them.
        Fixed bug when passing multiple audio files (again).
        Fixed audio fadein/fadeout time to 1 second
        Fixed bug in audio where it plays to fast when burned on dvd.
        Checks to make sure audio files exist before processing.
0.4.6	Fixed bug when passing multiple audio files. (thanks Scott Merrill)
	Removed -t option from toolame command for better support for old versions.
0.4.4	Only writes chapter markers when there is a picture or title
	First chapter marker is now fixed at time 0
	Max number of chapter markers is now 99 (thanks Jens Gecius)
	Fixed bug when checking for toolame (thanks Jens Gecius)
	Added "crossfade" option!
	Will use mpeg3cat from libmpeg3 to join mpegs if available.
	Small fix to allow semicolons in subtitles (thanks Jim Crumley)
	Added -s option to mpeg2enc calls for (maybe?) better compatibility.
0.4.2	Current working directory will be used if -o not specified.
	Allow "background" keyword in text file to insert background.
	Make sure all ImageMagick calls have -depth 8 to make ppmtoy4m happy.
	No font is specified in ImageMagick calls, so it should use the default.
	Changed default menu to a steelblue gradient when no image is passed.
0.4	Fixed bug when no background specified (again).
	Added error checking to make sure image files exist.
	Ogg audio format supported (you must have oggdec).
	Uses toolame for mp2 audio encoding when available.
	Audio timing improved.
	Fixed bug when double-quotes were in subtitle.
	Added black, fadein, and fadeout options in txtfile!
	-p  (PAL format option) added. Not tested, but should work.
0.3	Fixed error when no background specified.  Now default is black
	Added checking for required programs before running.
0.2	Initial release'
}

help ()
{
echo "`basename $0` Version $version "
echo 'http://freshmeat.net/dvdslideshow'
echo 'Copyright 2003-2004 Scott Dylewski <scott at dylewski.com>'
echo 	 
echo 'Description: 
	Creates a dvd-compatible mpeg2 file from a bunch of jpegs.
	You can add music if you want also. Supports several effects
	like fadein/fadeout/crossfade/crop/kenburns.  

Usage:
 dvd-slideshow -o <output_directory> [-b <background_jpeg>] 
  [-n <slideshow_name>] [-a <audio_file1> <audio_file2> ... <audio_fileN>] 
  -f input_file.txt [-p] [-L]
	
Options: 
 -o <outupt directory>
	  Directory where the final mpeg and dvdauthor files
	  will be written
 		
 [-b <background jpeg>]
	  Image to use for the background of the slideshow.
	  All of the pictures will be
	  overlaid on top of this background image. If no file 
	  is specified, black will be used for the slideshow
	  and a blue gradient for the title slide.
	  
 -n slideshow_name
	  This will be printed at the top of the slideshow
	  title slide, if it exists.  The program also uses this
	  string as the filename base for the output files
	  so you can distinguish it from other slideshows
	  that you can send to the same output directory.

 -a <audio file>
          Audio file to play in background during the slideshow.
          It will be faded out at the end.  Supports mp3, ogg, or wav
          formats at this point.  Multiple files will be joined.
	  See also the more flexible text file input method.
	  To pass multiple files, use the -a switch again.

 -p 
	  Use PAL output video format instead of NTSC

 -L 
	  Render a low-quality video suitable for debugging.
	  This sets the resolution to 1/2 of full resolution and
	  decreases the quality of fades/transitions.
 		
 -f input_file.txt
          File to specify all the parameters and order easily
          for bigger slideshows. It uses the ':' character as a 
	  separator for the fields:
          [image.jpg|keyword]:duration:subtitle:effect:effect_params
          with each line being separate.  File options
          will override the ones passed on the command line.
	  NOTE: the effect parameters are separated by a semicolon ;
	  instead of a colon :

	  Keywords:
	    title:duration:The_title_text
	    	makes a title slide
	    musictitle:duration:subtitle:Title;Artist;Album
	   	makes a black frame with the song info 
		printed in the bottom left corner.
	    black:duration:subtitle  (depreciated)
	    	Makes a blank black slide. Use the "background"
		keyword instead.
	    background:duration:subtitle:image 
	    	makes a slide with the current
		background (black or a jpeg), or it resets
		the current background image to a new one:
		"background:2:"  will display the current background
		for 2 seconds. 
		"background:2::image.jpg"  will set the background to
		image.jpg and also display it for 2 seconds.
		"background:0::image.jpg"  will set the background to 
		image.jpg, but will not use it until the next picture. 
		"black" can be used instead of an image name to display
		a black background.
	    fadein:duration:subtitle
	    	fades in to the next slide
	    fadeout:duration:subtitle
	    	fades out to the background
	    crossfade:duration:subtitle
	    	fades from one picture to the next.
	    
	  Effects:
	    Effects are only used with images, not keywords.
	    In the following effects, x0,y0 represents the
	    top left corner of a defined box, and x1,y1 is
	    the bottom right corner. 
	    NOTE: the effect parameters are separated by a
	    semicolon ; instead of a colon :
            crop:
	    	image.jpg:dur:sub:crop:x0,y0;x1,y1
		Crops the image about the coordinates
		specified.
	    kenburns:
	    	image.jpg:dur:sub:kenburns:xs0,ys0;xs1,ys1;xe0,ye0;xe1,ye1
	    	Where now we have starting (s) and ending (e) boxes.  
		The kenburns effect will crop/zoom from the start
		to the end point.
	    scroll:
	    	image.jpg:dur:sub:scroll:left
	    	image.jpg:dur:sub:scroll:right
		This is most useful for displaying panorama-style
		pictures that are much wider than they are tall.
		This will automatically resize the picture so that
		the image height is equal to the video display 
		height (480) before scrolling.

	    The subtitle field is optional, but if you are passing
	    effects after the subtitle field, be sure to include 
	    all the colons :: in order for the parser to get the
	    correct info.

	    When passing a picture, you can optionally use the
	    keyword "audio" instead of the integer duration in 
	    seconds.  What this does is force the duration of
	    that image to be the length of the previous audio 
	    track.  This is useful for making a music video dvd.

	  Audio:
	  Audio tracks can be inter-mixed with the video.  If 
	  an audio track is placed between two different images,
	  that audio track will begin playing at the start of the
	  second image.  When placing audio, use the syntax:

          audiofile:track:effect1:effect1_params:effect2:effect2_params

	  The audiofile can be a .ogg, .mp3, or .wav file.
	  Track is the resulting dvd audio track.
	  Effects are audio effects where
	  you can specify things like fadein/fadeout
	  for the audio.  Example:
          audiofile.ogg:1:fadein:3:fadeout:2
	
 -h or -help 
   Prints this help. 

 -v or -version 
   Prints dvd-slideshow version number. '
	echo '  '
}

if [ $# -lt 1 ]; then
	help
	exit 1
fi

## notes:
## note that ppmtoy4m needs a "TrueColor" type image from ImageMagick
## instead of a "PseudoClass" image

## setup initial variables:
debug=0 # 1 or 0
verbosity=0
pal=0  # not implemented yet
slideshow_name=""
titletext=""
i_audio=0
j_audio=0
write_chap=0
copy=0
low_quality=0
subtitle_number=1
# define some possible fonts:
font1='/usr/share/fonts/default/Type1/n019004l.pfb' # helvetica bold URW fonts
font2='/usr/share/fonts/default/TrueType/helb____.ttf' # helvetica bold truetype
n=0
m=0
new_vob=0
browse_num=0
submenu=0

for arg
do
	case "$arg" in
	-i) shift ; image[$n]="$1"; let n=$n+1; shift;;
	-o) shift; outdir="$1"; shift ;;
	-b) shift; bgfile="$1"; shift ;;
	-n) shift; slideshow_name="$1"; shift ;;
	-t) shift; time_per_picture="$1"; shift ;;  ## in tenths of seconds?
#	-T) shift; titletext="$1"; shift ;;   ## need to specify this in the file
	-f) shift; input_txtfile="$1"; shift
                if [ ! -f "$input_txtfile" ] ; then
                echo "[dvd-slideshow] ERROR: Input file $input_txtfile does not exist."
                exit 1
                fi ;;
#	-d) shift; delete_outdir=1 ;;  #user must manually delete if wanted 
	-p) shift; pal=1 ;;  # use pal format
	-c) shift; copy=1 ;;  # make backup copy of all pictures passed. not tested
	-s) shift; submenu=1 ;;  # create a sub-menu with options (not working yet)
	-L) shift; low_quality=1 ;;  # use low-quality mode
	-a) shift; 
                # make sure the file exists and is the correct type!
                suffix=`echo "$1" | awk -F. '{print tolower($NF)}'`
                if [ "$suffix" == 'ogg' ] || [ "$suffix" == 'mp3' ] || [ "$suffix" == 'wav' ] ; then
                	if [ ! -f "$1" ] ; then
                       	 echo "[dvd-slideshow] ERROR: File $1 does not exist"
                         exit 1
                        fi
                        audio[$m]="$1"
                        let m=$m+1
                        shift;
                else
                       	 echo "[dvd-slideshow] ERROR: File $1 is not an ogg, mp3, or wav."
                         exit 1
                fi ;;
	-h) help ; exit 0 ; shift ;;
	-?) help ; exit 0 ; shift ;;
	-help) help ; exit 0 ; shift ;;
	-v) echo "$version" ; exit 0 ; shift ;;
	-version) echo "$version" ; exit 0 ; shift ;;
	esac
done

if [ -z "$input_txtfile" ] ; then
	input_txtfile="$1"
fi
if [ ! -f "$input_txtfile" ] ; then
	echo "[dvd-slideshow] ERROR: Input file $input_txtfile does not exist."
	exit 1
fi

# make sure a slideshow name was given:
if [ -z "$slideshow_name" ] ; then
	echo "[dvd-slideshow] ERROR:  You must specify a slideshow name with -n <slideshow name>"
	exit 1
fi

## check_rm checks to see if the file exists before it's deleted:
check_rm ()
{
	if [ -f $1 ] ; then
		rm $1
	fi
}

cleanup ()
{
	## clean up temporary files
	echo ""
	echo "[dvd-slideshow] cleanup..."
	check_rm temp_slideshow_image.ppm
	check_rm temp_slideshow_image_scaled.ppm
	check_rm "$outdir/slideshow_background.ppm"
	check_rm "$outdir/title_background.ppm"
	check_rm "$outdir/title_background.png"
#	check_rm "$outdir/${slideshow_name}.chap"
	check_rm "$outdir/${slideshow_name}".spumux
#	check_rm "$outdir/"
	check_rm "$outdir/trash.txt"
	check_rm "$outdir/subtitle.png"
	check_rm "$outdir/dvd_title.png"
	check_rm "$outdir/dvd_title_2.png"
	check_rm "$outdir/video.mpg"
	check_rm "$outdir/audio1.mp2"
	check_rm "$outdir/audio2.mp2"
	check_rm "$outdir/audio1.wav"
	check_rm "$outdir/audio2.wav"
	check_rm "$outdir/audio.raw"
	check_rm "$outdir/audio_new.raw"
	k=0
	dk=0
	for file in "${image[@]}"; do
 		[ $k -lt 1000 ] && dk="0$k" || dk=$k
 		[ $k -lt 100 ] && dk="00$k" || dk=$dk
 		[ $k -lt 10 ] && dk="000$k" || dk=$dk
#		echo "k=$k  dk=$dk"
		check_rm "$outdir/audio1_$k.wav"
		check_rm "$outdir/audio1_$k.raw"
		check_rm "$outdir/audio2_$k.wav"
		check_rm "$outdir/audio2_$k.raw"
		check_rm "$outdir/slide_$k.ppm"
		check_rm "$outdir/slide_$dk.mpg"
		check_rm "$outdir/subtitle_$k.png"
		let k=$k+1
	done
}

forcequit () ## function gets run when we have some sort of forcequit...
{
	## clean up temporary files
	cleanup
	exit
}

trap 'forcequit' INT
trap 'forcequit' KILL
trap 'forcequit' TERM

## check for the necessary programs:
checkforprog ()
{
        it=`which $1`
        if [ -z "$it" ] ; then
                echo "[dvd-slideshow] ERROR:  $1 not found! "
                echo "[dvd-slideshow] Check the dependencies and make sure everything is installed."
                exit 1
        fi
}

hms ()
{
	## pass a number in hundreths of seconds and get back a 
	## time code of the form HR:MM:SS:HU
	if [ -z "$1" ] ; then
		echo ''
	else
		hours=$(( $1 / 360000 ))
		it=$(( $1 - $hours * 360000 ))
		minutes=$(( $it / 6000 ))
		it=$(( $1 - $minutes * 6000 ))
		seconds=$(( $it / 100 ))
		hundreths=$(( $it - $seconds * 100 ))
		it="$hours:$minutes:$seconds.$hundreths"
		echo "${it}"
	fi
}

max ()
{
	## get the max of the arguments
	last_number=0
	for number
	do
		if [ "$number" -gt "$last_number" ] ; then
			last_number="$number"
		fi
	done
	echo "$last_number"
}

min ()
{
	## get the min of the arguments
	last_number=10000000000000000
	for number
	do
		if [ "$number" -lt "$last_number" ] ; then
			last_number="$number"
		fi
	done
	echo "$last_number"
}

debug ()
{
	# only print if the debug variable is set to 1
	if [ "$debug" -eq 1 ] ; then
		echo "$1"
	fi
}

addzeros ()
{
			[ $1 -lt 1000 ] && dj2="0$1" || dj2=$1
			[ $1 -lt 100 ] && dj2="00$1" || dj2=$dj2
			[ $1 -lt 10 ] && dj2="000$1" || dj2=$dj2
			echo "$dj2"
}

strip1 ()
{
read junk
cat 
return 0
}

encode ()
{
if [ "$pal" -eq 1 ] ; then
	ppmtoy4m -v $verbosity -n "$frames" -r -F 25:1 -A 59:54 -I p "$outdir/slide_$i.ppm"\
	 | mpeg2enc -v $verbosity -a 2 -q 4 -s -M 3 -f 8 -o "$outdir/slide_$di.mpg"
else
	ppmtoy4m -v $verbosity -n "$frames" -r -F 30000:1001 -A 10:11 -I p "$outdir/slide_$i.ppm" \
	| mpeg2enc -v $verbosity -a 2 -q 4 -s -M 3 -f 8 -o "$outdir/slide_$di.mpg"
fi
}

encode_fade ()
{
if [ "$pal" -eq 1 ] ; then
        cat "$outdir"/fade_*.ppm | ppmtoy4m -v $verbosity -n 0 -F 25:1 -A 59:54 -I p \
        | mpeg2enc -v $verbosity -a 2 -q 4 -s -M 3 -f 8 -o "$outdir/slide_$di.mpg"
else
        cat "$outdir"/fade_*.ppm | ppmtoy4m -v $verbosity -n 0 -F 30000:1001 -A 10:11 -I p \
	| mpeg2enc -v $verbosity -a 2 -q 4 -s -M 3 -f 8 -o "$outdir/slide_$di.mpg"
fi
}

extracopies ()
{
	if [ "$stepsize" -eq 2 ] ; then
		dj2=`addzeros $(( $fr + 1 ))`
		cp "$outdir/fade_$dj.ppm" "$outdir/fade_$dj2.ppm"
	elif [ "$stepsize" -eq 5 ] ; then
		dj2=`addzeros $(( $fr + 1 ))`
		cp "$outdir/fade_$dj.ppm" "$outdir/fade_$dj2.ppm"
		dj3=`addzeros $(( $fr + 1 ))`
		cp "$outdir/fade_$dj.ppm" "$outdir/fade_$dj3.ppm"
		dj4=`addzeros $(( $fr + 1 ))`
		cp "$outdir/fade_$dj.ppm" "$outdir/fade_$dj4.ppm"
		dj5=`addzeros $(( $fr + 1 ))`
		cp "$outdir/fade_$dj.ppm" "$outdir/fade_$dj5.ppm"
	fi
}

make_arrows ()
{
	## make arrow buttons for future use:
	scale=2
	pt0x=550 ; pt0y=375 
	pt1x=$(( $pt0x + 0 * $scale )) ; pt1y=$(( $pt0y + -3 * $scale ))
	pt2x=$(( $pt0x + 10 * $scale )) ; pt2y=$(( $pt0y + -3 * $scale ))
	pt3x=$(( $pt0x + 10 * $scale )) ; pt3y=$(( $pt0y + -8 * $scale ))
	pt4x=$(( $pt0x + 18 * $scale )) ; pt4y=$(( $pt0y + 0 * $scale ))
	pt5x=$(( $pt0x + 10 * $scale )) ; pt5y=$(( $pt0y + 8 * $scale ))
	pt6x=$(( $pt0x + 10 * $scale )) ; pt6y=$(( $pt0y + 3 * $scale ))
	pt7x=$(( $pt0x + 0 * $scale )) ; pt7y=$(( $pt0y + 3 * $scale ))
	pt8x=$(( $pt0x + 0 * $scale )) ; pt8y=$(( $pt0y + -3 * $scale ))
	
	convert -size "$resolution" xc:transparent -depth 8 -fill white -stroke black \
		-draw "polygon $pt1x,$pt1y $pt2x,$pt2y $pt3x,$pt3y $pt4x,$pt4y $pt5x,$pt5y $pt6x,$pt6y $pt7x,$pt7y $pt8x,$pt8y" \
		"$outdir/right_arrow.png"
	convert -size "$resolution" xc:transparent -depth 8 -fill red -stroke red \
		-draw "polygon $pt1x,$pt1y $pt2x,$pt2y $pt3x,$pt3y $pt4x,$pt4y $pt5x,$pt5y $pt6x,$pt6y $pt7x,$pt7y $pt8x,$pt8y" \
		"$outdir/right_arrow_mask.png"
	
	convert "$outdir/right_arrow.png" -flop "$outdir/left_arrow.png"
	convert "$outdir/right_arrow_mask.png" -flop "$outdir/left_arrow_mask.png"
	
	pt0x=$(( $width / 2 )) ; pt0y=375 
	pt1x=$(( $pt0x + 0 * $scale )) ; pt1y=$(( $pt0y + -8 * $scale ))
	pt2x=$(( $pt0x + -8 * $scale )) ; pt2y=$(( $pt0y + 0 * $scale ))
	pt3x=$(( $pt0x + -3 * $scale )) ; pt3y=$(( $pt0y + 0 * $scale ))
	pt4x=$(( $pt0x + -3 * $scale )) ; pt4y=$(( $pt0y + 10 * $scale ))
	pt5x=$(( $pt0x + 3 * $scale )) ; pt5y=$(( $pt0y + 10 * $scale ))
	pt6x=$(( $pt0x + 3 * $scale )) ; pt6y=$(( $pt0y + 0 * $scale ))
	pt7x=$(( $pt0x + 8 * $scale )) ; pt7y=$(( $pt0y + 0 * $scale ))
	pt8x=$(( $pt0x + 0 * $scale )) ; pt8y=$(( $pt0y + -8 * $scale ))
	
	convert -size "$resolution" xc:transparent -depth 8 -fill white -stroke black \
	-draw "polygon $pt1x,$pt1y $pt2x,$pt2y $pt3x,$pt3y $pt4x,$pt4y $pt5x,$pt5y $pt6x,$pt6y $pt7x,$pt7y $pt8x,$pt8y" \
		"$outdir/up_arrow.png"
	convert -size "$resolution" xc:gray50 -depth 8 -fill red -stroke red \
		-draw "polygon $pt1x,$pt1y $pt2x,$pt2y $pt3x,$pt3y $pt4x,$pt4y $pt5x,$pt5y $pt6x,$pt6y $pt7x,$pt7y $pt8x,$pt8y" \
		"$outdir/up_arrow_mask.png"
	
	this_chap=0
}

checkforprog ppmtoy4m
checkforprog sox
checkforprog convert
checkforprog pngtopnm
checkforprog dvdauthor

# verify fonts exist:
if [ -f "$font1" ] ; then 
	font="-font $font1"
elif [ -f "$font2" ] ; then
	font="-font $font2"
else
	echo "[dvd-slideshow] Cannot find required fonts.  Using default ImageMagick font."
	font=""
fi

# verity output directory exists:
if [ -z "$outdir" ] ; then
	if [ -w `pwd` ] ; then
		echo "[dvd-slideshow] Output directory not specified."
		echo "[dvd-slideshow] Using `pwd`"
		outdir="`pwd`"
	else
		echo 'ERROR: Output directory not specified.'
		exit
	fi
fi

let i=0
if [ ! -z "${input_txtfile}" ] ; then
	## let's parse the txtfile:
	total_lines=`wc -l ${input_txtfile} | awk '{print $1}'`
	total_lines=$(( $total_lines + 1 ))
	let line=1
	while [ $line -ne $total_lines -a $total_lines -ne 0 ];
	do
		thisline=`sed -n "$line"p "${input_txtfile}"`
#		echo "thisline=$thisline"
		if [ "${thisline:0:1}" == '#' ] ; then
			line=$(( $line + 1 ))
			continue # commented line. ignore it.
		elif [ -z `echo "$thisline" | tr -d [:blank:]` ] ; then
			line=$(( $line + 1 ))
			continue # blank line. ignore it.
		elif [ `echo "$thisline" | awk -F: '{print NF}'` -eq 1 ] ; then
			echo "[dvd-slideshow] ERROR: Bad line $thisline"
			echo "[dvd-slideshow]        Check the syntax and try again."
			exit 1
		fi 
		image[$i]=`echo "${thisline}" | cut -d: -f1`
		## check data file type and build arrays
		filetype[$i]=`echo "${image[$i]}" | awk -F. '{print tolower($NF)}'`
		duration[$i]=`echo "${thisline}" | cut -d: -f2`
		subtitle[$i]=`echo "${thisline}" | cut -d: -f3`
		effect1[$i]=`echo "${thisline}" | cut -d: -f4`
		if [ "${filetype[$i]}" == 'musictitle' ] ; then
			effect1_params[$i]=`echo "${thisline}" | cut -d: -f5`
		else
			effect1_params[$i]=`echo "${thisline}" | cut -d: -f5 | tr -d [:blank:]`
		fi
		effect2[$i]=`echo "${thisline}" | cut -d: -f6`
		effect2_params[$i]=`echo "${thisline}" | cut -d: -f7 | tr -d [:blank:]`
		effect3[$i]=`echo "${thisline}" | cut -d: -f8`
		effect_params3[$i]=`echo "${thisline}" | cut -d: -f9 | tr -d [:blank:]`
		effect4[$i]=`echo "${thisline}" | cut -d: -f10`
		effect_params4[$i]=`echo "${thisline}" | cut -d: -f11 | tr -d [:blank:]`

		if [ "${filetype[$i]}" == 'jpg' ] || [ "${filetype[$i]}" == 'png' ]; then
			image_file[$i]=1 ; audio_file[$i]=0
			## optinally copy images to new directory for backup onto dvd:
			newname=`echo "${slideshow_name}" | sed -e 's/ /_/g'`
			if [ "$copy" -eq 1 ] && [ ! -d "$outdir/$newname"_pics ] ; then
				mkdir "$outdir/$newname"_pics
			fi
			if [ "$copy" -eq 1 ] ; then
				cp "${image[$i]}" "$outdir/$newname"_pics
			fi
		elif [ "${filetype[$i]}" == 'ogg' ] || [ "${filetype[$i]}" == 'mp3' ] || [ "${filetype[$i]}" == 'wav' ] || [ "${image[$i]}" == 'silence' ]; then
			audio_file[$i]=1 ; image_file[$i]=0
			effect1[$i]=`echo "${thisline}" | cut -d: -f3`  # no subtitle for audio 
			effect1_params[$i]=`echo "${thisline}" | cut -d: -f4 | tr -d [:blank:]`
			effect2[$i]=`echo "${thisline}" | cut -d: -f5`
			effect2_params[$i]=`echo "${thisline}" | cut -d: -f6 | tr -d [:blank:]`
			if [ "${effect1[$i]}" != 'fadein' ] && [ -n "${effect1[$i]}" ]; then
				echo "[dvd-slideshow] ERROR: First audio effect must be fadein"
				exit 1
			fi
			if [ "${effect2[$i]}" != 'fadeout' ] && [ -n "${effect2[$i]}" ]; then
				echo "[dvd-slideshow] ERROR: Second audio effect must be fadeout"
				exit 1
			fi
			## get audio track number:
			if [ -z "${duration[$i]}" ] ; then 
				# duration is the field for the audio track numuber
				# if empty, assume track=1
				audio_track[$i]='1'
			elif [ "${duration[$i]}" -gt 2 ]; then
				echo "[dvd-slideshow] ERROR: Only 2 audio tracks supported at this time."
				echo "[dvd-slideshow]        Fix this audio file track number!"
				exit 1
			else
				# use the duration as the audio track number:
				audio_track[$i]="${duration[$i]}"
			fi
			## get filetype:
			if [ "${filetype[$i]}" == 'ogg' ] ; then
				checkforprog oggdec
			fi
			if [ "${filetype[$i]}" == 'mp3' ] ; then
				checkforprog lame
			fi
			duration[$i]=0
			subtitle[$i]=''
		else
			image_file[$i]=0 ; audio_file[$i]=0
		fi
#		echo "line=$i"
		line=$(( $line + 1 ))
		i=$(( $i + 1 ))
	done
else
	## build the duration and subtitle arrays:
	let i=0
	for file in "${image[@]}"; do
		duration[$i]="${time_per_picture}"
		subtitle[$i]=''
	done
fi


if [ $debug -eq 1 ] ; then
	echo "outdir=$outdir"
	echo "time_per_picture=$time_per_picture"
	echo "pal=$pal"
	echo "audio files:"
	echo "${audio[@]}"
	echo "image files:" 
	echo "${image[@]}" 
	echo "image files:" 
	echo "${image_file[@]}" 
	echo "audio files:" 
	echo "${audio_file[@]}" 
	echo "duration:" 
	echo "${duration[@]}" 
	echo "subtitle:" 
	echo "${subtitle[@]}" 
	echo "effect:" 
	echo "${effect1[@]}" 
	echo "effect1_params:" 
	echo "${effect1_params[@]}" 
fi


if [ ! -d "$outdir" ] ; then	
        echo "ERROR... output directory does not exist!"
        exit
	echo "creating directory $outdir"
	mkdir "$outdir"  # create directory
fi

if [ "$pal" -eq 1 ] ; then
	framerate='25'
	frames_per_sec=2500  # in 1/100ths of a second
	if [ "$low_quality" -eq 1 ] ; then
		width='352' ; height='288'
		resolution='352x288'
	else
		width='720' ; height='576'
		resolution='720x576'
	fi
else
	framerate='29.97'
	frames_per_sec=2997  # in 1/100ths of a second
	if [ "$low_quality" -eq 1 ] ; then
		width='352' ; height='240'
		resolution='352x240'
	else
		width='720' ; height='480'
		resolution='720x480'
	fi
fi

let frame_time=0
let total_slideshow_frames=0
if [ "$low_quality" -eq 1 ] ; then
	subtitle_font_size=12
	title_font_size=24
	title_font_size_2=18
	echo "[dvd-slideshow] WARNING: Using low-quality mode.  Audio and chapter"
	echo "[dvd-slideshow] timings may be off.  This mode is for testing only."
else
	subtitle_font_size=24
	title_font_size=48
	title_font_size_2=36
fi
has_subtitles=0
bg_color='steelblue'
## other cool colors:  cadetblue cornflowerblue midnightblue

orig_slideshow_name="${slideshow_name}"
slideshow_name=`echo "${slideshow_name}" | sed -e 's/ /_/g'`
if [ "$orig_slideshow_name" != "$slideshow_name" ] ; then
	echo "[dvd-slideshow] Output filename is $slideshow_name"
fi

## make both a slideshow_background file and a title_background file
## (to prepare for the day when we can have any background for any slide?)
if [ -f "${bgfile}" ] ; then
	echo "[dvd-slideshow] using background image ${bgfile}"
	convert -depth 8 "${bgfile}" -resize x"$height" -bordercolor black -border "$width"x240 \
		-gravity center -crop "$width"x"$height"'+0+0!' \
		-quality 100 $outdir/slideshow_background.ppm
	cp "$outdir/slideshow_background.ppm" "$outdir/title_background.ppm"
else
	## need to write out a blank image of the given size:
	## WE NEED -depth 8 here!!! 
	echo "[dvd-slideshow] using $bg_color background color for menu"
	convert -size "$resolution" xc:black -type TrueColor \
		-depth 8 "$outdir"/slideshow_background.ppm
	convert -size "$resolution" gradient:white-$bg_color -type TrueColor \
		-depth 8 "$outdir"/title_background.ppm
fi
## overlay the white 50% part for the title slide text:
bgtop=$(( $height - 156 ))
bgbot=$(( $height - 100 ))
txtloc=$(( $height - 115 ))
convert -size "$resolution" xc:transparent -fill white \
       	-draw "Rectangle 0,0,$width,125" \
	-draw "Rectangle 0,$bgtop,$width,$bgbot" "$outdir/title_background.png"
composite -type TrueColor -depth 8 -dissolve 50 "$outdir/title_background.png" \
	"$outdir/title_background.ppm" "$outdir/title_background.ppm"

if [ "$submenu" -eq 1 ] ; then
	make_arrows # for future menu usage
fi

let i=0 # full
let v=0 # vob
for file in "${image[@]}"; do
	echo "[dvd-slideshow]########################################"
	## convert i to a 2-digit text version so we can cat the mpgs together
	## in the correct order easily:
	di=`addzeros $i`

	## loop over effects that get applied to pictures before other effects:
	## do not use this!! It may be taken out at any time. (because the code is really ugly)
	## I encourage you to rotate your pictures before you use this script!
	for e in `seq 2 1`; do
		if [ "$e" -eq 1 ] ; then
			this_effect="${effect1[$i]}"
			this_effect_params="${effect1_params[$i]}"
		elif [ "$e" -eq 2 ] ; then
			this_effect="${effect2[$i]}"
			this_effect_params="${effect2_params[$i]}"
		fi
#		echo "effect=$this_effect params=$this_effect_params"
		## rotate image first, then apply other effects?
		if [ "${image_file[$i]}" -eq 1 ] && [ "$this_effect" == 'rotate' ] ; then  #############
			## use real jpeg.  Rotate image!
			echo "[dvd-slideshow] Rotating picture"
#			echo "file=$file $outdir/temp.jpg"
			convert -rotate $this_effect_params "$file" -quality 100 "$outdir"/temp.jpg
			file="$outdir"/temp.jpg
			if [ "$e" -eq 1 ] ; then
				effect1[$i]="${effect2[$i]}"
				effect1_params[$i]="${effect2_params[$i]}"
				effect2[$i]=''
				effect2_params[$i]=''
			elif [ "$e" -eq 2 ] ; then
				effect2[$i]=''
				effect2_params[$i]=''
			fi
		fi
	done
	
#	echo "effect1=${effect1[$i]} params=${effect1_params[$i]}"
#	echo "effect2=${effect2[$i]} params=${effect2_params[$i]}"

	if [ "${duration[$i]}" == 'audio' ] ; then
		## make the duration the length of the last audio track
		if [ -z "$song_length_ms" ] ; then
			echo '# ERROR: You must have an audio track before a slide specifying "audio"'
			exit 1
		fi
		duration[$i]="$song_length"	# in seconds
	fi	

	if [ -z "${duration[$i]}" ] ; then
		echo "[dvd-slideshow] WARNING:  No duration specified for ${image[$i]}"
		echo "[dvd-slideshow]	     Using default duration of 5 seconds"
		duration[$i]=5
	fi

	## number of frames to render for this picture:
	frames=$(( $frames_per_sec * ${duration[$i]} / 100 ))
	## get start frame & time:
	slide_start_frame=$(( $total_slideshow_frames + 1 ))
	slide_start_time=$(( $slide_start_frame *100 * 100 / $frames_per_sec )) ## in hundreths of a sec.
	slide_start_hms=`hms "$slide_start_time"`
	if [ $debug -eq 1 ] ; then
		echo "[dvd-slideshow] start_frame_number=$slide_start_frame slide_start_time=$slide_start_hms"
	fi
#	echo "effect=${effect1[$i]} effect_params=${effect1_params[$i]}"
	echo "[dvd-slideshow] $i/${#image[@]} $file"
	if [ $debug -eq 1 ] ; then
		echo "[dvd-slideshow] frames=$frames duration=`echo ${duration[$i]} | tr -d [:blank:]` seconds"
	fi
	if [ "$file" == 'title' -o "$file" == 'Title' ] ; then
		## add the first title page:  ########################################
		echo "[dvd-slideshow] Making title slide:"
		echo "[dvd-slideshow] 	$orig_slideshow_name"
		echo "[dvd-slideshow] 	${subtitle[$i]}"
		convert -depth 8 -size $resolution -quality 100 xc:transparent \
			-pointsize $title_font_size -gravity NorthWest $font \
			-draw "text 80,100 \"${orig_slideshow_name}\"" "$outdir/dvd_title.png"
#		pngtopnm -alpha "$outdir/dvd_title.png" > "$outdir/dvd_title_mask.pnm"
#		pngtopnm "$outdir/dvd_title.png" > "$outdir/dvd_title.pnm"
		composite -type TrueColor -depth 8 -quality 100 \
			"$outdir/dvd_title.png" "$outdir/title_background.ppm" "$outdir/slide_$i.ppm"
#		pnmcomp -align=center -valign=middle -alpha="$outdir/dvd_title_mask.pnm" "$outdir/dvd_title.pnm" "$outdir/title_background.ppm" "$outdir/slide_$i.ppm"
		if [ -n "${subtitle[$i]}" ] ; then
#			echo "[dvd-slideshow] addding additional text to title:  ${subtitle[$i]}"
			convert -depth 8 -size $resolution -quality 100 xc:transparent \
				-pointsize $title_font_size_2 -gravity North $font \
				-draw "text 0,$txtloc \"${subtitle[$i]}\"" "$outdir/dvd_title_2.png"
#			pngtopnm -alpha "$outdir/dvd_title_2.png" > "$outdir/dvd_title_2_mask.pnm"
#			pngtopnm "$outdir/dvd_title_2.png" > "$outdir/dvd_title_2.pnm"
			composite -type TrueColor -depth 8 -quality 100 \
				"$outdir/dvd_title_2.png" "$outdir/slide_$i.ppm" "$outdir/newtitle.ppm"
#			pnmcomp -align=center -valign=middle -alpha="$outdir/dvd_title_2_mask.pnm" "$outdir/dvd_title_2.pnm" "$outdir/slide_$i.ppm" "$outdir/newtitle.ppm"
			mv "$outdir/newtitle.ppm" "$outdir/slide_$i.ppm" 
			subtitle[$i]=''  # set subtitle to nothing so we don't get a subtitle
		fi
		cp "$outdir/slide_$i.ppm" "$outdir/temp_slideshow_image.ppm"
		encode
		write_chap=1
	elif [ "$file" == 'musictitle' ] ; then
		## add a music-video style title page
		## format is:
		## musictitle:duration:subtitle:MusicTitle:MusicArtist;MusicAlbum
		echo "[dvd-slideshow] Making musictitle slide:"
		Title="Title: ${effect1[$i]}"
		Artist="Artist: `echo ${effect1_params[$i]} | awk -F';' '{print $1}'`"
		Album="Album: `echo ${effect1_params[$i]} | awk -F';' '{print $2}'`"
		echo "[dvd-slideshow] $Title $Artist $Album"
		# make the background (black) picture:
		convert -size "$resolution" xc:black -type TrueColor \
			-depth 8 "$outdir"/slideshow_background.ppm
		# draw text:
		convert -depth 8 -size $resolution -quality 100 xc:transparent \
			-pointsize $subtitle_font_size -gravity SouthWest $font \
			-draw "fill white text 80,200 \"$Title\"" \
			-draw "fill white text 80,150 \"$Artist\"" \
			-draw "fill white text 80,100 \"$Album\"" "$outdir/dvd_title.png"
		composite -type TrueColor -depth 8 -quality 100 \
			"$outdir/dvd_title.png" "$outdir/slideshow_background.ppm" "$outdir/slide_$i.ppm"
		cp "$outdir/slide_$i.ppm" "$outdir/temp_slideshow_image.ppm"
#		subtitle[$i]=''  # set subtitle to nothing so we don't get a subtitle
		## note that ppmtoy4m needs a "TrueColor" type image from ImageMagick
		## instead of a "PseudoClass" image
		encode
		write_chap=1
	elif [ "${image_file[$i]}" -eq 1 ] && [ -z "${effect1[$i]}" ] ; then  ############################
		## use real jpeg.  resize image first:
		## now, due to crossfade, the slide_$i.ppm may already exist.  check for it?
#		echo "[dvd-slideshow] Processing NORMAL picture, no effects"
#		echo "file=$file"
		convert -resize $resolution -type TrueColor -depth 8 -quality 100 \
			"$file" "$outdir"/temp_slideshow_image.ppm		
		composite -gravity center -type TrueColor -depth 8 -quality 100 \
		"$outdir"/temp_slideshow_image.ppm "$outdir/slideshow_background.ppm" "$outdir/slide_$i.ppm"
		encode
		write_chap=1
		new_vob=1
		## write out a test browsable image:
#		composite -dissolve 25 "$outdir"/right_arrow.png "$outdir/slide_$i.ppm" "$outdir/temp.ppm"
#		composite -dissolve 25 "$outdir"/left_arrow.png "$outdir/temp.ppm" "$outdir/temp.ppm"
#		composite -dissolve 25 "$outdir"/up_arrow.png "$outdir/temp.ppm" "$outdir/slide_nav_$di.ppm"
	
#		echo "browse_num=$browse_num"
		fixedslide[$browse_num]="slide_nav_$di.ppm"	## set up for output array
		browse_num=$(( $browse_num + 1 ))
	elif [ "${image_file[$i]}" -eq 1 ] && [ "${effect1[$i]}" == 'crop' ] ; then  ######################
		## use real jpeg.  resize image first:
		echo "[dvd-slideshow] Cropping picture"
		x0=`echo "${effect1_params[$i]}" | awk -F';' '{print $1}' | awk -F',' '{print $1}'`
		y0=`echo "${effect1_params[$i]}" | awk -F';' '{print $1}' | awk -F',' '{print $2}'`
		x1=`echo "${effect1_params[$i]}" | awk -F';' '{print $2}' | awk -F',' '{print $1}'`
		y1=`echo "${effect1_params[$i]}" | awk -F';' '{print $2}' | awk -F',' '{print $2}'`
		x_width=$(( $x1 - $x0 )) ; y_height=$(( $y1 - $y0 ))
		echo "[dvd-slideshow] $x0,$y0 ; $x1,$y1 width=$x_width height=$y_height"
		convert -crop "$x_width"x"$y_height+$x0+$y0" -resize $resolution -type TrueColor -depth 8 \
			"${file}" "$outdir"/temp_slideshow_image.ppm		
		composite -gravity center -type TrueColor -depth 8 -quality 100 \
		"$outdir"/temp_slideshow_image.ppm "$outdir/slideshow_background.ppm" "$outdir/slide_$i.ppm"
		encode
		write_chap=1
		new_vob=1
	elif [ "$file" == 'fadein' ] ; then
		## ok, let's copy the background and just fade the foreground:
		## check to make sure the next slide is an image:
#		echo "[dvd-slideshow] Doing fadeIN...."
		if [ "${image_file[$(($i+1))]}" -eq 0 ] ; then
			## next line is not an image!
			echo '[dvd-slideshow] ERROR:  You can only fadein before a real image, '
			echo '[dvd-slideshow]	      not "title", "background", "fadeout", audio etc.'
			echo '[dvd-slideshow]	      Fix this in your input file and re-run dvd-slideshow.'
			exit 1
		fi
		## we need to prepare the NEXT image now:
		convert -resize $resolution -type TrueColor -depth 8 -quality 100 \
			"${image[$(($i+1))]}" "$outdir"/temp_slideshow_image.ppm		
		[ "$frames" -lt 45 ] && stepsize=1 || stepsize=2 
		if [ "$low_quality" -eq 1 ] ; then
			stepsize=5
		fi
		echo -n "[dvd-slideshow] frame="
		## do two frames each loop so it's faster?
		for fr in `seq 1 $stepsize $frames`; do
			dj=`addzeros $fr`
			percent=$(( 100 * $fr / $frames ))
			[ $percent -lt 10 ] && percent_st="0$percent" || percent_st=$percent
			echo -n "$dj $percent_st%"
			composite -gravity center -type TrueColor -depth 8 -dissolve $percent \
			"$outdir/temp_slideshow_image.ppm" "$outdir/slideshow_background.ppm" "$outdir/fade_$dj.ppm"
			extracopies
			echo -ne "\b\b\b\b\b\b\b\b"
		done
		echo
		encode_fade
		rm "$outdir"/fade_????.ppm
	elif [ "$file" == 'fadeout' ] ; then  #############################################
		## ok, let's copy the background and just fade the foreground:
		## number of frames to render is $frames
#		echo "[dvd-slideshow] Doing fadeOUT to background...."
		[ "$frames" -lt 45 ] && stepsize=1 || stepsize=2 
		if [ "$low_quality" -eq 1 ] ; then
			stepsize=5
		fi
		echo -n "[dvd-slideshow] frame="
		for fr in `seq 1 $stepsize $frames`; do
			dj=`addzeros $fr`
			percent=$(( 100 - 100 * $fr / $frames ))
			[ $percent -lt 10 ] && percent_st="0$percent" || percent_st=$percent
			echo -n "$dj $percent_st%"
			composite -gravity center -type TrueColor -depth 8 -dissolve $percent \
			"$outdir/temp_slideshow_image.ppm" "$outdir/slideshow_background.ppm" "$outdir/fade_$dj.ppm"
			extracopies
			echo -ne "\b\b\b\b\b\b\b\b"
		done
		echo
		encode_fade
		rm "$outdir"/fade_????.ppm
	elif [ "$file" == 'crossfade' ] ; then  #############################################
		## ok, for crossfades, we need to fade both the foreground and background.
		## check to make sure the next slide is an image:
		if [ ! -f "${image[$(($i+1))]}" ] ; then
			## next line is not an image!
			echo '# ERROR:  You can only fadein before a real image, '
			echo '#	      not "title", "background", "fadeout", etc.'
			echo '#	      Fix this in your input file and re-run dvd-slideshow.'
		fi
#		echo "[dvd-slideshow] Doing CROSSfade...."
#		echo "i=$i lastimage=${image[$(($i-1))]} nextimage=${image[$(($i+1))]}"
		## last slide is slide_$(($i-1)).ppm (already rendered)
		## we need to prepare the NEXT image now:
		convert -resize $resolution -type TrueColor -depth 8 \
			"${image[$(($i+1))]}" "$outdir"/temp_slideshow_image.ppm		
		composite -gravity center -type TrueColor -depth 8 \
		"$outdir"/temp_slideshow_image.ppm "$outdir/slideshow_background.ppm" "$outdir/slide_$(($i+1)).ppm"
		[ "$frames" -lt 45 ] && stepsize=1 || stepsize=2 
		if [ "$low_quality" -eq 1 ] ; then
			stepsize=5
		fi
		echo -n "[dvd-slideshow] frame="
		## do two frames each loop so it's faster?
		for fr in `seq 1 $stepsize $frames`; do
			dj=`addzeros $fr`
			percent=$(( 100 * $fr / $frames ))
			[ $percent -lt 10 ] && percent_st="0$percent" || percent_st=$percent
			echo -n "$dj $percent_st%"
			composite -gravity center -type TrueColor -depth 8 -dissolve $percent \
			"$outdir/slide_$(($i+1)).ppm" "$outdir/slide_$(($i-1)).ppm" "$outdir/fade_$dj.ppm"
			frame2=$(( $fr + 1 )) # copy another slide
			dj2=`addzeros $frame2`
#			[ $frame2 -lt 1000 ] && dj2="0$frame2" || dj2=$frame2
#			[ $frame2 -lt 100 ] && dj2="00$frame2" || dj2=$dj2
#			[ $frame2 -lt 10 ] && dj2="000$frame2" || dj2=$dj2
			extracopies
			echo -ne "\b\b\b\b\b\b\b\b"
		done
		echo
		encode_fade
		rm "$outdir"/fade_????.ppm
	elif [ "${effect1[$i]}" == 'kenburns' ] ; then
		## Ken Burns effect from starting point to ending point
		echo "[dvd-slideshow] Doing KenBurns Effect...."
		echo "[dvd-slideshow] This is very slow since it needs to work in all cases."
		echo "[dvd-slideshow] Use the scroll options if you are just scrolling left/right."
		# x0,y0 is the top left corner of the image
		# x1,y1 is the bottom right corner of the image
		# xs0,ys1 is the starting point for the top left corner, etc
		# xe1,ye1 is the ending point for the bottom right corner
		# textfile format is:  
		# file:duration:comment:kenburns:xs0,ys0;xs1,ys1;xe0,ye0;xe1,ye1
#		echo "[dvd-slideshow] params=${effect1[$i]}"
		xs0=`echo "${effect1_params[$i]}" | awk -F';' '{print $1}' | awk -F',' '{print $1}'`
		ys0=`echo "${effect1_params[$i]}" | awk -F';' '{print $1}' | awk -F',' '{print $2}'`
		xs1=`echo "${effect1_params[$i]}" | awk -F';' '{print $2}' | awk -F',' '{print $1}'`
		ys1=`echo "${effect1_params[$i]}" | awk -F';' '{print $2}' | awk -F',' '{print $2}'`
		# ending point:
		xe0=`echo "${effect1_params[$i]}" | awk -F';' '{print $3}' | awk -F',' '{print $1}'`
		ye0=`echo "${effect1_params[$i]}" | awk -F';' '{print $3}' | awk -F',' '{print $2}'`
		xe1=`echo "${effect1_params[$i]}" | awk -F';' '{print $4}' | awk -F',' '{print $1}'`
		ye1=`echo "${effect1_params[$i]}" | awk -F';' '{print $4}' | awk -F',' '{print $2}'`
		echo "[dvd-slideshow] params=$xs0,$ys0 ; $xs1,$ys1 ; $xe0,$ye0 ; $xe1,$ye1"
		xs_width=$(( $xs1 - $xs0 )) ; ys_height=$(( $ys1 - $ys0 ))
		xe_width=$(( $xe1 - $xe0 )) ; ye_height=$(( $ye1 - $ye0 ))
		## get smallest size of image during effect to know how to rescale:
		min_width=`min $xs_width $xe_width`	
		min_height=`min $xs_height $xe_height`	
#		echo "min_width=$min_width min_height=$min_height"
		## crop the image to speed things up:
		xc0=`min $xs0 $xe0`; xc1=`max $xs1 $xe1`	
		yc0=`min $ys0 $ye0`; yc1=`max $ys1 $ye1`	
		xc_width=$(( $xc1 - $xc0 )) ; yc_height=$(( $yc1 - $yc0 ))
#		echo "crop_params=$xc0,$yc0 ; $xc1,$yc1"
#		echo "size=$xc_width,$yc_height"
		## do some error checking to make sure the effect parameters are ok?
		## first, rescale the initial picture so the resolution if fine enough
		## remember output resolution is $width x $height
		## I figure we want about twice that resolution at all times?
		factor=1  #  if effect seems "choppy", increase factor.  Slows down processing.
		factor_percent=$(( 100* $factor))  # in percent
		convert -crop "$xc_width"x"$yc_height"+$xc0+$yc0 -resize "$factor_percent"% \
		-depth 8 -quality 100 "${file}" "$outdir"/temp_slideshow_image_scaled.ppm		
		## now the image is cropped to be the large size and resized by 2
		## reset / change the start and end points: (coordiate transformation by xe0,ye0
		xs0=$(( ($xs0-$xc0) * $factor )); ys0=$(( ($ys0-$yc0) * $factor )); 
		xs1=$(( ($xs1-$xc0) * $factor )); ys1=$(( ($ys1-$yc0) * $factor )); 
		xe0=$(( ($xe0-$xc0) * $factor )); ye0=$(( ($ye0-$yc0) * $factor )); 
		xe1=$(( ($xe1-$xc0) * $factor )); ye1=$(( ($ye1-$yc0) * $factor )); 
#		echo "new params=$xs0,$ys0 ; $xs1,$ys1 ; $xe0,$ye0 ; $xe1,$ye1"

		[ "$frames" -lt 45 ] && stepsize=1 || stepsize=2 
		stepsize=1
		if [ "$low_quality" -eq 1 ] ; then
			stepsize=5
		fi
		echo -n "[dvd-slideshow] frame="
		for fr in `seq 1 $stepsize $frames`; do
			dj=`addzeros $fr`
			x0=$(( $xs0 + $(($xe0-$xs0)) * $fr / $frames ))
			y0=$(( $ys0 + $(($ye0-$ys0)) * $fr / $frames ))
			x1=$(( $xs1 + $(($xe1-$xs1)) * $fr / $frames ))
			y1=$(( $ys1 + $(($ye1-$ys1)) * $fr / $frames ))
			x_width=$(( $x1 - $x0 )) ; y_height=$(( $y1 - $y0 ))
			echo -n "$dj"
#			echo "$dj x_width=$x_width y_height=$y_height"
			## this would be way faster if we didn't have to resize every time.
			convert -crop "$x_width"x"$y_height"+$x0+$y0 -resize $resolution -type TrueColor \
			-depth 8 "$outdir/temp_slideshow_image_scaled.ppm" "$outdir"/temp_slideshow_image.ppm		
#			-depth 8 -quality 100 "${file}" "$outdir"/temp_slideshow_image.ppm		
			composite -gravity center -type TrueColor -depth 8 "$outdir/temp_slideshow_image.ppm" \
				"$outdir/slideshow_background.ppm" "$outdir/fade_$dj.ppm"
			extracopies
			echo -ne "\b\b\b\b"
		done
		echo
		encode_fade
		## just in case we want to fade out or crossfade, we need to save the last image:
		cp "$outdir/fade_$dj.ppm" "$outdir/slide_$i.ppm"
		rm "$outdir"/fade_????.ppm
	elif [ "${effect1[$i]}" == 'scroll' ] ; then
		echo "[dvd-slideshow] Doing scroll effect"
		## assume a panorama image?  use full image height.
		# textfile format is:  
		# file:duration:comment:scrollright

		## resize the image first to speed things up:
		## remember output resolution is $width x $height
		convert -resize x$height -depth 8 "${file}" \
			"$outdir"/temp_slideshow_image_scaled.ppm		
		# now the image is scaled so the height is correct
		image_width=`identify "$outdir/temp_slideshow_image_scaled.ppm" | cut -d ' ' -f 3 | cut -d 'x' -f 1`	
		image_height=`identify "$outdir/temp_slideshow_image_scaled.ppm" | cut -d ' ' -f 3 | cut -d 'x' -f 2 | cut -d '+' -f 1`	
		echo "[dvd-slideshow] image_width=$image_width image_height=$image_height"
		if [ "${effect1_params[$i]}" == 'right' ] ; then
			echo "[dvd-slideshow] Doing scroll right effect"
			xs0=0 ; ys0=0 # scroll right
			xs1="$image_width"; ys1="$image_height"
			xe0=$(( $image_width - $width )) ; ye0=0
			xe1="$image_width"; ye1="$image_height" # y doesn't change
		elif [ "${effect1_params[$i]}" == 'left' ] ; then
			echo "[dvd-slideshow] Doing scroll left effect"
			xe0=0 ; ye0=0 # scroll left
			xe1="$image_width"; ye1="$image_height"
			xs0=$(( $image_width - $width )) ; ys0=0
			xs1="$image_width"; ys1="$image_height" # y doesn't change
		else
			echo "[dvd-slideshow] ERROR: bad effect parameters ${effect1_params[$i]}"
			exit 1
		fi
		echo "[dvd-slideshow] params=$xs0,$ys0 ; $xs1,$ys1 ; $xe0,$ye0 ; $xe1,$ye1"
		[ "$frames" -lt 90 ] && stepsize=1 || stepsize=2 
		stepsize=1
		if [ "$low_quality" -eq 1 ] ; then
			stepsize=5
		fi
		echo -n "[dvd-slideshow] "
		for fr in `seq 1 $stepsize $frames`; do
			dj=`addzeros $fr`
			x0=$(( $xs0 + $(($xe0-$xs0)) * $fr / $frames ))
			y0=$(( $ys0 + $(($ye0-$ys0)) * $fr / $frames ))
			x1=$(( $xs1 + $(($xe1-$xs1)) * $fr / $frames ))
			y1=$(( $ys1 + $(($ye1-$ys1)) * $fr / $frames ))
			pan_rate=$((  ($xe0-$xs0) / $frames ))
#			x_width=$(( $x1 - $x0 )) ; y_height=$(( $y1 - $y0 ))
			echo -n "$dj"
#			echo "$dj $pan_rate width=$width height=$height x0=$x0 y0=$y0"
			# background makes no sense since it's the full size of the screen
			pnmcut $x0 $y0 $width $height "$outdir/temp_slideshow_image_scaled.ppm" > "$outdir/fade_$dj.ppm"
#			convert -crop "$width"x"$height"+$x0+$y0 -type TrueColor \
#			-depth 8 "$outdir/temp_slideshow_image_scaled.ppm" "$outdir"/temp_slideshow_image.ppm		
#			composite -gravity center -type TrueColor -depth 8 "$outdir/temp_slideshow_image.ppm" \
#				"$outdir/slideshow_background.ppm" "$outdir/fade_$dj.ppm"
			extracopies
			echo -ne "\b\b\b\b"
		done
		echo
		encode_fade
		## just in case we want to fade out or crossfade, we need to save the last image:
		cp "$outdir/fade_$dj.ppm" "$outdir/slide_$i.ppm"
		rm "$outdir"/fade_????.ppm
	elif [ "$file" == 'black' ] ; then  ###############################################
		## use plain black background with no picture
		## phase out "black" tag.  Use background:::black instead
		convert -size "$width"'x'"$height" xc:black -type TrueColor -depth 8 $outdir/slide_$i.ppm
		encode
	elif [ "$file" == 'background' ] ; then  ###############################################
		if [ -f "${effect1[$i]}" ] ; then # if effect is a background file
			bgfile="${effect1[$i]}"
			echo "[dvd-slideshow] using background image ${bgfile}"
			convert -depth 8 "${bgfile}" -resize x"$height" -bordercolor black -border "$width"x240 \
			-gravity center -crop "$width"x"$height"'+0+0!' \
			-quality 100 $outdir/slideshow_background.ppm
		elif [ "${effect1[$i]}" == 'black' ] ; then
			bgfile="${effect1[$i]}"
			## use plain black background with no picture
			convert -size "$width"'x'"$height" xc:black -type TrueColor -depth 8 $outdir/slideshow_background.ppm
		fi
		if [ "${duration[$i]}" -ne 0 ] ; then  
			## user wants to actually display background for a given time
			echo "[dvd-slideshow] Displaying background image ${bgfile}"
			cp "$outdir/slideshow_background.ppm" "$outdir/slide_$i.ppm"
			encode
		fi
	elif [ "${audio_file[$i]}" -eq 1 ] ; then  ###############################################
		if [ "${audio_track[$i]}" -eq 1 ] ; then
			audio_1[$i_audio]="$file"
			audio1_effect1[$i_audio]="${effect1[$i]}"
			audio1_effect1_params[$i_audio]="${effect1_params[$i]}"
			audio1_effect2[$i_audio]="${effect2[$i]}"
			audio1_effect2_params[$i_audio]="${effect2_params[$i]}"
			it="$i_audio"
			i_audio=$(( $i_audio + 1 ))
		elif [ "${audio_track[$i]}" -eq 2 ] ; then
			audio_2[$j_audio]="$file"
			audio2_effect1[$j_audio]="${effect1[$i]}"
			audio2_effect1_params[$j_audio]="${effect1_params[$i]}"
			audio2_effect2[$j_audio]="${effect2[$i]}"
			audio2_effect2_params[$j_audio]="${effect2_params[$i]}"
			it="$j_audio"
			j_audio=$(( $j_audio + 1 ))
		else
			echo "[dvd-slideshow] ERROR: Bad audio track number."
			exit 1
		fi
		track="${audio_track[$i]}"
#		duration[$i]=0  # set duration to zero (should already be set to zero!)
		suffix=`echo "$file" | awk -F. '{print tolower($NF)}'`
		if [ "$suffix" == "mp3" ] ; then
			echo "[dvd-slideshow] decoding mp3 audio... we will splice it later."
			lame --decode "$file" "$outdir/audio$track"_"$it.wav"
		elif [ "$suffix" == "ogg" ] ; then
			echo "[dvd-slideshow] decoding ogg audio... we will splice it later."
			oggdec -o "$outdir/audio$track"_"$it.wav" "$file"
		elif [ "$suffix" == "wav" ] ; then
			echo "[dvd-slideshow] processing wav audio... we will splice it later."
			cp "$file" "$outdir/audio$track"_"$it.wav"
		elif [ "$file" == 'silence' ]; then
			echo "[dvd-slideshow] creating silent audio track... we will splice it later."
			sox -t raw -s -w -c 2 -r 48000 /dev/zero -t wav -c 2 -r 48000 \
				"$outdir/audio$track"_"$it.wav" trim 0 1
		else
			echo "[dvd-slideshow] ERROR:  Unknown audio file format.  Must be .mp3, .ogg, .wav, or silence"
		fi
		## now set the starting and ending point of this audio track:
		echo "audio_track=${audio_track[$i]} "
		if [ "${audio_track[$i]}" -eq 1 ] ; then
			audio1_start[$it]="$slide_start_time"   # in ms
			## set ending point of the audio track:
			if [ "$it" -gt 0 ] ; then # not first audio track
				audio1_end[$(($it-1))]="$slide_end_time"   # in ms from last slide
			fi
		elif [ "${audio_track[$i]}" -eq 2 ] ; then
			audio2_start[$it]="$slide_start_time"   # in ms
			## set ending point of the audio track:
			if [ "$it" -gt 0 ] ; then
				audio2_end[$(($it-1))]="$slide_end_time"   # in ms from last slide
			fi
		fi
		echo "[dvd-slideshow] track=${audio_track[$i]} audio_start=$slide_start_time audio_end=$slide_end_time"
		sox "$outdir/audio$track"_"$it.wav" -e stat 2> trash.txt 
		## need to fix this so it's accurate to 0.01 sec, not just 1 sec
		## this will get floor(time) now.
		song_length=`cat trash.txt | grep 'Length (seconds):' | awk -F: '{print $2}' | awk -F. '{print $1}'`
		song_length_hms=`hms "$(( 100 * $song_length))"`
		song_length_ms="$(( 100 * $song_length))"
	else
		echo "[dvd-slideshow] Unrecognized or malformed line in your input file:"
		echo "[dvd-slideshow] $file effect=${effect1[$i]} effect_params=${effect1_params[$i]}"
		echo "Fix it and try again."
		exit 1
	fi
	
	## calculate the time point that we're at:
	total_slideshow_frames=$(( $total_slideshow_frames + $frames ))
	slide_end_frame="$total_slideshow_frames"
	slide_end_time=$(( $slide_end_frame * 100 * 100 / $frames_per_sec ))  ## in hundreths of a second
	slide_end_hms=`hms "$slide_end_time"`
	if [ "${audio_file[$i]}" -eq 0 ] && [ $debug -eq 1 ]; then 
		echo "[dvd-slideshow] end_frame_number=$slide_end_frame end_time=$slide_end_hms"
	fi

	## setup the chapter markers at the start of each picture:
	if [ "$write_chap" -eq 1 ] ; then
		chapter_marker="$(( ( ($slide_start_time / 100) + 1 ) * 100 ))" ## round up chapter marker
		chaps[$this_chap]=`hms "$chapter_marker"`
		this_chap=$(($this_chap + 1))
		write_chap=0
	fi

	## now make a tiny thumbnail for the menu?:
	# convert -depth 8 -resize $thumb_resolution -quality 100 "${file}" temp_slideshow_thumbnail.png
	
	## now, create the xml file to pass to spumux
	if [ "$v" -eq 0 ]; then
		echo '<subpictures>' > "$outdir/$slideshow_name".spumux
		echo '	<stream>' >> "$outdir/$slideshow_name".spumux
	fi	

	## add the subtitle track if it exists:
	if [ -n "${subtitle[$i]}" ] ; then
		## let's check for a config file first?

		## fix any special characters:
		subtitle[$i]=`echo "${subtitle[$i]}" | sed -e 's/"/\\\\"/g'`
		## make the subtitle break up into up to 4 different lines?
		font_width=15  # actually it's 14.4, but this should give us some margin
#		characters=`echo "${subtitle[$i]}" | wc -c`
		characters="${#subtitle[$i]}"
		line_width=$(( $font_width * $characters ))
#		echo "characters=$characters linewidth=$line_width"
		if [ "$line_width" -gt 720 ] ; then
			## need to split the line:
#			echo "splitting line..."
			characters2=$(( $characters / 2 + 1))
			# try cutting in the middle:
			subtitle1="${subtitle[$i]:0:$characters2}"
			subtitle2="${subtitle[$i]:$characters2:$characters2}" 
			# now re-join a potential broken word:
			if [ "${subtitle[$i]:$characters2:1}" != ' ' ] ; then	
				# break occurred in the middle of a word. re-join the word:
				wordend=`echo "$subtitle2" | awk '{print $1}'`
				subtitle1="$subtitle1$wordend"
				subtitle2="${subtitle2#$wordend }"
			fi
		else
			subtitle1=""
			subtitle2="${subtitle[$i]}"
		fi

#		echo "[dvd-slideshow] subtitle1=$subtitle1"
#		echo "[dvd-slideshow] subtitle2=$subtitle2"
		has_subtitles=1
        	convert -size $resolution xc:gray50 $font -pointsize $subtitle_font_size \
		-gravity South -fill gray99 -stroke black -strokewidth 3 \
		-draw "text 0,105 \"$subtitle1\"" -draw "text 0,75 \"$subtitle2\"" \
		-stroke none \
		-draw "text 0,105 \"$subtitle1\"" -draw "text 0,75 \"$subtitle2\"" \
		-quality 100 "$outdir/subtitle.png"
		## imagemagick can't seem to create a color depth less than 8 bit, so we need to use NetPBM

		pngtopnm "$outdir/subtitle.png" | pnmdepth 3 \
		| pnmtopng -transparent "#7f7f7f" > "$outdir/subtitle_out.png"
		mv "$outdir/subtitle_out.png" "$outdir/subtitle_$i.png"

		## let's assume the subtitle stays on the whole duration
		## of the slide
		echo '		<spu start="'${slide_start_hms}'" end="'${slide_end_hms}'" image="'$outdir/subtitle_$i.png'">' >> "$outdir/${slideshow_name}".spumux
		echo '		</spu>' >> "$outdir/${slideshow_name}".spumux

	fi
	let i=$i+1
done

## write the bottom of the subpictures file:
if [ -f "$outdir/${slideshow_name}".spumux ]; then
	echo '	</stream>' >> "$outdir/${slideshow_name}".spumux
	echo '</subpictures>' >> "$outdir/${slideshow_name}".spumux
fi
echo "[dvd-slideshow]########################################"

##  now we need to cat the mpeg files together:
echo "[dvd-slideshow] Joining each mpeg..."
cat "$outdir"/slide_*.mpg > "$outdir/video.mpg"

## calculate total slideshow time:
#end_time=$(( $total_slideshow_frames * 100 / $frames_per_sec ))  ## in seconds
end_time="$slide_end_time"
end_hms="$slide_end_hms"

############################################################################
# AUDIO section...
##########################################################################
echo "[dvd-slideshow] Processing audio..."

## now do the audio for this slideshow ##########################
let i=1
total_audio_length=0
commandline_audio=0
if [ -n "${audio[0]}" ] ; then  ## command-line passed audio
	for file in "${audio[@]}"; do
		echo "[dvd-slideshow] Working on track 1 audio file $i $file"
		fade_in_time="300"
		fade_out_time="300"
		fade_in_hms=`hms "$fade_in_time"`
		fade_out_hms=`hms "$fade_out_time"`
		echo "[dvd-slideshow] fade_in_time=$fade_in_hms fade_out_time=$fade_out_hms"
#		audio_end="$end_time"	
#		audio_end_hms=`hms $(( $audio_end ))`
#		audio_start_hms="0"  # cannot modify starting point yet...

		suffix=`echo "$file" | awk -F. '{print tolower($NF)}'`
		track=1
		if [ "$suffix" == "mp3" ] ; then
			echo "[dvd-slideshow] decoding mp3 audio... we will splice it later."
			lame --decode "$file" "$outdir/audio$track"_"$i.wav"
		elif [ "$suffix" == "ogg" ] ; then
			echo "[dvd-slideshow] decoding ogg audio... we will splice it later."
			oggdec -o "$outdir/audio$track"_"$i.wav" "$file"
		elif [ "$suffix" == "wav" ] ; then
			echo "[dvd-slideshow] processing wav audio... we will splice it later."
			cp "$file" "$outdir/audio$track"_"$i.wav"
		else
			echo "[dvd-slideshow] ERROR:  Unknown audio file format.  Must be .mp3, .ogg, .wav, or silence"
		fi	
		sox "$outdir/audio1_$i.wav" -e stat 2> trash.txt 
		## need to fix this so it's accurate to 0.01 sec, not just 1 sec
		## this will get floor(time) now.
		song_length=`cat trash.txt | grep 'Length (seconds):' | awk -F: '{print $2}' | awk -F. '{print $1}'`
		rm trash.txt
		song_length_hms=`hms "$(( 100 * $song_length ))"`
		song_length_ms="$(( 100 * $song_length ))"
		total_audio_length="$(( $total_audio_length + $song_length_ms ))"
		echo "total_audio_length=$total_audio_length"
		## fade in by default... may change later
		sox -v 0.95 "$outdir/audio$track"_"$i.wav" -w -s -c 2 -r 48000 "$outdir/audio1_$i.raw" \
		fade t "$fade_in_hms" "$song_length_hms" "$fade_out_hms"
		let i=$i+1
		echo "[dvd-slideshow] ###############"
	done
	let i=$i+1
	## check to make sure the audio spans the video time:
	echo "end_time=$end_time hms=$end_hms"
	if [ "$total_audio_length" -lt "$end_time" ] ; then
		# video is longer than audio.  need to add silence to end.
		thetime_hms=`hms $(( $end_time - $total_audio_length + 100 ))` #plus 10 so sox actually crops.
		echo "[dvd-slideshow] Buffering end of audio file with silence for $thetime_hms"
		sox -t raw -s -w -c 2 -r 48000 /dev/zero -w -s -c 2 -r 48000 "$outdir/audio1_$i.raw" trim 0 "$thetime_hms"
	fi
	
	## cat all the audio files together: 
	ls "$outdir"/audio1_?.raw | xargs -n 1 cat | sox -t raw -w -s -c 2 -r 48000 - "$outdir/audio1.wav"
#	sox "$outdir/audio1.wav" -e stat 2> trash.txt 
	## need to fix this so it's accurate to 0.01 sec, not just 1 sec
	## this will get floor(time) now.
#	song_length=`cat trash.txt | grep 'Length (seconds):' | awk -F: '{print $2}' | awk -F. '{print $1}'`
#	rm trash.txt
#	song_length_hms=`hms "$(( 100 * $song_length))"`
#	song_length_ms="$(( 100 * $song_length))"
	## fade out at end of video:
	echo "End Time=$end_hms fade_out=$fade_out_hms"
	sox "$outdir/audio1.wav" "$outdir/audio_out.wav" fade t 0 "$end_hms" "$fade_out_hms"
	mv "$outdir/audio_out.wav" "$outdir/audio1.wav"

	## toolame is way faster! (3x in my test)
	it=`which toolame`
	if [ -n "$it" ] ; then
		echo "[dvd-slideshow] using toolame..."
		toolame -s 48 -b 224 "$outdir/audio1.wav" "$outdir/audio1.mp2" 
	else
		echo "[dvd-slideshow] using mp2enc"
		mp2enc -v $verbosity -b 224 -r 48000 -s -o "$outdir/audio1.mp2" < "$outdir/audio1.wav"
	fi
	commandline_audio=1
fi

## do audio track 1 first:
let i=0
if [ -z "${audio_1[0]}" ] && [ "$commandline_audio" -eq 0 ] ; then
	## no audio file passed on command line or txtfile.  use silence:
	audio_1[0]='silence'  # no duration needed
	echo "[dvd-slideshow] No audio files passed.  Using $end_hms silence."
	audio1_start=0 
	audio1_end="$end_time"
fi
if [ -n "${audio_1[0]}" ] ; then
	for file in "${audio_1[@]}"; do
		echo "[dvd-slideshow] Working on track 1 audio file $i $file"
		if [ -z "${audio1_effect1_params[$i]}" ] ; then
			fade_in_time="0"
		else
			fade_in_time="$(( ${audio1_effect1_params[$i]} * 100 ))" 
		fi
		if [ -z "${audio1_effect2_params[$i]}" ] ; then
			fade_out_time="0"
		else
			fade_out_time="$(( ${audio1_effect2_params[$i]} * 100 ))" 
		fi
		fade_in_hms=`hms "$fade_in_time"`
		fade_out_hms=`hms "$fade_out_time"`
		echo "[dvd-slideshow] fade_in_time=$fade_in_hms fade_out_time=$fade_out_hms"
		if [ -z "${audio1_end[$i]}" ] ; then
			## must be last audio track.  assume run til end
			audio1_end[$i]="$end_time"	
		fi
		echo "[dvd-slideshow] audio_start=`hms ${audio1_start[$i]}`. audio_end=`hms ${audio1_end[$i]}`."
		audio_end_ms=$(( ${audio1_end[$i]} - ${audio1_start[$i]} ))
		audio_end_hms=`hms $(( ${audio1_end[$i]} - ${audio1_start[$i]} ))`
		audio_start_hms="0"  # cannot modify starting point yet...
	
		if [ "$file" == 'silence' ]; then  
			echo "[dvd-slideshow] creating silence .wav file for $audio_end_hms"
			sox -t raw -s -w -c 2 -r 48000 /dev/zero -w -s -c 2 -r 48000 "$outdir"/audio1_$i.raw trim "0" "$audio_end_hms"
		else
			## file should only be wav format at this point since it was decoded before
			## all audio files are of the format $outdir/audio_1.wav
			# I found some "popping" in the audio for some tracks.
			# it turns out that this is caused by audio going
			# too low or too high and getting clipped.
			# reducing the volume a little should help.
			volume=0.95
			sox "$outdir/audio1_$i.wav" -e stat 2> trash.txt 
			## need to fix this so it's accurate to 0.01 sec, not just 1 sec
			## this will get floor(time) now.
			song_length=`cat trash.txt | grep 'Length (seconds):' | awk -F: '{print $2}' | awk -F. '{print $1}'`
			rm trash.txt
			song_length_hms=`hms "$(( 100 * $song_length))"`
			song_length_ms="$(( 100 * $song_length))"
			echo "[dvd-slideshow] original_audio_track_length=$song_length_hms"
	#		echo "[dvd-slideshow] audio_start_hms=$audio_start_hms audio_end_hms=$audio_end_hms"
			if [ "$song_length_ms" -lt "$audio_end_ms" ] ; then
				# video is longer than audio.  need to add silence to end.
				# fade only to the end of song length now, because we may have to add silence:
				sox -v 0.95 "$outdir/audio1_$i.wav" -w -s -c 2 -r 48000 "$outdir/audio1_$i.raw" \
				fade t "$fade_in_hms" "$song_length_hms" "$fade_out_hms"
				thetime_hms=`hms $(( $audio_end_ms - $song_length_ms + 100 ))` #plus 10 so sox actually crops.
				echo "[dvd-slideshow] Buffering end of audio file with silence for $thetime_hms"
				sox -t raw -s -w -c 2 -r 48000 /dev/zero -w -s -c 2 -r 48000 "$outdir/silence.raw" trim 0 "$thetime_hms"
				cat "$outdir/audio1_$i.raw" "$outdir/silence.raw" > "$outdir/audio.raw" 
				mv "$outdir/audio.raw" "$outdir/audio1_$i.raw"
				# hopefully there won't be many times where the audio needs to be buffered 
				# at the end, so we'll add one extra step to make the coding easier:
				sox -t raw -s -w -c 2 -r 48000 "$outdir/audio1_$i.raw" "$outdir/audio1_$i.wav"
				rm "$outdir"/silence.raw
			fi
			## fade in by default... may change later
			sox -v 0.95 "$outdir/audio1_$i.wav" -w -s -c 2 -r 48000 "$outdir/audio1_$i.raw" \
			fade t "$fade_in_hms" "$audio_end_hms" "$fade_out_hms"
			if [ $i -eq 0 ] && [ "${audio1_start[$i]}" -ne 0 ] ; then
				## buffer beginning with silence:
				thetime_hms=`hms "${audio1_start[$i]}"`
				echo "[dvd-slideshow] Buffering beginning of audio file with silence for $thetime_hms"
				sox -t raw -s -w -c 2 -r 48000 /dev/zero -w -s -c 2 -r 48000 "$outdir/silence.raw" trim 0 "$thetime_hms"
				cat "$outdir"/silence.raw "$outdir/audio1_$i.raw" > "$outdir/audio.raw" 
				mv "$outdir/audio.raw" "$outdir/audio1_$i.raw"
				rm "$outdir"/silence.raw
			fi
		fi
		let i=$i+1
		let v=$v+1
		echo "[dvd-slideshow] ###############"
	done
		
	## cat all the audio files together: 
	ls "$outdir"/audio1_?.raw | xargs -n 1 cat | sox -t raw -w -s -c 2 -r 48000 - "$outdir/audio1.wav"
	## toolame is way faster! (3x in my test)
	it=`which toolame`
	if [ -n "$it" ] ; then
		echo "[dvd-slideshow] using toolame..."
		toolame -s 48 -b 224 "$outdir/audio1.wav" "$outdir/audio1.mp2" 
	else
		echo "[dvd-slideshow] using mp2enc"
		mp2enc -v $verbosity -b 224 -r 48000 -s -o "$outdir/audio1.mp2" < "$outdir/audio1.wav"
	fi
fi
		
#################################################################
## now do this all again for audio track number 2:
i=0
if [ -n "${audio_2[0]}" ] ; then
	## audio track is being used
	for file in "${audio_2[@]}"; do
		echo "[dvd-slideshow] Working on track 2 audio file $i $file"
	#	audio_2[$i_audio]="$file"
		if [ -z "${audio2_effect1_params[$i]}" ] ; then
			fade_in_time="0"
		else
			fade_in_time="$(( ${audio2_effect1_params[$i]} * 100 ))" 
		fi
		if [ -z "${audio2_effect2_params[$i]}" ] ; then
			fade_out_time="0"
		else
			fade_out_time="$(( ${audio2_effect2_params[$i]} * 100 ))" 
		fi
		fade_in_hms=`hms "$fade_in_time"`
		fade_out_hms=`hms "$fade_out_time"`
		echo "[dvd-slideshow] fade_in_time=$fade_in_hms fade_out_time=$fade_out_hms"
		echo "[dvd-slideshow] audio_start=`hms ${audio2_start[$i]}` audio_end=`hms ${audio2_end[$i]}`"
		if [ -z "${audio2_end[$i]}" ] ; then
			## must be last audio track.  assume run til end
			audio2_end[$i]="$end_time"	
		fi
		audio_end_ms=$(( ${audio2_end[$i]} - ${audio2_start[$i]} ))
		audio_end_hms=`hms $(( ${audio2_end[$i]} - ${audio2_start[$i]} ))`
		audio_start_hms="0"  # cannot modify starting point yet...

		if [ "$file" == 'silence' ]; then  
			echo "[dvd-slideshow] creating silence .wav file for $audio_end_hms"
			sox -t raw -s -w -c 2 -r 48000 /dev/zero -w -s -c 2 -r 48000 "$outdir"/audio2_$i.raw trim "0" "$audio_end_hms"
		else
			## file should only be wav format at this point since it was decoded before
			## all audio files are of the format $outdir/audio_2.wav
			# I found some "popping" in the audio for some tracks.
			# it turns out that this is caused by audio going
			# too low or too high and getting clipped.
			# reducing the volume a little should help.
			volume=0.95
			sox "$outdir/audio2_$i.wav" -e stat 2> trash.txt 
			## need to fix this so it's accurate to 0.01 sec, not just 1 sec
			## this will get floor(time) now.
			song_length=`cat trash.txt | grep 'Length (seconds):' | awk -F: '{print $2}' | awk -F. '{print $1}'`
			rm trash.txt
			song_length_hms=`hms "$(( 100 * $song_length))"`
			song_length_ms="$(( 100 * $song_length))"
			echo "[dvd-slideshow] original_audio_track_length=$song_length_hms"
#			echo "[dvd-slideshow] audio_start_hms=$audio_start_hms audio_end_hms=$audio_end_hms"
			if [ "$song_length_ms" -lt "$audio_end_ms" ] ; then
				# video is longer than audio.  need to add silence to end.
				# fade only to the end of song length now, because we may have to add silence:
				sox -v 0.95 "$outdir/audio2_$i.wav" -w -s -c 2 -r 48000 "$outdir/audio2_$i.raw" \
				fade t "$fade_in_hms" "$song_length_hms" "$fade_out_hms"
				thetime_hms=`hms $(( $audio_end_ms - $song_length_ms + 100 ))` #plus 10 so sox actually crops.
				echo "[dvd-slideshow] Buffering end of audio file with silence for $thetime_hms"
				sox -t raw -s -w -c 2 -r 48000 /dev/zero -w -s -c 2 -r 48000 "$outdir/silence.raw" trim 0 "$thetime_hms"
				cat "$outdir/audio2_$i.raw" "$outdir/silence.raw" > "$outdir/audio.raw" 
				mv "$outdir/audio.raw" "$outdir/audio2_$i.raw"
				# hopefully there won't be many times where the audio needs to be buffered 
				# at the end, so we'll add one extra step to make the coding easier:
				sox -t raw -s -w -c 2 -r 48000 "$outdir/audio2_$i.raw" "$outdir/audio2_$i.wav"
				rm "$outdir"/silence.raw
			fi
			## fade in by default... may change later
			sox -v 0.95 "$outdir/audio2_$i.wav" -w -s -c 2 -r 48000 "$outdir/audio2_$i.raw" \
			fade t "$fade_in_hms" "$audio_end_hms" "$fade_out_hms"
			if [ $i -eq 0 ] && [ "${audio2_start[$i]}" -ne 0 ] ; then
				## buffer beginning with silence:
				thetime_hms=`hms "${audio2_start[$i]}"`
				echo "[dvd-slideshow] Buffering beginning of audio file with silence for $thetime_hms"
				sox -t raw -s -w -c 2 -r 48000 /dev/zero -w -s -c 2 -r 48000 "$outdir/silence.raw" trim 0 "$thetime_hms"
				cat "$outdir"/silence.raw "$outdir/audio2_$i.raw" > "$outdir/audio.raw" 
				mv "$outdir/audio.raw" "$outdir/audio2_$i.raw"
				rm "$outdir"/silence.raw
			fi
		fi
		let i=$i+1
		echo "[dvd-slideshow] ###############"
	done
	## cat all the audio files together: 
	ls "$outdir"/audio2_?.raw | xargs -n 1 cat | sox -t raw -w -s -c 2 -r 48000 - "$outdir/audio2.wav"
	
	## toolame is way faster! (3x in my test)
	it=`which toolame`
	if [ -n "$it" ] ; then
		echo "[dvd-slideshow] using toolame..."
		toolame -s 48 -b 224 "$outdir/audio2.wav" "$outdir/audio2.mp2" 
	else
		echo "[dvd-slideshow] using mp2enc"
		mp2enc -v $verbosity -b 224 -r 48000 -s -o "$outdir/audio2.mp2" < "$outdir/audio2.wav"
	fi
fi	
	
	
echo "[dvd-slideshow]########################################"
echo "[dvd-slideshow] Multiplexing audio and video. Some sequence marker warnings here"
echo "[dvd-slideshow] may mean that the dvd will not play or be skippy for some people?"
echo "[dvd-slideshow] maybe we should try mpeg3cat?"

## now multiplex the audio and video:
## -M option is important:  it generates a "single" output file instead of "single-segement" ones
## if you don't use -M, the dvdauthor command will fail!
if [ -n "${audio_2[0]}" ] ; then
	mplex -v $verbosity -M -f 8 -o "$outdir/${slideshow_name}.mpg" "$outdir/video.mpg" "$outdir"/audio1.mp2 "$outdir"/audio2.mp2
else
	mplex -v $verbosity -M -f 8 -o "$outdir/${slideshow_name}.mpg" "$outdir/video.mpg" "$outdir"/audio1.mp2
fi

verbosity=0
## now run spumux only if the png was generated:
if [ "$has_subtitles" -eq 1 ] ; then   
	spumux -m dvd -v $verbosity -s 0 -P "$outdir/${slideshow_name}".spumux < "$outdir/${slideshow_name}.mpg" > "$outdir/tmp.mpg"
	mv "$outdir/tmp.mpg" "$outdir/${slideshow_name}.mpg"
else
#	rm "$outdir/${slideshow_name}".spumux
	echo "removing .spumux file"
fi

## build the chapters string for passing to dvdauthor:
a=0
echo "[dvd-slideshow] total chapters=${#chaps[@]}"
total_chapters="${#chaps[@]}"
new_total_chapters="$total_chapters"
factor=1  ;  mod=1
while [ $new_total_chapters -gt 99 ] ;  ## 99 chapters max
do
	factor=$(( 2 * $factor ))
	new_total_chapters=$(( $new_total_chapters / 2 ))	
done
if [ "$new_total_chapters" -ne "${#chaps[@]}" ] ; then
	echo "[dvd-slideshow] reduced total chapter markers to $new_total_chapters"
fi
for chap in "${chaps[@]}"; do
	if [ $a == 0 ] ; then  # no comma for first chapter
		## first chapter should always be at 0 time!
		chaps_string="0"
	else
		# only do every $factor chapters
		if [ "$mod" -eq "$factor" ] ; then
			chaps_string="$chaps_string,$chap"
			mod=1
		else
			mod=$(( $mod + 1 ))
		fi
	fi
	a=1
done
echo "[dvd-slideshow]##########################################"
echo "[dvd-slideshow] chapter markers at $chaps_string"
#echo "$chaps_string" > "$outdir/${slideshow_name}.chap"

if [ "$submenu" -eq 0 ] ; then
	## now, create the xml file to pass to dvdauthor
	#echo '<titleset>' > "$outdir/${slideshow_name}".xml
	#echo '	<titles>' >> "$outdir/${slideshow_name}".xml
	#echo '		<pgc>' > "$outdir/${slideshow_name}".xml
	echo '		<vob chapters="'$chaps_string'" file="'$outdir/${slideshow_name}.mpg'"  />' > "$outdir/${slideshow_name}".xml
	#echo '		</pgc>' >> "$outdir/${slideshow_name}".xml
	#echo '	</titles>' >> "$outdir/${slideshow_name}".xml
	#echo '</titleset>' >> "$outdir/${slideshow_name}".xml
	
	# cat "$outdir/${slideshow_name}.xml"
fi

# make browse menu:  ( NOT WORKING YET! )
if [ "$submenu" -eq 1 ] ; then
	sox -t raw -s -w -c 2 -r 48000 /dev/zero -c 2 -r 48000 "$outdir/audio.wav" trim 0 0.1
	it=`which toolame`
	if [ -n "$it" ] ; then
	        echo "[dvd-menu] # using toolame..."
	        toolame -s 48 -b 224 "$outdir/audio.wav" "$outdir/audio.mp2"
	else
	        echo "[dvd-menu] # using mp2enc"
	        mp2enc -v 0 -b 224 -r 48000 -s -o "$outdir/audio.mp2" < "$outdir/audio.wav"
	fi

	## create button masks:
	composite "$outdir"/right_arrow_mask.png "$outdir/up_arrow_mask.png" "$outdir/menu_mask_ur.png"
	composite "$outdir"/left_arrow_mask.png "$outdir/up_arrow_mask.png" "$outdir/menu_mask_lu.png"
	composite "$outdir"/left_arrow_mask.png "$outdir/menu_mask_ur.png" "$outdir/menu_mask_lur.png"
	top=355
	bottom=395
	
	## reduce mask colors:
	pngtopnm "$outdir/menu_mask_lur.png" | pnmdepth 3 | pnmtopng -transparent "#7f7f7f" > "$outdir/menu_mask_o.png"
	mv "$outdir/menu_mask_o.png" "$outdir/menu_mask_lur.png"
	pngtopnm "$outdir/menu_mask_ur.png" | pnmdepth 3 | pnmtopng -transparent "#7f7f7f" > "$outdir/menu_mask_o.png"
	mv "$outdir/menu_mask_o.png" "$outdir/menu_mask_ur.png"
	pngtopnm "$outdir/menu_mask_lu.png" | pnmdepth 3 | pnmtopng -transparent "#7f7f7f" > "$outdir/menu_mask_o.png"
	mv "$outdir/menu_mask_o.png" "$outdir/menu_mask_lu.png"
	
	
	let i=0
	total_files="${#fixedslide[@]}"
	echo '           <menus>' > "$outdir/$slideshow_name"_menu.xml
	for it in "${fixedslide[@]}"; do
#		echo "file=$it"
		di=`addzeros $(( $i + 1 ))`
		if [ "$pal" -eq 1 ] ; then
		        ppmtoy4m -v 0 -n 1 -r -F 25:1 -A 59:54 -I p "$outdir/$it" | \
			mpeg2enc -E-20 -G 12 -v 0 -a 2 -M 3 -f 8 -o "$outdir/menu.mpg"
		else
		        ppmtoy4m -v 0 -n 1 -r -F 30000:1001 -A 10:11 -I p "$outdir/$it" | \
			mpeg2enc -E-20 -G 12 -v 0 -a 2 -M 3 -f 8 -o "$outdir/menu.mpg"
		fi
		mplex -v 0 -f 8 -o "$outdir/menu_t.mpg" "$outdir/menu.mpg" "$outdir"/audio.mp2
	
		if [ "$i" -eq 0 ] ; then
			echo '               <pgc entry="root" >' >> "$outdir/$slideshow_name"_menu.xml
		else
			echo '               <pgc>' >> "$outdir/$slideshow_name"_menu.xml
		fi
		echo '      <vob file="'$outdir/slide_nav_$di.mpg'" pause="inf"/>' >> "$outdir/$slideshow_name"_menu.xml
		echo '<subpictures>' > "$outdir/menu.spumux"
		echo '  <stream>' >> "$outdir/menu.spumux"
	
		if [ "$i" -eq 0 ] ; then  # first slide
			echo -n '      <spu start="00:00:00.00" end="00:00:00.00" highlight="' >> "$outdir/menu.spumux"
			echo "$outdir/menu_mask_ur.png"'" force="yes" >' >> "$outdir/menu.spumux"
	        	echo ' <button x0="'340'" y0="'$top'" x1="'380'" y1="'$bottom'" />' >> "$outdir/menu.spumux"
	        	echo ' <button x0="'550'" y0="'$top'" x1="'586'" y1="'$bottom'" />' >> "$outdir/menu.spumux"
	
			echo '         <button> jump menu 1; </button>' >> "$outdir/$slideshow_name"_menu.xml
			echo '         <button> jump menu 3; </button>' >> "$outdir/$slideshow_name"_menu.xml
		elif [ "$(( $i + 1 ))" -eq "$total_files" ] ; then # last slide
			echo -n '      <spu start="00:00:00.00" end="00:00:00.00" highlight="' >> "$outdir/menu.spumux"
			echo "$outdir/menu_mask_lu.png"'" force="yes" >' >> "$outdir/menu.spumux"
	        	echo ' <button x0="'124'" y0="'$top'" x1="'180'" y1="'$bottom'" />' >> "$outdir/menu.spumux"
	        	echo ' <button x0="'340'" y0="'$top'" x1="'380'" y1="'$bottom'" />' >> "$outdir/menu.spumux"
			echo '         <button> jump menu '$(( $i + 1 ))'; </button>' >> "$outdir/$slideshow_name"_menu.xml
			echo '         <button> jump menu 1; </button>' >> "$outdir/$slideshow_name"_menu.xml
		else
			echo -n '      <spu start="00:00:00.00" end="00:00:00.00" highlight="' >> "$outdir/menu.spumux"
			echo "$outdir/menu_mask_lur.png"'" force="yes" >' >> "$outdir/menu.spumux"
       		 	echo ' <button x0="'124'" y0="'$top'" x1="'180'" y1="'$bottom'" />' >> "$outdir/menu.spumux"
	        	echo ' <button x0="'340'" y0="'$top'" x1="'380'" y1="'$bottom'" />' >> "$outdir/menu.spumux"
	        	echo ' <button x0="'550'" y0="'$top'" x1="'586'" y1="'$bottom'" />' >> "$outdir/menu.spumux"
			echo '         <button> jump menu '$(( $i + 1 ))'; </button>' >> "$outdir/$slideshow_name"_menu.xml
			echo '         <button> jump menu 1; </button>' >> "$outdir/$slideshow_name"_menu.xml
			echo '         <button> jump menu '$(( $i + 3 ))'; </button>' >> "$outdir/$slideshow_name"_menu.xml
		fi
		echo '          </spu>' >> "$outdir/menu.spumux"
		echo '  </stream>' >> "$outdir/menu.spumux"
		echo '</subpictures>' >> "$outdir/menu.spumux"
		echo '                </pgc>' >> "$outdir/$slideshow_name"_menu.xml
		
		## spumux the files:
		spumux -v 0 -P "$outdir/menu.spumux" < "$outdir/menu_t.mpg" > "$outdir/slide_nav_$di.mpg"
	
	        let i=$i+1
	done
	echo '           </menus>' >> "$outdir/$slideshow_name"_menu.xml


	## create slideshow submenu:
	dvd-menu -o "$outdir" -n "$orig_slideshow_name" -D -t 'Play Slideshow' -t 'Setup' -f "$outdir/$slideshow_name.xml" -f "$outdir/$slideshow_name.xml"
	mv "$outdir/vmgm.xml" "$outdir/$slideshow_name"_menu1.xml
	mv "$outdir/menu.mpg" "$outdir/$slideshow_name"_menu1.mpg
fi

cleanup

