#!/bin/sh
# Shell script to play/record sound files to/from unix style sound devices.
# Should auto detect most supported systems.
#
# Originally developed by Chris Bagwell (cbagwell@sprynet.com)
#
#   TODO:  Put each set of fopts and filenames on an array and then 
#          play each filename back with the given effect.h
#
# Change History:
#
#   Major updates have been supplied by Kjetil Torgrim Homme and 
#   Kirk Goff.

# Set up path so that it can find Sox if user's path doesn't already
# include it.
prefix=${DESTDIR}/usr/local
exec_prefix=${prefix}
bindir=${exec_prefix}/bin

# Look for sox in install directory first and then in current direction
# if not found.
PATH="$bindir:.:$PATH"

program_name=`basename $0`
program_version="2.0"

if [ -z "$1" ]; then
    echo "\
$program_name: too few arguments
Try \`$program_name --help' for more information." 1>&2
    exit 1
fi

version()
{
    echo "$program_name (sox) $program_version"
    exit 0
}

help()
{
    echo "\
Usage: $program_name [OPTION]... FILE [EFFECT]...
Play/record sound files to/from unix style sound devices.

  -c, --channels=CHANNELS      specifies the number of sound channels in FILE
  -d, --device=DEVICE          use DEVICE for input/output
  -f, --format=FORMAT          specifies bit format of sample
                               FORMAT is either s, u, U, A, a, or g
  -r, --rate=RATE              sample rate in hertz of FILE
  -s, --size=SIZE              interpret size of sample
                               SIZE is either b, w, l, f, d, or D
  -t, --type=TYPE              specifies file format of FILE
  -v, --volume=VOLUME          change amplitude
  -x, --xinu                   reverse bit order of sample
                               (only works with 16-bit and 32-bit integer data)
      --file                   next argument is FILE
  -h, --help                   display this help and exit
      --version                output version information and exit

EFFECTs are one or more of the following:  avg, band, chorus, copy, cut, 
deemph, echo, echos, flanger, highp, lowp, map, mask, phaser, pick, polyphase
rate, repeat, resample, reverb, reverse, split, stat, vibro.

See sox man page for detailed information on supported file types, data
formats, and effect options."
    exit 0
}


# loop over arguments
while [ $# -ne 0 ]; do
    case "$1" in
	avg|band|bandpass|bandreject|chorus|compand|copy|cut|deemph|earwax|echo|echos|fade|filter|flanger|highp|highpass|lowp|lowpass|map|mask|mcompand|pan|phaser|pick|pitch|polyphase|rate|repeat|resample|reverb|reverse|silence|speed|split|stat|stretch|swap|trim|vibro|vol)
	    effects="$@"
	    break
	    ;;
	-c)
	    shift
	    fopts="$fopts -c $1"
	    ;;
	--channels=*)
	    fopts="$fopts -c `echo $1 | sed 's/.*=//'`"
	    ;;
	-d)
	    shift
	    device="$1"
	    ;;
	--device=*)
	    device=`echo $1 | sed 's/.*=//'`
	    ;;
	-f)
	    shift
	    fopts="$fopts -$1"
	    ;;
	--format=*)
	    fopts="$fopts -`echo $1 | sed 's/.*=//'`"
	    ;;
	-r)
	    shift
	    fopts="$fopts -r $1"
	    ;;
	--rate=*)
	    fopts="$fopts -r `echo $1 | sed 's/.*=//'`"
	    ;;
	-s)
	    shift
	    fopts="$fopts -$1"
	    ;;
	--size=*)
	    fopts="$fopts -`echo $1 | sed 's/.*=//'`"
	    ;;
	-t)
	    shift
	    fopts2="$fopts -t $1"
	    ;;
	--type=*)
	    fopts2="$fopts -t `echo $1 | sed 's/.*=//'`"
	    ;;
	-v)
	    shift
	    volume="-v $1"
	    ;;
	--volume=*)
	    volume="-v `echo $1 | sed 's/.*=//'`"
	    ;;
	-x|--xinu)
	    fopts="$fopts -x"
	    ;;
	--file)
	    shift
	    if [ -z "$filename" ]; then
		filename="$1"
	    else
		echo "Filename already given.  Ignoring extra name: $1" 1>&2
	    fi
	    ;;
	-h)
	    help
	    ;;
	--help)
	    help
	    ;;
	--version)
	    version
	    ;;
	-)
	    filename="-"
	    ;;
	-*)
	    fopts="$fopts $1"
	    ;;
	*)
	    if [ -z "$filename" ]; then
		filename="$1"
	    else
		echo "Filename already given.  Ignoring extra name: $1" 1>&2
	    fi
	    
	    ;;
    esac
    shift
done

arch=`uname -s`
case $arch in
  SunOS)
    case `uname -r` in
        # Solaris software can auto-detect hardware capabilities.
        5.*)
	    arch_defines="-t sunau"
	    ;;
	# For SunOS default to signed words.  Some hardware can only play u-law and would need
	# to be changed here.
	*)
	    arch_defines="-t sunau -w -s"
	    ;;
    esac
    if [ -z "$device" ]; then
	device="/dev/audio"
    fi
    ;;
  Linux|FreeBSD)
    arch_defines="-t ossdsp"
    if [ -z "$device" ]; then
	device="/dev/dsp"
    fi
    ;;
  NetBSD|OpenBSD)
    arch_defines="-t sunau"
    if [ -z "$device" ]; then
        device="/dev/audio"
    fi
    ;;
esac

# If user sets AUDIODEV environment variable then force output device
# to by that.  Solaris SunRay's make use of this for sure.
if [ -n "$AUDIODEV" ]; then
    device="$AUDIODEV"
fi

# If name is "rec" then record else assume user is wanting to play
# a sound file.
if [ "$program_name" = "rec" ]; then

    # Don't send data to stdout if they are reading from it.
    if [ "$filename" = "-" ]; then
      echo "Send break (control-c) to end recording" 1>&2
    else
      echo "Send break (control-c) to end recording"
    fi
    sox $volume $arch_defines $fopts $device $fopts2 "$filename" $effects 

else
    sox $volume $fopts $fopts2 "$filename" $arch_defines $device $effects
fi
