home *** CD-ROM | disk | FTP | other *** search
/ Esprit de Apple Corps / EDAC-1.iso / MOD.Utilities / Info / MMD.TXT < prev    next >
Text File  |  1993-03-20  |  24KB  |  713 lines

  1.  
  2. -----------------------------------------------------------------------------
  3.         MED/OctaMED MMD0 and MMD1 file formats
  4.         written by Teijo Kinnunen (25.4.1992)
  5.         Revision 1
  6. -----------------------------------------------------------------------------
  7.  
  8. Background
  9. ~~~~~~~~~~
  10. A  couple of years ago, when programming MED V2.1, I needed a file format for
  11. MED  modules.   The  only  "module"  format  in  MED V2.0 was the Sng+samples
  12. format.  Although it produced compact files, it was very difficult and tricky
  13. to  read  in.  Therefore, I designed a new file format, that would be easy to
  14. use  in  module  player programs etc.  This file format was named 'MMD0' (Med
  15. MoDule  0).   The  limitations in MMD0 block format forced me to create a new
  16. file format for OctaMED Professional, this format is 'MMD1'.  It's mostly the
  17. same  as  MMD0, except the block structure is different.  At the time of this
  18. writing  (when  OctaMED  Pro is not even released yet), MMD0's are absolutely
  19. more common than MMD1's.
  20.  
  21. Design concepts
  22. ~~~~~~~~~~~~~~~
  23. One  of  the  main  goals  was  to  make MMD's (MED modules) as extensible as
  24. possible.   This  would  have  been  easy to implement with IFF-style chunks.
  25. However, this method is obviously not the best for play-routine use.
  26.  
  27. Therefore, MMD's are implemented in quite an extraordinary way.  They consist
  28. of  structures  (similar  to  C  structs),  and  pointers.  In a module file,
  29. pointers  are defined as offsets from the beginning of the module.  This way,
  30. a  particular  structure  can be read just by Seek()'ing using the pointer as
  31. the  offset from the beginning of the file.  When a module has been read into
  32. memory,  it has to be relocated before it can be used (the relocation is done
  33. simply by adding the address of the module to the pointers).
  34.  
  35. As  with  the  Amiga  OS,  a  MMD  file  does not contain absolute addresses.
  36. There's  a  module  header  structure  at  the  beginning  of the file.  This
  37. structure contains pointers to different parts of the module.  And you *MUST*
  38. use  these pointers.  You may NOT expect that the song structure is at offset
  39. $00000034,  for  example.   Although it usually is, this may change in future
  40. releases.   In  addition,  it's  possible that a structure even doesn't exist
  41. (the  structure  pointer is NULL).  Therefore, you *MUST* check the structure
  42. pointer  before  accessing  the  structure.   Finally, when writing MMD's you
  43. *MUST*  set  undefined/reserved  fields  to  zeros.  More finally, you *MUST*
  44. align  all  structures  to  even  boundaries!  (I forgot the alignment in MED
  45. V3.00 save routine, resulting Guruing modules under some conditions :-(
  46.  
  47. The module header
  48. ~~~~~~~~~~~~~~~~~
  49. This  structure must exist at the beginning of each MED module file.  Each of
  50. the structure members are described below.
  51.  
  52. In  multi-modules,  there  are header structs for each song.  (The subsequent
  53. header  pointers  can  be found from expdata structure.  Multi-modules should
  54. have  the  same  smplarr  pointer  in  every  header.) Older MEDs which don't
  55. recognize  multi-modules  consider a multi-module as an ordinary module (only
  56. the first song is loaded).
  57.  
  58. The numbers enclosed in /* */ at the beginning of each line are (decimal)
  59. offsets of each member (for assembly programmers).
  60.  
  61. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  62. struct MMD0 {
  63. /* 0 */        ULONG    id;
  64. /* 4 */        ULONG    modlen;
  65. /* 8 */        struct MMD0song *song;
  66. /* 12 */    ULONG    reserved0;
  67. /* 16 */    struct MMD0Block **blockarr;
  68. /* 20 */    ULONG    reserved1;
  69. /* 24 */    struct InstrHdr **smplarr;
  70. /* 28 */    ULONG    reserved2;
  71. /* 32 */    struct MMD0exp *expdata;
  72. /* 36 */    ULONG    reserved3;
  73. /* 40 */    UWORD    pstate;     /* some data for the player routine */
  74. /* 42 */    UWORD    pblock;
  75. /* 44 */    UWORD    pline;
  76. /* 46 */    UWORD    pseqnum;
  77. /* 48 */    WORD    actplayline;
  78. /* 50 */    UBYTE    counter;
  79. /* 51 */    UBYTE    extra_songs; /* number of songs - 1 */
  80. }; /* length = 52 bytes */
  81.  
  82. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  83. id
  84. --
  85. This longword is used to identify the MMD and its version.  Currently defined
  86. MMD  types are MMD0 (0x4D4D4430) and MMD1 (0x4D4D4431).  MMD2 and upwards are
  87. reserved for future versions.
  88.  
  89. In  multi-modules,  the  following  modules usually contain id MCNT, or MCN1.
  90. The first module always has MMD0 or MMD1 as an id.
  91.  
  92. modlen
  93. ------
  94. This longword contains the length of the entire module.
  95.  
  96. song
  97. ----
  98. Pointer to a MMD0song structure. This structure MUST ALWAYS EXIST!
  99.  
  100. blockarr
  101. --------
  102. Pointer to a table of block pointers. For example:
  103.     blockarr:  $00003000
  104.             block 0 ptr    block 1 ptr    block 2 ptr
  105. offset    $00003000:    $00002000,    $00002400,    $00002800 ....
  106.  
  107. offset    $00002000: block 0 data...
  108. offset    $00002400: block 1 data...
  109. ...
  110. The size of the table is MMD0song.numblocks longwords.
  111.  
  112. smplarr
  113. -------
  114. Pointer to a table of instrument pointers. The size of the table is
  115. MMD0song.songlen longwords. This pointer is zero in OctaMED Pro MMD1 songs.
  116. In this case, OctaMED Pro loads the instruments from disk(s).
  117.  
  118. expdata
  119. -------
  120. Pointer to an expansion structure.  The expansion structure contains a lot of
  121. extra  information.   The  exp.   structure does not exist in all MMD's.  (Be
  122. sure to check the pointer before using it.)
  123.  
  124. pstate, pblock, pline, pseqnum, actplayline, counter
  125. ----------------------------------------------------
  126. These  are  variables for the play routine.  You can read these fields to get
  127. the  current  song  position  (not all versions of the play routine use these
  128. fields,  however).   When writing a MMD, you should leave all fields to zero,
  129. except the 'actplayline', which ought to be -1 ($FFFF).
  130.  
  131. extra_songs
  132. -----------
  133. This  field  contains  the  number  of  songs  in  the  current  module.  For
  134. non-multi-modules,  this  is 0.  If there are two songs, extra_songs contains
  135. 1, and so on.
  136.  
  137. reserved0,1,2,3
  138. ---------------
  139. Not currently defined. Set to zero.
  140.  
  141.  
  142. The song structure (MMD0song)
  143. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  144. This  structure contains the basic information about the song.  It must exist
  145. on every module file.
  146.  
  147. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  148. struct MMD0song {
  149.     struct MMD0sample sample[63];    /* 63 * 8 bytes = 504 bytes */
  150.     UWORD    numblocks;        /* offs: 504 */
  151.     UWORD    songlen;        /* offs: 506 */
  152.     UBYTE    playseq[256];        /* offs: 508 */
  153.     UWORD    deftempo;        /* offs: 764 */
  154.     BYTE    playtransp;        /* offs: 766 */
  155.     UBYTE    flags;            /* offs: 767 */
  156.     UBYTE    flags2;            /* offs: 768 */
  157.     UBYTE    tempo2;            /* offs: 769 */
  158.     UBYTE    trkvol[16];        /* offs: 770 */
  159.     UBYTE    mastervol;        /* offs: 786 */
  160.     UBYTE    numsamples;        /* offs: 787 */
  161. }; /* length = 788 bytes */
  162.  
  163. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  164. sample
  165. ------
  166. Contains some basic info about each sample. The structure looks like this:
  167.  
  168. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  169.     struct MMD0sample {
  170.         UWORD rep,replen;    /* offs: 0(s), 2(s) */
  171.         UBYTE midich;        /* offs: 4(s) */
  172.         UBYTE midipreset;    /* offs: 5(s) */
  173.         UBYTE svol;        /* offs: 6(s) */
  174.         BYTE strans;        /* offs: 7(s) */
  175.     };
  176.  
  177. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  178.     rep        repeat start offset, shifted right one bit (as in
  179.             Protracker).
  180.     replen        repeat length, shifted right one bit.
  181.     midich        MIDI channel for current instrument, 0 if not MIDI.
  182.     midipreset    MIDI preset number for current instrument, 0 if no
  183.             preset.
  184.     svol        default volume for current instrument (0 - 64).
  185.     strans        instrument transpose value.
  186.  
  187. More information is defined in expdata structure.
  188.  
  189. numblocks
  190. ---------
  191. Number  of  blocks  in current song.  This field also indicates the length of
  192. the blockarr table in longwords.
  193.  
  194. songlen
  195. -------
  196. Song length (number of sequence numbers in the play sequence list).
  197.  
  198. playseq
  199. -------
  200. This is the play sequence list.
  201.  
  202. deftempo
  203. --------
  204. Default  song  tempo (the leftmost tempo slider in MED/OctaMED).  If BPM mode
  205. is on, this value indicates BPM.
  206.  
  207. playtransp
  208. ----------
  209. The global play transpose value for current song.
  210.  
  211. flags
  212. -----
  213. Contains many single-bit flags:
  214.     FLAG_FILTERON    0x1    the hardware audio filter is on
  215.     FLAG_JUMPINGON    0x2    mouse pointer jumping on (not in OctaMED Pro)
  216.     FLAG_JUMP8TH    0x4    jump every 8th line (not in OctaMED Pro)
  217.     FLAG_INSTRSATT    0x8     sng+samples indicator (not useful in MMD's)
  218.     FLAG_VOLHEX    0x10    volumes are HEX
  219.     FLAG_STSLIDE    0x20    use ST/NT/PT compatible sliding
  220.     FLAG_8CHANNEL    0x40    this is OctaMED 5-8 channel song
  221.  
  222.     (bit 0x80 is not defined, and must be set to zero)
  223.  
  224. flags2
  225. ------
  226. More flags, currently only BPM stuff:
  227.     FLAG2_BMASK    0x1F (bits 0-4)        BPM beat length (in lines)
  228.                         0 = 1 line, $1F = 32 lines.
  229.                     (The rightmost slider in OctaMED Pro
  230.                      BPM mode.)
  231.     FLAG2_BPM    0x20    BPM mode on
  232.  
  233.     (bits 0x40 and 0x80 are not defined, and must be set to zero)
  234.  
  235. tempo2
  236. ------
  237. This is the "secondary tempo" (the rightmost MED/OctaMED tempo slider),
  238. indicating the number of timing pulses per line.
  239.  
  240. trkvol[16]
  241. ----------
  242. The relative track volumes (1 - 64) for each track.
  243.  
  244. mastervol
  245. ---------
  246. The relative master volume (1 - 64).
  247.  
  248. numsamples
  249. ----------
  250. Number  of instruments (samples/synthsounds) in current song.  Also indicates
  251. the size of the smplarr table in longwords.
  252.  
  253.  
  254. The block format
  255. ~~~~~~~~~~~~~~~~
  256. As  described above, MMD0 header structure contains a pointer (blockarr) to a
  257. table of block pointers.  These block pointers point to the actual block data
  258. structures.  The format of these data structures differ in MMD0 and MMD1 file
  259. formats.
  260.  
  261. MMD0 block format
  262. -----------------
  263. At the beginning of each block, there's a small header:
  264.  
  265. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  266.     struct MMD0Block {
  267.         UBYTE numtracks,lines;
  268.     };
  269.  
  270. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  271.     numtracks    number of tracks (4, 8, 12 or 16) on this block
  272.     lines        number of lines on this block; 0 = 1 line,
  273.             255 = 256 lines
  274.  
  275. Following  this  header,  there is the actual note data, consisting of 3-byte
  276. structures  containing  a  note  and  its  command.   The  data  is  arranged
  277. sequentially a line at a time, i.e. in the following order:
  278.     line 0 track 0
  279.     line 0 track 1
  280.     line 0 track 2
  281.     line 0 track 3
  282.     line 1 track 0
  283.     line 1 track 1
  284.     ...
  285. The 3-byte structure looks like this (each letter corresponds to one bit):
  286.  
  287.     xynnnnnn iiiicccc dddddddd
  288.  
  289.     n = note number (0 - $3F). 0 = ---, 1 = C-1, 2 = C#1...
  290.     i = the low 4 bits of the instrument number
  291.     x = the 5th bit (#4) of the instrument number
  292.     y = the 6th bit (#5) of the instrument number
  293.     c = command number (0 - $F)
  294.     d = databyte ($00 - $FF)
  295.  
  296. MMD1 block format
  297. -----------------
  298. MMD1  block format can contain a lot more information than MMD0's.  The block
  299. header looks like this:
  300.  
  301. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  302.     struct MMD1Block {
  303.         UWORD numtracks;
  304.         UWORD lines;
  305.         struct BlockInfo *info;
  306.     };
  307.  
  308. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  309.     numtracks    Number of tracks in this block (4, 8, 12, or 16).
  310.     lines        Number of lines in this block (0 = 1 line etc.).
  311.             OctaMED Pro can handle upto 3200 lines/block, so
  312.             this is obviously the practical upper limit.
  313.     info        Pointer to structure containing extra information.
  314.             (Can be NULL, if no BlockInfo struct exists).
  315.  
  316.     The BlockInfo structure is:
  317.  
  318. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  319.     struct BlockInfo {
  320.         ULONG    *hlmask;
  321.         UBYTE    *blockname;
  322.         ULONG    blocknamelen;
  323.         ULONG    reserved[6];
  324.     };
  325.  
  326. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  327.     hlmask        Pointer to an array of longwords, containing info
  328.             about line highlighting (TAB key on MED). The number
  329.             of longwords depend on the number of lines on the
  330.             block. (E.g: 1 line -> 1 longword, 32 lines -> 1 lw,
  331.             33 lines -> 2 lws, 256 lines -> 4 lws)
  332.             The bits in the longwords are arranged in reversed
  333.             order (e.g. bit #0 = line 0, bit #31 = line 31).
  334.  
  335.     blockname    Pointer to the name of the block. Must be null-
  336.             terminated.
  337.  
  338.     blocknamelen    Length of the block name, including the terminating
  339.             zero. OctaMED Pro currently has the maximum length of
  340.             41 chars (+ zero). However, this may change in the
  341.             future. Don't read blocknames longer than you are
  342.             able to handle!
  343.  
  344.     reserved[6]    These are reserved for future extensions. Must be set
  345.             to zero.
  346.  
  347.     The note structures, which are 4 bytes long in MMD1 modules, are
  348.     arranged exactly as in MMD0 modules.
  349.  
  350.         xnnnnnnn xxiiiiii cccccccc dddddddd
  351.  
  352.     n = note number (0 - $7F, 0 = ---, 1 = C-1...)
  353.     i = instrument number (0 - $3F)
  354.     c = command ($00 - $FF)
  355.     d = databyte ($00 - $FF)
  356.     x = undefined, reserved for future expansion. MUST BE SET TO ZERO,
  357.         AND MASKED OUT WHEN READING THE NOTE OR INSTRUMENT NUMBER.
  358.  
  359.  
  360. The instrument format
  361. ~~~~~~~~~~~~~~~~~~~~~
  362. The  MMD0  header  structure  contains  a  pointer  (smplarr)  to  a table of
  363. instrument  pointers.   These  pointers  point  to the actual instrument data
  364. structures.   If an instrument pointer is zero, there's no instrument in that
  365. slot.
  366.  
  367. Every  instrument  has a six-byte header structure, which is the same for all
  368. instrument types (sample/synth/hybrid).
  369.  
  370. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  371.     struct InstrHdr {
  372.         ULONG    length;
  373.         WORD    type;
  374.         /* Followed by actual data */
  375.     };
  376.  
  377. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  378.     length        indicates the length of the instrument (the six byte
  379.             header data length is not included)
  380.     type        instrument type - currently the following types are
  381.             defined:
  382.  
  383.         HYBRID        -2
  384.         SYNTHETIC    -1
  385.         SAMPLE        0    (an ordinary 1-octave sample)
  386.         IFF5OCT        1    (5 octaves)
  387.         IFF3OCT        2    (3 octaves)
  388.         (The following ones are recognized by OctaMED Pro only)
  389.         IFF2OCT        3    (2 octaves)
  390.         IFF4OCT        4    (4 octaves)
  391.         IFF6OCT        5    (6 octaves)
  392.         IFF7OCT        6    (7 octaves)
  393.  
  394. The sample-type instruments (>= 0) contain the actual sample data straight
  395. after the header structure.
  396.  
  397. Synthetic instruments
  398. ---------------------
  399. Synthsounds  have  a  special  structure  of  their  own.   They also contain
  400. waveforms and pointers to them.  Therefore, relocation is required.  However,
  401. there's  an  important  difference:  pointers are expressed as an offset from
  402. the  beginning  of  the  synthsound,  NOT  the  beginning of the module.  The
  403. 'reloc.a' routine provided with MED/OctaMED automatically handles this.
  404.  
  405. The synthsound structure is as follows (note that this structure contains the
  406. header structure):
  407.  
  408. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  409.     struct SynthInstr {
  410.         ULONG    length;        /* length of this struct */
  411.         WORD    type;        /* -1 or -2 (offs: 4) */
  412.         UBYTE    defaultdecay;
  413.         UBYTE    reserved[3];
  414.         UWORD    rep;
  415.         UWORD    replen;
  416.         UWORD    voltbllen;    /* offs: 14 */
  417.         UWORD    wftbllen;    /* offs: 16 */
  418.         UBYTE    volspeed;    /* offs: 18 */
  419.         UBYTE    wfspeed;    /* offs: 19 */
  420.         UWORD    wforms;        /* offs: 20 */
  421.         UBYTE    voltbl[128];    /* offs: 22 */
  422.         UBYTE    wftbl[128];    /* offs: 150 */
  423.         struct    SynthWF *wf[64]; /* offs: 278 */
  424.     };
  425.  
  426. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  427.     defaultdecay    = the default decay of the current synthsound. This
  428.               is NOT used in modules. It's significant only when
  429.               saving a single synthsound.
  430.  
  431.     reserved[3]    = set to zero.
  432.  
  433.     rep, replen    = repeat/rep. length for hybrid sounds. Used only
  434.               when saving a single hybrid sound.
  435.  
  436.     voltbllen    = the length of the volume sequence table.
  437.  
  438.     wftbllen    = the length of the waveform sequence table.
  439.  
  440.     volspeed    = the initial volume table execution speed.
  441.  
  442.     wfspeed        = the initial waveform table execution speed.
  443.  
  444.     wforms        = the number of waveforms in the current synthsound.
  445.  
  446.     voltbl        = the actual volume sequence table. Values $00-$7F
  447.               are volumes or command arguments. Values >= $80 are
  448.               commands. The following commands are currently
  449.               defined:
  450.                 $FF END        $F4 EN1
  451.                 $FE JMP        $F3 CHU
  452.                 $FB HLT        $F2 CHD
  453.                 $FA JWS        $F1 WAI
  454.                 $F6 EST        $F0 SPD
  455.                 $F5 EN2
  456.  
  457.     wftbl        = the actual waveform sequence table. Values $00-$7F
  458.               are waveform numbers  or command arguments. Values
  459.               >= $80 are commands. The following commands are
  460.               currently defined:
  461.                 $FF END        $F6 RES
  462.                 $FE JMP        $F5 VBS
  463.                 $FD ARE        $F4 VBD
  464.                 $FC ARP        $F3 CHU
  465.                 $FB HLT        $F2 CHD
  466.                 $FA JVS        $F1 WAI
  467.                 $F7 VWF        $F0 SPD
  468.  
  469.     wf        = pointers to waveforms. (Once again: relative to the
  470.               beginning of the synthsound!) A waveform structure
  471.               is as follows:
  472.  
  473.                 struct SynthWF {
  474.                     UWORD length;    /* length in words */
  475.                     BYTE  wfdata[xx]; /* the waveform */
  476.                 };
  477.  
  478.                 (where xx = length in bytes)
  479.  
  480.               In hybrid sounds, however, wf[0] is different.
  481.  
  482. Hybrid instruments
  483. ------------------
  484. Hybrid  sounds  use  the same structure as synthsounds, except that the first
  485. waveform  (wf[0])  pointer  points to a sample.  (The sample header structure
  486. exists, as usual.)
  487.  
  488.  
  489. MMD0exp - the key to future expansions
  490. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  491. For  possible  future  expansions,  I  designed  a structure for carrying the
  492. miscellaneous things that were added to MED/OctaMED now and then.  (MED V3.00
  493. was the first version, which wrote this structure.) Most of its fields are in
  494. use  now,  but it's possible to even expand this structure (things will get a
  495. bit more tricky, though).
  496.  
  497. In multi-modules, you should extract all data from the expansion structure of
  498. the  first  song.   The  only  exceptions  are  currently  the  'nextmod' and
  499. 'songname' fields, which are song-specific.
  500.  
  501. Also,  there  has  been  need  for  extending the MMD0sample structure.  Both
  502. InstrExt  and  MMDInstrInfo  provide extra information about the instruments.
  503. These  are  defined as structure arrays (exp_smp and iinfo point to the first
  504. structure).  The extension structures don't have a constant size, instead you
  505. have  to  read s_ext_entrsz or i_ext_entrsz to get the structure sizes.  When
  506. reading,  you  have to check the entrsz fields to see which structure members
  507. do exist.
  508.  
  509. The  difference  between  InstrExt and MMDInstrInfo is that InstrExt contains
  510. information the play-routine is interested in (e.g.  finetune).  MMDInstrInfo
  511. contains  "secondary"  information,  which is of no use to the player routine
  512. (e.g.  instrument name).
  513.  
  514. The expansion structure follows:
  515.  
  516. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  517.     struct MMD0exp {
  518.         struct MMD0 *nextmod;
  519.         struct InstrExt *exp_smp;
  520.         UWORD  s_ext_entries;
  521.         UWORD  s_ext_entrsz;
  522.         UBYTE  *annotxt;
  523.         ULONG  annolen;
  524.         struct MMDInstrInfo *iinfo;
  525.         UWORD  i_ext_entries;
  526.         UWORD  i_ext_entrsz;
  527.         ULONG  jumpmask;
  528.         UWORD  *rgbtable;
  529.         UBYTE  channelsplit[4];
  530.         struct NotationInfo *n_info;
  531.         UBYTE  *songname;
  532.         ULONG  songnamelen;
  533.         struct MMDDumpData *dumps;
  534.         ULONG  reserved2[7];
  535.     };
  536.  
  537. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  538.     nextmod        = pointer to the next module (or zero). (Only used in
  539.               multi-modules!)
  540.  
  541.     exp_smp        = pointer to InstrExt. Currently the first four bytes
  542.               of InstrExt have been defined:
  543.  
  544.                 struct InstrExt {
  545.                     UBYTE hold;
  546.                     UBYTE decay;
  547.                     UBYTE suppress_midi_off;
  548.                     BYTE  finetune;
  549.                 };
  550.  
  551.                 hold, decay    = hold/decay values of the
  552.                           instrument
  553.  
  554.                 suppress_midi_off = 0 (FALSE) or not (TRUE)
  555.  
  556.                 finetune    = instrument finetune (-8-+7)
  557.  
  558.     s_ext_entries    = the size of InstrExt structure array (i.e. the
  559.               number of InstrExt structures).
  560.  
  561.     s_ext_entrsz    = the size of each InstrExt structure (in bytes).
  562.  
  563.     annotxt        = pointer to the annotation text (null-terminated).
  564.  
  565.     annolen        = length of 'annotxt', including the terminating \0.
  566.  
  567.     iinfo        = pointer to MMDInstrInfo. Currently the first forty
  568.               bytes have been defined:
  569.  
  570.                 struct MMDInstrInfo {
  571.                     UBYTE    name[40];
  572.                 };
  573.  
  574.                 name = null-terminated instrument name
  575.  
  576.     i_ext_entries    = the size of the MMDInstrInfo struct array (i.e. the
  577.               number of MMDInstrInfo structures).
  578.  
  579.     i_ext_entrsz    = the size of each MMDInstrInfo struct in bytes.
  580.  
  581.     jumpmask    = a mask controlling which instruments cause the
  582.               mouse pointer to jump. E.g. bit #1 = instr. #1.
  583.               This field has become obsolete in OctaMED Pro.
  584.  
  585.     rgbtable    = pointer to eight UWORDs (screen colors) to be
  586.               passed to LoadRGB4() routine.
  587.  
  588.     channelsplit    = this longword is divided to four boolean bytes,
  589.               controlling channel splitting in OctaMED 5 - 8 chnl
  590.               modes. (A non-zero byte means that the channel is
  591.               NOT splitted.) Currently only the following
  592.               combinations should be used:
  593.  
  594.               0x00000000 (8 channels (or normal 4 channel mode))
  595.               0x000000FF (7 channels)
  596.               0x0000FFFF (6 channels)
  597.               0x00FFFFFF (5 channels)
  598.  
  599.     n_info        = pointer to NotationInfo structure (used only in
  600.               OctaMED V2.0 and later). It contains some info for
  601.               the notation editor.
  602.  
  603.                 struct NotationInfo {
  604.                     UBYTE n_of_sharps;
  605.                     UBYTE flags;
  606.                     WORD  trksel[5];
  607.                     UBYTE trkshow[16];
  608.                     UBYTE trkghost[16];
  609.                     BYTE  notetr[63];
  610.                     UBYTE pad;
  611.                 };
  612.  
  613.               n_of_sharps    = number of sharps or flats (0 - 6)
  614.               flags        = misc. bits, these are defined:
  615.                         NFLG_FLAT    1
  616.                     (= use flats instead of sharps)
  617.                         NFLG_3_4    2
  618.                     (= display 12 lines instead of 16)
  619.  
  620.               trksel    = the number of the selected track,
  621.                       for each display preset
  622.                         (-1 = no track selected)
  623.  
  624.               trkshow    = tracks shown (five bits used in
  625.                         each byte, bit #0 = preset 1, etc.)
  626.  
  627.               trkghost    = tracks ghosted (as in 'trkshow')
  628.  
  629.               notetr    = note transpose value for each
  630.                         instrument (-24 - +24). If bit 6 is
  631.                       negated, the instrument is hidden.
  632.  
  633.               pad        = possibly holding info about struct
  634.                         expansions in the future. Don't
  635.                         touch!
  636.  
  637.     songname    = song name of the current song (0-terminated).
  638.               Each song of a multi-module can have a different
  639.               name.
  640.  
  641.     songnamelen    = song name length (including the terminating zero).
  642.  
  643.     dumps        = MIDI dump data (created using OctaMED Pro MIDI
  644.               message editor). The 'dumps' field points to the
  645.               following struct:
  646.  
  647.                 struct MMDDumpData {
  648.                     UWORD    numdumps;
  649.                     UWORD    reserved[3];
  650.                 };
  651.  
  652.               Immediately after this struct, there are 'numdumps'
  653.               pointers to the following struct:
  654.  
  655.                 struct MMDDump {
  656.                     ULONG    length;
  657.                     UBYTE    *data;
  658.                     UWORD    ext_len;
  659.                     /* if ext_len >= 20: */
  660.                     UBYTE    name[20];
  661.                 };
  662.  
  663.               length    = length of the MIDI message dump.
  664.  
  665.               data        = pointer to the actual MIDI dump
  666.                         data.
  667.  
  668.               ext_len    = MMDDump struct extension length.
  669.                         For flexible future expansion.
  670.  
  671.               (if ext_len >= 20, the following fields exist)
  672.  
  673.               name        = name of the dump.
  674.  
  675.     reserved2    = future expansion fields, that MUST be zero now.
  676.  
  677. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  678. Finally, here is a collection of the most important rules you should obey
  679. when handling MMD's:
  680.  
  681.     * ALWAYS USE POINTERS, NOT ABSOLUTE OFFSETS.
  682.  
  683.     * CHECK THAT A POINTER IS NONZERO BEFORE ACCESSING ANYTHING IT
  684.       POINTS TO.
  685.  
  686.     * WHEN WRITING, SET UNDEFINED/RESERVED BITS AND BYTES TO ZERO.
  687.       WHEN READING, MASK OUT UNDEFINED BITS, AND DON'T USE UNDEFINED
  688.       FIELDS.
  689.  
  690.     * WHEN WRITING, ALWAYS ALIGN EVERYTHING TO EVEN BOUNDARIES.
  691.  
  692.     * WHEN WRITING, ALWAYS WRITE THE SONG STRUCTURE.
  693.  
  694.     * REMEMBER TO HANDLE ERROR SITUATIONS CORRECTLY (IN ALL PROGRAMS,
  695.       NOT ONLY WHEN HANDLING MMDs ;^)
  696.  
  697. If  you  don't  understand  some  part  of this file completely, try saving a
  698. module using MED, and then examine the file with a file editor.  This way you
  699. can learn easily about the file format of MED/OctaMED.
  700.  
  701. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  702.  
  703. I  hope this document will help programmers who wish to be able to handle MED
  704. modules  in  their  programs.   This  text  file  is  in  PUBLIC DOMAIN.  All
  705. distribution of this file is strongly encouraged.  Thank you!
  706.  
  707.     Teijo Kinnunen
  708.     Oksantie 19
  709.     SF-86300  OULAINEN
  710.     FINLAND
  711.  
  712. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  713.