[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid.changes
|
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid.spec
^
|
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/README
^
|
@@ -1,6 +1,11 @@
PulseAudio Droid modules
========================
+Building of droid modules is split to two packages
+ * common (and common-devel) which contains shared library code for use in
+ PulseAudio modules in this package and for inclusion in other projects
+ * droid with actual PulseAudio modules
+
Supported Android versions:
* 4.1.x with Qualcomm extensions (tested with 4.1.2)
@@ -9,10 +14,11 @@
* 5.1
Headers for defining devices and strings for different droid versions are in
-src/droid/droid-util-XXX.h
+src/common/droid-util-XXX.h
-These headers are then included in src/droid/droid-util.h based on detected
-droid version.
+These headers are then included in src/common/droid-util.h based on detected
+droid version. Version is defined in android-version.h, included from
+android-config.h, which is part of droid hal devel package.
The purpose of droid-modules is to "replace AudioFlinger". Many hardware
adaptations use ALSA as the kernel interface, but there is no saying that
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/configure.ac
^
|
@@ -201,7 +201,7 @@
[droiddevice=$withval], [droiddevice="generic"]
)
if test "x$droiddevice" != x ; then
- DROID_DEVICE_CFLAGS="-DDROID_DEVICE_`echo $droiddevice | tr '[a-z]' '[A-Z]'`=1"
+ DROID_DEVICE_CFLAGS="-DDROID_DEVICE_`echo $droiddevice | tr '[a-z]' '[A-Z]'`=1 -DDROID_DEVICE_STRING=\"\\\"$droiddevice\\\"\""
AC_SUBST([DROID_DEVICE_CFLAGS])
fi
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/common/Makefile.am
^
|
@@ -13,6 +13,6 @@
modlibexec_LTLIBRARIES = libdroid-util.la
libdroid_util_la_SOURCES = droid-util.c droid-util.h
-libdroid_util_la_LDFLAGS = -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
+libdroid_util_la_LDFLAGS = -avoid-version -Wl,-z,noexecstack -lhybris-common
libdroid_util_la_LIBADD = $(AM_LIBADD)
libdroid_util_la_CFLAGS = $(AM_CFLAGS)
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/common/droid-util-42.h
^
|
@@ -139,34 +139,6 @@
};
/* Input devices */
-#ifdef DROID_DEVICE_MAKO
-struct string_conversion string_conversion_table_input_device[] = {
- { 0x10000, "AUDIO_DEVICE_IN_COMMUNICATION" },
- { 0x20000, "AUDIO_DEVICE_IN_AMBIENT" },
- { 0x40000, "AUDIO_DEVICE_IN_BUILTIN_MIC" },
- { 0x80000, "AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" },
- { 0x100000, "AUDIO_DEVICE_IN_WIRED_HEADSET" },
- { 0x200000, "AUDIO_DEVICE_IN_AUX_DIGITAL" },
- { 0x400000, "AUDIO_DEVICE_IN_VOICE_CALL" },
- { 0x800000, "AUDIO_DEVICE_IN_BACK_MIC" },
- { 0x80000000, "AUDIO_DEVICE_IN_DEFAULT" },
- { 0x80000000, "AUDIO_DEVICE_IN_REMOTE_SUBMIX" }, // What's this really??
- { 0, NULL }
-};
-
-struct string_conversion string_conversion_table_input_device_fancy[] = {
- { 0x10000, "input-communication" },
- { 0x20000, "input-ambient" },
- { 0x40000, "input-builtin_mic" },
- { 0x80000, "input-bluetooth_sco_headset" },
- { 0x100000, "input-wired_headset" },
- { 0x200000, "input-aux_digital" },
- { 0x400000, "input-voice_call" },
- { 0x800000, "input-back_mic" },
- { 0x80000000, "input-remote_submix" },
- { 0, NULL }
-};
-#else
struct string_conversion string_conversion_table_input_device[] = {
STRING_ENTRY(AUDIO_DEVICE_IN_COMMUNICATION),
STRING_ENTRY(AUDIO_DEVICE_IN_AMBIENT),
@@ -206,7 +178,6 @@
{ AUDIO_DEVICE_IN_DEFAULT, "input-default" },
{ 0, NULL }
};
-#endif
struct string_conversion string_conversion_table_audio_source_fancy[] = {
{ AUDIO_SOURCE_DEFAULT, "default" },
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/common/droid-util-44.h
^
|
@@ -90,7 +90,7 @@
};
uint32_t conversion_table_default_audio_source[][2] = {
-#ifdef DROID_DEVICE_HAMMERHEAD
+#if defined(DROID_DEVICE_HAMMERHEAD) || defined(DROID_DEVICE_ARMANI) || defined(DROID_DEVICE_MAKO)
{ AUDIO_DEVICE_IN_COMMUNICATION, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_AMBIENT, AUDIO_SOURCE_MIC },
{ AUDIO_DEVICE_IN_BUILTIN_MIC, AUDIO_SOURCE_MIC },
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/common/droid-util-51.h
^
|
@@ -218,6 +218,9 @@
STRING_ENTRY(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
STRING_ENTRY(AUDIO_DEVICE_IN_LOOPBACK),
#ifdef QCOM_HARDWARE
+#ifdef DROID_AUDIO_HAL_SECONDARY_MIC
+ STRING_ENTRY(AUDIO_DEVICE_IN_SECONDARY_MIC),
+#endif
STRING_ENTRY(AUDIO_DEVICE_IN_PROXY),
STRING_ENTRY(AUDIO_DEVICE_IN_FM_RX),
STRING_ENTRY(AUDIO_DEVICE_IN_FM_RX_A2DP),
@@ -254,6 +257,9 @@
{ AUDIO_DEVICE_IN_BLUETOOTH_A2DP, "input-bluetooth_a2dp" },
{ AUDIO_DEVICE_IN_LOOPBACK, "input-loopback" },
#ifdef QCOM_HARDWARE
+#ifdef DROID_AUDIO_HAL_SECONDARY_MIC
+ { AUDIO_DEVICE_IN_SECONDARY_MIC, "input-secondary_mic" },
+#endif
{ AUDIO_DEVICE_IN_PROXY, "input-proxy" },
{ AUDIO_DEVICE_IN_FM_RX, "input-fm_rx" },
{ AUDIO_DEVICE_IN_FM_RX_A2DP, "input-fm_rx_a2dp" },
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/common/droid-util.c
^
|
@@ -54,6 +54,8 @@
#include <pulsecore/refcnt.h>
#include <pulsecore/shared.h>
#include <pulsecore/mutex.h>
+#include <pulsecore/strlist.h>
+#include <pulsecore/atomic.h>
#include "droid-util.h"
@@ -80,6 +82,9 @@
/* Section defining custom global configuration variables. */
#define GLOBAL_CONFIG_EXT_TAG "custom_properties"
+static const char * const droid_combined_auto_outputs[3] = { "primary", "low_latency", NULL };
+static const char * const droid_combined_auto_inputs[2] = { "primary", NULL };
+
static void droid_port_free(pa_droid_port *p);
static bool string_convert_num_to_str(const struct string_conversion *list, const uint32_t value, const char **to_str) {
@@ -732,21 +737,50 @@
return NULL;
}
-pa_droid_profile *pa_droid_profile_new(pa_droid_profile_set *ps, const pa_droid_config_output *output, const pa_droid_config_input *input) {
+static pa_droid_profile *profile_new(pa_droid_profile_set *ps,
+ const pa_droid_config_hw_module *module,
+ const char *name,
+ const char *description) {
pa_droid_profile *p;
pa_assert(ps);
- pa_assert(output);
+ pa_assert(module);
+ pa_assert(name);
+ pa_assert(description);
p = pa_xnew0(pa_droid_profile, 1);
p->profile_set = ps;
- p->module = output->module;
- p->name = pa_sprintf_malloc("%s%s%s", output->name, input ? "-" : "", input ? input->name : "");
- p->description = pa_sprintf_malloc("%s output%s%s%s", output->name,
- input ? " and " : "",
- input ? input->name : "",
- input ? " input." : "");
+ p->module = module;
+ p->name = pa_xstrdup(name);
+ p->description = pa_xstrdup(description);
p->priority = DEFAULT_PRIORITY;
+
+ p->output_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+ p->input_mappings = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
+ pa_hashmap_put(ps->profiles, p->name, p);
+
+ return p;
+}
+
+pa_droid_profile *pa_droid_profile_new(pa_droid_profile_set *ps, const pa_droid_config_output *output, const pa_droid_config_input *input) {
+ pa_droid_profile *p;
+ char *name;
+ char *description;
+
+ pa_assert(ps);
+ pa_assert(output);
+
+ name = pa_sprintf_malloc("%s%s%s", output->name, input ? "-" : "", input ? input->name : "");
+ description = pa_sprintf_malloc("%s output%s%s%s", output->name,
+ input ? " and " : "",
+ input ? input->name : "",
+ input ? " input." : "");
+
+ p = profile_new(ps, output->module, name, description);
+ pa_xfree(name);
+ pa_xfree(description);
+
if (pa_streq(output->name, "primary")) {
p->priority += DEFAULT_PRIORITY;
@@ -755,16 +789,24 @@
}
if (output)
- p->output = pa_droid_mapping_get(ps, PA_DIRECTION_OUTPUT, output);
+ pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, PA_DIRECTION_OUTPUT, output), NULL);
if (input)
- p->input = pa_droid_mapping_get(ps, PA_DIRECTION_INPUT, input);
-
- pa_hashmap_put(ps->profiles, p->name, p);
+ pa_idxset_put(p->input_mappings, pa_droid_mapping_get(ps, PA_DIRECTION_INPUT, input), NULL);
return p;
}
-static void add_profile(pa_droid_profile_set *ps, const pa_droid_config_output *output, const pa_droid_config_input *input) {
+void pa_droid_profile_add_mapping(pa_droid_profile *p, pa_droid_mapping *am) {
+ pa_assert(p);
+ pa_assert(am);
+
+ if (am->direction == PA_DIRECTION_OUTPUT)
+ pa_idxset_put(p->output_mappings, am, NULL);
+ else
+ pa_idxset_put(p->input_mappings, am, NULL);
+}
+
+static pa_droid_profile *add_profile(pa_droid_profile_set *ps, const pa_droid_config_output *output, const pa_droid_config_input *input) {
pa_droid_profile *ap;
pa_log_debug("New profile: %s-%s", output->name, input ? input->name : "no input");
@@ -772,9 +814,144 @@
ap = pa_droid_profile_new(ps, output, input);
pa_hashmap_put(ps->profiles, ap->name, ap);
+
+ return ap;
}
-pa_droid_profile_set *pa_droid_profile_set_new(const pa_droid_config_hw_module *module) {
+static bool str_in_strlist(const char *str, pa_strlist *list) {
+ pa_strlist *iter;
+
+ pa_assert(str);
+ pa_assert(list);
+
+ for (iter = list; iter; iter = pa_strlist_next(iter)) {
+ if (pa_streq(str, pa_strlist_data(iter)))
+ return true;
+ }
+
+ return false;
+}
+
+/* If outputs or inputs string list contain string *all* it means all
+ * outputs or inputs are added to the combined profile.
+ * If outputs or inputs string list contain string *auto* it means
+ * all devices that are in module and listed in droid_combined_auto_*
+ * are added to the combined profile. */
+static pa_droid_profile *add_combined_profile(pa_droid_profile_set *ps,
+ const pa_droid_config_hw_module *module,
+ const pa_strlist *outputs,
+ const pa_strlist *inputs) {
+ pa_droid_profile *p;
+ char *description;
+ char *o_str;
+ char *i_str;
+ pa_strlist *to_outputs = NULL;
+ pa_strlist *to_inputs = NULL;
+ pa_droid_mapping *am;
+
+ pa_assert(ps);
+ pa_assert(module);
+
+ if (outputs) {
+ if (str_in_strlist(PA_DROID_COMBINED_AUTO, outputs)) {
+ for (unsigned i = 0; droid_combined_auto_outputs[i]; i++) {
+ for (unsigned j = 0; j < module->outputs_size; j++) {
+ if (pa_streq(droid_combined_auto_outputs[i], module->outputs[j].name)) {
+ pa_log_debug("Auto add to combined profile output %s", module->outputs[j].name);
+ to_outputs = pa_strlist_prepend(to_outputs, module->outputs[j].name);
+ }
+ }
+ }
+ } else {
+ for (unsigned i = 0; i < module->outputs_size; i++) {
+ if (!str_in_strlist(PA_DROID_COMBINED_ALL, outputs) &&
+ !str_in_strlist(module->outputs[i].name, outputs))
+ continue;
+
+ to_outputs = pa_strlist_prepend(to_outputs, module->outputs[i].name);
+ }
+ }
+
+ to_outputs = pa_strlist_reverse(to_outputs);
+ }
+
+ if (inputs) {
+ if (str_in_strlist(PA_DROID_COMBINED_AUTO, inputs)) {
+ for (unsigned i = 0; droid_combined_auto_inputs[i]; i++) {
+ for (unsigned j = 0; j < module->inputs_size; j++) {
+ if (pa_streq(droid_combined_auto_inputs[i], module->inputs[j].name)) {
+ pa_log_debug("Auto add to combined profile input %s", module->inputs[j].name);
+ to_inputs = pa_strlist_prepend(to_inputs, module->inputs[j].name);
+ }
+ }
+ }
+ } else {
+ for (unsigned i = 0; i < module->inputs_size; i++) {
+ if (!str_in_strlist(PA_DROID_COMBINED_ALL, inputs) &&
+ !str_in_strlist(module->inputs[i].name, inputs))
+ continue;
+
+ to_inputs = pa_strlist_prepend(to_inputs, module->inputs[i].name);
+ }
+ }
+
+ to_inputs = pa_strlist_reverse(to_inputs);
+ }
+
+#if (PULSEAUDIO_VERSION >= 8)
+ o_str = pa_strlist_to_string(to_outputs);
+ i_str = pa_strlist_to_string(to_inputs);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/common/droid-util.h
^
|
@@ -28,6 +28,8 @@
#include <pulsecore/core-util.h>
#include <pulsecore/macro.h>
#include <pulsecore/mutex.h>
+#include <pulsecore/strlist.h>
+#include <pulsecore/atomic.h>
#include <android-config.h>
@@ -50,8 +52,16 @@
#define PROP_DROID_DEVICES "droid.devices"
#define PROP_DROID_FLAGS "droid.flags"
#define PROP_DROID_HW_MODULE "droid.hw_module"
+#define PROP_DROID_API_STRING "droid-hal"
+
+#define PA_DROID_PRIMARY_DEVICE "primary"
+
+/* Special keywords for combined profile creation. */
+#define PA_DROID_COMBINED_ALL "*all*"
+#define PA_DROID_COMBINED_AUTO "*auto*"
typedef struct pa_droid_hw_module pa_droid_hw_module;
+typedef struct pa_droid_stream pa_droid_stream;
typedef struct pa_droid_card_data pa_droid_card_data;
typedef int (*common_set_parameters_cb_t)(pa_droid_card_data *card_data, const char *str);
@@ -67,6 +77,8 @@
pa_droid_config_audio *config;
const pa_droid_config_hw_module *enabled_module;
pa_mutex *hw_mutex;
+ pa_mutex *output_mutex;
+ pa_mutex *input_mutex;
struct hw_module_t *hwmod;
audio_hw_device_t *device;
@@ -76,6 +88,24 @@
uint32_t stream_out_id;
uint32_t stream_in_id;
+ pa_idxset *outputs;
+ pa_idxset *inputs;
+
+ pa_atomic_t active_outputs;
+ uint32_t output_device;
+};
+
+struct pa_droid_stream {
+ PA_REFCNT_DECLARE;
+
+ pa_droid_hw_module *module;
+
+ pa_sample_spec sample_spec;
+ pa_channel_map channel_map;
+ uint32_t flags;
+
+ struct audio_stream_out *out;
+ struct audio_stream_in *in;
};
struct pa_droid_card_data {
@@ -184,9 +214,10 @@
char *description;
unsigned priority;
- /* Profile doesn't own the mappings */
- pa_droid_mapping *output;
- pa_droid_mapping *input;
+ /* Idxsets contain pa_droid_mapping objects.
+ * Profile doesn't own the mappings. */
+ pa_idxset *output_mappings;
+ pa_idxset *input_mappings;
} pa_droid_profile;
@@ -251,17 +282,27 @@
/* Profiles */
pa_droid_profile_set *pa_droid_profile_set_new(const pa_droid_config_hw_module *module);
+pa_droid_profile_set *pa_droid_profile_set_combined_new(const pa_droid_config_hw_module *module,
+ const pa_strlist *outputs,
+ const pa_strlist *inputs);
void pa_droid_profile_set_free(pa_droid_profile_set *ps);
pa_droid_profile *pa_droid_profile_new(pa_droid_profile_set *ps, const pa_droid_config_output *output, const pa_droid_config_input *input);
+void pa_droid_profile_add_mapping(pa_droid_profile *p, pa_droid_mapping *am);
void pa_droid_profile_free(pa_droid_profile *p);
pa_droid_mapping *pa_droid_mapping_get(pa_droid_profile_set *ps, pa_direction_t direction, const void *data);
+bool pa_droid_mapping_is_primary(pa_droid_mapping *am);
+/* Go through idxset containing pa_droid_mapping objects and if primary output or input
+ * mapping is found, return pointer to that mapping. */
+pa_droid_mapping *pa_droid_idxset_get_primary(pa_idxset *i);
void pa_droid_mapping_free(pa_droid_mapping *am);
-/* Add ports from sinks/sources */
+/* Add ports from sinks/sources.
+ * May be called multiple times for one sink/source. */
void pa_droid_add_ports(pa_hashmap *ports, pa_droid_mapping *am, pa_card *card);
-/* Add ports from card */
+/* Add ports from card.
+ * May be called multiple times for one card profile. */
void pa_droid_add_card_ports(pa_card_profile *cp, pa_hashmap *ports, pa_droid_mapping *am, pa_core *core);
/* Pretty port names */
@@ -271,4 +312,45 @@
/* Pretty audio source names */
bool pa_droid_audio_source_name(audio_source_t value, const char **to_str);
+/* Module operations */
+int pa_droid_set_parameters(pa_droid_hw_module *hw, const char *parameters);
+
+/* Stream operations */
+pa_droid_stream *pa_droid_stream_ref(pa_droid_stream *s);
+void pa_droid_stream_unref(pa_droid_stream *s);
+
+int pa_droid_stream_set_parameters(pa_droid_stream *s, const char *parameters);
+
+/* Output stream operations */
+pa_droid_stream *pa_droid_open_output_stream(pa_droid_hw_module *module,
+ const pa_sample_spec *spec,
+ const pa_channel_map *map,
+ audio_output_flags_t flags,
+ audio_devices_t devices);
+
+/* Set routing to the output stream, with following side-effects:
+ * - if routing is set to primary output stream, set routing to all other
+ * open streams as well
+ * - if routing is set to non-primary stream and primary stream exists, do nothing
+ * - if routing is set to non-primary stream and primary stream doesn't exist, set routing
+ */
+int pa_droid_stream_set_output_route(pa_droid_stream *s, audio_devices_t device);
+
+/* Input stream operations */
+pa_droid_stream *pa_droid_open_input_stream(pa_droid_hw_module *module,
+ const pa_sample_spec *spec,
+ const pa_channel_map *map,
+ audio_devices_t devices);
+int pa_droid_stream_set_input_route(pa_droid_stream *s, audio_devices_t device, audio_source_t *new_source);
+
+bool pa_droid_stream_is_primary(pa_droid_stream *s);
+
+int pa_droid_stream_suspend(pa_droid_stream *s, bool suspend);
+
+static inline int pa_droid_output_stream_any_active(pa_droid_stream *s) {
+ return pa_atomic_load(&s->module->active_outputs);
+}
+
+bool pa_sink_is_droid_sink(pa_sink *s);
+
#endif
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/droid/Makefile.am
^
|
@@ -23,31 +23,31 @@
noinst_HEADERS = module-droid-sink-symdef.h module-droid-source-symdef.h module-droid-card-symdef.h module-droid-keepalive-symdef.h
module_droid_keepalive_la_SOURCES = keepalive.c keepalive.h module-droid-keepalive.c
-module_droid_keepalive_la_LDFLAGS = -module -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack
+module_droid_keepalive_la_LDFLAGS = -module -avoid-version -Wl,-z,noexecstack
module_droid_keepalive_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS)
module_droid_keepalive_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
libdroid_sink_la_SOURCES = droid-sink.c droid-sink.h
-libdroid_sink_la_LDFLAGS = -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
+libdroid_sink_la_LDFLAGS = -avoid-version -Wl,-z,noexecstack -lhybris-common
libdroid_sink_la_LIBADD = $(AM_LIBADD) $(top_builddir)/src/common/libdroid-util.la
libdroid_sink_la_CFLAGS = $(AM_CFLAGS)
libdroid_source_la_SOURCES = droid-source.c droid-source.h
-libdroid_source_la_LDFLAGS = -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
+libdroid_source_la_LDFLAGS = -avoid-version -Wl,-z,noexecstack -lhybris-common
libdroid_source_la_LIBADD = $(AM_LIBADD) $(top_builddir)/src/common/libdroid-util.la
libdroid_source_la_CFLAGS = $(AM_CFLAGS)
module_droid_sink_la_SOURCES = module-droid-sink.c
-module_droid_sink_la_LDFLAGS = -module -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
-module_droid_sink_la_LIBADD = $(AM_LIBADD) -lm $(top_builddir)/src/common/libdroid-util.la libdroid-sink.la
+module_droid_sink_la_LDFLAGS = -module -avoid-version -Wl,-z,noexecstack -lhybris-common
+module_droid_sink_la_LIBADD = $(AM_LIBADD) -lm libdroid-sink.la
module_droid_sink_la_CFLAGS = $(AM_CFLAGS)
module_droid_source_la_SOURCES = module-droid-source.c
-module_droid_source_la_LDFLAGS = -module -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
-module_droid_source_la_LIBADD = $(AM_LIBADD) -lm $(top_builddir)/src/common/libdroid-util.la libdroid-source.la
+module_droid_source_la_LDFLAGS = -module -avoid-version -Wl,-z,noexecstack -lhybris-common
+module_droid_source_la_LIBADD = $(AM_LIBADD) -lm libdroid-source.la
module_droid_source_la_CFLAGS = $(AM_CFLAGS)
module_droid_card_la_SOURCES = module-droid-card.c
-module_droid_card_la_LDFLAGS = -module -avoid-version -Wl,-no-undefined -Wl,-z,noexecstack -lhybris-common
-module_droid_card_la_LIBADD = $(AM_LIBADD) -lm $(top_builddir)/src/common/libdroid-util.la libdroid-sink.la libdroid-source.la
+module_droid_card_la_LDFLAGS = -module -avoid-version -Wl,-z,noexecstack -lhybris-common
+module_droid_card_la_LIBADD = $(AM_LIBADD) -lm libdroid-sink.la libdroid-source.la $(top_builddir)/src/common/libdroid-util.la
module_droid_card_la_CFLAGS = $(AM_CFLAGS)
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/droid/droid-sink.c
^
|
@@ -79,6 +79,12 @@
pa_usec_t buffer_time;
pa_usec_t write_time;
pa_usec_t write_threshold;
+ audio_devices_t prewrite_devices;
+ uint32_t prewrite_silence;
+ pa_hook_slot *sink_put_hook_slot;
+ pa_hook_slot *sink_unlink_hook_slot;
+ pa_hook_slot *sink_port_changed_hook_slot;
+ pa_sink *primary_stream_sink;
audio_devices_t primary_devices;
audio_devices_t extra_devices;
@@ -98,7 +104,7 @@
pa_droid_card_data *card_data;
pa_droid_hw_module *hw_module;
- struct audio_stream_out *stream_out;
+ pa_droid_stream *stream;
};
enum {
@@ -187,29 +193,27 @@
return need_update;
}
+static void clear_extra_devices(struct userdata *u) {
+ pa_assert(u);
+ pa_assert(u->extra_devices_map);
+
+ pa_hashmap_remove_all(u->extra_devices_map);
+ u->extra_devices = 0;
+}
+
/* Called from main context during voice calls, and from IO context during media operation. */
static void do_routing(struct userdata *u) {
- int ret;
audio_devices_t routing;
- char tmp[32];
pa_assert(u);
- pa_assert(u->stream_out);
+ pa_assert(u->stream);
- routing = u->primary_devices | u->extra_devices;
+ if (u->use_voice_volume && u->extra_devices)
+ clear_extra_devices(u);
- pa_snprintf(tmp, sizeof(tmp), "%s=%u;", AUDIO_PARAMETER_STREAM_ROUTING, routing);
- pa_log_debug("set_parameters(%s) %#010x", tmp, routing);
- pa_droid_hw_module_lock(u->hw_module);
- ret = u->stream_out->common.set_parameters(&u->stream_out->common, tmp);
- pa_droid_hw_module_unlock(u->hw_module);
+ routing = u->primary_devices | u->extra_devices;
- if (ret < 0) {
- if (ret == -ENOSYS)
- pa_log_warn("set_parameters(%s) not allowed while stream is active", tmp);
- else
- pa_log_warn("set_parameters(%s) failed", tmp);
- }
+ pa_droid_stream_set_output_route(u->stream, routing);
}
static bool parse_device_list(const char *str, audio_devices_t *dst) {
@@ -251,7 +255,7 @@
* here it's okay, as long as mute time isn't configured too strictly. */
p = pa_memblock_acquire(u->silence.memblock);
- wrote = u->stream_out->write(u->stream_out, (const uint8_t*) p + u->silence.index, u->silence.length);
+ wrote = u->stream->out->write(u->stream->out, (const uint8_t*) p + u->silence.index, u->silence.length);
pa_memblock_release(u->silence.memblock);
u->write_time = pa_rtclock_now() - u->write_time;
@@ -276,7 +280,7 @@
for (;;) {
p = pa_memblock_acquire(c.memblock);
- wrote = u->stream_out->write(u->stream_out, (const uint8_t*) p + c.index, c.length);
+ wrote = u->stream->out->write(u->stream->out, (const uint8_t*) p + c.index, c.length);
pa_memblock_release(c.memblock);
if (wrote < 0) {
@@ -403,7 +407,7 @@
/* Sleep */
#if (PULSEAUDIO_VERSION == 5)
if ((ret = pa_rtpoll_run(u->rtpoll, true)) < 0)
-#elif (PULSEAUDIO_VERSION == 6)
+#elif (PULSEAUDIO_VERSION >= 6)
if ((ret = pa_rtpoll_run(u->rtpoll)) < 0)
#endif
goto fail;
@@ -429,9 +433,9 @@
pa_assert(u);
pa_assert(u->sink);
- pa_assert(u->stream_out);
+ pa_assert(u->stream->out);
- ret = u->stream_out->common.standby(&u->stream_out->common);
+ ret = pa_droid_stream_suspend(u->stream, true);
if (ret == 0) {
pa_sink_set_max_request_within_thread(u->sink, 0);
@@ -447,6 +451,8 @@
}
static int unsuspend(struct userdata *u) {
+ uint32_t i;
+
pa_assert(u);
pa_assert(u->sink);
@@ -455,6 +461,15 @@
pa_log_info("Resuming...");
+ if (u->prewrite_silence &&
+ (u->primary_devices | u->extra_devices) & u->prewrite_devices &&
+ pa_droid_output_stream_any_active(u->stream) == 0) {
+ for (i = 0; i < u->prewrite_silence; i++)
+ thread_write_silence(u);
+ }
+
+ pa_droid_stream_suspend(u->stream, false);
+
return 0;
}
@@ -476,8 +491,8 @@
pa_usec_t r = 0;
/* HAL reports milliseconds */
- if (u->stream_out)
- r = u->stream_out->get_latency(u->stream_out) * PA_USEC_PER_MSEC;
+ if (u->stream->out)
+ r = u->stream->out->get_latency(u->stream->out) * PA_USEC_PER_MSEC;
*((pa_usec_t*) data) = r;
@@ -571,7 +586,7 @@
float val = pa_sw_volume_to_linear(r.values[0]);
pa_log_debug("Set hw volume %f", val);
pa_droid_hw_module_lock(u->hw_module);
- if (u->stream_out->set_volume(u->stream_out, val, val) < 0)
+ if (u->stream->out->set_volume(u->stream->out, val, val) < 0)
pa_log_warn("Failed to set hw volume.");
pa_droid_hw_module_unlock(u->hw_module);
} else if (r.channels == 2) {
@@ -580,7 +595,7 @@
val[i] = pa_sw_volume_to_linear(r.values[i]);
pa_log_debug("Set hw volume %f : %f", val[0], val[1]);
pa_droid_hw_module_lock(u->hw_module);
- if (u->stream_out->set_volume(u->stream_out, val[0], val[1]) < 0)
+ if (u->stream->out->set_volume(u->stream->out, val[0], val[1]) < 0)
pa_log_warn("Failed to set hw volume.");
pa_droid_hw_module_unlock(u->hw_module);
}
@@ -611,16 +626,18 @@
/* set_volume returns 0 if hw volume control is implemented, < 0 otherwise. */
pa_droid_hw_module_lock(u->hw_module);
- if (u->stream_out->set_volume) {
+ if (u->stream->out->set_volume) {
pa_log_debug("Probe hw volume support for %s", u->sink->name);
- ret = u->stream_out->set_volume(u->stream_out, 1.0f, 1.0f);
+ ret = u->stream->out->set_volume(u->stream->out, 1.0f, 1.0f);
}
pa_droid_hw_module_unlock(u->hw_module);
u->use_hw_volume = (ret == 0);
- /* Apply callbacks */
- pa_droid_sink_set_voice_control(u->sink, false);
+ if (pa_droid_stream_is_primary(u->stream)) {
+ /* Apply callbacks */
+ pa_droid_sink_set_voice_control(u->sink, false);
+ }
}
static void set_sink_name(pa_modargs *ma, pa_sink_new_data *data, const char *module_id) {
@@ -707,6 +724,11 @@
pa_assert(u);
pa_assert(u->sink == sink);
+ if (!pa_droid_stream_is_primary(u->stream)) {
+ pa_log_debug("skipping voice volume control with non-primary stream");
+ return;
+ }
+
if (u->use_voice_volume == enable)
return;
@@ -857,9 +879,7 @@
pa_assert(parameter);
tmp = pa_sprintf_malloc("%s=%s;", parameter->key, parameter->value);
pa_log_debug("set_parameters(): %s", tmp);
- pa_droid_hw_module_lock(u->hw_module);
- u->stream_out->common.set_parameters(&u->stream_out->common, tmp);
- pa_droid_hw_module_unlock(u->hw_module);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/droid/droid-source.c
^
|
@@ -73,7 +73,7 @@
pa_droid_card_data *card_data;
pa_droid_hw_module *hw_module;
- audio_stream_in_t *stream;
+ pa_droid_stream *stream;
};
#define DEFAULT_MODULE_ID "primary"
@@ -85,12 +85,10 @@
static int do_routing(struct userdata *u, audio_devices_t devices, bool force) {
int ret;
- char *setparam;
- char *devlist;
pa_proplist *p;
const char *source_str;
audio_devices_t old_device;
- audio_source_t source = (uint32_t) -1;
+ audio_source_t source;
pa_assert(u);
pa_assert(u->stream);
@@ -100,46 +98,21 @@
return 0;
}
- if (u->primary_devices == devices)
- pa_log_debug("Refresh active device routing.");
+ if (u->primary_devices == devices) {
+ if (force)
+ pa_log_debug("Refresh active device routing.");
+ else
+ return 0;
+ }
old_device = u->primary_devices;
u->primary_devices = devices;
- devlist = pa_list_string_input_device(devices);
- pa_assert(devlist);
-
-#ifdef DROID_DEVICE_I9305
- devices &= ~AUDIO_DEVICE_BIT_IN;
-#endif
+ ret = pa_droid_stream_set_input_route(u->stream, devices, &source);
- if (pa_input_device_default_audio_source(devices, &source))
-#ifdef DROID_AUDIO_HAL_ATOI_FIX
- setparam = pa_sprintf_malloc("%s=%d;%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, (int32_t) devices,
- AUDIO_PARAMETER_STREAM_INPUT_SOURCE, source);
-#else
- setparam = pa_sprintf_malloc("%s=%u;%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, devices,
- AUDIO_PARAMETER_STREAM_INPUT_SOURCE, source);
-#endif
- else
- setparam = pa_sprintf_malloc("%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, devices);
-
- pa_log_debug("set_parameters(%s) %s : %#010x", setparam, devlist, devices);
-
-#if defined(DROID_DEVICE_MAKO) || defined(DROID_DEVICE_IYOKAN)
-#warning Using mako set_parameters hack.
- ret = u->card_data->set_parameters(u->card_data, setparam);
-#else
- ret = u->stream->common.set_parameters(&u->stream->common, setparam);
-#endif
-
- if (ret < 0) {
- if (ret == -ENOSYS)
- pa_log_warn("set_parameters(%s) not allowed while stream is active", setparam);
- else
- pa_log_warn("set_parameters(%s) failed", setparam);
+ if (ret < 0)
u->primary_devices = old_device;
- } else {
+ else {
if (source != (uint32_t) -1)
pa_assert_se(pa_droid_audio_source_name(source, &source_str));
else
@@ -151,9 +124,6 @@
pa_proplist_free(p);
}
- pa_xfree(devlist);
- pa_xfree(setparam);
-
return ret;
}
@@ -191,7 +161,7 @@
chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) u->buffer_size);
p = pa_memblock_acquire(chunk.memblock);
- readd = u->stream->read(u->stream, (uint8_t*) p, pa_memblock_get_length(chunk.memblock));
+ readd = u->stream->in->read(u->stream->in, (uint8_t*) p, pa_memblock_get_length(chunk.memblock));
pa_memblock_release(chunk.memblock);
if (readd < 0) {
@@ -228,7 +198,7 @@
u->timestamp = pa_rtclock_now();
- u->stream->common.standby(&u->stream->common);
+ u->stream->in->common.standby(&u->stream->in->common);
for (;;) {
int ret;
@@ -243,7 +213,7 @@
/* Sleep */
#if (PULSEAUDIO_VERSION == 5)
if ((ret = pa_rtpoll_run(u->rtpoll, true)) < 0)
-#elif (PULSEAUDIO_VERSION == 6)
+#elif (PULSEAUDIO_VERSION >= 6)
if ((ret = pa_rtpoll_run(u->rtpoll)) < 0)
#endif
goto fail;
@@ -270,7 +240,7 @@
pa_assert(u);
pa_assert(u->stream);
- ret = u->stream->common.standby(&u->stream->common);
+ ret = pa_droid_stream_suspend(u->stream, true);
if (ret == 0)
pa_log_info("Device suspended.");
@@ -279,6 +249,15 @@
}
/* Called from IO context */
+static void unsuspend(struct userdata *u) {
+ pa_assert(u);
+ pa_assert(u->stream);
+
+ pa_droid_stream_suspend(u->stream, false);
+ pa_log_info("Resuming...");
+}
+
+/* Called from IO context */
static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
struct userdata *u = PA_SOURCE(o)->userdata;
@@ -299,7 +278,7 @@
case PA_SOURCE_IDLE:
break;
case PA_SOURCE_RUNNING: {
- pa_log_info("Resuming...");
+ unsuspend(u);
u->timestamp = pa_rtclock_now();
break;
}
@@ -393,7 +372,7 @@
#if (PULSEAUDIO_VERSION == 5)
static void source_get_mute_cb(pa_source *s) {
-#elif (PULSEAUDIO_VERSION == 6)
+#elif (PULSEAUDIO_VERSION >= 6)
static int source_get_mute_cb(pa_source *s, bool *muted) {
#endif
struct userdata *u = s->userdata;
@@ -413,7 +392,7 @@
#if (PULSEAUDIO_VERSION == 5)
if (ret == 0)
s->muted = b;
-#elif (PULSEAUDIO_VERSION == 6)
+#elif (PULSEAUDIO_VERSION >= 6)
if (ret == 0)
*muted = b;
@@ -482,10 +461,6 @@
pa_droid_config_audio *config = NULL; /* Only used when source is created without card */
uint32_t source_buffer = 0;
bool voicecall_source = false;
- int ret;
-
- audio_format_t hal_audio_format = 0;
- audio_channel_mask_t hal_channel_mask = 0;
pa_assert(m);
pa_assert(ma);
@@ -576,37 +551,6 @@
}
}
- if (!pa_convert_format(sample_spec.format, CONV_FROM_PA, &hal_audio_format)) {
- pa_log("Sample spec format %u not supported.", sample_spec.format);
- goto fail;
- }
-
- for (int i = 0; i < channel_map.channels; i++) {
- audio_channel_mask_t c;
- if (!pa_convert_input_channel(channel_map.map[i], CONV_FROM_PA, &c)) {
- pa_log("Failed to convert channel map.");
- goto fail;
- }
- hal_channel_mask |= c;
- }
-
- if (voicecall_source) {
- pa_channel_map_init_mono(&channel_map);
- sample_spec.channels = 1;
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/droid/module-droid-card.c
^
|
@@ -54,6 +54,7 @@
#include <pulsecore/card.h>
#include <pulsecore/device-port.h>
#include <pulsecore/idxset.h>
+#include <pulsecore/strlist.h>
//#include <droid/hardware/audio_policy.h>
//#include <droid/system/audio_policy.h>
@@ -79,7 +80,8 @@
"deferred_volume=<synchronize software and hardware volume changes to avoid momentary jumps?> "
"config=<location for droid audio configuration> "
"voice_property_key=<proplist key searched for sink-input that should control voice call volume> "
- "voice_property_value=<proplist value for the key for voice control sink-input>"
+ "voice_property_value=<proplist value for the key for voice control sink-input> "
+ "combine=<comma separated list of outputs that should be merged to one profile. defaults to none>"
);
static const char* const valid_modargs[] = {
@@ -105,9 +107,11 @@
"deferred_volume",
"mute_routing_before",
"mute_routing_after",
+ "prewrite_on_resume",
"config",
"voice_property_key",
"voice_property_value",
+ "combine",
NULL,
};
@@ -261,11 +265,7 @@
pa_assert_se((u = card_data->userdata));
pa_assert(str);
- pa_droid_hw_module_lock(u->hw_module);
- ret = u->hw_module->device->set_parameters(u->hw_module->device, str);
- pa_droid_hw_module_unlock(u->hw_module);
-
- return ret;
+ return pa_droid_set_parameters(u->hw_module, str);
}
static void set_card_name(pa_modargs *ma, pa_card_new_data *data, const char *module_id) {
@@ -291,6 +291,9 @@
static void add_profile(struct userdata *u, pa_hashmap *h, pa_hashmap *ports, pa_droid_profile *ap) {
pa_card_profile *cp;
struct profile_data *d;
+ pa_droid_mapping *am;
+ int max_channels;
+ uint32_t idx;
pa_assert(u);
pa_assert(h);
@@ -303,14 +306,23 @@
cp->available = PA_AVAILABLE_YES;
cp->priority = ap->priority;
- cp->n_sinks = 1;
- pa_droid_add_card_ports(cp, ports, ap->output, u->core);
- cp->max_sink_channels = popcount(ap->output->output->channel_masks);
- if (ap->input) {
- pa_droid_add_card_ports(cp, ports, ap->input, u->core);
- cp->n_sources = 1;
- cp->max_source_channels = popcount(ap->input->input->channel_masks);
+ max_channels = 0;
+ PA_IDXSET_FOREACH(am, ap->output_mappings, idx) {
+ cp->n_sinks++;
+ pa_droid_add_card_ports(cp, ports, am, u->core);
+ max_channels = popcount(am->output->channel_masks) > max_channels
+ ? popcount(am->output->channel_masks) : max_channels;
+ }
+ cp->max_sink_channels = max_channels;
+
+ max_channels = 0;
+ PA_IDXSET_FOREACH(am, ap->input_mappings, idx) {
+ cp->n_sources++;
+ pa_droid_add_card_ports(cp, ports, am, u->core);
+ max_channels = popcount(am->input->channel_masks) > max_channels
+ ? popcount(am->input->channel_masks) : max_channels;
}
+ cp->max_source_channels = max_channels;
d = PA_CARD_PROFILE_DATA(cp);
d->profile = ap;
@@ -336,6 +348,7 @@
static void init_profile(struct userdata *u) {
pa_droid_mapping *am;
struct profile_data *d;
+ uint32_t idx;
pa_assert(u);
@@ -343,14 +356,16 @@
d = PA_CARD_PROFILE_DATA(u->card->active_profile);
- if (d->profile && d->profile->output) {
- am = d->profile->output;
- am->sink = pa_droid_sink_new(u->module, u->modargs, __FILE__, &u->card_data, 0, am, u->card);
+ if (d->profile && pa_idxset_size(d->profile->output_mappings) > 0) {
+ PA_IDXSET_FOREACH(am, d->profile->output_mappings, idx) {
+ am->sink = pa_droid_sink_new(u->module, u->modargs, __FILE__, &u->card_data, 0, am, u->card);
+ }
}
- if (d->profile && d->profile->input) {
- am = d->profile->input;
- am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card);
+ if (d->profile && pa_idxset_size(d->profile->input_mappings) > 0) {
+ PA_IDXSET_FOREACH(am, d->profile->input_mappings, idx) {
+ am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card);
+ }
}
}
@@ -388,27 +403,51 @@
}
static void park_profile(pa_droid_profile *dp) {
+ struct profile_data *data;
+ pa_droid_mapping *am;
+ uint32_t idx;
+
pa_assert(dp);
- if (dp->output && dp->output->sink)
- pa_sink_set_port(dp->output->sink, PA_DROID_OUTPUT_PARKING, false);
- if (dp->input && dp->input->source)
- pa_source_set_port(dp->input->source, PA_DROID_INPUT_PARKING, false);
+ /* Virtual profiles don't have output mappings. */
+ if (dp->output_mappings) {
+ PA_IDXSET_FOREACH(am, dp->output_mappings, idx) {
+ if (pa_droid_mapping_is_primary(am))
+ pa_sink_set_port(am->sink, PA_DROID_OUTPUT_PARKING, false);
+ }
+ };
+
+ /* Virtual profiles don't have input mappings. */
+ if (dp->input_mappings) {
+ PA_IDXSET_FOREACH(am, dp->input_mappings, idx) {
+ if (pa_droid_mapping_is_primary(am))
+ pa_source_set_port(am->source, PA_DROID_INPUT_PARKING, false);
+ }
+ };
}
static bool voicecall_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling) {
pa_card_profile *cp;
+ pa_droid_mapping *am_output, *am_input;
pa_assert(u);
pa_assert(p);
pa_assert(u->old_profile);
+ if (!(am_output = pa_droid_idxset_get_primary(u->old_profile->output_mappings))) {
+ pa_log("Active profile doesn't have primary output device.");
+ return false;
+ }
+
+ if (!(am_input = pa_droid_idxset_get_primary(u->old_profile->input_mappings)))
+ pa_log_warn("Active profile doesn't have primary input device.");
+
/* call mode specialities */
if (enabling) {
- pa_droid_sink_set_voice_control(u->old_profile->output->sink, true);
- if (!u->voice_source_routing)
- pa_droid_source_set_routing(u->old_profile->input->source, false);
- if (u->old_profile->input->input->devices & AUDIO_DEVICE_IN_VOICE_CALL &&
+ pa_droid_sink_set_voice_control(am_output->sink, true);
+ if (am_input && !u->voice_source_routing)
+ pa_droid_source_set_routing(am_input->source, false);
+ if (am_input && am_input->input->devices & AUDIO_DEVICE_IN_VOICE_CALL &&
(cp = pa_hashmap_get(u->card->profiles, VOICE_RECORD_PROFILE_NAME))) {
if (cp->available == PA_AVAILABLE_NO) {
pa_log_debug("Enable %s profile.", VOICE_RECORD_PROFILE_NAME);
@@ -416,10 +455,10 @@
}
}
} else {
- pa_droid_sink_set_voice_control(u->old_profile->output->sink, false);
- if (!u->voice_source_routing)
- pa_droid_source_set_routing(u->old_profile->input->source, true);
- if (u->old_profile->input->input->devices & AUDIO_DEVICE_IN_VOICE_CALL &&
+ pa_droid_sink_set_voice_control(am_output->sink, false);
+ if (am_input && !u->voice_source_routing)
+ pa_droid_source_set_routing(am_input->source, true);
+ if (am_input && am_input->input->devices & AUDIO_DEVICE_IN_VOICE_CALL &&
(cp = pa_hashmap_get(u->card->profiles, VOICE_RECORD_PROFILE_NAME))) {
if (cp->available == PA_AVAILABLE_YES) {
pa_log_debug("Disable %s profile.", VOICE_RECORD_PROFILE_NAME);
@@ -431,7 +470,8 @@
return true;
}
-#if DROID_HAL == 1
+#if (DROID_HAL == 1) || \
+ (defined(QCOM_HARDWARE) && ANDROID_VERSION_MAJOR == 5 && ANDROID_VERSION_MINOR == 1)
static bool voicecall_record_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling) {
pa_queue *source_outputs = NULL;
pa_droid_mapping *am;
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.51.tar.bz2/src/droid/module-droid-sink.c
^
|
@@ -62,6 +62,7 @@
"module_id",
"mute_routing_before",
"mute_routing_after",
+ "prewrite_on_resume",
"sink_buffer",
"deferred_volume",
"voice_property_key",
@@ -80,6 +81,8 @@
int pa__init(pa_module *m) {
pa_modargs *ma = NULL;
+ const char *flags_str;
+ audio_output_flags_t flags = 0;
pa_assert(m);
@@ -88,7 +91,14 @@
goto fail;
}
- if (!(m->userdata = pa_droid_sink_new(m, ma, __FILE__, NULL, 0, NULL, NULL)))
+ if ((flags_str = pa_modargs_get_value(ma, "flags", NULL))) {
+ if (!pa_string_convert_flag_str_to_num(flags_str, &flags)) {
+ pa_log("Failed to parse flags");
+ goto fail;
+ }
+ }
+
+ if (!(m->userdata = pa_droid_sink_new(m, ma, __FILE__, NULL, flags, NULL, NULL)))
goto fail;
pa_modargs_free(ma);
|