MidiPlayerTK.MidiSynth

More...

Inheritance diagram for MidiPlayerTK.MidiSynth:
MidiPlayerTK.MidiFilePlayer MidiPlayerTK.MidiFilePlayer MidiPlayerTK.MidiInReader MidiPlayerTK.MidiStreamPlayer MidiPlayerTK.MidiStreamPlayer MidiPlayerTK.MidiExternalPlayer MidiPlayerTK.MidiSpatializer MidiPlayerTK.MidiExternalPlayer MidiPlayerTK.MidiSpatializer

Spatializer Midi Player

enum  ModeSpatializer { Channel , Track }
 
ModeSpatializer MPTK_ModeSpatializer
 
int MPTK_MaxSpatialSynth
 
bool MPTK_SpatialSynthEnabled
 
int MPTK_InstrumentNum
 
int MPTK_SpatialSynthIndex [get]
 
bool MPTK_IsSpatialSynthMaster [get]
 
string MPTK_InstrumentPlayed [get]
 
string MPTK_TrackName [get]
 
static List< MidiFilePlayerSpatialSynths
 
string instrumentPlayed
 

SoundFont

MPTKSoundFont MPTK_SoundFont = null
 

Synthesizer Settings

bool MPTK_EnablePresetDrum
 
bool MPTK_ReleaseSameNote = true
 
bool MPTK_KillByExclusiveClass = true
 
float MPTK_ReleaseTimeMod = 1f
 
float MPTK_CutOffVolume = 0.0001f
 
float MPTK_LeanSynthStarting = 0.05f
 
bool MPTK_ApplyRealTimeModulator
 
bool MPTK_ApplyModLfo
 
bool MPTK_ApplyVibLfo
 
bool MPTK_DirectSendToPlayer
 
bool MPTK_EnableChangeTempo
 
bool MPTK_EnablePanChange
 
bool MPTK_WeakDevice
 
uint MPTK_ReleaseTimeMin = 500000
 
bool MPTK_KeepPlayingNonLooped [get, set]
 
float MPTK_VelocityAttenuation [get, set]
 
float MPTK_Volume [get, set]
 
int MPTK_Transpose [get, set]
 
int MPTK_TransExcludedChannel [get, set]
 
bool MPTK_Dsp64 [get, set]
 
void MPTK_InitSynth (int channelCount=16, bool preserveChannelInfo=false, bool preserveActivVoice=true)
 
void MPTK_InitModulators ()
 
void MPTK_ClearAllSound (bool destroyAudioSource=false, int _idSession=-1)
 

Spatialization

float MPTK_OrientationToListener
 
bool MPTK_PauseOnMaxDistance = true
 
bool MPTK_Orientation [get, set]
 
bool MPTK_DistanceAttenuation [get, set]
 
float MPTK_MinDistance [get, set]
 
float MPTK_MaxDistance [get, set]
 
float MPTK_MinSoundAttenuation [get, set]
 

Synthesizer Performance

int MPTK_ThreadMidiWait = 10
 
bool MPTK_AutoBuffer = true
 
int MPTK_AutoCleanVoiceLimit
 
float MPTK_AutoCleanVoiceTime
 
int MPTK_ThreadMidiPriority [get, set]
 

Effects

MPTKEffectSoundFont MPTK_EffectSoundFont
 
MPTKEffectUnity MPTK_EffectUnity
 Unlike SoundFont effects, they are applied to the whole player. On the other hand, Unity effect parameters are richer and are obviously based on Unity algorithms!
https://docs.unity3d.com/Manual/class-AudioEffectMixer.html
Only the most important effects are integrated in Maestro: Reverb and Chorus. If needed, other effects could be added. More...
 

Audio Settings

bool MPTK_AudioSettingFromUnity
 
bool MPTK_EnableFreeSynthRate = false
 
bool MPTK_CorePlayer [get, set]
 
int MPTK_SynthRate [get, set]
 
int MPTK_IndexSynthRate [get, set]
 
int MPTK_IndexSynthBuffSize [get, set]
 

Log & Debug

bool MPTK_LogEvents
 
bool MPTK_LogWave
 
void MPTK_DebugActiveVoice ()
 
void MPTK_DebugFreeVoice ()
 

Voice Statistics

int MPTK_StatVoiceCountPlaying
 
int MPTK_StatVoiceCountActive
 
int MPTK_StatVoiceCountReused
 
int MPTK_StatVoiceCountFree
 
int MPTK_StatVoiceRatioReused
 
int MPTK_StatVoicePlayed
 
int MPTK_StatVoiceCountSustained [get]
 
void MPTK_ResetStat ()
 

Synthesizer Events

EventSynthClass OnEventSynthAwake
 
EventSynthClass OnEventSynthStarted
 
Func< MPTKEvent, bool > OnMidiEvent
 
Action< int, long, int, int > OnBeatEvent
 
OnAudioFrameStartHandler OnAudioFrameStart
 
delegate void OnAudioFrameStartHandler (double synthTime)
 

Start Stop and Wait

void MPTK_StartSequencerMidi ()
 
void MPTK_StartSynth ()
 
void MPTK_StopSynth ()
 
IEnumerator MPTK_WaitAllNotesOff (int _idSession=-1)
 

MIDI Direct Play

void MPTK_PlayDirectEvent (MPTKEvent midiEvent, bool playNoteOff=true)
 
void MPTK_StopDirectEvent (MPTKEvent midiEvent)
 

Pause and resume Voices

void MPTK_PauseVoices (float transitionDuration=30f)
 
void MPTK_ResumeVoices (float transitionDuration=30f)
 

Detailed Description

Base class which contains all the stuff to build a Wave Table Synth.

Core WaveTable MIDI synthesizer (base class).

Loads a SoundFont and its samples, processes incoming MIDI events, and renders voices (controllers, generators, etc.). This class is the common base used by the MPTK prefabs: MidiStreamPlayer, MidiFilePlayer, and MidiInReader.

