Skip to content

Commit

Permalink
AEC: add a kConfig switch to use 16int or 32float API
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
marcinszkudlinski committed Dec 22, 2023
1 parent 23e36d6 commit ae5361c
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 12 deletions.
8 changes: 8 additions & 0 deletions src/audio/google/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
47 changes: 36 additions & 11 deletions src/audio/google/google_rtc_audio_processing.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -602,17 +609,24 @@ 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;

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 */
Expand Down Expand Up @@ -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 */
Expand All @@ -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)
Expand All @@ -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,
Expand All @@ -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;
Expand Down
48 changes: 47 additions & 1 deletion src/audio/google/google_rtc_audio_processing_mock.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include <string.h>
#include <stdint.h>

#include <sof/audio/format.h>
#include <sof/math/numbers.h>

#include <rtos/alloc.h>
#include "ipc/topology.h"

Expand All @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit ae5361c

Please sign in to comment.