diff --git a/src/math/iir_df1.c b/src/math/iir_df1.c index 5e4d13b8cc70..6a2bde2f5ddd 100644 --- a/src/math/iir_df1.c +++ b/src/math/iir_df1.c @@ -21,8 +21,12 @@ int iir_delay_size_df1(struct sof_eq_iir_header *config) if (!n || n > SOF_EQ_IIR_BIQUADS_MAX) return -EINVAL; + /* The filter runs num_sections_in_series biquads per parallel + * branch, so the sections must split evenly into branches. + */ if (!config->num_sections_in_series || - config->num_sections_in_series > n) + config->num_sections_in_series > n || + n % config->num_sections_in_series) return -EINVAL; return 4 * n * sizeof(int32_t); diff --git a/src/math/iir_df2t.c b/src/math/iir_df2t.c index ed2b50a21a4e..8eac5c26aa07 100644 --- a/src/math/iir_df2t.c +++ b/src/math/iir_df2t.c @@ -21,8 +21,12 @@ int iir_delay_size_df2t(struct sof_eq_iir_header *config) if (!n || n > SOF_EQ_IIR_BIQUADS_MAX) return -EINVAL; + /* The filter runs num_sections_in_series biquads per parallel + * branch, so the sections must split evenly into branches. + */ if (!config->num_sections_in_series || - config->num_sections_in_series > n) + config->num_sections_in_series > n || + n % config->num_sections_in_series) return -EINVAL; return 2 * n * sizeof(int64_t); diff --git a/test/cmocka/src/audio/eq_iir/eq_iir_process.c b/test/cmocka/src/audio/eq_iir/eq_iir_process.c index f69eaa39c129..6b30a64c5217 100644 --- a/test/cmocka/src/audio/eq_iir/eq_iir_process.c +++ b/test/cmocka/src/audio/eq_iir/eq_iir_process.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include "../../util.h" #include "../../../include/cmocka_chirp_2ch.h" @@ -517,11 +519,29 @@ static struct test_parameters parameters[] = { }; +static void test_iir_delay_size_df1_series(void **state) +{ + struct sof_eq_iir_header hdr = { .num_sections = 11 }; + const int size = 4 * 11 * sizeof(int32_t); + + (void)state; + + hdr.num_sections_in_series = 11; + assert_int_equal(iir_delay_size_df1(&hdr), size); + + hdr.num_sections_in_series = 1; + assert_int_equal(iir_delay_size_df1(&hdr), size); + + /* iir_df1() would run 20 biquads against 11 sections of state */ + hdr.num_sections_in_series = 10; + assert_int_equal(iir_delay_size_df1(&hdr), -EINVAL); +} + int main(void) { int i; - struct CMUnitTest tests[ARRAY_SIZE(parameters)]; + struct CMUnitTest tests[ARRAY_SIZE(parameters) + 1]; for (i = 0; i < ARRAY_SIZE(parameters); i++) { tests[i].name = "test_audio_eq_iir"; @@ -531,6 +551,12 @@ int main(void) tests[i].initial_state = ¶meters[i]; } + tests[i].name = "test_iir_delay_size_df1_series"; + tests[i].test_func = test_iir_delay_size_df1_series; + tests[i].setup_func = NULL; + tests[i].teardown_func = NULL; + tests[i].initial_state = NULL; + cmocka_set_message_output(CM_OUTPUT_TAP); return cmocka_run_group_tests(tests, setup_group, NULL);