Playback: append OutputStream playback of recorded buffer
This commit is contained in:
@@ -85,6 +85,62 @@ try
|
||||
|
||||
WavWriter.Write(OutWav, buf, SampleRate);
|
||||
Console.WriteLine($"Wrote {OutWav} ({buf.Length} frames @ {SampleRate} Hz)");
|
||||
|
||||
Console.WriteLine($"Playing back through device {device}");
|
||||
|
||||
int playOffset = 0;
|
||||
object playGate = new();
|
||||
var doneEvent = new ManualResetEventSlim(false);
|
||||
|
||||
var outParams = new StreamParameters
|
||||
{
|
||||
device = device,
|
||||
channelCount = Channels,
|
||||
sampleFormat = SampleFormat.Int16,
|
||||
suggestedLatency = PortAudio.GetDeviceInfo(device).defaultLowOutputLatency,
|
||||
hostApiSpecificStreamInfo = IntPtr.Zero,
|
||||
};
|
||||
|
||||
Stream.Callback playCb = (IntPtr _, IntPtr output, uint frameCount,
|
||||
ref StreamCallbackTimeInfo _2, StreamCallbackFlags _3, IntPtr _4) =>
|
||||
{
|
||||
lock (playGate)
|
||||
{
|
||||
int remaining = buf.Length - playOffset;
|
||||
int take = (int)Math.Min(frameCount, (uint)remaining);
|
||||
int silence = (int)frameCount - take;
|
||||
|
||||
unsafe
|
||||
{
|
||||
short* dst = (short*)output.ToPointer();
|
||||
if (take > 0)
|
||||
{
|
||||
fixed (short* src = &buf[playOffset])
|
||||
Buffer.MemoryCopy(src, dst, take * sizeof(short), take * sizeof(short));
|
||||
playOffset += take;
|
||||
}
|
||||
if (silence > 0)
|
||||
{
|
||||
for (int i = take; i < frameCount; i++) dst[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (playOffset >= buf.Length)
|
||||
{
|
||||
doneEvent.Set();
|
||||
return StreamCallbackResult.Complete;
|
||||
}
|
||||
}
|
||||
return StreamCallbackResult.Continue;
|
||||
};
|
||||
|
||||
using var playStream = new Stream(
|
||||
null, outParams, SampleRate, BlockFrames, StreamFlags.NoFlag, playCb, IntPtr.Zero);
|
||||
playStream.Start();
|
||||
doneEvent.Wait();
|
||||
// Give PortAudio a moment to drain the device buffer before Stop().
|
||||
Thread.Sleep(200);
|
||||
playStream.Stop();
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user