#!/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. This # would allow the files to be of different data types # and sample rates. # # 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=/usr exec_prefix=/usr bindir=/usr/bin HAVE_ALSA=1 HAVE_OSS=1 HAVE_SUNAU=1 # Look for sox in install directory first and then in current direction # if not found. PATH="$bindir:.:$PATH" program_name=`basename $0` rec_mode="no" if [ "$program_name" = "rec" ]; then rec_mode="yes" fi program_version="3.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 [GENERAL OPTIONS] [FORMAT OPTIONS] FILE [EFFECT]... Play/record sound files to/from unix style sound devices. GENERAL OPTIONS: General options should only be specified one. -d, --device=DEVICE use DEVICE for input/output -V, --verbose print verbose information -h, --help display this help and exit --version output version information and exit FORMAT OPTIONS: File options can be specified for each filename. Multiple filenames can be specified when playing audio files but they must all be of the data type and sample rates. -c, --channels=CHANNELS specifies the number of sound channels in FILE -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=FILENAME specify filename 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|noiseprof|noisered|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 fopts2="$fopts2 -v $1" ;; --volume=*) fopts2="$fopts2 -v `echo $1 | sed 's/.*=//'`" ;; -V|--verbose) gopts="$gopts -V" ;; -x|--xinu) fopts="$fopts -x" ;; --file=*) if [ $rec_mode = "yes" ]; then if [ -z "$filename" ]; then filename=`echo $1 | sed 's/.*=//'` else echo "Filename already given. Ignoring extra name: $1" 1>&2 fi else filename=`echo $1 | sed 's/.*=//'` play_opts="$play_opts $fopts $fopts2 \"$filename\"" fopts="" fopts2="" fi ;; -h) help ;; --help) help ;; --version) version ;; -) if [ $rec_mode = "yes" ]; then if [ -z "$filename" ]; then filename="-" else echo "Filename already given. Ignoring extra name: $1" 1>&2 fi else filename="-" play_opts="$play_opts $fopts $fopts2 \"$filename\"" fopts="" fopts2="" fi ;; *) if [ $rec_mode = "yes" ]; then if [ -z "$filename" ]; then filename="$1" else echo "Filename already given. Ignoring extra name: $1" 1>&2 fi else filename=`echo $1 | sed 's/\ /\\\ /g'` filename=$1 play_opts="$play_opts $fopts $fopts2 \"$filename\"" fopts="" fopts2="" fi ;; esac shift done # 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 [ "$HAVE_ALSA" = "1" ]; then arch_defines="-t alsa" if [ -z "$device" ]; then device="default" fi else if [ "$HAVE_OSS" = "1" ]; then arch_defines="-t ossdsp" if [ -z "$device" ]; then device="/dev/dsp" fi else 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 ;; NetBSD|OpenBSD) arch_defines="-t sunau" if [ -z "$device" ]; then device="/dev/audio" fi ;; esac fi fi # If name is "rec" then record else assume user is wanting to play # a sound file. if [ "$rec_mode" = "yes" ]; 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 # $fopts are specified on both sides because audio driver # may not support the given format and might pick # something close to it. Asume user really wants the # file to be in the specified format and so request # sox to do any conversions. sox $gopts $arch_defines $fopts $device $fopts $fopts2 "$filename" $effects else # Eval is needed to recongnize the quotes around filename # and let them be passed to program as 1 option (in case # filename has spaces). eval sox $gopts $play_opts $arch_defines $device $effects fi