HMP File Format (Incomplete - Under Construction) Document version 1 Written by Chris Ison Last Edited 24 May 2014 Copyright (C) 2014 WildMidi Developers This document is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ Introduction This document describes the HMP format as used by the WildMIDI project. It is not a complete description of the HMP file format and only those parts that are relevant to the WildMidi project are described here. Unfortunately we cannot answer questions about the format that are not described within this document. If you feel there is an error in this document please feel free to report it as a bug at https://github.com/Mindwerks/wildmidi/issues/ The HMP format comes in 2 versions. Apart from the file header there is no difference between the 2 versions as far WildMIDI is concerned. Description // First version of hmp files { char header[] = "HMIMIDIP"; char no_idea_1[24]; // All zeros } // *** OR *** // Second version of hmp files { char header[] = "HMIMIDIP013195"; char no_idea_1[18]; // All zeros } // The remaining header section of hmp files { char file_length[4]; // File size minus header[] stored as little-endian char no_idea_2[16]; // All zeros char number_of_chunks[4]; // Number of chunks stored as little-endian char no_idea_3[4]; // Unknown char beats_per_minute[4]; // beats per minute stored as little-endian // *** NOTE: Using a division of 60 *** char song_length_s[4]; // length of song in seconds as little-endian } // First version of hmp files { char no_idea4[712]; // Unknown // chunks start here } // *** OR *** // Second version of hmp files { char no_idea4[840]; // Unknown // chunks start here } // Chunk information { char chunk_number[4]; // Stored as little-endian char chunk_length[4]; // Size of entire chunk stored as little-endian char track_number[4]; // Track numbe stored as little endian { // Repeat until end of chunk char midi_delta[] = ???; // See MIDI Delta char midi_event[] = ???; // See MIDI Events } } MIDI Delta This is a variable length value that determins how time (in MIDI ticks) is to pass before the following MIDI event is to be processed. Opposite to MIDI variable length values. In HMP files the variable length value is stored in LSB with bit 7 set off for all except the last 7 bit value. A value of 255 would be stored as 0x7f 0x81, or a value of 1 would be stored as 0x81 in the HMP variable length format. Examples: Delta of 255: < midi event > 0x7f 0x81 < midi event> Delta of 127: < midi event > 0xff < midi event > Delta of 65537: < midi event > 0x7f 0x00 0x82 < midi event > MIDI Events The first byte of a midi events is split into 2 x 4bits. Bits 7-4 is the command while bits 3-0 is the MIDI channel the command is to occur on. For example 0x94 means do command 9 on channel 4. The only exception to this is where bits 7-4 = F in hexidecimal as these are a special group of commands. The following commands are detailed in this document with the channel information (bits 3 - 0) set to 0, example 0x80. However the channel information could have a value anywhere from 0x0 to 0xf. For more detail about the folling MIDI command information please see MidiFileFormat.txt within the WildMIDI project source code. // Note Off { char cmd = 0x80; char note = 27; // Could be a value of 0 - 127 char velocity = 0; // Could be a value of 0 - 127. Ignored by WildMIDI } // Note On { char cmd = 0x90; char note = 32; // Could be a value of 0 - 127 char velocity = 100; // Could be a value of 0 - 127. // If this value is 0 then it is treated as a note of } // Aftertouch { // Adjust the velocity of a note as if adjusting the preasure you // are placing on the key of a preasure sensitive keyboard after // you started playing it. char cmd = 0xa0; char note = 32; // Could be a value of 0 - 127 char velocity = 100; // Could be a value of 0 - 127. } // Controller { char cmd = 0xb0; char controller = 32; // Could be a value of 0 - 127 char setting = 100; // Could be a value of 0 - 127 /* In track 1 of HMP files controller 110 is set to 255 to mark the start of the looped events of tracks 2 & 3. Controller 111 in track 1 set to 128 to mark the end of the looped events of track 2 & 3. */ } // Patch { /* Change the patch (or sound) used to play notes on the channel */ char cmd = 0xc0; char change_patch = 32; // Could be a value of 0 - 127 } // Preasure { /* Adjust the velocity of all active notes on the channel as if adjusting the preasure you are placing on the keys of a preasure sensitive keyboard after you started playing them. */ char cmd = 0xd0; char velocity = 32; // Could be a value of 0 - 127 } // Pitch { /* Adjust the pitch of a channel just like a pitch bend wheel does. */ char cmd = 0xe0; char data_1 = 32; // Could be a value of 0 - 127 char data_2 = 100; // Could be a value of 0 - 127. } // Sysex { ** It is uncertain if sysex events will apepar in a HMP file ** ** but they have been included because it is possible ** char cmd = 0xf0; // *** OR *** char cmd = 0xf7; char sysex_size[] = < variable length in MIDI file format >; char sysex_data[sysex_size] = ...; // Ending with 0xf7 } // Meta Events { char cmd = 0xff; char instruction = 0x02; // Could be 0 - 127 char data_size[] = < variable length in MIDI file format >; char data[data_size]; }