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