#!/bin/bash
# mko, mkorch  : makes csound orchestra file using Eastman Csound LIbrary instruments
#                and macros
if  ( [ $# == 0 ] ) ; then  # print usage summary
     echo "syntax: mko [- or -nh] [SR] [kr KR] [NCHNLS]  INSTRUMENT(S) [ -O sourcefile]"
    echo "  +  SR sets the sampling rate (default = 44100)"
    echo '  +  a KR argument MUST be preceded by "kr" and  a space'
    echo "  + NCHNLS (output channels) = 1 (mono, the default) 2 (stereo)"
    echo "  + INSTRUMENT(S) = (1) the names, in CAPS, of one or more Library "
    echo '  instruments, or (2) the name (lower case) of a TUTORIAL Eastman instrument,'
    echo ' such as "ex1-1", or (3) a file in your current working Unix directory, or'
    echo "  (4) a file preceded by its full Unix path"
    echo "  + If the first argument is a  - (minus sign), the source file will NOT"
    echo '  be expanded into Csound orchestra file "orch.orc" '
    echo "  + If the first argument is  -nh the file will be expanded but no"
    echo "    orchestra header will be included (useful with cecilia)"
    echo '  + -O followed by a file name specifies an alternative macro file to'
    echo '  the default "temp.orc"'
    echo "  Example 1 :    mko  MARIMBA "
    echo '  creates the following "temp.orc" file'
    echo "       SETUP(44100,2205,1)"
    echo "       MARIMBA "
    echo '  then expands this source file into usable Csound orchestra file "orch.orc"'
    echo "  Example 2 :  mko  96000 kr 9600  2 SAMP TSAMP"
    echo '  creates  an orchestra file including Library instruments samp and tsamp,'
    echo "   with sampling  rate = 96000, kr = 9600 and stereo output."
    echo "  ------- For more details, type:   man  mko  ------------- "
    exit 0
fi

PWDDIR=`pwd`
TUTDIR=$CSLIBDIR/tut/ins
INSDIR="$CSLIBDIR/ins"
INCDIR="$CSLIBDIR/Include"
OUTPUTFILE="temp.orc"  # default output file for source orchestra code
INS=""
ARGS=`echo  "$@"`
/bin/rm -f $OUTPUTFILE 
# default values :
     SR="44100"
     KR="NULL"
     NCHNLS="1"

case $1 in
     #  : if 1st argument is  -  , do not expand macro orchestra
     #   file  into  into executable Csound orchestra file
 "-") HEADER="YES" ;   shift; ;;  # EXPAND not defined, so do not include header
     #  If 1st argument is  -nh  , do not include an orchestra  header.
     #      This option is useful primarily in creating orchestra files
     #     to be read in to cecilia.

 "-nh") EXPAND="YES" ;    shift; ;;  # HEADER not defined so do not include it
  *) EXPAND="YES" ;  HEADER="YES"  ;;  # default: include header and create Csound orc
esac

while (( "$#" )); do
 # if no alphabetical chars in argument, or if arg. = kr or KR:
 if ( [ `echo $1 | grep -v "[[:alpha:]]"` ] ||  [ "$1" = "kr" ] ||  [ "$1" = "KR" ] ) ; then  
  if ( [ "$1" = "kr" ] ||  [ "$1" = "KR" ] ) ; then
     shift; KR=$1 ; shift;
  # sampling rate argument:
  elif ( [ "$1" -ge "100" >& /dev/null ] ) ; then
     SR="$1" ; shift;
   # abbreviations for sampling rate: 44, 48, 96, 22,24
     elif ( [ "$1" = "96" >& /dev/null ] ) ; then
        SR="96000" ; shift;
     elif ( [ "$1" = "48" >& /dev/null ] ) ; then
        SR="48000" ; shift;
     elif ( [ "$1" = "44" >& /dev/null ] ) ; then
        SR="44100" ; shift;
     elif ( [ "$1" = "88" >& /dev/null ] ) ; then
        SR="44100" ; shift;
     elif ( [ "$1" = "88200" >& /dev/null ] ) ; then
        SR="22050" ; shift;
     elif ( [ "$1" = "24" >& /dev/null ] ) ; then
        SR="24000" ; shift;
  # number of channels argument:
  elif ( [ "$1"  -ge "1" ] && [ "$1" -le "8" ] ) ; then
     NCHNLS="$1" # ;  shift;
    #if ( [ "$NCHNLS" -gt "2" ] &&  [ "$NCHNLS" <= "8" ] ) ; then
     if ( [ "$1"  -ge "3" ] && [ "$1" -le "8" ] ) ; then
       echo "WARNING: Output channels set to $NCHNLS. Library instruments do not provide"
        echo "default output statements when more than 2 channels are used. Unless you"
        echo "add a Csound output statement to the end of the instrument(s) in this orchestra"
        echo "the orchestra will produce silence. ------------------"
    fi
    shift;
  # check for Library instruments and macros:
  fi
else  ## argument includes alphabetical characters
  # test if argument is a defined Library instrument, UPPER case:
    if [ `grep -e "define($1,"  $INCDIR/idefs.m4  | grep -e "$1,"` ] ; then
       INS=`echo $INS $1`;  shift; 
  # Library instrument, lower case
    elif [ -f $INSDIR/$1 ] ; then
      x=`echo $1 | tr '[:lower:]' '[:upper:]'`
      INS=`echo $INS $x`;  shift;
  # test if argument is an Eastman Csound Tutorial instrument:
    elif [ -f $TUTDIR/$1 ] ; then
      INS=`echo "$INS include($TUTDIR/$1)dnl"` ; shift;
  # test if argument is a Library macro used in orchestra files:
    elif  [ "$1" = "GLOBALS" ] ; then
       INS=`echo $INS GLOBALS`;  shift;
  # test if argument is an instrument in user's current working directory:
    elif [ -f $PWDDIR/$1 ] ; then
       INS=`echo "$INS include($PWDDIR/$1)dnl"` ; shift;
  # test if user specifies full path to instrument definition:
    elif [ -f $1 ] ; then
       INS=`echo "$INS include($1)dnl"` ; shift;
    elif [ "$1" = "-o" ] || [ "$1" = "-O" ] ; then
       shift; OUTPUTFILE=$1 ;  shift ;
    else
      echo "ERROR: Invalid argument >> $1 << ; Quitting." # ; exit 1 
      echo Your arguments are:   "$0"  "$ARGS"   ; exit 1
    fi
 fi
 #  - - - - - - - - - - - -
done
# =========================================================
# Check for bad header values:
     if [  $KR == "NULL" ] ; then
        KR=`expr $SR / 10`
     fi
if  [ "$SR" -lt "20000" ] ; then
    echo "ERROR: Your $SR sampling rate is too low. Quitting."
    echo "Sampling rates must be between 20000 and 96000."
    echo Your arguments are:   "$0"  "$ARGS" 
    exit 1
  elif  [ "$SR" -gt "96000" ] ; then
  echo "ERROR: Your $SR sampling rate is too high. 96000 is the highest supported sampling rate. Quitting."
    echo Your arguments are:   "$0"  "$ARGS" 
    exit 1
fi
if ( [ "$SR" != "44100" ] && [ "$SR" != "48000" ] && [ "$SR" != "96000" ]  && [ "$SR" != "88200" ] && [ "$SR" != "22050" ] && [ "$SR" != "24000" ] ) ; then
  echo "WARNING: Uncommon sampling rate: $SR "
fi

 MOD=`expr $SR % $KR`
if ( [ $MOD != "0" ] ) ; then
  echo "ERROR: sr $SR is not  evenly divisible by kr $KR . Quitting."
echo Your arguments are:   "$0"  "$ARGS" 
  exit 1
fi

if [ -z "$INS" ] ; then
   echo "ERROR: No instruments specified. Quitting."
   echo Your arguments are:   "$0"  "$ARGS" 
   exit 1
fi

## --  Make the orchestra file   ------------------

if [ -n "$HEADER"  ] ; then
   echo "SETUP($SR,$KR,$NCHNLS)" >> $OUTPUTFILE  # include header
else  # do not include orchetsra header but define number of channels
   echo "define([NCHNLS],$NCHNLS) COMMENT set output channels to $NCHNLS" >> $OUTPUTFILE
fi
                                                                       
for i in `echo $INS` ; do
  echo $i >> $OUTPUTFILE
done 
  echo " Contents of source orchestra file >> $OUTPUTFILE << : "
  cat  $OUTPUTFILE

if [ -n "$EXPAND" ] ; then
  /bin/rm -f ./orch.orc ./orc
   m4orch $OUTPUTFILE >& /dev/null
  /bin/rm -f $OUTPUTFILE 
   echo "   The macro source code in this file has been expanded to usable"
   echo "   Csound orchestra file  >> orch.orc  (orc) << "
else
   echo "   Flag option   -    included on command line, so source orchestra file"
   echo "   $OUTPUTFILE  has NOT been expanded into a usable Csound orchestra file"
fi
