Maestro Music File format

Values are in hexadecimal
(B) indicates byte value
(W) indicates BASIC integer value; 5 bytes, 1st byte is hex 40, 4-byte value follows, lsbyte last.

Start of File

"Maestro" 0D (B) (carriage return)

02 (B) indicates type 2 music file

        (type 1 is old type not considered here)

Each section that follows starts with a byte 'label' indicating which section follows. Thus the sections may appear in any order. The labels are given on the left hand side:

01 indicates Music data follows (detailed description below) (W) number of 'Gates'
for C = 1 to 8

     {
     (W) length of queue of notes and rests in channel C (in bytes)
         (data for each note or rest occupies 2 bytes)
     }
for G=1 to Number of Gates (input above)
     {
     (B) data for gate G
     }
for C = 1 to 8
     {
     for Q = 1 to length of note queue in channel C (read above)
       {
       (B)(B) data for note or rest in channel C at point Q in queue
          (data for each note occupies 2 bytes)
       }
     }

02 indicates Stave data follows
(B) (0..3) number of music staves
(B) (0..1) number of percussion staves

03 indicates Instrument data follows
(instrument names are not recorded; only channel numbers) 8 times:

     {
     (B) channel number - 1;  1..8   (redundant, always consecutive 1..8)
     (B) voice number; 0 = no voice attached
     }

04 indicates Volume data follows
for n= 1 to 8

     {
     (B) Volume on channel n = 0..7 = ppp..fff
     }

05 indicates Stereo position data follows for n= 1 to 8

     {
     (B) Stereo position of channel n = 0..7 = Full Left..Full Right
     }

06 indicates Tempo data follows
(B) 0..14;

End Of File

/ Aside

Suggested extensions:

  1. Permit any number of repetitions of the above data within one file to allow for changes in any parameters, such as tempo or volume, in the middle of a piece of music.
    Parts of the piece could be edited as separate files in Maestro, and then concatenated to make an entire piece (retaining the separate files for continued editability.
    Only if complete compatibility is required, would it be necessary to modify Maestro,
  2. Add extra section (labelled 7) for title string of piece of music as zero-byte-terminated string.
  3. Add extra section (labelled 8) for text string names of instruments Each name should be zero-byte-terminated, and should define the names of each voice number used in ascending order in section 3. This section should be terminated by an extra zero byte (2 consecutive) to ensure it is simple to scan through. It is, however not obvious what should be done if the instrument isn't installed. Perhaps give a warning on starting to play.
  4. Add extra section (labelled 9) for MIDI channels setup information for C = 1 to 8
    {
    (B) MIDI channel number on this stave channel C. 1..16; 0 = not transmitted over MIDI } / End Aside

    Detailed description of Music Data

    There are 9 queues:

    1 Queue of 1- or 2-byte 'Gates'.
    A 'Gate' is a point in the music when something is interpreted - e.g. a note, time-signature, key-signature, bar-line

            or clef can each occupy a gate
    
    the gate data is 1 byte for a note or rest; 2 bytes for an attribute (time-signature, key-signature, bar-line or clef) {
    byte 0 = 0 -> Music Attribute follows: {
    byte 1 is prefix-encoded data for time-signature, key-signature, clef, slur, octave or bar:
          bit 0     = 1   -> Time signature:
            bit 1..4  = Number of beats - 1;  1..16
            bit 5..7 = Beat type - 1;         1..8 
    
         or
          bit 0..1  = 01 (binary)  -> Key signature
            bit 2      0 = #, 1 = b
            bit 3..5   0..7
    
         or
          bit 0..2  = 001 (binary) -> Clef
            bit 3..4  0 = Treble, 1 = Alto, 2 = Tenor, 3 = Bass
            bit 5..6  Stave - 1;  1..4
    
         or
          bit 0..3  = 0001 (binary) -> Slur  *
            bit 4     1 = on; 0 = off
            bit 6..7  Stave - 1;  1..4
    
          or
          bit 0..4  = 00001 (binary) -> Octave shift  *
            bit 5     0 = up, 1 = down
            bit 6..7  Stave - 1;  1..4
    
          or
          bit 0..5  = 000001 (binary) -> Bar
    
          or
          bit 0..6  = 0000001 (binary) -> Reserved   (for what?)
    
    }

    or
    byte 0 > 0 -> Gate Mask.
    bit n = 1 -> gate 1 note/rest from queue n (n=0..7) }

    8 Queues of Notes and Rests, data for each is 2 bytes: Note (bits 3..7 > 0) or Rest (bits 3..7 = 0)

    If a rest coincides with a note, its position is determined by the following note on the same channel.

      bit       Rest     Note
      0          0     Stem orientation : 0 = up; 1 = down;
      1          0     1 = Join beams (barbs) to next note *
      2          0     1 = tie with next note
      3..7       0     Stave line position, 1..31; 16=centre line
      8..10      0     Accidental 0 = natural, 1 = sharp, 2 = flat,
                                  3 = double-sharp, 4 = double-flat,
                                  5 = natural-sharp, 6 = natural-flat.
    
    11..12 number of dots: 0..3
    13..15 type: breve = 0 to hemidemisemiquaver = 7