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