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