WIP: testbench supports multiple output files

user input as "-o output_file1,output_file2,..." to assign multiple output
files.

Signed-off-by: Pin-chih Lin <johnylin@google.com>
diff --git a/tools/testbench/include/testbench/common_test.h b/tools/testbench/include/testbench/common_test.h
index 9ac2f43..fa875c4 100644
--- a/tools/testbench/include/testbench/common_test.h
+++ b/tools/testbench/include/testbench/common_test.h
@@ -17,13 +17,16 @@
 #define DEBUG_MSG_LEN		256
 #define MAX_LIB_NAME_LEN	256
 
+#define MAX_OUTPUT_FILE_NUM	4
+
 /* number of widgets types supported in testbench */
 #define NUM_WIDGETS_SUPPORTED	6
 
 struct testbench_prm {
 	char *tplg_file; /* topology file to use */
 	char *input_file; /* input file name */
-	char *output_file; /* output file name */
+	char *output_file[MAX_OUTPUT_FILE_NUM]; /* output file names */
+	int output_file_num; /* number of output files */
 	char *bits_in; /* input bit format */
 	/*
 	 * input and output sample rate parameters
diff --git a/tools/testbench/testbench.c b/tools/testbench/testbench.c
index 9375c87..919d998 100644
--- a/tools/testbench/testbench.c
+++ b/tools/testbench/testbench.c
@@ -40,6 +40,39 @@
 }
 
 /*
+ * Parse output filenames from user input
+ * This function takes in the output filenames as an input in the format:
+ * "output_file1,output_file2,..."
+ * The max supported output filename number is 4, min is 1.
+ */
+static int parse_output_files(char *outputs, struct testbench_prm *tp)
+{
+	char *output_token = NULL;
+	char *token = strtok_r(outputs, ",", &output_token);
+	int index;
+
+	for (index = 0; index < MAX_OUTPUT_FILE_NUM && token; index++) {
+		/* get output file name with current index */
+		tp->output_file[index] = strdup(token);
+
+		/* next output */
+		token = strtok_r(NULL, ",", &output_token);
+	}
+
+	if (index == MAX_OUTPUT_FILE_NUM && token) {
+		fprintf(stderr, "error: max output file number is %d\n",
+			MAX_OUTPUT_FILE_NUM);
+		for (index = 0; index < MAX_OUTPUT_FILE_NUM; index++)
+			free(tp->output_file[index]);
+		return -EINVAL;
+	}
+
+	/* set total output file number */
+	tp->output_file_num = index;
+	return 0;
+}
+
+/*
  * Parse shared library from user input
  * Currently only handles volume and src comp
  * This function takes in the libraries to be used as an input in the format:
@@ -86,13 +119,14 @@
 /* print usage for testbench */
 static void print_usage(char *executable)
 {
-	printf("Usage: %s -i <input_file> -o <output_file> ", executable);
-	printf("-t <tplg_file> -b <input_format> ");
+	printf("Usage: %s -i <input_file> ", executable);
+	printf("-o <output_file1,output_file2,...> ");
+	printf("-t <tplg_file> -b <input_format> -c <channels>");
 	printf("-a <comp1=comp1_library,comp2=comp2_library>\n");
 	printf("input_format should be S16_LE, S32_LE, S24_LE or FLOAT_LE\n");
 	printf("Example Usage:\n");
 	printf("%s -i in.txt -o out.txt -t test.tplg ", executable);
-	printf("-r 48000 -R 96000 ");
+	printf("-r 48000 -R 96000 -c 2");
 	printf("-b S16_LE -a vol=libsof_volume.so\n");
 }
 
@@ -138,9 +172,9 @@
 			tp->input_file = strdup(optarg);
 			break;
 
-		/* output sample file */
+		/* output sample files */
 		case 'o':
-			tp->output_file = strdup(optarg);
+			ret = parse_output_files(optarg, tp);
 			break;
 
 		/* topology file */
@@ -209,14 +243,17 @@
 	tp.fs_out = 0;
 	tp.bits_in = 0;
 	tp.input_file = NULL;
-	tp.output_file = NULL;
+	for (i = 0; i < MAX_OUTPUT_FILE_NUM; i++)
+		tp.output_file[i] = NULL;
+	tp.output_file_num = 0;
 	tp.channels = TESTBENCH_NCH;
 
 	/* command line arguments*/
 	parse_input_args(argc, argv, &tp);
 
 	/* check args */
-	if (!tp.tplg_file || !tp.input_file || !tp.output_file || !tp.bits_in) {
+	if (!tp.tplg_file || !tp.input_file || !tp.output_file_num ||
+	    !tp.bits_in) {
 		print_usage(argv[0]);
 		exit(EXIT_FAILURE);
 	}
@@ -294,7 +331,10 @@
 	printf("Input bit format: %s\n", tp.bits_in);
 	printf("Input sample rate: %d\n", tp.fs_in);
 	printf("Output sample rate: %d\n", tp.fs_out);
-	printf("Output written to file: \"%s\"\n", tp.output_file);
+	for (i = 0; i < tp.output_file_num; i++) {
+		printf("Output[%d] written to file: \"%s\"\n",
+		       i, tp.output_file[i]);
+	}
 	printf("Input sample count: %d\n", n_in);
 	printf("Output sample count: %d\n", n_out);
 	printf("Total execution time: %.2f us, %.2f x realtime\n",
@@ -304,7 +344,8 @@
 	free(tp.bits_in);
 	free(tp.input_file);
 	free(tp.tplg_file);
-	free(tp.output_file);
+	for (i = 0; i < tp.output_file_num; i++)
+		free(tp.output_file[i]);
 
 	/* close shared library objects */
 	for (i = 0; i < NUM_WIDGETS_SUPPORTED; i++) {
diff --git a/tools/testbench/topology.c b/tools/testbench/topology.c
index b216e6a..2e25456 100644
--- a/tools/testbench/topology.c
+++ b/tools/testbench/topology.c
@@ -22,6 +22,7 @@
 FILE *file;
 char pipeline_string[DEBUG_MSG_LEN];
 struct shared_lib_table *lib_table;
+int output_file_index;
 
 const struct sof_dai_types sof_dais[] = {
 	{"SSP", SOF_DAI_INTEL_SSP},
@@ -332,8 +333,13 @@
 		return -EINVAL;
 	}
 
-	/* configure filewrite */
-	filewrite.fn = strdup(tp->output_file);
+	/* configure filewrite (only single output is valid so far) */
+	if (!tp->output_file[output_file_index]) {
+		fprintf(stderr, "error: output[%d] file name is null\n",
+			output_file_index);
+		return -EINVAL;
+	}
+	filewrite.fn = strdup(tp->output_file[output_file_index]);
 	tp->fw_id = comp_id;
 
 	/* Set format from testbench command line*/
@@ -671,6 +677,9 @@
 {
 	struct snd_soc_tplg_hdr *hdr;
 
+	/* initialize output file index */
+	output_file_index = 0;
+
 	struct comp_info *temp_comp_list = NULL;
 	char message[DEBUG_MSG_LEN];
 	int next_comp_id = 0;