1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2012-2022 Intel Corporation. All rights reserved.
4 
5 /* @brief    Implementation of the sample rate converter. */
6 
7 #include <sof/common.h>
8 #include <rtos/panic.h>
9 #include <sof/math/numbers.h>
10 #include <sof/platform.h>
11 #include <rtos/string.h>
12 #include <sof/trace/trace.h>
13 #include <sof/audio/format.h>
14 #include <user/trace.h>
15 #include <sof/audio/asrc/asrc_config.h>
16 #include <sof/audio/asrc/asrc_farrow.h>
17 
18 LOG_MODULE_DECLARE(asrc, CONFIG_SOF_LOG_LEVEL);
19 
20 #define CONVERT_COEFF(x) ((int32_t)(x))
21 
22 /* Rate skew in Q2.30 format can be 0.5 - 2.0 x rate */
23 #define SKEW_MIN Q_CONVERT_FLOAT(0.5, 30)
24 #define SKEW_MAX INT32_MAX /* Near max. 2.0 value */
25 
26 /* Time value is stored as Q5.27. The latter limit value of 0.0001 is an
27  * empirically defined limit to issue warning of possibly non-successful
28  * processing.
29  */
30 #define TIME_VALUE_ONE Q_CONVERT_FLOAT(1, 27)
31 #define TIME_VALUE_LIMIT Q_CONVERT_FLOAT(0.0001, 27)
32 
33 /* Generic scale value for Q27 fractional arithmetic */
34 #define ONE_Q27 Q_CONVERT_FLOAT(1, 27)
35 
36 /*
37  * GLOBALS
38  */
39 
40 /*
41  * asrc_conversion_ratios: Enum which lists all conversion ratios with
42  * varying coefficient sets.  E.g. CR_44100TO48000 covers the
43  * coefficients for most upsample use cases.
44  */
45 enum asrc_conversion_ratios {
46 	/* mandatory, used for many use cases with fs_in <= fs_out */
47 	CR_44100TO48000,
48 	/* mandatory, used for all use cases with fs_in = 48000 Hz <= fs_out */
49 	CR_48000TO48000,
50 #if (CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_08000)
51 	CR_24000TO08000,
52 #endif
53 #if (CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_16000)
54 	CR_24000TO16000,
55 #endif
56 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_08000)
57 	CR_48000TO08000,
58 #endif
59 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_11025)
60 	CR_48000TO11025,
61 #endif
62 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_12000)
63 	CR_48000TO12000,
64 #endif
65 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_16000)
66 	CR_48000TO16000,
67 #endif
68 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_22050)
69 	CR_48000TO22050,
70 #endif
71 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_24000)
72 	CR_48000TO24000,
73 #endif
74 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_32000)
75 	CR_48000TO32000,
76 #endif
77 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_44100)
78 	CR_48000TO44100,
79 #endif
80 	CR_NUM
81 };
82 
83 /*
84  * Filter_params:
85  */
86 struct asrc_filter_params {
87 	int filter_length;	/*<! Length of each polyphase filter */
88 	int num_filters;	/*<! Number of polyphase filters */
89 };
90 
91 /*
92  * c_filter_params: Stores the filter parameters for every use case.
93  * Filter parameters consist of the filter length and the number of
94  * filters.
95  */
96 static const struct asrc_filter_params c_filter_params[CR_NUM] = {
97 #include <sof/audio/coefficients/asrc/asrc_farrow_param_44100Hz_to_48000Hz.h>
98 #include <sof/audio/coefficients/asrc/asrc_farrow_param_48000Hz_to_48000Hz.h>
99 
100 #if (CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_08000)
101 #include <sof/audio/coefficients/asrc/asrc_farrow_param_24000Hz_to_08000Hz.h>
102 #endif
103 
104 #if (CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_16000)
105 #include <sof/audio/coefficients/asrc/asrc_farrow_param_24000Hz_to_16000Hz.h>
106 #endif
107 
108 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_08000)
109 #include <sof/audio/coefficients/asrc/asrc_farrow_param_48000Hz_to_08000Hz.h>
110 #endif
111 
112 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_11025)
113 #include <sof/audio/coefficients/asrc/asrc_farrow_param_48000Hz_to_11025Hz.h>
114 #endif
115 
116 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_12000)
117 #include <sof/audio/coefficients/asrc/asrc_farrow_param_48000Hz_to_12000Hz.h>
118 #endif
119 
120 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_16000)
121 #include <sof/audio/coefficients/asrc/asrc_farrow_param_48000Hz_to_16000Hz.h>
122 #endif
123 
124 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_22050)
125 #include <sof/audio/coefficients/asrc/asrc_farrow_param_48000Hz_to_22050Hz.h>
126 #endif
127 
128 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_24000)
129 #include <sof/audio/coefficients/asrc/asrc_farrow_param_48000Hz_to_24000Hz.h>
130 #endif
131 
132 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_32000)
133 #include <sof/audio/coefficients/asrc/asrc_farrow_param_48000Hz_to_32000Hz.h>
134 #endif
135 
136 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_44100)
137 #include <sof/audio/coefficients/asrc/asrc_farrow_param_48000Hz_to_44100Hz.h>
138 #endif
139 
140 };
141 
142 /*
143  * Coefficients for each use case are included here The corresponding
144  * coefficients will be attached to the _Src_farrow struct via the
145  * initialise_filter function.
146  */
147 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_44100Hz_to_48000Hz.h>
148 
149 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_48000Hz_to_48000Hz.h>
150 
151 #if (CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_08000)
152 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_24000Hz_to_08000Hz.h>
153 #endif
154 
155 #if (CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_16000)
156 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_24000Hz_to_16000Hz.h>
157 #endif
158 
159 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_08000)
160 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_48000Hz_to_08000Hz.h>
161 #endif
162 
163 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_11025)
164 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_48000Hz_to_11025Hz.h>
165 #endif
166 
167 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_12000)
168 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_48000Hz_to_12000Hz.h>
169 #endif
170 
171 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_16000)
172 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_48000Hz_to_16000Hz.h>
173 #endif
174 
175 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_22050)
176 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_48000Hz_to_22050Hz.h>
177 #endif
178 
179 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_24000)
180 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_48000Hz_to_24000Hz.h>
181 #endif
182 
183 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_32000)
184 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_48000Hz_to_32000Hz.h>
185 #endif
186 
187 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_44100)
188 #include <sof/audio/coefficients/asrc/asrc_farrow_coeff_48000Hz_to_44100Hz.h>
189 #endif
190 
191 /*
192  * FUNCTION DECLARATIONS
193  */
194 
195 /*
196  * Initialise the pointers to the filters, set the number of filters
197  * and their length
198  */
199 static enum asrc_error_code initialise_filter(struct comp_dev *dev,
200 					      struct asrc_farrow *src_obj);
201 
202 /*
203  * FUNCTION DEFINITIONS + GENERAL SETUP
204  */
205 
206 /*
207  * The internal data will be stored as follows:
208  * Address:                      |Item:                                |
209  * ------------------------------|-------------------------------------|
210  * 0x0000                        |asrc_farrow src_obj                  |
211  * ------------------------------|-------------------------------------|
212  * &src_obj + 1                  |int32 impulse_response[filter_length]|
213  * ------------------------------|-------------------------------------|
214  * &impulse_response[0] +        |int_x *buffer_pointer[num_channels]  |
215  * filter_length                 |                                     |
216  * ------------------------------|-------------------------------------|
217  *
218  * Info:
219  *
220  * buffer_pointer[num_channels]:
221  * Pointers to each channels data. Buffers are allocated externally.
222  */
223 
asrc_get_required_size(struct comp_dev * dev,int * required_size,int num_channels,int bit_depth)224 enum asrc_error_code asrc_get_required_size(struct comp_dev *dev,
225 					    int *required_size,
226 					    int num_channels,
227 					    int bit_depth)
228 {
229 	int size;
230 
231 	/* check for parameter errors */
232 	if (!required_size) {
233 		comp_err(dev, "asrc_get_required_size(), invalid required_size");
234 		return ASRC_EC_INVALID_POINTER;
235 	}
236 
237 	if (num_channels < 1) {
238 		comp_err(dev, "asrc_get_required_size(), invalid num_channels = %d",
239 			 num_channels);
240 		return ASRC_EC_INVALID_NUM_CHANNELS;
241 	}
242 
243 	if (bit_depth != 16 && bit_depth != 32) {
244 		comp_err(dev, "asrc_get_required_size_bytes(), invalid bit_depth = %d",
245 			 bit_depth);
246 		return ASRC_EC_INVALID_BIT_DEPTH;
247 	}
248 
249 	/*
250 	 * At the current stage, memory is always allocated for the
251 	 * worst case scenario. Namely for the 48000Hz to 8000Hz use
252 	 * case, which corresponds to a filter length of 128. This
253 	 * allows switching between conversion ratios on the fly,
254 	 * without having to reallocate memory for the asrc_farrow
255 	 * instance and reinitialise the pointers.  If on the fly
256 	 * changes are not necessary, this function can be changed to
257 	 * give the minimum size needed for a certain conversion
258 	 * ratio.
259 	 */
260 
261 	/* accumulate the size */
262 	size = sizeof(struct asrc_farrow);
263 
264 	/* size of the impulse response */
265 	size += ASRC_MAX_FILTER_LENGTH * sizeof(int32_t);
266 
267 	/* size of pointers to the buffers */
268 	size += sizeof(int32_t *) * num_channels;
269 
270 	*required_size = size;
271 	return ASRC_EC_OK;
272 }
273 
asrc_initialise(struct comp_dev * dev,struct asrc_farrow * src_obj,int num_channels,int fs_prim,int fs_sec,enum asrc_io_format input_format,enum asrc_io_format output_format,enum asrc_buffer_mode buffer_mode,int buffer_length,int bit_depth,enum asrc_control_mode control_mode,enum asrc_operation_mode operation_mode)274 enum asrc_error_code asrc_initialise(struct comp_dev *dev,
275 				     struct asrc_farrow *src_obj,
276 				     int num_channels,
277 				     int fs_prim,
278 				     int fs_sec,
279 				     enum asrc_io_format input_format,
280 				     enum asrc_io_format output_format,
281 				     enum asrc_buffer_mode buffer_mode,
282 				     int buffer_length,
283 				     int bit_depth,
284 				     enum asrc_control_mode control_mode,
285 				     enum asrc_operation_mode operation_mode)
286 {
287 	enum asrc_error_code error_code;
288 
289 	/* check for parameter errors */
290 	if (!src_obj) {
291 		comp_err(dev, "asrc_initialise(), null src_obj");
292 		return ASRC_EC_INVALID_POINTER;
293 	}
294 
295 	if (num_channels < 1) {
296 		comp_err(dev, "asrc_initialise(), num_channels = %d",
297 			 num_channels);
298 		return ASRC_EC_INVALID_NUM_CHANNELS;
299 	}
300 
301 	if (fs_prim < 8000 || fs_prim > 192000) {
302 		comp_err(dev, "asrc_initialise(), fs_prim = %d", fs_prim);
303 		return ASRC_EC_INVALID_SAMPLE_RATE;
304 	}
305 
306 	if (fs_sec < 8000 || fs_sec > 192000) {
307 		comp_err(dev, "asrc_initialise(), fs_src = %d", fs_sec);
308 		return ASRC_EC_INVALID_SAMPLE_RATE;
309 	}
310 
311 	if (buffer_length < 2) {
312 		comp_err(dev, "asrc_initialise(), buffer_length = %d",
313 			 buffer_length);
314 		return ASRC_EC_INVALID_BUFFER_LENGTH;
315 	}
316 
317 	if (bit_depth != 16 && bit_depth != 32) {
318 		comp_err(dev, "asrc_initialise(), bit_depth = %d",
319 			 bit_depth);
320 		return ASRC_EC_INVALID_BIT_DEPTH;
321 	}
322 
323 	/* set up program values */
324 	src_obj->input_format = input_format;
325 	src_obj->output_format = output_format;
326 	src_obj->bit_depth = bit_depth;
327 	src_obj->io_buffer_mode = buffer_mode;
328 	src_obj->io_buffer_idx = 0;
329 	src_obj->io_buffer_length = buffer_length;
330 	src_obj->num_channels = num_channels;
331 	src_obj->fs_prim = fs_prim;
332 	src_obj->fs_sec = fs_sec;
333 	src_obj->fs_ratio = ((int64_t)ONE_Q27 * src_obj->fs_prim) /
334 		src_obj->fs_sec;    /* stored as Q5.27 fixed point value */
335 	src_obj->fs_ratio_inv = ((int64_t)ONE_Q27 * src_obj->fs_sec) /
336 		src_obj->fs_prim; /* stored as Q5.27 fixed point value */
337 	src_obj->time_value = 0;
338 	src_obj->time_value_pull = 0;
339 	src_obj->control_mode = control_mode;
340 	src_obj->operation_mode = operation_mode;
341 	src_obj->prim_num_frames = 0;
342 	src_obj->prim_num_frames_targ = 0;
343 	src_obj->sec_num_frames = 0;
344 	src_obj->sec_num_frames_targ = 0;
345 	src_obj->calc_ir = NULL;
346 	src_obj->is_initialised = false;
347 	src_obj->is_updated = false;
348 
349 	/* check conversion ratios */
350 	if (src_obj->fs_ratio == 0 || src_obj->fs_ratio_inv == 0) {
351 		comp_err(dev, "asrc_initialise(), fail to calculate ratios");
352 		return ASRC_EC_INVALID_CONVERSION_RATIO;
353 	}
354 
355 	/*
356 	 * Set the pointer for the impulse response. It is just after
357 	 * src_obj in memory.
358 	 */
359 	src_obj->impulse_response = (int32_t *)(src_obj + 1);
360 
361 	/*
362 	 * Load the filter coefficients and parameters.  This function
363 	 * also sets the pointer to the corresponding
364 	 * calc_impulse_response_nX function.
365 	 */
366 	error_code = initialise_filter(dev, src_obj);
367 
368 	/* check for errors */
369 	if (error_code != ASRC_EC_OK) {
370 		comp_err(dev, "asrc_initialise(), failed filter initialise");
371 		return error_code;
372 	}
373 
374 	/*
375 	 * The pointer to the internal ring buffer pointers is
376 	 * after impulse_response. Only one of the buffers is initialised,
377 	 * depending on the specified bit depth.
378 	 */
379 	if (src_obj->bit_depth == 32) {
380 		src_obj->ring_buffers16 = NULL;
381 		src_obj->ring_buffers32 = (int32_t **)(src_obj->impulse_response +
382 			src_obj->filter_length);
383 	} else if (src_obj->bit_depth == 16) {
384 		src_obj->ring_buffers32 = NULL;
385 		src_obj->ring_buffers16 = (int16_t **)(src_obj->impulse_response +
386 			src_obj->filter_length);
387 	}
388 
389 	/* return ok, if everything worked out */
390 	src_obj->is_initialised = true;
391 	return ASRC_EC_OK;
392 }
393 
asrc_set_fs_ratio(struct comp_dev * dev,struct asrc_farrow * src_obj,int32_t fs_prim,int32_t fs_sec)394 enum asrc_error_code asrc_set_fs_ratio(struct comp_dev *dev,
395 				       struct asrc_farrow *src_obj,
396 				       int32_t fs_prim, int32_t fs_sec)
397 {
398 	/* Check for parameter errors */
399 	if (!src_obj) {
400 		comp_err(dev, "asrc_set_fs_ratio(), null src_obj");
401 		return ASRC_EC_INVALID_POINTER;
402 	}
403 
404 	if (!src_obj->is_initialised) {
405 		comp_err(dev, "asrc_set_fs_ratio(), not initialised");
406 		return ASRC_EC_INIT_FAILED;
407 	}
408 
409 	if (fs_prim < 8000 || fs_prim > 192000) {
410 		comp_err(dev, "asrc_set_fs_ratio(), fs_prim = %d", fs_prim);
411 		return ASRC_EC_INVALID_SAMPLE_RATE;
412 	}
413 
414 	if (fs_sec < 8000 || fs_sec > 192000) {
415 		comp_err(dev, "asrc_set_fs_ratio(), fs_sec = %d", fs_sec);
416 		return ASRC_EC_INVALID_SAMPLE_RATE;
417 	}
418 
419 	/* set sampling rates */
420 	src_obj->fs_prim = fs_prim;
421 	src_obj->fs_sec = fs_sec;
422 
423 	/* calculate conversion ratios as Q5.27. Note that ratio
424 	 * 192 / 8 = 24 is beyond signed 32 bit fractional integer
425 	 * but since the type for fs_ratio is unsigned, the ratio
426 	 * can be up to 31.9999... (but not 32).
427 	 */
428 	src_obj->fs_ratio = ((int64_t)ONE_Q27 * src_obj->fs_prim) /
429 		src_obj->fs_sec;
430 	src_obj->fs_ratio_inv = ((int64_t)ONE_Q27 * src_obj->fs_sec) /
431 		src_obj->fs_prim;
432 
433 	/* check conversion ratios */
434 	if (src_obj->fs_ratio == 0 || src_obj->fs_ratio_inv == 0) {
435 		comp_err(dev, "asrc_set_fs_ratio(), failed to calculate ratios");
436 		return ASRC_EC_INVALID_CONVERSION_RATIO;
437 	}
438 
439 	/* Reset the t values */
440 	src_obj->time_value = 0;
441 	src_obj->time_value_pull = 0;
442 
443 	/* See initialise_asrc(...) for further information
444 	 * Update the filters accordingly
445 	 */
446 	enum asrc_error_code error_code = initialise_filter(dev, src_obj);
447 	/* check for errors */
448 	if (error_code != ASRC_EC_OK) {
449 		comp_err(dev, "asrc_set_fs_ratio(), failed filter initialise");
450 		return error_code;
451 	}
452 
453 	/* The pointer to the internal ring buffer pointers is
454 	 * after impulse_response. Only one of the buffers is initialised,
455 	 * depending on the specified bit depth.
456 	 */
457 	if (src_obj->bit_depth == 32) {
458 		src_obj->ring_buffers16 = NULL;
459 		src_obj->ring_buffers32 = (int32_t **)(src_obj->impulse_response +
460 			src_obj->filter_length);
461 	} else if (src_obj->bit_depth == 16) {
462 		src_obj->ring_buffers32 = NULL;
463 		src_obj->ring_buffers16 = (int16_t **)(src_obj->impulse_response +
464 			src_obj->filter_length);
465 	}
466 
467 	return ASRC_EC_OK;
468 }
469 
asrc_set_input_format(struct comp_dev * dev,struct asrc_farrow * src_obj,enum asrc_io_format input_format)470 enum asrc_error_code asrc_set_input_format(struct comp_dev *dev,
471 					   struct asrc_farrow *src_obj,
472 					   enum asrc_io_format input_format)
473 {
474 	/* check for parameter errors */
475 	if (!src_obj) {
476 		comp_err(dev, "asrc_set_input_format(), null src_obj");
477 		return ASRC_EC_INVALID_POINTER;
478 	}
479 
480 	if (!src_obj->is_initialised) {
481 		comp_err(dev, "asrc_set_input_format(), not initialised");
482 		return ASRC_EC_INIT_FAILED;
483 	}
484 
485 	/* See header for further information */
486 	src_obj->input_format = input_format;
487 	return ASRC_EC_OK;
488 }
489 
asrc_set_output_format(struct comp_dev * dev,struct asrc_farrow * src_obj,enum asrc_io_format output_format)490 enum asrc_error_code asrc_set_output_format(struct comp_dev *dev,
491 					    struct asrc_farrow *src_obj,
492 					    enum asrc_io_format output_format)
493 {
494 	/* check for parameter errors */
495 	if (!src_obj) {
496 		comp_err(dev, "asrc_set_output_format(), null src_obj");
497 		return ASRC_EC_INVALID_POINTER;
498 	}
499 
500 	if (!src_obj->is_initialised) {
501 		comp_err(dev, "asrc_set_output_format(), not initialised");
502 		return ASRC_EC_INIT_FAILED;
503 	}
504 
505 	/* See header for further information */
506 	src_obj->output_format = output_format;
507 	return ASRC_EC_OK;
508 }
509 
510 
511 /*
512  * FILTER FUNCTIONS
513  */
initialise_filter(struct comp_dev * dev,struct asrc_farrow * src_obj)514 static enum asrc_error_code initialise_filter(struct comp_dev *dev,
515 					      struct asrc_farrow *src_obj)
516 {
517 	int fs_in;
518 	int fs_out;
519 
520 	if (src_obj->operation_mode == ASRC_OM_PUSH) {
521 		fs_in = src_obj->fs_prim;
522 		fs_out = src_obj->fs_sec;
523 	} else {
524 		fs_in = src_obj->fs_sec;
525 		fs_out = src_obj->fs_prim;
526 	}
527 
528 	/*
529 	 * Store the filter length and number of filters from the
530 	 * c_filter_params constant in the src_obj. Also set the pointer
531 	 * to the polyphase filters coefficients.
532 	 */
533 
534 	/* Reset coefficients for possible exit with error. */
535 	src_obj->filter_length = 0;
536 	src_obj->num_filters = 0;
537 	src_obj->polyphase_filters = NULL;
538 
539 	if (fs_in == 0 || fs_out == 0) {
540 		/* Avoid possible divisions by zero. */
541 		comp_err(dev, "initialise_filter(), fs_in = %d, fs_out = %d",
542 			 fs_in, fs_out);
543 		return ASRC_EC_INVALID_SAMPLE_RATE;
544 	} else if (fs_in == 48000 && fs_out >= 48000) {
545 		/* For conversion from 48 kHz to 48 kHz (and above) we
546 		 * can apply shorter filters (M=48), due to the soft
547 		 * slope (transition bandwidth from 20 kHz to 24 kHz).
548 		 */
549 		src_obj->filter_length =
550 			c_filter_params[CR_48000TO48000].filter_length;
551 		src_obj->num_filters =
552 			c_filter_params[CR_48000TO48000].num_filters;
553 		src_obj->polyphase_filters = &coeff48000to48000[0];
554 	} else if (fs_in <= fs_out) {
555 		/* All upsampling use cases can share the same set of
556 		 * filter coefficients.
557 		 */
558 		src_obj->filter_length =
559 			c_filter_params[CR_44100TO48000].filter_length;
560 		src_obj->num_filters =
561 			c_filter_params[CR_44100TO48000].num_filters;
562 		src_obj->polyphase_filters = &coeff44100to48000[0];
563 	} else if (fs_in == 48000) {
564 		switch (fs_out) {
565 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_08000)
566 		case 8000:
567 			src_obj->filter_length =
568 				c_filter_params[CR_48000TO08000].filter_length;
569 			src_obj->num_filters =
570 				c_filter_params[CR_48000TO08000].num_filters;
571 			src_obj->polyphase_filters = &coeff48000to08000[0];
572 			break;
573 #endif
574 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_11025)
575 		case 11025:
576 			src_obj->filter_length =
577 				c_filter_params[CR_48000TO11025].filter_length;
578 			src_obj->num_filters =
579 				c_filter_params[CR_48000TO11025].num_filters;
580 			src_obj->polyphase_filters = &coeff48000to11025[0];
581 			break;
582 #endif
583 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_12000)
584 		case 12000:
585 			src_obj->filter_length =
586 				c_filter_params[CR_48000TO12000].filter_length;
587 			src_obj->num_filters =
588 				c_filter_params[CR_48000TO12000].num_filters;
589 			src_obj->polyphase_filters = &coeff48000to12000[0];
590 			break;
591 #endif
592 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_16000)
593 		case 16000:
594 			src_obj->filter_length =
595 				c_filter_params[CR_48000TO16000].filter_length;
596 			src_obj->num_filters =
597 				c_filter_params[CR_48000TO16000].num_filters;
598 			src_obj->polyphase_filters = &coeff48000to16000[0];
599 			break;
600 #endif
601 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_22050)
602 		case 22050:
603 			src_obj->filter_length =
604 				c_filter_params[CR_48000TO22050].filter_length;
605 			src_obj->num_filters =
606 				c_filter_params[CR_48000TO22050].num_filters;
607 			src_obj->polyphase_filters = &coeff48000to22050[0];
608 			break;
609 #endif
610 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_24000)
611 		case 24000:
612 			src_obj->filter_length =
613 				c_filter_params[CR_48000TO24000].filter_length;
614 			src_obj->num_filters =
615 				c_filter_params[CR_48000TO24000].num_filters;
616 			src_obj->polyphase_filters = &coeff48000to24000[0];
617 			break;
618 #endif
619 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_32000)
620 		case 32000:
621 			src_obj->filter_length =
622 				c_filter_params[CR_48000TO32000].filter_length;
623 			src_obj->num_filters =
624 				c_filter_params[CR_48000TO32000].num_filters;
625 			src_obj->polyphase_filters = &coeff48000to32000[0];
626 			break;
627 #endif
628 #if (CONFIG_ASRC_SUPPORT_CONVERSION_48000_TO_44100)
629 		case 44100:
630 			src_obj->filter_length =
631 				c_filter_params[CR_48000TO44100].filter_length;
632 			src_obj->num_filters =
633 				c_filter_params[CR_48000TO44100].num_filters;
634 			src_obj->polyphase_filters = &coeff48000to44100[0];
635 			break;
636 #endif
637 		default:
638 			comp_err(dev, "initialise_filter(), fs_out = %d",
639 				 fs_out);
640 			return ASRC_EC_INVALID_SAMPLE_RATE;
641 		}
642 	} else if (fs_in == 24000) {
643 		switch (fs_out) {
644 #if (CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_08000)
645 		case 8000:
646 			src_obj->filter_length =
647 				c_filter_params[CR_24000TO08000].filter_length;
648 			src_obj->num_filters =
649 				c_filter_params[CR_24000TO08000].num_filters;
650 			src_obj->polyphase_filters = &coeff24000to08000[0];
651 			break;
652 #endif
653 #if (CONFIG_ASRC_SUPPORT_CONVERSION_24000_TO_16000)
654 		case 16000:
655 			src_obj->filter_length =
656 				c_filter_params[CR_24000TO16000].filter_length;
657 			src_obj->num_filters =
658 				c_filter_params[CR_24000TO16000].num_filters;
659 			src_obj->polyphase_filters = &coeff24000to16000[0];
660 			break;
661 #endif
662 		default:
663 			comp_err(dev, "initialise_filter(), fs_out = %d",
664 				 fs_out);
665 			return ASRC_EC_INVALID_SAMPLE_RATE;
666 		}
667 	} else {
668 		/* Conversion ratio is not supported. */
669 		comp_err(dev, "initialise_filter(), fs_in = %d", fs_in);
670 		return ASRC_EC_INVALID_SAMPLE_RATE;
671 	}
672 
673 	/* Check that filter length does not exceed allocated */
674 	if (src_obj->filter_length > ASRC_MAX_FILTER_LENGTH) {
675 		comp_err(dev, "initialise_filter(), filter_length %d exceeds max",
676 			 src_obj->filter_length);
677 		return ASRC_EC_INVALID_FILTER_LENGTH;
678 	}
679 
680 	/* The function pointer is set according to the number of polyphase
681 	 * filters
682 	 */
683 	switch (src_obj->num_filters) {
684 	case 4:
685 		src_obj->calc_ir = &asrc_calc_impulse_response_n4;
686 		break;
687 	case 5:
688 		src_obj->calc_ir = &asrc_calc_impulse_response_n5;
689 		break;
690 	case 6:
691 		src_obj->calc_ir = &asrc_calc_impulse_response_n6;
692 		break;
693 	case 7:
694 		src_obj->calc_ir = &asrc_calc_impulse_response_n7;
695 		break;
696 	default:
697 		comp_err(dev, "initialise_filter(), num_filters = %d",
698 			 src_obj->num_filters);
699 		return ASRC_EC_INVALID_CONVERSION_RATIO;
700 	}
701 
702 	return ASRC_EC_OK;
703 }
704 
asrc_update_drift(struct comp_dev * dev,struct asrc_farrow * src_obj,uint32_t clock_skew)705 enum asrc_error_code asrc_update_drift(struct comp_dev *dev,
706 				       struct asrc_farrow *src_obj,
707 				       uint32_t clock_skew)
708 {
709 	uint32_t fs_ratio;
710 	uint32_t fs_ratio_inv;
711 
712 	/* check for parameter errors */
713 	if (!src_obj) {
714 		comp_err(dev, "asrc_update_drift(), null src_obj");
715 		return ASRC_EC_INVALID_POINTER;
716 	}
717 
718 	if (!src_obj->is_initialised) {
719 		comp_err(dev, "asrc_update_drift(), not initialised");
720 		return ASRC_EC_INIT_FAILED;
721 	}
722 
723 	if (src_obj->control_mode != ASRC_CM_FEEDBACK) {
724 		comp_err(dev, "update_drift(), need to use feedback mode");
725 		return ASRC_EC_INVALID_CONTROL_MODE;
726 	}
727 
728 	/* Skew is Q2.30 */
729 	if (clock_skew < SKEW_MIN || clock_skew > SKEW_MAX) {
730 		comp_err(dev, "asrc_update_drift(), clock_skew = %d",
731 			 clock_skew);
732 		return ASRC_EC_INVALID_CLOCK_SKEW;
733 	}
734 
735 	/* Update the fs ratios, result is Q5.27 */
736 	fs_ratio = ((uint64_t)ONE_Q27 * src_obj->fs_prim) /
737 		src_obj->fs_sec;
738 	fs_ratio_inv = ((uint64_t)ONE_Q27 * src_obj->fs_sec) /
739 		src_obj->fs_prim;
740 
741 	/* Q5.27 x Q2.30 -> Q7.57, shift right by 30 to get Q5.27 */
742 	src_obj->fs_ratio = (uint32_t)(((uint64_t)fs_ratio * clock_skew) >> 30);
743 
744 	/* Scale Q5.27 to Q5.54, scale Q2.30 to Q2.27,
745 	 * then Q5.54 / Q2.27 -> Q5.27
746 	 */
747 	src_obj->fs_ratio_inv = (uint32_t)(((uint64_t)fs_ratio_inv << 27) /
748 		(uint64_t)(clock_skew >> 3));
749 
750 	return ASRC_EC_OK;
751 }
752 
asrc_update_fs_ratio(struct comp_dev * dev,struct asrc_farrow * src_obj,int primary_num_frames,int secondary_num_frames)753 enum asrc_error_code asrc_update_fs_ratio(struct comp_dev *dev,
754 					  struct asrc_farrow *src_obj,
755 					  int primary_num_frames,
756 					  int secondary_num_frames)
757 {
758 	uint64_t tmp_fs_ratio;
759 
760 	/* Check input for errors */
761 	if (!src_obj) {
762 		comp_err(dev, "asrc_update_fs_ratio(), null src_obj");
763 		return ASRC_EC_INVALID_POINTER;
764 	}
765 
766 	if (!src_obj->is_initialised) {
767 		comp_err(dev, "asrc_update_fs_ratio(), not initialized");
768 		return ASRC_EC_INIT_FAILED;
769 	}
770 
771 	if (src_obj->control_mode != ASRC_CM_FIXED) {
772 		comp_err(dev, "update_fs_ratio(), need to use fixed mode");
773 		return ASRC_EC_INVALID_CONTROL_MODE;
774 	}
775 
776 	if (primary_num_frames < 1 || secondary_num_frames < 1) {
777 		comp_err(dev, "update_fs_ratio(), primary_num_frames = %d, secondary_num_frames = %d",
778 			 primary_num_frames, secondary_num_frames);
779 		return ASRC_EC_INVALID_FRAME_SIZE;
780 	}
781 
782 	/* Calculate the new ratios as Q5.27 */
783 	tmp_fs_ratio = ((uint64_t)primary_num_frames) << 27;
784 	src_obj->fs_ratio = (tmp_fs_ratio / secondary_num_frames) + 1;
785 	tmp_fs_ratio = ((uint64_t)secondary_num_frames) << 27;
786 	src_obj->fs_ratio_inv = (tmp_fs_ratio / primary_num_frames) + 1;
787 
788 	/* Reset the counter and set the new target level */
789 	src_obj->prim_num_frames = 0;
790 	src_obj->prim_num_frames_targ = primary_num_frames;
791 	src_obj->sec_num_frames = 0;
792 	src_obj->sec_num_frames_targ = secondary_num_frames;
793 
794 	/* Reset the timer values, since we want start a new control cycle. */
795 	src_obj->time_value = 0;
796 	src_obj->time_value_pull = 0;
797 
798 	/* set updated status */
799 	src_obj->is_updated = true;
800 
801 	return ASRC_EC_OK;
802 }
803 
asrc_write_to_ring_buffer16(struct asrc_farrow * src_obj,int16_t ** input_buffers,int index_input_frame)804 void asrc_write_to_ring_buffer16(struct asrc_farrow  *src_obj,
805 				 int16_t **input_buffers, int index_input_frame)
806 {
807 	int ch;
808 	int j;
809 	int k;
810 	int m;
811 
812 	/* update the buffer_write_position */
813 	(src_obj->buffer_write_position)++;
814 
815 	/* since it's a ring buffer we need a wrap around */
816 	if (src_obj->buffer_write_position >= src_obj->buffer_length)
817 		src_obj->buffer_write_position -= (src_obj->buffer_length >> 1);
818 
819 	/* handle input format */
820 	if (src_obj->input_format == ASRC_IOF_INTERLEAVED)
821 		m = src_obj->num_channels * index_input_frame;
822 	else
823 		m = index_input_frame; /* For SRC_IOF_DEINTERLEAVED */
824 
825 	/* write data to each channel */
826 	j = src_obj->buffer_write_position;
827 	k = j - (src_obj->buffer_length >> 1);
828 	for (ch = 0; ch < src_obj->num_channels; ch++) {
829 		/*
830 		 * Since we want the filter function to load 64 bit of
831 		 * buffer data in one cycle, this function writes each
832 		 * input sample to the buffer twice, one with an
833 		 * offset of half the buffer size. This way we don't
834 		 * need a wrap around while loading #filter_length of
835 		 * buffered samples. The upper and lower half of the
836 		 * buffer are redundant. If the memory tradeoff is
837 		 * critical, the buffer can be reduced to half the
838 		 * size but therefore increased filter operations have
839 		 * to be expected.
840 		 */
841 		src_obj->ring_buffers16[ch][j] = input_buffers[ch][m];
842 		src_obj->ring_buffers16[ch][k] = input_buffers[ch][m];
843 	}
844 }
845 
asrc_write_to_ring_buffer32(struct asrc_farrow * src_obj,int32_t ** input_buffers,int index_input_frame)846 void asrc_write_to_ring_buffer32(struct asrc_farrow  *src_obj,
847 				 int32_t **input_buffers, int index_input_frame)
848 {
849 	int ch;
850 	int j;
851 	int k;
852 	int m;
853 
854 	/* update the buffer_write_position */
855 	(src_obj->buffer_write_position)++;
856 
857 	/* since it's a ring buffer we need a wrap around */
858 	if (src_obj->buffer_write_position >= src_obj->buffer_length)
859 		src_obj->buffer_write_position -= (src_obj->buffer_length >> 1);
860 
861 	/* handle input format */
862 	if (src_obj->input_format == ASRC_IOF_INTERLEAVED)
863 		m = src_obj->num_channels * index_input_frame;
864 	else
865 		m = index_input_frame; /* For SRC_IOF_DEINTERLEAVED */
866 
867 	/* write data to each channel */
868 	j = src_obj->buffer_write_position;
869 	k = j - (src_obj->buffer_length >> 1);
870 	for (ch = 0; ch < src_obj->num_channels; ch++) {
871 		/*
872 		 * Since we want the filter function to load 64 bit of
873 		 * buffer data in one cycle, this function writes each
874 		 * input sample to the buffer twice, one with an
875 		 * offset of half the buffer size. This way we don't
876 		 * need a wrap around while loading #filter_length of
877 		 * buffered samples. The upper and lower half of the
878 		 * buffer are redundant. If the memory tradeoff is
879 		 * critical, the buffer can be reduced to half the
880 		 * size but therefore increased filter operations have
881 		 * to be expected.
882 		 */
883 		src_obj->ring_buffers32[ch][j] = input_buffers[ch][m];
884 		src_obj->ring_buffers32[ch][k] = input_buffers[ch][m];
885 	}
886 }
887 
asrc_process_push16(struct comp_dev * dev,struct asrc_farrow * src_obj,int16_t ** __restrict input_buffers,int * input_num_frames,int16_t ** __restrict output_buffers,int * output_num_frames,int * write_index,int read_index)888 enum asrc_error_code asrc_process_push16(struct comp_dev *dev,
889 					 struct asrc_farrow *src_obj,
890 					 int16_t **__restrict input_buffers,
891 					 int *input_num_frames,
892 					 int16_t **__restrict output_buffers,
893 					 int *output_num_frames,
894 					 int *write_index,
895 					 int read_index)
896 {
897 	int index_input_frame;
898 	int max_num_free_frames;
899 
900 	/* parameter error handling */
901 	if (!src_obj || !input_buffers || !output_buffers ||
902 	    !output_num_frames || !write_index) {
903 		return ASRC_EC_INVALID_POINTER;
904 	}
905 
906 	if (!src_obj->is_initialised)
907 		return ASRC_EC_INIT_FAILED;
908 
909 	if (src_obj->control_mode == ASRC_CM_FIXED && !src_obj->is_updated)
910 		return ASRC_EC_UPDATE_FS_FAILED;
911 
912 	if (src_obj->io_buffer_mode == ASRC_BM_LINEAR) {
913 		/* Write to the beginning of the output buffer */
914 		src_obj->io_buffer_idx = 0;
915 		max_num_free_frames = src_obj->io_buffer_length;
916 	} else {
917 		/* circular */
918 		if (read_index > *write_index)
919 			max_num_free_frames = read_index - *write_index;
920 		else
921 			max_num_free_frames = src_obj->io_buffer_length +
922 				read_index - *write_index;
923 	}
924 
925 	*output_num_frames = 0;
926 	index_input_frame = 0;
927 
928 	/* Run the state machine until all input samples are read */
929 	while (index_input_frame < *input_num_frames) {
930 		if (src_obj->time_value < TIME_VALUE_ONE) {
931 			if (*output_num_frames == max_num_free_frames)
932 				break;
933 
934 			/* Calculate impulse response */
935 			(*src_obj->calc_ir)(src_obj);
936 
937 			/* Filter and write one output sample for each
938 			 * channel to the output_buffer
939 			 */
940 			asrc_fir_filter16(src_obj, output_buffers,
941 					  src_obj->io_buffer_idx);
942 
943 			/* Update time and buffer index */
944 			src_obj->time_value += src_obj->fs_ratio;
945 			src_obj->io_buffer_idx++;
946 
947 			/* Wrap around */
948 			if (src_obj->io_buffer_mode == ASRC_BM_CIRCULAR &&
949 			    src_obj->io_buffer_idx >= src_obj->io_buffer_length)
950 				src_obj->io_buffer_idx = 0;
951 
952 			(*output_num_frames)++;
953 		} else {
954 			/* Consume one input sample */
955 			asrc_write_to_ring_buffer16(src_obj, input_buffers,
956 						    index_input_frame);
957 			index_input_frame++;
958 
959 			/* Update time */
960 			src_obj->time_value -= TIME_VALUE_ONE;
961 		}
962 	}
963 	*write_index = src_obj->io_buffer_idx;
964 	*input_num_frames = index_input_frame;
965 
966 	/* if fixed control mode, update the frames counters and check
967 	 * if we have reached end of control cycle.
968 	 */
969 	if (src_obj->control_mode == ASRC_CM_FIXED) {
970 		src_obj->prim_num_frames += *input_num_frames;
971 		src_obj->sec_num_frames += *output_num_frames;
972 		if (src_obj->prim_num_frames >= src_obj->prim_num_frames_targ &&
973 		    src_obj->sec_num_frames >= src_obj->sec_num_frames_targ) {
974 			if (src_obj->sec_num_frames !=
975 			    src_obj->sec_num_frames_targ) {
976 				comp_err(dev, "process_push16(), Generated = %d, Target = %d",
977 					 src_obj->sec_num_frames,
978 					 src_obj->sec_num_frames_targ);
979 				return ASRC_EC_FAILED_PUSH_MODE;
980 			}
981 
982 			if (src_obj->time_value > TIME_VALUE_LIMIT) {
983 				comp_err(dev, "process_push16(), Time value = %d",
984 					 src_obj->time_value);
985 				return ASRC_EC_FAILED_PUSH_MODE;
986 			}
987 
988 			/* Force that update_fs_ratio() will be called
989 			 * (this will reset the time value).
990 			 */
991 			src_obj->is_updated = false;
992 		}
993 	}
994 
995 	return ASRC_EC_OK;
996 }
997 
asrc_process_push32(struct comp_dev * dev,struct asrc_farrow * src_obj,int32_t ** __restrict input_buffers,int * input_num_frames,int32_t ** __restrict output_buffers,int * output_num_frames,int * write_index,int read_index)998 enum asrc_error_code asrc_process_push32(struct comp_dev *dev,
999 					 struct asrc_farrow *src_obj,
1000 					 int32_t **__restrict input_buffers,
1001 					 int *input_num_frames,
1002 					 int32_t **__restrict output_buffers,
1003 					 int *output_num_frames,
1004 					 int *write_index,
1005 					 int read_index)
1006 {
1007 	/* See 'process_push16' for a more detailed description of the
1008 	 * algorithm
1009 	 */
1010 	int index_input_frame;
1011 	int max_num_free_frames;
1012 
1013 	/* parameter error handling */
1014 	if (!src_obj || !input_buffers || !output_buffers ||
1015 	    !output_num_frames || !write_index)
1016 		return ASRC_EC_INVALID_POINTER;
1017 
1018 	if (!src_obj->is_initialised)
1019 		return ASRC_EC_INIT_FAILED;
1020 
1021 	if (src_obj->control_mode == ASRC_CM_FIXED && !src_obj->is_updated)
1022 		return ASRC_EC_UPDATE_FS_FAILED;
1023 
1024 	if (src_obj->io_buffer_mode == ASRC_BM_LINEAR) {
1025 		src_obj->io_buffer_idx = 0;
1026 		max_num_free_frames = src_obj->io_buffer_length;
1027 	} else {
1028 		if (read_index > *write_index)
1029 			max_num_free_frames = read_index - *write_index;
1030 		else
1031 			max_num_free_frames = src_obj->io_buffer_length +
1032 				read_index - *write_index;
1033 	}
1034 
1035 	*output_num_frames = 0;
1036 	index_input_frame = 0;
1037 	while (index_input_frame < *input_num_frames) {
1038 		if (src_obj->time_value < TIME_VALUE_ONE) {
1039 			if (*output_num_frames == max_num_free_frames)
1040 				break;
1041 
1042 			/* Calculate impulse response */
1043 			(*src_obj->calc_ir)(src_obj);
1044 
1045 			/* Filter and write output sample to
1046 			 * output_buffer
1047 			 */
1048 			asrc_fir_filter32(src_obj, output_buffers,
1049 					  src_obj->io_buffer_idx);
1050 
1051 			/* Update time and index */
1052 			src_obj->time_value += src_obj->fs_ratio;
1053 			src_obj->io_buffer_idx++;
1054 
1055 			/* Wrap around */
1056 			if (src_obj->io_buffer_mode == ASRC_BM_CIRCULAR &&
1057 			    src_obj->io_buffer_idx >= src_obj->io_buffer_length)
1058 				src_obj->io_buffer_idx = 0;
1059 
1060 			(*output_num_frames)++;
1061 		} else {
1062 			/* Consume input sample */
1063 			asrc_write_to_ring_buffer32(src_obj, input_buffers,
1064 						    index_input_frame);
1065 			index_input_frame++;
1066 
1067 			/* Update time */
1068 			src_obj->time_value -= TIME_VALUE_ONE;
1069 		}
1070 	}
1071 	*write_index = src_obj->io_buffer_idx;
1072 	*input_num_frames = index_input_frame;
1073 
1074 	/* if fixed control mode, update the frames counters and check if we
1075 	 * have reached end of control cycle.
1076 	 */
1077 	if (src_obj->control_mode == ASRC_CM_FIXED) {
1078 		src_obj->prim_num_frames += *input_num_frames;
1079 		src_obj->sec_num_frames += *output_num_frames;
1080 		if (src_obj->prim_num_frames >= src_obj->prim_num_frames_targ &&
1081 		    src_obj->sec_num_frames >= src_obj->sec_num_frames_targ) {
1082 			if (src_obj->sec_num_frames !=
1083 			    src_obj->sec_num_frames_targ) {
1084 				comp_err(dev, "process_push32(), Generated =  %d, Target = %d",
1085 					 src_obj->sec_num_frames,
1086 					 src_obj->sec_num_frames_targ);
1087 				return ASRC_EC_FAILED_PUSH_MODE;
1088 			}
1089 
1090 			if (src_obj->time_value > TIME_VALUE_LIMIT) {
1091 				comp_err(dev, "process_push32(), Time value = %d",
1092 					 src_obj->time_value);
1093 				return ASRC_EC_FAILED_PUSH_MODE;
1094 			}
1095 
1096 			/* Force that update_fs_ratio() will be called
1097 			 * (this will reset the time value).
1098 			 */
1099 			src_obj->is_updated = false;
1100 		}
1101 	}
1102 
1103 	return ASRC_EC_OK;
1104 }
1105 
asrc_process_pull16(struct comp_dev * dev,struct asrc_farrow * src_obj,int16_t ** __restrict input_buffers,int * input_num_frames,int16_t ** __restrict output_buffers,int * output_num_frames,int write_index,int * read_index)1106 enum asrc_error_code asrc_process_pull16(struct comp_dev *dev,
1107 					 struct asrc_farrow *src_obj,
1108 					 int16_t **__restrict input_buffers,
1109 					 int *input_num_frames,
1110 					 int16_t **__restrict output_buffers,
1111 					 int *output_num_frames,
1112 					 int write_index,
1113 					 int *read_index)
1114 {
1115 	int index_output_frame = 0;
1116 
1117 	/* parameter error handling */
1118 	if (!src_obj || !input_buffers || !output_buffers ||
1119 	    !input_num_frames || !read_index)
1120 		return ASRC_EC_INVALID_POINTER;
1121 
1122 	if (!src_obj->is_initialised)
1123 		return ASRC_EC_INIT_FAILED;
1124 
1125 	if (src_obj->control_mode == ASRC_CM_FIXED && !src_obj->is_updated)
1126 		return ASRC_EC_UPDATE_FS_FAILED;
1127 
1128 	if (src_obj->io_buffer_mode == ASRC_BM_CIRCULAR)
1129 		src_obj->io_buffer_idx = *read_index;
1130 	else
1131 		/* linear */
1132 		src_obj->io_buffer_idx = 0;
1133 
1134 	*input_num_frames = 0;
1135 
1136 	/* Run state machine until number of output samples are written */
1137 	while (index_output_frame < *output_num_frames) {
1138 		if (src_obj->time_value_pull < TIME_VALUE_ONE) {
1139 			/* Consume one input sample */
1140 			if (src_obj->io_buffer_idx == write_index)
1141 				break;
1142 
1143 			asrc_write_to_ring_buffer16(src_obj,
1144 						    input_buffers,
1145 						    src_obj->io_buffer_idx);
1146 			src_obj->io_buffer_idx++;
1147 
1148 			/* Wrap around */
1149 			if (src_obj->io_buffer_mode == ASRC_BM_CIRCULAR &&
1150 			    src_obj->io_buffer_idx >= src_obj->io_buffer_length)
1151 				src_obj->io_buffer_idx = 0;
1152 
1153 			(*input_num_frames)++;
1154 
1155 			/* Update time as Q5.27 */
1156 			src_obj->time_value = (((int64_t)TIME_VALUE_ONE -
1157 						src_obj->time_value_pull) *
1158 					       src_obj->fs_ratio_inv) >> 27;
1159 			src_obj->time_value_pull += src_obj->fs_ratio;
1160 		} else {
1161 			/* Calculate impulse response */
1162 			(*src_obj->calc_ir)(src_obj);
1163 
1164 			/* Filter and write output sample to output_buffer */
1165 			asrc_fir_filter16(src_obj, output_buffers,
1166 					  index_output_frame);
1167 
1168 			/* Update time and index */
1169 			src_obj->time_value += src_obj->fs_ratio_inv;
1170 			src_obj->time_value_pull -= TIME_VALUE_ONE;
1171 			index_output_frame++;
1172 		}
1173 	}
1174 	*read_index = src_obj->io_buffer_idx;
1175 	*output_num_frames = index_output_frame;
1176 
1177 	/* if fixed control mode, update the frames counters and check if we
1178 	 * have reached end of control cycle.
1179 	 */
1180 	if (src_obj->control_mode == ASRC_CM_FIXED) {
1181 		src_obj->prim_num_frames += *output_num_frames;
1182 		src_obj->sec_num_frames += *input_num_frames;
1183 		if (src_obj->prim_num_frames >= src_obj->prim_num_frames_targ &&
1184 		    src_obj->sec_num_frames >= src_obj->sec_num_frames_targ) {
1185 			if (src_obj->sec_num_frames !=
1186 			    src_obj->sec_num_frames_targ) {
1187 				comp_err(dev, "process_pull16(), Consumed = %d, Target = %d",
1188 					 src_obj->sec_num_frames,
1189 					 src_obj->sec_num_frames_targ);
1190 				return ASRC_EC_FAILED_PULL_MODE;
1191 			}
1192 
1193 			if (src_obj->time_value_pull > TIME_VALUE_LIMIT) {
1194 				comp_err(dev, "process_pull16(), Time value = %d",
1195 					 src_obj->time_value_pull);
1196 				return ASRC_EC_FAILED_PULL_MODE;
1197 			}
1198 
1199 			/* Force that update_fs_ratio() will be called
1200 			 * (this will reset the time value).
1201 			 */
1202 			src_obj->is_updated = false;
1203 		}
1204 	}
1205 
1206 	return ASRC_EC_OK;
1207 }
1208 
asrc_process_pull32(struct comp_dev * dev,struct asrc_farrow * src_obj,int32_t ** __restrict input_buffers,int * input_num_frames,int32_t ** __restrict output_buffers,int * output_num_frames,int write_index,int * read_index)1209 enum asrc_error_code asrc_process_pull32(struct comp_dev *dev,
1210 					 struct asrc_farrow *src_obj,
1211 					 int32_t **__restrict input_buffers,
1212 					 int *input_num_frames,
1213 					 int32_t **__restrict output_buffers,
1214 					 int *output_num_frames,
1215 					 int write_index,
1216 					 int *read_index)
1217 {
1218 	int index_output_frame = 0;
1219 
1220 	/* parameter error handling */
1221 	if (!src_obj || !input_buffers || !output_buffers ||
1222 	    !input_num_frames || !read_index)
1223 		return ASRC_EC_INVALID_POINTER;
1224 
1225 	if (!src_obj->is_initialised)
1226 		return ASRC_EC_INIT_FAILED;
1227 
1228 	if (src_obj->control_mode == ASRC_CM_FIXED && !src_obj->is_updated)
1229 		return ASRC_EC_UPDATE_FS_FAILED;
1230 
1231 	/* See 'process_pull16' for a more detailed description of the
1232 	 * algorithm
1233 	 */
1234 
1235 	if (src_obj->io_buffer_mode == ASRC_BM_CIRCULAR)
1236 		src_obj->io_buffer_idx = *read_index;
1237 	else
1238 		src_obj->io_buffer_idx = 0;
1239 
1240 	*input_num_frames = 0;
1241 	while (index_output_frame < *output_num_frames) {
1242 		if (src_obj->time_value_pull < TIME_VALUE_ONE) {
1243 			/* Consume input sample */
1244 			if (src_obj->io_buffer_idx == write_index)
1245 				break;
1246 
1247 			asrc_write_to_ring_buffer32(src_obj,
1248 						    input_buffers,
1249 						    src_obj->io_buffer_idx);
1250 			src_obj->io_buffer_idx++;
1251 
1252 			/* Wrap around */
1253 			if (src_obj->io_buffer_mode == ASRC_BM_CIRCULAR &&
1254 			    src_obj->io_buffer_idx >= src_obj->io_buffer_length)
1255 				src_obj->io_buffer_idx = 0;
1256 
1257 			(*input_num_frames)++;
1258 
1259 			/* Update time as Q5.27 */
1260 			src_obj->time_value = (((int64_t)TIME_VALUE_ONE -
1261 						src_obj->time_value_pull) *
1262 					       src_obj->fs_ratio_inv) >> 27;
1263 			src_obj->time_value_pull += src_obj->fs_ratio;
1264 		} else {
1265 			/* Calculate impulse response */
1266 			(*src_obj->calc_ir)(src_obj);
1267 
1268 			/* Filter and write output sample to output_buffer */
1269 			asrc_fir_filter32(src_obj, output_buffers,
1270 					  index_output_frame);
1271 
1272 			/* Update time and index */
1273 			src_obj->time_value += src_obj->fs_ratio_inv;
1274 			src_obj->time_value_pull -= TIME_VALUE_ONE;
1275 			index_output_frame++;
1276 		}
1277 	}
1278 	*read_index = src_obj->io_buffer_idx;
1279 	*output_num_frames = index_output_frame;
1280 
1281 	/* if fixed control mode, update the frames counters and check
1282 	 * if we have reached end of control cycle.
1283 	 */
1284 	if (src_obj->control_mode == ASRC_CM_FIXED) {
1285 		src_obj->prim_num_frames += *output_num_frames;
1286 		src_obj->sec_num_frames += *input_num_frames;
1287 		if (src_obj->prim_num_frames >= src_obj->prim_num_frames_targ &&
1288 		    src_obj->sec_num_frames >= src_obj->sec_num_frames_targ) {
1289 			if (src_obj->sec_num_frames !=
1290 			    src_obj->sec_num_frames_targ) {
1291 				comp_err(dev, "process_pull32(), Consumed = %d, Target = %d.\n",
1292 					 src_obj->sec_num_frames,
1293 					 src_obj->sec_num_frames_targ);
1294 				return ASRC_EC_FAILED_PULL_MODE;
1295 			}
1296 
1297 			if (src_obj->time_value_pull > TIME_VALUE_LIMIT) {
1298 				comp_err(dev, "process_pull32(): Time value = %d",
1299 					 src_obj->time_value_pull);
1300 				return ASRC_EC_FAILED_PULL_MODE;
1301 			}
1302 
1303 			/* Force that update_fs_ratio() will be called
1304 			 * (this will reset the time value).
1305 			 */
1306 			src_obj->is_updated = false;
1307 		}
1308 	}
1309 
1310 	return ASRC_EC_OK;
1311 }
1312