From 3c3c03f804a1e6b49cb117744bf121ddfa1c6e3f Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 21 Aug 2025 22:32:55 +0300 Subject: [PATCH 01/16] Math: Make mod_alloc() versions of all heap using functions Make mod_alloc() versions of all heap using functions. The new functions are simple copy-paste versions of the original, just using mod_alloc() and friend instead of rmalloc() friends. The idea is to get rid off the original versions once all the modules are converted to module API heap usage and the cmocka math tests have been fixed to work with mod_alloc() versions. Signed-off-by: Jyri Sarha --- src/include/sof/math/auditory.h | 2 + src/include/sof/math/dct.h | 1 + src/include/sof/math/fft.h | 4 + src/include/sof/math/matrix.h | 15 ++++ src/math/auditory/auditory.c | 126 ++++++++++++++++++++++++++++++++ src/math/dct.c | 48 ++++++++++++ src/math/fft/fft_common.c | 59 +++++++++++++++ 7 files changed, 255 insertions(+) diff --git a/src/include/sof/math/auditory.h b/src/include/sof/math/auditory.h index eef073092e22..0e082335f764 100644 --- a/src/include/sof/math/auditory.h +++ b/src/include/sof/math/auditory.h @@ -77,6 +77,8 @@ int16_t psy_mel_to_hz(int16_t mel); * \return Zero when success, otherwise error code. */ int psy_get_mel_filterbank(struct psy_mel_filterbank *mel_fb); +struct processing_module; +int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *mel_fb); /** * \brief Convert linear complex spectra from FFT into Mel band energies in desired diff --git a/src/include/sof/math/dct.h b/src/include/sof/math/dct.h index bb3aca81b202..c1c5caa808a6 100644 --- a/src/include/sof/math/dct.h +++ b/src/include/sof/math/dct.h @@ -30,5 +30,6 @@ struct dct_plan_16 { }; int dct_initialize_16(struct dct_plan_16 *dct); +int mod_dct_initialize_16(struct processing_module *mod, struct dct_plan_16 *dct); #endif /* __SOF_MATH_DCT_H__ */ diff --git a/src/include/sof/math/fft.h b/src/include/sof/math/fft.h index 504465401cad..16ae9ca97669 100644 --- a/src/include/sof/math/fft.h +++ b/src/include/sof/math/fft.h @@ -53,8 +53,12 @@ struct fft_plan { /* interfaces of the library */ struct fft_plan *fft_plan_new(void *inb, void *outb, uint32_t size, int bits); +struct processing_module; +struct fft_plan *mod_fft_plan_new(struct processing_module *mod, void *inb, + void *outb, uint32_t size, int bits); void fft_execute_16(struct fft_plan *plan, bool ifft); void fft_execute_32(struct fft_plan *plan, bool ifft); void fft_plan_free(struct fft_plan *plan16); +void mod_fft_plan_free(struct processing_module *mod, struct fft_plan *plan16); #endif /* __SOF_FFT_H__ */ diff --git a/src/include/sof/math/matrix.h b/src/include/sof/math/matrix.h index 74899371038a..f48f1ca4960d 100644 --- a/src/include/sof/math/matrix.h +++ b/src/include/sof/math/matrix.h @@ -10,6 +10,7 @@ #ifndef __SOF_MATH_MATRIX_H__ #define __SOF_MATH_MATRIX_H__ +#include #include #include #include @@ -44,6 +45,20 @@ static inline struct mat_matrix_16b *mat_matrix_alloc_16b(int16_t rows, int16_t return mat; } +static inline struct mat_matrix_16b *mod_mat_matrix_alloc_16b(struct processing_module *mod, + int16_t rows, int16_t columns, + int16_t fractions) +{ + struct mat_matrix_16b *mat; + const int mat_size = sizeof(int16_t) * rows * columns + sizeof(struct mat_matrix_16b); + + mat = mod_zalloc(mod, mat_size); + if (mat) + mat_init_16b(mat, rows, columns, fractions); + + return mat; +} + static inline void mat_copy_from_linear_16b(struct mat_matrix_16b *mat, const int16_t *lin_data) { size_t bytes = sizeof(int16_t) * mat->rows * mat->columns; diff --git a/src/math/auditory/auditory.c b/src/math/auditory/auditory.c index dbfe47b1699c..a10d13bbfc99 100644 --- a/src/math/auditory/auditory.c +++ b/src/math/auditory/auditory.c @@ -4,6 +4,7 @@ // // Author: Seppo Ingalsuo +#include #include #include #include @@ -210,3 +211,128 @@ int psy_get_mel_filterbank(struct psy_mel_filterbank *fb) fb->scratch_data2, sizeof(int16_t) * fb->data_length); return 0; } + +int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *fb) +{ + int32_t up_slope; + int32_t down_slope; + int32_t slope; + int32_t scale = ONE_Q16; + int32_t scale_inv = ONE_Q16; + int16_t *mel; + int16_t mel_start; + int16_t mel_end; + int16_t mel_step; + int16_t left_mel; + int16_t center_mel; + int16_t right_mel; + int16_t delta_cl; + int16_t delta_rc; + int16_t left_hz; + int16_t right_hz; + int16_t f; + int segment; + int i, j, idx; + int base_idx = 0; + int start_bin = 0; + int end_bin = 0; + + if (!fb) + return -ENOMEM; + + if (!fb->scratch_data1 || !fb->scratch_data2) + return -ENOMEM; + + /* Log power can be log, or log10 or dB, get multiply coef to convert + * log to desired format. + */ + switch (fb->mel_log_scale) { + case MEL_LOG: + fb->log_mult = ONE_OVER_LOG2E_Q29; + break; + case MEL_LOG10: + fb->log_mult = ONE_OVER_LOG2TEN_Q29; + break; + case MEL_DB: + fb->log_mult = TEN_OVER_LOG2TEN_Q29; + break; + default: + return -EINVAL; + } + + /* Use scratch area to hold vector of Mel values for each FFT frequency */ + if (fb->scratch_length1 < fb->half_fft_bins) + return -ENOMEM; + + fb->scale_log2 = 0; + + mel = fb->scratch_data1; + for (i = 0; i < fb->half_fft_bins; i++) { + f = fb->samplerate * i / fb->fft_bins; + mel[i] = psy_hz_to_mel(f); + } + + mel_start = psy_hz_to_mel(fb->start_freq); + mel_end = psy_hz_to_mel(fb->end_freq); + mel_step = (mel_end - mel_start) / (fb->mel_bins + 1); + for (i = 0; i < fb->mel_bins; i++) { + left_mel = mel_start + i * mel_step; + center_mel = mel_start + (i + 1) * mel_step; + right_mel = mel_start + (i + 2) * mel_step; + delta_cl = center_mel - left_mel; + delta_rc = right_mel - center_mel; + segment = 0; + idx = base_idx + 3; /* start of filter weight values */ + if (fb->slaney_normalize) { + left_hz = psy_mel_to_hz(left_mel); + right_hz = psy_mel_to_hz(right_mel); + scale = Q_SHIFT_RND(TWO_Q29 / (right_hz - left_hz), 29, 16); /* Q16.16*/ + if (i == 0) { + scale_inv = Q_SHIFT_LEFT(ONE_Q30 / scale, 14, 16); + fb->scale_log2 = base2_logarithm((uint32_t)scale) - LOG2_2P16; + } + + scale = Q_MULTSR_32X32((int64_t)scale, scale_inv, 16, 16, 16); + } + for (j = 0; j < fb->half_fft_bins; j++) { + up_slope = (((int32_t)mel[j] - left_mel) << 15) / delta_cl; /* Q17.15 */ + down_slope = (((int32_t)right_mel - mel[j]) << 15) / delta_rc; /* Q17.15 */ + slope = MIN(up_slope, down_slope); + slope = Q_MULTSR_32X32((int64_t)slope, scale, 15, 16, 15); + if (segment == 1 && slope <= 0) { + end_bin = j - 1; + break; + } + + if (segment == 0 && slope > 0) { + start_bin = j; + segment = 1; + } + + if (segment == 1) { + if (idx >= fb->scratch_length2) + return -EINVAL; + + fb->scratch_data2[idx++] = sat_int16(slope); + } + } + + if (idx + 2 >= fb->scratch_length2) + return -EINVAL; + + fb->scratch_data2[base_idx] = idx; /* index to next */ + fb->scratch_data2[base_idx + 1] = start_bin; + fb->scratch_data2[base_idx + 2] = end_bin - start_bin + 1; /* length */ + base_idx = idx; + } + + fb->data_length = &fb->scratch_data2[base_idx] - &fb->scratch_data2[0]; + fb->data = mod_zalloc(mod, sizeof(int16_t) * fb->data_length); + if (!fb->data) + return -ENOMEM; + + /* Copy the exact triangles data size to allocated buffer */ + memcpy_s(fb->data, sizeof(int16_t) * fb->data_length, + fb->scratch_data2, sizeof(int16_t) * fb->data_length); + return 0; +} diff --git a/src/math/dct.c b/src/math/dct.c index 15d23b67c7f9..db2d96525eea 100644 --- a/src/math/dct.c +++ b/src/math/dct.c @@ -4,6 +4,7 @@ // // Author: Seppo Ingalsuo +#include #include #include #include @@ -77,3 +78,50 @@ int dct_initialize_16(struct dct_plan_16 *dct) return 0; } + +int mod_dct_initialize_16(struct processing_module *mod, struct dct_plan_16 *dct) +{ + int16_t dct_val; + int32_t arg; + int32_t cos; + int32_t c1; + int16_t c2; + int16_t nk; + int n; + int k; + + if (dct->type != DCT_II || dct->ortho != true) + return -EINVAL; + + if (dct->num_in < 1 || dct->num_out < 1) + return -EINVAL; + + if (dct->num_in > DCT_MATRIX_SIZE_MAX || dct->num_out > DCT_MATRIX_SIZE_MAX) + return -EINVAL; + + dct->matrix = mod_mat_matrix_alloc_16b(mod, dct->num_in, dct->num_out, 15); + if (!dct->matrix) + return -ENOMEM; + + c1 = PI_Q29 / dct->num_in; + arg = Q_SHIFT_RND(TWO_Q29 / dct->num_in, 29, 12); + c2 = sqrt_int16(arg); /* Q4.12 */ + for (n = 0; n < dct->num_in; n++) { + for (k = 0; k < dct->num_out; k++) { + /* Note: Current int16_t nk works up to DCT_MATRIX_SIZE_MAX = 91 */ + nk = (Q_SHIFT_LEFT(n, 0, 1) + HALF_Q1) * Q_SHIFT_LEFT(k, 0, 1); /*Q14.2 */ + arg = Q_MULTSR_32X32((int64_t)c1, nk, 29, 2, 24); /* Q8.24 */ + /* Note: Q8.24 works up to DCT_MATRIX_SIZE_MAX = 42 */ + arg %= TWO_PI_Q24; + cos = cos_fixed_32b(Q_SHIFT_LEFT(arg, 24, 28)); /* Q1.31 */ + dct_val = Q_MULTSR_32X32((int64_t)cos, c2, 31, 12, 15); /* Q1.15 */ + if (k == 0) + dct_val = Q_MULTSR_32X32((int64_t)dct_val, + ONE_OVER_SQRT_TWO, 15, 31, 15); + + mat_set_scalar_16b(dct->matrix, n, k, dct_val); + } + } + + return 0; +} diff --git a/src/math/fft/fft_common.c b/src/math/fft/fft_common.c index a2afd09cf127..182bbb623078 100644 --- a/src/math/fft/fft_common.c +++ b/src/math/fft/fft_common.c @@ -5,6 +5,7 @@ // Author: Amery Song // Keyon Jie +#include #include #include #include @@ -63,6 +64,55 @@ struct fft_plan *fft_plan_new(void *inb, void *outb, uint32_t size, int bits) return plan; } +struct fft_plan *mod_fft_plan_new(struct processing_module *mod, void *inb, + void *outb, uint32_t size, int bits) +{ + struct fft_plan *plan; + int lim = 1; + int len = 0; + int i; + + if (!inb || !outb) + return NULL; + + plan = mod_zalloc(mod, sizeof(struct fft_plan)); + if (!plan) + return NULL; + + switch (bits) { + case 16: + plan->inb16 = inb; + plan->outb16 = outb; + break; + case 32: + plan->inb32 = inb; + plan->outb32 = outb; + break; + default: + return NULL; + } + + /* calculate the exponent of 2 */ + while (lim < size) { + lim <<= 1; + len++; + } + + plan->size = lim; + plan->len = len; + + plan->bit_reverse_idx = mod_zalloc(mod, plan->size * sizeof(uint16_t)); + if (!plan->bit_reverse_idx) + return NULL; + + /* set up the bit reverse index */ + for (i = 1; i < plan->size; ++i) + plan->bit_reverse_idx[i] = (plan->bit_reverse_idx[i >> 1] >> 1) | + ((i & 1) << (len - 1)); + + return plan; +} + void fft_plan_free(struct fft_plan *plan) { if (!plan) @@ -71,3 +121,12 @@ void fft_plan_free(struct fft_plan *plan) rfree(plan->bit_reverse_idx); rfree(plan); } + +void mod_fft_plan_free(struct processing_module *mod, struct fft_plan *plan) +{ + if (!plan) + return; + + mod_free(mod, plan->bit_reverse_idx); + mod_free(mod, plan); +} From 2aba590fc312946679b0e11dd7598a803b463a2b Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 21 Aug 2025 23:16:17 +0300 Subject: [PATCH 02/16] Audio: mfcc: Memory, blob, and fast_get allocs to module API Allocate all memory, blob handlers, and fast_get() buffers through module API mod_alloc() and friends. Signed-off-by: Jyri Sarha --- src/audio/mfcc/mfcc.c | 12 ++++---- src/audio/mfcc/mfcc_setup.c | 39 +++++++++++++------------- src/include/sof/audio/mfcc/mfcc_comp.h | 2 +- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/audio/mfcc/mfcc.c b/src/audio/mfcc/mfcc.c index da1fa9f3414e..868eb13b7c48 100644 --- a/src/audio/mfcc/mfcc.c +++ b/src/audio/mfcc/mfcc.c @@ -88,13 +88,13 @@ static int mfcc_init(struct processing_module *mod) return -EINVAL; } - cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); + cd = mod_zalloc(mod, sizeof(*cd)); if (!cd) return -ENOMEM; /* Handler for configuration data */ md->private = cd; - cd->model_handler = comp_data_blob_handler_new(dev); + cd->model_handler = mod_data_blob_handler_new(mod); if (!cd->model_handler) { comp_err(dev, "comp_data_blob_handler_new() failed."); ret = -ENOMEM; @@ -114,7 +114,7 @@ static int mfcc_init(struct processing_module *mod) comp_data_blob_handler_free(cd->model_handler); err: - rfree(cd); + mod_free(mod, cd); return ret; } @@ -123,9 +123,9 @@ static int mfcc_free(struct processing_module *mod) struct mfcc_comp_data *cd = module_get_private_data(mod); comp_info(mod->dev, "mfcc_free()"); - comp_data_blob_handler_free(cd->model_handler); - mfcc_free_buffers(cd); - rfree(cd); + mod_data_blob_handler_free(mod, cd->model_handler); + mod_free(mod, cd); + mfcc_free_buffers(mod); return 0; } diff --git a/src/audio/mfcc/mfcc_setup.c b/src/audio/mfcc/mfcc_setup.c index 802ea058bb6f..61db6b1f7a39 100644 --- a/src/audio/mfcc/mfcc_setup.c +++ b/src/audio/mfcc/mfcc_setup.c @@ -65,7 +65,7 @@ static int mfcc_get_window(struct mfcc_state *state, enum sof_mfcc_fft_window_ty * coef[i] = 1.0 + 0.5 * lifter * sin(pi * i / lifter), i = 0 to num_ceps-1 */ -static int mfcc_get_cepstral_lifter(struct mfcc_cepstral_lifter *cl) +static int mfcc_get_cepstral_lifter(struct processing_module *mod, struct mfcc_cepstral_lifter *cl) { int32_t inv_cepstral_lifter; int32_t val; @@ -75,7 +75,7 @@ static int mfcc_get_cepstral_lifter(struct mfcc_cepstral_lifter *cl) if (cl->num_ceps > DCT_MATRIX_SIZE_MAX) return -EINVAL; - cl->matrix = mat_matrix_alloc_16b(1, cl->num_ceps, 9); /* Use Q7.9 */ + cl->matrix = mod_mat_matrix_alloc_16b(mod, 1, cl->num_ceps, 9); /* Use Q7.9 */ if (!cl->matrix) return -ENOMEM; @@ -171,8 +171,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i comp_info(dev, "mfcc_setup(), buffer_size = %d, prev_size = %d", state->buffer_size, state->prev_data_size); - state->buffers = rzalloc(SOF_MEM_FLAG_USER, - state->sample_buffers_size); + state->buffers = mod_zalloc(mod, state->sample_buffers_size); if (!state->buffers) { comp_err(dev, "Failed buffer allocate"); ret = -ENOMEM; @@ -189,14 +188,14 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i #else fft->fft_buffer_size = fft->fft_padded_size * sizeof(struct icomplex32); #endif - fft->fft_buf = rzalloc(SOF_MEM_FLAG_USER, fft->fft_buffer_size); + fft->fft_buf = mod_zalloc(mod, fft->fft_buffer_size); if (!fft->fft_buf) { comp_err(dev, "Failed FFT buffer allocate"); ret = -ENOMEM; goto free_buffers; } - fft->fft_out = rzalloc(SOF_MEM_FLAG_USER, fft->fft_buffer_size); + fft->fft_out = mod_zalloc(mod, fft->fft_buffer_size); if (!fft->fft_out) { comp_err(dev, "Failed FFT output allocate"); ret = -ENOMEM; @@ -206,8 +205,8 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i fft->fft_fill_start_idx = 0; /* From config pad_type */ /* Setup FFT */ - fft->fft_plan = fft_plan_new(fft->fft_buf, fft->fft_out, fft->fft_padded_size, - MFCC_FFT_BITS); + fft->fft_plan = mod_fft_plan_new(mod, fft->fft_buf, fft->fft_out, fft->fft_padded_size, + MFCC_FFT_BITS); if (!fft->fft_plan) { comp_err(dev, "Failed FFT init"); ret = -EINVAL; @@ -242,7 +241,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i fb->scratch_data2 = (int16_t *)fft->fft_out; fb->scratch_length1 = fft->fft_buffer_size / sizeof(int16_t); fb->scratch_length2 = fft->fft_buffer_size / sizeof(int16_t); - ret = psy_get_mel_filterbank(fb); + ret = mod_psy_get_mel_filterbank(mod, fb); if (ret < 0) { comp_err(dev, "Failed Mel filterbank"); goto free_fft_out; @@ -253,7 +252,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i dct->num_out = config->num_ceps; dct->type = (enum dct_type)config->dct; dct->ortho = true; - ret = dct_initialize_16(dct); + ret = mod_dct_initialize_16(mod, dct); if (ret < 0) { comp_err(dev, "Failed DCT init"); goto free_melfb_data; @@ -261,7 +260,7 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i state->lifter.num_ceps = config->num_ceps; state->lifter.cepstral_lifter = config->cepstral_lifter; /* Q7.9 max 64.0*/ - ret = mfcc_get_cepstral_lifter(&state->lifter); + ret = mfcc_get_cepstral_lifter(mod, &state->lifter); if (ret < 0) { comp_err(dev, "Failed cepstral lifter"); goto free_dct_matrix; @@ -317,13 +316,15 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i return ret; } -void mfcc_free_buffers(struct mfcc_comp_data *cd) +void mfcc_free_buffers(struct processing_module *mod) { - fft_plan_free(cd->state.fft.fft_plan); - rfree(cd->state.fft.fft_buf); - rfree(cd->state.fft.fft_out); - rfree(cd->state.buffers); - rfree(cd->state.melfb.data); - rfree(cd->state.dct.matrix); - rfree(cd->state.lifter.matrix); + struct mfcc_comp_data *cd = module_get_private_data(mod); + + mod_fft_plan_free(mod, cd->state.fft.fft_plan); + mod_free(mod, cd->state.fft.fft_buf); + mod_free(mod, cd->state.fft.fft_out); + mod_free(mod, cd->state.buffers); + mod_free(mod, cd->state.melfb.data); + mod_free(mod, cd->state.dct.matrix); + mod_free(mod, cd->state.lifter.matrix); } diff --git a/src/include/sof/audio/mfcc/mfcc_comp.h b/src/include/sof/audio/mfcc/mfcc_comp.h index bbc01030e157..ec5cc90eb40c 100644 --- a/src/include/sof/audio/mfcc/mfcc_comp.h +++ b/src/include/sof/audio/mfcc/mfcc_comp.h @@ -154,7 +154,7 @@ static inline int16_t *mfcc_buffer_wrap(struct mfcc_buffer *buffer, int16_t *ptr int mfcc_setup(struct processing_module *mod, int max_frames, int rate, int channels); -void mfcc_free_buffers(struct mfcc_comp_data *cd); +void mfcc_free_buffers(struct processing_module *mod); void mfcc_s16_default(struct processing_module *mod, struct input_stream_buffer *bsource, struct output_stream_buffer *bsink, int frames); From eb7c7c628806101c48a096a6611398cc0607758a Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 22 Aug 2025 12:19:03 +0300 Subject: [PATCH 03/16] cmocka: Add mocks for mod_balloc_align() and mod_alloc_align() Add mocks for mod_balloc_align() and mod_alloc_align(). These dummy versions do not keep track of the allocated memory or provide real control over alignment. They just forward the calls to regular malloc() and free(). Signed-off-by: Jyri Sarha --- test/cmocka/src/common_mocks.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/cmocka/src/common_mocks.c b/test/cmocka/src/common_mocks.c index 1450af20ddfd..fca1d6300656 100644 --- a/test/cmocka/src/common_mocks.c +++ b/test/cmocka/src/common_mocks.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -88,6 +89,39 @@ void WEAK rfree(void *ptr) free(ptr); } +void WEAK *mod_balloc_align(struct processing_module *mod, size_t size, size_t alignment) +{ + void *ret; + (void)mod; + (void)alignment; + + ret = malloc(size); + + assert(ret); + + return ret; +} + +void WEAK *mod_alloc_align(struct processing_module *mod, size_t size, size_t alignment) +{ + void *ret; + (void)mod; + (void)alignment; + + ret = malloc(size); + + assert(ret); + + return ret; +} + +int WEAK mod_free(struct processing_module *mod, const void *ptr) +{ + (void)mod; + free((void *)ptr); + return 0; +} + int WEAK memcpy_s(void *dest, size_t dest_size, const void *src, size_t count) { From 30ffeb8100127080c953f3f500ef505772f3eb1c Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Sat, 23 Aug 2025 12:04:18 +0300 Subject: [PATCH 04/16] cmocka: math: Test using module memory API math function Convert auditory, dct, fft, and matrix math tests to use module heap API functions instead of the old version using rmalloc() and friends directly. Signed-off-by: Jyri Sarha --- test/cmocka/src/math/auditory/auditory.c | 7 +++++-- test/cmocka/src/math/dct/dct.c | 4 +++- test/cmocka/src/math/fft/fft.c | 23 +++++++++++++---------- test/cmocka/src/math/matrix/matrix.c | 9 ++++++--- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/test/cmocka/src/math/auditory/auditory.c b/test/cmocka/src/math/auditory/auditory.c index 1e3e903fb5fb..65be2e0dcfce 100644 --- a/test/cmocka/src/math/auditory/auditory.c +++ b/test/cmocka/src/math/auditory/auditory.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include "ref_hz_to_mel.h" @@ -38,6 +39,8 @@ #undef DEBUGFILES /* Change this to #define to get output data files for debugging */ +struct processing_module dummy; + static void filterbank_16_test(const int16_t *fft_real, const int16_t *fft_imag, const int16_t *ref_mel_log, int num_fft_bins, int num_mel_bins, int norm_slaney, @@ -87,7 +90,7 @@ static void filterbank_16_test(const int16_t *fft_real, const int16_t *fft_imag, fb.scratch_data2 = (int16_t *)fft_out; fb.scratch_length1 = fft_size / sizeof(int16_t); fb.scratch_length2 = fft_size / sizeof(int16_t); - ret = psy_get_mel_filterbank(&fb); + ret = mod_psy_get_mel_filterbank(&dummy, &fb); if (ret < 0) { fprintf(stderr, "Failed Mel filterbank\n"); goto err_get_filterbank; @@ -190,7 +193,7 @@ static void filterbank_32_test(const int32_t *fft_real, const int32_t *fft_imag, fb.scratch_data2 = (int16_t *)fft_out; fb.scratch_length1 = fft_size / sizeof(int16_t); fb.scratch_length2 = fft_size / sizeof(int16_t); - ret = psy_get_mel_filterbank(&fb); + ret = mod_psy_get_mel_filterbank(&dummy, &fb); if (ret < 0) { fprintf(stderr, "Failed Mel filterbank\n"); goto err_get_filterbank; diff --git a/test/cmocka/src/math/dct/dct.c b/test/cmocka/src/math/dct/dct.c index 4cfe38ef803b..fd7b2f64d0b5 100644 --- a/test/cmocka/src/math/dct/dct.c +++ b/test/cmocka/src/math/dct/dct.c @@ -22,6 +22,8 @@ #define MATRIX_MULT_16_MAX_ERROR_ABS 2.5 #define MATRIX_MULT_16_MAX_ERROR_RMS 1.1 +struct processing_module dummy; + static void dct_matrix_16_test(const int16_t *ref, int num_in, int num_out, enum dct_type type, bool ortho) { @@ -41,7 +43,7 @@ static void dct_matrix_16_test(const int16_t *ref, int num_in, int num_out, dct.num_out = num_out; dct.type = type; dct.ortho = ortho; - ret = dct_initialize_16(&dct); + ret = mod_dct_initialize_16(&dummy, &dct); if (ret) { fprintf(stderr, "Failed to initialize DCT.\n"); exit(EXIT_FAILURE); diff --git a/test/cmocka/src/math/fft/fft.c b/test/cmocka/src/math/fft/fft.c index 34f59cc656fb..06cd92a1c427 100644 --- a/test/cmocka/src/math/fft/fft.c +++ b/test/cmocka/src/math/fft/fft.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -39,6 +40,8 @@ #define MIN_SNR_512 125.0 #define MIN_SNR_1024 119.0 +struct processing_module dummy; + /** * \brief Doing Fast Fourier Transform (FFT) for mono real input buffers. * \param[in] src - pointer to input buffer. @@ -68,7 +71,7 @@ static void fft_real(struct comp_buffer *src, struct comp_buffer *dst, uint32_t if (!outb) goto err_outb; - plan = fft_plan_new(inb, outb, size, 32); + plan = mod_fft_plan_new(&dummy, inb, outb, size, 32); if (!plan) goto err_plan; @@ -85,7 +88,7 @@ static void fft_real(struct comp_buffer *src, struct comp_buffer *dst, uint32_t *((int32_t *)dst->stream.addr + 2 * i + 1) = outb[i].imag; } - fft_plan_free(plan); + mod_fft_plan_free(&dummy, plan); err_plan: rfree(outb); @@ -123,7 +126,7 @@ static void ifft_complex(struct comp_buffer *src, struct comp_buffer *dst, uint3 if (!outb) goto err_outb; - plan = fft_plan_new(inb, outb, size, 32); + plan = mod_fft_plan_new(&dummy, inb, outb, size, 32); if (!plan) goto err_plan; @@ -140,7 +143,7 @@ static void ifft_complex(struct comp_buffer *src, struct comp_buffer *dst, uint3 *((int32_t *)dst->stream.addr + 2 * i + 1) = outb[i].imag; } - fft_plan_free(plan); + mod_fft_plan_free(&dummy, plan); err_plan: rfree(outb); @@ -181,7 +184,7 @@ static void fft_real_2(struct comp_buffer *src, struct comp_buffer *dst1, if (!outb) goto err_outb; - plan = fft_plan_new(inb, outb, size, 32); + plan = mod_fft_plan_new(&dummy, inb, outb, size, 32); if (!plan) goto err_plan; @@ -210,7 +213,7 @@ static void fft_real_2(struct comp_buffer *src, struct comp_buffer *dst1, (outb[size - i].real - outb[i].real) / 2; } - fft_plan_free(plan); + mod_fft_plan_free(&dummy, plan); err_plan: rfree(outb); @@ -498,7 +501,7 @@ static void fft_real_16(struct comp_buffer *src, struct comp_buffer *dst, uint32 if (!outb) goto err_outb; - plan = fft_plan_new(inb, outb, size, 16); + plan = mod_fft_plan_new(&dummy, inb, outb, size, 16); if (!plan) goto err_plan; @@ -515,7 +518,7 @@ static void fft_real_16(struct comp_buffer *src, struct comp_buffer *dst, uint32 *((int16_t *)dst->stream.addr + 2 * i + 1) = outb[i].imag; } - fft_plan_free(plan); + mod_fft_plan_free(&dummy, plan); err_plan: rfree(outb); @@ -553,7 +556,7 @@ static void ifft_complex_16(struct comp_buffer *src, struct comp_buffer *dst, ui if (!outb) goto err_outb; - plan = fft_plan_new(inb, outb, size, 16); + plan = mod_fft_plan_new(&dummy, inb, outb, size, 16); if (!plan) goto err_plan; @@ -570,7 +573,7 @@ static void ifft_complex_16(struct comp_buffer *src, struct comp_buffer *dst, ui *((int16_t *)dst->stream.addr + 2 * i + 1) = outb[i].imag; } - fft_plan_free(plan); + mod_fft_plan_free(&dummy, plan); err_plan: rfree(outb); diff --git a/test/cmocka/src/math/matrix/matrix.c b/test/cmocka/src/math/matrix/matrix.c index 66200bc3e632..8806344dce09 100644 --- a/test/cmocka/src/math/matrix/matrix.c +++ b/test/cmocka/src/math/matrix/matrix.c @@ -4,6 +4,7 @@ // // Author: Seppo Ingalsuo +#include #include #include #include @@ -23,6 +24,8 @@ #define MATRIX_MULT_16_MAX_ERROR_ABS 1.5 #define MATRIX_MULT_16_MAX_ERROR_RMS 0.5 +struct processing_module dummy; + static void matrix_mult_16_test(const int16_t *a_ref, const int16_t *b_ref, const int16_t *c_ref, int elementwise, int a_rows, int a_columns, int b_rows, int b_columns, int c_rows, int c_columns, @@ -38,17 +41,17 @@ static void matrix_mult_16_test(const int16_t *a_ref, const int16_t *b_ref, cons int16_t x; int i, j, k; - a_matrix = mat_matrix_alloc_16b(a_rows, a_columns, a_frac); + a_matrix = mod_mat_matrix_alloc_16b(&dummy, a_rows, a_columns, a_frac); if (!a_matrix) exit(EXIT_FAILURE); - b_matrix = mat_matrix_alloc_16b(b_rows, b_columns, b_frac); + b_matrix = mod_mat_matrix_alloc_16b(&dummy, b_rows, b_columns, b_frac); if (!b_matrix) { free(a_matrix); exit(EXIT_FAILURE); } - c_matrix = mat_matrix_alloc_16b(c_rows, c_columns, c_frac); + c_matrix = mod_mat_matrix_alloc_16b(&dummy, c_rows, c_columns, c_frac); if (!c_matrix) { free(a_matrix); free(b_matrix); From b567aa47a8f88524402ed6b3244b1587fcdc5a3f Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Sun, 24 Aug 2025 21:10:07 +0300 Subject: [PATCH 05/16] Math: Remove directly heap using math functions Both unit tests and modules should now use the module API heap allocation functions, so we can now remove the directly heap using versions. Signed-off-by: Jyri Sarha --- src/include/sof/math/auditory.h | 1 - src/include/sof/math/dct.h | 1 - src/math/auditory/auditory.c | 126 -------------------------------- src/math/dct.c | 47 ------------ 4 files changed, 175 deletions(-) diff --git a/src/include/sof/math/auditory.h b/src/include/sof/math/auditory.h index 0e082335f764..997c1a6c4a58 100644 --- a/src/include/sof/math/auditory.h +++ b/src/include/sof/math/auditory.h @@ -76,7 +76,6 @@ int16_t psy_mel_to_hz(int16_t mel); * filter coefficients. * \return Zero when success, otherwise error code. */ -int psy_get_mel_filterbank(struct psy_mel_filterbank *mel_fb); struct processing_module; int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *mel_fb); diff --git a/src/include/sof/math/dct.h b/src/include/sof/math/dct.h index c1c5caa808a6..21cdd8ba817f 100644 --- a/src/include/sof/math/dct.h +++ b/src/include/sof/math/dct.h @@ -29,7 +29,6 @@ struct dct_plan_16 { bool ortho; }; -int dct_initialize_16(struct dct_plan_16 *dct); int mod_dct_initialize_16(struct processing_module *mod, struct dct_plan_16 *dct); #endif /* __SOF_MATH_DCT_H__ */ diff --git a/src/math/auditory/auditory.c b/src/math/auditory/auditory.c index a10d13bbfc99..56cd6f99a24e 100644 --- a/src/math/auditory/auditory.c +++ b/src/math/auditory/auditory.c @@ -86,132 +86,6 @@ int16_t psy_mel_to_hz(int16_t mel) return hz; } -int psy_get_mel_filterbank(struct psy_mel_filterbank *fb) -{ - int32_t up_slope; - int32_t down_slope; - int32_t slope; - int32_t scale = ONE_Q16; - int32_t scale_inv = ONE_Q16; - int16_t *mel; - int16_t mel_start; - int16_t mel_end; - int16_t mel_step; - int16_t left_mel; - int16_t center_mel; - int16_t right_mel; - int16_t delta_cl; - int16_t delta_rc; - int16_t left_hz; - int16_t right_hz; - int16_t f; - int segment; - int i, j, idx; - int base_idx = 0; - int start_bin = 0; - int end_bin = 0; - - if (!fb) - return -ENOMEM; - - if (!fb->scratch_data1 || !fb->scratch_data2) - return -ENOMEM; - - /* Log power can be log, or log10 or dB, get multiply coef to convert - * log to desired format. - */ - switch (fb->mel_log_scale) { - case MEL_LOG: - fb->log_mult = ONE_OVER_LOG2E_Q29; - break; - case MEL_LOG10: - fb->log_mult = ONE_OVER_LOG2TEN_Q29; - break; - case MEL_DB: - fb->log_mult = TEN_OVER_LOG2TEN_Q29; - break; - default: - return -EINVAL; - } - - /* Use scratch area to hold vector of Mel values for each FFT frequency */ - if (fb->scratch_length1 < fb->half_fft_bins) - return -ENOMEM; - - fb->scale_log2 = 0; - - mel = fb->scratch_data1; - for (i = 0; i < fb->half_fft_bins; i++) { - f = fb->samplerate * i / fb->fft_bins; - mel[i] = psy_hz_to_mel(f); - } - - mel_start = psy_hz_to_mel(fb->start_freq); - mel_end = psy_hz_to_mel(fb->end_freq); - mel_step = (mel_end - mel_start) / (fb->mel_bins + 1); - for (i = 0; i < fb->mel_bins; i++) { - left_mel = mel_start + i * mel_step; - center_mel = mel_start + (i + 1) * mel_step; - right_mel = mel_start + (i + 2) * mel_step; - delta_cl = center_mel - left_mel; - delta_rc = right_mel - center_mel; - segment = 0; - idx = base_idx + 3; /* start of filter weight values */ - if (fb->slaney_normalize) { - left_hz = psy_mel_to_hz(left_mel); - right_hz = psy_mel_to_hz(right_mel); - scale = Q_SHIFT_RND(TWO_Q29 / (right_hz - left_hz), 29, 16); /* Q16.16*/ - if (i == 0) { - scale_inv = Q_SHIFT_LEFT(ONE_Q30 / scale, 14, 16); - fb->scale_log2 = base2_logarithm((uint32_t)scale) - LOG2_2P16; - } - - scale = Q_MULTSR_32X32((int64_t)scale, scale_inv, 16, 16, 16); - } - for (j = 0; j < fb->half_fft_bins; j++) { - up_slope = (((int32_t)mel[j] - left_mel) << 15) / delta_cl; /* Q17.15 */ - down_slope = (((int32_t)right_mel - mel[j]) << 15) / delta_rc; /* Q17.15 */ - slope = MIN(up_slope, down_slope); - slope = Q_MULTSR_32X32((int64_t)slope, scale, 15, 16, 15); - if (segment == 1 && slope <= 0) { - end_bin = j - 1; - break; - } - - if (segment == 0 && slope > 0) { - start_bin = j; - segment = 1; - } - - if (segment == 1) { - if (idx >= fb->scratch_length2) - return -EINVAL; - - fb->scratch_data2[idx++] = sat_int16(slope); - } - } - - if (idx + 2 >= fb->scratch_length2) - return -EINVAL; - - fb->scratch_data2[base_idx] = idx; /* index to next */ - fb->scratch_data2[base_idx + 1] = start_bin; - fb->scratch_data2[base_idx + 2] = end_bin - start_bin + 1; /* length */ - base_idx = idx; - } - - fb->data_length = &fb->scratch_data2[base_idx] - &fb->scratch_data2[0]; - fb->data = rzalloc(SOF_MEM_FLAG_USER, - sizeof(int16_t) * fb->data_length); - if (!fb->data) - return -ENOMEM; - - /* Copy the exact triangles data size to allocated buffer */ - memcpy_s(fb->data, sizeof(int16_t) * fb->data_length, - fb->scratch_data2, sizeof(int16_t) * fb->data_length); - return 0; -} - int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *fb) { int32_t up_slope; diff --git a/src/math/dct.c b/src/math/dct.c index db2d96525eea..192846e6a082 100644 --- a/src/math/dct.c +++ b/src/math/dct.c @@ -32,53 +32,6 @@ * multiply with the returned matrix. * \param[in,out] dct In input provide DCT type and size, in output the DCT matrix */ -int dct_initialize_16(struct dct_plan_16 *dct) -{ - int16_t dct_val; - int32_t arg; - int32_t cos; - int32_t c1; - int16_t c2; - int16_t nk; - int n; - int k; - - if (dct->type != DCT_II || dct->ortho != true) - return -EINVAL; - - if (dct->num_in < 1 || dct->num_out < 1) - return -EINVAL; - - if (dct->num_in > DCT_MATRIX_SIZE_MAX || dct->num_out > DCT_MATRIX_SIZE_MAX) - return -EINVAL; - - dct->matrix = mat_matrix_alloc_16b(dct->num_in, dct->num_out, 15); - if (!dct->matrix) - return -ENOMEM; - - c1 = PI_Q29 / dct->num_in; - arg = Q_SHIFT_RND(TWO_Q29 / dct->num_in, 29, 12); - c2 = sqrt_int16(arg); /* Q4.12 */ - for (n = 0; n < dct->num_in; n++) { - for (k = 0; k < dct->num_out; k++) { - /* Note: Current int16_t nk works up to DCT_MATRIX_SIZE_MAX = 91 */ - nk = (Q_SHIFT_LEFT(n, 0, 1) + HALF_Q1) * Q_SHIFT_LEFT(k, 0, 1); /*Q14.2 */ - arg = Q_MULTSR_32X32((int64_t)c1, nk, 29, 2, 24); /* Q8.24 */ - /* Note: Q8.24 works up to DCT_MATRIX_SIZE_MAX = 42 */ - arg %= TWO_PI_Q24; - cos = cos_fixed_32b(Q_SHIFT_LEFT(arg, 24, 28)); /* Q1.31 */ - dct_val = Q_MULTSR_32X32((int64_t)cos, c2, 31, 12, 15); /* Q1.15 */ - if (k == 0) - dct_val = Q_MULTSR_32X32((int64_t)dct_val, - ONE_OVER_SQRT_TWO, 15, 31, 15); - - mat_set_scalar_16b(dct->matrix, n, k, dct_val); - } - } - - return 0; -} - int mod_dct_initialize_16(struct processing_module *mod, struct dct_plan_16 *dct) { int16_t dct_val; From eb7d6f043ab765ade0996a0e2b07494e0e9975c9 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 16:30:40 +0300 Subject: [PATCH 06/16] Math: auditory: Add mod_psy_free_mel_filterbank() Add mod_psy_free_mel_filterbank() for freeing the allocated memory. Signed-off-by: Jyri Sarha --- src/include/sof/math/auditory.h | 1 + src/math/auditory/auditory.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/include/sof/math/auditory.h b/src/include/sof/math/auditory.h index 997c1a6c4a58..b09017786e36 100644 --- a/src/include/sof/math/auditory.h +++ b/src/include/sof/math/auditory.h @@ -78,6 +78,7 @@ int16_t psy_mel_to_hz(int16_t mel); */ struct processing_module; int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *mel_fb); +int mod_psy_free_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *mel_fb); /** * \brief Convert linear complex spectra from FFT into Mel band energies in desired diff --git a/src/math/auditory/auditory.c b/src/math/auditory/auditory.c index 56cd6f99a24e..57641c46aa5a 100644 --- a/src/math/auditory/auditory.c +++ b/src/math/auditory/auditory.c @@ -210,3 +210,8 @@ int mod_psy_get_mel_filterbank(struct processing_module *mod, struct psy_mel_fil fb->scratch_data2, sizeof(int16_t) * fb->data_length); return 0; } + +int mod_psy_free_mel_filterbank(struct processing_module *mod, struct psy_mel_filterbank *mel_fb) +{ + return mod_free(mod, mel_fb->data); +} From b17aaab428c0314a6e9570174e7c0d2296489370 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 16:32:55 +0300 Subject: [PATCH 07/16] cmocka: math: auditiory: Fix memory leaks Fix memory leaks from auditory cmocka test. Signed-off-by: Jyri Sarha --- test/cmocka/src/math/auditory/auditory.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/cmocka/src/math/auditory/auditory.c b/test/cmocka/src/math/auditory/auditory.c index 65be2e0dcfce..2f8df53e8c6a 100644 --- a/test/cmocka/src/math/auditory/auditory.c +++ b/test/cmocka/src/math/auditory/auditory.c @@ -131,6 +131,10 @@ static void filterbank_16_test(const int16_t *fft_real, const int16_t *fft_imag, assert_true(error_rms < MEL_FB16_MAX_ERROR_RMS); assert_true(delta_max < MEL_FB16_MAX_ERROR_ABS); + free(mel_log); + free(fft_buf); + free(fft_out); + mod_psy_free_mel_filterbank(&dummy, &fb); return; err_get_filterbank: @@ -234,6 +238,10 @@ static void filterbank_32_test(const int32_t *fft_real, const int32_t *fft_imag, assert_true(error_rms < MEL_FB32_MAX_ERROR_RMS); assert_true(delta_max < MEL_FB32_MAX_ERROR_ABS); + free(mel_log); + free(fft_buf); + free(fft_out); + mod_psy_free_mel_filterbank(&dummy, &fb); return; err_get_filterbank: From 562f7e6d2ad5daef29e1f78eecae9ed690b89c09 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 17:54:08 +0300 Subject: [PATCH 08/16] cmocka: math: fft: Fix memory leaks Fix all memory leaks found from fft test when tests were run under Valgrind. Signed-off-by: Jyri Sarha --- test/cmocka/src/math/fft/fft.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/cmocka/src/math/fft/fft.c b/test/cmocka/src/math/fft/fft.c index 06cd92a1c427..1415b12d756c 100644 --- a/test/cmocka/src/math/fft/fft.c +++ b/test/cmocka/src/math/fft/fft.c @@ -303,6 +303,9 @@ static void test_math_fft_256(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_256, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_512(void **state) @@ -345,6 +348,9 @@ static void test_math_fft_512(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_512, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_1024(void **state) @@ -387,6 +393,9 @@ static void test_math_fft_1024(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_1024, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_1024_ifft(void **state) @@ -428,6 +437,10 @@ static void test_math_fft_1024_ifft(void **state) db = 10 * log10((float)signal / noise); printf("%s: SNR: %6.2f dB\n", __func__, db); assert_int_equal(db < FFT_DB_TH, 0); + + buffer_free(source); + buffer_free(intm); + buffer_free(sink); } static void test_math_fft_512_2ch(void **state) @@ -470,6 +483,10 @@ static void test_math_fft_512_2ch(void **state) /* the peak should be in range i +/-1 */ assert_in_range(r, i - 1, i + 1); + + buffer_free(source); + buffer_free(sink1); + buffer_free(sink2); } /** @@ -663,6 +680,9 @@ static void test_math_fft_256_16(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_256_16, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_512_16(void **state) @@ -705,6 +725,9 @@ static void test_math_fft_512_16(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_512_16, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_1024_16(void **state) @@ -747,6 +770,9 @@ static void test_math_fft_1024_16(void **state) snr = 10 * log10(signal / noise); printf("%s: SNR %5.2f dB\n", __func__, snr); assert_int_equal(snr < MIN_SNR_1024_16, 0); + + buffer_free(source); + buffer_free(sink); } static void test_math_fft_1024_ifft_16(void **state) @@ -787,6 +813,10 @@ static void test_math_fft_1024_ifft_16(void **state) db = 10 * log10((float)signal / noise); printf("%s: SNR: %6.2f dB\n", __func__, db); assert_int_equal(db < FFT_DB_TH_16, 0); + + buffer_free(source); + buffer_free(intm); + buffer_free(sink); } int main(void) From ab08569c561c39f8a737ce2a67f725e546956df1 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 18:19:10 +0300 Subject: [PATCH 09/16] cmocka: math: matrix: Fix memory leaks Fix all memory leaks found from matrix test when tests were run under Valgrind. Signed-off-by: Jyri Sarha --- test/cmocka/src/math/matrix/matrix.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/cmocka/src/math/matrix/matrix.c b/test/cmocka/src/math/matrix/matrix.c index 8806344dce09..63632ba58c4b 100644 --- a/test/cmocka/src/math/matrix/matrix.c +++ b/test/cmocka/src/math/matrix/matrix.c @@ -47,14 +47,14 @@ static void matrix_mult_16_test(const int16_t *a_ref, const int16_t *b_ref, cons b_matrix = mod_mat_matrix_alloc_16b(&dummy, b_rows, b_columns, b_frac); if (!b_matrix) { - free(a_matrix); + mod_free(&dummy, a_matrix); exit(EXIT_FAILURE); } c_matrix = mod_mat_matrix_alloc_16b(&dummy, c_rows, c_columns, c_frac); if (!c_matrix) { - free(a_matrix); - free(b_matrix); + mod_free(&dummy, a_matrix); + mod_free(&dummy, b_matrix); exit(EXIT_FAILURE); } @@ -86,6 +86,10 @@ static void matrix_mult_16_test(const int16_t *a_ref, const int16_t *b_ref, cons assert_true(error_rms < MATRIX_MULT_16_MAX_ERROR_RMS); assert_true(delta_max < MATRIX_MULT_16_MAX_ERROR_ABS); + + mod_free(&dummy, a_matrix); + mod_free(&dummy, b_matrix); + mod_free(&dummy, c_matrix); } static void test_matrix_mult_16_test1(void **state) From 098a097179b3ddbf0ec351d0cbe9fb51e201e3ba Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 18:29:04 +0300 Subject: [PATCH 10/16] Math: DCT: Add mod_dct_free_16() Add mod_dct_free_16() to free memory allocated by mod_dct_initialize_16(). Signed-off-by: Jyri Sarha --- src/include/sof/math/dct.h | 2 ++ src/math/dct.c | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/include/sof/math/dct.h b/src/include/sof/math/dct.h index 21cdd8ba817f..7c754f448c21 100644 --- a/src/include/sof/math/dct.h +++ b/src/include/sof/math/dct.h @@ -31,4 +31,6 @@ struct dct_plan_16 { int mod_dct_initialize_16(struct processing_module *mod, struct dct_plan_16 *dct); +int mod_dct_free_16(struct processing_module *mod, struct dct_plan_16 *dct); + #endif /* __SOF_MATH_DCT_H__ */ diff --git a/src/math/dct.c b/src/math/dct.c index 192846e6a082..de27cab4471e 100644 --- a/src/math/dct.c +++ b/src/math/dct.c @@ -78,3 +78,8 @@ int mod_dct_initialize_16(struct processing_module *mod, struct dct_plan_16 *dct return 0; } + +int mod_dct_free_16(struct processing_module *mod, struct dct_plan_16 *dct) +{ + return mod_free(mod, dct->matrix); +} From b85e93940559e8ceaa0aa235fbf01145266a73d4 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 18:30:48 +0300 Subject: [PATCH 11/16] cmocka: math: dct: Fix memory leaks Fix memory leaks found by running the tests with Valgrind. Signed-off-by: Jyri Sarha --- test/cmocka/src/math/dct/dct.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/cmocka/src/math/dct/dct.c b/test/cmocka/src/math/dct/dct.c index fd7b2f64d0b5..ea35d170e66e 100644 --- a/test/cmocka/src/math/dct/dct.c +++ b/test/cmocka/src/math/dct/dct.c @@ -71,6 +71,8 @@ static void dct_matrix_16_test(const int16_t *ref, int num_in, int num_out, assert_true(error_rms < MATRIX_MULT_16_MAX_ERROR_RMS); assert_true(delta_max < MATRIX_MULT_16_MAX_ERROR_ABS); + + mod_dct_free_16(&dummy, &dct); } static void test_dct_matrix_16_test1(void **state) From 1a4c8fa057f05bcd2d04c5737813f4bf047eb0d4 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 19:01:32 +0300 Subject: [PATCH 12/16] cmocka: module_adapter_test: Fix memory freeing error Fix memory freeing error from module_adapter_test_free(). Use free_test_source() for sources, not free_test_sink(). Signed-off-by: Jyri Sarha --- test/cmocka/src/audio/module_adapter_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cmocka/src/audio/module_adapter_test.c b/test/cmocka/src/audio/module_adapter_test.c index 29140e4581e9..81ec6cadc1b7 100644 --- a/test/cmocka/src/audio/module_adapter_test.c +++ b/test/cmocka/src/audio/module_adapter_test.c @@ -77,7 +77,7 @@ void module_adapter_test_free(struct processing_module_test_data *test_data) } for (i = 0; i < test_data->num_sources; i++) { - free_test_sink(test_data->sources[i]); + free_test_source(test_data->sources[i]); test_free(test_data->input_buffers[i]); } From 2556bc81ae9ce37d467e2e33deadbcefa766b752 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 19:03:51 +0300 Subject: [PATCH 13/16] cmocka: volume: Fix memory leaks Fix all memory leaks found from volume test when tests were run under Valgrind. Signed-off-by: Jyri Sarha --- test/cmocka/src/audio/volume/volume_process.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/cmocka/src/audio/volume/volume_process.c b/test/cmocka/src/audio/volume/volume_process.c index 10afdd1276a3..389a4e75a503 100644 --- a/test/cmocka/src/audio/volume/volume_process.c +++ b/test/cmocka/src/audio/volume/volume_process.c @@ -315,7 +315,7 @@ int main(void) struct vol_test_parameters *parameters; uint32_t volume_values[] = {VOL_MAX, VOL_ZERO_DB, VOL_MINUS_80DB}; int num_tests = ARRAY_SIZE(test_parameters) * ARRAY_SIZE(volume_values); - int i, j; + int i, j, ret; parameters = test_calloc(num_tests, sizeof(struct vol_test_parameters)); for (i = 0; i < ARRAY_SIZE(test_parameters); i++) { @@ -338,5 +338,9 @@ int main(void) cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); + ret = cmocka_run_group_tests(tests, NULL, NULL); + + test_free(parameters); + + return ret; } From 731d3625f225c77507c1e0e7dce594935584cab4 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 19:28:00 +0300 Subject: [PATCH 14/16] cmocka: mux_copy: Fix memory leaks Fix all memory leaks found from mux_copy test when tests were run under Valgrind. Signed-off-by: Jyri Sarha --- test/cmocka/src/audio/mux/mux_copy.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/cmocka/src/audio/mux/mux_copy.c b/test/cmocka/src/audio/mux/mux_copy.c index 97b7be7b9076..66b21b0df27c 100644 --- a/test/cmocka/src/audio/mux/mux_copy.c +++ b/test/cmocka/src/audio/mux/mux_copy.c @@ -211,6 +211,9 @@ static int teardown_test_case(void **state) struct test_data *td = *((struct test_data **)state); int i; + rfree(td->mod->input_buffers); + rfree(td->mod->output_buffers); + for (i = 0; i < MUX_MAX_STREAMS; ++i) free_test_source(td->sources[i]); @@ -357,8 +360,10 @@ int main(void) cmocka_set_message_output(CM_OUTPUT_TAP); ret = cmocka_run_group_tests(tests, setup_group, NULL); - for (ti = 0; ti < ARRAY_SIZE(valid_formats) * ARRAY_SIZE(masks); ti++) + for (ti = 0; ti < ARRAY_SIZE(valid_formats) * ARRAY_SIZE(masks); ti++) { free(tests[ti].initial_state); + free((void *)tests[ti].name); + } return ret; } From 9090979dff6aa357a438fc218174a928f88dd48d Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 19:36:04 +0300 Subject: [PATCH 15/16] cmocka: demux_copy: Fix memory leaks Fix all memory leaks found from demux_copy test when tests were run under Valgrind. Signed-off-by: Jyri Sarha --- test/cmocka/src/audio/mux/demux_copy.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/cmocka/src/audio/mux/demux_copy.c b/test/cmocka/src/audio/mux/demux_copy.c index 4934ab6dbdaa..8e331446bbf4 100644 --- a/test/cmocka/src/audio/mux/demux_copy.c +++ b/test/cmocka/src/audio/mux/demux_copy.c @@ -188,6 +188,9 @@ static int teardown_test_case(void **state) struct test_data *td = *((struct test_data **)state); int i; + rfree(td->mod->input_buffers); + rfree(td->mod->output_buffers); + free_test_source(td->source); for (i = 0; i < MUX_MAX_STREAMS; ++i) @@ -339,8 +342,10 @@ int main(void) cmocka_set_message_output(CM_OUTPUT_TAP); ret = cmocka_run_group_tests(tests, setup_group, NULL); - for (ti = 0; ti < ARRAY_SIZE(valid_formats) * ARRAY_SIZE(masks); ti++) + for (ti = 0; ti < ARRAY_SIZE(valid_formats) * ARRAY_SIZE(masks); ti++) { free(tests[ti].initial_state); + free((void *)tests[ti].name); + } return ret; } From fd4f8070bb301f322812f9c118a7668101ace861 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Tue, 26 Aug 2025 22:12:53 +0300 Subject: [PATCH 16/16] cmocka: pipeline: Fix memory leaks Fix all memory leaks found from all pipeline tests when tests were run under Valgrind. Signed-off-by: Jyri Sarha --- .../src/audio/pipeline/pipeline_connect_upstream.c | 1 + .../src/audio/pipeline/pipeline_connection_mocks.c | 13 ++++++++++--- .../src/audio/pipeline/pipeline_connection_mocks.h | 1 + test/cmocka/src/audio/pipeline/pipeline_free.c | 1 + test/cmocka/src/audio/pipeline/pipeline_new.c | 4 ++++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/test/cmocka/src/audio/pipeline/pipeline_connect_upstream.c b/test/cmocka/src/audio/pipeline/pipeline_connect_upstream.c index dea28ce65401..e911f0238162 100644 --- a/test/cmocka/src/audio/pipeline/pipeline_connect_upstream.c +++ b/test/cmocka/src/audio/pipeline/pipeline_connect_upstream.c @@ -24,6 +24,7 @@ static int setup(void **state) static int teardown(void **state) { + free_standard_connect_objects(*state); free(*state); return 0; } diff --git a/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.c b/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.c index 35899b14b297..de05f8e3b284 100644 --- a/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.c +++ b/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.c @@ -30,7 +30,7 @@ struct pipeline_connect_data *get_standard_connect_objects(void) struct pipeline_connect_data *pipeline_connect_data = calloc (sizeof(struct pipeline_connect_data), 1); - struct pipeline *pipe = calloc(sizeof(struct pipeline), 1); + struct pipeline *pipe = &pipeline_connect_data->p; pipe->frames_per_sched = 5; pipe->pipeline_id = PIPELINE_ID_SAME; @@ -83,7 +83,14 @@ struct pipeline_connect_data *get_standard_connect_objects(void) comp_buffer_reset_source_list(buffer_2); pipeline_connect_data->b2 = buffer_2; - pipeline_connect_data->p = *pipe; - return pipeline_connect_data; } + +void free_standard_connect_objects(struct pipeline_connect_data *data) +{ + free(data->p.pipe_task); + free(data->p.sched_comp); + free(data->second); + free(data->b1); + free(data->b2); +} diff --git a/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.h b/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.h index 6a8c0fce1a12..60eedabbd43b 100644 --- a/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.h +++ b/test/cmocka/src/audio/pipeline/pipeline_connection_mocks.h @@ -32,6 +32,7 @@ struct pipeline_connect_data { }; struct pipeline_connect_data *get_standard_connect_objects(void); +void free_standard_connect_objects(struct pipeline_connect_data *data); void cleanup_test_data(struct pipeline_connect_data *data); diff --git a/test/cmocka/src/audio/pipeline/pipeline_free.c b/test/cmocka/src/audio/pipeline/pipeline_free.c index d4d441012a29..6d76fde9a145 100644 --- a/test/cmocka/src/audio/pipeline/pipeline_free.c +++ b/test/cmocka/src/audio/pipeline/pipeline_free.c @@ -36,6 +36,7 @@ static int setup(void **state) static int teardown(void **state) { + free_standard_connect_objects(*state); free(*state); return 0; } diff --git a/test/cmocka/src/audio/pipeline/pipeline_new.c b/test/cmocka/src/audio/pipeline/pipeline_new.c index dda5d1a5c020..c08e499a5a05 100644 --- a/test/cmocka/src/audio/pipeline/pipeline_new.c +++ b/test/cmocka/src/audio/pipeline/pipeline_new.c @@ -55,6 +55,10 @@ static void test_audio_pipeline_pipeline_new_creation(void **state) /*Pipeline should have been created so pointer can't be null*/ assert_non_null(result); + + rfree(result->msg->tx_data); + rfree(result->msg); + rfree(result); } int main(void)