From ae5361ce6edad59001e78d8da452769df84a5878 Mon Sep 17 00:00:00 2001 From: Marcin Szkudlinski Date: Fri, 22 Dec 2023 12:36:18 +0100 Subject: [PATCH] AEC: add a kConfig switch to use 16int or 32float API Google AEC library allows 2 APIs to be used. This PR makes possible switching between APIs. kConfig COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API Signed-off-by: Marcin Szkudlinski --- src/audio/google/Kconfig | 8 ++++ .../google/google_rtc_audio_processing.c | 47 +++++++++++++----- .../google/google_rtc_audio_processing_mock.c | 48 ++++++++++++++++++- 3 files changed, 91 insertions(+), 12 deletions(-) diff --git a/src/audio/google/Kconfig b/src/audio/google/Kconfig index 74b64cccec0f..2b92dd573879 100644 --- a/src/audio/google/Kconfig +++ b/src/audio/google/Kconfig @@ -25,6 +25,14 @@ config COMP_GOOGLE_RTC_AUDIO_PROCESSING This component takes raw microphones input and playback reference and outputs an echo-free microphone signal. +config COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API + depends on COMP_GOOGLE_RTC_AUDIO_PROCESSING + bool "Use 32bit API in Google Audio processing" + default n + help + Selects an API to be used in communication with the Google real-time + communication audio processing: 32bit float or 16bit integer + config COMP_GOOGLE_RTC_AUDIO_PROCESSING_SAMPLE_RATE_HZ depends on COMP_GOOGLE_RTC_AUDIO_PROCESSING int "Sample rate for Google Real Time Communication Audio processing" diff --git a/src/audio/google/google_rtc_audio_processing.c b/src/audio/google/google_rtc_audio_processing.c index 69512e234de4..d7c9cc489ff8 100644 --- a/src/audio/google/google_rtc_audio_processing.c +++ b/src/audio/google/google_rtc_audio_processing.c @@ -43,6 +43,12 @@ #define GOOGLE_RTC_NUM_INPUT_PINS 2 #define GOOGLE_RTC_NUM_OUTPUT_PINS 1 +#if CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API +#define BUF_TYPE float +#else +#define BUF_TYPE int16_t +#endif + LOG_MODULE_REGISTER(google_rtc_audio_processing, CONFIG_SOF_LOG_LEVEL); /* b780a0a6-269f-466f-b477-23dfa05af758 */ @@ -59,10 +65,10 @@ struct google_rtc_audio_processing_comp_data { int num_aec_reference_channels; int num_capture_channels; GoogleRtcAudioProcessingState *state; - float *aec_reference_buffer; - float *aec_reference_buffer_ptrs[SOF_IPC_MAX_CHANNELS]; - float *process_buffer; - float *process_buffer_ptrs[SOF_IPC_MAX_CHANNELS]; + BUF_TYPE *aec_reference_buffer; + BUF_TYPE *aec_reference_buffer_ptrs[SOF_IPC_MAX_CHANNELS]; + BUF_TYPE *process_buffer; + BUF_TYPE *process_buffer_ptrs[SOF_IPC_MAX_CHANNELS]; uint8_t *memory_buffer; struct comp_data_blob_handler *tuning_handler; bool reconfigure; @@ -591,8 +597,9 @@ static int google_rtc_audio_processing_reset(struct processing_module *mod) return 0; } -static int16_t convert_float_to_uint16_hifi(float data) +static inline int16_t convert_google_aec_format_to_int16(BUF_TYPE data) { +#if CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API const xtfloat ratio = 2 << 14; xtfloat x0 = data; xtfloat x1; @@ -602,10 +609,14 @@ static int16_t convert_float_to_uint16_hifi(float data) x = XT_TRUNC_S(x1, 0); return x; +#else /* CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API */ + return data; +#endif } -static float convert_uint16_to_float_hifi(int16_t data) +static inline BUF_TYPE convert_int16_to_google_aec_format(int16_t data) { +#if CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API const xtfloat ratio = 2 << 14; xtfloat x0 = data; float x; @@ -613,6 +624,9 @@ static float convert_uint16_to_float_hifi(int16_t data) x = XT_DIV_S(x0, ratio); return x; +#else /* CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API */ + return data; +#endif } /* todo CONFIG_FORMAT_S32LE */ @@ -679,17 +693,22 @@ static int google_rtc_audio_processing_process(struct processing_module *mod, for (int i = 0; i < cd->num_frames; i++) { for (channel = 0; channel < cd->num_aec_reference_channels; ++channel) { cd->aec_reference_buffer_ptrs[channel][i] = - convert_uint16_to_float_hifi(ref[channel]); + convert_int16_to_google_aec_format(ref[channel]); } ref += cd->num_aec_reference_channels; if ((void *)ref >= (void *)ref_buf_end) ref = (void *)ref_buf_start; } +#if CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API GoogleRtcAudioProcessingAnalyzeRender_float32( cd->state, (const float **)cd->aec_reference_buffer_ptrs); - +#else + GoogleRtcAudioProcessingAnalyzeRender_int16( + cd->state, + (const int16_t *)cd->aec_reference_buffer); +#endif source_release_data(ref_stream, num_of_bytes_to_process); /* process main stream - de interlace and convert */ @@ -702,7 +721,7 @@ static int google_rtc_audio_processing_process(struct processing_module *mod, for (int i = 0; i < cd->num_frames; i++) { for (channel = 0; channel < cd->num_capture_channels; channel++) cd->process_buffer_ptrs[channel][i] = - convert_uint16_to_float_hifi(src[channel]); + convert_int16_to_google_aec_format(src[channel]); src += cd->num_capture_channels; if ((void *)src >= (void *)src_buf_end) @@ -712,9 +731,15 @@ static int google_rtc_audio_processing_process(struct processing_module *mod, source_release_data(src_stream, num_of_bytes_to_process); /* call the library, use same in/out buffers */ +#if CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API GoogleRtcAudioProcessingProcessCapture_float32(cd->state, (const float **)cd->process_buffer_ptrs, cd->process_buffer_ptrs); +#else + GoogleRtcAudioProcessingProcessCapture_int16(cd->state, + (const int16_t *)cd->process_buffer, + cd->process_buffer); +#endif /* same numnber of bytes to process for output stream as for mic stream */ ret = sink_get_buffer(dst_stream, num_of_bytes_to_process, (void **)&dst, @@ -724,8 +749,8 @@ static int google_rtc_audio_processing_process(struct processing_module *mod, for (int i = 0; i < cd->num_frames; i++) { for (channel = 0; channel < cd->num_capture_channels; channel++) - dst[channel] = - convert_float_to_uint16_hifi(cd->process_buffer_ptrs[channel][i]); + dst[channel] = convert_google_aec_format_to_int16( + cd->process_buffer_ptrs[channel][i]); dst += cd->num_capture_channels; if ((void *)dst >= (void *)dst_buf_end) dst = (void *)dst_buf_start; diff --git a/src/audio/google/google_rtc_audio_processing_mock.c b/src/audio/google/google_rtc_audio_processing_mock.c index 07f2f02bd722..a20a31ae1a6c 100644 --- a/src/audio/google/google_rtc_audio_processing_mock.c +++ b/src/audio/google/google_rtc_audio_processing_mock.c @@ -10,6 +10,9 @@ #include #include +#include +#include + #include #include "ipc/topology.h" @@ -21,7 +24,11 @@ struct GoogleRtcAudioProcessingState { int num_aec_reference_channels; int num_output_channels; int num_frames; +#if CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API float *aec_reference; +#else + int16_t *aec_reference; +#endif }; static void SetFormats(GoogleRtcAudioProcessingState *const state, @@ -138,13 +145,14 @@ int GoogleRtcAudioProcessingReconfigure(GoogleRtcAudioProcessingState *const sta return 0; } +#if CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API int GoogleRtcAudioProcessingProcessCapture_float32(GoogleRtcAudioProcessingState *const state, const float *const *src, float * const *dest) { float *ref = state->aec_reference; float **mic = (float **)src; - int n, chan, ref_chan; + int n, chan; for (chan = 0; chan < state->num_output_channels; chan++) { for (n = 0; n < state->num_frames; ++n) { @@ -174,6 +182,44 @@ int GoogleRtcAudioProcessingAnalyzeRender_float32(GoogleRtcAudioProcessingState return 0; } +#else /* CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API */ +int GoogleRtcAudioProcessingProcessCapture_int16(GoogleRtcAudioProcessingState *const state, + const int16_t *const src, + int16_t *const dest) +{ + int16_t *ref = state->aec_reference; + int16_t *mic = (int16_t *) src; + int16_t *out = dest; + int n, chan; + + for (chan = 0; chan < state->num_output_channels; chan++) { + for (n = 0; n < state->num_frames; ++n) { + int16_t mic_save = mic[n + (chan * state->num_frames)]; + + if (chan < state->num_aec_reference_channels) + dest[n + (chan * state->num_frames)] = + mic_save + ref[n + (chan * state->num_frames)]; + else + dest[n + (chan * state->num_frames)] = mic_save; + } + } + + return 0; +} + +int GoogleRtcAudioProcessingAnalyzeRender_int16(GoogleRtcAudioProcessingState *const state, + const int16_t *const data) +{ + const size_t buffer_size = + sizeof(state->aec_reference[0]) + * state->num_frames + * state->num_aec_reference_channels; + memcpy_s(state->aec_reference, buffer_size, + data, buffer_size); + return 0; +} + +#endif /* CONFIG_COMP_GOOGLE_RTC_USE_32_BIT_FLOAT_API */ void GoogleRtcAudioProcessingParseSofConfigMessage(uint8_t *message, size_t message_size,