예제 #1
0
    string ConvertToCaff(SoundsCategory cat, SoundItem item, SoundSubItem subItem)
    {
        int    bitrate    = 96;
        string sourcePath = Application.dataPath + subItem.clipref.FullPath.Substring(6);
        string fileName   = System.IO.Path.GetFileNameWithoutExtension(sourcePath);

        string projectDir  = "/StreamingAssets/Audio/iOS/" + cat.Name + "/" + item.Name + "/";
        string projectPath = projectDir + fileName + ".caf";

        string targetDir       = Application.dataPath + projectDir;
        string destanationPath = targetDir + fileName + ".caf";

        System.IO.Directory.CreateDirectory(targetDir);

        string channels = "";

        if (cat.SoundSettingsOverride != null && cat.SoundSettingsOverride.gameObject.name.Contains("3D"))
        {
            channels = " -c 1";
        }

        string attributes = string.Format("-f 'caff' -d aac -s 2 -b {0}000 {3} {1} {2}", bitrate, sourcePath, destanationPath, channels);

        //                            Debug.Log(attributes);

        System.Diagnostics.Process p = System.Diagnostics.Process.Start("afconvert", attributes);
        p.WaitForExit();

        return(projectPath);
    }
예제 #2
0
    internal void Initialize(SoundsCategory categ)
    {
        Category = categ;

        for (int i = 0; i < subItems.Length; i++)
        {
            subItems[i].Initialize(this);
        }

        ComputeNormalizedProbability();
    }
예제 #3
0
 public SoundsCategory GetCategory(string categoryName)
 {
     for (int i = 0; i < AudioCategories.Length; i++)
     {
         SoundsCategory cat = AudioCategories[i];
         if (cat.Name.Equals(categoryName))
         {
             return(cat);
         }
     }
     return(null);
 }
예제 #4
0
    static public float GetCategoryVolume(string categoryName)
    {
        SoundsCategory category = Instance.GetCategory(categoryName);

        if (category != null)
        {
            return(category.Volume);
        }
        else
        {
            Debug.LogWarning("No audio category with name " + categoryName);
            return(0);
        }
    }
예제 #5
0
    internal bool DoesBelongToCategory(string categoryName)
    {
        SoundsCategory curCategory = SubItem.Item.Category;

        while (curCategory != null)
        {
            if (curCategory.Name == categoryName)
            {
                return(true);
            }
            curCategory = curCategory.ParentCategory;
        }
        return(false);
    }
예제 #6
0
    internal Dictionary <string, SoundItem> AllSoundItems()
    {
        items.Clear();
        for (int i = 0; i < AudioCategories.Length; i++)
        {
            SoundsCategory category = AudioCategories[i];
            for (int j = 0; j < category.AudioItems.Length; j++)
            {
                SoundItem item = category.AudioItems[j];
                items.Add(item.Name, item);
            }
        }

        return(items);
    }
예제 #7
0
    public static void SetCategoryVolume(string categoryName, float volume)
    {
        bool           found = false;
        SoundsCategory cat   = Instance.GetCategory(categoryName);

        if (cat != null)
        {
            cat.Volume = volume;
            found      = true;
        }

        if (!found)
        {
            Debug.LogWarning("No audio category with name " + categoryName);
        }
    }
예제 #8
0
    bool _IsCategoryChildOf(SoundsCategory toTest, SoundsCategory parent)
    {
        var cat = toTest;

        while (cat != null)
        {
            if (cat.SoundsManager == null)
            {
                cat.SoundsManager = AC;
            }

            if (cat == parent)
            {
                return(true);
            }

            cat = cat.ParentCategory;
        }
        return(false);
    }
예제 #9
0
    private string[] GetItemNames()
    {
        SoundsCategory curCat = currentCategory;

        if (curCat == null || curCat.AudioItems == null)
        {
            return(new string[0]);
        }

        var names = new string[curCat.AudioItems.Length];

        for (int i = 0; i < curCat.AudioItems.Length; i++)
        {
            names[i] = curCat.AudioItems[i] != null ? curCat.AudioItems[i].Name : "";

            if (names[i] == _nameForNewAudioItemEntry)
            {
                names[i] = "---";
            }
        }
        return(names);
    }
예제 #10
0
    public SoundObject PlayAudioSubItem(SoundsCategory audioCategory, SoundItem audioItem, SoundSubItem subItem, Vector3 worldPosition, Transform parentObj, bool playWithoutAudioObject, SoundObject existingAudioObj, System.Action <SoundObject> onLoad = null)
    {
        GameObject audioPrefab = GetPrefabForSoundType(subItem.SubItemType);

        if (audioPrefab == null)
        {
            Debug.LogError("missing prefab for sound : " + audioCategory.Name + "/" + audioItem.Name + "   with type : " + subItem.SubItemType);
            Debug.LogError(subItem.clipref.FullPath);
            return(null);
        }

        //volume
        float subItemVolume = subItem.Volume;

        if (subItem.RandomVolume != 0)
        {
            subItemVolume += UnityEngine.Random.Range(-subItem.RandomVolume, subItem.RandomVolume);
            subItemVolume  = Mathf.Clamp01(subItemVolume);
        }
        float masterVolume = Volume * audioCategory.VolumeTotal * audioItem.Volume;
        float totalVolume  = masterVolume * subItemVolume;

        if (!PlayWithZeroVolume && (totalVolume <= 0))
        {
            return(null);
        }

        SoundSettings audioSettings = SoundSettings;

        if (audioCategory.SoundSettingsOverride != null)
        {
            audioSettings = audioCategory.SoundSettingsOverride;
        }
        if (audioItem.SoundSettingsOverride != null)
        {
            audioSettings = audioItem.SoundSettingsOverride;
        }


        GameObject  sndObjInstance;
        SoundObject sndObj;

        if (existingAudioObj == null)
        {
            sndObjInstance = (GameObject)ObjectPoolController.Instantiate(audioPrefab, worldPosition, Quaternion.identity);
            if (!audioItem.DestroyOnLoad)
            {
                Object.DontDestroyOnLoad(sndObjInstance);
            }

            sndObjInstance.transform.parent = parentObj ? parentObj : transform;
            sndObj = sndObjInstance.gameObject.GetComponent <SoundObject>();
        }
        else
        {
            sndObjInstance = existingAudioObj.gameObject;
            sndObj         = existingAudioObj;
        }
        sndObjInstance.name = "SoundObject:" + subItem.Name;


        sndObj.SubItem = subItem;
        sndObj.ApplySettings(audioSettings);
        //sndObj.primaryAudioSource.rolloffMode = AudioRolloffMode.Linear;

//        float startTime = subItem.RandomStartPosition ? UnityEngine.Random.Range( 0, sndObj.clipLength ) : 0;
//        sndObj.primaryAudioSource.time = startTime + subItem.ClipStartTime;

        if (audioItem.overrideAudioSourceSettings)
        {
            sndObj.MinDistance = audioItem.audioSource_MinDistance;
            sndObj.MaxDistance = audioItem.audioSource_MaxDistance;
        }

        sndObj.Volume       = subItemVolume;
        sndObj.MasterVolume = masterVolume;
        sndObj.Loop         = (audioItem.Loop == SoundLoopMode.LoopSubitem);
        sndObj.Pan          = subItem.Pan2D;
        sndObj.Pitch        = subItem.GetPitch();

        float delay = 0;

        if (subItem.RandomDelay > 0)
        {
            delay += UnityEngine.Random.Range(0, subItem.RandomDelay);
        }

        sndObj.Play(delay + subItem.Delay + audioItem.Delay, subItem.FadeIn);


        if (onLoad != null)
        {
            onLoad(sndObj);
        }

        return(sndObj);
    }
예제 #11
0
    private string[] _GenerateCategoryListIncludingNone(out int selectedParentCategoryIndex, SoundsCategory selectedAudioCategory)
    {
        string[] names;
        selectedParentCategoryIndex = 0;

        if (AC.AudioCategories != null)
        {
            names = new string[AC.AudioCategories.Length];

            int index = 1;

            var curCat = currentCategory;

            for (int i = 0; i < AC.AudioCategories.Length; i++)
            {
                if (_IsCategoryChildOf(AC.AudioCategories[i], curCat))       // prevent loops in tree
                {
                    continue;
                }
                names[index] = AC.AudioCategories[i].Name;
                if (selectedAudioCategory == AC.AudioCategories[i])
                {
                    selectedParentCategoryIndex = index;
                }

                index++;
                if (index == names.Length)
                {
                    break; // in case currentCategory is not found
                }
            }

            if (index < names.Length)
            {
                var newNames = new string[index];
                Array.Copy(names, newNames, index);
                names = newNames;
            }
        }
        else
        {
            names = new string[1];
        }

        names[0] = "*none*";
        return(names);
    }
예제 #12
0
    public override void OnInspectorGUI()
    {
        SetStyles();

        BeginInspectorGUI();

        _ValidateCurrentCategoryIndex();
        _ValidateCurrentItemIndex();
        _ValidateCurrentSubItemIndex();

        if (lastCategoryIndex != currentCategoryIndex ||
            lastItemIndex != currentItemIndex ||
            lastSubItemIndex != currentSubitemIndex)
        {
            GUIUtility.keyboardControl = 0; // workaround for Unity weirdness not changing the value of a focused GUI element when changing a category/item
            lastCategoryIndex          = currentCategoryIndex;
            lastItemIndex    = currentItemIndex;
            lastSubItemIndex = currentSubitemIndex;
        }


        EditorGUILayout.Space();

        if (globalFoldout = EditorGUILayout.Foldout(globalFoldout, "Global Audio Settings", foldoutStyle))
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Streaming Audio Buffer", labelFieldOption);
            AC.StreamingAudioBuffer = EditorGUILayout.ObjectField(AC.StreamingAudioBuffer, typeof(StreamingAudioBuffer), true) as StreamingAudioBuffer;
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Audio listener", labelFieldOption);
            AC.AudioListenerReference = EditorGUILayout.ObjectField(AC.AudioListenerReference, typeof(AudioListener), true) as AudioListener;
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Simple Sound Prefab", labelFieldOption);
            AC.SimpleSoundPrefab = EditorGUILayout.ObjectField(AC.SimpleSoundPrefab, typeof(SoundObject), true) as SoundObject;
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Stream Sound Prefab", labelFieldOption);
            AC.StreamingSoundPrefab = EditorGUILayout.ObjectField(AC.StreamingSoundPrefab, typeof(SoundObject), true) as SoundObject;
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("Native Sound Prefab", labelFieldOption);
            AC.NativeSoundPrefab = EditorGUILayout.ObjectField(AC.NativeSoundPrefab, typeof(SoundObject), true) as SoundObject;
            EditorGUILayout.EndHorizontal();

            EditBool(ref AC.Persistent, "Persist Scene Loading", "A non-persisting AudioController will get destroyed when loading the next scene.");
            EditBool(ref AC.UnloadAudioClipsOnDestroy, "Unload Audio On Destroy", "This option will unload all AudioClips from memory which referenced by this AudioController if the controller gets destroyed (e.g. when loading a new scene and the AudioController is not persistent). \n" +
                     "Use this option in combination with additional none-persistent AudioControllers to keep only those audios in memory that are used by the current scene. Use the primary persistent AudioController for all global audio that is used throughout all scenes."
                     );

            bool currentlyDisabled = AC.DisableAudio;

            bool changed = EditBool(ref currentlyDisabled, "Disable Audio", "Disables all audio");
            if (changed)
            {
                AC.DisableAudio = currentlyDisabled;
            }

            float vol = AC.Volume;

            EditFloat01(ref vol, "Volume", "%");

            AC.Volume = vol;

            EditPrefab(ref AC.SoundSettings, "Sound Settings", "You may specify a prefab here that will contains settings for all sounds");
            EditBool(ref AC.UsePooledAudioObjects, "Use Pooled AudioObjects", "Pooling increases performance when playing many audio files. Strongly recommended particularly on mobile platforms.");
            EditBool(ref AC.PlayWithZeroVolume, "Play With Zero Volume", "If disabled Play() calls with a volume of zero will not create an AudioObject.");
        }

        VerticalSpace();


        int categoryCount = AC.AudioCategories != null ? AC.AudioCategories.Length : 0;

        currentCategoryIndex = Mathf.Clamp(currentCategoryIndex, 0, categoryCount - 1);

        if (categoryFoldout = EditorGUILayout.Foldout(categoryFoldout, "Category Settings", foldoutStyle))
        {
            // Audio Items
            EditorGUILayout.BeginHorizontal();

            bool justCreatedNewCategory = false;

            var categoryNames = GetCategoryNames();

            int newCategoryIndex = PopupWithStyle("Category", currentCategoryIndex, categoryNames, popupStyleColored);
            if (GUILayout.Button("+", GUILayout.Width(30)))
            {
                bool lastEntryIsNew = false;

                if (categoryCount > 0)
                {
                    lastEntryIsNew = AC.AudioCategories[currentCategoryIndex].Name == _nameForNewCategoryEntry;
                }

                if (!lastEntryIsNew)
                {
                    newCategoryIndex = AC.AudioCategories != null ? AC.AudioCategories.Length : 0;
                    ArrayHelper.AddArrayElement(ref AC.AudioCategories, new SoundsCategory(AC));
                    AC.AudioCategories[newCategoryIndex].Name = _nameForNewCategoryEntry;
                    justCreatedNewCategory = true;
                    KeepChanges();
                }
            }

            if (GUILayout.Button("-", GUILayout.Width(30)) && categoryCount > 0)
            {
                if (currentCategoryIndex < AC.AudioCategories.Length - 1)
                {
                    newCategoryIndex = currentCategoryIndex;
                }
                else
                {
                    newCategoryIndex = Mathf.Max(currentCategoryIndex - 1, 0);
                }
                ArrayHelper.DeleteArrayElement(ref AC.AudioCategories, currentCategoryIndex);
                KeepChanges();
            }

            EditorGUILayout.EndHorizontal();

            if (newCategoryIndex != currentCategoryIndex)
            {
                currentCategoryIndex = newCategoryIndex;
                currentItemIndex     = 0;
                currentSubitemIndex  = 0;
                _ValidateCurrentItemIndex();
                _ValidateCurrentSubItemIndex();
            }


            SoundsCategory curCat = currentCategory;

            if (curCat != null)
            {
                if (curCat.SoundsManager == null)
                {
                    curCat.SoundsManager = AC;//TODO ???
                }
                if (justCreatedNewCategory)
                {
                    SetFocusForNextEditableField();
                }
                EditString(ref curCat.Name, "Name", curCat.Name == _nameForNewCategoryEntry ? textAttentionStyle : null);

                float volTmp = curCat.Volume;
                EditFloat01(ref volTmp, "Volume", " %");
                curCat.Volume = volTmp;

                EditPrefab(ref curCat.SoundSettingsOverride, "Sound Settings Override", "Use different settinfs if you want to specify different parameters such as the volume rolloff etc. per category");

                int selectedParentCategoryIndex;

                var catList = _GenerateCategoryListIncludingNone(out selectedParentCategoryIndex, curCat.ParentCategory);

                int newIndex = Popup("Parent Category", selectedParentCategoryIndex, catList, "The effective volume of a category is multiplied with the volume of the parent category.");
                if (newIndex != selectedParentCategoryIndex)
                {
                    KeepChanges();

                    if (newIndex <= 0)
                    {
                        curCat.ParentCategory = null;
                    }
                    else
                    {
                        curCat.ParentCategory = _GetCategory(catList[newIndex]);
                    }
                }

                int itemCount = currentItemCount;
                _ValidateCurrentItemIndex();

                VerticalSpace();

                SoundItem curItem = currentItem;

                if (itemFoldout = EditorGUILayout.Foldout(itemFoldout, "Audio Item Settings", foldoutStyle))
                {
                    EditorGUILayout.BeginHorizontal();
                    if (GUILayout.Button("Add selected audio clips", EditorStyles.miniButton))//TODO ???
                    {
                        UnityEngine.Object[] audioClips = GetSelectedAudioObjects();
                        if (audioClips.Length > 0)
                        {
                            int firstIndex = itemCount;
                            currentItemIndex = firstIndex;
                            foreach (AudioClip audioClip in audioClips)
                            {
                                ArrayHelper.AddArrayElement(ref curCat.AudioItems);
                                SoundItem audioItem = curCat.AudioItems[currentItemIndex];
                                audioItem.Name = audioClip.name;
                                ArrayHelper.AddArrayElement(ref audioItem.subItems).Clip = audioClip;
                                currentItemIndex++;
                            }
                            currentItemIndex = firstIndex;
                            KeepChanges();
                        }
                    }

                    GUILayout.Label("use inspector lock!");
                    EditorGUILayout.EndHorizontal();

                    // AudioItems

                    EditorGUILayout.BeginHorizontal();

                    int  newItemIndex       = PopupWithStyle("Item", currentItemIndex, GetItemNames(), popupStyleColored);
                    bool justCreatedNewItem = false;


                    if (GUILayout.Button("+", GUILayout.Width(30)))
                    {
                        bool lastEntryIsNew = false;

                        if (itemCount > 0)
                        {
                            lastEntryIsNew = curCat.AudioItems[currentItemIndex].Name == _nameForNewAudioItemEntry;
                        }

                        if (!lastEntryIsNew)
                        {
                            newItemIndex = curCat.AudioItems != null ? curCat.AudioItems.Length : 0;
                            ArrayHelper.AddArrayElement(ref curCat.AudioItems);
                            curCat.AudioItems[newItemIndex].Name = _nameForNewAudioItemEntry;
                            justCreatedNewItem = true;
                            KeepChanges();
                        }
                    }

                    if (GUILayout.Button("-", GUILayout.Width(30)) && itemCount > 0)
                    {
                        if (currentItemIndex < curCat.AudioItems.Length - 1)
                        {
                            newItemIndex = currentItemIndex;
                        }
                        else
                        {
                            newItemIndex = Mathf.Max(currentItemIndex - 1, 0);
                        }
                        ArrayHelper.DeleteArrayElement(ref curCat.AudioItems, currentItemIndex);
                        KeepChanges();
                    }



                    if (newItemIndex != currentItemIndex)
                    {
                        currentItemIndex    = newItemIndex;
                        currentSubitemIndex = 0;
                        _ValidateCurrentSubItemIndex();
                    }

                    curItem = currentItem;

                    EditorGUILayout.EndHorizontal();

                    if (curItem != null)
                    {
                        GUILayout.BeginHorizontal();
                        if (justCreatedNewItem)
                        {
                            SetFocusForNextEditableField();
                        }

                        bool isNewDummyName = curItem.Name == _nameForNewAudioItemEntry;
                        EditString(ref curItem.Name, "Name", isNewDummyName ? textAttentionStyle : null, "You must specify a unique name here (=audioID). This is the ID used in the script code to play this audio item.");

                        GUILayout.EndHorizontal();

                        int newItemCategoryIndex = Popup("Move to Category", currentCategoryIndex, GetCategoryNames());

                        if (newItemCategoryIndex != currentCategoryIndex)
                        {
                            var newCat = AC.AudioCategories[newItemCategoryIndex];
                            var oldCat = currentCategory;
                            ArrayHelper.AddArrayElement(ref newCat.AudioItems, curItem);
                            ArrayHelper.DeleteArrayElement(ref oldCat.AudioItems, currentItemIndex);
                            currentCategoryIndex = newItemCategoryIndex;
                            KeepChanges();
                            //AC.InitializeAudioItems(); //TODO
                            currentItemIndex = newCat.AudioItems.Length - 1;
                        }

                        if (EditFloat01(ref curItem.Volume, "Volume", " %"))
                        {
                            _AdjustVolumeOfAllAudioItems(curItem, null);
                        }

                        EditFloat(ref curItem.Delay, "Delay", "sec", "Delays the playback"); //TODO
                        EditInt(ref curItem.MaxInstanceCount, "Max Instance Count", "", "Sets the maximum number of simultaneously playing audio files of this particular audio item. If the maximum number would be exceeded, the oldest playing audio gets stopped.");
                        EditBool(ref curItem.SkipWhenExeeded, "Skip sound if Exeeded Limit", "");
                        EditBool(ref curItem.DestroyOnLoad, "Stop When Scene Loads", "If disabled, this audio item will continue playing even if a different scene is loaded.");
                        //TODO override prefab

                        curItem.Loop = (SoundLoopMode)EnumPopup("Loop Mode", curItem.Loop, "The Loop mode determines how the audio subitems are looped. \n'LoopSubitem' means that the chosen sub-item will loop. \n'LoopSequence' means that one subitem is played after the other. In which order the subitems are chosen depends on the subitem pick mode.");
                        if (curItem.Loop == SoundLoopMode.LoopSubitem)
                        {
                            EditFloat(ref curItem.OverlapTime, "When Overlap", "sec", "define time when start next clip"); //TODO
                        }
                        curItem.SubItemPickMode = (SoundPickSubItemMode)EnumPopup("Pick Subitem Mode", curItem.SubItemPickMode, "Determines which subitem is chosen when the audio item is played.");

                        EditPrefab(ref curItem.SoundSettingsOverride, "Sound Settings Override", "Use different settinfs if you want to specify different parameters such as the volume rolloff etc. per item");

                        EditBool(ref curItem.overrideAudioSourceSettings, "Override AudioSource Settings");
                        if (curItem.overrideAudioSourceSettings)
                        {
                            //EditorGUI.indentLevel++;

                            EditFloat(ref curItem.audioSource_MinDistance, "   Min Distance", "", "Overrides the 'Min Distance' parameter in the AudioSource settings of the AudioObject prefab (for 3d sounds)");
                            EditFloat(ref curItem.audioSource_MaxDistance, "   Max Distance", "", "Overrides the 'Max Distance' parameter in the AudioSource settings of the AudioObject prefab (for 3d sounds)");

                            //EditorGUI.indentLevel--;
                        }

                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Label("");

                        if (GUILayout.Button("Play", GUILayout.Width(60)) && curItem != null)
                        {
                            if (_IsAudioControllerInPlayMode())
                            {
                                SoundsManager.Play(curItem.Name);
                            }
                        }

                        EditorGUILayout.EndHorizontal();
                        VerticalSpace();

                        int subItemCount = curItem.subItems != null ? curItem.subItems.Length : 0;
                        currentSubitemIndex = Mathf.Clamp(currentSubitemIndex, 0, subItemCount - 1);
                        SoundSubItem subItem = currentSubItem;

                        if (subitemFoldout = EditorGUILayout.Foldout(subitemFoldout, "Audio Sub-Item Settings", foldoutStyle))
                        {
                            EditorGUILayout.BeginHorizontal();
                            if (GUILayout.Button("Add selected audio clips", EditorStyles.miniButton))
                            {
                                UnityEngine.Object[] audioObjects = GetSelectedAudioObjects();
                                if (audioObjects.Length > 0)
                                {
                                    int firstIndex = subItemCount;
                                    currentSubitemIndex = firstIndex;
                                    foreach (UnityEngine.Object audioObject in audioObjects)
                                    {
                                        SoundSubItem cSubItem = ArrayHelper.AddArrayElement(ref curItem.subItems);
                                        cSubItem.Clip = audioObject;
                                        currentSubitemIndex++;
                                    }
                                    currentSubitemIndex = firstIndex;
                                    KeepChanges();
                                }
                            }
                            GUILayout.Label("use inspector lock!");
                            EditorGUILayout.EndHorizontal();

                            EditorGUILayout.BeginHorizontal();

                            currentSubitemIndex = PopupWithStyle("SubItem", currentSubitemIndex, GetSubitemNames(), popupStyleColored);

                            if (GUILayout.Button("+", GUILayout.Width(30)))
                            {
                                bool lastEntryIsNew = false;

                                SoundClipType curSubItemType = SoundClipType.Clip;

                                if (subItemCount > 0)
                                {
                                    curSubItemType = curItem.subItems[currentSubitemIndex].SubItemType;
                                    if (curSubItemType == SoundClipType.Clip)
                                    {
                                        lastEntryIsNew = curItem.subItems[currentSubitemIndex].Clip == null;
                                    }
                                }

                                if (!lastEntryIsNew)
                                {
                                    currentSubitemIndex = subItemCount;
                                    ArrayHelper.AddArrayElement(ref curItem.subItems);
                                    KeepChanges();
                                }
                            }

                            if (GUILayout.Button("-", GUILayout.Width(30)) && subItemCount > 0)
                            {
                                ArrayHelper.DeleteArrayElement(ref curItem.subItems, currentSubitemIndex);
                                if (currentSubitemIndex >= curItem.subItems.Length)
                                {
                                    currentSubitemIndex = Mathf.Max(curItem.subItems.Length - 1, 0);
                                }
                                KeepChanges();
                            }
                            EditorGUILayout.EndHorizontal();

                            subItem = currentSubItem;

                            if (subItem != null)
                            {
                                _SubitemTypePopup(subItem);
                                _DisplaySubItem_Clip(subItem, subItemCount, curItem);
                            }
                        }
                    }
                }
            }
        }

        VerticalSpace();

        EditorGUILayout.Space();

        if (EditorApplication.isPlaying)
        {
            EditorGUILayout.BeginHorizontal();
            if (GUILayout.Button("Stop All Sounds"))
            {
                if (EditorApplication.isPlaying && SoundsManager.InstanceIfExist)
                {
                    SoundsManager.StopAllSounds();
                }
            }
            EditorGUILayout.EndHorizontal();
        }

        EndInspectorGUI();

        #if AUDIO_PLUGIN
        if (GUILayout.Button("convert from audio controller"))
        {
            AudioController audio = GameObjectExtension.GetAllObjectsInScene <AudioController>()[0];
            AC.AudioCategories = new SoundsCategory[audio.AudioCategories.Length];

            for (int i = 0; i < audio.AudioCategories.Length; i++)
            {
                AudioCategory cat = audio.AudioCategories[i];

                SoundsCategory scat = new SoundsCategory(AC);
                scat.AudioItems = new SoundItem[cat.AudioItems.Length];
                scat.Name       = cat.Name;
                scat.Volume     = cat.Volume;
                if (cat.parentCategory != null)
                {
                    scat.ParentCategory = SoundsManager.Instance.GetCategory(cat.parentCategory.Name);
                }
                AC.AudioCategories[i] = scat;

                for (int j = 0; j < cat.AudioItems.Length; j++)
                {
                    AudioItem item = cat.AudioItems[j];

                    SoundItem sitem = new SoundItem();
                    sitem.subItems                    = new SoundSubItem[item.subItems.Length];
                    sitem.Name                        = item.Name;
                    sitem.Volume                      = item.Volume;
                    sitem.MaxInstanceCount            = item.MaxInstanceCount;
                    sitem.SkipWhenExeeded             = item.SkipWhenExeeded;
                    sitem.Delay                       = item.Delay;
                    sitem.overrideAudioSourceSettings = item.overrideAudioSourceSettings;
                    sitem.audioSource_MinDistance     = item.audioSource_MinDistance;
                    sitem.audioSource_MaxDistance     = item.audioSource_MaxDistance;
                    sitem.Loop                        = (SoundLoopMode)item.Loop;
                    sitem.SubItemPickMode             = (SoundPickSubItemMode)item.SubItemPickMode;

                    scat.AudioItems[j] = sitem;

                    for (int k = 0; k < item.subItems.Length; k++)
                    {
                        AudioSubItem subItem = item.subItems[k];

                        SoundSubItem       ssubItem = new SoundSubItem();
                        UnityEngine.Object asset    = subItem.Clip;
                        if (asset == null)
                        {
                            string path = subItem.StreamingAudioClipData.Path;
                            if (path.Length > 0)
                            {
//                                asset = UnityEditor.AssetDatabase.LoadAssetAtPath<UnityEngine.Object>("Assets/StreamingAssets" + path);
                                Debug.Log(asset);
                            }
                            else
                            {
                                Debug.LogError(cat.Name + "  " + item.Name + "  missing path");
                            }
                        }
                        else
                        {
                            Debug.LogError("use existing clip : " + asset);
                        }
                        ssubItem.Clip         = asset;
                        ssubItem.Volume       = subItem.Volume;
                        ssubItem.RandomVolume = subItem.RandomVolume;
                        ssubItem.Delay        = subItem.Delay;
                        ssubItem.Pan2D        = subItem.Pan2D;
                        ssubItem.Probability  = subItem.Probability;
                        ssubItem.RandomPitch  = subItem.RandomPitch;
                        ssubItem.RandomDelay  = subItem.RandomDelay;
                        ssubItem.FadeIn       = subItem.FadeIn;
                        ssubItem.FadeOut      = subItem.FadeOut;

                        sitem.subItems[k] = ssubItem;
                    }
                }
            }

            AC._currentInspectorSelection = new SoundsManager.InspectorSelection();
            AC.ValidateSounds();
        }
        #endif

        if (GUILayout.Button("print .wav items"))
        {
            foreach (SoundsCategory cat in AC.AudioCategories)
            {
                foreach (SoundItem item in cat.AudioItems)
                {
                    foreach (SoundSubItem subItem in item.subItems)
                    {
                        if (subItem.SubItemType != SoundClipType.Native)
                        {
                            Debug.Log(cat.Name + "/" + item.Name + "/" + subItem.Name);
                        }
                    }
                }
            }
        }

        if (GUILayout.Button("convert all to caf"))
        {
            foreach (SoundsCategory cat in AC.AudioCategories)
            {
                foreach (SoundItem item in cat.AudioItems)
                {
                    foreach (SoundSubItem subItem in item.subItems)
                    {
                        if (subItem.clipref.FullPath.Length > 0)
                        {
                            ConvertToCaff(cat, item, subItem);
                        }
                    }
                }
            }
        }


        if (GUILayout.Button("convert wav to caf"))
        {
            foreach (SoundsCategory cat in AC.AudioCategories)
            {
                foreach (SoundItem item in cat.AudioItems)
                {
                    foreach (SoundSubItem subItem in item.subItems)
                    {
                        if (subItem.clipref.FullPath.Length > 0 && subItem.SubItemType == SoundClipType.Clip)
                        {
                            string path = ConvertToCaff(cat, item, subItem);
                            AssetDatabase.Refresh();
                            subItem.Clip = AssetDatabase.LoadAssetAtPath <DefaultAsset>("Assets" + path);
                        }
                    }
                }
            }
        }


        if (GUILayout.Button("convert all to ogg"))
        {
            string rootDirectory = Application.dataPath + "/StreamingAssets/";
            var    allFiles      = Directory.GetFiles(rootDirectory, "*.caf", SearchOption.AllDirectories);

            foreach (string file in allFiles)
            {
                string filePath = file;

                int fileExtPos = file.LastIndexOf(".");
                if (fileExtPos >= 0)
                {
                    filePath = file.Substring(0, fileExtPos);
                }

                string sourceFile      = filePath + ".caf";
                string destanationFile = filePath + ".ogg";

                string processPath = Application.dataPath + "/SoundsPlugin/ffmpeg";
                string attributes  = string.Format("-i {0} -acodec libvorbis {1}", sourceFile.ShellString(), destanationFile.ShellString());

                System.Diagnostics.Process p = System.Diagnostics.Process.Start(processPath, attributes);
                p.WaitForExit();
            }
        }
    }