diff options
Diffstat (limited to 'media/libcubeb/src/cubeb_jack.cpp')
-rw-r--r-- | media/libcubeb/src/cubeb_jack.cpp | 160 |
1 files changed, 93 insertions, 67 deletions
diff --git a/media/libcubeb/src/cubeb_jack.cpp b/media/libcubeb/src/cubeb_jack.cpp index 8f995da66..1ab876c3f 100644 --- a/media/libcubeb/src/cubeb_jack.cpp +++ b/media/libcubeb/src/cubeb_jack.cpp @@ -8,23 +8,20 @@ */ #define _DEFAULT_SOURCE #define _BSD_SOURCE +#ifndef __FreeBSD__ #define _POSIX_SOURCE -#include <algorithm> +#endif #include <dlfcn.h> -#include <limits> #include <stdio.h> -#include <sys/time.h> -#include <assert.h> #include <string.h> #include <limits.h> -#include <poll.h> -#include <unistd.h> #include <stdlib.h> #include <pthread.h> #include <math.h> #include "cubeb/cubeb.h" #include "cubeb-internal.h" #include "cubeb_resampler.h" +#include "cubeb_utils.h" #include <jack/jack.h> #include <jack/statistics.h> @@ -98,7 +95,9 @@ static int cbjack_stream_device_destroy(cubeb_stream * stream, cubeb_device * device); static int cbjack_stream_get_current_device(cubeb_stream * stm, cubeb_device ** const device); static int cbjack_enumerate_devices(cubeb * context, cubeb_device_type type, - cubeb_device_collection ** collection); + cubeb_device_collection * collection); +static int cbjack_device_collection_destroy(cubeb * context, + cubeb_device_collection * collection); static int cbjack_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_name, cubeb_devid input_device, cubeb_stream_params * input_stream_params, @@ -121,15 +120,16 @@ static struct cubeb_ops const cbjack_ops = { .get_min_latency = cbjack_get_min_latency, .get_preferred_sample_rate = cbjack_get_preferred_sample_rate, .enumerate_devices = cbjack_enumerate_devices, + .device_collection_destroy = cbjack_device_collection_destroy, .destroy = cbjack_destroy, .stream_init = cbjack_stream_init, .stream_destroy = cbjack_stream_destroy, .stream_start = cbjack_stream_start, .stream_stop = cbjack_stream_stop, + .stream_reset_default_device = NULL, .stream_get_position = cbjack_stream_get_position, .stream_get_latency = cbjack_get_latency, .stream_set_volume = cbjack_stream_set_volume, - .stream_set_panning = NULL, .stream_get_current_device = cbjack_stream_get_current_device, .stream_device_destroy = cbjack_stream_device_destroy, .stream_register_device_changed_callback = NULL, @@ -137,7 +137,10 @@ static struct cubeb_ops const cbjack_ops = { }; struct cubeb_stream { + /* Note: Must match cubeb_stream layout in cubeb.c. */ cubeb * context; + void * user_ptr; + /**/ /**< Mutex for each stream */ pthread_mutex_t mutex; @@ -147,7 +150,6 @@ struct cubeb_stream { cubeb_data_callback data_callback; cubeb_state_callback state_callback; - void * user_ptr; cubeb_stream_params in_params; cubeb_stream_params out_params; @@ -183,7 +185,6 @@ struct cubeb { cubeb_stream streams[MAX_STREAMS]; unsigned int active_streams; - cubeb_device_info * devinfo[2]; cubeb_device_collection_changed_callback collection_changed_callback; bool active; @@ -210,6 +211,9 @@ load_jack_lib(cubeb * context) # endif #else context->libjack = dlopen("libjack.so.0", RTLD_LAZY); + if (!context->libjack) { + context->libjack = dlopen("libjack.so", RTLD_LAZY); + } #endif if (!context->libjack) { return CUBEB_ERROR; @@ -230,9 +234,10 @@ load_jack_lib(cubeb * context) return CUBEB_OK; } -static void +static int cbjack_connect_ports (cubeb_stream * stream) { + int r = CUBEB_ERROR; const char ** phys_in_ports = api_jack_get_ports (stream->context->jack_client, NULL, NULL, JackPortIsInput @@ -242,7 +247,7 @@ cbjack_connect_ports (cubeb_stream * stream) JackPortIsOutput | JackPortIsPhysical); - if (*phys_in_ports == NULL) { + if (phys_in_ports == NULL || *phys_in_ports == NULL) { goto skipplayback; } @@ -252,9 +257,10 @@ cbjack_connect_ports (cubeb_stream * stream) api_jack_connect (stream->context->jack_client, src_port, phys_in_ports[c]); } + r = CUBEB_OK; skipplayback: - if (*phys_out_ports == NULL) { + if (phys_out_ports == NULL || *phys_out_ports == NULL) { goto end; } // Connect inputs to capture @@ -263,9 +269,15 @@ skipplayback: api_jack_connect (stream->context->jack_client, phys_out_ports[c], src_port); } + r = CUBEB_OK; end: - api_jack_free(phys_out_ports); - api_jack_free(phys_in_ports); + if (phys_out_ports) { + api_jack_free(phys_out_ports); + } + if (phys_in_ports) { + api_jack_free(phys_in_ports); + } + return r; } static int @@ -426,7 +438,6 @@ cbjack_process(jack_nframes_t nframes, void * arg) return 0; } - static void cbjack_deinterleave_playback_refill_float(cubeb_stream * stream, float ** in, float ** bufs_out, jack_nframes_t nframes) { @@ -439,7 +450,6 @@ cbjack_deinterleave_playback_refill_float(cubeb_stream * stream, float ** in, fl long done_frames = 0; long input_frames_count = (in != NULL) ? nframes : 0; - done_frames = cubeb_resampler_fill(stream->resampler, inptr, &input_frames_count, @@ -736,6 +746,12 @@ cbjack_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_ if (input_device || output_device) return CUBEB_ERROR_NOT_SUPPORTED; + // Loopback is unsupported + if ((input_stream_params && (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK)) || + (output_stream_params && (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK))) { + return CUBEB_ERROR_NOT_SUPPORTED; + } + *stream = NULL; // Find a free stream. @@ -867,7 +883,11 @@ cbjack_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_ } } - cbjack_connect_ports(stm); + if (cbjack_connect_ports(stm) != CUBEB_OK) { + pthread_mutex_unlock(&stm->mutex); + cbjack_stream_destroy(stm); + return CUBEB_ERROR; + } *stream = stm; @@ -940,7 +960,6 @@ cbjack_stream_set_volume(cubeb_stream * stm, float volume) return CUBEB_OK; } - static int cbjack_stream_get_current_device(cubeb_stream * stm, cubeb_device ** const device) { @@ -978,70 +997,77 @@ cbjack_stream_device_destroy(cubeb_stream * /*stream*/, return CUBEB_OK; } +#define JACK_DEFAULT_IN "JACK capture" +#define JACK_DEFAULT_OUT "JACK playback" + static int cbjack_enumerate_devices(cubeb * context, cubeb_device_type type, - cubeb_device_collection ** collection) + cubeb_device_collection * collection) { if (!context) return CUBEB_ERROR; uint32_t rate; - uint8_t i = 0; - uint8_t j; cbjack_get_preferred_sample_rate(context, &rate); - const char * j_in = "JACK capture"; - const char * j_out = "JACK playback"; + + cubeb_device_info * devices = new cubeb_device_info[2]; + if (!devices) + return CUBEB_ERROR; + PodZero(devices, 2); + collection->count = 0; if (type & CUBEB_DEVICE_TYPE_OUTPUT) { - context->devinfo[i] = (cubeb_device_info *)malloc(sizeof(cubeb_device_info)); - context->devinfo[i]->device_id = strdup(j_out); - context->devinfo[i]->devid = context->devinfo[i]->device_id; - context->devinfo[i]->friendly_name = strdup(j_out); - context->devinfo[i]->group_id = strdup(j_out); - context->devinfo[i]->vendor_name = strdup(j_out); - context->devinfo[i]->type = CUBEB_DEVICE_TYPE_OUTPUT; - context->devinfo[i]->state = CUBEB_DEVICE_STATE_ENABLED; - context->devinfo[i]->preferred = CUBEB_DEVICE_PREF_ALL; - context->devinfo[i]->format = CUBEB_DEVICE_FMT_F32NE; - context->devinfo[i]->default_format = CUBEB_DEVICE_FMT_F32NE; - context->devinfo[i]->max_channels = MAX_CHANNELS; - context->devinfo[i]->min_rate = rate; - context->devinfo[i]->max_rate = rate; - context->devinfo[i]->default_rate = rate; - context->devinfo[i]->latency_lo = 0; - context->devinfo[i]->latency_hi = 0; - i++; + cubeb_device_info * cur = &devices[collection->count]; + cur->device_id = JACK_DEFAULT_OUT; + cur->devid = (cubeb_devid) cur->device_id; + cur->friendly_name = JACK_DEFAULT_OUT; + cur->group_id = JACK_DEFAULT_OUT; + cur->vendor_name = JACK_DEFAULT_OUT; + cur->type = CUBEB_DEVICE_TYPE_OUTPUT; + cur->state = CUBEB_DEVICE_STATE_ENABLED; + cur->preferred = CUBEB_DEVICE_PREF_ALL; + cur->format = CUBEB_DEVICE_FMT_F32NE; + cur->default_format = CUBEB_DEVICE_FMT_F32NE; + cur->max_channels = MAX_CHANNELS; + cur->min_rate = rate; + cur->max_rate = rate; + cur->default_rate = rate; + cur->latency_lo = 0; + cur->latency_hi = 0; + collection->count +=1 ; } if (type & CUBEB_DEVICE_TYPE_INPUT) { - context->devinfo[i] = (cubeb_device_info *)malloc(sizeof(cubeb_device_info)); - context->devinfo[i]->device_id = strdup(j_in); - context->devinfo[i]->devid = context->devinfo[i]->device_id; - context->devinfo[i]->friendly_name = strdup(j_in); - context->devinfo[i]->group_id = strdup(j_in); - context->devinfo[i]->vendor_name = strdup(j_in); - context->devinfo[i]->type = CUBEB_DEVICE_TYPE_INPUT; - context->devinfo[i]->state = CUBEB_DEVICE_STATE_ENABLED; - context->devinfo[i]->preferred = CUBEB_DEVICE_PREF_ALL; - context->devinfo[i]->format = CUBEB_DEVICE_FMT_F32NE; - context->devinfo[i]->default_format = CUBEB_DEVICE_FMT_F32NE; - context->devinfo[i]->max_channels = MAX_CHANNELS; - context->devinfo[i]->min_rate = rate; - context->devinfo[i]->max_rate = rate; - context->devinfo[i]->default_rate = rate; - context->devinfo[i]->latency_lo = 0; - context->devinfo[i]->latency_hi = 0; - i++; + cubeb_device_info * cur = &devices[collection->count]; + cur->device_id = JACK_DEFAULT_IN; + cur->devid = (cubeb_devid) cur->device_id; + cur->friendly_name = JACK_DEFAULT_IN; + cur->group_id = JACK_DEFAULT_IN; + cur->vendor_name = JACK_DEFAULT_IN; + cur->type = CUBEB_DEVICE_TYPE_INPUT; + cur->state = CUBEB_DEVICE_STATE_ENABLED; + cur->preferred = CUBEB_DEVICE_PREF_ALL; + cur->format = CUBEB_DEVICE_FMT_F32NE; + cur->default_format = CUBEB_DEVICE_FMT_F32NE; + cur->max_channels = MAX_CHANNELS; + cur->min_rate = rate; + cur->max_rate = rate; + cur->default_rate = rate; + cur->latency_lo = 0; + cur->latency_hi = 0; + collection->count += 1; } - *collection = (cubeb_device_collection *) - malloc(sizeof(cubeb_device_collection) + - i * sizeof(cubeb_device_info *)); + collection->device = devices; - (*collection)->count = i; + return CUBEB_OK; +} - for (j = 0; j < i; j++) { - (*collection)->device[j] = context->devinfo[j]; - } +static int +cbjack_device_collection_destroy(cubeb * /*ctx*/, + cubeb_device_collection * collection) +{ + XASSERT(collection); + delete [] collection->device; return CUBEB_OK; } |