summaryrefslogtreecommitdiffstats
path: root/media/libcubeb/src/cubeb_jack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libcubeb/src/cubeb_jack.cpp')
-rw-r--r--media/libcubeb/src/cubeb_jack.cpp160
1 files changed, 67 insertions, 93 deletions
diff --git a/media/libcubeb/src/cubeb_jack.cpp b/media/libcubeb/src/cubeb_jack.cpp
index 1ab876c3f..8f995da66 100644
--- a/media/libcubeb/src/cubeb_jack.cpp
+++ b/media/libcubeb/src/cubeb_jack.cpp
@@ -8,20 +8,23 @@
*/
#define _DEFAULT_SOURCE
#define _BSD_SOURCE
-#ifndef __FreeBSD__
#define _POSIX_SOURCE
-#endif
+#include <algorithm>
#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>
@@ -95,9 +98,7 @@ 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);
-static int cbjack_device_collection_destroy(cubeb * context,
- cubeb_device_collection * collection);
+ 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,
@@ -120,16 +121,15 @@ 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,10 +137,7 @@ 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;
@@ -150,6 +147,7 @@ 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;
@@ -185,6 +183,7 @@ 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;
@@ -211,9 +210,6 @@ 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;
@@ -234,10 +230,9 @@ load_jack_lib(cubeb * context)
return CUBEB_OK;
}
-static int
+static void
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
@@ -247,7 +242,7 @@ cbjack_connect_ports (cubeb_stream * stream)
JackPortIsOutput
| JackPortIsPhysical);
- if (phys_in_ports == NULL || *phys_in_ports == NULL) {
+ if (*phys_in_ports == NULL) {
goto skipplayback;
}
@@ -257,10 +252,9 @@ 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 || *phys_out_ports == NULL) {
+ if (*phys_out_ports == NULL) {
goto end;
}
// Connect inputs to capture
@@ -269,15 +263,9 @@ skipplayback:
api_jack_connect (stream->context->jack_client, phys_out_ports[c], src_port);
}
- r = CUBEB_OK;
end:
- if (phys_out_ports) {
- api_jack_free(phys_out_ports);
- }
- if (phys_in_ports) {
- api_jack_free(phys_in_ports);
- }
- return r;
+ api_jack_free(phys_out_ports);
+ api_jack_free(phys_in_ports);
}
static int
@@ -438,6 +426,7 @@ 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)
{
@@ -450,6 +439,7 @@ 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,
@@ -746,12 +736,6 @@ 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.
@@ -883,11 +867,7 @@ cbjack_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_
}
}
- if (cbjack_connect_ports(stm) != CUBEB_OK) {
- pthread_mutex_unlock(&stm->mutex);
- cbjack_stream_destroy(stm);
- return CUBEB_ERROR;
- }
+ cbjack_connect_ports(stm);
*stream = stm;
@@ -960,6 +940,7 @@ 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)
{
@@ -997,77 +978,70 @@ 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);
-
- cubeb_device_info * devices = new cubeb_device_info[2];
- if (!devices)
- return CUBEB_ERROR;
- PodZero(devices, 2);
- collection->count = 0;
+ const char * j_in = "JACK capture";
+ const char * j_out = "JACK playback";
if (type & CUBEB_DEVICE_TYPE_OUTPUT) {
- 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 ;
+ 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++;
}
if (type & CUBEB_DEVICE_TYPE_INPUT) {
- 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;
+ 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++;
}
- collection->device = devices;
+ *collection = (cubeb_device_collection *)
+ malloc(sizeof(cubeb_device_collection) +
+ i * sizeof(cubeb_device_info *));
- return CUBEB_OK;
-}
+ (*collection)->count = i;
-static int
-cbjack_device_collection_destroy(cubeb * /*ctx*/,
- cubeb_device_collection * collection)
-{
- XASSERT(collection);
- delete [] collection->device;
+ for (j = 0; j < i; j++) {
+ (*collection)->device[j] = context->devinfo[j];
+ }
return CUBEB_OK;
}