using System.Collections.Generic; using UnityEngine; using SanAndreasUnity.Utilities; using SanAndreasUnity.Behaviours.Audio; using System.Linq; namespace SanAndreasUnity.UI { public class AudioWindow : PauseMenuWindow { public float toolbarAreaHeight = 40; public float timingAreaHeight = 40; public float sideBarWidthPerc = 0.25f; GTAAudioSharp.GTAAudioStreamsFile m_selectedStreamsFile; GTAAudioSharp.GTAAudioSFXFile m_selectedSfxFile; public GTAAudioSharp.AGTAAudioFile SelectedAudioFile => m_selectedStreamsFile != null ? (GTAAudioSharp.AGTAAudioFile) m_selectedStreamsFile : (GTAAudioSharp.AGTAAudioFile) m_selectedSfxFile; string m_bankIndexStr = "0"; string m_audioIndexStr = "0"; Vector2 m_sideBarScrollPos = Vector2.zero; AudioSource m_audioSource; bool m_isPaused = false; // GTAAudioSharp.GTAAudioStreamsFile m_playingStreamsFile; // int m_playingBankIndex = -1; bool m_playInterval = false; string m_playIntervalStartStr = "00:00.000"; string m_playIntervalEndStr = "00:00.000"; AudioWindow() { // set default parameters this.windowName = "Audio"; this.useScrollView = true; } void Start () { this.RegisterButtonInPauseMenu (); // adjust rect float minWidth = 600, maxWidth = 1000, desiredWidth = Screen.width * 0.9f ; float minHeight = 400, maxHeight = 700, desiredHeight = Screen.height * 0.9f; this.windowRect = GUIUtils.GetCenteredRect (new Vector2 (Mathf.Clamp (desiredWidth, minWidth, maxWidth), Mathf.Clamp (desiredHeight, minHeight, maxHeight))); } protected override void OnWindowGUI () { if (null == AudioManager.AudioFiles) { GUILayout.Label ("Audio not loaded"); return; } // TOOLBAR AREA // buttons for: play, pause, stop int selectedButtonIndex = GUILayout.Toolbar (-1, new string[]{ "Play", "Pause", "Stop" }, GUILayout.Height(this.toolbarAreaHeight)); if (0 == selectedButtonIndex) { // play button if (m_selectedStreamsFile != null) { int index; if (int.TryParse (m_bankIndexStr, out index)) { StartPlaying (AudioManager.CreateAudioClipFromStream (m_selectedStreamsFile.Name, index)); } } else if (m_selectedSfxFile != null) { int index; int audioIndex; if (int.TryParse (m_bankIndexStr, out index) && int.TryParse(m_audioIndexStr, out audioIndex)) { StartPlaying (AudioManager.CreateAudioClipFromSfx (m_selectedSfxFile.Name, index, audioIndex)); } } } else if (1 == selectedButtonIndex) { // pause button this.TogglePause (); } else if (2 == selectedButtonIndex) { // stop button this.StopPlaying (false); } // TIMINGS AREA GUILayout.Space (10); GUILayout.BeginHorizontal (); // elapsed time and total time of currently playing sound var timeSpanCurrent = System.TimeSpan.FromSeconds (this.CurrentClipTime); var timeSpanLength = System.TimeSpan.FromSeconds (this.CurrentClipLength); GUILayout.Label (string.Format ("{0:D2}:{1:D2} / {2:D2}:{3:D2}", timeSpanCurrent.Minutes, timeSpanCurrent.Seconds, timeSpanLength.Minutes, timeSpanLength.Seconds), GUILayout.Width(120), GUILayout.Height(this.timingAreaHeight)); float newTime = GUILayout.HorizontalSlider (this.CurrentClipTimePerc, 0f, 1f, GUILayout.Height (this.timingAreaHeight)); if (newTime != this.CurrentClipTimePerc) { this.CurrentClipTimePerc = newTime; } GUILayout.EndHorizontal (); // play interval GUILayout.BeginHorizontal (); m_playInterval = GUILayout.Toggle (m_playInterval, "Play interval", GUILayout.Height(20)); GUILayout.FlexibleSpace (); if (m_playInterval) { // 2 text fields for start and end GUILayout.Label ("From:"); m_playIntervalStartStr = GUILayout.TextField (m_playIntervalStartStr, 10, GUILayout.Width(120)); GUILayout.Space (10); GUILayout.Label ("To:"); m_playIntervalEndStr = GUILayout.TextField (m_playIntervalEndStr, 10, GUILayout.Width(120)); GUILayout.FlexibleSpace (); } GUILayout.EndHorizontal (); GUILayout.Space (10); // the rest of the window will be split in 2 parts - left will be the list of all SFXs and streams, and // right will be the list of sounds in currently selected SFX/stream // float startingY = this.toolbarAreaHeight + this.timingAreaHeight + 40f; GUILayout.BeginHorizontal (); GUILayout.Space(1); // SIDEBAR // GUILayout.BeginArea (new Rect( 0, startingY, this.WindowSize.x * this.sideBarWidthPerc, this.WindowSize.y - startingY - 40)); m_sideBarScrollPos = GUILayout.BeginScrollView (m_sideBarScrollPos, GUILayout.Width(this.WindowSize.x * this.sideBarWidthPerc)); GUILayout.Label ("Streams"); // Rect rect = StartHorizontal (400, 25, 2); // GUI.Label (rect, "Name"); // rect = NextElement (rect); // GUI.Label (rect, "Num banks"); foreach (var f in AudioManager.AudioFiles.StreamsAudioFiles) { // rect = StartHorizontal (400, 25, 2); // // GUI.Label (rect, f.Name); // // rect = NextElement (rect); // GUI.Label (rect, f.NumBanks.ToString ()); GUI.enabled = (null == m_selectedStreamsFile || m_selectedStreamsFile.Name != f.Name); if (GUILayout.Button (string.Format ("{0} [{1}]", f.Name, f.NumBanks))) { // select this file SelectStreamFile (f); } GUI.enabled = true; } GUILayout.Space (20); GUILayout.Label ("SFX"); // rect = StartHorizontal (400, 25, 3); // GUI.Label (rect, "Name"); // rect = NextElement (rect); // GUI.Label (rect, "Num banks"); // rect = NextElement (rect); // GUI.Label (rect, "Num audios"); foreach (var f in AudioManager.AudioFiles.SFXAudioFiles) { // rect = StartHorizontal(400, 25, 3); // // GUI.Label (rect, f.Name); // // rect = NextElement (rect); // GUI.Label (rect, f.NumBanks.ToString ()); // // rect = NextElement (rect); // GUI.Label (rect, f.NumAudios.ToString ()); GUI.enabled = (null == m_selectedSfxFile || m_selectedSfxFile.Name != f.Name); if (GUILayout.Button (string.Format ("{0} [{1}]", f.Name, f.NumBanks))) { // select this file SelectSfxFile (f); } GUI.enabled = true; } GUILayout.EndScrollView (); // GUILayout.EndArea (); // LIST OF SOUNDS IN CURRENTLY SELECTED SFX/STREAM // GUILayout.BeginArea (new Rect( this.WindowSize.x * this.sideBarWidthPerc, startingY, this.WindowSize.x - this.WindowSize.x * this.sideBarWidthPerc, // this.WindowSize.y - startingY - 40)); // we can't display a list, because there is no way to enumerate all sounds // for now, just display text field for bank index GUILayout.Space (15); GUILayout.BeginVertical(); if (null == this.SelectedAudioFile) { GUILayout.Label("Select stream or SFX file"); } if (this.SelectedAudioFile != null) { GUILayout.Label ("bank index [0 - " + (this.SelectedAudioFile.NumBanks - 1) + "]:", GUILayout.ExpandWidth(false)); m_bankIndexStr = GUILayout.TextField (m_bankIndexStr, 6, GUILayout.Width (120)); } // if SFX is selected, also display text field for audio index if (m_selectedSfxFile != null) { GUILayout.Space(5); uint bankIndex; bool isValidBankIndex = uint.TryParse(m_bankIndexStr, out bankIndex); bool displayAudioIndex = isValidBankIndex && bankIndex < m_selectedSfxFile.NumBanks; GUILayout.Label ("audio index " + (displayAudioIndex ? "[0 - " + (m_selectedSfxFile.GetNumAudioClipsFromBank(bankIndex) - 1).ToString() + "]" : "") + ":", GUILayout.ExpandWidth(false)); m_audioIndexStr = GUILayout.TextField (m_audioIndexStr, 6, GUILayout.Width (120)); } // display info about current clip if (m_audioSource != null && m_audioSource.clip != null) { GUILayout.Space(15); GUILayout.Label("Current clip info:"); var clip = m_audioSource.clip; GUILayout.Label(string.Format("length {0} sec, num samples {1}, frequency {2}, num channels {3}, name {4}", clip.length, clip.samples, clip.frequency, clip.channels, clip.name)); } // GUILayout.EndArea (); GUILayout.EndVertical(); GUILayout.Space(1); GUILayout.EndHorizontal (); } static Rect StartHorizontal(float width, float height, int numElements) { Rect rect = GUILayoutUtility.GetRect (width, height); rect.width /= numElements; return rect; } static Rect NextElement(Rect rect) { rect.x += rect.width; return rect; } public void StartPlaying(AudioClip clip) { StopPlaying (); if (null == m_audioSource) { var go = new GameObject ("AudioWindowSound"); go.hideFlags = HideFlags.HideInHierarchy; m_audioSource = go.AddComponent (); } m_audioSource.clip = clip; if (m_playInterval) { System.TimeSpan timeSpanStart, timeSpanEnd; var fp = System.Globalization.CultureInfo.InvariantCulture; if (System.TimeSpan.TryParseExact (m_playIntervalStartStr, "mm\\:ss\\.fff", fp, out timeSpanStart) && System.TimeSpan.TryParseExact (m_playIntervalEndStr, "mm\\:ss\\.fff", fp, out timeSpanEnd) && timeSpanStart.CompareTo (timeSpanEnd) < 0) { m_audioSource.time = (float) timeSpanStart.TotalSeconds; m_audioSource.Play (); m_audioSource.SetScheduledEndTime (AudioSettings.dspTime + (timeSpanEnd.TotalSeconds - timeSpanStart.TotalSeconds)); } } else { m_audioSource.time = 0f; m_audioSource.Play (); } } public void StopPlaying(bool destroyClip = true) { if (m_audioSource) { m_audioSource.Stop (); if (destroyClip) { Destroy (m_audioSource.clip); m_audioSource.clip = null; } } } public void TogglePause() { if (m_audioSource) { m_isPaused = !m_isPaused; if (m_isPaused) m_audioSource.Pause (); else m_audioSource.UnPause (); } } public void SelectSfxFile (GTAAudioSharp.GTAAudioSFXFile f) { m_selectedSfxFile = f; m_selectedStreamsFile = null; } public void SelectStreamFile (GTAAudioSharp.GTAAudioStreamsFile f) { m_selectedSfxFile = null; m_selectedStreamsFile = f; } public float CurrentClipTimePerc { get { if (m_audioSource && m_audioSource.clip) { return m_audioSource.time / m_audioSource.clip.length; } return 0f; } set { value = Mathf.Clamp01 (value); if (m_audioSource && m_audioSource.clip) { m_audioSource.time = value * m_audioSource.clip.length; } } } public float CurrentClipTime { get { return this.CurrentClipTimePerc * this.CurrentClipLength; } } public float CurrentClipLength { get { if (m_audioSource && m_audioSource.clip) { return m_audioSource.clip.length; } return 0f; } } } }