forked from MoonsideGames/MoonWorks
stream ogg from memory instead of disk
parent
5e2b8de2d3
commit
ba66ed4225
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue