MidiPlayerTK.MidiLoad

Base class for loading a MIDI file and reading MIDI event in a MIDI sequencer. It's not possible to instanciate directly this class.
Rather, use MidiFilePlayer to load a MIDI This class is used by MidiFilePlayer, MidiListPlayer, MidiFileWrite2, MidiFileLoader (see members MPTK_MidiLoaded of these classes).
More...

Public Member Functions

void MPTK_CalculateTiming ()
 
void MPTK_Clear ()
 
void MPTK_ComputeDuration ()
 
double MPTK_ConvertTickToTime (long tick)
 
long MPTK_ConvertTimeToTick (double time)
 
void MPTK_DisplayMidiAttributes ()
 
MPTKEvent MPTK_FindLastNote ()
 
bool MPTK_Load (byte[] datamidi, bool strict=false)
 
bool MPTK_Load (int index, bool strict=false, bool extendedText=false)
 
bool MPTK_Load (MPTKWriter mfw2)
 
bool MPTK_Load (string midiname, bool strict=false)
 
bool MPTK_LoadFile (string filename, bool strict=false)
 
List< MPTKEventMPTK_ReadMidiEvents (long fromTicks=0, long toTicks=long.MaxValue)
 
MPTKEvent MPTK_SearchEventFromTime (double time)
 
long MPTK_SearchTickFromTime (double time)
 
MPTKEvent.EnumLength NoteLength (MPTKEvent mptkEvent)
 

Static Public Member Functions

static int MPTK_BPM2MPQN (int bpm)
 
static int MPTK_MPQN2BPM (int microsecondsPerQuaterNote)
 
static int MPTK_SearchEventFromTick (List< MPTKEvent > midiEvents, long tickSearched)
 
static List< MPTKEventMPTK_SortEvents (List< MPTKEvent > midiEvents, bool logPerf=false)
 

Public Attributes

bool KeepNoteOff
 
int MPTK_CurrentBeat
 
int MPTK_CurrentIndexSignMap
 
int MPTK_CurrentIndexTempoMap
 
int MPTK_CurrentMeasure
 
MPTKSignature MPTK_CurrentSignMap
 
MPTKTempo MPTK_CurrentTempoMap
 
int MPTK_DeltaTicksPerQuarterNote
 
TimeSpan MPTK_Duration
 
float MPTK_DurationMS
 
bool MPTK_EnableChangeTempo
 
MPTKEvent MPTK_EventLastNote
 
bool MPTK_ExtendedText
 
double MPTK_InitialTempo
 
bool MPTK_KeepEndTrack
 
bool MPTK_KeepNoteOff
 
int MPTK_KeySigMajorMinor
 
int MPTK_KeySigSharpsFlats
 
MPTKEvent MPTK_LastEventPlayed
 
float MPTK_LoadTime
 
bool MPTK_LogLoadEvents
 
long MPTK_MeasureLastNote
 
int MPTK_MicrosecondsPerQuarterNote
 
List< MPTKEventMPTK_MidiEvents
 
int MPTK_No32ndNotesInQuarterNote
 
int MPTK_NumberBeatsMeasure
 
int MPTK_NumberQuarterBeat
 
double MPTK_PositionFirstNote
 
double MPTK_PositionLastNote
 
double MPTK_Pulse
 
bool MPTK_RawSeek
 
List< MPTKSignatureMPTK_SignMap
 
List< MPTKTempoMPTK_TempoMap
 
long MPTK_TickCurrent
 
long MPTK_TickEnd
 
long MPTK_TickFirstNote
 
long MPTK_TickLast
 
long MPTK_TickLastNote
 
long MPTK_TickPlayer
 
int MPTK_TicksInMetronomeClick
 
long MPTK_TickStart
 
int MPTK_TimeSigDenominator
 
int MPTK_TimeSigNumerator
 
int MPTK_TrackCount
 

Properties

double MPTK_CurrentTempo [get, set]
 

Detailed Description

Base class for loading a MIDI file and reading MIDI event in a MIDI sequencer. It's not possible to instanciate directly this class.
Rather, use MidiFilePlayer to load a MIDI This class is used by MidiFilePlayer, MidiListPlayer, MidiFileWrite2, MidiFileLoader (see members MPTK_MidiLoaded of these classes).

Member Function Documentation

◆ MPTK_BPM2MPQN()

static int MidiPlayerTK.MidiLoad.MPTK_BPM2MPQN ( int  bpm)
static

Deprecated:
MidiLoad.BeatPerMinute2QuarterPerMicroSecond is deprecated and will be removed. Please investigate MPTKEvent.BeatPerMinute2QuarterPerMicroSecond.

◆ MPTK_CalculateTiming()

void MidiPlayerTK.MidiLoad.MPTK_CalculateTiming ( )

Calculate all timing in the MIDI file:

  • Tempo Map
  • Signature Map
  • For each events: Realtime, Measure, Beat
private void OnGUI_ModifyMidiAndPlay()
{
HelperDemo.GUI_Horizontal(HelperDemo.Zone.BEGIN, myStyle.BacgDemosLight);
HelperDemo.GUI_Indent(widthIndent);
HelperDemo.GUI_Vertical(HelperDemo.Zone.BEGIN, myStyle.BacgDemosLight);
GUILayout.Label("It's possible to change the MIDI events before playing. This demo loads the selected MIDI, adds some notes and plays the MIDI without reloading it. Result not guaranteed!", myStyle.TitleLabel3);
countNoteToInsert = (int)HelperDemo.GUI_Slider("Count notes to insert:", (float)countNoteToInsert, 1, 100,
alignCaptionRight: false, enableButton: true, widthCaption: 170, widthSlider: 250, widthLabelValue: 50);
tickPositionToInsert = (long)HelperDemo.GUI_Slider("Tick position to insert:", (long)tickPositionToInsert, 0, (long)midiFilePlayer.MPTK_TickLast,
alignCaptionRight: false, enableButton: true, widthCaption: 170, widthSlider: 250, widthLabelValue: 50);
long quarterPosition = tickPositionToInsert / midiFilePlayer.MPTK_DeltaTicksPerQuarterNote;
long newQuarter = (long)HelperDemo.GUI_Slider("Tick position by quarter:", (long)quarterPosition, 0, (long)midiFilePlayer.MPTK_TickLast / midiFilePlayer.MPTK_DeltaTicksPerQuarterNote,
alignCaptionRight: false, enableButton: true, widthCaption: 170, widthSlider: 250, widthLabelValue: 50);
if (newQuarter != quarterPosition)
{
quarterPosition = newQuarter;
tickPositionToInsert = quarterPosition * midiFilePlayer.MPTK_DeltaTicksPerQuarterNote;
}
channelToInsert = (int)HelperDemo.GUI_Slider("Channel to insert:", channelToInsert, 0, 15,
alignCaptionRight: false, enableButton: true, widthCaption: 170, widthSlider: 250, widthLabelValue: 50);
HelperDemo.GUI_Horizontal(HelperDemo.Zone.BEGIN, null, GUILayout.Width(500));
clearNote = GUILayout.Toggle(clearNote, "Clear MIDI list before inserting");
GUILayout.Space(10);
randomNote = GUILayout.Toggle(randomNote, "Random Note");
GUILayout.Space(10);
randomDuration = GUILayout.Toggle(randomDuration, "Random Duration");
GUILayout.Space(10);
quickSort = GUILayout.Toggle(quickSort, "Quick Sort");
GUILayout.Space(10);
calculateTiming = GUILayout.Toggle(calculateTiming, "Timing Recalculation");
HelperDemo.GUI_Horizontal(HelperDemo.Zone.END);
HelperDemo.GUI_Horizontal(HelperDemo.Zone.BEGIN);
if (GUILayout.Button("Insert And Play", GUILayout.Width(120)))
{
#if MPTK_PRO
// Better to stop playing.
midiFilePlayer.MPTK_Stop();
// There is no need of note-off events.
midiFilePlayer.MPTK_KeepNoteOff = false;
// MPTK_MidiName must contains the name of the MIDI to load.
if (midiFilePlayer.MPTK_Load() != null)
{
Debug.Log($"Duration: {midiFilePlayer.MPTK_Duration.TotalSeconds} seconds");
Debug.Log($"Count MIDI Events: {midiFilePlayer.MPTK_MidiEvents.Count}");
if (clearNote)
midiFilePlayer.MPTK_MidiEvents.Clear();
// Insert weird notes in this beautiful MIDI!
// ------------------------------------------
long tickToInsert = tickPositionToInsert;
for (int insertNote = 0; insertNote < countNoteToInsert; insertNote++)
{
int note;
if (randomNote)
note = UnityEngine.Random.Range(50, 73); // Random notes between 48 (C4) and 72 (C6)
else
note = 60 + insertNote % 12; // Hust a remap of notes!
int eightCount; // How many eight duration to generate
if (randomDuration)
eightCount = UnityEngine.Random.Range(0, 9); // max 8, so a whole note
else
eightCount = 2; // a quarter
int tickDuration = eightCount * midiFilePlayer.MPTK_DeltaTicksPerQuarterNote;
// Add a note
midiFilePlayer.MPTK_MidiEvents.Insert(0,
new MPTKEvent()
{
Channel = channelToInsert,
Command = MPTKCommand.NoteOn,
Value = note,
Length = tickDuration,
Duration = (long)(tickDuration * midiFilePlayer.MPTK_Pulse), // Transform ticks to millisecond
Tick = tickToInsert,
});
// Add a text
midiFilePlayer.MPTK_MidiEvents.Insert(0,
new MPTKEvent()
{
Command = MPTKCommand.MetaEvent,
Meta = MPTKMeta.TextEvent,
Info = $"Add a weird note {HelperNoteLabel.LabelFromMidi(note)}",
Tick = tickToInsert,
});
// Move to the next insert, add length of note added.
tickToInsert += tickDuration;
}
// New events has been inserted, MIDI events list must be sorted by tick value.
// ---------------------------------------------------------------------------
if (quickSort)
// This is a quick sort based on the tick value, regardless of the type of MIDI event.
midiFilePlayer.MPTK_SortEvents();
else
// This sort is also based on tick value, but for the same tick value,
// 'preset change' and 'meta' events are placed before other events such as 'noteon'.
// Avoid if possible: take more time and realloc the entire MIDI list.
midiFilePlayer.midiLoaded.MPTK_MidiEvents = MidiLoad.MPTK_SortEvents(midiFilePlayer.MPTK_MidiEvents, logPerf: true);
if (calculateTiming)
{
// Timing recalculation is not useful for all use cases.
// Avoid if possible because this takes time and realloc data.
midiFilePlayer.midiLoaded.MPTK_CalculateTiming();
}
// Then play the event list modified (not guaranteed to be the hit of the year!)
// ----------------------------------------------------------------------------------
midiFilePlayer.MPTK_Play(alreadyLoaded: true);
}
#else
Debug.LogWarning("MIDI preload and alter MIDI events are available only with the PRO version");
#endif
}
HelperDemo.LinkTo("https://mptkapi.paxstellar.com/d7/deb/class_midi_player_t_k_1_1_midi_file_player.html#a7c1b1b1efab0022731f69e5161952c59");
if (GUILayout.Button("View MIDI events", GUILayout.Width(120)))
{
midiFilePlayer.MPTK_MidiEvents.ForEach(midi => Debug.Log(midi));
}
HelperDemo.GUI_Horizontal(HelperDemo.Zone.END);
HelperDemo.GUI_Vertical(HelperDemo.Zone.END);
HelperDemo.GUI_Horizontal(HelperDemo.Zone.END);
}
Description of a MIDI Event. It's the heart of MPTK! Essential to handling MIDI by script from all ot...
Definition: MPTKEvent.cs:45
MPTKMeta
Definition: MPTKEnum.cs:321
MPTKCommand
Definition: MPTKEnum.cs:12

