1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2017 Intel Corporation. All rights reserved.
4 //
5 // Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
6 //         Liam Girdwood <liam.r.girdwood@linux.intel.com>
7 //         Keyon Jie <yang.jie@linux.intel.com>
8 
9 #include <sof/common.h>
10 #include <sof/audio/buffer.h>
11 #include <sof/audio/component.h>
12 #include <sof/audio/pipeline.h>
13 #include <sof/audio/ipc-config.h>
14 #include <sof/audio/src/src.h>
15 #include <sof/audio/src/src_config.h>
16 #include <sof/debug/panic.h>
17 #include <sof/ipc/msg.h>
18 #include <sof/lib/alloc.h>
19 #include <sof/lib/memory.h>
20 #include <sof/lib/uuid.h>
21 #include <sof/list.h>
22 #include <sof/math/numbers.h>
23 #include <sof/platform.h>
24 #include <sof/string.h>
25 #include <sof/ut.h>
26 #include <sof/trace/trace.h>
27 #include <ipc/control.h>
28 #include <ipc/stream.h>
29 #include <ipc/topology.h>
30 #include <user/trace.h>
31 #include <errno.h>
32 #include <stddef.h>
33 #include <stdint.h>
34 
35 #if SRC_SHORT || CONFIG_COMP_SRC_TINY
36 #include <sof/audio/coefficients/src/src_tiny_int16_define.h>
37 #include <sof/audio/coefficients/src/src_tiny_int16_table.h>
38 #else
39 #if CONFIG_COMP_SRC_SMALL
40 #include <sof/audio/coefficients/src/src_small_int32_define.h>
41 #include <sof/audio/coefficients/src/src_small_int32_table.h>
42 #endif
43 #if CONFIG_COMP_SRC_STD
44 #include <sof/audio/coefficients/src/src_std_int32_define.h>
45 #include <sof/audio/coefficients/src/src_std_int32_table.h>
46 #endif
47 #endif
48 
49 /* The FIR maximum lengths are per channel so need to multiply them */
50 #define MAX_FIR_DELAY_SIZE_XNCH (PLATFORM_MAX_CHANNELS * MAX_FIR_DELAY_SIZE)
51 #define MAX_OUT_DELAY_SIZE_XNCH (PLATFORM_MAX_CHANNELS * MAX_OUT_DELAY_SIZE)
52 
53 static const struct comp_driver comp_src;
54 
55 /* c1c5326d-8390-46b4-aa47-95c3beca6550 */
56 DECLARE_SOF_RT_UUID("src", src_uuid, 0xc1c5326d, 0x8390, 0x46b4,
57 		 0xaa, 0x47, 0x95, 0xc3, 0xbe, 0xca, 0x65, 0x50);
58 
59 DECLARE_TR_CTX(src_tr, SOF_UUID(src_uuid), LOG_LEVEL_INFO);
60 
61 /* src component private data */
62 struct comp_data {
63 	struct polyphase_src src;
64 	struct src_param param;
65 	struct ipc_config_src ipc_config;
66 	int32_t *delay_lines;
67 	uint32_t sink_rate;
68 	uint32_t source_rate;
69 	int32_t *sbuf_w_ptr;
70 	int32_t *sbuf_r_ptr;
71 	int sbuf_avail;
72 	int data_shift;
73 	int source_frames;
74 	int sink_frames;
75 	int sample_container_bytes;
76 	void (*src_func)(struct comp_dev *dev,
77 			 const struct audio_stream *source,
78 			 struct audio_stream *sink,
79 			 int *consumed,
80 			 int *produced);
81 	void (*polyphase_func)(struct src_stage_prm *s);
82 };
83 
84 /* Calculates the needed FIR delay line length */
src_fir_delay_length(struct src_stage * s)85 static int src_fir_delay_length(struct src_stage *s)
86 {
87 	return s->subfilter_length + (s->num_of_subfilters - 1) * s->idm
88 		+ s->blk_in;
89 }
90 
91 /* Calculates the FIR output delay line length */
src_out_delay_length(struct src_stage * s)92 static int src_out_delay_length(struct src_stage *s)
93 {
94 	return 1 + (s->num_of_subfilters - 1) * s->odm;
95 }
96 
97 /* Returns index of a matching sample rate */
src_find_fs(int fs_list[],int list_length,int fs)98 static int src_find_fs(int fs_list[], int list_length, int fs)
99 {
100 	int i;
101 
102 	for (i = 0; i < list_length; i++) {
103 		if (fs_list[i] == fs)
104 			return i;
105 	}
106 	return -EINVAL;
107 }
108 
109 /* Calculates buffers to allocate for a SRC mode */
src_buffer_lengths(struct src_param * a,int fs_in,int fs_out,int nch,int source_frames)110 int src_buffer_lengths(struct src_param *a, int fs_in, int fs_out, int nch,
111 		       int source_frames)
112 {
113 	struct src_stage *stage1;
114 	struct src_stage *stage2;
115 	int r1;
116 
117 	if (nch > PLATFORM_MAX_CHANNELS) {
118 		/* TODO: should be device, not class */
119 		comp_cl_err(&comp_src, "src_buffer_lengths(): nch = %u > PLATFORM_MAX_CHANNELS",
120 			    nch);
121 		return -EINVAL;
122 	}
123 
124 	a->nch = nch;
125 	a->idx_in = src_find_fs(src_in_fs, NUM_IN_FS, fs_in);
126 	a->idx_out = src_find_fs(src_out_fs, NUM_OUT_FS, fs_out);
127 
128 	/* Check that both in and out rates are supported */
129 	if (a->idx_in < 0 || a->idx_out < 0) {
130 		comp_cl_err(&comp_src, "src_buffer_lengths(): rates not supported, fs_in: %u, fs_out: %u",
131 			    fs_in, fs_out);
132 		return -EINVAL;
133 	}
134 
135 	stage1 = src_table1[a->idx_out][a->idx_in];
136 	stage2 = src_table2[a->idx_out][a->idx_in];
137 
138 	/* Check from stage1 parameter for a deleted in/out rate combination.*/
139 	if (stage1->filter_length < 1) {
140 		comp_cl_err(&comp_src, "src_buffer_lengths(): Non-supported combination sfs_in = %d, fs_out = %d",
141 			    fs_in, fs_out);
142 		return -EINVAL;
143 	}
144 
145 	a->fir_s1 = nch * src_fir_delay_length(stage1);
146 	a->out_s1 = nch * src_out_delay_length(stage1);
147 
148 	/* Computing of number of blocks to process is done in
149 	 * copy() per each frame.
150 	 */
151 	a->stage1_times = 0;
152 	a->stage2_times = 0;
153 	a->blk_in = 0;
154 	a->blk_out = 0;
155 
156 	if (stage2->filter_length == 1) {
157 		a->fir_s2 = 0;
158 		a->out_s2 = 0;
159 		a->sbuf_length = 0;
160 	} else {
161 		a->fir_s2 = nch * src_fir_delay_length(stage2);
162 		a->out_s2 = nch * src_out_delay_length(stage2);
163 
164 		/* Stage 1 is repeated max. amount that just exceeds one
165 		 * period.
166 		 */
167 		r1 = source_frames / stage1->blk_in + 1;
168 
169 		/* Set sbuf length to allow storing two stage 1 output
170 		 * periods. This is an empirically found value for no
171 		 * xruns to happen with SRC in/out buffers. Due to
172 		 * variable number of blocks to process per each stage
173 		 * there is no equation known for minimum size.
174 		 */
175 		a->sbuf_length = 2 * nch * stage1->blk_out * r1;
176 	}
177 
178 	a->src_multich = a->fir_s1 + a->fir_s2 + a->out_s1 + a->out_s2;
179 	a->total = a->sbuf_length + a->src_multich;
180 
181 	return 0;
182 }
183 
src_state_reset(struct src_state * state)184 static void src_state_reset(struct src_state *state)
185 {
186 	state->fir_delay_size = 0;
187 	state->out_delay_size = 0;
188 }
189 
init_stages(struct src_stage * stage1,struct src_stage * stage2,struct polyphase_src * src,struct src_param * p,int n,int32_t * delay_lines_start)190 static int init_stages(struct src_stage *stage1, struct src_stage *stage2,
191 		       struct polyphase_src *src, struct src_param *p,
192 		       int n, int32_t *delay_lines_start)
193 {
194 	/* Clear FIR state */
195 	src_state_reset(&src->state1);
196 	src_state_reset(&src->state2);
197 
198 	src->number_of_stages = n;
199 	src->stage1 = stage1;
200 	src->stage2 = stage2;
201 	if (n == 1 && stage1->blk_out == 0)
202 		return -EINVAL;
203 
204 	/* Optimized SRC requires subfilter length multiple of 4 */
205 	if (stage1->filter_length > 1 && (stage1->subfilter_length & 0x3) > 0)
206 		return -EINVAL;
207 
208 	if (stage2->filter_length > 1 && (stage2->subfilter_length & 0x3) > 0)
209 		return -EINVAL;
210 
211 	/* Delay line sizes */
212 	src->state1.fir_delay_size = p->fir_s1;
213 	src->state1.out_delay_size = p->out_s1;
214 	src->state1.fir_delay = delay_lines_start;
215 	src->state1.out_delay =
216 		src->state1.fir_delay + src->state1.fir_delay_size;
217 	/* Initialize to last ensures that circular wrap cannot happen
218 	 * mid-frame. The size is multiple of channels count.
219 	 */
220 	src->state1.fir_wp = &src->state1.fir_delay[p->fir_s1 - 1];
221 	src->state1.out_rp = src->state1.out_delay;
222 	if (n > 1) {
223 		src->state2.fir_delay_size = p->fir_s2;
224 		src->state2.out_delay_size = p->out_s2;
225 		src->state2.fir_delay =
226 			src->state1.out_delay + src->state1.out_delay_size;
227 		src->state2.out_delay =
228 			src->state2.fir_delay + src->state2.fir_delay_size;
229 		/* Initialize to last ensures that circular wrap cannot happen
230 		 * mid-frame. The size is multiple of channels count.
231 		 */
232 		src->state2.fir_wp = &src->state2.fir_delay[p->fir_s2 - 1];
233 		src->state2.out_rp = src->state2.out_delay;
234 	} else {
235 		src->state2.fir_delay_size = 0;
236 		src->state2.out_delay_size = 0;
237 		src->state2.fir_delay = NULL;
238 		src->state2.out_delay = NULL;
239 	}
240 
241 	/* Check the sizes are less than MAX */
242 	if (src->state1.fir_delay_size > MAX_FIR_DELAY_SIZE_XNCH ||
243 	    src->state1.out_delay_size > MAX_OUT_DELAY_SIZE_XNCH ||
244 	    src->state2.fir_delay_size > MAX_FIR_DELAY_SIZE_XNCH ||
245 	    src->state2.out_delay_size > MAX_OUT_DELAY_SIZE_XNCH) {
246 		src->state1.fir_delay = NULL;
247 		src->state1.out_delay = NULL;
248 		src->state2.fir_delay = NULL;
249 		src->state2.out_delay = NULL;
250 		return -EINVAL;
251 	}
252 
253 	return 0;
254 }
255 
src_polyphase_reset(struct polyphase_src * src)256 void src_polyphase_reset(struct polyphase_src *src)
257 {
258 	src->number_of_stages = 0;
259 	src->stage1 = NULL;
260 	src->stage2 = NULL;
261 	src_state_reset(&src->state1);
262 	src_state_reset(&src->state2);
263 }
264 
src_polyphase_init(struct polyphase_src * src,struct src_param * p,int32_t * delay_lines_start)265 int src_polyphase_init(struct polyphase_src *src, struct src_param *p,
266 		       int32_t *delay_lines_start)
267 {
268 	struct src_stage *stage1;
269 	struct src_stage *stage2;
270 	int n_stages;
271 	int ret;
272 
273 	if (p->idx_in < 0 || p->idx_out < 0)
274 		return -EINVAL;
275 
276 	/* Get setup for 2 stage conversion */
277 	stage1 = src_table1[p->idx_out][p->idx_in];
278 	stage2 = src_table2[p->idx_out][p->idx_in];
279 	ret = init_stages(stage1, stage2, src, p, 2, delay_lines_start);
280 	if (ret < 0)
281 		return -EINVAL;
282 
283 	/* Get number of stages used for optimize opportunity. 2nd
284 	 * stage length is one if conversion needs only one stage.
285 	 * If input and output rate is the same return 0 to
286 	 * use a simple copy function instead of 1 stage FIR with one
287 	 * tap.
288 	 */
289 	n_stages = (src->stage2->filter_length == 1) ? 1 : 2;
290 	if (p->idx_in == p->idx_out)
291 		n_stages = 0;
292 
293 	/* If filter length for first stage is zero this is a deleted
294 	 * mode from in/out matrix. Computing of such SRC mode needs
295 	 * to be prevented.
296 	 */
297 	if (src->stage1->filter_length == 0)
298 		return -EINVAL;
299 
300 	return n_stages;
301 }
302 
303 /* Fallback function */
src_fallback(struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,int * n_read,int * n_written)304 static void src_fallback(struct comp_dev *dev,
305 			 const struct audio_stream *source,
306 			 struct audio_stream *sink, int *n_read, int *n_written)
307 {
308 	*n_read = 0;
309 	*n_written = 0;
310 }
311 
312 /* Normal 2 stage SRC */
src_2s(struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,int * n_read,int * n_written)313 static void src_2s(struct comp_dev *dev, const struct audio_stream *source,
314 		   struct audio_stream *sink, int *n_read, int *n_written)
315 {
316 	struct src_stage_prm s1;
317 	struct src_stage_prm s2;
318 	int s1_blk_in;
319 	int s1_blk_out;
320 	int s2_blk_in;
321 	int s2_blk_out;
322 	struct comp_data *cd = comp_get_drvdata(dev);
323 	void *sbuf_addr = cd->delay_lines;
324 	void *sbuf_end_addr = &cd->delay_lines[cd->param.sbuf_length];
325 	size_t sbuf_size = cd->param.sbuf_length * sizeof(int32_t);
326 	int nch = source->channels;
327 	int sbuf_free = cd->param.sbuf_length - cd->sbuf_avail;
328 	int avail_b = audio_stream_get_avail_bytes(source);
329 	int free_b = audio_stream_get_free_bytes(sink);
330 	int sz = cd->sample_container_bytes;
331 
332 	*n_read = 0;
333 	*n_written = 0;
334 	s1.x_end_addr = source->end_addr;
335 	s1.x_size = source->size;
336 	s1.y_addr = sbuf_addr;
337 	s1.y_end_addr = sbuf_end_addr;
338 	s1.y_size = sbuf_size;
339 	s1.state = &cd->src.state1;
340 	s1.stage = cd->src.stage1;
341 	s1.x_rptr = source->r_ptr;
342 	s1.y_wptr = cd->sbuf_w_ptr;
343 	s1.nch = nch;
344 	s1.shift = cd->data_shift;
345 
346 	s2.x_end_addr = sbuf_end_addr;
347 	s2.x_size = sbuf_size;
348 	s2.y_addr = sink->addr;
349 	s2.y_end_addr = sink->end_addr;
350 	s2.y_size = sink->size;
351 	s2.state = &cd->src.state2;
352 	s2.stage = cd->src.stage2;
353 	s2.x_rptr = cd->sbuf_r_ptr;
354 	s2.y_wptr = sink->w_ptr;
355 	s2.nch = nch;
356 	s2.shift = cd->data_shift;
357 
358 	/* Test if 1st stage can be run with default block length to reach
359 	 * the period length or just under it.
360 	 */
361 	s1.times = cd->param.stage1_times;
362 	s1_blk_in = s1.times * cd->src.stage1->blk_in * nch;
363 	s1_blk_out = s1.times * cd->src.stage1->blk_out * nch;
364 
365 	/* The sbuf may limit how many times s1 can be looped. It's harder
366 	 * to prepare for in advance so the repeats number is adjusted down
367 	 * here if need.
368 	 */
369 	if (s1_blk_out > sbuf_free) {
370 		s1.times = sbuf_free / (cd->src.stage1->blk_out * nch);
371 		s1_blk_in = s1.times * cd->src.stage1->blk_in * nch;
372 		s1_blk_out = s1.times * cd->src.stage1->blk_out * nch;
373 		comp_dbg(dev, "s1.times = %d", s1.times);
374 	}
375 
376 	if (avail_b >= s1_blk_in * sz && sbuf_free >= s1_blk_out) {
377 		cd->polyphase_func(&s1);
378 
379 		cd->sbuf_w_ptr = s1.y_wptr;
380 		cd->sbuf_avail += s1_blk_out;
381 		*n_read += s1.times * cd->src.stage1->blk_in;
382 	}
383 
384 	s2.times = cd->param.stage2_times;
385 	s2_blk_in = s2.times * cd->src.stage2->blk_in * nch;
386 	s2_blk_out = s2.times * cd->src.stage2->blk_out * nch;
387 	if (s2_blk_in > cd->sbuf_avail) {
388 		s2.times = cd->sbuf_avail / (cd->src.stage2->blk_in * nch);
389 		s2_blk_in = s2.times * cd->src.stage2->blk_in * nch;
390 		s2_blk_out = s2.times * cd->src.stage2->blk_out * nch;
391 		comp_dbg(dev, "s2.times = %d", s2.times);
392 	}
393 
394 	/* Test if second stage can be run with default block length. */
395 	if (cd->sbuf_avail >= s2_blk_in && free_b >= s2_blk_out * sz) {
396 		cd->polyphase_func(&s2);
397 
398 		cd->sbuf_r_ptr = s2.x_rptr;
399 		cd->sbuf_avail -= s2_blk_in;
400 		*n_written += s2.times * cd->src.stage2->blk_out;
401 	}
402 }
403 
404 /* 1 stage SRC for simple conversions */
src_1s(struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,int * n_read,int * n_written)405 static void src_1s(struct comp_dev *dev, const struct audio_stream *source,
406 		   struct audio_stream *sink, int *n_read, int *n_written)
407 {
408 	struct src_stage_prm s1;
409 	struct comp_data *cd = comp_get_drvdata(dev);
410 
411 	s1.times = cd->param.stage1_times;
412 	s1.x_rptr = source->r_ptr;
413 	s1.x_end_addr = source->end_addr;
414 	s1.x_size = source->size;
415 	s1.y_wptr = sink->w_ptr;
416 	s1.y_end_addr = sink->end_addr;
417 	s1.y_size = sink->size;
418 	s1.state = &cd->src.state1;
419 	s1.stage = cd->src.stage1;
420 	s1.nch = source->channels;
421 	s1.shift = cd->data_shift;
422 
423 	cd->polyphase_func(&s1);
424 
425 	*n_read = cd->param.blk_in;
426 	*n_written = cd->param.blk_out;
427 }
428 
429 /* A fast copy function for same in and out rate */
src_copy_sxx(struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,int * n_read,int * n_written)430 static void src_copy_sxx(struct comp_dev *dev,
431 			 const struct audio_stream *source,
432 			 struct audio_stream *sink,
433 			 int *n_read, int *n_written)
434 {
435 	struct comp_data *cd = comp_get_drvdata(dev);
436 	int frames = cd->param.blk_in;
437 
438 	switch (sink->frame_fmt) {
439 	case SOF_IPC_FRAME_S16_LE:
440 	case SOF_IPC_FRAME_S24_4LE:
441 	case SOF_IPC_FRAME_S32_LE:
442 		audio_stream_copy(source, 0, sink, 0,
443 				  frames * source->channels);
444 		*n_read = frames;
445 		*n_written = frames;
446 		break;
447 	default:
448 		*n_read = 0;
449 		*n_written = 0;
450 	}
451 }
452 
src_new(const struct comp_driver * drv,struct comp_ipc_config * config,void * spec)453 static struct comp_dev *src_new(const struct comp_driver *drv,
454 				struct comp_ipc_config *config,
455 				void *spec)
456 {
457 	struct comp_dev *dev;
458 	struct comp_data *cd;
459 	struct ipc_config_src *ipc_src = spec;
460 
461 	comp_cl_info(&comp_src, "src_new()");
462 
463 	/* validate init data - either SRC sink or source rate must be set */
464 	if (ipc_src->source_rate == 0 && ipc_src->sink_rate == 0) {
465 		comp_cl_err(&comp_src, "src_new(): SRC sink and source rate are not set");
466 		return NULL;
467 	}
468 
469 	dev = comp_alloc(drv, sizeof(*dev));
470 	if (!dev)
471 		return NULL;
472 	dev->ipc_config = *config;
473 
474 	cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd));
475 	if (!cd) {
476 		rfree(dev);
477 		return NULL;
478 	}
479 
480 	comp_set_drvdata(dev, cd);
481 	cd->ipc_config = *ipc_src;
482 
483 	cd->delay_lines = NULL;
484 	cd->src_func = src_fallback;
485 	cd->polyphase_func = NULL;
486 	src_polyphase_reset(&cd->src);
487 
488 	dev->state = COMP_STATE_READY;
489 	return dev;
490 }
491 
src_free(struct comp_dev * dev)492 static void src_free(struct comp_dev *dev)
493 {
494 	struct comp_data *cd = comp_get_drvdata(dev);
495 
496 	comp_info(dev, "src_free()");
497 
498 	/* Free dynamically reserved buffers for SRC algorithm */
499 	if (cd->delay_lines)
500 		rfree(cd->delay_lines);
501 
502 	rfree(cd);
503 	rfree(dev);
504 }
505 
src_verify_params(struct comp_dev * dev,struct sof_ipc_stream_params * params)506 static int src_verify_params(struct comp_dev *dev,
507 			     struct sof_ipc_stream_params *params)
508 {
509 	struct comp_data *cd = comp_get_drvdata(dev);
510 	int ret;
511 
512 	comp_dbg(dev, "src_verify_params()");
513 
514 	/* check whether params->rate (received from driver) are equal
515 	 * to src->source_rate (PLAYBACK) or src->sink_rate (CAPTURE) set during
516 	 * creating src component in src_new().
517 	 * src->source/sink_rate = 0 means that source/sink rate can vary.
518 	 */
519 	if (dev->direction == SOF_IPC_STREAM_PLAYBACK) {
520 		if (cd->ipc_config.source_rate && (params->rate != cd->ipc_config.source_rate)) {
521 			comp_err(dev, "src_verify_params(): runtime stream pcm rate %u does not match rate %u fetched from ipc.",
522 				 params->rate, cd->ipc_config.source_rate);
523 			return -EINVAL;
524 		}
525 	} else {
526 		if (cd->ipc_config.sink_rate && (params->rate != cd->ipc_config.sink_rate)) {
527 			comp_err(dev, "src_verify_params(): runtime stream pcm rate %u does not match rate %u fetched from ipc.",
528 				 params->rate, cd->ipc_config.sink_rate);
529 			return -EINVAL;
530 		}
531 	}
532 
533 	/* update downstream (playback) or upstream (capture) buffer parameters
534 	 */
535 	ret = comp_verify_params(dev, BUFF_PARAMS_RATE, params);
536 	if (ret < 0) {
537 		comp_err(dev, "src_verify_params(): comp_verify_params() failed.");
538 		return ret;
539 	}
540 
541 	return 0;
542 }
543 
544 /* set component audio stream parameters */
src_params(struct comp_dev * dev,struct sof_ipc_stream_params * params)545 static int src_params(struct comp_dev *dev,
546 		      struct sof_ipc_stream_params *params)
547 {
548 	struct comp_data *cd = comp_get_drvdata(dev);
549 	struct comp_buffer *sinkb;
550 	struct comp_buffer *sourceb;
551 	size_t delay_lines_size;
552 	int32_t *buffer_start;
553 	int n = 0;
554 	int err;
555 
556 	comp_info(dev, "src_params()");
557 
558 	err = src_verify_params(dev, params);
559 	if (err < 0) {
560 		comp_err(dev, "src_params(): pcm params verification failed.");
561 		return -EINVAL;
562 	}
563 
564 	cd->sample_container_bytes = params->sample_container_bytes;
565 
566 	/* src components will only ever have 1 source and 1 sink buffer */
567 	sourceb = list_first_item(&dev->bsource_list, struct comp_buffer,
568 				  sink_list);
569 	sinkb = list_first_item(&dev->bsink_list, struct comp_buffer,
570 				source_list);
571 
572 	comp_info(dev, "src_params(): src->source_rate: %d", cd->ipc_config.source_rate);
573 	comp_info(dev, "src_params(): src->sink_rate: %d", cd->ipc_config.sink_rate);
574 
575 	/* Set source/sink_rate/frames */
576 	cd->source_rate = sourceb->stream.rate;
577 	cd->sink_rate = sinkb->stream.rate;
578 	if (!cd->sink_rate) {
579 		comp_err(dev, "src_params(), zero sink rate");
580 		return -EINVAL;
581 	}
582 
583 	cd->source_frames = dev->frames * cd->source_rate / cd->sink_rate;
584 	cd->sink_frames = dev->frames;
585 
586 	/* Allocate needed memory for delay lines */
587 	comp_info(dev, "src_params(), source_rate = %u, sink_rate = %u",
588 		  cd->source_rate, cd->sink_rate);
589 	comp_info(dev, "src_params(), sourceb->channels = %u, sinkb->channels = %u, dev->frames = %u",
590 		  sourceb->stream.channels,
591 		  sinkb->stream.channels, dev->frames);
592 	err = src_buffer_lengths(&cd->param, cd->source_rate,
593 				 cd->sink_rate,
594 				 sourceb->stream.channels, cd->source_frames);
595 	if (err < 0) {
596 		comp_err(dev, "src_params(): src_buffer_lengths() failed");
597 		return err;
598 	}
599 
600 	comp_info(dev, "src_params(), blk_in = %u, blk_out = %u",
601 		  cd->param.blk_in, cd->param.blk_out);
602 
603 	delay_lines_size = sizeof(int32_t) * cd->param.total;
604 	if (delay_lines_size == 0) {
605 		comp_err(dev, "src_params(): delay_lines_size = 0");
606 		return -EINVAL;
607 	}
608 
609 	/* free any existing delay lines. TODO reuse if same size */
610 	if (cd->delay_lines)
611 		rfree(cd->delay_lines);
612 
613 	cd->delay_lines = rballoc(0, SOF_MEM_CAPS_RAM, delay_lines_size);
614 	if (!cd->delay_lines) {
615 		comp_err(dev, "src_params(): failed to alloc cd->delay_lines, delay_lines_size = %u",
616 			 delay_lines_size);
617 		return -EINVAL;
618 	}
619 
620 	/* Clear all delay lines here */
621 	memset(cd->delay_lines, 0, delay_lines_size);
622 	buffer_start = cd->delay_lines + cd->param.sbuf_length;
623 
624 	/* Initialize SRC for actual sample rate */
625 	n = src_polyphase_init(&cd->src, &cd->param, buffer_start);
626 
627 	/* Reset stage buffer */
628 	cd->sbuf_r_ptr = cd->delay_lines;
629 	cd->sbuf_w_ptr = cd->delay_lines;
630 	cd->sbuf_avail = 0;
631 
632 	switch (n) {
633 	case 0:
634 		/* 1:1 fast copy */
635 		cd->src_func = src_copy_sxx;
636 		break;
637 	case 1:
638 		cd->src_func = src_1s; /* Simpler 1 stage SRC */
639 		break;
640 	case 2:
641 		cd->src_func = src_2s; /* Default 2 stage SRC */
642 		break;
643 	default:
644 		/* This is possibly due to missing coefficients for
645 		 * requested rates combination.
646 		 */
647 		comp_info(dev, "src_params(), missing coefficients for requested rates combination");
648 		cd->src_func = src_fallback;
649 		return -EINVAL;
650 	}
651 
652 	return 0;
653 }
654 
src_ctrl_cmd(struct comp_dev * dev,struct sof_ipc_ctrl_data * cdata)655 static int src_ctrl_cmd(struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata)
656 {
657 	comp_err(dev, "src_ctrl_cmd()");
658 	return -EINVAL;
659 }
660 
661 /* used to pass standard and bespoke commands (with data) to component */
src_cmd(struct comp_dev * dev,int cmd,void * data,int max_data_size)662 static int src_cmd(struct comp_dev *dev, int cmd, void *data,
663 		   int max_data_size)
664 {
665 	struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4);
666 	int ret = 0;
667 
668 	comp_info(dev, "src_cmd()");
669 
670 	if (cmd == COMP_CMD_SET_VALUE)
671 		ret = src_ctrl_cmd(dev, cdata);
672 
673 	return ret;
674 }
675 
src_trigger(struct comp_dev * dev,int cmd)676 static int src_trigger(struct comp_dev *dev, int cmd)
677 {
678 	struct comp_data *cd = comp_get_drvdata(dev);
679 
680 	comp_info(dev, "src_trigger()");
681 
682 	if (cmd == COMP_TRIGGER_START || cmd == COMP_TRIGGER_RELEASE)
683 		assert(cd->polyphase_func);
684 
685 	return comp_set_state(dev, cmd);
686 }
687 
src_get_copy_limits(struct comp_data * cd,const struct comp_buffer * source,const struct comp_buffer * sink)688 static int src_get_copy_limits(struct comp_data *cd,
689 			       const struct comp_buffer *source,
690 			       const struct comp_buffer *sink)
691 {
692 	struct src_param *sp;
693 	struct src_stage *s1;
694 	struct src_stage *s2;
695 	int frames_src;
696 	int frames_snk;
697 
698 	/* Get SRC parameters */
699 	sp = &cd->param;
700 	s1 = cd->src.stage1;
701 	s2 = cd->src.stage2;
702 
703 	/* Calculate how many blocks can be processed with
704 	 * available source and free sink frames amount.
705 	 */
706 	if (s2->filter_length > 1) {
707 		/* Two polyphase filters case */
708 		frames_snk = audio_stream_get_free_frames(&sink->stream);
709 		frames_snk = MIN(frames_snk, cd->sink_frames + s2->blk_out);
710 		sp->stage2_times = frames_snk / s2->blk_out;
711 		frames_src = audio_stream_get_avail_frames(&source->stream);
712 		frames_src = MIN(frames_src, cd->source_frames + s1->blk_in);
713 		sp->stage1_times = frames_src / s1->blk_in;
714 		sp->blk_in = sp->stage1_times * s1->blk_in;
715 		sp->blk_out = sp->stage2_times * s2->blk_out;
716 	} else {
717 		/* Single polyphase filter case */
718 		frames_snk = audio_stream_get_free_frames(&sink->stream);
719 		frames_snk = MIN(frames_snk, cd->sink_frames + s1->blk_out);
720 		sp->stage1_times = frames_snk / s1->blk_out;
721 		frames_src = audio_stream_get_avail_frames(&source->stream);
722 		sp->stage1_times = MIN(sp->stage1_times,
723 				       frames_src / s1->blk_in);
724 		sp->blk_in = sp->stage1_times * s1->blk_in;
725 		sp->blk_out = sp->stage1_times * s1->blk_out;
726 	}
727 
728 	if (sp->blk_in == 0 || sp->blk_out == 0)
729 		return -EIO;
730 
731 	return 0;
732 }
733 
src_process(struct comp_dev * dev,struct comp_buffer * source,struct comp_buffer * sink)734 static void src_process(struct comp_dev *dev, struct comp_buffer *source,
735 			struct comp_buffer *sink)
736 {
737 	struct comp_data *cd = comp_get_drvdata(dev);
738 	int consumed = 0;
739 	int produced = 0;
740 
741 	/* consumed bytes are not known at this point */
742 	buffer_invalidate(source, source->stream.size);
743 	cd->src_func(dev, &source->stream, &sink->stream, &consumed, &produced);
744 	buffer_writeback(sink, produced *
745 			 audio_stream_frame_bytes(&sink->stream));
746 
747 	comp_dbg(dev, "src_copy(), consumed = %u,  produced = %u",
748 		 consumed, produced);
749 
750 	comp_update_buffer_consume(source, consumed *
751 				   audio_stream_frame_bytes(&source->stream));
752 	comp_update_buffer_produce(sink, produced *
753 				   audio_stream_frame_bytes(&sink->stream));
754 }
755 
756 /* copy and process stream data from source to sink buffers */
src_copy(struct comp_dev * dev)757 static int src_copy(struct comp_dev *dev)
758 {
759 	struct comp_data *cd = comp_get_drvdata(dev);
760 	struct comp_buffer *source;
761 	struct comp_buffer *sink;
762 	int ret;
763 	uint32_t flags = 0;
764 
765 	comp_dbg(dev, "src_copy()");
766 
767 	/* src component needs 1 source and 1 sink buffer */
768 	source = list_first_item(&dev->bsource_list, struct comp_buffer,
769 				 sink_list);
770 	sink = list_first_item(&dev->bsink_list, struct comp_buffer,
771 			       source_list);
772 
773 	buffer_lock(source, &flags);
774 	buffer_lock(sink, &flags);
775 
776 	/* Get from buffers and SRC conversion specific block constraints
777 	 * how many frames can be processed. If sufficient number of samples
778 	 * is not available the processing is omitted.
779 	 */
780 	ret = src_get_copy_limits(cd, source, sink);
781 
782 	buffer_unlock(sink, flags);
783 	buffer_unlock(source, flags);
784 
785 	if (ret) {
786 		comp_info(dev, "No data to process.");
787 		return PPL_STATUS_PATH_STOP;
788 	}
789 
790 	src_process(dev, source, sink);
791 
792 	/* produced no data */
793 	return 0;
794 }
795 
src_prepare(struct comp_dev * dev)796 static int src_prepare(struct comp_dev *dev)
797 {
798 	struct comp_data *cd = comp_get_drvdata(dev);
799 	struct comp_buffer *sinkb;
800 	struct comp_buffer *sourceb;
801 	enum sof_ipc_frame source_format;
802 	enum sof_ipc_frame sink_format;
803 	uint32_t source_period_bytes;
804 	uint32_t sink_period_bytes;
805 	int ret;
806 
807 	comp_info(dev, "src_prepare()");
808 
809 	ret = comp_set_state(dev, COMP_TRIGGER_PREPARE);
810 	if (ret < 0)
811 		return ret;
812 
813 	if (ret == COMP_STATUS_STATE_ALREADY_SET)
814 		return PPL_STATUS_PATH_STOP;
815 
816 	/* SRC component will only ever have 1 source and 1 sink buffer */
817 	sourceb = list_first_item(&dev->bsource_list,
818 				  struct comp_buffer, sink_list);
819 	sinkb = list_first_item(&dev->bsink_list,
820 				struct comp_buffer, source_list);
821 
822 	/* get source data format and period bytes */
823 	source_format = sourceb->stream.frame_fmt;
824 	source_period_bytes = audio_stream_period_bytes(&sourceb->stream,
825 							dev->frames);
826 
827 	/* get sink data format and period bytes */
828 	sink_format = sinkb->stream.frame_fmt;
829 	sink_period_bytes = audio_stream_period_bytes(&sinkb->stream,
830 						      dev->frames);
831 
832 	if (sinkb->stream.size < dev->ipc_config.periods_sink * sink_period_bytes) {
833 		comp_err(dev, "src_prepare(): sink buffer size %d is insufficient < %d * %d",
834 			 sinkb->stream.size, dev->ipc_config.periods_sink, sink_period_bytes);
835 		ret = -ENOMEM;
836 		goto err;
837 	}
838 
839 	/* validate */
840 	if (!sink_period_bytes) {
841 		comp_err(dev, "src_prepare(): sink_period_bytes = 0");
842 		ret = -EINVAL;
843 		goto err;
844 	}
845 	if (!source_period_bytes) {
846 		comp_err(dev, "src_prepare(): source_period_bytes = 0");
847 		ret = -EINVAL;
848 		goto err;
849 	}
850 
851 	/* SRC supports S16_LE, S24_4LE and S32_LE formats */
852 	if (source_format != sink_format) {
853 		comp_err(dev, "src_prepare(): Source fmt %d and sink fmt %d are different.",
854 			 source_format, sink_format);
855 		ret = -EINVAL;
856 		goto err;
857 	}
858 
859 	switch (source_format) {
860 #if CONFIG_FORMAT_S16LE
861 	case SOF_IPC_FRAME_S16_LE:
862 		cd->data_shift = 0;
863 		cd->polyphase_func = src_polyphase_stage_cir_s16;
864 		break;
865 #endif /* CONFIG_FORMAT_S16LE */
866 #if CONFIG_FORMAT_S24LE
867 	case SOF_IPC_FRAME_S24_4LE:
868 		cd->data_shift = 8;
869 		cd->polyphase_func = src_polyphase_stage_cir;
870 		break;
871 #endif /* CONFIG_FORMAT_S24LE */
872 #if CONFIG_FORMAT_S32LE
873 	case SOF_IPC_FRAME_S32_LE:
874 		cd->data_shift = 0;
875 		cd->polyphase_func = src_polyphase_stage_cir;
876 		break;
877 #endif /* CONFIG_FORMAT_S32LE */
878 	default:
879 		comp_err(dev, "src_prepare(): invalid format %d", source_format);
880 		ret = -EINVAL;
881 		goto err;
882 	}
883 
884 	return 0;
885 
886 err:
887 	comp_set_state(dev, COMP_TRIGGER_RESET);
888 	return ret;
889 }
890 
src_reset(struct comp_dev * dev)891 static int src_reset(struct comp_dev *dev)
892 {
893 	struct comp_data *cd = comp_get_drvdata(dev);
894 
895 	comp_info(dev, "src_reset()");
896 
897 	cd->src_func = src_fallback;
898 	src_polyphase_reset(&cd->src);
899 
900 	comp_set_state(dev, COMP_TRIGGER_RESET);
901 	return 0;
902 }
903 
904 static const struct comp_driver comp_src = {
905 	.type = SOF_COMP_SRC,
906 	.uid = SOF_RT_UUID(src_uuid),
907 	.tctx = &src_tr,
908 	.ops = {
909 		.create = src_new,
910 		.free = src_free,
911 		.params = src_params,
912 		.cmd = src_cmd,
913 		.trigger = src_trigger,
914 		.copy = src_copy,
915 		.prepare = src_prepare,
916 		.reset = src_reset,
917 	},
918 };
919 
920 static SHARED_DATA struct comp_driver_info comp_src_info = {
921 	.drv = &comp_src,
922 };
923 
sys_comp_src_init(void)924 UT_STATIC void sys_comp_src_init(void)
925 {
926 	comp_register(platform_shared_get(&comp_src_info,
927 					  sizeof(comp_src_info)));
928 }
929 
930 DECLARE_MODULE(sys_comp_src_init);
931