1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 *
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <stdarg.h>
11 #include <signal.h>
12
13 #include "uvoice_types.h"
14
15 #include "uvoice_os.h"
16 #include "uvoice_common.h"
17 #include "uvoice_audio.h"
18 #include "audio_common.h"
19 #include "audio_stream.h"
20 #include "audio_process.h"
21 #include "audio_aec.h"
22
23
24 #define AEC_REFER_DELAY_MS 10
25
26
audio_out_process(struct out_stream * out,uint8_t * buffer,int nbytes)27 int audio_out_process(struct out_stream *out, uint8_t *buffer, int nbytes)
28 {
29 if (!out) {
30 snd_err("out null !\n");
31 return -1;
32 }
33
34 #ifdef UVOICE_EQ_ENABLE
35 equalizer_process(&out->pcm.config, buffer, nbytes);
36 #endif
37
38 return 0;
39 }
40
audio_out_process_init(struct audio_device * adev,struct out_stream * out)41 int audio_out_process_init(struct audio_device *adev, struct out_stream *out)
42 {
43 #ifdef UVOICE_EQ_ENABLE
44 struct pcm_config *config;
45 int period_size;
46 int bits;
47
48 if (!adev || !out) {
49 snd_err("args null !\n");
50 return -1;
51 }
52
53 config = &out->pcm.config;
54 bits = pcm_format_to_bits(config->format);
55 period_size = period_samples_to_bytes(config);
56
57 if (adev->equalizer_enable && !out->eq) {
58 out->eq = equalizer_create(period_size,
59 config->rate, bits, config->channels);
60 if (!out->eq) {
61 snd_err("create equalizer failed !\n");
62 return -1;
63 }
64 }
65 #endif
66
67 return 0;
68 }
69
audio_out_process_deinit(struct out_stream * out)70 int audio_out_process_deinit(struct out_stream *out)
71 {
72 #ifdef UVOICE_EQ_ENABLE
73 if (!out) {
74 snd_err("out null !\n");
75 return -1;
76 }
77
78 if (out->eq) {
79 equalizer_release(out->eq);
80 out->eq = NULL;
81 }
82 #endif
83 return 0;
84 }
85
audio_out_conserve(struct audio_device * adev,uint8_t * buffer,int nbytes)86 int audio_out_conserve(struct audio_device *adev, uint8_t *buffer,
87 int nbytes)
88 {
89 struct in_stream *in;
90
91 in = adev->in;
92 if (!in)
93 goto __exit;
94
95 #ifdef UVOICE_AEC_ENABLE
96 if (in->state == STREAM_RUNNING) {
97 if (in->aec)
98 return audio_aec_refer_conserve(in->aec, buffer, nbytes);
99 }
100 #endif
101
102 __exit:
103 return 0;
104 }
105
audio_in_process(struct in_stream * in,uint8_t * buffer,int nbytes)106 int audio_in_process(struct in_stream *in, uint8_t *buffer, int nbytes)
107 {
108 if (!in) {
109 snd_err("stream null !\n");
110 return -1;
111 }
112
113 if (!buffer) {
114 snd_err("buffer null !\n");
115 return -1;
116 }
117
118 #ifdef UVOICE_AEC_ENABLE
119 if (in->aec) {
120 if (audio_aec_process(in->aec, buffer, nbytes)) {
121 snd_err("aec process failed !\n");
122 return -1;
123 }
124 }
125 #endif
126
127 #ifdef UVOICE_ANC_ENABLE
128 if (in->ns) {
129 if (noise_suppression_process(in->ns, buffer, nbytes)) {
130 snd_err("ns process failed !\n");
131 return -1;
132 }
133 }
134 #endif
135
136 #ifdef UVOICE_AGC_ENABLE
137 if (in->agc) {
138 if (auto_gain_control_process(in->agc, buffer, nbytes)) {
139 snd_err("agc process failed !\n");
140 return -1;
141 }
142 }
143 #endif
144
145 return 0;
146 }
147
audio_in_process_init(struct audio_device * adev,struct in_stream * in)148 int audio_in_process_init(struct audio_device *adev, struct in_stream *in)
149 {
150 struct pcm_config *config;
151 int bits;
152
153 if (!adev || !in) {
154 snd_err("args null !\n");
155 return -1;
156 }
157
158 #ifdef UVOICE_ANC_ENABLE
159 if (adev->noise_suppression) {
160 in->ns = snd_zalloc(sizeof(struct noise_suppression), AFM_EXTN);
161 if (!in->ns) {
162 snd_err("alloc noise supression struct failed !\n");
163 return -1;
164 }
165 }
166 #endif
167
168 #ifdef UVOICE_AGC_ENABLE
169 if (adev->auto_gain_control) {
170 in->agc = snd_zalloc(sizeof(struct auto_gain_control), AFM_EXTN);
171 if (!in->agc) {
172 snd_err("alloc auto gain control struct failed !\n");
173 if (in->ns) {
174 snd_free(in->ns);
175 in->ns = NULL;
176 }
177 return -1;
178 }
179 }
180 #endif
181
182 config = &in->pcm.config;
183 bits = pcm_format_to_bits(config->format);
184
185 #ifdef UVOICE_ANC_ENABLE
186 if (in->ns) {
187 if (noise_suppression_create(in->ns,
188 config->rate, bits, config->period_size, 3)) {
189 snd_err("create ns failed !\n");
190 audio_in_process_deinit(in);
191 return -1;
192 }
193 }
194 #endif
195
196 #ifdef UVOICE_AGC_ENABLE
197 if (in->agc) {
198 if (auto_gain_control_create(in->agc,
199 config->rate, bits, config->period_size)) {
200 snd_err("create agc failed !\n");
201 audio_in_process_deinit(in);
202 return -1;
203 }
204 }
205 #endif
206
207 #ifdef UVOICE_AEC_ENABLE
208 if (adev->echo_cancellation) {
209 if (audio_aec_init(in)) {
210 snd_err("init audio aec failed !\n");
211 audio_in_process_deinit(in);
212 return -1;
213 }
214 }
215 #endif
216
217 return 0;
218 }
219
audio_in_process_deinit(struct in_stream * in)220 int audio_in_process_deinit(struct in_stream *in)
221 {
222 if (!in) {
223 snd_err("stream null !\n");
224 return -1;
225 }
226
227 #ifdef UVOICE_AEC_ENABLE
228 if (in->aec)
229 audio_aec_deinit(in);
230 #endif
231
232 #ifdef UVOICE_ANC_ENABLE
233 if (in->ns) {
234 noise_suppression_release(in->ns);
235 snd_free(in->ns);
236 in->ns = NULL;
237 }
238 #endif
239
240 #ifdef UVOICE_AGC_ENABLE
241 if (in->agc) {
242 auto_gain_control_release(in->agc);
243 snd_free(in->agc);
244 in->agc = NULL;
245 }
246 #endif
247
248 return 0;
249 }
250
251