◆ MPTK_Clear()

void MidiPlayerTK.MidiLoad.MPTK_Clear ( )

Removes all information about the MIDI loaded

◆ MPTK_ComputeDuration()

void MidiPlayerTK.MidiLoad.MPTK_ComputeDuration ( )

Calculate MPTK_Duration, MPTK_DurationMS, MPTK_TickLast from the MIDI events list MPTK_MidiEvents.

This is done automatically when loading a MIDI file but not when MIDI events are added by script. In this case you will have to call this method.

◆ MPTK_ConvertTickToTime()

double MidiPlayerTK.MidiLoad.MPTK_ConvertTickToTime ( long  tick)

Deprecated:
Convert the tick duration to a real time duration in millisecond regarding the current tempo. Please investigate the tempo map capabilities, see MPTK_TempoMap.
Parameters
tickduration in ticks
Returns
duration in milliseconds

◆ MPTK_ConvertTimeToTick()

long MidiPlayerTK.MidiLoad.MPTK_ConvertTimeToTick ( double  time)

Deprecated:
Convert a real time duration in millisecond to a number of tick regarding the current tempo. Please investigate the tempo map capabilities, see MPTK_TempoMap.
Parameters
timeduration in milliseconds
Returns
duration in ticks

◆ MPTK_DisplayMidiAttributes()

void MidiPlayerTK.MidiLoad.MPTK_DisplayMidiAttributes ( )

Display in console the attributes of the MIDI loaded - v2.9.0

Parameters
tmEvents

◆ MPTK_FindLastNote()

MPTKEvent MidiPlayerTK.MidiLoad.MPTK_FindLastNote ( )

Find the last MIDI event note-on.

Version
2.12.1
Returns
return the last MPTKEvent note-on found or null if not found

◆ MPTK_Load() [1/4]

bool MidiPlayerTK.MidiLoad.MPTK_Load ( byte[]  datamidi,
bool  strict = false 
)

Load Midi from an array of bytes. If result is true, MPTK_MidiEvents contains list of MIDI events.

Parameters
datamidibyte arry midi
strictIf true will error on non-paired note events, default:false
Returns
true if loaded

◆ MPTK_Load() [2/4]

bool MidiPlayerTK.MidiLoad.MPTK_Load ( int  index,
bool  strict = false,
bool  extendedText = false 
)

Load Midi from midi MPTK referential (Unity resource).
The index of the Midi file can be found in the windo "Midi File Setup". Display with menu MPTK / Midi File Setup
If result is true, MPTK_MidiEvents contains list of MIDI events.

public MidiLoad MidiLoaded;
// .....
MidiLoaded = new MidiLoad();
MidiLoaded.MPTK_Load(14) // index for "Beattles - Michelle"
Debug.Log("Duration:" + MidiLoaded.MPTK_Duration);
Base class for loading a MIDI file and reading MIDI event in a MIDI sequencer. It's not possible to i...
Definition: MidiLoad.cs:18
TimeSpan MPTK_Duration
Definition: MidiLoad.cs:109
bool MPTK_Load(int index, bool strict=false, bool extendedText=false)
Definition: MidiLoad.cs:483
Parameters
index
strictIf true will error on non-paired note events, default:false
Returns
true if loaded

◆ MPTK_Load() [3/4]

bool MidiPlayerTK.MidiLoad.MPTK_Load ( MPTKWriter  mfw2)

Load Midi from a MidiFileWriter2 object

Parameters
mfw2MidiFileWriter2 object
Returns
true if loaded

◆ MPTK_Load() [4/4]

bool MidiPlayerTK.MidiLoad.MPTK_Load ( string  midiname,
bool  strict = false 
)

Load Midi from a Midi file from Unity resources. The Midi file must be present in Unity MidiDB ressource folder.

public MidiLoad MidiLoaded;
// .....
MidiLoaded = new MidiLoad();
MidiLoaded.MPTK_Load("Beattles - Michelle")
Debug.Log("Duration:" + MidiLoaded.MPTK_Duration);
Parameters
midinameMidi file name without path and extension
strictif true, check strict compliance with the Midi norm
Returns
true if loaded

◆ MPTK_LoadFile()

bool MidiPlayerTK.MidiLoad.MPTK_LoadFile ( string  filename,
bool  strict = false 
)

Load MIDI file from a local file (Moved to PRO since version 2.89.5)

Parameters
filenameMidi path and filename to load (OS dependant)
strictif true the MIDI must strictely respect the midi norm
Returns

