Maestro - Midi Player Tool Kit for Unity Version 2.18.2
Loading...
Searching...
No Matches
MPTKWriter

Scripted MIDI authoring, editing, and export APIs (Maestro Pro). More...

Topics

 Initialization and Import
 Constructor, reset, and event-list import/merge APIs.
 Tempo and Time Conversion
 Tempo state and tick/millisecond conversion helpers.
 Sequence State and Event Collections
 Core sequence metadata and event-list accessors.
 Loading Existing MIDI Content
 Load MIDI data into the writer from file system or MidiDB.
 Track Statistics
 Build per-track counters from current event content.
 MIDI Event Creation API
 Author notes, controls, tempo/signature, and meta events.
 Event List Maintenance and Timing Recalculation
 Delete, sort, and recompute timing data for event lists.
 Export and Diagnostics
 Export to MIDI outputs and inspect writer/raw event state.

Classes

class  MidiPlayerTK.MPTKWriter
 Create, build, write, import, and play MIDI from script. See full examples in: More...

MIDI Event Creation API

Add musical, control, and meta events to the sequence.

This section is the main authoring API for building MIDI content: notes, chords, program/controller changes, pitch wheel, tempo/signature, and text meta events.

bool MidiPlayerTK.MPTKWriter.ExtendedText [get, set]
 If true, META text (for example lyrics) is written with UTF-8 encoding. Default is false.
Standard MIDI text meta events are ASCII. With this extension, you can also store and display
non-ASCII characters (Korean, Chinese, Japanese, accented Latin characters, and more).
To enable reading UTF8 characters from an MPTK MIDI player, set MidiFilePlayer.MPTK_ExtendedText to true.
.
MPTKEvent MidiPlayerTK.MPTKWriter.AddNote (int track, long tick, int channel, int note, int velocity, int length)
 Adds a NoteOn event at an absolute tick position.
A corresponding NoteOff is generated automatically when length is greater than 0.
If length is less than 0, no automatic NoteOff is created.
MPTKEvent MidiPlayerTK.MPTKWriter.AddSilence (int track, long tick, int channel, int length)
 Adds a silence placeholder.
.
void MidiPlayerTK.MPTKWriter.AddChordFromScale (int track, long tick, int channel, MPTKScaleLib scale, MPTKChordBuilder chord)
 Adds a chord built from a scale range.
MPTKEvent MidiPlayerTK.MPTKWriter.AddRawEvent (MPTKEvent mptkEvent)
 Adds an event directly from an MPTKEvent instance.
.
MPTKEvent MidiPlayerTK.MPTKWriter.AddOff (int track, long tick, int channel, int note)
 Adds a note-off event.
It must always follow the corresponding NoteOn, on the same channel.
void MidiPlayerTK.MPTKWriter.AddChordFromLib (int track, long tick, int channel, MPTKChordName chordName, MPTKChordBuilder chord)
 Adds a chord from a chord library.
MPTKEvent MidiPlayerTK.MPTKWriter.AddChangePreset (int track, long tick, int channel, int preset)
 Adds a preset change.
MPTKEvent MidiPlayerTK.MPTKWriter.AddChannelAfterTouch (int track, long tick, int channel, int afterTouchPressure)
 Adds a Channel After-Touch event.
MPTKEvent MidiPlayerTK.MPTKWriter.AddControlChange (int track, long tick, int channel, MPTKController controller, int controllerValue)
 Creates a general Control Change event (CC).
MPTKEvent MidiPlayerTK.MPTKWriter.AddPitchWheelChange (int track, long tick, int channel, float pitchWheel)
 Creates a Pitch Wheel event from a normalized value.
pitchWheel:
MPTKEvent MidiPlayerTK.MPTKWriter.AddBPMChange (int track, long tick, int bpm)
 Adds a tempo change to the MIDI stream. There is no channel parameter because a tempo change is applied to all tracks and channels.
Subsequent duration/time conversions use the new BPM value.
MPTKEvent MidiPlayerTK.MPTKWriter.AddTempoChange (int track, long tick, int microsecondsPerQuarterNote)
 Adds a tempo change to the MIDI stream in microseconds per quarter note.
There is no channel parameter because a tempo change is applied to all tracks and channels.
Subsequent duration/time conversions use the new tempo value.
MPTKEvent MidiPlayerTK.MPTKWriter.AddTimeSignature (int track, long tick, int numerator=4, int denominator=2, int ticksInMetronomeClick=24, int no32ndNotesInQuarterNote=32)
 Creates a TimeSignature meta event (optional). The internal sequencer default is 4,2,24,32. No channel is required because time signature applies globally. More information: https://paxstellar.fr/2020/09/11/midi-timing/.
MPTKEvent MidiPlayerTK.MPTKWriter.AddText (int track, long tick, MPTKMeta typeMeta, string text)
 Creates a MIDI text event.

Event List Maintenance and Timing Recalculation

Modify event collections and recompute sorted/timed state.

Use these methods to delete subsets of events, apply stable sorting, and rebuild real-time/measure/beat values after content changes.

void MidiPlayerTK.MPTKWriter.CalculateTiming (bool logPerf=false, bool logDebug=false)
 Calculates real-time position, measure, and beat for each event.

Export and Diagnostics

Export MIDI files and inspect generated output/logs.

This section converts MPTK events to NAudio structures, writes files to disk or MidiDB, and provides detailed logging helpers for validation.

MidiFile MidiPlayerTK.MPTKWriter.BuildNAudioMidi ()
 Builds an NAudio MidiFile object from MPTK_MidiEvents. WriteToMidiDB and WriteToFile call this method before exporting.
bool MidiPlayerTK.MPTKWriter.LogWriter ()
 Logs writer state and MIDI events.
void MidiPlayerTK.MPTKWriter.LogTempoMap ()
 Logs information about the tempo map.
void MidiPlayerTK.MPTKWriter.LogSignMap ()
 Logs information about the signature map.
void MidiPlayerTK.MPTKWriter.LogTrackStat ()
 Logs information about track statistics.
bool MidiPlayerTK.MPTKWriter.LogRaw ()
 Logs raw NAudio MIDI events built from the current writer state.

Detailed Description

Scripted MIDI authoring, editing, and export APIs (Maestro Pro).

This module covers the MPTKWriter class and its workflow-oriented API.

Includes
  • initialization and import
  • tempo/time conversion
  • sequence state and loading
  • event creation and maintenance
  • export and diagnostics

Function Documentation

◆ AddNote()

MPTKEvent MidiPlayerTK.MPTKWriter.AddNote ( int track,
long tick,
int channel,
int note,
int velocity,
int length )

Adds a NoteOn event at an absolute tick position.
A corresponding NoteOff is generated automatically when length is greater than 0.
If length is less than 0, no automatic NoteOff is created.

Parameters
trackTrack for this event (do not add to track 0)
tickAbsolute tick position for this event.
channelChannel must be in the range 0-15
noteNote must be in the range 0-127
velocityVelocity must be in the range 0-127.
lengthDuration in ticks. If less than 0, you must add NoteOff manually with AddOff.
Returns
The MIDI event created, or null on error.

◆ AddSilence()

MPTKEvent MidiPlayerTK.MPTKWriter.AddSilence ( int track,
long tick,
int channel,
int length )

Adds a silence placeholder.
.

Note
MIDI has no native "silent note". This method simulates silence with a NoteOn event at velocity 1.
A NoteOn velocity of 0 is interpreted as NoteOff by the MIDI standard.
Parameters
trackTrack for this event (do not add to track 0)
tickTick time for this event.
channelChannel must be in the range 0-15
lengthDuration in ticks.
Returns
The MIDI event created, or null on error.

◆ AddChordFromScale()

void MidiPlayerTK.MPTKWriter.AddChordFromScale ( int track,
long tick,
int channel,
MPTKScaleLib scale,
MPTKChordBuilder chord )

Adds a chord built from a scale range.

