mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2024-12-23 03:45:31 +00:00
JACK: ability to list devices
This commit is contained in:
parent
447a241c2e
commit
42961553d8
245
src/jack.cpp
245
src/jack.cpp
|
@ -8,6 +8,7 @@
|
||||||
#include "jack.hpp"
|
#include "jack.hpp"
|
||||||
#include "soundio.hpp"
|
#include "soundio.hpp"
|
||||||
#include "atomics.hpp"
|
#include "atomics.hpp"
|
||||||
|
#include "os.hpp"
|
||||||
|
|
||||||
#include <jack/jack.h>
|
#include <jack/jack.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -16,18 +17,52 @@ static atomic_flag global_msg_callback_flag = ATOMIC_FLAG_INIT;
|
||||||
|
|
||||||
struct SoundIoJack {
|
struct SoundIoJack {
|
||||||
jack_client_t *client;
|
jack_client_t *client;
|
||||||
|
SoundIoOsMutex *mutex;
|
||||||
|
SoundIoOsCond *cond;
|
||||||
|
// this one is ready to be read with flush_events. protected by mutex
|
||||||
|
struct SoundIoDevicesInfo *ready_devices_info;
|
||||||
|
bool initialized;
|
||||||
|
int sample_rate;
|
||||||
|
int buffer_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void flush_events_jack(struct SoundIoPrivate *) {
|
static void flush_events_jack(struct SoundIoPrivate *si) {
|
||||||
soundio_panic("TODO");
|
SoundIo *soundio = &si->pub;
|
||||||
|
SoundIoJack *sij = (SoundIoJack *)si->backend_data;
|
||||||
|
|
||||||
|
bool change = false;
|
||||||
|
SoundIoDevicesInfo *old_devices_info = nullptr;
|
||||||
|
|
||||||
|
soundio_os_mutex_lock(sij->mutex);
|
||||||
|
|
||||||
|
if (sij->ready_devices_info) {
|
||||||
|
old_devices_info = si->safe_devices_info;
|
||||||
|
si->safe_devices_info = sij->ready_devices_info;
|
||||||
|
sij->ready_devices_info = nullptr;
|
||||||
|
change = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
soundio_os_mutex_unlock(sij->mutex);
|
||||||
|
|
||||||
|
if (change)
|
||||||
|
soundio->on_devices_change(soundio);
|
||||||
|
|
||||||
|
soundio_destroy_devices_info(old_devices_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wait_events_jack(struct SoundIoPrivate *) {
|
static void wait_events_jack(struct SoundIoPrivate *si) {
|
||||||
soundio_panic("TODO");
|
SoundIoJack *sij = (SoundIoJack *)si->backend_data;
|
||||||
|
flush_events_jack(si);
|
||||||
|
soundio_os_mutex_lock(sij->mutex);
|
||||||
|
soundio_os_cond_wait(sij->cond, sij->mutex);
|
||||||
|
soundio_os_mutex_unlock(sij->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wakeup_jack(struct SoundIoPrivate *) {
|
static void wakeup_jack(struct SoundIoPrivate *si) {
|
||||||
soundio_panic("TODO");
|
SoundIoJack *sij = (SoundIoJack *)si->backend_data;
|
||||||
|
soundio_os_mutex_lock(sij->mutex);
|
||||||
|
soundio_os_cond_signal(sij->cond, sij->mutex);
|
||||||
|
soundio_os_mutex_unlock(sij->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,12 +124,159 @@ static int instream_pause_jack(struct SoundIoPrivate *, struct SoundIoInStreamPr
|
||||||
soundio_panic("TODO");
|
soundio_panic("TODO");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int refresh_devices(SoundIoPrivate *si) {
|
||||||
|
SoundIo *soundio = &si->pub;
|
||||||
|
SoundIoJack *sij = (SoundIoJack *)si->backend_data;
|
||||||
|
|
||||||
|
SoundIoDevicesInfo *devices_info = create<SoundIoDevicesInfo>();
|
||||||
|
if (!devices_info)
|
||||||
|
return SoundIoErrorNoMem;
|
||||||
|
|
||||||
|
devices_info->default_output_index = -1;
|
||||||
|
devices_info->default_input_index = -1;
|
||||||
|
const char **port_names = jack_get_ports(sij->client, nullptr, nullptr, 0);
|
||||||
|
if (!port_names) {
|
||||||
|
destroy(devices_info);
|
||||||
|
return SoundIoErrorNoMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char **port_name_ptr = port_names;
|
||||||
|
while (*port_name_ptr) {
|
||||||
|
const char *port_name = *port_name_ptr;
|
||||||
|
jack_port_t *port = jack_port_by_name(sij->client, port_name);
|
||||||
|
int flags = jack_port_flags(port);
|
||||||
|
|
||||||
|
SoundIoDevice *device = create<SoundIoDevice>();
|
||||||
|
if (!device) {
|
||||||
|
jack_free(port_names);
|
||||||
|
destroy(devices_info);
|
||||||
|
return SoundIoErrorNoMem;
|
||||||
|
}
|
||||||
|
device->ref_count = 1;
|
||||||
|
device->soundio = soundio;
|
||||||
|
device->is_raw = false;
|
||||||
|
device->name = strdup(port_name);
|
||||||
|
device->description = strdup(port_name);
|
||||||
|
device->layout_count = 1;
|
||||||
|
device->layouts = create<SoundIoChannelLayout>();
|
||||||
|
device->format_count = 1;
|
||||||
|
device->formats = create<SoundIoFormat>();
|
||||||
|
|
||||||
|
if (!device->name || !device->description || !device->layouts || !device->formats) {
|
||||||
|
jack_free(port_names);
|
||||||
|
soundio_device_unref(device);
|
||||||
|
destroy(devices_info);
|
||||||
|
return SoundIoErrorNoMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO figure out how jack does channel layout
|
||||||
|
device->layouts[0] = *soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdMono);
|
||||||
|
device->current_layout = *soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdMono);
|
||||||
|
|
||||||
|
device->formats[0] = SoundIoFormatFloat32NE;
|
||||||
|
device->current_format = SoundIoFormatFloat32NE;
|
||||||
|
|
||||||
|
device->sample_rate_min = sij->sample_rate;
|
||||||
|
device->sample_rate_max = sij->sample_rate;
|
||||||
|
device->sample_rate_current = sij->sample_rate;
|
||||||
|
|
||||||
|
device->buffer_duration_min = sij->buffer_size / (double) sij->sample_rate;
|
||||||
|
device->buffer_duration_max = device->buffer_duration_min;
|
||||||
|
device->buffer_duration_current = device->buffer_duration_min;
|
||||||
|
|
||||||
|
|
||||||
|
SoundIoList<SoundIoDevice *> *device_list;
|
||||||
|
if (flags & JackPortIsInput) {
|
||||||
|
device->purpose = SoundIoDevicePurposeOutput;
|
||||||
|
device_list = &devices_info->output_devices;
|
||||||
|
if (devices_info->default_output_index < 0 && (flags & JackPortIsPhysical))
|
||||||
|
devices_info->default_output_index = device_list->length;
|
||||||
|
} else {
|
||||||
|
assert(flags & JackPortIsOutput);
|
||||||
|
device->purpose = SoundIoDevicePurposeInput;
|
||||||
|
device_list = &devices_info->input_devices;
|
||||||
|
if (devices_info->default_input_index < 0 && (flags & JackPortIsPhysical))
|
||||||
|
devices_info->default_input_index = device_list->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device_list->append(device)) {
|
||||||
|
jack_free(port_names);
|
||||||
|
soundio_device_unref(device);
|
||||||
|
destroy(devices_info);
|
||||||
|
return SoundIoErrorNoMem;
|
||||||
|
}
|
||||||
|
|
||||||
|
port_name_ptr += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
jack_free(port_names);
|
||||||
|
|
||||||
|
soundio_os_mutex_lock(sij->mutex);
|
||||||
|
soundio_destroy_devices_info(sij->ready_devices_info);
|
||||||
|
sij->ready_devices_info = devices_info;
|
||||||
|
soundio_os_cond_signal(sij->cond, sij->mutex);
|
||||||
|
soundio->on_events_signal(soundio);
|
||||||
|
soundio_os_mutex_unlock(sij->mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int process_callback(jack_nframes_t nframes, void *arg) {
|
||||||
|
////SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||||
|
//soundio_panic("TODO process callback");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int buffer_size_callback(jack_nframes_t nframes, void *arg) {
|
||||||
|
SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||||
|
SoundIoJack *sij = (SoundIoJack *)si->backend_data;
|
||||||
|
sij->buffer_size = nframes;
|
||||||
|
if (sij->initialized)
|
||||||
|
refresh_devices(si);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sample_rate_callback(jack_nframes_t nframes, void *arg) {
|
||||||
|
SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||||
|
SoundIoJack *sij = (SoundIoJack *)si->backend_data;
|
||||||
|
sij->sample_rate = nframes;
|
||||||
|
if (sij->initialized)
|
||||||
|
refresh_devices(si);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xrun_callback(void *arg) {
|
||||||
|
//SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||||
|
soundio_panic("TODO xrun callback");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void port_registration_callback(jack_port_id_t port_id, int reg, void *arg) {
|
||||||
|
//SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||||
|
soundio_panic("TODO port registration callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int port_rename_calllback(jack_port_id_t port_id,
|
||||||
|
const char *old_name, const char *new_name, void *arg)
|
||||||
|
{
|
||||||
|
//SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||||
|
soundio_panic("TODO port rename callback");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void shutdown_callback(void *arg) {
|
||||||
|
//SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||||
|
soundio_panic("TODO shutdown callback");
|
||||||
|
}
|
||||||
|
|
||||||
static void destroy_jack(SoundIoPrivate *si) {
|
static void destroy_jack(SoundIoPrivate *si) {
|
||||||
SoundIoJack *sij = (SoundIoJack *)si->backend_data;
|
SoundIoJack *sij = (SoundIoJack *)si->backend_data;
|
||||||
if (!sij)
|
if (!sij)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (sij->client)
|
||||||
|
jack_client_close(sij->client);
|
||||||
|
|
||||||
destroy(sij);
|
destroy(sij);
|
||||||
si->backend_data = nullptr;
|
si->backend_data = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -118,13 +300,23 @@ int soundio_jack_init(struct SoundIoPrivate *si) {
|
||||||
}
|
}
|
||||||
si->backend_data = sij;
|
si->backend_data = sij;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
jack_status_t status;
|
jack_status_t status;
|
||||||
sij->client = jack_client_open(soundio->app_name, JackNoStartServer, &status);
|
sij->client = jack_client_open(soundio->app_name, JackNoStartServer, &status);
|
||||||
if (!sij->client) {
|
if (!sij->client) {
|
||||||
destroy_jack(si);
|
destroy_jack(si);
|
||||||
assert(!(status & JackInvalidOption));
|
assert(!(status & JackInvalidOption));
|
||||||
if (status & JackNameNotUnique)
|
|
||||||
return SoundIoErrorNameNotUnique;
|
|
||||||
if (status & JackShmFailure)
|
if (status & JackShmFailure)
|
||||||
return SoundIoErrorSystemResources;
|
return SoundIoErrorSystemResources;
|
||||||
if (status & JackNoSuchClient)
|
if (status & JackNoSuchClient)
|
||||||
|
@ -133,6 +325,43 @@ int soundio_jack_init(struct SoundIoPrivate *si) {
|
||||||
return SoundIoErrorInitAudioBackend;
|
return SoundIoErrorInitAudioBackend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int err;
|
||||||
|
if ((err = jack_set_process_callback(sij->client, process_callback, si))) {
|
||||||
|
destroy_jack(si);
|
||||||
|
return SoundIoErrorInitAudioBackend;
|
||||||
|
}
|
||||||
|
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_xrun_callback(sij->client, xrun_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);
|
||||||
|
|
||||||
|
if ((err = jack_activate(sij->client))) {
|
||||||
|
destroy_jack(si);
|
||||||
|
return SoundIoErrorInitAudioBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
sij->initialized = true;
|
||||||
|
if ((err = refresh_devices(si))) {
|
||||||
|
destroy_jack(si);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
si->destroy = destroy_jack;
|
si->destroy = destroy_jack;
|
||||||
si->flush_events = flush_events_jack;
|
si->flush_events = flush_events_jack;
|
||||||
|
|
|
@ -70,7 +70,6 @@ const char *soundio_strerror(int error) {
|
||||||
case SoundIoErrorBackendUnavailable: return "backend unavailable";
|
case SoundIoErrorBackendUnavailable: return "backend unavailable";
|
||||||
case SoundIoErrorStreaming: return "unrecoverable streaming failure";
|
case SoundIoErrorStreaming: return "unrecoverable streaming failure";
|
||||||
case SoundIoErrorIncompatibleDevice: return "incompatible device";
|
case SoundIoErrorIncompatibleDevice: return "incompatible device";
|
||||||
case SoundIoErrorNameNotUnique: return "name not unique";
|
|
||||||
case SoundIoErrorNoSuchClient: return "no such client";
|
case SoundIoErrorNoSuchClient: return "no such client";
|
||||||
}
|
}
|
||||||
soundio_panic("invalid error enum value: %d", error);
|
soundio_panic("invalid error enum value: %d", error);
|
||||||
|
@ -188,7 +187,7 @@ int soundio_connect(struct SoundIo *soundio) {
|
||||||
int soundio_connect_backend(SoundIo *soundio, SoundIoBackend backend) {
|
int soundio_connect_backend(SoundIo *soundio, SoundIoBackend backend) {
|
||||||
SoundIoPrivate *si = (SoundIoPrivate *)soundio;
|
SoundIoPrivate *si = (SoundIoPrivate *)soundio;
|
||||||
|
|
||||||
if (si->current_backend)
|
if (soundio->current_backend)
|
||||||
return SoundIoErrorInvalid;
|
return SoundIoErrorInvalid;
|
||||||
|
|
||||||
if (backend <= 0 || backend > SoundIoBackendDummy)
|
if (backend <= 0 || backend > SoundIoBackendDummy)
|
||||||
|
@ -214,7 +213,7 @@ void soundio_disconnect(struct SoundIo *soundio) {
|
||||||
si->destroy(si);
|
si->destroy(si);
|
||||||
assert(!si->backend_data);
|
assert(!si->backend_data);
|
||||||
|
|
||||||
si->current_backend = SoundIoBackendNone;
|
soundio->current_backend = SoundIoBackendNone;
|
||||||
|
|
||||||
soundio_destroy_devices_info(si->safe_devices_info);
|
soundio_destroy_devices_info(si->safe_devices_info);
|
||||||
si->safe_devices_info = nullptr;
|
si->safe_devices_info = nullptr;
|
||||||
|
@ -390,7 +389,7 @@ int soundio_outstream_open(struct SoundIoOutStream *outstream) {
|
||||||
outstream->sample_rate = clamp(device->sample_rate_min, 48000, device->sample_rate_max);
|
outstream->sample_rate = clamp(device->sample_rate_min, 48000, device->sample_rate_max);
|
||||||
|
|
||||||
if (!outstream->name)
|
if (!outstream->name)
|
||||||
outstream->name = "SoundIo";
|
outstream->name = "SoundIoOutStream";
|
||||||
|
|
||||||
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)outstream;
|
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)outstream;
|
||||||
outstream->bytes_per_frame = soundio_get_bytes_per_frame(outstream->format, outstream->layout.channel_count);
|
outstream->bytes_per_frame = soundio_get_bytes_per_frame(outstream->format, outstream->layout.channel_count);
|
||||||
|
@ -471,7 +470,7 @@ int soundio_instream_open(struct SoundIoInStream *instream) {
|
||||||
instream->sample_rate = clamp(device->sample_rate_min, 48000, device->sample_rate_max);
|
instream->sample_rate = clamp(device->sample_rate_min, 48000, device->sample_rate_max);
|
||||||
|
|
||||||
if (!instream->name)
|
if (!instream->name)
|
||||||
instream->name = "SoundIo";
|
instream->name = "SoundIoInStream";
|
||||||
|
|
||||||
|
|
||||||
instream->bytes_per_frame = soundio_get_bytes_per_frame(instream->format, instream->layout.channel_count);
|
instream->bytes_per_frame = soundio_get_bytes_per_frame(instream->format, instream->layout.channel_count);
|
||||||
|
|
|
@ -26,7 +26,6 @@ enum SoundIoError {
|
||||||
SoundIoErrorBackendUnavailable,
|
SoundIoErrorBackendUnavailable,
|
||||||
SoundIoErrorStreaming,
|
SoundIoErrorStreaming,
|
||||||
SoundIoErrorIncompatibleDevice,
|
SoundIoErrorIncompatibleDevice,
|
||||||
SoundIoErrorNameNotUnique,
|
|
||||||
SoundIoErrorNoSuchClient,
|
SoundIoErrorNoSuchClient,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -198,7 +197,7 @@ struct SoundIoChannelArea {
|
||||||
|
|
||||||
// The size of this struct is not part of the API or ABI.
|
// The size of this struct is not part of the API or ABI.
|
||||||
struct SoundIo {
|
struct SoundIo {
|
||||||
// Defaults to NULL. Put whatever you want here.
|
// Optional. Put whatever you want here. Defaults to NULL.
|
||||||
void *userdata;
|
void *userdata;
|
||||||
// Optional callback. Called when the list of devices change. Only called
|
// Optional callback. Called when the list of devices change. Only called
|
||||||
// during a call to soundio_flush_events or soundio_wait_events.
|
// during a call to soundio_flush_events or soundio_wait_events.
|
||||||
|
@ -216,9 +215,15 @@ struct SoundIo {
|
||||||
// Optional: JACK info and error callbacks.
|
// Optional: JACK info and error callbacks.
|
||||||
// By default, libsoundio sets these to empty functions in order to
|
// By default, libsoundio sets these to empty functions in order to
|
||||||
// silence stdio messages from JACK. You may override the behavior by
|
// silence stdio messages from JACK. You may override the behavior by
|
||||||
// setting these to `NULL` or providing your own function.
|
// setting these to `NULL` or providing your own function. These are
|
||||||
|
// registered with JACK regardless of whether `soundio_connect_backend`
|
||||||
|
// succeeds.
|
||||||
void (*jack_info_callback)(const char *msg);
|
void (*jack_info_callback)(const char *msg);
|
||||||
void (*jack_error_callback)(const char *msg);
|
void (*jack_error_callback)(const char *msg);
|
||||||
|
|
||||||
|
// Read-only. After calling `soundio_connect` or `soundio_connect_backend`,
|
||||||
|
// this field tells which backend is currently connected.
|
||||||
|
enum SoundIoBackend current_backend;
|
||||||
};
|
};
|
||||||
|
|
||||||
// The size of this struct is not part of the API or ABI.
|
// The size of this struct is not part of the API or ABI.
|
||||||
|
@ -285,9 +290,9 @@ struct SoundIoDevice {
|
||||||
// Tells whether this device is an input device or an output device.
|
// Tells whether this device is an input device or an output device.
|
||||||
enum SoundIoDevicePurpose purpose;
|
enum SoundIoDevicePurpose purpose;
|
||||||
|
|
||||||
// raw means that you are directly opening the hardware device and not
|
// Raw means that you are directly opening the hardware device and not
|
||||||
// going through a proxy such as dmix or PulseAudio. When you open a raw
|
// going through a proxy such as dmix, PulseAudio, or JACK. When you open a
|
||||||
// device, other applications on the computer are not able to
|
// raw device, other applications on the computer are not able to
|
||||||
// simultaneously access the device. Raw devices do not perform automatic
|
// simultaneously access the device. Raw devices do not perform automatic
|
||||||
// resampling and thus tend to have fewer formats available.
|
// resampling and thus tend to have fewer formats available.
|
||||||
bool is_raw;
|
bool is_raw;
|
||||||
|
@ -359,10 +364,13 @@ struct SoundIoOutStream {
|
||||||
// invalid state and must be destroyed.
|
// invalid state and must be destroyed.
|
||||||
// If you do not supply `error_callback`, the default callback will print
|
// If you do not supply `error_callback`, the default callback will print
|
||||||
// a message to stderr and then call `abort`.
|
// a message to stderr and then call `abort`.
|
||||||
// This is called fram the `write_callback` thread context.
|
// This is called from the `write_callback` thread context.
|
||||||
void (*error_callback)(struct SoundIoOutStream *, int err);
|
void (*error_callback)(struct SoundIoOutStream *, int err);
|
||||||
|
|
||||||
// Name of the stream. This is used by PulseAudio. Defaults to "SoundIo".
|
// Optional: Name of the stream. Defaults to "SoundIoOutStream"
|
||||||
|
// PulseAudio uses this for the stream name.
|
||||||
|
// JACK uses this for the client name of the client that connects when you
|
||||||
|
// open the stream.
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
|
|
||||||
|
@ -413,7 +421,10 @@ struct SoundIoInStream {
|
||||||
// This is called from the `read_callback` thread context.
|
// This is called from the `read_callback` thread context.
|
||||||
void (*error_callback)(struct SoundIoInStream *, int err);
|
void (*error_callback)(struct SoundIoInStream *, int err);
|
||||||
|
|
||||||
// Name of the stream. This is used by PulseAudio. Defaults to "SoundIo".
|
// Optional: Name of the stream. Defaults to "SoundIoInStream";
|
||||||
|
// PulseAudio uses this for the stream name.
|
||||||
|
// JACK uses this for the client name of the client that connects when you
|
||||||
|
// open the stream.
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
// computed automatically when you call soundio_instream_open
|
// computed automatically when you call soundio_instream_open
|
||||||
|
|
|
@ -32,8 +32,6 @@ struct SoundIoInStreamPrivate {
|
||||||
struct SoundIoPrivate {
|
struct SoundIoPrivate {
|
||||||
struct SoundIo pub;
|
struct SoundIo pub;
|
||||||
|
|
||||||
enum SoundIoBackend current_backend;
|
|
||||||
|
|
||||||
// Safe to read from a single thread without a mutex.
|
// Safe to read from a single thread without a mutex.
|
||||||
struct SoundIoDevicesInfo *safe_devices_info;
|
struct SoundIoDevicesInfo *safe_devices_info;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue