Question

When I using ResamplerDmoStream and selecting Anything except WaveOutput (e.g. WASAPI, DirectSound) I've getting below exception: Unable to cast COM Object NAudio.DMO.ResamplerMediaComObject to interface type Naudio.Dmo.IMediaObject ...

Exception Call stack:

at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget, Boolean& pfNeedsRelease)
at NAudio.Dmo.IMediaObject.GetInputStatus(Int32 inputStreamIndex, DmoInputStatusFlags& flags)
at NAudio.Dmo.MediaObject.IsAcceptingData(Int32 inputStreamIndex) in NAudio\Dmo\MediaObject.cs:line 468
at NAudio.Wave.ResamplerDmoStream.Read(Byte[] buffer, Int32 offset, Int32 count) in NAudio\Wave\WaveStreams\ResamplerDmoStream.cs:line 136
at NAudio.Wave.Wave16ToFloatProvider.Read(Byte[] destBuffer, Int32 offset, Int32 numBytes) in NAudio\Wave\WaveProviders\Wave16toFloatProvider.cs:line 47
at NAudio.Wave.MixingWaveProvider32.Read(Byte[] buffer, Int32 offset, Int32 count) in NAudio\Wave\WaveProviders\MixingWaveProvider32.cs:line 116
at NAudio.Wave.SampleProviders.WaveToSampleProvider.Read(Single[] buffer, Int32 offset, Int32 count) in NAudio\Wave\SampleProviders\WaveToSampleProvider.cs:line 33
at NAudio.Wave.SampleProviders.MeteringSampleProvider.Read(Single[] buffer, Int32 offset, Int32 count) in NAudio\Wave\SampleProviders\MeteringSampleProvider.cs:line 72
at NAudio.Wave.SampleProviders.VolumeSampleProvider.Read(Single[] buffer, Int32 offset, Int32 sampleCount) in NAudio\Wave\SampleProviders\VolumeSampleProvider.cs:line 42
at NAudio.Wave.SampleProviders.SampleChannel.Read(Single[] buffer, Int32 offset, Int32 sampleCount) in NAudio\Wave\SampleProviders\SampleChannel.cs:line 58
at NAudio.Wave.SampleProviders.MeteringSampleProvider.Read(Single[] buffer, Int32 offset, Int32 count) in NAudio\Wave\SampleProviders\MeteringSampleProvider.cs:line 72
at NAudio.Wave.SampleProviders.MultiplexingSampleProvider.Read(Single[] buffer, Int32 offset, Int32 count) in NAudio\Wave\SampleProviders\MultiplexingSampleProvider.cs:line 93
at NAudio.Wave.SampleProviders.SampleToWaveProvider.Read(Byte[] buffer, Int32 offset, Int32 count) in NAudio\Wave\SampleProviders\SampleToWaveProvider.cs:line 35
at NAudio.Wave.DirectSoundOut.Feed(Int32 bytesToCopy) in NAudio\Wave\WaveOutputs\DirectSoundOut.cs:line 516
at NAudio.Wave.DirectSoundOut.PlaybackThreadFunc() in NAudio\Wave\WaveOutputs\DirectSoundOut.cs:line 415
Was it helpful?

Solution

The problem is very likely that you are creating COM objects (in this case the DMO Resampler) on a STAThread (which will be the case if you are using WinForms or WPF) and then passing them to NAudio output driver models that will attempt to access them on a background thread, which is not allowed.

It is a very annoying problem to work around, since if you set your GUI thread to be MTAThread, other stuff will break (e.g. open file dialogs). Your main options are as follows:

  1. Stick with using WaveOut which has windowed callbacks. You will also be able to use WasapiOutGuiThread, which is an experimental class I added to the demo project recently. This is by far the easiest solution. Is there any reason you really need to use DirectSound?
  2. Don't have a ResamplerDmoStream in your audio pipeline. Use WaveFormatConversionStream instead, or simply let WASAPI insert one (which it does automatically)
  3. Create a background thread which will be used for your audio playback, and send messages from your GUI thread to it, telling it you want to start, stop, reposition etc. This unfortunately is a fairly complicated option.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top