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