more audio implementation
							parent
							
								
									9ca745e5e0
								
							
						
					
					
						commit
						5237ee4622
					
				| 
						 | 
				
			
			@ -0,0 +1,61 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
namespace MoonWorks.Audio
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// For streaming long playback.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class DynamicSound : Sound, IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        public const int BUFFER_SIZE = 1024 * 128;
 | 
			
		||||
 | 
			
		||||
        internal IntPtr FileHandle { get; }
 | 
			
		||||
        internal FAudio.stb_vorbis_info Info { get; }
 | 
			
		||||
 | 
			
		||||
        private bool IsDisposed;
 | 
			
		||||
 | 
			
		||||
        // FIXME: what should this value be?
 | 
			
		||||
 | 
			
		||||
        public DynamicSound(FileInfo fileInfo, ushort channels, uint samplesPerSecond) : base(channels, samplesPerSecond)
 | 
			
		||||
        {
 | 
			
		||||
            FileHandle = FAudio.stb_vorbis_open_filename(fileInfo.FullName, out var error, IntPtr.Zero);
 | 
			
		||||
 | 
			
		||||
            if (error != 0)
 | 
			
		||||
            {
 | 
			
		||||
                Logger.LogError("Error opening OGG file!");
 | 
			
		||||
                throw new AudioLoadException("Error opening OGG file!");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Info = FAudio.stb_vorbis_get_info(FileHandle);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual void Dispose(bool disposing)
 | 
			
		||||
        {
 | 
			
		||||
            if (!IsDisposed)
 | 
			
		||||
            {
 | 
			
		||||
                if (disposing)
 | 
			
		||||
                {
 | 
			
		||||
                    // dispose managed state (managed objects)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                FAudio.stb_vorbis_close(FileHandle);
 | 
			
		||||
                IsDisposed = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
 | 
			
		||||
        ~DynamicSound()
 | 
			
		||||
        {
 | 
			
		||||
            // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
 | 
			
		||||
            Dispose(disposing: false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
 | 
			
		||||
            Dispose(disposing: true);
 | 
			
		||||
            GC.SuppressFinalize(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,154 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
namespace MoonWorks.Audio
 | 
			
		||||
{
 | 
			
		||||
    public class DynamicSoundInstance : SoundInstance
 | 
			
		||||
    {
 | 
			
		||||
        private List<IntPtr> queuedBuffers;
 | 
			
		||||
        private List<uint> queuedSizes;
 | 
			
		||||
        private const int MINIMUM_BUFFER_CHECK = 3;
 | 
			
		||||
 | 
			
		||||
        public int PendingBufferCount => queuedBuffers.Count;
 | 
			
		||||
 | 
			
		||||
        private readonly float[] buffer;
 | 
			
		||||
 | 
			
		||||
        public override SoundState State { get; protected set; }
 | 
			
		||||
 | 
			
		||||
        public DynamicSoundInstance(
 | 
			
		||||
            AudioDevice device,
 | 
			
		||||
            DynamicSound parent,
 | 
			
		||||
            bool is3D
 | 
			
		||||
        ) : base(device, parent, is3D)
 | 
			
		||||
        {
 | 
			
		||||
            queuedBuffers = new List<IntPtr>();
 | 
			
		||||
            queuedSizes = new List<uint>();
 | 
			
		||||
 | 
			
		||||
            buffer = new float[DynamicSound.BUFFER_SIZE];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Play()
 | 
			
		||||
        {
 | 
			
		||||
            Update();
 | 
			
		||||
 | 
			
		||||
            if (State == SoundState.Playing)
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            QueueBuffers();
 | 
			
		||||
 | 
			
		||||
            FAudio.FAudioSourceVoice_Start(Handle, 0, 0);
 | 
			
		||||
            State = SoundState.Playing;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Pause()
 | 
			
		||||
        {
 | 
			
		||||
            if (State == SoundState.Playing)
 | 
			
		||||
            {
 | 
			
		||||
                FAudio.FAudioSourceVoice_Stop(Handle, 0, 0);
 | 
			
		||||
                State = SoundState.Paused;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Stop()
 | 
			
		||||
        {
 | 
			
		||||
            FAudio.FAudioSourceVoice_Stop(Handle, 0, 0);
 | 
			
		||||
            FAudio.FAudioSourceVoice_FlushSourceBuffers(Handle);
 | 
			
		||||
            State = SoundState.Stopped;
 | 
			
		||||
            ClearBuffers();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Update()
 | 
			
		||||
        {
 | 
			
		||||
            if (State != SoundState.Playing)
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FAudio.FAudioSourceVoice_GetState(
 | 
			
		||||
                Handle,
 | 
			
		||||
                out var state,
 | 
			
		||||
                FAudio.FAUDIO_VOICE_NOSAMPLESPLAYED
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            while (PendingBufferCount > state.BuffersQueued)
 | 
			
		||||
            lock (queuedBuffers)
 | 
			
		||||
            {
 | 
			
		||||
                Marshal.FreeHGlobal(queuedBuffers[0]);
 | 
			
		||||
                queuedBuffers.RemoveAt(0);
 | 
			
		||||
                queuedSizes.RemoveAt(0);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void QueueBuffers()
 | 
			
		||||
        {
 | 
			
		||||
            for (
 | 
			
		||||
                int i = MINIMUM_BUFFER_CHECK - PendingBufferCount;
 | 
			
		||||
                i > 0;
 | 
			
		||||
                i -= 1
 | 
			
		||||
            ) {
 | 
			
		||||
                AddBuffer();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ClearBuffers()
 | 
			
		||||
        {
 | 
			
		||||
            lock (queuedBuffers)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (IntPtr buf in queuedBuffers)
 | 
			
		||||
                {
 | 
			
		||||
                    Marshal.FreeHGlobal(buf);
 | 
			
		||||
                }
 | 
			
		||||
                queuedBuffers.Clear();
 | 
			
		||||
                queuedBuffers.Clear();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddBuffer()
 | 
			
		||||
        {
 | 
			
		||||
            var parent = (DynamicSound) Parent;
 | 
			
		||||
 | 
			
		||||
            var samples = FAudio.stb_vorbis_get_samples_float_interleaved(
 | 
			
		||||
                parent.FileHandle,
 | 
			
		||||
                parent.Info.channels,
 | 
			
		||||
                buffer,
 | 
			
		||||
                buffer.Length
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            IntPtr next = Marshal.AllocHGlobal(buffer.Length);
 | 
			
		||||
            Marshal.Copy(buffer, 0, next, buffer.Length);
 | 
			
		||||
 | 
			
		||||
            lock (queuedBuffers)
 | 
			
		||||
            {
 | 
			
		||||
                var lengthInBytes = (uint) buffer.Length * sizeof(float);
 | 
			
		||||
 | 
			
		||||
                queuedBuffers.Add(next);
 | 
			
		||||
                if (State != SoundState.Stopped)
 | 
			
		||||
                {
 | 
			
		||||
                    FAudio.FAudioBuffer buf = new FAudio.FAudioBuffer
 | 
			
		||||
                    {
 | 
			
		||||
                        AudioBytes = lengthInBytes,
 | 
			
		||||
                        pAudioData = next,
 | 
			
		||||
                        PlayLength = (
 | 
			
		||||
                            lengthInBytes /
 | 
			
		||||
                            (uint) parent.Info.channels /
 | 
			
		||||
                            (uint) (parent.Format.wBitsPerSample / 8)
 | 
			
		||||
                        )
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    FAudio.FAudioSourceVoice_SubmitSourceBuffer(
 | 
			
		||||
                        Handle,
 | 
			
		||||
                        ref buf,
 | 
			
		||||
                        IntPtr.Zero
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    queuedSizes.Add(lengthInBytes);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								Sound.cs
								
								
								
								
							
							
						
						
									
										77
									
								
								Sound.cs
								
								
								
								
							| 
						 | 
				
			
			@ -1,73 +1,26 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
namespace MoonWorks.Audio
 | 
			
		||||
{
 | 
			
		||||
    public class Sound
 | 
			
		||||
    public abstract class Sound
 | 
			
		||||
    {
 | 
			
		||||
        internal FAudio.FAudioBuffer Handle;
 | 
			
		||||
        internal FAudio.FAudioWaveFormatEx Format;
 | 
			
		||||
        internal FAudio.FAudioWaveFormatEx Format { get; }
 | 
			
		||||
 | 
			
		||||
        public uint LoopStart { get; set; } = 0;
 | 
			
		||||
        public uint LoopLength { get; set; } = 0;
 | 
			
		||||
 | 
			
		||||
        public static Sound FromFile(FileInfo fileInfo)
 | 
			
		||||
        {
 | 
			
		||||
            var filePointer = FAudio.stb_vorbis_open_filename(fileInfo.FullName, out var error, IntPtr.Zero);
 | 
			
		||||
 | 
			
		||||
            if (error != 0)
 | 
			
		||||
            {
 | 
			
		||||
                throw new AudioLoadException("Error loading file!");
 | 
			
		||||
            }
 | 
			
		||||
            var info = FAudio.stb_vorbis_get_info(filePointer);
 | 
			
		||||
            var bufferSize =  (uint)(info.sample_rate * info.channels);
 | 
			
		||||
            var buffer = new float[bufferSize];
 | 
			
		||||
            var align = (ushort) (4 * info.channels);
 | 
			
		||||
 | 
			
		||||
            FAudio.stb_vorbis_close(filePointer);
 | 
			
		||||
 | 
			
		||||
            return new Sound(
 | 
			
		||||
                buffer,
 | 
			
		||||
                0,
 | 
			
		||||
                (ushort) info.channels,
 | 
			
		||||
                info.sample_rate,
 | 
			
		||||
                align
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* we only support float decoding! WAV sucks! */
 | 
			
		||||
        /* NOTE: we only support float decoding! WAV sucks! */
 | 
			
		||||
        public Sound(
 | 
			
		||||
            float[] buffer,
 | 
			
		||||
            uint bufferOffset,
 | 
			
		||||
            ushort channels,
 | 
			
		||||
            uint samplesPerSecond,
 | 
			
		||||
            ushort blockAlign
 | 
			
		||||
            uint samplesPerSecond
 | 
			
		||||
        ) {
 | 
			
		||||
            var bufferLength = 4 * buffer.Length;
 | 
			
		||||
            var blockAlign = (ushort) (4 * channels);
 | 
			
		||||
 | 
			
		||||
            Format = new FAudio.FAudioWaveFormatEx();
 | 
			
		||||
            Format.wFormatTag = 3;
 | 
			
		||||
            Format.wBitsPerSample = 32;
 | 
			
		||||
            Format.nChannels = channels;
 | 
			
		||||
            Format.nBlockAlign = (ushort) (4 * Format.nChannels);
 | 
			
		||||
            Format.nSamplesPerSec = samplesPerSecond;
 | 
			
		||||
            Format.nAvgBytesPerSec = Format.nBlockAlign * Format.nSamplesPerSec;
 | 
			
		||||
            Format.nBlockAlign = blockAlign;
 | 
			
		||||
            Format.cbSize = 0;
 | 
			
		||||
 | 
			
		||||
            Handle = new FAudio.FAudioBuffer();
 | 
			
		||||
            Handle.Flags = FAudio.FAUDIO_END_OF_STREAM;
 | 
			
		||||
            Handle.pContext = IntPtr.Zero;
 | 
			
		||||
            Handle.AudioBytes = (uint) bufferLength;
 | 
			
		||||
            Handle.pAudioData = Marshal.AllocHGlobal((int) bufferLength);
 | 
			
		||||
            Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, (int) bufferLength);
 | 
			
		||||
            Handle.PlayBegin = 0;
 | 
			
		||||
            Handle.PlayLength = (
 | 
			
		||||
                Handle.AudioBytes /
 | 
			
		||||
                (uint) Format.nChannels /
 | 
			
		||||
                (uint) (Format.wBitsPerSample / 8)
 | 
			
		||||
            );
 | 
			
		||||
            Format = new FAudio.FAudioWaveFormatEx
 | 
			
		||||
            {
 | 
			
		||||
                wFormatTag = 3,
 | 
			
		||||
                wBitsPerSample = 32,
 | 
			
		||||
                nChannels = channels,
 | 
			
		||||
                nBlockAlign = blockAlign,
 | 
			
		||||
                nSamplesPerSec = samplesPerSecond,
 | 
			
		||||
                nAvgBytesPerSec = blockAlign * samplesPerSecond,
 | 
			
		||||
                cbSize = 0
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,15 +7,15 @@ namespace MoonWorks.Audio
 | 
			
		|||
    {
 | 
			
		||||
        protected AudioDevice Device { get; }
 | 
			
		||||
        internal IntPtr Handle { get; }
 | 
			
		||||
        protected Sound Parent { get; }
 | 
			
		||||
        public Sound Parent { get; }
 | 
			
		||||
        protected FAudio.F3DAUDIO_DSP_SETTINGS dspSettings;
 | 
			
		||||
        public SoundState State { get; protected set; }
 | 
			
		||||
 | 
			
		||||
        protected bool is3D;
 | 
			
		||||
 | 
			
		||||
        private float _pan = 0;
 | 
			
		||||
        private bool IsDisposed;
 | 
			
		||||
 | 
			
		||||
        public abstract SoundState State { get; protected set; }
 | 
			
		||||
 | 
			
		||||
        private float _pan = 0;
 | 
			
		||||
        public float Pan
 | 
			
		||||
        {
 | 
			
		||||
            get => _pan;
 | 
			
		||||
| 
						 | 
				
			
			@ -168,8 +168,11 @@ namespace MoonWorks.Audio
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public SoundInstance(AudioDevice device, Sound parent, bool is3D)
 | 
			
		||||
        {
 | 
			
		||||
        public SoundInstance(
 | 
			
		||||
            AudioDevice device,
 | 
			
		||||
            Sound parent,
 | 
			
		||||
            bool is3D
 | 
			
		||||
        ) {
 | 
			
		||||
            Device = device;
 | 
			
		||||
            Parent = parent;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -195,7 +198,6 @@ namespace MoonWorks.Audio
 | 
			
		|||
            Handle = handle;
 | 
			
		||||
            this.is3D = is3D;
 | 
			
		||||
            InitDSPSettings(Parent.Format.nChannels);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void InitDSPSettings(uint srcChannels)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,87 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
namespace MoonWorks.Audio
 | 
			
		||||
{
 | 
			
		||||
    public class StaticSound : Sound, IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        internal FAudio.FAudioBuffer Handle;
 | 
			
		||||
        private bool IsDisposed;
 | 
			
		||||
 | 
			
		||||
        public uint LoopStart { get; set; } = 0;
 | 
			
		||||
        public uint LoopLength { get; set; } = 0;
 | 
			
		||||
 | 
			
		||||
        public static StaticSound FromOgg(FileInfo fileInfo)
 | 
			
		||||
        {
 | 
			
		||||
            var filePointer = FAudio.stb_vorbis_open_filename(fileInfo.FullName, out var error, IntPtr.Zero);
 | 
			
		||||
 | 
			
		||||
            if (error != 0)
 | 
			
		||||
            {
 | 
			
		||||
                throw new AudioLoadException("Error loading file!");
 | 
			
		||||
            }
 | 
			
		||||
            var info = FAudio.stb_vorbis_get_info(filePointer);
 | 
			
		||||
            var bufferSize =  (uint)(info.sample_rate * info.channels);
 | 
			
		||||
            var buffer = new float[bufferSize];
 | 
			
		||||
 | 
			
		||||
            FAudio.stb_vorbis_close(filePointer);
 | 
			
		||||
 | 
			
		||||
            return new StaticSound(
 | 
			
		||||
                buffer,
 | 
			
		||||
                0,
 | 
			
		||||
                (ushort) info.channels,
 | 
			
		||||
                info.sample_rate
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public StaticSound(
 | 
			
		||||
            float[] buffer,
 | 
			
		||||
            uint bufferOffset,
 | 
			
		||||
            ushort channels,
 | 
			
		||||
            uint samplesPerSecond
 | 
			
		||||
        ) : base(channels, samplesPerSecond) {
 | 
			
		||||
            var bufferLength = 4 * buffer.Length;
 | 
			
		||||
 | 
			
		||||
            Handle = new FAudio.FAudioBuffer();
 | 
			
		||||
            Handle.Flags = FAudio.FAUDIO_END_OF_STREAM;
 | 
			
		||||
            Handle.pContext = IntPtr.Zero;
 | 
			
		||||
            Handle.AudioBytes = (uint) bufferLength;
 | 
			
		||||
            Handle.pAudioData = Marshal.AllocHGlobal((int) bufferLength);
 | 
			
		||||
            Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, (int) bufferLength);
 | 
			
		||||
            Handle.PlayBegin = 0;
 | 
			
		||||
            Handle.PlayLength = (
 | 
			
		||||
                Handle.AudioBytes /
 | 
			
		||||
                (uint) Format.nChannels /
 | 
			
		||||
                (uint) (Format.wBitsPerSample / 8)
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual void Dispose(bool disposing)
 | 
			
		||||
        {
 | 
			
		||||
            if (!IsDisposed)
 | 
			
		||||
            {
 | 
			
		||||
                if (disposing)
 | 
			
		||||
                {
 | 
			
		||||
                    // dispose managed state (managed objects)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Marshal.FreeHGlobal(Handle.pAudioData);
 | 
			
		||||
                IsDisposed = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
 | 
			
		||||
        ~StaticSound()
 | 
			
		||||
        {
 | 
			
		||||
            // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
 | 
			
		||||
            Dispose(disposing: false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
 | 
			
		||||
            Dispose(disposing: true);
 | 
			
		||||
            GC.SuppressFinalize(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -4,39 +4,67 @@ namespace MoonWorks.Audio
 | 
			
		|||
{
 | 
			
		||||
    public class StaticSoundInstance : SoundInstance
 | 
			
		||||
    {
 | 
			
		||||
        public bool Loop { get; protected set; }
 | 
			
		||||
        public bool Loop { get; }
 | 
			
		||||
 | 
			
		||||
        private SoundState _state = SoundState.Stopped;
 | 
			
		||||
        public override SoundState State
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                FAudio.FAudioSourceVoice_GetState(
 | 
			
		||||
                    Handle,
 | 
			
		||||
                    out var state,
 | 
			
		||||
                    FAudio.FAUDIO_VOICE_NOSAMPLESPLAYED
 | 
			
		||||
                );
 | 
			
		||||
                if (state.BuffersQueued == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    Stop(true);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return _state;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            protected set
 | 
			
		||||
            {
 | 
			
		||||
                _state = value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public StaticSoundInstance(
 | 
			
		||||
            AudioDevice device,
 | 
			
		||||
            Sound parent,
 | 
			
		||||
            bool is3D
 | 
			
		||||
        ) : base(device, parent, is3D) { }
 | 
			
		||||
 | 
			
		||||
        public void Play(bool loop = false)
 | 
			
		||||
            StaticSound parent,
 | 
			
		||||
            bool is3D,
 | 
			
		||||
            bool loop = false
 | 
			
		||||
        ) : base(device, parent, is3D)
 | 
			
		||||
        {
 | 
			
		||||
            Loop = loop;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Play()
 | 
			
		||||
        {
 | 
			
		||||
            var parent = (StaticSound) Parent;
 | 
			
		||||
 | 
			
		||||
            if (State == SoundState.Playing)
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (loop)
 | 
			
		||||
            if (Loop)
 | 
			
		||||
            {
 | 
			
		||||
                Loop = true;
 | 
			
		||||
                Parent.Handle.LoopCount = 255;
 | 
			
		||||
                Parent.Handle.LoopBegin = 0;
 | 
			
		||||
                Parent.Handle.LoopLength = Parent.LoopLength;
 | 
			
		||||
                parent.Handle.LoopCount = 255;
 | 
			
		||||
                parent.Handle.LoopBegin = parent.LoopStart;
 | 
			
		||||
                parent.Handle.LoopLength = parent.LoopLength;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                Loop = false;
 | 
			
		||||
                Parent.Handle.LoopCount = 0;
 | 
			
		||||
                Parent.Handle.LoopBegin = 0;
 | 
			
		||||
                Parent.Handle.LoopLength = 0;
 | 
			
		||||
                parent.Handle.LoopCount = 0;
 | 
			
		||||
                parent.Handle.LoopBegin = 0;
 | 
			
		||||
                parent.Handle.LoopLength = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            FAudio.FAudioSourceVoice_SubmitSourceBuffer(
 | 
			
		||||
                Handle,
 | 
			
		||||
                ref Parent.Handle,
 | 
			
		||||
                ref parent.Handle,
 | 
			
		||||
                IntPtr.Zero
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue