StaticSound external byte buffer constructor

pull/48/head
cosmonaut 2023-04-04 17:12:03 -07:00
parent 8134761e44
commit 3bd435746b
2 changed files with 86 additions and 23 deletions

42
src/Audio/AudioUtils.cs Normal file
View File

@ -0,0 +1,42 @@
using System.IO;
namespace MoonWorks.Audio
{
public static class AudioUtils
{
public struct WaveHeaderData
{
public int FileLength;
public short FormatTag;
public short Channels;
public int SampleRate;
public short BitsPerSample;
public short BlockAlign;
public int DataLength;
}
public static WaveHeaderData ReadWaveHeaderData(string filePath)
{
WaveHeaderData headerData;
var fileInfo = new FileInfo(filePath);
using FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
using BinaryReader br = new BinaryReader(fs);
headerData.FileLength = (int)fileInfo.Length - 8;
fs.Position = 20;
headerData.FormatTag = br.ReadInt16();
fs.Position = 22;
headerData.Channels = br.ReadInt16();
fs.Position = 24;
headerData.SampleRate = br.ReadInt32();
fs.Position = 32;
headerData.BlockAlign = br.ReadInt16();
fs.Position = 34;
headerData.BitsPerSample = br.ReadInt16();
fs.Position = 40;
headerData.DataLength = br.ReadInt32();
return headerData;
}
}
}

View File

@ -19,6 +19,8 @@ namespace MoonWorks.Audio
private Stack<StaticSoundInstance> Instances = new Stack<StaticSoundInstance>(); private Stack<StaticSoundInstance> Instances = new Stack<StaticSoundInstance>();
private bool OwnsBuffer;
public static StaticSound LoadOgg(AudioDevice device, string filePath) public static StaticSound LoadOgg(AudioDevice device, string filePath)
{ {
var filePointer = FAudio.stb_vorbis_open_filename(filePath, out var error, IntPtr.Zero); var filePointer = FAudio.stb_vorbis_open_filename(filePath, out var error, IntPtr.Zero);
@ -190,7 +192,7 @@ namespace MoonWorks.Audio
); );
} }
public StaticSound( public unsafe StaticSound(
AudioDevice device, AudioDevice device,
ushort formatTag, ushort formatTag,
ushort bitsPerSample, ushort bitsPerSample,
@ -212,33 +214,18 @@ namespace MoonWorks.Audio
Handle.Flags = FAudio.FAUDIO_END_OF_STREAM; Handle.Flags = FAudio.FAUDIO_END_OF_STREAM;
Handle.pContext = IntPtr.Zero; Handle.pContext = IntPtr.Zero;
Handle.AudioBytes = bufferLength; Handle.AudioBytes = bufferLength;
Handle.pAudioData = Marshal.AllocHGlobal((int) bufferLength); Handle.pAudioData = (nint) NativeMemory.Alloc(bufferLength);
Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, (int) bufferLength); Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, (int) bufferLength);
Handle.PlayBegin = 0; Handle.PlayBegin = 0;
Handle.PlayLength = 0; Handle.PlayLength = 0;
if (formatTag == 1)
{
Handle.PlayLength = (uint) (
bufferLength /
channels /
(bitsPerSample / 8)
);
}
else if (formatTag == 2)
{
Handle.PlayLength = (uint) (
bufferLength /
blockAlign *
(((blockAlign / channels) - 6) * 2)
);
}
LoopStart = 0; LoopStart = 0;
LoopLength = 0; LoopLength = 0;
OwnsBuffer = true;
} }
public StaticSound( public unsafe StaticSound(
AudioDevice device, AudioDevice device,
ushort channels, ushort channels,
uint samplesPerSecond, uint samplesPerSecond,
@ -258,13 +245,44 @@ namespace MoonWorks.Audio
Handle.Flags = FAudio.FAUDIO_END_OF_STREAM; Handle.Flags = FAudio.FAUDIO_END_OF_STREAM;
Handle.pContext = IntPtr.Zero; Handle.pContext = IntPtr.Zero;
Handle.AudioBytes = (uint) bufferLengthInBytes; Handle.AudioBytes = (uint) bufferLengthInBytes;
Handle.pAudioData = Marshal.AllocHGlobal(bufferLengthInBytes); Handle.pAudioData = (nint) NativeMemory.Alloc((nuint) bufferLengthInBytes);
Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, (int) bufferLength); Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, (int) bufferLength);
Handle.PlayBegin = 0; Handle.PlayBegin = 0;
Handle.PlayLength = 0; Handle.PlayLength = 0;
LoopStart = 0; LoopStart = 0;
LoopLength = 0; LoopLength = 0;
OwnsBuffer = true;
}
public StaticSound(
AudioDevice device,
ushort formatTag,
ushort bitsPerSample,
ushort blockAlign,
ushort channels,
uint samplesPerSecond,
IntPtr bufferPtr,
uint bufferLengthInBytes) : base(device)
{
FormatTag = formatTag;
BitsPerSample = bitsPerSample;
BlockAlign = blockAlign;
Channels = channels;
SamplesPerSecond = samplesPerSecond;
Handle = new FAudio.FAudioBuffer
{
Flags = FAudio.FAUDIO_END_OF_STREAM,
pContext = IntPtr.Zero,
pAudioData = bufferPtr,
AudioBytes = bufferLengthInBytes,
PlayBegin = 0,
PlayLength = 0
};
OwnsBuffer = false;
} }
/// <summary> /// <summary>
@ -287,9 +305,12 @@ namespace MoonWorks.Audio
Instances.Push(instance); Instances.Push(instance);
} }
protected override void Destroy() protected override unsafe void Destroy()
{ {
Marshal.FreeHGlobal(Handle.pAudioData); if (OwnsBuffer)
{
NativeMemory.Free((void*) Handle.pAudioData);
}
} }
} }
} }