HMP File Format
(Incomplete - Under Construction)

Document version 1
Authored by Chris Ison chrisisonwildcode@gmail.com

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 HMI format as used by the WildMIDI project.
It is not a complete description of the HMI file format and only those
parts that have been decyphered and 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/


Description

// Header
{
    char header[18] = "HMI-MIDISONG061595";
    char no_idea_1[196];
    char beats_per_minute;
    char no_idea_2[15];
    char track_count;
    char no_idea_3[141];
    {
        // Repeat for number of tracks in track_count
        char track_offset[4]; // Stored as little endian;
    }
    char no_idea_4[??]; // this is the remaining amout up to the first
                        // track chunk marked by the first track offset.
}

// Track Chunk
{
    char track_header[] = "HMI-MIDITRACK";
    char no_idea_4[74];
    char track_header_size[4];
    char no_idea_5[(track_header_size - 91];

    {
        // Repeat until end of track detected
        // ** NOTE ** Since track chunk has no length details,
        //           you need to scan for end of track marker.
        char midi_delta[] = ???; // See MIDI Delta
        char midi_event[] = ???; // See MIDI Events
                // ** NOTE ** Note On event is slightly different to the
                // normal MIDI note on event. See MIDI Events below.
                // Last event in track chunk is end of track meta event,
                // defined as 0xff 0x2f 0x00.
    }
{

// Extra Data
{
    // Some HMI files have data after the tracks.
    // Details are unknown about these bytes of data.
    char no_idea_6[] = ???;
}


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.
Just like MIDI's variable length values, HMI files have bit 7 set
on the each value in the variable length value except the last one.
A value of 255 would be stored as 0x81 0x7f, or a value of 1 would
be stored as 0x01 in the HMI variable length format.

    Examples:
    Delta of 255: < midi event > 0x81 0x7f < midi event>
    Delta of 127: < midi event > 0x7f < midi event >
    Delta of 65537: < midi event > 0x82 0x80 0x71 < 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 0 to F in hexidecimal.

// Note On Event
{
    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 off
    char length[] = < variable length value >; // See MIDI Delta for example
}

// Aftertouch Event
{
    // See "Aftertouch Event" in MidFileFormat.txt
}

// Controller Events
{
    // See "Controller Events" in MidFileFormat.txt
}

// Patch Event
{
    // See "Patch Event" in MidFileFormat.txt
}

// Preasure Event
{
    // See "Pressure Event" in MidFileFormat.txt
}

// Pitch Event
{
    // See "Patch Event" in MidFileFormat.txt
}

// Sysexs Events
{
    // See "Sysex Events" in MidFileFormat.txt
}

// HMI Events
{
    // This is undocumented in specifications others have put together
    // so nothing other than the following is known about it.
    char cmd = 0xfe;

    {
        char type = 0x10;
        char data_1[2];
        char size; // Could be anything from 0x00 to 0xff
        char data_2[size];
        char data_3[5];
    }
    // *** OR ***
    {
        char type = 0x15;
        char data[6];

    }
    // *** OR ***
    {
        char type;
        char data[2];
    }
}

// Meta Events
{
    // See "Meta Events" MidFileFormat.txt
}

