[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