summaryrefslogtreecommitdiff
path: root/cras
diff options
context:
space:
mode:
authorCheng-Yi Chiang <cychiang@chromium.org>2016-09-20 00:46:46 +0800
committerchrome-bot <chrome-bot@chromium.org>2016-09-26 04:59:47 -0700
commitc9f56d936f63f56186b6daaa3f0c9abed828531a (patch)
tree95a8419b9d12cfeae6b48d6dc56b6b89342475ad /cras
parent4f86aad321250a527075476dac94241c24817521 (diff)
downloadadhd-c9f56d936f63f56186b6daaa3f0c9abed828531a.tar.gz
CRAS: iodev - Add function to swap left and right channel using dsp
Add cras_iodev_dsp_set_swap_mode_for_node to swap left and right channel using dsp. It is used as the default implementation of set_swap_mode_for_node ops on alsa_io device. To use this function, there must be a swap_lr section in dsp.ini: [swap_lr] library=builtin label=swap_lr disable=swap_lr_disabled input_0={swap_lr:0} input_1={swap_lr:1} output_2={dst:1} output_3={dst:0} where {swap_lr:0}, {swap_lr:1} are the output ports of the block which was before output sink (usually eq2). cras_iodev_dsp_set_swap_mode_for_node must support two use cases: - User sets swap mode when device is not playing. - User sets swap mode when device is playing. In the first use case, cras_iodev_update_dsp sets swap_lr_disabled variable based on left_right_swapped on active node. For the second use case, we need to udpate dsp in cras_iodev_dsp_set_swap_mode_for_node so the change takes effect right away. It is fine to do so because pipeline in the context is protected by a mutex. BUG=chromium:645051 TEST=with modified dsp, check left right swap works using cras_test_client --swap_left_right n:m:1. Signed-off-by: Cheng-Yi Chiang <cychiang@chromium.org> Change-Id: I78fa29f3bd9edbe59eda73242cc855aa8781bce0 Reviewed-on: https://chromium-review.googlesource.com/386703 Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'cras')
-rw-r--r--cras/src/server/cras_alsa_io.c1
-rw-r--r--cras/src/server/cras_dsp.c1
-rw-r--r--cras/src/server/cras_iodev.c27
-rw-r--r--cras/src/server/cras_iodev.h16
-rw-r--r--cras/src/tests/alsa_io_unittest.cc15
-rw-r--r--cras/src/tests/iodev_unittest.cc6
6 files changed, 65 insertions, 1 deletions
diff --git a/cras/src/server/cras_alsa_io.c b/cras/src/server/cras_alsa_io.c
index c972f3c1..ca9cb59f 100644
--- a/cras/src/server/cras_alsa_io.c
+++ b/cras/src/server/cras_alsa_io.c
@@ -1577,6 +1577,7 @@ struct cras_iodev *alsa_iodev_create(size_t card_index,
iodev->get_hotword_models = get_hotword_models;
iodev->no_stream = cras_iodev_default_no_stream_playback;
iodev->get_num_underruns = get_num_underruns;
+ iodev->set_swap_mode_for_node = cras_iodev_dsp_set_swap_mode_for_node;
if (card_type == ALSA_CARD_TYPE_USB)
iodev->min_buffer_level = USB_EXTRA_BUFFER_FRAMES;
diff --git a/cras/src/server/cras_dsp.c b/cras/src/server/cras_dsp.c
index 7b3df8f7..8052a047 100644
--- a/cras/src/server/cras_dsp.c
+++ b/cras/src/server/cras_dsp.c
@@ -45,6 +45,7 @@ static void initialize_environment(struct cras_expr_env *env)
cras_expr_env_set_variable_boolean(env, "disable_eq", 0);
cras_expr_env_set_variable_boolean(env, "disable_drc", 0);
cras_expr_env_set_variable_string(env, "dsp_name", "");
+ cras_expr_env_set_variable_boolean(env, "swap_lr_disabled", 1);
}
static struct pipeline *prepare_pipeline(struct cras_dsp_context *ctx)
diff --git a/cras/src/server/cras_iodev.c b/cras/src/server/cras_iodev.c
index 6172fb74..3490ac53 100644
--- a/cras/src/server/cras_iodev.c
+++ b/cras/src/server/cras_iodev.c
@@ -441,15 +441,42 @@ error:
void cras_iodev_update_dsp(struct cras_iodev *iodev)
{
+ char swap_lr_disabled = 1;
+
if (!iodev->dsp_context)
return;
cras_dsp_set_variable_string(iodev->dsp_context, "dsp_name",
iodev->dsp_name ? : "");
+ if (iodev->active_node && iodev->active_node->left_right_swapped)
+ swap_lr_disabled = 0;
+
+ cras_dsp_set_variable_boolean(iodev->dsp_context, "swap_lr_disabled",
+ swap_lr_disabled);
+
cras_dsp_load_pipeline(iodev->dsp_context);
}
+
+int cras_iodev_dsp_set_swap_mode_for_node(struct cras_iodev *iodev,
+ struct cras_ionode *node, int enable)
+{
+ if (node->left_right_swapped == enable)
+ return 0;
+
+ /* Sets left_right_swapped property on the node. It will be used
+ * when cras_iodev_update_dsp is called. */
+ node->left_right_swapped = enable;
+
+ /* Possibly updates dsp if the node is active on the device and there
+ * is dsp context. If dsp context is not created yet,
+ * cras_iodev_update_dsp returns right away. */
+ if (iodev->active_node == node)
+ cras_iodev_update_dsp(iodev);
+ return 0;
+}
+
void cras_iodev_free_format(struct cras_iodev *iodev)
{
free(iodev->format);
diff --git a/cras/src/server/cras_iodev.h b/cras/src/server/cras_iodev.h
index ca480bc8..1d32d732 100644
--- a/cras/src/server/cras_iodev.h
+++ b/cras/src/server/cras_iodev.h
@@ -296,6 +296,22 @@ void cras_iodev_set_capture_timestamp(size_t frame_rate,
*/
void cras_iodev_update_dsp(struct cras_iodev *iodev);
+
+/* Sets swap mode on a node using dsp. This function can be called when
+ * dsp pipline is not created yet. It will take effect when dsp pipeline
+ * is created later. If there is dsp pipeline, this function causes the dsp
+ * pipeline to be reloaded and swap mode takes effect right away.
+ * Args:
+ * iodev - device to be changed for swap mode.
+ * node - the node to be changed for swap mode.
+ * enable - 1 to enable swap mode, 0 otherwise.
+ * Returns:
+ * 0 on success, error code on failure.
+ */
+int cras_iodev_dsp_set_swap_mode_for_node(struct cras_iodev *iodev,
+ struct cras_ionode *node,
+ int enable);
+
/* Handles a plug event happening on this node.
* Args:
* node - ionode on which a plug event was detected.
diff --git a/cras/src/tests/alsa_io_unittest.cc b/cras/src/tests/alsa_io_unittest.cc
index 26daa966..eeec9c1a 100644
--- a/cras/src/tests/alsa_io_unittest.cc
+++ b/cras/src/tests/alsa_io_unittest.cc
@@ -148,6 +148,7 @@ static int cras_alsa_resume_appl_ptr_ahead;
static int ucm_get_optimize_no_stream_flag_ret;
static int ucm_get_enable_htimestamp_flag_ret;
static const struct cras_volume_curve *fake_get_dBFS_volume_curve_val;
+static int cras_iodev_dsp_set_swap_mode_for_node_called;
void ResetStubData() {
cras_alsa_open_called = 0;
@@ -234,6 +235,7 @@ void ResetStubData() {
ucm_get_optimize_no_stream_flag_ret = 0;
ucm_get_enable_htimestamp_flag_ret = 0;
fake_get_dBFS_volume_curve_val = NULL;
+ cras_iodev_dsp_set_swap_mode_for_node_called = 0;
}
static long fake_get_dBFS(const struct cras_volume_curve *curve, size_t volume)
@@ -821,7 +823,10 @@ TEST(AlsaIoInit, SwapMode) {
fake_mixer, fake_ucm, fake_hctl,
CRAS_STREAM_OUTPUT, 0, 0);
ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev *)aio));
- EXPECT_EQ(NULL, aio->base.set_swap_mode_for_node);
+
+ aio->base.set_swap_mode_for_node((cras_iodev*)aio, fake_node, 1);
+ /* Swap mode is implemented by dsp. */
+ EXPECT_EQ(1, cras_iodev_dsp_set_swap_mode_for_node_called);
// Stub replies that swap mode exists.
ucm_swap_mode_exists_ret_value = 1;
@@ -2605,4 +2610,12 @@ enum CRAS_IODEV_STATE cras_iodev_state(const struct cras_iodev *iodev)
return iodev->state;
}
+int cras_iodev_dsp_set_swap_mode_for_node(struct cras_iodev *iodev,
+ struct cras_ionode *node,
+ int enable)
+{
+ cras_iodev_dsp_set_swap_mode_for_node_called++;
+ return 0;
+}
+
}
diff --git a/cras/src/tests/iodev_unittest.cc b/cras/src/tests/iodev_unittest.cc
index c59627e1..6a71413a 100644
--- a/cras/src/tests/iodev_unittest.cc
+++ b/cras/src/tests/iodev_unittest.cc
@@ -1433,6 +1433,12 @@ void cras_dsp_set_variable_string(struct cras_dsp_context *ctx, const char *key,
{
}
+void cras_dsp_set_variable_boolean(struct cras_dsp_context *ctx,
+ const char *key,
+ char value)
+{
+}
+
struct pipeline *cras_dsp_get_pipeline(struct cras_dsp_context *ctx)
{
cras_dsp_get_pipeline_called++;