From 1c741726699643ecb8a94fd40ee13adfd7c689cb Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 10 Dec 2024 21:22:50 +0200 Subject: [PATCH] Audio: SRC: Coefficients in prepare() to fast SRAM with fast_get() The SRC coefficients are loaded to DRAM and commit copies the coefficients to SRAM when they are needed. The copying is done using fast_get() and the copy is released with fast_put() when its not needed anymore. Signed-off-by: Jyri Sarha --- src/audio/src/src.c | 7 +++-- src/audio/src/src_common.c | 59 +++++++++++++++++++++++++++++++++++++- src/audio/src/src_common.h | 3 ++ src/audio/src/src_lite.c | 7 +++-- 4 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/audio/src/src.c b/src/audio/src/src.c index ce3d00ba2399..57c957eb5f78 100644 --- a/src/audio/src/src.c +++ b/src/audio/src/src.c @@ -59,8 +59,11 @@ static int src_prepare(struct processing_module *mod, if (ret < 0) return ret; - a->stage1 = src_table1[a->idx_out][a->idx_in]; - a->stage2 = src_table2[a->idx_out][a->idx_in]; + ret = src_allocate_copy_stages(mod->dev, a, + src_table1[a->idx_out][a->idx_in], + src_table2[a->idx_out][a->idx_in]); + if (ret < 0) + return ret; ret = src_params_general(mod, sources[0], sinks[0]); if (ret < 0) diff --git a/src/audio/src/src_common.c b/src/audio/src/src_common.c index 3a8135592ce6..f482b676fa78 100644 --- a/src/audio/src/src_common.c +++ b/src/audio/src/src_common.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -593,6 +594,60 @@ int src_param_set(struct comp_dev *dev, struct comp_data *cd) return 0; } +static void debug_print(struct comp_dev *dev, const char *name, const struct src_stage *s) +{ + comp_info(dev, "%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %p", name, + s->idm, s->odm, s->num_of_subfilters, s->subfilter_length, + s->filter_length, s->blk_in, s->blk_out, s->halfband, s->shift, + s->coefs); +} + +int src_allocate_copy_stages(struct comp_dev *dev, struct src_param *prm, + const struct src_stage *stage_src1, + const struct src_stage *stage_src2) +{ + struct src_stage *stage_dst1; + struct src_stage *stage_dst2; + size_t coef_size1; + size_t coef_size2; + char *coef_dst; + const char *coef_src; +#if SRC_SHORT + size_t tap_size = sizeof(int16_t); +#else + size_t tap_size = sizeof(int32_t); +#endif + int ret; + + stage_dst1 = rmalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, + 2 * sizeof(*stage_dst1)); + if (!stage_dst1) { + comp_err(dev, "src_allocate_copy_stages(): failed allocate stages"); + return -ENOMEM; + } + + /* Make local copies of the src_stages */ + stage_dst2 = stage_dst1 + 1; + ret = memcpy_s(stage_dst1, sizeof(*stage_dst1), stage_src1, sizeof(*stage_src1)); + ret = memcpy_s(stage_dst2, sizeof(*stage_dst2), stage_src2, sizeof(*stage_src2)); + + coef_size1 = tap_size * stage_src1->filter_length; + coef_size2 = tap_size * stage_src2->filter_length; + + stage_dst1->coefs = fast_get(stage_src1->coefs, coef_size1); + stage_dst2->coefs = fast_get(stage_src2->coefs, coef_size2); + + if (!stage_dst1->coefs || !stage_dst2->coefs) { + comp_err(dev, "src_allocate_copy_stages(): failed allocate coefficients"); + return -ENOMEM; + } + + prm->stage1 = stage_dst1; + prm->stage2 = stage_dst2; + + return 0; +} + bool src_is_ready_to_process(struct processing_module *mod, struct sof_source **sources, int num_of_sources, struct sof_sink **sinks, int num_of_sinks) @@ -653,7 +708,9 @@ __cold int src_free(struct processing_module *mod) /* Free dynamically reserved buffers for SRC algorithm */ rfree(cd->delay_lines); - + fast_put((void *)cd->param.stage1->coefs); + fast_put((void *)cd->param.stage2->coefs); + rfree((void *)cd->param.stage1); rfree(cd); return 0; } diff --git a/src/audio/src/src_common.h b/src/audio/src/src_common.h index d3ed218016db..4f1faf1df94a 100644 --- a/src/audio/src/src_common.h +++ b/src/audio/src/src_common.h @@ -215,6 +215,9 @@ static inline int src_fallback(struct comp_data *cd, return 0; } +int src_allocate_copy_stages(struct comp_dev *dev, struct src_param *prm, + const struct src_stage *stage_src1, + const struct src_stage *stage_src2); int src_rate_check(const void *spec); int src_set_params(struct processing_module *mod, struct sof_sink *sink); diff --git a/src/audio/src/src_lite.c b/src/audio/src/src_lite.c index 1602ce68ea6c..e291118fe859 100644 --- a/src/audio/src/src_lite.c +++ b/src/audio/src/src_lite.c @@ -44,8 +44,11 @@ static int src_lite_prepare(struct processing_module *mod, if (ret < 0) return ret; - a->stage1 = src_table1[a->idx_out][a->idx_in]; - a->stage2 = src_table2[a->idx_out][a->idx_in]; + ret = src_allocate_copy_stages(mod->dev, a, + src_table1[a->idx_out][a->idx_in], + src_table2[a->idx_out][a->idx_in]); + if (ret < 0) + return ret; ret = src_params_general(mod, sources[0], sinks[0]); if (ret < 0)