Пример #1
0
        /// <summary>
        /// Loading of a SoundFontt when playing using a thread
        /// </summary>
        /// <param name="restartPlayer"></param>
        /// <returns></returns>
        private static IEnumerator <float> LoadSoundFontThread(bool restartPlayer = true)
        {
            //if (MidiPlayerGlobal.ImSFCurrent != null)
            {
                //Debug.Log("Load MidiPlayerGlobal.ImSFCurrent: " + MidiPlayerGlobal.ImSFCurrent.SoundFontName);
                //Debug.Log("Load CurrentMidiSet.ActiveSounFontInfo: " + CurrentMidiSet.ActiveSounFontInfo.Name);

                MidiSynth[]           synths          = FindObjectsOfType <MidiSynth>();
                List <MidiFilePlayer> playerToRestart = new List <MidiFilePlayer>();
                MPTK_SoundFontLoaded = false;
                if (Application.isPlaying)
                {
                    if (synths != null)
                    {
                        foreach (MidiSynth synth in synths)
                        {
                            if (synth is MidiFilePlayer)
                            {
                                MidiFilePlayer player = (MidiFilePlayer)synth;
                                if (player.MPTK_IsPlaying)
                                {
                                    playerToRestart.Add(player);
                                    player.MPTK_Stop(); // stop and clear all sound
                                }
                            }
                            //synth.MPTK_ClearAllSound();
                            yield return(Routine.WaitUntilDone(Routine.RunCoroutine(synth.ThreadWaitAllStop(), Segment.RealtimeUpdate), false));

                            synth.MPTK_StopSynth();
                        }
                    }
                    DicAudioClip.Init();
                    DicAudioWave.Init();
                }
                LoadCurrentSF();

                //Debug.Log("   Time To Load SoundFont: " + Math.Round(MidiPlayerGlobal.MPTK_TimeToLoadSoundFont.TotalSeconds, 3).ToString() + " second");
                //Debug.Log("   Time To Load Waves: " + Math.Round(MidiPlayerGlobal.MPTK_TimeToLoadWave.TotalSeconds, 3).ToString() + " second");

                if (synths != null)
                {
                    foreach (MidiSynth synth in synths)
                    {
                        synth.MPTK_InitSynth();
                        if (synth is MidiFilePlayer)
                        {
                            synth.MPTK_StartSequencerMidi();
                        }
                    }
                    if (restartPlayer)
                    {
                        foreach (MidiFilePlayer player in playerToRestart)
                        {
                            player.MPTK_RePlay();
                        }
                    }
                }
            }
        }
Пример #2
0
        public void MidiFileInfo(MidiFilePlayer instance)
        {
            instance.showMidiInfo = DrawFoldoutAndHelp(instance.showMidiInfo, "Show Midi Info", "https://paxstellar.fr/midi-file-player-detailed-view-2/#Foldout-Midi-Info");
            if (instance.showMidiInfo)
            {
                EditorGUI.indentLevel++;

                if (!string.IsNullOrEmpty(instance.MPTK_SequenceTrackName))
                {
                    if (taSequence == null)
                    {
                        taSequence = new TextArea("Sequence");
                    }
                    taSequence.Display(instance.MPTK_SequenceTrackName);
                }

                if (!string.IsNullOrEmpty(instance.MPTK_ProgramName))
                {
                    if (taProgram == null)
                    {
                        taProgram = new TextArea("Program");
                    }
                    taProgram.Display(instance.MPTK_ProgramName);
                }

                if (!string.IsNullOrEmpty(instance.MPTK_TrackInstrumentName))
                {
                    if (taInstrument == null)
                    {
                        taInstrument = new TextArea("Instrument");
                    }
                    taInstrument.Display(instance.MPTK_TrackInstrumentName);
                }

                if (!string.IsNullOrEmpty(instance.MPTK_TextEvent))
                {
                    if (taText == null)
                    {
                        taText = new TextArea("TextEvent");
                    }
                    taText.Display(instance.MPTK_TextEvent);
                }

                if (!string.IsNullOrEmpty(instance.MPTK_Copyright))
                {
                    if (taCopyright == null)
                    {
                        taCopyright = new TextArea("Copyright");
                    }
                    taCopyright.Display(instance.MPTK_Copyright);
                }
                EditorGUI.indentLevel--;
            }
        }
Пример #3
0
        public void MidiFileInfo(MidiFilePlayer instance)
        {
            showMidiInfo = EditorGUILayout.Foldout(showMidiInfo, "Show Midi Info");
            if (showMidiInfo)
            {
                EditorGUI.indentLevel++;

                if (!string.IsNullOrEmpty(instance.MPTK_SequenceTrackName))
                {
                    if (taSequence == null)
                    {
                        taSequence = new TextArea("Sequence");
                    }
                    taSequence.Display(instance.MPTK_SequenceTrackName);
                }

                if (!string.IsNullOrEmpty(instance.MPTK_ProgramName))
                {
                    if (taProgram == null)
                    {
                        taProgram = new TextArea("Program");
                    }
                    taProgram.Display(instance.MPTK_ProgramName);
                }

                if (!string.IsNullOrEmpty(instance.MPTK_TrackInstrumentName))
                {
                    if (taInstrument == null)
                    {
                        taInstrument = new TextArea("Instrument");
                    }
                    taInstrument.Display(instance.MPTK_TrackInstrumentName);
                }

                if (!string.IsNullOrEmpty(instance.MPTK_TextEvent))
                {
                    if (taText == null)
                    {
                        taText = new TextArea("TextEvent");
                    }
                    taText.Display(instance.MPTK_TextEvent);
                }

                if (!string.IsNullOrEmpty(instance.MPTK_Copyright))
                {
                    if (taCopyright == null)
                    {
                        taCopyright = new TextArea("Copyright");
                    }
                    taCopyright.Display(instance.MPTK_Copyright);
                }
                EditorGUI.indentLevel--;
            }
        }
        /// <summary>
        /// Loading of a SoundFonttwhen playing using a thread
        /// </summary>
        /// <returns></returns>
        private static IEnumerator <float> LoadSoundFontThread()
        {
            if (MidiPlayerGlobal.ImSFCurrent != null)
            {
                //Debug.Log("Load MidiPlayerGlobal.ImSFCurrent: " + MidiPlayerGlobal.ImSFCurrent.SoundFontName);
                //Debug.Log("Load CurrentMidiSet.ActiveSounFontInfo: " + CurrentMidiSet.ActiveSounFontInfo.Name);

                MidiSynth[] midiplayers = FindObjectsOfType <MidiSynth>();
                MPTK_SoundFontLoaded = false;
                if (Application.isPlaying)
                {
                    if (midiplayers != null)
                    {
                        foreach (MidiSynth mp in midiplayers)
                        {
                            if (mp is MidiFilePlayer)
                            {
                                MidiFilePlayer mfp = (MidiFilePlayer)mp;
                                if (!mfp.MPTK_IsPaused)
                                {
                                    mfp.MPTK_Pause();
                                }
                                yield return(Timing.WaitUntilDone(Timing.RunCoroutine(mp.ThreadClearAllSound(true))));
                            }
                        }
                    }
                    DicAudioClip.Init();
                    DicAudioWave.Init();
                }
                LoadCurrentSF();

                //Debug.Log("   Time To Load SoundFont: " + Math.Round(MidiPlayerGlobal.MPTK_TimeToLoadSoundFont.TotalSeconds, 3).ToString() + " second");
                //Debug.Log("   Time To Load Waves: " + Math.Round(MidiPlayerGlobal.MPTK_TimeToLoadWave.TotalSeconds, 3).ToString() + " second");

                if (midiplayers != null)
                {
                    foreach (MidiSynth mp in midiplayers)
                    {
                        if (mp is MidiFilePlayer)
                        {
                            MidiFilePlayer mfp = (MidiFilePlayer)mp;
                            if (mfp.MPTK_IsPaused)
                            {
                                mfp.MPTK_InitSynth();
                                mfp.MPTK_RePlay();
                            }
                        }
                    }
                }
            }
        }
Пример #5
0
 /// <summary>
 /// Stop all Midi Synthesizer dans Midi Sequencer
 /// </summary>
 public static void MPTK_Stop()
 {
     MidiSynth[] synths = FindObjectsOfType <MidiSynth>();
     if (synths != null)
     {
         foreach (MidiSynth synth in synths)
         {
             if (synth is MidiFilePlayer)
             {
                 MidiFilePlayer player = (MidiFilePlayer)synth;
                 if (player.MPTK_IsPlaying)
                 {
                     player.MPTK_Stop(); // stop and clear all sound
                 }
             }
             synth.MPTK_StopSynth();
         }
     }
 }
Пример #6
0
        //static private GUIStyle styleInfoMidi;

        // PopupSelectMidi PopMidi;


        void OnEnable()
        {
            try
            {
                //Debug.Log("OnEnable MidiFilePlayerEditor");
                CustomEventStartPlayMidi  = serializedObject.FindProperty("OnEventStartPlayMidi");
                CustomEventListNotesEvent = serializedObject.FindProperty("OnEventNotesMidi");
                CustomEventEndPlayMidi    = serializedObject.FindProperty("OnEventEndPlayMidi");

                instance = (MidiFilePlayer)target;
                // Load description of available soundfont
                if (MidiPlayerGlobal.CurrentMidiSet == null || MidiPlayerGlobal.CurrentMidiSet.ActiveSounFontInfo == null)
                {
                    ToolsEditor.LoadMidiSet();
                    ToolsEditor.CheckMidiSet();
                }
            }
            catch (System.Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
        }
Пример #7
0
        void OnEnable()
        {
            try
            {
                instance = (MidiFilePlayer)target;
                //Debug.Log("MidiFilePlayerEditor OnEnable " + instance.MPTK_MidiIndex);
                //Debug.Log("OnEnable MidiFilePlayerEditor");
                CustomEventStartPlayMidi  = serializedObject.FindProperty("OnEventStartPlayMidi");
                CustomEventListNotesEvent = serializedObject.FindProperty("OnEventNotesMidi");
                CustomEventEndPlayMidi    = serializedObject.FindProperty("OnEventEndPlayMidi");

                if (!Application.isPlaying)
                {
                    // Load description of available soundfont
                    if (MidiPlayerGlobal.CurrentMidiSet == null || MidiPlayerGlobal.CurrentMidiSet.ActiveSounFontInfo == null)
                    {
                        MidiPlayerGlobal.InitPath();
                        ToolsEditor.LoadMidiSet();
                        ToolsEditor.CheckMidiSet();
                    }
                }

                if (winSelectMidi != null)
                {
                    //Debug.Log("OnEnable winSelectMidi " + winSelectMidi.Title);
                    winSelectMidi.SelectedItem = instance.MPTK_MidiIndex;
                    winSelectMidi.Repaint();
                    winSelectMidi.Focus();
                }

                //EditorApplication.playModeStateChanged += EditorApplication_playModeStateChanged;
            }
            catch (System.Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
        }
Пример #8
0
        public void MidiFileParameters(MidiFilePlayer instance)
        {
            instance.MPTK_PlayOnStart        = EditorGUILayout.Toggle(new GUIContent("Play At Startup", "Start playing midi when the application starts"), instance.MPTK_PlayOnStart);
            instance.MPTK_DirectSendToPlayer = EditorGUILayout.Toggle(new GUIContent("Send To Synth", "Midi events are send to the midi player directly"), instance.MPTK_DirectSendToPlayer);

            instance.MPTK_Loop = EditorGUILayout.Toggle(new GUIContent("Loop", "Enable loop on midi play"), instance.MPTK_Loop);

            if (EditorApplication.isPlaying)
            {
                EditorGUILayout.Separator();
                string infotime = "Real time from start and total duration regarding the current tempo";
                EditorGUILayout.LabelField(new GUIContent("Time", infotime), new GUIContent(instance.playTimeEditorModeOnly + " / " + instance.durationEditorModeOnly, infotime));

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PrefixLabel(new GUIContent("Position", "Set real time position since the startup regarding the current tempo"));
                float currentpos = (float)instance.MPTK_Position;
                float pos        = EditorGUILayout.Slider(currentpos, 0f, (float)instance.MPTK_Duration.TotalMilliseconds);
                if (currentpos != pos)
                {
                    instance.MPTK_Position = pos;
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.Separator();
                string infotick = "Tick count for start and total duration regardless the current tempo";
                EditorGUILayout.LabelField(new GUIContent("Ticks", infotick), new GUIContent(instance.MPTK_TickCurrent + " / " + instance.MPTK_TickLast, infotime));

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PrefixLabel(new GUIContent("Position", "Set tick position since the startup regardless the current tempo"));
                float currenttick = (float)instance.MPTK_TickCurrent;
                long  ticks       = Convert.ToInt64(EditorGUILayout.Slider(currenttick, 0f, (float)instance.MPTK_TickLast));
                if (currenttick != ticks)
                {
                    instance.MPTK_TickCurrent = ticks;
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Separator();

                EditorGUILayout.BeginHorizontal();
                if (instance.MPTK_IsPlaying && !instance.MPTK_IsPaused)
                {
                    GUI.color = ToolsEditor.ButtonColor;
                }
                if (GUILayout.Button(new GUIContent("Play", "")))
                {
                    instance.MPTK_Play();
                }
                GUI.color = Color.white;

                if (instance.MPTK_IsPaused)
                {
                    GUI.color = ToolsEditor.ButtonColor;
                }
                if (GUILayout.Button(new GUIContent("Pause", "")))
                {
                    if (instance.MPTK_IsPaused)
                    {
                        instance.MPTK_Play();
                    }
                    else
                    {
                        instance.MPTK_Pause();
                    }
                }
                GUI.color = Color.white;

                if (GUILayout.Button(new GUIContent("Stop", "")))
                {
                    instance.MPTK_Stop();
                }

                if (GUILayout.Button(new GUIContent("Restart", "")))
                {
                    instance.MPTK_RePlay();
                }
                EditorGUILayout.EndHorizontal();
#if MPTK_PRO
                if (!(instance is MidiExternalPlayer))
                {
                    EditorGUILayout.BeginHorizontal();
                    if (GUILayout.Button(new GUIContent("Previous", "")))
                    {
                        instance.MPTK_Previous();
                    }
                    if (GUILayout.Button(new GUIContent("Next", "")))
                    {
                        instance.MPTK_Next();
                    }
                    EditorGUILayout.EndHorizontal();
                }
#endif
            }

            showMidiParameter = EditorGUILayout.Foldout(showMidiParameter, "Show Midi Parameters");
            if (showMidiParameter)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField(new GUIContent("Quantization", ""), GUILayout.Width(150));
                int newLevel = EditorGUILayout.Popup(instance.MPTK_Quantization, popupQuantization);
                if (newLevel != instance.MPTK_Quantization && newLevel >= 0 && newLevel < popupQuantization.Length)
                {
                    instance.MPTK_Quantization = newLevel;
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PrefixLabel("Speed");
                float speed = EditorGUILayout.Slider(instance.MPTK_Speed, 0.1f, 5f);
                if (instance.MPTK_Speed != speed)
                {
                    instance.MPTK_Speed = speed;
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                instance.MPTK_EnableChangeTempo = EditorGUILayout.Toggle(new GUIContent("Tempo Change", "Enable midi event tempo change when playing."), instance.MPTK_EnableChangeTempo);
                EditorGUILayout.LabelField(new GUIContent("Current:" + Math.Round(instance.MPTK_Tempo, 0), "Current tempo defined in Midi"));
                EditorGUILayout.EndHorizontal();

                instance.MPTK_EnablePresetDrum = EditorGUILayout.Toggle(new GUIContent("Drum Preset Change", "Enable Preset change on the canal 10 for drum. By default disabled, could sometimes create bad sound with midi files not really compliant with the Midi norm."), instance.MPTK_EnablePresetDrum);
                instance.MPTK_KeepNoteOff      = EditorGUILayout.Toggle(new GUIContent("Keep Midi NoteOff", "Keep Midi NoteOff and NoteOn with Velocity=0 (need to restart the playing Midi)"), instance.MPTK_KeepNoteOff);
                instance.MPTK_LogEvents        = EditorGUILayout.Toggle(new GUIContent("Log Midi Events", "Log information about each midi events read."), instance.MPTK_LogEvents);
            }
        }
        private void Start()
        {
            if (!HelperDemo.CheckSFExists())
            {
                return;
            }

            // Warning: when defined by script, this event is not triggered at first load of MPTK
            // because MidiPlayerGlobal is loaded before any other gamecomponent
            if (!MidiPlayerGlobal.OnEventPresetLoaded.HasEvent())
            {
                // To be done in Start event (not Awake)
                MidiPlayerGlobal.OnEventPresetLoaded.AddListener(EndLoadingSF);
            }

            PopMidi = new PopupListItem()
            {
                Title    = "Select A Midi File",
                OnSelect = MidiChanged,
                Tag      = "NEWMIDI",
                ColCount = 3,
                ColWidth = 250,
            };

            if (midiFilePlayer == null)
            {
                Debug.Log("No MidiFilePLayer defined with the editor inspector, try to find one");
                MidiFilePlayer fp = FindObjectOfType <MidiFilePlayer>();
                if (fp == null)
                {
                    Debug.Log("Can't find a MidiFilePLayer in the Hierarchy. No music will be played");
                }
                else
                {
                    midiFilePlayer = fp;
                }
            }

            if (midiFilePlayer != null)
            {
                // There is two methods to trigger event:
                //      1) in inpector from the Unity editor
                //      2) by script, see below
                // ------------------------------------------

                SetStartEvent();

                // Event trigger when midi file end playing
                if (!midiFilePlayer.OnEventEndPlayMidi.HasEvent())
                {
                    // Set event by script
                    Debug.Log("OnEventEndPlayMidi defined by script");
                    midiFilePlayer.OnEventEndPlayMidi.AddListener(EndPlay);
                }
                else
                {
                    Debug.Log("OnEventEndPlayMidi defined by Unity editor");
                }

                // Event trigger for each group of notes read from midi file
                if (!midiFilePlayer.OnEventNotesMidi.HasEvent())
                {
                    // Set event by scripit
                    Debug.Log("OnEventNotesMidi defined by script");
                    midiFilePlayer.OnEventNotesMidi.AddListener(MidiReadEvents);
                }
                else
                {
                    Debug.Log("OnEventNotesMidi defined by Unity editor");
                }

                InitPlay();
            }
        }
Пример #10
0
        public void MidiFileParameters(MidiFilePlayer instance)
        {
            instance.MPTK_PlayOnStart          = EditorGUILayout.Toggle(new GUIContent("Play At Startup", "Start playing Midi when the application starts"), instance.MPTK_PlayOnStart);
            instance.MPTK_StartPlayAtFirstNote = EditorGUILayout.Toggle(new GUIContent("Start Play From First Note", "Start playing Midi from the first note found in the midi"), instance.MPTK_StartPlayAtFirstNote);
            instance.MPTK_PauseOnFocusLoss     = EditorGUILayout.Toggle(new GUIContent("Pause When Focus Loss", "Pause when application loss the focus"), instance.MPTK_PauseOnFocusLoss);

            instance.MPTK_DirectSendToPlayer = EditorGUILayout.Toggle(new GUIContent("Send To Synth", "Midi events are send to the midi player directly"), instance.MPTK_DirectSendToPlayer);

            instance.MPTK_Loop = EditorGUILayout.Toggle(new GUIContent("Loop On Midi", "Enable loop on midi play"), instance.MPTK_Loop);

            if (EditorApplication.isPlaying)
            {
                EditorGUILayout.Separator();
                string infotime = "Real time from start and total duration regarding the current tempo";
                EditorGUILayout.LabelField(new GUIContent("Time", infotime), new GUIContent(instance.playTimeEditorModeOnly + " / " + instance.durationEditorModeOnly, infotime));

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PrefixLabel(new GUIContent("Position", "Set real time position since the startup regarding the current tempo"));
                float currentPosition = (float)Math.Round(instance.MPTK_Position);
                float newPosition     = (float)Math.Round(EditorGUILayout.Slider(currentPosition, 0f, instance.MPTK_DurationMS));
                if (currentPosition != newPosition)
                {
                    // Avoid event as layout triggered when duration is changed
                    if (Event.current.type == EventType.Used)
                    {
                        //Debug.Log("New position " + currentPosition + " --> " + newPosition + " " + Event.current.type);
                        instance.MPTK_Position = newPosition;
                    }
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.Separator();
                string infotick = "Tick count for start and total duration regardless the current tempo";
                EditorGUILayout.LabelField(new GUIContent("Ticks", infotick), new GUIContent(instance.MPTK_TickCurrent + " / " + instance.MPTK_TickLast, infotime));

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PrefixLabel(new GUIContent("Position", "Set tick position since the startup regardless the current tempo"));
                long currenttick = instance.MPTK_TickCurrent;
                long ticks       = Convert.ToInt64(EditorGUILayout.Slider(currenttick, 0f, (float)instance.MPTK_TickLast));
                if (currenttick != ticks)
                {
                    // Avoid event as layout triggered when duration is changed
                    if (Event.current.type == EventType.Used)
                    {
                        //Debug.Log("New tick " + currenttick + " --> " + ticks + " " + Event.current.type);
                        instance.MPTK_TickCurrent = ticks;
                    }
                }
                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Separator();

                EditorGUILayout.BeginHorizontal();
                if (instance.MPTK_IsPlaying && !instance.MPTK_IsPaused)
                {
                    GUI.color = ToolsEditor.ButtonColor;
                }
                if (GUILayout.Button(new GUIContent("Play", "")))
                {
                    instance.MPTK_Play();
                }
                GUI.color = Color.white;

                if (instance.MPTK_IsPaused)
                {
                    GUI.color = ToolsEditor.ButtonColor;
                }
                if (GUILayout.Button(new GUIContent("Pause", "")))
                {
                    if (instance.MPTK_IsPaused)
                    {
                        //instance.MPTK_Play();
                        instance.MPTK_UnPause();
                    }
                    else
                    {
                        instance.MPTK_Pause();
                    }
                }
                GUI.color = Color.white;

                if (GUILayout.Button(new GUIContent("Stop", "")))
                {
                    instance.MPTK_Stop();
                }

                if (GUILayout.Button(new GUIContent("Restart", "")))
                {
                    instance.MPTK_RePlay();
                }
                EditorGUILayout.EndHorizontal();
#if MPTK_PRO
                if (!(instance is MidiExternalPlayer))
                {
                    EditorGUILayout.BeginHorizontal();
                    if (GUILayout.Button(new GUIContent("Previous", "")))
                    {
                        instance.MPTK_Previous();
                    }
                    if (GUILayout.Button(new GUIContent("Next", "")))
                    {
                        instance.MPTK_Next();
                    }
                    EditorGUILayout.EndHorizontal();
                }
#endif
            }

            instance.showMidiParameter = DrawFoldoutAndHelp(instance.showMidiParameter, "Show Midi Parameters", "https://paxstellar.fr/midi-file-player-detailed-view-2/#Foldout-Midi-Parameters");
            if (instance.showMidiParameter)
            {
                EditorGUI.indentLevel++;
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField(new GUIContent("Quantization", ""), GUILayout.Width(150));
                int newLevel = EditorGUILayout.Popup(instance.MPTK_Quantization, popupQuantization);
                if (newLevel != instance.MPTK_Quantization && newLevel >= 0 && newLevel < popupQuantization.Length)
                {
                    instance.MPTK_Quantization = newLevel;
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.PrefixLabel("Speed");
                float speed = EditorGUILayout.Slider(instance.MPTK_Speed, 0.1f, 10f);
                //          Debug.Log("New speed " + instance.MPTK_Speed + " --> " + speed + " " + Event.current.type);
                if (speed != instance.MPTK_Speed)
                {
                    //Debug.Log("New speed " + instance.MPTK_Speed + " --> " + speed + " " + Event.current.type);
                    instance.MPTK_Speed = speed;
                }
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal();
                instance.MPTK_EnableChangeTempo = EditorGUILayout.Toggle(new GUIContent("Tempo Change", "Enable midi event tempo change when playing."), instance.MPTK_EnableChangeTempo);
                EditorGUILayout.LabelField(new GUIContent("Current:" + Math.Round(instance.MPTK_Tempo, 0), "Current tempo defined in Midi"));
                EditorGUILayout.EndHorizontal();

                instance.MPTK_EnablePresetDrum = EditorGUILayout.Toggle(new GUIContent("Drum Preset Change", "Enable Preset change on the canal 10 for drum. By default disabled, could sometimes create bad sound with midi files not really compliant with the Midi norm."), instance.MPTK_EnablePresetDrum);
                instance.MPTK_KeepNoteOff      = EditorGUILayout.Toggle(new GUIContent("Keep Midi NoteOff", "Keep Midi NoteOff and NoteOn with Velocity=0 (need to restart the playing Midi)"), instance.MPTK_KeepNoteOff);
                instance.MPTK_LogEvents        = EditorGUILayout.Toggle(new GUIContent("Log Midi Events", "Log information about each midi events read."), instance.MPTK_LogEvents);
                EditorGUI.indentLevel--;
            }
        }