1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2021 Google LLC.
4 //
5 // Author: Lionel Koenig <lionelk@google.com>
6 #include "google_rtc_audio_processing.h"
7 #include "google_rtc_audio_processing_sof_message_reader.h"
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdint.h>
12
13 #include <rtos/alloc.h>
14 #include "ipc/topology.h"
15
16 #define GOOGLE_RTC_AUDIO_PROCESSING_FREQENCY_TO_PERIOD_FRAMES 100
17 #define GOOGLE_RTC_AUDIO_PROCESSING_MS_PER_SECOND 1000
18
19 struct GoogleRtcAudioProcessingState {
20 int num_capture_channels;
21 int num_aec_reference_channels;
22 int num_output_channels;
23 int num_frames;
24 int16_t *aec_reference;
25 };
26
SetFormats(GoogleRtcAudioProcessingState * const state,int capture_sample_rate_hz,int num_capture_input_channels,int num_capture_output_channels,int render_sample_rate_hz,int num_render_channels)27 static void SetFormats(GoogleRtcAudioProcessingState *const state,
28 int capture_sample_rate_hz,
29 int num_capture_input_channels,
30 int num_capture_output_channels,
31 int render_sample_rate_hz,
32 int num_render_channels)
33 {
34 state->num_capture_channels = num_capture_input_channels;
35 state->num_output_channels = num_capture_output_channels;
36 state->num_frames = capture_sample_rate_hz /
37 GOOGLE_RTC_AUDIO_PROCESSING_FREQENCY_TO_PERIOD_FRAMES;
38
39 state->num_aec_reference_channels = num_render_channels;
40 rfree(state->aec_reference);
41 state->aec_reference = rballoc(0,
42 SOF_MEM_CAPS_RAM,
43 sizeof(state->aec_reference[0]) *
44 state->num_frames *
45 state->num_aec_reference_channels);
46 }
47
GoogleRtcAudioProcessingAttachMemoryBuffer(uint8_t * const buffer,int buffer_size)48 void GoogleRtcAudioProcessingAttachMemoryBuffer(uint8_t *const buffer,
49 int buffer_size)
50 {
51 }
52
GoogleRtcAudioProcessingDetachMemoryBuffer(void)53 void GoogleRtcAudioProcessingDetachMemoryBuffer(void)
54 {
55 }
56
GoogleRtcAudioProcessingCreateWithConfig(int capture_sample_rate_hz,int num_capture_input_channels,int num_capture_output_channels,int render_sample_rate_hz,int num_render_channels,const uint8_t * const config,int config_size)57 GoogleRtcAudioProcessingState *GoogleRtcAudioProcessingCreateWithConfig(int capture_sample_rate_hz,
58 int num_capture_input_channels,
59 int num_capture_output_channels,
60 int render_sample_rate_hz,
61 int num_render_channels,
62 const uint8_t *const config,
63 int config_size)
64 {
65 struct GoogleRtcAudioProcessingState *s =
66 rballoc(0, SOF_MEM_CAPS_RAM, sizeof(GoogleRtcAudioProcessingState));
67 if (!s)
68 return NULL;
69
70 s->aec_reference = NULL;
71 SetFormats(s,
72 capture_sample_rate_hz,
73 num_capture_input_channels,
74 num_capture_output_channels,
75 render_sample_rate_hz,
76 num_render_channels);
77
78 if (!s->aec_reference) {
79 rfree(s);
80 return NULL;
81 }
82 return s;
83 }
84
GoogleRtcAudioProcessingCreate(void)85 GoogleRtcAudioProcessingState *GoogleRtcAudioProcessingCreate(void)
86 {
87 return GoogleRtcAudioProcessingCreateWithConfig(CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING_SAMPLE_RATE_HZ,
88 1,
89 1,
90 CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING_SAMPLE_RATE_HZ,
91 2,
92 NULL,
93 0);
94 }
95
GoogleRtcAudioProcessingFree(GoogleRtcAudioProcessingState * state)96 void GoogleRtcAudioProcessingFree(GoogleRtcAudioProcessingState *state)
97 {
98 if (state != NULL) {
99 rfree(state->aec_reference);
100 rfree(state);
101 }
102 }
103
GoogleRtcAudioProcessingSetStreamFormats(GoogleRtcAudioProcessingState * const state,int capture_sample_rate_hz,int num_capture_input_channels,int num_capture_output_channels,int render_sample_rate_hz,int num_render_channels)104 int GoogleRtcAudioProcessingSetStreamFormats(GoogleRtcAudioProcessingState *const state,
105 int capture_sample_rate_hz,
106 int num_capture_input_channels,
107 int num_capture_output_channels,
108 int render_sample_rate_hz,
109 int num_render_channels)
110 {
111 SetFormats(state,
112 capture_sample_rate_hz,
113 num_capture_input_channels,
114 num_capture_output_channels,
115 render_sample_rate_hz,
116 num_render_channels);
117 return 0;
118 }
119
GoogleRtcAudioProcessingParameters(GoogleRtcAudioProcessingState * const state,float * capture_headroom_linear,float * echo_path_delay_ms)120 int GoogleRtcAudioProcessingParameters(GoogleRtcAudioProcessingState *const state,
121 float *capture_headroom_linear,
122 float *echo_path_delay_ms)
123 {
124 return 0;
125 }
126
GoogleRtcAudioProcessingGetFramesizeInMs(GoogleRtcAudioProcessingState * state)127 int GoogleRtcAudioProcessingGetFramesizeInMs(GoogleRtcAudioProcessingState *state)
128 {
129 return state->num_frames *
130 GOOGLE_RTC_AUDIO_PROCESSING_MS_PER_SECOND /
131 CONFIG_COMP_GOOGLE_RTC_AUDIO_PROCESSING_SAMPLE_RATE_HZ;
132 }
133
GoogleRtcAudioProcessingReconfigure(GoogleRtcAudioProcessingState * const state,const uint8_t * const config,int config_size)134 int GoogleRtcAudioProcessingReconfigure(GoogleRtcAudioProcessingState *const state,
135 const uint8_t *const config,
136 int config_size)
137 {
138 return 0;
139 }
140
GoogleRtcAudioProcessingProcessCapture_int16(GoogleRtcAudioProcessingState * const state,const int16_t * const src,int16_t * const dest)141 int GoogleRtcAudioProcessingProcessCapture_int16(GoogleRtcAudioProcessingState *const state,
142 const int16_t *const src,
143 int16_t *const dest)
144 {
145 int16_t *ref = state->aec_reference;
146 int16_t *mic = (int16_t *) src;
147 int16_t *out = dest;
148 int n;
149
150 memset(dest, 0, sizeof(int16_t) * state->num_output_channels * state->num_frames);
151 for (n = 0; n < state->num_frames; ++n) {
152 *out = *mic + *ref;
153 ref += state->num_aec_reference_channels;
154 out += state->num_output_channels;
155 mic += state->num_capture_channels;
156 }
157 return 0;
158 }
159
GoogleRtcAudioProcessingAnalyzeRender_int16(GoogleRtcAudioProcessingState * const state,const int16_t * const data)160 int GoogleRtcAudioProcessingAnalyzeRender_int16(GoogleRtcAudioProcessingState *const state,
161 const int16_t *const data)
162 {
163 const size_t buffer_size =
164 sizeof(state->aec_reference[0])
165 * state->num_frames
166 * state->num_aec_reference_channels;
167 memcpy_s(state->aec_reference, buffer_size,
168 data, buffer_size);
169 return 0;
170 }
171
GoogleRtcAudioProcessingParseSofConfigMessage(uint8_t * message,size_t message_size,uint8_t ** google_rtc_audio_processing_config,size_t * google_rtc_audio_processing_config_size,int * num_capture_input_channels,int * num_capture_output_channels,float * aec_reference_delay,float * mic_gain,bool * google_rtc_audio_processing_config_present,bool * num_capture_input_channels_present,bool * num_capture_output_channels_present,bool * aec_reference_delay_present,bool * mic_gain_present)172 void GoogleRtcAudioProcessingParseSofConfigMessage(uint8_t *message,
173 size_t message_size,
174 uint8_t **google_rtc_audio_processing_config,
175 size_t *google_rtc_audio_processing_config_size,
176 int *num_capture_input_channels,
177 int *num_capture_output_channels,
178 float *aec_reference_delay,
179 float *mic_gain,
180 bool *google_rtc_audio_processing_config_present,
181 bool *num_capture_input_channels_present,
182 bool *num_capture_output_channels_present,
183 bool *aec_reference_delay_present,
184 bool *mic_gain_present)
185 {
186 *google_rtc_audio_processing_config = NULL;
187 *google_rtc_audio_processing_config_size = 0;
188 *num_capture_input_channels = 1;
189 *num_capture_output_channels = 1;
190 *aec_reference_delay = 0;
191 *mic_gain = 1;
192 *google_rtc_audio_processing_config_present = false;
193 *num_capture_input_channels_present = false;
194 *num_capture_output_channels_present = false;
195 *aec_reference_delay_present = false;
196 *mic_gain_present = false;
197 }
198