MidiPlayerTK.MidiFileWriter2

Create, build, write, import, play MIDI by script. See full example with these scripts: More...

Public Member Functions

 MidiFileWriter2 (int deltaTicksPerQuarterNote=240, int midiFileType=1, int bpm=120)
 
MPTKEvent MPTK_AddBPMChange (int track, long tick, int bpm)
 
MPTKEvent MPTK_AddChangePreset (int track, long tick, int channel, int preset)
 
MPTKEvent MPTK_AddChangePresetMilli (int track, float timeToPlay, int channel, int preset)
 
MPTKEvent MPTK_AddChannelAfterTouch (int track, long tick, int channel, int afterTouchPressure)
 
MPTKEvent MPTK_AddChannelAfterTouchMilli (int track, float timeToPlay, int channel, int afterTouchPressure)
 
void MPTK_AddChordFromLib (int track, long tick, int channel, MPTKChordName chordName, MPTKChordBuilder chord)
 
void MPTK_AddChordFromScale (int track, long tick, int channel, MPTKScaleLib scale, MPTKChordBuilder chord)
 
MPTKEvent MPTK_AddControlChange (int track, long tick, int channel, MPTKController controller, int controllerValue)
 
MPTKEvent MPTK_AddControlChangeMilli (int track, float timeToPlay, int channel, MPTKController controller, int controllerValue)
 
MPTKEvent MPTK_AddNote (int track, long tick, int channel, int note, int velocity, int length)
 
MPTKEvent MPTK_AddNoteMilli (int track, float timeToPlay, int channel, int note, int velocity, float duration)
 
MPTKEvent MPTK_AddOff (int track, long tick, int channel, int note)
 
MPTKEvent MPTK_AddOffMilli (int track, float timeToPlay, int channel, int note)
 
MPTKEvent MPTK_AddPitchWheelChange (int track, long tick, int channel, float pitchWheel)
 
MPTKEvent MPTK_AddPitchWheelChangeMilli (int track, float timeToPlay, int channel, float pitchWheel)
 
MPTKEvent MPTK_AddRawEvent (MPTKEvent mptkEvent)
 
MPTKEvent MPTK_AddSilence (int track, long tick, int channel, int length)
 
MPTKEvent MPTK_AddSilenceMilli (int track, float timeToPlay, int channel, float duration)
 
MPTKEvent MPTK_AddTempoChange (int track, long tick, int microsecondsPerQuarterNote)
 
MPTKEvent MPTK_AddText (int track, long tick, MPTKMeta typeMeta, string text)
 
MPTKEvent MPTK_AddTextMilli (int track, float timeToPlay, MPTKMeta typeMeta, string text)
 
MPTKEvent MPTK_AddTimeSignature (int track, long tick, int numerator=4, int denominator=2, int ticksInMetronomeClick=24, int no32ndNotesInQuarterNote=32)
 
MidiFile MPTK_BuildNAudioMidi ()
 
void MPTK_CalculateTiming (bool logPerf=false, bool logDebug=false)
 
void MPTK_Clear ()
 
long MPTK_ConvertMilliToTick (float time, int indexTempo=-1)
 
float MPTK_ConvertTickToMilli (long tick, int indexTempo=-1)
 
void MPTK_CreateTrack (int count)
 
Dictionary< long, MPTKStat > MPTK_CreateTracksStat ()
 Build the tracks information (MPTK_TrackStat) from the MIDI event found in MPTK_Events. MPTK_TrackStat is a dictionary with the track number as a key and the item holds some informatio about the track. More...
 
bool MPTK_Debug ()
 
bool MPTK_DebugRaw ()
 
void MPTK_DeleteChannel (int channel)
 
void MPTK_DeleteTrack (int track)
 
long MPTK_DurationMilliToTick (float time)
 
long MPTK_DurationTickToMilli (long tick)
 
void MPTK_EndTrack (int trackNumber)
 
bool MPTK_ImportFromEventsList (List< MPTKEvent > midiEventsToInsert, int deltaTicksPerQuarterNote, long position=-1, string name=null, bool logPerf=false, bool logDebug=false)
 
bool MPTK_LoadFromFile (string filename)
 
bool MPTK_LoadFromMidiDB (int indexMidiDb)
 
bool MPTK_LoadFromMPTK ()
 
void MPTK_LogSignMap ()
 
void MPTK_LogTempoMap ()
 
void MPTK_LogTrackStat ()
 
void MPTK_StableSortEvents (bool logPerf=false)
 
bool MPTK_WriteToFile (string filename)
 
bool MPTK_WriteToMidiDB (string filename)
 

Static Public Member Functions

static int MPTK_BPM2MPQN (double bpm)
 
static int MPTK_GetMicrosecondsPerQuaterNote (int bpm)
 
static double MPTK_MPQN2BPM (int microsecondsPerQuaterNote)
 

Public Attributes

int MPTK_DeltaTicksPerQuarterNote
 
List< MPTKEventMPTK_MidiEvents
 
int MPTK_MidiFileType
 
string MPTK_MidiName
 
List< MPTKSignatureMPTK_SignMap
 
List< MPTKTempoMPTK_TempoMap
 
long MPTK_TickLast
 

Properties

double Bpm [get]
 
int MPTK_CountEvent [get]
 
MPTKEvent MPTK_LastEvent [get]
 
int MPTK_MicrosecondsPerQuaterNote [get]
 
int MPTK_NumberBeatsMeasure [get, set]
 
float MPTK_PulseLenght [get]
 
double MPTK_Tempo [get]
 
int MPTK_TrackCount [get]
 

Detailed Description

Create, build, write, import, play MIDI by script. See full example with these scripts:

  • TestMidiGenerator.cs for MIDI creation examples.
  • TinyMidiSequencer.cs for a light sequencer.
  • MidiEditorProWindow.cs.cs for a full Midi Editor.
    Note
    Method like MPTK_AddxxxxMilli will be soon deprecated. Explanation:
    Adding MIDI event is done with method like MPTK_Addxxxxxxx. There is two kind of method: adding with a tick position (MPTK_AddNote) or with a time position (MPTK_AddNoteMilli). For clarity, all MPTK_AddxxxxMilli will be deprecated in future version. The method MPTK_ConvertTickToMilli will be used in place. More information here: https://paxstellar.fr/class-midifilewriter2/
    Version
    Maestro Pro
    private MidiFileWriter2 CreateMidiStream_preset_tempo_pitchWheel()
    {
    // In this demo, we are using variable to contains tracks and channel values only for better understanding.
    // Using multiple tracks is not mandatory, you can arrange your song as you want.
    // But first track (index=0) is often use for general MIDI information track, lyrics, tempo change. By convention contains no noteon.
    int track0 = 0;
    // Second track (index=1) will contains the notes, preset change, .... all events associated to a channel.
    int track1 = 1;
    int channel0 = 0; // we are using only one channel in this demo
    // https://paxstellar.fr/2020/09/11/midi-timing/
    int beatsPerMinute = 60;
    // a classical value for a Midi. define the time precision
    int ticksPerQuarterNote = 500;
    // Create a Midi file of type 1 (recommended)
    MidiFileWriter2 mfw = new MidiFileWriter2(ticksPerQuarterNote, 1);
    // Time to play a note expressed in ticks.
    // All durations are expressed in ticks, so this value can be used to convert
    // duration notes as quarter to ticks. https://paxstellar.fr/2020/09/11/midi-timing/
    // If ticksPerQuarterNote = 120 and absoluteTime = 120 then the note will be played a quarter delay from the start.
    // If ticksPerQuarterNote = 120 and absoluteTime = 1200 then the note will be played a 10 quarter delay from the start.
    long absoluteTime = 0;
    // Some textual information added to the track 0 at time=0
    mfw.MPTK_AddText(track0, absoluteTime, MPTKMeta.SequenceTrackName, "MIDI Generated with MPTK with tempo, preset, pitch wheel change");
    // TimeSignatureEvent (not mandatory) https://paxstellar.fr/2020/09/11/midi-timing/
    // Numerator(number of beats in a bar,
    // Denominator(which is confusingly) in 'beat units' so 1 means 2, 2 means 4(crochet), 3 means 8(quaver), 4 means 16 and 5 means 32),
    mfw.MPTK_AddTimeSignature(track0, absoluteTime, 4, 2); // for a 4/4 signature
    // Tempo is defined in beat per minute (not mandatory, by default MIDI are played with a tempo of 120).
    // beatsPerMinute set to 60 at start, it's a slow tempo, one quarter per second.
    // Tempo is global for the whole MIDI independantly of each track and channel.
    mfw.MPTK_AddBPMChange(track0, absoluteTime, beatsPerMinute);
    // Preset for channel 1. Generally 25 is Acoustic Guitar, see https://en.wikipedia.org/wiki/General_MIDI
    // It seems that some reader (as Media Player) refused Midi file if change preset is defined in the track 0, so we set it in track 1.
    mfw.MPTK_AddChangePreset(track1, absoluteTime, channel0, preset: 25);
    //
    // Build first bar
    // ---------------
    // Creation of the first bar in the partition :
    // add four quarter with a tick duration of one quarter (one second with BPM=60)
    // 57 --> A4
    // 60 --> C5
    // 62 --> D5
    // 65 --> F5
    // Some lyrics added to the track 0
    mfw.MPTK_AddText(track0, absoluteTime, MPTKMeta.Lyric, "Build first bar");
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: 57, velocity: 50, length: ticksPerQuarterNote);
    absoluteTime += ticksPerQuarterNote; // Next note will be played one quarter after the previous (time signature is 4/4)
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: 60, velocity: 80, length: ticksPerQuarterNote);
    absoluteTime += ticksPerQuarterNote;
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: 62, velocity: 100, length: ticksPerQuarterNote);
    absoluteTime += ticksPerQuarterNote;
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: 65, velocity: 100, length: ticksPerQuarterNote);
    absoluteTime += ticksPerQuarterNote;
    //
    // Build second bar: Same notes but dobble tempo (using the microsecond per quarter change method)
    // -----------------------------------------------------------------------------------------------
    mfw.MPTK_AddTempoChange(track0, absoluteTime, MPTKEvent.MPTK_BPM2MPQN(beatsPerMinute * 2));
    //return mfw;
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: 57, velocity: 50, length: ticksPerQuarterNote);
    absoluteTime += ticksPerQuarterNote; // Next note will be played one quarter after the previous (time signature is 4/4)
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: 60, velocity: 80, length: ticksPerQuarterNote);
    absoluteTime += ticksPerQuarterNote;
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: 62, velocity: 100, length: ticksPerQuarterNote);
    absoluteTime += ticksPerQuarterNote;
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: 65, velocity: 100, length: ticksPerQuarterNote);
    absoluteTime += ticksPerQuarterNote;
    //
    // Build third bar : one note with a pitch change along the bar
    // -------------------------------------------------------------
    mfw.MPTK_AddChangePreset(track1, absoluteTime, channel0, preset: 50); // synth string
    // Some lyrics added to the track 0
    mfw.MPTK_AddText(track0, absoluteTime, MPTKMeta.Lyric, "Pitch wheel effect");
    // Play an infinite note A4 (duration = -1) don't forget the noteoff!
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: 57, velocity: 100, length: -1);
    // Apply pitch wheel on the channel 0
    for (float pitch = 0f; pitch <= 2f; pitch += 0.05f) // 40 steps of 0.05
    {
    mfw.MPTK_AddPitchWheelChange(track1, absoluteTime, channel0, pitch);
    // Advance position 40 steps and for a total duration of 4 quarters
    absoluteTime += (long)((float)ticksPerQuarterNote * 4f / 40f);
    }
    // The noteoff for A4
    mfw.MPTK_AddOff(track1, absoluteTime, channel0, 57);
    // Reset pitch change to normal value
    mfw.MPTK_AddPitchWheelChange(track1, absoluteTime, channel0, 0.5f);
    //
    // Build fourth bar : arpeggio of 16 sixteenth along the bar
    // --------------------------------------------------------
    // Some lyrics added to the track 0
    mfw.MPTK_AddText(track0, absoluteTime, MPTKMeta.Lyric, "Arpeggio");
    // Dobble the tempo with a variant of MPTK_AddBPMChange,
    // change tempo defined in microsecond. Use MPTK_BPM2MPQN to convert or use directly MPTK_AddBPMChange
    //mfw.MPTK_AddTempoChange(track0, absoluteTime, MidiFileWriter2.MPTK_BPM2MPQN(beatsPerMinute));
    // Patch/preset to use for channel 1. Generally 11 is Music Box, see https://en.wikipedia.org/wiki/General_MIDI
    mfw.MPTK_AddChangePreset(track1, absoluteTime, channel0, preset: 11);
    // Add sixteenth notes (duration = quarter / 4) : need 16 sixteenth to build a bar of 4 quarter
    int note = 57;
    for (int i = 0; i < 16; i++)
    {
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: note, velocity: 100, ticksPerQuarterNote / 4);
    // Advance the position by one sixteenth
    absoluteTime += ticksPerQuarterNote / 4;
    note += 1;
    }
    //
    // Build fifth bar : one whole note with vibrato
    // ----------------------------------------------
    // Some lyrics added to the track 0
    mfw.MPTK_AddText(track0, absoluteTime, MPTKMeta.Lyric, "Vibrato");
    // Add a last whole note (4 quarters duration = 1 bar)
    mfw.MPTK_AddNote(track1, absoluteTime, channel0, note: 85, velocity: 100, length: ticksPerQuarterNote * 4);
    // Apply modulation change, (vibrato)
    mfw.MPTK_AddControlChange(track1, absoluteTime, channel0, MPTKController.Modulation, 127);
    absoluteTime += ticksPerQuarterNote * 4;
    // Reset modulation change to normal value
    mfw.MPTK_AddControlChange(track1, absoluteTime, channel0, MPTKController.Modulation, 0);
    //
    // wrap up : add a silence
    // -----------------------------
    mfw.MPTK_AddText(track0, absoluteTime, MPTKMeta.Lyric, "Silence");
    absoluteTime += ticksPerQuarterNote;
    //
    // optional : build tempo and signature map, measure and beat
    // ----------------------------------------------------------
    // Sort the events by ascending absolute time
    // Calculate time, measure and beat for each events
    mfw.MPTK_CalculateTiming(logDebug: true, logPerf: true);
    return mfw;
    }
    Description of a MIDI Event. It's the heart of MPTK! Essential to handling MIDI by script from all ot...
    Definition: MPTKEvent.cs:418
    static int MPTK_BPM2MPQN(double bpm)
    Definition: MPTKEvent.cs:765
    Create, build, write, import, play MIDI by script. See full example with these scripts:
    Definition: MidiFileWriter2.cs:28
    void MPTK_StableSortEvents(bool logPerf=false)
    Definition: MidiFileWriter2.cs:1335
    MPTKEvent MPTK_AddChangePreset(int track, long tick, int channel, int preset)
    Definition: MidiFileWriter2.cs:971
    MPTKEvent MPTK_AddBPMChange(int track, long tick, int bpm)
    Definition: MidiFileWriter2.cs:1138
    MPTKEvent MPTK_AddControlChange(int track, long tick, int channel, MPTKController controller, int controllerValue)
    Definition: MidiFileWriter2.cs:1065
    MPTKEvent MPTK_AddPitchWheelChange(int track, long tick, int channel, float pitchWheel)
    Definition: MidiFileWriter2.cs:1113
    MPTKEvent MPTK_AddTimeSignature(int track, long tick, int numerator=4, int denominator=2, int ticksInMetronomeClick=24, int no32ndNotesInQuarterNote=32)
    Definition: MidiFileWriter2.cs:1206
    MPTKEvent MPTK_AddText(int track, long tick, MPTKMeta typeMeta, string text)
    Definition: MidiFileWriter2.cs:1266
    MPTKEvent MPTK_AddTempoChange(int track, long tick, int microsecondsPerQuarterNote)
    Definition: MidiFileWriter2.cs:1170
    MidiFileWriter2(int deltaTicksPerQuarterNote=240, int midiFileType=1, int bpm=120)
    Definition: MidiFileWriter2.cs:250
    MPTKEvent MPTK_AddOff(int track, long tick, int channel, int note)
    Definition: MidiFileWriter2.cs:853
    void MPTK_CalculateTiming(bool logPerf=false, bool logDebug=false)
    Definition: MidiFileWriter2.cs:1377
    MPTKEvent MPTK_AddNote(int track, long tick, int channel, int note, int velocity, int length)
    Definition: MidiFileWriter2.cs:734
    MPTKMeta
    Definition: MPTKEvent.cs:320
    MPTKController
    Definition: MPTKEvent.cs:130

Constructor & Destructor Documentation

◆ MidiFileWriter2()

MidiPlayerTK.MidiFileWriter2.MidiFileWriter2 ( int  deltaTicksPerQuarterNote = 240,
int  midiFileType = 1,
int  bpm = 120 
)

Create an empty MidiFileWriter2 with default or specific header midi value (for advanced use)
Default:

  • Delta Ticks Per Beat Note = 240
  • Midi file type = 1
  • Beats Per Minute = 120
Parameters
deltaTicksPerQuarterNoteDelta Ticks Per Beat Note, default is 240. See MPTK_DeltaTicksPerQuarterNote.
midiFileTypetype of Midi format. Must be 0 or 1, default 1
bpmInitial Beats Per Minute, default 120

Member Function Documentation

◆ MPTK_AddBPMChange()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddBPMChange ( int  track,
long  tick,
int  bpm 
)

Add a tempo change to the midi stream. There is no channel in parameter because tempo change is applied to all tracks and channels.
Next note-on with milliseconds defined after the tempo change will take into account the new value of the BPM.

Note
TempoMap is not updated, call MPTK_CalculateTempoMap to recreate the full tempo map.
Parameters
trackTrack for this event (it's a good practive to use track 0 for this event)
tickTick time for this event
bpmquarter per minute
Returns
Return the MIDI event created or null if error

◆ MPTK_AddChangePreset()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddChangePreset ( int  track,
long  tick,
int  channel,
int  preset 
)

Add a change preset

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

◆ MPTK_AddChangePresetMilli()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddChangePresetMilli ( int  track,
float  timeToPlay,
int  channel,
int  preset 
)

Add a change preset

Parameters
trackTrack for this event (do not add to track 0)
timeToPlayTime in millisecond from the start of the MIDI when playing 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

◆ MPTK_AddChannelAfterTouch()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddChannelAfterTouch ( int  track,
long  tick,
int  channel,
int  afterTouchPressure 
)

Add 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

◆ MPTK_AddChannelAfterTouchMilli()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddChannelAfterTouchMilli ( int  track,
float  timeToPlay,
int  channel,
int  afterTouchPressure 
)

Add a Channel After-Touch Event

Parameters
trackTrack for this event (do not add to track 0)
timeToPlayTime in millisecond from the start of the MIDI when playing 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

◆ MPTK_AddChordFromLib()

void MidiPlayerTK.MidiFileWriter2.MPTK_AddChordFromLib ( int  track,
long  tick,
int  channel,
MPTKChordName  chordName,
MPTKChordBuilder  chord 
)

Add a chord from a library of chord

MPTKChordBuilder chordLib = new MPTKChordBuilder() { Tonic = 60, Duration = duration, Velocity = 80, };
mfw.MPTK_AddChordFromLib(track1, absoluteTime, channel0, MPTKChordName.Major, chordLib); absoluteTime += ticksPerQuarterNote;
chordLib.Tonic = 62;
mfw.MPTK_AddChordFromLib(track1, absoluteTime, channel0, MPTKChordName.mM7, chordLib); absoluteTime += ticksPerQuarterNote;
chordLib.Tonic = 67;
mfw.MPTK_AddChordFromLib(track1, absoluteTime, channel0, MPTKChordName.m7b5, chordLib); absoluteTime += ticksPerQuarterNote;
chordLib.Tonic = 65;
mfw.MPTK_AddChordFromLib(track1, absoluteTime, channel0, MPTKChordName.M7, chordLib); absoluteTime += ticksPerQuarterNote;
Build Chord and Play with MidiStreamPlayer.
Definition: MPTKChordBuilder.cs:12
MPTKChordName
List of chords available
Definition: MPTKChordName.cs:8
Parameters
trackTrack for this event (do not add to track 0)
tick
channel
chordNameName of the chord See MPTKChordName
chordSee MPTKChordBuilder
Returns
Return the MIDI event created or null if error

◆ MPTK_AddChordFromScale()

void MidiPlayerTK.MidiFileWriter2.MPTK_AddChordFromScale ( int  track,
long  tick,
int  channel,
MPTKScaleLib  scale,
MPTKChordBuilder  chord 
)

Add a chord from a range

// Play 4 chords, degree I - V - IV - V
// ------------------------------------
mfw.MPTK_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.MPTK_AddChordFromScale(track1, absoluteTime, channel0, scaleMajor, chordDegreeI); absoluteTime += ticksPerQuarterNote;
mfw.MPTK_AddChordFromScale(track1, absoluteTime, channel0, scaleMajor, chordDegreeV); absoluteTime += ticksPerQuarterNote;
mfw.MPTK_AddChordFromScale(track1, absoluteTime, channel0, scaleMajor, chordDegreeIV); absoluteTime += ticksPerQuarterNote;
mfw.MPTK_AddChordFromScale(track1, absoluteTime, channel0, scaleMajor, chordDegreeV); absoluteTime += ticksPerQuarterNote;
Build Scale and Play with MidiStreamPlayer.
Definition: MPTKScaleLib.cs:44
static MPTKScaleLib CreateScale(MPTKScaleName index, bool log=false)
Definition: MPTKScaleLib.cs:141
MPTKScaleName
List of ranges available
Definition: MPTKScaleLib.cs:254
Parameters
trackTrack for this event (do not add to track 0)
tick
channel
scaleSee MPTKScaleLib
chordSee MPTKChordBuilder
Returns
Return the MIDI event created or null if error

◆ MPTK_AddControlChange()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_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

◆ MPTK_AddControlChangeMilli()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddControlChangeMilli ( int  track,
float  timeToPlay,
int  channel,
MPTKController  controller,
int  controllerValue 
)

Creates a control change event

Parameters
trackTrack for this event (do not add to track 0)
timeToPlayTime in millisecond from the start of the MIDI when playing 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

◆ MPTK_AddNote()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddNote ( int  track,
long  tick,
int  channel,
int  note,
int  velocity,
int  length 
)

Add a note on event at an absolute time (tick count). The corresponding Noteoff is automatically created if length > 0
If an infinite note-on is added (length < 0), don't forget to add a note-off, it will never created automatically.

Parameters
trackTrack for this event (do not add to track 0)
tickTick time 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 tick. No automatic noteoff is added if duration is < 0, need to be added with MPTK_AddOff
Returns
Return the MIDI event created or null if error

◆ MPTK_AddNoteMilli()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddNoteMilli ( int  track,
float  timeToPlay,
int  channel,
int  note,
int  velocity,
float  duration 
)

Add a note on event at a specific time in millisecond. The corresponding Noteoff is automatically created if duration > 0
If an infinite note-on is added (duration < 0), don't forget to add a note-off, it will never created automatically.

Parameters
trackTrack for this event (do not add to track 0)
timeToPlayTime in millisecond from the start of the MIDI when playing 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.
durationDuration in millisecond. No noteoff is added if duration is < 0, need to be added with MPTK_AddOffMilli
Returns
Return the MIDI event created or null if error

◆ MPTK_AddOff()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddOff ( int  track,
long  tick,
int  channel,
int  note 
)

Add a note off event.
Must always succeed the corresponding NoteOn, obviously on the same channel!

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

◆ MPTK_AddOffMilli()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddOffMilli ( int  track,
float  timeToPlay,
int  channel,
int  note 
)

Add a note off event at a specific time in millisecond.
Must always succeed the corresponding NoteOn, obviously on the same channel!

Parameters
trackTrack for this event (do not add to track 0)
timeToPlayTime in millisecond from the start of the MIDI when playing this event.
channelChannel must be in the range 0-15
noteNote must be in the range 0-127
Returns
Return the MIDI event created or null if error

◆ MPTK_AddPitchWheelChange()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddPitchWheelChange ( int  track,
long  tick,
int  channel,
float  pitchWheel 
)

Creates a control change event (CC) for the pitch (Pitch Wheel)
pitchWheel=

  • 0 minimum (0 also for midi standard event value)
  • 0.5 centered value (8192 for midi standard event value)
  • 1 maximum (16383 for midi standard event value)
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. Range 0 to 1. V2.88.2 range normalized from 0 to 1.
Returns
Return the MIDI event created or null if error

◆ MPTK_AddPitchWheelChangeMilli()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddPitchWheelChangeMilli ( int  track,
float  timeToPlay,
int  channel,
float  pitchWheel 
)

Creates a control change event (CC) for the pitch (Pitch Wheel)

Parameters
trackTrack for this event (do not add to track 0)
timeToPlayTime in millisecond from the start of the MIDI when playing this event.
channelChannel must be in the range 0-15
pitchWheelPitch Wheel Value. 1:normal value, 0:pitch mini, 2:pitch max
Returns
Return the MIDI event created or null if error

◆ MPTK_AddRawEvent()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddRawEvent ( MPTKEvent  mptkEvent)

Add a MPTK Midi event from a MptkEvent instance. Useful to add a raw MIDI event.

These attributs must be defined in the MptkEvent instance:

  • MptkEvent.Track
  • MptkEvent.Channel
  • MptkEvent.Command
  • MptkEvent.Tick
    Note
    Others attributs must be defined depending on the value of MptkEvent.Command, see class MidiPlayerTK.MPTKCommand.
    For example, MptkEvent.Length must be defined if MptkEvent.Command=MPTKCommand.NoteOn

.

Parameters
mptkEvent
Returns
Return the MIDI event created or null if error

◆ MPTK_AddSilence()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddSilence ( int  track,
long  tick,
int  channel,
int  length 
)

Add a silence.

Note
A silent note does not exist in the MIDI norm, we simulate it with a noteon and a very low velocity = 1.
it's not possible to create a noteon with a velocity = 0, it's considered as a noteof by MIDI
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 tick.
Returns
Return the MIDI event created or null if error

◆ MPTK_AddSilenceMilli()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddSilenceMilli ( int  track,
float  timeToPlay,
int  channel,
float  duration 
)

Add a silence.

Note
A silent note does not exist in the MIDI norm, we simulate it with a noteon and a very low velocity = 1.
it's not possible to create a noteon with a velocity = 0, it's considered as a noteof by MIDI
Parameters
trackTrack for this event (do not add to track 0)
timeToPlayTime in millisecond from the start of the MIDI when playing this event.
channelChannel must be in the range 0-15
durationDuration in millisecond.
Returns
Return the MIDI event created or null if error

◆ MPTK_AddTempoChange()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddTempoChange ( int  track,
long  tick,
int  microsecondsPerQuarterNote 
)

Add a tempo change to the midi stream in microseconds per quarter note.
There is no channel in parameter because tempo change is applied to all tracks and channels.
Next note-on with milliseconds defined after the tempo change will take into account the new value of the BPM.

Note
MPTK_TempoMap 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)
mfw.MPTK_StableSortEvents();
// Calculate time, measure and beat for each events
mfw.MPTK_CalculateTiming(logDebug: true, logPerf: true);
mfw.MPTK_Debug();
Parameters
trackTrack for this event (it's a good practive to use track 0 for this event)
tickTick time for this event
microsecondsPerQuarterNoteMicroseconds per quarter note
Returns
Return the MIDI event created or null if error

◆ MPTK_AddText()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddText ( int  track,
long  tick,
MPTKMeta  typeMeta,
string  text 
)

Create a MIDI Text Event.

private MidiFileWriter2 CreateMidiStream_inner_loop_set_with_META()
{
int ticksPerQuarterNote = 500;
// A querter each DTPQN
MidiFileWriter2 mfw = new MidiFileWriter2(deltaTicksPerQuarterNote: ticksPerQuarterNote, 1);
long absoluteTime = 0;
mfw.MPTK_AddBPMChange(track: 0, absoluteTime, 120);
mfw.MPTK_AddChangePreset(track: 1, absoluteTime, channel: 0, preset: 0);
Debug.Log("Create first loop @ACTION:INNER_LOOP(500,1000,4)");
mfw.MPTK_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.MPTK_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.MPTK_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.MPTK_AddNote(track: 1, absoluteTime, channel: 0, note: note + 50, velocity: 100, length: ticksPerQuarterNote);
absoluteTime += ticksPerQuarterNote;
}
return mfw;
}
Parameters
trackTrack for this event (it's a good practice to use track 0 for this event)
tickAbsolute time of this event
typeMetaMetaEvent type
textThe text associated to this MIDI event
Returns
Return the MIDI event created or null if error

◆ MPTK_AddTextMilli()

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_AddTextMilli ( int  track,
float  timeToPlay,
MPTKMeta  typeMeta,
string  text 
)

Create a MIDI Text Event.

Parameters
trackTrack for this event (it's a good practice to use track 0 for this event)
timeToPlayTime in millisecond from the start of the MIDI when playing this event.
typeMetaMetaEvent type
textThe text associated to this MIDI event
Returns
Return the MIDI event created or null if error

◆ MPTK_AddTimeSignature()

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

Create a new TimeSignatureEvent. This event is optionnal. Internal Midi sequencer assumes the default value is 4,2,24,32. No track nor channel as teampo change applied to the whole midi. More info here 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)
mfw.MPTK_StableSortEvents();
// Calculate time, measure and beat for each events
mfw.MPTK_CalculateTiming(logDebug: true, logPerf: true);
mfw.MPTK_Debug();
Parameters
trackTrack for this event (it's a good practive to use track 0 for this event)
tickTime at which to create this event
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.
no32ndNotesInQuarterNoteNo of 32nd Notes in Beat Click. Set to 32 for a standard value.
Returns
Return the MIDI event created or null if error

◆ MPTK_BPM2MPQN()

static int MidiPlayerTK.MidiFileWriter2.MPTK_BPM2MPQN ( double  bpm)
static

Deprecated:
moved to class MptkEvent replaced with MptkEvent.MPTK_BPM2MPQN

◆ MPTK_BuildNAudioMidi()

MidiFile MidiPlayerTK.MidiFileWriter2.MPTK_BuildNAudioMidi ( )

Build a NAudio midi object from the midi events. MPTK_WriteToMidiDB and MPTK_WriteToFile call these methods just before writing the MIDI file.

Returns
NAudio MidiFile

◆ MPTK_CalculateTiming()

void MidiPlayerTK.MidiFileWriter2.MPTK_CalculateTiming ( bool  logPerf = false,
bool  logDebug = false 
)

Calculate real time, measure and quarter position

  • Calculate MPTK_TempoMap with #MPTKTempo.MPTK_CalculateMap
  • Calculate MPTK_SignMap with #MPTKSignature.MPTK_CalculateMap
  • Calculate time and duration of each events from the tick value and from the tempo map.
  • Calculate measure and quarter position taking into account time signature.
    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)
    mfw.MPTK_StableSortEvents();
    // Calculate time, measure and beat for each events
    mfw.MPTK_CalculateTiming(logDebug: true, logPerf: true);
    mfw.MPTK_Debug();
Parameters
logPerf
logDebug

◆ MPTK_Clear()

void MidiPlayerTK.MidiFileWriter2.MPTK_Clear ( )

Remove all MIDI events and restore default attributs:

  • MPTK_DeltaTicksPerQuarterNote = 240
  • MPTK_MidiFileType = 1
  • Tempo = 120

◆ MPTK_ConvertMilliToTick()

long MidiPlayerTK.MidiFileWriter2.MPTK_ConvertMilliToTick ( float  time,
int  indexTempo = -1 
)

Convert a time position in millisecond to an absolute tick position.

Parameters
timeTime position in milliseconds
indexTempoIndex in MPTK_TempoMap for this position. Optional, if not defined or -1, MPTK_TempoMap will be recalculated and the segment for this position will be searched
Returns
Absolute tick position

◆ MPTK_ConvertTickToMilli()

float MidiPlayerTK.MidiFileWriter2.MPTK_ConvertTickToMilli ( long  tick,
int  indexTempo = -1 
)

Convert an absolute tick position to a time in millisecond.

Parameters
tickAbsolute tick position
indexTempoIndex in MPTK_TempoMap for this position. Optional, if not defined or -1, MPTK_TempoMap will be recalculated and the segment for this position will be searched
Returns
Duration in milliseconds

◆ MPTK_CreateTrack()

void MidiPlayerTK.MidiFileWriter2.MPTK_CreateTrack ( int  count)

Deprecated:
With V2.9.0 tracks are automatically created when needed.
Parameters
countnumber of tracks to create

◆ MPTK_CreateTracksStat()

Dictionary< long, MPTKStat > MidiPlayerTK.MidiFileWriter2.MPTK_CreateTracksStat ( )

Build the tracks information (MPTK_TrackStat) from the MIDI event found in MPTK_Events. MPTK_TrackStat is a dictionary with the track number as a key and the item holds some informatio about the track.

Returns
Stat dictionary
Exceptions
MaestroException

◆ MPTK_Debug()

bool MidiPlayerTK.MidiFileWriter2.MPTK_Debug ( )

Log information about the MIDI

Returns

◆ MPTK_DebugRaw()

bool MidiPlayerTK.MidiFileWriter2.MPTK_DebugRaw ( )

Log information about the MIDI

Returns

◆ MPTK_DeleteChannel()

void MidiPlayerTK.MidiFileWriter2.MPTK_DeleteChannel ( int  channel)

Delete all MIDI events on this channel

Parameters
channel

◆ MPTK_DeleteTrack()

void MidiPlayerTK.MidiFileWriter2.MPTK_DeleteTrack ( int  track)

Delete all MIDI events on this track

Parameters
track

◆ MPTK_DurationMilliToTick()

long MidiPlayerTK.MidiFileWriter2.MPTK_DurationMilliToTick ( float  time)

Convert the tick duration to a real time duration in millisecond regarding the current tempo.

Note
Previous call to MPTK_AddBPMChange and MPTK_AddTempoChange have direct impact on this calculation.
Parameters
tickduration in ticks
Returns
duration in milliseconds

◆ MPTK_DurationTickToMilli()

long MidiPlayerTK.MidiFileWriter2.MPTK_DurationTickToMilli ( long  tick)

Convert the tick duration to a time duration in millisecond regarding the current tempo.

Note
Previous call to MPTK_AddBPMChange and MPTK_AddTempoChange have direct impact on this calculation.
Parameters
tickduration in ticks
Returns
duration in milliseconds

◆ MPTK_EndTrack()

void MidiPlayerTK.MidiFileWriter2.MPTK_EndTrack ( int  trackNumber)

Deprecated:
With V2.9.0 tracks are automatically closed when needed.
Parameters
trackNumberTrack number to close

◆ MPTK_GetMicrosecondsPerQuaterNote()

static int MidiPlayerTK.MidiFileWriter2.MPTK_GetMicrosecondsPerQuaterNote ( int  bpm)
static

Deprecated:
moved to class MptkEvent see MptkEvent.MPTK_BPM2MPQN

◆ MPTK_ImportFromEventsList()

bool MidiPlayerTK.MidiFileWriter2.MPTK_ImportFromEventsList ( List< MPTKEvent midiEventsToInsert,
int  deltaTicksPerQuarterNote,
long  position = -1,
string  name = null,
bool  logPerf = false,
bool  logDebug = false 
)

New with version V2.9.0 Import a list of MptkEvent.

Multiple imports can be done for joining MIDI events from different sources 😁.

  • The first import will be the reference for the DeltaTicksPerQuarterNote (MPTK_DeltaTicksPerQuarterNote is set with the value in parameter).
  • The next imports will convert time and duration of the MIDI events with the ratio of DeltaTicksPerQuarterNote in parameter and the initial DeltaTicksPerQuarterNote.
  • real time, measure and beat for each events are recalculated for the whole MIDI events at the end off the import with MPTK_CalculateTiming() Example from MIDI Generator
    private MidiFileWriter2 CreateMidiStream_midi_merge()
    {
    // Join two MIDI from the MidiDB
    // - create an empty MIDI writer
    // - Import a first one (MIDI index 0 from the MIDI DB)
    // - Import a second one (MIDI index 1 from the MIDI DB)
    MidiFileWriter2 mfw = null;
    try
    {
    // Create a Midi File Writer instance
    // -----------------------------------
    mfw = new MidiFileWriter2();
    // A MIDI loader is useful to load all MIDI events from a MIDI file.
    MidiFilePlayer mfLoader = FindObjectOfType<MidiFilePlayer>();
    if (mfLoader == null)
    {
    Debug.LogWarning("Can't find a MidiFilePlayer Prefab in the current Scene Hierarchy. Add it with the Maestro menu.");
    return null;
    }
    // No, with v2.10.0 - It's mandatory to keep noteoff when loading MIDI events for merging
    // mfLoader.MPTK_KeepNoteOff = true;
    // it's recommended to not keep end track
    mfLoader.MPTK_KeepEndTrack = false;
    // Load the initial MIDI index 0 from the MidiDB
    // ---------------------------------------------
    mfLoader.MPTK_MidiIndex = 0;
    mfLoader.MPTK_Load();
    // All merge operation will be done with the ticksPerQuarterNote of the first MIDI
    mfw.MPTK_ImportFromEventsList(mfLoader.MPTK_MidiEvents, mfLoader.MPTK_DeltaTicksPerQuarterNote, name: mfLoader.MPTK_MidiName, logPerf: true);
    Debug.Log($"{mfLoader.MPTK_MidiName} Events loaded: {mfLoader.MPTK_MidiEvents.Count} DeltaTicksPerQuarterNote:{mfw.MPTK_DeltaTicksPerQuarterNote}");
    // Load the MIDI index 1 from the MidiDB
    // -------------------------------------
    mfLoader.MPTK_MidiIndex = 1;
    mfLoader.MPTK_Load();
    // All MIDI events loaded will be added to the MidiFileWriter2.
    // Position and Duration will be converted according the ticksPerQuarterNote initial and ticksPerQuarterNote from the MIDI to be inserted.
    mfw.MPTK_ImportFromEventsList(mfLoader.MPTK_MidiEvents, mfLoader.MPTK_DeltaTicksPerQuarterNote, name: "MidiMerged", logPerf: true);
    Debug.Log($"{mfLoader.MPTK_MidiName} Events loaded: {mfLoader.MPTK_MidiEvents.Count} DeltaTicksPerQuarterNote:{mfw.MPTK_DeltaTicksPerQuarterNote}");
    // Add a silence of a 4 Beat Notes after the last event.
    // It's optionnal but recommended if you want to automatic restart on the generated MIDI with a silence before looping.
    long absoluteTime = mfw.MPTK_MidiEvents.Last().Tick + mfw.MPTK_MidiEvents.Last().Length;
    Debug.Log($"Add a silence at {mfw.MPTK_MidiEvents.Last().Tick} + {mfw.MPTK_MidiEvents.Last().Length} = {absoluteTime} ");
    mfw.MPTK_AddSilence(track: 1, absoluteTime, channel: 0, length: mfw.MPTK_DeltaTicksPerQuarterNote * 4);
    }
    catch (Exception ex) { Debug.LogException(ex); }
    //
    return mfw;
    }
    Play a MIDI file from the MidiDB. This class must be used with the prefab MidiFilePlayer....
    Definition: MidiFilePlayer.cs:69
    virtual string MPTK_MidiName
    Definition: MidiFilePlayer.cs:86
    List< MPTKEvent > MPTK_MidiEvents
    Definition: MidiFilePlayer.cs:809
    MidiLoad MPTK_Load()
    Definition: MidiFilePlayer.cs:1248
    int MPTK_DeltaTicksPerQuarterNote
    Definition: MidiFilePlayer.cs:826
    int MPTK_DeltaTicksPerQuarterNote
    Definition: MidiFileWriter2.cs:35
    List< MPTKEvent > MPTK_MidiEvents
    Definition: MidiFileWriter2.cs:212
    bool MPTK_ImportFromEventsList(List< MPTKEvent > midiEventsToInsert, int deltaTicksPerQuarterNote, long position=-1, string name=null, bool logPerf=false, bool logDebug=false)
    Definition: MidiFileWriter2.cs:310
    MPTKEvent MPTK_AddSilence(int track, long tick, int channel, int length)
    Definition: MidiFileWriter2.cs:801

    Example from MIDI Join And Import
    public void InsertMidi()
    {
    if (mfWriter == null)
    Debug.LogWarning("First, create a MidiFileWriter instance");
    else
    {
    // Load the MIDI file selected
    mfLoader.MPTK_MidiIndex = indexSelectedMidi;
    Debug.Log($"MPTK_KeepNoteOff:{mfLoader.MPTK_KeepNoteOff} MPTK_KeepEndTrack:{mfLoader.MPTK_KeepEndTrack} ");
    mfLoader.MPTK_Load();
    // From the UI, get the tick position where to insert
    if (string.IsNullOrWhiteSpace(InputPosition.text)) InputPosition.text = "0";
    long position = Convert.ToInt64(InputPosition.text);
    if (position < 0) { InputPosition.text = "-1"; position = -1; }
    // Insert the MPTK_MidiEvents of the MIDI loaded in the MPTK_MidiEvents of the MIDI Writer.
    mfWriter.MPTK_ImportFromEventsList(mfLoader.MPTK_MidiEvents, mfLoader.MPTK_DeltaTicksPerQuarterNote, position: position, name: "MidiJoined", logPerf: true, logDebug: true); ;
    // If a MIDI player is already playing then update duration.
    // Playing of a MIDI Writer is done with: mfPlayer.MPTK_Play(mfWriter)
    if (mfPlayer != null && mfPlayer.MPTK_IsPlaying)
    mfPlayer.MPTK_MidiLoaded.MPTK_ComputeDuration();
    Debug.Log($"{mfLoader.MPTK_MidiName} Loaded {mfLoader.MPTK_MidiEvents.Count} events added, total events: {mfWriter.MPTK_MidiEvents.Count}");
    UpdatePosition();
    }
    }
    public void PlayMidi()
    {
    if (mfWriter != null && mfWriter.MPTK_MidiEvents != null)
    {
    // The MIDI file player will play the MIDI events list found in the MIDI Writer.
    // In fact the mfPlayer.MPTK_MidiEvents will directly use the mfWriter.MPTK_MidiEvents for playing the MIDI.
    // All changes done on the mfWriter.MPTK_MidiEvents have direct impact on the player.
    // When playing, it's possible to add, modify or insert MIDI events in mfWriter.MPTK_MidiEvents,
    // changes will be automatically taken into account by the player if the change position if after the current tick player (mfPlayer.MPTK_TickPlayer) .
    // Inserting before mfPlayer.MPTK_TickPlayer could perturbate the player.
    mfPlayer.MPTK_Play(mfWriter);
    }
    else
    Debug.LogWarning("No MidiWriter ready for playing");
    }

Parameters
midiEventsToInsertList of MptkEvent to insert
deltaTicksPerQuarterNoteIt's the DTPQN of the MIDI events to insert.
positiontick position to insert, -1 to append, 0 at beguinning
nameName of the MIDI created (set MPTK_MidiName).
logDebugDebug log.
Returns
true if no error

◆ MPTK_LoadFromFile()

bool MidiPlayerTK.MidiFileWriter2.MPTK_LoadFromFile ( string  filename)

Load a Midi file from OS system file (could be dependant of the OS)

Parameters
filename
Returns
true if no error

◆ MPTK_LoadFromMidiDB()

bool MidiPlayerTK.MidiFileWriter2.MPTK_LoadFromMidiDB ( int  indexMidiDb)

Create a MidiFileWriter2 from a Midi found in MPTK MidiDB. All existing MIDI events before the load will be lost. If you add some MIDI events after loading, don't forget to sort the MIDI events after. See example.

private MidiFileWriter2 LoadMidi_add_four_notes_at_beginning()
{
// Join two MIDI from the MidiDB
// - create an empty MIDI writer
// - Import a first one (MIDI index 0 from the MIDI DB)
// - Import a second one (MIDI index 1 from the MIDI DB)
MidiFileWriter2 mfw = null;
try
{
// Create a Midi File Writer instance
// -----------------------------------
mfw = new MidiFileWriter2();
// Load MIDI from DB at index 2 (for testing with just a drum line so in channel 9)
// Select preset 10 for channel 0
mfw.MPTK_AddChangePreset(track: 1, tick: 0, channel: 0, 10);
// Add four notes (here, we consider Delta Ticks Per Beat Note = 1024)
mfw.MPTK_AddNote(track: 1, tick: 0, channel: 0, note: 60, velocity: 100, length: 512);
mfw.MPTK_AddNote(track: 1, tick: 512, channel: 0, note: 60, velocity: 100, length: 512);
mfw.MPTK_AddNote(track: 1, tick: 1024, channel: 0, note: 60, velocity: 100, length: 512);
mfw.MPTK_AddNote(track: 1, tick: 1536, channel: 0, note: 60, velocity: 100, length: 512);
// MPTK_Addxxxx methods add event at the end of the MIDI events list
// We need to sort the events by ascending absolute time
// Optional if you want just playing the MIDI
// Calculate real time, measure and quarter for each events
// Without this call, you will get the warning "No tempo map detected".
// @li Calculate #MPTK_TempoMap with #MPTKTempo.MPTK_CalculateMap
// @li Calculate #MPTK_SignMap with #MPTKSignature.MPTK_CalculateMap
// @li Calculate time and duration of each events from the tick value and from the tempo map.
// @li Calculate measure and quarter position taking into account time signature.
// Find a MidiFilePlayer in the hierarchy
// MidiFilePlayer midiPlayer = FindObjectOfType<MidiFilePlayer>();
// And play!
// midiPlayer.MPTK_Play(mfw2: mfw);
}
catch (Exception ex) { Debug.LogException(ex); }
//
return mfw;
}
bool MPTK_LoadFromMidiDB(int indexMidiDb)
Definition: MidiFileWriter2.cs:578
Parameters
indexMidiDb
Returns
true if no error

◆ MPTK_LoadFromMPTK()

bool MidiPlayerTK.MidiFileWriter2.MPTK_LoadFromMPTK ( )

Deprecated:
with V2.9.0 rather use MPTK_ImportFromEventsList.

◆ MPTK_LogSignMap()

void MidiPlayerTK.MidiFileWriter2.MPTK_LogSignMap ( )

Log information about the signature map

◆ MPTK_LogTempoMap()

void MidiPlayerTK.MidiFileWriter2.MPTK_LogTempoMap ( )

Log information about the tempo map

◆ MPTK_LogTrackStat()

void MidiPlayerTK.MidiFileWriter2.MPTK_LogTrackStat ( )

Log information about the stat map

◆ MPTK_MPQN2BPM()

static double MidiPlayerTK.MidiFileWriter2.MPTK_MPQN2BPM ( int  microsecondsPerQuaterNote)
static

Deprecated:
moved to class MptkEvent replaced with MptkEvent.MPTK_MPQN2BPM

◆ MPTK_StableSortEvents()

void MidiPlayerTK.MidiFileWriter2.MPTK_StableSortEvents ( bool  logPerf = false)

Sort in place events in MPTK_MidiEvents by ascending tick position. First priority is applied for 'preset change' and 'meta' event for a group of events with the same position (but 'end track' are set at end of the group.

Note
  • No reallocation of the list is done, the events in the list are sorted in place.
  • good performance for low disorder
  • not efficient for high disorder list. Typically when reading a MIDI file, list is sorted by tracks.
  • in case of high disorder the use of MPTK_SortEvents is recommended at the price of a realocation of the list.
Parameters
logPerf

◆ MPTK_WriteToFile()

bool MidiPlayerTK.MidiFileWriter2.MPTK_WriteToFile ( string  filename)

Write Midi file to an OS folder

private void WriteMidiSequenceToFileAndPlay(string name, MidiFileWriter2 mfw)
{
// build the path + filename to the midi
string filename = Path.Combine(Application.persistentDataPath, name + ".mid");
Debug.Log("Write MIDI file:" + filename);
// 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.MPTK_CalculateTiming(logDebug: true, logPerf: true);
mfw.MPTK_Debug();
// Write the MIDI file
mfw.MPTK_WriteToFile(filename);
// Need an external player to play MIDI from a file from a folder
MidiExternalPlayer midiExternalPlayer = FindObjectOfType<MidiExternalPlayer>();
if (midiExternalPlayer == null)
{
Debug.LogWarning("Can't find a MidiExternalPlayer Prefab in the current Scene Hierarchy. Add it with the MPTK menu.");
return;
}
midiExternalPlayer.MPTK_Stop();
// this prefab is able to load a MIDI file from the device or from an url (http)
// -----------------------------------------------------------------------------
midiExternalPlayer.MPTK_MidiName = "file://" + filename;
midiExternalPlayer.OnEventStartPlayMidi.RemoveAllListeners();
midiExternalPlayer.OnEventStartPlayMidi.AddListener((string midiname) =>
{
Debug.Log($"Start playing {midiname}");
});
midiExternalPlayer.OnEventEndPlayMidi.RemoveAllListeners();
midiExternalPlayer.OnEventEndPlayMidi.AddListener((string midiname, EventEndMidiEnum reason) =>
{
if (reason == EventEndMidiEnum.MidiErr)
Debug.LogWarning($"Error {midiExternalPlayer.MPTK_StatusLastMidiLoaded} when loading '{midiname}'");
else
Debug.Log($"End playing {midiname} {reason}");
});
midiExternalPlayer.MPTK_MidiAutoRestart = midiAutoRestart;
midiExternalPlayer.MPTK_Play();
}
Play a Local MIDI file or from a Web site. This class must be used with the prefab MidiExternalPlayer
Definition: MidiExternalPlayer.cs:42
override void MPTK_Play(bool alreadyLoaded=false)
Play the midi file defined with MPTK_MidiName or MPTK_MidiIndex.
Definition: MidiExternalPlayer.cs:94
void MPTK_Stop(bool stopAllSound=true)
Definition: MidiFilePlayer.cs:1035
EventEndMidiClass OnEventEndPlayMidi
Definition: MidiFilePlayer.cs:737
EventStartMidiClass OnEventStartPlayMidi
Definition: MidiFilePlayer.cs:701
bool MPTK_WriteToFile(string filename)
Definition: MidiFileWriter2.cs:1443
bool MPTK_Debug()
Definition: MidiFileWriter2.cs:1705
Parameters
filenamefilename of the midi file
Returns
true if ok

◆ MPTK_WriteToMidiDB()

bool MidiPlayerTK.MidiFileWriter2.MPTK_WriteToMidiDB ( string  filename)

Write Midi file to MidiDB.
To be used only in edit mode not in a standalone application.
A call to AssetDatabase.Refresh() must be required after the file has been added to the resource.

Parameters
filenamefilename of the midi file without any folder and any extension
Returns
true if ok

Member Data Documentation

◆ MPTK_DeltaTicksPerQuarterNote

int MidiPlayerTK.MidiFileWriter2.MPTK_DeltaTicksPerQuarterNote

Delta Ticks Per Beat Note (or DTPQN) represent the duration time in "ticks" which make up a quarter-note.
For example, with 96 a duration of an eighth-note in the file would be 48.
From a MIDI file, this value is found in the MIDI Header and remains constant for all the MIDI file.
More info here https://paxstellar.fr/2020/09/11/midi-timing/

◆ MPTK_MidiEvents

List<MPTKEvent> MidiPlayerTK.MidiFileWriter2.MPTK_MidiEvents

Get all the MIDI events created.

◆ MPTK_MidiFileType

int MidiPlayerTK.MidiFileWriter2.MPTK_MidiFileType

Get the MIDI file type of the loaded MIDI (0,1,2)

◆ MPTK_MidiName

string MidiPlayerTK.MidiFileWriter2.MPTK_MidiName

Name of this MIDI stream.

◆ MPTK_SignMap

List<MPTKSignature> MidiPlayerTK.MidiFileWriter2.MPTK_SignMap

List of signature changes found in MPTK_MidiEvents. Must be updated with MPTKSignature.MPTK_CalculateMap.
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)
mfw.MPTK_StableSortEvents();
// Calculate time, measure and beat for each events
mfw.MPTK_CalculateTiming(logDebug: true, logPerf: true);
mfw.MPTK_Debug();
Version
2.10.0

◆ MPTK_TempoMap

List<MPTKTempo> MidiPlayerTK.MidiFileWriter2.MPTK_TempoMap

List of tempo changes found in MPTK_MidiEvents. Must be updated with MPTKTempo.MPTK_CalculateMap.
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)
mfw.MPTK_StableSortEvents();
// Calculate time, measure and beat for each events
mfw.MPTK_CalculateTiming(logDebug: true, logPerf: true);
mfw.MPTK_Debug();
Version
2.10.0

