0

I have an usb audio board that supports asio driver with 4 inputs and 4 outputs. I want to send and receive data simultaneously. But currently I can receive and send data only to one channels at a time. I cannot figure out how to set it in asioOut class from Naudio c# library.

I have to threads

It is possible to have one AudioAvailable event for each channel? Similar to waveIn / waveOut classes. How can I achive this?

Here is my code:

int sampleRate = 44100;
int channels = 4;

buffWaveProvider = new BufferedWaveProvider(new NAudio.Wave.WaveFormat(sampleRate, 32, channels));
asioOut = new AsioOut(radioForm.driverName);
asioOut.ChannelOffset = OUTdevID;
asioOut.InputChannelOffset = INdevId;
asioOut.AudioAvailable += OnAsioOutAudioAvailable;
asioOut.InitRecordAndPlayback(buffWaveProvider, channels, sampleRate);
asioOut.Play();

for AudioAvailable event I have to send for each input channel the inputstream on different multicast address:

public void OnAsioOutAudioAvailable(object sender, AsioAudioAvailableEventArgs e)
{
    if (speakersOn && e.InputBuffers.Length != 0 && !monitorRequest)
    {
        byte[] buf = new byte[e.SamplesPerBuffer*4];
        for (int i = 0; i < e.InputBuffers.Length; i++)
        {
            Marshal.Copy(e.InputBuffers[i], buf, 0, e.SamplesPerBuffer*4);
        }
        e.WrittenToOutputBuffers = true;
        udp4VoiceSend.Send(buf, buf.Length);
    }
}

Is there a way to access input buffers for each channel? enter image description here

For the outputs I've checked the naudio source code and I saw I can set the number of output channels to waveProvider.WaveFormat.Channels. So I suppose that when calling InitRecordAndPlayback method the IWaveProvider buffer should have 4 channels.

None of stackoverflow post about this subject helped me. I've tried them all.

https://stackoverflow.com/questions/22543513/naudio-using-asio-to-record-audio-and-output-with-a-guitar

NAudio Asio Record and Playback

How to record and playback with NAudio using AsioOut

NAudio AsioOut + Sockets

Thanks!

UPDATE:

I've checked the Naudio Demo Project, Asio Recording Panel and seems that I can listen to only one channel at a time: enter image description here

The naudio driver class creates 4 input and 4 output buffers as expected, but I'm not able to access them. enter image description here

In AsioRecordingPanel file if asioOut object listens to 1 channel and user wants to change channel the object is disposed.

enter image description here

Is a library limitation or a driver limitation?

When I add samples to asio buffer it's possible to send data directly to an output channel?

if (Main.buffWaveProvider != null)
Main.buffWaveProvider.AddSamples(data, 0, dataLen);

Thanks!!

Community
  • 1
  • 1
Adrian Stanculescu
  • 1,040
  • 2
  • 13
  • 21

1 Answers1

2

Here's a simple example I created that is accessing both the input and output ASIO buffers and performing low-level manipulation of the samples.

Mark Heath
  • 48,273
  • 29
  • 137
  • 194
  • HI, Mark. Thanks for your example. It is possible to add samples to an output channel? For example I want to send track1 to output1 and track2 to output2 once at a time. And in buffWaveProvider.AddSamples(data, 0, dataLen) I can add samples for all outputs. I've tried to set asioOut.ChannelOffset to desired channel and then add samples in buffer, but doesn't seem to work this hack. It's possible? – Adrian Stanculescu Nov 14 '16 at 20:10
  • yes, that's what the sample does. Reads from the inputs, writes to the outputs – Mark Heath Nov 14 '16 at 20:12
  • Ok, thanks. So, if the voice stream doesn't come from the inputs, but from the network, how can I manage it? Let me be more specific: I have a voice application where a dispatcher sends voice over network and he specifies the stream sending channel. In asio driver gateway application I have the event udp4VoiceRecv_OnNewDataRecv(byte[] data, int dataLen). So when this is fired I have to route the stream to specific output. Thank you! – Adrian Stanculescu Nov 14 '16 at 20:27
  • For example in waveout class I choose a device number and I can define a buffer for each device. buffWaveProvider = new BufferedWaveProvider(waveInClass.WaveFormat); waveOutClass = new WaveOut(); waveOutClass.DeviceNumber = OUTdevID; waveOutClass.Init(buffWaveProvider); waveOutClass.Play(); – Adrian Stanculescu Nov 14 '16 at 20:32
  • I'd just use a `BufferedWaveProvider` for that, and then you can give it to AsioOut or any other NAudio output device to play. – Mark Heath Nov 14 '16 at 20:40
  • Hi @mark-heath, Please can you extend the NaudioAsioPatchBay example on the link to be able to record the input channels to different files, instead of just passing them to output? Please update and repost the link. Thanks – Timothy Ayodele Sep 03 '23 at 00:00