From ed25859955402b306d5af31e64ed6ce9a7d3408b Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Tue, 25 Jul 2023 14:59:07 +0800 Subject: [PATCH 1/5] audio: add fixup for S24_3LE It is missed in kconfig. Signed-off-by: Rander Wang --- src/audio/Kconfig | 6 ++++++ src/include/sof/audio/audio_stream.h | 11 +++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/audio/Kconfig b/src/audio/Kconfig index 77c6586db9f2..4f3839fca072 100644 --- a/src/audio/Kconfig +++ b/src/audio/Kconfig @@ -566,6 +566,12 @@ config FORMAT_S24LE help Support 24 bit processing data format with sign and in little endian format +config FORMAT_S24_3LE + bool "Support S24_3LE" + default n + help + Support packed 24 bit processing data format with sign and in little endian format + config FORMAT_S32LE bool "Support S32LE" default y diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index bf5de7f39a6b..ecfc63432d86 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -1055,10 +1055,13 @@ static inline void audio_stream_fmt_conversion(enum ipc4_bit_depth depth, *valid_fmt = SOF_IPC_FRAME_U8; #endif /* CONFIG_FORMAT_U8 */ - /* really 24_3LE */ - if (valid == 24 && depth == 24) { - *frame_fmt = SOF_IPC_FRAME_S24_3LE; - *valid_fmt = SOF_IPC_FRAME_S24_3LE; + if (valid == 24) { +#ifdef CONFIG_FORMAT_S24_3LE + if (depth == 24) { + *frame_fmt = SOF_IPC_FRAME_S24_3LE; + *valid_fmt = SOF_IPC_FRAME_S24_3LE; + } +#endif } if (type == IPC4_TYPE_FLOAT && depth == 32) { From 432af74b805c5cef0079fa969bcc78bd8bb5872a Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Mon, 17 Jul 2023 16:58:25 +0800 Subject: [PATCH 2/5] ipc4: add S24_4LE_MSB format support For sample format with 24 bits valid sample bit and 32 bits container, valid sample is at msb 24bits if IPC4_TYPE_MSB_INTEGER is set. Signed-off-by: Rander Wang --- src/audio/Kconfig | 12 ++++++++++++ src/include/ipc/stream.h | 1 + src/include/kernel/abi.h | 2 +- test/cmocka/src/audio/selector/selector_test.c | 1 + test/cmocka/src/audio/volume/volume_process.c | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/audio/Kconfig b/src/audio/Kconfig index 4f3839fca072..be2ff5f360b2 100644 --- a/src/audio/Kconfig +++ b/src/audio/Kconfig @@ -572,6 +572,12 @@ config FORMAT_S24_3LE help Support packed 24 bit processing data format with sign and in little endian format +config FORMAT_S24_4LE_MSB + bool "Support S24_4LE_MSB" + default y + help + Support 24 bit processing data format with sign and in msb 24 bits format + config FORMAT_S32LE bool "Support S32LE" default y @@ -608,6 +614,12 @@ config PCM_CONVERTER_FORMAT_S24LE help Support 24 bit processing data format with sign and in little endian format +config PCM_CONVERTER_FORMAT_S24_4LE_MSB + bool "Support S24_4LE_MSB" + default y + help + Support 24 bit processing data format with sign and in msb 24 bits format + config PCM_CONVERTER_FORMAT_S24_3LE bool "Support S24_3LE" default n diff --git a/src/include/ipc/stream.h b/src/include/ipc/stream.h index e7eb93407ddb..1c9bd7a824ac 100644 --- a/src/include/ipc/stream.h +++ b/src/include/ipc/stream.h @@ -56,6 +56,7 @@ enum sof_ipc_frame { SOF_IPC_FRAME_FLOAT, /* other formats here */ SOF_IPC_FRAME_S24_3LE, + SOF_IPC_FRAME_S24_4LE_MSB, SOF_IPC_FRAME_U8, }; diff --git a/src/include/kernel/abi.h b/src/include/kernel/abi.h index 3fcf1c85a331..9c7f8afda136 100644 --- a/src/include/kernel/abi.h +++ b/src/include/kernel/abi.h @@ -29,7 +29,7 @@ /** \brief SOF ABI version major, minor and patch numbers */ #define SOF_ABI_MAJOR 3 -#define SOF_ABI_MINOR 27 +#define SOF_ABI_MINOR 28 #define SOF_ABI_PATCH 0 /** \brief SOF ABI version number. Format within 32bit word is MMmmmppp */ diff --git a/test/cmocka/src/audio/selector/selector_test.c b/test/cmocka/src/audio/selector/selector_test.c index 7edbe6bded49..4bcc8df7fea5 100644 --- a/test/cmocka/src/audio/selector/selector_test.c +++ b/test/cmocka/src/audio/selector/selector_test.c @@ -440,6 +440,7 @@ static void test_audio_sel(void **state) #endif /* CONFIG_FORMAT_S24LE || CONFIG_FORMAT_S32LE */ /* TODO: add S24_3LE support */ + /* TODO: add S24_4LE_MSB support */ /* TODO: add U8 support */ default: break; diff --git a/test/cmocka/src/audio/volume/volume_process.c b/test/cmocka/src/audio/volume/volume_process.c index eaf3bb8bf60d..10afdd1276a3 100644 --- a/test/cmocka/src/audio/volume/volume_process.c +++ b/test/cmocka/src/audio/volume/volume_process.c @@ -280,6 +280,7 @@ static void test_audio_vol(void **state) break; /* TODO: add 3LE support */ + /* TODO: add 4LE_MSB support */ /* TODO: add U8 support */ default: break; From ff21e26b87270354b31b78024534a3993c72dcb0 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Mon, 17 Jul 2023 17:16:45 +0800 Subject: [PATCH 3/5] pcm:_converter: simplify the pcm conversion algorithm Remove gateway type and direction for pcm conversion check and will move them to copier module. This will make pcm conversion check more general and simple. Also remove s16/c32 for gateway since it is never used. Signed-off-by: Rander Wang --- .../pcm_converter/pcm_converter_generic.c | 113 +++++++----------- src/audio/pcm_converter/pcm_converter_hifi3.c | 110 +++++++---------- src/include/sof/audio/pcm_converter.h | 9 +- 3 files changed, 85 insertions(+), 147 deletions(-) diff --git a/src/audio/pcm_converter/pcm_converter_generic.c b/src/audio/pcm_converter/pcm_converter_generic.c index ee1801fcfe59..db3bbe9b88d4 100644 --- a/src/audio/pcm_converter/pcm_converter_generic.c +++ b/src/audio/pcm_converter/pcm_converter_generic.c @@ -883,106 +883,77 @@ static int pcm_convert_s24_c32_to_s24_c24_link_gtw(const struct audio_stream __s #endif -/* Different gateway has different sample layout requirement - * (1) hda link gateway: 24le sample should be converted to 24be one - * (2) alh gateway: all data format layout should be in big-endian style in 32bit container, - * .e.g. 24le stream should be convert to 24be one - * (3) ssp gateway: all sample should be in container size of 32bit - */ const struct pcm_func_vc_map pcm_func_vc_map[] = { #if CONFIG_PCM_CONVERTER_FORMAT_S16_C16_AND_S16_C32 { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, - ipc4_gtw_all, ipc4_bidirection, pcm_convert_s16_c16_to_s16_c32 }, + pcm_convert_s16_c16_to_s16_c32 }, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, - ipc4_gtw_all, ipc4_bidirection, pcm_convert_s16_c32_to_s16_c16 }, + pcm_convert_s16_c32_to_s16_c16 }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S16_C32_AND_S32_C32 { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, - ipc4_gtw_all, ipc4_bidirection, pcm_convert_s16_c32_to_s32_c32 }, + pcm_convert_s16_c32_to_s32_c32 }, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, - ipc4_gtw_all, ipc4_bidirection, pcm_convert_s32_c32_to_s16_c32 }, + pcm_convert_s32_c32_to_s16_c32 }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S16_C32_AND_S24_C32 { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_all & ~ipc4_gtw_alh, ipc4_bidirection, pcm_convert_s16_c32_to_s24_c32 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_alh, ipc4_capture, pcm_convert_s32_to_s24 }, + pcm_convert_s16_c32_to_s24_c32 }, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, - ipc4_gtw_all & ~ipc4_gtw_alh, ipc4_bidirection, pcm_convert_s24_c32_to_s16_c32 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, - ipc4_gtw_alh, ipc4_playback, pcm_convert_s24_to_s32 }, + pcm_convert_s24_c32_to_s16_c32 }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_U8 && CONFIG_PCM_CONVERTER_FORMAT_S16LE { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_U8, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_U8, - ipc4_gtw_all, ipc4_bidirection, audio_stream_copy }, + audio_stream_copy }, #endif /* CONFIG_PCM_CONVERTER_FORMAT_U8 && CONFIG_PCM_CONVERTER_FORMAT_S16LE */ #if CONFIG_PCM_CONVERTER_FORMAT_S32LE && CONFIG_PCM_CONVERTER_FORMAT_S24LE { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_all & ~(ipc4_gtw_link | ipc4_gtw_alh | ipc4_gtw_host | ipc4_gtw_dmic), - ipc4_bidirection, audio_stream_copy}, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_link | ipc4_gtw_alh, ipc4_playback, pcm_convert_s24_to_s32 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_link | ipc4_gtw_alh | ipc4_gtw_dmic, ipc4_capture, - pcm_convert_s32_to_s24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_host, ipc4_playback, pcm_convert_s32_to_s24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_host, ipc4_capture, pcm_convert_s24_to_s32 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, - ipc4_gtw_all & ~ipc4_gtw_host, ipc4_bidirection, pcm_convert_s24_to_s32}, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, - ipc4_gtw_host, ipc4_playback, audio_stream_copy}, + audio_stream_copy}, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, - ipc4_gtw_host, ipc4_capture, pcm_convert_s24_to_s32}, + pcm_convert_s24_to_s32}, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_all & ~(ipc4_gtw_link | ipc4_gtw_alh | ipc4_gtw_host), ipc4_bidirection, pcm_convert_s32_to_s24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_link | ipc4_gtw_alh, ipc4_playback, pcm_convert_s32_to_s24_be }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_link | ipc4_gtw_alh, ipc4_capture, pcm_convert_s32_to_s24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_host, ipc4_playback, pcm_convert_s32_to_s24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_host, ipc4_capture, pcm_convert_s32_to_s24_be }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S24LE && CONFIG_PCM_CONVERTER_FORMAT_S16LE - { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_all & ~(ipc4_gtw_link | ipc4_gtw_alh | ipc4_gtw_host), - ipc4_bidirection, pcm_convert_s16_to_s24 }, - { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S24_4LE, ipc4_gtw_link | ipc4_gtw_alh, ipc4_playback, - pcm_convert_s16_to_s32}, - { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S24_4LE, ipc4_gtw_host, - ipc4_playback, pcm_convert_s16_to_s24 }, - { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S24_4LE, ipc4_gtw_host, - ipc4_capture, pcm_convert_s16_to_s32 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, - SOF_IPC_FRAME_S16_LE, ipc4_gtw_all & ~ipc4_gtw_host, - ipc4_bidirection, pcm_convert_s24_to_s16 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, - SOF_IPC_FRAME_S16_LE, ipc4_gtw_host, ipc4_playback, pcm_convert_s32_to_s16 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, - SOF_IPC_FRAME_S16_LE, ipc4_gtw_host, ipc4_capture, pcm_convert_s24_to_s16 }, + { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, + pcm_convert_s16_to_s24 }, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, + pcm_convert_s24_to_s16 }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S24_C24_AND_S24_C32 - { SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S24_4LE, ipc4_gtw_all, ipc4_bidirection, + { SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, pcm_convert_s24_c24_to_s24_c32}, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_3LE, - SOF_IPC_FRAME_S24_3LE, ipc4_gtw_all & ~ipc4_gtw_link, - ipc4_bidirection, pcm_convert_s24_c32_to_s24_c24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_3LE, - SOF_IPC_FRAME_S24_3LE, ipc4_gtw_link, ipc4_playback, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S24_4LE, + pcm_convert_s24_c32_to_s24_c24 }, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S24_3LE, pcm_convert_s24_c32_to_s24_c24_link_gtw }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S16_C32_AND_S16_C32 - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S16_LE, ipc4_gtw_all, ipc4_bidirection, audio_stream_copy }, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, + audio_stream_copy }, +#endif + +#if CONFIG_PCM_CONVERTER_FORMAT_S24_4LE_MSB && CONFIG_PCM_CONVERTER_FORMAT_S24LE + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S24_4LE_MSB, pcm_convert_s24_to_s32}, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE_MSB, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S24_4LE, pcm_convert_s32_to_s24}, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE_MSB, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S24_4LE_MSB, audio_stream_copy}, +#endif + +#if CONFIG_PCM_CONVERTER_FORMAT_S32LE && CONFIG_PCM_CONVERTER_FORMAT_S24_4LE_MSB + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S24_4LE_MSB, pcm_convert_s32_to_s24_be}, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE_MSB, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, audio_stream_copy}, +#endif + +#if CONFIG_PCM_CONVERTER_FORMAT_S24_4LE_MSB && CONFIG_PCM_CONVERTER_FORMAT_S16LE + { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S24_4LE_MSB, pcm_convert_s16_to_s32 }, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE_MSB, SOF_IPC_FRAME_S16_LE, + SOF_IPC_FRAME_S16_LE, pcm_convert_s32_to_s16 }, #endif }; diff --git a/src/audio/pcm_converter/pcm_converter_hifi3.c b/src/audio/pcm_converter/pcm_converter_hifi3.c index 0980cc656a93..ac5c14b379bc 100644 --- a/src/audio/pcm_converter/pcm_converter_hifi3.c +++ b/src/audio/pcm_converter/pcm_converter_hifi3.c @@ -1206,99 +1206,73 @@ static int pcm_convert_s24_c32_to_s24_c24(const struct audio_stream __sparse_cac */ #endif -/* Different gateway has different sample layout requirement - * (1) hda link gateway: 24le sample should be converted to 24be one - * (2) alh gateway: all data format layout should be in big-endian style in 32bit container, - * .e.g. 24le stream should be convert to 24be one - * (3) ssp gateway: all sample should be in container size of 32bit - */ const struct pcm_func_vc_map pcm_func_vc_map[] = { #if CONFIG_PCM_CONVERTER_FORMAT_S16_C16_AND_S16_C32 { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, - ipc4_gtw_all, ipc4_bidirection, pcm_convert_s16_c16_to_s16_c32 }, + pcm_convert_s16_c16_to_s16_c32 }, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, - ipc4_gtw_all, ipc4_bidirection, pcm_convert_s16_c32_to_s16_c16 }, + pcm_convert_s16_c32_to_s16_c16 }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S16_C32_AND_S32_C32 { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, - ipc4_gtw_all, ipc4_bidirection, pcm_convert_s16_c32_to_s32_c32 }, + pcm_convert_s16_c32_to_s32_c32 }, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, - ipc4_gtw_all, ipc4_bidirection, pcm_convert_s32_c32_to_s16_c32 }, + pcm_convert_s32_c32_to_s16_c32 }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S16_C32_AND_S24_C32 { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_all & ~ipc4_gtw_alh, ipc4_bidirection, pcm_convert_s16_c32_to_s24_c32 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_alh, ipc4_capture, pcm_convert_s32_to_s24 }, + pcm_convert_s16_c32_to_s24_c32 }, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, - ipc4_gtw_all & ~ipc4_gtw_alh, ipc4_bidirection, pcm_convert_s24_c32_to_s16_c32 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, - ipc4_gtw_alh, ipc4_playback, pcm_convert_s24_to_s32 }, + pcm_convert_s24_c32_to_s16_c32 }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S32LE && CONFIG_PCM_CONVERTER_FORMAT_S24LE { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_all & ~(ipc4_gtw_link | ipc4_gtw_alh | ipc4_gtw_host | ipc4_gtw_dmic), - ipc4_bidirection, audio_stream_copy}, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_link | ipc4_gtw_alh, ipc4_playback, pcm_convert_s24_to_s32 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_link | ipc4_gtw_alh | ipc4_gtw_dmic, ipc4_capture, - pcm_convert_s32_to_s24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_host, ipc4_playback, pcm_convert_s32_to_s24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_host, ipc4_capture, pcm_convert_s24_to_s32 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, - ipc4_gtw_all & ~ipc4_gtw_host, ipc4_bidirection, pcm_convert_s24_to_s32}, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, - ipc4_gtw_host, ipc4_playback, audio_stream_copy}, + audio_stream_copy}, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, - ipc4_gtw_host, ipc4_capture, pcm_convert_s24_to_s32}, + pcm_convert_s24_to_s32}, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_all & ~(ipc4_gtw_link | ipc4_gtw_alh | ipc4_gtw_host), ipc4_bidirection, pcm_convert_s32_to_s24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_link | ipc4_gtw_alh, ipc4_playback, pcm_convert_s32_to_s24_be }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_link | ipc4_gtw_alh, ipc4_capture, pcm_convert_s32_to_s24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_host, ipc4_playback, pcm_convert_s32_to_s24 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_host, ipc4_capture, pcm_convert_s32_to_s24_be }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S24LE && CONFIG_PCM_CONVERTER_FORMAT_S16LE - { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S24_4LE, - ipc4_gtw_all & ~(ipc4_gtw_link | ipc4_gtw_alh | ipc4_gtw_host), - ipc4_bidirection, pcm_convert_s16_to_s24 }, - { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S24_4LE, ipc4_gtw_link | ipc4_gtw_alh, ipc4_playback, - pcm_convert_s16_to_s32}, - { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S24_4LE, ipc4_gtw_host, - ipc4_playback, pcm_convert_s16_to_s24 }, - { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S24_4LE, ipc4_gtw_host, - ipc4_capture, pcm_convert_s16_to_s32 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, - SOF_IPC_FRAME_S16_LE, ipc4_gtw_all & ~ipc4_gtw_host, - ipc4_bidirection, pcm_convert_s24_to_s16 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, - SOF_IPC_FRAME_S16_LE, ipc4_gtw_host, ipc4_playback, pcm_convert_s32_to_s16 }, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, - SOF_IPC_FRAME_S16_LE, ipc4_gtw_host, ipc4_capture, pcm_convert_s24_to_s16 }, + { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, + pcm_convert_s16_to_s24 }, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, + pcm_convert_s24_to_s16 }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S24_C24_AND_S24_C32 - { SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S24_4LE, ipc4_gtw_all, ipc4_bidirection, + { SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, pcm_convert_s24_c24_to_s24_c32}, - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_3LE, - SOF_IPC_FRAME_S24_3LE, ipc4_gtw_all & ~ipc4_gtw_link, - ipc4_bidirection, pcm_convert_s24_c32_to_s24_c24 }, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S24_4LE, + pcm_convert_s24_c32_to_s24_c24 }, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_3LE, SOF_IPC_FRAME_S24_3LE, + pcm_convert_s24_c32_to_s24_c24_link_gtw }, #endif #if CONFIG_PCM_CONVERTER_FORMAT_S16_C32_AND_S16_C32 - { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, - SOF_IPC_FRAME_S16_LE, ipc4_gtw_all, ipc4_bidirection, audio_stream_copy }, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S16_LE, + audio_stream_copy }, +#endif + +#if CONFIG_PCM_CONVERTER_FORMAT_S24_4LE_MSB && CONFIG_PCM_CONVERTER_FORMAT_S24LE + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S24_4LE_MSB, pcm_convert_s24_to_s32}, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE_MSB, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S24_4LE, pcm_convert_s32_to_s24}, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE_MSB, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S24_4LE_MSB, audio_stream_copy}, +#endif + +#if CONFIG_PCM_CONVERTER_FORMAT_S32LE && CONFIG_PCM_CONVERTER_FORMAT_S24_4LE_MSB + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S24_4LE_MSB, pcm_convert_s32_to_s24_be}, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE_MSB, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S32_LE, audio_stream_copy}, +#endif + +#if CONFIG_PCM_CONVERTER_FORMAT_S24_4LE_MSB && CONFIG_PCM_CONVERTER_FORMAT_S16LE + { SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S16_LE, SOF_IPC_FRAME_S32_LE, + SOF_IPC_FRAME_S24_4LE_MSB, pcm_convert_s16_to_s32 }, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S24_4LE_MSB, SOF_IPC_FRAME_S16_LE, + SOF_IPC_FRAME_S16_LE, pcm_convert_s32_to_s16 }, #endif }; diff --git a/src/include/sof/audio/pcm_converter.h b/src/include/sof/audio/pcm_converter.h index a649ba37539f..09d20f5568b6 100644 --- a/src/include/sof/audio/pcm_converter.h +++ b/src/include/sof/audio/pcm_converter.h @@ -100,8 +100,7 @@ struct pcm_func_vc_map { enum sof_ipc_frame valid_src_bits; /**< source frame format */ enum sof_ipc_frame sink; /**< sink frame container format */ enum sof_ipc_frame valid_sink_bits; /**< sink frame format */ - uint32_t type; /**< gateway type */ - enum ipc4_direction_type direction; /**< support playback, capture or both */ + pcm_converter_func func; /**< PCM conversion function */ }; @@ -140,12 +139,6 @@ pcm_get_conversion_vc_function(enum sof_ipc_frame in_bits, if (valid_out_bits != pcm_func_vc_map[i].valid_sink_bits) continue; - if (!(type & pcm_func_vc_map[i].type)) - continue; - - if (!(dir & pcm_func_vc_map[i].direction)) - continue; - return pcm_func_vc_map[i].func; } From 201e965b1dbd227b4cf3a3fb02f9b42ce3842c89 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 18 Aug 2023 15:21:47 +0800 Subject: [PATCH 4/5] topology2: change the sample type for Linux audio system At first the sample type is set to MSB_INTEGER to follow windows settings, but actually we use LSB_INTERGER type such as S24_4LE. Now change the default sample type to LSB_INTERGER to align with FW usage. For DAI copier we need to use MSB_INTERGER for hardware requirement. Currently sample type only affect s24/c32 case, so only change sample type in dai for this format config. FW will use sample type to choose correct format conversion function and can deal with Windows audio stream correctly with MSB s24/c32 format. out_fmt_cfg is redefined for a alsa-lib bug. Alsa-lib will first process out_fmt_cfg = '$[($out_channels | ($out_valid_bit_depth * 256)) | ($out_sample_type * 65536)]' in base class and then deal with out_sample_type, so error is reported. Now first define out_sample_type and then out_fmt_cfg, everything works. Signed-off-by: Rander Wang --- tools/topology/topology2/include/common/audio_format.conf | 4 ++-- .../topology/topology2/include/common/input_audio_format.conf | 2 +- .../topology2/include/common/output_audio_format.conf | 2 +- .../topology2/include/pipelines/cavs/dai-copier-be.conf | 2 ++ .../topology/topology2/include/pipelines/cavs/dai-kpb-be.conf | 2 ++ .../topology/topology2/include/pipelines/cavs/io-gateway.conf | 2 ++ 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tools/topology/topology2/include/common/audio_format.conf b/tools/topology/topology2/include/common/audio_format.conf index 94e34ec50f79..8ee2e6bed86c 100644 --- a/tools/topology/topology2/include/common/audio_format.conf +++ b/tools/topology/topology2/include/common/audio_format.conf @@ -211,13 +211,13 @@ Class.Base."audio_format" { in_valid_bit_depth 16 in_channels 2 in_interleaving_style "interleaved" - in_sample_type $SAMPLE_TYPE_MSB_INTEGER + in_sample_type $SAMPLE_TYPE_LSB_INTEGER out_rate 48000 out_bit_depth 16 out_valid_bit_depth 16 out_channels 2 out_interleaving_style "interleaved" - out_sample_type $SAMPLE_TYPE_MSB_INTEGER + out_sample_type $SAMPLE_TYPE_LSB_INTEGER in_ch_cfg $CHANNEL_CONFIG_STEREO in_ch_map $CHANNEL_MAP_STEREO out_ch_cfg $CHANNEL_CONFIG_STEREO diff --git a/tools/topology/topology2/include/common/input_audio_format.conf b/tools/topology/topology2/include/common/input_audio_format.conf index 6eb8b1e0204d..f5b9956d841b 100644 --- a/tools/topology/topology2/include/common/input_audio_format.conf +++ b/tools/topology/topology2/include/common/input_audio_format.conf @@ -124,7 +124,7 @@ Class.Base."input_audio_format" { in_valid_bit_depth 16 in_channels 2 in_interleaving_style "interleaved" - in_sample_type $SAMPLE_TYPE_MSB_INTEGER + in_sample_type $SAMPLE_TYPE_LSB_INTEGER in_ch_cfg $CHANNEL_CONFIG_STEREO in_ch_map $CHANNEL_MAP_STEREO diff --git a/tools/topology/topology2/include/common/output_audio_format.conf b/tools/topology/topology2/include/common/output_audio_format.conf index f67f8b7d2796..915edc000820 100644 --- a/tools/topology/topology2/include/common/output_audio_format.conf +++ b/tools/topology/topology2/include/common/output_audio_format.conf @@ -124,7 +124,7 @@ Class.Base."output_audio_format" { out_valid_bit_depth 16 out_channels 2 out_interleaving_style "interleaved" - out_sample_type $SAMPLE_TYPE_MSB_INTEGER + out_sample_type $SAMPLE_TYPE_LSB_INTEGER out_ch_cfg $CHANNEL_CONFIG_STEREO out_ch_map $CHANNEL_MAP_STEREO diff --git a/tools/topology/topology2/include/pipelines/cavs/dai-copier-be.conf b/tools/topology/topology2/include/pipelines/cavs/dai-copier-be.conf index 8727184ee485..d17e651316b9 100644 --- a/tools/topology/topology2/include/pipelines/cavs/dai-copier-be.conf +++ b/tools/topology/topology2/include/pipelines/cavs/dai-copier-be.conf @@ -67,6 +67,8 @@ Class.Pipeline."dai-copier-be" { in_valid_bit_depth 24 out_bit_depth 32 out_valid_bit_depth 24 + out_sample_type $SAMPLE_TYPE_MSB_INTEGER + out_fmt_cfg "$[($out_channels | ($out_valid_bit_depth * 256))]" } } diff --git a/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf b/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf index 7d3faef7a25d..70bc4f2c8dba 100644 --- a/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf +++ b/tools/topology/topology2/include/pipelines/cavs/dai-kpb-be.conf @@ -54,6 +54,8 @@ Class.Pipeline."dai-kpb-be" { in_valid_bit_depth 24 out_bit_depth 32 out_valid_bit_depth 24 + out_sample_type $SAMPLE_TYPE_MSB_INTEGER + out_fmt_cfg "$[($out_channels | ($out_valid_bit_depth * 256))]" } Object.Base.audio_format.1 { diff --git a/tools/topology/topology2/include/pipelines/cavs/io-gateway.conf b/tools/topology/topology2/include/pipelines/cavs/io-gateway.conf index ef77ef0ea6b9..fd160d0d4721 100644 --- a/tools/topology/topology2/include/pipelines/cavs/io-gateway.conf +++ b/tools/topology/topology2/include/pipelines/cavs/io-gateway.conf @@ -67,6 +67,8 @@ Class.Pipeline."io-gateway" { { out_bit_depth 32 out_valid_bit_depth 24 + out_sample_type $SAMPLE_TYPE_MSB_INTEGER + out_fmt_cfg "$[($out_channels | ($out_valid_bit_depth * 256))]" } { out_bit_depth 32 From 0d8c90ecd490c965b631260ecb7b8ae5d446f062 Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Mon, 21 Aug 2023 10:07:23 +0800 Subject: [PATCH 5/5] copier: adjust valid format based on sample type Adjust valid format in copier for some types of dai gateway which need to use MSB type. Currently sample type only affect the copier module so we don't do it in audio_stream_fmt_conversion. Signed-off-by: Rander Wang --- src/audio/copier/copier_generic.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/audio/copier/copier_generic.c b/src/audio/copier/copier_generic.c index e9ca748a8b2e..c610d05a049d 100644 --- a/src/audio/copier/copier_generic.c +++ b/src/audio/copier/copier_generic.c @@ -284,6 +284,11 @@ 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; + /* check container & sample size */ if (use_no_container_convert_function(in, in_valid, out, out_valid)) return pcm_get_conversion_function(in, out);