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
11 #include "uvoice_os.h"
12 #include "uvoice_audio.h"
13 #include "audio_common.h"
14 #include "audio_stream.h"
15
16 #include "opensource/webrtc/modules/audio_processing/ns/noise_suppression_x.h"
17
18
19 typedef struct {
20 short *in[2];
21 short *out[2];
22 int32_t *filter_state[4];
23 int samples;
24 int band_samples;
25 int band_num;
26 NsxHandle *inst;
27 } webrtc_ns_t;
28
29
ns_buffer_alloc(webrtc_ns_t * webrtc_ns)30 static int ns_buffer_alloc(webrtc_ns_t *webrtc_ns)
31 {
32 int i;
33
34 if (!webrtc_ns) {
35 snd_err("webrtc_ns null !\n");
36 return -1;
37 }
38
39 for (i = 0; i < webrtc_ns->band_num; i++) {
40 webrtc_ns->in[i] = snd_zalloc(
41 webrtc_ns->band_samples * sizeof(short), AFM_MAIN);
42 if (!webrtc_ns->in) {
43 snd_err("alloc in buffer failed !\n");
44 return -1;
45 }
46
47 webrtc_ns->out[i] = snd_zalloc(
48 webrtc_ns->band_samples * sizeof(short), AFM_MAIN);
49 if (!webrtc_ns->out) {
50 snd_err("alloc out buffer failed !\n");
51 return -1;
52 }
53 }
54
55 if (webrtc_ns->band_num == 2) {
56 for (i = 0; i < 4; i++) {
57 webrtc_ns->filter_state[i] = snd_zalloc(
58 6 * sizeof(int32_t), AFM_MAIN);
59 if (!webrtc_ns->filter_state[i]) {
60 snd_err("alloc filter state failed !\n");
61 return -1;
62 }
63 }
64 }
65
66 return 0;
67 }
68
ns_buffer_free(webrtc_ns_t * webrtc_ns)69 static int ns_buffer_free(webrtc_ns_t *webrtc_ns)
70 {
71 int i;
72
73 if (!webrtc_ns) {
74 snd_err("webrtc_ns null !\n");
75 return -1;
76 }
77
78 for (i = 0; i < 4; i++) {
79 if (webrtc_ns->filter_state[i]) {
80 snd_free(webrtc_ns->filter_state[i]);
81 webrtc_ns->filter_state[i] = NULL;
82 }
83 }
84
85 for (i = 0; i < webrtc_ns->band_num; i++) {
86 if (webrtc_ns->in[i]) {
87 snd_free(webrtc_ns->in[i]);
88 webrtc_ns->in[i] = NULL;
89 }
90
91 if (webrtc_ns->out[i]) {
92 snd_free(webrtc_ns->out[i]);
93 webrtc_ns->out[i] = NULL;
94 }
95 }
96
97 return 0;
98 }
99
noise_suppression_process(struct noise_suppression * ns,uint8_t * buffer,int nbytes)100 int noise_suppression_process(struct noise_suppression *ns,
101 uint8_t *buffer, int nbytes)
102 {
103 webrtc_ns_t *webrtc_ns;
104 int proc_size;
105 int ret;
106 int i;
107
108 if (!ns) {
109 snd_err("ns null !\n");
110 return -1;
111 }
112
113 webrtc_ns = ns->handler;
114 if (!webrtc_ns) {
115 snd_err("webrtc_ns null !\n");
116 return -1;
117 }
118
119 proc_size = webrtc_ns->samples * sizeof(short);
120
121 if (nbytes % proc_size != 0) {
122 snd_err("invalid input size !\n");
123 return -1;
124 }
125
126 if (webrtc_ns->band_num == 1) {
127 for (i = 0; i < nbytes; i += proc_size) {
128 memcpy(webrtc_ns->in[0], buffer + i, proc_size);
129 WebRtcNsx_Process(webrtc_ns->inst,
130 webrtc_ns->in, 1, webrtc_ns->out);
131 memcpy(buffer + i, webrtc_ns->out[0], proc_size);
132 }
133 } else if (webrtc_ns->band_num == 2) {
134 for (i = 0; i < nbytes; i += proc_size) {
135 WebRtcSpl_AnalysisQMF(buffer + i,
136 webrtc_ns->samples,
137 webrtc_ns->in[0],
138 webrtc_ns->in[1],
139 webrtc_ns->filter_state[0],
140 webrtc_ns->filter_state[1]);
141
142 WebRtcNsx_Process(webrtc_ns->inst,
143 webrtc_ns->in, 2, webrtc_ns->out);
144
145 WebRtcSpl_SynthesisQMF(webrtc_ns->out[0],
146 webrtc_ns->out[1],
147 webrtc_ns->band_samples,
148 buffer + i,
149 webrtc_ns->filter_state[2],
150 webrtc_ns->filter_state[3]);
151 }
152 }
153
154 return 0;
155 }
156
noise_suppression_create(struct noise_suppression * ns,int rate,int bits,int samples,int mode)157 int noise_suppression_create(struct noise_suppression *ns,
158 int rate, int bits, int samples, int mode)
159 {
160 webrtc_ns_t *webrtc_ns;
161 int ret;
162
163 if (!ns) {
164 snd_err("ns null !\n");
165 return -1;
166 }
167
168 if (bits != 16) {
169 snd_err("bits %d ns not support !\n", bits);
170 return -1;
171 }
172
173 if (samples % (rate / 100) != 0) {
174 snd_err("samples and rate not mulitple !\n");
175 return -1;
176 }
177
178 webrtc_ns = snd_zalloc(sizeof(webrtc_ns_t), AFM_EXTN);
179 if (!webrtc_ns) {
180 snd_err("alloc webrtc ns failed !\n");
181 return -1;
182 }
183
184 webrtc_ns->inst = WebRtcNsx_Create();
185 if (!webrtc_ns->inst) {
186 snd_err("create webrtc nsx failed !\n");
187 snd_free(webrtc_ns);
188 return -1;
189 }
190
191 ret = WebRtcNsx_Init(webrtc_ns->inst, rate);
192 if (ret) {
193 snd_err("init webrtc nsx failed !\n");
194 WebRtcNsx_Free(webrtc_ns->inst);
195 snd_free(webrtc_ns);
196 return -1;
197 }
198
199 webrtc_ns->samples = rate / 100;
200 if (rate == 48000 || rate == 32000) {
201 webrtc_ns->band_num = 2;
202 webrtc_ns->band_samples = webrtc_ns->samples / 2;
203 } else {
204 webrtc_ns->band_num = 1;
205 webrtc_ns->band_samples = webrtc_ns->samples;
206 }
207
208 ret = WebRtcNsx_set_policy(webrtc_ns->inst, mode);
209 if (ret) {
210 snd_err("set webrtc policy failed %d!\n", ret);
211 WebRtcNsx_Free(webrtc_ns->inst);
212 snd_free(webrtc_ns);
213 return -1;
214 }
215
216 if (ns_buffer_alloc(webrtc_ns)) {
217 snd_err("alloc ns buffer failed !\n");
218 ns_buffer_free(webrtc_ns);
219 WebRtcNsx_Free(webrtc_ns->inst);
220 snd_free(webrtc_ns);
221 return -1;
222 }
223
224 snd_info("noise suppression create\n");
225 ns->handler = webrtc_ns;
226 return 0;
227 }
228
noise_suppression_release(struct noise_suppression * ns)229 int noise_suppression_release(struct noise_suppression *ns)
230 {
231 webrtc_ns_t *webrtc_ns;
232
233 if (!ns) {
234 snd_err("ns null !\n");
235 return -1;
236 }
237
238 webrtc_ns = ns->handler;
239 if (!webrtc_ns) {
240 snd_err("webrtc_ns null !\n");
241 return -1;
242 }
243
244 ns_buffer_free(webrtc_ns);
245
246 WebRtcNsx_Free(webrtc_ns->inst);
247 snd_free(webrtc_ns);
248 ns->handler = NULL;
249
250 snd_info("noise suppression release\n");
251 return 0;
252 }
253
254