◆ MPTK_TickLast

long MidiPlayerTK.MidiFileWriter2.MPTK_TickLast

Tick position of the last MIDI event found including the duration of this event.

Property Documentation

◆ Bpm

double MidiPlayerTK.MidiFileWriter2.Bpm
get

Deprecated:
with V2.9.0 - use MPTK_Tempo in place.

◆ MPTK_CountEvent

int MidiPlayerTK.MidiFileWriter2.MPTK_CountEvent
get

Count of MIDI events in the MPTK_Events

◆ MPTK_LastEvent

MPTKEvent MidiPlayerTK.MidiFileWriter2.MPTK_LastEvent
get

Last MIDI events created.

◆ MPTK_MicrosecondsPerQuaterNote

int MidiPlayerTK.MidiFileWriter2.MPTK_MicrosecondsPerQuaterNote
get

Get current Microseconds Per Quater Note: 60 * 1000 * 1000 https://en.wikipedia.org/wiki/Tempo

The tempo in a MIDI file is given in micro seconds per quarter beat. To convert this to BPM use method MPTK_MPQN2BPM.
This value can change during the generation when MPTK_AddTempoChange is called.
See here for more information https://paxstellar.fr/2020/09/11/midi-timing/

◆ MPTK_NumberBeatsMeasure

int MidiPlayerTK.MidiFileWriter2.MPTK_NumberBeatsMeasure
getset

◆ MPTK_PulseLenght

float MidiPlayerTK.MidiFileWriter2.MPTK_PulseLenght
get

Current lenght in millisecond of a MIDI tick (related to the current tempo).

Obviously depends on the current tempo (MPTK_Tempo) and the MPTK_DeltaTicksPerQuarterNote.
PulseLenght = 60000 / MPTK_Tempo / MPTK_DeltaTicksPerQuarterNote

◆ MPTK_Tempo

double MidiPlayerTK.MidiFileWriter2.MPTK_Tempo
get

V2.9.0 - Get the current tempo. Set with MPTK_AddTempoChange.
https://en.wikipedia.org/wiki/Tempo

◆ MPTK_TrackCount

int MidiPlayerTK.MidiFileWriter2.MPTK_TrackCount
get

Get the count of track. The value is available only when MPTK_CreateTracksStat() has been called. There no more limit of count of track with V2.9.0