diff --git a/app/boards/intel_adsp/Kconfig.defconfig b/app/boards/intel_adsp/Kconfig.defconfig index fc0e11eaafed..066112c8113e 100644 --- a/app/boards/intel_adsp/Kconfig.defconfig +++ b/app/boards/intel_adsp/Kconfig.defconfig @@ -29,6 +29,9 @@ config FORMAT_MU_LAW config FORMAT_U8 default y +config FORMAT_S8 + default y + config PCM_CONVERTER_FORMAT_A_LAW default y @@ -59,5 +62,8 @@ config PCM_CONVERTER_FORMAT_S24_C32_AND_S24_C24 config PCM_CONVERTER_FORMAT_U8 default y +config PCM_CONVERTER_FORMAT_S8 + default y + config PIPELINE_2_0 default y diff --git a/src/audio/Kconfig b/src/audio/Kconfig index ce3ba346b1e5..7de00f98519c 100644 --- a/src/audio/Kconfig +++ b/src/audio/Kconfig @@ -168,6 +168,11 @@ config FORMAT_U8 help Support unsigned 8 bit processing data format +config FORMAT_S8 + bool "Support S8" + help + Support signed 8 bit processing data format + config FORMAT_A_LAW bool "Support A-law" help @@ -224,6 +229,11 @@ config PCM_CONVERTER_FORMAT_U8 help Support 8 bit processing data format without sign +config PCM_CONVERTER_FORMAT_S8 + bool "Support S8" + help + Support signed 8 bit processing data format + config PCM_CONVERTER_FORMAT_A_LAW bool "Support A-law" select MATH_A_LAW_CODEC diff --git a/src/audio/pcm_converter/pcm_converter_generic.c b/src/audio/pcm_converter/pcm_converter_generic.c index fe96e6d1f124..84ad631d8f70 100644 --- a/src/audio/pcm_converter/pcm_converter_generic.c +++ b/src/audio/pcm_converter/pcm_converter_generic.c @@ -95,6 +95,66 @@ static int pcm_convert_s32_to_u8(const struct audio_stream *source, } #endif /* CONFIG_PCM_CONVERTER_FORMAT_U8 && CONFIG_PCM_CONVERTER_FORMAT_S32LE */ +#if CONFIG_PCM_CONVERTER_FORMAT_S8 && CONFIG_PCM_CONVERTER_FORMAT_S32LE +static int pcm_convert_s8_to_s32(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples, uint32_t chmap) +{ + int8_t *src = audio_stream_get_rptr(source); + int32_t *dst = audio_stream_get_wptr(sink); + uint32_t processed; + uint32_t nmax, i, n; + + src += ioffset; + dst += ooffset; + for (processed = 0; processed < samples; processed += n) { + src = audio_stream_wrap(source, src); + dst = audio_stream_wrap(sink, dst); + n = samples - processed; + nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_U8_SAMPLES; + n = MIN(n, nmax); + nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_S32_SAMPLES; + n = MIN(n, nmax); + for (i = 0; i < n; i++) { + *dst = *src << 24; + src++; + dst++; + } + } + + return samples; +} + +static int pcm_convert_s32_to_s8(const struct audio_stream *source, + uint32_t ioffset, struct audio_stream *sink, + uint32_t ooffset, uint32_t samples, uint32_t chmap) +{ + int32_t *src = audio_stream_get_rptr(source); + int8_t *dst = audio_stream_get_wptr(sink); + uint32_t processed; + uint32_t nmax, i, n; + + src += ioffset; + dst += ooffset; + for (processed = 0; processed < samples; processed += n) { + src = audio_stream_wrap(source, src); + dst = audio_stream_wrap(sink, dst); + n = samples - processed; + nmax = audio_stream_bytes_without_wrap(source, src) >> BYTES_TO_S32_SAMPLES; + n = MIN(n, nmax); + nmax = audio_stream_bytes_without_wrap(sink, dst) >> BYTES_TO_U8_SAMPLES; + n = MIN(n, nmax); + for (i = 0; i < n; i++) { + *dst = sat_int8(Q_SHIFT_RND(*src, 24, 0)); + src++; + dst++; + } + } + + return samples; +} +#endif /* CONFIG_PCM_CONVERTER_FORMAT_S8 && CONFIG_PCM_CONVERTER_FORMAT_S32LE */ + #if CONFIG_PCM_CONVERTER_FORMAT_A_LAW && CONFIG_PCM_CONVERTER_FORMAT_S32LE static int pcm_convert_alaw_to_s32(const struct audio_stream *source, uint32_t ioffset, struct audio_stream *sink, @@ -677,6 +737,13 @@ const struct pcm_func_map pcm_func_map[] = { { SOF_IPC_FRAME_U8, SOF_IPC_FRAME_S32_LE, pcm_convert_u8_to_s32 }, { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_U8, pcm_convert_s32_to_u8 }, #endif /* CONFIG_PCM_CONVERTER_FORMAT_U8 && CONFIG_PCM_CONVERTER_FORMAT_S32LE */ +#if CONFIG_PCM_CONVERTER_FORMAT_S8 + { SOF_IPC_FRAME_S8, SOF_IPC_FRAME_S8, just_copy }, +#endif /* CONFIG_PCM_CONVERTER_FORMAT_S8 */ +#if CONFIG_PCM_CONVERTER_FORMAT_S8 && CONFIG_PCM_CONVERTER_FORMAT_S32LE + { SOF_IPC_FRAME_S8, SOF_IPC_FRAME_S32_LE, pcm_convert_s8_to_s32 }, + { SOF_IPC_FRAME_S32_LE, SOF_IPC_FRAME_S8, pcm_convert_s32_to_s8 }, +#endif /* CONFIG_PCM_CONVERTER_FORMAT_S8 && CONFIG_PCM_CONVERTER_FORMAT_S32LE */ #if CONFIG_PCM_CONVERTER_FORMAT_A_LAW { SOF_IPC_FRAME_A_LAW, SOF_IPC_FRAME_A_LAW, just_copy }, #endif /* CONFIG_PCM_CONVERTER_FORMAT_A_LAW */ diff --git a/src/include/module/audio/format.h b/src/include/module/audio/format.h index 7fccef12f49e..bdfcd386ad40 100644 --- a/src/include/module/audio/format.h +++ b/src/include/module/audio/format.h @@ -22,6 +22,7 @@ static inline uint32_t get_sample_bytes(enum sof_ipc_frame fmt) case SOF_IPC_FRAME_S24_3LE: return 3; case SOF_IPC_FRAME_U8: + case SOF_IPC_FRAME_S8: case SOF_IPC_FRAME_A_LAW: case SOF_IPC_FRAME_MU_LAW: return 1; @@ -39,6 +40,7 @@ static inline uint32_t get_sample_bitdepth(enum sof_ipc_frame fmt) case SOF_IPC_FRAME_S24_3LE: return 24; case SOF_IPC_FRAME_U8: + case SOF_IPC_FRAME_S8: case SOF_IPC_FRAME_A_LAW: case SOF_IPC_FRAME_MU_LAW: return 8; diff --git a/src/include/module/ipc/stream.h b/src/include/module/ipc/stream.h index 6e49d9f75cf2..cc14651effa0 100644 --- a/src/include/module/ipc/stream.h +++ b/src/include/module/ipc/stream.h @@ -25,6 +25,7 @@ enum sof_ipc_frame { SOF_IPC_FRAME_S16_4LE, /* 16-bit in 32-bit container */ SOF_IPC_FRAME_A_LAW, SOF_IPC_FRAME_MU_LAW, + SOF_IPC_FRAME_S8, SOF_IPC_FRAME_INVALID, /* keep last */ }; diff --git a/src/include/sof/audio/audio_stream.h b/src/include/sof/audio/audio_stream.h index 9703ec9cadea..2c88552ddb86 100644 --- a/src/include/sof/audio/audio_stream.h +++ b/src/include/sof/audio/audio_stream.h @@ -1036,6 +1036,12 @@ static inline int audio_stream_fmt_conversion(enum ipc4_bit_depth depth, *valid_fmt = SOF_IPC_FRAME_S24_3LE; ret = 0; #endif + } else if (depth == 8 && valid == 8) { +#ifdef CONFIG_FORMAT_S8 + *frame_fmt = SOF_IPC_FRAME_S8; + *valid_fmt = SOF_IPC_FRAME_S8; + ret = 0; +#endif /* CONFIG_FORMAT_S8 */ } else { /* IPC4_DEPTH_16BIT (16) <---> SOF_IPC_FRAME_S16_LE (0) * IPC4_DEPTH_24BIT (24) <---> SOF_IPC_FRAME_S24_4LE (1) diff --git a/tools/topology/topology2/cavs-nocodec.conf b/tools/topology/topology2/cavs-nocodec.conf index 1795fdb12668..205a7a84c383 100644 --- a/tools/topology/topology2/cavs-nocodec.conf +++ b/tools/topology/topology2/cavs-nocodec.conf @@ -226,7 +226,7 @@ IncludeByKey.PASSTHROUGH { Object.Widget.host-copier.1 { stream_name 'SSP0 Playback' pcm_id 0 - num_input_audio_formats 49 + num_input_audio_formats 56 num_output_audio_formats 7 Object.Base.input_audio_format [ @@ -490,6 +490,62 @@ IncludeByKey.PASSTHROUGH { in_ch_map $CHANNEL_MAP_7_POINT_1 in_sample_type $SAMPLE_TYPE_UNSIGNED_INTEGER } + { + in_bit_depth 8 + in_valid_bit_depth 8 + in_channels 1 + in_ch_cfg $CHANNEL_CONFIG_MONO + in_ch_map $CHANNEL_MAP_MONO + in_sample_type $SAMPLE_TYPE_SIGNED_INTEGER + } + { + in_bit_depth 8 + in_valid_bit_depth 8 + in_channels 2 + in_ch_cfg $CHANNEL_CONFIG_STEREO + in_ch_map $CHANNEL_MAP_STEREO + in_sample_type $SAMPLE_TYPE_SIGNED_INTEGER + } + { + in_bit_depth 8 + in_valid_bit_depth 8 + in_channels 3 + in_ch_cfg $CHANNEL_CONFIG_2_POINT_1 + in_ch_map $CHANNEL_MAP_2_POINT_1 + in_sample_type $SAMPLE_TYPE_SIGNED_INTEGER + } + { + in_bit_depth 8 + in_valid_bit_depth 8 + in_channels 4 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + in_sample_type $SAMPLE_TYPE_SIGNED_INTEGER + } + { + in_bit_depth 8 + in_valid_bit_depth 8 + in_channels 5 + in_ch_cfg $CHANNEL_CONFIG_5_POINT_0 + in_ch_map $CHANNEL_MAP_5_POINT_0 + in_sample_type $SAMPLE_TYPE_SIGNED_INTEGER + } + { + in_bit_depth 8 + in_valid_bit_depth 8 + in_channels 6 + in_ch_cfg $CHANNEL_CONFIG_5_POINT_1 + in_ch_map $CHANNEL_MAP_5_POINT_1 + in_sample_type $SAMPLE_TYPE_SIGNED_INTEGER + } + { + in_bit_depth 8 + in_valid_bit_depth 8 + in_channels 8 + in_ch_cfg $CHANNEL_CONFIG_7_POINT_1 + in_ch_map $CHANNEL_MAP_7_POINT_1 + in_sample_type $SAMPLE_TYPE_SIGNED_INTEGER + } { in_bit_depth 8 in_valid_bit_depth 8 @@ -779,7 +835,7 @@ IncludeByKey.PASSTHROUGH { stream_name 'SSP0 Capture' pcm_id $SSP0_PCM_ID num_input_audio_formats 1 - num_output_audio_formats 7 + num_output_audio_formats 8 Object.Base.input_audio_format [ { in_bit_depth 32 @@ -792,6 +848,11 @@ IncludeByKey.PASSTHROUGH { out_valid_bit_depth 8 out_sample_type $SAMPLE_TYPE_UNSIGNED_INTEGER } + { + out_bit_depth 8 + out_valid_bit_depth 8 + out_sample_type $SAMPLE_TYPE_SIGNED_INTEGER + } { out_bit_depth 8 out_valid_bit_depth 8 @@ -1581,7 +1642,7 @@ Object.PCM.pcm [ Object.PCM.pcm_caps.1 { direction "playback" name "SSP0 Playback" - formats 'S16_LE,S24_LE,S32_LE,U8,A_LAW,MU_LAW,FLOAT_LE' + formats 'S16_LE,S24_LE,S32_LE,U8,S8,A_LAW,MU_LAW,FLOAT_LE' IncludeByKey.SSP0_RATE { "48000" { rates '48000' @@ -1604,7 +1665,7 @@ Object.PCM.pcm [ Object.PCM.pcm_caps.2 { direction "capture" name "SSP0 Capture" - formats 'S16_LE,S24_LE,S32_LE,U8,A_LAW,MU_LAW,FLOAT_LE' + formats 'S16_LE,S24_LE,S32_LE,U8,S8,A_LAW,MU_LAW,FLOAT_LE' IncludeByKey.SSP0_RATE { "48000" { rates '48000'