Portability | GHC (at least generalized newtype deriving) |
---|---|
Stability | unstable |
Maintainer | Stephen Tetley <stephen.tetley@gmail.com> |
Safe Haskell | None |
Concrete syntax tree for MIDI files.
Values are sometimes not interpreted. This means that the the data types do not fully represent the sematics of the data, but all the data is either stored in the tree or synthesizeable.
readFile >>= writeFile
will produce an identical binary [1].
[1] Or it should, failure indicates a bug...
- data DeltaTime
- type TagByte = Word8
- data MidiFile = MidiFile {
- mf_header :: MidiHeader
- mf_tracks :: [MidiTrack]
- data MidiHeader = MidiHeader {}
- newtype MidiTrack = MidiTrack {}
- data MidiFormat
- type MidiMessage = (DeltaTime, MidiEvent)
- data MidiEvent
- newtype MidiDataEvent = MidiDataEvent {}
- data MidiVoiceEvent
- data MidiSysExEvent = SysEx Word32 [Word8]
- data MidiSysCommonEvent
- data MidiSysRealTimeEvent
- data MidiMetaEvent
- data MidiTimeDivision
- data MidiTextType
- = GENERIC_TEXT
- | COPYRIGHT_NOTICE
- | SEQUENCE_NAME
- | INSTRUMENT_NAME
- | LYRICS
- | MARKER
- | CUE_POINT
- data MidiScaleType
MidiFile syntax.
All time values in a MIDI track are represented as a delta from the previous event rather than an absolute time.
DeltaTime is a newtype wrapper over Word32, note that in MIDI
files it is represented as a varlen
to save space rather than
a four byte number.
data MidiHeader Source
Header
: format * num_tracks * time_division
TimeDivision
is often 384 or 480 ticks per beat.
The header is the start of a MIDI file, it is indicated by the
4 character marker MThd
.
Track
: [message]
In MIDI files, the start of a track is indicated by the 4
character marker MTrk
.
data MidiFormat Source
The file format - in a MIDI file this is a big-endian word16 with 0,1 or 2 being the only valid values.
type MidiMessage = (DeltaTime, MidiEvent)Source
MIDI messages are pairs of DeltaTime
and Event
wrapped in
a newtype.
Sequential messages with delta time 0 are played simultaneously.
DataEvent MidiDataEvent | Data event - just initial tag byte, uninterpreted |
VoiceEvent MidiVoiceEvent | Voice event (e.g |
SysExEvent MidiSysExEvent | SysEx - system exclusive event. Usually synthesizer specific, not interpreted. |
SysCommonEvent MidiSysCommonEvent | SysCommon - system common event. |
SysRealTimeEvent MidiSysRealTimeEvent | SysRealTime - system realtime event. |
MetaEvent MidiMetaEvent | Meta event - interpreted (e.g. |
newtype MidiDataEvent Source
Data events are events with tags from 0x00 to 0x7F.
Data events have no payload - they are represented only by the tag byte.
data MidiVoiceEvent Source
Voice events control the output of the synthesizer.
Note - the constructors are not in the the same order as their byte values. Controller and ProgramChange are higher than they naturally occur so the will come first after a comparison or sort.
When generating MIDI, Controller and ProgramChange events should be signalled before NoteOn or NoteOff events at the same delta-time. Changing the order of the constructors helps to sort for this.
Controller Word8 Word8 Word8 | channel * controller_number * value Controller change, e.g. by a footswitch. |
ProgramChange Word8 Word8 |
|
NoteOff Word8 Word8 Word8 | channel * note * velocity Turn off a sounding note. |
NoteOn Word8 Word8 Word8 | channel * note * velocity Start playing a note. |
NoteAftertouch Word8 Word8 Word8 | channel * note * pressure_value Change of pressure applied to the synthesizer key. |
ChanAftertouch Word8 Word8 | channel * pressure_value |
PitchBend Word8 Word16 | channel * value Change the pitch of a sounding note. Often used to approximate microtonal tunings. NOTE - currently value is uninterpreted. |
data MidiSysExEvent Source
SysEx - system exclusive event.
data MidiSysCommonEvent Source
System common event.
Common information for all channels in a system.
These events may not be pertinent to MIDI files generated on a computer (as opposed to MIDI generated by a synthesizer or sequencer).
QuarterFrame Word8 | Time code quarter frame. Note the payload is really a byte split into two 4-bit values, however here it is uninterpreted. |
SongPosPointer Word8 Word8 | Song position pointer. |
SongSelect Word8 | song_number Song number should be in the range 0..127. |
Common_undefined TagByte | Tag should be limited to 0xF4 or 0xF5. Other values would indicate either a badly formed MIDI file or a failure with the parser. |
TuneRequest | Tune request message for analogue synthesizers. |
EOX | End-of-system-exclusive message. |
data MidiSysRealTimeEvent Source
System real-time event.
These events may not be pertinent to MIDI files generated on a computer (as opposed to MIDI generated by a synthesizer or sequencer).
TimingClock | Timing signal. |
RT_undefined TagByte | Tag should be limited to either 0xF9 or 0xFD. Other values would indicate either a badly formed MIDI file or a failure with the parser. |
StartSequence | Start playing a sequence. |
ContinueSequence | Continue playing a stopped sequence. |
StopSequence | Stop playing a sequence. |
ActiveSensing | Synchronization pulse... |
SystemReset | Reset to power-up status. |
data MidiMetaEvent Source
Meta event
In Format 1 files general events (e.g. text events) should only appear in track 1. Certain events (e.g. end-of-track) can appear in any track where necessary.
TextEvent MidiTextType String | text_type * contents Free text field (e.g. copyright statement). The contents can notionally be any length. |
SequenceNumber Word16 | value Format 1 files - only track 1 should have a sequence number. Format 2 files - a sequence number should identify each track. The sequence number event should occur at the start of a track, before any non-zero time events. |
ChannelPrefix Word8 Word8 | 1 * channel Relay all meta and sys-ex events to the given channel. The first byte should always be 1. |
EndOfTrack | End-of-track event. |
SetTempo Word32 | microseconds_per_quarter_note |
SMPTEOffset Word8 Word8 Word8 Word8 Word8 | hour * minute * second * frac * subfrac The SMPTE time when a track should start. This event should occur at the start of a track, before any non-zero time events. |
TimeSignature Word8 Word8 Word8 Word8 | numerator * denominator * metro * num_32nd_notes |
KeySignature Int8 MidiScaleType | key_type * scale_type
|
SSME Word32 [Word8] | length * data Sequencer specific meta-event - uninterpreted. |
data MidiTimeDivision Source
Default unit of time in the MIDI file.
data MidiTextType Source
Enumeration of the text meta event types.
data MidiScaleType Source
Scale type - major
or minor
.