1 /*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/audio_coding/codecs/isac/main/source/isac_vad.h"
12
13 #include <math.h>
14
WebRtcIsac_InitPitchFilter(PitchFiltstr * pitchfiltdata)15 void WebRtcIsac_InitPitchFilter(PitchFiltstr* pitchfiltdata) {
16 int k;
17
18 for (k = 0; k < PITCH_BUFFSIZE; k++) {
19 pitchfiltdata->ubuf[k] = 0.0;
20 }
21 pitchfiltdata->ystate[0] = 0.0;
22 for (k = 1; k < (PITCH_DAMPORDER); k++) {
23 pitchfiltdata->ystate[k] = 0.0;
24 }
25 pitchfiltdata->oldlagp[0] = 50.0;
26 pitchfiltdata->oldgainp[0] = 0.0;
27 }
28
WebRtcIsac_InitWeightingFilter(WeightFiltstr * wfdata)29 static void WebRtcIsac_InitWeightingFilter(WeightFiltstr* wfdata) {
30 int k;
31 double t, dtmp, dtmp2, denum, denum2;
32
33 for (k = 0; k < PITCH_WLPCBUFLEN; k++)
34 wfdata->buffer[k] = 0.0;
35
36 for (k = 0; k < PITCH_WLPCORDER; k++) {
37 wfdata->istate[k] = 0.0;
38 wfdata->weostate[k] = 0.0;
39 wfdata->whostate[k] = 0.0;
40 }
41
42 /* next part should be in Matlab, writing to a global table */
43 t = 0.5;
44 denum = 1.0 / ((double)PITCH_WLPCWINLEN);
45 denum2 = denum * denum;
46 for (k = 0; k < PITCH_WLPCWINLEN; k++) {
47 dtmp = PITCH_WLPCASYM * t * denum + (1 - PITCH_WLPCASYM) * t * t * denum2;
48 dtmp *= 3.14159265;
49 dtmp2 = sin(dtmp);
50 wfdata->window[k] = dtmp2 * dtmp2;
51 t++;
52 }
53 }
54
WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct * State)55 void WebRtcIsac_InitPitchAnalysis(PitchAnalysisStruct* State) {
56 int k;
57
58 for (k = 0; k < PITCH_CORR_LEN2 + PITCH_CORR_STEP2 + PITCH_MAX_LAG / 2 -
59 PITCH_FRAME_LEN / 2 + 2;
60 k++)
61 State->dec_buffer[k] = 0.0;
62 for (k = 0; k < 2 * ALLPASSSECTIONS + 1; k++)
63 State->decimator_state[k] = 0.0;
64 for (k = 0; k < 2; k++)
65 State->hp_state[k] = 0.0;
66 for (k = 0; k < QLOOKAHEAD; k++)
67 State->whitened_buf[k] = 0.0;
68 for (k = 0; k < QLOOKAHEAD; k++)
69 State->inbuf[k] = 0.0;
70
71 WebRtcIsac_InitPitchFilter(&(State->PFstr_wght));
72
73 WebRtcIsac_InitPitchFilter(&(State->PFstr));
74
75 WebRtcIsac_InitWeightingFilter(&(State->Wghtstr));
76 }
77
WebRtcIsac_InitPreFilterbank(PreFiltBankstr * prefiltdata)78 void WebRtcIsac_InitPreFilterbank(PreFiltBankstr* prefiltdata) {
79 int k;
80
81 for (k = 0; k < QLOOKAHEAD; k++) {
82 prefiltdata->INLABUF1[k] = 0;
83 prefiltdata->INLABUF2[k] = 0;
84
85 prefiltdata->INLABUF1_float[k] = 0;
86 prefiltdata->INLABUF2_float[k] = 0;
87 }
88 for (k = 0; k < 2 * (QORDER - 1); k++) {
89 prefiltdata->INSTAT1[k] = 0;
90 prefiltdata->INSTAT2[k] = 0;
91 prefiltdata->INSTATLA1[k] = 0;
92 prefiltdata->INSTATLA2[k] = 0;
93
94 prefiltdata->INSTAT1_float[k] = 0;
95 prefiltdata->INSTAT2_float[k] = 0;
96 prefiltdata->INSTATLA1_float[k] = 0;
97 prefiltdata->INSTATLA2_float[k] = 0;
98 }
99
100 /* High pass filter states */
101 prefiltdata->HPstates[0] = 0.0;
102 prefiltdata->HPstates[1] = 0.0;
103
104 prefiltdata->HPstates_float[0] = 0.0f;
105 prefiltdata->HPstates_float[1] = 0.0f;
106
107 return;
108 }
109
WebRtcIsac_LevDurb(double * a,double * k,double * r,size_t order)110 double WebRtcIsac_LevDurb(double* a, double* k, double* r, size_t order) {
111 const double LEVINSON_EPS = 1.0e-10;
112
113 double sum, alpha;
114 size_t m, m_h, i;
115 alpha = 0; // warning -DH
116 a[0] = 1.0;
117 if (r[0] < LEVINSON_EPS) { /* if r[0] <= 0, set LPC coeff. to zero */
118 for (i = 0; i < order; i++) {
119 k[i] = 0;
120 a[i + 1] = 0;
121 }
122 } else {
123 a[1] = k[0] = -r[1] / r[0];
124 alpha = r[0] + r[1] * k[0];
125 for (m = 1; m < order; m++) {
126 sum = r[m + 1];
127 for (i = 0; i < m; i++) {
128 sum += a[i + 1] * r[m - i];
129 }
130 k[m] = -sum / alpha;
131 alpha += k[m] * sum;
132 m_h = (m + 1) >> 1;
133 for (i = 0; i < m_h; i++) {
134 sum = a[i + 1] + k[m] * a[m - i];
135 a[m - i] += k[m] * a[i + 1];
136 a[i + 1] = sum;
137 }
138 a[m + 1] = k[m];
139 }
140 }
141 return alpha;
142 }
143
144 /* The upper channel all-pass filter factors */
145 const float WebRtcIsac_kUpperApFactorsFloat[2] = {0.03470000000000f,
146 0.38260000000000f};
147
148 /* The lower channel all-pass filter factors */
149 const float WebRtcIsac_kLowerApFactorsFloat[2] = {0.15440000000000f,
150 0.74400000000000f};
151
152 /* This function performs all-pass filtering--a series of first order all-pass
153 * sections are used to filter the input in a cascade manner.
154 * The input is overwritten!!
155 */
WebRtcIsac_AllPassFilter2Float(float * InOut,const float * APSectionFactors,int lengthInOut,int NumberOfSections,float * FilterState)156 void WebRtcIsac_AllPassFilter2Float(float* InOut,
157 const float* APSectionFactors,
158 int lengthInOut,
159 int NumberOfSections,
160 float* FilterState) {
161 int n, j;
162 float temp;
163 for (j = 0; j < NumberOfSections; j++) {
164 for (n = 0; n < lengthInOut; n++) {
165 temp = FilterState[j] + APSectionFactors[j] * InOut[n];
166 FilterState[j] = -APSectionFactors[j] * temp + InOut[n];
167 InOut[n] = temp;
168 }
169 }
170 }
171
172 /* The number of composite all-pass filter factors */
173 #define NUMBEROFCOMPOSITEAPSECTIONS 4
174
175 /* Function WebRtcIsac_SplitAndFilter
176 * This function creates low-pass and high-pass decimated versions of part of
177 the input signal, and part of the signal in the input 'lookahead buffer'.
178
179 INPUTS:
180 in: a length FRAMESAMPLES array of input samples
181 prefiltdata: input data structure containing the filterbank states
182 and lookahead samples from the previous encoding
183 iteration.
184 OUTPUTS:
185 LP: a FRAMESAMPLES_HALF array of low-pass filtered samples that
186 have been phase equalized. The first QLOOKAHEAD samples are
187 based on the samples in the two prefiltdata->INLABUFx arrays
188 each of length QLOOKAHEAD.
189 The remaining FRAMESAMPLES_HALF-QLOOKAHEAD samples are based
190 on the first FRAMESAMPLES_HALF-QLOOKAHEAD samples of the input
191 array in[].
192 HP: a FRAMESAMPLES_HALF array of high-pass filtered samples that
193 have been phase equalized. The first QLOOKAHEAD samples are
194 based on the samples in the two prefiltdata->INLABUFx arrays
195 each of length QLOOKAHEAD.
196 The remaining FRAMESAMPLES_HALF-QLOOKAHEAD samples are based
197 on the first FRAMESAMPLES_HALF-QLOOKAHEAD samples of the input
198 array in[].
199
200 LP_la: a FRAMESAMPLES_HALF array of low-pass filtered samples.
201 These samples are not phase equalized. They are computed
202 from the samples in the in[] array.
203 HP_la: a FRAMESAMPLES_HALF array of high-pass filtered samples
204 that are not phase equalized. They are computed from
205 the in[] vector.
206 prefiltdata: this input data structure's filterbank state and
207 lookahead sample buffers are updated for the next
208 encoding iteration.
209 */
WebRtcIsac_SplitAndFilterFloat(float * pin,float * LP,float * HP,double * LP_la,double * HP_la,PreFiltBankstr * prefiltdata)210 void WebRtcIsac_SplitAndFilterFloat(float* pin,
211 float* LP,
212 float* HP,
213 double* LP_la,
214 double* HP_la,
215 PreFiltBankstr* prefiltdata) {
216 int k, n;
217 float CompositeAPFilterState[NUMBEROFCOMPOSITEAPSECTIONS];
218 float ForTransform_CompositeAPFilterState[NUMBEROFCOMPOSITEAPSECTIONS];
219 float ForTransform_CompositeAPFilterState2[NUMBEROFCOMPOSITEAPSECTIONS];
220 float tempinoutvec[FRAMESAMPLES + MAX_AR_MODEL_ORDER];
221 float tempin_ch1[FRAMESAMPLES + MAX_AR_MODEL_ORDER];
222 float tempin_ch2[FRAMESAMPLES + MAX_AR_MODEL_ORDER];
223 float in[FRAMESAMPLES];
224 float ftmp;
225
226 /* HPstcoeff_in = {a1, a2, b1 - b0 * a1, b2 - b0 * a2}; */
227 static const float kHpStCoefInFloat[4] = {
228 -1.94895953203325f, 0.94984516000000f, -0.05101826139794f,
229 0.05015484000000f};
230
231 /* The composite all-pass filter factors */
232 static const float WebRtcIsac_kCompositeApFactorsFloat[4] = {
233 0.03470000000000f, 0.15440000000000f, 0.38260000000000f,
234 0.74400000000000f};
235
236 // The matrix for transforming the backward composite state to upper channel
237 // state.
238 static const float WebRtcIsac_kTransform1Float[8] = {
239 -0.00158678506084f, 0.00127157815343f, -0.00104805672709f,
240 0.00084837248079f, 0.00134467983258f, -0.00107756549387f,
241 0.00088814793277f, -0.00071893072525f};
242
243 // The matrix for transforming the backward composite state to lower channel
244 // state.
245 static const float WebRtcIsac_kTransform2Float[8] = {
246 -0.00170686041697f, 0.00136780109829f, -0.00112736532350f,
247 0.00091257055385f, 0.00103094281812f, -0.00082615076557f,
248 0.00068092756088f, -0.00055119165484f};
249
250 /* High pass filter */
251
252 for (k = 0; k < FRAMESAMPLES; k++) {
253 in[k] = pin[k] + kHpStCoefInFloat[2] * prefiltdata->HPstates_float[0] +
254 kHpStCoefInFloat[3] * prefiltdata->HPstates_float[1];
255 ftmp = pin[k] - kHpStCoefInFloat[0] * prefiltdata->HPstates_float[0] -
256 kHpStCoefInFloat[1] * prefiltdata->HPstates_float[1];
257 prefiltdata->HPstates_float[1] = prefiltdata->HPstates_float[0];
258 prefiltdata->HPstates_float[0] = ftmp;
259 }
260
261 /* First Channel */
262
263 /*initial state of composite filter is zero */
264 for (k = 0; k < NUMBEROFCOMPOSITEAPSECTIONS; k++) {
265 CompositeAPFilterState[k] = 0.0;
266 }
267 /* put every other sample of input into a temporary vector in reverse
268 * (backward) order*/
269 for (k = 0; k < FRAMESAMPLES_HALF; k++) {
270 tempinoutvec[k] = in[FRAMESAMPLES - 1 - 2 * k];
271 }
272
273 /* now all-pass filter the backwards vector. Output values overwrite the
274 * input vector. */
275 WebRtcIsac_AllPassFilter2Float(
276 tempinoutvec, WebRtcIsac_kCompositeApFactorsFloat, FRAMESAMPLES_HALF,
277 NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
278
279 /* save the backwards filtered output for later forward filtering,
280 but write it in forward order*/
281 for (k = 0; k < FRAMESAMPLES_HALF; k++) {
282 tempin_ch1[FRAMESAMPLES_HALF + QLOOKAHEAD - 1 - k] = tempinoutvec[k];
283 }
284
285 /* save the backwards filter state becaue it will be transformed
286 later into a forward state */
287 for (k = 0; k < NUMBEROFCOMPOSITEAPSECTIONS; k++) {
288 ForTransform_CompositeAPFilterState[k] = CompositeAPFilterState[k];
289 }
290
291 /* now backwards filter the samples in the lookahead buffer. The samples were
292 placed there in the encoding of the previous frame. The output samples
293 overwrite the input samples */
294 WebRtcIsac_AllPassFilter2Float(
295 prefiltdata->INLABUF1_float, WebRtcIsac_kCompositeApFactorsFloat,
296 QLOOKAHEAD, NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
297
298 /* save the output, but write it in forward order */
299 /* write the lookahead samples for the next encoding iteration. Every other
300 sample at the end of the input frame is written in reverse order for the
301 lookahead length. Exported in the prefiltdata structure. */
302 for (k = 0; k < QLOOKAHEAD; k++) {
303 tempin_ch1[QLOOKAHEAD - 1 - k] = prefiltdata->INLABUF1_float[k];
304 prefiltdata->INLABUF1_float[k] = in[FRAMESAMPLES - 1 - 2 * k];
305 }
306
307 /* Second Channel. This is exactly like the first channel, except that the
308 even samples are now filtered instead (lower channel). */
309 for (k = 0; k < NUMBEROFCOMPOSITEAPSECTIONS; k++) {
310 CompositeAPFilterState[k] = 0.0;
311 }
312
313 for (k = 0; k < FRAMESAMPLES_HALF; k++) {
314 tempinoutvec[k] = in[FRAMESAMPLES - 2 - 2 * k];
315 }
316
317 WebRtcIsac_AllPassFilter2Float(
318 tempinoutvec, WebRtcIsac_kCompositeApFactorsFloat, FRAMESAMPLES_HALF,
319 NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
320
321 for (k = 0; k < FRAMESAMPLES_HALF; k++) {
322 tempin_ch2[FRAMESAMPLES_HALF + QLOOKAHEAD - 1 - k] = tempinoutvec[k];
323 }
324
325 for (k = 0; k < NUMBEROFCOMPOSITEAPSECTIONS; k++) {
326 ForTransform_CompositeAPFilterState2[k] = CompositeAPFilterState[k];
327 }
328
329 WebRtcIsac_AllPassFilter2Float(
330 prefiltdata->INLABUF2_float, WebRtcIsac_kCompositeApFactorsFloat,
331 QLOOKAHEAD, NUMBEROFCOMPOSITEAPSECTIONS, CompositeAPFilterState);
332
333 for (k = 0; k < QLOOKAHEAD; k++) {
334 tempin_ch2[QLOOKAHEAD - 1 - k] = prefiltdata->INLABUF2_float[k];
335 prefiltdata->INLABUF2_float[k] = in[FRAMESAMPLES - 2 - 2 * k];
336 }
337
338 /* Transform filter states from backward to forward */
339 /*At this point, each of the states of the backwards composite filters for the
340 two channels are transformed into forward filtering states for the
341 corresponding forward channel filters. Each channel's forward filtering
342 state from the previous
343 encoding iteration is added to the transformed state to get a proper forward
344 state */
345
346 /* So the existing NUMBEROFCOMPOSITEAPSECTIONS x 1 (4x1) state vector is
347 multiplied by a NUMBEROFCHANNELAPSECTIONSxNUMBEROFCOMPOSITEAPSECTIONS (2x4)
348 transform matrix to get the new state that is added to the previous 2x1
349 input state */
350
351 for (k = 0; k < NUMBEROFCHANNELAPSECTIONS; k++) { /* k is row variable */
352 for (n = 0; n < NUMBEROFCOMPOSITEAPSECTIONS;
353 n++) { /* n is column variable */
354 prefiltdata->INSTAT1_float[k] +=
355 ForTransform_CompositeAPFilterState[n] *
356 WebRtcIsac_kTransform1Float[k * NUMBEROFCHANNELAPSECTIONS + n];
357 prefiltdata->INSTAT2_float[k] +=
358 ForTransform_CompositeAPFilterState2[n] *
359 WebRtcIsac_kTransform2Float[k * NUMBEROFCHANNELAPSECTIONS + n];
360 }
361 }
362
363 /*obtain polyphase components by forward all-pass filtering through each
364 * channel */
365 /* the backward filtered samples are now forward filtered with the
366 * corresponding channel filters */
367 /* The all pass filtering automatically updates the filter states which are
368 exported in the prefiltdata structure */
369 WebRtcIsac_AllPassFilter2Float(tempin_ch1, WebRtcIsac_kUpperApFactorsFloat,
370 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,
371 prefiltdata->INSTAT1_float);
372 WebRtcIsac_AllPassFilter2Float(tempin_ch2, WebRtcIsac_kLowerApFactorsFloat,
373 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,
374 prefiltdata->INSTAT2_float);
375
376 /* Now Construct low-pass and high-pass signals as combinations of polyphase
377 * components */
378 for (k = 0; k < FRAMESAMPLES_HALF; k++) {
379 LP[k] = 0.5f * (tempin_ch1[k] + tempin_ch2[k]); /* low pass signal*/
380 HP[k] = 0.5f * (tempin_ch1[k] - tempin_ch2[k]); /* high pass signal*/
381 }
382
383 /* Lookahead LP and HP signals */
384 /* now create low pass and high pass signals of the input vector. However, no
385 backwards filtering is performed, and hence no phase equalization is
386 involved. Also, the input contains some samples that are lookahead samples.
387 The high pass and low pass signals that are created are used outside this
388 function for analysis (not encoding) purposes */
389
390 /* set up input */
391 for (k = 0; k < FRAMESAMPLES_HALF; k++) {
392 tempin_ch1[k] = in[2 * k + 1];
393 tempin_ch2[k] = in[2 * k];
394 }
395
396 /* the input filter states are passed in and updated by the all-pass filtering
397 routine and exported in the prefiltdata structure*/
398 WebRtcIsac_AllPassFilter2Float(tempin_ch1, WebRtcIsac_kUpperApFactorsFloat,
399 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,
400 prefiltdata->INSTATLA1_float);
401 WebRtcIsac_AllPassFilter2Float(tempin_ch2, WebRtcIsac_kLowerApFactorsFloat,
402 FRAMESAMPLES_HALF, NUMBEROFCHANNELAPSECTIONS,
403 prefiltdata->INSTATLA2_float);
404
405 for (k = 0; k < FRAMESAMPLES_HALF; k++) {
406 LP_la[k] = (float)(0.5f * (tempin_ch1[k] + tempin_ch2[k])); /*low pass */
407 HP_la[k] = (double)(0.5f * (tempin_ch1[k] - tempin_ch2[k])); /* high pass */
408 }
409 }
410