C# 使用NAudio/WASAPI进行设备反射率测试
背景-为了确保设备满足听力学测试的需要,开发了一种称为反射的方法C# 使用NAudio/WASAPI进行设备反射率测试,c#,naudio,C#,Naudio,背景-为了确保设备满足听力学测试的需要,开发了一种称为反射的方法 在环回模式下连接设备(使用两根电缆将L输出连接到L麦克风输入,R输出连接到R麦克风输入) 在输出端播放扫频啁啾,并从麦克风捕获录制的输入。执行此操作两次,然后比较两次录制的输入 在步骤2上循环数百次,每次运行时使用一些数学函数比较时域、频域、信噪比等两种波 比较所有数百次运行的输出,确保值在所需范围内 我们可以使用ASIO(特别是InitRecordAndPlayback方法并捕获AudioAvailable事件中的数据)来实现这
public class SignalGenerator : ISampleProvider
{
private readonly WaveFormat waveFormat;
public SignalGenerator()
: this(44100, 2)
{
}
public SignalGenerator(int sampleRate, int channel)
{
waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channel);
}
public WaveFormat WaveFormat => waveFormat;
private int position;
public int Read(float[] buffer, int offset, int count)
{
int outIndex = offset;
var availableSamples = OutputData.Length - position;
var samplesToCopy = Math.Min(availableSamples, count / waveFormat.Channels);
for (int i = 0; i < samplesToCopy; i++)
{
for (var j = 0; j < waveFormat.Channels; j++)
{
buffer[outIndex++] = (float)OutputData[position];
}
position++;
}
var retCount = Math.Min(count, availableSamples);
if (retCount == 0)
{
System.Diagnostics.Debug.WriteLine("SignalGenerator: EOF");
Array.Clear(buffer, 0, buffer.Length);
position = 0;
}
return retCount;
}
public float[] OutputData { get; set; }
}
公共类信号生成器:ISampleProvider
{
专用只读波形格式;
公共信号发生器()
:这(44100,2)
{
}
公共信号发生器(int采样器、int通道)
{
waveFormat=波形。CreateEEFloatWaveFormat(采样器,通道);
}
公共波形格式WaveFormat=>WaveFormat;
私人职位;
公共整数读取(浮点[]缓冲区、整数偏移量、整数计数)
{
int OUTIDEX=偏移量;
var availableSamples=OutputData.Length-position;
var samplesToCopy=Math.Min(可用的示例、计数/波形通道);
对于(int i=0;i
private IWavePlayer GetWavePlayer()
{
var enumerator = new MMDeviceEnumerator();
var wasapi = enumerator.EnumerateAudioEndPoints(DataFlow.All, DeviceState.All).FirstOrDefault(w => w.FriendlyName == _modelOut.Name);
var waveOut = new WasapiOut(wasapi, UseExclusiveMode ? AudioClientShareMode.Exclusive : AudioClientShareMode.Shared, true, 10);
return waveOut;
}
private IWaveIn GetWaveIn(int rate, int channels)
{
var enumerator = new MMDeviceEnumerator();
var wasapi = enumerator.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.Active).FirstOrDefault();
var wasapiIn = new WasapiCapture(wasapi);
wasapiIn.ShareMode = UseExclusiveMode ? AudioClientShareMode.Exclusive : AudioClientShareMode.Shared;
wasapiIn.WaveFormat = WaveFormat.CreateIeeeFloatWaveFormat(rate, channels);
return wasapiIn;
}
public class SignalGenerator : ISampleProvider
{
private readonly WaveFormat waveFormat;
public SignalGenerator()
: this(44100, 2)
{
}
public SignalGenerator(int sampleRate, int channel)
{
waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channel);
}
public WaveFormat WaveFormat => waveFormat;
private int position;
public int Read(float[] buffer, int offset, int count)
{
int outIndex = offset;
var availableSamples = OutputData.Length - position;
var samplesToCopy = Math.Min(availableSamples, count / waveFormat.Channels);
for (int i = 0; i < samplesToCopy; i++)
{
for (var j = 0; j < waveFormat.Channels; j++)
{
buffer[outIndex++] = (float)OutputData[position];
}
position++;
}
var retCount = Math.Min(count, availableSamples);
if (retCount == 0)
{
System.Diagnostics.Debug.WriteLine("SignalGenerator: EOF");
Array.Clear(buffer, 0, buffer.Length);
position = 0;
}
return retCount;
}
public float[] OutputData { get; set; }
}