2022-02-23 05:14:32 +00:00
|
|
|
|
using System;
|
2021-01-20 03:26:30 +00:00
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
|
|
|
|
namespace MoonWorks.Audio
|
|
|
|
|
{
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public class StaticSound : AudioResource
|
|
|
|
|
{
|
|
|
|
|
internal FAudio.FAudioBuffer Handle;
|
|
|
|
|
public ushort Channels { get; }
|
|
|
|
|
public uint SamplesPerSecond { get; }
|
2021-01-20 03:26:30 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public uint LoopStart { get; set; } = 0;
|
|
|
|
|
public uint LoopLength { get; set; } = 0;
|
2021-01-20 03:26:30 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public static StaticSound LoadOgg(AudioDevice device, string filePath)
|
|
|
|
|
{
|
|
|
|
|
var filePointer = FAudio.stb_vorbis_open_filename(filePath, out var error, IntPtr.Zero);
|
2021-01-20 03:26:30 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
if (error != 0)
|
|
|
|
|
{
|
|
|
|
|
throw new AudioLoadException("Error loading file!");
|
|
|
|
|
}
|
|
|
|
|
var info = FAudio.stb_vorbis_get_info(filePointer);
|
|
|
|
|
var bufferSize = FAudio.stb_vorbis_stream_length_in_samples(filePointer) * info.channels;
|
|
|
|
|
var buffer = new float[bufferSize];
|
2021-01-20 03:26:30 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
FAudio.stb_vorbis_get_samples_float_interleaved(
|
|
|
|
|
filePointer,
|
|
|
|
|
info.channels,
|
|
|
|
|
buffer,
|
|
|
|
|
(int) bufferSize
|
|
|
|
|
);
|
2021-01-20 05:33:25 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
FAudio.stb_vorbis_close(filePointer);
|
2021-01-20 03:26:30 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
return new StaticSound(
|
|
|
|
|
device,
|
|
|
|
|
(ushort) info.channels,
|
|
|
|
|
info.sample_rate,
|
|
|
|
|
buffer,
|
|
|
|
|
0,
|
|
|
|
|
(uint) buffer.Length
|
|
|
|
|
);
|
|
|
|
|
}
|
2021-01-20 03:26:30 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public StaticSound(
|
|
|
|
|
AudioDevice device,
|
|
|
|
|
ushort channels,
|
|
|
|
|
uint samplesPerSecond,
|
|
|
|
|
float[] buffer,
|
|
|
|
|
uint bufferOffset, /* in floats */
|
|
|
|
|
uint bufferLength /* in floats */
|
|
|
|
|
) : base(device)
|
|
|
|
|
{
|
|
|
|
|
Channels = channels;
|
|
|
|
|
SamplesPerSecond = samplesPerSecond;
|
2021-01-20 05:33:25 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
var bufferLengthInBytes = (int) (bufferLength * sizeof(float));
|
|
|
|
|
Handle = new FAudio.FAudioBuffer();
|
|
|
|
|
Handle.Flags = FAudio.FAUDIO_END_OF_STREAM;
|
|
|
|
|
Handle.pContext = IntPtr.Zero;
|
|
|
|
|
Handle.AudioBytes = (uint) bufferLengthInBytes;
|
|
|
|
|
Handle.pAudioData = Marshal.AllocHGlobal(bufferLengthInBytes);
|
|
|
|
|
Marshal.Copy(buffer, (int) bufferOffset, Handle.pAudioData, (int) bufferLength);
|
|
|
|
|
Handle.PlayBegin = 0;
|
|
|
|
|
Handle.PlayLength = 0;
|
2021-01-20 05:33:25 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
LoopStart = 0;
|
|
|
|
|
LoopLength = 0;
|
|
|
|
|
}
|
2021-01-20 05:33:25 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public StaticSoundInstance CreateInstance(bool loop = false)
|
|
|
|
|
{
|
|
|
|
|
return new StaticSoundInstance(Device, this, false, loop);
|
|
|
|
|
}
|
2021-01-20 03:26:30 +00:00
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
protected override void Destroy()
|
|
|
|
|
{
|
|
|
|
|
Marshal.FreeHGlobal(Handle.pAudioData);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-20 03:26:30 +00:00
|
|
|
|
}
|