diff --git a/src/audio/copier/copier_generic.c b/src/audio/copier/copier_generic.c index c4991363eb7f..d33926bf0ac0 100644 --- a/src/audio/copier/copier_generic.c +++ b/src/audio/copier/copier_generic.c @@ -274,10 +274,45 @@ pcm_converter_func get_converter_func(const struct ipc4_audio_format *in_fmt, audio_stream_fmt_conversion(out_fmt->depth, out_fmt->valid_bit_depth, &out, &out_valid, out_fmt->s_type); - if (in_fmt->s_type == IPC4_TYPE_MSB_INTEGER && in_valid == SOF_IPC_FRAME_S24_4LE) - in_valid = SOF_IPC_FRAME_S24_4LE_MSB; - if (out_fmt->s_type == IPC4_TYPE_MSB_INTEGER && out_valid == SOF_IPC_FRAME_S24_4LE) - out_valid = SOF_IPC_FRAME_S24_4LE_MSB; + /* use MSB sample type to select conversion function if the data is enter or exit dsp. + * In playback case, host input and dai output and in capture case, host output and + * dai input. + */ + if (in_fmt->s_type == IPC4_TYPE_MSB_INTEGER && in_valid == SOF_IPC_FRAME_S24_4LE) { + switch (type) { + case ipc4_gtw_host: + if (dir == ipc4_playback) + in_valid = SOF_IPC_FRAME_S24_4LE_MSB; + break; + case ipc4_gtw_alh: + case ipc4_gtw_link: + case ipc4_gtw_ssp: + case ipc4_gtw_dmic: + if (dir == ipc4_capture) + in_valid = SOF_IPC_FRAME_S24_4LE_MSB; + break; + default: + break; + } + } + + if (out_fmt->s_type == IPC4_TYPE_MSB_INTEGER && out_valid == SOF_IPC_FRAME_S24_4LE) { + switch (type) { + case ipc4_gtw_host: + if (dir == ipc4_capture) + out_valid = SOF_IPC_FRAME_S24_4LE_MSB; + break; + case ipc4_gtw_alh: + case ipc4_gtw_link: + case ipc4_gtw_ssp: + case ipc4_gtw_dmic: + if (dir == ipc4_playback) + out_valid = SOF_IPC_FRAME_S24_4LE_MSB; + break; + default: + break; + } + } /* check container & sample size */ if (use_no_container_convert_function(in, in_valid, out, out_valid))