mirror of
https://github.com/Ryujinx/libsoundio.git
synced 2025-01-03 17:55:42 +00:00
JACK emits on_backend_shutdown event
This commit is contained in:
parent
6df84096f3
commit
eeae08e1a3
|
@ -237,6 +237,7 @@ view `coverage/index.html` in a browser.
|
||||||
0. Ability to parse PulseAudio's "front-left" "front-right" channel label strings
|
0. Ability to parse PulseAudio's "front-left" "front-right" channel label strings
|
||||||
0. When two soundio clients are talking to each other, use port names to
|
0. When two soundio clients are talking to each other, use port names to
|
||||||
negotiate channel maps.
|
negotiate channel maps.
|
||||||
|
0. JACK: implement prebuffering
|
||||||
0. why does pulseaudio microphone use up all the CPU?
|
0. why does pulseaudio microphone use up all the CPU?
|
||||||
0. merge in/out stream structures and functions?
|
0. merge in/out stream structures and functions?
|
||||||
0. implement CoreAudio (OSX) backend, get examples working
|
0. implement CoreAudio (OSX) backend, get examples working
|
||||||
|
@ -248,7 +249,11 @@ view `coverage/index.html` in a browser.
|
||||||
the microphone example.
|
the microphone example.
|
||||||
0. PulseAudio: when prebuf gets set to 0 need to pass `PA_STREAM_START_CORKED`.
|
0. PulseAudio: when prebuf gets set to 0 need to pass `PA_STREAM_START_CORKED`.
|
||||||
0. In ALSA do we need to wake up the poll when destroying the in or out stream?
|
0. In ALSA do we need to wake up the poll when destroying the in or out stream?
|
||||||
0. Create a test for clearing the playback buffer.
|
0. Verify that JACK xrun callback context is the same as process callback.
|
||||||
|
If not, might need to hav xrun callback set a flag and have process callback
|
||||||
|
call the underflow callback.
|
||||||
|
0. Detect PulseAudio server going offline and emit `on_backend_disconnect`.
|
||||||
|
0. Create a test for clearing the playback buffer and prebuffering.
|
||||||
0. Create a test for pausing and resuming input and output streams.
|
0. Create a test for pausing and resuming input and output streams.
|
||||||
0. Create a test for the latency / synchronization API.
|
0. Create a test for the latency / synchronization API.
|
||||||
- Input is an audio file and some events indexed at particular frame - when
|
- Input is an audio file and some events indexed at particular frame - when
|
||||||
|
|
157
src/jack.cpp
157
src/jack.cpp
|
@ -35,7 +35,8 @@ static void flush_events_jack(struct SoundIoPrivate *si) {
|
||||||
SoundIo *soundio = &si->pub;
|
SoundIo *soundio = &si->pub;
|
||||||
SoundIoJack *sij = &si->backend_data.jack;
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
|
||||||
bool change = false;
|
bool change_devices = false;
|
||||||
|
bool cb_shutdown = false;
|
||||||
SoundIoDevicesInfo *old_devices_info = nullptr;
|
SoundIoDevicesInfo *old_devices_info = nullptr;
|
||||||
|
|
||||||
soundio_os_mutex_lock(sij->mutex);
|
soundio_os_mutex_lock(sij->mutex);
|
||||||
|
@ -44,15 +45,22 @@ static void flush_events_jack(struct SoundIoPrivate *si) {
|
||||||
old_devices_info = si->safe_devices_info;
|
old_devices_info = si->safe_devices_info;
|
||||||
si->safe_devices_info = sij->ready_devices_info;
|
si->safe_devices_info = sij->ready_devices_info;
|
||||||
sij->ready_devices_info = nullptr;
|
sij->ready_devices_info = nullptr;
|
||||||
change = true;
|
change_devices = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sij->is_shutdown && !sij->emitted_shutdown_cb) {
|
||||||
|
sij->emitted_shutdown_cb = true;
|
||||||
|
cb_shutdown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
soundio_os_mutex_unlock(sij->mutex);
|
soundio_os_mutex_unlock(sij->mutex);
|
||||||
|
|
||||||
if (change)
|
if (change_devices)
|
||||||
soundio->on_devices_change(soundio);
|
soundio->on_devices_change(soundio);
|
||||||
|
|
||||||
soundio_destroy_devices_info(old_devices_info);
|
soundio_destroy_devices_info(old_devices_info);
|
||||||
|
|
||||||
|
if (cb_shutdown)
|
||||||
|
soundio->on_backend_disconnect(soundio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wait_events_jack(struct SoundIoPrivate *si) {
|
static void wait_events_jack(struct SoundIoPrivate *si) {
|
||||||
|
@ -96,17 +104,58 @@ static SoundIoDeviceJackPort *find_port_matching_channel(SoundIoDevice *device,
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int outstream_xrun_callback(void *arg) {
|
||||||
|
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg;
|
||||||
|
SoundIoOutStream *outstream = &os->pub;
|
||||||
|
outstream->underflow_callback(outstream);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int outstream_buffer_size_callback(jack_nframes_t nframes, void *arg) {
|
||||||
|
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg;
|
||||||
|
SoundIoOutStream *outstream = &os->pub;
|
||||||
|
SoundIo *soundio = outstream->device->soundio;
|
||||||
|
SoundIoPrivate *si = (SoundIoPrivate *)soundio;
|
||||||
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
if ((jack_nframes_t)sij->buffer_size == nframes) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int outstream_sample_rate_callback(jack_nframes_t nframes, void *arg) {
|
||||||
|
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg;
|
||||||
|
SoundIoOutStream *outstream = &os->pub;
|
||||||
|
if (nframes == (jack_nframes_t)outstream->sample_rate) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void outstream_shutdown_callback(void *arg) {
|
||||||
|
SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg;
|
||||||
|
SoundIoOutStream *outstream = &os->pub;
|
||||||
|
outstream->error_callback(outstream, SoundIoErrorStreaming);
|
||||||
|
}
|
||||||
|
|
||||||
static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) {
|
||||||
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
||||||
SoundIoOutStream *outstream = &os->pub;
|
SoundIoOutStream *outstream = &os->pub;
|
||||||
SoundIoDevice *device = outstream->device;
|
SoundIoDevice *device = outstream->device;
|
||||||
SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device;
|
SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device;
|
||||||
SoundIoDeviceJack *dj = &dev->backend_data.jack;
|
SoundIoDeviceJack *dj = &dev->backend_data.jack;
|
||||||
|
|
||||||
|
if (sij->is_shutdown)
|
||||||
|
return SoundIoErrorBackendDisconnected;
|
||||||
|
|
||||||
outstream->buffer_duration = 0.0; // TODO
|
outstream->buffer_duration = device->buffer_duration_current;
|
||||||
outstream->period_duration = 0.0; // TODO
|
outstream->period_duration = 0.0;
|
||||||
outstream->prebuf_duration = 0.0; // TODO
|
outstream->prebuf_duration = 0.0;
|
||||||
|
|
||||||
jack_status_t status;
|
jack_status_t status;
|
||||||
osj->client = jack_client_open(outstream->name, JackNoStartServer, &status);
|
osj->client = jack_client_open(outstream->name, JackNoStartServer, &status);
|
||||||
|
@ -125,7 +174,19 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea
|
||||||
outstream_destroy_jack(si, os);
|
outstream_destroy_jack(si, os);
|
||||||
return SoundIoErrorOpeningDevice;
|
return SoundIoErrorOpeningDevice;
|
||||||
}
|
}
|
||||||
// TODO register the other callbacks and emit a stream error if they're called
|
if ((err = jack_set_buffer_size_callback(osj->client, outstream_buffer_size_callback, os))) {
|
||||||
|
outstream_destroy_jack(si, os);
|
||||||
|
return SoundIoErrorOpeningDevice;
|
||||||
|
}
|
||||||
|
if ((err = jack_set_sample_rate_callback(osj->client, outstream_sample_rate_callback, os))) {
|
||||||
|
outstream_destroy_jack(si, os);
|
||||||
|
return SoundIoErrorOpeningDevice;
|
||||||
|
}
|
||||||
|
if ((err = jack_set_xrun_callback(osj->client, outstream_xrun_callback, os))) {
|
||||||
|
outstream_destroy_jack(si, os);
|
||||||
|
return SoundIoErrorOpeningDevice;
|
||||||
|
}
|
||||||
|
jack_on_shutdown(osj->client, outstream_shutdown_callback, os);
|
||||||
|
|
||||||
|
|
||||||
// register ports and map channels
|
// register ports and map channels
|
||||||
|
@ -171,9 +232,10 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea
|
||||||
static int outstream_pause_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
|
static int outstream_pause_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
|
||||||
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
SoundIoOutStreamJack *osj = &os->backend_data.jack;
|
||||||
SoundIoOutStream *outstream = &os->pub;
|
SoundIoOutStream *outstream = &os->pub;
|
||||||
// TODO SoundIoDevice *device = outstream->device;
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
// TODO SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device;
|
if (sij->is_shutdown)
|
||||||
// TODO SoundIoDeviceJack *dj = &dev->backend_data.jack;
|
return SoundIoErrorBackendDisconnected;
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
if (pause) {
|
if (pause) {
|
||||||
if ((err = jack_deactivate(osj->client)))
|
if ((err = jack_deactivate(osj->client)))
|
||||||
|
@ -227,35 +289,50 @@ static int outstream_end_write_jack(struct SoundIoPrivate *, struct SoundIoOutSt
|
||||||
}
|
}
|
||||||
|
|
||||||
static int outstream_clear_buffer_jack(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *) {
|
static int outstream_clear_buffer_jack(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *) {
|
||||||
soundio_panic("TODO clear buffer");
|
// JACK does not support `prebuf` which is the same as a `prebuf` value of 0,
|
||||||
|
// which means that clearing the buffer is always successful and does nothing.
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int instream_open_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *) {
|
|
||||||
soundio_panic("TODO open instream");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void instream_destroy_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *) {
|
static void instream_destroy_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *) {
|
||||||
soundio_panic("TODO destroy instream");
|
soundio_panic("TODO destroy instream");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int instream_start_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *) {
|
static int instream_open_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) {
|
||||||
|
//SoundIoInStream *outstream = &is->pub;
|
||||||
|
//SoundIoInStreamJack *isj = &is->backend_data.jack;
|
||||||
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
if (sij->is_shutdown) {
|
||||||
|
instream_destroy_jack(si, is);
|
||||||
|
return SoundIoErrorBackendDisconnected;
|
||||||
|
}
|
||||||
|
soundio_panic("TODO open instream");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int instream_start_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) {
|
||||||
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
if (sij->is_shutdown)
|
||||||
|
return SoundIoErrorBackendDisconnected;
|
||||||
|
|
||||||
soundio_panic("TODO start instream");
|
soundio_panic("TODO start instream");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int instream_begin_read_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *,
|
static int instream_begin_read_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is,
|
||||||
SoundIoChannelArea **out_areas, int *frame_count)
|
SoundIoChannelArea **out_areas, int *frame_count)
|
||||||
{
|
{
|
||||||
soundio_panic("TODO begin read");
|
soundio_panic("TODO begin read");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int instream_end_read_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *) {
|
static int instream_end_read_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) {
|
||||||
soundio_panic("TODO end read");
|
soundio_panic("TODO end read");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int instream_pause_jack(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *, bool pause) {
|
static int instream_pause_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) {
|
||||||
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
if (sij->is_shutdown)
|
||||||
|
return SoundIoErrorBackendDisconnected;
|
||||||
soundio_panic("TODO pause");
|
soundio_panic("TODO pause");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,6 +403,10 @@ static int refresh_devices(SoundIoPrivate *si) {
|
||||||
SoundIo *soundio = &si->pub;
|
SoundIo *soundio = &si->pub;
|
||||||
SoundIoJack *sij = &si->backend_data.jack;
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
|
||||||
|
if (sij->is_shutdown)
|
||||||
|
return SoundIoErrorBackendDisconnected;
|
||||||
|
|
||||||
|
|
||||||
SoundIoDevicesInfo *devices_info = create<SoundIoDevicesInfo>();
|
SoundIoDevicesInfo *devices_info = create<SoundIoDevicesInfo>();
|
||||||
if (!devices_info)
|
if (!devices_info)
|
||||||
return SoundIoErrorNoMem;
|
return SoundIoErrorNoMem;
|
||||||
|
@ -513,12 +594,6 @@ static int refresh_devices(SoundIoPrivate *si) {
|
||||||
return 0;
|
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) {
|
static int buffer_size_callback(jack_nframes_t nframes, void *arg) {
|
||||||
SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||||
SoundIoJack *sij = &si->backend_data.jack;
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
@ -537,12 +612,6 @@ static int sample_rate_callback(jack_nframes_t nframes, void *arg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO
|
|
||||||
static int xrun_callback(void *arg) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void port_registration_callback(jack_port_id_t port_id, int reg, void *arg) {
|
static void port_registration_callback(jack_port_id_t port_id, int reg, void *arg) {
|
||||||
SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||||
SoundIoJack *sij = &si->backend_data.jack;
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
@ -561,8 +630,13 @@ static int port_rename_calllback(jack_port_id_t port_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shutdown_callback(void *arg) {
|
static void shutdown_callback(void *arg) {
|
||||||
//SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
SoundIoPrivate *si = (SoundIoPrivate *)arg;
|
||||||
soundio_panic("TODO shutdown callback");
|
SoundIo *soundio = &si->pub;
|
||||||
|
SoundIoJack *sij = &si->backend_data.jack;
|
||||||
|
soundio_os_mutex_lock(sij->mutex);
|
||||||
|
sij->is_shutdown = true;
|
||||||
|
soundio->on_events_signal(soundio);
|
||||||
|
soundio_os_mutex_unlock(sij->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_jack(SoundIoPrivate *si) {
|
static void destroy_jack(SoundIoPrivate *si) {
|
||||||
|
@ -620,10 +694,6 @@ int soundio_jack_init(struct SoundIoPrivate *si) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int err;
|
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))) {
|
if ((err = jack_set_buffer_size_callback(sij->client, buffer_size_callback, si))) {
|
||||||
destroy_jack(si);
|
destroy_jack(si);
|
||||||
return SoundIoErrorInitAudioBackend;
|
return SoundIoErrorInitAudioBackend;
|
||||||
|
@ -632,12 +702,6 @@ int soundio_jack_init(struct SoundIoPrivate *si) {
|
||||||
destroy_jack(si);
|
destroy_jack(si);
|
||||||
return SoundIoErrorInitAudioBackend;
|
return SoundIoErrorInitAudioBackend;
|
||||||
}
|
}
|
||||||
/* TODO
|
|
||||||
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))) {
|
if ((err = jack_set_port_registration_callback(sij->client, port_registration_callback, si))) {
|
||||||
destroy_jack(si);
|
destroy_jack(si);
|
||||||
return SoundIoErrorInitAudioBackend;
|
return SoundIoErrorInitAudioBackend;
|
||||||
|
@ -648,6 +712,9 @@ int soundio_jack_init(struct SoundIoPrivate *si) {
|
||||||
}
|
}
|
||||||
jack_on_shutdown(sij->client, shutdown_callback, si);
|
jack_on_shutdown(sij->client, shutdown_callback, si);
|
||||||
|
|
||||||
|
sij->buffer_size = jack_get_buffer_size(sij->client);
|
||||||
|
sij->sample_rate = jack_get_sample_rate(sij->client);
|
||||||
|
|
||||||
if ((err = jack_activate(sij->client))) {
|
if ((err = jack_activate(sij->client))) {
|
||||||
destroy_jack(si);
|
destroy_jack(si);
|
||||||
return SoundIoErrorInitAudioBackend;
|
return SoundIoErrorInitAudioBackend;
|
||||||
|
|
|
@ -35,6 +35,8 @@ struct SoundIoJack {
|
||||||
bool initialized;
|
bool initialized;
|
||||||
int sample_rate;
|
int sample_rate;
|
||||||
int buffer_size;
|
int buffer_size;
|
||||||
|
bool is_shutdown;
|
||||||
|
bool emitted_shutdown_cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SoundIoOutStreamJackPort {
|
struct SoundIoOutStreamJackPort {
|
||||||
|
|
|
@ -59,6 +59,7 @@ const char *soundio_strerror(int error) {
|
||||||
case SoundIoErrorIncompatibleDevice: return "incompatible device";
|
case SoundIoErrorIncompatibleDevice: return "incompatible device";
|
||||||
case SoundIoErrorNoSuchClient: return "no such client";
|
case SoundIoErrorNoSuchClient: return "no such client";
|
||||||
case SoundIoErrorIncompatibleBackend: return "incompatible backend";
|
case SoundIoErrorIncompatibleBackend: return "incompatible backend";
|
||||||
|
case SoundIoErrorBackendDisconnected: return "backend disconnected";
|
||||||
}
|
}
|
||||||
soundio_panic("invalid error enum value: %d", error);
|
soundio_panic("invalid error enum value: %d", error);
|
||||||
}
|
}
|
||||||
|
@ -139,8 +140,7 @@ void soundio_destroy(struct SoundIo *soundio) {
|
||||||
destroy(si);
|
destroy(si);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void default_on_devices_change(struct SoundIo *) { }
|
static void do_nothing_cb(struct SoundIo *) { }
|
||||||
static void default_on_events_signal(struct SoundIo *) { }
|
|
||||||
static void default_msg_callback(const char *msg) { }
|
static void default_msg_callback(const char *msg) { }
|
||||||
|
|
||||||
struct SoundIo * soundio_create(void) {
|
struct SoundIo * soundio_create(void) {
|
||||||
|
@ -149,8 +149,9 @@ struct SoundIo * soundio_create(void) {
|
||||||
if (!si)
|
if (!si)
|
||||||
return NULL;
|
return NULL;
|
||||||
SoundIo *soundio = &si->pub;
|
SoundIo *soundio = &si->pub;
|
||||||
soundio->on_devices_change = default_on_devices_change;
|
soundio->on_devices_change = do_nothing_cb;
|
||||||
soundio->on_events_signal = default_on_events_signal;
|
soundio->on_backend_disconnect = do_nothing_cb;
|
||||||
|
soundio->on_events_signal = do_nothing_cb;
|
||||||
soundio->app_name = "SoundIo";
|
soundio->app_name = "SoundIo";
|
||||||
soundio->jack_info_callback = default_msg_callback;
|
soundio->jack_info_callback = default_msg_callback;
|
||||||
soundio->jack_error_callback = default_msg_callback;
|
soundio->jack_error_callback = default_msg_callback;
|
||||||
|
|
|
@ -28,6 +28,7 @@ enum SoundIoError {
|
||||||
SoundIoErrorIncompatibleDevice,
|
SoundIoErrorIncompatibleDevice,
|
||||||
SoundIoErrorNoSuchClient,
|
SoundIoErrorNoSuchClient,
|
||||||
SoundIoErrorIncompatibleBackend,
|
SoundIoErrorIncompatibleBackend,
|
||||||
|
SoundIoErrorBackendDisconnected,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SoundIoChannelId {
|
enum SoundIoChannelId {
|
||||||
|
@ -203,6 +204,12 @@ struct SoundIo {
|
||||||
// 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.
|
||||||
void (*on_devices_change)(struct SoundIo *);
|
void (*on_devices_change)(struct SoundIo *);
|
||||||
|
// Optional callback. Called when the backend disconnects. For example,
|
||||||
|
// when the JACK server shuts down. When this happens, listing devices
|
||||||
|
// and opening streams will always fail with
|
||||||
|
// SoundIoErrorBackendDisconnected. This callback is only called during a
|
||||||
|
// call to soundio_flush_events or soundio_wait_events.
|
||||||
|
void (*on_backend_disconnect)(struct SoundIo *);
|
||||||
// Optional callback. Called from an unknown thread that you should not use
|
// Optional callback. Called from an unknown thread that you should not use
|
||||||
// to call any soundio functions. You may use this to signal a condition
|
// to call any soundio functions. You may use this to signal a condition
|
||||||
// variable to wake up. Called when soundio_wait_events would be woken up.
|
// variable to wake up. Called when soundio_wait_events would be woken up.
|
||||||
|
@ -349,6 +356,9 @@ struct SoundIoOutStream {
|
||||||
// How many seconds need to be in the buffer before playback will commence.
|
// How many seconds need to be in the buffer before playback will commence.
|
||||||
// If a buffer underflow occurs, this prebuffering will be again enabled.
|
// If a buffer underflow occurs, this prebuffering will be again enabled.
|
||||||
// This value defaults to being the same as `buffer_duration`.
|
// This value defaults to being the same as `buffer_duration`.
|
||||||
|
// After you call `soundio_outstream_open` this value is replaced with the
|
||||||
|
// actual `prebuf_duration`, as near to this value as possible.
|
||||||
|
// JACK does not support prebuffering; `prebuf_duration` is effectively 0.
|
||||||
double prebuf_duration;
|
double prebuf_duration;
|
||||||
|
|
||||||
// Defaults to NULL. Put whatever you want here.
|
// Defaults to NULL. Put whatever you want here.
|
||||||
|
|
Loading…
Reference in a new issue