summaryrefslogtreecommitdiff
path: root/cras/src/tests/cras_dsp_pipeline_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'cras/src/tests/cras_dsp_pipeline_unittest.cc')
-rw-r--r--cras/src/tests/cras_dsp_pipeline_unittest.cc518
1 files changed, 0 insertions, 518 deletions
diff --git a/cras/src/tests/cras_dsp_pipeline_unittest.cc b/cras/src/tests/cras_dsp_pipeline_unittest.cc
deleted file mode 100644
index b6c733ac..00000000
--- a/cras/src/tests/cras_dsp_pipeline_unittest.cc
+++ /dev/null
@@ -1,518 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cras_dsp_pipeline.h"
-
-#include <gtest/gtest.h>
-
-#include "cras_config.h"
-#include "cras_dsp_module.h"
-
-#define MAX_MODULES 10
-#define MAX_MOCK_PORTS 30
-#define FILENAME_TEMPLATE "DspIniTest.XXXXXX"
-
-static void fill_test_data(int16_t* data, size_t size) {
- for (size_t i = 0; i < size; i++)
- data[i] = i;
-}
-
-static void verify_processed_data(int16_t* data, size_t size, int times) {
- /* Each time the audio data flow through the mock plugin, the data
- * will be multiplied by 2 in module->run() below, so if there are n
- * plugins, the data will be multiplied by (1 << n). */
- int multiples = (1 << times);
- for (size_t i = 0; i < size; i++) {
- EXPECT_EQ(i * multiples, data[i]);
- if ((int16_t)i * multiples != data[i])
- return;
- }
-}
-
-struct data {
- const char* title;
- int nr_ports;
- port_direction port_dir[MAX_MOCK_PORTS];
- int nr_in_audio;
- int nr_in_control;
- int nr_out_audio;
- int nr_out_control;
- int in_audio[MAX_MOCK_PORTS];
- int in_control[MAX_MOCK_PORTS];
- int out_audio[MAX_MOCK_PORTS];
- int out_control[MAX_MOCK_PORTS];
- int properties;
-
- int instantiate_called;
- int sample_rate;
-
- int connect_port_called[MAX_MOCK_PORTS];
- float* data_location[MAX_MOCK_PORTS];
-
- int run_called;
- float input[MAX_MOCK_PORTS];
- float output[MAX_MOCK_PORTS];
-
- int sample_count;
-
- int get_delay_called;
- int deinstantiate_called;
- int free_module_called;
- int get_properties_called;
-};
-
-static int instantiate(struct dsp_module* module, unsigned long sample_rate) {
- struct data* data = (struct data*)module->data;
- data->instantiate_called++;
- data->sample_rate = sample_rate;
- return 0;
-}
-
-static void connect_port(struct dsp_module* module,
- unsigned long port,
- float* data_location) {
- struct data* data = (struct data*)module->data;
- data->connect_port_called[port]++;
- data->data_location[port] = data_location;
-}
-
-static int get_delay(struct dsp_module* module) {
- struct data* data = (struct data*)module->data;
- data->get_delay_called++;
-
- /* If the module title is "mN", then use N as the delay. */
- int delay = 0;
- sscanf(data->title, "m%d", &delay);
- return delay;
-}
-
-static void run(struct dsp_module* module, unsigned long sample_count) {
- struct data* data = (struct data*)module->data;
- data->run_called++;
- data->sample_count = sample_count;
-
- for (int i = 0; i < data->nr_ports; i++) {
- if (data->port_dir[i] == PORT_INPUT)
- data->input[i] = *data->data_location[i];
- }
-
- /* copy the control port data */
- for (int i = 0; i < std::min(data->nr_in_control, data->nr_out_control);
- i++) {
- int from = data->in_control[i];
- int to = data->out_control[i];
- data->data_location[to][0] = data->data_location[from][0];
- }
-
- /* multiply the audio port data by 2 */
- for (int i = 0; i < std::min(data->nr_in_audio, data->nr_out_audio); i++) {
- int from = data->in_audio[i];
- int to = data->out_audio[i];
- for (unsigned int j = 0; j < sample_count; j++)
- data->data_location[to][j] = data->data_location[from][j] * 2;
- }
-}
-
-static void deinstantiate(struct dsp_module* module) {
- struct data* data = (struct data*)module->data;
- data->deinstantiate_called++;
-}
-
-static void free_module(struct dsp_module* module) {
- struct data* data = (struct data*)module->data;
- data->free_module_called++;
-}
-
-static void really_free_module(struct dsp_module* module) {
- struct data* data = (struct data*)module->data;
- free(data);
- free(module);
-}
-
-static int get_properties(struct dsp_module* module) {
- struct data* data = (struct data*)module->data;
- data->get_properties_called++;
- return data->properties;
-}
-static void dump(struct dsp_module* module, struct dumper* d) {}
-
-static struct dsp_module* create_mock_module(struct plugin* plugin) {
- struct data* data;
- struct dsp_module* module;
-
- data = (struct data*)calloc(1, sizeof(struct data));
- data->title = plugin->title;
- data->nr_ports = ARRAY_COUNT(&plugin->ports);
- for (int i = 0; i < data->nr_ports; i++) {
- struct port* port = ARRAY_ELEMENT(&plugin->ports, i);
- data->port_dir[i] = port->direction;
-
- if (port->direction == PORT_INPUT) {
- if (port->type == PORT_AUDIO)
- data->in_audio[data->nr_in_audio++] = i;
- else
- data->in_control[data->nr_in_control++] = i;
- } else {
- if (port->type == PORT_AUDIO)
- data->out_audio[data->nr_out_audio++] = i;
- else
- data->out_control[data->nr_out_control++] = i;
- }
- }
- if (strcmp(plugin->label, "inplace_broken") == 0) {
- data->properties = MODULE_INPLACE_BROKEN;
- } else {
- data->properties = 0;
- }
-
- module = (struct dsp_module*)calloc(1, sizeof(struct dsp_module));
- module->data = data;
- module->instantiate = &instantiate;
- module->connect_port = &connect_port;
- module->get_delay = &get_delay;
- module->run = &run;
- module->deinstantiate = &deinstantiate;
- module->free_module = &free_module;
- module->get_properties = &get_properties;
- module->dump = &dump;
- return module;
-}
-
-static struct dsp_module* modules[MAX_MODULES];
-static struct dsp_module* cras_dsp_module_set_sink_ext_module_val;
-static int num_modules;
-static struct dsp_module* find_module(const char* name) {
- for (int i = 0; i < num_modules; i++) {
- struct data* data = (struct data*)modules[i]->data;
- if (strcmp(name, data->title) == 0)
- return modules[i];
- }
- return NULL;
-}
-
-extern "C" {
-struct dsp_module* cras_dsp_module_load_ladspa(struct plugin* plugin) {
- return NULL;
-}
-struct dsp_module* cras_dsp_module_load_builtin(struct plugin* plugin) {
- struct dsp_module* module = create_mock_module(plugin);
- modules[num_modules++] = module;
- return module;
-}
-void cras_dsp_module_set_sink_ext_module(struct dsp_module* module,
- struct ext_dsp_module* ext_module) {
- cras_dsp_module_set_sink_ext_module_val = module;
-}
-}
-
-namespace {
-
-class DspPipelineTestSuite : public testing::Test {
- protected:
- virtual void SetUp() {
- num_modules = 0;
- strcpy(filename, FILENAME_TEMPLATE);
- int fd = mkstemp(filename);
- fp = fdopen(fd, "w");
- }
-
- virtual void TearDown() {
- CloseFile();
- unlink(filename);
- }
-
- virtual void CloseFile() {
- if (fp) {
- fclose(fp);
- fp = NULL;
- }
- }
-
- char filename[sizeof(FILENAME_TEMPLATE) + 1];
- FILE* fp;
- struct ext_dsp_module ext_mod;
-};
-
-TEST_F(DspPipelineTestSuite, Simple) {
- const char* content =
- "[M1]\n"
- "library=builtin\n"
- "label=source\n"
- "purpose=capture\n"
- "output_0={audio}\n"
- "output_1=<control>\n"
- "input_2=3.0\n"
- "[M2]\n"
- "library=builtin\n"
- "label=sink\n"
- "purpose=capture\n"
- "input_0=<control>\n"
- "input_1={audio}\n"
- "\n";
- fprintf(fp, "%s", content);
- CloseFile();
-
- struct cras_expr_env env = CRAS_EXPR_ENV_INIT;
- struct ini* ini = cras_dsp_ini_create(filename);
- ASSERT_TRUE(ini);
- struct pipeline* p = cras_dsp_pipeline_create(ini, &env, "capture");
- ASSERT_TRUE(p);
- ASSERT_EQ(0, cras_dsp_pipeline_load(p));
-
- ASSERT_EQ(2, num_modules);
- struct dsp_module* m1 = find_module("m1");
- struct dsp_module* m2 = find_module("m2");
- ASSERT_TRUE(m1);
- ASSERT_TRUE(m2);
-
- ASSERT_EQ(1, cras_dsp_pipeline_get_num_input_channels(p));
- ASSERT_EQ(0, cras_dsp_pipeline_instantiate(p, 48000));
-
- struct data* d1 = (struct data*)m1->data;
- struct data* d2 = (struct data*)m2->data;
-
- /* check m1 */
- ASSERT_STREQ("m1", d1->title);
- ASSERT_EQ(3, d1->nr_ports);
- ASSERT_EQ(PORT_OUTPUT, d1->port_dir[0]);
- ASSERT_EQ(PORT_OUTPUT, d1->port_dir[1]);
- ASSERT_EQ(PORT_INPUT, d1->port_dir[2]);
- ASSERT_EQ(1, d1->instantiate_called);
- ASSERT_EQ(1, d1->get_delay_called);
- ASSERT_EQ(48000, d1->sample_rate);
- ASSERT_EQ(1, d1->connect_port_called[0]);
- ASSERT_EQ(1, d1->connect_port_called[1]);
- ASSERT_EQ(1, d1->connect_port_called[2]);
- ASSERT_TRUE(d1->data_location[0]);
- ASSERT_TRUE(d1->data_location[1]);
- ASSERT_TRUE(d1->data_location[2]);
- ASSERT_EQ(0, d1->run_called);
- ASSERT_EQ(0, d1->deinstantiate_called);
- ASSERT_EQ(0, d1->free_module_called);
- ASSERT_EQ(1, d1->get_properties_called);
-
- /* check m2 */
- ASSERT_STREQ("m2", d2->title);
- ASSERT_EQ(2, d2->nr_ports);
- ASSERT_EQ(PORT_INPUT, d2->port_dir[0]);
- ASSERT_EQ(PORT_INPUT, d2->port_dir[1]);
- ASSERT_EQ(1, d2->instantiate_called);
- ASSERT_EQ(1, d2->get_delay_called);
- ASSERT_EQ(48000, d2->sample_rate);
- ASSERT_EQ(1, d2->connect_port_called[0]);
- ASSERT_EQ(1, d2->connect_port_called[1]);
- ASSERT_TRUE(d2->data_location[0]);
- ASSERT_TRUE(d2->data_location[1]);
- ASSERT_EQ(0, d2->run_called);
- ASSERT_EQ(0, d2->deinstantiate_called);
- ASSERT_EQ(0, d2->free_module_called);
- ASSERT_EQ(1, d2->get_properties_called);
-
- /* check the buffer is shared */
- ASSERT_EQ(d1->data_location[0], d2->data_location[1]);
- ASSERT_EQ(d1->data_location[1], d2->data_location[0]);
- ASSERT_EQ(1, cras_dsp_pipeline_get_peak_audio_buffers(p));
-
- d1->data_location[0][0] = 100;
- cras_dsp_pipeline_run(p, DSP_BUFFER_SIZE);
- ASSERT_EQ(1, d1->run_called);
- ASSERT_EQ(1, d2->run_called);
- ASSERT_EQ(3, d1->input[2]);
- ASSERT_EQ(3, d2->input[0]);
- ASSERT_EQ(100, d2->input[1]);
-
- d1->data_location[0][0] = 1000;
- cras_dsp_pipeline_run(p, DSP_BUFFER_SIZE);
- ASSERT_EQ(2, d1->run_called);
- ASSERT_EQ(2, d2->run_called);
- ASSERT_EQ(3, d1->input[2]);
- ASSERT_EQ(3, d2->input[0]);
- ASSERT_EQ(1000, d2->input[1]);
-
- /* Expect the sink module "m2" is set. */
- cras_dsp_pipeline_set_sink_ext_module(p, &ext_mod);
- struct data* d = (struct data*)cras_dsp_module_set_sink_ext_module_val->data;
- ASSERT_STREQ("m2", d->title);
-
- cras_dsp_pipeline_deinstantiate(p);
- ASSERT_EQ(1, d1->deinstantiate_called);
- ASSERT_EQ(1, d2->deinstantiate_called);
-
- cras_dsp_pipeline_free(p);
- ASSERT_EQ(1, d1->free_module_called);
- ASSERT_EQ(1, d2->free_module_called);
-
- cras_dsp_ini_free(ini);
- cras_expr_env_free(&env);
-
- really_free_module(m1);
- really_free_module(m2);
-}
-
-TEST_F(DspPipelineTestSuite, Complex) {
- /*
- * / --(b)-- 2 --(c)-- \
- * 0 ==(a0, a1)== 1 4 ==(f0,f1)== 5
- * \ --(d)-- 3 --(e)-- /
- *
- *
- * --(g)-- 6 --(h)--
- */
-
- const char* content =
- "[M6]\n"
- "library=builtin\n"
- "label=foo\n"
- "input_0={g}\n"
- "output_1={h}\n"
- "[M5]\n"
- "library=builtin\n"
- "label=sink\n"
- "purpose=playback\n"
- "input_0={f0}\n"
- "input_1={f1}\n"
- "[M4]\n"
- "library=builtin\n"
- "label=foo\n"
- "disable=(equal? output_device \"HDMI\")\n"
- "input_0=3.14\n"
- "input_1={c}\n"
- "output_2={f0}\n"
- "input_3={e}\n"
- "output_4={f1}\n"
- "[M3]\n"
- "library=builtin\n"
- "label=foo\n"
- "input_0={d}\n"
- "output_1={e}\n"
- "[M2]\n"
- "library=builtin\n"
- "label=inplace_broken\n"
- "input_0={b}\n"
- "output_1={c}\n"
- "[M1]\n"
- "library=builtin\n"
- "label=foo\n"
- "disable=(equal? output_device \"USB\")\n"
- "input_0={a0}\n"
- "input_1={a1}\n"
- "output_2={b}\n"
- "output_3={d}\n"
- "[M0]\n"
- "library=builtin\n"
- "label=source\n"
- "purpose=playback\n"
- "output_0={a0}\n"
- "output_1={a1}\n";
- fprintf(fp, "%s", content);
- CloseFile();
-
- struct cras_expr_env env = CRAS_EXPR_ENV_INIT;
- cras_expr_env_install_builtins(&env);
- cras_expr_env_set_variable_string(&env, "output_device", "HDMI");
- cras_expr_env_set_variable_boolean(&env, "swap_lr_disabled", 1);
-
- struct ini* ini = cras_dsp_ini_create(filename);
- ASSERT_TRUE(ini);
- struct pipeline* p = cras_dsp_pipeline_create(ini, &env, "playback");
- ASSERT_TRUE(p);
- ASSERT_EQ(0, cras_dsp_pipeline_load(p));
-
- ASSERT_EQ(5, num_modules); /* one not connected, one disabled */
- struct dsp_module* m0 = find_module("m0");
- struct dsp_module* m1 = find_module("m1");
- struct dsp_module* m2 = find_module("m2");
- struct dsp_module* m3 = find_module("m3");
- struct dsp_module* m5 = find_module("m5");
-
- ASSERT_TRUE(m0);
- ASSERT_TRUE(m1);
- ASSERT_TRUE(m2);
- ASSERT_TRUE(m3);
- ASSERT_FALSE(find_module("m4"));
- ASSERT_TRUE(m5);
- ASSERT_FALSE(find_module("m6"));
-
- ASSERT_EQ(2, cras_dsp_pipeline_get_num_input_channels(p));
- ASSERT_EQ(0, cras_dsp_pipeline_instantiate(p, 48000));
-
- struct data* d0 = (struct data*)m0->data;
- struct data* d1 = (struct data*)m1->data;
- struct data* d2 = (struct data*)m2->data;
- struct data* d3 = (struct data*)m3->data;
- struct data* d5 = (struct data*)m5->data;
-
- /*
- * / --(b)-- 2 --(c)-- \
- * 0 ==(a0, a1)== 1 4 ==(f0,f1)== 5
- * \ --(d)-- 3 --(e)-- /
- *
- *
- * --(g)-- 6 --(h)--
- */
-
- ASSERT_EQ(d0->data_location[0], d1->data_location[0]);
- ASSERT_EQ(d0->data_location[1], d1->data_location[1]);
- ASSERT_EQ(d1->data_location[2], d2->data_location[0]);
- ASSERT_EQ(d1->data_location[3], d3->data_location[0]);
- ASSERT_NE(d2->data_location[0], d2->data_location[1]); /* inplace-broken */
- ASSERT_EQ(d2->data_location[1], d5->data_location[0]); /* m4 is disabled */
- ASSERT_EQ(d3->data_location[1], d5->data_location[1]);
-
- /* need 3 buffers because m2 has inplace-broken flag */
- ASSERT_EQ(3, cras_dsp_pipeline_get_peak_audio_buffers(p));
-
- int16_t* samples = new int16_t[DSP_BUFFER_SIZE];
- fill_test_data(samples, DSP_BUFFER_SIZE);
- cras_dsp_pipeline_apply(p, (uint8_t*)samples, SND_PCM_FORMAT_S16_LE, 100);
- /* the data flow through 2 plugins because m4 is disabled. */
- verify_processed_data(samples, 100, 2);
- delete[] samples;
-
- ASSERT_EQ(1, d1->run_called);
- ASSERT_EQ(1, d3->run_called);
-
- /* check m5 */
- ASSERT_EQ(1, d5->run_called);
- ASSERT_EQ(100, d5->sample_count);
-
- /* Expect the sink module "m5" is set. */
- cras_dsp_pipeline_set_sink_ext_module(p, &ext_mod);
- struct data* d = (struct data*)cras_dsp_module_set_sink_ext_module_val->data;
- ASSERT_STREQ("m5", d->title);
-
- /* re-instantiate */
- ASSERT_EQ(1, d5->instantiate_called);
- ASSERT_EQ(1, d5->get_delay_called);
- ASSERT_EQ(1 + 3 + 5, cras_dsp_pipeline_get_delay(p));
-
- cras_dsp_pipeline_deinstantiate(p);
- cras_dsp_pipeline_instantiate(p, 44100);
-
- ASSERT_EQ(1, d5->deinstantiate_called);
- ASSERT_EQ(2, d5->instantiate_called);
- ASSERT_EQ(2, d5->get_delay_called);
- ASSERT_EQ(1 + 3 + 5, cras_dsp_pipeline_get_delay(p));
- ASSERT_EQ(0, d5->free_module_called);
- ASSERT_EQ(44100, d5->sample_rate);
- ASSERT_EQ(2, d5->connect_port_called[0]);
- ASSERT_EQ(2, d5->connect_port_called[1]);
-
- cras_dsp_pipeline_free(p);
- cras_dsp_ini_free(ini);
- cras_expr_env_free(&env);
-
- really_free_module(m0);
- really_free_module(m1);
- really_free_module(m2);
- really_free_module(m3);
- really_free_module(m5);
-}
-
-} // namespace
-
-int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}