Do not instantiate MidiSynth directly. Instead, add one of the MPTK prefabs to your scene and access its properties and methods from your scripts.

Examples:

midiFilePlayer.MPTK_ChorusDelay = 0.2f;
midiStreamPlayer.MPTK_InitSynth();

Loads SoundFont and samples, process midi event, play voices, controllers, generators ...
This class is inherited by others class to build these prefabs: MidiStreamPlayer, MidiFilePlayer, MidiInReader.
It is not recommended to instanciate directly this class, rather add prefabs to the hierarchy of your scene. and use attributes and methods from an instance of them in your script. Example:

  • midiFilePlayer.MPTK_ChorusDelay = 0.2
  • midiStreamPlayer.MPTK_InitSynth()

Maestro MPTK Pro extension for MidiSynth.

Version
Maestro Pro

Member Enumeration Documentation

◆ ModeSpatializer

Spatializer mode for the MidiSpatializer prefab.

Version
Maestro Pro
Enumerator
Channel 

Spatial synths are enabled to dispatch note-on messages by channel.
As a reminder, only one instrument at a time can be played by a MIDI channel.
Instruments (presets) are defined per channel with the MIDI message MPTKCommand.PatchChange.

Track 

Spatial synths are enabled to dispatch note-on messages by tracks defined in the MIDI.
As a reminder, multiple channels can be played on a track, so multiple instruments can be played on a synth.
Track names are defined with the Meta MIDI message SequenceTrackName. This MIDI message is not always defined in a MIDI file, so the name can be missing.

Member Function Documentation

◆ MPTK_ClearAllSound()

void MidiPlayerTK.MidiSynth.MPTK_ClearAllSound ( bool  destroyAudioSource = false,
int  _idSession = -1 
)

Clear all sound by sending note off. That could take some seconds because release time for sample need to be played.

if (GUILayout.Button("Clear"))
midiStreamPlayer.MPTK_ClearAllSound(true);
Parameters
destroyAudioSourceuseful only in non core mode
_idSessionclear only for sample playing with this session, -1 for all (default)

◆ MPTK_DebugActiveVoice()

void MidiPlayerTK.MidiSynth.MPTK_DebugActiveVoice ( )

Log information about active voices

◆ MPTK_DebugFreeVoice()

void MidiPlayerTK.MidiSynth.MPTK_DebugFreeVoice ( )

Log information about free voices

◆ MPTK_InitModulators()

void MidiPlayerTK.MidiSynth.MPTK_InitModulators ( )

Accept preset changes for Drum Channel 9 (drum). If set, this may sometimes produce unexpected results with MIDI files that are not compliant with the MIDI standard. If not set, preset change on channel 9 will be disabled (preset 0 still used).

Note
:
  • Generally bank 128 and preset 0 is used for drum kit. @Attention:
  • Set to false in MidiFilePlayer.
  • Set to true in MidiStreamPlayer (all MIDI events are generated by your script, so you are aware of what is happening).

◆ MPTK_InitSynth()

void MidiPlayerTK.MidiSynth.MPTK_InitSynth ( int  channelCount = 16,
bool  preserveChannelInfo = false,
bool  preserveActivVoice = true 
)

Initialize the synthesizer:

  • channels information: instrument & bank selected, pitch, volume, ...
  • voices cache,
  • synth modulator. This method is call by MidiFilePlayer with MPTK_Play() But in some cases, you could have to call MPTK_InitSynth to restore initial condition of the synth (mainly useful with MidiStreamPlayer)
Parameters
channelCountNumber of channel to create. Default is 16. Any other values are experimental!
preserveChannelInfoif true, the channel information will not be reset, Default is false: reinit also channel information

◆ MPTK_PauseVoices()

void MidiPlayerTK.MidiSynth.MPTK_PauseVoices ( float  transitionDuration = 30f)

Pauses all active voices using the specified transition duration.

Note
  • Iterates over all active voices and pauses them with the given transition duration.
See also
MPTK_ResumeVoices Example with the MidiStreamPlayer prefab:
midiStreamPlayer.MPTK_PauseVoices(100);
Version
2.17.0 Pro

◆ MPTK_PlayDirectEvent()

void MidiPlayerTK.MidiSynth.MPTK_PlayDirectEvent ( MPTKEvent  midiEvent,
bool  playNoteOff = true 
)

Plays immediately one MIDI event. It's a synchrone processing: method return after the MIDI has been treated by the MIDI synth.

// OnBeatEvent (pro) is triggered by the MPTK MIDI sequencer at each beat independently of MIDI events
// - OnBeatEvent is executed at each beat even if there is there no MIDI event on the beat.
// - Accuracy is guaranteed (internal thread).
// - Direct call to Unity API is not possible (but you have access to all your script variables and most part of the MPTK API).
// Parameters received:
// - time Time in milliseconds since the start of the playing MIDI.
// - tick Current tick of the beat.
// - measure Current measure (start from 1).
// - beat Current beat (start from 1).
midiFilePlayer.OnBeatEvent = (int time, long tick, int measure, int beat) =>
{
if (FoldOutMetronome)
{
// Calculate the value to be displayed on the FoldOut Metronome and on the log
beatTimeTick = $"Time: {TimeSpan.FromMilliseconds(time)} Tick: {tick}";
beatMeasure = $"Beat/Measure: {beat}/{measure}";
Debug.Log($"OnBeatEvent - {beatTimeTick} Signature segment:{midiFilePlayer.MPTK_MidiLoaded.MPTK_CurrentSignMap.Index} {beatMeasure}");
// for testing interaction with Maestro MPTK player
if (stopPlayingAtMeasure != -1 && measure >= stopPlayingAtMeasure)
// Stops playback of the MIDI file. But the triggering event could be still playing (too late for stop it).
midiFilePlayer.MPTK_Stop(false);
// Plays an extra drum sound with each beat
midiFilePlayer.MPTK_PlayDirectEvent(new MPTKEvent()
{
Command = MPTKCommand.NoteOn,
Channel = 9,
Value = instrumentMetronome,
Velocity = volumeMetronome,
Measure = measure,
Beat = beat
});
}
};
Description of a MIDI Event. It's the heart of MPTK! Essential to handling MIDI by script from all ot...
Definition: MPTKEvent.cs:45
MPTKCommand
Definition: MPTKEnum.cs:12
Parameters
midiEvent

◆ MPTK_ResetStat()

void MidiPlayerTK.MidiSynth.MPTK_ResetStat ( )

Reset voices statistics

◆ MPTK_ResumeVoices()

void MidiPlayerTK.MidiSynth.MPTK_ResumeVoices ( float  transitionDuration = 30f)

Resumes all active voices using the specified transition duration.

Note
  • Iterates over all active voices and resumes them with the given transition duration.
See also
MPTK_PauseVoices Example with the MidiStreamPlayer prefab:
midiStreamPlayer.MPTK_ResumeVoices(100);
Version
2.17.0 Pro

◆ MPTK_StartSequencerMidi()

void MidiPlayerTK.MidiSynth.MPTK_StartSequencerMidi ( )

Start the MIDI sequencer: each MIDI event is read and played in a dedicated thread. This thread is automatically started by prefabs MidiFilePlayer, MidiListPlayer, MidiExternalPlayer.

Note
: available only in MPTK_CorePlayer mode. No effect in Legacy mode

◆ MPTK_StartSynth()

void MidiPlayerTK.MidiSynth.MPTK_StartSynth ( )

Start processing samples by the synth and the MIDI sequencer. Useful only if MPTK_StopSynth has been called and MidiStreamPlayer.

Version
2.11.2

◆ MPTK_StopDirectEvent()

void MidiPlayerTK.MidiSynth.MPTK_StopDirectEvent ( MPTKEvent  midiEvent)

Stops immediately the MIDI event play with @MPTK_PlayDirectEvent. It's a synchrone processing: method return after all voices of the notes has been processed by the MIDI synth.

Parameters
midiEvent

◆ MPTK_StopSynth()

void MidiPlayerTK.MidiSynth.MPTK_StopSynth ( )

Stops processing samples by the synth and the MIDI sequencer. See also MPTK_StartSynth.

◆ MPTK_WaitAllNotesOff()

IEnumerator MidiPlayerTK.MidiSynth.MPTK_WaitAllNotesOff ( int  _idSession = -1)

Wait until all notes are off. That could take some seconds due to the samples release time. Therefore, the method exit after a timeout of 3 seconds. *** Use this method only as a coroutine ***

// Call this method with: StartCoroutine(NextPreviousWithWait(false));
// See TestMidiFilePlayerScripting.cs
public IEnumerator NextPreviousWithWait(bool next)
{
midiFilePlayer.MPTK_Stop();
yield return midiFilePlayer.MPTK_WaitAllNotesOff(midiFilePlayer.IdSession);
if (next)
midiFilePlayer.MPTK_Next();
else
midiFilePlayer.MPTK_Previous();
CurrentIndexPlaying = midiFilePlayer.MPTK_MidiIndex;
yield return 0;
}
Parameters
_idSessionclear only for samples playing with this session, -1 for all
Returns

◆ OnAudioFrameStartHandler()

delegate void MidiPlayerTK.MidiSynth.OnAudioFrameStartHandler ( double  synthTime)

Delegate for the OnAudioFrameStart event.

Version
Maestro Pro

Member Data Documentation

◆ instrumentPlayed

string MidiPlayerTK.MidiSynth.instrumentPlayed
protected

Spatializer mode for the MidiSpatializer prefab.

Version
Maestro Pro

◆ MPTK_ApplyModLfo

bool MidiPlayerTK.MidiSynth.MPTK_ApplyModLfo

Apply LFO effect defined in the SoundFont

◆ MPTK_ApplyRealTimeModulator

bool MidiPlayerTK.MidiSynth.MPTK_ApplyRealTimeModulator

Apply real time modulator effects defined in the SoundFont: pitch bend, control change, envelope modulation

◆ MPTK_ApplyVibLfo

bool MidiPlayerTK.MidiSynth.MPTK_ApplyVibLfo

Apply vibrato effect defined in the SoundFont

◆ MPTK_AudioSettingFromUnity

bool MidiPlayerTK.MidiSynth.MPTK_AudioSettingFromUnity

Allow direct setting of the Synth Rate

◆ MPTK_AutoBuffer

bool MidiPlayerTK.MidiSynth.MPTK_AutoBuffer = true

Enable voice buffering to improve runtime performance.

When enabled:

When disabled, voices whose state becomes OFF are removed directly from the Active list.

◆ MPTK_AutoCleanVoiceLimit

int MidiPlayerTK.MidiSynth.MPTK_AutoCleanVoiceLimit

Free voices older than MPTK_AutoCleanVoiceLimit are removed when count is over than MPTK_AutoCleanVoiceTime

◆ MPTK_AutoCleanVoiceTime

float MidiPlayerTK.MidiSynth.MPTK_AutoCleanVoiceTime

Delay (in milliseconds) that the MIDI sequencing thread waits between processing MIDI event batches.

◆ MPTK_CutOffVolume

float MidiPlayerTK.MidiSynth.MPTK_CutOffVolume = 0.0001f

When amplitude of a sample is below this value the playing of sample is stopped. Can be increase for better performance (when a lot of samples are played concurrently) but with degraded quality because sample could be stopped too early. Remember: Amplitude can varying between 0 and 1.

Version
2.9.1 // was 0.03

◆ MPTK_DirectSendToPlayer

bool MidiPlayerTK.MidiSynth.MPTK_DirectSendToPlayer

