fix static sound loading + window title
							parent
							
								
									5237ee4622
								
							
						
					
					
						commit
						933c2a434a
					
				| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
namespace MoonWorks.Audio
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +18,8 @@ namespace MoonWorks.Audio
 | 
			
		|||
 | 
			
		||||
        private FAudio.FAudioVoiceSends reverbSends;
 | 
			
		||||
 | 
			
		||||
        private readonly List<WeakReference<DynamicSoundInstance>> dynamicSoundInstances = new List<WeakReference<DynamicSoundInstance>>();
 | 
			
		||||
 | 
			
		||||
        public unsafe AudioDevice()
 | 
			
		||||
        {
 | 
			
		||||
            FAudio.FAudioCreate(out var handle, 0, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -177,16 +180,39 @@ namespace MoonWorks.Audio
 | 
			
		|||
 | 
			
		||||
            /* Init reverb sends */
 | 
			
		||||
 | 
			
		||||
            reverbSends = new FAudio.FAudioVoiceSends();
 | 
			
		||||
            reverbSends.SendCount = 2;
 | 
			
		||||
            reverbSends.pSends = Marshal.AllocHGlobal(
 | 
			
		||||
                2 * Marshal.SizeOf<FAudio.FAudioSendDescriptor>()
 | 
			
		||||
            );
 | 
			
		||||
            reverbSends = new FAudio.FAudioVoiceSends
 | 
			
		||||
            {
 | 
			
		||||
                SendCount = 2,
 | 
			
		||||
                pSends = Marshal.AllocHGlobal(
 | 
			
		||||
                    2 * Marshal.SizeOf<FAudio.FAudioSendDescriptor>()
 | 
			
		||||
                )
 | 
			
		||||
            };
 | 
			
		||||
            FAudio.FAudioSendDescriptor* sendDesc = (FAudio.FAudioSendDescriptor*) reverbSends.pSends;
 | 
			
		||||
            sendDesc[0].Flags = 0;
 | 
			
		||||
            sendDesc[0].pOutputVoice = MasteringVoice;
 | 
			
		||||
            sendDesc[1].Flags = 0;
 | 
			
		||||
            sendDesc[1].pOutputVoice = ReverbVoice;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Update()
 | 
			
		||||
        {
 | 
			
		||||
            for (var i = dynamicSoundInstances.Count - 1; i >= 0; i--)
 | 
			
		||||
            {
 | 
			
		||||
                var weakReference = dynamicSoundInstances[i];
 | 
			
		||||
                if (weakReference.TryGetTarget(out var dynamicSoundInstance))
 | 
			
		||||
                {
 | 
			
		||||
                    dynamicSoundInstance.Update();
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    dynamicSoundInstances.RemoveAt(i);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        internal void AddDynamicSoundInstance(DynamicSoundInstance instance)
 | 
			
		||||
        {
 | 
			
		||||
            dynamicSoundInstances.Add(new WeakReference<DynamicSoundInstance>(instance));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,10 +4,13 @@ using System.IO;
 | 
			
		|||
namespace MoonWorks.Audio
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// For streaming long playback.
 | 
			
		||||
    /// For streaming long playback. Reads an OGG file.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class DynamicSound : Sound, IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        internal override FAudio.FAudioWaveFormatEx Format { get; }
 | 
			
		||||
 | 
			
		||||
        // FIXME: what should this value be?
 | 
			
		||||
        public const int BUFFER_SIZE = 1024 * 128;
 | 
			
		||||
 | 
			
		||||
        internal IntPtr FileHandle { get; }
 | 
			
		||||
| 
						 | 
				
			
			@ -15,9 +18,7 @@ namespace MoonWorks.Audio
 | 
			
		|||
 | 
			
		||||
        private bool IsDisposed;
 | 
			
		||||
 | 
			
		||||
        // FIXME: what should this value be?
 | 
			
		||||
 | 
			
		||||
        public DynamicSound(FileInfo fileInfo, ushort channels, uint samplesPerSecond) : base(channels, samplesPerSecond)
 | 
			
		||||
        public DynamicSound(AudioDevice device, FileInfo fileInfo) : base(device)
 | 
			
		||||
        {
 | 
			
		||||
            FileHandle = FAudio.stb_vorbis_open_filename(fileInfo.FullName, out var error, IntPtr.Zero);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +29,26 @@ namespace MoonWorks.Audio
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            Info = FAudio.stb_vorbis_get_info(FileHandle);
 | 
			
		||||
 | 
			
		||||
            var blockAlign = (ushort)(4 * Info.channels);
 | 
			
		||||
 | 
			
		||||
            Format = new FAudio.FAudioWaveFormatEx
 | 
			
		||||
            {
 | 
			
		||||
                wFormatTag = 3,
 | 
			
		||||
                wBitsPerSample = 32,
 | 
			
		||||
                nChannels = (ushort) Info.channels,
 | 
			
		||||
                nBlockAlign = blockAlign,
 | 
			
		||||
                nSamplesPerSec = Info.sample_rate,
 | 
			
		||||
                nAvgBytesPerSec = blockAlign * Info.sample_rate,
 | 
			
		||||
                cbSize = 0
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public DynamicSoundInstance CreateInstance()
 | 
			
		||||
        {
 | 
			
		||||
            var instance = new DynamicSoundInstance(Device, this, false);
 | 
			
		||||
            Device.AddDynamicSoundInstance(instance);
 | 
			
		||||
            return instance;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual void Dispose(bool disposing)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ namespace MoonWorks.Audio
 | 
			
		|||
 | 
			
		||||
        public override SoundState State { get; protected set; }
 | 
			
		||||
 | 
			
		||||
        public DynamicSoundInstance(
 | 
			
		||||
        internal DynamicSoundInstance(
 | 
			
		||||
            AudioDevice device,
 | 
			
		||||
            DynamicSound parent,
 | 
			
		||||
            bool is3D
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +26,8 @@ namespace MoonWorks.Audio
 | 
			
		|||
            queuedSizes = new List<uint>();
 | 
			
		||||
 | 
			
		||||
            buffer = new float[DynamicSound.BUFFER_SIZE];
 | 
			
		||||
 | 
			
		||||
            State = SoundState.Stopped;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Play()
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +62,7 @@ namespace MoonWorks.Audio
 | 
			
		|||
            ClearBuffers();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Update()
 | 
			
		||||
        internal void Update()
 | 
			
		||||
        {
 | 
			
		||||
            if (State != SoundState.Playing)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +119,7 @@ namespace MoonWorks.Audio
 | 
			
		|||
                buffer.Length
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            IntPtr next = Marshal.AllocHGlobal(buffer.Length);
 | 
			
		||||
            IntPtr next = Marshal.AllocHGlobal(buffer.Length * sizeof(float));
 | 
			
		||||
            Marshal.Copy(buffer, 0, next, buffer.Length);
 | 
			
		||||
 | 
			
		||||
            lock (queuedBuffers)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										23
									
								
								Sound.cs
								
								
								
								
							
							
						
						
									
										23
									
								
								Sound.cs
								
								
								
								
							| 
						 | 
				
			
			@ -2,25 +2,12 @@ namespace MoonWorks.Audio
 | 
			
		|||
{
 | 
			
		||||
    public abstract class Sound
 | 
			
		||||
    {
 | 
			
		||||
        internal FAudio.FAudioWaveFormatEx Format { get; }
 | 
			
		||||
        internal AudioDevice Device { get; }
 | 
			
		||||
        internal abstract FAudio.FAudioWaveFormatEx Format { get; }
 | 
			
		||||
 | 
			
		||||
        /* NOTE: we only support float decoding! WAV sucks! */
 | 
			
		||||
        public Sound(
 | 
			
		||||
            ushort channels,
 | 
			
		||||
            uint samplesPerSecond
 | 
			
		||||
        ) {
 | 
			
		||||
            var blockAlign = (ushort) (4 * channels);
 | 
			
		||||
 | 
			
		||||
            Format = new FAudio.FAudioWaveFormatEx
 | 
			
		||||
            {
 | 
			
		||||
                wFormatTag = 3,
 | 
			
		||||
                wBitsPerSample = 32,
 | 
			
		||||
                nChannels = channels,
 | 
			
		||||
                nBlockAlign = blockAlign,
 | 
			
		||||
                nSamplesPerSec = samplesPerSecond,
 | 
			
		||||
                nAvgBytesPerSec = blockAlign * samplesPerSecond,
 | 
			
		||||
                cbSize = 0
 | 
			
		||||
            };
 | 
			
		||||
        public Sound(AudioDevice device)
 | 
			
		||||
        {
 | 
			
		||||
            Device = device;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,13 +6,15 @@ namespace MoonWorks.Audio
 | 
			
		|||
{
 | 
			
		||||
    public class StaticSound : Sound, IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        internal override FAudio.FAudioWaveFormatEx Format { get; }
 | 
			
		||||
        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)
 | 
			
		||||
        private bool IsDisposed;
 | 
			
		||||
 | 
			
		||||
        public static StaticSound LoadOgg(AudioDevice device, FileInfo fileInfo)
 | 
			
		||||
        {
 | 
			
		||||
            var filePointer = FAudio.stb_vorbis_open_filename(fileInfo.FullName, out var error, IntPtr.Zero);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -21,12 +23,20 @@ namespace MoonWorks.Audio
 | 
			
		|||
                throw new AudioLoadException("Error loading file!");
 | 
			
		||||
            }
 | 
			
		||||
            var info = FAudio.stb_vorbis_get_info(filePointer);
 | 
			
		||||
            var bufferSize =  (uint)(info.sample_rate * info.channels);
 | 
			
		||||
            var bufferSize = FAudio.stb_vorbis_stream_length_in_samples(filePointer);
 | 
			
		||||
            var buffer = new float[bufferSize];
 | 
			
		||||
 | 
			
		||||
            FAudio.stb_vorbis_get_samples_float_interleaved(
 | 
			
		||||
                filePointer,
 | 
			
		||||
                info.channels,
 | 
			
		||||
                buffer,
 | 
			
		||||
                (int) bufferSize
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            FAudio.stb_vorbis_close(filePointer);
 | 
			
		||||
 | 
			
		||||
            return new StaticSound(
 | 
			
		||||
                device,
 | 
			
		||||
                buffer,
 | 
			
		||||
                0,
 | 
			
		||||
                (ushort) info.channels,
 | 
			
		||||
| 
						 | 
				
			
			@ -35,25 +45,42 @@ namespace MoonWorks.Audio
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        public StaticSound(
 | 
			
		||||
            AudioDevice device,
 | 
			
		||||
            float[] buffer,
 | 
			
		||||
            uint bufferOffset,
 | 
			
		||||
            ushort channels,
 | 
			
		||||
            uint samplesPerSecond
 | 
			
		||||
        ) : base(channels, samplesPerSecond) {
 | 
			
		||||
            var bufferLength = 4 * buffer.Length;
 | 
			
		||||
        ) : base(device) {
 | 
			
		||||
            var blockAlign = (ushort)(4 * channels);
 | 
			
		||||
 | 
			
		||||
            Format = new FAudio.FAudioWaveFormatEx
 | 
			
		||||
            {
 | 
			
		||||
                wFormatTag = 3,
 | 
			
		||||
                wBitsPerSample = 32,
 | 
			
		||||
                nChannels = channels,
 | 
			
		||||
                nBlockAlign = blockAlign,
 | 
			
		||||
                nSamplesPerSec = samplesPerSecond,
 | 
			
		||||
                nAvgBytesPerSec = blockAlign * samplesPerSecond
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var bufferLengthInBytes = sizeof(float) * 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.AudioBytes = (uint) bufferLengthInBytes;
 | 
			
		||||
            Handle.pAudioData = Marshal.AllocHGlobal(bufferLengthInBytes);
 | 
			
		||||
            Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, buffer.Length);
 | 
			
		||||
            Handle.PlayBegin = 0;
 | 
			
		||||
            Handle.PlayLength = (
 | 
			
		||||
                Handle.AudioBytes /
 | 
			
		||||
                (uint) Format.nChannels /
 | 
			
		||||
                (uint) (Format.wBitsPerSample / 8)
 | 
			
		||||
            );
 | 
			
		||||
            Handle.PlayLength = 0;
 | 
			
		||||
 | 
			
		||||
            LoopStart = 0;
 | 
			
		||||
            LoopLength = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public StaticSoundInstance CreateInstance()
 | 
			
		||||
        {
 | 
			
		||||
            return new StaticSoundInstance(Device, this, false, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected virtual void Dispose(bool disposing)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,7 @@ namespace MoonWorks.Audio
 | 
			
		|||
        ) : base(device, parent, is3D)
 | 
			
		||||
        {
 | 
			
		||||
            Loop = loop;
 | 
			
		||||
            State = SoundState.Stopped;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Play()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue