Playback: append OutputStream playback of recorded buffer
This commit is contained in:
@@ -85,6 +85,62 @@ try
|
|||||||
|
|
||||||
WavWriter.Write(OutWav, buf, SampleRate);
|
WavWriter.Write(OutWav, buf, SampleRate);
|
||||||
Console.WriteLine($"Wrote {OutWav} ({buf.Length} frames @ {SampleRate} Hz)");
|
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
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user