mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-23 03:35:29 +00:00
CoreAudio: emit on_backend_disconnecte when service restarts
This commit is contained in:
parent
7371ce5146
commit
6d185de82c
|
@ -20,18 +20,36 @@ static OSStatus on_devices_changed(AudioObjectID in_object_id, UInt32 in_number_
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static OSStatus on_service_restarted(AudioObjectID in_object_id, UInt32 in_number_addresses,
|
||||||
|
const AudioObjectPropertyAddress in_addresses[], void *in_client_data)
|
||||||
|
{
|
||||||
|
SoundIoPrivate *si = (SoundIoPrivate*)in_client_data;
|
||||||
|
SoundIoCoreAudio *sica = &si->backend_data.coreaudio;
|
||||||
|
|
||||||
|
sica->service_restarted.store(true);
|
||||||
|
soundio_os_cond_signal(sica->cond, nullptr);
|
||||||
|
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
|
||||||
static void destroy_ca(struct SoundIoPrivate *si) {
|
static void destroy_ca(struct SoundIoPrivate *si) {
|
||||||
SoundIoCoreAudio *sica = &si->backend_data.coreaudio;
|
SoundIoCoreAudio *sica = &si->backend_data.coreaudio;
|
||||||
|
|
||||||
|
int err;
|
||||||
AudioObjectPropertyAddress prop_address = {
|
AudioObjectPropertyAddress prop_address = {
|
||||||
kAudioHardwarePropertyDevices,
|
kAudioHardwarePropertyDevices,
|
||||||
kAudioObjectPropertyScopeGlobal,
|
kAudioObjectPropertyScopeGlobal,
|
||||||
kAudioObjectPropertyElementMaster
|
kAudioObjectPropertyElementMaster
|
||||||
};
|
};
|
||||||
int err = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop_address,
|
err = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop_address,
|
||||||
on_devices_changed, si);
|
on_devices_changed, si);
|
||||||
assert(!err);
|
assert(!err);
|
||||||
|
|
||||||
|
prop_address.mSelector = kAudioHardwarePropertyServiceRestarted;
|
||||||
|
err = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop_address,
|
||||||
|
on_service_restarted, si);
|
||||||
|
assert(!err);
|
||||||
|
|
||||||
if (sica->thread) {
|
if (sica->thread) {
|
||||||
sica->abort_flag.clear();
|
sica->abort_flag.clear();
|
||||||
soundio_os_cond_signal(sica->cond, nullptr);
|
soundio_os_cond_signal(sica->cond, nullptr);
|
||||||
|
@ -83,14 +101,6 @@ static int aim_to_scope(SoundIoDeviceAim aim) {
|
||||||
@constant kAudioHardwarePropertyDefaultOutputDevice
|
@constant kAudioHardwarePropertyDefaultOutputDevice
|
||||||
The AudioObjectID of the default output AudioDevice.
|
The AudioObjectID of the default output AudioDevice.
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
@constant kAudioHardwarePropertyServiceRestarted
|
|
||||||
A UInt32 whose value has no meaning. Rather, this property exists so that
|
|
||||||
clients can be informed when the service has been reset for some reason.
|
|
||||||
When a reset happens, any state the client has , such as cached data or
|
|
||||||
added listeners, must be re-established by the client.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
@constant kAudioDevicePropertyDeviceHasChanged
|
@constant kAudioDevicePropertyDeviceHasChanged
|
||||||
|
@ -295,6 +305,10 @@ static void device_thread_run(void *arg) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!sica->abort_flag.test_and_set())
|
if (!sica->abort_flag.test_and_set())
|
||||||
break;
|
break;
|
||||||
|
if (sica->service_restarted.load()) {
|
||||||
|
shutdown_backend(si, SoundIoErrorBackendDisconnected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (sica->device_scan_queued.exchange(false)) {
|
if (sica->device_scan_queued.exchange(false)) {
|
||||||
if ((err = refresh_devices(si))) {
|
if ((err = refresh_devices(si))) {
|
||||||
shutdown_backend(si, err);
|
shutdown_backend(si, err);
|
||||||
|
@ -374,6 +388,7 @@ int soundio_coreaudio_init(SoundIoPrivate *si) {
|
||||||
|
|
||||||
sica->have_devices_flag.store(false);
|
sica->have_devices_flag.store(false);
|
||||||
sica->device_scan_queued.store(true);
|
sica->device_scan_queued.store(true);
|
||||||
|
sica->service_restarted.store(false);
|
||||||
sica->abort_flag.test_and_set();
|
sica->abort_flag.test_and_set();
|
||||||
|
|
||||||
sica->mutex = soundio_os_mutex_create();
|
sica->mutex = soundio_os_mutex_create();
|
||||||
|
@ -405,6 +420,13 @@ int soundio_coreaudio_init(SoundIoPrivate *si) {
|
||||||
soundio_panic("add prop listener");
|
soundio_panic("add prop listener");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prop_address.mSelector = kAudioHardwarePropertyServiceRestarted;
|
||||||
|
if ((err = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &prop_address,
|
||||||
|
on_service_restarted, si)))
|
||||||
|
{
|
||||||
|
soundio_panic("add prop listener 2");
|
||||||
|
}
|
||||||
|
|
||||||
if ((err = soundio_os_thread_create(device_thread_run, si, false, &sica->thread))) {
|
if ((err = soundio_os_thread_create(device_thread_run, si, false, &sica->thread))) {
|
||||||
destroy_ca(si);
|
destroy_ca(si);
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct SoundIoCoreAudio {
|
||||||
SoundIoOsCond *have_devices_cond;
|
SoundIoOsCond *have_devices_cond;
|
||||||
|
|
||||||
atomic_bool device_scan_queued;
|
atomic_bool device_scan_queued;
|
||||||
|
atomic_bool service_restarted;
|
||||||
int shutdown_err;
|
int shutdown_err;
|
||||||
bool emitted_shutdown_cb;
|
bool emitted_shutdown_cb;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue