filoe / cscore

An advanced audio library, written in C#. Provides tons of features. From playing/recording audio to decoding/encoding audio streams/files to processing audio data in realtime (e.g. applying custom effects during playback, create visualizations,...). The possibilities are nearly unlimited.
Other
2.14k stars 450 forks source link

'System.InvalidCastException' occurred in CSCore. Unable to cast object of type 'NAudio.CoreAudioApi.Interfaces.MMDeviceEnumeratorComObject' to type 'MMDeviceEnumeratorObject'. #468

Closed agaertner closed 2 years ago

agaertner commented 2 years ago

Hello, I am reviving an old project of mine and the code that this issue is occuring worked before.

The error occurs at the initialize() call in the following code snippet:

       private void Play(IWaveSource source) {
            if (source == null) return;
            var outputDevice = new WasapiOut(){ Latency = 100 };

            #if DEBUG
            outputDevice.Stopped += (o, e) => {
                if (!e.HasError) return;
                Logger.Warn(e.Exception.Message);
            };
            #endif

            var fadeStrategy = new LinearFadeStrategy(){ SampleRate = source.WaveFormat.SampleRate, Channels = source.WaveFormat.Channels };
            _fadeInOut = new FadeInOut(source.ToSampleSource()){FadeStrategy = fadeStrategy};
            _biQuadFilter = new BiQuadFilterSource(_fadeInOut) { Filter = new LowpassFilter(source.WaveFormat.SampleRate, 400) };
            _equalizer = Equalizer.Create10BandEqualizer(_biQuadFilter);

            var finalSource = _equalizer
                    .ToStereo()
                    .ChangeSampleRate(source.WaveFormat.SampleRate)
                    .ToWaveSource(source.WaveFormat.BitsPerSample);

            outputDevice.Initialize(finalSource); // InvalidCastException (see title) here.
            _initialized = true;

            _outputDevice = outputDevice;

            // Restore previous sound effects.
            SetVolume(ModuleInstance.MasterVolume);

            Fade(0, 1, TimeSpan.FromSeconds(_fadeSeconds));
            _outputDevice.Play();

        }

stacktrace

   at CSCore.CoreAudioAPI.MMDeviceEnumerator.CreateMmDeviceEnumerator()
   at CSCore.CoreAudioAPI.MMDeviceEnumerator..ctor()
   at CSCore.CoreAudioAPI.MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow dataFlow, Role role)
   at CSCore.SoundOut.WasapiOut.get_Device()
   at CSCore.SoundOut.WasapiOut.InitializeInternal()
   at CSCore.SoundOut.WasapiOut.Initialize(IWaveSource source)
   at Nekres.Music_Mixer.Core.Player.Soundtrack.Play(IWaveSource source) in I:\Repositories\github.com\Blish-HUD-Modules-Releases\Music Mixer Module\Core\Player\Soundtrack.cs:line 195
   at Nekres.Music_Mixer.Core.Player.Soundtrack.<>c__DisplayClass15_0.<.ctor>b__2(Task`1 response) in I:\Repositories\github.com\Blish-HUD-Modules-Releases\Music Mixer Module\Core\Player\Soundtrack.cs:line 52
   at System.Threading.Tasks.Task.Execute()

I also tried getting the default device myself but somehow inside the static call of

MMDeviceEnumerator.TryGetDefaultAudioEndpoint()

it fails with a cast exception. I am not sure why it tries to cast to the wrong MMDeviceEnumerator in the first place. NAudio is loaded before CSCore. My assembly and its dependencies (CSCore) is loaded into another project but this entire code worked before without issues.

Info: This project is a module for a framework. The module depends on CSCore. The framework on NAudio. The framework loads the module and all its dependencies on runtime when enabled by the user.

agaertner commented 2 years ago

It even fails when I try to create a new enumerator.

image

filoe commented 2 years ago

This is related to NAudio. You are combining NAudio with cscore.

agaertner commented 2 years ago

I literally just closed an NAudio issue and moved it here because they told me it was an CSCore issue. I never combined NAudio anywhere. All classes come from CSCore. I checked them all. The code I posted worked flawlessly before.

So after no help from both repositories I started refactoring. Removing CSCore from my dependencies.

I still got an InvalidCastException but this time at least it was a more clear one and I found an issue from 2019 describing that it is actually a threading issue. The ComObject is created on the wrong thread. Basically I am now creating the outputDevice on my main thread (which is very bad) probably where the comObject is created and the error doesn't occur anymore.

It actually has been an issue for people starting from Windows 10 Professional onwards. I am on Win11. This makes sense cause my project has been working before even creating the outputdevice on a different thread than my main thread and all.

Here's is the more precise issue that I encountered after my refactor: https://github.com/naudio/NAudio/issues/425

filoe commented 2 years ago

CSCore uses a different approach on creating comobjects. You should not encounteer the threading issue.

Am 16.05.2022 um 04:25 schrieb Andreas G. @.***>:

 I literally just closed an NAudio issue and moved it here. I never combined NAudio anywhere except for the dependencies in the framework my module is loaded in it already has NAudio loaded. The code I posted worked flawlessly before.

So after no help from both repositories I started refactoring. Removing CSCore from my dependencies.

I still got an InvalidCastException but this time at least it was a more clear one and I found an issue from 2019 describing that it is actually a threading issue. The ComObject is created on the wrong thread. Basically I am now creating the outputDevice on my main thread (which is very bad)) probably where the comObject is created and the error doesn't occur anymore.

It actually has been an issue for people starting from Windows 10 Professional onwards. I am on Win11. This makes sense cause my project has been working before even creating the outputdevice on a different thread than my main thread and all.

Here's is the more precise issue that I encountered after my refactor: naudio/NAudio#425

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you modified the open/close state.