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 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.

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]);

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.

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

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

Source

Click here to view the source of this module.