Copyright © 2006-2023 MultiMedia Soft

How to manage ASIO drivers

Previous pageReturn to chapter overviewNext page

ASIO (Audio Stream Input/Output) is a sound card driver protocol for digital audio specified by Steinberg, providing a low-latency and high fidelity interface between a software application and a computer's sound card. ASIO bypasses the normal audio path from the user application through layers of intermediary Windows operating system software, so that the application connects directly to the hardware of the sound card. Each layer that is bypassed means a reduction in latency, the delay between an application sending sound to the sound being reproduced by the sound card.

 

By default Audio Sound Recorder enumerates input devices (sound cards) supporting the DirectSound protocol: in order to let Audio Sound Recorder enumerating devices supporting ASIO drivers, you need to make a call to the InitDriversType method and to specify which kind of drivers/protocols your application will support and, in case you should need supporting both ASIO and DirectSound at the same time, in which order; if a certain sound card should support both DirectSound and ASIO drivers, it would be enumerated as two different sound cards, one supporting DirectSound and one supporting ASIO.

 

IMPORTANT NOTE: When using the Audio Sound Recorder API component in conjunction with our Audio DJ Studio API component, which also contains the InitDriversType method, it should be preferred calling the InitDriversType method from Audio DJ Studio API so it will automatically affect both input and output devices.

 

 

The call to the InitDriversType method is mandatory before performing calls to the InitRecordingSystem, GetInputDevicesCount and GetInputDeviceDesc methods: if the InitDriversType method should be called at a later time, it would report back an error; if for any reason you should need calling it at a later time, you would need performing the following sequence of calls:

1. ResetEngine method

2. InitDriversType method

3. Eventual new enumeration of input devices through the GetInputDevicesCount and GetInputDeviceDesc methods.

4. ResetControl method

 

After having initialized the type of driver(s) in use through the InitDriversType method, it will be possible enumerating available input devices through the GetInputDevicesCount and GetInputDeviceDesc methods: depending upon the driver set, these methods will return the overall list of available input devices (DirectSound + ASIO) so it will be possible setting them inside the nDeviceIndex parameter of the StartFromAsioDevice method. You can also obtain the driver in use by a specific input device through the GetInputDeviceDriverType method.

 

If the InitDriversType method should be set to initialize the use of ASIO devices, you could access specific ASIO features through methods exposed by the ASIO property which implements the ASIOMan class:

 

Enumerating available ASIO devices through the ASIO.DeviceGetCount and ASIO.DeviceGetDesc methods: it's important to note that this kind of enumeration will only report existing ASIO devices and not the overall list of available input devices as reported by the GetInputDevicesCount and GetInputDeviceDesc methods.
Obtaining the zero-based index of an ASIO device inside the overall list of available input devices through the ASIO.DeviceGetInputIndex method.
Given the zero-based index of an ASIO device inside the overall list of available output devices, obtaining the zero-based index of the same ASIO device inside the list of available ASIO devices through the ASIO.DeviceGetIndexFromInput method.
For each ASIO device, enumerating the list of available input and output channels through the ASIO.DeviceGetChannelsCount and ASIO.DeviceGetChannelDesc methods.
Displaying the control panel provided by the ASIO driver of a specific device through the ASIO.ControlPanelDisplay method.
Obtaining the absolute pathname of the file containing the ASIO driver of a specific ASIO device through the ASIO.DeviceGetDriverPathname method.
Starting and stopping the usage of a specific ASIO device through the ASIO.DeviceStart and ASIO.DeviceStop methods.

 

The call to the ASIO.DeviceStart method is mandatory in order to be able starting a recording session on a specific ASIO device. You can know if a specific ASIO device is already started through the ASIO.DeviceIsStarted method.

 

IMPORTANT NOTE: When using Audio Sound Recorder API in conjunction with Audio DJ Studio API, you should prefer calling this method using the same ASIO.DeviceStart method available inside Audio DJ Studio API so you would have a better control over the playback mode.

 

After starting an ASIO device, it will be possible performing the following tasks:

 

Starting a recording session on the device through the StartFromAsioDevice method.
Getting and setting the volume for input and output channels through the ASIO.DeviceMasterVolumeGet and ASIO.DeviceMasterVolumeSet methods (applies the same volume level to all channels in one shot) and through the ASIO.DeviceChannelVolumeGet and ASIO.DeviceChannelVolumeSet methods (applies the volume level on a specific channel allowing separate volume level for each channel).
Obtaining the current latency, expressed in samples per second, for input and output channels as reported by the ASIO driver itself.

 

 

When dealing with sound cards having multiple input channels, like the M-Audio Delta 1010LT, there is the possibility to:

 

mix the input of all of the selected channels into one single recording session.
by using multiple instances of Audio Sound Recorder API for .NET, record at the same time each channel (or couple of channels) on a separate destination file.
by outputting the recording session into a single destination file, whose audio format supports multi-channel (like WAV, WMA, Ogg Vorbis, Opus, etc.), store each input channel into a separate channel of the destination file. Fort this purpose, you need to instruct the component to avoid mixing mono channels together and to keep them separated through the ASIO.DeviceRecordParamsSet method, by passing "FALSE" to the bPerformMixOnStereoOut parameter.

 

Let's see these situations with a couple of small snippets of code.

 

In the first sample we need to record the first 8 input channels of an ASIO device selected from the comboInputDevices combobox and mix all of the channels inside the same output file:

 

Visual Basic .NET

 

' init some variable

Dim nInputChannel as Integer = 0

Dim nTotalChannels as Integer = 8

 

' start the recording session

m_recorderAPI.StartFromAsioDevice(comboInputDevices.SelectedIndex, _

                   nFirstInputChannel, nTotalChannels, "c:\mydir\output.wav")

 

 

Visual C#

 

// init some variable

short nInputChannel = 0;

short nTotalChannels = 8;

 

// start the recording session

m_recorderAPI.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   nFirstInputChannel, nTotalChannels, @"c:\mydir\output.wav");

 

 

In the second sample we need to record the first 4 input channels of an ASIO device selected from the comboInputDevices combobox and keep them separated in 4 different output files, for this purpose we will use 4 instances of the component (m_recorderAPI1, m_recorderAPI2, m_recorderAPI3, and m_recorderAPI4):

 

Visual Basic .NET

 

' init some variable

Dim nTotalChannels as Integer = 1

 

' start the recording session from channel 0 and save it inside the output1.wav file

m_recorderAPI1.StartFromAsioDevice(comboInputDevices.SelectedIndex, _

                   0, nTotalChannels, "c:\mydir\output1.wav")

' start the recording session from channel 1 and save it inside the output2.wav file

m_recorderAPI2.StartFromAsioDevice(comboInputDevices.SelectedIndex, _

                   1, nTotalChannels, "c:\mydir\output2.wav")

' start the recording session from channel 2 and save it inside the output3.wav file

m_recorderAPI3.StartFromAsioDevice(comboInputDevices.SelectedIndex, _

                   2, nTotalChannels, "c:\mydir\output3.wav")

' start the recording session from channel 3 and save it inside the output4.wav file

m_recorderAPI4.StartFromAsioDevice(comboInputDevices.SelectedIndex, _

                   3, nTotalChannels, "c:\mydir\output4.wav")

 

 

Visual C#

 

// init some variable

short nTotalChannels = 1;

 

// start the recording session from channel 0 and save it inside the output1.wav file

m_recorderAPI1.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   0, nTotalChannels, @"c:\mydir\output1.wav");

// start the recording session from channel 1 and save it inside the output2.wav file

m_recorderAPI2.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   1, nTotalChannels, @"c:\mydir\output2.wav");

// start the recording session from channel 2 and save it inside the output3.wav file

m_recorderAPI3.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   2, nTotalChannels, @"c:\mydir\output3.wav");

// start the recording session from channel 3 and save it inside the output4.wav file

m_recorderAPI4.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   3, nTotalChannels, @"c:\mydir\output4.wav");

 

 

In the third sample we need to record the first 8 input channels of an ASIO device selected from the comboInputDevices combobox and keep them separated in 4 different output files having each 2 input channels mixed together, for this purpose we will use 4 instances of the component (m_recorderAPI1, m_recorderAPI2, m_recorderAPI3, and m_recorderAPI4):

 

Visual Basic .NET

 

 ' init some variable

Dim nTotalChannels as Integer = 2

 

' start the recording session from channels 0-1 and save it inside the output1.wav file

m_recorderAPI1.StartFromAsioDevice(comboInputDevices.SelectedIndex, _

                   0, nTotalChannels, "c:\mydir\output1.wav")

' start the recording session from channels 2-3 and save it inside the output2.wav file

m_recorderAPI2.StartFromAsioDevice(comboInputDevices.SelectedIndex, _

                   2, nTotalChannels, "c:\mydir\output2.wav")

' start the recording session from channels 4-5 and save it inside the output3.wav file

m_recorderAPI3.StartFromAsioDevice(comboInputDevices.SelectedIndex, _

                   4, nTotalChannels, "c:\mydir\output3.wav")

' start the recording session from channels 6-7 and save it inside the output4.wav file

m_recorderAPI4.StartFromAsioDevice(comboInputDevices.SelectedIndex, _

                   6, nTotalChannels, "c:\mydir\output4.wav")

 

 

Visual C#

 

 ' init some variable

short nTotalChannels = 2;

 

' start the recording session from channels 0-1 and save it inside the output1.wav file

m_recorderAPI1.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   0, nTotalChannels, @"c:\mydir\output1.wav");

' start the recording session from channels 2-3 and save it inside the output2.wav file

m_recorderAPI2.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   2, nTotalChannels, @"c:\mydir\output2.wav");

' start the recording session from channels 4-5 and save it inside the output3.wav file

m_recorderAPI3.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   4, nTotalChannels, @"c:\mydir\output3.wav");

' start the recording session from channels 6-7 and save it inside the output4.wav file

m_recorderAPI4.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   6, nTotalChannels, @"c:\mydir\output4.wav");

 

 

In the fourth sample we need to record 6 input channels, starting from channel 2 (so we won't consider channels 0 and 1) of an ASIO device selected from the comboInputDevices combobox and keep them separated in in one single destination file supporting multi-channel:

 

Visual Basic .NET

 

' use custom resampling format 44100 Hz, 6 channels

m_recorderAPI.EncodeFormats.ResampleMode = enumResampleModes.RESAMPLE_MODE_CUSTOM_FORMAT

m_recorderAPI.EncodeFormats.ResampleCustomFrequency = 44100

m_recorderAPI.EncodeFormats.ResampleCustomChannels = 6

 

 ' init some variable

Dim nTotalChannels as Integer = 6

 

' keep mono channels separated

m_recorderAPI.ASIO.DeviceRecordParamsSet (comboInputDevices.ListIndex, _

                   false, enumAsioRecordMonoToStereoMode.ASIO_REC_MONO_BOTH_CHANS)

 

' start the recording session from channel 2 (ignore 0 and 1) and save it inside the output.wav file

m_recorderAPI.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   6, nTotalChannels, "c:\mydir\output.wav")

 

 

Visual C#

 

// use custom resampling format 44100 Hz, 6 channels

m_recorderAPI.EncodeFormats.ResampleMode = enumResampleModes.RESAMPLE_MODE_CUSTOM_FORMAT;

m_recorderAPI.EncodeFormats.ResampleCustomFrequency = 44100;

m_recorderAPI.EncodeFormats.ResampleCustomChannels = 6;

 

// init some variable

short nTotalChannels = 6;

 

// keep mono channels separated

m_recorderAPI.ASIO.DeviceRecordParamsSet (comboInputDevices.ListIndex,

                   false, enumAsioRecordMonoToStereoMode.ASIO_REC_MONO_BOTH_CHANS);

 

// start the recording session from channel 2 (ignore 0 and 1) and save it inside the output.wav file

m_recorderAPI.StartFromAsioDevice(comboInputDevices.SelectedIndex,

                   6, nTotalChannels, @"c:\mydir\output.wav");

 

 

It's important to note that code snippets above simply show how to call the StartFromAsioDevice method and don't show the calls to the InitDriversType method and to the ASIO.DeviceStart method which are in any case mandatory for starting the recording session: finally, don't forget that, when using multiple instances of the component as seen inside the latest 2 code snippets, the need to call these mandatory methods is only from one single instance of the component, for example from the instance identified by activeSoundRecorder1 because,.once an ASIO device is started, it can be automatically accessed by all of the other instances.

 

 

In case you should simply need to render audio data incoming from one or more input channels to one or more output channels directly, with the advantage of a smaller CPU footprint, a possible alternative to the ASIO.DeviceStart method would to invoke the ASIO.DeviceListenInputStart method: the limitation of this approach would be the fact that you would loose the capability to record or cast incoming audio data. When the ASIO device is started in this way, you may pause direct playback through the ASIO.DeviceListenInputPause method and resume playback through the ASIO.DeviceListenInputResume method.

 

Also in this case, the ASIO device can be stopped through the ASIO.DeviceStop method.

 

 

Samples of usage of ASIO drivers in C# and VB.NET can be found inside the following samples installed with the product's setup package:

- AsioList

- AsioSimpleRecorder

- AsioMultiChanRecorder