#pragma once #include namespace midi { struct division_t { enum struct type_t : uint8_t { time_code, metrical, } type; union { struct { int8_t smpte; uint8_t ticks_per_frame; } time_code; struct { uint16_t ticks_per_quarter_note; } metrical; }; }; struct header_t { enum struct format_t : uint8_t { _0, _1, _2, } format; uint16_t ntrks; division_t division; }; struct midi_event_t { struct note_off_t { uint8_t channel; uint8_t note; uint8_t velocity; }; struct note_on_t { uint8_t channel; uint8_t note; uint8_t velocity; }; struct polyphonic_key_pressure_t { uint8_t channel; uint8_t note; uint8_t pressure; }; struct control_change_t { uint8_t channel; uint8_t control; uint8_t value; }; struct program_change_t { uint8_t channel; uint8_t program; }; struct channel_pressure_t { uint8_t channel; uint8_t pressure; }; struct pitch_bend_change_t { uint8_t channel; uint8_t lsb; uint8_t msb; }; struct channel_mode_t { uint8_t channel; uint8_t controller; uint8_t value; }; enum struct type_t { note_off, note_on, polyphonic_key_pressure, control_change, program_change, channel_pressure, pitch_bend_change, channel_mode, } type; union event_t { note_off_t note_off; note_on_t note_on; polyphonic_key_pressure_t polyphonic_key_pressure; control_change_t control_change; program_change_t program_change; channel_pressure_t channel_pressure; pitch_bend_change_t pitch_bend_change; channel_mode_t channel_mode; } data; }; struct sysex_event_t { const uint8_t * data; uint32_t length; uint8_t tag; }; struct meta_event_t { const uint8_t * data; uint32_t length; uint8_t type; }; struct event_t { enum struct type_t { midi, sysex, meta, } type; union _event_t { midi_event_t midi; sysex_event_t sysex; meta_event_t meta; } event; }; struct mtrk_event_t { uint32_t delta_time; event_t event; }; struct track_t { uint32_t length; }; } // midi