This project has moved and is read-only. For the latest updates, please go here.

Asio under NAudio: Problem with passing audio in to audio out on same AsioOut instance

Jan 23, 2015 at 3:37 PM
Hi,

Trying unsuccessfully to pass audio data collected using the AsioOut object, to an audio out channel on the same device.

using NAudio 1.7.2.19, source code brought into project and re-compiled.

We get data in, from a USB Audio 2.0 interface, six channels in and six channels out, all OK, great, awesome, low latency as expected, etc.

Problem is, we need to be able to pass this input stream to an audio out, just as in comes in, and with as small latency as possible, in this platform, which is why we are employing Asio, instead of WaveIn/WaveOut or Wasapi.

We can't seem to get signal out any of the audio output channels.

We set up the AsioOut object as follows:
//source - ASIO
private static NAudio.Wave.AsioOut asioSourceStream = null;

We get a list of Asio drivers as follows:
//fill our collection
foreach(var device in AsioOut.GetDriverNames())
{
latestASIO_Source = device;
_ASIO_Devices.Add(latestASIO_Source);
listboxAudioSources.Items.Add(latestASIO_Source);
}

The chosen Asio driver gets assigned to
public static string AsioInputName = null;

When the user clicks the button in the GUI to start "listening", we instantiate the object and set up the event handler as follows:
//instantiate
asioSourceStream = new NAudio.Wave.AsioOut(AsioInputName);

We want to sample at 48kHz, 24bit, and have been collecting data successfully in this format using Asio, but since we were encountering problems with Asio audio out in the same object, I dropped back the sampling to the more standard 44.1kHz, 16bit, which is what we assign the WaveFormat as (note UserChannels = 6)

// try 16
NAudio.Wave.WaveFormat format = new NAudio.Wave.WaveFormat(44100, 16, UserChannels);

We then pass this format to
asioSourceStream.InitRecordAndPlayback(MyBuffer, UserChannels, 44100);

Then:
//specify the event handler
asioSourceStream.AudioAvailable += asioSourceStream_AudioAvailable;

//start recording and playback
asioSourceStream.Play();

In the event handler, we can extract the data in e.OutputBuffers and present to the application, but we want to send this data out the audio output channel(s)

I can copy the data over to e.OutputBuffers as follows
for (int outer_loop = 0; outer_loop < e.InputBuffers.Length; outer_loop++)
{
Array.Copy(e.InputBuffers, e.OutputBuffers, UserChannels);
}

and then raise the flag (or not raise it, same result, no audio output....)
e.WrittenToOutputBuffers = true;

Tried to copy data over to the output buffers this way also, did not work, syntax problem?
Marshal.Copy(e.InputBuffers[outer_loop], e.OutputBuffers[outer_loop], 0, e.SamplesPerBuffer);

If I step through the code down into
driver_BufferUpdate(..) in class AsioOut in file AsioOut.c
or
BufferSwitchCallBack(...) in class BufferSwitchCallBack in file ASIODriverExt.cs

Nothing really jumps out yet

Anyone see the missing piece of the puzzle?
Feb 23, 2015 at 8:03 PM
you are not copying over the output buffers. You are copying the array of output buffer pointers, which will have no effect.
This option is only advised for people who are comfortable for working with pointers. You need to go through each InputBuffer pointer, and copy the number of bytes available from that pointer to the pointer in the corresponding output buffer pointer.