[Sound-open-firmware] [PATCH v4 5/5] testbench: Passthrough component testbench added
Ranjani Sridharan
ranjani.sridharan at linux.intel.com
Thu Sep 7 17:01:31 CEST 2017
This patch adds the testbench code for the passthrough component.
The testbench simulates a simple pipeline with a passthrough comp
connected to 1 source buffer and 1 sink buffer and the contents of
input file are copied to the output file.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
---
tune/c/include/common_test.h | 1 +
tune/passthrough/Makefile.am | 27 ++++
tune/passthrough/passthrough_test.c | 259 ++++++++++++++++++++++++++++++++++++
3 files changed, 287 insertions(+)
create mode 100644 tune/passthrough/Makefile.am
create mode 100644 tune/passthrough/passthrough_test.c
diff --git a/tune/c/include/common_test.h b/tune/c/include/common_test.h
index 01eadec..3cd6bfd 100644
--- a/tune/c/include/common_test.h
+++ b/tune/c/include/common_test.h
@@ -71,6 +71,7 @@
.config = SCONFIG}
#define SPIPE_MIX(scomp) {.comp = scomp, .config = SCONFIG}
#define SPIPE_MUX(scomp) {.comp = scomp, .config = SCONFIG}
+#define SPIPE_PASS(scomp) {.comp = scomp, .config = SCONFIG}
#define SPIPE_SRC(scomp) {.comp = scomp, .config = SCONFIG}
#define SPIPE_EQ_FIR(scomp) {.comp = scomp, .config = SCONFIG}
#define SPIPE_EQ_IIR(scomp) {.comp = scomp, .config = SCONFIG}
diff --git a/tune/passthrough/Makefile.am b/tune/passthrough/Makefile.am
new file mode 100644
index 0000000..1ca1b60
--- /dev/null
+++ b/tune/passthrough/Makefile.am
@@ -0,0 +1,27 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+SOF = ../../../sof.git
+SRCADIR = $(SOF)/src/audio
+INCDIR1 = ../c/include
+INCDIR2 = $(SOF)/src/include
+INCDIR3 = $(SOF)/src/arch/xtensa/include
+INCDIR4 = $(SOF)/src/platform/baytrail/include
+INCLUDE = -I$(INCDIR1) -I$(INCDIR2) -I$(INCDIR3) -I$(INCDIR4) -I$(SRCADIR)
+DEFINE = -DCONFIG_BAYTRAIL -D__XTENSA__ -DMODULE_TEST
+
+AM_CPPFLAGS = $(INCLUDE) $(DEFINE)
+AM_CFLAGS = -m32 -g -Wall
+LDADD = -lm
+
+bin_PROGRAMS = passthrough_test
+
+passthrough_test_SOURCES = passthrough_test.c \
+ ../../../sof.git/src/audio/passthrough.c \
+ ../../../sof.git/src/audio/component.c \
+ ../../../sof.git/src/audio/pipeline.c \
+ ../../../sof.git/src/audio/buffer.c \
+ ../../../sof.git/src/ipc/ipc.c \
+ ../c/src/fileread.c \
+ ../c/src/filewrite.c \
+ ../c/src/common_test.h \
+ ../c/src/common_test.c
diff --git a/tune/passthrough/passthrough_test.c b/tune/passthrough/passthrough_test.c
new file mode 100644
index 0000000..a6f9099
--- /dev/null
+++ b/tune/passthrough/passthrough_test.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2017, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Intel Corporation nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
+ */
+
+#include "common_test.h"
+
+/* Internal buffer */
+#define TEST_BENCH_DEADLINE 5000 /* 5 ms */
+#define TEST_BENCH_NCH 2 /* Stereo */
+#define TEST_BENCH_RATE_MAX 192000 /* Hz */
+#define TEST_BENCH_FRAME_SIZE (4 * TEST_BENCH_NCH) /* 4bytes x NCH */
+#define TEST_BENCH_PERIOD_FRAMES (TEST_BENCH_RATE_MAX*TEST_BENCH_DEADLINE/1e6)
+#define INT_PERIOD_SIZE (TEST_BENCH_PERIOD_FRAMES * TEST_BENCH_FRAME_SIZE)
+
+/* main firmware context */
+static struct reef reef;
+
+/*
+ * Test Pipeline (ID=0)
+ *
+ * Fileread(0) ---> B(3)---> Passthrough(1) ---> B(4) ---> Filewrite(2)
+ *
+ */
+
+#define FR_ID 0
+#define PASSTHROUGH_ID 1 /* scheduling component */
+#define FW_ID1 2
+#define FW_ID2 3
+#define PIPE_ID 0
+#define PIPE_COMP_ID 7
+#define SCHED_ID PASSTHROUGH_ID
+
+
+/* components used in static pipeline */
+static struct sof_ipc_comp_fileread fileread_p0[] = {
+ SPIPE_FILEREAD(SPIPE_COMP(0, SOF_COMP_FILEREAD, sof_ipc_comp_fileread),
+ "in.txt"), /* ID = 0 */
+};
+
+static struct sof_ipc_comp_filewrite filewrite_p0[] = {
+ SPIPE_FILEWRITE(SPIPE_COMP(2, SOF_COMP_FILEWRITE,
+ sof_ipc_comp_filewrite), "out_1.txt"), /* ID = 2 */
+};
+
+static struct sof_ipc_comp_passthrough passthrough_p0[] = {
+ SPIPE_PASS(SPIPE_COMP(1, SOF_COMP_PASSTHROUGH,
+ sof_ipc_comp_passthrough)), /* ID = 1 */
+};
+
+static struct scomps scomps_p0[] = {
+ SCOMP(fileread_p0),
+ SCOMP(passthrough_p0),
+ SCOMP(filewrite_p0),
+};
+
+/*
+ * Buffers used in static pipeline 2.
+ */
+static struct sof_ipc_buffer buffers_p0[] = {
+ SPIPE_BUFFER(3, INT_PERIOD_SIZE * 2), /* B(3) */
+ SPIPE_BUFFER(4, INT_PERIOD_SIZE * 2), /* B(4) */
+
+};
+
+/* pipeline 0 component/buffer connections */
+static struct sof_ipc_pipe_comp_connect connect_p0[] = {
+ SPIPE_COMP_CONNECT(0, 3), /* p(0): Fileread(0) -> B(3) */
+ SPIPE_COMP_CONNECT(3, 1), /* p(0): B(3) -> Passthrough(1) */
+ SPIPE_COMP_CONNECT(1, 4), /* p(0): Passthrough(1) -> B(4) */
+ SPIPE_COMP_CONNECT(4, 2), /* p(0): B(4)-> Filewrite(2) */
+};
+
+/* the static pipelines */
+static struct spipe spipe[] = {
+ SPIPE(scomps_p0, buffers_p0, connect_p0),
+};
+
+/* pipelines */
+struct sof_ipc_pipe_new pipeline[] = {
+ SPIPE_PIPE(PIPE_ID, 0, PIPE_COMP_ID, SCHED_ID, TEST_BENCH_DEADLINE,
+ TASK_PRI_LOW, TEST_BENCH_PERIOD_FRAMES),
+};
+
+/* pipeline setup, params and start */
+static int pipeline_calls(int i)
+{
+ int ret = 0;
+ struct pipeline *p;
+ struct ipc_comp_dev *pcm_dev;
+
+ /* construct pipeline */
+ ret = test_bench_pipeline_setup(&reef, &pipeline[i], &spipe[i]);
+ if (ret < 0) {
+ printf("error: pipeline setup\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* set up pipeline params */
+ ret = test_bench_pipeline_params(reef.ipc, TEST_BENCH_RATE_MAX,
+ TEST_BENCH_NCH, FR_ID, TEST_BENCH_DEADLINE,
+ pipeline[i].pipeline_id);
+ if (ret < 0) {
+ printf("error: pipeline params\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* prepare pipeline */
+ pcm_dev = ipc_get_comp(reef.ipc, FR_ID);
+ p = pcm_dev->cd->pipeline;
+ ret = pipeline_prepare(p, pcm_dev->cd);
+ if (ret < 0) {
+ printf("error: pipeline prepare\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* start pipeline */
+ ret = pipeline_cmd(p, pcm_dev->cd, COMP_CMD_START, NULL);
+ if (ret < 0) {
+ printf("error: start pipeline cmd\n");
+ ret = -EINVAL;
+ }
+
+out:
+ return ret;
+}
+
+/* copy frames from input file until EOF */
+static int schedule_pipeline(struct ipc_comp_dev *pcm_dev,
+ struct pipeline *p, struct fileread_comp_data *frcd)
+{
+ /* copy period frames from input file to output files */
+ while (frcd->frs.reached_eof == 0)
+ pipeline_schedule_copy(p, pcm_dev->cd);
+
+ return 0;
+}
+
+void usage(char *executable)
+{
+ fprintf(stderr, "Usage: %s <input.txt> <output.txt>\n",
+ executable);
+}
+
+int main(int argc, char **argv)
+{
+ struct ipc_comp_dev *pcm_dev;
+ struct pipeline *p;
+ struct comp_dev *cd;
+ int ret = 0, samples_in, samples_out, i = 0;
+ struct fileread_comp_data *frcd;
+ struct filewrite_comp_data *fwcd1;
+ clock_t tic, toc;
+ double c_realtime, t_exec;
+
+ /* handle command line arguments*/
+ if (argc > 2) {
+ switch (argc) {
+ case 3:
+ fileread_p0[0].fn = argv[1];
+ filewrite_p0[0].fn = argv[2];
+ break;
+ default:
+ usage(argv[0]);
+ return EXIT_SUCCESS;
+ }
+ } else {
+ usage(argv[0]);
+ return EXIT_SUCCESS;
+ }
+
+ /* init components */
+ sys_comp_init();
+ sys_comp_fileread_init();
+ sys_comp_filewrite_init();
+ sys_comp_passthrough_init();
+
+ for (i = 0; i < ARRAY_SIZE(pipeline); i++) {
+ /* perform pipeline set up and start*/
+ ret = pipeline_calls(i);
+ if (ret < 0)
+ exit(EXIT_FAILURE);
+
+ /* Reduce print output */
+ test_bench_disable_trace();
+
+ /* fileread and filewrite component data */
+ pcm_dev = ipc_get_comp(reef.ipc, FW_ID1);
+ fwcd1 = comp_get_drvdata(pcm_dev->cd);
+ pcm_dev = ipc_get_comp(reef.ipc, FR_ID);
+ frcd = comp_get_drvdata(pcm_dev->cd);
+ p = pcm_dev->cd->pipeline;
+ cd = pcm_dev->cd;
+
+ tic = clock();
+
+ /*
+ * Run copy until EOF from fileread
+ */
+ ret = schedule_pipeline(pcm_dev, p, frcd);
+ if (ret < 0)
+ exit(EXIT_FAILURE);
+
+ toc = clock();
+
+ /* samples read in and written out */
+ samples_in = frcd->frs.n;
+ samples_out = fwcd1->fws.n;
+
+ test_bench_enable_trace();
+
+ /* reset and free pipeline */
+ ret = pipeline_reset(p, cd);
+ if (ret < 0) {
+ printf("error: pipeline reset\n");
+ exit(EXIT_FAILURE);
+ }
+ pipeline_free(p);
+
+ /* report test results */
+ t_exec = (double) (toc - tic) / CLOCKS_PER_SEC;
+ c_realtime = (double) samples_out / TEST_BENCH_NCH /
+ TEST_BENCH_RATE_MAX / t_exec;
+ printf("Read %d input samples,\n", samples_in);
+ printf("wrote %d output samples,\n", samples_out);
+ printf("test execution time was %.2f us, %.2fx realtime.\n",
+ 1e3 * t_exec, c_realtime);
+ }
+
+ return EXIT_SUCCESS;
+}
--
2.9.3
More information about the Sound-open-firmware
mailing list