예제 #1
0
        public void AddSoundFont(ImSoundFont imsf)
        {
            SoundFontInfo sfi = new SoundFontInfo();

            sfi.Name = imsf.SoundFontName;
            SoundFonts.Add(sfi);
        }
예제 #2
0
 public void SetActiveSoundFont(int index)
 {
     try
     {
         if (index > -1 && index < SoundFonts.Count)
         {
             ActiveSounFontInfo = SoundFonts[index];
         }
         else
         {
             ActiveSounFontInfo = null;
         }
     }
     catch (System.Exception ex)
     {
         MidiPlayerGlobal.ErrorDetail(ex);
     }
 }
예제 #3
0
        /// <summary>
        /// Display, add, remove Soundfont
        /// </summary>
        /// <param name="localstartX"></param>
        /// <param name="localstartY"></param>
        private void ShowListSoundFonts(float startX, float startY, float width, float height)
        {
            try
            {
                Rect zone = new Rect(startX, startY, width, height);
                GUI.color = new Color(.8f, .8f, .8f, 1f);
                GUI.Box(zone, "");
                GUI.color = Color.white;
                float      localstartX = 0;
                float      localstartY = 0;
                GUIContent content;
                if (MidiPlayerGlobal.CurrentMidiSet != null && MidiPlayerGlobal.CurrentMidiSet.SoundFonts != null && MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count > 0)
                {
                    content = new GUIContent()
                    {
                        text = "SoundFont available", tooltip = "Each SoundFonts contains a set of bank of sound. \nOnly one SoundFont can be active at the same time for the midi player"
                    }
                }
                ;
                else
                {
                    content = new GUIContent()
                    {
                        text = "No SoundFont found, click on button 'Add SoundFont'", tooltip = "See the documentation here http://paxstellar.fr/"
                    }
                };

                localstartX += xpostitlebox;
                localstartY += ypostitlebox;
                EditorGUI.LabelField(new Rect(startX + localstartX + 5, startY + localstartY, width, titleHeight), content, styleBold);
                localstartY += titleHeight;
                Rect rect1 = new Rect(startX + localstartX + espace, startY + localstartY, buttonLargeWidth, buttonHeight);

#if MPTK_PRO
                if (GUI.Button(rect1, "Add SoundFont"))
                {
                    if (Application.isPlaying)
                    {
                        EditorUtility.DisplayDialog("Add a SoundFont", "This action is not possible when application is running.", "Ok");
                    }
                    else
                    {
                        //if (EditorUtility.DisplayDialog("Import SoundFont", "This action could take time, do you confirm ?", "Ok", "Cancel"))
                        {
                            this.AddSoundFont();
                            scrollPosSoundFont = Vector2.zero;
                        }
                    }
                }
#else
                if (GUI.Button(rect1, "Add a new SoundFont [PRO]"))
                {
                    PopupWindow.Show(new Rect(startX + localstartX, startY + localstartY, buttonLargeWidth, buttonHeight), new GetFullVersion());
                }
#endif
                rect1 = new Rect(width - buttonMediumWidth - 25, startY + localstartY, buttonMediumWidth, buttonHeight);
#if MPTK_PRO
                //rect = new Rect(width - 1 * (buttonWidth), localstartY, buttonWidth, buttonHeight);

                if (GUI.Button(rect1, "Remove"))
                {
                    if (Application.isPlaying)
                    {
                        EditorUtility.DisplayDialog("Add a SoundFont", "This action is not possible when application is running.", "Ok");
                    }
                    else
                    {
                        this.DeleteSf();
                    }
                }
#else
                if (GUI.Button(rect1, "Remove"))
                {
                    PopupWindow.Show(rect1, new GetFullVersion());
                }
#endif
                localstartY += buttonHeight + espace;

                // Draw title list box
                GUI.color = new Color(.6f, .6f, .6f, 1f);
                GUI.Box(new Rect(startX + localstartX + espace, startY + localstartY, width - 35, 20), "", styleListTitle);
                GUI.color = Color.white;

                // Draw text title list box
                GUI.Label(new Rect(startX + localstartX + espace, startY + localstartY, width - 25, itemHeight), " SoundFont Name                            Patch  Wave     Size");
                localstartY += itemHeight;

                if (MidiPlayerGlobal.CurrentMidiSet != null && MidiPlayerGlobal.CurrentMidiSet.SoundFonts != null && MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count > 0)
                {
                    Rect listVisibleRect = new Rect(startX + localstartX, startY + localstartY - 11, width - 10, height - localstartY);
                    Rect listContentRect = new Rect(0, 0, width - 25, MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count * itemHeight + 5);

                    scrollPosSoundFont = GUI.BeginScrollView(listVisibleRect, scrollPosSoundFont, listContentRect, false, true);
                    float boxY = 0;

                    // Loop on each soundfont
                    for (int i = 0; i < MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count; i++)
                    {
                        SoundFontInfo sf       = MidiPlayerGlobal.CurrentMidiSet.SoundFonts[i];
                        bool          selected = (MidiPlayerGlobal.ImSFCurrent != null && sf.Name == MidiPlayerGlobal.CurrentMidiSet.ActiveSounFontInfo.Name);

                        GUI.color = selected ? ToolsEditor.ButtonColor : new Color(.7f, .7f, .7f, 1f);
                        float boxX = espace;
                        GUI.Box(new Rect(boxX, boxY + 5, width - 35, itemHeight), "");//,  styleRowListNormal);
                        GUI.color = Color.white;
                        boxX     += espace;

                        float colw = 210;
                        content = new GUIContent()
                        {
                            text = sf.Name, tooltip = ""
                        };
                        EditorGUI.LabelField(new Rect(boxX, boxY + 9, colw, itemHeight - 5), content);
                        boxX = colw + espace;

                        colw    = 30;
                        content = new GUIContent()
                        {
                            text = sf.PatchCount.ToString(), tooltip = ""
                        };
                        EditorGUI.LabelField(new Rect(boxX, boxY + 9, colw, itemHeight - 7), content, styleLabelRight);
                        boxX += colw + espace;

                        content = new GUIContent()
                        {
                            text = sf.WaveCount.ToString(), tooltip = ""
                        };
                        EditorGUI.LabelField(new Rect(boxX, boxY + 9, colw, itemHeight - 7), content, styleLabelRight);
                        boxX += colw + espace;

                        string sizew = (sf.WaveSize < 1000000) ?
                                       Math.Round((double)sf.WaveSize / 1000d).ToString() + " Ko" :
                                       Math.Round((double)sf.WaveSize / 1000000d).ToString() + " Mo";
                        content = new GUIContent()
                        {
                            text = sizew, tooltip = ""
                        };
                        EditorGUI.LabelField(new Rect(boxX, boxY + 9, colw * 2, itemHeight - 7), content, styleLabelRight);
                        boxX += colw * 2 + espace;

                        string textselect = "Select";
                        if (MidiPlayerGlobal.ImSFCurrent != null && sf.Name == MidiPlayerGlobal.CurrentMidiSet.ActiveSounFontInfo.Name)
                        {
                            textselect = "Default";// GUI.color = ToolsEditor.ButtonColor;
                        }
                        // Select button right aligned
                        if (GUI.Button(new Rect(width - 35 - 1 * buttonMediumWidth, boxY + 9, buttonMediumWidth, buttonHeight), textselect))
                        {
#if MPTK_PRO
                            this.SelectSf(i);
#endif
                        }
                        boxY     += itemHeight - 1;
                        GUI.color = Color.white;
                    }
                    GUI.EndScrollView();
                }
            }
            catch (ExitGUIException) { }
            catch (Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
        }
예제 #4
0
        //! @cond NODOC

        /// <summary>
        /// Core function to load a SF when playing or from editor from the Unity asset
        /// </summary>
        public static void LoadCurrentSF()
        {
            MPTK_SoundFontLoaded = false;
            // Load simplfied soundfont
            try
            {
                DateTime start = DateTime.Now;
                if (CurrentMidiSet == null)
                {
                    Debug.Log(MidiPlayerGlobal.ErrorNoSoundFont);
                }
                else
                {
                    SoundFontInfo sfi = CurrentMidiSet.ActiveSounFontInfo;
                    if (sfi == null)
                    {
                        Debug.Log(MidiPlayerGlobal.ErrorNoSoundFont);
                    }
                    else
                    {
                        //Debug.Log("Start loading " + sfi.Name);

                        // Path to the soundfonts directory for this SF, start from resource folder
                        string pathToImSF = Path.Combine(SoundfontsDB + "/", sfi.Name);

                        WavePath = Path.Combine(pathToImSF + "/", PathToWave);
                        // Load all presets defined in the sf
                        ImSFCurrent = ImSoundFont.Load(pathToImSF, sfi.Name);

                        // Add
                        if (ImSFCurrent == null)
                        {
                            Debug.LogWarning("Error loading " + sfi.Name ?? "name not defined");
                        }
                        else
                        {
                            BuildBankList();
                            BuildPresetList(true);
                            BuildPresetList(false);
                            //BuildDrumList();
                            timeToLoadSoundFont = DateTime.Now - start;

                            //Debug.Log("End loading SoundFont " + timeToLoadSoundFont.TotalSeconds + " seconds");
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }

            if (ImSFCurrent == null)
            {
                Debug.LogWarning("SoundFont not loaded.");
                return;
            }

            // Load samples only in run mode
            if (Application.isPlaying)
            {
                try
                {
                    MPTK_CountWaveLoaded = 0;
                    System.Diagnostics.Stopwatch watchLoadWave = new System.Diagnostics.Stopwatch(); // High resolution time
                    watchLoadWave.Start();
                    if (MPTK_LoadWaveAtStartup)
                    {
                        LoadAudioClip();
                    }
                    LoadWave();
                    timeToLoadWave = watchLoadWave.Elapsed;
                    //Debug.Log("End loading Waves " + timeToLoadWave.TotalSeconds + " seconds" + " count:" + MPTK_CountWaveLoaded);
                }
                catch (System.Exception ex)
                {
                    MidiPlayerGlobal.ErrorDetail(ex);
                }
            }
            if (ImSFCurrent != null)
            {
                MPTK_SoundFontLoaded = true;
            }

            if (OnEventPresetLoaded != null)
            {
                OnEventPresetLoaded.Invoke();
            }
        }
예제 #5
0
        private void ShowListBanks(float localstartX, float localstartY, float width, float height)
        {
            try
            {
                Rect zone = new Rect(localstartX, localstartY, width, height);
                GUI.color = new Color(.8f, .8f, .8f, 1f);
                GUI.Box(zone, "");
                GUI.color = Color.white;

                if (MidiPlayerGlobal.ImSFCurrent != null && MidiPlayerGlobal.ImSFCurrent.Banks != null)
                {
                    string     tooltip = "Each bank contains a set of patchs (instrument).\nOnly two banks can be active at the same time : default sound (piano, ...) and drum kit (percussive)";
                    GUIContent content = new GUIContent()
                    {
                        text = "Banks available in SoundFont " + MidiPlayerGlobal.ImSFCurrent.SoundFontName, tooltip = tooltip
                    };
                    //GUIContent content = new GUIContent() { text = "Banks available in SoundFont ", tooltip = tooltip };
                    EditorGUI.LabelField(new Rect(localstartX + xpostitlebox, localstartY + ypostitlebox, width, itemHeight), content, styleBold);

                    //if (GUI.Button(new Rect(localstartX + width - buttonWidth - espace, localstartY + ypostitlebox, buttonWidth, buttonHeight), new GUIContent() { text = "2) Removed not used", tooltip = tooltip }))
                    //{
                    //    SoundFontOptim.OptimizeBanks(MidiPlayerGlobal.ImSFCurrent);
                    //    MidiPlayerGlobal.CurrentMidiSet.Save();
                    //}

                    // Count available banks
                    int countBank = 0;
                    foreach (ImBank bank in MidiPlayerGlobal.ImSFCurrent.Banks)
                    {
                        if (bank != null)
                        {
                            countBank++;
                        }
                    }
                    Rect listVisibleRect = new Rect(localstartX, localstartY + itemHeight, width, height - itemHeight - 5);
                    Rect listContentRect = new Rect(0, 0, width - 15, countBank * itemHeight + 5);

                    scrollPosBanks = GUI.BeginScrollView(listVisibleRect, scrollPosBanks, listContentRect);

                    float         boxY = 0;
                    SoundFontInfo sfi  = MidiPlayerGlobal.CurrentMidiSet.ActiveSounFontInfo;
                    if (sfi != null)
                    {
                        foreach (ImBank bank in MidiPlayerGlobal.ImSFCurrent.Banks)
                        {
                            if (bank != null)
                            {
                                GUI.color = new Color(.7f, .7f, .7f, 1f);
                                GUI.Box(new Rect(5, boxY + 5, width - 25, itemHeight), "");

                                GUI.color = Color.white;

                                content = new GUIContent()
                                {
                                    text = string.Format("Bank [{0,3:000}] Patch:{1}", bank.BankNumber, bank.PatchCount), tooltip = bank.Description
                                };
                                GUI.Label(new Rect(10, boxY + 9, 130, itemHeight), content);

                                //Debug.Log(sfi.DefaultBankNumber );
                                if (sfi.DefaultBankNumber == bank.BankNumber)
                                {
                                    GUI.color = ToolsEditor.ButtonColor;
                                }
                                if (GUI.Button(new Rect(155, boxY + 9, 120, buttonHeight), new GUIContent("Default Bank", "Select this bank to be used for all instruments except drum")))
                                {
                                    sfi.DefaultBankNumber = sfi.DefaultBankNumber != bank.BankNumber ? bank.BankNumber : -1;
                                    MidiPlayerGlobal.ImSFCurrent.DefaultBankNumber = bank.BankNumber;
                                    MidiPlayerGlobal.CurrentMidiSet.Save();
                                }
                                GUI.color = Color.white;

                                if (sfi.DrumKitBankNumber == bank.BankNumber)
                                {
                                    GUI.color = ToolsEditor.ButtonColor;
                                }
                                if (GUI.Button(new Rect(155 + 120 + 5, boxY + 9, 120, buttonHeight), new GUIContent("Drum Bank", "Select this bank to be used for playing drum hit")))
                                {
                                    sfi.DrumKitBankNumber = sfi.DrumKitBankNumber != bank.BankNumber ? bank.BankNumber : -1;
                                    MidiPlayerGlobal.ImSFCurrent.DrumKitBankNumber = bank.BankNumber;
                                    MidiPlayerGlobal.CurrentMidiSet.Save();
                                }
                                GUI.color = Color.white;
                                boxY     += itemHeight;
                            }
                        }
                    }

                    GUI.EndScrollView();
                }
                else
                {
                    EditorGUI.LabelField(new Rect(localstartX + xpostitlebox, localstartY + ypostitlebox, 300, itemHeight), "No SoundFont selected", styleBold);
                }
            }
            catch (Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
        }
예제 #6
0
        /// <summary>
        /// Display, add, remove Soundfont
        /// </summary>
        /// <param name="localstartX"></param>
        /// <param name="localstartY"></param>
        private void ShowListSoundFonts(float localstartX, float localstartY, float width, float height)
        {
            try
            {
                Rect zone = new Rect(localstartX, localstartY, width, height);
                GUI.color = new Color(.8f, .8f, .8f, 1f);
                GUI.Box(zone, "");
                GUI.color = Color.white;
                if (MidiPlayerGlobal.CurrentMidiSet != null && MidiPlayerGlobal.CurrentMidiSet.SoundFonts != null)
                {
                    string caption = "SoundFont available";
                    if (MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count == 0)
                    {
                        caption = "No SoundFont available yet";
                        MidiPlayerGlobal.ImSFCurrent = null;
                    }

                    GUIContent content = new GUIContent()
                    {
                        text = caption, tooltip = "Each SoundFonts contains a set of bank of sound. \nOnly one SoundFont can be active at the same time for the midi player"
                    };
                    EditorGUI.LabelField(new Rect(localstartX + xpostitlebox, localstartY + ypostitlebox, 300, itemHeight), content, styleBold);
                    Rect rect = new Rect(width - buttonWidth, localstartY + ypostitlebox, buttonWidth, buttonHeight);
#if MPTK_PRO
                    if (GUI.Button(rect, "Add SoundFont"))
                    {
                        //if (EditorUtility.DisplayDialog("Import SoundFont", "This action could take time, do you confirm ?", "Ok", "Cancel"))
                        {
                            SoundFontOptim.AddSoundFont();
                            scrollPosSoundFont = Vector2.zero;
                            KeepAllPatchs      = false;
                            KeepAllZones       = false;
                            //listPatchs = PatchOptim.PatchUsed();
                        }
                    }
#else
                    if (GUI.Button(rect, "Add SoundFont [PRO]"))
                    {
                        try
                        {
                            PopupWindow.Show(rect, new GetVersionPro());
                        }
                        catch (Exception)
                        {
                            // generate some weird exception ...
                        }
                    }
#endif

                    Rect listVisibleRect = new Rect(localstartX, localstartY + itemHeight, width - 5, height - itemHeight - 5);
                    Rect listContentRect = new Rect(0, 0, width - 20, MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count * itemHeight + 5);

                    scrollPosSoundFont = GUI.BeginScrollView(listVisibleRect, scrollPosSoundFont, listContentRect);
                    float boxY = 0;

                    for (int i = 0; i < MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count; i++)
                    {
                        SoundFontInfo sf = MidiPlayerGlobal.CurrentMidiSet.SoundFonts[i];

                        GUI.color = new Color(.7f, .7f, .7f, 1f);
                        float boxX = 5;
                        GUI.Box(new Rect(boxX, boxY + 5, width - 30, itemHeight), "");
                        GUI.color = Color.white;

                        content = new GUIContent()
                        {
                            text = sf.Name, tooltip = ""
                        };
                        EditorGUI.LabelField(new Rect(boxX, boxY + 9, 200, itemHeight), content);

                        if (sf.Name == MidiPlayerGlobal.CurrentMidiSet.ActiveSounFontInfo.Name)
                        {
                            GUI.color = ToolsEditor.ButtonColor;
                        }

                        boxX += 200 + espace;
                        if (GUI.Button(new Rect(boxX, boxY + 9, 80, buttonHeight), "Select"))
                        {
#if MPTK_PRO
                            OptimInfo = new BuilderInfo();
#endif
                            MidiPlayerGlobal.CurrentMidiSet.SetActiveSoundFont(i);
                            string soundPath = Path.Combine(Application.dataPath + "/", MidiPlayerGlobal.PathToSoundfonts);
                            soundPath = Path.Combine(soundPath + "/", sf.Name);
                            ToolsEditor.LoadImSF(soundPath, sf.Name);
                            MidiPlayerGlobal.CurrentMidiSet.Save();
                            if (MidiPlayerGlobal.ImSFCurrent != null)
                            {
                                KeepAllPatchs     = MidiPlayerGlobal.ImSFCurrent.KeepAllPatchs;
                                KeepAllZones      = MidiPlayerGlobal.ImSFCurrent.KeepAllZones;
                                RemoveUnusedWaves = MidiPlayerGlobal.ImSFCurrent.RemoveUnusedWaves;
                                if (Application.isPlaying)
                                {
                                    MidiPlayerGlobal.MPTK_SelectSoundFont(null);
                                }
                            }
                            //listPatchs = PatchOptim.PatchUsed();
                        }
                        boxX += 80 + espace;

                        GUI.color = Color.white;
                        rect      = new Rect(boxX, boxY + 9, 80, buttonHeight);
                        if (GUI.Button(rect, "Remove"))
                        {
#if MPTK_PRO
                            OptimInfo = new BuilderInfo();
                            string soundFontPath = Path.Combine(Application.dataPath + "/", MidiPlayerGlobal.PathToSoundfonts);
                            string path          = Path.Combine(soundFontPath, sf.Name);
                            if (!string.IsNullOrEmpty(path) && EditorUtility.DisplayDialog("Delete SoundFont", "Are you sure to delete all the content of this folder ? " + path, "ok", "cancel"))
                            {
                                try
                                {
                                    Directory.Delete(path, true);
                                    File.Delete(path + ".meta");
                                }
                                catch (Exception ex)
                                {
                                    Debug.Log("Remove SF " + ex.Message);
                                }
                                AssetDatabase.Refresh();
                                ToolsEditor.CheckMidiSet();
                            }
#else
                            try
                            {
                                PopupWindow.Show(rect, new GetVersionPro());
                            }
                            catch (Exception)
                            {
                                // generate some weird exception ...
                            }
#endif
                        }

                        GUI.color = Color.white;

                        //boxX = 5;
                        //boxY += itemHeight;
                        //if (MidiPlayerGlobal.ImSFCurrent.WaveSize < 1000000)
                        //    strSize = Math.Round((double)MidiPlayerGlobal.ImSFCurrent.WaveSize / 1000d).ToString() + " Ko";
                        //else
                        //    strSize = Math.Round((double)MidiPlayerGlobal.ImSFCurrent.WaveSize / 1000000d).ToString() + " Mo";
                        //string.Format("Patch count: {0} Wave count:{1} Wave size:{2}", MidiPlayerGlobal.ImSFCurrent.PatchCount, MidiPlayerGlobal.ImSFCurrent.WaveCount, strSize);

                        //content = new GUIContent() { text = sf.Name, tooltip = "" };
                        //EditorGUI.LabelField(new Rect(boxX, boxY + 9, 200, itemHeight), content);

                        boxY += itemHeight;
                    }
                    GUI.EndScrollView();
                }
            }
            catch (Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
        }
예제 #7
0
        public static void LoadCurrentSF()
        {
            // Load simplfied soundfont
            try
            {
                DateTime start = DateTime.Now;
                if (CurrentMidiSet == null)
                {
                    Debug.LogWarning("No SoundFont defined, go to Unity menu Tools to add a Soundfont");
                }
                else
                {
                    SoundFontInfo sfi = CurrentMidiSet.ActiveSounFontInfo;
                    if (sfi == null)
                    {
                        Debug.LogWarning("No SoundFont defined, go to Unity menu Tools to add a Soundfont");
                    }
                    else
                    {
                        // Path to the soundfonts directory for this SF, start from resource folder
                        string pathToImSF = Path.Combine(SoundfontsDB + "/", sfi.Name);
                        // Path to the soundfonts file for this SF
                        TextAsset sf = Resources.Load <TextAsset>(Path.Combine(pathToImSF + "/", sfi.Name));
                        if (sf == null)
                        {
                            Debug.LogWarning("No SoundFont found " + pathToImSF);
                        }
                        else
                        {
                            WavePath = Path.Combine(pathToImSF + "/", PathToWave);
                            // Load all presets defined in the XML sf
                            ImSFCurrent         = ImSoundFont.Load(sf.text);
                            timeToLoadSoundFont = DateTime.Now - start;
                            BuildPresetList();
                            BuildDrumList();
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }

            if (ImSFCurrent == null)
            {
                Debug.LogWarning("SoundFont not loaded.");
                return;
            }

            // Load samples only in run mode
            if (Application.isPlaying)
            {
                try
                {
                    MPTK_CountWaveLoaded   = 0;
                    MPTK_CountPresetLoaded = 0;
                    DateTime start = DateTime.Now;
                    for (int ibank = 0; ibank < ImSFCurrent.Banks.Length; ibank++)
                    {
                        if (ImSFCurrent.Banks[ibank] != null)
                        {
                            for (int ipreset = 0; ipreset < ImSFCurrent.Banks[ibank].Presets.Length; ipreset++)
                            {
                                MPTK_CountPresetLoaded++;
                                if (ImSFCurrent.Banks[ibank].Presets[ipreset] != null)
                                {
                                    LoadSamples(ibank, ipreset);
                                }
                            }
                        }
                    }
                    timeToLoadWave = DateTime.Now - start;
                }
                catch (System.Exception ex)
                {
                    MidiPlayerGlobal.ErrorDetail(ex);
                }
            }
            if (OnEventPresetLoaded != null)
            {
                OnEventPresetLoaded.Invoke();
            }
        }
        /// <summary>
        /// Display, add, remove Soundfont
        /// </summary>
        /// <param name="localstartX"></param>
        /// <param name="localstartY"></param>
        private void ShowListSoundFonts(float startX, float startY, float width, float height)
        {
            try
            {
                if (columnSF == null)
                {
                    columnSF          = new ToolsEditor.DefineColumn[6];
                    columnSF[0].Width = 215; columnSF[0].Caption = "SoundFont Name"; columnSF[0].PositionCaption = 1f;
                    columnSF[1].Width = 40; columnSF[1].Caption = "Patch"; columnSF[1].PositionCaption = 6f;
                    columnSF[2].Width = 45; columnSF[2].Caption = "Wave"; columnSF[2].PositionCaption = 15f;
                    columnSF[3].Width = 60; columnSF[3].Caption = "Size"; columnSF[3].PositionCaption = 25f;
                    columnSF[4].Width = 85; columnSF[4].Caption = "SoundFont"; columnSF[4].PositionCaption = 5f;
                    columnSF[5].Width = 50; columnSF[5].Caption = "Remove"; columnSF[5].PositionCaption = -7f;
                }

                Rect zone = new Rect(startX, startY, width, height);
                //GUI.color = new Color(.8f, .8f, .8f, 1f);
                GUI.Box(zone, "", stylePanel);
                GUI.color = Color.white;
                float      localstartX = 0;
                float      localstartY = 0;
                GUIContent content;
                if (MidiPlayerGlobal.CurrentMidiSet != null && MidiPlayerGlobal.CurrentMidiSet.SoundFonts != null && MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count > 0)
                {
                    content = new GUIContent()
                    {
                        text = "SoundFont available", tooltip = "Each SoundFonts contains a set of bank of sound. \nOnly one SoundFont can be active at the same time for the midi player"
                    }
                }
                ;
                else
                {
                    content = new GUIContent()
                    {
                        text = "No SoundFont found, click on button 'Add SoundFont'", tooltip = "See the documentation here https://paxstellar.fr/"
                    };
                    MidiPlayerGlobal.ImSFCurrent = null;
                }
                localstartX += xpostitlebox;
                localstartY += ypostitlebox;
                EditorGUI.LabelField(new Rect(startX + localstartX + 5, startY + localstartY, width, titleHeight), content, styleBold);
                localstartY += titleHeight;

#if MPTK_PRO
                if (GUI.Button(new Rect(startX + localstartX + espace, startY + localstartY, buttonLargeWidth, buttonHeight), "Add SoundFont"))
                {
                    if (Application.isPlaying)
                    {
                        EditorUtility.DisplayDialog("Add a SoundFont", "This action is not possible when application is running.", "Ok");
                    }
                    else
                    {
                        //if (EditorUtility.DisplayDialog("Import SoundFont", "This action could take time, do you confirm ?", "Ok", "Cancel"))
                        {
                            this.AddSoundFont();
                            scrollPosSoundFont = Vector2.zero;
                        }
                    }
                }
#else
                if (GUI.Button(new Rect(startX + localstartX + espace, startY + localstartY, buttonLargeWidth, buttonHeight), "Add a new SoundFont [PRO]"))
                {
                    PopupWindow.Show(new Rect(startX + localstartX, startY + localstartY, buttonLargeWidth, buttonHeight), new GetFullVersion());
                }
#endif
                if (GUI.Button(new Rect(startX + localstartX + width - 65, startY + localstartY - 18, 35, 35), buttonIconHelp))
                {
                    //CreateWave createwave = new CreateWave();
                    //string path = System.IO.Path.Combine(MidiPlayerGlobal.MPTK_PathToResources, "unitySample") + ".wav";
                    ////string path = "unitySample.wav";
                    //HiSample sample = new HiSample();
                    ////sample.LoopStart = sample.LoopEnd = 0;
                    //byte[] data = new byte[10000];
                    //for (int i = 0; i < data.Length; i++) data[i] = (byte)255;
                    //sample.SampleRate = 44100;
                    //sample.End = (uint)data.Length/2;
                    //createwave.Build(path, sample, data);
                    Application.OpenURL("https://paxstellar.fr/setup-mptk-add-soundfonts-v2/");
                }

                localstartY += buttonHeight + espace;

                // Draw title list box
                GUI.Box(new Rect(startX + localstartX + espace, startY + localstartY, width - 35, itemHeight), "", styleListTitle);
                float boxX = startX + localstartX + espace;
                foreach (ToolsEditor.DefineColumn column in columnSF)
                {
                    GUI.Label(new Rect(boxX + column.PositionCaption, startY + localstartY, column.Width, itemHeight), column.Caption, styleLabelLeft);
                    boxX += column.Width;
                }

                localstartY += itemHeight + espace;

                if (MidiPlayerGlobal.CurrentMidiSet != null && MidiPlayerGlobal.CurrentMidiSet.SoundFonts != null && MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count > 0)
                {
                    Rect listVisibleRect = new Rect(startX + localstartX, startY + localstartY - 6, width - 10, height - localstartY);
                    Rect listContentRect = new Rect(0, 0, width - 25, MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count * itemHeight + 5);

                    scrollPosSoundFont = GUI.BeginScrollView(listVisibleRect, scrollPosSoundFont, listContentRect, false, true);
                    float boxY = 0;

                    // Loop on each soundfont
                    for (int i = 0; i < MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count; i++)
                    {
                        SoundFontInfo sf       = MidiPlayerGlobal.CurrentMidiSet.SoundFonts[i];
                        bool          selected = (MidiPlayerGlobal.ImSFCurrent != null && sf.Name == MidiPlayerGlobal.CurrentMidiSet.ActiveSounFontInfo.Name);

                        // Draw a row
                        GUI.Box(new Rect(espace, boxY, width - 35, itemHeight), "", selected ? styleListRowSelected : styleListRow);

                        // Start content position (from the visible rect)
                        boxX = espace;

                        // col 1 - name
                        float colw = columnSF[0].Width;
                        EditorGUI.LabelField(new Rect(boxX + 1, boxY + 2, colw, itemHeight - 5), sf.Name, styleLabelLeft);
                        boxX += colw;

                        // col 2 - patch count
                        colw = columnSF[1].Width;
                        EditorGUI.LabelField(new Rect(boxX, boxY + 3, colw, itemHeight - 7), sf.PatchCount.ToString(), styleLabelRight);
                        boxX += colw;

                        // col 3 - wave count
                        colw = columnSF[2].Width;
                        EditorGUI.LabelField(new Rect(boxX, boxY + 3, colw, itemHeight - 7), sf.WaveCount.ToString(), styleLabelRight);
                        boxX += colw;

                        // col 4 - size
                        colw = columnSF[3].Width;
                        string sizew = (sf.WaveSize < 1000000) ?
                                       Math.Round((double)sf.WaveSize / 1000d).ToString() + " Ko" :
                                       Math.Round((double)sf.WaveSize / 1000000d).ToString() + " Mo";
                        EditorGUI.LabelField(new Rect(boxX, boxY + 3, colw, itemHeight - 7), sizew, styleLabelRight);
                        boxX += colw;

                        string textselect = "Select";
                        if (MidiPlayerGlobal.ImSFCurrent != null && sf.Name == MidiPlayerGlobal.CurrentMidiSet.ActiveSounFontInfo.Name)
                        {
                            textselect = "Default";// GUI.color = ToolsEditor.ButtonColor;
                        }
                        // col 5 - select and remove buttons
                        colw  = columnSF[4].Width;
                        boxX += 10;
                        if (GUI.Button(new Rect(boxX, boxY + 3, buttonMediumWidth, buttonHeight), textselect))
                        {
#if MPTK_PRO
                            this.SelectSf(i);
#else
                            PopupWindow.Show(new Rect(boxX, boxY + 3, buttonMediumWidth, buttonHeight), new GetFullVersion());
#endif
                        }
                        boxX += colw;

                        colw = columnSF[5].Width;
                        if (GUI.Button(new Rect(boxX, boxY + 3, 30, buttonHeight), new GUIContent(buttonIconDelete, "Remove SoundFont and samples associated")))
                        {
#if MPTK_PRO
                            if (Application.isPlaying)
                            {
                                EditorUtility.DisplayDialog("Remove a SoundFont", "This action is not possible when application is running.", "Ok");
                            }
                            else
                            {
                                if (this.DeleteSf(i))
                                {
                                    if (MidiPlayerGlobal.CurrentMidiSet.SoundFonts.Count > 0)
                                    {
                                        this.SelectSf(0);
                                    }
                                    else
                                    {
                                        MidiPlayerGlobal.ImSFCurrent = null;
                                    }
                                }
                            }
#else
                            PopupWindow.Show(new Rect(boxX, boxY + 3, 30, buttonHeight), new GetFullVersion());
#endif
                        }
                        boxX += colw;

                        boxY += itemHeight - 1;
                    }
                    GUI.EndScrollView();
                }
            }
            catch (ExitGUIException) { }
            catch (Exception ex)
            {
                MidiPlayerGlobal.ErrorDetail(ex);
            }
        }