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

Start, stop, pause, resume, replay, and sequence MIDI playback. More...

Play and Stop MIDI

bool MidiPlayerTK.MidiFilePlayer.MPTK_StartPlayAtFirstNote
 If the value is true, MIDI playing will begin at the first note found in the MIDI.
bool MidiPlayerTK.MidiFilePlayer.MPTK_StopPlayOnLastNote
 By default, the end of a MIDI file is not the last note. It is the last MIDI event.
If this value is true, MIDI playback will stop at the last note found in the MIDI file
and the OnEventEndPlay will be triggered at the last note.
ModeStopPlay MidiPlayerTK.MidiFilePlayer.MPTK_ModeStopVoice
 Defined the behavior of the MIDI player when playback is stopped with MPTK_Stop or restarted when the last MIDI events is reached and MPTK_MidiAutoRestart is set to true.
Code example:
bool MidiPlayerTK.MidiFilePlayer.MPTK_PlayOnStart [get, set]
 Whether the MIDI playback starts when the application starts?
bool MidiPlayerTK.MidiFilePlayer.MPTK_MidiAutoRestart [get, set]
 When the value is true, the current MIDI playing is restarted when it reaches the end of the MIDI file or #MPTK_MidiLoaded.MPTK_TickEnd.
.
bool MidiPlayerTK.MidiFilePlayer.MPTK_IsPaused [get]
 Is MIDI file playing is paused ?
bool MidiPlayerTK.MidiFilePlayer.MPTK_IsPlaying [get]
 Is MIDI file is playing ?
virtual void MidiPlayerTK.MidiFilePlayer.MPTK_Play (bool alreadyLoaded=false)
 Plays the midi file defined with MPTK_MidiName or MPTK_MidiIndex. In the most part of the case, just call midiFilePlayer.MPTK_Play() in your script. But sometimes, you want to apply some changes on the MIDI file before playing it. The script example below describes how to load a MIDI file, apply some changes and play it. Thank to the parameter 'alreadyLoaded'. When true, the MIDI has been already loaded with MPTK_Load().
void MidiPlayerTK.MidiFilePlayer.MPTK_Stop (bool stopAllSound=true, float wait=-1f)
 Stops MIDI playback and cancels all sounds. This operation is performed in background, so MIDI may really stop after this method returns.
void MidiPlayerTK.MidiFilePlayer.MPTK_RePlay ()
 Restart playing of the current midi file.
void MidiPlayerTK.MidiFilePlayer.MPTK_Pause (float timeToPauseMS=-1f)
 Pause the current playing. Use MPTK_UnPause to continue playing.
void MidiPlayerTK.MidiFilePlayer.MPTK_UnPause ()
 UnPause the current playing when MidiPlayer is paused with MPTK_Pause.
void MidiPlayerTK.MidiFilePlayer.MPTK_Next ()
 Plays next MIDI from the list of midi defined in MPTK (see Unity menu Midi).
void MidiPlayerTK.MidiFilePlayer.MPTK_Previous ()
 Plays previous MIDI from the list of midi defined in MPTK (see Unity menu Midi).
void MidiPlayerTK.MidiFilePlayer.MPTK_PlayNextOrPrevious (int offset)
 Plays the next or previous MIDI from the MidiDB list.
void MidiPlayerTK.MidiFilePlayer.MPTK_SwitchMidiWithDelay (int index, string name, float volume, float delayToStopMillisecond, float delayToStartMillisecond)
 Switches playback between two MIDIs with ramp-up.
This method is useful for integration with Bolt: main MIDI parameters are defined in one call.
virtual void MidiPlayerTK.MidiFilePlayer.MPTK_Play (float delayRampUp, float startDelay=0)
 Plays the MIDI file defined by MPTK_MidiName or MPTK_MidiIndex with ramp-up to the volume defined by MPTK_Volume.
The time to get a MIDI playing at full MPTK_Volume is delayRampUp + startDelay.
A delayed start can also be set.
void MidiPlayerTK.MidiFilePlayer.MPTK_Play (byte[] data)
 Plays a MIDI file from a byte array.
Check MPTK_StatusLastMidiLoaded to get the load status.
void MidiPlayerTK.MidiFilePlayer.MPTK_Play (MPTKWriter mfw2, float delayRampUp=0f, float fromPosition=0, float toPosition=0, long fromTick=0, long toTick=0, bool timePosition=true)
 Plays a MIDI from a MidiFileWriter2 object.
virtual void MidiPlayerTK.MidiFilePlayer.MPTK_Stop (float delayRampDown, float stopDelay=0)
 Stops playback after a delay. After the stop delay (0 by default), the volume decreases until playback stops.
The time to get a real MIDI stop is delayRampDown + stopDelay.

Detailed Description

Start, stop, pause, resume, replay, and sequence MIDI playback.

Function Documentation

◆ MPTK_Play() [1/4]

virtual void MidiPlayerTK.MidiFilePlayer.MPTK_Play ( bool alreadyLoaded = false)
virtual

Plays the midi file defined with MPTK_MidiName or MPTK_MidiIndex. In the most part of the case, just call midiFilePlayer.MPTK_Play() in your script. But sometimes, you want to apply some changes on the MIDI file before playing it. The script example below describes how to load a MIDI file, apply some changes and play it. Thank to the parameter 'alreadyLoaded'. When true, the MIDI has been already loaded with MPTK_Load().

Note
  • No effect when already playing, resume pause if playing.
  • corrected v2.17.1 - When MIDI player is paused and not yet playing, the player just resume pause and not playing ... now, resume pause and play!
public class LoadMidiAndPlay : MonoBehaviour
{
// This demo enables you to load a MIDI file before playing it, modify some MIDI events, and then play the modified MIDI.
// It also demonstrates how to change the tempo using three methods:
// 1) From the MidiFilePlayer inspector, under the "Show MIDI Parameters" tab, adjust the speed (default is 1).
// 2) Programmatically, at any time when the MIDI is playing, change the tempo using midiFilePlayer.MPTK_Tempo = bpm (bpm must be > 0).
// 3) Programmatically, load the MIDI, modify the MIDI tempo events, and then play.
//
// This demo showcases the third method.
// In your Unity scene:
// - Add a MidiFilePlayer prefab to your scene.
// - In the MidiFilePlayer inspector:
// - Select the MIDI file you wish to load.
// - Uncheck "Automatic MIDI Start".
// - Attach this script to an existing GameObject (whether empty or not).
// MPTK component for playing a MIDI file.
// You can set it in the inspector or let this script find it automatically.
public MidiFilePlayer midiFilePlayer;
private void Awake()
{
// Find a MidiFilePlayer added to the scene or set it directly in the inspector.
if (midiFilePlayer == null)
midiFilePlayer = FindFirstObjectByType<MidiFilePlayer>();
}
void Start()
{
if (midiFilePlayer == null)
{
Debug.LogWarning("No MidiFilePlayer Prefab found in the current Scene Hierarchy. See 'Maestro / Add Prefab' in the menu.");
}
else
{
// Index of the MIDI file from the MIDI database (find it using 'Midi File Setup' from the Maestro menu).
// Optionally, the MIDI file to load can also be defined in the inspector. Uncomment to select the MIDI programmatically.
// midiFilePlayer.MPTK_MidiIndex = 0;
// Load the MIDI without playing it.
MidiLoad midiloaded = midiFilePlayer.MPTK_Load();
if (midiloaded != null)
{
Debug.Log($"Duration: {midiloaded.MPTK_Duration.TotalSeconds} seconds, Initial Tempo: {midiloaded.MPTK_InitialTempo}, MIDI Event Count: {midiloaded.MPTK_ReadMidiEvents().Count}");
foreach (MPTKEvent mptkEvent in midiloaded.MPTK_MidiEvents)
{
if (mptkEvent.Command == MPTKCommand.MetaEvent && mptkEvent.Meta == MPTKMeta.SetTempo)
{
// The value contains Microseconds Per Beat, convert it to BPM for clarity.
double bpm = MPTKEvent.QuarterPerMicroSecond2BeatPerMinute(mptkEvent.Value);
// Double the tempo and convert back to Microseconds Per Beat.
mptkEvent.Value = MPTKEvent.BeatPerMinute2QuarterPerMicroSecond(bpm * 2);
Debug.Log($" Tempo doubled at tick position {mptkEvent.Tick} and {mptkEvent.RealTime / 1000f:F2} seconds. New tempo: {MPTKEvent.QuarterPerMicroSecond2BeatPerMinute(mptkEvent.Value)} BPM");
}
}
// Start playback.
midiFilePlayer.MPTK_Play(alreadyLoaded: true);
}
}
}
}
Parameters
alreadyLoadedtrue: the MIDI has already been loaded (see MPTK_Load() v2.9.0

Reimplemented in MidiPlayerTK.MidiExternalPlayer.

◆ MPTK_Stop() [1/2]

void MidiPlayerTK.MidiFilePlayer.MPTK_Stop ( bool stopAllSound = true,
float wait = -1f )

Stops MIDI playback and cancels all sounds. This operation is performed in background, so MIDI may really stop after this method returns.

Parameters
stopAllSoundSet to true to stop all sounds (default), otherwise currently playing notes will continue until they finish.
waitWith Legacy mode and if greater than -1 (v2.16), waits until MIDI playback is fully stopped or the specified wait time (in milliseconds) is reached. Otherwise, returns immediately.

◆ MPTK_Pause()

void MidiPlayerTK.MidiFilePlayer.MPTK_Pause ( float timeToPauseMS = -1f)

Pause the current playing. Use MPTK_UnPause to continue playing.

Parameters
timeToPauseMStime to pause in milliseconds. default or < 0 : indefinitely

◆ MPTK_PlayNextOrPrevious()

void MidiPlayerTK.MidiFilePlayer.MPTK_PlayNextOrPrevious ( int offset)

Plays the next or previous MIDI from the MidiDB list.

Version
Maestro Pro
Parameters
offsetForward or backward offset in the list. 1 = next, -1 = previous.

◆ MPTK_SwitchMidiWithDelay()

void MidiPlayerTK.MidiFilePlayer.MPTK_SwitchMidiWithDelay ( int index,
string name,
float volume,
float delayToStopMillisecond,
float delayToStartMillisecond )

Switches playback between two MIDIs with ramp-up.
This method is useful for integration with Bolt: main MIDI parameters are defined in one call.

Version
Maestro Pro
Parameters
indexIndex of the MIDI to play. Used only if name is null or empty.
nameName of the MIDI to play. Can be part of the MIDI name. If set, this parameter has priority over index .
volumeVolume of the MIDI. Use -1 to keep the default volume.
delayToStopMillisecondDelay before stopping the currently playing MIDI (with volume decrease), or delay before playback if no MIDI is playing.
delayToStartMillisecondDelay to reach full MIDI volume (ramp-up volume).

◆ MPTK_Play() [2/4]

virtual void MidiPlayerTK.MidiFilePlayer.MPTK_Play ( float delayRampUp,
float startDelay = 0 )
virtual

Plays the MIDI file defined by MPTK_MidiName or MPTK_MidiIndex with ramp-up to the volume defined by MPTK_Volume.
The time to get a MIDI playing at full MPTK_Volume is delayRampUp + startDelay.
A delayed start can also be set.

Version
Maestro Pro
Parameters
delayRampUpRamp-up delay, in milliseconds, to reach the default volume.
startDelayDelayed start, in milliseconds. V2.89.1

◆ MPTK_Play() [3/4]

void MidiPlayerTK.MidiFilePlayer.MPTK_Play ( byte[] data)

Plays a MIDI file from a byte array.
Check MPTK_StatusLastMidiLoaded to get the load status.

Version
Maestro Pro
// Example for Windows or macOS
using (Stream fsMidi = new FileStream(filepath, FileMode.Open, FileAccess.Read))
{
byte[] data = new byte[fsMidi.Length];
fsMidi.Read(data, 0, (int) fsMidi.Length);
midiFilePlayer.MPTK_Play(data);
}

◆ MPTK_Play() [4/4]

void MidiPlayerTK.MidiFilePlayer.MPTK_Play ( MPTKWriter mfw2,
float delayRampUp = 0f,
float fromPosition = 0,
float toPosition = 0,
long fromTick = 0,
long toTick = 0,
bool timePosition = true )

Plays a MIDI from a MidiFileWriter2 object.

Version
Maestro Pro
private void PlayDirectlyMidiSequence(string name, MPTKWriter mfw)
{
// Play MIDI with the MidiExternalPlay prefab without saving MIDI in a file
MidiFilePlayer midiPlayer = FindFirstObjectByType<MidiFilePlayer>();
if (midiPlayer == null)
{
Debug.LogWarning("Can't find a MidiFilePlayer Prefab in the current Scene Hierarchy. Add it with the MPTK menu.");
return;
}
midiPlayer.MPTK_Stop();
mfw.MidiName = name;
midiPlayer.OnEventStartPlayMidi.RemoveAllListeners();
midiPlayer.OnEventStartPlayMidi.AddListener((string midiname) =>
{
startPlaying = DateTime.Now;
Debug.Log($"Start playing '{midiname}'");
});
midiPlayer.OnEventEndPlayMidi.RemoveAllListeners();
midiPlayer.OnEventEndPlayMidi.AddListener((string midiname, EventEndMidiEnum reason) =>
{
Debug.Log($"End playing '{midiname}' {reason} Real Duration={(DateTime.Now - startPlaying).TotalSeconds:F3} seconds");
});
//midiPlayer.OnEventNotesMidi.RemoveAllListeners();
//midiPlayer.OnEventNotesMidi.AddListener((List<MPTKEvent> events) =>
//{
// foreach (MPTKEvent midievent in events)
// Debug.Log($"At {midievent.RealTime:F1} \t\t{midievent}");
//});
// In case of an inner loop has been defined in a Meta
midiPlayer.MPTK_InnerLoop.OnEventInnerLoop = (MPTKInnerLoop.InnerLoopPhase mode, long tickPlayer, long tickSeek, int count) =>
{
Debug.Log($"Inner Loop {mode} - MPTK_TickPlayer:{tickPlayer} --> TickSeek:{tickSeek} Count:{count}/{midiPlayer.MPTK_InnerLoop.Max}");
return true;
};
// Sort the events by ascending absolute time
// Calculate time, measure and quarter for each events
mfw.CalculateTiming(logPerf: true);
//midiPlayer.MPTK_InitSynth(channelCount: 128);
midiPlayer.MPTK_MidiAutoRestart = midiAutoRestart;
midiPlayer.MPTK_Play(mfw2: mfw);
}
Parameters
mfw2A MidiFileWriter2 object.
delayRampUp

◆ MPTK_Stop() [2/2]

virtual void MidiPlayerTK.MidiFilePlayer.MPTK_Stop ( float delayRampDown,
float stopDelay = 0 )
virtual

Stops playback after a delay. After the stop delay (0 by default), the volume decreases until playback stops.
The time to get a real MIDI stop is delayRampDown + stopDelay.

Version
Maestro Pro
Parameters
delayRampDownFade-out time in milliseconds.
stopDelayDelayed stop in milliseconds. V2.89.1

Variable Documentation

◆ MPTK_StartPlayAtFirstNote

bool MidiPlayerTK.MidiFilePlayer.MPTK_StartPlayAtFirstNote

If the value is true, MIDI playing will begin at the first note found in the MIDI.

Obviously, all previous events are processed, but at the same tick as the first note-on.
Often, the first note is not set at the beginning of the MIDI file (which is tick 0), alSo there is a delay before playing the first note.
This setting is useful to start playing sound immediately. Works also when looping.

Note
  • Does not affect the value of MPTK_Duration that remains the same.
  • If enabled, there will be a difference between the real time of the MIDI and the theoretical duration.

◆ MPTK_StopPlayOnLastNote

bool MidiPlayerTK.MidiFilePlayer.MPTK_StopPlayOnLastNote

By default, the end of a MIDI file is not the last note. It is the last MIDI event.
If this value is true, MIDI playback will stop at the last note found in the MIDI file
and the OnEventEndPlay will be triggered at the last note.

Note
  • Does not affect the value of MPTK_Duration, which remains the same.
  • If enabled, MIDI playback could stop before MPTK_Duration. See below how get this real duration.
  • Get MPTK_PositionLastNote for the duration at the last note.
    // Build string with MIDI duration.
    TimeSpan tsDuration;
    if (midiFilePlayer.MPTK_StopPlayOnLastNote)
    tsDuration = TimeSpan.FromMilliseconds(midiFilePlayer.midiLoaded.MPTK_PositionLastNote);
    else
    tsDuration = midiFilePlayer.MPTK_Duration;
    string sRealDuration = $"{tsDuration.Hours:00}:{tsDuration.Minutes:00}:{tsDuration.Seconds:00}:{tsDuration.Milliseconds:000}";

◆ MPTK_ModeStopVoice

ModeStopPlay MidiPlayerTK.MidiFilePlayer.MPTK_ModeStopVoice

Defined the behavior of the MIDI player when playback is stopped with MPTK_Stop or restarted when the last MIDI events is reached and MPTK_MidiAutoRestart is set to true.
Code example:

midiFilePlayer.MPTK_ModeStopVoice = MidiFilePlayer.ModeStopPlay.StopWhenAllVoicesReleased;
Plays a MIDI file from the MidiDB. This class must be used with the prefab MidiFilePlayer....
Definition MidiFilePlayer.cs:69
ModeStopPlay
Defined the behavior of the MIDI player when playback is stopped with MPTK_Stop or restarted when the...
Definition MidiFilePlayer.cs:211
Version
2.9.1
Note
  • The time at which OnEventEndPlayMidi is triggered is linked to this parameter.
  • No impact on MPTK_Duration, remains the same including the duration of the last note.

Properties

◆ MPTK_MidiAutoRestart

bool MidiPlayerTK.MidiFilePlayer.MPTK_MidiAutoRestart
getset

When the value is true, the current MIDI playing is restarted when it reaches the end of the MIDI file or #MPTK_MidiLoaded.MPTK_TickEnd.
.

Note
  • The MIDI file is not reloaded, the restart is quite immediate.
  • The restart is processed by the main Unity thread, also one Unity frame or more is needed to restart the playing of the MIDI.
  • #MPTK_MidiLoaded.MPTK_TickStart and #MPTK_MidiLoaded.MPTK_TickEnd are useful to defined start and end playing position.
  • Better looping accuracy can be done with MPTK_InnerLoop (pro).
  • MPTK_ModeStopVoice must be consider to define more precisely when the MIDI will be restarted.