◆ MPTK_MPQN2BPM()

static int MidiPlayerTK.MidiLoad.MPTK_MPQN2BPM ( int  microsecondsPerQuaterNote)
static

Deprecated:
MidiLoad.QuarterPerMicroSecond2BeatPerMinute is deprecated and will be removed. Please investigate MPTKEvent.QuarterPerMicroSecond2BeatPerMinute.

◆ MPTK_ReadMidiEvents()

List< MPTKEvent > MidiPlayerTK.MidiLoad.MPTK_ReadMidiEvents ( long  fromTicks = 0,
long  toTicks = long.MaxValue 
)

Read the list of midi events available in the Midi from a ticks position to an end position.

Parameters
fromTicksticks start, default 0
toTicksticks end, default end of Midi file
Returns

◆ MPTK_SearchEventFromTick()

static int MidiPlayerTK.MidiLoad.MPTK_SearchEventFromTick ( List< MPTKEvent midiEvents,
long  tickSearched 
)
static

Search for a MIDI event from a tick position. v2.9.0

Parameters
tickSearchedtick position
Returns
MPTKEvent or null

◆ MPTK_SearchEventFromTime()

MPTKEvent MidiPlayerTK.MidiLoad.MPTK_SearchEventFromTime ( double  time)

Search for a Midi event from a time position expressed in millisecond.
So time=19.3 and time=19.9 will find the same event.

Parameters
timeposition in milliseconds
Returns
MPTKEvent or null

◆ MPTK_SearchTickFromTime()

long MidiPlayerTK.MidiLoad.MPTK_SearchTickFromTime ( double  time)

Search a tick position in the current midi from a position in millisecond.
Warning: this method loop on the whole midi to find the position.
Could be CPU costly but this method take care of the tempo change in the Midi.
Use MPTK_ConvertTimeToTick if there is no tempo change in the midi.

Parameters
timeposition in milliseconds
Returns
position in ticks

◆ MPTK_SortEvents()

static List< MPTKEvent > MidiPlayerTK.MidiLoad.MPTK_SortEvents ( List< MPTKEvent midiEvents,
bool  logPerf = false 
)
static

Sort MIDI event list based on tick value, but for the same tick value, 'preset change' and 'meta' events are placed before other events such as 'noteon'.

Note
  • Realloc of the list is done, the new sorted list is available at return.
  • Good performance for high disorder.
Parameters
midiEvents
logPerf
Returns
sorted list
private void OnGUI_ModifyMidiAndPlay()
{
HelperDemo.GUI_Horizontal(HelperDemo.Zone.BEGIN, myStyle.BacgDemosLight);
HelperDemo.GUI_Indent(widthIndent);
HelperDemo.GUI_Vertical(HelperDemo.Zone.BEGIN, myStyle.BacgDemosLight);
GUILayout.Label("It's possible to change the MIDI events before playing. This demo loads the selected MIDI, adds some notes and plays the MIDI without reloading it. Result not guaranteed!", myStyle.TitleLabel3);
countNoteToInsert = (int)HelperDemo.GUI_Slider("Count notes to insert:", (float)countNoteToInsert, 1, 100,
alignCaptionRight: false, enableButton: true, widthCaption: 170, widthSlider: 250, widthLabelValue: 50);
tickPositionToInsert = (long)HelperDemo.GUI_Slider("Tick position to insert:", (long)tickPositionToInsert, 0, (long)midiFilePlayer.MPTK_TickLast,
alignCaptionRight: false, enableButton: true, widthCaption: 170, widthSlider: 250, widthLabelValue: 50);
long quarterPosition = tickPositionToInsert / midiFilePlayer.MPTK_DeltaTicksPerQuarterNote;
long newQuarter = (long)HelperDemo.GUI_Slider("Tick position by quarter:", (long)quarterPosition, 0, (long)midiFilePlayer.MPTK_TickLast / midiFilePlayer.MPTK_DeltaTicksPerQuarterNote,
alignCaptionRight: false, enableButton: true, widthCaption: 170, widthSlider: 250, widthLabelValue: 50);
if (newQuarter != quarterPosition)
{
quarterPosition = newQuarter;
tickPositionToInsert = quarterPosition * midiFilePlayer.MPTK_DeltaTicksPerQuarterNote;
}
channelToInsert = (int)HelperDemo.GUI_Slider("Channel to insert:", channelToInsert, 0, 15,
alignCaptionRight: false, enableButton: true, widthCaption: 170, widthSlider: 250, widthLabelValue: 50);
HelperDemo.GUI_Horizontal(HelperDemo.Zone.BEGIN, null, GUILayout.Width(500));
clearNote = GUILayout.Toggle(clearNote, "Clear MIDI list before inserting");
GUILayout.Space(10);
randomNote = GUILayout.Toggle(randomNote, "Random Note");
GUILayout.Space(10);
randomDuration = GUILayout.Toggle(randomDuration, "Random Duration");
GUILayout.Space(10);
quickSort = GUILayout.Toggle(quickSort, "Quick Sort");
GUILayout.Space(10);
calculateTiming = GUILayout.Toggle(calculateTiming, "Timing Recalculation");
HelperDemo.GUI_Horizontal(HelperDemo.Zone.END);
HelperDemo.GUI_Horizontal(HelperDemo.Zone.BEGIN);
if (GUILayout.Button("Insert And Play", GUILayout.Width(120)))
{
#if MPTK_PRO
// Better to stop playing.
midiFilePlayer.MPTK_Stop();
// There is no need of note-off events.
midiFilePlayer.MPTK_KeepNoteOff = false;
// MPTK_MidiName must contains the name of the MIDI to load.
if (midiFilePlayer.MPTK_Load() != null)
{
Debug.Log($"Duration: {midiFilePlayer.MPTK_Duration.TotalSeconds} seconds");
Debug.Log($"Count MIDI Events: {midiFilePlayer.MPTK_MidiEvents.Count}");
if (clearNote)
midiFilePlayer.MPTK_MidiEvents.Clear();
// Insert weird notes in this beautiful MIDI!
// ------------------------------------------
long tickToInsert = tickPositionToInsert;
for (int insertNote = 0; insertNote < countNoteToInsert; insertNote++)
{
int note;
if (randomNote)
note = UnityEngine.Random.Range(50, 73); // Random notes between 48 (C4) and 72 (C6)
else
note = 60 + insertNote % 12; // Hust a remap of notes!
int eightCount; // How many eight duration to generate
if (randomDuration)
eightCount = UnityEngine.Random.Range(0, 9); // max 8, so a whole note
else
eightCount = 2; // a quarter
int tickDuration = eightCount * midiFilePlayer.MPTK_DeltaTicksPerQuarterNote;
// Add a note
midiFilePlayer.MPTK_MidiEvents.Insert(0,
new MPTKEvent()
{
Channel = channelToInsert,
Command = MPTKCommand.NoteOn,
Value = note,
Length = tickDuration,
Duration = (long)(tickDuration * midiFilePlayer.MPTK_Pulse), // Transform ticks to millisecond
Tick = tickToInsert,
});
// Add a text
midiFilePlayer.MPTK_MidiEvents.Insert(0,
new MPTKEvent()
{
Command = MPTKCommand.MetaEvent,
Meta = MPTKMeta.TextEvent,
Info = $"Add a weird note {HelperNoteLabel.LabelFromMidi(note)}",
Tick = tickToInsert,
});
// Move to the next insert, add length of note added.
tickToInsert += tickDuration;
}
// New events has been inserted, MIDI events list must be sorted by tick value.
// ---------------------------------------------------------------------------
if (quickSort)
// This is a quick sort based on the tick value, regardless of the type of MIDI event.
midiFilePlayer.MPTK_SortEvents();
else
// This sort is also based on tick value, but for the same tick value,
// 'preset change' and 'meta' events are placed before other events such as 'noteon'.
// Avoid if possible: take more time and realloc the entire MIDI list.
midiFilePlayer.midiLoaded.MPTK_MidiEvents = MidiLoad.MPTK_SortEvents(midiFilePlayer.MPTK_MidiEvents, logPerf: true);
if (calculateTiming)
{
// Timing recalculation is not useful for all use cases.
// Avoid if possible because this takes time and realloc data.
midiFilePlayer.midiLoaded.MPTK_CalculateTiming();
}
// Then play the event list modified (not guaranteed to be the hit of the year!)
// ----------------------------------------------------------------------------------
midiFilePlayer.MPTK_Play(alreadyLoaded: true);
}
#else
Debug.LogWarning("MIDI preload and alter MIDI events are available only with the PRO version");
#endif
}
HelperDemo.LinkTo("https://mptkapi.paxstellar.com/d7/deb/class_midi_player_t_k_1_1_midi_file_player.html#a7c1b1b1efab0022731f69e5161952c59");
if (GUILayout.Button("View MIDI events", GUILayout.Width(120)))
{
midiFilePlayer.MPTK_MidiEvents.ForEach(midi => Debug.Log(midi));
}
HelperDemo.GUI_Horizontal(HelperDemo.Zone.END);
HelperDemo.GUI_Vertical(HelperDemo.Zone.END);
HelperDemo.GUI_Horizontal(HelperDemo.Zone.END);
}

◆ NoteLength()

MPTKEvent.EnumLength MidiPlayerTK.MidiLoad.NoteLength ( MPTKEvent  mptkEvent)

https://en.wikipedia.org/wiki/Note_value

Parameters
mptkEvent
Returns

Member Data Documentation

◆ KeepNoteOff

bool MidiPlayerTK.MidiLoad.KeepNoteOff

Deprecated:
v2.9.0 rather use MPTK_KeepNoteOff

◆ MPTK_CurrentBeat

int MidiPlayerTK.MidiLoad.MPTK_CurrentBeat

Current beat of the current event played [Pro].

◆ MPTK_CurrentIndexSignMap

int MidiPlayerTK.MidiLoad.MPTK_CurrentIndexSignMap

Current index of the Signature segment.

◆ MPTK_CurrentIndexTempoMap

int MidiPlayerTK.MidiLoad.MPTK_CurrentIndexTempoMap

Current index of the Tempo segment.

◆ MPTK_CurrentMeasure

int MidiPlayerTK.MidiLoad.MPTK_CurrentMeasure

Current measure of the current event played [Pro].

◆ MPTK_CurrentSignMap

MPTKSignature MidiPlayerTK.MidiLoad.MPTK_CurrentSignMap

Current Signature segment.

◆ MPTK_CurrentTempoMap

MPTKTempo MidiPlayerTK.MidiLoad.MPTK_CurrentTempoMap

Current Tempo Map.

◆ MPTK_DeltaTicksPerQuarterNote

int MidiPlayerTK.MidiLoad.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_Duration

TimeSpan MidiPlayerTK.MidiLoad.MPTK_Duration

