[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid.changes
|
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid.spec
^
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -2,7 +2,7 @@
<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">12.2.78</param>
+ <param name="revision">HEAD</param>
<param name="token"/>
<param name="debian"/>
<param name="dumb"/>
|
[-]
[+]
|
Deleted |
_service:tar_git:pulseaudio-modules-droid-12.2.78.tar.bz2/src/droid/keepalive.c
^
|
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2013-2018 Jolla Ltd.
- *
- * Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
- *
- * These PulseAudio Modules are free software; you can redistribute
- * it and/or modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation
- * version 2.1 of the License.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
- * USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <signal.h>
-#include <stdio.h>
-
-#ifdef HAVE_VALGRIND_MEMCHECK_H
-#include <valgrind/memcheck.h>
-#endif
-
-#include <pulse/rtclock.h>
-#include <pulse/timeval.h>
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/core.h>
-#include <pulsecore/core-error.h>
-#include <pulsecore/dbus-shared.h>
-#include <pulsecore/dbus-util.h>
-#include <pulsecore/atomic.h>
-
-#include "keepalive.h"
-
-#define MCE_BUS (DBUS_BUS_SYSTEM)
-#define MCE_DBUS_NAME "com.nokia.mce"
-#define MCE_DBUS_PATH "/com/nokia/mce/request"
-#define MCE_DBUS_IFACE "com.nokia.mce.request"
-#define MCE_DBUS_KEEPALIVE_PERIOD_REQ "req_cpu_keepalive_period"
-#define MCE_DBUS_KEEPALIVE_START_REQ "req_cpu_keepalive_start"
-#define MCE_DBUS_KEEPALIVE_STOP_REQ "req_cpu_keepalive_stop"
-
-struct pa_droid_keepalive {
- pa_core *core;
- pa_dbus_connection *dbus_connection;
- DBusPendingCall *pending;
-
- pa_atomic_t started;
- pa_usec_t timeout;
- pa_time_event *timer_event;
-
-};
-
-pa_droid_keepalive* pa_droid_keepalive_new(pa_core *c) {
- pa_droid_keepalive *k;
- pa_dbus_connection *dbus;
- DBusError error;
-
- pa_assert(c);
-
- dbus_error_init(&error);
-
- dbus = pa_dbus_bus_get(c, MCE_BUS, &error);
- if (dbus_error_is_set(&error)) {
- pa_log("Failed to get %s bus: %s", MCE_BUS == DBUS_BUS_SESSION ? "session" : "system", error.message);
- dbus_error_free(&error);
- return NULL;
- }
-
- k = pa_xnew0(pa_droid_keepalive, 1);
- k->core = c;
- k->dbus_connection = dbus;
- k->timeout = 0;
- pa_atomic_store(&k->started, 0);
-
- return k;
-}
-
-static void send_dbus_signal(pa_dbus_connection *dbus) {
- DBusMessage *msg;
-
- pa_assert(dbus);
-
- /* pa_log_debug("Send keepalive heartbeat."); */
-
- pa_assert_se((msg = dbus_message_new_method_call(MCE_DBUS_NAME,
- MCE_DBUS_PATH,
- MCE_DBUS_IFACE,
- MCE_DBUS_KEEPALIVE_START_REQ)));
-
- dbus_connection_send(pa_dbus_connection_get(dbus), msg, NULL);
- dbus_message_unref(msg);
-}
-
-static void keepalive_cb(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {
- pa_droid_keepalive *k = userdata;
-
- pa_assert(k);
- pa_assert(k->timer_event == e);
-
- send_dbus_signal(k->dbus_connection);
- pa_core_rttime_restart(k->core, k->timer_event, pa_rtclock_now() + k->timeout);
-}
-
-static void keepalive_start(pa_droid_keepalive *k) {
- pa_assert(k);
- pa_assert(k->timeout);
- pa_assert(!k->timer_event);
-
- pa_log_info("Start keepalive heartbeat with interval %lu seconds.", (unsigned long) (k->timeout / PA_USEC_PER_SEC));
-
- /* Send first keepalive heartbeat immediately. */
- send_dbus_signal(k->dbus_connection);
-
- k->timer_event = pa_core_rttime_new(k->core, pa_rtclock_now() + k->timeout, keepalive_cb, k);
-}
-
-static void pending_req_reply_cb(DBusPendingCall *pending, void *userdata) {
- pa_droid_keepalive *k = userdata;
- DBusMessage *msg;
- uint32_t period;
-
- 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) {
- pa_log("Failed to get %s", MCE_DBUS_KEEPALIVE_PERIOD_REQ);
- goto finish;
- }
-
- pa_assert_se(dbus_message_get_args(msg, NULL,
- DBUS_TYPE_INT32, &period,
- DBUS_TYPE_INVALID));
-
- k->timeout = PA_USEC_PER_SEC * period;
-
- keepalive_start(k);
-
-finish:
- dbus_message_unref(msg);
- dbus_pending_call_unref(pending);
-}
-
-void pa_droid_keepalive_start(pa_droid_keepalive *k) {
- DBusMessage *msg = NULL;
-
- pa_assert(k);
-
- /* Only allow first call go through. pa_atomic_inc() returns previous value before incrementing. */
- if (pa_atomic_inc(&k->started) > 0)
- return;
-
- pa_assert(!k->timer_event);
- pa_assert(!k->pending);
-
- /* Period time already requested, just start hearbeat. */
- if (k->timeout > 0) {
- keepalive_start(k);
- return;
- }
-
- pa_log_debug("Starting keepalive - Request keepalive period.");
- /* Send first keepalive heartbeat immediately. */
- send_dbus_signal(k->dbus_connection);
-
- pa_assert_se((msg = dbus_message_new_method_call(MCE_DBUS_NAME,
- MCE_DBUS_PATH,
- MCE_DBUS_IFACE,
- MCE_DBUS_KEEPALIVE_PERIOD_REQ)));
-
- dbus_connection_send_with_reply(pa_dbus_connection_get(k->dbus_connection), msg, &k->pending, -1);
- dbus_message_unref(msg);
-
- 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) {
- DBusMessage *msg;
-
- pa_assert(k);
-
- /* Only allow last call go through. pa_atomic_dec() returns previous value before decrementing. */
- if (pa_atomic_dec(&k->started) != 1)
- return;
-
- pa_assert(pa_atomic_load(&k->started) == 0);
-
- pa_log_debug("Stopping keepalive.");
-
- 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,
- MCE_DBUS_IFACE,
- MCE_DBUS_KEEPALIVE_STOP_REQ)));
-
- dbus_connection_send(pa_dbus_connection_get(k->dbus_connection), msg, NULL);
- dbus_message_unref(msg);
-}
-
-void pa_droid_keepalive_free(pa_droid_keepalive *k) {
- pa_assert(k);
- pa_assert(k->dbus_connection);
-
- 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);
-}
|
[-]
[+]
|
Deleted |
_service:tar_git:pulseaudio-modules-droid-12.2.78.tar.bz2/src/droid/keepalive.h
^
|
@@ -1,44 +0,0 @@
-#ifndef foodroidkeepalivefoo
-#define foodroidkeepalivefoo
-
-/*
- * Copyright (C) 2013-2018 Jolla Ltd.
- *
- * Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
- *
- * These PulseAudio Modules are free software; you can redistribute
- * it and/or modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation
- * version 2.1 of the License.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
- * USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <pulsecore/core.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/dbus-shared.h>
-#include <pulsecore/atomic.h>
-
-typedef struct pa_droid_keepalive pa_droid_keepalive;
-
-pa_droid_keepalive* pa_droid_keepalive_new(pa_core *c);
-void pa_droid_keepalive_free(pa_droid_keepalive *k);
-
-void pa_droid_keepalive_start(pa_droid_keepalive *k);
-void pa_droid_keepalive_stop(pa_droid_keepalive *k);
-
-
-#endif
|
[-]
[+]
|
Deleted |
_service:tar_git:pulseaudio-modules-droid-12.2.78.tar.bz2/src/droid/module-droid-keepalive-symdef.h
^
|
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2013-2018 Jolla Ltd.
- *
- * Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
- *
- * These PulseAudio Modules are free software; you can redistribute
- * it and/or modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation
- * version 2.1 of the License.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
- * USA.
- */
-#ifndef foomoduledroidkeepalivesymdeffoo
-#define foomoduledroidkeepalivesymdeffoo
-
-#include <pulsecore/core.h>
-#include <pulsecore/module.h>
-
-#define pa__init module_droid_keepalive_LTX_pa__init
-#define pa__done module_droid_keepalive_LTX_pa__done
-#define pa__get_author module_droid_keepalive_LTX_pa__get_author
-#define pa__get_description module_droid_keepalive_LTX_pa__get_description
-#define pa__get_usage module_droid_keepalive_LTX_pa__get_usage
-#define pa__get_version module_droid_keepalive_LTX_pa__get_version
-
-int pa__init(struct pa_module*m);
-void pa__done(struct pa_module*m);
-
-const char* pa__get_author(void);
-const char* pa__get_description(void);
-const char* pa__get_usage(void);
-const char* pa__get_version(void);
-
-#endif
|
[-]
[+]
|
Deleted |
_service:tar_git:pulseaudio-modules-droid-12.2.78.tar.bz2/src/droid/module-droid-keepalive.c
^
|
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2013-2018 Jolla Ltd.
- *
- * Contact: Juho Hämäläinen <juho.hamalainen@jolla.com>
- *
- * These PulseAudio Modules are free software; you can redistribute
- * it and/or modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation
- * version 2.1 of the License.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
- * USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <signal.h>
-#include <stdio.h>
-
-#ifdef HAVE_VALGRIND_MEMCHECK_H
-#include <valgrind/memcheck.h>
-#endif
-
-#include <pulse/xmalloc.h>
-
-#include <pulsecore/core.h>
-#include <pulsecore/i18n.h>
-#include <pulsecore/module.h>
-#include <pulsecore/sink.h>
-#include <pulsecore/source.h>
-#include <pulsecore/modargs.h>
-#include <pulsecore/core-util.h>
-#include <pulsecore/log.h>
-#include <pulsecore/macro.h>
-#include <pulsecore/idxset.h>
-
-#include "keepalive.h"
-
-#include "module-droid-keepalive-symdef.h"
-
-PA_MODULE_AUTHOR("Juho Hämäläinen");
-PA_MODULE_DESCRIPTION("Droid keepalive. Send cpu wakeup heartbeat while streams are active.");
-PA_MODULE_VERSION(PACKAGE_VERSION);
-PA_MODULE_USAGE(
- "-"
-);
-
-static const char* const valid_modargs[] = {
- NULL,
-};
-
-struct userdata {
- pa_core *core;
- pa_module *module;
-
- pa_droid_keepalive *keepalive;
- bool active;
- pa_hook_slot *sink_state_changed_slot;
- pa_hook_slot *source_state_changed_slot;
-};
-
-static void start(struct userdata *u) {
- if (u->active)
- return;
-
- u->active = true;
-
- pa_droid_keepalive_start(u->keepalive);
-}
-
-static void stop(struct userdata *u) {
- void *state = NULL;
- pa_sink *sink;
- pa_source *source;
-
- if (!u->active)
- return;
-
- while ((sink = pa_idxset_iterate(u->core->sinks, &state, NULL))) {
- if (pa_sink_get_state(sink) != PA_SINK_SUSPENDED)
- return;
- }
-
- state = NULL;
- while ((source = pa_idxset_iterate(u->core->sources, &state, NULL))) {
- if (source->monitor_of)
- continue;
- if (pa_source_get_state(source) != PA_SOURCE_SUSPENDED)
- return;
- }
-
- /* We get here if all sinks and sources are in suspended state. */
- pa_droid_keepalive_stop(u->keepalive);
- u->active = false;
-}
-
-static void update_sink(pa_sink *sink, struct userdata *u) {
- pa_assert(sink);
- pa_assert(u);
-
- if (pa_sink_get_state(sink) != PA_SINK_SUSPENDED)
- start(u);
- else
- stop(u);
-}
-
-static void update_source(pa_source *source, struct userdata *u) {
- pa_assert(source);
- pa_assert(u);
-
- /* Don't react on monitor state changes. */
- if (!source->monitor_of) {
- if (pa_source_get_state(source) != PA_SOURCE_SUSPENDED)
- start(u);
- else
- stop(u);
- }
-}
-
-static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, struct userdata *u) {
- pa_assert(c);
- pa_object_assert_ref(o);
- pa_assert(u);
-
- if (pa_source_isinstance(o))
- update_source(PA_SOURCE(o), u);
- else if (pa_sink_isinstance(o))
- update_sink(PA_SINK(o), u);
-
- return PA_HOOK_OK;
-}
-
-
-int pa__init(pa_module *m) {
- uint32_t idx = 0;
- pa_sink *sink;
- pa_source *source;
- struct userdata *u;
-
- pa_assert(m);
-
- u = pa_xnew0(struct userdata, 1);
- u->core = m->core;
- u->active = false;
- u->module = m;
- m->userdata = u;
-
- if (!(u->keepalive = pa_droid_keepalive_new(u->core))) {
- pa_log("Failed to create keepalive handler.");
- goto fail;
- }
-
- u->sink_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) device_state_changed_hook_cb, u);
- u->source_state_changed_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_STATE_CHANGED], PA_HOOK_NORMAL, (pa_hook_cb_t) device_state_changed_hook_cb, u);
-
- PA_IDXSET_FOREACH(source, u->core->sources, idx)
- update_source(source, u);
-
- PA_IDXSET_FOREACH(sink, u->core->sinks, idx)
- update_sink(sink, u);
-
- return 0;
-
-fail:
- pa__done(m);
-
- return -1;
-}
-
-void pa__done(pa_module *m) {
- struct userdata *u;
-
- pa_assert(m);
-
- if ((u = m->userdata)) {
-
- if (u->sink_state_changed_slot)
- pa_hook_slot_free(u->sink_state_changed_slot);
- if (u->source_state_changed_slot)
- pa_hook_slot_free(u->source_state_changed_slot);
-
- if (u->keepalive) {
- pa_droid_keepalive_stop(u->keepalive);
- pa_droid_keepalive_free(u->keepalive);
- }
-
- pa_xfree(u);
- }
-}
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/README
^
|
@@ -15,25 +15,32 @@
* 6.0.x
* 7.x
* 8.x
+ * 9.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).
-When new devices with relevant new enums appear, add enum check to configure.ac,
-for example: (the CC_CHECK_DROID_ENUM m4 macro will create define HAVE_ENUM_FOO
-if the enum FOO exists in HAL audio.h)
+When new devices with relevant new enums appear, add enum check to configure.ac.
+CC_CHECK_DROID_ENUM macro will create macros HAVE_ENUM_FOO, STRING_ENTRY_IF_FOO
+and FANCY_ENTRY_IF_FOO if enum FOO exists in HAL audio.h.
+
+For example:
+
+# configure.ac:
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_DEVICE_OUT_IP])
+ CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_DEVICE_OUT_OTHER_NEW])
-and then in droid-util-audio.h add the enum to proper tables with ifdefs:
+# and then in droid-util-audio.h add macros to proper tables:
/* string_conversion_table_output_device[] */
- #ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_IP
- STRING_ENTRY( AUDIO_DEVICE_OUT_IP ),
- #endif
+ STRING_ENTRY_IF_OUT_IP
+ STRING_ENTRY_IF_OUT_OTHER_NEW
/* string_conversion_table_output_device_fancy[] */
- #ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_IP
- { AUDIO_DEVICE_OUT_IP, "output-ip" },
- #endif
+ FANCY_ENTRY_IF_OUT_IP("output-ip")
+ FANCY_ENTRY_IF_OUT_OTHER_NEW("output-other_new")
+
+In addition to the above macros there are also now defines
+HAVE_ENUM_AUDIO_DEVICE_OUT_IP and HAVE_ENUM_AUDIO_DEVICE_OUT_OTHER_NEW.
The purpose of droid-modules is to "replace AudioFlinger". Many hardware
adaptations use ALSA as the kernel interface, but there is no saying that
@@ -74,10 +81,12 @@
By default files are tried in following order,
- /vendor/etc/audio_policy_configuration.xml (new xml format)
- /vendor/etc/audio_policy.conf (legacy format)
- /system/etc/audio_policy_configuration.xml (new xml format)
- /system/etc/audio_policy.conf (legacy format)
+ /odm/etc/audio_policy_configuration.xml (new xml format)
+ /vendor/etc/audio/audio_policy_configuration.xml (new xml format)
+ /vendor/etc/audio_policy_configuration.xml (new xml format)
+ /vendor/etc/audio_policy.conf (legacy format)
+ /system/etc/audio_policy_configuration.xml (new xml format)
+ /system/etc/audio_policy.conf (legacy format)
module-droid-card
-----------------
@@ -92,8 +101,7 @@
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.
+to allow use of possible low latency or deep buffer outputs.
For example configuration with
@@ -104,8 +112,8 @@
deep_buffer {}
}
inputs {
- builtin {}
- external {}
+ primary {}
+ voice_rx {}
}
}
other {
@@ -114,39 +122,11 @@
}
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).
+and one source, source.droid.
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 {
- outputs {
- primary {}
- lpa {}
- }
- inputs {
- primary {}
- }
- }
- other {
- ...
- }
- }
-
-Would map to card profiles (input-output) primary-primary and lpa-primary.
-When module-droid-card is run without module_id argument, as default "primary"
-is used.
-
virtual profiles
----------------
@@ -196,6 +176,33 @@
related optimizations etc. Voicecall-record profile can be enabled when
voicecall profile is active.
+debugging profiles
+------------------
+
+If needed in favour of default profile one can opt to creating combinations
+of all output and input definitions in a module definition. This can be
+done by passing "default=false" to module-droid-card. Module argument
+module_id will then defines which module to load (by default "primary").
+Without default profile all input and output definitions are translated
+to PulseAudio card profiles. For example configuration with
+
+ audio_hw_modules {
+ primary {
+ outputs {
+ primary {}
+ lpa {}
+ }
+ inputs {
+ primary {}
+ }
+ }
+ other {
+ ...
+ }
+ }
+
+Would map to card profiles (<output>-<input>) primary-primary and lpa-primary.
+
module-droid-sink and module-droid-source
-----------------------------------------
@@ -246,6 +253,41 @@
accessory-plugin and pulseaudio-policy-enforcement module for actually making
the port switching)
+Droid source automatic reconfiguration
+--------------------------------------
+
+As droid HAL makes assumptions on (input) routing based on what the parameters
+for the stream are (device, sample rate, channels, format, etc.) normal
+PulseAudio sources are a bit inflexible as only sample rate can change after
+source creation and even then there are restrictions based on alternative
+sample rate value.
+
+To overcome this and to allow some more variables affecting the stream being
+passed to the input stream droid source is modified to reconfigure itself
+with the source-output that connects to it. This means, that just looking at
+inactive source from "pactl list" listing doesn't tell the whole story.
+
+Droid source is always reconfigured with the *last* source-output that
+connects to it, possibly already connected source-outputs will continue
+to read from the source but through resampler.
+
+For example,
+
+ 1) source-output 44100Hz, stereo connects (so1)
+ a) source is configured with 44100Hz, stereo
+ b) so1 connects to the source without resampler
+ 2) source-output 16000Hz, mono connects (so2)
+ a) so1 is detached from the source
+ b) source is configured with 16000Hz, mono
+ c) so2 connects to the source without resampler
+ d) resampler is created for so1, 16000Hz, mono -> 44100Hz stereo
+ f) so1 is re-attached to the source through resampler
+ 3) source-output 16000Hz, mono connects (so3)
+ a) so1 and so2 are detached from the source
+ b) so3 connects to the source without resampler
+ c) so1 is re-attached to the source through resampler
+ d) so2 is attached to the source
+
Classifying sinks and sources
-----------------------------
@@ -279,9 +321,8 @@
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.
+Right now there exists only one source (input device) which will always have
+both properties as true.
Quirks
------
@@ -331,6 +372,14 @@
* Some HAL module implementations get stuck in mutex or segfault when
trying to unload the module. To avoid confusing segfaults call
exit(0) instead of calling unload for the module.
+ * output_fast
+ * Enabled by default.
+ * Create separate sink if AUDIO_OUTPUT_FLAG_FAST is found. If this sink
+ is misbehaving try disabling this quirk.
+ * output_deep_buffer
+ * Enabled by default.
+ * Create separate sink if AUDIO_OUTPUT_FLAG_DEEP_BUFFER is found. If
+ this sink is misbehaving try disabling this quirk.
For example, to disable input_atoi and enable close_input quirks, use module
argument
@@ -368,6 +417,4 @@
module-droid-keepalive
----------------------
-Keepalive module is MCE (https://github.com/nemomobile/mce) specific module
-tracking sink/source activity and keeping a WAKELOCK when there are active
-streams.
+Module relocated to its own package pulseaudio-module-keepalive.
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/configure.ac
^
|
@@ -183,10 +183,6 @@
AC_SUBST(HYBRIS_CFLAGS)
AC_SUBST(HYBRIS_LIBS)
-PKG_CHECK_MODULES([DBUS], [dbus-1 >= 1.2])
-AC_SUBST(DBUS_CFLAGS)
-AC_SUBST(DBUS_LIBS)
-
#### expat (for xml config format parsing) (optional) ####
AC_ARG_ENABLE([xml],
@@ -260,17 +256,18 @@
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_INPUT_FLAG_NONE])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_INPUT_FLAG_FAST])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_INPUT_FLAG_HW_HOTWORD])
-# Added in 6.0
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_INPUT_FLAG_RAW])
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_INPUT_FLAG_SYNC])
+CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_INPUT_FLAG_MMAP_NOIRQ])
+CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_INPUT_FLAG_VOIP_TX])
# Channels
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_OUT_SURROUND])
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])
+CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO])
+CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO])
# Formats
CC_CHECK_DROID_ENUM([${DROIDHEADERS_CFLAGS}], [AUDIO_FORMAT_PCM_OFFLOAD])
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/m4/check_droid_enum.m4
^
|
@@ -17,5 +17,10 @@
AC_MSG_RESULT([$cc_check_droid_enum])
if test x"$cc_check_droid_enum" = x"yes"; then
AC_DEFINE(HAVE_ENUM_$2,,[define if enum $2 is found in headers])
+ AC_DEFINE(STRING_ENTRY_IF_$2,[STRING_ENTRY($2),],[string entry for enum $2])
+ AC_DEFINE(FANCY_ENTRY_IF_$2(n),[{$2, n},],[fancy entry for enum $2])
+else
+ AC_DEFINE(STRING_ENTRY_IF_$2,,[string entry for enum $2])
+ AC_DEFINE(FANCY_ENTRY_IF_$2(n),,[fancy entry for enum $2])
fi
])
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/common/config-parser-xml.c
^
|
@@ -343,86 +343,70 @@
return str;
}
-static void device_free(struct device *d) {
- pa_assert(d);
- pa_xfree(d->name);
- pa_xfree(d);
-}
+static void device_list_free(struct device *list) {
+ struct device *d;
-static void profile_free(struct profile *p) {
- pa_assert(p);
- pa_xfree(p->name);
- pa_xfree(p);
+ while (list) {
+ SLLIST_STEAL_FIRST(d, list);
+ pa_xfree(d->name);
+ pa_xfree(d);
+ }
}
-static void mix_port_free(struct mix_port *p) {
- struct profile *profile;
-
- pa_assert(p);
+static void profile_list_free(struct profile *list) {
+ struct profile *p;
- while (p->profiles) {
- SLLIST_STEAL_FIRST(profile, p->profiles);
- profile_free(profile);
+ while (list) {
+ SLLIST_STEAL_FIRST(p, list);
+ pa_xfree(p->name);
+ pa_xfree(p);
};
-
- pa_xfree(p->name);
- pa_xfree(p->role);
- pa_xfree(p);
}
-static void device_port_free(struct device_port *p) {
- pa_assert(p);
- pa_xfree(p->tag_name);
- pa_xfree(p->role);
- pa_xfree(p);
+static void mix_port_list_free(struct mix_port *list) {
+ struct mix_port *p;
+
+ while (list) {
+ SLLIST_STEAL_FIRST(p, list);
+ profile_list_free(p->profiles);
+ pa_xfree(p->name);
+ pa_xfree(p->role);
+ pa_xfree(p);
+ }
}
-static void route_free(struct route *r) {
- struct device *d;
+static void device_port_list_free(struct device_port *list) {
+ struct device_port *p;
- pa_assert(r);
+ while (list) {
+ SLLIST_STEAL_FIRST(p, list);
+ profile_list_free(p->profiles);
+ pa_xfree(p->tag_name);
+ pa_xfree(p->role);
+ pa_xfree(p);
+ }
+}
- while (r->sources) {
- SLLIST_STEAL_FIRST(d, r->sources);
- device_free(d);
- }
- pa_xfree(r->type);
- pa_xfree(r->sink);
- pa_xfree(r);
+static void route_list_free(struct route *list) {
+ struct route *r;
+
+ while (list) {
+ SLLIST_STEAL_FIRST(r, list);
+ device_list_free(r->sources);
+ pa_xfree(r->type);
+ pa_xfree(r->sink);
+ pa_xfree(r);
+ }
}
static void module_free(struct module *m) {
- struct device *dev;
- struct mix_port *mix_port;
- struct device_port *device_port;
- struct route *route;
-
pa_assert(m);
- while (m->attached_devices) {
- SLLIST_STEAL_FIRST(dev, m->attached_devices);
- device_free(dev);
- };
-
- while (m->default_output) {
- SLLIST_STEAL_FIRST(dev, m->default_output);
- device_free(dev);
- };
-
- while (m->mix_ports) {
- SLLIST_STEAL_FIRST(mix_port, m->mix_ports);
- mix_port_free(mix_port);
- };
-
- while (m->device_ports) {
- SLLIST_STEAL_FIRST(device_port, m->device_ports);
- device_port_free(device_port);
- };
-
- while (m->routes) {
- SLLIST_STEAL_FIRST(route, m->routes);
- route_free(route);
- };
+ device_list_free(m->attached_devices);
+ device_list_free(m->default_output);
+ mix_port_list_free(m->mix_ports);
+ device_port_list_free(m->device_ports);
+ route_list_free(m->routes);
pa_xfree(m->name);
pa_xfree(m);
@@ -535,7 +519,7 @@
element = xml_string_dup(element_name, -1);
- if (pa_streq(data->current->name, element)) {
+ if (pa_safe_streq(data->current->name, element)) {
ELEMENT_STACK_POP(data->stack, data->current);
if (pa_streq(element, ELEMENT_mixPort))
@@ -554,7 +538,7 @@
int whitespace = 0;
char *str = NULL;
- if (len <= 0)
+ if (len <= 0 || !data->current->char_data)
goto done;
str = xml_string_dup(s, len);
@@ -563,8 +547,7 @@
if (whitespace == len)
goto done;
- if (data->current->char_data)
- data->current->char_data(data, str);
+ data->current->char_data(data, str);
done:
pa_xfree(str);
@@ -680,7 +663,7 @@
data->current_mix_port = p;
} else {
pa_log("[%s:%u] Failed to parse element <" ELEMENT_mixPort ">", data->fn, data->lineno);
- mix_port_free(p);
+ mix_port_list_free(p);
}
return parsed;
@@ -760,15 +743,15 @@
if (!parsed) {
pa_log_error("[%s:%u] Failed to parse element <" ELEMENT_profile ">", data->fn, data->lineno);
- profile_free(p);
+ profile_list_free(p);
} else if (unknown_format) {
pa_log_info("[%s:%u] Ignore profile with unknown format.", data->fn, data->lineno);
- profile_free(p);
+ profile_list_free(p);
} else {
if (data->current_mix_port)
- SLLIST_APPEND(struct profile, data->current_module->mix_ports->profiles, p);
+ SLLIST_APPEND(struct profile, data->current_mix_port->profiles, p);
else if (data->current_device_port)
- SLLIST_APPEND(struct profile, data->current_module->device_ports->profiles, p);
+ SLLIST_APPEND(struct profile, data->current_device_port->profiles, p);
else
pa_assert_not_reached();
}
@@ -803,10 +786,10 @@
if (!parsed) {
pa_log("[%s:%u] Failed to parse element <" ELEMENT_devicePort ">", data->fn, data->lineno);
- device_port_free(d);
+ device_port_list_free(d);
} else if (unknown_device) {
pa_log_info("[%s:%u] Ignore <" ELEMENT_devicePort "> with unknown device.", data->fn, data->lineno);
- device_port_free(d);
+ device_port_list_free(d);
} else {
SLLIST_APPEND(struct device_port, data->current_module->device_ports, d);
data->current_device_port = d;
@@ -845,7 +828,7 @@
SLLIST_APPEND(struct route, data->current_module->routes, r);
} else {
pa_log("[%s:%u] Failed to parse element <" ELEMENT_route ">", data->fn, data->lineno);
- route_free(r);
+ route_list_free(r);
}
return parsed;
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/common/conversion.c
^
|
@@ -117,6 +117,34 @@
return str;
}
+/* Generic conversion */
+bool pa_string_convert_num_to_str(pa_conversion_string_t type, uint32_t value, const char **to_str) {
+ switch (type) {
+ case CONV_STRING_FORMAT:
+ return string_convert_num_to_str(string_conversion_table_format, value, to_str);
+
+ case CONV_STRING_OUTPUT_CHANNELS:
+ return string_convert_num_to_str(string_conversion_table_output_channels, value, to_str);
+
+ case CONV_STRING_INPUT_CHANNELS:
+ return string_convert_num_to_str(string_conversion_table_input_channels, value, to_str);
+
+ case CONV_STRING_OUTPUT_DEVICE:
+ return string_convert_num_to_str(string_conversion_table_output_device, value, to_str);
+
+ case CONV_STRING_INPUT_DEVICE:
+ return string_convert_num_to_str(string_conversion_table_input_device, value, to_str);
+
+ case CONV_STRING_OUTPUT_FLAG:
+ return string_convert_num_to_str(string_conversion_table_output_flag, value, to_str);
+
+ case CONV_STRING_INPUT_FLAG:
+ return string_convert_num_to_str(string_conversion_table_input_flag, value, to_str);
+ }
+
+ pa_assert_not_reached();
+ return false;
+}
/* Output device */
bool pa_string_convert_output_device_num_to_str(audio_devices_t value, const char **to_str) {
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/common/droid-config.c
^
|
@@ -66,6 +66,8 @@
#include <hardware/audio.h>
#include <hardware_legacy/audio_policy_conf.h>
+#define ODM_AUDIO_POLICY_CONFIG_XML_FILE "/odm/etc/audio_policy_configuration.xml"
+#define VENDOR_AUDIO_AUDIO_POLICY_CONFIG_XML_FILE "/vendor/etc/audio/audio_policy_configuration.xml"
#define VENDOR_AUDIO_POLICY_CONFIG_XML_FILE "/vendor/etc/audio_policy_configuration.xml"
#define SYSTEM_AUDIO_POLICY_CONFIG_XML_FILE "/system/etc/audio_policy_configuration.xml"
@@ -74,6 +76,8 @@
pa_droid_config_audio *config = NULL;
const char *manual_config;
const char *config_location[] = {
+ ODM_AUDIO_POLICY_CONFIG_XML_FILE,
+ VENDOR_AUDIO_AUDIO_POLICY_CONFIG_XML_FILE,
VENDOR_AUDIO_POLICY_CONFIG_XML_FILE,
AUDIO_POLICY_VENDOR_CONFIG_FILE,
SYSTEM_AUDIO_POLICY_CONFIG_XML_FILE,
@@ -195,6 +199,28 @@
return NULL;
}
+static const pa_droid_config_device *find_device(const pa_droid_config_hw_module *module, bool output, const char* device_name) {
+ pa_droid_config_device *device;
+
+ pa_assert(module);
+ pa_assert(device_name);
+
+ SLLIST_FOREACH(device, output ? module->outputs : module->inputs) {
+ if (pa_streq(device_name, device->name))
+ return device;
+ }
+
+ return NULL;
+}
+
+const pa_droid_config_device *pa_droid_config_find_output(const pa_droid_config_hw_module *module, const char* output_name) {
+ return find_device(module, true, output_name);
+}
+
+const pa_droid_config_device *pa_droid_config_find_input(const pa_droid_config_hw_module *module, const char* input_name) {
+ return find_device(module, false, input_name);
+}
+
pa_droid_config_hw_module *pa_droid_config_hw_module_new(const pa_droid_config_audio *config, const char *name) {
pa_droid_config_hw_module *hw_module;
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/common/droid-util-audio.h
^
|
@@ -140,45 +140,19 @@
/* Devices which may or may not be defined for all devices,
* update configure.ac CC_CHECK_DROID_ENUM list if you encounter new ones. */
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_HDMI
- STRING_ENTRY( AUDIO_DEVICE_OUT_HDMI ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_HDMI_ARC
- STRING_ENTRY( AUDIO_DEVICE_OUT_HDMI_ARC ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_TELEPHONY_TX
- STRING_ENTRY( AUDIO_DEVICE_OUT_TELEPHONY_TX ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_LINE
- STRING_ENTRY( AUDIO_DEVICE_OUT_LINE ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_SPDIF
- STRING_ENTRY( AUDIO_DEVICE_OUT_SPDIF ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_AUX_LINE
- STRING_ENTRY( AUDIO_DEVICE_OUT_AUX_LINE ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_SPEAKER_SAFE
- STRING_ENTRY( AUDIO_DEVICE_OUT_SPEAKER_SAFE ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_FM
- STRING_ENTRY( AUDIO_DEVICE_OUT_FM ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_FM_TX
- STRING_ENTRY( AUDIO_DEVICE_OUT_FM_TX ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_ANC_HEADSET
- STRING_ENTRY( AUDIO_DEVICE_OUT_ANC_HEADSET ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_ANC_HEADPHONE
- STRING_ENTRY( AUDIO_DEVICE_OUT_ANC_HEADPHONE ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_PROXY
- STRING_ENTRY( AUDIO_DEVICE_OUT_PROXY ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_IP
- STRING_ENTRY( AUDIO_DEVICE_OUT_IP ),
-#endif
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_HDMI
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_HDMI_ARC
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_TELEPHONY_TX
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_LINE
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_SPDIF
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_AUX_LINE
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_SPEAKER_SAFE
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_FM
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_FM_TX
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_ANC_HEADSET
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_ANC_HEADPHONE
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_PROXY
+ STRING_ENTRY_IF_AUDIO_DEVICE_OUT_IP
/* Combination entries consisting of multiple devices defined above.
* These don't require counterpart in string_conversion_table_output_device_fancy. */
@@ -212,45 +186,19 @@
{ AUDIO_DEVICE_OUT_DEFAULT, "output-default" },
/* Devices which may or may not be defined for all devices, */
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_HDMI
- { AUDIO_DEVICE_OUT_HDMI, "output-hdmi" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_HDMI_ARC
- { AUDIO_DEVICE_OUT_HDMI_ARC, "output-hdmi_arc" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_TELEPHONY_TX
- { AUDIO_DEVICE_OUT_TELEPHONY_TX, "output-telephony_tx" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_LINE
- { AUDIO_DEVICE_OUT_LINE, "output-line" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_SPDIF
- { AUDIO_DEVICE_OUT_SPDIF, "output-spdif" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_AUX_LINE
- { AUDIO_DEVICE_OUT_AUX_LINE, "output-aux_line" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_SPEAKER_SAFE
- { AUDIO_DEVICE_OUT_SPEAKER_SAFE, "output-speaker_safe" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_FM
- { AUDIO_DEVICE_OUT_FM, "output-fm" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_FM_TX
- { AUDIO_DEVICE_OUT_FM_TX, "output-fm_tx" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_ANC_HEADSET
- { AUDIO_DEVICE_OUT_ANC_HEADSET, "output-anc_headset" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_ANC_HEADPHONE
- { AUDIO_DEVICE_OUT_ANC_HEADPHONE, "output-anc_headphone" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_PROXY
- { AUDIO_DEVICE_OUT_PROXY, "output-proxy" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_OUT_IP
- { AUDIO_DEVICE_OUT_IP, "output-ip" },
-#endif
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_HDMI ( "output-hdmi" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_HDMI_ARC ( "output-hdmi_arc" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_TELEPHONY_TX ( "output-telephony_tx" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_LINE ( "output-line" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_SPDIF ( "output-spdif" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_AUX_LINE ( "output-aux_line" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_SPEAKER_SAFE ( "output-speaker_safe" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_FM ( "output-fm" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_FM_TX ( "output-fm_tx" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_ANC_HEADSET ( "output-and_headset" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_ANC_HEADPHONE ( "output-anc_headphone" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_PROXY ( "output-proxy" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_OUT_IP ( "output-ip" )
{ 0, NULL }
};
@@ -276,42 +224,18 @@
/* Devices which may or may not be defined for all devices,
* update configure.ac CC_CHECK_DROID_ENUM list if you encounter new ones. */
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_HDMI
- STRING_ENTRY( AUDIO_DEVICE_IN_HDMI ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_TELEPHONY_RX
- STRING_ENTRY( AUDIO_DEVICE_IN_TELEPHONY_RX ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_FM_TUNER
- STRING_ENTRY( AUDIO_DEVICE_IN_FM_TUNER ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_TV_TUNER
- STRING_ENTRY( AUDIO_DEVICE_IN_TV_TUNER ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_LINE
- STRING_ENTRY( AUDIO_DEVICE_IN_LINE ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_SPDIF
- STRING_ENTRY( AUDIO_DEVICE_IN_SPDIF ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_BLUETOOTH_A2DP
- STRING_ENTRY( AUDIO_DEVICE_IN_BLUETOOTH_A2DP ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_LOOPBACK
- STRING_ENTRY( AUDIO_DEVICE_IN_LOOPBACK ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_PROXY
- STRING_ENTRY( AUDIO_DEVICE_IN_PROXY ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_FM_RX
- STRING_ENTRY( AUDIO_DEVICE_IN_FM_RX ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_FM_RX_A2DP
- STRING_ENTRY( AUDIO_DEVICE_IN_FM_RX_A2DP ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_IP
- STRING_ENTRY( AUDIO_DEVICE_IN_IP ),
-#endif
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_HDMI
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_TELEPHONY_RX
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_FM_TUNER
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_TV_TUNER
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_LINE
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_SPDIF
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_BLUETOOTH_A2DP
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_LOOPBACK
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_PROXY
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX_A2DP
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_IP
#ifdef DROID_AUDIO_HAL_SECONDARY_MIC
STRING_ENTRY( AUDIO_DEVICE_IN_SECONDARY_MIC ),
@@ -321,9 +245,7 @@
* These don't require counterpart in string_conversion_table_input_device_fancy. */
STRING_ENTRY( AUDIO_DEVICE_IN_ALL ),
STRING_ENTRY( AUDIO_DEVICE_IN_ALL_SCO ),
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_ALL_USB
- STRING_ENTRY( AUDIO_DEVICE_IN_ALL_USB ),
-#endif
+ STRING_ENTRY_IF_AUDIO_DEVICE_IN_ALL_USB
{ 0, NULL }
};
@@ -345,42 +267,18 @@
{ AUDIO_DEVICE_IN_DEFAULT, "input-default" },
/* Devices which may or may not be defined for all devices, */
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_HDMI
- { AUDIO_DEVICE_IN_HDMI, "input-hdmi" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_TELEPHONY_RX
- { AUDIO_DEVICE_IN_TELEPHONY_RX, "input-telephony_rx" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_FM_TUNER
- { AUDIO_DEVICE_IN_FM_TUNER, "input-fm_tuner" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_TV_TUNER
- { AUDIO_DEVICE_IN_TV_TUNER, "input-tv_tuner" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_LINE
- { AUDIO_DEVICE_IN_LINE, "input-line" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_SPDIF
- { AUDIO_DEVICE_IN_SPDIF, "input-spdif" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_BLUETOOTH_A2DP
- { AUDIO_DEVICE_IN_BLUETOOTH_A2DP, "input-bluetooth_a2dp" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_LOOPBACK
- { AUDIO_DEVICE_IN_LOOPBACK, "input-loopback" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_PROXY
- { AUDIO_DEVICE_IN_PROXY, "input-proxy" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_FM_RX
- { AUDIO_DEVICE_IN_FM_RX, "input-fm_rx" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_FM_RX_A2DP
- { AUDIO_DEVICE_IN_FM_RX_A2DP, "input-fm_rx_a2dp" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_DEVICE_IN_IP
- { AUDIO_DEVICE_IN_IP, "input-ip" },
-#endif
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_HDMI ( "input-hdmi" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_TELEPHONY_RX ( "input-telephony_rx" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_FM_TUNER ( "input-fm_tuner" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_TV_TUNER ( "input-tv_tuner" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_LINE ( "input-line" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_SPDIF ( "input-spdif" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_BLUETOOTH_A2DP ( "input-bluetooth_a2dp" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_LOOPBACK ( "input-loopback" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_PROXY ( "input-proxy" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX ( "input-fm_rx" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_FM_RX_A2DP ( "input-fm_rx_a2dp" )
+ FANCY_ENTRY_IF_AUDIO_DEVICE_IN_IP ( "input-ip" )
#ifdef DROID_AUDIO_HAL_SECONDARY_MIC
{ AUDIO_DEVICE_IN_SECONDARY_MIC, "input-secondary_mic" },
@@ -402,15 +300,9 @@
{ AUDIO_SOURCE_REMOTE_SUBMIX, "remote submix" },
/* Audio sources which may or may not be defined for all devices, */
-#ifdef HAVE_ENUM_AUDIO_SOURCE_FM_TUNER
- { AUDIO_SOURCE_FM_TUNER, "fm tuner" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_SOURCE_FM_RX
- { AUDIO_SOURCE_FM_RX, "fm rx" },
-#endif
-#ifdef HAVE_ENUM_AUDIO_SOURCE_FM_RX_A2DP
- { AUDIO_SOURCE_FM_RX_A2DP, "fm rx a2dp" },
-#endif
+ FANCY_ENTRY_IF_AUDIO_SOURCE_FM_TUNER ( "fm tuner" )
+ FANCY_ENTRY_IF_AUDIO_SOURCE_FM_RX ( "fm rx" )
+ FANCY_ENTRY_IF_AUDIO_SOURCE_FM_RX_A2DP ( "fm rx a2dp" )
{ (uint32_t)-1, NULL }
};
@@ -425,36 +317,16 @@
/* Audio output flags which may or may not be defined for all devices,
* update configure.ac CC_CHECK_DROID_ENUM list if you encounter new ones. */
-#ifdef HAVE_ENUM_AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD
- STRING_ENTRY( AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_OUTPUT_FLAG_NON_BLOCKING
- STRING_ENTRY( AUDIO_OUTPUT_FLAG_NON_BLOCKING ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_OUTPUT_FLAG_HW_AV_SYNC
- STRING_ENTRY( AUDIO_OUTPUT_FLAG_HW_AV_SYNC ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_OUTPUT_FLAG_VOIP_RX
- STRING_ENTRY( AUDIO_OUTPUT_FLAG_VOIP_RX ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_OUTPUT_FLAG_INCALL_MUSIC
- STRING_ENTRY( AUDIO_OUTPUT_FLAG_INCALL_MUSIC ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
- STRING_ENTRY( AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_OUTPUT_FLAG_TTS
- STRING_ENTRY( AUDIO_OUTPUT_FLAG_TTS ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_OUTPUT_FLAG_RAW
- STRING_ENTRY( AUDIO_OUTPUT_FLAG_RAW ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_OUTPUT_FLAG_SYNC
- STRING_ENTRY( AUDIO_OUTPUT_FLAG_SYNC ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO
- STRING_ENTRY( AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO ),
-#endif
+ STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD
+ STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_NON_BLOCKING
+ STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_HW_AV_SYNC
+ STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_VOIP_RX
+ STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_INCALL_MUSIC
+ STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
+ STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_TTS
+ STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_RAW
+ STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_SYNC
+ STRING_ENTRY_IF_AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO
{ 0, NULL }
};
@@ -462,21 +334,13 @@
struct string_conversion string_conversion_table_input_flag[] = {
/* Audio output flags which may or may not be defined for all devices,
* update configure.ac CC_CHECK_DROID_ENUM list if you encounter new ones. */
-#ifdef HAVE_ENUM_AUDIO_INPUT_FLAG_NONE
- STRING_ENTRY( AUDIO_INPUT_FLAG_NONE ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_INPUT_FLAG_FAST
- STRING_ENTRY( AUDIO_INPUT_FLAG_FAST ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_INPUT_FLAG_HW_HOTWORD
- STRING_ENTRY( AUDIO_INPUT_FLAG_HW_HOTWORD ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_INPUT_FLAG_RAW
- STRING_ENTRY( AUDIO_INPUT_FLAG_RAW ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_INPUT_FLAG_SYNC
- STRING_ENTRY( AUDIO_INPUT_FLAG_SYNC ),
-#endif
+ STRING_ENTRY_IF_AUDIO_INPUT_FLAG_NONE
+ STRING_ENTRY_IF_AUDIO_INPUT_FLAG_FAST
+ STRING_ENTRY_IF_AUDIO_INPUT_FLAG_HW_HOTWORD
+ STRING_ENTRY_IF_AUDIO_INPUT_FLAG_RAW
+ STRING_ENTRY_IF_AUDIO_INPUT_FLAG_SYNC
+ STRING_ENTRY_IF_AUDIO_INPUT_FLAG_MMAP_NOIRQ
+ STRING_ENTRY_IF_AUDIO_INPUT_FLAG_VOIP_TX
{ 0, NULL }
};
@@ -504,16 +368,11 @@
STRING_ENTRY( AUDIO_CHANNEL_OUT_MONO ),
STRING_ENTRY( AUDIO_CHANNEL_OUT_STEREO ),
STRING_ENTRY( AUDIO_CHANNEL_OUT_QUAD ),
-#ifdef HAVE_ENUM_AUDIO_CHANNEL_OUT_SURROUND
- STRING_ENTRY( AUDIO_CHANNEL_OUT_SURROUND ),
-#endif
+
+ STRING_ENTRY_IF_AUDIO_CHANNEL_OUT_SURROUND
STRING_ENTRY( AUDIO_CHANNEL_OUT_5POINT1 ),
-#ifdef HAVE_ENUM_AUDIO_CHANNEL_OUT_5POINT1_BACK
- STRING_ENTRY( AUDIO_CHANNEL_OUT_5POINT1_BACK ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_CHANNEL_OUT_5POINT1_SIDE
- STRING_ENTRY( AUDIO_CHANNEL_OUT_5POINT1_SIDE ),
-#endif
+ STRING_ENTRY_IF_AUDIO_CHANNEL_OUT_5POINT1_BACK
+ STRING_ENTRY_IF_AUDIO_CHANNEL_OUT_5POINT1_SIDE
STRING_ENTRY(AUDIO_CHANNEL_OUT_7POINT1 ),
STRING_ENTRY(AUDIO_CHANNEL_OUT_ALL ),
@@ -539,15 +398,9 @@
STRING_ENTRY( AUDIO_CHANNEL_IN_STEREO ),
STRING_ENTRY( AUDIO_CHANNEL_IN_FRONT_BACK ),
STRING_ENTRY( AUDIO_CHANNEL_IN_ALL ),
-#ifdef HAVE_ENUM_AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO
- STRING_ENTRY( AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO
- STRING_ENTRY( AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_CHANNEL_IN_VOICE_CALL_MONO
- STRING_ENTRY( AUDIO_CHANNEL_IN_VOICE_CALL_MONO ),
-#endif
+ STRING_ENTRY_IF_AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO
+ STRING_ENTRY_IF_AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO
+ STRING_ENTRY_IF_AUDIO_CHANNEL_IN_VOICE_CALL_MONO
{ 0, NULL }
};
@@ -573,15 +426,9 @@
/* Audio formats which may or may not be defined for all devices,
* update configure.ac CC_CHECK_DROID_ENUM list if you encounter new ones. */
-#ifdef HAVE_ENUM_AUDIO_FORMAT_PCM_OFFLOAD
- STRING_ENTRY( AUDIO_FORMAT_PCM_OFFLOAD ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_FORMAT_FLAC
- STRING_ENTRY( AUDIO_FORMAT_FLAC ),
-#endif
-#ifdef HAVE_ENUM_AUDIO_FORMAT_OPUS
- STRING_ENTRY( AUDIO_FORMAT_OPUS ),
-#endif
+ STRING_ENTRY_IF_AUDIO_FORMAT_PCM_OFFLOAD
+ STRING_ENTRY_IF_AUDIO_FORMAT_FLAC
+ STRING_ENTRY_IF_AUDIO_FORMAT_OPUS
{ 0, NULL }
};
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/common/droid-util.c
^
|
@@ -80,10 +80,13 @@
{ "output_make_writable", QUIRK_OUTPUT_MAKE_WRITABLE },
{ "realcall", QUIRK_REALCALL },
{ "unload_call_exit", QUIRK_UNLOAD_CALL_EXIT },
+ { "output_fast", QUIRK_OUTPUT_FAST },
+ { "output_deep_buffer", QUIRK_OUTPUT_DEEP_BUFFER },
};
-#define DEFAULT_PRIORITY (100)
+#define DEFAULT_PRIORITY (100)
+#define DEFAULT_AUDIO_FORMAT (AUDIO_FORMAT_PCM_16_BIT)
static const char * const droid_combined_auto_outputs[3] = { "primary", "low_latency", NULL };
@@ -91,8 +94,7 @@
static void droid_port_free(pa_droid_port *p);
-static pa_droid_stream *get_primary_output(pa_droid_hw_module *hw);
-static int input_stream_set_route(pa_droid_stream *s, audio_devices_t device);
+static int input_stream_set_route(pa_droid_hw_module *hw_module, pa_droid_stream *s);
static pa_droid_profile *profile_new(pa_droid_profile_set *ps,
const pa_droid_config_hw_module *module,
@@ -113,7 +115,6 @@
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);
@@ -123,7 +124,7 @@
static pa_droid_profile *droid_profile_new(pa_droid_profile_set *ps,
const pa_droid_config_device *primary_output,
const pa_droid_config_device *output,
- const pa_droid_config_device *input) {
+ const pa_droid_config_device *inputs) {
pa_droid_profile *p;
char *name;
char *description;
@@ -131,13 +132,13 @@
pa_assert(ps);
pa_assert(output);
pa_assert(!primary_output || primary_output->direction == PA_DIRECTION_OUTPUT);
- pa_assert(!input || input->direction == PA_DIRECTION_INPUT);
+ pa_assert(!inputs || inputs->direction == PA_DIRECTION_INPUT);
- name = pa_sprintf_malloc("%s%s%s", output->name, input ? "-" : "", input ? input->name : "");
+ name = pa_sprintf_malloc("%s%s%s", output->name, inputs ? "-" : "", inputs ? inputs->name : "");
description = pa_sprintf_malloc("%s output%s%s%s", output->name,
- input ? " and " : "",
- input ? input->name : "",
- input ? " input." : "");
+ inputs ? " and " : "",
+ inputs ? inputs->name : "",
+ inputs ? " inputs." : "");
p = profile_new(ps, output->module, name, description);
pa_xfree(name);
@@ -146,7 +147,7 @@
if (pa_streq(output->name, "primary")) {
p->priority += DEFAULT_PRIORITY;
- if (input && pa_streq(input->name, "primary"))
+ if (inputs && pa_streq(inputs->name, "primary"))
p->priority += DEFAULT_PRIORITY;
}
@@ -154,8 +155,8 @@
pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, primary_output), NULL);
if (output)
pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, output), NULL);
- if (input)
- pa_idxset_put(p->input_mappings, pa_droid_mapping_get(ps, input), NULL);
+ if (inputs)
+ p->input_mapping = pa_droid_mapping_get(ps, inputs);
return p;
}
@@ -167,7 +168,7 @@
if (am->direction == PA_DIRECTION_OUTPUT)
pa_idxset_put(p->output_mappings, am, NULL);
else
- pa_idxset_put(p->input_mappings, am, NULL);
+ p->input_mapping = am;
}
static pa_droid_profile *add_profile(pa_droid_profile_set *ps,
@@ -176,7 +177,7 @@
const pa_droid_config_device *input) {
pa_droid_profile *ap;
- pa_assert(primary_output && primary_output->direction == PA_DIRECTION_OUTPUT);
+ pa_assert(!primary_output || primary_output->direction == PA_DIRECTION_OUTPUT);
pa_assert(output && output->direction == PA_DIRECTION_OUTPUT);
pa_assert(!input || input->direction == PA_DIRECTION_INPUT);
@@ -209,14 +210,20 @@
}
static void add_all_profiles(pa_droid_profile_set *ps,
- const pa_droid_config_hw_module *module,
- const pa_droid_config_device *primary_output) {
- pa_droid_config_device *output;
- pa_droid_config_device *input;
+ const pa_droid_config_hw_module *module) {
+ const pa_droid_config_device *primary_output = NULL;
+ const pa_droid_config_device *output;
+ const pa_droid_config_device *input;
pa_assert(ps);
pa_assert(module);
- pa_assert(primary_output && primary_output->direction == PA_DIRECTION_OUTPUT);
+
+ SLLIST_FOREACH(output, module->outputs) {
+ if (output->flags & AUDIO_OUTPUT_FLAG_PRIMARY) {
+ primary_output = output;
+ break;
+ }
+ }
/* Each distinct hw module output matches one profile. If there are multiple inputs
* combinations are made so that all possible outputs and inputs can be selected.
@@ -237,7 +244,7 @@
pa_droid_profile_set *ps;
ps = profile_set_new(module);
- add_all_profiles(ps, module, NULL);
+ add_all_profiles(ps, module);
return ps;
}
@@ -247,19 +254,15 @@
const pa_droid_config_device *primary_output,
const pa_droid_config_device *low_latency_output,
const pa_droid_config_device *media_latency_output,
- const pa_droid_config_device *builtin_input,
- const pa_droid_config_device *external_input,
- bool merge_inputs) {
+ const pa_droid_config_device *inputs) {
pa_droid_profile *p;
pa_assert(ps);
pa_assert(module);
pa_assert(!primary_output || primary_output->direction == PA_DIRECTION_OUTPUT);
- pa_assert(!low_latency_output || primary_output->direction == PA_DIRECTION_OUTPUT);
- pa_assert(!media_latency_output || primary_output->direction == PA_DIRECTION_OUTPUT);
- pa_assert(!builtin_input || builtin_input->direction == PA_DIRECTION_INPUT);
- pa_assert(!external_input || external_input->direction == PA_DIRECTION_INPUT);
+ pa_assert(!low_latency_output || low_latency_output->direction == PA_DIRECTION_OUTPUT);
+ pa_assert(!media_latency_output || media_latency_output->direction == PA_DIRECTION_OUTPUT);
pa_log_debug("New default profile");
@@ -272,35 +275,21 @@
if (media_latency_output && primary_output != media_latency_output && low_latency_output != media_latency_output)
pa_idxset_put(p->output_mappings, pa_droid_mapping_get(ps, media_latency_output), NULL);
- if (builtin_input && external_input && builtin_input != external_input && merge_inputs) {
- pa_idxset_put(p->input_mappings, pa_droid_mapping_merged_get(ps, builtin_input, external_input), NULL);
- } else {
- if (builtin_input)
- pa_idxset_put(p->input_mappings, pa_droid_mapping_get(ps, builtin_input), NULL);
- if (external_input && builtin_input != external_input)
- pa_idxset_put(p->input_mappings, pa_droid_mapping_get(ps, external_input), NULL);
- }
+ if (inputs)
+ p->input_mapping = pa_droid_mapping_get(ps, inputs);
- p->priority += DEFAULT_PRIORITY * (pa_idxset_size(p->output_mappings) + pa_idxset_size(p->input_mappings));
+ p->priority += DEFAULT_PRIORITY * (pa_idxset_size(p->output_mappings) + p->input_mapping ? 1 : 0);
p->priority += primary_output ? DEFAULT_PRIORITY : 0;
pa_hashmap_put(ps->profiles, p->name, p);
}
static void auto_add_profiles(pa_droid_profile_set *ps,
- const pa_droid_config_hw_module *module,
- bool merge_inputs) {
+ const pa_droid_config_hw_module *module) {
const pa_droid_config_device *output;
- const pa_droid_config_device *input;
-
const pa_droid_config_device *primary_output = NULL;
const pa_droid_config_device *low_latency_output = NULL;
const pa_droid_config_device *media_latency_output = NULL;
- const pa_droid_config_device *builtin_input = NULL;
- const pa_droid_config_device *external_input = NULL;
-
- uint32_t input_devices;
-
pa_assert(ps);
pa_assert(module);
@@ -314,6 +303,11 @@
pa_log_debug("Ignore output %s with flag AUDIO_OUTPUT_FLAG_RAW", output->name);
#endif
+#if defined(HAVE_ENUM_AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
+ else if (output->flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
+ pa_log_debug("Ignore output %s with flag AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD", output->name);
+#endif
+
else if (output->flags & AUDIO_OUTPUT_FLAG_FAST)
low_latency_output = output;
@@ -321,30 +315,16 @@
media_latency_output = output;
}
- SLLIST_FOREACH(input, module->inputs) {
- input_devices = input->devices;
-#if AUDIO_API_VERSION_MAJ >= 2
- input_devices &= ~AUDIO_DEVICE_BIT_IN;
-#endif
- if (input_devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC))
- builtin_input = input;
-
- else if (input_devices & AUDIO_DEVICE_IN_WIRED_HEADSET)
- external_input = input;
- }
-
add_default_profile(ps, module,
primary_output, low_latency_output, media_latency_output,
- builtin_input, external_input, merge_inputs);
- add_all_profiles(ps, module, primary_output);
+ module->inputs);
}
-pa_droid_profile_set *pa_droid_profile_set_default_new(const pa_droid_config_hw_module *module,
- bool merge_inputs) {
+pa_droid_profile_set *pa_droid_profile_set_default_new(const pa_droid_config_hw_module *module) {
pa_droid_profile_set *ps;
ps = profile_set_new(module);
- auto_add_profiles(ps, module, merge_inputs);
+ auto_add_profiles(ps, module);
return ps;
}
@@ -365,8 +345,7 @@
pa_xfree(ap->description);
if (ap->output_mappings)
pa_idxset_free(ap->output_mappings, NULL);
- if (ap->input_mappings)
- pa_idxset_free(ap->input_mappings, NULL);
+ ap->input_mapping = NULL;
pa_xfree(ap);
}
@@ -510,8 +489,8 @@
p->priority = DEFAULT_PRIORITY;
p->device = device;
- if (am->input->module->global_config ? am->input->module->global_config->attached_input_devices & device
- : am->profile_set->config->global_config->attached_input_devices & device)
+ if (am->inputs->module->global_config ? am->inputs->module->global_config->attached_input_devices & device
+ : am->profile_set->config->global_config->attached_input_devices & device)
p->priority += DEFAULT_PRIORITY;
pa_hashmap_put(am->profile_set->all_ports, p->name, p);
@@ -524,14 +503,14 @@
static void add_i_ports(pa_droid_mapping *am) {
pa_droid_port *p;
const char *name;
- uint32_t devices;
+ const pa_droid_config_device *input;
+ uint32_t devices = AUDIO_DEVICE_IN_DEFAULT;
uint32_t i = 0;
pa_assert(am);
- devices = am->input->devices | AUDIO_DEVICE_IN_DEFAULT;
- if (am->input2)
- devices |= am->input2->devices;
+ SLLIST_FOREACH(input, am->inputs)
+ devices |= input->devices;
#if AUDIO_API_VERSION_MAJ >= 2
devices &= ~AUDIO_DEVICE_BIT_IN;
@@ -593,16 +572,19 @@
am = pa_xnew0(pa_droid_mapping, 1);
am->profile_set = ps;
- am->name = pa_xstrdup(device->name);
am->proplist = pa_proplist_new();
am->direction = device->direction;
am->ports = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);;
if (am->direction == PA_DIRECTION_OUTPUT) {
+ am->name = pa_xstrdup(device->name);
am->output = device;
add_o_ports(am);
} else {
- am->input = device;
+ /* Use common name */
+ am->name = pa_xstrdup("droid");
+ /* Use all inputs as a list */
+ am->inputs = device;
add_i_ports(am);
}
@@ -611,56 +593,15 @@
return am;
}
-pa_droid_mapping *pa_droid_mapping_merged_get(pa_droid_profile_set *ps,
- const pa_droid_config_device *input1,
- const pa_droid_config_device *input2) {
- pa_droid_mapping *am;
- pa_hashmap *map = ps->input_mappings;
- char *name;
-
- pa_assert(ps);
- pa_assert(input1 && input1->direction == PA_DIRECTION_INPUT);
- pa_assert(input2 && input2->direction == PA_DIRECTION_INPUT);
-
- name = pa_sprintf_malloc("%s+%s", input1->name, input2->name);
-
- if ((am = pa_hashmap_get(map, name))) {
- pa_log_debug(" input mapping %s from cache", name);
- pa_xfree(name);
- return am;
- }
- pa_log_debug(" New input mapping %s", name);
-
- am = pa_xnew0(pa_droid_mapping, 1);
- am->profile_set = ps;
- am->name = name;
- am->proplist = pa_proplist_new();
- am->direction = PA_DIRECTION_INPUT;
- am->output = NULL;
- am->input = input1;
- am->input2 = input2;
- am->ports = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
-
- add_i_ports(am);
-
- pa_hashmap_put(map, am->name, am);
-
- return am;
-}
-
bool pa_droid_mapping_is_primary(pa_droid_mapping *am) {
pa_assert(am);
if (am->direction == PA_DIRECTION_OUTPUT) {
pa_assert(am->output);
return am->output->flags & AUDIO_OUTPUT_FLAG_PRIMARY;
- } else {
- pa_assert(am->input);
- /* merged input mapping is always primary */
- if (am->input && am->input2)
- return true;
- return pa_startswith(am->input->name, PA_DROID_PRIMARY_DEVICE);
}
+
+ return true;
}
pa_droid_mapping *pa_droid_idxset_get_primary(pa_idxset *i) {
@@ -677,33 +618,6 @@
return NULL;
}
-pa_droid_mapping *pa_droid_idxset_mapping_with_device(pa_idxset *i, uint32_t device) {
- pa_droid_mapping *am;
- uint32_t idx;
-
- pa_assert(i);
-
-#if AUDIO_API_VERSION_MAJ >= 2
- device &= ~AUDIO_DEVICE_BIT_IN;
-#endif
-
- PA_IDXSET_FOREACH(am, i, idx) {
- if (am->direction == PA_DIRECTION_OUTPUT) {
- pa_assert(am->output);
- if (am->output->devices & device)
- return am;
- } else {
- uint32_t all_devices;
- pa_assert(am->input);
- all_devices = am->input->devices | (am->input2 ? am->input2->devices : 0);
- if (all_devices & device)
- return am;
- }
- }
-
- return NULL;
-}
-
static int add_ports(pa_core *core, pa_card_profile *cp, pa_hashmap *ports, pa_droid_mapping *am, pa_hashmap *extra) {
pa_droid_port *p;
pa_device_port_new_data dp_data;
@@ -797,8 +711,12 @@
static pa_droid_quirks *set_default_quirks(pa_droid_quirks *q) {
q = NULL;
-#if (ANDROID_VERSION_MAJOR >= 5) || defined(DROID_AUDIO_HAL_ATOI_FIX)
q = get_quirks(q);
+ q->enabled[QUIRK_CLOSE_INPUT] = true;
+ q->enabled[QUIRK_OUTPUT_FAST] = true;
+ q->enabled[QUIRK_OUTPUT_DEEP_BUFFER] = true;
+
+#if (ANDROID_VERSION_MAJOR >= 5) || defined(DROID_AUDIO_HAL_ATOI_FIX)
q->enabled[QUIRK_INPUT_ATOI] = true;
#endif
@@ -808,13 +726,9 @@
defined(DROID_DEVICE_MANGO) || defined(DROID_DEVICE_SATSUMA) ||\
defined(DROID_DEVICE_SMULTRON) || defined(DROID_DEVICE_URUSHI)
#warning Using set_parameters hack, originating from previous cm10 mako.
- q = get_quirks(q);
q->enabled[QUIRK_SET_PARAMETERS] = true;
#endif
- q = get_quirks(q);
- q->enabled[QUIRK_CLOSE_INPUT] = true;
-
return q;
}
@@ -885,10 +799,10 @@
if (s->output->flags & AUDIO_OUTPUT_FLAG_PRIMARY)
primary_sink = sink;
- if (s->output->flags & AUDIO_OUTPUT_FLAG_FAST)
+ if (pa_droid_quirk(hw, QUIRK_OUTPUT_FAST) && s->output->flags & AUDIO_OUTPUT_FLAG_FAST)
low_latency_sink = sink;
- if (s->output->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
+ if (pa_droid_quirk(hw, QUIRK_OUTPUT_DEEP_BUFFER) && s->output->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
media_latency_sink = sink;
#if defined(HAVE_ENUM_AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
@@ -943,68 +857,6 @@
return PA_HOOK_OK;
}
-static void update_source_types(pa_droid_hw_module *hw, pa_source *ignore_source) {
- pa_source *source;
- pa_source *builtin_source = NULL;
- pa_source *external_source = NULL;
-
- pa_droid_stream *s;
- uint32_t idx;
-
- /* only update primary hw module types for now. */
- if (!pa_streq(hw->module_id, PA_DROID_PRIMARY_DEVICE))
- return;
-
- PA_IDXSET_FOREACH(s, hw->inputs, idx) {
- if (!(source = pa_droid_stream_get_data(s)))
- continue;
-
- if (source == ignore_source)
- continue;
-
- if (s->input->all_devices & (AUDIO_DEVICE_IN_BUILTIN_MIC | AUDIO_DEVICE_IN_BACK_MIC))
- builtin_source = source;
-
- if (s->input->all_devices & AUDIO_DEVICE_IN_WIRED_HEADSET)
- external_source = source;
- }
-
- if (builtin_source)
- pa_proplist_sets(builtin_source->proplist, PROP_DROID_INPUT_BUILTIN, "true");
-
- if (external_source)
- pa_proplist_sets(external_source->proplist, PROP_DROID_INPUT_EXTERNAL, "true");
-
- if (builtin_source && external_source && builtin_source != external_source) {
- pa_proplist_sets(builtin_source->proplist, PROP_DROID_INPUT_EXTERNAL, "false");
- pa_proplist_sets(external_source->proplist, PROP_DROID_INPUT_BUILTIN, "false");
- }
-}
-
-static pa_hook_result_t source_put_hook_cb(void *hook_data, void *call_data, void *slot_data) {
- pa_source *source = call_data;
- pa_droid_hw_module *hw = slot_data;
-
- if (!pa_source_is_droid_source(source))
- return PA_HOOK_OK;
-
- update_source_types(hw, NULL);
-
- return PA_HOOK_OK;
-}
-
-static pa_hook_result_t source_unlink_hook_cb(void *hook_data, void *call_data, void *slot_data) {
- pa_source *source = call_data;
- pa_droid_hw_module *hw = slot_data;
-
- if (!pa_source_is_droid_source(source))
- return PA_HOOK_OK;
-
- update_source_types(hw, source);
-
- return PA_HOOK_OK;
-}
-
static char *shared_name_get(const char *module_id) {
pa_assert(module_id);
return pa_sprintf_malloc("droid-hardware-module-%s", module_id);
@@ -1015,7 +867,6 @@
pa_droid_hw_module *hw = NULL;
struct hw_module_t *hwmod = NULL;
audio_hw_device_t *device = NULL;
- int h;
int ret;
pa_assert(core);
@@ -1078,13 +929,6 @@
sink_put_hook_cb, hw);
hw->sink_unlink_hook_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_EARLY-10,
sink_unlink_hook_cb, hw);
- hw->source_put_hook_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_EARLY-10,
- source_put_hook_cb, hw);
- hw->source_unlink_hook_slot = pa_hook_connect(&core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_EARLY-10,
- source_unlink_hook_cb, hw);
-
- for (h = 0; h < PA_DROID_HOOK_MAX; h++)
- pa_hook_init(&hw->hooks[h], hw);
pa_assert_se(pa_shared_set(core, hw->shared_name, hw) >= 0);
@@ -1126,8 +970,6 @@
}
static void droid_hw_module_close(pa_droid_hw_module *hw) {
- int h;
-
pa_assert(hw);
pa_log_info("Closing hw module %s.%s (%s)", AUDIO_HARDWARE_MODULE_ID, hw->enabled_module->name, DROID_DEVICE_STRING);
@@ -1137,14 +979,6 @@
if (hw->sink_unlink_hook_slot)
pa_hook_slot_free(hw->sink_unlink_hook_slot);
- if (hw->source_put_hook_slot)
- pa_hook_slot_free(hw->source_put_hook_slot);
- if (hw->source_unlink_hook_slot)
- pa_hook_slot_free(hw->source_unlink_hook_slot);
-
- for (h = 0; h < PA_DROID_HOOK_MAX; h++)
- pa_hook_done(&hw->hooks[h]);
-
if (hw->config)
pa_droid_config_free(hw->config);
@@ -1212,13 +1046,15 @@
pa_mutex_unlock(hw->hw_mutex);
}
-static pa_droid_stream *droid_stream_new(pa_droid_hw_module *module) {
+static pa_droid_stream *droid_stream_new(pa_droid_hw_module *module,
+ const pa_droid_config_device *device_def) {
pa_droid_stream *s;
s = pa_xnew0(pa_droid_stream, 1);
PA_REFCNT_INIT(s);
s->module = pa_droid_hw_module_ref(module);
+ s->device_def = device_def;
return s;
}
@@ -1228,10 +1064,37 @@
}
static pa_droid_input_stream *droid_input_stream_new(void) {
- return pa_xnew0(pa_droid_input_stream, 1);
+ pa_droid_input_stream *input = pa_xnew0(pa_droid_input_stream, 1);
+ input->first = true;
+
+ return input;
}
-static bool stream_config_fill(audio_devices_t devices,
+static int stream_standby(pa_droid_stream *s) {
+ int ret = 0;
+
+ pa_assert(s);
+ pa_assert(s->output || s->input);
+
+ if ((s->output && !s->output->stream) ||
+ (s->input && !s->input->stream))
+ return ret;
+
+ if (s->output) {
+ pa_mutex_lock(s->module->output_mutex);
+ ret = s->output->stream->common.standby(&s->output->stream->common);
+ pa_mutex_unlock(s->module->output_mutex);
+ } else {
+ pa_mutex_lock(s->module->input_mutex);
+ ret = s->input->stream->common.standby(&s->input->stream->common);
+ pa_mutex_unlock(s->module->input_mutex);
+ }
+
+ return ret;
+}
+
+static bool stream_config_fill(const pa_droid_config_device *device_def,
+ audio_devices_t devices,
pa_sample_spec *sample_spec,
pa_channel_map *channel_map,
struct audio_config *config) {
@@ -1239,6 +1102,7 @@
audio_channel_mask_t hal_channel_mask = 0;
bool voicecall_record = false;
bool output = true;
+ int i;
pa_assert(sample_spec);
pa_assert(channel_map);
@@ -1253,15 +1117,12 @@
output = !(devices & AUDIO_DEVICE_IN_ALL);
#endif
- if (devices & AUDIO_DEVICE_IN_VOICE_CALL)
+ if (devices & AUDIO_DEVICE_IN_VOICE_CALL) {
+ pa_log_debug("Fill config: Use voice call");
voicecall_record = true;
-
- 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++) {
+ for (i = 0; i < channel_map->channels; i++) {
bool found;
audio_channel_mask_t c;
@@ -1295,8 +1156,81 @@
sample_spec->channels = 1;
hal_channel_mask = AUDIO_CHANNEL_IN_MONO;
#endif
+ pa_log_debug("Fill config: Use %d channel(s) for voice call.", sample_spec->channels);
}
+ if (!pa_convert_format(sample_spec->format, CONV_FROM_PA, &hal_audio_format)) {
+ pa_log_warn("Sample spec format %u not supported.", sample_spec->format);
+ goto fail;
+ }
+
+ /* As input sample metrics are based on user request we need to make sure that the sample
+ * format requested is actually usable with the input route. */
+ if (!output) {
+ const pa_droid_config_device *ddef;
+ uint32_t tmp;
+ const char *fmt;
+ uint32_t format_found = 0;
+
+ pa_log_debug("Fill config: Try to use format %s, sample rate %u",
+ pa_string_convert_num_to_str(CONV_STRING_FORMAT, hal_audio_format, &fmt) ? fmt : "<unknown>",
+ sample_spec->rate);
+
+ SLLIST_FOREACH(ddef, device_def) {
+ format_found |= ddef->formats & hal_audio_format;
+
+ if (!(ddef->formats & hal_audio_format) ||
+ !(ddef->devices & devices))
+ continue;
+
+ for (i = 0; i < AUDIO_MAX_SAMPLING_RATES && ddef->sampling_rates[i]; i++) {
+ if (ddef->sampling_rates[i] == (uint32_t) -1 ||
+ ddef->sampling_rates[i] == sample_spec->rate) {
+ goto format_found;
+ }
+ }
+ }
+
+ if (!format_found && hal_audio_format != DEFAULT_AUDIO_FORMAT) {
+ hal_audio_format = DEFAULT_AUDIO_FORMAT;
+ pa_assert_se(pa_convert_format(hal_audio_format, CONV_FROM_HAL, &tmp));
+ sample_spec->format = tmp;
+ pa_log_debug("Fill config: Override sample format, use default %s.",
+ pa_string_convert_num_to_str(CONV_STRING_FORMAT, hal_audio_format, &fmt) ? fmt : "<unknown>");
+ }
+
+ SLLIST_FOREACH(ddef, device_def) {
+ if (!(ddef->devices & devices) ||
+ !ddef->sampling_rates[0])
+ continue;
+
+ if (ddef->sampling_rates[0] == (uint32_t) -1)
+ goto format_found;
+
+ for (i = 0; i < AUDIO_MAX_SAMPLING_RATES && ddef->sampling_rates[i]; i++) {
+ if (ddef->sampling_rates[i] == sample_spec->rate)
+ goto format_found;
+ }
+
+ /* Start from highest sample rate value */
+ for (i = 0; i < AUDIO_MAX_SAMPLING_RATES && ddef->sampling_rates[i]; i++)
+ ;
+
+ for (i -= 1; i >= 0; i--) {
+ if ((ddef->sampling_rates[i] % 11025 == 0 && sample_spec->rate % 11025 == 0) ||
+ (ddef->sampling_rates[i] % 4000 == 0 && sample_spec->rate % 4000 == 0)) {
+ sample_spec->rate = ddef->sampling_rates[i];
+ pa_log_debug("Fill config: Override sample rate, use %u.", sample_spec->rate);
+ goto format_found;
+ }
+ }
+ }
+
+ /* Format not found, fail */
+ goto fail;
+ }
+format_found:
+
memset(config, 0, sizeof(*config));
config->sample_rate = sample_spec->rate;
config->channel_mask = hal_channel_mask;
@@ -1311,8 +1245,9 @@
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,
+ const char *module_output_name,
audio_devices_t devices) {
+ const pa_droid_config_device *module_output = NULL;
pa_droid_stream *s = NULL;
pa_droid_output_stream *output = NULL;
pa_droid_stream *primary_stream = NULL;
@@ -1325,16 +1260,22 @@
pa_assert(module);
pa_assert(spec);
pa_assert(map);
+ pa_assert(module_output_name);
sample_spec = *spec;
channel_map = *map;
- if (!stream_config_fill(devices, &sample_spec, &channel_map, &config_out))
+ if (!(module_output = pa_droid_config_find_output(module->enabled_module, module_output_name))) {
+ pa_log("Could not find output %s from module %s.", module_output_name, module->enabled_module->name);
+ goto fail;
+ }
+
+ if (!stream_config_fill(module_output, devices, &sample_spec, &channel_map, &config_out))
goto fail;
if (pa_idxset_size(module->outputs) == 0)
pa_log_debug("Set initial output device to %#010x", devices);
- else if ((primary_stream = get_primary_output(module))) {
+ else if ((primary_stream = pa_droid_hw_primary_output_stream(module))) {
pa_log_debug("Primary output with device %#010x already open, using as initial device.",
primary_stream->output->device);
devices = primary_stream->output->device;
@@ -1342,9 +1283,9 @@
pa_droid_hw_module_lock(module);
ret = module->device->open_output_stream(module->device,
- module->stream_out_id++,
+ ++module->stream_out_id,
devices,
- flags,
+ module_output->flags,
&config_out,
&stream
#if AUDIO_API_VERSION_MAJ >= 3
@@ -1360,12 +1301,12 @@
goto fail;
}
- s = droid_stream_new(module);
+ s = droid_stream_new(module, module_output);
s->output = output = droid_output_stream_new();
output->stream = stream;
output->sample_spec = *spec;
output->channel_map = *map;
- output->flags = flags;
+ output->flags = module_output->flags;
output->device = devices;
if ((output->sample_spec.rate = output->stream->common.get_sample_rate(&output->stream->common)) != spec->rate)
@@ -1394,171 +1335,352 @@
return NULL;
}
+static const char *audio_mode_to_string(audio_mode_t mode) {
+ switch (mode) {
+ case AUDIO_MODE_RINGTONE: return "AUDIO_MODE_RINGTONE";
+ case AUDIO_MODE_IN_CALL: return "AUDIO_MODE_IN_CALL";
+ case AUDIO_MODE_IN_COMMUNICATION: return "AUDIO_MODE_IN_COMMUNICATION";
+ default: break;
+ }
+
+ return "AUDIO_MODE_NORMAL";
+}
+
+static void set_active_input(pa_droid_hw_module *hw_module, pa_droid_stream *stream) {
+ pa_assert(hw_module);
+
+ if (hw_module->state.active_input != stream) {
+ pa_log_info("Set active input to %p", (void *) stream);
+ hw_module->state.active_input = stream;
+ }
+}
+
+static bool config_diff(const struct audio_config *a, const struct audio_config *b,
+ bool *sample_rate, bool *channel_mask, bool *format) {
+ bool diff = false;
+
+ pa_assert(a);
+ pa_assert(b);
+ pa_assert(sample_rate);
+ pa_assert(channel_mask);
+ pa_assert(format);
+
+ *sample_rate = *channel_mask = *format = false;
+
+ if (a->sample_rate != b->sample_rate)
+ diff = *sample_rate = true;
+
+ if (a->channel_mask != b->channel_mask)
+ diff = *channel_mask = true;
+
+ if (a->format != b->format)
+ diff = *format = true;
+
+ return diff;
+}
+
+static bool stream_config_convert(pa_direction_t direction,
+ const struct audio_config *config,
+ pa_sample_spec *sample_spec,
+ pa_channel_map *channel_map) {
+ uint32_t format;
+ uint32_t channel_mask;
+ uint32_t pa_channel = 0;
+ uint32_t channel = 0;
+ uint32_t i = 0;
+
+ pa_assert(direction == PA_DIRECTION_INPUT || direction == PA_DIRECTION_OUTPUT);
+ pa_assert(config);
+ pa_assert(sample_spec);
+ pa_assert(channel_map);
+
+ if (!pa_convert_format(config->format, CONV_FROM_HAL, (uint32_t *) &format)) {
+ pa_log("Config format %#010x not supported.", config->format);
+ return false;
+ }
+
+ sample_spec->format = format;
+
+ channel_mask = config->channel_mask;
+
+ while (channel_mask) {
+ uint32_t current = (1 << i++);
+
+ if (channel_mask & current) {
+ if (!pa_convert_input_channel(current, CONV_FROM_HAL, &pa_channel)) {
+ pa_log_warn("Could not convert channel mask value %#010x", current);
+ return false;
+ }
+
+ channel_map->map[channel] = pa_channel;
+
+ channel++;
+ channel_mask &= ~current;
+ }
+ }
+
+ channel_map->channels = channel;
+
+ sample_spec->rate = config->sample_rate;
+ sample_spec->channels = channel_map->channels;
+
+ if (!pa_sample_spec_valid(sample_spec)) {
+ pa_log_warn("Conversion resulted in invalid sample spec.");
+ return false;
+ }
+
+ if (!pa_channel_map_valid(channel_map)) {
+ pa_log_warn("Conversion resulted in invalid channel map.");
+ return false;
+ }
+
+ return true;
+}
+
+static void log_input_open(pa_log_level_t log_level, const char *prefix,
+ audio_devices_t device,
+ audio_source_t source,
+ uint32_t flags, /* audio_input_flags_t */
+ const pa_sample_spec *sample_spec,
+ const struct audio_config *config,
+ int return_code) {
+ pa_logl(log_level,
+ "%s input stream with device: %#010x source: %#010x flags: %#010x sample rate: %u (%u) channels: %u (%#010x) format: %u (%#010x) (return code %d)",
+ prefix,
+ device,
+ source,
+ flags,
+ sample_spec->rate,
+ config->sample_rate,
+ sample_spec->channels,
+ config->channel_mask,
+ sample_spec->format,
+ config->format,
+ return_code);
+}
+
static int input_stream_open(pa_droid_stream *s, bool resume_from_suspend) {
- pa_droid_input_stream *input;
- audio_stream_in_t *stream;
- audio_source_t audio_source = AUDIO_SOURCE_DEFAULT;
+ pa_droid_hw_module *hw_module;
+ pa_droid_input_stream *input = NULL;
pa_channel_map channel_map;
pa_sample_spec sample_spec;
- struct audio_config config_in;
size_t buffer_size;
- bool buffer_size_changed = false;
- bool channel_map_changed = false;
+ bool try_defaults = true;
int ret = -1;
+ struct audio_config config_try;
+ struct audio_config config_in;
+
+ bool diff_sample_rate = false;
+ bool diff_channel_mask = false;
+ bool diff_format = false;
+
pa_assert(s);
pa_assert(s->input);
- pa_assert(!s->input->stream);
+ pa_assert_se((hw_module = s->module));
- input = s->input;
+ if (s->input->stream) /* already open */
+ return 0;
- channel_map = input->channel_map;
- sample_spec = input->sample_spec;
+ pa_assert(!s->module->state.active_input);
- if (!stream_config_fill(input->device, &sample_spec, &channel_map, &config_in))
- goto done;
+ input = s->input;
+ input->stream = NULL;
- pa_input_device_default_audio_source(input->device, &audio_source);
+ /* Copy our requested specs */
+ sample_spec = input->req_sample_spec;
+ channel_map = input->req_channel_map;
- if (channel_map.channels != input->input_channel_map.channels)
- channel_map_changed = true;
+ if (!stream_config_fill(s->device_def, hw_module->state.input_device, &sample_spec, &channel_map, &config_try))
+ goto done;
pa_droid_hw_module_lock(s->module);
- ret = s->module->device->open_input_stream(s->module->device,
- s->module->stream_in_id++,
- input->device,
- &config_in,
- &stream
+ while (true) {
+ config_in = config_try;
+
+ log_input_open(PA_LOG_INFO, "Trying to open",
+ hw_module->state.input_device,
+ hw_module->state.audio_source,
+ 0, /* AUDIO_INPUT_FLAG_NONE on v3. v1 and v2 don't have input flags. */
+ &sample_spec,
+ &config_in,
+ 0);
+
+ ret = hw_module->device->open_input_stream(hw_module->device,
+ ++hw_module->stream_in_id,
+ hw_module->state.input_device,
+ &config_in,
+ &input->stream
#if AUDIO_API_VERSION_MAJ >= 3
- , input->flags
- , NULL /* Don't define address */
- , audio_source
+ , 0
+ , NULL /* Don't define address */
+ , hw_module->state.audio_source
#endif
- );
+ );
+ if (ret < 0) {
+ if (config_diff(&config_in, &config_try, &diff_sample_rate, &diff_channel_mask, &diff_format)) {
+ pa_log_info("Could not open input stream, differences in%s%s%s",
+ diff_sample_rate ? " sample_rate" : "",
+ diff_channel_mask ? " channel_mask" : "",
+ diff_format ? " format" : "");
+ if (diff_sample_rate)
+ pa_log_info("Wanted sample_rate %d suggested %d", config_try.sample_rate, config_in.sample_rate);
+ if (diff_channel_mask)
+ pa_log_info("Wanted channel_mask %#010x suggested %#010x", config_try.channel_mask, config_in.channel_mask);
+ if (diff_format)
+ pa_log_info("Wanted format %#010x suggested %#010x", config_try.format, config_in.format);
+
+ if (!stream_config_convert(PA_DIRECTION_INPUT, &config_in, &sample_spec, &channel_map)) {
+ pa_log_warn("Failed to update PulseAudio structures from received config values.");
+ goto open_done;
+ }
+
+ config_try = config_in;
+ continue;
+ } else if (try_defaults) {
+ pa_log_info("Could not open input stream, trying with defaults.");
+ sample_spec = input->default_sample_spec;
+ channel_map = input->default_channel_map;
+
+ if (!stream_config_fill(s->device_def, hw_module->state.input_device, &sample_spec, &channel_map, &config_try))
+ goto done;
+
+ try_defaults = false;
+ continue;
+ } else {
+ pa_log_warn("Could not open input stream and no suggested changes received, bailing out.");
+ goto open_done;
+ }
+ } else if (config_diff(&config_in, &config_try, &diff_sample_rate, &diff_channel_mask, &diff_format)) {
+ pa_log_info("Opened input stream, but differences in%s%s%s",
+ diff_sample_rate ? " sample_rate" : "",
+ diff_channel_mask ? " channel_mask" : "",
+ diff_format ? " format" : "");
+ if (!stream_config_convert(PA_DIRECTION_INPUT, &config_in, &sample_spec, &channel_map)) {
+ pa_log_warn("Failed to update PulseAudio structures from received config values.");
+ input->stream->common.standby(&input->stream->common);
+ hw_module->device->close_input_stream(hw_module->device, input->stream);
+ input->stream = NULL;
+ ret = -1;
+ }
+ }
+
+ goto open_done;
+ }
+open_done:
pa_droid_hw_module_unlock(s->module);
- if (ret < 0 || !stream) {
- pa_logl(resume_from_suspend ? PA_LOG_DEBUG : PA_LOG_ERROR,
- "Failed to open input stream: %d with device: %u flags: %u sample rate: %u channels: %u (%u) format: %u (%u)",
- ret,
- input->device,
- 0, /* AUDIO_INPUT_FLAG_NONE on v3. v1 and v2 don't have input flags. */
- config_in.sample_rate,
- sample_spec.channels,
- config_in.channel_mask,
- sample_spec.format,
- config_in.format);
+ if (ret < 0 || !input->stream) {
+ log_input_open(resume_from_suspend ? PA_LOG_INFO : PA_LOG_ERROR, "Failed to open",
+ hw_module->state.input_device,
+ hw_module->state.audio_source,
+ 0, /* AUDIO_INPUT_FLAG_NONE on v3. v1 and v2 don't have input flags. */
+ &sample_spec,
+ &config_in,
+ ret);
+
goto done;
}
- input->stream = stream;
- input->input_sample_spec = sample_spec;
- input->input_channel_map = channel_map;
+ log_input_open(PA_LOG_INFO, "Opened",
+ hw_module->state.input_device,
+ hw_module->state.audio_source,
+ 0, /* AUDIO_INPUT_FLAG_NONE on v3. v1 and v2 don't have input flags. */
+ &sample_spec,
+ &config_in,
+ ret);
+
+ input->req_sample_spec = input->sample_spec = sample_spec;
+ input->req_channel_map = input->channel_map = channel_map;
buffer_size = input->stream->common.get_buffer_size(&input->stream->common);
- if (s->buffer_size != 0 && s->buffer_size != buffer_size)
- buffer_size_changed = true;
s->buffer_size = buffer_size;
- /* we need to call standby before reading with some devices. */
- input->stream->common.standby(&input->stream->common);
-
- pa_log_debug("Opened input stream %p", (void *) s);
+ /* Set input stream to standby */
+ stream_standby(s);
- input_stream_set_route(s, input->device);
-
- if (buffer_size_changed) {
- pa_log_debug("Input stream %p buffer size changed to %u.", (void *) s, s->buffer_size);
- pa_hook_fire(&s->module->hooks[PA_DROID_HOOK_INPUT_BUFFER_SIZE_CHANGED], (void *) s);
- }
+ /* As audio_source_t may not have any effect when opening the input stream
+ * set input parameters immediately after opening the stream. */
+ input_stream_set_route(s->module, s);
- if (channel_map_changed) {
- pa_log_debug("Input stream %p channel count changed to %d.", (void *) s, input->input_channel_map.channels);
- pa_hook_fire(&s->module->hooks[PA_DROID_HOOK_INPUT_CHANNEL_MAP_CHANGED], (void *) s);
- }
+ pa_log_debug("Opened input stream %p", (void *) s);
+ set_active_input(s->module, s);
done:
return ret;
}
static void input_stream_close(pa_droid_stream *s) {
- pa_droid_input_stream *input;
-
pa_assert(s);
pa_assert(s->input);
- pa_assert(s->input->stream);
- input = s->input;
+ if (!s->input->stream)
+ return;
pa_mutex_lock(s->module->input_mutex);
- s->module->device->close_input_stream(s->module->device, input->stream);
- input->stream = NULL;
+ set_active_input(s->module, NULL);
+ s->input->stream->common.standby(&s->input->stream->common);
+ s->module->device->close_input_stream(s->module->device, s->input->stream);
+ s->input->stream = NULL;
pa_log_debug("Closed input stream %p", (void *) s);
pa_mutex_unlock(s->module->input_mutex);
}
-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,
- pa_droid_mapping *am) {
-
- pa_droid_stream *s = NULL;
- pa_droid_input_stream *input = NULL;
- int ret = -1;
-
- s = droid_stream_new(module);
- s->input = input = droid_input_stream_new();
- input->sample_spec = *spec;
- input->channel_map = *map;
- input->flags = 0; /* AUDIO_INPUT_FLAG_NONE */
- input->device = devices;
- if (am)
- input->all_devices = am->input->devices | (am->input2 ? am->input2->devices : 0);
- else
- input->all_devices = devices;
-#if AUDIO_API_VERSION_MAJ >= 2
- input->all_devices &= ~AUDIO_DEVICE_BIT_IN;
-#endif
+bool pa_droid_stream_reconfigure_input(pa_droid_stream *s,
+ const pa_sample_spec *requested_sample_spec,
+ const pa_channel_map *requested_channel_map) {
+ pa_assert(s);
+ pa_assert(s->input);
+ pa_assert(requested_sample_spec);
+ pa_assert(requested_channel_map);
- if (am && am->input && am->input2)
- input->merged = true;
+ /* Copy our requested specs, so we know them when resuming from suspend
+ * as well. */
+ s->input->req_sample_spec = *requested_sample_spec;
+ s->input->req_channel_map = *requested_channel_map;
+
+ input_stream_close(s);
+
+ if (input_stream_open(s, false) < 0) {
+ if (!s->input->first) {
+ pa_log_debug("Input stream reconfigure failed, restore default values.");
+ s->input->req_sample_spec = s->input->default_sample_spec;
+ s->input->req_channel_map = s->input->default_channel_map;
+ input_stream_open(s, false);
+ }
+ return false;
+ }
- /* We need to open the stream for a while so that we can know
- * what sample rate we get. We need the rate for droid source. */
+ return true;
+}
- if ((ret = input_stream_open(s, false)) < 0)
- goto fail;
+pa_droid_stream *pa_droid_open_input_stream(pa_droid_hw_module *hw_module,
+ const pa_sample_spec *default_sample_spec,
+ const pa_channel_map *default_channel_map) {
- if ((input->sample_spec.rate = input->stream->common.get_sample_rate(&input->stream->common)) != spec->rate)
- pa_log_warn("Requested sample rate %u but got %u instead.", spec->rate, input->sample_spec.rate);
+ pa_droid_stream *s = NULL;
+ pa_droid_input_stream *input = NULL;
- pa_idxset_put(module->inputs, s, NULL);
+ pa_assert(hw_module);
+ pa_assert(default_sample_spec);
+ pa_assert(default_channel_map);
- pa_log_info("Opened droid input stream %p with device: %u flags: %u sample rate: %u channels: %u format: %u buffer size: %u (%llu usec)",
- (void *) s,
- devices,
- input->flags,
- input->sample_spec.rate,
- input->sample_spec.channels,
- input->sample_spec.format,
- s->buffer_size,
- pa_bytes_to_usec(s->buffer_size, &input->sample_spec));
+ if (hw_module->state.active_input) {
+ pa_log("Opening input stream while there is already active input stream.");
+ return NULL;
+ }
- /* As audio_source_t may not have any effect when opening the input stream
- * set input parameters immediately after opening the stream. */
- if (!s->input->merged && !pa_droid_quirk(module, QUIRK_CLOSE_INPUT))
- input_stream_set_route(s, devices);
+ s = droid_stream_new(hw_module, hw_module->enabled_module->inputs);
+ s->input = input = droid_input_stream_new();
+ s->input->default_sample_spec = *default_sample_spec;
+ s->input->default_channel_map = *default_channel_map;
- /* We start the stream in suspended state. */
- pa_droid_stream_suspend(s, true);
+ if (!pa_droid_stream_reconfigure_input(s, default_sample_spec, default_channel_map)) {
+ pa_droid_stream_unref(s);
+ s = NULL;
+ } else
+ s->input->first = false;
return s;
-
-fail:
- pa_xfree(input);
- pa_xfree(s);
-
- return NULL;
}
pa_droid_stream *pa_droid_stream_ref(pa_droid_stream *s) {
@@ -1578,19 +1700,16 @@
return;
if (s->output) {
+ pa_log_debug("Destroy output stream %p", (void *) s);
pa_mutex_lock(s->module->output_mutex);
pa_idxset_remove_by_data(s->module->outputs, s, NULL);
s->module->device->close_output_stream(s->module->device, s->output->stream);
pa_mutex_unlock(s->module->output_mutex);
pa_xfree(s->output);
} else {
- pa_mutex_lock(s->module->input_mutex);
+ pa_log_debug("Destroy input stream %p", (void *) s);
pa_idxset_remove_by_data(s->module->inputs, s, NULL);
- if (s->input->stream) {
- s->input->stream->common.standby(&s->input->stream->common);
- s->module->device->close_input_stream(s->module->device, s->input->stream);
- }
- pa_mutex_unlock(s->module->input_mutex);
+ input_stream_close(s);
pa_xfree(s->input);
}
@@ -1599,7 +1718,7 @@
pa_xfree(s);
}
-static pa_droid_stream *get_primary_output(pa_droid_hw_module *hw) {
+pa_droid_stream *pa_droid_hw_primary_output_stream(pa_droid_hw_module *hw) {
pa_droid_stream *s;
uint32_t idx;
@@ -1630,7 +1749,7 @@
pa_mutex_lock(s->module->output_mutex);
- if (output->flags & AUDIO_OUTPUT_FLAG_PRIMARY || get_primary_output(s->module) == NULL) {
+ if (output->flags & AUDIO_OUTPUT_FLAG_PRIMARY || pa_droid_hw_primary_output_stream(s->module) == NULL) {
parameters = pa_sprintf_malloc("%s=%u;", AUDIO_PARAMETER_STREAM_ROUTING, device);
pa_log_debug("output stream %p set_parameters(%s) %#010x", (void *) s, parameters, device);
@@ -1674,44 +1793,52 @@
return ret;
}
-static int input_stream_set_route(pa_droid_stream *s, audio_devices_t device) {
+static int input_stream_set_route(pa_droid_hw_module *hw_module, pa_droid_stream *s) {
pa_droid_input_stream *input;
- audio_source_t source = (uint32_t) -1;
- char *parameters;
+ audio_devices_t device;
+ audio_source_t source;
+ char *parameters = NULL;
int ret = 0;
- pa_assert(s);
- pa_assert(s->input);
- pa_assert(s->input->stream);
+ pa_assert(hw_module);
+
+ if (!s)
+ s = hw_module->state.active_input;
+
+ /* No active input, no need for set parameters */
+ if (!s)
+ goto done;
input = s->input;
+ /* Input stream closed, no need for set parameters */
+ if (!input->stream)
+ goto done;
+
+ device = hw_module->state.input_device;
+ source = hw_module->state.audio_source;
#ifdef DROID_DEVICE_I9305
device &= ~AUDIO_DEVICE_BIT_IN;
#endif
- if (pa_input_device_default_audio_source(device, &source)) {
- if (pa_droid_quirk(s->module, QUIRK_INPUT_ATOI))
- parameters = pa_sprintf_malloc("%s=%d;%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, (int32_t) device,
- AUDIO_PARAMETER_STREAM_INPUT_SOURCE, source);
- else
- parameters = pa_sprintf_malloc("%s=%u;%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, device,
- AUDIO_PARAMETER_STREAM_INPUT_SOURCE, source);
- } else
- parameters = pa_sprintf_malloc("%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, device);
+ if (pa_droid_quirk(hw_module, QUIRK_INPUT_ATOI))
+ parameters = pa_sprintf_malloc("%s=%d;%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, (int32_t) device,
+ AUDIO_PARAMETER_STREAM_INPUT_SOURCE, source);
+ else
+ parameters = pa_sprintf_malloc("%s=%u;%s=%u", AUDIO_PARAMETER_STREAM_ROUTING, device,
+ AUDIO_PARAMETER_STREAM_INPUT_SOURCE, source);
pa_log_debug("input stream %p set_parameters(%s) %#010x ; %#010x",
(void *) s, parameters, device, source);
-
- if (pa_droid_quirk(s->module, QUIRK_SET_PARAMETERS)) {
- pa_mutex_lock(s->module->hw_mutex);
- ret = s->module->device->set_parameters(s->module->device, parameters);
- pa_mutex_unlock(s->module->hw_mutex);
+ if (pa_droid_quirk(hw_module, QUIRK_SET_PARAMETERS)) {
+ pa_mutex_lock(hw_module->hw_mutex);
+ ret = hw_module->device->set_parameters(hw_module->device, parameters);
+ pa_mutex_unlock(hw_module->hw_mutex);
} else {
- pa_mutex_lock(s->module->input_mutex);
+ pa_mutex_lock(hw_module->input_mutex);
ret = input->stream->common.set_parameters(&input->stream->common, parameters);
- pa_mutex_unlock(s->module->input_mutex);
+ pa_mutex_unlock(hw_module->input_mutex);
}
if (ret < 0) {
@@ -1719,27 +1846,11 @@
pa_log_warn("input set_parameters(%s) not allowed while stream is active", parameters);
else
pa_log_warn("input set_parameters(%s) failed", parameters);
- } else
- input->device = device;
+ }
pa_xfree(parameters);
- return ret;
-}
-
-static int droid_input_stream_set_route(pa_droid_stream *s, audio_devices_t device) {
- int ret = 0;
-
- pa_assert(s);
- pa_assert(s->input);
-
- if (s->input->stream) {
- input_stream_set_route(s, device);
- } else {
- s->input->device = device;
- pa_log_debug("input stream (inactive) %p store route %#010x", (void *) s, device);
- }
-
+done:
return ret;
}
@@ -1748,8 +1859,10 @@
if (s->output)
return droid_output_stream_set_route(s, device);
- else
- return droid_input_stream_set_route(s, device);
+ else {
+ pa_droid_hw_set_input_device(s->module, device);
+ return input_stream_set_route(s->module, NULL);
+ }
}
int pa_droid_stream_set_parameters(pa_droid_stream *s, const char *parameters) {
@@ -1799,14 +1912,14 @@
pa_assert(s);
pa_assert(s->output || s->input);
+ if (s->output)
+ return s->output->flags & AUDIO_OUTPUT_FLAG_PRIMARY;
+
/* Even though earlier (< 3) HALs don't have input flags,
* input flags don't have anything similar as output stream's
- * primary flag and we can just always reply false for
+ * primary flag and we can just always reply true for
* input streams. */
- if (s->output)
- return s->output->flags & AUDIO_OUTPUT_FLAG_PRIMARY;
- else
- return false;
+ return true;
}
int pa_droid_stream_suspend(pa_droid_stream *s, bool suspend) {
@@ -1816,20 +1929,19 @@
if (s->output) {
if (suspend) {
pa_atomic_dec(&s->module->active_outputs);
- return s->output->stream->common.standby(&s->output->stream->common);
+ return stream_standby(s);
} else {
pa_atomic_inc(&s->module->active_outputs);
}
} else {
if (suspend) {
if (s->input->stream) {
- if (s->input->merged || pa_droid_quirk(s->module, QUIRK_CLOSE_INPUT)) {
- s->input->stream->common.standby(&s->input->stream->common);
+ if (pa_droid_quirk(s->module, QUIRK_CLOSE_INPUT))
input_stream_close(s);
- } else
- return s->input->stream->common.standby(&s->input->stream->common);
+ else
+ return stream_standby(s);
}
- } else if (s->input->merged || pa_droid_quirk(s->module, QUIRK_CLOSE_INPUT))
+ } else if (pa_droid_quirk(s->module, QUIRK_CLOSE_INPUT))
return input_stream_open(s, true);
}
@@ -1898,9 +2010,141 @@
return buffer_size;
}
-pa_hook *pa_droid_hooks(pa_droid_hw_module *hw) {
+bool pa_droid_hw_has_mic_control(pa_droid_hw_module *hw) {
pa_assert(hw);
- pa_assert(PA_REFCNT_VALUE(hw) >= 1);
+ pa_assert(hw->device);
+
+ if (hw->device->set_mic_mute && hw->device->get_mic_mute) {
+ pa_log_info("Module has HAL mic mute control.");
+ return true;
+ }
+
+ pa_log_info("Module has soft mic mute control.");
+ return false;
+}
+
+int pa_droid_hw_mic_get_mute(pa_droid_hw_module *hw_module, bool *muted) {
+ int ret = 0;
+
+ pa_assert(hw_module);
+ pa_assert(hw_module->device);
+ pa_assert(hw_module->device->get_mic_mute);
+
+ pa_droid_hw_module_lock(hw_module);
+ if (hw_module->device->get_mic_mute(hw_module->device, muted) < 0) {
+ pa_log("Failed to get mute state.");
+ ret = -1;
+ }
+ pa_droid_hw_module_unlock(hw_module);
+
+ return ret;
+}
+
+void pa_droid_hw_mic_set_mute(pa_droid_hw_module *hw_module, bool muted) {
+ pa_assert(hw_module);
+ pa_assert(hw_module->device);
+ pa_assert(hw_module->device->set_mic_mute);
+
+ pa_droid_hw_module_lock(hw_module);
+ if (hw_module->device->set_mic_mute(hw_module->device, muted) < 0)
+ pa_log("Failed to set mute state to %smuted.", muted ? "" : "un");
+ pa_droid_hw_module_unlock(hw_module);
+}
+
+bool pa_droid_hw_set_mode(pa_droid_hw_module *hw_module, audio_mode_t mode) {
+ bool ret = true;
+
+ pa_assert(hw_module);
+ pa_assert(hw_module->device);
+
+ pa_log_info("Set mode to %s.", audio_mode_to_string(mode));
+
+ pa_droid_hw_module_lock(hw_module);
+ if (hw_module->device->set_mode(hw_module->device, mode) < 0) {
+ ret = false;
+ pa_log_warn("Failed to set mode.");
+ } else {
+ hw_module->state.mode = mode;
+ }
+ pa_droid_hw_module_unlock(hw_module);
+
+ /* Update possible audio source. */
+ pa_droid_hw_set_input_device(hw_module, hw_module->state.input_device);
+
+ return ret;
+}
+
+bool pa_droid_hw_set_input_device(pa_droid_hw_module *hw_module,
+ audio_devices_t device) {
+ audio_source_t audio_source = AUDIO_SOURCE_DEFAULT;
+ audio_source_t audio_source_override = AUDIO_SOURCE_DEFAULT;
+ bool device_changed = false;
+ bool source_changed = false;
+
+ pa_assert(hw_module);
+
+ if (hw_module->state.input_device != device) {
+ const char *name = NULL;
+ pa_log_debug("Set global input to %s (%#010x)",
+ pa_string_convert_input_device_num_to_str(device, &name)
+ ? name : "<unknown>",
+ device);
+ hw_module->state.input_device = device;
+ device_changed = true;
+ }
+
+ pa_input_device_default_audio_source(hw_module->state.input_device, &audio_source);
+
+ /* Override audio source based on mode. */
+ switch (hw_module->state.mode) {
+ case AUDIO_MODE_IN_CALL:
+ audio_source_override = AUDIO_SOURCE_VOICE_CALL;
+ break;
+ case AUDIO_MODE_IN_COMMUNICATION:
+ audio_source_override = AUDIO_SOURCE_VOICE_COMMUNICATION;
+ break;
+ default:
+ audio_source_override = audio_source;
+ break;
+ }
+
+ if (audio_source != audio_source_override) {
+ const char *from, *to;
+ pa_droid_audio_source_name(audio_source, &from);
+ pa_droid_audio_source_name(audio_source_override, &to);
+ pa_log_info("Audio mode %s, overriding audio source %s with %s",
+ audio_mode_to_string(hw_module->state.mode),
+ from ? from : "<unknown>",
+ to ? to : "<unknown>");
+ audio_source = audio_source_override;
+ }
+
+ if (audio_source != hw_module->state.audio_source) {
+ const char *name = NULL;
+ pa_log_debug("set global audio source to %s (%#010x)",
+ pa_droid_audio_source_name(audio_source, &name)
+ ? name : "<unknown>",
+ audio_source);
+ hw_module->state.audio_source = audio_source;
+ source_changed = true;
+ }
+
+ if (hw_module->state.active_input && (device_changed || source_changed))
+ input_stream_set_route(hw_module, NULL);
+
+ return true;
+}
+
+const pa_sample_spec *pa_droid_stream_sample_spec(pa_droid_stream *stream) {
+ pa_assert(stream);
+ pa_assert(stream->output || stream->input);
+
+ return stream->output ? &stream->output->sample_spec : &stream->input->sample_spec;
+}
+
+const pa_channel_map *pa_droid_stream_channel_map(pa_droid_stream *stream) {
+ pa_assert(stream);
+ pa_assert(stream->output || stream->input);
- return hw->hooks;
+ return stream->output ? &stream->output->channel_map : &stream->input->channel_map;
}
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/common/include/droid/conversion.h
^
|
@@ -55,6 +55,8 @@
CONV_STRING_INPUT_FLAG
} pa_conversion_string_t;
+bool pa_string_convert_num_to_str(pa_conversion_string_t type, uint32_t value, const char **to_str);
+
bool pa_convert_output_channel(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
bool pa_convert_input_channel(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
bool pa_convert_format(uint32_t value, pa_conversion_field_t from, uint32_t *to_value);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/common/include/droid/droid-config.h
^
|
@@ -91,6 +91,8 @@
pa_droid_config_audio *pa_parse_droid_audio_config(const char *filename);
const pa_droid_config_hw_module *pa_droid_config_find_module(const pa_droid_config_audio *config, const char* module_id);
+const pa_droid_config_device *pa_droid_config_find_output(const pa_droid_config_hw_module *module, const char* output_name);
+const pa_droid_config_device *pa_droid_config_find_input(const pa_droid_config_hw_module *module, const char* input_name);
pa_droid_config_hw_module *pa_droid_config_hw_module_new(const pa_droid_config_audio *config, const char *name);
void pa_droid_config_hw_module_free(pa_droid_config_hw_module *hw_module);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/common/include/droid/droid-util.h
^
|
@@ -92,13 +92,18 @@
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;
pa_droid_quirks *quirks;
- pa_hook hooks[PA_DROID_HOOK_MAX];
+
+ /* Mode and input control */
+ struct _state {
+ audio_mode_t mode;
+ audio_devices_t input_device;
+ audio_source_t audio_source;
+ pa_droid_stream *active_input;
+ } state;
};
struct pa_droid_output_stream {
@@ -111,20 +116,22 @@
struct pa_droid_input_stream {
struct audio_stream_in *stream;
+ pa_sample_spec default_sample_spec;
+ pa_channel_map default_channel_map;
pa_sample_spec sample_spec;
pa_channel_map channel_map;
- pa_sample_spec input_sample_spec;
- pa_channel_map input_channel_map;
+ pa_sample_spec req_sample_spec;
+ pa_channel_map req_channel_map;
uint32_t flags;
uint32_t device;
- audio_devices_t all_devices;
- bool merged;
+ bool first;
};
struct pa_droid_stream {
PA_REFCNT_DECLARE;
pa_droid_hw_module *module;
+ const pa_droid_config_device *device_def;
size_t buffer_size;
void *data;
@@ -162,8 +169,8 @@
pa_droid_profile_set *profile_set;
const pa_droid_config_device *output;
- const pa_droid_config_device *input;
- const pa_droid_config_device *input2;
+ /* Use all devices in one input */
+ const pa_droid_config_device *inputs;
char *name;
char *description;
@@ -189,9 +196,12 @@
unsigned priority;
/* Idxsets contain pa_droid_mapping objects.
- * Profile doesn't own the mappings. */
+ * Profile doesn't own the mappings, these
+ * are references to structs in profile set
+ * hashmaps. */
pa_idxset *output_mappings;
- pa_idxset *input_mappings;
+ /* Only one input */
+ pa_droid_mapping *input_mapping;
} pa_droid_profile;
@@ -216,6 +226,8 @@
QUIRK_OUTPUT_MAKE_WRITABLE,
QUIRK_REALCALL,
QUIRK_UNLOAD_CALL_EXIT,
+ QUIRK_OUTPUT_FAST,
+ QUIRK_OUTPUT_DEEP_BUFFER,
QUIRK_COUNT
};
@@ -240,24 +252,24 @@
return hw->quirks && hw->quirks->enabled[quirk];
}
+bool pa_droid_hw_set_mode(pa_droid_hw_module *hw_module, audio_mode_t mode);
+bool pa_droid_hw_has_mic_control(pa_droid_hw_module *hw);
+int pa_droid_hw_mic_get_mute(pa_droid_hw_module *hw_module, bool *muted);
+void pa_droid_hw_mic_set_mute(pa_droid_hw_module *hw_module, bool muted);
+
/* 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_default_new(const pa_droid_config_hw_module *module,
- bool merge_inputs);
+pa_droid_profile_set *pa_droid_profile_set_default_new(const pa_droid_config_hw_module *module);
void pa_droid_profile_set_free(pa_droid_profile_set *ps);
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, const pa_droid_config_device *device);
-pa_droid_mapping *pa_droid_mapping_merged_get(pa_droid_profile_set *ps,
- const pa_droid_config_device *input1,
- const pa_droid_config_device *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.
@@ -267,10 +279,9 @@
* 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);
-pa_hook *pa_droid_hooks(pa_droid_hw_module *hw);
-
/* Module operations */
int pa_droid_set_parameters(pa_droid_hw_module *hw, const char *parameters);
+pa_droid_stream *pa_droid_hw_primary_output_stream(pa_droid_hw_module *hw);
/* Stream operations */
pa_droid_stream *pa_droid_stream_ref(pa_droid_stream *s);
@@ -282,7 +293,7 @@
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,
+ const char *module_output_name,
audio_devices_t devices);
/* Set routing to the input or output stream, with following side-effects:
@@ -296,12 +307,19 @@
*/
int pa_droid_stream_set_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,
- pa_droid_mapping *am);
+/* Open input stream with currently active routing, sample_spec and channel_map
+ * are requests and may change when opening the stream. */
+pa_droid_stream *pa_droid_open_input_stream(pa_droid_hw_module *hw_module,
+ const pa_sample_spec *default_sample_spec,
+ const pa_channel_map *default_channel_map);
+bool pa_droid_stream_reconfigure_input(pa_droid_stream *s,
+ const pa_sample_spec *requested_sample_spec,
+ const pa_channel_map *requested_channel_map);
+bool pa_droid_hw_set_input_device(pa_droid_hw_module *hw_module,
+ audio_devices_t device);
+
+const pa_sample_spec *pa_droid_stream_sample_spec(pa_droid_stream *stream);
+const pa_channel_map *pa_droid_stream_channel_map(pa_droid_stream *stream);
bool pa_droid_stream_is_primary(pa_droid_stream *s);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/droid/Makefile.am
^
|
@@ -15,17 +15,11 @@
modlibexec_LTLIBRARIES = \
libdroid-sink.la \
libdroid-source.la \
- module-droid-keepalive.la \
module-droid-sink.la \
module-droid-source.la \
module-droid-card.la
-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,-z,noexecstack
-module_droid_keepalive_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS)
-module_droid_keepalive_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
+noinst_HEADERS = module-droid-sink-symdef.h module-droid-source-symdef.h module-droid-card-symdef.h
libdroid_sink_la_SOURCES = droid-sink.c droid-sink.h
libdroid_sink_la_LDFLAGS = -avoid-version -Wl,-z,noexecstack -lhybris-common
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/droid/droid-sink.c
^
|
@@ -54,6 +54,7 @@
#include <pulsecore/time-smoother.h>
#include <pulsecore/hashmap.h>
#include <pulsecore/core-subscribe.h>
+#include <pulse/version.h>
#include "droid-sink.h"
#include <droid/droid-util.h>
@@ -371,7 +372,11 @@
pa_log_debug("Thread starting up.");
if (u->core->realtime_scheduling)
+#if PA_CHECK_VERSION(13,0,0)
+ pa_thread_make_realtime(u->core->realtime_priority);
+#else
pa_make_realtime(u->core->realtime_priority);
+#endif
pa_thread_mq_install(&u->thread_mq);
@@ -398,11 +403,7 @@
pa_rtpoll_set_timer_disabled(u->rtpoll);
/* Sleep */
-#if (PULSEAUDIO_VERSION == 5)
- if ((ret = pa_rtpoll_run(u->rtpoll, true)) < 0)
-#elif (PULSEAUDIO_VERSION >= 6)
if ((ret = pa_rtpoll_run(u->rtpoll)) < 0)
-#endif
goto fail;
if (ret == 0)
@@ -1045,6 +1046,7 @@
pa_card *card) {
struct userdata *u = NULL;
+ const pa_droid_config_device *output = NULL;
bool deferred_volume = false;
char *thread_name = NULL;
pa_sink_new_data data;
@@ -1067,15 +1069,18 @@
pa_assert(ma);
pa_assert(driver);
+ pa_log_info("Create new droid-sink");
+
deferred_volume = m->core->deferred_volume;
if (pa_modargs_get_value_boolean(ma, "deferred_volume", &deferred_volume) < 0) {
pa_log("Failed to parse deferred_volume argument.");
goto fail;
}
- if (card && am)
- module_id = am->output->module->name;
- else
+ if (card && am) {
+ output = am->output;
+ module_id = output->module->name;
+ } else
module_id = pa_modargs_get_value(ma, "module_id", DEFAULT_MODULE_ID);
sample_spec = m->core->default_sample_spec;
@@ -1149,6 +1154,18 @@
pa_assert(card);
pa_assert_se((u->hw_module = pa_droid_hw_module_get(u->core, NULL, card_data->module_id)));
} else {
+ const char *output_name;
+
+ if (!(output_name = pa_modargs_get_value(ma, "output", NULL))) {
+ pa_log("No output name defined.");
+ goto fail;
+ }
+
+ if (!(output = pa_droid_config_find_output(u->hw_module->enabled_module, output_name))) {
+ pa_log("Could not find output %s from module %s.", output_name, u->hw_module->enabled_module->name);
+ goto fail;
+ }
+
/* Sink wasn't created from inside card module, so we'll need to open
* hw module ourself.
*
@@ -1168,8 +1185,8 @@
}
/* Default routing */
- dev_out = (am && am->output->module->global_config) ? am->output->module->global_config->default_output_device
- : u->hw_module->config->global_config->default_output_device;
+ dev_out = output->module->global_config ? output->module->global_config->default_output_device
+ : u->hw_module->config->global_config->default_output_device;
if ((tmp = pa_modargs_get_value(ma, "output_devices", NULL))) {
audio_devices_t tmp_dev;
@@ -1180,10 +1197,9 @@
pa_log_debug("Set initial devices %s", tmp);
}
- if (am)
- flags = am->output->flags;
+ flags = output->flags;
- u->stream = pa_droid_open_output_stream(u->hw_module, &sample_spec, &channel_map, flags, dev_out);
+ u->stream = pa_droid_open_output_stream(u->hw_module, &sample_spec, &channel_map, output->name, dev_out);
if (!u->stream) {
pa_log("Failed to open output stream.");
@@ -1198,7 +1214,7 @@
pa_log_info("Using buffer size %u.", u->buffer_size);
if ((prewrite_resume = pa_modargs_get_value(ma, "prewrite_on_resume", NULL))) {
- if (!parse_prewrite_on_resume(u, prewrite_resume, am ? am->output->name : module_id)) {
+ if (!parse_prewrite_on_resume(u, prewrite_resume, output->name)) {
pa_log("Failed to parse prewrite_on_resume (%s)", prewrite_resume);
goto fail;
}
@@ -1215,10 +1231,7 @@
data.module = m;
data.card = card;
- if (am)
- set_sink_name(ma, &data, am->output->name);
- else
- set_sink_name(ma, &data, module_id);
+ set_sink_name(ma, &data, output->name);
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, PROP_DROID_API_STRING);
@@ -1284,10 +1297,7 @@
/* Rewind internal memblockq */
pa_sink_set_max_rewind(u->sink, 0);
- if (am)
- thread_name = pa_sprintf_malloc("droid-sink-%s", am->output->name);
- else
- thread_name = pa_sprintf_malloc("droid-sink-%s", module_id);
+ thread_name = pa_sprintf_malloc("droid-sink-%s", output->name);
if (!(u->thread = pa_thread_new(thread_name, thread_func, u))) {
pa_log("Failed to create thread.");
goto fail;
@@ -1328,9 +1338,6 @@
pa_droid_config_free(config);
pa_xfree(thread_name);
- if (config)
- pa_xfree(config);
-
if (u)
userdata_free(u);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/droid/droid-source.c
^
|
@@ -51,6 +51,7 @@
#include <pulsecore/rtpoll.h>
#include <pulsecore/time-smoother.h>
#include <pulsecore/resampler.h>
+#include <pulse/version.h>
#include "droid-source.h"
#include <droid/droid-util.h>
@@ -73,8 +74,6 @@
size_t buffer_size;
pa_usec_t timestamp;
- pa_hook_slot *input_buffer_size_changed_slot;
- pa_hook_slot *input_channel_map_changed_slot;
pa_resampler *resampler;
pa_droid_card_data *card_data;
@@ -83,10 +82,6 @@
bool stream_valid;
};
-enum {
- SOURCE_MESSAGE_DO_ROUTING = PA_SOURCE_MESSAGE_MAX
-};
-
#define DEFAULT_MODULE_ID "primary"
#define DROID_AUDIO_SOURCE "droid.audio_source"
@@ -95,13 +90,22 @@
static void userdata_free(struct userdata *u);
static int suspend(struct userdata *u);
static void unsuspend(struct userdata *u);
+static void source_reconfigure(struct userdata *u,
+ const pa_sample_spec *reconfigure_sample_spec,
+ const pa_channel_map *reconfigure_channel_map,
+ audio_devices_t update_device);
+
+/* Our droid source may be left in a state of not having an input stream
+ * if reconfiguration fails and fallback to previously active values fails
+ * as well. In this case just avoid using the stream but don't die. */
+#define assert_stream(x, action) if (!x) do { pa_log_warn("Assert " #x " failed."); action; } while(0)
static int do_routing(struct userdata *u, audio_devices_t devices) {
int ret;
audio_devices_t old_device;
pa_assert(u);
- pa_assert(u->stream);
+ assert_stream(u->stream, return 0);
if (u->primary_devices == devices)
pa_log_debug("Refresh active device routing.");
@@ -157,7 +161,7 @@
if (!u->stream_valid) {
p = pa_memblock_acquire(chunk.memblock);
chunk.length = pa_memblock_get_length(chunk.memblock);
- memset(p, 0, chunk.length);
+ pa_silence_memory(p, chunk.length, &u->source->sample_spec);
pa_source_post(u->source, &chunk);
pa_memblock_release(chunk.memblock);
goto end;
@@ -208,7 +212,11 @@
pa_log_debug("Thread starting up.");
if (u->core->realtime_scheduling)
+#if PA_CHECK_VERSION(13,0,0)
+ pa_thread_make_realtime(u->core->realtime_priority);
+#else
pa_make_realtime(u->core->realtime_priority);
+#endif
pa_thread_mq_install(&u->thread_mq);
@@ -225,11 +233,7 @@
pa_rtpoll_set_timer_disabled(u->rtpoll);
/* Sleep */
-#if (PULSEAUDIO_VERSION == 5)
- if ((ret = pa_rtpoll_run(u->rtpoll, true)) < 0)
-#elif (PULSEAUDIO_VERSION >= 6)
if ((ret = pa_rtpoll_run(u->rtpoll)) < 0)
-#endif
goto fail;
if (ret == 0)
@@ -252,7 +256,7 @@
int ret;
pa_assert(u);
- pa_assert(u->stream);
+ assert_stream(u->stream, return 0);
ret = pa_droid_stream_suspend(u->stream, true);
@@ -265,9 +269,10 @@
/* Called from IO context */
static void unsuspend(struct userdata *u) {
pa_assert(u);
- pa_assert(u->stream);
- if (pa_droid_stream_suspend(u->stream, false) >= 0) {
+ if (!u->stream) {
+ assert_stream(u->stream, u->stream_valid = false);
+ } else if (pa_droid_stream_suspend(u->stream, false) >= 0) {
u->stream_valid = true;
pa_log_info("Resuming...");
} else
@@ -321,28 +326,17 @@
/* Called from IO context */
static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+#if PULSEAUDIO_VERSION < 12
struct userdata *u = PA_SOURCE(o)->userdata;
switch (code) {
- case SOURCE_MESSAGE_DO_ROUTING: {
- audio_devices_t device = PA_PTR_TO_UINT(data);
-
- pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state));
-
- suspend(u);
- do_routing(u, device);
- unsuspend(u);
- break;
- }
-
-#if PULSEAUDIO_VERSION < 12
case PA_SOURCE_MESSAGE_SET_STATE: {
int r;
if ((r = source_set_state_in_io_thread_cb(u->source, PA_PTR_TO_UINT(data), 0)) < 0)
return r;
}
-#endif
}
+#endif
return pa_source_process_msg(o, code, data, offset, chunk);
}
@@ -364,13 +358,12 @@
return 0;
}
- pa_log_debug("Source set port %u", data->device);
+ pa_log_debug("Source set port %#010x", data->device);
- if (!PA_SOURCE_IS_OPENED(pa_source_get_state(u->source)))
+ if (!PA_SOURCE_IS_OPENED(u->source->state))
do_routing(u, data->device);
- else {
- pa_asyncmsgq_post(u->source->asyncmsgq, PA_MSGOBJECT(u->source), SOURCE_MESSAGE_DO_ROUTING, PA_UINT_TO_PTR(data->device), 0, NULL, NULL);
- }
+ else
+ source_reconfigure(u, NULL, NULL, data->device);
return 0;
}
@@ -396,60 +389,30 @@
}
}
-#if (PULSEAUDIO_VERSION == 5)
-static void source_get_mute_cb(pa_source *s) {
-#elif (PULSEAUDIO_VERSION >= 6)
static int source_get_mute_cb(pa_source *s, bool *muted) {
-#endif
struct userdata *u = s->userdata;
- int ret = 0;
- bool b;
pa_assert(u);
- pa_assert(u->hw_module && u->hw_module->device);
-
- pa_droid_hw_module_lock(u->hw_module);
- if (u->hw_module->device->get_mic_mute(u->hw_module->device, &b) < 0) {
- pa_log("Failed to get mute state.");
- ret = -1;
- }
- pa_droid_hw_module_unlock(u->hw_module);
+ pa_assert(u->hw_module);
-#if (PULSEAUDIO_VERSION == 5)
- if (ret == 0)
- s->muted = b;
-#elif (PULSEAUDIO_VERSION >= 6)
- if (ret == 0)
- *muted = b;
-
- return ret;
-#endif
+ return pa_droid_hw_mic_get_mute(u->hw_module, muted);
}
static void source_set_mute_cb(pa_source *s) {
struct userdata *u = s->userdata;
pa_assert(u);
- pa_assert(u->hw_module && u->hw_module->device);
- pa_droid_hw_module_lock(u->hw_module);
- if (u->hw_module->device->set_mic_mute(u->hw_module->device, s->muted) < 0)
- pa_log("Failed to set mute state to %smuted.", s->muted ? "" : "un");
- pa_droid_hw_module_unlock(u->hw_module);
+ pa_droid_hw_mic_set_mute(u->hw_module, s->muted);
}
static void source_set_mute_control(struct userdata *u) {
pa_assert(u);
pa_assert(u->hw_module && u->hw_module->device);
- if (u->hw_module->device->set_mic_mute) {
- pa_log_info("Using hardware mute control for %s", u->source->name);
+ if (pa_droid_hw_has_mic_control(u->hw_module)) {
pa_source_set_get_mute_callback(u->source, source_get_mute_cb);
pa_source_set_set_mute_callback(u->source, source_set_mute_cb);
- } else {
- pa_log_info("Using software mute control for %s", u->source->name);
- pa_source_set_get_mute_callback(u->source, NULL);
- pa_source_set_set_mute_callback(u->source, NULL);
}
}
@@ -457,9 +420,13 @@
static void update_latency(struct userdata *u) {
pa_assert(u);
pa_assert(u->source);
- pa_assert(u->stream);
- u->buffer_size = pa_droid_stream_buffer_size(u->stream);
+ if (u->stream)
+ u->buffer_size = pa_droid_stream_buffer_size(u->stream);
+ else
+ u->buffer_size = 1024; /* Random valid value */
+
+ assert_stream(u->stream, return);
if (u->source_buffer_size) {
u->buffer_size = pa_droid_buffer_size_round_up(u->source_buffer_size, u->buffer_size);
@@ -468,55 +435,123 @@
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->input->sample_spec));
+ pa_source_set_fixed_latency_within_thread(u->source, pa_bytes_to_usec(u->buffer_size, pa_droid_stream_sample_spec(u->stream)));
else
- pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, &u->stream->input->sample_spec));
+ pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, pa_droid_stream_sample_spec(u->stream)));
- pa_log_debug("Set fixed latency %" PRIu64 " usec", 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, pa_droid_stream_sample_spec(u->stream)));
}
-/* Called from IO context. */
-static pa_hook_result_t input_buffer_size_changed_cb(pa_droid_hw_module *module,
- pa_droid_stream *stream,
- struct userdata *u) {
- pa_assert(module);
- pa_assert(stream);
- pa_assert(u);
+static void source_reconfigure(struct userdata *u,
+ const pa_sample_spec *reconfigure_sample_spec,
+ const pa_channel_map *reconfigure_channel_map,
+ audio_devices_t update_device) {
+ pa_channel_map old_channel_map;
+ pa_sample_spec old_sample_spec;
+ pa_channel_map new_channel_map;
+ pa_sample_spec new_sample_spec;
+ pa_queue *source_outputs = NULL;
- if (stream != u->stream)
- return PA_HOOK_OK;
+ if (pa_source_used_by(u->source)) {
+ /* If we already have connected source outputs detach those
+ * so that when re-attaching them to our source resampling etc.
+ * is renegotiated correctly. */
+ source_outputs = pa_source_move_all_start(u->source, NULL);
+ }
+
+ pa_source_suspend(u->source, true, PA_SUSPEND_UNAVAILABLE);
+
+ old_channel_map = *pa_droid_stream_channel_map(u->stream);
+ old_sample_spec = *pa_droid_stream_sample_spec(u->stream);
+ new_channel_map = reconfigure_channel_map ? *reconfigure_channel_map : old_channel_map;
+ new_sample_spec = reconfigure_sample_spec ? *reconfigure_sample_spec : old_sample_spec;
+
+ if (update_device)
+ do_routing(u, update_device);
+
+ if (pa_droid_stream_reconfigure_input(u->stream, &new_sample_spec, &new_channel_map))
+ pa_log_info("Source reconfigured.");
+ else
+ pa_log_info("Failed to reconfigure input stream, no worries, using defaults.");
+
+ /* We need to be really careful here as we are modifying
+ * quite profound internal structures. */
+ new_sample_spec = *pa_droid_stream_sample_spec(u->stream);
+ new_channel_map = *pa_droid_stream_channel_map(u->stream);
+ u->source->channel_map = new_channel_map;
+ u->source->sample_spec = new_sample_spec;
+ pa_assert_se(pa_cvolume_remap(&u->source->reference_volume, &old_channel_map, &new_channel_map));
+ pa_assert_se(pa_cvolume_remap(&u->source->real_volume, &old_channel_map, &new_channel_map));
+ pa_assert_se(pa_cvolume_remap(&u->source->soft_volume, &old_channel_map, &new_channel_map));
update_latency(u);
+ pa_source_suspend(u->source, false, PA_SUSPEND_UNAVAILABLE);
- return PA_HOOK_OK;
+ if (source_outputs && u->source) {
+ pa_source_move_all_finish(u->source, source_outputs, false);
+ }
}
-/* Called from IO context. */
-static pa_hook_result_t input_channel_map_changed_cb(pa_droid_hw_module *module,
- pa_droid_stream *stream,
- struct userdata *u) {
- pa_assert(module);
- pa_assert(stream);
- pa_assert(u);
+static pa_hook_result_t source_output_new_hook_callback(void *hook_data,
+ void *call_data,
+ void *slot_data) {
+ pa_source_output_new_data *new_data = call_data;
+ struct userdata *u = slot_data;
+ pa_droid_stream *primary_output;
+
+ /* Not meant for us */
+ if (new_data->source != u->source)
+ return PA_HOOK_OK;
- if (stream != u->stream)
+ if (pa_sample_spec_equal(&new_data->sample_spec, pa_droid_stream_sample_spec(u->stream)) &&
+ pa_channel_map_equal(&new_data->channel_map, pa_droid_stream_channel_map(u->stream)))
return PA_HOOK_OK;
- 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->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,
- 0);
- } else if (u->resampler) {
- pa_resampler_free(u->resampler);
- u->resampler = NULL;
+ pa_log_info("New source-output connecting and our source needs to be reconfigured.");
+
+ /* Workaround for fm-radio loopback */
+ if (pa_safe_streq(pa_proplist_gets(new_data->proplist, "media.name"), "fmradio-loopback-source") &&
+ (primary_output = pa_droid_hw_primary_output_stream(u->hw_module))) {
+ pa_log_debug("Workaround for fm-radio loopback.");
+ source_reconfigure(u,
+ pa_droid_stream_sample_spec(primary_output),
+ pa_droid_stream_channel_map(primary_output),
+ 0);
+
+ } else
+ source_reconfigure(u, &new_data->sample_spec, &new_data->channel_map, 0);
+
+ return PA_HOOK_OK;
+}
+
+static void source_reconfigure_after_changes(struct userdata *u) {
+ pa_source_output *so = NULL;
+ pa_source_output *so_i;
+ void *state = NULL;
+
+ if (!pa_source_used_by(u->source))
+ return;
+
+ /* Find last inserted source-output */
+ so = pa_idxset_iterate(u->source->outputs, &state, NULL);
+ if (so) {
+ while ((so_i = pa_idxset_iterate(u->source->outputs, &state, NULL)))
+ so = so_i;
+ }
+
+ if (so) {
+ if (!pa_sample_spec_equal(&so->sample_spec, pa_droid_stream_sample_spec(u->stream)) ||
+ !pa_channel_map_equal(&so->channel_map, pa_droid_stream_channel_map(u->stream))) {
+ pa_log_info("Source-output disconnected and our source needs to be reconfigured.");
+ source_reconfigure(u, &so->sample_spec, &so->channel_map, 0);
+ }
}
+}
+static pa_hook_result_t source_output_unlink_post_hook_callback(void *hook_data,
+ void *call_data,
+ void *slot_data) {
+ source_reconfigure_after_changes(slot_data);
return PA_HOOK_OK;
}
@@ -546,9 +581,11 @@
pa_assert(ma);
pa_assert(driver);
+ pa_log_info("Create new droid-source");
+
/* When running under card use hw module name for source by default. */
if (am)
- module_id = am->input->module->name;
+ module_id = am->inputs->module->name;
else
module_id = pa_modargs_get_value(ma, "module_id", DEFAULT_MODULE_ID);
@@ -649,10 +686,8 @@
}
}
- 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);
+ pa_droid_hw_set_input_device(u->hw_module, dev_in);
+ u->stream = pa_droid_open_input_stream(u->hw_module, &sample_spec, &channel_map);
if (!u->stream) {
pa_log("Failed to open input stream.");
@@ -663,6 +698,7 @@
data.driver = driver;
data.module = m;
data.card = card;
+ /* Start suspended */
data.suspend_cause = PA_SUSPEND_IDLE;
if (am)
@@ -672,6 +708,8 @@
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, PROP_DROID_API_STRING);
+ pa_proplist_sets(data.proplist, PROP_DROID_INPUT_EXTERNAL, "true");
+ pa_proplist_sets(data.proplist, PROP_DROID_INPUT_BUILTIN, "true");
/* We need to give pa_modargs_get_value_boolean() a pointer to a local
* variable instead of using &data.namereg_fail directly, because
@@ -685,8 +723,8 @@
}
data.namereg_fail = namereg_fail;
- 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_sample_spec(&data, pa_droid_stream_sample_spec(u->stream));
+ pa_source_new_data_set_channel_map(&data, pa_droid_stream_channel_map(u->stream));
pa_source_new_data_set_alternate_sample_rate(&data, alternate_sample_rate);
if (am && card)
@@ -730,17 +768,23 @@
if (u->source->active_port)
source_set_port_cb(u->source, u->source->active_port);
- u->input_buffer_size_changed_slot = pa_hook_connect(&pa_droid_hooks(u->hw_module)[PA_DROID_HOOK_INPUT_BUFFER_SIZE_CHANGED],
- PA_HOOK_NORMAL,
- (pa_hook_cb_t) input_buffer_size_changed_cb, u);
-
- u->input_channel_map_changed_slot = pa_hook_connect(&pa_droid_hooks(u->hw_module)[PA_DROID_HOOK_INPUT_CHANNEL_MAP_CHANGED],
- PA_HOOK_NORMAL,
- (pa_hook_cb_t) input_channel_map_changed_cb, u);
+ /* Since we started in suspended mode suspend our stream immediately as well. */
+ pa_droid_stream_suspend(u->stream, true);
pa_droid_stream_set_data(u->stream, u->source);
pa_source_put(u->source);
+ /* As late as possible */
+ pa_module_hook_connect(u->module,
+ &u->module->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW],
+ PA_HOOK_LATE * 2,
+ source_output_new_hook_callback, u);
+
+ pa_module_hook_connect(u->module,
+ &u->module->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_UNLINK_POST],
+ PA_HOOK_LATE * 2,
+ source_output_unlink_post_hook_callback, u);
+
return u->source;
fail:
@@ -765,12 +809,6 @@
static void userdata_free(struct userdata *u) {
pa_assert(u);
- if (u->input_channel_map_changed_slot)
- pa_hook_slot_free(u->input_channel_map_changed_slot);
-
- if (u->input_buffer_size_changed_slot)
- pa_hook_slot_free(u->input_buffer_size_changed_slot);
-
if (u->source)
pa_source_unlink(u->source);
@@ -790,7 +828,6 @@
if (u->stream)
pa_droid_stream_unref(u->stream);
- // Stand alone source
if (u->hw_module)
pa_droid_hw_module_unref(u->hw_module);
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/droid/module-droid-card.c
^
|
@@ -60,6 +60,7 @@
//#include <droid/system/audio_policy.h>
#include <droid/droid-util.h>
+#include <droid/sllist.h>
#include "droid-sink.h"
#include "droid-source.h"
@@ -82,7 +83,7 @@
"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> "
"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> "
+ "merge_inputs=<unused, always true> "
"quirks=<comma separated list of quirks to enable/disable>"
);
@@ -116,6 +117,7 @@
"voice_property_value",
"default_profile",
"combine",
+ "merge_inputs",
"quirks",
NULL,
};
@@ -138,8 +140,8 @@
typedef bool (*virtual_profile_event_cb)(struct userdata *u, pa_droid_profile *p, bool enabling);
struct virtual_profile {
+ bool enabled;
pa_card_profile *parent;
- pa_card_profile *extension;
virtual_profile_event_cb event_cb;
};
@@ -156,14 +158,15 @@
pa_droid_hw_module *hw_module;
pa_droid_card_data card_data;
- pa_droid_profile *old_profile;
+ pa_card_profile *real_profile;
pa_modargs *modargs;
pa_card *card;
};
struct profile_data {
- pa_droid_profile *profile;
+ pa_droid_profile *droid_profile;
+ pa_card_profile *card_profile;
audio_mode_t mode;
bool virtual_profile;
/* Variables for virtual profiles: */
@@ -177,10 +180,12 @@
#define AUDIO_PARAMETER_KEY_CALL_STATE "call_state"
/* From hal/voice_extn/voice_extn.c */
-#define VOICE2_VSID 0x10DC1000
-#define VOLTE_VSID 0x10C02000
-#define QCHAT_VSID 0x10803000
-#define VOWLAN_VSID 0x10002000
+#define VOICE2_VSID (0x10DC1000)
+#define VOLTE_VSID (0x10C02000)
+#define QCHAT_VSID (0x10803000)
+#define VOWLAN_VSID (0x10002000)
+#define VOICEMMODE1_VSID (0x11C05000)
+#define VOICEMMODE2_VSID (0x11DC5000)
/* From hal/voice.h */
#define BASE_CALL_STATE 1
@@ -189,22 +194,28 @@
#define VOICE_VSID 0x10C01000
/* For virtual profiles */
-#define VOICE_SESSION_VOICE1_PROFILE_NAME "voicecall-voice1"
-#define VOICE_SESSION_VOICE1_PROFILE_DESC "Call mode, default to voice 1 vsid"
-#define VOICE_SESSION_VOICE2_PROFILE_NAME "voicecall-voice2"
-#define VOICE_SESSION_VOICE2_PROFILE_DESC "Call mode, default to voice 2 vsid"
-#define VOICE_SESSION_VOLTE_PROFILE_NAME "voicecall-volte"
-#define VOICE_SESSION_VOLTE_PROFILE_DESC "Call mode, default to volte vsid"
-#define VOICE_SESSION_QCHAT_PROFILE_NAME "voicecall-qchat"
-#define VOICE_SESSION_QCHAT_PROFILE_DESC "Call mode, default to qchat vsid"
-#define VOICE_SESSION_VOWLAN_PROFILE_NAME "voicecall-vowlan"
-#define VOICE_SESSION_VOWLAN_PROFILE_DESC "Call mode, default to vowlan vsid"
+#define VOICE_SESSION_VOICE1_PROFILE_NAME "voicecall-voice1"
+#define VOICE_SESSION_VOICE1_PROFILE_DESC "Call mode, default to voice 1 vsid"
+#define VOICE_SESSION_VOICE2_PROFILE_NAME "voicecall-voice2"
+#define VOICE_SESSION_VOICE2_PROFILE_DESC "Call mode, default to voice 2 vsid"
+#define VOICE_SESSION_VOLTE_PROFILE_NAME "voicecall-volte"
+#define VOICE_SESSION_VOLTE_PROFILE_DESC "Call mode, default to volte vsid"
+#define VOICE_SESSION_QCHAT_PROFILE_NAME "voicecall-qchat"
+#define VOICE_SESSION_QCHAT_PROFILE_DESC "Call mode, default to qchat vsid"
+#define VOICE_SESSION_VOWLAN_PROFILE_NAME "voicecall-vowlan"
+#define VOICE_SESSION_VOWLAN_PROFILE_DESC "Call mode, default to vowlan vsid"
+#define VOICE_SESSION_VOICEMMODE1_PROFILE_NAME "voicecall-voicemmode1"
+#define VOICE_SESSION_VOICEMMODE1_PROFILE_DESC "Call mode, default to voicemmode1 vsid"
+#define VOICE_SESSION_VOICEMMODE2_PROFILE_NAME "voicecall-voicemmode2"
+#define VOICE_SESSION_VOICEMMODE2_PROFILE_DESC "Call mode, default to voicemmode2 vsid"
static bool voicecall_voice1_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling);
static bool voicecall_voice2_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling);
static bool voicecall_volte_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling);
static bool voicecall_qchat_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling);
static bool voicecall_vowlan_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling);
+static bool voicecall_voicemmode1_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling);
+static bool voicecall_voicemmode2_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling);
#endif /* DROID_AUDIO_HAL_USE_VSID */
@@ -216,7 +227,8 @@
cp->available = PA_AVAILABLE_YES;
d = PA_CARD_PROFILE_DATA(cp);
- d->profile = NULL;
+ d->droid_profile = NULL;
+ d->card_profile = cp;
pa_hashmap_put(profiles, cp->name, cp);
}
@@ -228,7 +240,7 @@
pa_hashmap *profiles) {
pa_droid_profile *ap;
pa_card_profile *cp;
- struct profile_data *d, *ext;
+ struct profile_data *d;
pa_assert(u);
pa_assert(u->profile_set);
@@ -246,17 +258,12 @@
cp = pa_card_profile_new(ap->name, ap->description, sizeof(struct profile_data));
cp->available = available;
d = PA_CARD_PROFILE_DATA(cp);
- d->profile = ap;
+ d->droid_profile = ap;
+ d->card_profile = cp;
d->virtual_profile = true;
d->mode = audio_mode;
d->virtual.event_cb = event_cb;
- d->virtual.extension = NULL;
- if (extension_to) {
- ext = PA_CARD_PROFILE_DATA(extension_to);
- ext->virtual.extension = cp;
- d->virtual.parent = extension_to;
- } else
- d->virtual.parent = NULL;
+ d->virtual.parent = extension_to;
pa_hashmap_put(profiles, cp->name, cp);
@@ -293,6 +300,19 @@
data->namereg_fail = false;
}
+static bool output_enabled(struct userdata *u, pa_droid_mapping *am) {
+ pa_assert(u);
+ pa_assert(am);
+
+ if (!pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_FAST) && am->output->flags & AUDIO_OUTPUT_FLAG_FAST)
+ return false;
+
+ if (!pa_droid_quirk(u->hw_module, QUIRK_OUTPUT_DEEP_BUFFER) && am->output->flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER)
+ return false;
+
+ return true;
+}
+
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;
@@ -313,6 +333,9 @@
max_channels = 0;
PA_IDXSET_FOREACH(am, ap->output_mappings, idx) {
+ if (!output_enabled(u, am))
+ continue;
+
cp->n_sinks++;
pa_droid_add_card_ports(cp, ports, am, u->core);
max_channels = popcount(am->output->channel_masks) > max_channels
@@ -321,16 +344,19 @@
cp->max_sink_channels = max_channels;
max_channels = 0;
- PA_IDXSET_FOREACH(am, ap->input_mappings, idx) {
+ if ((am = ap->input_mapping)) {
+ const pa_droid_config_device *input;
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;
+ SLLIST_FOREACH(input, am->inputs)
+ max_channels = popcount(input->channel_masks) > max_channels
+ ? popcount(input->channel_masks) : max_channels;
}
cp->max_source_channels = max_channels;
d = PA_CARD_PROFILE_DATA(cp);
- d->profile = ap;
+ d->droid_profile = ap;
+ d->card_profile = cp;
d->virtual_profile = false;
d->mode = AUDIO_MODE_NORMAL;
@@ -361,52 +387,20 @@
d = PA_CARD_PROFILE_DATA(u->card->active_profile);
- if (d->profile && pa_idxset_size(d->profile->output_mappings) > 0) {
- PA_IDXSET_FOREACH(am, d->profile->output_mappings, idx) {
+ if (d->droid_profile && pa_idxset_size(d->droid_profile->output_mappings) > 0) {
+ PA_IDXSET_FOREACH(am, d->droid_profile->output_mappings, idx) {
+ if (!output_enabled(u, am))
+ continue;
+
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->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);
- }
+ if (d->droid_profile && (am = d->droid_profile->input_mapping)) {
+ am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card);
}
}
-static int set_mode(struct userdata *u, audio_mode_t mode) {
- int ret;
- const char *mode_str;
-
- pa_assert(u);
- pa_assert(u->hw_module);
- pa_assert(u->hw_module->device);
-
- switch (mode) {
- case AUDIO_MODE_RINGTONE:
- mode_str = "AUDIO_MODE_RINGTONE";
- break;
- case AUDIO_MODE_IN_CALL:
- mode_str = "AUDIO_MODE_IN_CALL";
- break;
- case AUDIO_MODE_IN_COMMUNICATION:
- mode_str = "AUDIO_MODE_IN_COMMUNICATION";
- break;
- default:
- mode_str = "AUDIO_MODE_NORMAL";
- break;
- }
-
- pa_log_debug("Set mode to %s.", mode_str);
-
- pa_droid_hw_module_lock(u->hw_module);
- if ((ret = u->hw_module->device->set_mode(u->hw_module->device, mode)) < 0)
- pa_log("Failed to set mode.");
- pa_droid_hw_module_unlock(u->hw_module);
-
- return ret;
-}
-
static void park_profile(pa_droid_profile *dp) {
pa_droid_mapping *am;
uint32_t idx;
@@ -422,46 +416,44 @@
};
/* 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);
- }
+ if ((am = dp->input_mapping)) {
+ if (pa_droid_mapping_is_primary(am))
+ pa_source_set_port(am->source, PA_DROID_INPUT_PARKING, false);
};
}
+static pa_droid_profile *card_get_droid_profile(pa_card_profile *cp) {
+ struct profile_data *pd;
+
+ pa_assert(cp);
+
+ pd = PA_CARD_PROFILE_DATA(cp);
+ return pd->droid_profile;
+}
+
static bool voicecall_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling) {
- pa_card_profile *cp = NULL;
+ pa_droid_profile *dp = NULL;
pa_droid_mapping *am_output;
pa_assert(u);
pa_assert(p);
- pa_assert(u->old_profile);
+ pa_assert(u->real_profile);
- if (!(am_output = pa_droid_idxset_get_primary(u->old_profile->output_mappings))) {
+ dp = card_get_droid_profile(u->real_profile);
+ if (!(am_output = pa_droid_idxset_get_primary(dp->output_mappings))) {
pa_log("Active profile doesn't have primary output device.");
return false;
}
- 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 (cp && cp->available == PA_AVAILABLE_NO) {
- pa_log_debug("Enable " VOICE_RECORD_PROFILE_NAME " profile.");
- pa_card_profile_set_available(cp, PA_AVAILABLE_YES);
- }
+
if (pa_droid_quirk(u->hw_module, QUIRK_REALCALL))
pa_droid_set_parameters(u->hw_module, VENDOR_EXT_REALCALL_ON);
} else {
pa_droid_sink_set_voice_control(am_output->sink, false);
- 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);
- }
+
if (pa_droid_quirk(u->hw_module, QUIRK_REALCALL))
pa_droid_set_parameters(u->hw_module, VENDOR_EXT_REALCALL_OFF);
}
@@ -474,8 +466,6 @@
{
char *setparam;
- voicecall_profile_event_cb(u, p, enabling);
-
setparam = pa_sprintf_malloc("%s=%u;%s=%d", AUDIO_PARAMETER_KEY_VSID, vsid,
AUDIO_PARAMETER_KEY_CALL_STATE,
enabling ? CALL_ACTIVE : CALL_INACTIVE);
@@ -510,43 +500,123 @@
{
return voicecall_vsid(u, p, VOWLAN_VSID, enabling);
}
+
+static bool voicecall_voicemmode1_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling)
+{
+ return voicecall_vsid(u, p, VOICEMMODE1_VSID, enabling);
+}
+
+static bool voicecall_voicemmode2_vsid_profile_event_cb(struct userdata *u, pa_droid_profile *p, bool enabling)
+{
+ return voicecall_vsid(u, p, VOICEMMODE2_VSID, enabling);
+}
#endif /* DROID_AUDIO_HAL_USE_VSID */
-static void leave_virtual_profile(struct userdata *u, pa_card *c, pa_card_profile *cp, pa_card_profile *new_profile) {
- struct profile_data *pd, *parent;
+static void virtual_event(struct userdata *u, struct profile_data *profile, bool enabling) {
+ pa_assert(u);
+ pa_assert(profile);
+ pa_assert(profile->virtual_profile);
+
+ if (profile->virtual.enabled == enabling)
+ return;
+
+ pa_log_info("Virtual profile %s changes to %s%s", profile->droid_profile->name,
+ enabling ? "enabled" : "disabled",
+ profile->virtual.event_cb ? " (calling event callback)" : "");
+
+ if (profile->virtual.event_cb)
+ profile->virtual.event_cb(u, profile->droid_profile, enabling);
+
+ profile->virtual.enabled = enabling;
+}
+
+static pa_card_profile *leave_virtual_profile(struct userdata *u, pa_card *c,
+ struct profile_data *current, struct profile_data *next) {
+ pa_card_profile *real = NULL;
pa_assert(u);
pa_assert(c);
- pa_assert(cp);
- pa_assert_se((pd = PA_CARD_PROFILE_DATA(cp)));
+ pa_assert(current);
+ pa_assert(next);
+ pa_assert(current->virtual_profile);
- if (pd->virtual.parent)
- pa_log_debug("Leaving extension %s.", cp->name);
+ pa_log_debug("Leave virtual profile %s", current->droid_profile->name);
- /* First run event for old virtual profile, unless new profile is extension
- * to the old profile. */
- if (pd->virtual.extension) {
- if (pd->virtual.extension != new_profile && pd->virtual.event_cb)
- pd->virtual.event_cb(u, pd->profile, false);
- } else {
- if (pd->virtual.event_cb)
- pd->virtual.event_cb(u, pd->profile, false);
+ if (next->mode != current->mode) {
+ park_profile(current->droid_profile);
+ pa_droid_hw_set_mode(u->hw_module, next->mode);
}
- /* If old virtual profile was extension, and new profile is not extensions parent, run event
- * for extension's parent as well. */
- if (pd->virtual.parent != new_profile && pd->virtual.parent) {
- parent = PA_CARD_PROFILE_DATA(pd->virtual.parent);
+ virtual_event(u, current, false);
+
+ /* If new profile is the same as from which we switched to
+ * virtual profile, transfer ownership back to that profile.
+ * Otherwise destroy sinks & sources and switch to new profile. */
+ if (!next->virtual_profile) {
+ if (current->virtual.parent) {
+ struct profile_data *pd = PA_CARD_PROFILE_DATA(current->virtual.parent);
+ virtual_event(u, pd, false);
+ }
- if (parent->virtual.event_cb)
- parent->virtual.event_cb(u, parent->profile, false);
+ if (next->card_profile != u->real_profile)
+ real = u->real_profile;
+ u->real_profile = NULL;
}
+
+ pa_log_debug("Left virtual profile %s%s", current->droid_profile->name,
+ next->virtual_profile ? "" : " for real profile");
+
+ return real;
+}
+
+static void enter_virtual_profile(struct userdata *u, pa_card *c,
+ struct profile_data *current, struct profile_data *next) {
+ pa_assert(u);
+ pa_assert(c);
+ pa_assert(current);
+ pa_assert(next);
+ pa_assert(next->virtual_profile);
+
+ pa_log_debug("Enter virtual profile %s", next->droid_profile->name);
+
+ /* real_profile should always be real profile. */
+ if (u->real_profile == NULL) {
+ pa_assert(!current->virtual_profile);
+ u->real_profile = current->card_profile;
+ }
+
+ if (current->virtual_profile) {
+ if (current->card_profile != next->virtual.parent) {
+ struct profile_data *parent = current;
+ while (parent && parent != next && parent->card_profile != next->virtual.parent) {
+ virtual_event(u, parent, false);
+ parent = parent->virtual.parent ? PA_CARD_PROFILE_DATA(parent->virtual.parent) : NULL;
+ }
+ }
+ }
+
+ if (next->mode != current->mode) {
+ park_profile(current->droid_profile);
+ pa_droid_hw_set_mode(u->hw_module, next->mode);
+ }
+
+ if (next->virtual.parent) {
+ if (next->virtual.parent != current->card_profile) {
+ struct profile_data *pd = PA_CARD_PROFILE_DATA(next->virtual.parent);
+ virtual_event(u, pd, true);
+ }
+ }
+
+ virtual_event(u, next, true);
+
+ pa_log_debug("Entered virtual profile %s", next->droid_profile->name);
}
static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
struct userdata *u;
+ pa_card_profile *real_profile;
pa_droid_mapping *am;
- struct profile_data *nd, *od;
+ struct profile_data *next, *curr;
pa_queue *sink_inputs = NULL, *source_outputs = NULL;
pa_sink *primary_sink = NULL;
uint32_t idx;
@@ -560,65 +630,34 @@
return -1;
}
- nd = PA_CARD_PROFILE_DATA(new_profile);
- od = PA_CARD_PROFILE_DATA(c->active_profile);
-
- if (nd->virtual_profile) {
- /* old_profile should always be real profile. */
- if (u->old_profile == NULL) {
- pa_assert(!od->virtual_profile);
- u->old_profile = od->profile;
- }
-
- if (od->virtual_profile)
- leave_virtual_profile(u, c, c->active_profile, new_profile);
-
- park_profile(od->profile);
-
- if (nd->mode != od->mode)
- set_mode(u, nd->mode);
-
- if (od->virtual.parent != new_profile && nd->virtual.event_cb)
- nd->virtual.event_cb(u, nd->profile, true);
+ next = PA_CARD_PROFILE_DATA(new_profile);
+ curr = PA_CARD_PROFILE_DATA(c->active_profile);
+ if (next->virtual_profile) {
+ enter_virtual_profile(u, c, curr, next);
return 0;
- }
-
- if (od->virtual_profile) {
- pa_assert(u->old_profile);
-
- if (od->virtual_profile)
- leave_virtual_profile(u, c, c->active_profile, NULL);
-
- park_profile(nd->profile);
-
- if (nd->mode != od->mode)
- set_mode(u, nd->mode);
-
- /* If new profile is the same as from which we switched to
- * virtual profile, transfer ownership back to that profile.
- * Otherwise destroy sinks & sources and switch to new profile. */
- if (nd->profile == u->old_profile) {
- u->old_profile = NULL;
- return 0;
- } else {
- od->profile = u->old_profile;
- u->old_profile = NULL;
-
- /* Continue to sink-input/source-output transfer below. */
+ } else {
+ if (curr->virtual_profile) {
+ if ((real_profile = leave_virtual_profile(u, c, curr, next)))
+ curr = PA_CARD_PROFILE_DATA(real_profile);
+ else
+ return 0;
}
+
+ /* Continue to sink-input/source-output transfer below. */
}
/* If there are connected sink inputs/source outputs in old profile's sinks/sources move
* them all to new sinks/sources. */
+ pa_log_debug("Update sinks and sources for profile %s", new_profile->name);
- if (od->profile && pa_idxset_size(od->profile->output_mappings) > 0) {
- PA_IDXSET_FOREACH(am, od->profile->output_mappings, idx) {
+ if (curr->droid_profile && pa_idxset_size(curr->droid_profile->output_mappings) > 0) {
+ PA_IDXSET_FOREACH(am, curr->droid_profile->output_mappings, idx) {
if (!am->sink)
continue;
- if (nd->profile &&
- pa_idxset_get_by_data(nd->profile->output_mappings, am, NULL)) {
+ if (next->droid_profile &&
+ pa_idxset_get_by_data(next->droid_profile->output_mappings, am, NULL)) {
if (pa_droid_mapping_is_primary(am))
primary_sink = am->sink;
@@ -631,23 +670,19 @@
}
}
- if (od->profile && pa_idxset_size(od->profile->input_mappings) > 0) {
- PA_IDXSET_FOREACH(am, od->profile->input_mappings, idx) {
- if (!am->source)
- continue;
-
- if (nd->profile &&
- pa_idxset_get_by_data(nd->profile->input_mappings, am, NULL))
- continue;
-
+ if (curr->droid_profile && (am = curr->droid_profile->input_mapping)) {
+ if (am->source && next->droid_profile && next->droid_profile->input_mapping) {
source_outputs = pa_source_move_all_start(am->source, source_outputs);
pa_droid_source_free(am->source);
am->source = NULL;
}
}
- if (nd->profile && pa_idxset_size(nd->profile->output_mappings) > 0) {
- PA_IDXSET_FOREACH(am, nd->profile->output_mappings, idx) {
+ if (next->droid_profile && pa_idxset_size(next->droid_profile->output_mappings) > 0) {
+ PA_IDXSET_FOREACH(am, next->droid_profile->output_mappings, idx) {
+ if (!output_enabled(u, am))
+ continue;
+
if (!am->sink)
am->sink = pa_droid_sink_new(u->module, u->modargs, __FILE__, &u->card_data, 0, am, u->card);
@@ -658,15 +693,13 @@
}
}
- if (nd->profile && pa_idxset_size(nd->profile->input_mappings) > 0) {
- PA_IDXSET_FOREACH(am, nd->profile->input_mappings, idx) {
- if (!am->source)
- am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card);
-
- if (source_outputs && am->source) {
- pa_source_move_all_finish(am->source, source_outputs, false);
- source_outputs = NULL;
- }
+ if (next->droid_profile && (am = next->droid_profile->input_mapping)) {
+ if (!am->source)
+ am->source = pa_droid_source_new(u->module, u->modargs, __FILE__, (audio_devices_t) 0, &u->card_data, am, u->card);
+
+ if (source_outputs && am->source) {
+ pa_source_move_all_finish(am->source, source_outputs, false);
+ source_outputs = NULL;
}
}
@@ -694,13 +727,14 @@
pa_droid_config_audio *config = NULL;
const char *module_id;
bool namereg_fail = false;
- pa_card_profile *virtual;
bool default_profile = true;
- bool merge_inputs = true;
const char *quirks;
+ pa_card_profile *voicecall = NULL;
pa_assert(m);
+ pa_log_info("Create new droid-card");
+
if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
pa_log("Failed to parse module arguments.");
goto fail;
@@ -711,11 +745,6 @@
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;
- }
-
u = pa_xnew0(struct userdata, 1);
u->core = m->core;
m->userdata = u;
@@ -749,10 +778,10 @@
u->card_data.module_id = pa_xstrdup(module_id);
u->card_data.userdata = u;
- if (!default_profile || !pa_streq(module_id, DEFAULT_MODULE_ID))
- u->profile_set = pa_droid_profile_set_new(u->hw_module->enabled_module);
+ if (default_profile)
+ u->profile_set = pa_droid_profile_set_default_new(u->hw_module->enabled_module);
else
- u->profile_set = pa_droid_profile_set_default_new(u->hw_module->enabled_module, merge_inputs);
+ u->profile_set = pa_droid_profile_set_new(u->hw_module->enabled_module);
pa_card_new_data_init(&data);
data.driver = __FILE__;
@@ -780,13 +809,13 @@
goto fail;
}
- virtual =
+ voicecall =
add_virtual_profile(u, VOICE_CALL_PROFILE_NAME, VOICE_CALL_PROFILE_DESC,
AUDIO_MODE_IN_CALL, voicecall_profile_event_cb,
PA_AVAILABLE_YES, NULL, data.profiles);
add_virtual_profile(u, VOICE_RECORD_PROFILE_NAME, VOICE_RECORD_PROFILE_DESC,
AUDIO_MODE_IN_CALL, NULL,
- PA_AVAILABLE_NO, virtual, data.profiles);
+ PA_AVAILABLE_YES, voicecall, data.profiles);
add_virtual_profile(u, COMMUNICATION_PROFILE_NAME, COMMUNICATION_PROFILE_DESC,
AUDIO_MODE_IN_COMMUNICATION, NULL,
PA_AVAILABLE_YES, NULL, data.profiles);
@@ -796,20 +825,26 @@
#ifdef DROID_AUDIO_HAL_USE_VSID
add_virtual_profile(u, VOICE_SESSION_VOICE1_PROFILE_NAME, VOICE_SESSION_VOICE1_PROFILE_DESC,
AUDIO_MODE_IN_CALL, voicecall_voice1_vsid_profile_event_cb,
- PA_AVAILABLE_YES, NULL, data.profiles);
+ PA_AVAILABLE_YES, voicecall, data.profiles);
add_virtual_profile(u, VOICE_SESSION_VOICE2_PROFILE_NAME, VOICE_SESSION_VOICE2_PROFILE_DESC,
AUDIO_MODE_IN_CALL, voicecall_voice2_vsid_profile_event_cb,
- PA_AVAILABLE_YES, NULL, data.profiles);
+ PA_AVAILABLE_YES, voicecall, data.profiles);
/* TODO: Probably enabled state needs to be determined dynamically for VOLTE and friends. */
add_virtual_profile(u, VOICE_SESSION_VOLTE_PROFILE_NAME, VOICE_SESSION_VOLTE_PROFILE_DESC,
AUDIO_MODE_IN_CALL, voicecall_volte_vsid_profile_event_cb,
- PA_AVAILABLE_YES, NULL, data.profiles);
+ PA_AVAILABLE_YES, voicecall, data.profiles);
add_virtual_profile(u, VOICE_SESSION_QCHAT_PROFILE_NAME, VOICE_SESSION_QCHAT_PROFILE_DESC,
AUDIO_MODE_IN_CALL, voicecall_qchat_vsid_profile_event_cb,
- PA_AVAILABLE_YES, NULL, data.profiles);
+ PA_AVAILABLE_YES, voicecall, data.profiles);
add_virtual_profile(u, VOICE_SESSION_VOWLAN_PROFILE_NAME, VOICE_SESSION_VOWLAN_PROFILE_DESC,
AUDIO_MODE_IN_CALL, voicecall_vowlan_vsid_profile_event_cb,
- PA_AVAILABLE_YES, NULL, data.profiles);
+ PA_AVAILABLE_YES, voicecall, data.profiles);
+ add_virtual_profile(u, VOICE_SESSION_VOICEMMODE1_PROFILE_NAME, VOICE_SESSION_VOICEMMODE1_PROFILE_DESC,
+ AUDIO_MODE_IN_CALL, voicecall_voicemmode1_vsid_profile_event_cb,
+ PA_AVAILABLE_YES, voicecall, data.profiles);
+ add_virtual_profile(u, VOICE_SESSION_VOICEMMODE2_PROFILE_NAME, VOICE_SESSION_VOICEMMODE2_PROFILE_DESC,
+ AUDIO_MODE_IN_CALL, voicecall_voicemmode2_vsid_profile_event_cb,
+ PA_AVAILABLE_YES, voicecall, data.profiles);
#endif /* DROID_AUDIO_HAL_USE_VSID */
add_disabled_profile(data.profiles);
@@ -830,14 +865,9 @@
u->modargs = ma;
u->module = m;
-#if (PULSEAUDIO_VERSION >= 10)
pa_card_choose_initial_profile(u->card);
-#endif
init_profile(u);
-
-#if (PULSEAUDIO_VERSION >= 10)
pa_card_put(u->card);
-#endif
return 0;
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/droid/module-droid-sink.c
^
|
@@ -50,6 +50,7 @@
PA_MODULE_VERSION(PACKAGE_VERSION);
static const char* const valid_modargs[] = {
+ "config",
"rate",
"format",
"channels",
@@ -59,6 +60,7 @@
"sink_channel_map",
"sink_mix_route",
"flags",
+ "output",
"output_devices",
"sink_name",
"module_id",
|
[-]
[+]
|
Changed |
_service:tar_git:pulseaudio-modules-droid-12.2.83.tar.bz2/src/droid/module-droid-source.c
^
|
@@ -49,6 +49,7 @@
PA_MODULE_VERSION(PACKAGE_VERSION);
static const char* const valid_modargs[] = {
+ "config",
"rate",
"format",
"channels",
|