This project has moved. For the latest updates, please go here.

Asio Sample type returns wrong value

Sep 15, 2013 at 1:10 AM
Hello Community,

when i'm recording with 16 Bit int, the property of the event argument responses with "Int32LSB". The Wav File has the correct information (16Bit LSB, checked with SOX). I need the SampleType (actually its size) to calculate the running time. Is there an offset or why am i getting the wrong information?

Cheers
Jan
Coordinator
Sep 16, 2013 at 2:22 PM
this value comes direct from the ASIO driver. It might be that there are 16 bit samples in a 32 bit integer. How are you creating the WAV file that has the correct information?
Sep 16, 2013 at 2:59 PM
Hi mark,

I used your code from the NAudio Demo. This is the AudioAvailable Function:
void asioOut_AudioAvailable(object sender, AsioAudioAvailableEventArgs e)
                {
                    // audio output is dumped to wav file
                    // output format is ALWAYS 32Bit float, convert with sox if required
                    var samples = e.GetAsInterleavedSamples();
                  
                    wavWriter.WriteSamples(samples, 0, samples.Length);
                
                    sampleType = e.AsioSampleType ;
                    //Console.WriteLine((int)sampleType);
                }
The Wav-Writer is initialized with fixed settings, maybe that's the trick?!
this.wavWriter = new WaveFileWriter(wavPath, new WaveFormat(sampleFrq, channels));
And when hitting the "Stop"button:
private void Stop()
        {
            this.asioOut.Stop();
            //this.asioOut.Pause();
            if (this.wavWriter != null)
            {
                this.asioOut.AudioAvailable -= asioOut_AudioAvailable;
                this.wavWriter.Flush();//test
                this.wavWriter.Close();//test
                this.wavWriter.Dispose();
                this.wavWriter = null;
            }
            this.recStateTimer.Enabled = false;
            CleanUp();
            gbDevice.Enabled= true;
            SetButtonStates();
        }
Cheers
Jan
Coordinator
Sep 17, 2013 at 3:08 PM
that WaveFormat is a 16 bit one, and it is WriteSamples that is converting from 32 bit into 16
Sep 18, 2013 at 12:19 PM
Alright,
two questions left:

1.) this means that my 16 Bit Integer is stored as 32Bit,? Or are the samples in the puffer already interleaved?
2.) When using a 24 Bit (usually signed?? ) int stream storing as 24Bit wave file, this means two conversions? 24Bit (configured) --> 32Bit Float (GetAsInterleavedSamples) --> 24 Bit Wav (wav writer) . Is there any loss of precision during that conversion?? (Especially from int to float)

Cheers
Jan
Coordinator
Sep 19, 2013 at 1:04 PM
1) the ASIO driver is providing 32 bit samples. They are not interleaved left/right unless you call "GetAsInterleavedSamples"
2) yes, if you want to directly access the ASIO samples, use the IntPtrs in the event args which point directly at the ASIO buffers for each channel. Then you can avoid conversions.
Sep 19, 2013 at 6:10 PM
Edited Sep 20, 2013 at 2:55 AM
i just want to dump the buffers. I suppose, you don't suggest accessing the asio buffers directly, otherwise there would not be "GetAsInterleavedSamples".

During debugging i captured this:
Image

Just for my understanding. In this case i've got 512 samples per buffer, and two pointers (one for each channel?). The distance between thoses addresses is 2048 (4 byte per sample), which means that this are the start addresses for channel one and channel two. Could you explain how GetAsInterleavedSamples is doing the conversion?
Now i know that the 16 bit samples configured by the driver are stored as 32 bit, which is ok. The higher bits of the 32 bit integer are just cut off by the wavewriter, but what should i do when converting from 32 bit int to 32bit float? Usually i should add dither.
Cheers
Jan

[edit]
Today i did some test with an moto express,. Recording 4 channels, 96khz and 24 bit works fine. I also tried other combinations. When is set the wavwriter to 32 bit (the asioout is just initialized with samplerate and number of channels, and no playback device) it crashed....

WavWriter:
Image

Message:

Image

SampleFormat of buffer:
Image

The interface uses 24Bit....... the buffer are represented as 32 int...

Whats happening when i use a wave writer which uses 16 Bit as output format?
Coordinator
Sep 20, 2013 at 11:54 AM
Take a look at the source code for GetAsInterleavedSamples - it should help you understand how NAudio is reading the values from the ASIO buffers
https://naudio.codeplex.com/SourceControl/latest#NAudio/Wave/WaveOutputs/AsioAudioAvailableEventArgs.cs

GetAsInterleavedSamples is just a helper method. My assumption is that people who are working with ASIO are doing so because they need ultra-low latency, so they may prefer to use the IntPtrs directly