Wasapi Recording Resampling

Sep 6, 2011 at 2:23 PM

Hi,

Is there any way to use the resampler dmo to resample audio during recording with wasapi capture? If not, is there any other solution?

I know about using the WaveIn provider with its built-in resampling, but my project doesn’t need to support XP and I want to use wasapi instead.

Thanks,

Eric

Sep 8, 2011 at 8:49 AM

I was able to get it working. First set up the wasapi capture and dmo resampler objects:

 

capture = new WasapiCapture(device);
inputFormat = capture.WaveFormat;
resampler = new Resampler();
resampler.MediaObject.SetInputWaveFormat(0, inputFormat);
resampler.MediaObject.SetOutputWaveFormat(0,outputFormat);
resampler.MediaObject.AllocateStreamingResources();
writer = new WaveFileWriter(@"e:\temp\test.wav", outputFormat);
capture.DataAvailable += new EventHandler<WaveInEventArgs>(waveIn_DataAvailable);
capture.RecordingStopped += new EventHandler(waveIn_RecordingStopped);
            capture.StartRecording();

 

Then on DataAvailable:

 

            //should this be on ui thread?
           if (this.Dispatcher.Thread == Thread.CurrentThread)
            {
                MediaBuffer b=new MediaBuffer(e.Buffer.Length);
                b.LoadData(e.Buffer,e.BytesRecorded);
                resampler.MediaObject.ProcessInput(0,b,DmoInputDataBufferFlags.None,0,0);
                using (DmoOutputDataBuffer outputBuffer = new DmoOutputDataBuffer(outputFormat.AverageBytesPerSecond))
                {
                    resampler.MediaObject.ProcessOutput(DmoProcessOutputFlags.None,1, new DmoOutputDataBuffer[]{outputBuffer});
                    byte[] oBytes=new byte[outputBuffer.Length];
                    outputBuffer.RetrieveData(oBytes, 0);
                    writer.Write(oBytes,0,oBytes.Length);
                }

            }
            else
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new EventHandler<WaveInEventArgs>(waveIn_DataAvailable), sender,
                                            new object[] { e });
            }