[Sound-open-firmware] [PATCH 4/5] SRC: IPC updates and fixes v3

Seppo Ingalsuo seppo.ingalsuo at linux.intel.com
Wed Jun 28 18:25:51 CEST 2017


SRC sets the sink and downstream pipeline PCM rate, period_count and
period_bytes in src_params() according to received out_rate via IPC.

Fail in delay lines allocation results to -ENOMEM error.

Function call comp_set_sink_params() is renamed to
comp_buffer_sink_params().

Added void to functions and corresponding headers without parameters.

Plus white space and long lines fixes for all SRC source files.


Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
---
 src/audio/src.c        | 71 +++++++++++++++++++++++++++++++++++---------------
 src/audio/src_core.c   | 40 ++++++++++++++++++----------
 src/audio/src_core.h   | 12 +++++----
 src/include/uapi/ipc.h |  1 +
 4 files changed, 84 insertions(+), 40 deletions(-)

diff --git a/src/audio/src.c b/src/audio/src.c
index c338220..4e46338 100644
--- a/src/audio/src.c
+++ b/src/audio/src.c
@@ -56,9 +56,13 @@
 /* src component private data */
 struct comp_data {
 	struct polyphase_src src[PLATFORM_MAX_CHANNELS];
+	/* Next two elements must be kept in this order since
+	 * the end of pcm_params is a flexible array.
+	 */
+	struct sof_ipc_pcm_params pcm_params;
+	enum sof_ipc_chmap channel_map[PLATFORM_MAX_CHANNELS];
 	int32_t *delay_lines;
 	int scratch_length;
-	//int32_t z[STAGE_BUF_SIZE];
 	void (*src_func)(struct comp_dev *dev,
 		struct comp_buffer *source,
 		struct comp_buffer *sink,
@@ -149,7 +153,8 @@ static void src_2s_s32_default(struct comp_dev *dev,
 	int n_written = 0;
 
 	if (cd->src[0].mute) {
-		src_muted_s32(source, sink, blk_in, blk_out, nch, source_frames);
+		src_muted_s32(source, sink, blk_in, blk_out, nch,
+			source_frames);
 		return;
 	}
 
@@ -214,14 +219,15 @@ static void src_1s_s32_default(struct comp_dev *dev,
 	int blk_out = cd->src[0].blk_out;
 	int n_times = cd->src[0].stage1_times;
 	int nch = sink->params.pcm->channels;
-	int32_t *dest = (int32_t*) sink->w_ptr;
-	int32_t *src = (int32_t*) source->r_ptr;
+	int32_t *dest = (int32_t *) sink->w_ptr;
+	int32_t *src = (int32_t *) source->r_ptr;
 	int n_read = 0;
 	int n_written = 0;
 	struct src_stage_prm s1;
 
 	if (cd->src[0].mute) {
-		src_muted_s32(source, sink, blk_in, blk_out, nch, source_frames);
+		src_muted_s32(source, sink, blk_in, blk_out, nch,
+			source_frames);
 		return;
 	}
 
@@ -263,7 +269,7 @@ static struct comp_dev *src_new(struct sof_ipc_comp *comp)
 {
 	struct comp_dev *dev;
 	struct sof_ipc_comp_src *src;
-	struct sof_ipc_comp_src *ipc_src = (struct sof_ipc_comp_src *)comp;
+	struct sof_ipc_comp_src *ipc_src = (struct sof_ipc_comp_src *) comp;
 	struct comp_data *cd;
 	int i;
 
@@ -274,7 +280,7 @@ static struct comp_dev *src_new(struct sof_ipc_comp *comp)
 	if (dev == NULL)
 		return NULL;
 
-	src = (struct sof_ipc_comp_src *)&dev->comp;
+	src = (struct sof_ipc_comp_src *) &dev->comp;
 	memcpy(src, ipc_src, sizeof(struct sof_ipc_comp_src));
 
 	cd = rmalloc(RZONE_RUNTIME, RFLAGS_NONE, sizeof(*cd));
@@ -317,6 +323,7 @@ static int src_params(struct comp_dev *dev, struct stream_params *params)
 	int32_t *buffer_start;
 	int n = 0;
 	struct comp_data *cd = comp_get_drvdata(dev);
+	struct sof_ipc_comp_src *src = (struct sof_ipc_comp_src *) &dev->comp;
 
 	trace_src("SPa");
 
@@ -325,23 +332,45 @@ static int src_params(struct comp_dev *dev, struct stream_params *params)
 		|| (params->pcm->frame_fmt != SOF_IPC_FRAME_S32_LE))
 		return -EINVAL;
 
-	/* No data transformation */
-	comp_set_sink_params(dev, params);
+	comp_buffer_sink_params(dev, params);
 
-	/* Allocate needed memory for delay lines */
 	source = list_first_item(&dev->bsource_list, struct comp_buffer,
 		sink_list);
 	sink = list_first_item(&dev->bsink_list, struct comp_buffer,
 		source_list);
-	src_buffer_lengths(&need, source->params.pcm->rate,
-		sink->params.pcm->rate, source->params.pcm->channels);
+
+	/* Copy PCM stream parameters and the channel map array */
+	memcpy(&cd->pcm_params, &(*params->pcm),
+		sizeof(struct sof_ipc_pcm_params));
+	for (i = 0; i < params->pcm->channels; i++)
+		cd->pcm_params.channel_map[i] = params->pcm->channel_map[i];
+
+	/* Point sink stream parameters to copy */
+	sink->params.pcm = &cd->pcm_params;
+
+	/* Stored IPC from src_new() contains the output rate for sink,
+	 * set the new rate for sink.
+	 */
+	sink->params.pcm->rate = src->out_rate;
+
+	/* Adjust sink buffer parameters to match fs_out/fs_in */
+	sink->params.pcm->period_count = sink->params.pcm->period_count
+		* sink->params.pcm->rate / source->params.pcm->rate;
+	sink->params.pcm->period_bytes = sink->params.pcm->period_bytes
+		* sink->params.pcm->rate / source->params.pcm->rate;
+
+	/* Allocate needed memory for delay lines */
+	if (src_buffer_lengths(&need, source->params.pcm->rate,
+		sink->params.pcm->rate, source->params.pcm->channels) < 0)
+		return -EINVAL;
+
 	delay_lines_size = sizeof(int32_t) * need.total;
 	if (cd->delay_lines != NULL)
 		rfree(cd->delay_lines);
 
 	cd->delay_lines = rmalloc(RZONE_RUNTIME, RFLAGS_NONE, delay_lines_size);
 	if (cd->delay_lines == NULL)
-		return -EINVAL;
+		return -ENOMEM;
 
 	/* Clear all delay lines here */
 	memset(cd->delay_lines, 0, delay_lines_size);
@@ -369,18 +398,19 @@ static int src_params(struct comp_dev *dev, struct stream_params *params)
 		 */
 		trace_src("SFa");
 		cd->src_func = fallback_s32;
-		return(-EINVAL);
-		break;
+		return -EINVAL;
 	}
 
 	/* Check that src blk_in and blk_out are less than params.period_frames.
 	 * Return an error if the period is too short.
 	 */
-	if (src_polyphase_get_blk_in(&cd->src[0]) > source->params.pcm->period_count)
-		return(-EINVAL);
+	if (src_polyphase_get_blk_in(&cd->src[0])
+		> source->params.pcm->period_count)
+		return -EINVAL;
 
-	if (src_polyphase_get_blk_out(&cd->src[0]) > sink->params.pcm->period_count)
-		return(-EINVAL);
+	if (src_polyphase_get_blk_out(&cd->src[0])
+		> sink->params.pcm->period_count)
+		return -EINVAL;
 
 
 	return 0;
@@ -548,8 +578,7 @@ static int src_reset(struct comp_dev *dev)
 
 struct comp_driver comp_src = {
 	.type = SOF_COMP_SRC,
-	.ops =
-	{
+	.ops = {
 		.new = src_new,
 		.free = src_free,
 		.params = src_params,
diff --git a/src/audio/src_core.c b/src/audio/src_core.c
index a9c503d..7deae14 100644
--- a/src/audio/src_core.c
+++ b/src/audio/src_core.c
@@ -65,7 +65,7 @@ int src_fir_delay_length(struct src_stage *s)
 int src_out_delay_length(struct src_stage *s)
 {
 
-	return(s->num_of_subfilters - 1) * s->odm + 1;
+	return (s->num_of_subfilters - 1) * s->odm + 1;
 }
 
 /* Calculates the buffer length needed between two SRC stages */
@@ -86,6 +86,7 @@ int src_stage_buf_length(struct src_stage *s1, struct src_stage *s2)
 int src_find_fs(int fs_list[], int list_length, int fs)
 {
 	int i;
+
 	for (i = 0; i < list_length; i++) {
 		if (fs_list[i] == fs)
 			return i;
@@ -94,10 +95,11 @@ int src_find_fs(int fs_list[], int list_length, int fs)
 }
 
 /* Match SOF and defined SRC input rates into a bit mask */
-int32_t src_input_rates()
+int32_t src_input_rates(void)
 {
 	int n, b;
 	int mask = 0;
+
 	for (n = SOF_RATES_LENGTH - 1; n >= 0; n--) {
 		b = (src_find_fs(src_in_fs, NUM_IN_FS, sof_rates[n]) >= 0)
 			? 1 : 0;
@@ -107,10 +109,11 @@ int32_t src_input_rates()
 }
 
 /* Match SOF and defined SRC output rates into a bit mask */
-int32_t src_output_rates()
+int32_t src_output_rates(void)
 {
 	int n, b;
 	int mask = 0;
+
 	for (n = SOF_RATES_LENGTH - 1; n >= 0; n--) {
 		b = (src_find_fs(src_out_fs, NUM_OUT_FS, sof_rates[n]) >= 0)
 			? 1 : 0;
@@ -152,7 +155,7 @@ int src_buffer_lengths(struct src_alloc *a, int fs_in, int fs_out, int nch)
 	return 0;
 }
 
-static void src_state_reset(struct src_state* state)
+static void src_state_reset(struct src_state *state)
 {
 
 	state->fir_delay_size = 0;
@@ -316,7 +319,8 @@ static inline int32_t fir_filter(
 	n1 = fir->fir_ri + 1;
 	if (n1 > filter_length) {
 		/* No need to un-wrap fir read index, make sure fir_fi
-		 * is ge 0 after FIR computation */
+		 * is ge 0 after FIR computation.
+		 */
 		fir_part(&y, filter_length, coefs, coefi, fir->fir_delay,
 			&fir->fir_ri);
 	} else {
@@ -331,7 +335,7 @@ static inline int32_t fir_filter(
 	/* Q9.47 -> Q9.24, saturate to Q8.24 */
 	y = y >> (23 + shift);
 
-	return(int32_t) sat_int32(y);
+	return (int32_t)sat_int32(y);
 }
 
 void src_polyphase_stage_cir(struct src_stage_prm *s)
@@ -377,7 +381,8 @@ void src_polyphase_stage_cir(struct src_stage_prm *s)
 				if (s->x_rptr >= s->x_end_addr)
 					s->x_rptr = (int32_t *)
 					((size_t) s->x_rptr - s->x_size);
-				if (s->state->fir_wi == s->state->fir_delay_size)
+				if (s->state->fir_wi
+					== s->state->fir_delay_size)
 					s->state->fir_wi = 0;
 			}
 		}
@@ -416,14 +421,16 @@ void src_polyphase_stage_cir(struct src_stage_prm *s)
 			if (m < n_wrap_min) {
 				/* No circular wrap need */
 				while (m > 0) {
-					*s->y_wptr = s->state->out_delay[s->state->out_ri++];
+					*s->y_wptr = s->state->out_delay[
+						s->state->out_ri++];
 					s->y_wptr += s->y_inc;
 					m -= s->y_inc;
 				}
 			} else {
 				/* Wrap in n_wrap_min/y_inc samples */
 				while (n_wrap_min > 0) {
-					*s->y_wptr = s->state->out_delay[s->state->out_ri++];
+					*s->y_wptr = s->state->out_delay[
+						s->state->out_ri++];
 					s->y_wptr += s->y_inc;
 					n_wrap_min -= s->y_inc;
 					m -= s->y_inc;
@@ -434,7 +441,8 @@ void src_polyphase_stage_cir(struct src_stage_prm *s)
 					(int32_t *)
 					((size_t) s->y_wptr - s->y_size);
 
-				if (s->state->out_ri == s->state->out_delay_size)
+				if (s->state->out_ri
+					== s->state->out_delay_size)
 					s->state->out_ri = 0;
 			}
 		}
@@ -460,7 +468,8 @@ void src_print_info(struct polyphase_src *src)
 
 	printf("SRC1 filter length %d\n", n1);
 	printf("SRC1 subfilter length %d\n", src->stage1->subfilter_length);
-	printf("SRC1 number of subfilters %d\n", src->stage1->num_of_subfilters);
+	printf("SRC1 number of subfilters %d\n",
+		src->stage1->num_of_subfilters);
 	printf("SRC1 idm %d\n", src->stage1->idm);
 	printf("SRC1 odm %d\n", src->stage1->odm);
 	printf("SRC1 input blk %d\n", src->stage1->blk_in);
@@ -470,14 +479,16 @@ void src_print_info(struct polyphase_src *src)
 	if (n1 > 3) {
 		printf("SRC1 coef[1] %d\n", src->stage1->coefs[1]);
 		printf("SRC1 coef[2] %d\n", src->stage1->coefs[2]);
-		printf("SRC1 coef[%d] %d\n", n1 - 1, src->stage1->coefs[n1 - 1]);
+		printf("SRC1 coef[%d] %d\n",
+			n1 - 1, src->stage1->coefs[n1 - 1]);
 	}
 	printf("SRC1 FIR delay %d\n", src->state1.fir_delay_size);
 	printf("SRC1 out delay %d\n", src->state1.out_delay_size);
 
 	printf("SRC2 filter length %d\n", n2);
 	printf("SRC2 subfilter length %d\n", src->stage2->subfilter_length);
-	printf("SRC2 number of subfilters %d\n", src->stage2->num_of_subfilters);
+	printf("SRC2 number of subfilters %d\n",
+		src->stage2->num_of_subfilters);
 	printf("SRC2 idm %d\n", src->stage2->idm);
 	printf("SRC2 odm %d\n", src->stage2->odm);
 	printf("SRC2 input blk %d\n", src->stage2->blk_in);
@@ -487,7 +498,8 @@ void src_print_info(struct polyphase_src *src)
 	if (n2 > 3) {
 		printf("SRC2 coef[1] %d\n", src->stage2->coefs[1]);
 		printf("SRC2 coef[2] %d\n", src->stage2->coefs[2]);
-		printf("SRC2 coef[%d] %d\n", n1 - 1, src->stage2->coefs[n2 - 1]);
+		printf("SRC2 coef[%d] %d\n",
+			n1 - 1, src->stage2->coefs[n2 - 1]);
 	}
 	printf("SRC2 FIR delay %d\n", src->state2.fir_delay_size);
 	printf("SRC2 out delay %d\n", src->state2.out_delay_size);
diff --git a/src/audio/src_core.h b/src/audio/src_core.h
index f7a9c67..0444215 100644
--- a/src/audio/src_core.h
+++ b/src/audio/src_core.h
@@ -32,7 +32,7 @@
 #ifndef SRC_CORE_H
 #define SRC_CORE_H
 
-#define MAX(a,b) ((a) > (b)) ? (a) : (b)
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
 
 /* Include SRC min/max constants etc. */
 #include <reef/audio/coefficients/src/src_int24_define.h>
@@ -125,17 +125,19 @@ static inline int src_polyphase_get_blk_out(struct polyphase_src *src)
 
 void src_polyphase_reset(struct polyphase_src *src);
 
-int src_polyphase_init(struct polyphase_src *src, int fs1, int fs2, int32_t *delay_lines_start);
+int src_polyphase_init(struct polyphase_src *src, int fs1, int fs2,
+	int32_t *delay_lines_start);
 
-int src_polyphase(struct polyphase_src *src, int32_t x[], int32_t y[], int n_in);
+int src_polyphase(struct polyphase_src *src, int32_t x[], int32_t y[],
+	int n_in);
 
 void src_polyphase_stage_cir(struct src_stage_prm *s);
 
 int src_buffer_lengths(struct src_alloc *a, int fs_in, int fs_out, int nch);
 
-int32_t src_input_rates();
+int32_t src_input_rates(void);
 
-int32_t src_output_rates();
+int32_t src_output_rates(void);
 
 #ifdef MODULE_TEST
 void src_print_info(struct polyphase_src *src);
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h
index 5af07f2..9d5fa80 100644
--- a/src/include/uapi/ipc.h
+++ b/src/include/uapi/ipc.h
@@ -490,6 +490,7 @@ struct sof_ipc_comp_src {
 	struct sof_ipc_pcm_comp pcm;
 	uint32_t in_mask;	/* SOF_RATE_ supported input rates */
 	uint32_t out_mask;	/* SOF_RATE_ supported output rates */
+	int32_t out_rate;
 } __attribute__((packed));
 
 /* generic MUX component */
-- 
2.11.0



More information about the Sound-open-firmware mailing list