[Sound-open-firmware] [PATCH v4 3/5] testbench: updated common_test methods

Ranjani Sridharan ranjani.sridharan at linux.intel.com
Thu Sep 7 17:01:29 CEST 2017


This patch updates the following in the common_test methods

testbench_pipeline_setup() updated with pointer to pipeline desc
and connection description

testbench_pipeline_params() method added to set stream params

testbench_params_unmute_start() updated with the above method

formatting changes to print relevant error messages

MUX component specific convenience constructors

Signed-off-by: Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
---
 tune/c/include/common_test.h |   6 +-
 tune/c/src/common_test.c     | 419 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 423 insertions(+), 2 deletions(-)
 create mode 100644 tune/c/src/common_test.c

diff --git a/tune/c/include/common_test.h b/tune/c/include/common_test.h
index 73d6fe5..01eadec 100644
--- a/tune/c/include/common_test.h
+++ b/tune/c/include/common_test.h
@@ -39,6 +39,7 @@
 #include <stdio.h>
 
 #include <reef/ipc.h>
+#include <reef/reef.h>
 #include <reef/audio/pipeline.h>
 #include <reef/audio/format.h>
 
@@ -69,6 +70,7 @@
 	{.comp = scomp, .min_value = vmin, .max_value = vmax,\
 	.config = SCONFIG}
 #define SPIPE_MIX(scomp) {.comp = scomp, .config = SCONFIG}
+#define SPIPE_MUX(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}
@@ -76,7 +78,6 @@
 #define SPIPE_FILEREAD(scomp, fn_in) {.comp = scomp, .config = SCONFIG, .fn = fn_in}
 #define SPIPE_FILEWRITE(scomp, fn_out) {.comp = scomp, .config = SCONFIG, .fn = fn_out}
 
-
 /*
  * Static Pipeline Convenience Constructor
  */
@@ -96,7 +97,6 @@
 	{.comps = (struct sof_ipc_comp *)ccomps, .num_comps \
 		= ARRAY_SIZE(ccomps)}
 
-
 #define SPIPE(ncomp, sbuffer, sconnect) \
 	{.scomps = ncomp, .num_scomps = ARRAY_SIZE(ncomp), \
 	.buffer = sbuffer, .num_buffers = ARRAY_SIZE(sbuffer), \
@@ -178,6 +178,8 @@ int test_bench_pipeline_setup(struct reef *reef,
 
 int test_bench_pipeline_params_unmute_start(struct ipc *ipc,
 	int32_t fs, int nch, int deadline, int sched_id, int pipe_id);
+int test_bench_pipeline_params(struct ipc *ipc, int32_t fs,
+	int nch, int host_comp_id, int deadline, uint32_t pipe_id);
 
 void test_bench_enable_trace(void);
 void test_bench_disable_trace(void);
diff --git a/tune/c/src/common_test.c b/tune/c/src/common_test.c
new file mode 100644
index 0000000..a245286
--- /dev/null
+++ b/tune/c/src/common_test.c
@@ -0,0 +1,419 @@
+/* Simple test bench versions of SOF functions */
+
+/*
+ * 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: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
+ *         Liam Girdwood <liam.r.girdwood at linux.intel.com>
+ *         Keyon Jie <yang.jie at linux.intel.com>
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <reef/task.h>
+#include <reef/alloc.h>
+#include <reef/ipc.h>
+#include <reef/wait.h>
+#include <reef/intel-ipc.h>
+#include <reef/audio/pipeline.h>
+#include "common_test.h"
+
+/* Use simplified host test bench versions for features */
+#define TB_HOST_ALLOC_FREE_MEMCPY 1
+#define TB_TRACE 1
+#define TB_SCHEDULE 1
+#define TB_IPC 1
+#define TB_TIMER 1
+
+#if TB_IPC
+struct ipc *_ipc;
+
+int ipc_stream_send_xrun(struct comp_dev *dev,
+	struct sof_ipc_stream_posn *posn)
+{
+	return 0;
+}
+#endif
+
+#if TB_SCHEDULE
+
+struct schedule_data {
+	spinlock_t lock;
+	struct list_item list; /* list of tasks in priority queue */
+	uint32_t clock;
+};
+static struct schedule_data *sch;
+#endif
+
+#if TB_TRACE
+static int test_bench_trace = 1;
+#endif
+
+#if TB_TRACE
+
+char replace_blank(char x)
+{
+	char y = x;
+
+	if ((y != '-') && (y != '+') && (y != '_')) {
+		if (y < 'A')
+			y = ' ';
+
+		if (y > 'z')
+			y = ' ';
+	}
+	return y;
+}
+
+void _trace_event(uint32_t event)
+{
+	char a, b, c;
+
+	if (test_bench_trace > 0) {
+		a = replace_blank((char) (event & 0xff));
+		b = replace_blank((char) ((event >> 8) & 0xff));
+		c = replace_blank((char) ((event >> 16) & 0xff));
+		printf("Trace %10d %c%c%c\n", event, c, b, a);
+	}
+}
+
+void test_bench_enable_trace(void)
+{
+	test_bench_trace = 1;
+	printf("Trace print enabled\n");
+}
+
+void test_bench_disable_trace(void)
+{
+	test_bench_trace = 0;
+	printf("Trace print disabled\n");
+}
+#endif
+
+#if TB_HOST_ALLOC_FREE_MEMCPY
+
+void *rmalloc(int zone, int module, size_t bytes)
+{
+	return malloc(bytes);
+}
+
+void *rzalloc(int zone, int module, size_t bytes)
+{
+	return malloc(bytes);
+}
+
+void rfree(void *ptr)
+{
+	free(ptr);
+}
+
+void *rballoc(int zone, int module, size_t bytes)
+{
+	return malloc(bytes);
+}
+
+void rbfree(void *ptr)
+{
+	free(ptr);
+}
+
+void *xthal_memcpy(void *dest, const void *src, size_t size)
+{
+	return memcpy(dest, src, size);
+}
+
+#endif
+
+#if TB_SCHEDULE
+
+void schedule_task_complete(struct task *task)
+{
+
+	list_item_del(&task->list);
+	task->state = TASK_STATE_COMPLETED;
+}
+
+void schedule_task(struct task *task, uint32_t deadline, uint16_t priority,
+	void *data)
+{
+	task->deadline = deadline;
+	task->priority = priority;
+	task->sdata = data;
+	list_item_prepend(&task->list, &sch->list);
+	task->state = TASK_STATE_QUEUED;
+
+	if (task->func)
+		task->func(task->data);
+
+	schedule_task_complete(task);
+}
+
+void schedule(void)
+{
+}
+
+int scheduler_init(struct reef *reef)
+{
+	trace_pipe("ScI");
+
+	sch = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(*sch));
+	list_init(&sch->list);
+	spinlock_init(&sch->lock);
+
+	return 0;
+}
+
+#endif
+
+#if TB_IPC
+
+int platform_ipc_init(struct ipc *ipc)
+{
+	struct intel_ipc_data *iipc;
+	//uint32_t imrd;
+	int i;
+
+	_ipc = ipc;
+
+	/* init ipc data */
+	iipc = rzalloc(RZONE_SYS, RFLAGS_NONE, sizeof(struct intel_ipc_data));
+	ipc_set_drvdata(_ipc, iipc);
+	_ipc->dsp_msg = NULL;
+	list_init(&ipc->empty_list);
+	list_init(&ipc->msg_list);
+	spinlock_init(&ipc->lock);
+
+	for (i = 0; i < MSG_QUEUE_SIZE; i++)
+		list_item_prepend(&ipc->message[i].list, &ipc->empty_list);
+
+	/* allocate page table buffer */
+	iipc->page_table = rballoc(RZONE_SYS, RFLAGS_NONE,
+		HOST_PAGE_SIZE);
+	if (iipc->page_table)
+		bzero(iipc->page_table, HOST_PAGE_SIZE);
+
+	/* PM */
+	iipc->pm_prepare_D3 = 0;
+
+	return 0;
+}
+
+int ipc_stream_send_xrun(struct comp_dev *cdev,
+	struct sof_ipc_stream_posn *posn)
+{
+	return 0;
+}
+
+#endif
+
+#if TB_TIMER
+
+/* get timestamp for DAI stream DMA position */
+void platform_dai_timestamp(struct comp_dev *dai,
+	struct sof_ipc_stream_posn *posn)
+{
+}
+
+/* get timestamp for host stream DMA position */
+void platform_host_timestamp(struct comp_dev *host,
+	struct sof_ipc_stream_posn *posn)
+{
+}
+
+#endif
+
+int test_bench_pipeline_setup(struct reef *reef,
+	struct sof_ipc_pipe_new *pipeline, struct spipe *spipe)
+{
+	struct scomps *sc;
+	int i, j;
+	struct sof_ipc_comp *c;
+	struct ipc *ipc;
+
+	/* Init IPC */
+	if (ipc_init(reef) < 0) {
+		fprintf(stderr, "error: IPC init\n");
+		return -EINVAL;
+	}
+	ipc = reef->ipc;
+
+	/* Init scheduler */
+	if (scheduler_init(reef) < 0) {
+		fprintf(stderr, "error: scheduler init\n");
+		return -EINVAL;
+	}
+
+	/* Init pipeline system */
+	if (pipeline_init() < 0) {
+		fprintf(stderr, "error: pipeline init\n");
+		return -EINVAL;
+	}
+
+
+	/* Register components */
+	sc = spipe->scomps;
+	for (i = 0; i < spipe->num_scomps; i++) {
+		c = sc[i].comps;
+		for (j = 0; j < sc[i].num_comps; j++) {
+			if (ipc_comp_new(ipc, c) < 0) {
+				fprintf(stderr, "error: comp register\n");
+				return -EINVAL;
+			}
+			c = (void *) c + c->hdr.size;
+		}
+	}
+
+	/* Pipeline new must be after component registration since the
+	 * scheduling component	must exist.
+	 */
+	if (ipc_pipeline_new(ipc, pipeline) < 0) {
+		fprintf(stderr, "error: pipeline new\n");
+		return -EINVAL;
+	}
+
+	/* Register buffers */
+	for (i = 0; i < spipe->num_buffers; i++) {
+		if (ipc_buffer_new(ipc, &spipe->buffer[i]) < 0) {
+			fprintf(stderr, "error: buffer new\n");
+			return -EINVAL;
+		}
+	}
+
+	/* Connect components */
+	for (i = 0; i < spipe->num_connections; i++) {
+		if (ipc_comp_connect(ipc, &spipe->connect[i]) < 0) {
+			fprintf(stderr, "error: comp connect\n");
+			return -EINVAL;
+		}
+	}
+
+	/* Pipeline complete */
+	ipc_pipeline_complete(ipc, pipeline->comp_id);
+
+	return 0;
+}
+
+int test_bench_pipeline_params_unmute_start(struct ipc *ipc,
+	int32_t fs, int nch, int deadline, int sched_id, int pipe_id)
+{
+	int ret;
+	struct ipc_comp_dev *pcm_dev;
+	struct pipeline *p;
+	struct comp_dev *cd;
+
+	ret = test_bench_pipeline_params(ipc, fs, nch, sched_id, deadline,
+		pipe_id);
+	if (ret < 0) {
+		printf("error: pipeline params\n");
+		return -EINVAL;
+	}
+
+	/* Get IPC component device for pipeline and f */
+	pcm_dev = ipc_get_comp(ipc, sched_id);
+	if (pcm_dev == NULL) {
+		printf("error: ipc get comp\n");
+		return -EINVAL;
+	}
+
+	/* Point to pipeline */
+	cd = pcm_dev->cd;
+	p = pcm_dev->cd->pipeline;
+
+	/* Unmute and start the pipeline */
+	pipeline_cmd(p, cd, COMP_CMD_UNMUTE, NULL);
+	pipeline_cmd(p, cd, COMP_CMD_START, NULL);
+
+	return 0;
+}
+
+int test_bench_pipeline_params(struct ipc *ipc, int32_t fs,
+	int nch, int host_comp_id, int deadline, uint32_t pipe_id)
+{
+	int fs_period, ret = 0;
+	struct ipc_comp_dev *pcm_dev;
+	struct pipeline *p;
+	struct comp_dev *cd;
+	struct sof_ipc_pcm_params params;
+	struct sof_ipc_ctrl_data ctrl_cmd;
+
+	/* Compute period from sample rates */
+	fs_period = (int) (0.9999 + fs * deadline / 1e6);
+
+	params.comp_id = pipe_id;
+	params.params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
+	params.params.frame_fmt = SOF_IPC_FRAME_S32_LE;
+	params.params.direction = SOF_IPC_STREAM_PLAYBACK;
+	params.params.rate = fs;
+	params.params.channels = nch;
+	switch (params.params.frame_fmt) {
+	case(SOF_IPC_FRAME_S16_LE):
+		params.params.sample_container_bytes = 2;
+		params.params.sample_valid_bytes = 2;
+		params.params.host_period_bytes = fs_period * nch *
+			params.params.sample_container_bytes;
+		break;
+	case(SOF_IPC_FRAME_S32_LE):
+		params.params.sample_container_bytes = 4;
+		params.params.sample_valid_bytes = 4;
+		params.params.host_period_bytes = fs_period * nch *
+			params.params.sample_container_bytes;
+		break;
+	default:
+		printf("error: invalid frame format\n");
+		return -EINVAL;
+	}
+
+	/* Get IPC component device for pipeline*/
+	pcm_dev = ipc_get_comp(ipc, host_comp_id);
+	if (pcm_dev == NULL) {
+		printf("error: ipc get comp\n");
+		return -EINVAL;
+	}
+
+	/* Point to pipeline */
+	cd = pcm_dev->cd;
+	p = pcm_dev->cd->pipeline;
+
+	/* Pipeline params */
+	if (p == NULL) {
+		printf("error: pipeline NULL\n");
+		return -EINVAL;
+	}
+
+	ret = pipeline_params(p, cd, &params);
+	if (ret < 0) {
+		printf("error: pipeline_params\n");
+	}
+
+	return ret;
+}
-- 
2.9.3



More information about the Sound-open-firmware mailing list