Prefab MidiFilePlayer

MidiFilePlayer is a Prefab that you can use to play a Midi  files in your application. See Quick Start to understand how to add a MidiFilePlayer in your application.

Also, you can use MidiFilePlayer gameObject in your script to create a more complex interaction. See an example with source code at the end of this page.

Basics parameters

Select your midi in the Inspector and run your application, the Midi is playing . It’s as simple as that ! See below the specific parameters that can be apply.

  • Select Midi: open a popup with all your Midi available in your project. Select one Midi. Before your Midi list must to be define with MPTK Midi Setup.
  • Volume :set the default volume of the playing.
  • V2.82 move to Spatialization foldout, see below. Pause with distance: if checked, automatically pause the play if distance between the gameobject MidiFilePlayer and the AudioListener is greater than MaxDistance.
  • MaxDistance: distance for the pause with distance function.
  • Transpose: transpose the music by half tone.
  • Play At Startup: if checked, start playing when your application starts.
  • Start Play From First Note: search for first note in Midi and plays immediately with this note. Useful to avoid latency at start.
  • Pause When Focus Loss: Pause the Midi playing when the application lost the focus, go in background, or is suspended.
  • Send To Synth: if not check, Midi file is read but no Midi events are send to the synthesizer. Nevertheless, The Unity event
    OnEventNotesMidi is fire.
  • Loop On Midi: if check, restart playing automatically when the end of the Midi file is reached. The Midi files is not reload.

Parameters when running

  • Time / Position current time position of the playing Midi and total length. The time can change if a tempo change is received from the Midi sequencer. The slider can be use to change this position when playing.
  • Ticks / Position current ticks position of the playing Midi and total length. The value is independent of the tempo change. The slider can be use to change this position when playing.
  • Play / Pause / Stop / Restart, change the current playing status.
  • Previous / Next load previous or next Midi in the MPTK Midi list.

Foldout Spatialization (V2.82)

Setup Spatialization in Unity

See here.

MPTK Inspector For Spatialization Parameters

MPTK Inspector for spatialization parameters
  • Spatialization: if checked, Unity spatializer is enabled.
    Moreover, playing is paused if distance between the gameobject which hold this prefab and the AudioListener is greater than Max Distance.
  • Max Distance: distance for the pause with distance function.

Tip: To take advantage of this effect, you must listen with an headphone.

Tip: do not mix up “stereo” and “spatialization” effects. The stereo information (pan) comes up from the SoundFont properties. For example: left right panning for a piano is depending on the key position.
These two effects could counteracted each other. The “pan” properties can be disabled within the foldout “Show Synth Parameters” in inspector. See here Modulator / Pan Change.

Foldout Midi Parameters

  • Quantization: define quantization to remove some imprecision in tempo. With quantization, notes are plays on beats or on fractions of beats.
  • Speed: to play the Midi file. with 1 play at the tempo defined in the Midi file.
  • Tempo Change: enable tempo change from the Midi.
  • Drum Preset Change: enable control change preset for drum. Disabled by default.
  • Release Same Note: the default behavior of a Midi player is to release a note when the same note is played again. A physical keyboard can’t plays two keys at the same time! It’s possible to change this behavior by unchecking this checkbox.
  • Kill By Exclusive Class: the default behavior of a Midi player is to released a note when a note of the same class is played in the same preset. Class is defined in the SoundFont. Generally, this function is used by drum kit. It’s possible to change this behavior by unchecking this checkbox.
  • Keep Notes Off: notes off are not used to play the Midi (duration is used). If you have the need to get Note Off (for example to write a consistent Midi file or process these events in your code), check this option.
  • Log Midi Events: check to have a log for each Midi events when playing.

Foldout Events

Fires actions in your script in relation with the Midi Player. These actions can be define with the inspector or by script with MPTK API.

  • On Event Start Play Midi: start playing the Midi file. Receives the Midi name in parameter as a string.
  • On Event Notes Midi: when a group of notes is ready to be play by the sequencer. Receives a list of MptkEvent in the parameter.
  • On Event End Play Midi: end playing the Midi file. Receives the Midi name in parameter as a string and the reason of the end.

Foldout Midi Info

Display information from the META chunks of the midi file. Enabled only when playing a Midi which contains META data.

Foldout Synth Parameters

The midi synthesizer is based on fluidsynth. It’s an adaption on this well known synth from C to C# for Unity.