Real duration expressed in TimeSpan of the full midi from the first event (tick=0) to the last event.
If MPTK_KeepEndTrack is false, the MIDI events End Track are not considered to calculate this time.
The tempo changes are taken into account if MPTK_EnableChangeTempo is set to true before loading the MIDI.

◆ MPTK_DurationMS

float MidiPlayerTK.MidiLoad.MPTK_DurationMS

Real duration expressed in milliseconds of the full midi from the first event (tick=0) to the last event.
If MPTK_KeepEndTrack is false, the MIDI events End Track are not considered to calculate this time.
The tempo changes are taken into account if MPTK_EnableChangeTempo is set to true before loading the MIDI.

◆ MPTK_EnableChangeTempo

bool MidiPlayerTK.MidiLoad.MPTK_EnableChangeTempo

Should enable or disable change tempo from MIDI Events ? If disabled, the first tempo defined (or default to 120 BPM) will be used for all the MIDI played.

◆ MPTK_EventLastNote

MPTKEvent MidiPlayerTK.MidiLoad.MPTK_EventLastNote

Last MIDI event note-on found in the MIDI.
There is often other MIDI events after the last note-on: for example event track-end.
Use this attribute to known the tick position time when all sound will be stop.
See also the MPTK_PositionLastNote which provides the last tich of the MIDI.

Version
v2.12.1

◆ MPTK_ExtendedText

bool MidiPlayerTK.MidiLoad.MPTK_ExtendedText

If the value is true, text read from Text META (e.g. lyrics) will be read with UTF8 encoding. The default is false.
The MIDI standard only allows ASCII characters for this META, but with this extension you will be able to read and display
characters like Korean, Chinese, Japanese and even French accented letters ;-)

Version
2.11.3

◆ MPTK_InitialTempo

double MidiPlayerTK.MidiLoad.MPTK_InitialTempo

Initial tempo found in the MIDI. Available from MPTK_MidiLoaded attribut from MidiFilePLayer or MidiExternal.

if (midiPlayer.MPTK_MidiLoaded != null)
infoMidi += $"Initial Tempo: {midiPlayer.MPTK_MidiLoaded.MPTK_InitialTempo:F2}\n";
Note
  • Available only when a MIDI is loaded.

◆ MPTK_KeepEndTrack

bool MidiPlayerTK.MidiLoad.MPTK_KeepEndTrack

If set to true, the meta MIDI events 'End Track' are kept and the MIDI duration includes the 'End Track' events.
Default value is false.

◆ MPTK_KeepNoteOff

bool MidiPlayerTK.MidiLoad.MPTK_KeepNoteOff

A MIDI file is a kind of keyboard simulation: in general, a key pressed generates a 'note-on' and a key release generates a 'note-off'.
But there is an other possibility in a MIDI file: create a 'note-on' with a velocity=0 wich must act as a 'midi-off'
By default, MPTK create only one MPTK event with the command NoteOn and a duration.
But in some cases, you could want to keep the note-off events if they exist in the MIDI file.
Set to false if there is no need (could greatly increases the MIDI list events).
Set to true to keep 'note-off' events.

◆ MPTK_KeySigMajorMinor

int MidiPlayerTK.MidiLoad.MPTK_KeySigMajorMinor

Updated from KeySignature event when playing MIDI: specifies the scale of the MIDI file.

◆ MPTK_KeySigSharpsFlats

int MidiPlayerTK.MidiLoad.MPTK_KeySigSharpsFlats

Updated from KeySignature event when playing MIDI: values between -7 and 7 and specifies the key signature in terms of number of flats (if negative) or sharps (if positive) https://www.recordingblogs.com/wiki/midi-key-signature-meta-message

◆ MPTK_LastEventPlayed

MPTKEvent MidiPlayerTK.MidiLoad.MPTK_LastEventPlayed

Current MIDI event read when the MIDI sequencer is playing the MIDI. See MPTK_TickCurrent.

◆ MPTK_LoadTime

float MidiPlayerTK.MidiLoad.MPTK_LoadTime

Processing time in millisecond for loading the MIDI file.

◆ MPTK_LogLoadEvents

bool MidiPlayerTK.MidiLoad.MPTK_LogLoadEvents

If true display in console all midi events when a MIDI file is loaded. v2.9.0
Set to true could increase greatly the load time. To be used only for debug.

◆ MPTK_MeasureLastNote

long MidiPlayerTK.MidiLoad.MPTK_MeasureLastNote

Measure position for the last note-on found.
There is often other MIDI events after the last note-on: for example event track-end.

◆ MPTK_MicrosecondsPerQuarterNote

int MidiPlayerTK.MidiLoad.MPTK_MicrosecondsPerQuarterNote

Read from the SetTempo event: The tempo is given in micro seconds per quarter beat. To convert this to BPM we needs to use the following equation:BPM = 60,000,000/[tt tt tt] Warning: this value can change during the playing when a change tempo event is find.
https://paxstellar.fr/2020/09/11/midi-timing/

◆ MPTK_MidiEvents

List<MPTKEvent> MidiPlayerTK.MidiLoad.MPTK_MidiEvents

List of MIDI events loaded and played by the MIDI sequencer. It's possible to modify directly the content but with unpredictable results!

◆ MPTK_No32ndNotesInQuarterNote

int MidiPlayerTK.MidiLoad.MPTK_No32ndNotesInQuarterNote

Updated from TimeSignature event when playing MIDI: This value specifies the number of 1/32nds of a note happen every MIDI quarter note.
It is usually 8 which means that a quarter note happens every quarter note.
https://paxstellar.fr/2020/09/11/midi-timing/

