重新取样的例外情况

时间:2012-11-21 06:25:15

标签: naudio directsound wasapi

当我使用ResamplerDmoStream并选择除 WaveOutput 之外的任何内容(例如 WASAPI DirectSound )时,我遇到以下异常: 无法将COM对象NAudio.DMO.ResamplerMediaComObject强制转换为接口类型Naudio.Dmo.IMediaObject ...

异常调用堆栈:

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

1 个答案:

答案 0 :(得分:2)

问题很可能是你在STAThread上创建COM对象(在这种情况下是DMO重采样器)(如果你使用的是WinForms或WPF就是这种情况)然后将它们传递给NAudio输出驱动程序模型尝试在后台线程上访问它们,这是不允许的。

这是一个非常恼人的问题,因为如果将GUI线程设置为MTAThread,其他内容将会中断(例如打开文件对话框)。您的主要选项如下:

  1. 坚持使用WaveOut,它有窗口回调。您还可以使用WasapiOutGuiThread,这是我最近添加到演示项目的实验课程。这是迄今为止最简单的解决方案。你真的需要使用DirectSound吗?
  2. 音频管道中没有ResamplerDmoStream。请改用WaveFormatConversionStream,或者简单地让WASAPI插入一个(它会自动执行)
  3. 创建一个后台线程,用于音频播放,并从GUI线程向其发送消息,告诉您要启动,停止,重新定位等。不幸的是,这是一个相当复杂的选项。