Module mididi.types
The implementation (and some of the documentation) is based on this specification: https://www.cs.cmu.edu/~music/cmsip/readings/Standard-MIDI-file-format-updated.pdf
Authors: https://github.com/w2ptr
Members
Name | Kind | Description |
---|---|---|
MIDI |
struct | description |
Chunk |
struct | description |
HeaderChunk |
struct | description |
TimeDivision |
struct | description |
TrackChunk |
struct | description |
TrackEvent |
struct | description |
MIDIEvent |
struct | description |
SysExEvent |
struct | description |
MetaEvent |
struct | description |
struct MIDI
MIDI
represents the data of a complete MIDI file.
struct Chunk
A more general chunk type, which is essentially a tagged union of HeaderChunk
and TrackChunk
.
Use asHeaderChunk()
or asTrackChunk()
to find out which one this is.
method inout(mididi.types.HeaderChunk)* asHeaderChunk()
Returns:
a pointer to the header chunk or null
if this chunk is not a header
chunk
method inout(mididi.types.TrackChunk)* asTrackChunk()
Returns:
a pointer to the track chunk or null
if this chunk is not a track
chunk
struct HeaderChunk
HeaderChunk
is the first chunk in a MIDI file. It gives information about the
format of the other chunks.
member variable mididi.def.TrackFormat trackFormat
The track format (the possible values are given in the enum
mididi.def.TrackFormat
).
Cast this to ushort
to get the raw value, which should be either 0, 1 or
2.
member variable ushort nTracks
The number of tracks in the data.
nTracks
should always be 1 for if trackFormat
is TrackFormat.single
.
struct TimeDivision
method mididi.types.TimeDivision fromRawValue(ushort rawValue)
fromRawValue
creates a TimeDivision
object from the raw encoding of
this property in the header chunk.
property ushort rawValue()
(read-only)
method int getFormat()
Returns the time division's format. If the format is 0
, then use
getTicksPerQuarterNote()
. If it is 1
, use getNegativeSMPTEFormat()
and getTicksPerFrame()
.
Returns:
0
if the division's format is how many ticks make up a quarter note
(bit 15 is 0) or 1
if it is ticks-per-frame (bit 15 is 1)
method ushort getTicksPerQuarterNote()
Preconditions:
getFormat()
must be 0
method byte getNegativeSMPTEFormat()
Returns:
one of the four standard SMPTE formats (-24, -25, -29, -30),
representing the negative of the number of frames/second
Preconditions:
getFormat()
must be 1
method ubyte getTicksPerFrame()
Returns:
the number of ticks per frame
Preconditions:
getFormat()
must be 1
struct TrackChunk
A track chunk is a chunk that stores the actual data. It contains a number of track events.
struct TrackEvent
A TrackEvent
is a delta time coupled with either a MIDI event, a system
exclusive event or a meta event.
TrackEvent
has an underlying union that uses the status byte to discriminate
(which cannot be changed after construction). Use asMIDIEvent()
,
asSysExEvent()
or asMetaEvent()
to access the underlying values from the
union.
See the documentation of mididi.def.isMIDIEvent()
to see what each type of
message means.
Note: system exclusive events ARE also semantically system
common messages. The confusing thing is that all other system common messages
are syntactically MIDI events, but system exclusive events are not MIDI events.
Example:
Here is an example of how to use TrackEvent
.
auto statusByte = cast(ubyte) ((ChannelMessageType.noteOn << 4) | 0x7);
auto event = TrackEvent(
200,
MIDIEvent(statusByte, [0x0F, 0x00]),
);
// get underlying value
assert(event.asSysExEvent() is null);
assert(event.asMetaEvent() is null);
const message = event.asMIDIEvent();
assert(message !is null);
// MIDI event = either a channel message or a system message
assert(message.isChannelMessage());
assert(!message.isSystemMessage());
// since it's a channel message, we can use these properties of the
// `MIDIEvent` struct:
assert(message.getChannelMessageType() == ChannelMessageType.noteOn);
assert(message.getChannelNumber() == 0x7);
assert(message.data == [0x0F, 0x00]);
constructor this(int deltaTime, mididi.types.MIDIEvent event)
constructor this(int deltaTime, mididi.types.SysExEvent event)
constructor this(int deltaTime, mididi.types.MetaEvent event)
These constructors initialize the object with a delta time and an event.
member variable int deltaTime
deltaTime
is the time between the previous event and this event.
Its meaning depends on the time division in the header chunk.
If the header chunk of the MIDI
has a division format of 0, then this
delta time represents a fraction of a beat (a beat that has length
getTicksPerQuarterNote()
); if the format is 1, then this is a fraction of
a second. TODO: I don't get it myself; research SMPTE format and MIDI time code!!!!!
property ubyte statusByte()
Returns:
this event's status byte (see TrackEvent
's' documentation)
Note: this property cannot be changed after construction
method inout(mididi.types.MIDIEvent)* asMIDIEvent()
method inout(mididi.types.SysExEvent)* asSysExEvent()
method inout(mididi.types.MetaEvent)* asMetaEvent()
Returns:
a pointer to the underlying MIDIEvent
, SysExEvent
or MetaEvent
if the object is of that variety; null
otherwise
Note:
do not reassign the TrackEvent
object while still having a reference
to the object in the union.
method bool opEquals(ref const(mididi.types.TrackEvent) rhs)
method ulong toHash()
Equality and hash methods.
struct MIDIEvent
A MIDI event is any normal channel message or system message (except for system exclusive events).
See also:
mididi.def.isMIDIEvent
member variable ubyte[2] data
The data bytes in this message.
The first bit of both bytes must be 0 and if the message type only needs
one byte, the second byte should be 0x00
.
method mididi.def.ChannelMessageType getChannelMessageType()
method ubyte getChannelNumber()
These methods give the channel message type and the channel number (upper and lower four bits, respectively).
Preconditions:
this message must be a channel message, so this.isChannelMessage()
must be true.
See also:
mididi.def.ChannelMessageType
method mididi.def.SystemMessageType getSystemMessageType()
Preconditions:
this message must be a system message, so this.isSystemMessage()
must
be true.
See also:
mididi.def.SystemMessageType
method bool opEquals(ref const(mididi.types.MIDIEvent) rhs)
method ulong toHash()
Equality and hash methods.
struct SysExEvent
A system exclusive event is one unit ("packet") of a system exclusive message, which can be used as an escape to emit any arbitrary bytes.
See also:
mididi.def.isSysExEvent
member variable mididi.def.SystemMessageType type
The kind of system exclusive event. This can be either systemExclusive
(0xF0
) or endOfExclusive
(0xF7
).
struct MetaEvent
A meta event is an event that is not regular MIDI message, used to send meta information. Not every meta event has to be supported or acted upon.
See Also:
mididi.def.isMetaEvent
; mididi.def.MetaEventType