mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2025-01-03 15:15:32 +00:00
add soundio_force_device_scan API
This commit is contained in:
parent
2d8f8e7f31
commit
7a714298c1
|
@ -14,7 +14,11 @@
|
|||
// list or keep a watch on audio devices
|
||||
|
||||
static int usage(char *exe) {
|
||||
fprintf(stderr, "Usage: %s [--watch] [--backend dummy|alsa|pulseaudio|jack|coreaudio|wasapi]\n", exe);
|
||||
fprintf(stderr, "Usage: %s [options]\n"
|
||||
"Options:\n"
|
||||
" [--watch]\n"
|
||||
" [--backend dummy|alsa|pulseaudio|jack|coreaudio|wasapi]\n"
|
||||
" [--short]\n", exe);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -29,10 +33,14 @@ static void print_channel_layout(const struct SoundIoChannelLayout *layout) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool short_output = false;
|
||||
|
||||
static void print_device(struct SoundIoDevice *device, bool is_default) {
|
||||
const char *default_str = is_default ? " (default)" : "";
|
||||
const char *raw_str = device->is_raw ? " (raw)" : "";
|
||||
fprintf(stderr, "%s%s%s\n", device->name, default_str, raw_str);
|
||||
if (short_output)
|
||||
return;
|
||||
fprintf(stderr, " id: %s\n", device->id);
|
||||
|
||||
if (device->probe_error) {
|
||||
|
@ -114,6 +122,8 @@ int main(int argc, char **argv) {
|
|||
char *arg = argv[i];
|
||||
if (strcmp("--watch", arg) == 0) {
|
||||
watch = true;
|
||||
} else if (strcmp("--short", arg) == 0) {
|
||||
short_output = true;
|
||||
} else if (arg[0] == '-' && arg[1] == '-') {
|
||||
i += 1;
|
||||
if (i >= argc) {
|
||||
|
|
|
@ -725,6 +725,22 @@ SOUNDIO_EXPORT void soundio_wait_events(struct SoundIo *soundio);
|
|||
SOUNDIO_EXPORT void soundio_wakeup(struct SoundIo *soundio);
|
||||
|
||||
|
||||
/// If necessary you can manually trigger a device rescan. Normally you will
|
||||
/// not ever have to call this function, as libsoundio listens to system events
|
||||
/// for device changes and responds to them by rescanning devices and preparing
|
||||
/// the new device information for you to be atomically replaced when you call
|
||||
/// ::soundio_flush_events. However you might run into cases where you want to
|
||||
/// force trigger a device rescan, for example if an ALSA device has a
|
||||
/// SoundIoDevice::probe_error.
|
||||
///
|
||||
/// After you call this you still have to use ::soundio_flush_events or
|
||||
/// ::soundio_wait_events and then wait for the
|
||||
/// SoundIo::on_devices_change callback.
|
||||
///
|
||||
/// This can be called from any thread context except for
|
||||
/// SoundIoOutStream::write_callback and SoundIoInStream::read_callback
|
||||
SOUNDIO_EXPORT void soundio_force_device_scan(struct SoundIo *soundio);
|
||||
|
||||
|
||||
// Channel Layouts
|
||||
|
||||
|
|
|
@ -913,6 +913,11 @@ static void wakeup_alsa(SoundIoPrivate *si) {
|
|||
soundio_os_mutex_unlock(sia->mutex);
|
||||
}
|
||||
|
||||
static void force_device_scan_alsa(SoundIoPrivate *si) {
|
||||
SoundIoAlsa *sia = &si->backend_data.alsa;
|
||||
wakeup_device_poll(sia);
|
||||
}
|
||||
|
||||
static void outstream_destroy_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamAlsa *osa = &os->backend_data.alsa;
|
||||
|
||||
|
@ -1771,6 +1776,7 @@ int soundio_alsa_init(SoundIoPrivate *si) {
|
|||
si->flush_events = flush_events_alsa;
|
||||
si->wait_events = wait_events_alsa;
|
||||
si->wakeup = wakeup_alsa;
|
||||
si->force_device_scan = force_device_scan_alsa;
|
||||
|
||||
si->outstream_open = outstream_open_alsa;
|
||||
si->outstream_destroy = outstream_destroy_alsa;
|
||||
|
|
|
@ -820,6 +820,12 @@ static void wakeup_ca(struct SoundIoPrivate *si) {
|
|||
soundio_os_cond_signal(sica->cond, nullptr);
|
||||
}
|
||||
|
||||
static void force_device_scan_ca(struct SoundIoPrivate *si) {
|
||||
SoundIoCoreAudio *sica = &si->backend_data.coreaudio;
|
||||
sica->device_scan_queued.store(true);
|
||||
soundio_os_cond_signal(sica->scan_devices_cond, nullptr);
|
||||
}
|
||||
|
||||
static void device_thread_run(void *arg) {
|
||||
SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||
SoundIo *soundio = &si->pub;
|
||||
|
@ -1365,6 +1371,7 @@ int soundio_coreaudio_init(SoundIoPrivate *si) {
|
|||
si->flush_events = flush_events_ca;
|
||||
si->wait_events = wait_events_ca;
|
||||
si->wakeup = wakeup_ca;
|
||||
si->force_device_scan = force_device_scan_ca;
|
||||
|
||||
si->outstream_open = outstream_open_ca;
|
||||
si->outstream_destroy = outstream_destroy_ca;
|
||||
|
|
|
@ -129,6 +129,10 @@ static void wakeup_dummy(SoundIoPrivate *si) {
|
|||
soundio_os_cond_signal(sid->cond, nullptr);
|
||||
}
|
||||
|
||||
static void force_device_scan_dummy(SoundIoPrivate *si) {
|
||||
// nothing to do; dummy devices never change
|
||||
}
|
||||
|
||||
static void outstream_destroy_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
|
||||
|
||||
|
@ -508,6 +512,7 @@ int soundio_dummy_init(SoundIoPrivate *si) {
|
|||
si->flush_events = flush_events_dummy;
|
||||
si->wait_events = wait_events_dummy;
|
||||
si->wakeup = wakeup_dummy;
|
||||
si->force_device_scan = force_device_scan_dummy;
|
||||
|
||||
si->outstream_open = outstream_open_dummy;
|
||||
si->outstream_destroy = outstream_destroy_dummy;
|
||||
|
|
11
src/jack.cpp
11
src/jack.cpp
|
@ -339,6 +339,16 @@ static void wakeup_jack(struct SoundIoPrivate *si) {
|
|||
soundio_os_mutex_unlock(sij->mutex);
|
||||
}
|
||||
|
||||
static void force_device_scan_jack(struct SoundIoPrivate *si) {
|
||||
SoundIo *soundio = &si->pub;
|
||||
SoundIoJack *sij = &si->backend_data.jack;
|
||||
sij->refresh_devices_flag.clear();
|
||||
soundio_os_mutex_lock(sij->mutex);
|
||||
soundio_os_cond_signal(sij->cond, sij->mutex);
|
||||
soundio->on_events_signal(soundio);
|
||||
soundio_os_mutex_unlock(sij->mutex);
|
||||
}
|
||||
|
||||
static int outstream_process_callback(jack_nframes_t nframes, void *arg) {
|
||||
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg;
|
||||
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
||||
|
@ -892,6 +902,7 @@ int soundio_jack_init(struct SoundIoPrivate *si) {
|
|||
si->flush_events = flush_events_jack;
|
||||
si->wait_events = wait_events_jack;
|
||||
si->wakeup = wakeup_jack;
|
||||
si->force_device_scan = force_device_scan_jack;
|
||||
|
||||
si->outstream_open = outstream_open_jack;
|
||||
si->outstream_destroy = outstream_destroy_jack;
|
||||
|
|
|
@ -491,9 +491,21 @@ static void wait_events_pa(SoundIoPrivate *si) {
|
|||
my_flush_events(si, true);
|
||||
}
|
||||
|
||||
static void wakeup(SoundIoPrivate *si) {
|
||||
static void wakeup_pa(SoundIoPrivate *si) {
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
pa_threaded_mainloop_signal(sipa->main_loop, 0);
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
}
|
||||
|
||||
static void force_device_scan_pa(SoundIoPrivate *si) {
|
||||
SoundIo *soundio = &si->pub;
|
||||
SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
|
||||
pa_threaded_mainloop_lock(sipa->main_loop);
|
||||
sipa->device_scan_queued = true;
|
||||
pa_threaded_mainloop_signal(sipa->main_loop, 0);
|
||||
soundio->on_events_signal(soundio);
|
||||
pa_threaded_mainloop_unlock(sipa->main_loop);
|
||||
}
|
||||
|
||||
static pa_sample_format_t to_pulseaudio_format(SoundIoFormat format) {
|
||||
|
@ -1062,7 +1074,8 @@ int soundio_pulseaudio_init(SoundIoPrivate *si) {
|
|||
si->destroy = destroy_pa;
|
||||
si->flush_events = flush_events_pa;
|
||||
si->wait_events = wait_events_pa;
|
||||
si->wakeup = wakeup;
|
||||
si->wakeup = wakeup_pa;
|
||||
si->force_device_scan = force_device_scan_pa;
|
||||
|
||||
si->outstream_open = outstream_open_pa;
|
||||
si->outstream_destroy = outstream_destroy_pa;
|
||||
|
|
|
@ -417,6 +417,11 @@ void soundio_wakeup(struct SoundIo *soundio) {
|
|||
si->wakeup(si);
|
||||
}
|
||||
|
||||
void soundio_force_device_scan(struct SoundIo *soundio) {
|
||||
SoundIoPrivate *si = (SoundIoPrivate *)soundio;
|
||||
si->force_device_scan(si);
|
||||
}
|
||||
|
||||
int soundio_outstream_begin_write(struct SoundIoOutStream *outstream,
|
||||
SoundIoChannelArea **areas, int *frame_count)
|
||||
{
|
||||
|
|
|
@ -137,6 +137,7 @@ struct SoundIoPrivate {
|
|||
void (*flush_events)(struct SoundIoPrivate *);
|
||||
void (*wait_events)(struct SoundIoPrivate *);
|
||||
void (*wakeup)(struct SoundIoPrivate *);
|
||||
void (*force_device_scan)(struct SoundIoPrivate *);
|
||||
|
||||
int (*outstream_open)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *);
|
||||
void (*outstream_destroy)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *);
|
||||
|
|
|
@ -1017,6 +1017,12 @@ static void wakeup_wasapi(struct SoundIoPrivate *si) {
|
|||
soundio_os_cond_signal(siw->cond, siw->mutex);
|
||||
}
|
||||
|
||||
static void force_device_scan_wasapi(struct SoundIoPrivate *si) {
|
||||
SoundIoWasapi *siw = &si->backend_data.wasapi;
|
||||
siw->device_scan_queued.store(true);
|
||||
soundio_os_cond_signal(siw->scan_devices_cond, nullptr);
|
||||
}
|
||||
|
||||
static void outstream_thread_deinit(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
|
||||
SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi;
|
||||
|
||||
|
@ -1903,11 +1909,7 @@ static STDMETHODIMP_(ULONG) soundio_MMNotificationClient_Release(IMMNotification
|
|||
|
||||
static HRESULT queue_device_scan(IMMNotificationClient *client) {
|
||||
SoundIoPrivate *si = soundio_MMNotificationClient_si(client);
|
||||
SoundIoWasapi *siw = &si->backend_data.wasapi;
|
||||
|
||||
siw->device_scan_queued.store(true);
|
||||
soundio_os_cond_signal(siw->scan_devices_cond, nullptr);
|
||||
|
||||
force_device_scan_wasapi(si);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1986,6 +1988,7 @@ int soundio_wasapi_init(SoundIoPrivate *si) {
|
|||
si->flush_events = flush_events_wasapi;
|
||||
si->wait_events = wait_events_wasapi;
|
||||
si->wakeup = wakeup_wasapi;
|
||||
si->force_device_scan = force_device_scan_wasapi;
|
||||
|
||||
si->outstream_open = outstream_open_wasapi;
|
||||
si->outstream_destroy = outstream_destroy_wasapi;
|
||||
|
|
Loading…
Reference in a new issue