diff options
Diffstat (limited to 'cras/src/tests/cras_dsp_pipeline_unittest.cc')
-rw-r--r-- | cras/src/tests/cras_dsp_pipeline_unittest.cc | 518 |
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(); -} |