65.9K
CodeProject 正在变化。 阅读更多。
Home

如何通过 WASAPI 和 Audio Sound Recorder for .NET 录制任何 PC 声音

2014年5月9日

CPOL

4分钟阅读

viewsIcon

47299

如何在 Windows Vista 及更高版本上,通过利用 Audio Sound Recorder for .NET 中的 WASAPI 子系统,以编程方式启动录音会话,录制 Windows Media Player 或 YouTube 等第三方应用程序正在通过特定输出设备播放的任何声音。

引言

从 Windows Vista 开始,Microsoft 从头开始重写了 Windows 操作系统的多媒体子系统;与此同时,Microsoft 引入了一个名为Core Audio API 的新 API,该 API 允许与多媒体子系统和音频终结点设备(声卡)进行交互。新的 Core Audio API 之一是Windows Audio Session API (也称为WASAPI),它可以管理三种不同类型的设备:

  • 渲染设备 是音频数据从应用程序流向音频终结点设备(渲染音频流)的播放设备。
  • 捕获设备 是音频数据从捕获音频流的音频终结点设备流向应用程序的录制设备。
  • 环回设备 是录制设备,它捕获特定渲染设备正在渲染的所有音频流的混合,即使音频流是由 Windows Media Player 等第三方多媒体应用程序播放的:每个渲染设备始终都有一个相应的环回设备。

Audio Sound Recorder for .NET 如何帮助轻松管理 WASAPI

正如大多数 Microsoft 开发的 API 一样,WASAPI 由多个 COM 接口组成,这些接口的使用并不总是直接的:Audio Sound Recorder for .NET 允许开发人员轻松利用 WASAPI 功能的子集,以便在他们的应用程序中创建和管理与音频终结点设备之间的数据流。

通过 Audio Sound Recorder for .NET 组件使用 WASAPI 功能的主要方面如下:

  • 初始化 WASAPI 子系统
  • 枚举各种类型的音频终结点设备(渲染、捕获和环回)
  • 启动特定终结点设备并录制其数据流
  • 停止录音会话和特定音频终结点设备

在本教程中,我们想了解如何从捕获设备或环回设备启动录音会话,以便将传入的音频数据存储到特定音频格式的输出声音文件中,并在录音会话停止后回放同一文件。

我们的示例应用程序的用户界面如下所示:

初始化 WASAPI 子系统和组件的录音系统

默认情况下,Audio Sound Recorder for .NET 通过 DirectSound 和 WDM 驱动程序访问音频设备,因此,为了利用 WASAPI,我们需要通过 InitDriversType 方法指定该组件我们想使用不同类型的驱动程序,然后通过强制调用 InitRecordingSystem 方法来初始化该组件。

