Portability | As per dependencies. |
---|---|
Stability | unstable |
Maintainer | Stephen Tetley <stephen.tetley@gmail.com> |
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 MidiFile = MidiFile {}
- data Header = Header {}
- newtype Track = Track {
- getMessages :: [Message]
- data Format
- type DeltaTime = Word32
- type Message = (DeltaTime, Event)
- data Event
- data DataEvent = Data1 TagByte
- data VoiceEvent
- data SysExEvent = SysEx Word32 [Word8]
- data SysCommonEvent
- = QuarterFrame SplitByte
- | SongPosPointer Word8 Word8
- | SongSelect Word8
- | Common_undefined TagByte
- | TuneRequest
- | EOX
- data SysRealTimeEvent
- = TimingClock
- | RT_undefined TagByte
- | StartSequence
- | ContinueSequence
- | StopSequence
- | ActiveSensing
- | SystemReset
- data MetaEvent
- data TimeDivision
- data TextType
- = GENERIC_TEXT
- | COPYRIGHT_NOTICE
- | SEQUENCE_NAME
- | INSTRUMENT_NAME
- | LYRICS
- | MARKER
- | CUE_POINT
- data ScaleType
- data SplitByte = SB {}
- splitByte :: Word8 -> SplitByte
- joinByte :: SplitByte -> Word8
- data Varlen
- fromVarlen :: Varlen -> Word32
- toVarlen :: Word32 -> Varlen
- hexStr :: Integral a => a -> String
MidiFile representation.
MidiFile
: header * tracks
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
.
Track | |
|
The file format - in a MIDI file this is a big-endian word16 with 0,1 or 2 being the only valid values.
All time values in a MIDI track are represented as a delta from the previous event rather than an absolute time.
Although DeltaTime is a type synonym for Word32, in MIDI
files it is represented as a varlen
to save space.
DataEvent DataEvent | Data event - just initial tag byte, uninterpreted |
VoiceEvent VoiceEvent | Voice event (e.g |
SysExEvent SysExEvent | SysEx - system exclusive event. Usually synthesizer specific, not interpreted. |
SysCommonEvent SysCommonEvent | SysCommon - system common event. |
SysRealTimeEvent SysRealTimeEvent | SysRealTime - system realtime event. |
MetaEvent MetaEvent | Meta event - interpreted (e.g. |
Data events are events with tags from 0x00 to 0x7F.
Data events have no payload - they are represented only by the tag byte.
Data1 TagByte |
data VoiceEvent 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 SysExEvent Source
SysEx - system exclusive event.
data SysCommonEvent 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 SplitByte | Time code quarter frame. |
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 SysRealTimeEvent 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. |
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 TextType 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 ScaleType | key_type * scale_type
|
SSME Word32 [Word8] | length * data Sequencer specific meta-event - uninterpreted. |
data TimeDivision Source
Default unit of time in the MIDI file.
Enumeration of the text meta event types.
Scale type - major
or minor
.
Interim types.
SplitByte
SplitByte - divide a byte into the upper four and lower 4 bits.
Varlen
Space efficient representation of length fields.
This data type is not used directly in the syntax tree where it would be cumbersome. But it is used as an intermediate type in the parser and emitter.
fromVarlen :: Varlen -> Word32Source