start reimplementing streaming audio on voice API
parent
c2cb83f93f
commit
a0408a863c
|
@ -159,6 +159,8 @@ namespace MoonWorks.Audio
|
||||||
previousTickTime = TickStopwatch.Elapsed.Ticks;
|
previousTickTime = TickStopwatch.Elapsed.Ticks;
|
||||||
float elapsedSeconds = (float) tickDelta / System.TimeSpan.TicksPerSecond;
|
float elapsedSeconds = (float) tickDelta / System.TimeSpan.TicksPerSecond;
|
||||||
|
|
||||||
|
// TODO: call an Update on all active voices
|
||||||
|
|
||||||
for (var i = autoUpdateStreamingSoundReferences.Count - 1; i >= 0; i -= 1)
|
for (var i = autoUpdateStreamingSoundReferences.Count - 1; i >= 0; i -= 1)
|
||||||
{
|
{
|
||||||
var streamingSound = autoUpdateStreamingSoundReferences[i];
|
var streamingSound = autoUpdateStreamingSoundReferences[i];
|
||||||
|
@ -206,6 +208,8 @@ namespace MoonWorks.Audio
|
||||||
FAudio.FAudio_CommitChanges(Handle, syncGroup);
|
FAudio.FAudio_CommitChanges(Handle, syncGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: is pooling SourceVoices generically a good idea? there are a lot of different kinds
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Obtains an appropriate source voice from the voice pool.
|
/// Obtains an appropriate source voice from the voice pool.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -160,11 +160,6 @@ namespace MoonWorks.Audio
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Submit(StreamingSound streamingSound)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Designates that this source voice will return to the voice pool once all its buffers are exhausted.
|
/// Designates that this source voice will return to the voice pool once all its buffers are exhausted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -165,7 +165,7 @@ namespace MoonWorks.Audio
|
||||||
queuedBufferCount = 0;
|
queuedBufferCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected unsafe void AddBuffer()
|
public unsafe void AddBuffer()
|
||||||
{
|
{
|
||||||
var buffer = buffers[nextBufferIndex];
|
var buffer = buffers[nextBufferIndex];
|
||||||
nextBufferIndex = (nextBufferIndex + 1) % BUFFER_COUNT;
|
nextBufferIndex = (nextBufferIndex + 1) % BUFFER_COUNT;
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue