From 82361d86a2923b49e2947540744d4816a98982c0 Mon Sep 17 00:00:00 2001 From: Ben Zhang Date: Tue, 8 Mar 2022 15:18:13 +0100 Subject: [PATCH] google_rtc_audio_processing: Add config controls 1. Added a byte control to accept Google RTC audio processing configuration blob `name='GOOGLE_RTC_PROCESSING10.0 Config'` Tested using: sof-ctl -n 48 -t 0 -b -r -s /root/tuning.bin And verified correct audio processing behaviour on a alderlake board. Signed-off-by: Ben Zhang Signed-off-by: Lionel Koenig --- src/audio/google_rtc_audio_processing.c | 51 +++++++++++++++++++ src/audio/google_rtc_audio_processing_mock.c | 19 ++++--- .../include/google_rtc_audio_processing.h | 22 +++++--- .../m4/google_rtc_audio_processing.m4 | 7 ++- .../m4/google_rtc_audio_processing_default.m4 | 22 +++----- ...ipe-google-rtc-audio-processing-capture.m4 | 25 +++++---- 6 files changed, 104 insertions(+), 42 deletions(-) diff --git a/src/audio/google_rtc_audio_processing.c b/src/audio/google_rtc_audio_processing.c index 551c392902bf..f64262bf3c3d 100644 --- a/src/audio/google_rtc_audio_processing.c +++ b/src/audio/google_rtc_audio_processing.c @@ -84,6 +84,39 @@ static int google_rtc_audio_processing_params( return 0; } +static int google_rtc_audio_processing_reconfigure(struct comp_dev *dev) +{ + struct google_rtc_audio_processing_comp_data *cd = comp_get_drvdata(dev); + uint8_t *config; + size_t size; + int ret; + + comp_dbg(dev, "google_rtc_audio_processing_reconfigure()"); + + config = comp_get_data_blob(cd->tuning_handler, &size, NULL); + if (size == 0) { + /* No data to be handled */ + return 0; + } + + if (!config) { + comp_err(dev, "google_rtc_audio_processing_reconfigure(): Tuning config not set"); + return -EINVAL; + } + + comp_info(dev, "google_rtc_audio_processing_reconfigure(): New tuning config %p (%zu bytes)", + config, size); + + ret = GoogleRtcAudioProcessingReconfigure(cd->state, config, size); + if (ret) { + comp_err(dev, "GoogleRtcAudioProcessingReconfigure failed: %d", + ret); + return -EINVAL; + } + + return 0; +} + static int google_rtc_audio_processing_cmd_set_data( struct comp_dev *dev, struct sof_ipc_ctrl_data *cdata) @@ -129,6 +162,9 @@ static int google_rtc_audio_processing_cmd(struct comp_dev *dev, int cmd, void * comp_dbg(dev, "google_rtc_audio_processing_cmd(): %d - data_cmd: %d", cmd, cdata->cmd); switch (cmd) { + case COMP_CMD_SET_VALUE: + case COMP_CMD_GET_VALUE: + return 0; case COMP_CMD_SET_DATA: return google_rtc_audio_processing_cmd_set_data(dev, cdata); case COMP_CMD_GET_DATA: @@ -246,6 +282,7 @@ static int google_rtc_audio_processing_prepare(struct comp_dev *dev) struct google_rtc_audio_processing_comp_data *cd = comp_get_drvdata(dev); struct comp_buffer *source_buffer; struct list_item *source_buffer_list_item; + int ret; comp_dbg(dev, "google_rtc_audio_processing_prepare()"); @@ -288,6 +325,13 @@ static int google_rtc_audio_processing_prepare(struct comp_dev *dev) return -EINVAL; } + /* Blobs sent during COMP_STATE_READY is assigned to blob_handler->data + * directly, so comp_is_new_data_blob_available always returns false. + */ + ret = google_rtc_audio_processing_reconfigure(dev); + if (ret) + return ret; + return comp_set_state(dev, COMP_TRIGGER_PREPARE); } @@ -312,6 +356,13 @@ static int google_rtc_audio_processing_copy(struct comp_dev *dev) uint32_t num_aec_reference_frames; uint32_t num_aec_reference_bytes; int channel; + int ret; + + if (comp_is_new_data_blob_available(cd->tuning_handler)) { + ret = google_rtc_audio_processing_reconfigure(dev); + if (ret) + return ret; + } cd->aec_reference = buffer_acquire(cd->aec_reference); num_aec_reference_frames = audio_stream_get_avail_frames(&cd->aec_reference->stream); diff --git a/src/audio/google_rtc_audio_processing_mock.c b/src/audio/google_rtc_audio_processing_mock.c index 1c38c36aeaed..de7fd15df6ea 100644 --- a/src/audio/google_rtc_audio_processing_mock.c +++ b/src/audio/google_rtc_audio_processing_mock.c @@ -31,11 +31,11 @@ GoogleRtcAudioProcessingState *GoogleRtcAudioProcessingCreate() s->num_output_channels = 1; s->num_frames = GOOGLE_RTC_AUDIO_PROCESSING_SAMPLE_RATE_HZ * 10 / 1000; s->aec_reference = rballoc(0, - SOF_MEM_CAPS_RAM, - sizeof(s->aec_reference[0]) * - s->num_frames * - s->num_aec_reference_channels - ); + SOF_MEM_CAPS_RAM, + sizeof(s->aec_reference[0]) * + s->num_frames * + s->num_aec_reference_channels + ); return s; } @@ -52,6 +52,13 @@ int GoogleRtcAudioProcessingGetFramesizeInMs(GoogleRtcAudioProcessingState *stat return state->num_frames * 1000 / GOOGLE_RTC_AUDIO_PROCESSING_SAMPLE_RATE_HZ; } +int GoogleRtcAudioProcessingReconfigure( + GoogleRtcAudioProcessingState * const state, const uint8_t *const config, + int config_size) +{ + return 0; +} + int GoogleRtcAudioProcessingProcessCapture_int16( GoogleRtcAudioProcessingState *const state, const int16_t *const src, int16_t *const dest) @@ -78,6 +85,6 @@ int GoogleRtcAudioProcessingAnalyzeRender_int16( * state->num_frames * state->num_aec_reference_channels; memcpy_s(state->aec_reference, buffer_size, - data, buffer_size); + data, buffer_size); return 0; } diff --git a/third_party/include/google_rtc_audio_processing.h b/third_party/include/google_rtc_audio_processing.h index 6832391311ec..fcc401c3214a 100644 --- a/third_party/include/google_rtc_audio_processing.h +++ b/third_party/include/google_rtc_audio_processing.h @@ -26,7 +26,13 @@ void GoogleRtcAudioProcessingFree(GoogleRtcAudioProcessingState *state); // Returns the framesize used for processing. int GoogleRtcAudioProcessingGetFramesizeInMs( - GoogleRtcAudioProcessingState *state); + GoogleRtcAudioProcessingState *const state); + +// Reconfigure the audio processing. +// Returns 0 if success and non zero if failure. +int GoogleRtcAudioProcessingReconfigure( + GoogleRtcAudioProcessingState *const state, const uint8_t *const config, + int config_size); // Processes the microphone stream. // Accepts deinterleaved float audio with the range [-1, 1]. Each element of @@ -34,30 +40,30 @@ int GoogleRtcAudioProcessingGetFramesizeInMs( // will be in |dest|. // Returns 0 if success and non zero if failure. int GoogleRtcAudioProcessingProcessCapture_float32( - GoogleRtcAudioProcessingState *const state, const float *const *src, - float *const *dest); + GoogleRtcAudioProcessingState *const state, const float *const *src, + float *const *dest); // Accepts and and produces a frame of interleaved 16 bit integer audio. `src` // and `dest` may use the same memory, if desired. // Returns 0 if success and non zero if failure. int GoogleRtcAudioProcessingProcessCapture_int16( - GoogleRtcAudioProcessingState *const state, const int16_t *const src, - int16_t *const dest); + GoogleRtcAudioProcessingState *const state, const int16_t *const src, + int16_t *const dest); // Analyzes the playback stream. // Accepts deinterleaved float audio with the range [-1, 1]. Each element // of |src| points to an array of samples for the channel. // Returns 0 if success and non zero if failure. int GoogleRtcAudioProcessingAnalyzeRender_float32( - GoogleRtcAudioProcessingState *const state, const float *const *src); + GoogleRtcAudioProcessingState *const state, const float *const *src); // Accepts interleaved int16 audio. // Returns 0 if success and non zero if failure. int GoogleRtcAudioProcessingAnalyzeRender_int16( - GoogleRtcAudioProcessingState *const state, const int16_t *const src); + GoogleRtcAudioProcessingState *const state, const int16_t *const src); #ifdef __cplusplus } #endif -#endif // GOOGLE_RTC_AUDIO_PROCESSING_H +#endif // GOOGLE_RTC_AUDIO_PROCESSING_H diff --git a/tools/topology/topology1/m4/google_rtc_audio_processing.m4 b/tools/topology/topology1/m4/google_rtc_audio_processing.m4 index 1cea9dbbf0b5..8489b6717ba7 100644 --- a/tools/topology/topology1/m4/google_rtc_audio_processing.m4 +++ b/tools/topology/topology1/m4/google_rtc_audio_processing.m4 @@ -7,7 +7,7 @@ DECLARE_SOF_RT_UUID("google-rtc-audio-processing", google_rtc_audio_processing_u dnl N_GOOGLE_RTC_AUDIO_PROCESSING(name) define(`N_GOOGLE_RTC_AUDIO_PROCESSING', `GOOGLE_RTC_AUDIO_PROCESSING'PIPELINE_ID`.'$1) -dnl W_GOOGLE_RTC_AUDIO_PROCESSING(name, format, periods_sink, periods_source, core, kcontrols_list) +dnl W_GOOGLE_RTC_AUDIO_PROCESSING(name, format, periods_sink, periods_source, core, mixer_kcontrols_list, byte_kcontrols_list) define(`W_GOOGLE_RTC_AUDIO_PROCESSING', `SectionVendorTuples."'N_GOOGLE_RTC_AUDIO_PROCESSING($1)`_tuples_uuid" {' ` tokens "sof_comp_tokens"' @@ -57,9 +57,12 @@ define(`W_GOOGLE_RTC_AUDIO_PROCESSING', ` "'N_GOOGLE_RTC_AUDIO_PROCESSING($1)`_data_str"' ` "'N_GOOGLE_RTC_AUDIO_PROCESSING($1)`_data_str_type"' ` ]' -` bytes [' +` mixer [' $6 ` ]' +` bytes [' + $7 +` ]' `}') divert(0)dnl diff --git a/tools/topology/topology1/m4/google_rtc_audio_processing_default.m4 b/tools/topology/topology1/m4/google_rtc_audio_processing_default.m4 index 047129d4c22c..388cc9175a05 100644 --- a/tools/topology/topology1/m4/google_rtc_audio_processing_default.m4 +++ b/tools/topology/topology1/m4/google_rtc_audio_processing_default.m4 @@ -1,20 +1,10 @@ +# Google RTC Audio Processing initial config. +# Empty configuration +# sof_abi_hdr.size = 0 +# sof_abi_hdr.type = 0 (BINARY_DATA) CONTROLBYTES_PRIV(GOOGLE_RTC_AUDIO_PROCESSING_priv, ` bytes "0x53,0x4f,0x46,0x00,0x00,0x00,0x00,0x00,' -` 0x6c,0x00,0x00,0x00,0x00,0x20,0x01,0x03,' +` 0x00,0x00,0x00,0x00,0x00,0x50,0x01,0x03,' ` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' -` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' -` 0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' -` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' -` 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,' -` 0x00,0x00,0x00,0xe8,0x00,0x00,0x00,0x1e,' -` 0x00,0x00,0x00,0x01,0xd3,0x4d,0x62,0x00,' -` 0xb1,0xc2,0x09,0x04,0x00,0x00,0x00,0x40,' -` 0xa6,0x99,0x01,0x00,0xce,0xd8,0x0f,0x0a,' -` 0x1f,0x1a,0xf0,0xf5,0x83,0xc9,0xfe,0x01,' -` 0xdf,0x30,0x61,0x3a,0xcb,0x83,0x0e,0x01,' -` 0xef,0x84,0x73,0x01,0x6d,0x64,0x6b,0xff,' -` 0x03,0x41,0x22,0x00,0x05,0x00,0x00,0x00,' -` 0x00,0x10,0xf8,0x00,0xaa,0x81,0x10,0x00,' -` 0xf4,0xf0,0x8a,0x00,0xaa,0xe1,0x22,0x00,' -` 0xb9,0x9b,0x02,0x00"' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00"' ) diff --git a/tools/topology/topology1/sof/pipe-google-rtc-audio-processing-capture.m4 b/tools/topology/topology1/sof/pipe-google-rtc-audio-processing-capture.m4 index 9ec7aaa772b9..13a8a82c5de9 100644 --- a/tools/topology/topology1/sof/pipe-google-rtc-audio-processing-capture.m4 +++ b/tools/topology/topology1/sof/pipe-google-rtc-audio-processing-capture.m4 @@ -16,16 +16,20 @@ include(`bytecontrol.m4') include(`enumcontrol.m4') include(`google_rtc_audio_processing.m4') -define(GOOGLE_RTC_AUDIO_PROCESSING_priv, concat(`google_rtc_audio_processing_bytes_', PIPELINE_ID)) -define(GOOGLE_RTC_AUDIO_PROCESSING_CTRL, concat(`google_rtc_audio_processing_control_', PIPELINE_ID)) +# +# Controls +# + include(`google_rtc_audio_processing_default.m4') -C_CONTROLBYTES(GOOGLE_RTC_AUDIO_PROCESSING_CTRL, PIPELINE_ID, - CONTROLBYTES_OPS(bytes, 258 binds the control to bytes get/put handlers, 258, 258), - CONTROLBYTES_EXTOPS(258 binds the control to bytes get/put handlers, 258, 258), - , , , - CONTROLBYTES_MAX(, 2048), - , - GOOGLE_RTC_AUDIO_PROCESSING_priv) + +# Byte control for AEC tuning data +C_CONTROLBYTES(`Config', PIPELINE_ID, + CONTROLBYTES_OPS(bytes, 258 binds the control to bytes get/put handlers, 258, 258), + CONTROLBYTES_EXTOPS(258 binds the control to bytes get/put handlers, 258, 258), + , , , + CONTROLBYTES_MAX(, 2048), + , + GOOGLE_RTC_AUDIO_PROCESSING_priv) # # Components and Buffers @@ -36,7 +40,8 @@ C_CONTROLBYTES(GOOGLE_RTC_AUDIO_PROCESSING_CTRL, PIPELINE_ID, W_PCM_CAPTURE(PCM_ID, Google RTC Audio Processing, 0, DAI_PERIODS, SCHEDULE_CORE) W_GOOGLE_RTC_AUDIO_PROCESSING(0, PIPELINE_FORMAT, 2, DAI_PERIODS, SCHEDULE_CORE, - LIST(` ', "GOOGLE_RTC_AUDIO_PROCESSING_CTRL")) + `', + LIST(` ', "Config")) # Capture Buffers W_BUFFER(0, COMP_BUFFER_SIZE(2,