Introduction
Starting from Windows Vista, Microsoft has rewritten the multimedia sub-system of the Windows operating system from the ground-up; at the same time Microsoft introduced a new API named Core Audio API which allows interacting with the multimedia sub-system and with audio endpoint devices (sound cards). One of the new Core Audio APIs is the Windows Audio Session API (also known as WASAPI) which can manage three different types of devices:
- Render devices are playback devices where audio data flows from the application to the audio endpoint device, which renders the audio stream.
- Capture devices are recording devices where audio data flows from the audio endpoint device, that captures the audio stream, to the application.
- Loopback devices are recording devices that capture the mixing of all of the audio streams being rendered by a specific render device, also if audio streams are being played by third-party multimedia application like Windows Media Player: each render device always has a corresponding loopback device.
How Audio Sound Recorder for .NET can be of help in managing WASAPI easily
As seen for most of the APIs developed by Microsoft, WASAPI consists of a combination of several COM interfaces whose usage is not always straightforward: Audio Sound Recorder for .NET allows developers leveraging in a easy way a subset of WASAPI features in order to create and manage audio streams to and from audio endpoint devices inside their applications.
The main points related to the usage of WASAPI features through the Audio Sound Recorder for .NET component are the following:
- Initializing the WASAPI subsystem
- Enumerating various types of audio endpoint devices (render, capture and loopback)
- Starting the specific endpoint device and recording its data flow
- Stopping the recording session and the specific audio endpoint device
In this tutorial we want to see how to start a recording session, from a capture device or from a loopback device, in order to store incoming audio data into an output sound file of a specific audio format with the possibility to playback the same file once the recording session is stopped.
The user interface of our sample application will look like this:
Initializing the WASAPI subsystem and the component’s recording system
By default Audio Sound Recorder for .NET accesses audio devices through DirectSound and WDM drivers so, in order to leverage WASAPI, we need to specify to the component that we want to use a different kind of drivers through the InitDriversType
method, then we can initialize the component through the mandatory call to the InitRecordingSystem
method:
private void Form1_Load(object sender, EventArgs e)
{
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;
}
audioSoundRecorder1.InitRecordingSystem();
...
Enumerating various types of audio endpoint devices (render, capture and loopback)
After the drivers initialization we can enumerate available audio endpoint devices through the combination of WASAPI.DeviceGetCount
and WASAPI.DeviceGetDesc
methods that will also allow to fill a couple of combo boxes on the user interface; due to the fact that we will use this sample as a recording system, we are mainly interested in enumerating capture and loopback devices while for playback we will use the system default device:
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);
}
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;
}
...
Starting the specific endpoint device and recording its data flow
We can now decide to start recording and saving on a sound file what Windows Media Player or YouTube are currently playing on our system: for their playback, usually these desktop or web applications make use of the system default render device so we should identify inside the combo box which loopback device corresponds to the system default render device: the first device listed on the combo box is the right one.
When pressing the "Start recording” button our sample’s code will start the loopback device through the StartWasapiDevice
function (see below its detail) and the recording session through the StartFromWasapiLoopbackDevice
method
private void buttonStartRecordingLoopback_Click(object sender, EventArgs e)
{
...
if (!StartWasapiDevice(comboLoopbackDevices.SelectedIndex,
enumWasapiDeviceTypes.WASAPI_DEVICE_TYPE_LOOPBACK))
return;
enumErrorCodes nResult = audioSoundRecorder1.StartFromWasapiLoopbackDevice
(comboLoopbackDevices.SelectedIndex, m_strOutputPathname);
if (nResult != enumErrorCodes.ERR_NOERROR)+
MessageBox.Show("Cannot start recording due to error " + nResult.ToString());
}
Internally to the StartWasapiDevice
function we verify if the chosen audio endpoint device is already started through the WASAPI.DeviceIsStarted
method and, if not, we start it in shared mode through the WASAPI.DeviceStartShared
method:
private bool StartWasapiDevice(int nDeviceIndex, enumWasapiDeviceTypes nDeviceType)
{
if (audioSoundRecorder1.WASAPI.DeviceIsStarted(nDeviceIndex, nDeviceType))
return true;
enumErrorCodes nResult = audioSoundRecorder1.WASAPI.DeviceStartShared(nDeviceIndex,
nDeviceType, enumWasapiChannelModes.WASAPI_CHANNEL_MODE_STEREO, 0, 0);
if (nResult != enumErrorCodes.ERR_NOERROR)
{
...
return false;
}
return true;
}
As mentioned, the call to the StartFromWasapiLoopbackDevice
method will start recording anything being played through the chosen audio endpoint device and all incoming audio data will be stored inside an output file of a chosen format.
Stopping the recording session and the specific audio endpoint device
Once our recording session has enough audio data, we can stop the recording session through a call to the Stop method and, due to the fact that we no more need accessing the audio endpoint device, we can stop it as well through the WASAPI.DeviceStop
method:
private void buttonStopRecordingLoopback_Click(object sender, EventArgs e)
{
audioSoundRecorder1.Stop();
audioSoundRecorder1.WASAPI.DeviceStop(comboLoopbackDevices.SelectedIndex,
enumWasapiDeviceTypes.WASAPI_DEVICE_TYPE_LOOPBACK, true);
}
Download the full WASAPI recorder example
You can download a fully functional demo which includes the features discussed above in both VB.NET and C#. To run these examples you will need the following:
- Install Audio
Sound Suite for .NET (fully functional trial version) http://www.multimediasoft.com/bins/asostnet_t.exe
- Browse to "C:\Program Files\Audio Sound Suite for .NET\Audio Sound Recorder for .NET\Samples\[C#.NET or VB.NET] \WasapiRecorder" and compile the project
Support
Need help getting this sample up and going? Contact our support team for free technical support! For pricing or licensing questions, you can contact our sales team.
http://www.multimediasoft.com/contact
Company website http://www.multimediasoft.com
Follow on Facebook (https://www.facebook.com/MultiMediaSoft) or Twitter (https://twitter.com/MultiMediaSoft)