static void my_flush_events(struct SoundIoPrivate *si, bool wait) { SoundIo *soundio = &si->pub; SoundIoJack *sij = &si->backend_data.jack; int err; bool cb_shutdown = false; soundio_os_mutex_lock(sij->mutex); if (wait) soundio_os_cond_wait(sij->cond, sij->mutex); if (sij->is_shutdown && !sij->emitted_shutdown_cb) { sij->emitted_shutdown_cb = true; cb_shutdown = true; } soundio_os_mutex_unlock(sij->mutex); if (cb_shutdown) { soundio->on_backend_disconnect(soundio, SoundIoErrorBackendDisconnected); } else { if (!sij->refresh_devices_flag.test_and_set()) { if ((err = refresh_devices(si))) { sij->refresh_devices_flag.clear(); } else { soundio->on_devices_change(soundio); } } } }
static void my_flush_events(struct SoundIoPrivate *si, bool wait) { struct SoundIo *soundio = &si->pub; struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; bool change = false; bool cb_shutdown = false; struct SoundIoDevicesInfo *old_devices_info = NULL; pa_threaded_mainloop_lock(sipa->main_loop); if (wait) pa_threaded_mainloop_wait(sipa->main_loop); if (sipa->device_scan_queued && !sipa->connection_err) { sipa->device_scan_queued = false; sipa->connection_err = refresh_devices(si); cleanup_refresh_devices(si); } if (sipa->connection_err && !sipa->emitted_shutdown_cb) { sipa->emitted_shutdown_cb = true; cb_shutdown = true; } else if (sipa->ready_devices_info) { old_devices_info = si->safe_devices_info; si->safe_devices_info = sipa->ready_devices_info; sipa->ready_devices_info = NULL; change = true; } pa_threaded_mainloop_unlock(sipa->main_loop); if (cb_shutdown) soundio->on_backend_disconnect(soundio, sipa->connection_err); else if (change) soundio->on_devices_change(soundio); soundio_destroy_devices_info(old_devices_info); }
int soundio_jack_init(struct SoundIoPrivate *si) { SoundIoJack *sij = &si->backend_data.jack; SoundIo *soundio = &si->pub; if (!global_msg_callback_flag.test_and_set()) { if (soundio->jack_error_callback) jack_set_error_function(soundio->jack_error_callback); if (soundio->jack_info_callback) jack_set_info_function(soundio->jack_info_callback); global_msg_callback_flag.clear(); } sij->mutex = soundio_os_mutex_create(); if (!sij->mutex) { destroy_jack(si); return SoundIoErrorNoMem; } sij->cond = soundio_os_cond_create(); if (!sij->cond) { destroy_jack(si); return SoundIoErrorNoMem; } // We pass JackNoStartServer due to // https://github.com/jackaudio/jack2/issues/138 jack_status_t status; sij->client = jack_client_open(soundio->app_name, JackNoStartServer, &status); if (!sij->client) { destroy_jack(si); assert(!(status & JackInvalidOption)); if (status & JackShmFailure) return SoundIoErrorSystemResources; if (status & JackNoSuchClient) return SoundIoErrorNoSuchClient; return SoundIoErrorInitAudioBackend; } int err; if ((err = jack_set_buffer_size_callback(sij->client, buffer_size_callback, si))) { destroy_jack(si); return SoundIoErrorInitAudioBackend; } if ((err = jack_set_sample_rate_callback(sij->client, sample_rate_callback, si))) { destroy_jack(si); return SoundIoErrorInitAudioBackend; } if ((err = jack_set_port_registration_callback(sij->client, port_registration_callback, si))) { destroy_jack(si); return SoundIoErrorInitAudioBackend; } if ((err = jack_set_port_rename_callback(sij->client, port_rename_calllback, si))) { destroy_jack(si); return SoundIoErrorInitAudioBackend; } jack_on_shutdown(sij->client, shutdown_callback, si); sij->refresh_devices_flag.clear(); sij->period_size = jack_get_buffer_size(sij->client); sij->sample_rate = jack_get_sample_rate(sij->client); if ((err = jack_activate(sij->client))) { destroy_jack(si); return SoundIoErrorInitAudioBackend; } if ((err = refresh_devices(si))) { destroy_jack(si); return err; } si->destroy = destroy_jack; 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; si->outstream_start = outstream_start_jack; si->outstream_begin_write = outstream_begin_write_jack; si->outstream_end_write = outstream_end_write_jack; si->outstream_clear_buffer = outstream_clear_buffer_jack; si->outstream_pause = outstream_pause_jack; si->outstream_get_latency = outstream_get_latency_jack; si->instream_open = instream_open_jack; si->instream_destroy = instream_destroy_jack; si->instream_start = instream_start_jack; si->instream_begin_read = instream_begin_read_jack; si->instream_end_read = instream_end_read_jack; si->instream_pause = instream_pause_jack; si->instream_get_latency = instream_get_latency_jack; return 0; }