/*
 * MUSIC.H
 *   Defines for Music Studio song structure
 *
 * Music studio songs consist of a header portion, a setup frame, and
 *  zero or more frames.  The header portion corresponds to a Music Studio
 *  sound file, and defines the synthesized instruments associated with
 *  the song.  The setup frame defines the key signature, time signature,
 *  tempo, and volume for the song.  These values are defined once and may
 *  not change during the song.  
 *  The setup frame is followed by the frames making up the song.  Each frame
 *  is displayed as a column of notes on the screen.  Frames are of variable
 *  length; a frame always starts with a zero, and continues up to the next
 *  zero in the song.  The first command of every frame must be the minimum
 *  duration command in the frame.  A frame that contains no notes or rests
 *  does not have a duration.  After the first, minimum duration, command,
 *  commands may be in any order;  the frame does not have to be sorted by
 *  command duration. 
 *
 *  Commands
 *  --------
 *    The first byte of a command has the high bit set.  It is followed
 *    by zero or more data bytes, depending on the command.
 *
 *   Turn on voice as note or rest: 3 byte command
 *     Byte 1 = Command byte:
 *       Bit 7: set to 1 to indicate that this is a command 
 *       Bit 6: set if this is a note tied to a subsequent note
 *          (tie will extend to next note of the same frequency)
 *       Bit 5: set if this is a note tied to a prior note
 *       Bit 4: set if this is a rest, clear if a note
 *       Bits 3-0: which instrument (color) plays this note (unused for rests)
 *         possible instrument numbers are 1-15
 *     Byte 2: Duration byte:
 *       Bit 7,6: Accidental status
 *         00: not an accidental, played in key
 *         01: note is played and displayed as a natural
 *         10: note is played and displayed as a sharp
 *         11: note is played and displayed as a flat
 *       Bit 5: Accented note: play this note at maximum volume
 *       Bits 0-4: Duration information: index into DurTab
 *     Byte 3: Frequency byte
 *       Bits 6-0: MIDI tone byte 1-127
 *         If the note is not an accidental, then the actual frequency
 *         will be keytab[MIDI tone byte]
 *
 *   Measure Bar: one byte command
 *     Byte 1 = 0x81
 *   
 *   Start Repeat: two byte command
 *     Byte 1 = 0x85
 *     Byte 2 = number of times to repeat
 *
 *   End Repeat: one byte command
 *     Byte 1 = 0x86
 *
 *   End of Song: one byte command
 *     Byte 1 = 0xFF
 */

#define  MAXCOLORS   15    /* Maximum # of Music Studio instruments */
  
  /* return true if Cmd points to start of Music Studio command */
#define Is_MS_Cmd(Cmd)        (((Cmd)->colbyt) < 128)
#define Is_MS_Accented(Cmd)  ((((Cmd)->durbyt) & 0x20) != 0)

#define TIEMASK   0x70     /* mask to get tie status bits : */
#define STARTTIE  0x40     /* note is tied to subsequent note */
#define ENDTIE  0x20       /* note is tied to prior note */
#define MIDTIE  0x10       /* note is in middle of tie */

#define ACCMASK      0xC0  /* mask to get accidental status bits: */
#define NOTACCIDENT  0x00  /* 0000 0000 */
#define NATURAL      0x40  /* 0100 0000 */
#define SHARP        0x80  /* 1000 0000 */
#define FLAT         0xC0  /* 1100 0000 */

#define KEYOFC 1
#define KEYOFCS 8

/* Music Studio command type constants */
#define FRAMEMARK 0x00     /* Start of frame delimiter */
#define SONGEND   0xFF     /* End of Song mark */
#define CHGKEY    0x80     /* Change Key Signature command */
#define CHGTEMPO  0x81     /* Change Tempo command */
#define MEASURE   0x82     /* Measure bar command for MS editor */
#define SETTSIG   0x83     /* Change Time Signature command */
#define CHGVOL    0x84     /* Change Volume command */
#define BEGREP    0x85     /* Repeat begin command */
#define ENDREP    0x86     /* Repeat end comand */

/*
 * Structure of a Music Studio command
 */
typedef struct {
   UBYTE colbyt;     /* cmd:1; ties:2, rest:1, color:4 */
   UBYTE durbyt;     /* accidental:2, accent:1, duration: 5 */
   UBYTE freq;       /* MSB of this byte not used: 0-127 */
} MCmd;

struct Ainstr
{
   char  vol[7][8];           /* seven steps for each harmonic */
   short time[7];             /* time = 1-300 in steps of 10 millisec. */
   char  harmnum[7];          /* harmonic number 1-31,32=Noise,>33=Off */
   char  lrchnl;              /* bit 0 = left channel allocation flag */
                              /* bit 1 = right channel allocation flag */
                              /* bit 2 = vibrato field */
                              /* bit 3 = tremolo flag */
                              /* bit 4 = sustain flag */
   char  vibrato;             /* vibrato level 1-5 */
   char  tremolo;             /* tremolo level 1-5 */
};

/*
 * Music Studio Song array
 */
/*
      mshead            10 bytes          /0xcdMstudio0xcd "
      adsrname          150 bytes         15 9-byte (+NULL) adsr names
      adsrtbl           15*sizeof(Ainstr)  15 Ainstr adsr entries
      midname           150 bytes         15 9-byte (+NULL) midi names
      midcha            15 bytes          15 1-byte midi channel numbers
      midpre            15 bytes          15 1-byte midi preset numbers
*/

#define SNDLEN (10+150+sizeof(struct Ainstr)+150+150+15)

/*
----------------   SOUND FILES END HERE  -----------------

      vptrs             16 bytes          4 4-byte verse text ptrs
      textend           4 bytes           1 4-byte end-of-text pointer
      stitle            32 bytes          32 bytes of song title
      tracks            8 bytes           4 2-byte track indicators
      song              32000 bytes       Song area - about 8000 notes

Structure of the setup frame of a Music Studio song:


      DANGER DANGER WARNING WARNING:
         Some 'older' Music Studio files may not have these
         commands in this order.  Also, at least SETTSIG may be missing
         E.G. canon.song,canon2.song

         song[0] = FRAMEMARK     'Setup' frame

         song[1] = CHGKEY        Change Key
         song[2] = 1             Staff number -- not used
         song[3] = key           Key Signature for this song

         song[4] = SETSIG        Set Time Signature
         song[5] = curtsig       current time signature

         song[6] = CHGTEMPO      Change tempo
         song[7] = tempo         current tempo

         song[8] = CHGVOL        Change Volume
         song[9] = 1             Staff number - not used
         song[10] = volume       current volume

         song[11] = 0            'beginning of song' frame

         song[12] = SONGEND      Current end of song

*/
   /* maximum length of a Music Studio song */
#define MAXMSLEN (10+150+(15*sizeof(struct Ainstr))+150+15+15+4*4+4+32+8+32000)

/* Offsets into song[] of initial parameters */
/* and intro.song defaults in case commands not found in startup frame */
#define  INITIAL_KEY 3
#define  DEFAULT_KEY 0x09
#define  INITIAL_TIME 5
#define  DEFAULT_TIME 0x05
#define  INITIAL_TEMPO 7
#define  DEFAULT_TEMPO 0xA0
#define  INITIAL_VOLUME 10
#define  DEFAULT_VOLUME 0x7F

/* Offset into song[] of start of actual song data */
#define  FIRST_FRAME 11

/* Maximum length of a Music Studio score name */
#define  MS_NAME_MAX 32

/* height of all rests on staff */
#define  MS_REST_HEIGHT 0x50

typedef struct {
   char  *TrakData;
   int   TrakSize;      /* size of TrakData in bytes */
   int   CurrEvent;     /* current note being filled in TrakData */
   LONG  CurrTime;      /* current time in 144ths of a whole note */
   int   TimeToGo;      /* Time to go on note being played, or 0 if free */
   int   Ins1Reg;       /* IFF Instrument Register for this track */
} MSTrak;

extern   MSTrak Traks[];

/* Forward References */

extern   UBYTE MSDurTab[];       /* Array of MS Duration table indices */
extern   char  TimeSigTab[];        /* Array of MS Time signatures by IFF */

#define  MAX_MS_TSIG    7        /* 6/8 time in Music Studio is max */
#define  MS_TSIG44      5        /* 4/4 is default time sig for SMUS */

extern   char  keychart[];          /* Used to build keytab from key sig */
extern   char  keytab[];            /* Table used to play in key */

extern   int   DurTab[];            /* Durations of notes in 144ths */

#define  MS_WHOLE_NOTE 18

extern   int   RestTab[];
extern   int   RestDurInd[];

#define  MAX_REST 5

extern   int   IFFDurTab[];
extern   char  msinit[];
extern   char  mshead[];            /* MS song array incl. header+song */

extern   int   MaxTracks;           /* Maximum number of tracks to create */
extern   BOOL  IFFChords;           /* True when setting IFF Chord bits */
extern   BOOL  Debug;

extern   int   NumNotes[];

extern   char  *stitle;             /* Title of MS song */
extern   char  *song;               /* Start of MS Song data */
extern   char  *midcha;		    /* Start of MIDI channel array */
extern   char  *midpre; 	    /* Start of MIDI preset array */
extern   char  *adsrname;	    /* Start of instrument name array */

extern   char  *cursng;             /* Cursor points into MS song */

extern   char  *MakeName();         
extern   char  *MakeInName();
extern   BOOL  IsMSFile();

