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