From 2d0d8cbc780425beb301c6175f54a9f7724be01b 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 | 56 +++++++++++++++++++++++++++++++++++++- src/audio/src/src_common.h | 21 ++++++++------ src/audio/src/src_lite.c | 7 +++-- 4 files changed, 77 insertions(+), 14 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 a798a4cf59e8..5b8bb3e00913 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 @@ -592,6 +593,53 @@ int src_param_set(struct comp_dev *dev, 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) +{ +#if CONFIG_FAST_GET + struct src_stage *stage_dst; + size_t coef_size[2]; +#if SRC_SHORT + size_t tap_size = sizeof(int16_t); +#else + size_t tap_size = sizeof(int32_t); +#endif + + stage_dst = rmalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, + 2 * sizeof(*stage_dst)); + if (!stage_dst) { + comp_err(dev, "failed to allocate stages"); + return -ENOMEM; + } + + /* Make local copies of the src_stages */ + stage_dst[0] = *stage_src1; + stage_dst[1] = *stage_src2; + + coef_size[0] = tap_size * stage_src1->filter_length; + coef_size[1] = tap_size * stage_src2->filter_length; + + stage_dst[0].coefs = fast_get(stage_src1->coefs, coef_size[0]); + stage_dst[1].coefs = fast_get(stage_src2->coefs, coef_size[1]); + + if (!stage_dst[0].coefs || !stage_dst[1].coefs) { + comp_err(dev, "failed to allocate coefficients"); + fast_put(stage_dst[0].coefs); + rfree(stage_dst); + return -ENOMEM; + } + + prm->stage1 = stage_dst; + prm->stage2 = stage_dst + 1; +#else + prm->stage1 = stage_src1; + prm->stage2 = stage_src2; +#endif + + 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) @@ -652,7 +700,13 @@ __cold int src_free(struct processing_module *mod) /* Free dynamically reserved buffers for SRC algorithm */ rfree(cd->delay_lines); - +#if CONFIG_FAST_GET + if (cd->param.stage1) { + fast_put(cd->param.stage1->coefs); + fast_put(cd->param.stage2->coefs); + } + rfree((void *)cd->param.stage1); +#endif rfree(cd); return 0; } diff --git a/src/audio/src/src_common.h b/src/audio/src/src_common.h index d3ed218016db..56b07a0b03a2 100644 --- a/src/audio/src/src_common.h +++ b/src/audio/src/src_common.h @@ -18,15 +18,15 @@ #include "src_ipc.h" struct src_stage { - const int idm; - const int odm; - const int num_of_subfilters; - const int subfilter_length; - const int filter_length; - const int blk_in; - const int blk_out; - const int halfband; - const int shift; + int idm; + int odm; + int num_of_subfilters; + int subfilter_length; + int filter_length; + int blk_in; + int blk_out; + int halfband; + int shift; const void *coefs; /* Can be int16_t or int32_t depending on config */ }; @@ -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 35423dad9225..b1bf87b8ddfd 100644 --- a/src/audio/src/src_lite.c +++ b/src/audio/src/src_lite.c @@ -43,8 +43,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)