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