◆ MPTK_NumberBeatsMeasure

int MidiPlayerTK.MidiLoad.MPTK_NumberBeatsMeasure

Updated from TimeSignature event when playing MIDI: the numerator counts the number of beats in a measure.
For example a numerator of 4 means that each bar contains four beats.

Note

◆ MPTK_NumberQuarterBeat

int MidiPlayerTK.MidiLoad.MPTK_NumberQuarterBeat

Updated from TimeSignature event when playing MIDI: describe of what note value a beat is (ie, how many quarter notes there are in a beat).

Note
This value is updated at each time signature meta event played.
Calculated with 2^MPTK_TimeSigDenominatorn
  • 1 for a whole-note
  • 2 for a half-note
  • 4 for a quarter-note
  • 8 for an eighth-note, etc.

Equal 2 Power TimeSigDenominator.
https://paxstellar.fr/2020/09/11/midi-timing/

◆ MPTK_PositionFirstNote

double MidiPlayerTK.MidiLoad.MPTK_PositionFirstNote

Real time position in millisecond for the first note-on found.
Most MIDI don't start playing a note immediately. There is often a delay.
Use this attribute to known the real time wich it will start.
See also MPTK_TickFirstNote

◆ MPTK_PositionLastNote

double MidiPlayerTK.MidiLoad.MPTK_PositionLastNote

Real time position in millisecond for the last note-on found in the MIDI.
There is often other MIDI events after the last note-on: for example event track-end.
Use this attribute to known the real time when all sound will be stop.
See also the MPTK_DurationMS which provides the full time of all MIDI events including track-end, control at the beginning and at the end, ....
See also MPTK_TickLastNote

◆ MPTK_Pulse

double MidiPlayerTK.MidiLoad.MPTK_Pulse

Real-time duration in millisecond of a MIDI tick. This value is updated when a tempo change is found.
The pulse length is the minimum time in millisecond between two MIDI events.

Note
  • Depends on the current tempo, the MPTK_DeltaTicksPerQuarterNote and the Speed.
  • Formula: Pulse = (60000000 / MPTK_CurrentTempo) / MPTK_DeltaTicksPerQuarterNote / 1000 / Speed

◆ MPTK_RawSeek

bool MidiPlayerTK.MidiLoad.MPTK_RawSeek

This parameter is used when changing the playback position in a MIDI.
By default (false), all events other than note-on are replayed from the beginning of the MIDI to the new position, to put the synthesizer back in the right context (tempo, selected instruments, controller, ...).
If set to true, the current playback position is set, but the previous context is retained. This can produce undesired effects (or funny!) on some MIDIs, but it also makes it possible to change position much more quickly.
It's a choice to be made according to your needs.

Note
  • Value returns to false (default) each time a MIDI is loaded. You can use MPTK_Load() to load the MIDI, change this parameter and play the MIDI with #MPTK_Play().

◆ MPTK_SignMap

List<MPTKSignature> MidiPlayerTK.MidiLoad.MPTK_SignMap

List of all signature changes found in the MIDI.

◆ MPTK_TempoMap

List<MPTKTempo> MidiPlayerTK.MidiLoad.MPTK_TempoMap

List of all tempo changes found in the MIDI.

◆ MPTK_TickCurrent

long MidiPlayerTK.MidiLoad.MPTK_TickCurrent

Get the tick value of the last MIDI event played.
Set the tick value of the next MIDI event to played.
Unlike MPTK_TickPlayer which is updated continuously, this properties is updated only when a MIDI event is read from the sequencer.

Midi tick is an easy way to identify a position in a song independently of the time which could vary with tempo change event.
The count of ticks by quarter is constant all along a MIDI, it's a properties of the whole MIDI. see MPTK_DeltaTicksPerQuarterNote.
With a time signature of 4/4 the ticks length of a bar is 4 * MPTK_DeltaTicksPerQuarterNote.
More info here https://paxstellar.fr/2020/09/11/midi-timing/ @notes

  • Works only when the MIDI sequencer is playing.
  • It's not possible to set the current tick when the MIDI is not playing. Rather use the event OnEventStartPlayMidi to change the start position.
  • See also MidiFilePlayer::MPTK_Position: set or get the position in milliseconds.

◆ MPTK_TickEnd

long MidiPlayerTK.MidiLoad.MPTK_TickEnd

Tick to end playing the MIDI. All MIDI events with MIDI tick higher or equal are not played.

// Full source code in MidiLoop.cs
void LoadAndPlay()
{
// Preload the MIDI file to be able to set MIDI attributes before playing
midiFilePlayer.MPTK_Load();
SetLoopingMode();
midiFilePlayer.MPTK_Play(alreadyLoaded: true);
}
private void SetLoopingMode()
{
// Set start / end position by bar
midiFilePlayer.MPTK_MidiLoaded.MPTK_TickStart = ConvertBarToTick(StartBar);
midiFilePlayer.MPTK_MidiLoaded.MPTK_TickEnd = ConvertBarToTick(EndBar);
midiFilePlayer.MPTK_ModeStopVoice = MidiFilePlayer.ModeStopPlay.StopWhenAllVoicesReleased;
midiFilePlayer.MPTK_MidiAutoRestart = true;
}
// Convert a bar number (musical score concept) to a tick position (MIDI concept).\n
long ConvertBarToTick(int bar)
{
// was MPTK_NumberQuarterBeat, replaced by MPTK_NumberBeatsMeasure
return (long)(bar * midiFilePlayer.MPTK_MidiLoaded.MPTK_NumberBeatsMeasure * midiFilePlayer.MPTK_MidiLoaded.MPTK_DeltaTicksPerQuarterNote);
}
Play a MIDI file from the MidiDB. This class must be used with the prefab MidiFilePlayer....
Definition: MidiFilePlayer.cs:69
ModeStopPlay
Defined when the MIDI player is stopped. Immediately, waits for the release phase or the complete sto...
Definition: MidiFilePlayer.cs:192

◆ MPTK_TickFirstNote

long MidiPlayerTK.MidiLoad.MPTK_TickFirstNote

Tick position for the first note-on found.
Most MIDI don't start playing a note immediately. There is often a delay.
Use this attribute to known the tick position where the player will start to play a sound.
See also MPTK_PositionFirstNote

◆ MPTK_TickLast

long MidiPlayerTK.MidiLoad.MPTK_TickLast

Tick value of the last MIDI event found in the MIDI loaded.

◆ MPTK_TickLastNote

long MidiPlayerTK.MidiLoad.MPTK_TickLastNote

Tick position for the last note-on found.
There is often other MIDI events after the last note-on: for example event track-end.
Use this attribute to known the tick position time when all sound will be stop.
See also the MPTK_PositionLastNote which provides the last tich of the MIDI.

◆ MPTK_TickPlayer

long MidiPlayerTK.MidiLoad.MPTK_TickPlayer

Get the real-time tick value of the MIDI Player.
Unlike MPTK_TickCurrent which is updated only when a MIDI event is read, this properties is continusously updated when the MIDI thread is playing.

More info about tick here here https://paxstellar.fr/2020/09/11/midi-timing/ @notes

  • Works only when the MIDI is playing.
  • Can't be modified.
  • Used by the MIDI Editor (pro) to display in real time the sequencer position.
  • Available also from MidiFilePlayer.MPTK_MidiLoaded

◆ MPTK_TicksInMetronomeClick

int MidiPlayerTK.MidiLoad.MPTK_TicksInMetronomeClick

Updated from TimeSignature event when playing MIDI: The standard MIDI clock ticks every 24 times every quarter note (crotchet)
So a MPTK_TicksInMetronomeClick value of 24 would mean that the metronome clicks once every quarter note.
A MPTK_TicksInMetronomeClick value of 6 would mean that the metronome clicks once every 1/8th of a note (quaver).
https://paxstellar.fr/2020/09/11/midi-timing/

◆ MPTK_TickStart

long MidiPlayerTK.MidiLoad.MPTK_TickStart

Tick to start playing the MIDI.

// Full source code in MidiLoop.cs
void LoadAndPlay()
{
// Preload the MIDI file to be able to set MIDI attributes before playing
midiFilePlayer.MPTK_Load();
SetLoopingMode();
midiFilePlayer.MPTK_Play(alreadyLoaded: true);
}
private void SetLoopingMode()
{
// Set start / end position by bar
midiFilePlayer.MPTK_MidiLoaded.MPTK_TickStart = ConvertBarToTick(StartBar);
midiFilePlayer.MPTK_MidiLoaded.MPTK_TickEnd = ConvertBarToTick(EndBar);
midiFilePlayer.MPTK_ModeStopVoice = MidiFilePlayer.ModeStopPlay.StopWhenAllVoicesReleased;
midiFilePlayer.MPTK_MidiAutoRestart = true;
}
// Convert a bar number (musical score concept) to a tick position (MIDI concept).\n
long ConvertBarToTick(int bar)
{
// was MPTK_NumberQuarterBeat, replaced by MPTK_NumberBeatsMeasure
return (long)(bar * midiFilePlayer.MPTK_MidiLoaded.MPTK_NumberBeatsMeasure * midiFilePlayer.MPTK_MidiLoaded.MPTK_DeltaTicksPerQuarterNote);
}

◆ MPTK_TimeSigDenominator

int MidiPlayerTK.MidiLoad.MPTK_TimeSigDenominator

Updated from TimeSignature event when playing MIDI: The denominator specifies the number of quarter notes in a beat.

◆ MPTK_TimeSigNumerator

int MidiPlayerTK.MidiLoad.MPTK_TimeSigNumerator

Updated from TimeSignature event when playing MIDI: The numerator counts the number of beats in a measure.
For example a numerator of 4 means that each bar contains four beats.
This is important to know because usually the first beat of each bar has extra emphasis.
In MIDI the denominator value is stored in a special format. i.e. the real denominator = 2 ^ MPTK_TimeSigNumerator
https://paxstellar.fr/2020/09/11/midi-timing/

◆ MPTK_TrackCount

int MidiPlayerTK.MidiLoad.MPTK_TrackCount

Count of track in the MIDI file

Property Documentation

◆ MPTK_CurrentTempo

double MidiPlayerTK.MidiLoad.MPTK_CurrentTempo
getset

Get or change the current tempo played by the internal MIDI sequencer. Available from MPTK_MidiLoaded attribut from MidiFilePLayer or MidiExternal.

if (midiPlayer.MPTK_MidiLoaded != null)
infoMidi += $"Current Tempo: {midiPlayer.MPTK_MidiLoaded.MPTK_CurrentTempo:F2}\n";
Note
  • Available only when a MIDI is loaded.
  • Warning: changing the current tempo when playing has no impact on the calculated duration of the MIDI. https://en.wikipedia.org/wiki/Tempo