在工控机功能测试行业做了10来年,大部分功能测试都已实现自动化,唯独感官测试,因为都是模拟量,所以难以测定,不过经过多年的尝试,还是在逐步的突破,Audio全自动化测试就是其中之一。也许有人说,直接上仪器就好了,“成本、成本、成本!”我们要做的就是已最低的成本来实现自动化。话不多说,进入正题!
之前一直用C++ Bulider,最近一年才用VS C#开发,发现C#是真香,很多功能都打包在程序集里,引用后直接调用它的方法,简直是傻瓜式编程开发,无愧低代码。
目录
-
安装程序集
在项目名称上右击--管理GuGet程序包(N)
在搜索框里输入NAudio进行安装
-
引用程序集
using NAudio;
using NAudio.CoreAudioApi;
using MMDevice = NAudio.CoreAudioApi.MMDevice;
using MMDeviceEnumerator = NAudio.CoreAudioApi.MMDeviceEnumerator;
-
枚举声音设备(输入/输出)
//定义一个dataFlow对象
MMDeviceEnumerator enumerator;
//实例化enumerator
enumerator = new MMDeviceEnumerator();
DataFlow.Render用来表达要枚举的声音输出设备,DataFlow.Capture用来表达要枚举的是声音输入设备,另外还有DataFlow.ALL用来表达要枚举的是所有设备,包含输入和输出。
NAudio.CoreAudioApi.DeviceState.Active代表获取的处于活跃状态的设备,什么叫活跃状态,看下面的解释。
//声音输出设备
IEnumerable<MMDevice> playBackList;
//获取声音输出设备
playBackList = enumerator.EnumerateAudioEndPoints(DataFlow.Render, NAudio.CoreAudioApi.DeviceState.Active).ToArray();
//声音输入设备
IEnumerable<MMDevice> captureList;
//获取声音输入设备
captureList = enumerator.EnumerateAudioEndPoints(DataFlow.Capture, NAudio.CoreAudioApi.DeviceState.Active).ToArray();
所谓的活跃就是如下图高亮的图标,那种灰色的图标就是非活跃状态。
如果要获取其它状态的设备,只需要更改参数NAudio.CoreAudioApi.DeviceState为对应的状态即可,支持的状态如下:
namespace NAudio.CoreAudioApi
{
[Flags]
public enum DeviceState
{
Active = 1,
Disabled = 2,
NotPresent = 4,
Unplugged = 8,
All = 15
}
}
获取的设备信息中,针对于我们做自动化测试,需要用到两个信息,一个是FriendlyName,用来确认该设备是不是我们要测试的设备,如果不是则将其排除;另一个是ID,用来将该设备切换为默认设备,因为接下来对声音设备的操作,都是对默认设备的操作,所以要操作哪个设备,就要先根据ID将其切换为默认设备以及默认通信设备。
-
完整的代码段
public partial class Form1 : Form
{
//定義一個dataFlow对象
MMDeviceEnumerator enumerator;
//音頻輸出設備List
//List<WaveInCapabilities> waveInList = new List<WaveInCapabilities>();
IEnumerable<MMDevice> playBackList;
ICollection<MMDevice> playbackListCurr;
Dictionary<int, MMDevice> playbackGroup;
//音頻輸入設備List
IEnumerable<MMDevice> captureList;
ICollection<MMDevice> captureListCurr;
Dictionary<int, ICollection<MMDevice>> captureGroup;
private void Form1_Load(object sender, EventArgs e)
{
enumerator = new MMDeviceEnumerator();
GetWaveDevice();
}
/// <summary>
/// 獲取音頻輸入/輸出設備
/// </summary>
/// <returns></returns>
private bool GetWaveDevice()
{
richTextBox1.AppendText("#Get Wave Output/Input Device\n");
bool flag = true;
//先釋放輸入/輸出設備緩存,並重新實例化
if (playBackList != null)
{
playBackList = null;
}
if (playbackListCurr != null)
{
playbackListCurr.Clear();
playbackListCurr = null;
}
if (captureList != null)
{
captureList = null;
}
if (captureListCurr != null)
{
captureListCurr.Clear();
captureListCurr = null;
}
playbackListCurr = new List<MMDevice>();
captureListCurr = new List<MMDevice>();
//獲取音頻輸出設備
try
{
playBackList = enumerator.EnumerateAudioEndPoints(DataFlow.Render, NAudio.CoreAudioApi.DeviceState.Active).ToArray();
if (playBackList.Count() == 0)
{
richTextBox1.AppendText(" Not Find Any Output Device\n");
}
else
{
foreach (var ad in playBackList)
{
if (audioParamConfig.IncludePlaybackString.Contains(ad.FriendlyName))
{
playbackListCurr.Add(ad);
richTextBox1.AppendText(" Output Device {" + ad.ID.ToString() + "}:" + ad.FriendlyName + "\n");
}
}
}
}
catch (Exception msg)
{
richTextBox2.AppendText("獲取音頻輸出設備失敗:" + msg.Message + "\n");
richTextBox1.AppendText(" Get Output Device Error: " + msg.Message + "\n");
flag = false;
}
//獲取音頻輸入設備
try
{
captureList = enumerator.EnumerateAudioEndPoints(DataFlow.Capture, NAudio.CoreAudioApi.DeviceState.Active).ToArray();
if (captureList.Count() == 0)
{
richTextBox1.AppendText(" Not Find Any Input Device\n");
}
else
{
foreach (var ad in captureList)
{
if (audioParamConfig.IncludeCaptureString.Contains(ad.FriendlyName))
{
captureListCurr.Add(ad);
richTextBox1.AppendText(" Input Device {" + ad.ID.ToString() + "}:" + ad.FriendlyName + "\n");
}
}
}
}
catch (Exception msg)
{
richTextBox2.AppendText("獲取音頻輸入設備失敗:" + msg.Message + "\n");
richTextBox1.AppendText(" Get Input Device Error: " + msg.Message + "\n");
flag = false;
}
return flag;
}
}
声音设备操作https://blog.csdn.net/u011465910/article/details/127868804