Letzte Änderungen: 12.03.2009

Zur Hauptseite kurs9


Das MIDI-File-Format

Das MIDI-File-Format dient zum Austauschen von Song-Daten zwischen Sequencern. Ein MIDI-File wird im Song/Track Format abgespeichert, so dass man diese Aufteilung direkt in den eigenen Sequencer übernehmen kann.

Ein MIDI-File beginnt immer mit einem Header-Chunk, gefolgt von den eigentlichen Track-Chuncks.

Der Header Chunk <MThd>

Format:

PPQ Auflösung:

Dieser Wert ist die interne Auflösung des MIDI-Files. Diesen Wert braucht man um einen Multiplikator -Wert zur Erstellung der Timestamp-Werte zu erhalten. Falls z.B. die Sequencerauflösung 768ppq ist, der Song eine Aufösung von 96ppq hat ist der PPQ-Multiplikator 768/96=8.

Die Timestamp-Werte in den MIDI-Files werden übrigens nicht absolut angegeben, sondern relativ zum vorherigen Event - Deltatime genannt.

Der Track <MTrk>

Nach dem Header Chunk gehts weiter mit dem 1. Track gefolgt von dem 2. Track usw...

Die Events (Meta-Events)

Nach dem Track-Chunk folgen die Events die sich auf diesem Track befinden. Neben den eigentlich MIDI-Events (Noten, ProgChg usw...) können auch andere Events übertragen werden (z.B. Tempoänderungen, Taktänderungen).

Der Deltawert

Alle Events (Midi- und Metaevents) besitzen einen Deltawert, der x Bytes lang sein kann. Dieser Deltawert setzt praktisch den Timestamp-Zähler für den Track beim Einlesen weiter.

Diesen Deltawert kann man durch eine einfache Routine einlesen. Ob der Wert 8,16 oder 32 Bit ist wird durch das Bit 7 festgelegt. Somit können praktisch 7,14,21 ... Bit Werte eingelesen werden..

ULONG
ReadSMFDeltaWert (BOOL setdeltatime)
{
ULONG deltawert;
ULONG rbyte;

rbyte = ReadByte ();

if(deltawert = rbyte)
{
if (file->filelen && (rbyte & 0x80)) /* Bit 7 gesetzt ? */
{
deltawert &= 0x7f;

do
{
rbyte = ReadByte ();

deltawert<<= 7;
deltawert += (rbyte & 0x7f);
}
while (file->filelen && (rbyte & 0x80)); /* Solange in Delta einlesen bis Bit 7 nicht mehr gesetzt */
}

if(setdeltatime==TRUE) // In Deltatime schreiben ?
{
deltawert *=rmidi.ppqfaktor; // Der PPQ Faktor Sequencer -> MIDI-File z.B. 768/24 = 32
file->deltatime += deltatime; // Timestamp des Tracks festlegen
}

return(deltawert);
}

Die MIDI-Events

Die MIDI-Events werden ganz einfach im rohen MIDI-Event-Format abgespeichert. Vor den Event-Daten wird stets der Delta-Wert abgespeichert.

Beispiele:

00 C0 4 ; ProgramChange Kanal 1, Program 4

00 92 48 96; NoteOn Kanal 2, Taste 96

00 48 95; NoteOn Kanal 2, Taste 95; im runningstatus !

192 82 48 64; NoteOff Kanal 2, Taste 96

00 48 64; NoteOff Kanal 2, Taste 95; im runningstatus !

Der Deltawert 192 legt dann entsprechend dem Deltawert die Länge der Note fest.

Wie im MIDI-Datenstrom gibt es auch hier einen Running-Status für die Statusbytes um etwas Daten zu sparen

Die Meta-Events

Mit Hilfe der Meta-Event können songinterne Information abgespeichert werden. Meta und MIDI-Events können gemischt werden. Meta-Events beginnen immer mit FF.

Der Wert len ist ebenfalls ein Deltawert muss also ebenfalls wie die Deltazeit eingelesen werden. Die wichtigsten Meta-Events:

FF 01 len text - Text Event

FF 02 len text - Copyright

FF 03 len Text - Track Name

FF 04 len Text - Instrument-Name für den Track

FF 05 len Text - Gesangstext

FF 06 len Text - Markertext

FF 07 len Text - Cue Point

FF 2F 00 - Ende des Tracks, muss gesetzt werden

FF 51 03 tttttt - Tempowert/änderung in Microsekunden/Viertelnote - Mircosekunden nicht Millisekunden !. Hierbei muss dann in BPM umgerechnet werden. 500000 Mikro entsprechen eben 120 BPM

FF 54 05 hr mn se ff ff - SMPTE Offset


FF 58 04 nn dd cc bb - Taktart/Taktwechsel

nn: Numerator, dd: Denominator (0: /1, 1: /2,2: 1/4 usw...), cc: Anzahl der MIDI-Clocks pro Metronome Click (Standard: 24), bb: Anzahl der 1/32 Note pro Viertelnote (Standard: 08)

Eine Taktwechsel auf 3/4 wäre dann:

FF 58 04 03 02 24 08