question

75905375 avatar image
0 Votes"
75905375 asked 75905375 commented

How to judge whether the audio device is unplugged or occupied

I'm dealing with some compatibility scenarios related to audio devices through C++ code in Windows System. For example, when the software is collecting microphone data, if the device is unplugged, or the microphone permission of the application is disabled, or the microphone device is preempted by other software in exclusive mode.

When collecting microphone data, if the above three situations occur, the IAudioCaptureClient::GetBuffer interface returns the same error code [HRESULT = - 2004287484], so I can't tell what the problem is through the error code.

Now I can get whether the application has microphone permission, so I just need to distinguish whether the audio device is unplugged or preempted by other applications in exclusive mode. I tried to traverse the system audio device list again when receiving the error code returned by IAudioCaptureClient::GetBuffer. If there is no device matching the specified ID in the system audio device list, I think it has been pulled out.

However, after trying many times, I found that this method is not reliable. I listened to the IMMNotificationClient::OnDeviceStateChanged callback. When the device is unplugged, I always receive the message of speaker device disconnect first, and then receive the message of microphone device disconnect again after hundreds of milliseconds. When I received the speaker device disconnect message, I went through the system audio device list and found that the unplugged device was still in the list.

So is there a better way to judge whether the device is pulled out or preempted by other applications in exclusive mode?I hope there can be a scheme that can be processed through C++ code.

I look forward to your enthusiastic reply. Thank you!

windows-apic++windows-hardware-code-audio
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

XiaopoYang-MSFT avatar image
0 Votes"
XiaopoYang-MSFT answered 75905375 commented

According to Recovering from an Invalid-Device Error, Perhaps you need the IAudioSessionEvents interface.

An application can determine more precisely the cause of an invalid-device error by registering to receive a notification when a session loses its connection to a device. To enable this notification, the application implements an IAudioSessionEvents interface and calls the IAudioSessionControl::RegisterAudioSessionNotification method to register the interface. When an invalid-device error causes the session to be disconnected, WASAPI calls the IAudioSessionEvents::OnSessionDisconnected method in the registered interface. Through this method, WASAPI informs the application of the reason for the disconnection. In Windows Vista, the OnSessionDisconnected call identifies the following reasons:

The user removed the audio endpoint device.
The Windows audio service has shut down.
The preferred stream format changed for the device that the audio session is connected to.
The user logged off the Windows Terminal Services (WTS) session that the audio session was running in. For more information about WTS sessions, see the Windows SDK documentation.
The WTS session that the audio session was running in was disconnected.
The (shared-mode) audio session was disconnected to make the audio endpoint device available for an exclusive-mode connection.

· 5
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for your answer. I temporarily call the IMMdevice::GetState method to determine whether the device is unplugged.

I have another question: is there an interface or parameter that can let me know that the microphone device is being used by other software in exclusive mode? Or can I get that the microphone device is being used by other software (whether in shared or exclusive mode)?

0 Votes 0 ·

Do you mean IAudioSessionEvents::OnSessionDisconnected ? Also Have a look at the question.

0 Votes 0 ·
75905375 avatar image 75905375 XiaopoYang-MSFT ·

thank you
I tried the IAudioSessionEvents::OnSessionDisconnected method. I did get the notification of exclusive mode preemption, but I found a problem. As shown in the screenshot, I unplugged the device or used exclusive mode preemption in the first two times, and I did get the correct notification. But the third time I disabled the microphone permission, the notification I got was the same as unplugging the device, it was AudioSessionDisconnectReason::DisconnectReasonSessionDisconnected. Did your internal implementation not distinguish between the two cases? (by the way, why do I only perform the three operations of appeal once, but I can receive several same notices every time, hahaha)
194110-1.png


0 Votes 0 ·
1.png (50.4 KiB)
Show more comments
Castorix31 avatar image
0 Votes"
Castorix31 answered 75905375 commented

To get notified when the microphone is unplugged, it works fine on my OS (Windows 10 21H1) with RegisterDeviceNotification
and DEVINTERFACE_AUDIO_CAPTURE for dbcc_classguid
In WM_DEVICECHANGE, I get DBT_DEVICEREMOVECOMPLETE event with right infos in
PDEV_BROADCAST_DEVICEINTERFACE pInfos = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;





· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for your reply. Through registerdevicenotification, I can receive the message that the device is unplugged or the microphone device is connected faster.

For design reasons, I must take the error returned by IAudioCaptureClient::GetBufferr as the starting point of code execution. Therefore, when I receive the error code given to me by IAudioCaptureClient::GetBufferr, I must take the initiative to get the reason - whether it is because the microphone device is unplugged or other applications are preempted in exclusive mode.

Of course, it's cool to listen to the message of device status change more quickly through the way you give. I also tried to set a status bit (bool deviceunplugged = true;) when receiving the message of device unplugging, If I receive the error code returned by IAudioCaptureClient::GetBufferr after that, I think it is caused by the device being pulled out. However, I believe that as a developer, you also know that this method is not reliable and is not a reasonable method (there are problems of multi-threaded access and code call time sequence). It can only be used as one of the debugging methods.

Therefore, I hope to find the most reasonable way - whether there is a more accurate and active way to confirm whether the current microphone device is unplugged or occupied by other applications.

Looking forward to receiving your reply again, thank you!

0 Votes 0 ·
EduleteTechnologiesLLP-6449 avatar image
0 Votes"
EduleteTechnologiesLLP-6449 answered 75905375 commented

There are three ways to judge whether the audio device is unplugged or occupied:

  • Visual inspection: look at the audio jack and see if there is a plug in it.

  • Audible inspection: If you can hear sound coming from the audio jack, then the audio device is plugged in.

  • Tactile inspection: If you can feel a plug in the audio jack, then the audio device is plugged in.


· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for your answer, but what I want is to distinguish programmatically.

0 Votes 0 ·