#!/bin/bash

#
#	stereo2surround
#	this bash script builds a surround (6ch) file using a few tools out of
#	a stereo (2ch) file. After processing it's converting to ogg, ac3 or aac.
#	You can also use videos as input, as we're dumping with mplayer.
#
#	Syntax:
#	  ./stereo2surround filename [ogg|aac|ac3]
#
#	License: this script comes with absolutely no warranty
#						USE IT (this script) ON YOUR OWN RISK !
#				 This script is free to use. Please let me know if
#				 it was of any use for you.
#
#	Author: Jean-Michel Bruenn <himself@jeanbruenn.info>
#	Date: 21th March 2010
#
originalsound="$1";
newextension="$2";

mplayer=$(which mplayer);
normalize=$(which normalize);
if [ -z $normalize ]; then
	# weird Debian uses normalize-audio instead of "normalize" dunno why.
	# seems to be nice to change the default every time its possible.
	normalize=$(which normalize-audio);
fi
sox=$(which sox);
aften=$(which aften);
oggenc=$(which oggenc);
faac=$(which faac);
multimux=$(which multimux);

# there are for sure nicer variants than doing this with mplayer,
# feel free to change this in this script
if [ ! -x "$mplayer" ]; then
	echo "MPlayer not found, we need it for dumping...";
	err=1;
fi

if [ ! -x "$sox" ]; then
	echo "Sox not found, we need it for audio-processing...";
	err=1;
fi

if [ ! -x "$multimux" ]; then
	echo "Multimux not found, we need it to mux the sound files together...";
	err=1;
fi

if [ ! -x "$normalize" ]; then
	err=1;
	echo "Normalize not found, we need it to normalize the sound...";
fi

if [ "$newextension" = "ac3" ]; then
	if [ ! -x "$aften" ]; then
		echo "Aften not found, we need it to create .ac3";
		err=1;
	fi
elif [ "$newextension" = "aac" ]; then
	if [ ! -x "$faac" ]; then
		echo "Faac not found, we need it to create .aac";
		err=1;
	fi
elif [ "$newextension" = "mp3" ]; then
	echo "Sorry, i have no idea how to create 6channel mp3";
elif [ "$newextension" = "ogg" ]; then
	if [ ! -x "$oggenc" ]; then
		echo "Oggenc not found, we need it to create .ogg";
		err=1;
	fi
else
	echo "No matching extension found, try: ac3, aac or ogg";
	err=1;
fi

if [ ! -f $originalsound ]; then
	echo "Soundfile not found or no soundfile given, exiting...";
	err=1;
fi

channels=$(sox --i "$originalsound" | grep Channels | cut -d " " -f 9);
if [[ ! $channels -eq 2 ]]; then
	echo "Too many or less channels - this script takes 2 channels as input";
	err=1;
fi

if [[ $err -eq 1 ]]; then
	echo "One or more errors occured, exiting...";
else
	# dump the audio to audiodump.wav
	echo "Dumping audio...";
	$mplayer -ao pcm:fast -vc null -vo null "$originalsound" -benchmark -really-quiet &>/dev/null

	# checking the sample rate
	echo "Checking sample rate...";
	samplerate=$(file audiodump.wav | cut -d " " -f 12);
	if [[ $samplerate -eq 48000 ]]; then
		echo "Found 48kHz sample rate...";
	else
		echo "Found $samplerate sample rate, resampling to 48kHz...";
		$sox -v 0.5 audiodump.wav -r 48k audiodump.tmp.wav
		mv audiodump.tmp.wav audiodump.wav
	fi

	# create front left channel file
	echo "Creating front left channel...";
	$sox -c 2 -v 1.1 audiodump.wav -r 48000 -c 1 front_left.wav mixer -l sinc 20-20000 bass -3 highpass -2 750
	# create front right channel file
	echo "Creating front right channel...";
	$sox -c 2 -v 1.1 audiodump.wav -r 48000 -c 1 front_right.wav mixer -r sinc 20-20000 bass -3 highpass -2 750
	# ceate center channel file
	echo "Creating center channel...";
	$sox -c 2 -v 0.8 audiodump.wav -r 48000 -c 1 center.wav loudness +2 bass -1
	# create rear left channel file
	echo "Creating rear left channel...";
	$sox -c 2 -v 0.7 audiodump.wav -r 48000 -c 1 rear_left.wav mixer -l bass -1 treble -3 sinc 100-8000
	# create rear right channel file
	echo "Creating rear right channel...";
	$sox -c 2 -v 0.7 audiodump.wav -r 48000 -c 1 rear_right.wav mixer -r bass -1 treble -3 sinc 100-8000
	# create subwoofer channel file
	echo "Creating subwoofer channel...";
	$sox -c 2 -v 0.7 audiodump.wav -r 48000 -c 1 lfe.wav loudness +2 bass +6 treble -6 lowpass -2 120

	# normalize the sound in batch mode (to have the volume correctly)
	echo "Normalizing...";
	$normalize -b front_left.wav front_right.wav rear_left.wav rear_right.wav center.wav lfe.wav &>/dev/null

	# Note: Channel Layout was a difficult task. I found the correct mappings out by
	#		  using a 5.1 surround wav with left right etc voices, splitting that file, and
	#		  mixing it together again, testing with mplayer file -channels 6 afterwards.
	#		  So the channel mappings here should be correct - Or as wrong as mplayers
	#		  (if wrong)

	if [ "$newextension" = "ogg" ]; then
		# muxing it together
		# 1 => rear right | 2 => lfe/bass | 3 => front left | 4 => center | 5 => front_right | 6 => rear_left
		echo "Muxing...";
		$multimux -d 15,0,0,0,0,15 rear_right.wav lfe.wav front_left.wav center.wav front_right.wav rear_left.wav > final.wav 2>/dev/null
		echo "Creating OGG...";
		$oggenc -R 48000 -q 5 -C 6 final.wav &>/dev/null
	elif [ "$newextension" = "aac" ]; then
		# muxing it together
		# 1 => front left | 2 => front right | 3 => center | 4 => lfe/bass | 5 => rear left | 6 => rear right
		echo "Muxing...";
		$multimux -d 0,0,0,0,15,15 front_left.wav front_right.wav center.wav lfe.wav rear_left.wav rear_right.wav > final.wav 2>/dev/null
		echo "Creating AAC...";
		# -c 48000
		$faac -q 100 -c 48000 -I 3,4 --mpeg-vers 4 final.wav &>/dev/null
	elif [ "$newextension" = "ac3" ]; then
		# muxing it together
		# 1 => rear left | 2 => rear right | 3 => front left | 4 => front right | 5 => center | 6 => lfe/bass
		echo "Muxing...";
		$multimux -d 15,15,0,0,0,0 rear_left.wav rear_right.wav front_left.wav front_right.wav center.wav lfe.wav > final.wav 2>/dev/null
		echo "Creating AC3...";
		$aften -pad 0 -m 1 -smix 2 -acmod 7 -lfe 1 -raw_ch 6 final.wav final.ac3 &>/dev/null
		echo "done";
	else
		# this should never happen :)
		echo "??";
	fi
fi
