TASK 4 ship step 4: WASAPI audio capture — NAudio loopback + mic behind an IAudioSource seam, AudioMixer driving AudioLevel while live, pure level meter + WaveToFloat, NAudio.Wasapi 2.2.1 (MIT, notices item 9) — 139 tests passing, 0 warnings
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
using NAudio.Dmo;
|
||||
using NAudio.Wave;
|
||||
|
||||
namespace ytLive.Services.Audio;
|
||||
|
||||
/// <summary>
|
||||
/// Converts NAudio's raw WASAPI capture buffers (byte[], whatever bit depth the
|
||||
/// device's mix format reports) into interleaved PCM float samples. Pure —
|
||||
/// unit-tested; the two WASAPI sources share it.
|
||||
/// </summary>
|
||||
public static class WaveToFloat
|
||||
{
|
||||
public static float[] Convert(byte[] buffer, int bytesRecorded, WaveFormat format)
|
||||
{
|
||||
if (format.Encoding == WaveFormatEncoding.IeeeFloat && format.BitsPerSample == 32)
|
||||
return ConvertIeeeFloat(buffer, bytesRecorded);
|
||||
if (format.Encoding == WaveFormatEncoding.Pcm && format.BitsPerSample == 16)
|
||||
return ConvertPcm16(buffer, bytesRecorded);
|
||||
if (format is WaveFormatExtensible extensible
|
||||
&& extensible.SubFormat == AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT)
|
||||
return ConvertIeeeFloat(buffer, bytesRecorded);
|
||||
return ConvertPcm16(buffer, bytesRecorded);
|
||||
}
|
||||
|
||||
private static float[] ConvertIeeeFloat(byte[] buffer, int bytesRecorded)
|
||||
{
|
||||
var count = bytesRecorded / 4;
|
||||
var result = new float[count];
|
||||
Buffer.BlockCopy(buffer, 0, result, 0, count * 4);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static float[] ConvertPcm16(byte[] buffer, int bytesRecorded)
|
||||
{
|
||||
var count = bytesRecorded / 2;
|
||||
var result = new float[count];
|
||||
for (var i = 0; i < count; i++)
|
||||
result[i] = BitConverter.ToInt16(buffer, i * 2) / 32768f;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user