Changes

Jump to navigation Jump to search

MIDI format

10,781 bytes added, 17:33, 12 March 2005
no edit summary
This = Standard MIDI File (SMF) Format = The <B>Standard MIDI File</B> (SMF) is a file is an archive the contains 117 files. I created map format used to store MIDI data (plus someother kinds of data typically needed by reading [[FF8/Menu_mngrphd_bin|mngrphda sequencer.bin]] and filling in  This format stores the standard MIDI messages (ie, status bytes with appropriate data from [http://forums.qhimm.com/index.php?topic=17099.0 FF8 bytes)plus a time- mngrp.bin by JWP].stamp for each message (ie, a series of bytes that represent how many clock pulses==Mapped Data=={| class=to wait before "wikitableplaying"the event). The format also allows saving information about tempo,|-time and key signatures, the names of tracks and patterns, and other information typically! Posneeded by a sequencer. One SMF can store information for numerous patterns and tracks so that any! Seeksequencer can preserve these structures when loading the file.! Size! Filename<B><FONT COLOR=RED>NOTE:</FONT></B> A <B>track</B> usually is analogous to one musical part,! Description|-| 0| 0x0| 0x800| [[FF8/Menu_tkmnmes|tkmnmes1such as a Trumpet part.bin]]| Encoded string archiveStarts with padding valuesA <br/B>Has location values before stringspattern<br/B>would be analogous to all of the musical parts (ie,Strings end with '''0x00'''Trumpet, Drums, Piano, etc) for one song.|-| 1The format was designed to be generic so that the most important data can be read by all| 0x800| 0x1800| [[FF8/Menu_tkmnmes|tkmnmes2sequencers.bin]]Think of a MIDI file as a musical version of an ASCII text file (except| Encoded string archivethat the MIDI file contains binary data), and the various sequencer programs as text editorsStarts with padding valuesall capable of reading that file. But, unlike ASCII, MIDI file format saves data in <br/B>Has location values before stringschunks<br/B>Strings end with '''0x00'''(ie, groups of bytes preceded by an ID and size) which can be parsed, loaded, skipped, etc.|-Therefore, SMF format is flexible enough for a particular sequencer to store| 2its own proprietary, "extra" data in such a way that another sequencer won't be confused when| 0x2000loading the file and can safely ignore this extra stuff that it doesn't need.| 0x2000For example, maybe a sequencer wants to save a "flag byte"| [[FF8/Menu_tkmnmes|tkmnmes3that indicates whether the user has turned on an audible metronome click.bin]]The sequencer can save| Encoded string archivethis flag byte in such a way that another sequencer can skip this byte withoutStarts with padding values<br/>having to understand what that byte is for. In the future, the SMF format can also beHas location values before strings<br/>extended to include new "official" chunks that all sequencer programs may elect to load and use.Strings end with '''0x00'''This can be done without making old data files obsolete, nor making old sequencers no longer|-| 3able to load the new files. So, the format is designed to be| 0x4000extensible in a backwardly compatible way.| 0xE000|Of course, SMF files may be used by other MIDI software than just sequencers.|Since SMF files can store any and all types of MIDI messages, including System Exclusive|-messages, they may be used to store/load data by all kinds of MIDI software, such as a Patch| 4Editor that wants to save some System Exclusive messages it received from a MIDI module. (The| 0x12000"timestamp" for each message may be irrelevant to such a Patch Editor. But it's easily| 0x1000ignored for programs that don't really need it).||In conclusion, any software that saves or loads MIDI data should use SMF format for its data|-files.| 5| 0x13000== Chunks ==| 0x6800| [[FF8Data is always saved within a <B>chunk</Menu_sp2#Content_of_face1B>.tex_and_face2There can be many chunks inside of a MIDI file.tex|face1.tim]]| Character portraits|Each chunk can be a different size (and likely will be). A chunk's size is how many (8-bit)| 6bytes are contained in the chunk.| 0x19800| 0x6800| [[FF8/Menu_sp2#Content_of_face1The data bytes in a chunk are typically related in some way.tex_and_face2For example, all of the bytes in one chunk may be for one particular sequencer track.tex|face2The bytes for another sequencer track may be put ina different chunk. So, a chunk is simply a group of related bytes.tim]]| GF portraits|-Each chunk must begin with a 4 character (ie, 4 ascii bytes) <B>ID</B> which tells what "type"| 7of chunk this is.| 0x20000| 0x800| magitaThe next 4 bytes must form a 32-bit length (ie, size) of the chunk.tim| Tutorial/Magazine background texture|-| <U>All chunks must begin with these two fields</U> (ie, 8bytes), which are referred to as the| 0x20800| 0xE000| start00_and_start01<B>chunk header</B>.tim| Title screen logo|-Here's what a chunk's header looks like if you defined it in C:| 9<pre>| 0x2E800struct CHUNK_HEADER| 0xC800{| char ID[[ff8/Menu_mag_textures|mag00.tim]]4];| Weapons Monthly, 1st Issue unsigned long Length; |-};| 10</pre>| 0x3B000| 0xC800| [[ff8<B><FONT COLOR=RED>NOTE:</Menu_mag_textures|mag07.tim]]| Pet PalsFONT></B> The <B>Length</B> does not include the 8 byte chunk|-header. It simply tells you how many bytes of data are in the chunk <U>following this header</U>.| 11| 0x47800And here's an example chunk header (with bytes expressed in hex) if you examined it with a hex editor:| 0xC800| [[ff8/Menu_mag_textures|mag00.tim]]4D 54 68 64 00 00 00 06| Weapons Monthly, 1st Issueduplicate Note that the first 4 bytes make up the ascii ID of 0x2E800|-| 12| 0x54000| 0xC800| [[ff8<B>MThd</Menu_mag_textures|mag01.tim]]| Weapons MonthlyB> (ie, March Issuethe first four|-bytes are the ascii values for 'M', 'T', 'h', and 'd'). The next 4 bytes tell us that there should| 13be 6 more data bytes in the chunk (and after that we should find the next chunk header or the end| 0x60800of the file).| 0xC800| [[ff8=== MThd Chunk === The MThd header has an ID of <B>MThd</B>, and a Length of <B>6</Menu_mag_textures|mag02B>.tim]]| Weapons Monthly, April Issue|-Let's examine the 6 data bytes (which follow the MThd header) in an MThd chunk.| 14| 0x6D000| 0xC800| [[ff8The first two data bytes tell the <B>Format</Menu_mag_textures|mag03B> (which I prefer to call "type").tim]]| Weapons MonthlyThere are actually 3 different types (ie, May Issueformats) of MIDI files. A type of 0 means that the file|-contains one single track containing midi data on possibly all 16 midi channels. If your sequencer| 15| 0x79800sorts/stores all of its midi data in one single block of memory with the data in the order that it's| 0xC800| [[ff8"played", then it should read/Menu_mag_textures|mag04write this type.tim]]A type of 1 means that the file contains one or| Weapons Monthlymore simultaneous (ie, all start from an assumed time of 0) tracks, June Issueperhaps each on a single midi|-channel. Together, all of these tracks are considered one sequence or pattern. If your| 16sequencer separates its midi data (i.e. tracks) into different blocks of memory but plays them back| 0x86000| 0xC800| [[ff8simultaneously (ie, as one "pattern"), it will read/Menu_mag_textures|mag05write this type.tim]]A type of 2 means that the| Weapons Monthly, July Issue|file contains one or more sequentially independant single-track patterns. If your sequencer| 17separates its midi data into different blocks of memory, but plays only one block at a time (ie,each block is considered a different "excerpt" or "song"), then it will read/write this type.| 0x92800| 0xC800| [[ff8The next 2 bytes tell how many tracks are stored in the file, <B>NumTracks</Menu_mag_textures|mag06B>.tim]]Of course,| Weapons Monthlyfor format type 0, this is always 1. For the other 2 types, August Issuethere can be numerous tracks.|-| 18| 0x9F000| 0xC800| [[ff8The last two bytes indicate how many Pulses (i.e. clocks) Per Quarter Note (abbreviated as PPQN) resolution the time-stamps are based upon, <B>Division</Menu_mag_textures|mag08B>.tim]]For example, if your sequencer has 96 ppqn, this field would be (in hex):| Occult Fan I & II|-00 60| 19| 0xAB800| 0xC800| [[ff8<B><FONT COLOR=RED>NOTE:</FONT></B> The 4 bytes that make up the <B>Length</Menu_mag_textures|mag09B> are stored in (Motorola) "Big Endian" byte order, not (Intel) "Little Endian" reverse byte order.tim]](ie, The 06 is the fourth byte instead| Occult Fan III & IVof the first of the four).|-| 20In fact, all MIDI files begin with the above <B>MThd header</B> (and that's how you know that it'sa MIDI file).| 0xB8000| 0xC800Alternately, if the first byte of Division is negative, then this represents the division| [[FF8/Menu_sp2#Content_of_mc00of a second that the time-stamps are based upon.texThe first byte will be -mc09.tex|mc0024, -25, -29, or -30,corresponding to the 4 SMPTE standards representing frames per second.tim]]The second byte (a| Card textures for menuspositive number) is the resolution within a frame (ie, subframe). Typical values may be 4 (MIDI|-Time Code), 8, 10, 80 (SMPTE bit resolution), or 100.| 21| 0xC4800| 0xC800| [[FF8/Menu_sp2#Content_of_mc00.texYou can specify millisecond-based timing by the data bytes of -mc0925 and 40 subframes.tex|mc01.tim]]| Card textures for menus|-Here's what an MThd chunk looks like if you defined it in C: | 22<pre>| 0xD1000struct MTHD_CHUNK| 0xC800{| [[FF8 /Menu_sp2#Content_of_mc00.tex-mc09.tex|mc02.tim]* Here's the 8 byte header that all chunks must have */ char ID[4]; /* This will be 'M','T','h','d' */| Card textures for menus unsigned long Length; /* This will be 6 */|-| 23 /* Here are the 6 bytes */| 0xDD800 unsigned short Format;| 0xC800 unsigned short NumTracks;| [[FF8/Menu_sp2#Content_of_mc00.tex-mc09.tex|mc03.tim]] unsigned short Division;| Card textures for menus};|-</pre>| 24| 0xEA000And here's an example of a complete MThd chunk (with header) if you examined it in a hex editor:| 0xC800<pre>| [[FF8/Menu_sp2#Content_of_mc004D 54 68 64 MThd ID00 00 00 06 Length of the MThd chunk is always 6.tex-mc0900 01 The Format type is 1.tex|mc0400 02 There are 2 MTrk chunks in this file.tim]]| Card textures for menus|E7 28 Each increment of delta-time represents a millisecond.| 25</pre>| 0xF6800| 0xC800=== MTrk Chunk ===| [[FF8After the MThd chunk, you should find an <B>MTrk chunk</Menu_sp2#Content_of_mc00B>, as this is the only othercurrently defined chunk.tex-mc09.tex|mc05.tim]](If you find some other chunk ID, it must be proprietary to some other| Card textures for menusprogram, so skip it by ignoring the following data bytes indicated by the chunk's|-Length).| 26| 0x103000An MTrk chunk contains all of the midi data (with timing bytes), plus optional non-midi data| 0xC800| [[FF8for <U>one track</Menu_sp2#Content_of_mc00U>.tex-mc09Obviously, you should encounter as many MTrk chunks in the file as theMThd chunk's NumTracks field indicated.tex|mc06.tim]]| Card textures for menus|-| 27| 0x10F800| 0xC800| [[FF8The MTrk header begins with the ID of <b>MTrk</Menu_sp2#Content_of_mc00B>, followed by the Length (ie, number of data bytes for this track).tex-mc09The Length will likely be different for each track.tex|mc07(After all, a track containing the violin part for a Bach concerto will likely contain more data than a track containing a simple 2 bar drum beat).tim]]| Card textures for menus|-Here's what an MTrk chunk looks like if you defined it in C:<pre>| 28struct MTRK_CHUNK| 0x11C000{| 0xC800 /* Here's the 8 byte header that all chunks must have */| char ID[[FF84]; /Menu_sp2#Content_of_mc00.tex-mc09.tex|mc08.tim]* This will be 'M','T','r','k' */ unsigned long Length; /* This will be the actual size of Data[]*/| Card textures for menus|- /* Here are the data bytes */| 29| 0x128800| 0xC800| unsigned char Data[]; /* Its actual size is Data[FF8Length] */Menu_sp2#Content_of_mc00.tex-mc09.tex|mc09.tim]]| Card textures for menus};|-</pre>| 30| 0x135000| 0x11800==== Variable Quantities ====| PSX_Controller00.tim| Field controls tutorial imageThink of a track in the MIDI file in the same way that you normally think of a track in a|-sequencer. A sequencer track contains a series of <B>events</B>. For example, the first| 31event in the track may be to sound a middle C note. The second event may be to sound the| 0x146800E above middle C. These two events may both happen at the same time. The third event may| 0x11800| PSX_Controller01be to release the middle C note.timThis event may happen a few musical beats after the first| World map controls tutorial imagetwo events (ie, the middle C note is held down for a few musical beats). Each event has a|-"time" when it must occur, and the events are arranged within a "chunk" of memory in the order| 32that they occur.| 0x158000| 0x11800In a MIDI file, an event's "time" precedes the data bytes that make up that event itself. In| PSX_Controller02other words, the bytes that make up the event's time-stamp come first.timA given event's| Battle controls tutorial imagetime-stamp is referenced from the previous event. For example, if the first event occurs 4 clocks|after the start of play, then its "delta-time" is 04. If the next event occurs simultaneously with| 33that first event, its time is 00. So, a delta-time is the duration (in clocks) between an event| 0x169800and the preceding event.| 0xC800| [[ff8<B><FONT COLOR=RED>NOTE:</FONT></Menu_mag_textures|mag10B> Since all tracks start with an assumed time of 0, the firstevent's delta-time is referenced from 0.tim]]| Triple Triad tutorial|A delta-time is stored as a series of bytes which is called a <B>variable length| 34| 0x176000quantity</B>. Only the first 7 bits of each byte is significant (right-justified; sort of like an| 0xC800ASCII byte). So, if you have a 32-bit delta-time, you have to unpack it into a series of 7-bit| [[ff8/Menu_mag_textures|mag11bytes (ie, as if you were going to transmit it over midi in a SYSEX message).tim]]Of course, you| Triple Triad tutorial|will have a variable number of bytes depending upon your delta-time. To indicate which is the| 35last byte of the series, you leave bit #7 clear. In all of the preceding bytes, you set bit #7. So,| 0x182800| 0xC800| [[ff8/Menu_mag_textures|mag12if a delta-time is between 0-127, it can be represented as one byte.tim]]| Triple Triad tutorial|The largest delta-time| 36allowed is 0FFFFFFF, which translates to 4 bytes variable length. Here are examples ofdelta-times as 32-bit values, and the variable length quantities that they translate to:| 0x18F000| 0xC800<pre>| [[ff8/Menu_mag_textures|mag13.tim]] NUMBER VARIABLE QUANTITY| Battle tutorial00000000 00|-00000040 40| 370000007F 7F| 0x19B80000000080 81 00| 0xC80000002000 C0 00| [[ff8/Menu_mag_textures|mag14.tim]]00003FFF FF 7F| Battle tutorial00004000 81 80 00|-00100000 C0 80 00| 38001FFFFF FF FF 7F| 0x1A800000200000 81 80 80 00| 0x300008000000 C0 80 80 00| [[FF8/Menu_mngrp_strings_locations|strings_locations00.bin]]0FFFFFFF FF FF FF 7F| Encoded string archive.Has location values before strings<br/pre>Strings end with '''0x00'''|Here are some C routines to read and write variable length quantities such as delta-| 39| 0x1AB000| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations01times.bin]]With| Encoded string archive.Has location values before strings<brB>WriteVarLen()</B>, you pass a 32-bit value (ie, unsigned long) and it spits out the correctseries of bytes to a file. <B>ReadVarLen()</B> reads a series of bytes from a file until itStrings end with '''0x00'''|reaches the last byte of a variable length quantity, and returns a 32-bit value.| 40| 0x1AB800<pre>| 0x1000void WriteVarLen(register unsigned long value)| [[FF8/Menu_mngrp_strings_locations|strings_locations02.bin]]{ register unsigned long buffer; buffer = value & 0x7F;| Encoded string archive.Has location values before strings<br/ while ( (value >>= 7) )Strings end with '''0x00''' {|- buffer <<= 8; buffer | 41= ((value & 0x7F) | 0x80); } | 0x1AC800 while (TRUE)| 0x1000 {| [[FF8/Menu_mngrp_strings_locations|strings_locations03.bin]] putc(buffer,outfile);| Encoded string archive. if (buffer & 0x80)Has location values before strings<br/ buffer >>= 8;Strings end with '''0x00''' else|- break;| 42 }| 0x1AD800}| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations04.bin]]unsigned long ReadVarLen()| Encoded string archive.{Has location values before strings<br/> register unsigned long value;Strings end with '''0x00''' register unsigned char c;|-| 43 if ( (value = getc(infile)) & 0x80 )| 0x1AE000 {| 0x800 value &= 0x7F;| [[FF8/Menu_mngrp_strings_locations|strings_locations05.bin]] do| Encoded string archive. {Has location values before strings value = (value <<br/>7) + ((c = getc(infile)) & 0x7F);Strings end with '''0x00''' } while (c & 0x80);|- }| 44| 0x1AE800 return(value);| 0x800}| [[FF8</Menu_mngrp_strings_locations|strings_locations06.bin]]pre>| Encoded string archive.Has location values before strings<brB><FONT COLOR=RED>NOTE:</FONT></B>The concept of variable length quantities (ie, breaking up aStrings end large value into a series of bytes) is used with other fields in a MIDI file besides delta-times,as you'''0x00'''ll see later. |For those not writing in C, you may benefit from a psuedo-code explanation of| 45| 0x1AF000| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations07the above routines.bin]]In pseudo-code, ReadVarLen() is:| Encoded string archive.Has location values before strings<br/OL>Strings end with <LI>Initialize the variable which will hold the value. Set it to 0. We'llcall this variable 'result'0x00'''|-| 46| 0x1AF800| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations08.bin]]| Encoded string archive.Has location values before strings<br/LI>Strings end with <LI>Read the next byte of the Variable Length quantity from the MIDI file.</LI><LI>Shift all of the bits in 'result'7 places to the left. (ie, Multiply '0x00result'by 128).</LI><LI>Logically OR 'result'with the byte that was read in, but first mask off bit #7|-of the byte. (ie, AND the byte with hexadecimal 7F before you OR with| 47| 0x1B0000| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations09'result'.bin]]But make sure you save the original value of the byte for the test| Encoded string archivein the next step).Has location values before strings<br/LI>Strings end with '''0x00<LI>Test if bit #7 of the byte is set. (ie, Is the byte AND hexadecimal80 equal to hexadecimal 80)? If so, loop back to step #2. Otherwise,you're done, and 'result'now has the appropriate value.</LI>|-</OL>| 48| 0x1B0800In pseudo code, WriteVarLen() could be:| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations10.bin]]<OL><LI>Assume that you have a variable named 'result' which| Encoded string archivecontains the value to write out as a Variable Length Quantity.Has location values before strings<br/LI>Strings end with <LI>Declare an array which can contain 4 numbers. We'll callthis variable 'array'0x00. Initialize a variable named 'count''|-| 49| 0x1B1000| 0x800| [[FF8to 0.</Menu_mngrp_strings_locations|strings_locations11.bin]]LI>| Encoded string archive<LI>Is 'result' less than 128? If so, skip to step #8.Has location values before strings<br/LI>Strings end with <LI>Take the value 'result'AND with hexadecimal 7F, and ORwith hexadecimal 80, and store it in '0x00count'element of 'array'.|-(ie, The first time through the loop, this gets stored in the first| 50| 0x1B1800| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations12element of 'array'). NOTE: Don't alter the value of 'result' itself.bin]]| Encoded string archive<LI>Increment 'count' by 1.Has location values before strings<br/LI>Strings end with '''0x00'<LI>Shift all bits in 'result'7 places to the right. (This can be done by dividing by 128).</LI>|-| 51| 0x1B2000| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations13.bin]]| Encoded string archive<LI>Loop back to step #3.Has location values before strings<br/LI>Strings end with <LI>Take the value 'result'AND with hexadecimal 7F, and storeit in '0x00count'element of 'array'|-| 52| 0x1B2800| 0x800| [[FF8.</Menu_mngrp_strings_locations|strings_locations14.bin]]LI>| Encoded string archive<LI>Increment 'count' by 1.Has location values before strings<br/LI>Strings end with '''0x00'<LI>Write out the values stored in 'array'. Start with the last|-element stored above, and finish with the first element stored.| 53(ie, Write them out in reverse order so that the first element of| 0x1B3000| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations15'array' gets written to the MIDI file last).bin]]NOTE: The variable| Encoded string archive'count' tells you how many total bytes to write.It also can beHas location values before stringsused as an index into the array (if you subtract one from it, andkeep writing out bytes until it is -1).<br/LI>Strings end with '''0x00'''</OL>|-| 54==== Events in an MTrk ====| 0x1B3800| 0x800An MTrk can contain MIDI events and non-MIDI events (ie, events that contain data such as| [[FF8/Menu_mngrp_strings_locations|strings_locations16tempo settings, track names, etc).bin]]| Encoded string archive.Has location values before strings<br/>The first (1 to 4) byte(s) in an MTrk will be the first event's delta-time as a variable lengthStrings end with quantity. The next data byte is actually the first byte of that event itself. I'll refer to this asthe event''0x00'''|-| 55| 0x1B4000| 0x800| [[FF8s <B>Status</Menu_mngrp_strings_locations|strings_locations17B>.bin]]For MIDI events, this will be the actual MIDI Status byte| Encoded string archive(or the first midi data byte if running status).Has location values before stringsFor example, if the byte is hex 90, then thisevent is a <B>Note-On<br/B>upon midi channel 0. If for example, the byte was hex 23, you'd have toStrings end with '''0x00''recall the previous event's status (ie, midi running status). Obviously, the first MIDI event in|-| 56| 0x1B4800| 0x800| [[FF8the MTrk <U>must</Menu_mngrp_strings_locations|strings_locations18U> have a status byte.bin]]After a midi status byte comes its 1 or 2 data bytes| Encoded string archive(depending upon the status - some MIDI messages only have 1 subsequent data byte).After thatHas location values before strings<br/>Strings end with '''0x00'you'll find the next event's delta time (as a variable quantity), etc. |----| 57| 0x1B5000| 0x800| [[FF8<CENTER><FONT COLOR=RED><B>SYSEX events</B></Menu_mngrp_strings_locations|strings_locations19.bin]]| Encoded string archive.Has location values before stringsFONT><br/CENTER>Strings end SYSEX (system exclusive) events (status = F0) are a special case because a SYSEX event canbe any length. After the F0 status (which is always stored -- no running status here), you'll findyet another series of variable length bytes. Combine them with ReadVarLen() and you'll come upwith a 32-bit value that tells you how many more bytes follow which make up this SYSEX event.This length doesn''0x00'''t include the F0 status.|-| 58For example, consider the following SYSEX MIDI message:| 0x1B5800| 0x800F0 7F 7F 04 01 7F 7F F7| [[FF8/Menu_mngrp_strings_locations|strings_locations20.bin]]| Encoded string archive.This would be stored in a MIDI file as the following series of bytes (minus the delta-timeHas location values before strings<br/>bytes which would precede it):Strings end with '''0x00'''|-F0 07 7F 7F 04 01 7F 7F F7| 59| 0x1B6000| 0x800The 07 above is the variable length quantity (which happens to fit in just one byte for this| [[FF8/Menu_mngrp_strings_locations|strings_locations21example). It indicates that there are seven, following bytes that comprise this SYSEX message.bin]]| Encoded string archiveReally oddball midi units send a system exclusive message as a series of small "packets" (witha time delay inbetween transmission of each packet).The first packet begins with an F0, but itHas location values before strings<br/>Strings doesn't end with an F7. The subsequent packets don't start with an F0 nor end with F7. The lastpacket doesn''0x00'''t start with an F0, but does end with the F7. So, between the first packet's opening F0 and|-the last packet's closing F7, there's 1 SYSEX message there. (Note: only extremely poor designs,| 60such as the crap marketed by Casio exhibit such horrid behavior). Of course, since a delay is| 0x1B6800needed inbetween each packet, you need to store each packet as a separate event with its own| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations22time in the MTrk.bin]]Also, you need some way of knowing which events shouldn't begin with an F0| Encoded string archive(ie, all of them except the first packet).So, the MIDI file redefines a midi status of F7Has location values before strings<br/>(normally used as an end mark for SYSEX packets) as a way to indicate an event that doesn'tStrings end begin with F0. If such an event follows an F0 event, then it's assumed that the F7 event is thesecond "packet" of a series. In this context, it''0x00'''s referred to as a SYSEX CONTINUATION event.|-Just like the F0 type of event, it has a variable length followed by data bytes. On the other| 61hand, the F7 event could be used to store MIDI REALTIME or MIDI COMMON messages. In this case,| 0x1B7000| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations23after the variable length bytes, you should expect to find a MIDI Status byte of F1, F2, F3, F6,F8, FA, FB, FC, or FE.bin]](Note that you wouldn't find any such bytes inside of a SYSEX CONTINUATION| Encoded string archiveevent). When used in this manner, the F7 event is referred to as an ESCAPED event.Has location values before strings----<br/CENTER><FONT COLOR=RED><B>Non-MIDI events</B></FONT></CENTER>Strings end with '''0x00'''|A status of FF is reserved to indicate a special non-MIDI event. (Note that FF is used in MIDI| 62| 0x1B7800| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations24to mean "reset", so it wouldn't be all that useful to store in a data file.bin]]Therefore, the MIDI| Encoded string archivefile arbitrarily redefines the use of this status).After the FF status byte is another byte thatHas location values before stringstells you what <B>Type<br/B>of non-MIDI event it is. It's sort of like a second status byte. ThenStrings end with '''0x00'''|after this byte is another byte(s --a variable length quantity again) that tells how many more| 63| 0x1B8000| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations25data bytes follow in this event (ie, its Length).bin]]This Length doesn't include the FF, Type| Encoded string archivebyte, nor the Length byte.Has location values before stringsThese special, non-MIDI events are called <br/B>Meta-Events</B>, andStrings end with '''0x00'''most are optional unless otherwise noted. The section of this online book entitled "Meta-Events"|lists the currently defined Meta-| 64| 0x1B8800| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations26Events.bin]]Note that unless otherwise mentioned, more than one of| Encoded string archivethese events can be placed in an MTrk (even the same Meta-Event) at any delta-time.(Just likeHas location values before strings<br/>Strings end with '''0x00'''|all midi events, Meta-Events have a delta-time from the previous event regardless of what type| 65of event that may be. So, you can freely intermix MIDI and Meta events).| 0x1B9000| 0x800==== Meta-Events in an MTrk ====| [[FF8/Menu_mngrp_strings_locations|strings_locations27.bin]]----| Encoded string archive.===== Sequence Number =====Has location values before stringsFF 00 02 <I><FONT COLOR=RED><B>ss ss<br/B></FONT></I>Strings end with '''0x00'''|-or...| 66| 0x1B9800FF 00 00| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations28This optional event must occur at the beginning of a MTrk (ie, before any non-zerodelta-times and before any midi events).bin]]| Encoded string archiveIt specifies the sequence number.The two data bytesHas location values before strings<brI><FONT COLOR=RED><B>ss ss</B></FONT></I>, are that number which corresponds to the <B>MIDIStrings end with '''0x00'''|-| 67| 0x1BA000| 0x800| [[FF8Cue</Menu_mngrp_strings_locations|strings_locations29B> message.bin]]In a format 2 MIDI file, this number identifies each "pattern" (ie, Mtrk) so| Encoded string archivethat a "song" sequence can use the MIDI Cue message to refer to patterns.Has location values before stringsIf the <I><FONT COLOR=RED><B>ss ss</B></FONT><br/I>numbers are omitted (ie, the second formStrings end with shown above), then the MTrk'''0x00'''|-s location in the file is used. (ie, The first MTrk chunk is| 68sequence number 0. The second MTrk is sequence number 1. Etc).| 0x1BA800| 0x800In format 0 or 1, which contain only one "pattern" (even though format 1 contains| [[FF8/Menu_mngrp_strings_locations|strings_locations30several MTrks), this event is placed in only the first MTrk.bin]]So, a group of format 0 or 1 files| Encoded string archivewith different sequence numbers can comprise a "song collection".Has location values before strings<br/>Strings end with '''0x00'''There can be only one of these events per MTrk chunk in a Format 2. There can be only oneof these events in a Format 0 or 1, and it must be in the first MTrk.|----| 69===== Text =====| 0x1BB000| 0x800| [[FF8FF 01 <I><FONT COLOR=GREEN><B>len</Menu_mngrp_strings_locations|strings_locations31.bin]]| Encoded string archive.Has location values before stringsB><br/FONT>Strings end with '''0x00'''|-| 70| 0x1BB800| 0x800| [[FF8</Menu_mngrp_strings_locations|strings_locations32.bin]]| Encoded string archive.Has location values before stringsI> <br/I>Strings end with '''0x00'''|-| 71| 0x1BC000| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations33.bin]]| Encoded string archive.Has location values before strings<brFONT COLOR=RED><B>text</B>Strings end with '''0x00'''|-| 72| 0x1BC800| 0x800| [[FF8</Menu_mngrp_strings_locations|strings_locations34.bin]]| Encoded string archive.Has location values before stringsFONT><br/I>Strings end with '''0x00''Any amount of text (amount of bytes = <I><FONT COLOR=GREEN><B>len</B></FONT></I>) for anypurpose. It's best to put this event at the beginning of an MTrk. Although this text could be|used for any purpose, there are other text-based Meta-Events for such things as orchestration,| 73lyrics, track name, etc. This event is primarily used to add "comments" to a MIDI file which a| 0x1BD000| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations35program would be expected to ignore when loading that file.bin]]| Encoded string archive.Has location values before stringsNote that <br/I><FONT COLOR=GREEN><B>len</B></FONT></I> could be a series of bytes since itStrings end with '''0x00'''is expressed as a variable length quantity.|----| 74| 0x1BD800| 0x800===== Copyright =====| [[FF8FF 02 <I><FONT COLOR=GREEN><B>len</B></FONT></Menu_mngrp_complex_strings|Complex_Map.bin]]| Map for Complex Strings 00-05|-I> <I><FONT COLOR=RED><B>text</B></FONT></I>| 75| 0x1BE000A copyright message. It's best to put this event at the beginning of an MTrk.| 0x4800| [[FF8Note that <I><FONT COLOR=GREEN><B>len</B></Menu_mngrp_complex_strings|Complex_Strings00.bin]]FONT></I> could be a series of bytes since it| Encoded string archiveis expressed as a variable length quantity.|----| 76===== Sequence/Track Name =====| 0x1C2800| 0x4000| [[FF8FF 03 <I><FONT COLOR=GREEN><B>len</Menu_mngrp_complex_strings|Complex_Strings01.bin]]| Encoded string archive.|-| 77| 0x1C6800| 0x4800| [[FF8B></Menu_mngrp_complex_strings|Complex_Strings02FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I> The name of the sequence or track.bin]]It's best to put this event at the beginning of an| Encoded string archiveMTrk.|-| 78| 0x1CB000| 0x4000| [[FF8Note that <I><FONT COLOR=GREEN><B>len</B></FONT></Menu_mngrp_complex_strings|Complex_Strings03.bin]]I> could be a series of bytes since it| Encoded string archiveis expressed as a variable length quantity.|----| 79===== Instrument =====| 0x1CF000| 0x2800| [[FF8FF 04 <I><FONT COLOR=GREEN><B>len</B></FONT></Menu_mngrp_complex_strings|Complex_Strings04.bin]]| Encoded string archive.I> <I><FONT COLOR=RED><B>text</B></FONT></I>|-| 80The name of the instrument (ie, MIDI module) being used to play the track. This may be| 0x1D1800| 0x4800different than the Sequence/Track Name. For example, maybe the name of your sequence (ie, Mtrk)| [[FF8/Menu_mngrp_complex_strings|Complex_Strings05.bin]]is "Butterfly", but since the track is played upon a Roland S-770, you may also include an| Encoded string archiveInstrument Name of "Roland S-770".|-| 81It's best to put one (or more) of this event at the beginning of an MTrk to provide the user| 0x1D6000with identification of what instrument(s) is playing the track. Usually, the instruments (ie,| 0x1000patches, tones, banks, etc) are setup on the audio devices via <B>MIDI Program Change</B>| [[FF8and <B>MIDI Bank Select Controller</Menu_mngrp_strings_locations|strings_locations36B> events within the MTrk.bin]]So, this event exists merely to| Encoded string archiveprovide the user with visual feedback of what instruments are used for a track.Has location values before stringsNote that <I><FONT COLOR=GREEN><B>len</B></FONT><br/I>could be a series of bytes since itStrings end with '''0x00'''is expressed as a variable length quantity.|----| 82| 0x1D7000===== Lyric =====| 0x800| [[FF8FF 05 <I><FONT COLOR=GREEN><B>len</Menu_mngrp_strings_locations|strings_locations37.bin]]| Encoded string archive.Has location values before stringsB><br/FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>Strings end with '''0x00'''|-| 83A song lyric which occurs on a given beat. A single Lyric| 0x1D7800MetaEvent should contain only one syllable.| 0x800| [[FF8Note that <I><FONT COLOR=GREEN><B>len</B></Menu_mngrp_strings_locations|strings_locations38.bin]]| Encoded string archive.Has location values before stringsFONT><br/I>could be a series of bytes since itStrings end with '''0x00'''is expressed as a variable length quantity.|----| 84| 0x1D8000| 0x800| [[FF8/Menu_mngrp_strings_locations|strings_locations39.bin]]===== Marker =====| Encoded string archive.Has location values before stringsFF 06 <br/I>Strings end with '''0x00'''|-| 85| 0x1D8800| 0x800| [[FF8<FONT COLOR=GREEN><B>len</Menu_mngrp_strings_locations|strings_locations40.bin]]| Encoded string archive.Has location values before stringsB><br/FONT>Strings end with '''0x00'''|-| 86| 0x1D9000| 0x800| [[FF8</Menu_mngrp_strings_locations|strings_locations41.bin]]| Encoded string archive.Has location values before stringsI> <br/I><FONT COLOR=RED><B>text</B></FONT></I>Strings end with '''0x00'''|-| 87The text for a marker which occurs on a given beat. Marker events might be used to denote a loop start and loop end (ie, where the sequence loops back to a previous event).| 0x1D9800| 0x800| [[FF8Note that <I><FONT COLOR=GREEN><B>len</B></Menu_mngrp_strings_locations|strings_locations42.bin]]| Encoded string archive.Has location values before stringsFONT><br/I>could be a series of bytes since itStrings end with '''0x00'''|is expressed as a variable length quantity.----| 88===== Cue Point=====| 0x1DA000| 0x800| [[FF8FF 07 <I><FONT COLOR=GREEN><B>len</Menu_mngrp_strings_locations|strings_locations43.bin]]| Encoded string archive.Has location values before stringsB></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT><br/I>Strings end with '''0x00''The text for a cue point which occurs on a given beat. A Cue Point might be used to denotewhere a WAVE (ie, sampled sound) file starts playing, for example, where the<I><FONT COLOR=RED><B>text</B></FONT></I> would be the WAVE's filename.|-| 89Note that <I><FONT COLOR=GREEN><B>len</B></FONT></I> could be a series of bytes since it| 0x1DA800is expressed as a variable length quantity.| 0x800|-| 90| 0x1DB000| 0x800|---| 91===== Program (Patch) Name =====| 0x1DB800| 0x800|-| 92| 0x1DC000| 0x800|-FF 08 <I><FONT COLOR=GREEN><B>len</B></FONT></I> <I><FONT COLOR=RED><B>text</B></FONT></I>| 93| 0x1DC800The name of the program (ie, patch) used to play the MTrk. This may be| 0x800|-different than the Sequence/Track Name. For example, maybe the name of your sequence (ie, Mtrk)| 94is "Butterfly", but since the track is played upon an electric piano patch, you may also include a| 0x1DD000Program Name of "ELECTRIC PIANO".| 0x800|-Usually, the instruments (ie, patches, tones, banks, etc) are setup on the audio devices via| 95| 0x1DD800| 0x800<B>MIDI Program Change</B> and <B>MIDI Bank Select Controller</B> events within the MTrk. So,|-this event exists merely to provide the user with visual feedback of what particular patch is| 96used for a track. But it can also give a hint to intelligent software if patch remapping needs| 0x1DE000| 0x800|to be done. For example, if the MIDI file was created on a non-General MIDI instrument, then| 97| 0x1DE800the <B>MIDI Program Change</B> event will likely contain the| 0x800wrong value when played on a General MIDI instrument. Intelligent software can use the|-Program Name event to look up the correct value for the <B>MIDI Program Change</B> event.| 98| 0x1DF000| 0x800|| text with binary dataGF names some misspelled/truncated |-| 99| 0x1DF800| 0x800|-| 100| 0x1E0000| 0x800|| text with binary dataGF names some misspelled/truncatedNote that <I><FONT COLOR=GREEN><B>len<BR/B>Very similar to 0x1DF000|-| 101| 0x1E0800| 0xC800| [[ff8/Menu_mag_textures|mag15.tim]]| Chocobo world cartoon|-| 102| 0x1ED000| 0xC800| [[ff8/Menu_mag_textures|mag16.tim]]| Tutorial image|-| 103| 0x1F9800| 0xC800| [[ff8/Menu_mag_textures|mag17.tim]]| Tutorial image|-| 104| 0x206000| 0xC800| [[ff8/Menu_mag_textures|mag18.tim]]| Chocobo world sketch cartoon|-| 105| 0x212800| 0xC800| [[ff8/Menu_mag_textures|mag19.tim]]| Chocobo world sketch cartoon<br/>Duplicate of 0x206000|-| 106| 0x21F000| 0x800| [[FF8/Menu_m000_m004|m000.bin]]| Locations for msg file|-| 107| 0x21F800| 0x800| [[FF8/Menu_m000_m004|m001.bin]]| Locations for msg file|-| 108| 0x220000| 0x800| [[FF8/Menu_m000_m004|m002.bin]]| Locations for msg file|-| 109| 0x220800| 0x800| [[FF8/Menu_m000_m004|m003.bin]]| Locations for msg file|-| 110| 0x221000| 0x800| [[FF8/Menu_m000_m004|m004.bin]]| Locations for msg file|-| 111| 0x221800| 0x1800| [[FF8/Menu_m000_m004|m000.msg]]| Strings end with '''0x00'''|-| 112| 0x223000| 0x2000| [[FF8/Menu_m000_m004|m001.msg]]| Strings end with '''0x00'''|-| 113| 0x225000| 0x800| [[FF8/Menu_m000_m004|m002.msg]]| Strings end with '''0x00'''|-| 114| 0x225800| 0x800| [[FF8/Menu_m000_m004|m003.msg]]| Strings end with '''0x00'''|-| 115| 0x226000| 0x1800| [[FF8/Menu_m000_m004|m004.msg]]| Strings end with '''0x00'''|-| 116| 0x227800| 0x800| [[FF8</Menu_mngrp_strings_locations|strings_locations44.bin]]| Encoded string archive.Has location values before stringsFONT><br/I>could be a series of bytes since itStrings end with '''0x00'''|-| 117| 0x228000| 0x800|}is expressed as a variable length quantity.
Anonymous user

Navigation menu