#!/bin/bash

# sfnorm -- normalizes a soundfile to maxamp or any other amplitude value
# input soundfile can be at any sampling rate, 16 or 24 bit ints or 32 bit floats,
# any number of channels

if  ( [ $# == 0 ] ) ; then  # print usage summary
echo " syntax:  sfnorm  [-p peak] infile [infile2  infileN]"
echo ' where  "peak" is the desired output amplitude. (Default = 90 % of maxamp.) '
echo " Example:   sfnorm newflute.wav explosion.wav"
echo " Result: The user's input soundfiles 'newflute' and 'explosion' are"
echo " normalized to 90 % of maxamp, written to output soundfiles 'newflute.wav.norm' "
echo " and 'explosion.wav.norm'"
echo ' See the man page for "sfnorm" and possibly for "stripnorm" for details. '
echo '  '
exit 0
fi

. /usr/local/lib/tklabashfuncs  # access bash functions in this file 
 TYPE="FLOAT"  # defaults if no -p flag and argument
 MAX=".9"
case ${1} in
 (-p) 
  if ( [ $2 == '1' ] || [ $2 == '1.' ] || [ $2 == '1.0' ] || [ $2 == '32767' ]) ; then
     #echo it is a one  ; fi ;;
  TYPE="FLOAT"
  MAX=".999"  
  else

   if [ `echo $2 |  grep -e '\.'` ] ; then
      # echo there is a dot
     TYPE="FLOAT"
     MAX="${2}"
   else
      # echo No there is no dot
     TYPE="INT"
     #MAX="${2}"
     INTMAX="${2}"
    fi
  shift; shift;
 fi ;;
esac
# -------------

cd $SFDIR
for i in $* ; do
  sfexist $i # check that soundfile exists
  getsffmt $SOURCESF # WAVE or AIFF
  getsfsr $SOURCESF # get sr $SFSR
  getsfbits  $SOURCESF # get word size $SFBITS
  getsfchans $SOURCESF # get number of channels $CHANS
  getsfdur $SOURCESF # get duration

# Get current maxamp scaling factor
MAXFAC=`sfpeak $SOURCESF | grep -e "multiplier required" | awk '{print $1}'`
if [ $MAXAMP -e "" ] ; then 
   echo "ERROR: Rescaling not computed correctly. Source soundfile $SOURCESF may be silent."
    exit 1
fi

if [  $TYPE == "INT" ] ; then
MAX=`bc << EOF
scale=8
( ${INTMAX} / 32767 )
EOF`
fi

GAIN=`bc << EOF
scale=8
( $MAX * $MAXFAC )
EOF`
	# DO not indent bc
	# bc returns 1 if true, 0 if false
COMPARE=`bc << EOF
scale=6
$GAIN < 1.00
EOF`
if [ $COMPARE == 1 ] ; then  # amplitude gain multiplier is less than 1.0
  echo "WARNING: Your normalization value [ $INTMAX $MAX ] will DECREASE the amplitude of $SOURCESF."
 echo "To abort, type ^c ( control and c keys) immediately."
 sleep 2
fi
######################################################
# write source sflib soundfiles to user's $SFDIR
if ( [ `echo $SOURCESF | grep -e "\/sflib\/"` ] || [ `echo $SOURCESF | grep -e "\/sflib96\/"` ] ) ; then
   BASE=`basename $SOURCESF`
   OUTPUTSF="$SFDIR/$BASE.norm"
 else
  OUTPUTSF="$SOURCESF.norm"
fi
######################################################

    CSOUND="/usr/bin/csound"  # ECMC csound alias  includes -W
    CSFLAGS="-d -m0"
if [ $FMT == "WAVE" ] ; then
   #CSFLAGS=`echo $CSFLAGS -W`
   CSFLAGS="$CSFLAGS -W"
elif [ $FMT == "AIFF" ] ; then
   CSFLAGS=`echo $CSFLAGS -A`
#elif [ $FMT == "NEXT" ] ;  then
#   echo "ERROR:  sfnorm does not work with  NeXT format soundfiles. Quitting."
#   exit 1
fi
   KR=`expr $SR \/ 10`
    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, CHANS is $CHANS, DUR is $DUR and FMT is $FMT ### DELETE 

###########################################
# Prepare csound orc and sco files:
TMPORC=~/tmpsfnorm.orc
TMPSCO=~/tmpsfnorm.sco
TMPOUT=~/tmpsfnorm.out
	# TMPORC=/tmp/tmp$$.orc
	# TMPSCO=/tmp/tmp$$.sco
	# TMPOUT=/tmp/tmp$$.out
rm -f $TMPORC $TMPSCO $TMPOUT 
  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

chan=1
while [ "$chan" -le $CHANS ] ;  do
  echo "a$chan = $GAIN * a$chan" >> $TMPORC

  let "chan+=1"
done 

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
#################
# Compile the rescaled soundfile with csound:
$CSOUND $CSFLAGS -o $OUTPUTSF $TMPORC $TMPSCO >& $TMPOUT
rm -f $TMPORC $TMPSCO # $TMPOUT

if [ -f $OUTPUTSF ] ; then
   echo "Output soundfile : "
   sfpeak $OUTPUTSF
   echo "You can rename this soundfile with the >>  stripnorm << command."
else
   echo 'ERROR somewhere in this job: No output soundfile created.  If "Divide by zero"'
   echo 'error appears above input soundfile '$SOURCESF' may be silent.'
   exit 1
fi
rm -f  $TMPOUT 
done
