Exemplo n.º 1
0
static void context_state_callback(pa_context *context, void *userdata) {
    SoundIoPrivate *si = (SoundIoPrivate *)userdata;
    SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
    SoundIo *soundio = &si->pub;

    switch (pa_context_get_state(context)) {
    case PA_CONTEXT_UNCONNECTED: // The context hasn't been connected yet.
        return;
    case PA_CONTEXT_CONNECTING: // A connection is being established.
        return;
    case PA_CONTEXT_AUTHORIZING: // The client is authorizing itself to the daemon.
        return;
    case PA_CONTEXT_SETTING_NAME: // The client is passing its application name to the daemon.
        return;
    case PA_CONTEXT_READY: // The connection is established, the context is ready to execute operations.
        sipa->ready_flag = true;
        pa_threaded_mainloop_signal(sipa->main_loop, 0);
        return;
    case PA_CONTEXT_TERMINATED: // The connection was terminated cleanly.
        pa_threaded_mainloop_signal(sipa->main_loop, 0);
        return;
    case PA_CONTEXT_FAILED: // The connection failed or was disconnected.
        if (sipa->ready_flag) {
            sipa->connection_err = SoundIoErrorBackendDisconnected;
        } else {
            sipa->connection_err = SoundIoErrorInitAudioBackend;
            sipa->ready_flag = true;
        }
        pa_threaded_mainloop_signal(sipa->main_loop, 0);
        soundio->on_events_signal(soundio);
        return;
    }
}
Exemplo n.º 2
0
static void notify_devices_change(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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
static void shutdown_callback(void *arg) {
    SoundIoPrivate *si = (SoundIoPrivate *)arg;
    SoundIo *soundio = &si->pub;
    SoundIoJack *sij = &si->backend_data.jack;
    soundio_os_mutex_lock(sij->mutex);
    sij->is_shutdown = true;
    soundio_os_cond_signal(sij->cond, sij->mutex);
    soundio->on_events_signal(soundio);
    soundio_os_mutex_unlock(sij->mutex);
}
Exemplo n.º 5
0
static void subscribe_callback(pa_context *context,
        pa_subscription_event_type_t event_bits, uint32_t index, void *userdata)
{
    SoundIoPrivate *si = (SoundIoPrivate *)userdata;
    SoundIo *soundio = &si->pub;
    SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;
    sipa->device_scan_queued = true;
    pa_threaded_mainloop_signal(sipa->main_loop, 0);
    soundio->on_events_signal(soundio);
}
Exemplo n.º 6
0
// call this while holding the main loop lock
static int refresh_devices(SoundIoPrivate *si) {
    SoundIo *soundio = &si->pub;
    SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio;

    assert(!sipa->current_devices_info);
    sipa->current_devices_info = allocate<SoundIoDevicesInfo>(1);
    if (!sipa->current_devices_info)
        return SoundIoErrorNoMem;

    pa_operation *list_sink_op = pa_context_get_sink_info_list(sipa->pulse_context, sink_info_callback, si);
    pa_operation *list_source_op = pa_context_get_source_info_list(sipa->pulse_context, source_info_callback, si);
    pa_operation *server_info_op = pa_context_get_server_info(sipa->pulse_context, server_info_callback, si);

    int err;
    if ((err = perform_operation(si, list_sink_op))) {
        return err;
    }
    if ((err = perform_operation(si, list_source_op))) {
        return err;
    }
    if ((err = perform_operation(si, server_info_op))) {
        return err;
    }

    if (sipa->device_query_err) {
        return sipa->device_query_err;
    }

    // based on the default sink name, figure out the default output index
    // if the name doesn't match just pick the first one. if there are no
    // devices then we need to set it to -1.
    sipa->current_devices_info->default_output_index = -1;
    sipa->current_devices_info->default_input_index = -1;

    if (sipa->current_devices_info->input_devices.length > 0) {
        sipa->current_devices_info->default_input_index = 0;
        for (int i = 0; i < sipa->current_devices_info->input_devices.length; i += 1) {
            SoundIoDevice *device = sipa->current_devices_info->input_devices.at(i);
            assert(device->aim == SoundIoDeviceAimInput);
            if (strcmp(device->id, sipa->default_source_name) == 0) {
                sipa->current_devices_info->default_input_index = i;
            }
        }
    }

    if (sipa->current_devices_info->output_devices.length > 0) {
        sipa->current_devices_info->default_output_index = 0;
        for (int i = 0; i < sipa->current_devices_info->output_devices.length; i += 1) {
            SoundIoDevice *device = sipa->current_devices_info->output_devices.at(i);
            assert(device->aim == SoundIoDeviceAimOutput);
            if (strcmp(device->id, sipa->default_sink_name) == 0) {
                sipa->current_devices_info->default_output_index = i;
            }
        }
    }

    soundio_destroy_devices_info(sipa->ready_devices_info);
    sipa->ready_devices_info = sipa->current_devices_info;
    sipa->current_devices_info = nullptr;
    pa_threaded_mainloop_signal(sipa->main_loop, 0);
    soundio->on_events_signal(soundio);

    return 0;
}