stream ogg from memory instead of disk

pull/18/head
cosmonaut 2022-04-07 14:19:43 -07:00
parent 5e2b8de2d3
commit ba66ed4225
5 changed files with 34 additions and 37 deletions

View File

@ -12,7 +12,7 @@ namespace MoonWorks.Audio
protected FAudio.F3DAUDIO_DSP_SETTINGS dspSettings; protected FAudio.F3DAUDIO_DSP_SETTINGS dspSettings;
protected bool is3D; public bool Is3D { get; protected set; }
public abstract SoundState State { get; protected set; } public abstract SoundState State { get; protected set; }
@ -33,7 +33,7 @@ namespace MoonWorks.Audio
_pan = 1f; _pan = 1f;
} }
if (is3D) { return; } if (Is3D) { return; }
SetPanMatrixCoefficients(); SetPanMatrixCoefficients();
FAudio.FAudioVoice_SetOutputMatrix( FAudio.FAudioVoice_SetOutputMatrix(
@ -167,8 +167,7 @@ namespace MoonWorks.Audio
ushort bitsPerSample, ushort bitsPerSample,
ushort blockAlign, ushort blockAlign,
ushort channels, ushort channels,
uint samplesPerSecond, uint samplesPerSecond
bool is3D
) : base(device) ) : base(device)
{ {
var format = new FAudio.FAudioWaveFormatEx var format = new FAudio.FAudioWaveFormatEx
@ -200,7 +199,6 @@ namespace MoonWorks.Audio
return; return;
} }
this.is3D = is3D;
InitDSPSettings(Format.nChannels); InitDSPSettings(Format.nChannels);
// FIXME: not everything should be running through reverb... // FIXME: not everything should be running through reverb...
@ -216,7 +214,7 @@ namespace MoonWorks.Audio
public void Apply3D(AudioListener listener, AudioEmitter emitter) public void Apply3D(AudioListener listener, AudioEmitter emitter)
{ {
is3D = true; Is3D = true;
emitter.emitterData.CurveDistanceScaler = Device.CurveDistanceScalar; emitter.emitterData.CurveDistanceScaler = Device.CurveDistanceScalar;
emitter.emitterData.ChannelCount = dspSettings.SrcChannelCount; emitter.emitterData.ChannelCount = dspSettings.SrcChannelCount;
@ -273,7 +271,7 @@ namespace MoonWorks.Audio
{ {
float doppler; float doppler;
float dopplerScale = Device.DopplerScale; float dopplerScale = Device.DopplerScale;
if (!is3D || dopplerScale == 0.0f) if (!Is3D || dopplerScale == 0.0f)
{ {
doppler = 1.0f; doppler = 1.0f;
} }

View File

@ -275,7 +275,7 @@ namespace MoonWorks.Audio
{ {
if (Instances.Count == 0) if (Instances.Count == 0)
{ {
Instances.Push(new StaticSoundInstance(Device, this, false)); Instances.Push(new StaticSoundInstance(Device, this));
} }
return Instances.Pop(); return Instances.Pop();

View File

@ -32,9 +32,8 @@ namespace MoonWorks.Audio
internal StaticSoundInstance( internal StaticSoundInstance(
AudioDevice device, AudioDevice device,
StaticSound parent, StaticSound parent
bool is3D ) : base(device, parent.FormatTag, parent.BitsPerSample, parent.BlockAlign, parent.Channels, parent.SamplesPerSecond)
) : base(device, parent.FormatTag, parent.BitsPerSample, parent.BlockAlign, parent.Channels, parent.SamplesPerSecond, is3D)
{ {
Parent = parent; Parent = parent;
} }

View File

@ -22,9 +22,8 @@ namespace MoonWorks.Audio
ushort bitsPerSample, ushort bitsPerSample,
ushort blockAlign, ushort blockAlign,
ushort channels, ushort channels,
uint samplesPerSecond, uint samplesPerSecond
bool is3D ) : base(device, formatTag, bitsPerSample, blockAlign, channels, samplesPerSecond) { }
) : base(device, formatTag, bitsPerSample, blockAlign, channels, samplesPerSecond, is3D) { }
public override void Play(bool loop = false) public override void Play(bool loop = false)
{ {

View File

@ -1,5 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
namespace MoonWorks.Audio namespace MoonWorks.Audio
{ {
@ -8,52 +9,51 @@ namespace MoonWorks.Audio
// FIXME: what should this value be? // FIXME: what should this value be?
public const int BUFFER_SIZE = 1024 * 128; public const int BUFFER_SIZE = 1024 * 128;
internal IntPtr FileHandle { get; } private IntPtr VorbisHandle;
internal FAudio.stb_vorbis_info Info { get; } 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 override SoundState State { get; protected set; }
public static StreamingSoundOgg Load( public static StreamingSoundOgg Load(AudioDevice device, string filePath)
AudioDevice device,
string filePath,
bool is3D = false
)
{ {
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) if (error != 0)
{ {
((GCHandle) fileDataPtr).Free();
Logger.LogError("Error opening OGG file!"); Logger.LogError("Error opening OGG file!");
throw new AudioLoadException("Error opening OGG file!"); throw new AudioLoadException("Error opening OGG file!");
} }
var info = FAudio.stb_vorbis_get_info(vorbisHandle);
var info = FAudio.stb_vorbis_get_info(fileHandle);
return new StreamingSoundOgg( return new StreamingSoundOgg(
device, device,
fileHandle, fileDataPtr,
info, vorbisHandle,
is3D info
); );
} }
internal StreamingSoundOgg( internal StreamingSoundOgg(
AudioDevice device, AudioDevice device,
IntPtr fileHandle, IntPtr fileDataPtr, // MUST BE PINNED!!
FAudio.stb_vorbis_info info, IntPtr vorbisHandle,
bool is3D FAudio.stb_vorbis_info info
) : base( ) : base(
device, device,
3, /* float type */ 3, /* float type */
32, /* size of float */ 32, /* size of float */
(ushort) (4 * info.channels), (ushort) (4 * info.channels),
(ushort) info.channels, (ushort) info.channels,
info.sample_rate, info.sample_rate
is3D
) )
{ {
FileHandle = fileHandle; FileDataPtr = fileDataPtr;
VorbisHandle = vorbisHandle;
Info = info; Info = info;
buffer = new float[BUFFER_SIZE]; buffer = new float[BUFFER_SIZE];
@ -71,7 +71,7 @@ namespace MoonWorks.Audio
/* NOTE: this function returns samples per channel, not total samples */ /* NOTE: this function returns samples per channel, not total samples */
var samples = FAudio.stb_vorbis_get_samples_float_interleaved( var samples = FAudio.stb_vorbis_get_samples_float_interleaved(
FileHandle, VorbisHandle,
Info.channels, Info.channels,
buffer, buffer,
buffer.Length buffer.Length
@ -85,12 +85,13 @@ namespace MoonWorks.Audio
protected override void SeekStart() protected override void SeekStart()
{ {
FAudio.stb_vorbis_seek_start(FileHandle); FAudio.stb_vorbis_seek_start(VorbisHandle);
} }
protected override void Destroy() protected override void Destroy()
{ {
FAudio.stb_vorbis_close(FileHandle); ((GCHandle) FileDataPtr).Free();
FAudio.stb_vorbis_close(VorbisHandle);
} }
} }
} }