From cbb786e3f43257922cf03898a6ba2769bdbeb389 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 7 Apr 2022 14:19:43 -0700 Subject: [PATCH] stream ogg from memory instead of disk --- SoundInstance.cs | 12 +++++------ StaticSound.cs | 2 +- StaticSoundInstance.cs | 5 ++--- StreamingSound.cs | 5 ++--- StreamingSoundOgg.cs | 47 +++++++++++++++++++++--------------------- 5 files changed, 34 insertions(+), 37 deletions(-) diff --git a/SoundInstance.cs b/SoundInstance.cs index 78b5eec..731237e 100644 --- a/SoundInstance.cs +++ b/SoundInstance.cs @@ -12,7 +12,7 @@ namespace MoonWorks.Audio protected FAudio.F3DAUDIO_DSP_SETTINGS dspSettings; - protected bool is3D; + public bool Is3D { get; protected set; } public abstract SoundState State { get; protected set; } @@ -33,7 +33,7 @@ namespace MoonWorks.Audio _pan = 1f; } - if (is3D) { return; } + if (Is3D) { return; } SetPanMatrixCoefficients(); FAudio.FAudioVoice_SetOutputMatrix( @@ -167,8 +167,7 @@ namespace MoonWorks.Audio ushort bitsPerSample, ushort blockAlign, ushort channels, - uint samplesPerSecond, - bool is3D + uint samplesPerSecond ) : base(device) { var format = new FAudio.FAudioWaveFormatEx @@ -200,7 +199,6 @@ namespace MoonWorks.Audio return; } - this.is3D = is3D; InitDSPSettings(Format.nChannels); // FIXME: not everything should be running through reverb... @@ -216,7 +214,7 @@ namespace MoonWorks.Audio public void Apply3D(AudioListener listener, AudioEmitter emitter) { - is3D = true; + Is3D = true; emitter.emitterData.CurveDistanceScaler = Device.CurveDistanceScalar; emitter.emitterData.ChannelCount = dspSettings.SrcChannelCount; @@ -273,7 +271,7 @@ namespace MoonWorks.Audio { float doppler; float dopplerScale = Device.DopplerScale; - if (!is3D || dopplerScale == 0.0f) + if (!Is3D || dopplerScale == 0.0f) { doppler = 1.0f; } diff --git a/StaticSound.cs b/StaticSound.cs index 5f0d851..4976244 100644 --- a/StaticSound.cs +++ b/StaticSound.cs @@ -275,7 +275,7 @@ namespace MoonWorks.Audio { if (Instances.Count == 0) { - Instances.Push(new StaticSoundInstance(Device, this, false)); + Instances.Push(new StaticSoundInstance(Device, this)); } return Instances.Pop(); diff --git a/StaticSoundInstance.cs b/StaticSoundInstance.cs index 0ca6bd0..cb7966a 100644 --- a/StaticSoundInstance.cs +++ b/StaticSoundInstance.cs @@ -32,9 +32,8 @@ namespace MoonWorks.Audio internal StaticSoundInstance( AudioDevice device, - StaticSound parent, - bool is3D - ) : base(device, parent.FormatTag, parent.BitsPerSample, parent.BlockAlign, parent.Channels, parent.SamplesPerSecond, is3D) + StaticSound parent + ) : base(device, parent.FormatTag, parent.BitsPerSample, parent.BlockAlign, parent.Channels, parent.SamplesPerSecond) { Parent = parent; } diff --git a/StreamingSound.cs b/StreamingSound.cs index 81c4553..18a5a33 100644 --- a/StreamingSound.cs +++ b/StreamingSound.cs @@ -22,9 +22,8 @@ namespace MoonWorks.Audio ushort bitsPerSample, ushort blockAlign, ushort channels, - uint samplesPerSecond, - bool is3D - ) : base(device, formatTag, bitsPerSample, blockAlign, channels, samplesPerSecond, is3D) { } + uint samplesPerSecond + ) : base(device, formatTag, bitsPerSample, blockAlign, channels, samplesPerSecond) { } public override void Play(bool loop = false) { diff --git a/StreamingSoundOgg.cs b/StreamingSoundOgg.cs index 8bad790..502581d 100644 --- a/StreamingSoundOgg.cs +++ b/StreamingSoundOgg.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Runtime.InteropServices; namespace MoonWorks.Audio { @@ -8,52 +9,51 @@ namespace MoonWorks.Audio // FIXME: what should this value be? public const int BUFFER_SIZE = 1024 * 128; - internal IntPtr FileHandle { get; } - internal FAudio.stb_vorbis_info Info { get; } + private IntPtr VorbisHandle; + private IntPtr FileDataPtr; + private FAudio.stb_vorbis_info Info; - private readonly float[] buffer; + private readonly float[] buffer; // currently decoded bytes public override SoundState State { get; protected set; } - public static StreamingSoundOgg Load( - AudioDevice device, - string filePath, - bool is3D = false - ) + public static StreamingSoundOgg Load(AudioDevice device, string filePath) { - var fileHandle = FAudio.stb_vorbis_open_filename(filePath, out var error, IntPtr.Zero); + var fileData = File.ReadAllBytes(filePath); + var fileDataPtr = (IntPtr) GCHandle.Alloc(fileData, GCHandleType.Pinned); + var vorbisHandle = FAudio.stb_vorbis_open_memory(fileDataPtr, fileData.Length, out int error, IntPtr.Zero); if (error != 0) { + ((GCHandle) fileDataPtr).Free(); Logger.LogError("Error opening OGG file!"); throw new AudioLoadException("Error opening OGG file!"); } - - var info = FAudio.stb_vorbis_get_info(fileHandle); + var info = FAudio.stb_vorbis_get_info(vorbisHandle); return new StreamingSoundOgg( device, - fileHandle, - info, - is3D + fileDataPtr, + vorbisHandle, + info ); } internal StreamingSoundOgg( AudioDevice device, - IntPtr fileHandle, - FAudio.stb_vorbis_info info, - bool is3D + IntPtr fileDataPtr, // MUST BE PINNED!! + IntPtr vorbisHandle, + FAudio.stb_vorbis_info info ) : base( device, 3, /* float type */ 32, /* size of float */ (ushort) (4 * info.channels), (ushort) info.channels, - info.sample_rate, - is3D + info.sample_rate ) { - FileHandle = fileHandle; + FileDataPtr = fileDataPtr; + VorbisHandle = vorbisHandle; Info = info; buffer = new float[BUFFER_SIZE]; @@ -71,7 +71,7 @@ namespace MoonWorks.Audio /* NOTE: this function returns samples per channel, not total samples */ var samples = FAudio.stb_vorbis_get_samples_float_interleaved( - FileHandle, + VorbisHandle, Info.channels, buffer, buffer.Length @@ -85,12 +85,13 @@ namespace MoonWorks.Audio protected override void SeekStart() { - FAudio.stb_vorbis_seek_start(FileHandle); + FAudio.stb_vorbis_seek_start(VorbisHandle); } protected override void Destroy() { - FAudio.stb_vorbis_close(FileHandle); + ((GCHandle) FileDataPtr).Free(); + FAudio.stb_vorbis_close(VorbisHandle); } } }