Audio Parameters

  • Core Player: if checked, the synthesizer is working on a system thread apart from the main Unity thread: accuracy and latency are better. On top of that, synthesizer is based on a full migration of fluidsynth: sound is better.
    When Core Player is not checked, the legacy mode is enabled (available since the V1). Many AudioSource are used to play each sample and the synth is simplified. Warning, the legacy mode is not compatible with all the MPTK functions. It will be removed with the next major version.
  • Rate Synth Output: defined the rate of the FMOD component in Unity. High rate enhance the quality of the sound but with cost on performance (linear impact). It’s a global parameter for your application. The default value can be also defined with Project Setting/Audio.
  • Buffer Synth Size: defined the size of the FMOD buffer. Small buffer enhance the accurate of the playing but with a little cost on performance. It’s a global parameter for your application. The default value can be also defined with Project Setting/Audio.
  • Interpolation Method: convert the wave sample to the synth format.
    • None: no interpolation. Just take the sample, which is closest to the playback pointer. Very efficient but questionable quality.
    • Linear: Straight line interpolation. A good balancing. Cost performance: 17% from none interpolation.
    • 4th order: Even Better ! Cost performance: 30%
    • 7th order: Even Better ! Cost performance: 65%

Tip: Changing audio parameters on iOS is disabled because the hardware don’t like changing the default value. Seems to be 24kHz.

Tip: See performance information here

Modulator

  • Log Samples: log to console information about each samples for each notes: sample name, instrument.
  • Pan Change: panoramic setting (stereo) are processed with specific Midi events. On the other hand, the pan information comes up from the SoundFont properties. For example: left right panning for a piano is depending on the key position.
    Uncheck Pan Change if left/right is managed by your application or you have enabled Spatialization.
  • Apply Modulator: apply real time modulator as Pitch Bend and Control Change.
  • Apply Mod LFO: apply LFO modulator (amplitude LFO).
  • Apply Vib LFO: apply LFO vibrator (pitch LFO).

SoundFont Effects [Pro]

Important: by default these effects are not enabled in the prefab. You have to enable them from the inspector (or by script) and enjoy a better sound. See below. Adding low-filter effect is often good to get a better sound!

A SoundFont contains parameters to apply three kinds of effects: low-pass, reverb, chorus. These parameters can be specifics for each intruments and even each notes. See below for low-pass frequency set for Piano. Viena is a perfect tool to edit SoundFont.

FluidSynth effect modules have been also migrated to MPTK. Furthermore, these default SoundFont parameters can be increased or decreased with MPTK.

In summary:

  • Effects are applied independently for each notes.
  • More CPU is need for these effects. See impact of effect on DSP load here.
  • MPTK parameters can increase or decrease default SoundFont Values. See below.
  • See performance information here

Integration with Unity Effects [Pro]

Obviously, Unity effects are also available, but unlike SoundFont effects, they applied to the whole player. On the other hand, the effects parameters are rich!

Balance Performance / Quality

  • Thread Midi Delay: Delay in milliseconds between call to the midi sequencer. A delay below 20 ms is recommended.
  • Max Level DSP Load: When DSP Load is over the ‘Max Level DSP Load’ (by default 50%), some actions are taken on current playing voices for better performance (see below).
  • Device Performance: To be adapted to the device capabilities: lower for weak device. If cleaning is need, sustained voices are stopped and release time is diminished in proportion of this variable. If value <=25 voices could be forced to stop playing (move to Release step like a noteoff).

Synth Events

  • On Event Synth Awake: fired just at the beginning of the Awake() of the synth gameobject.
  • On Event Synth Started: fired at the end of the Start() of the synth gameobject.

Performance vs Synthesizer Parameters

These performance has been recorded with an Intel i5-9600K 3.7 GHz CPU.

Foldout Show Default Editor

Some parameters, mainly for the synth, are not defined in the custom inspector. You can change some values for experimentation or debug … at your own risks!

There is also some information about time processing of Midi and Synth. To activate statistics, add these Define Symbols (see here how to):

  • DEBUG_PERF_AUDIO
  • DEBUG_PERF_MIDI
  • DEBUG_STATUS_STAT

Integration of MidiFilePlayer in your script

See TestMidiFilePlayerScripting.cs for the whole example.

using MidiPlayerTK; ... MidiFilePlayer mfp = FindObjectOfType<MidiFilePlayer>(); // Set event by script mfp.OnEventEndPlayMidi.AddListener(EndPlay); mfp.OnEventNotesMidi.AddListener(MidiReadEvents); // Event fired when a midi is ended public void EndPlay(string midiname, EventEndMidiEnum reason) { Debug.LogFormat("End playing {0} reason:{1}", midiname, reason); } // Event fired by MidiFilePlayer when midi notes are available public void MidiReadEvents(List<MPTKEvent> events) { foreach (MPTKEvent midievent in events) ... } void OnGUI() { ... mfp.MPTK_Play(); midiFilePlayer.MPTK_Position = position; ... }