From 821f961fbad4c353a0cdda87f65a085a72dd13d9 Mon Sep 17 00:00:00 2001 From: Tobiasz Dryjanski Date: Mon, 8 Apr 2024 16:08:06 +0200 Subject: [PATCH] smart_amp_test: fix crash due to different source formats Smart amp test chooses a process function based on the sink only. Because of this, there's a possibility that one of the sources has a 16bit format, which can't be safely processed by the 32bit process function. The crash only happened when dai_copier sent one less sample than usual to the smart_amp. This makes total sample count an odd number, making the data in the audio_stream buffer misaligned. This patch changes the prepare function of smart_amp_test to consider all the sources and sinks while deciding which process function to use. Signed-off-by: Tobiasz Dryjanski --- src/samples/audio/smart_amp_test_ipc4.c | 39 ++++++++++++++++++------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/samples/audio/smart_amp_test_ipc4.c b/src/samples/audio/smart_amp_test_ipc4.c index 13f5f866e..789f70a5b 100644 --- a/src/samples/audio/smart_amp_test_ipc4.c +++ b/src/samples/audio/smart_amp_test_ipc4.c @@ -327,18 +327,35 @@ static int smart_amp_reset(struct processing_module *mod) return 0; } -static smart_amp_proc get_smart_amp_process(struct sof_sink *sink) +static smart_amp_proc get_smart_amp_process(struct sof_source **sources, int num_of_sources, + struct sof_sink **sinks, int num_of_sinks) { - switch (sink_get_frm_fmt(sink)) { - case SOF_IPC_FRAME_S16_LE: - return process_s16; - case SOF_IPC_FRAME_S24_4LE: - case SOF_IPC_FRAME_S32_LE: - return process_s32; - default: - LOG_ERR("smart_amp_process() error: not supported frame format"); - return NULL; + /* Find if any of the sources/sinks needs 16bit process, else use 32bit */ + for (int i = 0; i < num_of_sources; i++) { + switch (source_get_frm_fmt(sources[i])) { + case SOF_IPC_FRAME_S16_LE: + return process_s16; + case SOF_IPC_FRAME_S24_4LE: + case SOF_IPC_FRAME_S32_LE: + break; + default: + LOG_ERR("smart_amp_process() error: not supported frame format"); + return NULL; + } } + for (int i = 0; i < num_of_sinks; i++) { + switch (sink_get_frm_fmt(sinks[i])) { + case SOF_IPC_FRAME_S16_LE: + return process_s16; + case SOF_IPC_FRAME_S24_4LE: + case SOF_IPC_FRAME_S32_LE: + break; + default: + LOG_ERR("smart_amp_process() error: not supported frame format"); + return NULL; + } + } + return process_s32; } static int smart_amp_prepare(struct processing_module *mod, @@ -349,7 +366,7 @@ static int smart_amp_prepare(struct processing_module *mod, LOG_DBG("smart_amp_prepare()"); - sad->process = get_smart_amp_process(sinks[0]); + sad->process = get_smart_amp_process(sources, num_of_sources, sinks, num_of_sinks); if (!sad->process) { LOG_ERR("smart_amp_prepare(): get_smart_amp_process failed"); return -EINVAL;