#!/bin/bash
# sfpeak -- 
# Runs Csound to find peak amplitude of a soundfile, 1-8 channels, any sampling rate
# This is a poorly written script that U hope no one looks at but it works."

if  ( [ $# == 0 ] ) ; then  # print usage summary
echo " syntax:  sfpeak   [-s] soundfile [soundfile2  soundfileN]"
echo '     For usage details see the sfpeak man page. '
exit 0
fi

case $1 in
 "-s") SHORT="YES" ; shift; ;; #succinct output
#  *) SHORT="" ;;
esac
cd $SFDIR
for i in $* ; do
  if [ -f $i ] ; then
    SOURCESF=$i
  elif [ -f $i.wav ] ; then
    SOURCESF=$i.wav
  elif [ -f $i.aif ] ; then
    SOURCESF=$i.aif
  elif [ -f $i.aiff ] ; then
    SOURCESF=$i.aiff
  else
    echo "ERROR: No file named >> $i << found. Quitting."
          echo " (Your current working soundfile directory is $SFDIR)" 
    exit 1
  fi
######################################################
# Get header information
cd $SFDIR
FMT=`sfcheck $SOURCESF | awk '{print $1}'`
# check to make sure input file is a playable soundfile
if [ `echo $FMT | grep  -e "ERROR:"` ] ; then  
   sfcheck $1
   echo "Input file $1 does not appear to be a soundfile. Quitting."
   exit 1
fi
    CSOUND="/usr/bin/csound"  # ECMC csound alias  includes -W
    CSFLAGS="-d -n -m0"
if [ $FMT == "WAVE" ] ; then
   CSFLAGS="$CSFLAGS -W"
elif [ $FMT == "AIFF" ] ; then
   CSFLAGS=`echo $CSFLAGS -A`
else
   echo "ERROR:  Only WAVE and AIFF input formats are supported."
   echo "Format of >> $SOURCESF << is $FMT. Quitting."
   exit 1
fi
	SR=`sfsr $SOURCESF | awk '{print $1}'`
        KR=`expr $SR \/ 10`
	CHANS=`sfchans $SOURCESF | awk '{print $1}'`
	DUR=`sfdur $SOURCESF | awk '{print $1}'`
	BITS=`sfbits $SOURCESF | awk '{print $1}'`
          if [ $BITS == '24' ] ; then
            CSFLAGS=`echo $CSFLAGS -3`
          elif [ $BITS == '32' ] ;  then # make sure 32 bits are floats, then add csound float flag
       if ( ! ( `sfinfo $SOURCESF | grep -e "32-bit" | grep -e "float"` == "" >& /dev/null ) ) ; then
               CSFLAGS=`echo $CSFLAGS -f`  # float input & output
            fi
          fi
#  echo SR is $SR, BITS is $BITS, CHANS is $CHANS, DUR is $DUR and FMT is $FMT ### DELETE 
       if [ -z "$SHORT" ] ; then
             sfinfo -s $SOURCESF
        fi
###########################################
# Prepare csound orc and sco files:
#TMPORC=~/tmpsfpeak.orc
#TMPSCO=~/tmpsfpeak.sco
#TMPOUT=~/tmpsfpeak.out
	 TMPORC=/tmp/tmpsfpeak$$.orc
	 TMPSCO=/tmp/tmpsfpeak$$.sco
	 TMPOUT=/tmp/tmpsfpeak$$.out
	 TMPOUT2=/tmp/tmpsfpeak2$$.out
	 TMPOUT3=/tmp/tmpsfpeak3$$.out
rm -f $TMPORC $TMPSCO $TMPOUT  $TMPOUT2 $TMPOUT3 # should never be needed, just a precaution
  echo "i1 0 $DUR " > $TMPSCO # score file
  echo "e" >> $TMPSCO

   echo "sr=$SR" > $TMPORC  # orchestra file
   echo "kr=$KR" >> $TMPORC  # orchestra file
   echo "nchnls=$CHANS" >> $TMPORC
   echo "instr 1 " >> $TMPORC

# -- loop functions for soundin and outc depending on number of channels
chan=1

while [ "$chan" -le $CHANS ] ; do
  if [ "$chan" -lt $CHANS ] ; then
          echo -n  "a$chan, " >> $TMPORC
    #     let "chan+=1"
   else
       echo -n  "a$chan " >> $TMPORC
   fi
  let "chan+=1"
done
echo  'soundin "'$SOURCESF'" , 0' >> $TMPORC

echo -n "outc " >> $TMPORC
chan=1
while [ "$chan" -le $CHANS ] ; do
  if [ "$chan" -lt $CHANS ] ; then
          echo -n  "a$chan, " >> $TMPORC
    #     let "chan+=1"
   else
       echo -n  "a$chan " >> $TMPORC
   fi
  let "chan+=1"
done
echo "" >> $TMPORC
echo "endin" >> $TMPORC
#################
# Run scratch csound job to find peak amp:
$CSOUND $CSFLAGS  $TMPORC $TMPSCO  >& $TMPOUT
rm -r $TMPORC $TMPSCO
########## Monophonic inputs: #########
if  [ $CHANS -eq "1" ] ; then   # for mono sounfiles:
INT=`grep  "end of score" $TMPOUT | grep  "overall amps:" | awk '{print $6}'`
FLOAT==`bc << EOF
scale=8
( ${INT} / 32767 )
EOF`
FLOAT=`echo $FLOAT | sed -e 's/\=//g' # |  awk '{print $1}'`
MAXSCALE=`bc << EOF
scale=8
( 1. / ${FLOAT}  )
EOF`
echo -e "       Peak amplitude of $SOURCESF in floats and 16 bit shorts:"
echo -e "$FLOAT      (on a floating point scale 0-1.0), equivalent to "
echo -e "$INT        (on a scale of 0-32767)"
echo "$MAXSCALE  =   multiplier required to re-scale this soundfile to maxamp"
unset INT FLOAT MAXSCALE

else   ###### 2 or more input channels #################
 # This is rotten programming because I couldn't find a way to reference nested
# variables w/ awk.
INT[1]=`grep  "end of score" $TMPOUT | grep  "overall amps:" | awk '{print $6}'`
INT[2]=`grep  "end of score" $TMPOUT | grep  "overall amps:" | awk '{print $7}'`
INT[3]=`grep  "end of score" $TMPOUT | grep  "overall amps:" | awk '{print $8}'`
INT[4]=`grep  "end of score" $TMPOUT | grep  "overall amps:" | awk '{print $9}'`
INT[5]=`grep  "end of score" $TMPOUT | grep  "overall amps:" | awk '{print $10}'`
INT[6]=`grep  "end of score" $TMPOUT | grep  "overall amps:" | awk '{print $11}'`
INT[7]=`grep  "end of score" $TMPOUT | grep  "overall amps:" | awk '{print $12}'`
INT[8]=`grep  "end of score" $TMPOUT | grep  "overall amps:" | awk '{print $13}'`
rm -f $TMPOUT
#------------ LOOP -------------------------
x=1 # get float equivalents of Csound 16 bit peak ams for each channel
while [ $x -le $CHANS ] ; do

TMPINT=${INT[$x]}
FLOAT=`bc << EOF
scale=8
  ( ${TMPINT} / 32767 )
EOF`
FLOAT[$x]="$FLOAT"
echo -e " \t ${FLOAT[$x]}  \t ${INT[$x]} \t  $x "  >> $TMPOUT2
echo -e " ${FLOAT[$x]} "  >> $TMPOUT3
 let "x+=1"
done

for i in `echo ${INT[*]}` ; do 
   echo $i >> $TMPOUT 
done
PEAKINT=`sort -n -r $TMPOUT | head -1`
PEAKFLOAT=`sort -n -r $TMPOUT3 | head -1`
MAXSCALE=`bc << EOF
scale=8
( 1. / $PEAKFLOAT  )
EOF`

# echo -------------------------------
PRINTCHAN=`grep -e "$PEAKFLOAT" $TMPOUT2 | grep -e "$PEAKINT" |  awk '{print $3 }'`
# 7 lines below necessary for proper formatting in case more than 1  channels have same peak value
FIXPRINTCHAN=`echo -n $PRINTCHAN | awk '{print $1, $2, $3, $4, $5, $6, $7, $8}'`
CHARGS=`echo $FIXPRINTCHAN | wc -w`
  if [ "$CHARGS" -gt 1 ] ; then
      CHS="channels" 
   else 
      CHS="channel" 
  fi

  if [ -z "$SHORT" ] ; then
         echo  -e "     Peak amplitude of >> $SOURCESF << occurs on $CHS $FIXPRINTCHAN "
  else
         echo -n -e "     Peak amplitude of >> $SOURCESF << occurs on $CHS $FIXPRINTCHAN "
  fi
echo -e "$PEAKFLOAT  (on a floating point scale 0-1.0), equivalent to "
echo -e " $PEAKINT     (on a scale of 0-32767)"
echo "$MAXSCALE  =  multiplier required to re-scale this soundfile to maxamp"
echo "      -  -  -  -  -  -  -"
  if [ -z "$SHORT" ] ; then
     echo -e "           Peak amplitudes of the individual channels are:"
     echo -e "     (float: 0-1.0)  (int.: 0-32767)  Channel number:"
     cat $TMPOUT2
  fi

rm -f $TMPOUT $TMPOUT2 $TMPOUT3
unset INT FLOAT MAXSCALE PEAKINT PEAKFLOAT
fi
echo "     -------------------------------------------------"
rm -f $TMPOUT
done

