Beispiel #1
0
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);
            }
        }
    }
}
Beispiel #2
0
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);
}
Beispiel #3
0
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;
}