1

I'm trying to write my own VST Host and for that i need to record and play audio from an Asio Driver (in my case for an audio interface). That's why i'm trying to use NAudio's AsioOut.

For testing purposes i'm currently just trying to record the input, copy and play it to the output.

My code looks like this:

var asioout = new AsioOut();
BufferedWaveProvider wavprov = new BufferedWaveProvider(new WaveFormat(44100, 2));
asioout.AudioAvailable += new EventHandler<AsioAudioAvailableEventArgs>(asio_DataAvailable);
asioout.InitRecordAndPlayback(wavprov, 2, 25);
asioout.Play();

...

void asio_DataAvailable(object sender, AsioAudioAvailableEventArgs e)
{
    Array.Copy(e.InputBuffers, e.OutputBuffers, e.InputBuffers.Length);
    e.WrittenToOutputBuffers = true;
}

This way i can't hear any output. I also tried it this way:

void asio_DataAvailable(object sender, AsioAudioAvailableEventArgs e)
{
    byte[] buf = new byte[e.SamplesPerBuffer];
    for (int i = 0; i < e.InputBuffers.Length; i++)
    {
        //Marshal.Copy(e.InputBuffers[i], e.OutputBuffers, 0, e.InputBuffers.Length);
        //also tried to upper one but this way i also couldn't hear anything
        Marshal.Copy(e.InputBuffers[i], buf, 0, e.SamplesPerBuffer);
        Marshal.Copy(buf, 0, e.OutputBuffers[i], e.SamplesPerBuffer);
    }
    e.WrittenToOutputBuffers = true;
}

This way i can hear sound in the volume of my input but it's very distorded.

What am i doing wrong here?

PS: I know how to record and playback.... exists but i couldn't really get a complete answer from this thread, just the idea to try it with Marshall.Copy....

Community
  • 1
  • 1
MariusR
  • 1,534
  • 2
  • 11
  • 20

1 Answers1

0

Your second attempt is more correct than the first: each input buffer must be copied separately. However the final parameter of the copy method should be the number of bytes, not the number of samples in the buffer. This will typically be 3 or 4 bytes per sample, depending on your ASIO bit depth.

Mark Heath
  • 48,273
  • 29
  • 137
  • 194
  • Thank you so much for your answer. Using e.SamplesPerBuffer*4 instead of just the amount of samples solved the problem. – MariusR May 17 '14 at 21:49
  • A small followup question: In what format are the bytes inside the bite array. I know the once from WaveIn are 16bit mono so it goes: AABBCCDDEEFF positioning-wise inside the array but the asioout one seems a bit different to that... – MariusR May 17 '14 at 22:00
  • ASIO supports many different sample modes and the bytes can be packed in several different ways (e.g. 24 bit in 4 bytes, big endian, little endian etc), you need to find out which one your driver is using. – Mark Heath May 18 '14 at 07:11
  • So i'm still having a problem how i can work with this byte array. They seem to be in a little endian pattern like: 0 (some number) (some number between 250 and 253) 255 With WaveIn I was getting 16 bit data. So i took the two bytes pairs converted them to an Int16 and divided them through Int16.MaxValue to transform it to a float ranging from -1 to 1 (Then i pumped it into a VST Plugin). With the output i did it the other way around. Now i'm having the problem that with Int16 the values get too high and it wants byte[2] not 4. And Int32 is too big for it. Is it possible that this is 24 bit? – MariusR May 24 '14 at 17:40
  • yes, ASIO has multiple possible bit representations for audio. There is an enum in the event args that will tell you what one is being used – Mark Heath May 29 '14 at 09:32