Open mail2mhossain opened 4 months ago
Are there any solutions for this problem?
This sounds like a bug in SDL; I'll try to reproduce it here tomorrow morning.
This reproduces for me with testaudiohotplug on both SDL2 and SDL3 (just unplug USB headphones and plug them back in while the test program is running). Digging deeper.
Looks like (in SDL3, at least) device->currently_opened
is zero when DeviceAliveNotification is fired...so when we tell SDL that the device is disconnected, it doesn't try to close it, so all sorts of stuff is still dangling.
Not sure why yet, looking into it still.
Wait, no, that was the recording half of the USB headset. But I'm also noticing the testaudiohotplug doesn't close the device at all, so I bet that's what's happening.
Nope, that didn't fix it.
I'm starting to believe this is a macOS bug; the internet (since Mac OS X 10.5, apparently) has been asking "why does this error pop up some times?" and no one seems to know.
Notably, it seems to hang all the other playing devices too, for several seconds, when replugging the USB headset. If I start the device as unplugged and plug it in after everything else, it picks it up fine and works (but then, an unplug/replug after will still cause failure).
I added a 5 second delay to see if it just needed a little time to get itself together on hotplug; didn't fix it.
Feels like the CoreAudio framework is holding some state from the previous device connection that confuses it on replugging. I could be wrong. I'll ask our Apple contact.
Okay, I've moved the SDL coreaudio code out to a standalone program that still reproduces the issue, which is to say this could still be our bug, since it's still our code, but now I can hand this to Apple as a ~500 line Objective-C program without any external dependencies, including SDL itself:
https://gist.github.com/icculus/b021a110eb1bcdfa72f169a620e2d46e
Stay tuned!
Any Update
I never got a reply from Apple. :(
I filed this with Apple, outside of the usual contact.
rdar://15576779
Moving to 3.x, but if Apple moves on the bug report, we can revisit.
Hi, I am also seeing a crash that I believe is related to this. If I try to re-open the default device after seeing the first -66681 error message, I get this crash with the following trace:
frame #0: 0x0000000101385430 tlplay`SDL_AtomicSet_REAL(a=0x000000000000006c, v=1) at SDL_atomic.c:194:12
frame #1: 0x000000010148d330 tlplay`default_device_changed(inObjectID=1, inNumberAddresses=1, inAddresses=0x000060000000ded0, inUserData=0x000060000332d9a0) at SDL_coreaudio.m:675:5
frame #2: 0x000000018fd17a04 CoreAudio`HALObject::PropertiesChanged(unsigned int, AudioObjectPropertyAddress const*) + 1564
frame #3: 0x000000018fb9c228 CoreAudio`HALSystem::PropertiesChanged(unsigned int, AudioObjectPropertyAddress const*) + 412
frame #4: 0x000000018fc6bce8 CoreAudio`HALC_ShellPlugIn::ProxyObject_PropertiesChanged(unsigned int, unsigned int, AudioObjectPropertyAddress const*) + 1060
frame #5: 0x000000018fcc31cc CoreAudio`HALC_ProxyNotifications::CallListener_f(void*) + 92
frame #6: 0x000000018d81c400 libdispatch.dylib`_dispatch_client_callout + 20
frame #7: 0x000000018d823a88 libdispatch.dylib`_dispatch_lane_serial_drain + 668
frame #8: 0x000000018d82462c libdispatch.dylib`_dispatch_lane_invoke + 436
frame #9: 0x000000018d8258e8 libdispatch.dylib`_dispatch_workloop_invoke + 1764
frame #10: 0x000000018d82f244 libdispatch.dylib`_dispatch_workloop_worker_thread + 648
frame #11: 0x000000018d9c8074 libsystem_pthread.dylib`_pthread_wqthread + 288
In default_device_changed()
it looks like this->hidden
is null. If I change the code to add a check for null the crash seems to be fixed, does this seem like a reasonable change?
if (this->hidden)
{
SDL_AtomicSet(&this->hidden->device_change_flag, 1); /* let the audioqueue thread pick up on this when safe to do so. */
}
This is on macOS 13.7 with SDL2 2.30.9. I am triggering the error by turning on/off a bluetooth headset.
I am also seeing these errors in lldb when turning on/off the bluetooth headset:
2024-11-04 14:15:58.569647-0800 tlplay[29868:35257908] HALC_ProxyObjectMap.cpp:153 HALC_ProxyObjectMap::_CopyObjectByObjectID: failed to create the local object
2024-11-04 14:15:58.569670-0800 tlplay[29868:35257908] HALC_ShellDevice.cpp:2606 HALC_ShellDevice::RebuildControlList: couldn't find the control object
2024-11-04 14:15:58.632811-0800 tlplay[29868:35258610] AudioHardware-mac-imp.cpp:660 AudioObjectGetPropertyData: no object with given ID 0
2024-11-04 14:15:58.772863-0800 tlplay[29868:35258812] [aqsrv] AQServer.cpp:80 Exception caught in AudioQueueInternalNotifyRunning - error -66671
2024-11-04 14:15:58.796104-0800 tlplay[29868:35258812] [aqsrv] AQServer.cpp:80 Exception caught in AudioQueueInternalNotifyRunning - error -66671
2024-11-04 14:15:59.016756-0800 tlplay[29868:35258812] [aqsrv] AQServer.cpp:80 Exception caught in AudioQueueInternalStop_Sync - error -66671
2024-11-04 14:15:59.039934-0800 tlplay[29868:35257955] [aqsrv] AQServer.cpp:80 Exception caught in AudioQueueInternalStop_Sync - error -66671
When using our app, if an audio input or output device is unplugged, I can switch to another available device on all platforms (Windows, MacOS, Linux). However, after plugging the device back in, the app can only switch back to it on Windows.
On MacOS, I encounter the following error: "Failed to open audio recording device [name]. SDL Error: CoreAudio error (AudioQueueStart): -66681".
This indicates that the unplugged device is still in use or blocked by SDL2 or MacOS. I have tried the following code in the "InitRecordingDevice" method after calling "CloseAudio()", but it still does not work:
SDL_QuitSubSystem(SDL_INIT_AUDIO); SDL_InitSubSystem(SDL_INIT_AUDIO);
I have also added "SDL_ClearQueuedAudio(dev)" in the "CloseAudio" method before calling "CloseAudioRecordingDevice", but this has not resolved the issue either.
Are there any solutions for this problem?