I am developing an audio recording program in C++ (I use OpenAL and ImGui with OpenGL if that helps) and i want to know if i can detect if my default audio output device changes without running a loop that blocks my program. Is there a way for me to detect it like with callbacks maybe?
I tried using
alcGetString(device, ALC_DEFAULT_DEVICE_SPECIFIER);
function to get the name of the default device and compare it with last one i used in a loop on another thread. It did the job but it cost me lots of performance.
Thanks to @PaulSanders i have found a solution. It is not what i was looking for but i think it is still a good one. Here is the code:
Let me explain the code:
NotificationClientclass inheritsIMMNotificationClientso i can override its functions likeOnDefaultDeviceChangedto handle audio output device change for my app. You can also add your own logic to functions likeOnDeviceAddedorOnDeviceRemovedto handle other types of events, but since i don't need them i just returns_Okfrom those functions. You should also know that those functions are pure-virtual functions so you need to override them even if you don't want to use them. I useIMMDeviceEnumeratorso i can register my inheritedNotificationClientclass to receive audio device messages. But if the COM library isn't initialized then you need to callCoInitializefunction to initialize it. I create a thread with a loop and usePeekMessageto get messages and useWaitMessagefunction to suspend the thread until it receives another message. This solves my performance problem with busy-looping to check for a message continually. To close this thread safely i send aWM_QUITmessage to the thread usingPostThreadMessagefunction and useWaitForSingleObjectto wait for it to close.I wrapped all of this to a
AudioDeviceNotificationListenerclass so i can just callStartfunction to begin listening for messages andClosefunction to exit the thread and stop listening.(Edit: I also found a way without creating a thread. The code is pretty much the same, i just removed
AudioDeviceNotificationListenerclass. The code is shown below)You can use one of these codes for your own preference both of them works for me.