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

WASAPI recording device with more then 2 channels

Jun 25, 2014 at 1:11 PM
I faced a problem with recording loopback device having more then 2 channels
public MMDevice Device;
private WasapiCapture _waveIn;
_waveIn = IsLoopback ? new WasapiLoopbackCapture(Device) : new WasapiCapture(Device);

               _waveIn.DataAvailable += OnDataAvailable;
               _waveIn.RecordingStopped += OnRecordingStopped;
It crashes on StartRecording with "Unsupported Wave Format" error
Error is coming from WasapiCapture.InitializeCaptureDevice() while it calls
if (!audioClient.IsFormatSupported(ShareMode, WaveFormat))
                throw new ArgumentException("Unsupported Wave Format");
Is there any walk around this problem? Can I change MMDevice wave format?
Jun 27, 2014 at 9:42 AM
Edited Jun 27, 2014 at 9:43 AM
I investigated what is happening. There is a constructor of WasapiCapture class in NAudio library
 public WasapiCapture(MMDevice captureDevice)
            syncContext = SynchronizationContext.Current;
            audioClient = captureDevice.AudioClient;
            ShareMode = AudioClientShareMode.Shared;

            waveFormat = audioClient.MixFormat;
            var wfe = waveFormat as WaveFormatExtensible;
            if (wfe != null)
                    waveFormat = wfe.ToStandardWaveFormat();
                catch (InvalidOperationException)
                    // couldn't convert to a standard format
It is using WaveFormat.ToStandardWaveFormat(). I tried to comment out part which changes format to standard one
            //var wfe = waveFormat as WaveFormatExtensible;
            //if (wfe != null)
            //    try
            //    {
            //        waveFormat = wfe.ToStandardWaveFormat();
            //    }
            //    catch (InvalidOperationException)
            //    {
            //        // couldn't convert to a standard format
            //    }
So in my case I just leaving original
[NAudio.Wave.WaveFormatExtensible] = {32 bit PCM: 44kHz 6 channels wBitsPerSample:32 dwChannelMask:1551 subFormat:00000003-0000-0010-8000-00aa00389b71 extraSize:22}

Now I'm getting data. Though I didn't find what to do with this format yet. Actually I need only two channels left and right.
Any suggestions aprpeciated.
Jun 27, 2014 at 9:48 AM
OK makes sense. The conversion to a standard format was because lots of users write the WasapiCapture direct to WAV file using the WaveFormat, but if it is a WaveFormatExtensible (which WASAPI always seems to use), then a lot of players won't play the file).

If you only need two channels, then you need to keep every 8 bytes (two 32 bit samples) and throw away 16 (remaining four channels).
Jun 27, 2014 at 9:58 AM
The problem is that I don't know in advance what will be format. 1 channel, 2 or 6,8. As I'm recording both Mic and speakers I downmixing to 1 channel speakers and to another mic. Sometimes I use MediaFoundationTransform to adjust Samplerate
I'm wandering if MediaFoundationTransform can help me with this transformation as well?
Jun 27, 2014 at 2:38 PM
It looks like MediaFoundationTransform is the solution
  • I'm leaving the original format in WasapiCapture as shown above
  • saving data to buffer
  • passing it through MediaFoundationTransform. At the end I have format I need with number of channels I need.
Thanks a lot Mark for creating such a great library
Jun 27, 2014 at 2:40 PM
great, glad you found a solution