// Play 4 chords, degree I - V - IV - V
// ------------------------------------
mfw.AddText(track0, absoluteTime, MPTKMeta.SequenceTrackName, "Play 4 chords, degree I - V - IV - V ");
// We need degrees in major, so build a major range
MPTKScaleLib scaleMajor = MPTKScaleLib.CreateScale(MPTKScaleName.MajorHarmonic);
// Build chord degree 1
MPTKChordBuilder chordDegreeI = new MPTKChordBuilder()
{
// Parameters to build the chord
Tonic = 60, // play in C
Count = 3, // 3 notes to build the chord (between 2 and 20, of course it doesn't make sense more than 7, its only for fun or experiementation ...)
Degree = 1,
// Midi Parameters how to play the chord
Duration = duration, // millisecond, -1 to play indefinitely
Velocity = 80, // Sound can vary depending on the iQuarter
// Optionnal MPTK specific parameters
Arpeggio = 0, // delay in milliseconds between each notes of the chord
Delay = 0, // delay in milliseconds before playing the chord
};
// Build chord degree V
MPTKChordBuilder chordDegreeV = new MPTKChordBuilder() { Tonic = 60, Count = 3, Degree = 5, Duration = duration, Velocity = 80, };
// Build chord degree IV
MPTKChordBuilder chordDegreeIV = new MPTKChordBuilder() { Tonic = 60, Count = 3, Degree = 4, Duration = duration, Velocity = 80, };
// Add degrees I - V - IV - V in the MIDI (all in major)
mfw.AddChordFromScale(track1, absoluteTime, channel0, scaleMajor, chordDegreeI); absoluteTime += ticksPerQuarterNote;
mfw.AddChordFromScale(track1, absoluteTime, channel0, scaleMajor, chordDegreeV); absoluteTime += ticksPerQuarterNote;
mfw.AddChordFromScale(track1, absoluteTime, channel0, scaleMajor, chordDegreeIV); absoluteTime += ticksPerQuarterNote;
mfw.AddChordFromScale(track1, absoluteTime, channel0, scaleMajor, chordDegreeV); absoluteTime += ticksPerQuarterNote;
Parameters
trackTrack for this event (do not add to track 0)
tickStart tick for all generated notes.
channelMIDI channel (0-15).
scaleScale definition (see MPTKScaleLib).
chordChord builder settings (see MPTKChordBuilder).

◆ CalculateTiming()

void MidiPlayerTK.MPTKWriter.CalculateTiming ( bool logPerf = false,
bool logDebug = false )

Calculates real-time position, measure, and beat for each event.

  • Calculate MPTK_TempoMap with #MPTKTempo.MPTK_CalculateMap
  • Calculate MPTK_SignMap with #MPTKSignature.MPTK_CalculateMap
  • Calculates time and duration of each event from tick values and the tempo map.
  • Calculates measure and beat using the time-signature map.
    Version
    2.10.0
    // A MidiFileWriter2 (mfw) has been created with new MidiFileWriter2() With a set of MIDI events.
    // Sort the events by ascending absolute time (optional)
    // Calculate time, measure and beat for each events
    mfw.CalculateTiming(logDebug: true, logPerf: true);
    mfw.LogWriter();
    Parameters
    logPerfEnable performance logging.
    logDebugEnable detailed debug logging.

◆ BuildNAudioMidi()

MidiFile MidiPlayerTK.MPTKWriter.BuildNAudioMidi ( )

Builds an NAudio MidiFile object from MPTK_MidiEvents. WriteToMidiDB and WriteToFile call this method before exporting.

Returns
NAudio MidiFile instance.

◆ LogWriter()

bool MidiPlayerTK.MPTKWriter.LogWriter ( )

Logs writer state and MIDI events.

Returns
True when logging completes without exception.

◆ LogRaw()

bool MidiPlayerTK.MPTKWriter.LogRaw ( )

Logs raw NAudio MIDI events built from the current writer state.

Returns
True when logging completes without exception.

◆ AddRawEvent()

MPTKEvent MidiPlayerTK.MPTKWriter.AddRawEvent ( MPTKEvent mptkEvent)

Adds an event directly from an MPTKEvent instance.
.

The following fields must be set in the input event:

◆ AddOff()

MPTKEvent MidiPlayerTK.MPTKWriter.AddOff ( int track,
long tick,
int channel,
int note )

Adds a note-off event.
It must always follow the corresponding NoteOn, on the same channel.

Parameters
trackTrack for this event (do not add to track 0)
tickAbsolute tick position for this event.
channelChannel must be in the range 0-15
noteNote must be in the range 0-127
Returns
The matching NoteOn event that was updated, or null if not found/error.

◆ AddChordFromLib()

void MidiPlayerTK.MPTKWriter.AddChordFromLib ( int track,
long tick,
int channel,
MPTKChordName chordName,
MPTKChordBuilder chord )

Adds a chord from a chord library.

MPTKChordBuilder chordLib = new MPTKChordBuilder() { Tonic = 60, Duration = duration, Velocity = 80, };
mfw.AddChordFromLib(track1, absoluteTime, channel0, MPTKChordName.Major, chordLib); absoluteTime += ticksPerQuarterNote;
chordLib.Tonic = 62;
mfw.AddChordFromLib(track1, absoluteTime, channel0, MPTKChordName.mM7, chordLib); absoluteTime += ticksPerQuarterNote;
chordLib.Tonic = 67;
mfw.AddChordFromLib(track1, absoluteTime, channel0, MPTKChordName.m7b5, chordLib); absoluteTime += ticksPerQuarterNote;
chordLib.Tonic = 65;
mfw.AddChordFromLib(track1, absoluteTime, channel0, MPTKChordName.M7, chordLib); absoluteTime += ticksPerQuarterNote;
Parameters
trackTrack for this event (do not add to track 0)
tickStart tick for all generated notes.
channelMIDI channel (0-15).
chordNameChord name (see MPTKChordName).
chordChord builder settings (see MPTKChordBuilder).

◆ AddChangePreset()

MPTKEvent MidiPlayerTK.MPTKWriter.AddChangePreset ( int track,
long tick,
int channel,
int preset )

Adds a preset change.

Parameters
trackTrack for this event (do not add to track 0)
tickTick time for this event
channelChannel must be in the range 0-15
presetPreset (program/patch) must be in the range 0-127
Returns
Return the MIDI event created or null if error

◆ AddChannelAfterTouch()

MPTKEvent MidiPlayerTK.MPTKWriter.AddChannelAfterTouch ( int track,
long tick,
int channel,
int afterTouchPressure )

Adds a Channel After-Touch event.

Parameters
trackTrack for this event (do not add to track 0)
tickTick time for this event
channelChannel must be in the range 0-15
afterTouchPressureAfter-touch pressure from 0 to 127
Returns
Return the MIDI event created or null if error

◆ AddControlChange()

MPTKEvent MidiPlayerTK.MPTKWriter.AddControlChange ( int track,
long tick,
int channel,
MPTKController controller,
int controllerValue )

Creates a general Control Change event (CC).

Parameters
trackTrack for this event (do not add to track 0)
tickTick time for this event
channelChannel must be in the range 0-15
controllerThe MIDI Controller. See MPTKController
controllerValueController value
Returns
Return the MIDI event created or null if error

◆ AddPitchWheelChange()

MPTKEvent MidiPlayerTK.MPTKWriter.AddPitchWheelChange ( int track,
long tick,
int channel,
float pitchWheel )

Creates a Pitch Wheel event from a normalized value.
pitchWheel:

  • 0.0 = minimum (MIDI value 0)
  • 0.5 = center (MIDI value 8192)
  • 1.0 = maximum (MIDI value 16383)
Parameters
trackTrack for this event (do not add to track 0)
tickTick time for this event
channelChannel must be in the range 0-15
pitchWheelNormalized pitch-wheel value in range [0..1].
Returns
The MIDI event created, or null on error.

◆ AddBPMChange()

MPTKEvent MidiPlayerTK.MPTKWriter.AddBPMChange ( int track,
long tick,
int bpm )

Adds a tempo change to the MIDI stream. There is no channel parameter because a tempo change is applied to all tracks and channels.
Subsequent duration/time conversions use the new BPM value.

Note
MPTK_TempoMap is not updated automatically; call CalculateTiming to rebuild maps.
Parameters
trackTrack for this event (it is good practice to use track 0 for this event).
tickAbsolute tick position for this event.
bpmQuarters per minute.
Returns
The MIDI event created, or null on error.

◆ AddTempoChange()

MPTKEvent MidiPlayerTK.MPTKWriter.AddTempoChange ( int track,
long tick,
int microsecondsPerQuarterNote )

Adds a tempo change to the MIDI stream in microseconds per quarter note.
There is no channel parameter because a tempo change is applied to all tracks and channels.
Subsequent duration/time conversions use the new tempo value.

Note
MPTK_TempoMap is not updated automatically. See example:
// A MidiFileWriter2 (mfw) has been created with new MidiFileWriter2() With a set of MIDI events.
// Sort the events by ascending absolute time (optional)
// Calculate time, measure and beat for each events
mfw.CalculateTiming(logDebug: true, logPerf: true);
mfw.LogWriter();
Parameters
trackTrack for this event (it is good practice to use track 0 for this event).
tickAbsolute tick position for this event.
microsecondsPerQuarterNoteTempo in microseconds per quarter note.
Returns
The MIDI event created, or null on error.

◆ AddTimeSignature()

MPTKEvent MidiPlayerTK.MPTKWriter.AddTimeSignature ( int track,
long tick,
int numerator = 4,
int denominator = 2,
int ticksInMetronomeClick = 24,
int no32ndNotesInQuarterNote = 32 )

Creates a TimeSignature meta event (optional). The internal sequencer default is 4,2,24,32. No channel is required because time signature applies globally. More information: https://paxstellar.fr/2020/09/11/midi-timing/.

Note
MPTK_SignMap is not updated. See example:
// A MidiFileWriter2 (mfw) has been created with new MidiFileWriter2() With a set of MIDI events.
// Sort the events by ascending absolute time (optional)
// Calculate time, measure and beat for each events
mfw.CalculateTiming(logDebug: true, logPerf: true);
mfw.LogWriter();
Parameters
trackTrack for this event (it is good practice to use track 0 for this event).
tickAbsolute tick position where the event is added.
numeratorNumerator, beats per measure. Will be MPTKSignature.NumberBeatsMeasure in MPTK_SignMap
denominatorDenominator, beat unit: 1 means 2, 2 means 4 (crochet), 3 means 8 (quaver), 4 means 16, ...
ticksInMetronomeClickTicks in Metronome Click. Set to 24 for a standard value.
no32ndNotesInQuarterNoteNumber of 32nd notes per quarter note. Standard MIDI value is usually 8.
Returns
The MIDI event created, or null on error.

◆ AddText()

MPTKEvent MidiPlayerTK.MPTKWriter.AddText ( int track,
long tick,
MPTKMeta typeMeta,
string text )

Creates a MIDI text event.

private MPTKWriter CreateMidiStream_inner_loop_set_with_META()
{
int ticksPerQuarterNote = 500;
// A querter each DTPQN
MPTKWriter mfw = new MPTKWriter(deltaTicksPerQuarterNote: ticksPerQuarterNote, 1);
long absoluteTime = 0;
mfw.AddBPMChange(track: 0, absoluteTime, 120);
mfw.AddChangePreset(track: 1, absoluteTime, channel: 0, preset: 0);
Debug.Log("Create first loop @ACTION:INNER_LOOP(500,1000,4)");
mfw.AddText(track: 1, absoluteTime, MPTKMeta.TextEvent, "@ACTION:INNER_LOOP(500,1000,4)");
// Generate 4 measures of 4 quarters
for (int note = 0; note < 16; note++)
{
// Duration = 0.25 second for a quarter at BPM 240
mfw.AddNote(track: 1, absoluteTime, channel: 0, note: note + 50, velocity: 100, length: ticksPerQuarterNote);
absoluteTime += ticksPerQuarterNote;
}
// absoluteTime = 8000 at this step
Debug.Log($"Create second loop at position {absoluteTime} @ACTION:INNER_LOOP(8500,9000,4)");
mfw.AddText(track: 1, absoluteTime, MPTKMeta.TextEvent, "@ACTION:INNER_LOOP(8500,9000,4)");
// Generate 4 measures of 4 quarters
for (int note = 16; note < 32; note++)
{
// Duration = 0.25 second for a quarter at BPM 240
mfw.AddNote(track: 1, absoluteTime, channel: 0, note: note + 50, velocity: 100, length: ticksPerQuarterNote);
absoluteTime += ticksPerQuarterNote;
}
return mfw;
}
Parameters
trackTrack for this event (good practice: track 0).
tickAbsolute tick position of this event.
typeMetaMeta-event type.
textThe text associated with this MIDI event.
Returns
The MIDI event created, or null on error.

Properties

◆ ExtendedText

bool MidiPlayerTK.MPTKWriter.ExtendedText
getset

If true, META text (for example lyrics) is written with UTF-8 encoding. Default is false.
Standard MIDI text meta events are ASCII. With this extension, you can also store and display
non-ASCII characters (Korean, Chinese, Japanese, accented Latin characters, and more).
To enable reading UTF8 characters from an MPTK MIDI player, set MidiFilePlayer.MPTK_ExtendedText to true.
.

Warning
This is an MPTK extension of the MIDI standard, so if you read your MIDI file with another application, you may not find your original text.
Version
2.11.3