diff --git a/README.md b/README.md index 7734ceb..99ffd97 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ exposed. **This library is a work-in-progress.** -## Features +## Features and Limitations * Supported backends: - [PulseAudio](http://www.freedesktop.org/wiki/Software/PulseAudio/) diff --git a/src/jack.cpp b/src/jack.cpp index 48db9b5..95686ce 100644 --- a/src/jack.cpp +++ b/src/jack.cpp @@ -7,10 +7,13 @@ #include "jack.hpp" #include "soundio.hpp" +#include "atomics.hpp" #include #include +static atomic_flag global_msg_callback_flag = ATOMIC_FLAG_INIT; + struct SoundIoJack { jack_client_t *client; }; @@ -96,16 +99,17 @@ static void destroy_jack(SoundIoPrivate *si) { si->backend_data = nullptr; } -static void error_callback(const char *msg) { - //fprintf(stderr, "JACK error: %s\n", msg); -} - -static void info_callback(const char *msg) { - //fprintf(stderr, "JACK info: %s\n", msg); -} - int soundio_jack_init(struct SoundIoPrivate *si) { 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(); + } + assert(!si->backend_data); SoundIoJack *sij = create(); if (!sij) { @@ -114,9 +118,6 @@ int soundio_jack_init(struct SoundIoPrivate *si) { } si->backend_data = sij; - jack_set_error_function(error_callback); - jack_set_info_function(info_callback); - jack_status_t status; sij->client = jack_client_open(soundio->app_name, JackNoStartServer, &status); if (!sij->client) { diff --git a/src/soundio.cpp b/src/soundio.cpp index d97229b..f49a0a4 100644 --- a/src/soundio.cpp +++ b/src/soundio.cpp @@ -154,6 +154,7 @@ void soundio_destroy(struct SoundIo *soundio) { static void default_on_devices_change(struct SoundIo *) { } static void default_on_events_signal(struct SoundIo *) { } +static void default_msg_callback(const char *msg) { } struct SoundIo * soundio_create(void) { soundio_os_init(); @@ -164,6 +165,8 @@ struct SoundIo * soundio_create(void) { soundio->on_devices_change = default_on_devices_change; soundio->on_events_signal = default_on_events_signal; soundio->app_name = "SoundIo"; + soundio->jack_info_callback = default_msg_callback; + soundio->jack_error_callback = default_msg_callback; return soundio; } diff --git a/src/soundio.h b/src/soundio.h index 6291ba3..399302a 100644 --- a/src/soundio.h +++ b/src/soundio.h @@ -212,6 +212,13 @@ struct SoundIo { // PulseAudio uses this for "application name". // JACK uses this for `client_name`. const char *app_name; + + // Optional: JACK info and error callbacks. + // By default, libsoundio sets these to empty functions in order to + // silence stdio messages from JACK. You may override the behavior by + // setting these to `NULL` or providing your own function. + void (*jack_info_callback)(const char *msg); + void (*jack_error_callback)(const char *msg); }; // The size of this struct is not part of the API or ABI. @@ -426,11 +433,10 @@ struct SoundIo * soundio_create(void); void soundio_destroy(struct SoundIo *soundio); -// Provided these backends were compiled in, this tries JACK, then PulseAudio, -// then ALSA, then CoreAudio, then ASIO, then DirectSound, then OSS, then Dummy. +// This is a convenience function you could implement yourself if you wanted +// to. It tries `soundio_connect_backend` on all available backends in order. int soundio_connect(struct SoundIo *soundio); // Instead of calling `soundio_connect` you may call this function to try a -// specific backend. int soundio_connect_backend(struct SoundIo *soundio, enum SoundIoBackend backend); void soundio_disconnect(struct SoundIo *soundio);