private void Form1_Load(object sender, EventArgs e)
{
       // initialize usage of WASAPI audio drivers
       enumErrorCodes nReturn = audioSoundRecorder1.InitDriversType (enumDriverTypes.DRIVER_TYPE_WASAPI);
       if (nReturn == enumErrorCodes.ERR_INVALID_PLATFORM)
       {
             MessageBox.Show("This sample can only work on Windows Vista or higher versions.
                           The program will now close.");
             Close();
             return;
       }
 
       // init the control
       audioSoundRecorder1.InitRecordingSystem();
 
       // do other initialization stuffs
       ...

枚举各种类型的音频终结点设备(渲染、捕获和环回)

在驱动程序初始化之后,我们可以通过 WASAPI.DeviceGetCountWASAPI.DeviceGetDesc 方法的组合来枚举可用的音频终结点设备,这些方法还将允许填充用户界面上的几个组合框;由于我们将此示例用作录音系统,因此我们主要对枚举捕获和环回设备感兴趣,而对于播放,我们将使用系统的默认设备。

       // enumerate audio input devices
       int nCaptureDevices = 0;
       audioSoundRecorder1.WASAPI.DeviceGetCount (enumWasapiDeviceTypes.WASAPI_DEVICE_TYPE_CAPTURE,
                                        ref nCaptureDevices);
       for (int i = 0; i < nCaptureDevices; i++)
       {
             string strCaptureDevice = audioSoundRecorder1.WASAPI.DeviceGetDesc (i,
                                        enumWasapiDeviceTypes.WASAPI_DEVICE_TYPE_CAPTURE);
             comboCaptureDevices.Items.Add(strCaptureDevice);
       }
 
       // enumerate loopback devices
       int nLoopbackDevices = 0;
       audioSoundRecorder1.WASAPI.DeviceGetCount (enumWasapiDeviceTypes.WASAPI_DEVICE_TYPE_LOOPBACK,
                                        ref nLoopbackDevices);
       for (int i = 0; i < nLoopbackDevices; i++)
       {
             string strLoopbackDevice = audioSoundRecorder1.WASAPI.DeviceGetDesc (i,
                                        enumWasapiDeviceTypes.WASAPI_DEVICE_TYPE_LOOPBACK);
             comboLoopbackDevices.Items.Add(strLoopbackDevice);
       }
 
       if (nCaptureDevices == 0 && nLoopbackDevices == 0)
       {
             MessageBox.Show("No capture device detected and/or connected");
             Close();
             return;
       }
 
       // do other stuffs
       ...

启动特定终结点设备并录制其数据流

现在我们可以决定开始录音并将 Windows Media Player 或 YouTube 当前在我们系统上播放的内容保存到声音文件中:对于它们的播放,通常这些桌面或 Web 应用程序会使用系统的默认渲染设备,因此我们应该在组合框中识别出哪个环回设备对应于系统的默认渲染设备:组合框中列出的第一个设备就是正确的。

当按下“开始录音”按钮时,我们的示例代码将通过 StartWasapiDevice 函数(请参阅下文详情)启动环回设备,并通过 StartFromWasapiLoopbackDevice 方法启动录音会话。

private void buttonStartRecordingLoopback_Click(object sender, EventArgs e)
{
       // set the recording format
       ...
 
       // start the loopback device in shared mode
       if (!StartWasapiDevice(comboLoopbackDevices.SelectedIndex,
             enumWasapiDeviceTypes.WASAPI_DEVICE_TYPE_LOOPBACK))
             return;
 
       // start the recording session from the selected loopback device
       enumErrorCodes nResult = audioSoundRecorder1.StartFromWasapiLoopbackDevice
             (comboLoopbackDevices.SelectedIndex, m_strOutputPathname);
       if (nResult != enumErrorCodes.ERR_NOERROR)+
             MessageBox.Show("Cannot start recording due to error " + nResult.ToString());
}

StartWasapiDevice 函数内部,我们通过 WASAPI.DeviceIsStarted 方法验证所选的音频终结点设备是否已启动,如果尚未启动,则通过 WASAPI.DeviceStartShared 方法以共享模式启动它。

 
private bool StartWasapiDevice(int nDeviceIndex, enumWasapiDeviceTypes nDeviceType)
{
       // check if the given device is already started
       if (audioSoundRecorder1.WASAPI.DeviceIsStarted(nDeviceIndex, nDeviceType))
             // the device is already started
             return true;
 
       // start the device in shared mode
       enumErrorCodes nResult = audioSoundRecorder1.WASAPI.DeviceStartShared(nDeviceIndex,
             nDeviceType, enumWasapiChannelModes.WASAPI_CHANNEL_MODE_STEREO, 0, 0);
       if (nResult != enumErrorCodes.ERR_NOERROR)
       {
             // manage the error
             ...
 
             return false;
       }
 
       return true;
}

如前所述,调用 StartFromWasapiLoopbackDevice 方法将开始录制通过所选音频终结点设备播放的所有内容,并且所有传入的音频数据都将存储在选定格式的输出文件中。

停止录音会话和特定音频终结点设备

一旦我们的录音会话获得了足够的音频数据,我们就可以通过调用 Stop 方法来停止录音会话,并且由于我们不再需要访问音频终结点设备,因此我们也可以通过 WASAPI.DeviceStop 方法来停止它。

private void buttonStopRecordingLoopback_Click(object sender, EventArgs e)
{
       // stop the recording session
       audioSoundRecorder1.Stop();
 
       // stop the device
       audioSoundRecorder1.WASAPI.DeviceStop(comboLoopbackDevices.SelectedIndex,
                           enumWasapiDeviceTypes.WASAPI_DEVICE_TYPE_LOOPBACK, true);
}

下载完整的 WASAPI 录音器示例

您可以下载一个功能齐全的演示,其中包含 VB.NET 和 C# 两种语言讨论的功能。要运行这些示例,您将需要以下内容:

  • 安装 Audio
    Sound Suite for .NET(功能齐全的试用版) http://www.multimediasoft.com/bins/asostnet_t.exe
  • 浏览至“C:\Program Files\Audio Sound Suite for .NET\Audio Sound Recorder for .NET\Samples\[C#.NET 或 VB.NET] \WasapiRecorder”并编译项目。

支持

需要帮助才能启动和运行此示例吗?请联系我们的支持团队以获得免费技术支持!有关定价或许可问题,您可以联系我们的销售团队。

http://www.multimediasoft.com/contact

公司网站 http://www.multimediasoft.com

关注 Facebook(https://#/MultiMediaSoft)或 Twitter (https://twitter.com/MultiMediaSoft)

© . All rights reserved.