If true (default) then MIDI events are sent automatically to the MIDI player. Sets to false if you want to process events without playing sound. OnEventNotesMidi Unity Event can be used to process each note.

◆ MPTK_EffectSoundFont

MPTKEffectSoundFont MidiPlayerTK.MidiSynth.MPTK_EffectSoundFont

A SoundFont contains parameters to apply three kinds of effects: low-pass filter, reverb, chorus. These parameters can be specifics for each instruments and even each voices. Maestro MPTK effects are based on FluidSynth algo effects modules. Furthermore, to get more liberty from SoundFont, Maestro Pro can increase or decrease the impact of effects (from the inspector or by script). To summarize:

  • Effects are applied individually to each voices, yet they are statically defined within the SoundFont.
  • Maestro parameters can be adjusted to increase or decrease the default values set in the SoundFont.
  • These adjustments will be applied across the entire prefab, but the effect will depend on the initial settings defined in the SoundFont preset.
  • Please note that these effects require additional CPU resources. See more detailed information here https://paxstellar.fr/sound-effects/
    Note
  • By default, only low-filter effect is enabled in Maestro.
  • To enable them, you�ll need to adjust the settings from the prefab inspector (Synth Parameters / SoundFont Effect) or by script!
  • For enhanced sound quality, it�s beneficial to add a low-filter effect, it is enabled by default..
    // Find a MPTK Prefab, will work also for MidiStreamPlayer, MidiExternalPlayer ... all classes which inherit from MidiSynth.
    MidiFilePlayer fp = FindFirstObjectByType<MidiFilePlayer>();
    fp.MPTK_EffectSoundFont.EnableFilter = true;
    fp.MPTK_EffectSoundFont.FilterFreqOffset = 500;
    Plays a MIDI file from the MidiDB. This class must be used with the prefab MidiFilePlayer....
    Definition: MidiFilePlayer.cs:68

◆ MPTK_EffectUnity

MPTKEffectUnity MidiPlayerTK.MidiSynth.MPTK_EffectUnity

Unlike SoundFont effects, they are applied to the whole player. On the other hand, Unity effect parameters are richer and are obviously based on Unity algorithms!
https://docs.unity3d.com/Manual/class-AudioEffectMixer.html
Only the most important effects are integrated in Maestro: Reverb and Chorus. If needed, other effects could be added.

Note
  • Unity effects integration modules are exclusively available with the Maestro MPTK Pro version.
  • By default, these effects are disabled in Maestro.
  • To enable them, you’ll need to adjust the settings from the prefab inspector: Synth Parameters / Unity Effect.
  • Each setting is available by script.
Version
Maestro Pro
// Find an MPTK prefab; this will also work for MidiStreamPlayer, MidiExternalPlayer, and all classes that inherit from MidiSynth.
MidiFilePlayer fp = FindFirstObjectByType<MidiFilePlayer>();
fp.MPTK_EffectUnity.EnableReverb = true;
float ReverbDelay
Definition: MPTKEffectUnityPro.cs:231
MPTKEffectUnity MPTK_EffectUnity
Unlike SoundFont effects, they are applied to the whole player. On the other hand,...
Definition: MidiSynthPro.cs:420

◆ MPTK_EnableChangeTempo

bool MidiPlayerTK.MidiSynth.MPTK_EnableChangeTempo

Enable MIDI events tempo change from the MIDI file when playing. If disabled, only the first tempo change found in the MIDI will be applied (or 120 if not tempo change). Disable it when you want to change tempo by your script.

◆ MPTK_EnableFreeSynthRate

bool MidiPlayerTK.MidiSynth.MPTK_EnableFreeSynthRate = false

Allow direct setting of the Synth Rate

◆ MPTK_EnablePanChange

bool MidiPlayerTK.MidiSynth.MPTK_EnablePanChange

Change pan from MIDI Events in the SoundFont. Pan is disabled when Spatialization is activated.

◆ MPTK_EnablePresetDrum

bool MidiPlayerTK.MidiSynth.MPTK_EnablePresetDrum

Accept preset changes for Drum Channel 9 (drum). If set, this may sometimes produce unexpected results with MIDI files that are not compliant with the MIDI standard. If not set, preset change on channel 9 will be disabled (preset 0 still used).

Note
:
  • Generally bank 128 and preset 0 is used for drum kit. @Attention:
  • Set to false in MidiFilePlayer.
  • Set to true in MidiStreamPlayer (all MIDI events are generated by your script, so you are aware of what is happening).

◆ MPTK_InstrumentNum

int MidiPlayerTK.MidiSynth.MPTK_InstrumentNum

When spatialization is track mode, contains the last instrument (preset) played.

Version
Maestro Pro

◆ MPTK_KillByExclusiveClass

bool MidiPlayerTK.MidiSynth.MPTK_KillByExclusiveClass = true

Find the exclusive class of this voice. If set, kill all voices that match the exclusive class and are younger than the first voice process created by this note-on event.

◆ MPTK_LeanSynthStarting

float MidiPlayerTK.MidiSynth.MPTK_LeanSynthStarting = 0.05f

A lean startup of the volume of the synth is useful to avoid weird sound at the beginning of the application (in some cases). This parameter sets the speed of the increase of the volume of the audio source. Sets to 1 for an immediate full volume at start.

◆ MPTK_LogEvents

bool MidiPlayerTK.MidiSynth.MPTK_LogEvents

Log MIDI events (v2.9.0 moved from MidiFilePlayer)

◆ MPTK_LogWave

bool MidiPlayerTK.MidiSynth.MPTK_LogWave

Log for each sample to be played

◆ MPTK_MaxSpatialSynth

int MidiPlayerTK.MidiSynth.MPTK_MaxSpatialSynth

Gets or sets the maximum number of spatial synthesizers that can be used.

Version
Maestro Pro

◆ MPTK_ModeSpatializer

ModeSpatializer MidiPlayerTK.MidiSynth.MPTK_ModeSpatializer

Spatializer mode for the MidiSpatializer prefab.

Version
Maestro Pro

◆ MPTK_OrientationToListener

float MidiPlayerTK.MidiSynth.MPTK_OrientationToListener

Return the angle in degree between the sound source and the listener. 0� = in front +90� = right -90� = left �180� = behind

Note
:
  • Convert to 360 angle with MPTK_OrientatioToListener < 0f ? MPTK_OrientatioToListener + 360f : MPTK_OrientatioToListener;
  • When the source is exactly behind the listener, floating-point precision may cause the signed angle to be either +180� or -180�. After remapping to [0..360[, both cases consistently yield 180�.
Version
2.18.0 Pro

◆ MPTK_PauseOnMaxDistance

bool MidiPlayerTK.MidiSynth.MPTK_PauseOnMaxDistance = true

If true, the MIDI player will be automatically paused when the distance from the listener exceeds MPTK_MaxDistance.

Version
2.16.1

◆ MPTK_ReleaseSameNote

bool MidiPlayerTK.MidiSynth.MPTK_ReleaseSameNote = true

If the same note is hit twice on the same channel, then the older voice process is advanced to the release stage. It's the default Midi processing.

◆ MPTK_ReleaseTimeMin

uint MidiPlayerTK.MidiSynth.MPTK_ReleaseTimeMin = 500000

[Only when CorePlayer=False] Define a minimum release time at note-off in 100 nanosecond units. Default 50 ms is a good tradeoff. Below some unpleasant sound could be heard. Useless when MPTK_CorePlayer is true.

◆ MPTK_ReleaseTimeMod

float MidiPlayerTK.MidiSynth.MPTK_ReleaseTimeMod = 1f

When a note is stopped with a note-off or when the duration is over, note continue to play for a short time depending the instrument. This parameter is a multiplier to increase or decrease the default release time defined in the SoundFont for each instrument. Recommended values between 0.1 and 10. Default is 1 (no modification of the release time). Performance issue: the longer it lasts the more CPU is used after the note-on. With a long release time, a lot of samples will be played simultaneously.

◆ MPTK_SoundFont

MPTKSoundFont MidiPlayerTK.MidiSynth.MPTK_SoundFont = null

When your application is running, SoundFonts can be dynamically loaded either from a local file system or directly from the web. This means you don't need to include a SoundFont in your build, making it ideal for scenarios like in-app purchases or downloadable content. For compatibility, the legacy mode still allows loading SoundFonts from the internal MPTK database. Additionally, Maestro MPTK supports assigning different SoundFonts to different MIDI players (MidiFilePlayer, MidiStreamPlayer, ...), enabling flexible and customized audio rendering across multiple instruments or scenes.

Version
2.15 An instance of this class is automatically created when the MPTK prefab is loaded in the scene. See MPTKSoundFont class for more details.
Note

◆ MPTK_SpatialSynthEnabled

bool MidiPlayerTK.MidiSynth.MPTK_SpatialSynthEnabled

In spatialization mode, not all MidiSynths are enabled.

Version
Maestro Pro

◆ MPTK_StatVoiceCountActive

int MidiPlayerTK.MidiSynth.MPTK_StatVoiceCountActive

Count of the active voices (playing and releasing) - Readonly

◆ MPTK_StatVoiceCountFree

int MidiPlayerTK.MidiSynth.MPTK_StatVoiceCountFree

Count of the free voices for reusing on need. Voice older than AutoCleanVoiceTime are removed but only when count is over than AutoCleanVoiceLimit - Readonly

◆ MPTK_StatVoiceCountPlaying

int MidiPlayerTK.MidiSynth.MPTK_StatVoiceCountPlaying

Count of the active voices (playing excluding voices in release step). Also, sound could be ear even if count = 0 from voices in release phase - Readonly

◆ MPTK_StatVoiceCountReused

int MidiPlayerTK.MidiSynth.MPTK_StatVoiceCountReused

Count of the voices reused - Readonly

◆ MPTK_StatVoicePlayed

int MidiPlayerTK.MidiSynth.MPTK_StatVoicePlayed

Count of voice played since the start of the synth

◆ MPTK_StatVoiceRatioReused

int MidiPlayerTK.MidiSynth.MPTK_StatVoiceRatioReused

Percentage of voice reused during the synth life. 0: any reuse, 100:all voice reused (unattainable, of course!)

◆ MPTK_ThreadMidiWait

int MidiPlayerTK.MidiSynth.MPTK_ThreadMidiWait = 10

Delay (in milliseconds) that the MIDI sequencing thread waits between processing MIDI event batches.

◆ MPTK_WeakDevice

bool MidiPlayerTK.MidiSynth.MPTK_WeakDevice

Should play on a weak device (cheaper smartphone) ? Apply only with AudioSource mode (MPTK_CorePlayer=False). Playing MIDI files with WeakDevice activated could cause some bad interpretation of MIDI Event, consequently bad sound.

◆ OnBeatEvent

Action<int, long, int, int> MidiPlayerTK.MidiSynth.OnBeatEvent

Invoked on each beat with the following parameters:

  • time: time in milliseconds since MIDI playback started.
  • tick: current tick.
  • measure: current measure (starts at 1).
  • beat: current beat (starts at 1).
    Note
  • OnBeatEvent is invoked on every beat, even if there is no MIDI event exactly on that beat.
  • Timing accuracy is guaranteed (runs on an internal thread).
  • Direct calls to the Unity API are not allowed, but Debug.Log and Maestro APIs (for example, playing a sound on each beat) are allowed.
    Version
    Maestro Pro
    // OnBeatEvent (pro) is triggered by the MPTK MIDI sequencer at each beat independently of MIDI events
    // - OnBeatEvent is executed at each beat even if there is there no MIDI event on the beat.
    // - Accuracy is guaranteed (internal thread).
    // - Direct call to Unity API is not possible (but you have access to all your script variables and most part of the MPTK API).
    // Parameters received:
    // - time Time in milliseconds since the start of the playing MIDI.
    // - tick Current tick of the beat.
    // - measure Current measure (start from 1).
    // - beat Current beat (start from 1).
    midiFilePlayer.OnBeatEvent = (int time, long tick, int measure, int beat) =>
    {
    if (FoldOutMetronome)
    {
    // Calculate the value to be displayed on the FoldOut Metronome and on the log
    beatTimeTick = $"Time: {TimeSpan.FromMilliseconds(time)} Tick: {tick}";
    beatMeasure = $"Beat/Measure: {beat}/{measure}";
    Debug.Log($"OnBeatEvent - {beatTimeTick} Signature segment:{midiFilePlayer.MPTK_MidiLoaded.MPTK_CurrentSignMap.Index} {beatMeasure}");
    // for testing interaction with Maestro MPTK player
    if (stopPlayingAtMeasure != -1 && measure >= stopPlayingAtMeasure)
    // Stops playback of the MIDI file. But the triggering event could be still playing (too late for stop it).
    midiFilePlayer.MPTK_Stop(false);
    // Plays an extra drum sound with each beat
    midiFilePlayer.MPTK_PlayDirectEvent(new MPTKEvent()
    {
    Command = MPTKCommand.NoteOn,
    Channel = 9,
    Value = instrumentMetronome,
    Velocity = volumeMetronome,
    Measure = measure,
    Beat = beat
    });
    }
    };

◆ OnEventSynthAwake

EventSynthClass MidiPlayerTK.MidiSynth.OnEventSynthAwake

Unity event fired at awake of the synthesizer. Name of the gameobject component is passed as a parameter. Setting this callback function by script (AddListener) is not recommended. It's better to set callback function from the inspector.

Example of script (but it's recommended to set callback function from the inspector).

...
midiStreamPlayer.OnEventSynthAwake.AddListener(StartLoadingSynth);
...
public void StartLoadingSynth(string name)
{
Debug.LogFormat("Synth {0} loading", name);
}

◆ OnEventSynthStarted

EventSynthClass MidiPlayerTK.MidiSynth.OnEventSynthStarted

Unity event fired at start of the synthesizer. Name of the gameobject component is passed as a parameter. Setting this callback function by script (AddListener) is not recommended. It's better to set callback function from the inspector.

Example of script (it's recommended to set callback function from the inspector).

public void EndLoadingSynth(string name)
{
Debug.Log($"EndLoadingSynth - Synth {name} loaded, now change bank and preset");
if (MAX_CHANNEL != 16)
// MIDI standard is limited to 16 channels.
// With MidiStream it's possible to extend channels number until 256.
// Warning: it's not possible to create MIDI file with channels number over 16.
midiStreamPlayer.MPTK_InitSynth(MAX_CHANNEL);
// Mandatory for updating UI list but not for playing sample.
// The default instrument and drum banks are defined with the popup "SoundFont Setup Alt-F" in the Unity editor.
// This method can be used by script to change the instrument bank and build presets available for it: MPTK_ListPreset.
midiStreamPlayer.MPTK_SoundFont.SelectBankInstrument(CurrentBank);
// Don't forget to initialize your MidiStreamPlayer variable, see link below:
// https://paxstellar.fr/api-mptk-v2/#DefinedVariablePrefab
// Channel 0: set Piano (if SoundFont is GeneralUser GS v1.471)
// Define bank with CurrentBank (value defined in inspector to 0).
midiStreamPlayer.MPTK_PlayEvent(new MPTKEvent() { Command = MPTKCommand.ControlChange, Controller = MPTKController.BankSelectMsb, Value = CurrentBank, Channel = StreamChannel, });
Debug.LogFormat($" Bank '{CurrentBank}' defined on channel {StreamChannel}");
// Defined preset with CurrentPreset (value defined in inspector to 0).
midiStreamPlayer.MPTK_Channels[StreamChannel].PresetNum = CurrentPreset;
Debug.LogFormat($" Preset '{midiStreamPlayer.MPTK_Channels[StreamChannel].PresetName}' defined on channel {StreamChannel}");
// Playing a preset from another bank in the channel 1
// Channel 1: set Laser Gun (if SoundFont is GeneralUser GS v1.471)
// TBD int channel = 1, bank = 2, preset = 127;
//midiStreamPlayer.MPTK_PlayEvent(new MPTKEvent() { Command = MPTKCommand.ControlChange, Controller = MPTKController.BankSelectMsb, Value = bank, Channel = channel, });
//midiStreamPlayer.MPTK_ChannelPresetChange(channel, preset);
// Before v2.10.1 Debug.LogFormat($" Preset '{MidiPlayerGlobal.MPTK_GetPatchName(bank, preset)}' defined on channel {channel} and bank {bank}");
}
MPTKController
Definition: MPTKEnum.cs:131

◆ OnMidiEvent

Func<MPTKEvent, bool> MidiPlayerTK.MidiSynth.OnMidiEvent

This function is called by the MIDI sequencer before sending the MIDI message to the MIDI synthesizer.
From version 2.10.0, the callback must return a boolean (see example): true to keep the event, false to skip it.

It can be used as a MIDI event preprocessor: it is possible to change the values of MIDI events and therefore change song playback.
The callback function receives an MPTKEvent object by reference (which is normal because it is a C# class).
See https://mptkapi.paxstellar.com/d9/d50/class_midi_player_t_k_1_1_m_p_t_k_event.html
Many changes are possible on the MIDI event: change note, velocity, channel, skip ..., even changing the MIDI type of the message!!!
See below for some examples of run-time changes.

Version
Maestro Pro
Note
  • The callback runs on a system thread, not on the Unity main thread. Unity API calls are not allowed, except Debug.Log (use sparingly as it consumes CPU).
  • Avoid heavy processing or waiting inside the callback, otherwise timing accuracy will degrade.
  • The midiEvent is passed by reference (it is a C# class). Re-instantiating it (midiEvent = new MPTKEvent()) or setting it to null has no effect.
  • MIDI position attributes (Tick and RealTime) can be used in your algorithm, but changing their values has no effect.
  • Changing a SetTempo event is too late for the MIDI sequencer (it has already been processed). Use midiFilePlayer.CurrentTempo to change the tempo at runtime.
Examples:
// See TestMidiFilePlayerScripting.cs for the demo.
void Start()
{
MidiFilePlayer midiFilePlayer = FindFirstObjectByType<MidiFilePlayer>();
midiFilePlayer.OnMidiEvent = PreProcessMidi;
}
// Example
bool PreProcessMidi(MPTKEvent midiEvent)
{
bool playEvent=true;
switch (midiEvent.Command)
{
case MPTKCommand.NoteOn:
if (midiEvent.Channel != 9)
// transpose 2 octaves
midiEvent.Value += 24;
else
// Drums are muted
playEvent= false;
break;
case MPTKCommand.PatchChange:
// Remove all patch changes: all channels will play the default preset 0!!!
midiEvent.Command = MPTKCommand.MetaEvent;
midiEvent.Meta = MPTKMeta.TextEvent;
midiEvent.Info = "Patch Change removed";
break;
case MPTKCommand.MetaEvent:
if (midiEvent.Meta == MPTKMeta.SetTempo)
// Tempo forced to 100
midiFilePlayer.CurrentTempo = 100
break;
}
// true: plays this event, false to skip
return playEvent;
}
MPTKMeta Meta
Definition: MPTKEvent.cs:111
MPTKCommand Command
Definition: MPTKEvent.cs:99
int Channel
Definition: MPTKEvent.cs:182
MPTKMeta
Definition: MPTKEnum.cs:321

◆ SpatialSynths

List<MidiFilePlayer> MidiPlayerTK.MidiSynth.SpatialSynths
static

Contains each Midi Synth for each channel or track when the prefab MidiSpatializer is used and IsMidiChannelSpace=true. Warning: only one MidiSpatializer can be used in a hierarchy.

Property Documentation

◆ MPTK_CorePlayer

bool MidiPlayerTK.MidiSynth.MPTK_CorePlayer
getset

If true then rate synth and buffer size will be automatically defined by Unity in accordance of the capacity of the hardware. - V2.89.0 - Look at Unity menu "Edit / Project Settings..." and select between best latency and best performance. If false, then rate and buffer size can be defined manually ... but with the risk of bad audio quality. It's more an experimental capacities!

If true then MIDI events are read and playededed from a dedicated thread. If false, MidiSynth will use AudioSource gameobjects to play sound. This properties must be defined before running the application from the inspector. The default is true. Warning: The non core mode player (MPTK_CorePlayer=false) will be removed with the next major version (V3)

◆ MPTK_DistanceAttenuation

bool MidiPlayerTK.MidiSynth.MPTK_DistanceAttenuation
getset

Should the Unity attenuation on distance effect must be enabled?
See here how to setup attenuation with Unity https://paxstellar.fr/midi-file-player-detailed-view-2/#Foldout-Spatialization-Parameters if MPTK_DistanceAttenuation is true:
AudioSource.minDistance = MPTK_MinDistance; AudioSource.maxDistance = MPTK_MaxDistance
AudioSource.spatialBlend = 1
AudioSource.spatialize = true
AudioSource.spatializePostEffects = true
AudioSource.rolloffMode = AudioRolloffMode.Custom; AudioSource.SetCustomCurve(AudioSourceCurveType.CustomRolloff, customCurveAudioSource); AudioSource.loop = true; AudioSource.volume = 1f;

Note
:
  • MPTK_Spatilize has been renamed to MPTK_DistanceAttenuation in v2.18.0.
  • To be used also with MPTK_Orientation (Pro) to apply panning and filtering effects depending on the position of the sound source and the listener.

◆ MPTK_Dsp64

bool MidiPlayerTK.MidiSynth.MPTK_Dsp64
getset

Accept preset changes for Drum Channel 9 (drum). If set, this may sometimes produce unexpected results with MIDI files that are not compliant with the MIDI standard. If not set, preset change on channel 9 will be disabled (preset 0 still used).

Note
:
  • Generally bank 128 and preset 0 is used for drum kit. @Attention:
  • Set to false in MidiFilePlayer.
  • Set to true in MidiStreamPlayer (all MIDI events are generated by your script, so you are aware of what is happening).

◆ MPTK_IndexSynthBuffSize

int MidiPlayerTK.MidiSynth.MPTK_IndexSynthBuffSize
getset

Sets or Get synth buffer size -1:default, 0:64, 1;128, 2:256, 3:512, 4:1024, 5:2048. The change is global for all prefab. It's better to stop playing for all prefab before changing on fly to avoid bad noise or crash.

◆ MPTK_IndexSynthRate

int MidiPlayerTK.MidiSynth.MPTK_IndexSynthRate
getset

Sets or Get sample rate output of the synth. -1:default, 0:24000, 1:36000, 2:48000, 3:60000, 4:72000, 5:84000, 6:96000. It's better to stop playing before changing on fly to avoid bad noise.

◆ MPTK_InstrumentPlayed

string MidiPlayerTK.MidiSynth.MPTK_InstrumentPlayed
get

If spatialization is track mode, contains the last instrument played on this track.

Version
Maestro Pro

◆ MPTK_IsSpatialSynthMaster

bool MidiPlayerTK.MidiSynth.MPTK_IsSpatialSynthMaster
get

True if this MidiSynth is the master synth responsible for reading MIDI events and dispatching them to other MidiSynths.

Version
Maestro Pro

◆ MPTK_KeepPlayingNonLooped

bool MidiPlayerTK.MidiSynth.MPTK_KeepPlayingNonLooped
getset

When the value is true, NoteOff and Duration for non-looped samples are ignored and the samples play through to the end.

◆ MPTK_MaxDistance

float MidiPlayerTK.MidiSynth.MPTK_MaxDistance
getset

When MPTK_DistanceAttenuation is enabled, the volume of the audio source depends on the distance between the audio source and the listener. Distance at which attenuation reaches its minimum level. Beyond this distance, the volume remains constant and does not decrease further

◆ MPTK_MinDistance

float MidiPlayerTK.MidiSynth.MPTK_MinDistance
getset

When MPTK_DistanceAttenuation is enabled, the volume of the audio source depends on the distance between the audio source and the listener. Distance at which attenuation begins. When the listener is closer than this value, the audio plays at full volume(1.0).

◆ MPTK_MinSoundAttenuation

float MidiPlayerTK.MidiSynth.MPTK_MinSoundAttenuation
getset

If MPTK_DistanceAttenuation is enabled, the volume of the audio source depends on the distance between the audio source and the listener. Minimum volume applied at Max Distance

◆ MPTK_Orientation

bool MidiPlayerTK.MidiSynth.MPTK_Orientation
getset

Should the Unity orientation effect (pan + front/back + filtering) based on the relative orientation between the sound source and the listener must be enabled?

Note
MPTK_AudioListener by default is defined with the first AudioListener found in the scene. You can define your own AudioListener from the inspector of the MidiPlayerGlobal prefab.
Version
2.18.0 Pro

◆ MPTK_SpatialSynthIndex

int MidiPlayerTK.MidiSynth.MPTK_SpatialSynthIndex
get

Index of the MidiSynth for the dedicated Channel or Track when the prefab MidiSpatializer is used. If MPTK_ModeSpatializer = Channel then represent the playing channel. If MPTK_ModeSpatializer = Track then represent the playing track. The value is -1 for the Midi reader because no voice is played.

◆ MPTK_StatVoiceCountSustained

int MidiPlayerTK.MidiSynth.MPTK_StatVoiceCountSustained
get

Gets the number of active voices currently in the sustained state.

A sustained voice typically indicates that a note is being held, such as when a sustain pedal is engaged or a note-on event has not yet been released. This property can be used to monitor sustained notes for performance analysis or MIDI event handling.

◆ MPTK_SynthRate

int MidiPlayerTK.MidiSynth.MPTK_SynthRate
getset

Gets the the current synth rate or set free value (only if MPTK_EnableFreeSynthRate is true).

◆ MPTK_ThreadMidiPriority

int MidiPlayerTK.MidiSynth.MPTK_ThreadMidiPriority
getset

The MIDI thread�s priority shows how frequently a thread gains the access to CPU. The default value is 0 (normal), you can increase the priority to 1 and 2 (higher). This is useful when the hardware is weak, to get a more stable reading of the MIDI.

Note
: A higher priority thread might consume all the CPU time. It's recommended to set MPTK_ThreadMidiWait higher than 5 ms.

◆ MPTK_TrackName

string MidiPlayerTK.MidiSynth.MPTK_TrackName
get

If spatialization is track mode, contains the last track name.

Version
Maestro Pro

◆ MPTK_TransExcludedChannel

int MidiPlayerTK.MidiSynth.MPTK_TransExcludedChannel
getset

Transpose will apply to all channels except this one. Set to -1 to apply to all channel. V2.89.0 Default is 9 because generally we don't want to transpose drum channel.

◆ MPTK_Transpose

int MidiPlayerTK.MidiSynth.MPTK_Transpose
getset

Transpose note from -24 to 24

◆ MPTK_VelocityAttenuation

float MidiPlayerTK.MidiSynth.MPTK_VelocityAttenuation
getset

Experimental feature: modify the Fluidsynth constant FLUID_PEAK_ATTENUATION to change how velocity affects the voice attenuation. The default value is 960 (96 Db) Other values may produce unwanted results, use with care!

◆ MPTK_Volume

float MidiPlayerTK.MidiSynth.MPTK_Volume
getset

Sets the global volume between 0 and 1 for the current MPTK Synth.

Note
:

Event Documentation

◆ OnAudioFrameStart

OnAudioFrameStartHandler MidiPlayerTK.MidiSynth.OnAudioFrameStart

Raised at the start of each audio frame by the audio engine.

The callback parameter is the current synth time, in milliseconds.
The callback does not run on the Unity main thread, so you must not call Unity APIs (except Debug.Log).

Version
Maestro Pro
// See Assets\MidiPlayer\Demo\ProDemos\Script\EuclideSeq\TestEuclideanRhythme.cs for the full code.
public void Play()
{
if (IsPlaying)
midiStream.OnAudioFrameStart += PlayHits;
else
midiStream.OnAudioFrameStart -= PlayHits;
}
private void PlayHits(double synthTimeMS)
{
if (lastSynthTime <= 0d)
// First call, initialize the last time
lastSynthTime = synthTimeMS;
// Time (ms) since the last callback
double deltaTime = synthTimeMS - lastSynthTime;
lastSynthTime = synthTimeMS;
timeMidiFromStartPlay += deltaTime;
// Time since last beat played
timeSinceLastBeat += deltaTime;
// Slider SldTempo in BPM.
// 60 BPM means 60 beats per minute: 1 beat per second, 1000 ms between beats.
// 120 BPM is twice as fast: 2 beats per second, 500 ms between beats.
// Delay between two quarter notes (ms)
CurrentTempo = (60d / SldTempo.Value) * 1000d;
// Is it time to play a hit?
if (IsPlaying && timeSinceLastBeat > CurrentTempo)
{
timeSinceLastBeat = 0d;
CurrentBeat++;
}
}