Chris Chalmers
Chris Chalmers

Reputation: 43

CSCore: access violation when listening to audio session events

I'm just getting started with CSCore, and getting back to C# after a lot of C++. Here's a test program that enumerates the audio sessions of the default audio session manager, and attaches an empty event handler to each one:

using System;
using CSCore.CoreAudioAPI;

class Program
{
    static void Main(string[] args)
    {
        using (var enumerator = new MMDeviceEnumerator())
        using (var device = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia))
        using (var sessionManager = AudioSessionManager2.FromMMDevice(device))
        using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
        {
            foreach (var control in sessionEnumerator)
            {
                var control2 = control.QueryInterface<AudioSessionControl2>();
                RegisterAudioSession(control2);
            }
        }

        Console.WriteLine("Waiting...");
        Console.ReadKey();
    }

    static void RegisterAudioSession(AudioSessionControl2 session)
    {
        if (session.Process != null)
        {
            var events = new AudioSessionEvents();
            session.RegisterAudioSessionNotification(events);
        }
    }
}

I would expect to be able to change the volume of my computer while this program is running without any problems. If you try this, however, the program crashes with an access violation in native code. Here's the stack trace:

>   AudioSes.dll!CLockedList<ATL::CComPtr<IAudioSessionEvents>,0,1>::ForEachEntry() Unknown
AudioSes.dll!CAudioSessionControl::OnAudioSessionEvent()    Unknown
AudioSes.dll!CAudioSessionControl::CAudioSessionNotificationDelegator::OnMediaNotification(struct MEDIA_NOTIFICATION_BLOCK *)   Unknown
MMDevAPI.dll!CMediaNotifications::OnMediaNotificationWorkerHandler(struct _TP_CALLBACK_INSTANCE *)  Unknown
MMDevAPI.dll!CMediaNotifications::MediaNotificationWorkerHandler(struct _TP_CALLBACK_INSTANCE *,void *) Unknown
ntdll.dll!TppSimplepExecuteCallback()   Unknown
ntdll.dll!TppWorkerThread() Unknown
kernel32.dll!@BaseThreadInitThunk@12()  Unknown
ntdll.dll!__RtlUserThreadStart()    Unknown
ntdll.dll!__RtlUserThreadStart@8()  Unknown

The crash does not occur if you remove the call to RegisterAudioSessionNotification.

The crash still occurs if you register a non-empty event handler.

I tried moving Console.ReadKey(); into the using block in case a necessary resource was being disposed, but the failure persisted.

I searched all over the place for an explanation and solution. There are no relevant open issues on CSCore's github page. I read somewhere that crashes in native code are often caused by incorrect signatures in wrapper assemblies. I compared all of the methods on CSCore's IAudioSessionEvents to the native IAudioSessionEvents methods (enumerated here) but found no obvious discrepancies.

This Firefox bug is the only reference I found online to this particular stack trace, and it has been resolved. Apparently it was resolved in Flash Player 19.0.0.159, but as far as I know that source isn't available for perusal.

Am I overlooking an error in my code, or is this a bug in CSCore?

Upvotes: 2

Views: 930

Answers (1)

Chris Chalmers
Chris Chalmers

Reputation: 43

Turns out this crash occurs if the target platform is 32-bit (or in my case, "Any CPU" but running in the 32-bit VS process). Switching to a 64-bit target platform fixed it for me

Upvotes: 1

Related Questions