Skip to content

Commit

Permalink
Merge pull request mozilla#67 from achronop/device-notification
Browse files Browse the repository at this point in the history
Device notification for PulseAudio
  • Loading branch information
kinetiknz committed Jan 26, 2016
2 parents 2d8fc93 + 07d6558 commit 72949db
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 14 deletions.
4 changes: 4 additions & 0 deletions src/cubeb-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ struct cubeb_ops {
cubeb_device * device);
int (* stream_register_device_changed_callback)(cubeb_stream * stream,
cubeb_device_changed_callback device_changed_callback);
int (* register_device_collection_changed)(cubeb * context,
cubeb_device_type devtype,
cubeb_device_collection_changed_callback callback,
void * user_ptr);
};

#define XASSERT(expr) do { \
Expand Down
9 changes: 7 additions & 2 deletions src/cubeb.c
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,13 @@ int cubeb_register_device_collection_changed(cubeb * context,
cubeb_device_collection_changed_callback callback,
void * user_ptr)
{
if ((devtype & (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT)) == 0)
if (context == NULL || (devtype & (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT)) == 0)
return CUBEB_ERROR_INVALID_PARAMETER;
return CUBEB_ERROR_NOT_SUPPORTED;

if (!context->ops->register_device_collection_changed) {
return CUBEB_ERROR_NOT_SUPPORTED;
}

return context->ops->register_device_collection_changed(context, devtype, callback, user_ptr);
}

3 changes: 2 additions & 1 deletion src/cubeb_alsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -1138,5 +1138,6 @@ static struct cubeb_ops const alsa_ops = {
.stream_set_panning = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL
.stream_register_device_changed_callback = NULL,
.register_device_collection_changed = NULL
};
3 changes: 2 additions & 1 deletion src/cubeb_audiotrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,5 +436,6 @@ static struct cubeb_ops const audiotrack_ops = {
.stream_set_panning = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL
.stream_register_device_changed_callback = NULL,
.register_device_collection_changed = NULL
};
3 changes: 2 additions & 1 deletion src/cubeb_audiounit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1317,5 +1317,6 @@ static struct cubeb_ops const audiounit_ops = {
.stream_set_panning = audiounit_stream_set_panning,
.stream_get_current_device = audiounit_stream_get_current_device,
.stream_device_destroy = audiounit_stream_device_destroy,
.stream_register_device_changed_callback = audiounit_stream_register_device_changed_callback
.stream_register_device_changed_callback = audiounit_stream_register_device_changed_callback,
.register_device_collection_changed = NULL
};
3 changes: 2 additions & 1 deletion src/cubeb_jack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ static struct cubeb_ops const cbjack_ops = {
.stream_set_panning = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL
.stream_register_device_changed_callback = NULL,
.register_device_collection_changed = NULL
};

struct cubeb_stream {
Expand Down
3 changes: 2 additions & 1 deletion src/cubeb_kai.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,5 +341,6 @@ static struct cubeb_ops const kai_ops = {
/*.stream_set_panning =*/ NULL,
/*.stream_get_current_device =*/ NULL,
/*.stream_device_destroy =*/ NULL,
/*.stream_register_device_changed_callback=*/ NULL
/*.stream_register_device_changed_callback=*/ NULL,
/*.register_device_collection_changed=*/ NULL
};
3 changes: 2 additions & 1 deletion src/cubeb_opensl.c
Original file line number Diff line number Diff line change
Expand Up @@ -838,5 +838,6 @@ static struct cubeb_ops const opensl_ops = {
.stream_set_panning = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL
.stream_register_device_changed_callback = NULL,
.register_device_collection_changed = NULL
};
112 changes: 109 additions & 3 deletions src/cubeb_pulse.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@
X(pa_stream_peek) \
X(pa_stream_drop) \
X(pa_stream_get_buffer_attr) \
X(pa_stream_get_device_name) \
X(pa_context_set_subscribe_callback) \
X(pa_context_subscribe) \

#define MAKE_TYPEDEF(x) static typeof(x) * cubeb_##x;
LIBPULSE_API_VISIT(MAKE_TYPEDEF);
Expand All @@ -101,6 +104,8 @@ struct cubeb {
pa_sink_info * default_sink_info;
char * context_name;
int error;
cubeb_device_collection_changed_callback collection_changed_callback;
void * collection_changed_user_ptr;
};

struct cubeb_stream {
Expand Down Expand Up @@ -1174,6 +1179,106 @@ pulse_enumerate_devices(cubeb * context, cubeb_device_type type,
return CUBEB_OK;
}

int pulse_stream_get_current_device(cubeb_stream * stm, cubeb_device ** const device)
{
#if PA_CHECK_VERSION(0, 9, 8)
*device = calloc(1, sizeof(cubeb_device));
if (*device == NULL)
return CUBEB_ERROR;

if (stm->input_stream) {
const char * name = WRAP(pa_stream_get_device_name)(stm->input_stream);
(*device)->input_name = (name == NULL) ? NULL : strdup(name);
}

if (stm->output_stream) {
const char * name = WRAP(pa_stream_get_device_name)(stm->output_stream);
(*device)->output_name = (name == NULL) ? NULL : strdup(name);
}

return CUBEB_OK;
#else
return CUBEB_ERROR_NOT_SUPPORTED;
#endif
}

int pulse_stream_device_destroy(cubeb_stream * stream,
cubeb_device * device)
{
free(device->input_name);
free(device->output_name);
free(device);
return CUBEB_OK;
}

void pulse_subscribe_callback(pa_context * ctx,
pa_subscription_event_type_t t,
uint32_t index, void * userdata)
{
cubeb * context = userdata;

switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
case PA_SUBSCRIPTION_EVENT_SOURCE:
case PA_SUBSCRIPTION_EVENT_SINK:

#ifdef LOGGING_ENABLED
if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE &&
(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
LOG("Removing sink index %d\n", index);
else if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE &&
(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
LOG("Adding sink index %d\n", index);
if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK &&
(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE)
LOG("Removing source index %d\n", index);
else if ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK &&
(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW)
LOG("Adding source index %d\n", index);
#endif

if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE ||
(t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
context->collection_changed_callback(context, context->collection_changed_user_ptr);
}
break;
}
}

int pulse_register_device_collection_changed(cubeb * context,
cubeb_device_type devtype,
cubeb_device_collection_changed_callback collection_changed_callback,
void * user_ptr)
{
context->collection_changed_callback = collection_changed_callback;
context->collection_changed_user_ptr = user_ptr;

pa_subscription_mask_t mask;
if (context->collection_changed_callback == NULL) {
// Unregister subscription
WRAP(pa_context_set_subscribe_callback)(context->context, NULL, NULL);
mask = PA_SUBSCRIPTION_MASK_NULL;
} else {
WRAP(pa_context_set_subscribe_callback)(context->context, pulse_subscribe_callback, context);
if (devtype == CUBEB_DEVICE_TYPE_INPUT)
mask = PA_SUBSCRIPTION_MASK_SOURCE;
else if (devtype == CUBEB_DEVICE_TYPE_OUTPUT)
mask = PA_SUBSCRIPTION_MASK_SINK;
else
mask = PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE;
}

pa_operation * o;
o = WRAP(pa_context_subscribe)(context->context, mask, NULL, NULL);
if (o == NULL) {
LOG("Context subscribe failed\n");
return CUBEB_ERROR;
}
operation_wait(context, NULL, o);
WRAP(pa_operation_unref)(o);

return CUBEB_OK;
}

static struct cubeb_ops const pulse_ops = {
.init = pulse_init,
.get_backend_id = pulse_get_backend_id,
Expand All @@ -1190,7 +1295,8 @@ static struct cubeb_ops const pulse_ops = {
.stream_get_latency = pulse_stream_get_latency,
.stream_set_volume = pulse_stream_set_volume,
.stream_set_panning = pulse_stream_set_panning,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL
.stream_get_current_device = pulse_stream_get_current_device,
.stream_device_destroy = pulse_stream_device_destroy,
.stream_register_device_changed_callback = NULL,
.register_device_collection_changed = pulse_register_device_collection_changed
};
3 changes: 2 additions & 1 deletion src/cubeb_sndio.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,5 +378,6 @@ static struct cubeb_ops const sndio_ops = {
.stream_set_panning = NULL,
.stream_get_current_device = NULL,
.stream_device_destroy = NULL,
.stream_register_device_changed_callback = NULL
.stream_register_device_changed_callback = NULL,
.register_device_collection_changed = NULL
};
3 changes: 2 additions & 1 deletion src/cubeb_wasapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1718,6 +1718,7 @@ cubeb_ops const wasapi_ops = {
/*.stream_set_panning =*/ NULL,
/*.stream_get_current_device =*/ NULL,
/*.stream_device_destroy =*/ NULL,
/*.stream_register_device_changed_callback =*/ NULL
/*.stream_register_device_changed_callback =*/ NULL,
/*.register_device_collection_changed =*/ NULL
};
} // namespace anonymous
3 changes: 2 additions & 1 deletion src/cubeb_winmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1023,5 +1023,6 @@ static struct cubeb_ops const winmm_ops = {
/*.stream_set_panning =*/ NULL,
/*.stream_get_current_device =*/ NULL,
/*.stream_device_destroy =*/ NULL,
/*.stream_register_device_changed_callback=*/ NULL
/*.stream_register_device_changed_callback=*/ NULL,
/*.register_device_collection_changed =*/ NULL
};

0 comments on commit 72949db

Please sign in to comment.