#
#	MTXHEADER.AWK
#
#  -----------------------------------------------------------------------
#  Copyright 2009  Alfred Steffens Jr.
#  -----------------------------------------------------------------------
#  -----------------------------------------------------------------------
#    Copying Permission:
#
#    mscore is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation.
#
#    mscore is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with mscore (see file called "COPYING"); if not, write to the Free
#    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
#    02111-1307  USA
#  ------------------------------------------------------------------------
#
#   Revision history:
#   1.6     06/18/2009  A. Steffens Jr. Added bankdefs capability.
#   1.4     07/09/2008  A. Steffens Jr. Added multiport capability
#   1.4     06/01/2008  A. Steffens Jr. Added SYSEX
#   1.3     05/17/2008  A. Steffens Jr. Added code to fetch reverb settings (ES6)
#   1.2     05/10/2008  A. Steffens Jr. Added code to fetch bank settings
#
#   Mscore release 1.1
#
#
#	Usage:
#
#		echo "junk" | awk -f mtxheader.awk [options] >  header.mtx
#
#
#		options:
#
#       numtracks
#       bpm
#       ticks
#       name
#       tracks
#       programs
#       volumes
#       bankdefs
#
BEGIN {
	numtracks = 1		# default -- number of tracks
	bpm = 120			# default
	ticks = 220			# default
	name = ""
	tracks = ""			#	list of channel numbers to be assigned to tracks
	programs = ""		#	list of program numbers to be assigned to tracks
	volumes = ""		#	list of volumes to be assigned to tracks
	banks = ""		    #	list of bank numbers to be assigned to tracks
    reverbs = ""
    sysex = ""
    bankdefs = ""       #   defines a control sequence for programing a bank
    max_bankdef = 0
}

{


}


END {

	print "#	-----------------------------------------------------------"
	print "#	MIDI SCORE FILE   (from mtxheader.awk)"
	print "#	-----------------------------------------------------------"
	print "#"
	print "#	" name "	--	MTX file"
	print "#"

	if (tracks != "") {
		numtracks = split(tracks, tary, ",")
	}
	if (programs != "") {
		perr = split(programs, pary, ",")
	}
	if (volumes != "") {
		verr = split(volumes, vary, ",")
	}
	if (banks != "") {
		berr = split(banks, bary, ",")
	}
	if (sysex != "") {
		serr = split(sysex, sary, ",")
	}
	if (reverbs != "") {
		rerr = split(reverbs, rary, ",")
	}
    #
    #   bankdefs is different from programs,tracks,banks,etc., because
    #   it also has ";" separators
    #   The string received from pre_cs2mtx.awk should look similar to,
    #       bankdefs=c1,v1,c2,v2;c3,v3,c4,v4;c5,v5;c6,v6,c7,v7
    #   where each bank def corresponds to
    #       bank 0:  control message c1 v2 , control message c2 v2
    #       bank 1:  control message c3 v3 , control message c4 v4
    #       bank 2:  control message c5 v5
    #       bank 3:  control message c6 v6 , control message c7 v7
    #   where
    #       c1,c2,c3,... are MIDI control numbers (integers 0..127)
    #       v1,v2,v3,... are the control values   (integers 0..127)
    #
	if (bankdefs != "") {
        #
        #   split each bankdef on a "+" boundary
        #
		d1err = split(bankdefs, d1ary, "+")
        if (d1err > 0)
        {
            max_bankdef = d1err
            for (i=1; i <=d1err; i++)
            {
                #
                #   split the values with each bankdef statement
                #
                print "#    bankdef" i " = " d1ary[i]
                d2err = split(d1ary[i], d2ary, ",")
                if (d2err > 0)
                {
                    k = 1
                    jj=0
                    banksiz[i] = int(d2err / 2);
                    for (j=1; j<=d2err; j++)
                    {
                        if (jj % 2 == 0)
                        {
                            bankctr[i,k] = d2ary[j]
                        }
                        else
                        {
                            bankval[i,k] = d2ary[j]
                            k++
                        }
                        jj++
                    }
                }
                else
                {
                    #
                    #   something wrong, empty bankdef sequence between ";"s
                    #
                    bankctr[i,1] = 0;
                    bankval[i,1] = 63;
                    bankctr[i,2] = 32;
                    bankval[i,2] = 0;
                    banksiz[i] = 2;
                    print "ERROR: mtxheader.awk, empty bankdef"  |  "cat 1>&2"
                }
            }
        }
	}

	if (numtracks > 1) {
		print "MIDI_FORMAT multi_track"
	}
	else {
		print "MIDI_FORMAT single_track"
	}

	print "TRACKS " numtracks

	print "TICS_PER_BEAT " ticks
	print "#	-----------------------------------------------------------"

	for (i=1; i<= numtracks; i++) {


		if (tary[i] < 1 || tary[i] > 128) {
			#
			#	invalid channel number
			#	we allow this in the case where we need a dummy track
			#
			print "	0		META	TK" i "	MIDIPORT	" 0
			print "	0		META	TK" i "	TEMPO	" bpm
			print "	0		META	TK" i "	TIME_SIGNATURE	04	02	24	08"
			continue
		} # if -- invalid channel number

		print "	0		META	TK" i "	MIDIPORT	" int((tary[i]-1) / 16)
		print "	0		META	TK" i "	TEMPO	" bpm
		print "	0		META	TK" i "	TIME_SIGNATURE	04	02	24	08"
		if (tracks != "") {
			if (volumes != ""  &&  i <= verr) {
				print "	0		MIDI	TK" i "	CH" tary[i] "	CT7	VL" vary[i]
			}
			else {
				print "	0		MIDI	TK" i "	CH" tary[i] "	CT7	VL90"
			}
			if (banks != ""  &&  i <= berr) {
				#
				#	don't set a bank if it is set to -1
				#
                if (bary[i] >= 0) {
                    bank_no = bary[i]
                    if (bankdefs != "" && bank_no <= max_bankdef)
                    {
                        #
                        #   bank switch messages user-defined
                        #
                        kmax = banksiz[bank_no+1]
                        for (kk=1; kk <= kmax; kk++)
                        {
                            strCT = sprintf("   CT%d", bankctr[bank_no+1,kk])
                            strVL = sprintf("   VL%d", bankval[bank_no+1,kk])
                            print "	0       MIDI    TK" i "	CH" tary[i], strCT, strVL 
                        }
                    }
                    else
                    {
                        #   default (Yamaha ES)
                        print "	0		MIDI	TK" i "	CH" tary[i] "	CT0    VL63"
                        print "	0		MIDI	TK" i "	CH" tary[i] "	CT32   VL" bank_no
                    }
                }
			}
			if (sysex != ""  &&  i <= serr) {
				#
				#	don't set a sysex if it is set to -1
				#
				if (sary[i]  !=  "-1") {
                    #
                    #   replace underscores with spaces
                    #
                    sysex_str = ""
                    sysex_err = split(sary[i], sysex_ary, "_")
                    for (sysj=1; sysj <= sysex_err; sysj++)
                    {
                        if (sysj == 1)
                            sysex_str = sysex_ary[1]
                        else
                            sysex_str = sprintf("%s %s", sysex_str, sysex_ary[sysj])
                    }
					print "	0		SYSEX	TK" i "	CH" tary[i], sysex_str
				}
			}
			if (reverbs != ""  &&  i <= rerr) {
				#
				#	don't set a program if it is set to -1
				#
				if (rary[i] >= 0) {
                    reverb_no = rary[i]
					print "	0		MIDI	TK" i "	CH" tary[i] "	CT6    VL1"
					print "	0		MIDI	TK" i "	CH" tary[i] "	CT38   VL" reverb_no
				}
			}
			if (programs != ""  &&  i <= perr) {
				#
				#	don't set a program if it is set to -1
				#
				if (pary[i] >= 0) {
					print "	0		MIDI	TK" i "	CH" tary[i] "	PG" pary[i]
				}
			}
		}
	}


	print "#	-------------------------------------------------------------"

}

