[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid.changes
|
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid.spec
^
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -1,10 +1,10 @@
<services>
<service name="tar_git">
- <param name="url">https://github.com/mer-hybris/pulseaudio-modules-droid.git</param>
- <param name="branch">master</param>
- <param name="revision">d53995823d335a06a25b98d9a7ecd25f06afbcea</param>
- <param name="token"/>
- <param name="debian">N</param>
- <param name="dumb">N</param>
+ <param name="url">https://github.com/mer-hybris/pulseaudio-modules-droid.git</param>
+ <param name="branch">master</param>
+ <param name="revision">e013a5b2eeeab61f1e500d4043521c521c052459</param>
+ <param name="token"/>
+ <param name="debian">N</param>
+ <param name="dumb">N</param>
</service>
-</services>
\ No newline at end of file
+</services>
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/README
^
|
@@ -13,6 +13,7 @@
* 4.4.x
* 5.x
* 6.0.x
+ * 7.x
Headers for defining devices and strings for different droid versions are in
src/common/droid-util-audio.h (legacy headers for Jolla 1 in droid-util-41qc.h).
@@ -41,13 +42,10 @@
difficult to do if interfacing directly with ALSA to replace AudioFlinger.
Also using ALSA directly would mean that the whole HAL adaptation would need to
be ported for each new device adaptation. With droid-modules this is much more
-simpler, with somewhat stable HAL (HALv2 as of now, also different vendors add
+simpler, with somewhat stable HAL (HALv3 as of now, also different vendors add
their own incompatible extensions) API. In best scenarios using droid-modules
with new device is just compiling against target.
-Android version and device specific variations should be optimally handled in
-droid-util-XXX.h files, without modifying other parts of the implementation.
-
Components
==========
@@ -63,8 +61,47 @@
config is found, configuration is read from there, otherwise from system
configuration.
-From audio_policy.conf file input and output definitions are translated to
-PulseAudio card profiles. For example configuration with
+default profile
+---------------
+
+When module-droid-card is loaded with default arguments, droid-card will try
+to create a default profile (called surprisingly "default"). The default
+profile will try to merge useful output and input streams to one profile,
+to allow use of possible low latency outputs or multiple inputs if the
+input streams are split to multiple devices.
+
+For example configuration with
+
+ audio_hw_modules {
+ primary {
+ outputs {
+ primary {}
+ deep_buffer {}
+ }
+ inputs {
+ builtin {}
+ external {}
+ }
+ }
+ other {
+ ...
+ }
+ }
+
+The default profile would contain two sinks, sink.primary and sink.deep_buffer
+and one source, source.builtin_external. Then this combined source would use
+either "builtin" or "external" input stream, depending on which one has the
+input route currently in use (for example, input-wired_headset from "external"
+and input-back_mic from "builtin" input stream).
+
+Usually this default profile is everything that is needed in normal use, and
+additional profiles created should be needed only for testing things out etc.
+
+additional profiles
+-------------------
+
+In addition to the default profile all input and output definitions are
+translated to PulseAudio card profiles. For example configuration with
audio_hw_modules {
primary {
@@ -184,6 +221,80 @@
accessory-plugin and pulseaudio-policy-enforcement module for actually making
the port switching)
+Classifying sinks and sources
+-----------------------------
+
+Certain property values are set to all active sinks and sources based on their
+functionality to ease device classification.
+
+Currently following properties are set:
+
+ * For droid sinks
+ * droid.output.primary
+ * droid.output.low_latency
+ * droid.output.media_latency
+ * droid.output.offload
+ * For droid sources
+ * droid.input.builtin
+ * droid.input.external
+
+If the property is set and with value "true", the sink or source should be
+used for the property type. If the property is not defined or contains
+value "false" it shouldn't be used for the property type.
+
+For example, we might have sink.primary and sink.low_latency with following
+properties:
+
+ * sink.primary
+ * droid.output.primary "true"
+ * droid.output.media_latency "true"
+ * sink.low_latency
+ * droid.output.low_latency "true"
+
+There also may be just one sink, with all the properties defined as "true"
+and so on.
+
+Similarly if there is only one input device the sole source would have both
+input type properties set as "true", but it also might be that the different
+input type properties are split to two different sources.
+
+Quirks
+------
+
+There are some adaptations that require hacks to get things working. These
+hacks can be enabled or disabled with module argument "quirks". Some quirks
+are enabled by default with some adaptations etc.
+
+Currently there are following quirks:
+
+ * input_atoi
+ * Enabled by default with Android versions 5 and up.
+ * Due to how atoi works in bionic vs libc we need to pass the input
+ route a bit funny. If input routing doesn't work switch this on or off.
+ * set_parameters
+ * Disabled by default.
+ * Some adaptations need to use hw module's generic set_parameters call
+ to change input routing. If input routing doesn't work switch this
+ on or off. (mostly just older adaptations)
+ * close_input
+ * Enabled by default.
+ * Close input stream when not in use instead of suspending the stream.
+ Cannot be changed when multiple inputs are merged to single source.
+ * unload_no_close
+ * Disabled by default.
+ * Don't call audio_hw_device_close() for the hw module when unloading.
+ Mostly useful for tracking module unload issues.
+ * no_hw_volume
+ * Disabled by default.
+ * Some broken implementations are incorrectly probed for supporting hw
+ volume control. This is manifested by always full volume with volume
+ control not affecting volume level. To fix this enable this quirk.
+
+For example, to disable input_atoi and enable close_input quirks, use module
+argument
+
+ quirks=-input_atoi,+close_input
+
Volume control during voicecall
-------------------------------
@@ -200,17 +311,17 @@
Temporary sink audio routing
----------------------------
-It is possible to add temporary extra route(s) to sink audio routing with
-specific stream property. When stream with property key
-droid.device.additional-route connects to droid-sink, this extra route is added
-(if possible) to the enabled routes for the duration of the stream.
+It is possible to add temporary route to sink audio routing with specific
+stream property. When stream with property key
+droid.device.additional-route connects to droid-sink, this extra route is set
+(if possible) as the enabled route for the duration of the stream.
For example, if droid-sink has active port output-wired_headphone:
paplay --property=droid.device.additional-route=AUDIO_DEVICE_OUT_SPEAKER a.wav
As long as the new stream is connected to droid-sink, output routing is
-SPEAKER+WIRED_HEADPHONE.
+SPEAKER.
module-droid-keepalive
----------------------
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/configure.ac
^
|
@@ -22,9 +22,11 @@
m4_define(pa_major, `echo $VERSION | cut -d. -f1 | cut -d- -f1`)
m4_define(pa_minor, `echo $VERSION | cut -d. -f2 | cut -d- -f1`)
+m4_define(pa_module_version, `echo $VERSION | cut -d. -f3 | cut -d- -f1`)
AC_SUBST(PA_MAJOR, pa_major)
AC_SUBST(PA_MAJORMINOR, pa_major.pa_minor)
+AC_SUBST(PA_MODULE_VERSION, pa_module_version)
DESIRED_FLAGS="-Wall -W -Wextra -pedantic -pipe -Wno-long-long -Winline -Wvla -Wno-overlength-strings -Wunsafe-loop-optimizations -Wundef -Wformat=2 -Wlogical-op -Wsign-compare -Wpacked -Wformat-security -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wpointer-arith -Winit-self -Wfloat-equal -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-declarations -Wmissing-noreturn -Wshadow -Wendif-labels -Wstrict-aliasing=2 -Wwrite-strings -Wno-unused-parameter -ffast-math -Wp,-D_FORTIFY_SOURCE=2 -fno-common -fdiagnostics-show-option" # PulseAudio 0.9.15 usess same + -Wcast-align -Wdeclaration-after-statement
@@ -250,6 +252,8 @@
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_OUT_5POINT1_BACK])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_OUT_5POINT1_SIDE])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_IN_VOICE_CALL_MONO])
+CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_IN_VOICE_UPLINK])
+CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_IN_VOICE_DNLINK])
# Formats
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_FORMAT_PCM_OFFLOAD])
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/src/common/droid-util.c
^
|
@@ -68,7 +68,9 @@
struct droid_quirk valid_quirks[] = {
{ "input_atoi", QUIRK_INPUT_ATOI },
{ "set_parameters", QUIRK_SET_PARAMETERS },
- { "close_input", QUIRK_CLOSE_INPUT }
+ { "close_input", QUIRK_CLOSE_INPUT },
+ { "unload_no_close", QUIRK_UNLOAD_NO_CLOSE },
+ { "no_hw_volume", QUIRK_NO_HW_VOLUME },
};
struct pa_droid_quirks {
@@ -393,8 +395,8 @@
return check_and_log(fn, ln, "formats", count, str, unknown, false);
}
-static int parse_channels(const char *fn, const unsigned ln,
- const char *str, bool in_output, audio_channel_mask_t *channels) {
+static bool parse_channels(const char *fn, const unsigned ln,
+ const char *str, bool in_output, audio_channel_mask_t *channels) {
int count;
char *unknown = NULL;
@@ -944,7 +946,10 @@
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) {
+static pa_droid_profile *droid_profile_new(pa_droid_profile_set *ps,
+ const pa_droid_config_output *primary_output,
+ const pa_droid_config_output *output,
+ const pa_droid_config_input *input) {
pa_droid_profile *p;
char *name;
char *description;
@@ -969,6 +974,8 @@
p->priority += DEFAULT_PRIORITY;
}
+ if (primary_output && primary_output != output)
+ pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, PA_DIRECTION_OUTPUT, primary_output), NULL);
if (output)
pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, PA_DIRECTION_OUTPUT, output), NULL);
if (input)
@@ -987,153 +994,21 @@
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) {
+static pa_droid_profile *add_profile(pa_droid_profile_set *ps,
+ const pa_droid_config_output *primary_output,
+ 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");
- ap = pa_droid_profile_new(ps, output, input);
+ ap = droid_profile_new(ps, primary_output, output, input);
pa_hashmap_put(ps->profiles, ap->name, ap);
return ap;
}
-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,
- pa_strlist *outputs,
- 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_droid_config_output *output;
- pa_droid_config_input *input;
-
- 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++) {
- SLLIST_FOREACH(output, module->outputs) {
- if (pa_streq(droid_combined_auto_outputs[i], output->name)) {
- pa_log_debug("Auto add to combined profile output %s", output->name);
- to_outputs = pa_strlist_prepend(to_outputs, output->name);
- }
- }
- }
- } else {
- SLLIST_FOREACH(output, module->outputs) {
- if (!str_in_strlist(PA_DROID_COMBINED_ALL, outputs) &&
- !str_in_strlist(output->name, outputs))
- continue;
-
- to_outputs = pa_strlist_prepend(to_outputs, output->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++) {
- SLLIST_FOREACH(input, module->inputs) {
- if (pa_streq(droid_combined_auto_inputs[i], input->name)) {
- pa_log_debug("Auto add to combined profile input %s", input->name);
- to_inputs = pa_strlist_prepend(to_inputs, input->name);
- }
- }
- }
- } else {
- SLLIST_FOREACH(input, module->inputs) {
- if (!str_in_strlist(PA_DROID_COMBINED_ALL, inputs) &&
- !str_in_strlist(input->name, inputs))
- continue;
-
- to_inputs = pa_strlist_prepend(to_inputs, input->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);
-#else
- o_str = pa_strlist_tostring(to_outputs);
- i_str = pa_strlist_tostring(to_inputs);
-#endif
-
- pa_log_debug("New combined profile: %s (outputs: %s, inputs: %s)", module->name, o_str, i_str);
-
- if (!to_outputs && !to_inputs)
- pa_log("Combined profile doesn't have any outputs or inputs!");
-
- description = pa_sprintf_malloc("Combined outputs (%s) and inputs (%s) of %s.", o_str,
- i_str,
- module->name);
- p = profile_new(ps, module, module->name, description);
- pa_xfree(description);
- pa_xfree(o_str);
- pa_xfree(i_str);
-
- if (to_outputs) {
- SLLIST_FOREACH(output, module->outputs) {
- if (!str_in_strlist(output->name, to_outputs))
- continue;
-
- am = pa_droid_mapping_get(ps, PA_DIRECTION_OUTPUT, output);
- pa_droid_profile_add_mapping(p, am);
-
- if (pa_streq(output->name, "primary"))
- p->priority += DEFAULT_PRIORITY;
- }
- }
-
- if (to_inputs) {
- SLLIST_FOREACH(input, module->inputs) {
- if (!str_in_strlist(input->name, to_inputs))
- continue;
-
- am = pa_droid_mapping_get(ps, PA_DIRECTION_INPUT, input);
- pa_droid_profile_add_mapping(p, am);
-
- if (pa_streq(input->name, "primary"))
- p->priority += DEFAULT_PRIORITY;
- }
- }
-
- pa_strlist_free(to_outputs);
- pa_strlist_free(to_inputs);
-
- return p;
-}
-
static pa_droid_profile_set *profile_set_new(const pa_droid_config_hw_module *module) {
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/src/common/droid-util.h
^
|
@@ -66,14 +66,19 @@
#define PROP_DROID_HW_MODULE "droid.hw_module"
#define PROP_DROID_API_STRING "droid-hal"
-#define PA_DROID_PRIMARY_DEVICE "primary"
+#define PROP_DROID_OUTPUT_PRIMARY "droid.output.primary"
+#define PROP_DROID_OUTPUT_LOW_LATENCY "droid.output.low_latency"
+#define PROP_DROID_OUTPUT_MEDIA_LATENCY "droid.output.media_latency"
+#define PROP_DROID_OUTPUT_OFFLOAD "droid.output.offload"
+#define PROP_DROID_INPUT_BUILTIN "droid.input.builtin"
+#define PROP_DROID_INPUT_EXTERNAL "droid.input.external"
-/* Special keywords for combined profile creation. */
-#define PA_DROID_COMBINED_ALL "*all*"
-#define PA_DROID_COMBINED_AUTO "*auto*"
+#define PA_DROID_PRIMARY_DEVICE "primary"
typedef struct pa_droid_hw_module pa_droid_hw_module;
typedef struct pa_droid_stream pa_droid_stream;
+typedef struct pa_droid_output_stream pa_droid_output_stream;
+typedef struct pa_droid_input_stream pa_droid_input_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);
@@ -111,6 +116,10 @@
pa_idxset *outputs;
pa_idxset *inputs;
+ pa_hook_slot *sink_put_hook_slot;
+ pa_hook_slot *sink_unlink_hook_slot;
+ pa_hook_slot *source_put_hook_slot;
+ pa_hook_slot *source_unlink_hook_slot;
pa_atomic_t active_outputs;
@@ -118,21 +127,35 @@
pa_hook hooks[PA_DROID_HOOK_MAX];
};
-struct pa_droid_stream {
- PA_REFCNT_DECLARE;
-
- pa_droid_hw_module *module;
+struct pa_droid_output_stream {
+ struct audio_stream_out *stream;
+ pa_sample_spec sample_spec;
+ pa_channel_map channel_map;
+ uint32_t flags;
+ uint32_t device;
+};
+struct pa_droid_input_stream {
+ struct audio_stream_in *stream;
pa_sample_spec sample_spec;
pa_channel_map channel_map;
pa_sample_spec input_sample_spec;
pa_channel_map input_channel_map;
uint32_t flags;
uint32_t device;
+ audio_devices_t all_devices;
+ bool merged;
+};
+
+struct pa_droid_stream {
+ PA_REFCNT_DECLARE;
+
+ pa_droid_hw_module *module;
size_t buffer_size;
+ void *data;
- struct audio_stream_out *out;
- struct audio_stream_in *in;
+ pa_droid_output_stream *output;
+ pa_droid_input_stream *input;
};
struct pa_droid_card_data {
@@ -220,6 +243,7 @@
const pa_droid_config_output *output;
const pa_droid_config_input *input;
+ const pa_droid_config_input *input2;
char *name;
char *description;
@@ -267,6 +291,8 @@
QUIRK_INPUT_ATOI,
QUIRK_SET_PARAMETERS,
QUIRK_CLOSE_INPUT,
+ QUIRK_UNLOAD_NO_CLOSE,
+ QUIRK_NO_HW_VOLUME,
QUIRK_COUNT
};
@@ -323,20 +349,22 @@
/* 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,
- pa_strlist *outputs,
- pa_strlist *inputs);
+pa_droid_profile_set *pa_droid_profile_set_default_new(const pa_droid_config_hw_module *module,
+ bool merge_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);
+pa_droid_mapping *pa_droid_mapping_merged_get(pa_droid_profile_set *ps,
+ const pa_droid_config_input *input1,
+ const pa_droid_config_input *input2);
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);
+pa_droid_mapping *pa_droid_idxset_mapping_with_device(pa_idxset *i, uint32_t flag);
void pa_droid_mapping_free(pa_droid_mapping *am);
/* Add ports from sinks/sources.
@@ -386,27 +414,32 @@
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);
+ audio_devices_t devices,
+ pa_droid_mapping *am);
bool pa_droid_stream_is_primary(pa_droid_stream *s);
int pa_droid_stream_suspend(pa_droid_stream *s, bool suspend);
size_t pa_droid_stream_buffer_size(pa_droid_stream *s);
+pa_usec_t pa_droid_stream_get_latency(pa_droid_stream *s);
static inline int pa_droid_output_stream_any_active(pa_droid_stream *s) {
return pa_atomic_load(&s->module->active_outputs);
}
static inline ssize_t pa_droid_stream_write(pa_droid_stream *stream, const void *buffer, size_t bytes) {
- return stream->out->write(stream->out, buffer, bytes);
+ return stream->output->stream->write(stream->output->stream, buffer, bytes);
}
static inline ssize_t pa_droid_stream_read(pa_droid_stream *stream, void *buffer, size_t bytes) {
- return stream->in->read(stream->in, buffer, bytes);
+ return stream->input->stream->read(stream->input->stream, buffer, bytes);
}
-bool pa_sink_is_droid_sink(pa_sink *s);
+void pa_droid_stream_set_data(pa_droid_stream *s, void *data);
+void *pa_droid_stream_get_data(pa_droid_stream *s);
+bool pa_sink_is_droid_sink(pa_sink *sink);
+bool pa_source_is_droid_source(pa_source *source);
/* Misc */
size_t pa_droid_buffer_size_round_up(size_t buffer_size, size_t block_size);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/src/common/libdroid-util.pc.in
^
|
@@ -6,6 +6,6 @@
Name: libdroid-util
Description: Common droid module building interface.
-Version: @PACKAGE_VERSION@
+Version: @PA_MODULE_VERSION@
Libs: -L${libdir}/pulse-@PA_MAJORMINOR@/modules -ldroid-util
Cflags: -D_REENTRANT -I${includedir}/pulsecore/modules
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/src/droid/Makefile.am
^
|
@@ -29,25 +29,25 @@
libdroid_sink_la_SOURCES = droid-sink.c droid-sink.h
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_LIBADD = $(top_builddir)/src/common/libdroid-util.la $(AM_LIBADD)
libdroid_sink_la_CFLAGS = $(AM_CFLAGS)
libdroid_source_la_SOURCES = droid-source.c droid-source.h
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_LIBADD = $(top_builddir)/src/common/libdroid-util.la $(AM_LIBADD)
libdroid_source_la_CFLAGS = $(AM_CFLAGS)
module_droid_sink_la_SOURCES = module-droid-sink.c
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_LIBADD = -lm libdroid-sink.la $(AM_LIBADD)
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,-z,noexecstack -lhybris-common
-module_droid_source_la_LIBADD = $(AM_LIBADD) -lm libdroid-source.la
+module_droid_source_la_LIBADD = -lm libdroid-source.la $(AM_LIBADD)
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,-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_LIBADD = -lm libdroid-sink.la libdroid-source.la $(top_builddir)/src/common/libdroid-util.la $(AM_LIBADD)
module_droid_card_la_CFLAGS = $(AM_CFLAGS)
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/src/droid/droid-sink.c
^
|
@@ -67,9 +67,6 @@
pa_thread *thread;
pa_thread_mq thread_mq;
pa_rtpoll *rtpoll;
- int32_t routing_counter;
- int32_t mute_routing_before;
- int32_t mute_routing_after;
bool deferred_volume; /* TODO */
@@ -89,13 +86,14 @@
audio_devices_t primary_devices;
audio_devices_t extra_devices;
pa_hashmap *extra_devices_map;
+ bool mix_route;
bool use_hw_volume;
bool use_voice_volume;
char *voice_property_key;
char *voice_property_value;
pa_sink_input *voice_control_sink_input;
- pa_subscription *sink_input_subscription;
+ pa_hook_slot *sink_input_volume_changed_hook_slot;
pa_hook_slot *sink_input_put_hook_slot;
pa_hook_slot *sink_input_unlink_hook_slot;
@@ -107,10 +105,6 @@
pa_droid_stream *stream;
};
-enum {
- SINK_MESSAGE_DO_ROUTING = PA_SINK_MESSAGE_MAX,
-};
-
#define DEFAULT_MODULE_ID "primary"
/* sink properties */
@@ -211,7 +205,10 @@
if (u->use_voice_volume && u->extra_devices)
clear_extra_devices(u);
- routing = u->primary_devices | u->extra_devices;
+ if (!u->mix_route && u->extra_devices)
+ routing = u->extra_devices;
+ else
+ routing = u->primary_devices | u->extra_devices;
pa_droid_stream_set_route(u->stream, routing);
}
@@ -254,8 +251,8 @@
* is multiples of buffer_size. Even if we don't write whole buffer size
* here it's okay, as long as mute time isn't configured too strictly. */
- p = pa_memblock_acquire(u->silence.memblock);
- wrote = pa_droid_stream_write(u->stream, (const uint8_t *) p + u->silence.index, u->silence.length);
+ p = pa_memblock_acquire_chunk(&u->silence);
+ wrote = pa_droid_stream_write(u->stream, p, u->silence.length);
pa_memblock_release(u->silence.memblock);
u->write_time = pa_rtclock_now() - u->write_time;
@@ -279,8 +276,8 @@
u->write_time = pa_rtclock_now();
for (;;) {
- p = pa_memblock_acquire(c.memblock);
- wrote = pa_droid_stream_write(u->stream, (const uint8_t *) p + c.index, c.length);
+ p = pa_memblock_acquire_chunk(&c);
+ wrote = pa_droid_stream_write(u->stream, p, c.length);
pa_memblock_release(c.memblock);
if (wrote < 0) {
@@ -386,15 +383,7 @@
pa_usec_t sleept = 0;
thread_render(u);
-
- if (u->routing_counter == u->mute_routing_after) {
- do_routing(u);
- u->routing_counter--;
- } else if (u->routing_counter > -1) {
- thread_write_silence(u);
- u->routing_counter--;
- } else
- thread_write(u);
+ thread_write(u);
if (u->write_time > u->write_threshold)
sleept = u->buffer_time;
@@ -433,7 +422,6 @@
pa_assert(u);
pa_assert(u->sink);
- pa_assert(u->stream->out);
ret = pa_droid_stream_suspend(u->stream, true);
@@ -478,24 +466,9 @@
struct userdata *u = PA_SINK(o)->userdata;
switch (code) {
- case SINK_MESSAGE_DO_ROUTING: {
- /* When mute_routing_before & mute_routing_after are 0, routing change is done
- * immediately when next round in thread_func. Otherwise write silence until
- * counter equals mute_routing_after, execute routing, and write silence until
- * routing_counter is 0. */
- u->routing_counter = u->mute_routing_before + u->mute_routing_after;
- return 0;
- }
case PA_SINK_MESSAGE_GET_LATENCY: {
- 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;
-
- *((pa_usec_t*) data) = r;
-
+ *((pa_usec_t*) data) = pa_droid_stream_get_latency(u->stream);
return 0;
}
@@ -564,13 +537,7 @@
pa_log_debug("Sink set port %u", data->device);
set_primary_devices(u, data->device);
- /* If we are in voice call, sink is usually in suspended state and routing change can be applied immediately.
- * When in media use cases, do the routing change in IO thread if we are currently in RUNNING or IDLE state. */
- if (u->use_voice_volume || !PA_SINK_IS_OPENED(pa_sink_get_state(u->sink)))
- do_routing(u);
- else {
- pa_asyncmsgq_post(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_DO_ROUTING, NULL, 0, NULL, NULL);
- }
+ do_routing(u);
return 0;
}
@@ -584,18 +551,18 @@
if (r.channels == 1) {
float val = pa_sw_volume_to_linear(r.values[0]);
- pa_log_debug("Set hw volume %f", val);
+ pa_log_debug("Set %s hw volume %f", s->name, val);
pa_droid_hw_module_lock(u->hw_module);
- if (u->stream->out->set_volume(u->stream->out, val, val) < 0)
+ if (u->stream->output->stream->set_volume(u->stream->output->stream, val, val) < 0)
pa_log_warn("Failed to set hw volume.");
pa_droid_hw_module_unlock(u->hw_module);
} else if (r.channels == 2) {
float val[2];
for (unsigned i = 0; i < 2; i++)
val[i] = pa_sw_volume_to_linear(r.values[i]);
- pa_log_debug("Set hw volume %f : %f", val[0], val[1]);
+ pa_log_debug("Set %s hw volume %f : %f", s->name, 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->output->stream->set_volume(u->stream->output->stream, val[0], val[1]) < 0)
pa_log_warn("Failed to set hw volume.");
pa_droid_hw_module_unlock(u->hw_module);
}
@@ -626,18 +593,27 @@
/* 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) {
- 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);
+ if (u->stream->output->stream->set_volume) {
+ ret = u->stream->output->stream->set_volume(u->stream->output->stream, 1.0f, 1.0f);
+ pa_log_debug("Probe hw volume support for %s (ret %d)", u->sink->name, ret);
}
pa_droid_hw_module_unlock(u->hw_module);
u->use_hw_volume = (ret == 0);
-
- if (pa_droid_stream_is_primary(u->stream)) {
- /* Apply callbacks */
- pa_droid_sink_set_voice_control(u->sink, false);
+ if (u->use_hw_volume &&
+#if defined(HAVE_ENUM_AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
+ !(u->stream->output->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
+#endif
+ pa_droid_quirk(u->hw_module, QUIRK_NO_HW_VOLUME)) {
+ pa_log_info("Forcing software volume control with %s", u->sink->name);
+ u->use_hw_volume = false;
+ } else {
+ pa_log_debug("Using %s volume control with %s",
+ u->use_hw_volume ? "hardware" : "software", u->sink->name);
}
+
+ if (u->use_hw_volume)
+ pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
}
static void set_sink_name(pa_modargs *ma, pa_sink_new_data *data, const char *module_id) {
@@ -661,9 +637,22 @@
}
}
+static bool sink_input_is_voice_control(struct userdata *u, pa_sink_input *si) {
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/src/droid/droid-source.c
^
|
@@ -432,11 +432,11 @@
pa_log_info("Using buffer size %u.", u->buffer_size);
if (pa_thread_mq_get())
- pa_source_set_fixed_latency_within_thread(u->source, pa_bytes_to_usec(u->buffer_size, &u->stream->sample_spec));
+ pa_source_set_fixed_latency_within_thread(u->source, pa_bytes_to_usec(u->buffer_size, &u->stream->input->sample_spec));
else
- pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, &u->stream->sample_spec));
+ pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, &u->stream->input->sample_spec));
- pa_log_debug("Set fixed latency %" PRIu64 " usec", pa_bytes_to_usec(u->buffer_size, &u->stream->sample_spec));
+ pa_log_debug("Set fixed latency %" PRIu64 " usec", pa_bytes_to_usec(u->buffer_size, &u->stream->input->sample_spec));
}
/* Called from IO context. */
@@ -466,12 +466,12 @@
if (stream != u->stream)
return PA_HOOK_OK;
- if (u->stream->input_channel_map.channels != u->source->channel_map.channels) {
+ if (u->stream->input->input_channel_map.channels != u->source->channel_map.channels) {
if (u->resampler)
pa_resampler_free(u->resampler);
u->resampler = pa_resampler_new(u->core->mempool,
- &u->stream->input_sample_spec, &u->stream->input_channel_map,
+ &u->stream->input->input_sample_spec, &u->stream->input->input_channel_map,
&u->source->sample_spec, &u->source->channel_map,
u->core->lfe_crossover_freq,
PA_RESAMPLER_COPY,
@@ -607,7 +607,10 @@
}
}
- u->stream = pa_droid_open_input_stream(u->hw_module, &sample_spec, &channel_map, dev_in);
+ if (am)
+ u->stream = pa_droid_open_input_stream(u->hw_module, &sample_spec, &channel_map, dev_in, am);
+ else
+ u->stream = pa_droid_open_input_stream(u->hw_module, &sample_spec, &channel_map, dev_in, NULL);
if (!u->stream) {
pa_log("Failed to open input stream.");
@@ -620,7 +623,13 @@
data.card = card;
data.suspend_cause = PA_SUSPEND_IDLE;
- source_set_name(ma, &data, module_id);
+ if (am)
+ source_set_name(ma, &data, am->name);
+ else
+ source_set_name(ma, &data, module_id);
+
+ pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
+ pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, PROP_DROID_API_STRING);
/* We need to give pa_modargs_get_value_boolean() a pointer to a local
* variable instead of using &data.namereg_fail directly, because
@@ -634,8 +643,8 @@
}
data.namereg_fail = namereg_fail;
- pa_source_new_data_set_sample_spec(&data, &u->stream->sample_spec);
- pa_source_new_data_set_channel_map(&data, &u->stream->channel_map);
+ pa_source_new_data_set_sample_spec(&data, &u->stream->input->sample_spec);
+ pa_source_new_data_set_channel_map(&data, &u->stream->input->channel_map);
pa_source_new_data_set_alternate_sample_rate(&data, alternate_sample_rate);
if (am && card)
@@ -684,6 +693,7 @@
PA_HOOK_NORMAL,
(pa_hook_cb_t) input_channel_map_changed_cb, u);
+ pa_droid_stream_set_data(u->stream, u->source);
pa_source_put(u->source);
return u->source;
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/src/droid/keepalive.c
^
|
@@ -53,6 +53,7 @@
struct pa_droid_keepalive {
pa_core *core;
pa_dbus_connection *dbus_connection;
+ DBusPendingCall *pending;
pa_atomic_t started;
pa_usec_t timeout;
@@ -131,7 +132,9 @@
pa_assert(pending);
pa_assert(k);
+ pa_assert(pending == k->pending);
+ k->pending = NULL;
pa_assert_se(msg = dbus_pending_call_steal_reply(pending));
if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_ERROR) {
@@ -143,7 +146,7 @@
DBUS_TYPE_INT32, &period,
DBUS_TYPE_INVALID));
- k->timeout = PA_USEC_PER_SEC * (period - 5);
+ k->timeout = PA_USEC_PER_SEC * period;
keepalive_start(k);
@@ -153,7 +156,6 @@
}
void pa_droid_keepalive_start(pa_droid_keepalive *k) {
- DBusPendingCall *pending = NULL;
DBusMessage *msg = NULL;
pa_assert(k);
@@ -163,6 +165,7 @@
return;
pa_assert(!k->timer_event);
+ pa_assert(!k->pending);
/* Period time already requested, just start hearbeat. */
if (k->timeout > 0) {
@@ -179,10 +182,13 @@
MCE_DBUS_IFACE,
MCE_DBUS_KEEPALIVE_PERIOD_REQ)));
- dbus_connection_send_with_reply(pa_dbus_connection_get(k->dbus_connection), msg, &pending, -1);
+ dbus_connection_send_with_reply(pa_dbus_connection_get(k->dbus_connection), msg, &k->pending, -1);
dbus_message_unref(msg);
- dbus_pending_call_set_notify(pending, pending_req_reply_cb, k, NULL);
+ if (k->pending)
+ dbus_pending_call_set_notify(k->pending, pending_req_reply_cb, k, NULL);
+ else
+ pa_log("D-Bus method call failed.");
}
void pa_droid_keepalive_stop(pa_droid_keepalive *k) {
@@ -196,12 +202,18 @@
pa_assert(pa_atomic_load(&k->started) == 0);
- if (!k->timer_event)
- return;
-
pa_log_debug("Stopping keepalive.");
- k->core->mainloop->time_free(k->timer_event);
- k->timer_event = NULL;
+
+ if (k->pending) {
+ dbus_pending_call_cancel(k->pending);
+ dbus_pending_call_unref(k->pending);
+ k->pending = NULL;
+ }
+
+ if (k->timer_event) {
+ k->core->mainloop->time_free(k->timer_event);
+ k->timer_event = NULL;
+ }
pa_assert_se((msg = dbus_message_new_method_call(MCE_DBUS_NAME,
MCE_DBUS_PATH,
@@ -218,6 +230,14 @@
pa_assert(pa_atomic_load(&k->started) == 0);
+ if (k->timer_event)
+ k->core->mainloop->time_free(k->timer_event);
+
+ if (k->pending) {
+ dbus_pending_call_cancel(k->pending);
+ dbus_pending_call_unref(k->pending);
+ }
+
pa_dbus_connection_unref(k->dbus_connection);
pa_xfree(k);
}
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/src/droid/module-droid-card.c
^
|
@@ -81,7 +81,8 @@
"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> "
- "combine=<comma separated list of outputs that should be merged to one profile. defaults to none> "
+ "default_profile=<boolean. create default profile for primary module or not. defaults to true> "
+ "merge_inputs=<boolean. merge input streams to single source with default profile. defaults to true> "
"quirks=<comma separated list of quirks to enable/disable>"
);
@@ -97,6 +98,7 @@
"sink_rate",
"sink_format",
"sink_channel_map",
+ "sink_mix_route",
"source_rate",
"source_format",
"source_channel_map",
@@ -112,6 +114,7 @@
"config",
"voice_property_key",
"voice_property_value",
+ "default_profile",
"combine",
"quirks",
NULL,
@@ -207,6 +210,7 @@
struct profile_data *d;
cp = pa_card_profile_new("off", _("Off"), sizeof(struct profile_data));
+ cp->available = PA_AVAILABLE_YES;
d = PA_CARD_PROFILE_DATA(cp);
d->profile = NULL;
@@ -424,8 +428,8 @@
}
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_card_profile *cp = NULL;
+ pa_droid_mapping *am_output;
pa_assert(u);
pa_assert(p);
@@ -436,27 +440,22 @@
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.");
+ if (pa_droid_idxset_mapping_with_device(u->old_profile->input_mappings,
+ AUDIO_DEVICE_IN_VOICE_CALL))
+ cp = pa_hashmap_get(u->card->profiles, VOICE_RECORD_PROFILE_NAME);
/* call mode specialities */
if (enabling) {
pa_droid_sink_set_voice_control(am_output->sink, 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_NO) {
- pa_log_debug("Enable %s profile.", VOICE_RECORD_PROFILE_NAME);
- pa_card_profile_set_available(cp, PA_AVAILABLE_YES);
- }
+ if (cp && cp->available == PA_AVAILABLE_NO) {
+ pa_log_debug("Enable " VOICE_RECORD_PROFILE_NAME " profile.");
+ pa_card_profile_set_available(cp, PA_AVAILABLE_YES);
}
} else {
pa_droid_sink_set_voice_control(am_output->sink, 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_YES) {
- pa_log_debug("Disable %s profile.", VOICE_RECORD_PROFILE_NAME);
- pa_card_profile_set_available(cp, PA_AVAILABLE_NO);
- }
+ if (cp && cp->available == PA_AVAILABLE_YES) {
+ pa_log_debug("Disable " VOICE_RECORD_PROFILE_NAME " profile.");
+ pa_card_profile_set_available(cp, PA_AVAILABLE_NO);
}
}
@@ -542,6 +541,7 @@
pa_droid_mapping *am;
struct profile_data *nd, *od;
pa_queue *sink_inputs = NULL, *source_outputs = NULL;
+ pa_sink *primary_sink = NULL;
uint32_t idx;
pa_assert(c);
@@ -611,8 +611,12 @@
continue;
if (nd->profile &&
- pa_idxset_get_by_data(nd->profile->output_mappings, am, NULL))
+ pa_idxset_get_by_data(nd->profile->output_mappings, am, NULL)) {
+
+ if (pa_droid_mapping_is_primary(am))
+ primary_sink = am->sink;
continue;
+ }
sink_inputs = pa_sink_move_all_start(am->sink, sink_inputs);
pa_droid_sink_free(am->sink);
@@ -659,6 +663,13 @@
}
}
+ /* if only primary sink is left after profile change and we have detached sink-inputs attach
+ * them to primary sink. */
+ if (sink_inputs && primary_sink) {
+ pa_sink_move_all_finish(primary_sink, sink_inputs, false);
+ sink_inputs = NULL;
+ }
+
if (sink_inputs)
pa_sink_move_all_fail(sink_inputs);
@@ -670,13 +681,15 @@
int pa__init(pa_module *m) {
+ struct userdata *u = NULL;
pa_modargs *ma = NULL;
pa_card_new_data data;
pa_droid_config_audio *config = NULL;
const char *module_id;
bool namereg_fail = false;
pa_card_profile *virtual;
- const char *combine;
+ bool default_profile = true;
+ bool merge_inputs = true;
const char *quirks;
pa_assert(m);
@@ -686,9 +699,17 @@
goto fail;
}
- combine = pa_modargs_get_value(ma, "combine", NULL);
+ if (pa_modargs_get_value_boolean(ma, "default_profile", &default_profile) < 0) {
+ pa_log("Failed to parse default_profile argument. Expects boolean value");
+ goto fail;
+ }
+
+ if (pa_modargs_get_value_boolean(ma, "merge_inputs", &merge_inputs) < 0) {
+ pa_log("Failed to parse merge_inputs argument. Expects boolean value");
+ goto fail;
+ }
- struct userdata *u = pa_xnew0(struct userdata, 1);
+ u = pa_xnew0(struct userdata, 1);
u->core = m->core;
m->userdata = u;
@@ -714,41 +735,10 @@
u->card_data.module_id = pa_xstrdup(module_id);
u->card_data.userdata = u;
- if (combine) {
- pa_strlist *o = NULL;
- pa_strlist *i = NULL;
-
- if (pa_streq(combine, PA_DROID_COMBINED_AUTO)) {
- o = pa_strlist_parse(PA_DROID_COMBINED_AUTO);
- i = pa_strlist_parse(PA_DROID_COMBINED_AUTO);
- } else {
- char *tmp, *d;
- const char *inputs = NULL;
- const char *outputs = NULL;
-
- tmp = pa_replace(combine, ",", " ");
-
- outputs = tmp;
- if ((d = strstr(tmp, ":"))) {
- d[0] = '\0';
- inputs = d + 1;
- }
-
- if (outputs)
- o = pa_strlist_parse(outputs);
-
- if (inputs)
- i = pa_strlist_parse(inputs);
-
- pa_xfree(tmp);
- }
-
- u->profile_set = pa_droid_profile_set_combined_new(u->hw_module->enabled_module, o, i);
-
- pa_strlist_free(o);
- pa_strlist_free(i);
- } else
+ if (!default_profile || !pa_streq(module_id, DEFAULT_MODULE_ID))
u->profile_set = pa_droid_profile_set_new(u->hw_module->enabled_module);
+ else
+ u->profile_set = pa_droid_profile_set_default_new(u->hw_module->enabled_module, merge_inputs);
pa_card_new_data_init(&data);
data.driver = __FILE__;
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-8.0.65.tar.bz2/src/droid/module-droid-sink.c
^
|
@@ -56,6 +56,7 @@
"sink_rate",
"sink_format",
"sink_channel_map",
+ "sink_mix_route",
"flags",
"output_devices",
"sink_name",
|