SanAndreasUnity/Assets/Scripts/UI/AudioWindow.cs
2020-05-31 19:09:48 +02:00

408 lines
10 KiB
C#

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 ("<b>Streams</b>");
// 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 ("<b>SFX</b>");
// 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<AudioSource> ();
}
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;
}
}
}
}