optimize StreamingSound allocation and update
parent
b4a0c7de88
commit
dc7e68fecc
|
@ -1,23 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MoonWorks.Audio
|
||||
{
|
||||
/// <summary>
|
||||
/// For streaming long playback.
|
||||
/// Can be extended to support custom decoders.
|
||||
/// Must be extended with a decoder routine called by FillBuffer.
|
||||
/// See StreamingSoundOgg for an example.
|
||||
/// </summary>
|
||||
public abstract class StreamingSound : SoundInstance
|
||||
{
|
||||
private readonly List<IntPtr> queuedBuffers = new List<IntPtr>();
|
||||
private const int MINIMUM_BUFFER_CHECK = 3;
|
||||
|
||||
private int PendingBufferCount => queuedBuffers.Count;
|
||||
|
||||
private const int BUFFER_COUNT = 3;
|
||||
private readonly IntPtr[] buffers;
|
||||
private int nextBufferIndex = 0;
|
||||
private uint queuedBufferCount = 0;
|
||||
public abstract int BUFFER_SIZE { get; }
|
||||
|
||||
public StreamingSound(
|
||||
public unsafe StreamingSound(
|
||||
AudioDevice device,
|
||||
ushort formatTag,
|
||||
ushort bitsPerSample,
|
||||
|
@ -27,6 +26,12 @@ namespace MoonWorks.Audio
|
|||
) : base(device, formatTag, bitsPerSample, blockAlign, channels, samplesPerSecond)
|
||||
{
|
||||
device.AddDynamicSoundInstance(this);
|
||||
|
||||
buffers = new IntPtr[BUFFER_COUNT];
|
||||
for (int i = 0; i < BUFFER_COUNT; i += 1)
|
||||
{
|
||||
buffers[i] = (IntPtr) NativeMemory.Alloc((nuint) BUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Play()
|
||||
|
@ -78,25 +83,14 @@ namespace MoonWorks.Audio
|
|||
FAudio.FAUDIO_VOICE_NOSAMPLESPLAYED
|
||||
);
|
||||
|
||||
while (PendingBufferCount > state.BuffersQueued)
|
||||
{
|
||||
lock (queuedBuffers)
|
||||
{
|
||||
NativeMemory.Free((void*) queuedBuffers[0]);
|
||||
queuedBuffers.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
queuedBufferCount = state.BuffersQueued;
|
||||
|
||||
QueueBuffers();
|
||||
}
|
||||
|
||||
protected void QueueBuffers()
|
||||
{
|
||||
for (
|
||||
int i = MINIMUM_BUFFER_CHECK - PendingBufferCount;
|
||||
i > 0;
|
||||
i -= 1
|
||||
)
|
||||
for (int i = 0; i < BUFFER_COUNT - queuedBufferCount; i += 1)
|
||||
{
|
||||
AddBuffer();
|
||||
}
|
||||
|
@ -104,32 +98,22 @@ namespace MoonWorks.Audio
|
|||
|
||||
protected unsafe void ClearBuffers()
|
||||
{
|
||||
lock (queuedBuffers)
|
||||
{
|
||||
foreach (IntPtr buf in queuedBuffers)
|
||||
{
|
||||
NativeMemory.Free((void*) buf);
|
||||
}
|
||||
queuedBuffers.Clear();
|
||||
}
|
||||
nextBufferIndex = 0;
|
||||
queuedBufferCount = 0;
|
||||
}
|
||||
|
||||
protected unsafe void AddBuffer()
|
||||
{
|
||||
void* buffer = NativeMemory.Alloc((nuint) BUFFER_SIZE);
|
||||
var buffer = buffers[nextBufferIndex];
|
||||
nextBufferIndex = (nextBufferIndex + 1) % BUFFER_COUNT;
|
||||
|
||||
FillBuffer(
|
||||
buffer,
|
||||
(void*) buffer,
|
||||
BUFFER_SIZE,
|
||||
out int filledLengthInBytes,
|
||||
out bool reachedEnd
|
||||
);
|
||||
|
||||
lock (queuedBuffers)
|
||||
{
|
||||
queuedBuffers.Add((IntPtr) buffer);
|
||||
if (State != SoundState.Stopped)
|
||||
{
|
||||
FAudio.FAudioBuffer buf = new FAudio.FAudioBuffer
|
||||
{
|
||||
AudioBytes = (uint) filledLengthInBytes,
|
||||
|
@ -146,9 +130,8 @@ namespace MoonWorks.Audio
|
|||
ref buf,
|
||||
IntPtr.Zero
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
queuedBufferCount += 1;
|
||||
|
||||
/* We have reached the end of the file, what do we do? */
|
||||
if (reachedEnd)
|
||||
|
@ -169,9 +152,14 @@ namespace MoonWorks.Audio
|
|||
out bool reachedEnd
|
||||
);
|
||||
|
||||
protected override void Destroy()
|
||||
protected unsafe override void Destroy()
|
||||
{
|
||||
StopImmediate();
|
||||
|
||||
for (int i = 0; i < BUFFER_COUNT; i += 1)
|
||||
{
|
||||
NativeMemory.Free((void*) buffers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue