2020-05-31 17:07:22 +00:00
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 ;
2019-08-28 17:12:34 +00:00
public GTAAudioSharp . AGTAAudioFile SelectedAudioFile = > m_selectedStreamsFile ! = null ? ( GTAAudioSharp . AGTAAudioFile ) m_selectedStreamsFile : ( GTAAudioSharp . AGTAAudioFile ) m_selectedSfxFile ;
string m_bankIndexStr = "0" ;
string m_audioIndexStr = "0" ;
2020-05-31 17:07:22 +00:00
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 ;
2019-08-28 17:12:34 +00:00
int audioIndex ;
if ( int . TryParse ( m_bankIndexStr , out index ) & & int . TryParse ( m_audioIndexStr , out audioIndex ) )
2020-05-31 17:07:22 +00:00
{
2019-08-28 17:12:34 +00:00
StartPlaying ( AudioManager . CreateAudioClipFromSfx ( m_selectedSfxFile . Name , index , audioIndex ) ) ;
2020-05-31 17:07:22 +00:00
}
}
}
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 ( ) ;
2019-08-28 20:00:02 +00:00
GUILayout . Space ( 1 ) ;
2020-05-31 17:07:22 +00:00
// 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
2019-08-28 20:00:02 +00:00
GUILayout . Space ( 15 ) ;
GUILayout . BeginVertical ( ) ;
2019-08-28 17:12:34 +00:00
if ( null = = this . SelectedAudioFile )
{
GUILayout . Label ( "Select stream or SFX file" ) ;
}
if ( this . SelectedAudioFile ! = null )
{
2019-08-28 20:00:02 +00:00
GUILayout . Label ( "bank index [0 - " + ( this . SelectedAudioFile . NumBanks - 1 ) + "]:" , GUILayout . ExpandWidth ( false ) ) ;
2019-08-28 17:12:34 +00:00
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 )
{
2019-08-28 20:26:40 +00:00
GUILayout . Space ( 5 ) ;
2019-08-28 17:12:34 +00:00
uint bankIndex ;
bool isValidBankIndex = uint . TryParse ( m_bankIndexStr , out bankIndex ) ;
bool displayAudioIndex = isValidBankIndex & & bankIndex < m_selectedSfxFile . NumBanks ;
2019-08-28 20:00:02 +00:00
GUILayout . Label ( "audio index " + ( displayAudioIndex ? "[0 - " + ( m_selectedSfxFile . GetNumAudioClipsFromBank ( bankIndex ) - 1 ) . ToString ( ) + "]" : "" ) + ":" , GUILayout . ExpandWidth ( false ) ) ;
2019-08-28 17:12:34 +00:00
m_audioIndexStr = GUILayout . TextField ( m_audioIndexStr , 6 , GUILayout . Width ( 120 ) ) ;
}
2020-05-31 17:07:22 +00:00
2019-08-28 20:26:40 +00:00
// 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 ) ) ;
}
2020-05-31 17:07:22 +00:00
// GUILayout.EndArea ();
2019-08-28 20:00:02 +00:00
GUILayout . EndVertical ( ) ;
GUILayout . Space ( 1 ) ;
2020-05-31 17:07:22 +00:00
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 ;
}
}
}
}