93 lines
1.7 KiB
C#
93 lines
1.7 KiB
C#
using System;
|
|
|
|
namespace MoonWorks.Audio
|
|
{
|
|
public abstract class StreamingVoice : SourceVoice
|
|
{
|
|
private const int BUFFER_COUNT = 3;
|
|
private readonly IntPtr[] buffers;
|
|
private int nextBufferIndex = 0;
|
|
private uint BufferSize;
|
|
|
|
public bool Loop { get; set; }
|
|
|
|
public StreamingVoice(AudioDevice device, Format format, uint bufferSize) : base(device, format)
|
|
{
|
|
BufferSize = bufferSize;
|
|
}
|
|
|
|
internal unsafe void Update()
|
|
{
|
|
lock (StateLock)
|
|
{
|
|
if (!IsDisposed)
|
|
{
|
|
if (State != SoundState.Playing)
|
|
{
|
|
return;
|
|
}
|
|
|
|
QueueBuffers();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected void QueueBuffers()
|
|
{
|
|
var buffersQueued = BuffersQueued;
|
|
for (int i = 0; i < BUFFER_COUNT - buffersQueued; i += 1)
|
|
{
|
|
AddBuffer();
|
|
}
|
|
}
|
|
|
|
protected unsafe void AddBuffer()
|
|
{
|
|
var buffer = buffers[nextBufferIndex];
|
|
nextBufferIndex = (nextBufferIndex + 1) % BUFFER_COUNT;
|
|
|
|
FillBuffer(
|
|
(void*) buffer,
|
|
(int) BufferSize,
|
|
out int filledLengthInBytes,
|
|
out bool reachedEnd
|
|
);
|
|
|
|
if (filledLengthInBytes > 0)
|
|
{
|
|
var buf = new FAudio.FAudioBuffer
|
|
{
|
|
AudioBytes = (uint) filledLengthInBytes,
|
|
pAudioData = buffer,
|
|
PlayLength = (
|
|
(uint) (filledLengthInBytes /
|
|
Format.Channels /
|
|
(uint) (Format.BitsPerSample / 8))
|
|
)
|
|
};
|
|
|
|
Submit(buf);
|
|
}
|
|
|
|
if (reachedEnd)
|
|
{
|
|
/* We have reached the end of the data, what do we do? */
|
|
if (Loop)
|
|
{
|
|
SeekStart();
|
|
AddBuffer();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected unsafe abstract void FillBuffer(
|
|
void* buffer,
|
|
int bufferLengthInBytes, /* in bytes */
|
|
out int filledLengthInBytes, /* in bytes */
|
|
out bool reachedEnd
|
|
);
|
|
|
|
protected abstract void SeekStart();
|
|
}
|
|
}
|