Line data Source code
1 : /*
2 : * Copyright (c) 2012 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 : /*
12 : * entropy_coding.c
13 : *
14 : * This header file defines all of the functions used to arithmetically
15 : * encode the iSAC bistream
16 : *
17 : */
18 :
19 :
20 : #include "entropy_coding.h"
21 : #include "settings.h"
22 : #include "arith_routines.h"
23 : #include "signal_processing_library.h"
24 : #include "spectrum_ar_model_tables.h"
25 : #include "lpc_tables.h"
26 : #include "pitch_gain_tables.h"
27 : #include "pitch_lag_tables.h"
28 : #include "encode_lpc_swb.h"
29 : #include "lpc_shape_swb12_tables.h"
30 : #include "lpc_shape_swb16_tables.h"
31 : #include "lpc_gain_swb_tables.h"
32 : #include "os_specific_inline.h"
33 :
34 : #include <math.h>
35 : #include <string.h>
36 :
37 : static const uint16_t kLpcVecPerSegmentUb12 = 5;
38 : static const uint16_t kLpcVecPerSegmentUb16 = 4;
39 :
40 : /* CDF array for encoder bandwidth (12 vs 16 kHz) indicator. */
41 : static const uint16_t kOneBitEqualProbCdf[3] = {
42 : 0, 32768, 65535 };
43 :
44 : /* Pointer to cdf array for encoder bandwidth (12 vs 16 kHz) indicator. */
45 : static const uint16_t* kOneBitEqualProbCdf_ptr[1] = {
46 : kOneBitEqualProbCdf };
47 :
48 : /*
49 : * Initial cdf index for decoder of encoded bandwidth
50 : * (12 vs 16 kHz) indicator.
51 : */
52 : static const uint16_t kOneBitEqualProbInitIndex[1] = { 1 };
53 :
54 :
55 : static const int kIsSWB12 = 1;
56 :
57 : /* compute correlation from power spectrum */
58 0 : static void FindCorrelation(int32_t* PSpecQ12, int32_t* CorrQ7) {
59 : int32_t summ[FRAMESAMPLES / 8];
60 : int32_t diff[FRAMESAMPLES / 8];
61 : const int16_t* CS_ptrQ9;
62 : int32_t sum;
63 : int k, n;
64 :
65 0 : for (k = 0; k < FRAMESAMPLES / 8; k++) {
66 0 : summ[k] = (PSpecQ12[k] + PSpecQ12[FRAMESAMPLES_QUARTER - 1 - k] + 16) >> 5;
67 0 : diff[k] = (PSpecQ12[k] - PSpecQ12[FRAMESAMPLES_QUARTER - 1 - k] + 16) >> 5;
68 : }
69 :
70 0 : sum = 2;
71 0 : for (n = 0; n < FRAMESAMPLES / 8; n++) {
72 0 : sum += summ[n];
73 : }
74 0 : CorrQ7[0] = sum;
75 :
76 0 : for (k = 0; k < AR_ORDER; k += 2) {
77 0 : sum = 0;
78 0 : CS_ptrQ9 = WebRtcIsac_kCos[k];
79 0 : for (n = 0; n < FRAMESAMPLES / 8; n++)
80 0 : sum += (CS_ptrQ9[n] * diff[n] + 256) >> 9;
81 0 : CorrQ7[k + 1] = sum;
82 : }
83 :
84 0 : for (k = 1; k < AR_ORDER; k += 2) {
85 0 : sum = 0;
86 0 : CS_ptrQ9 = WebRtcIsac_kCos[k];
87 0 : for (n = 0; n < FRAMESAMPLES / 8; n++)
88 0 : sum += (CS_ptrQ9[n] * summ[n] + 256) >> 9;
89 0 : CorrQ7[k + 1] = sum;
90 : }
91 0 : }
92 :
93 : /* compute inverse AR power spectrum */
94 : /* Changed to the function used in iSAC FIX for compatibility reasons */
95 0 : static void FindInvArSpec(const int16_t* ARCoefQ12,
96 : const int32_t gainQ10,
97 : int32_t* CurveQ16) {
98 : int32_t CorrQ11[AR_ORDER + 1];
99 : int32_t sum, tmpGain;
100 : int32_t diffQ16[FRAMESAMPLES / 8];
101 : const int16_t* CS_ptrQ9;
102 : int k, n;
103 0 : int16_t round, shftVal = 0, sh;
104 :
105 0 : sum = 0;
106 0 : for (n = 0; n < AR_ORDER + 1; n++) {
107 0 : sum += WEBRTC_SPL_MUL(ARCoefQ12[n], ARCoefQ12[n]); /* Q24 */
108 : }
109 0 : sum = ((sum >> 6) * 65 + 32768) >> 16; /* Q8 */
110 0 : CorrQ11[0] = (sum * gainQ10 + 256) >> 9;
111 :
112 : /* To avoid overflow, we shift down gainQ10 if it is large.
113 : * We will not lose any precision */
114 0 : if (gainQ10 > 400000) {
115 0 : tmpGain = gainQ10 >> 3;
116 0 : round = 32;
117 0 : shftVal = 6;
118 : } else {
119 0 : tmpGain = gainQ10;
120 0 : round = 256;
121 0 : shftVal = 9;
122 : }
123 :
124 0 : for (k = 1; k < AR_ORDER + 1; k++) {
125 0 : sum = 16384;
126 0 : for (n = k; n < AR_ORDER + 1; n++)
127 0 : sum += WEBRTC_SPL_MUL(ARCoefQ12[n - k], ARCoefQ12[n]); /* Q24 */
128 0 : sum >>= 15;
129 0 : CorrQ11[k] = (sum * tmpGain + round) >> shftVal;
130 : }
131 0 : sum = CorrQ11[0] << 7;
132 0 : for (n = 0; n < FRAMESAMPLES / 8; n++) {
133 0 : CurveQ16[n] = sum;
134 : }
135 0 : for (k = 1; k < AR_ORDER; k += 2) {
136 0 : for (n = 0; n < FRAMESAMPLES / 8; n++) {
137 0 : CurveQ16[n] += (WebRtcIsac_kCos[k][n] * CorrQ11[k + 1] + 2) >> 2;
138 : }
139 : }
140 :
141 0 : CS_ptrQ9 = WebRtcIsac_kCos[0];
142 :
143 : /* If CorrQ11[1] too large we avoid getting overflow in the
144 : * calculation by shifting */
145 0 : sh = WebRtcSpl_NormW32(CorrQ11[1]);
146 0 : if (CorrQ11[1] == 0) { /* Use next correlation */
147 0 : sh = WebRtcSpl_NormW32(CorrQ11[2]);
148 : }
149 0 : if (sh < 9) {
150 0 : shftVal = 9 - sh;
151 : } else {
152 0 : shftVal = 0;
153 : }
154 0 : for (n = 0; n < FRAMESAMPLES / 8; n++) {
155 0 : diffQ16[n] = (CS_ptrQ9[n] * (CorrQ11[1] >> shftVal) + 2) >> 2;
156 : }
157 0 : for (k = 2; k < AR_ORDER; k += 2) {
158 0 : CS_ptrQ9 = WebRtcIsac_kCos[k];
159 0 : for (n = 0; n < FRAMESAMPLES / 8; n++) {
160 0 : diffQ16[n] += (CS_ptrQ9[n] * (CorrQ11[k + 1] >> shftVal) + 2) >> 2;
161 : }
162 : }
163 :
164 0 : for (k = 0; k < FRAMESAMPLES / 8; k++) {
165 0 : int32_t diff_q16_shifted = (int32_t)((uint32_t)(diffQ16[k]) << shftVal);
166 0 : CurveQ16[FRAMESAMPLES_QUARTER - 1 - k] = CurveQ16[k] - diff_q16_shifted;
167 0 : CurveQ16[k] += diff_q16_shifted;
168 : }
169 0 : }
170 :
171 : /* Generate array of dither samples in Q7. */
172 0 : static void GenerateDitherQ7Lb(int16_t* bufQ7, uint32_t seed,
173 : int length, int16_t AvgPitchGain_Q12) {
174 : int k, shft;
175 : int16_t dither1_Q7, dither2_Q7, dither_gain_Q14;
176 :
177 : /* This threshold should be equal to that in decode_spec(). */
178 0 : if (AvgPitchGain_Q12 < 614) {
179 0 : for (k = 0; k < length - 2; k += 3) {
180 : /* New random unsigned int. */
181 0 : seed = (seed * 196314165) + 907633515;
182 :
183 : /* Fixed-point dither sample between -64 and 64 (Q7). */
184 : /* dither = seed * 128 / 4294967295 */
185 0 : dither1_Q7 = (int16_t)(((int32_t)(seed + 16777216)) >> 25);
186 :
187 : /* New random unsigned int. */
188 0 : seed = (seed * 196314165) + 907633515;
189 :
190 : /* Fixed-point dither sample between -64 and 64. */
191 0 : dither2_Q7 = (int16_t)(((int32_t)(seed + 16777216)) >> 25);
192 :
193 0 : shft = (seed >> 25) & 15;
194 0 : if (shft < 5) {
195 0 : bufQ7[k] = dither1_Q7;
196 0 : bufQ7[k + 1] = dither2_Q7;
197 0 : bufQ7[k + 2] = 0;
198 0 : } else if (shft < 10) {
199 0 : bufQ7[k] = dither1_Q7;
200 0 : bufQ7[k + 1] = 0;
201 0 : bufQ7[k + 2] = dither2_Q7;
202 : } else {
203 0 : bufQ7[k] = 0;
204 0 : bufQ7[k + 1] = dither1_Q7;
205 0 : bufQ7[k + 2] = dither2_Q7;
206 : }
207 : }
208 : } else {
209 0 : dither_gain_Q14 = (int16_t)(22528 - 10 * AvgPitchGain_Q12);
210 :
211 : /* Dither on half of the coefficients. */
212 0 : for (k = 0; k < length - 1; k += 2) {
213 : /* New random unsigned int */
214 0 : seed = (seed * 196314165) + 907633515;
215 :
216 : /* Fixed-point dither sample between -64 and 64. */
217 0 : dither1_Q7 = (int16_t)(((int32_t)(seed + 16777216)) >> 25);
218 :
219 : /* Dither sample is placed in either even or odd index. */
220 0 : shft = (seed >> 25) & 1; /* Either 0 or 1 */
221 :
222 0 : bufQ7[k + shft] = (((dither_gain_Q14 * dither1_Q7) + 8192) >> 14);
223 0 : bufQ7[k + 1 - shft] = 0;
224 : }
225 : }
226 0 : }
227 :
228 :
229 :
230 : /******************************************************************************
231 : * GenerateDitherQ7LbUB()
232 : *
233 : * generate array of dither samples in Q7 There are less zeros in dither
234 : * vector compared to GenerateDitherQ7Lb.
235 : *
236 : * A uniform random number generator with the range of [-64 64] is employed
237 : * but the generated dithers are scaled by 0.35, a heuristic scaling.
238 : *
239 : * Input:
240 : * -seed : the initial seed for the random number generator.
241 : * -length : the number of dither values to be generated.
242 : *
243 : * Output:
244 : * -bufQ7 : pointer to a buffer where dithers are written to.
245 : */
246 0 : static void GenerateDitherQ7LbUB(
247 : int16_t* bufQ7,
248 : uint32_t seed,
249 : int length) {
250 : int k;
251 0 : for (k = 0; k < length; k++) {
252 : /* new random unsigned int */
253 0 : seed = (seed * 196314165) + 907633515;
254 :
255 : /* Fixed-point dither sample between -64 and 64 (Q7). */
256 : /* bufQ7 = seed * 128 / 4294967295 */
257 0 : bufQ7[k] = (int16_t)(((int32_t)(seed + 16777216)) >> 25);
258 :
259 : /* Scale by 0.35. */
260 0 : bufQ7[k] = (int16_t)WEBRTC_SPL_MUL_16_16_RSFT(bufQ7[k], 2048, 13);
261 : }
262 0 : }
263 :
264 : /*
265 : * Function to decode the complex spectrum from the bit stream
266 : * returns the total number of bytes in the stream.
267 : */
268 0 : int WebRtcIsac_DecodeSpec(Bitstr* streamdata, int16_t AvgPitchGain_Q12,
269 : enum ISACBand band, double* fr, double* fi) {
270 : int16_t DitherQ7[FRAMESAMPLES];
271 : int16_t data[FRAMESAMPLES];
272 : int32_t invARSpec2_Q16[FRAMESAMPLES_QUARTER];
273 : uint16_t invARSpecQ8[FRAMESAMPLES_QUARTER];
274 : int16_t ARCoefQ12[AR_ORDER + 1];
275 : int16_t RCQ15[AR_ORDER];
276 : int16_t gainQ10;
277 : int32_t gain2_Q10, res;
278 : int32_t in_sqrt;
279 : int32_t newRes;
280 : int k, len, i;
281 0 : int is_12khz = !kIsSWB12;
282 0 : int num_dft_coeff = FRAMESAMPLES;
283 : /* Create dither signal. */
284 0 : if (band == kIsacLowerBand) {
285 0 : GenerateDitherQ7Lb(DitherQ7, streamdata->W_upper, FRAMESAMPLES,
286 : AvgPitchGain_Q12);
287 : } else {
288 0 : GenerateDitherQ7LbUB(DitherQ7, streamdata->W_upper, FRAMESAMPLES);
289 0 : if (band == kIsacUpperBand12) {
290 0 : is_12khz = kIsSWB12;
291 0 : num_dft_coeff = FRAMESAMPLES_HALF;
292 : }
293 : }
294 :
295 : /* Decode model parameters. */
296 0 : if (WebRtcIsac_DecodeRc(streamdata, RCQ15) < 0)
297 0 : return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
298 :
299 0 : WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
300 :
301 0 : if (WebRtcIsac_DecodeGain2(streamdata, &gain2_Q10) < 0)
302 0 : return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
303 :
304 : /* Compute inverse AR power spectrum. */
305 0 : FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16);
306 :
307 : /* Convert to magnitude spectrum,
308 : * by doing square-roots (modified from SPLIB). */
309 0 : res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1);
310 0 : for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
311 0 : in_sqrt = invARSpec2_Q16[k];
312 0 : i = 10;
313 :
314 : /* Negative values make no sense for a real sqrt-function. */
315 0 : if (in_sqrt < 0)
316 0 : in_sqrt = -in_sqrt;
317 :
318 0 : newRes = (in_sqrt / res + res) >> 1;
319 : do {
320 0 : res = newRes;
321 0 : newRes = (in_sqrt / res + res) >> 1;
322 0 : } while (newRes != res && i-- > 0);
323 :
324 0 : invARSpecQ8[k] = (int16_t)newRes;
325 : }
326 :
327 0 : len = WebRtcIsac_DecLogisticMulti2(data, streamdata, invARSpecQ8, DitherQ7,
328 : num_dft_coeff, is_12khz);
329 : /* Arithmetic decoding of spectrum. */
330 0 : if (len < 1) {
331 0 : return -ISAC_RANGE_ERROR_DECODE_SPECTRUM;
332 : }
333 :
334 0 : switch (band) {
335 : case kIsacLowerBand: {
336 : /* Scale down spectral samples with low SNR. */
337 : int32_t p1;
338 : int32_t p2;
339 0 : if (AvgPitchGain_Q12 <= 614) {
340 0 : p1 = 30 << 10;
341 0 : p2 = 32768 + (33 << 16);
342 : } else {
343 0 : p1 = 36 << 10;
344 0 : p2 = 32768 + (40 << 16);
345 : }
346 0 : for (k = 0; k < FRAMESAMPLES; k += 4) {
347 0 : gainQ10 = WebRtcSpl_DivW32W16ResW16(p1, (int16_t)(
348 0 : (invARSpec2_Q16[k >> 2] + p2) >> 16));
349 0 : *fr++ = (double)((data[ k ] * gainQ10 + 512) >> 10) / 128.0;
350 0 : *fi++ = (double)((data[k + 1] * gainQ10 + 512) >> 10) / 128.0;
351 0 : *fr++ = (double)((data[k + 2] * gainQ10 + 512) >> 10) / 128.0;
352 0 : *fi++ = (double)((data[k + 3] * gainQ10 + 512) >> 10) / 128.0;
353 : }
354 0 : break;
355 : }
356 : case kIsacUpperBand12: {
357 0 : for (k = 0, i = 0; k < FRAMESAMPLES_HALF; k += 4) {
358 0 : fr[i] = (double)data[ k ] / 128.0;
359 0 : fi[i] = (double)data[k + 1] / 128.0;
360 0 : i++;
361 0 : fr[i] = (double)data[k + 2] / 128.0;
362 0 : fi[i] = (double)data[k + 3] / 128.0;
363 0 : i++;
364 : }
365 : /* The second half of real and imaginary coefficients is zero. This is
366 : * due to using the old FFT module which requires two signals as input
367 : * while in 0-12 kHz mode we only have 8-12 kHz band, and the second
368 : * signal is set to zero. */
369 0 : memset(&fr[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER *
370 : sizeof(double));
371 0 : memset(&fi[FRAMESAMPLES_QUARTER], 0, FRAMESAMPLES_QUARTER *
372 : sizeof(double));
373 0 : break;
374 : }
375 : case kIsacUpperBand16: {
376 0 : for (i = 0, k = 0; k < FRAMESAMPLES; k += 4, i++) {
377 0 : fr[i] = (double)data[ k ] / 128.0;
378 0 : fi[i] = (double)data[k + 1] / 128.0;
379 0 : fr[(FRAMESAMPLES_HALF) - 1 - i] = (double)data[k + 2] / 128.0;
380 0 : fi[(FRAMESAMPLES_HALF) - 1 - i] = (double)data[k + 3] / 128.0;
381 : }
382 0 : break;
383 : }
384 : }
385 0 : return len;
386 : }
387 :
388 :
389 0 : int WebRtcIsac_EncodeSpec(const int16_t* fr, const int16_t* fi,
390 : int16_t AvgPitchGain_Q12, enum ISACBand band,
391 : Bitstr* streamdata) {
392 : int16_t ditherQ7[FRAMESAMPLES];
393 : int16_t dataQ7[FRAMESAMPLES];
394 : int32_t PSpec[FRAMESAMPLES_QUARTER];
395 : int32_t invARSpec2_Q16[FRAMESAMPLES_QUARTER];
396 : uint16_t invARSpecQ8[FRAMESAMPLES_QUARTER];
397 : int32_t CorrQ7[AR_ORDER + 1];
398 : int32_t CorrQ7_norm[AR_ORDER + 1];
399 : int16_t RCQ15[AR_ORDER];
400 : int16_t ARCoefQ12[AR_ORDER + 1];
401 : int32_t gain2_Q10;
402 : int16_t val;
403 : int32_t nrg, res;
404 : uint32_t sum;
405 : int32_t in_sqrt;
406 : int32_t newRes;
407 : int16_t err;
408 : uint32_t nrg_u32;
409 : int shift_var;
410 : int k, n, j, i;
411 0 : int is_12khz = !kIsSWB12;
412 0 : int num_dft_coeff = FRAMESAMPLES;
413 :
414 : /* Create dither signal. */
415 0 : if (band == kIsacLowerBand) {
416 0 : GenerateDitherQ7Lb(ditherQ7, streamdata->W_upper, FRAMESAMPLES,
417 : AvgPitchGain_Q12);
418 : } else {
419 0 : GenerateDitherQ7LbUB(ditherQ7, streamdata->W_upper, FRAMESAMPLES);
420 0 : if (band == kIsacUpperBand12) {
421 0 : is_12khz = kIsSWB12;
422 0 : num_dft_coeff = FRAMESAMPLES_HALF;
423 : }
424 : }
425 :
426 : /* add dither and quantize, and compute power spectrum */
427 0 : switch (band) {
428 : case kIsacLowerBand: {
429 0 : for (k = 0; k < FRAMESAMPLES; k += 4) {
430 0 : val = ((*fr++ + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k];
431 0 : dataQ7[k] = val;
432 0 : sum = val * val;
433 :
434 0 : val = ((*fi++ + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1];
435 0 : dataQ7[k + 1] = val;
436 0 : sum += val * val;
437 :
438 0 : val = ((*fr++ + ditherQ7[k + 2] + 64) & 0xFF80) - ditherQ7[k + 2];
439 0 : dataQ7[k + 2] = val;
440 0 : sum += val * val;
441 :
442 0 : val = ((*fi++ + ditherQ7[k + 3] + 64) & 0xFF80) - ditherQ7[k + 3];
443 0 : dataQ7[k + 3] = val;
444 0 : sum += val * val;
445 :
446 0 : PSpec[k >> 2] = sum >> 2;
447 : }
448 0 : break;
449 : }
450 : case kIsacUpperBand12: {
451 0 : for (k = 0, j = 0; k < FRAMESAMPLES_HALF; k += 4) {
452 0 : val = ((*fr++ + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k];
453 0 : dataQ7[k] = val;
454 0 : sum = val * val;
455 :
456 0 : val = ((*fi++ + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1];
457 0 : dataQ7[k + 1] = val;
458 0 : sum += val * val;
459 :
460 0 : PSpec[j++] = sum >> 1;
461 :
462 0 : val = ((*fr++ + ditherQ7[k + 2] + 64) & 0xFF80) - ditherQ7[k + 2];
463 0 : dataQ7[k + 2] = val;
464 0 : sum = val * val;
465 :
466 0 : val = ((*fi++ + ditherQ7[k + 3] + 64) & 0xFF80) - ditherQ7[k + 3];
467 0 : dataQ7[k + 3] = val;
468 0 : sum += val * val;
469 :
470 0 : PSpec[j++] = sum >> 1;
471 : }
472 0 : break;
473 : }
474 : case kIsacUpperBand16: {
475 0 : for (j = 0, k = 0; k < FRAMESAMPLES; k += 4, j++) {
476 0 : val = ((fr[j] + ditherQ7[k] + 64) & 0xFF80) - ditherQ7[k];
477 0 : dataQ7[k] = val;
478 0 : sum = val * val;
479 :
480 0 : val = ((fi[j] + ditherQ7[k + 1] + 64) & 0xFF80) - ditherQ7[k + 1];
481 0 : dataQ7[k + 1] = val;
482 0 : sum += val * val;
483 :
484 0 : val = ((fr[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k + 2] + 64) &
485 0 : 0xFF80) - ditherQ7[k + 2];
486 0 : dataQ7[k + 2] = val;
487 0 : sum += val * val;
488 :
489 0 : val = ((fi[(FRAMESAMPLES_HALF) - 1 - j] + ditherQ7[k + 3] + 64) &
490 0 : 0xFF80) - ditherQ7[k + 3];
491 0 : dataQ7[k + 3] = val;
492 0 : sum += val * val;
493 :
494 0 : PSpec[k >> 2] = sum >> 2;
495 : }
496 0 : break;
497 : }
498 : }
499 :
500 : /* compute correlation from power spectrum */
501 0 : FindCorrelation(PSpec, CorrQ7);
502 :
503 : /* Find AR coefficients */
504 : /* Aumber of bit shifts to 14-bit normalize CorrQ7[0]
505 : * (leaving room for sign) */
506 0 : shift_var = WebRtcSpl_NormW32(CorrQ7[0]) - 18;
507 :
508 0 : if (shift_var > 0) {
509 0 : for (k = 0; k < AR_ORDER + 1; k++) {
510 0 : CorrQ7_norm[k] = CorrQ7[k] << shift_var;
511 : }
512 : } else {
513 0 : for (k = 0; k < AR_ORDER + 1; k++) {
514 0 : CorrQ7_norm[k] = CorrQ7[k] >> (-shift_var);
515 : }
516 : }
517 :
518 : /* Find RC coefficients. */
519 0 : WebRtcSpl_AutoCorrToReflCoef(CorrQ7_norm, AR_ORDER, RCQ15);
520 :
521 : /* Quantize & code RC Coefficient. */
522 0 : WebRtcIsac_EncodeRc(RCQ15, streamdata);
523 :
524 : /* RC -> AR coefficients */
525 0 : WebRtcSpl_ReflCoefToLpc(RCQ15, AR_ORDER, ARCoefQ12);
526 :
527 : /* Compute ARCoef' * Corr * ARCoef in Q19. */
528 0 : nrg = 0;
529 0 : for (j = 0; j <= AR_ORDER; j++) {
530 0 : for (n = 0; n <= j; n++) {
531 0 : nrg += (ARCoefQ12[j] * ((CorrQ7_norm[j - n] * ARCoefQ12[n] + 256) >> 9) +
532 0 : 4) >> 3;
533 : }
534 0 : for (n = j + 1; n <= AR_ORDER; n++) {
535 0 : nrg += (ARCoefQ12[j] * ((CorrQ7_norm[n - j] * ARCoefQ12[n] + 256) >> 9) +
536 0 : 4) >> 3;
537 : }
538 : }
539 :
540 0 : nrg_u32 = (uint32_t)nrg;
541 0 : if (shift_var > 0) {
542 0 : nrg_u32 = nrg_u32 >> shift_var;
543 : } else {
544 0 : nrg_u32 = nrg_u32 << (-shift_var);
545 : }
546 0 : if (nrg_u32 > 0x7FFFFFFF) {
547 0 : nrg = 0x7FFFFFFF;
548 : } else {
549 0 : nrg = (int32_t)nrg_u32;
550 : }
551 : /* Also shifts 31 bits to the left! */
552 0 : gain2_Q10 = WebRtcSpl_DivResultInQ31(FRAMESAMPLES_QUARTER, nrg);
553 :
554 : /* Quantize & code gain2_Q10. */
555 0 : if (WebRtcIsac_EncodeGain2(&gain2_Q10, streamdata)) {
556 0 : return -1;
557 : }
558 :
559 : /* Compute inverse AR power spectrum. */
560 0 : FindInvArSpec(ARCoefQ12, gain2_Q10, invARSpec2_Q16);
561 : /* Convert to magnitude spectrum, by doing square-roots
562 : * (modified from SPLIB). */
563 0 : res = 1 << (WebRtcSpl_GetSizeInBits(invARSpec2_Q16[0]) >> 1);
564 0 : for (k = 0; k < FRAMESAMPLES_QUARTER; k++) {
565 0 : in_sqrt = invARSpec2_Q16[k];
566 0 : i = 10;
567 : /* Negative values make no sense for a real sqrt-function. */
568 0 : if (in_sqrt < 0) {
569 0 : in_sqrt = -in_sqrt;
570 : }
571 0 : newRes = (in_sqrt / res + res) >> 1;
572 : do {
573 0 : res = newRes;
574 0 : newRes = (in_sqrt / res + res) >> 1;
575 0 : } while (newRes != res && i-- > 0);
576 :
577 0 : invARSpecQ8[k] = (int16_t)newRes;
578 : }
579 : /* arithmetic coding of spectrum */
580 0 : err = WebRtcIsac_EncLogisticMulti2(streamdata, dataQ7, invARSpecQ8,
581 : num_dft_coeff, is_12khz);
582 0 : if (err < 0) {
583 0 : return (err);
584 : }
585 0 : return 0;
586 : }
587 :
588 :
589 : /* step-up */
590 0 : void WebRtcIsac_Rc2Poly(double* RC, int N, double* a) {
591 : int m, k;
592 : double tmp[MAX_AR_MODEL_ORDER];
593 :
594 0 : a[0] = 1.0;
595 0 : tmp[0] = 1.0;
596 0 : for (m = 1; m <= N; m++) {
597 : /* copy */
598 0 : memcpy(&tmp[1], &a[1], (m - 1) * sizeof(double));
599 0 : a[m] = RC[m - 1];
600 0 : for (k = 1; k < m; k++) {
601 0 : a[k] += RC[m - 1] * tmp[m - k];
602 : }
603 : }
604 0 : return;
605 : }
606 :
607 : /* step-down */
608 0 : void WebRtcIsac_Poly2Rc(double* a, int N, double* RC) {
609 : int m, k;
610 : double tmp[MAX_AR_MODEL_ORDER];
611 : double tmp_inv;
612 :
613 0 : RC[N - 1] = a[N];
614 0 : for (m = N - 1; m > 0; m--) {
615 0 : tmp_inv = 1.0 / (1.0 - RC[m] * RC[m]);
616 0 : for (k = 1; k <= m; k++) {
617 0 : tmp[k] = (a[k] - RC[m] * a[m - k + 1]) * tmp_inv;
618 : }
619 :
620 0 : memcpy(&a[1], &tmp[1], (m - 1) * sizeof(double));
621 0 : RC[m - 1] = tmp[m];
622 : }
623 0 : return;
624 : }
625 :
626 :
627 : #define MAX_ORDER 100
628 :
629 : /* Matlab's LAR definition */
630 0 : void WebRtcIsac_Rc2Lar(const double* refc, double* lar, int order) {
631 : int k;
632 0 : for (k = 0; k < order; k++) {
633 0 : lar[k] = log((1 + refc[k]) / (1 - refc[k]));
634 : }
635 0 : }
636 :
637 :
638 0 : void WebRtcIsac_Lar2Rc(const double* lar, double* refc, int order) {
639 : int k;
640 : double tmp;
641 :
642 0 : for (k = 0; k < order; k++) {
643 0 : tmp = exp(lar[k]);
644 0 : refc[k] = (tmp - 1) / (tmp + 1);
645 : }
646 0 : }
647 :
648 0 : void WebRtcIsac_Poly2Lar(double* lowband, int orderLo, double* hiband,
649 : int orderHi, int Nsub, double* lars) {
650 : int k;
651 : double rc[MAX_ORDER], *inpl, *inph, *outp;
652 :
653 0 : inpl = lowband;
654 0 : inph = hiband;
655 0 : outp = lars;
656 0 : for (k = 0; k < Nsub; k++) {
657 : /* gains */
658 0 : outp[0] = inpl[0];
659 0 : outp[1] = inph[0];
660 0 : outp += 2;
661 :
662 : /* Low band */
663 0 : inpl[0] = 1.0;
664 0 : WebRtcIsac_Poly2Rc(inpl, orderLo, rc);
665 0 : WebRtcIsac_Rc2Lar(rc, outp, orderLo);
666 0 : outp += orderLo;
667 :
668 : /* High band */
669 0 : inph[0] = 1.0;
670 0 : WebRtcIsac_Poly2Rc(inph, orderHi, rc);
671 0 : WebRtcIsac_Rc2Lar(rc, outp, orderHi);
672 0 : outp += orderHi;
673 :
674 0 : inpl += orderLo + 1;
675 0 : inph += orderHi + 1;
676 : }
677 0 : }
678 :
679 :
680 0 : int16_t WebRtcIsac_Poly2LarUB(double* lpcVecs, int16_t bandwidth) {
681 : double poly[MAX_ORDER];
682 : double rc[MAX_ORDER];
683 : double* ptrIO;
684 : int16_t vecCntr;
685 : int16_t vecSize;
686 : int16_t numVec;
687 :
688 0 : vecSize = UB_LPC_ORDER;
689 0 : switch (bandwidth) {
690 : case isac12kHz: {
691 0 : numVec = UB_LPC_VEC_PER_FRAME;
692 0 : break;
693 : }
694 : case isac16kHz: {
695 0 : numVec = UB16_LPC_VEC_PER_FRAME;
696 0 : break;
697 : }
698 : default:
699 0 : return -1;
700 : }
701 :
702 0 : ptrIO = lpcVecs;
703 0 : poly[0] = 1.0;
704 0 : for (vecCntr = 0; vecCntr < numVec; vecCntr++) {
705 0 : memcpy(&poly[1], ptrIO, sizeof(double) * vecSize);
706 0 : WebRtcIsac_Poly2Rc(poly, vecSize, rc);
707 0 : WebRtcIsac_Rc2Lar(rc, ptrIO, vecSize);
708 0 : ptrIO += vecSize;
709 : }
710 0 : return 0;
711 : }
712 :
713 :
714 0 : void WebRtcIsac_Lar2Poly(double* lars, double* lowband, int orderLo,
715 : double* hiband, int orderHi, int Nsub) {
716 : int k, orderTot;
717 : double rc[MAX_ORDER], *outpl, *outph, *inp;
718 :
719 0 : orderTot = (orderLo + orderHi + 2);
720 0 : outpl = lowband;
721 0 : outph = hiband;
722 : /* First two elements of 'inp' store gains*/
723 0 : inp = lars;
724 0 : for (k = 0; k < Nsub; k++) {
725 : /* Low band */
726 0 : WebRtcIsac_Lar2Rc(&inp[2], rc, orderLo);
727 0 : WebRtcIsac_Rc2Poly(rc, orderLo, outpl);
728 :
729 : /* High band */
730 0 : WebRtcIsac_Lar2Rc(&inp[orderLo + 2], rc, orderHi);
731 0 : WebRtcIsac_Rc2Poly(rc, orderHi, outph);
732 :
733 : /* gains */
734 0 : outpl[0] = inp[0];
735 0 : outph[0] = inp[1];
736 :
737 0 : outpl += orderLo + 1;
738 0 : outph += orderHi + 1;
739 0 : inp += orderTot;
740 : }
741 0 : }
742 :
743 : /*
744 : * assumes 2 LAR vectors interpolates to 'numPolyVec' A-polynomials
745 : * Note: 'numPolyVecs' includes the first and the last point of the interval
746 : */
747 0 : void WebRtcIsac_Lar2PolyInterpolUB(double* larVecs, double* percepFilterParams,
748 : int numPolyVecs) {
749 : int polyCntr, coeffCntr;
750 : double larInterpol[UB_LPC_ORDER];
751 : double rc[UB_LPC_ORDER];
752 : double delta[UB_LPC_ORDER];
753 :
754 : /* calculate the step-size for linear interpolation coefficients */
755 0 : for (coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++) {
756 0 : delta[coeffCntr] = (larVecs[UB_LPC_ORDER + coeffCntr] -
757 0 : larVecs[coeffCntr]) / (numPolyVecs - 1);
758 : }
759 :
760 0 : for (polyCntr = 0; polyCntr < numPolyVecs; polyCntr++) {
761 0 : for (coeffCntr = 0; coeffCntr < UB_LPC_ORDER; coeffCntr++) {
762 0 : larInterpol[coeffCntr] = larVecs[coeffCntr] +
763 0 : delta[coeffCntr] * polyCntr;
764 : }
765 0 : WebRtcIsac_Lar2Rc(larInterpol, rc, UB_LPC_ORDER);
766 :
767 : /* convert to A-polynomial, the following function returns A[0] = 1;
768 : * which is written where gains had to be written. Then we write the
769 : * gain (outside this function). This way we say a memcpy. */
770 0 : WebRtcIsac_Rc2Poly(rc, UB_LPC_ORDER, percepFilterParams);
771 0 : percepFilterParams += (UB_LPC_ORDER + 1);
772 : }
773 0 : }
774 :
775 0 : int WebRtcIsac_DecodeLpc(Bitstr* streamdata, double* LPCCoef_lo,
776 : double* LPCCoef_hi) {
777 : double lars[KLT_ORDER_GAIN + KLT_ORDER_SHAPE];
778 : int err;
779 :
780 0 : err = WebRtcIsac_DecodeLpcCoef(streamdata, lars);
781 0 : if (err < 0) {
782 0 : return -ISAC_RANGE_ERROR_DECODE_LPC;
783 : }
784 0 : WebRtcIsac_Lar2Poly(lars, LPCCoef_lo, ORDERLO, LPCCoef_hi, ORDERHI,
785 : SUBFRAMES);
786 0 : return 0;
787 : }
788 :
789 0 : int16_t WebRtcIsac_DecodeInterpolLpcUb(Bitstr* streamdata,
790 : double* percepFilterParams,
791 : int16_t bandwidth) {
792 : double lpcCoeff[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
793 : int err;
794 : int interpolCntr;
795 : int subframeCntr;
796 : int16_t numSegments;
797 : int16_t numVecPerSegment;
798 : int16_t numGains;
799 :
800 : double percepFilterGains[SUBFRAMES << 1];
801 0 : double* ptrOutParam = percepFilterParams;
802 :
803 0 : err = WebRtcIsac_DecodeLpcCoefUB(streamdata, lpcCoeff, percepFilterGains,
804 : bandwidth);
805 0 : if (err < 0) {
806 0 : return -ISAC_RANGE_ERROR_DECODE_LPC;
807 : }
808 :
809 0 : switch (bandwidth) {
810 : case isac12kHz: {
811 0 : numGains = SUBFRAMES;
812 0 : numSegments = UB_LPC_VEC_PER_FRAME - 1;
813 0 : numVecPerSegment = kLpcVecPerSegmentUb12;
814 0 : break;
815 : }
816 : case isac16kHz: {
817 0 : numGains = SUBFRAMES << 1;
818 0 : numSegments = UB16_LPC_VEC_PER_FRAME - 1;
819 0 : numVecPerSegment = kLpcVecPerSegmentUb16;
820 0 : break;
821 : }
822 : default:
823 0 : return -1;
824 : }
825 :
826 0 : for (interpolCntr = 0; interpolCntr < numSegments; interpolCntr++) {
827 0 : WebRtcIsac_Lar2PolyInterpolUB(&lpcCoeff[interpolCntr * UB_LPC_ORDER],
828 : ptrOutParam, numVecPerSegment + 1);
829 0 : ptrOutParam += (numVecPerSegment * (UB_LPC_ORDER + 1));
830 : }
831 :
832 0 : ptrOutParam = percepFilterParams;
833 :
834 0 : if (bandwidth == isac16kHz) {
835 0 : ptrOutParam += (1 + UB_LPC_ORDER);
836 : }
837 :
838 0 : for (subframeCntr = 0; subframeCntr < numGains; subframeCntr++) {
839 0 : *ptrOutParam = percepFilterGains[subframeCntr];
840 0 : ptrOutParam += (1 + UB_LPC_ORDER);
841 : }
842 0 : return 0;
843 : }
844 :
845 :
846 : /* decode & dequantize LPC Coef */
847 0 : int WebRtcIsac_DecodeLpcCoef(Bitstr* streamdata, double* LPCCoef) {
848 : int j, k, n, pos, pos2, posg, poss, offsg, offss, offs2;
849 : int index_g[KLT_ORDER_GAIN], index_s[KLT_ORDER_SHAPE];
850 : double tmpcoeffs_g[KLT_ORDER_GAIN], tmpcoeffs_s[KLT_ORDER_SHAPE];
851 : double tmpcoeffs2_g[KLT_ORDER_GAIN], tmpcoeffs2_s[KLT_ORDER_SHAPE];
852 : double sum;
853 : int err;
854 0 : int model = 1;
855 :
856 : /* entropy decoding of model number */
857 : /* We are keeping this for backward compatibility of bit-streams. */
858 0 : err = WebRtcIsac_DecHistOneStepMulti(&model, streamdata,
859 : WebRtcIsac_kQKltModelCdfPtr,
860 : WebRtcIsac_kQKltModelInitIndex, 1);
861 0 : if (err < 0) {
862 0 : return err;
863 : }
864 : /* Only accepted value of model is 0. It is kept in bit-stream for backward
865 : * compatibility. */
866 0 : if (model != 0) {
867 0 : return -ISAC_DISALLOWED_LPC_MODEL;
868 : }
869 :
870 : /* entropy decoding of quantization indices */
871 0 : err = WebRtcIsac_DecHistOneStepMulti(
872 : index_s, streamdata, WebRtcIsac_kQKltCdfPtrShape,
873 : WebRtcIsac_kQKltInitIndexShape, KLT_ORDER_SHAPE);
874 0 : if (err < 0) {
875 0 : return err;
876 : }
877 0 : err = WebRtcIsac_DecHistOneStepMulti(
878 : index_g, streamdata, WebRtcIsac_kQKltCdfPtrGain,
879 : WebRtcIsac_kQKltInitIndexGain, KLT_ORDER_GAIN);
880 0 : if (err < 0) {
881 0 : return err;
882 : }
883 :
884 : /* find quantization levels for coefficients */
885 0 : for (k = 0; k < KLT_ORDER_SHAPE; k++) {
886 0 : tmpcoeffs_s[k] =
887 0 : WebRtcIsac_kQKltLevelsShape[WebRtcIsac_kQKltOffsetShape[k] +
888 0 : index_s[k]];
889 : }
890 0 : for (k = 0; k < KLT_ORDER_GAIN; k++) {
891 0 : tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[WebRtcIsac_kQKltOffsetGain[k] +
892 0 : index_g[k]];
893 : }
894 :
895 : /* Inverse KLT */
896 :
897 : /* Left transform, transpose matrix! */
898 0 : offsg = 0;
899 0 : offss = 0;
900 0 : posg = 0;
901 0 : poss = 0;
902 0 : for (j = 0; j < SUBFRAMES; j++) {
903 0 : offs2 = 0;
904 0 : for (k = 0; k < LPC_GAIN_ORDER; k++) {
905 0 : sum = 0;
906 0 : pos = offsg;
907 0 : pos2 = offs2;
908 0 : for (n = 0; n < LPC_GAIN_ORDER; n++) {
909 0 : sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2++];
910 : }
911 0 : tmpcoeffs2_g[posg++] = sum;
912 0 : offs2 += LPC_GAIN_ORDER;
913 : }
914 0 : offs2 = 0;
915 0 : for (k = 0; k < LPC_SHAPE_ORDER; k++) {
916 0 : sum = 0;
917 0 : pos = offss;
918 0 : pos2 = offs2;
919 0 : for (n = 0; n < LPC_SHAPE_ORDER; n++) {
920 0 : sum += tmpcoeffs_s[pos++] * WebRtcIsac_kKltT1Shape[pos2++];
921 : }
922 0 : tmpcoeffs2_s[poss++] = sum;
923 0 : offs2 += LPC_SHAPE_ORDER;
924 : }
925 0 : offsg += LPC_GAIN_ORDER;
926 0 : offss += LPC_SHAPE_ORDER;
927 : }
928 :
929 : /* Right transform, transpose matrix */
930 0 : offsg = 0;
931 0 : offss = 0;
932 0 : posg = 0;
933 0 : poss = 0;
934 0 : for (j = 0; j < SUBFRAMES; j++) {
935 0 : posg = offsg;
936 0 : for (k = 0; k < LPC_GAIN_ORDER; k++) {
937 0 : sum = 0;
938 0 : pos = k;
939 0 : pos2 = j;
940 0 : for (n = 0; n < SUBFRAMES; n++) {
941 0 : sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2];
942 0 : pos += LPC_GAIN_ORDER;
943 0 : pos2 += SUBFRAMES;
944 :
945 : }
946 0 : tmpcoeffs_g[posg++] = sum;
947 : }
948 0 : poss = offss;
949 0 : for (k = 0; k < LPC_SHAPE_ORDER; k++) {
950 0 : sum = 0;
951 0 : pos = k;
952 0 : pos2 = j;
953 0 : for (n = 0; n < SUBFRAMES; n++) {
954 0 : sum += tmpcoeffs2_s[pos] * WebRtcIsac_kKltT2Shape[pos2];
955 0 : pos += LPC_SHAPE_ORDER;
956 0 : pos2 += SUBFRAMES;
957 : }
958 0 : tmpcoeffs_s[poss++] = sum;
959 : }
960 0 : offsg += LPC_GAIN_ORDER;
961 0 : offss += LPC_SHAPE_ORDER;
962 : }
963 :
964 : /* scaling, mean addition, and gain restoration */
965 0 : posg = 0;
966 0 : poss = 0;
967 0 : pos = 0;
968 0 : for (k = 0; k < SUBFRAMES; k++) {
969 : /* log gains */
970 0 : LPCCoef[pos] = tmpcoeffs_g[posg] / LPC_GAIN_SCALE;
971 0 : LPCCoef[pos] += WebRtcIsac_kLpcMeansGain[posg];
972 0 : LPCCoef[pos] = exp(LPCCoef[pos]);
973 0 : pos++;
974 0 : posg++;
975 0 : LPCCoef[pos] = tmpcoeffs_g[posg] / LPC_GAIN_SCALE;
976 0 : LPCCoef[pos] += WebRtcIsac_kLpcMeansGain[posg];
977 0 : LPCCoef[pos] = exp(LPCCoef[pos]);
978 0 : pos++;
979 0 : posg++;
980 :
981 : /* Low-band LAR coefficients. */
982 0 : for (n = 0; n < LPC_LOBAND_ORDER; n++, pos++, poss++) {
983 0 : LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_LOBAND_SCALE;
984 0 : LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss];
985 : }
986 :
987 : /* High-band LAR coefficients. */
988 0 : for (n = 0; n < LPC_HIBAND_ORDER; n++, pos++, poss++) {
989 0 : LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_HIBAND_SCALE;
990 0 : LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss];
991 : }
992 : }
993 0 : return 0;
994 : }
995 :
996 : /* Encode LPC in LAR domain. */
997 0 : void WebRtcIsac_EncodeLar(double* LPCCoef, Bitstr* streamdata,
998 : IsacSaveEncoderData* encData) {
999 : int j, k, n, pos, pos2, poss, offss, offs2;
1000 : int index_s[KLT_ORDER_SHAPE];
1001 : int index_ovr_s[KLT_ORDER_SHAPE];
1002 : double tmpcoeffs_s[KLT_ORDER_SHAPE];
1003 : double tmpcoeffs2_s[KLT_ORDER_SHAPE];
1004 : double sum;
1005 0 : const int kModel = 0;
1006 :
1007 : /* Mean removal and scaling. */
1008 0 : poss = 0;
1009 0 : pos = 0;
1010 0 : for (k = 0; k < SUBFRAMES; k++) {
1011 : /* First two element are gains, move over them. */
1012 0 : pos += 2;
1013 :
1014 : /* Low-band LAR coefficients. */
1015 0 : for (n = 0; n < LPC_LOBAND_ORDER; n++, poss++, pos++) {
1016 0 : tmpcoeffs_s[poss] = LPCCoef[pos] - WebRtcIsac_kLpcMeansShape[poss];
1017 0 : tmpcoeffs_s[poss] *= LPC_LOBAND_SCALE;
1018 : }
1019 :
1020 : /* High-band LAR coefficients. */
1021 0 : for (n = 0; n < LPC_HIBAND_ORDER; n++, poss++, pos++) {
1022 0 : tmpcoeffs_s[poss] = LPCCoef[pos] - WebRtcIsac_kLpcMeansShape[poss];
1023 0 : tmpcoeffs_s[poss] *= LPC_HIBAND_SCALE;
1024 : }
1025 : }
1026 :
1027 : /* KLT */
1028 :
1029 : /* Left transform. */
1030 0 : offss = 0;
1031 0 : for (j = 0; j < SUBFRAMES; j++) {
1032 0 : poss = offss;
1033 0 : for (k = 0; k < LPC_SHAPE_ORDER; k++) {
1034 0 : sum = 0;
1035 0 : pos = offss;
1036 0 : pos2 = k;
1037 0 : for (n = 0; n < LPC_SHAPE_ORDER; n++) {
1038 0 : sum += tmpcoeffs_s[pos++] * WebRtcIsac_kKltT1Shape[pos2];
1039 0 : pos2 += LPC_SHAPE_ORDER;
1040 : }
1041 0 : tmpcoeffs2_s[poss++] = sum;
1042 : }
1043 0 : offss += LPC_SHAPE_ORDER;
1044 : }
1045 :
1046 : /* Right transform. */
1047 0 : offss = 0;
1048 0 : offs2 = 0;
1049 0 : for (j = 0; j < SUBFRAMES; j++) {
1050 0 : poss = offss;
1051 0 : for (k = 0; k < LPC_SHAPE_ORDER; k++) {
1052 0 : sum = 0;
1053 0 : pos = k;
1054 0 : pos2 = offs2;
1055 0 : for (n = 0; n < SUBFRAMES; n++) {
1056 0 : sum += tmpcoeffs2_s[pos] * WebRtcIsac_kKltT2Shape[pos2++];
1057 0 : pos += LPC_SHAPE_ORDER;
1058 : }
1059 0 : tmpcoeffs_s[poss++] = sum;
1060 : }
1061 0 : offs2 += SUBFRAMES;
1062 0 : offss += LPC_SHAPE_ORDER;
1063 : }
1064 :
1065 : /* Quantize coefficients. */
1066 0 : for (k = 0; k < KLT_ORDER_SHAPE; k++) {
1067 0 : index_s[k] = (WebRtcIsac_lrint(tmpcoeffs_s[k] / KLT_STEPSIZE)) +
1068 0 : WebRtcIsac_kQKltQuantMinShape[k];
1069 0 : if (index_s[k] < 0) {
1070 0 : index_s[k] = 0;
1071 0 : } else if (index_s[k] > WebRtcIsac_kQKltMaxIndShape[k]) {
1072 0 : index_s[k] = WebRtcIsac_kQKltMaxIndShape[k];
1073 : }
1074 0 : index_ovr_s[k] = WebRtcIsac_kQKltOffsetShape[k] + index_s[k];
1075 : }
1076 :
1077 :
1078 : /* Only one model remains in this version of the code, kModel = 0. We
1079 : * are keeping for bit-streams to be backward compatible. */
1080 : /* entropy coding of model number */
1081 0 : WebRtcIsac_EncHistMulti(streamdata, &kModel, WebRtcIsac_kQKltModelCdfPtr, 1);
1082 :
1083 : /* Save data for creation of multiple bit streams */
1084 : /* Entropy coding of quantization indices - shape only. */
1085 0 : WebRtcIsac_EncHistMulti(streamdata, index_s, WebRtcIsac_kQKltCdfPtrShape,
1086 : KLT_ORDER_SHAPE);
1087 :
1088 : /* Save data for creation of multiple bit streams. */
1089 0 : for (k = 0; k < KLT_ORDER_SHAPE; k++) {
1090 0 : encData->LPCindex_s[KLT_ORDER_SHAPE * encData->startIdx + k] = index_s[k];
1091 : }
1092 :
1093 : /* Find quantization levels for shape coefficients. */
1094 0 : for (k = 0; k < KLT_ORDER_SHAPE; k++) {
1095 0 : tmpcoeffs_s[k] = WebRtcIsac_kQKltLevelsShape[index_ovr_s[k]];
1096 : }
1097 : /* Inverse KLT. */
1098 : /* Left transform, transpose matrix.! */
1099 0 : offss = 0;
1100 0 : poss = 0;
1101 0 : for (j = 0; j < SUBFRAMES; j++) {
1102 0 : offs2 = 0;
1103 0 : for (k = 0; k < LPC_SHAPE_ORDER; k++) {
1104 0 : sum = 0;
1105 0 : pos = offss;
1106 0 : pos2 = offs2;
1107 0 : for (n = 0; n < LPC_SHAPE_ORDER; n++) {
1108 0 : sum += tmpcoeffs_s[pos++] * WebRtcIsac_kKltT1Shape[pos2++];
1109 : }
1110 0 : tmpcoeffs2_s[poss++] = sum;
1111 0 : offs2 += LPC_SHAPE_ORDER;
1112 : }
1113 0 : offss += LPC_SHAPE_ORDER;
1114 : }
1115 :
1116 : /* Right transform, Transpose matrix */
1117 0 : offss = 0;
1118 0 : poss = 0;
1119 0 : for (j = 0; j < SUBFRAMES; j++) {
1120 0 : poss = offss;
1121 0 : for (k = 0; k < LPC_SHAPE_ORDER; k++) {
1122 0 : sum = 0;
1123 0 : pos = k;
1124 0 : pos2 = j;
1125 0 : for (n = 0; n < SUBFRAMES; n++) {
1126 0 : sum += tmpcoeffs2_s[pos] * WebRtcIsac_kKltT2Shape[pos2];
1127 0 : pos += LPC_SHAPE_ORDER;
1128 0 : pos2 += SUBFRAMES;
1129 : }
1130 0 : tmpcoeffs_s[poss++] = sum;
1131 : }
1132 0 : offss += LPC_SHAPE_ORDER;
1133 : }
1134 :
1135 : /* Scaling, mean addition, and gain restoration. */
1136 0 : poss = 0;
1137 0 : pos = 0;
1138 0 : for (k = 0; k < SUBFRAMES; k++) {
1139 : /* Ignore gains. */
1140 0 : pos += 2;
1141 :
1142 : /* Low band LAR coefficients. */
1143 0 : for (n = 0; n < LPC_LOBAND_ORDER; n++, pos++, poss++) {
1144 0 : LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_LOBAND_SCALE;
1145 0 : LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss];
1146 : }
1147 :
1148 : /* High band LAR coefficients. */
1149 0 : for (n = 0; n < LPC_HIBAND_ORDER; n++, pos++, poss++) {
1150 0 : LPCCoef[pos] = tmpcoeffs_s[poss] / LPC_HIBAND_SCALE;
1151 0 : LPCCoef[pos] += WebRtcIsac_kLpcMeansShape[poss];
1152 : }
1153 : }
1154 0 : }
1155 :
1156 :
1157 0 : void WebRtcIsac_EncodeLpcLb(double* LPCCoef_lo, double* LPCCoef_hi,
1158 : Bitstr* streamdata, IsacSaveEncoderData* encData) {
1159 : double lars[KLT_ORDER_GAIN + KLT_ORDER_SHAPE];
1160 : int k;
1161 :
1162 0 : WebRtcIsac_Poly2Lar(LPCCoef_lo, ORDERLO, LPCCoef_hi, ORDERHI, SUBFRAMES,
1163 : lars);
1164 0 : WebRtcIsac_EncodeLar(lars, streamdata, encData);
1165 0 : WebRtcIsac_Lar2Poly(lars, LPCCoef_lo, ORDERLO, LPCCoef_hi, ORDERHI,
1166 : SUBFRAMES);
1167 : /* Save data for creation of multiple bit streams (and transcoding). */
1168 0 : for (k = 0; k < (ORDERLO + 1)*SUBFRAMES; k++) {
1169 0 : encData->LPCcoeffs_lo[(ORDERLO + 1)*SUBFRAMES * encData->startIdx + k] =
1170 0 : LPCCoef_lo[k];
1171 : }
1172 0 : for (k = 0; k < (ORDERHI + 1)*SUBFRAMES; k++) {
1173 0 : encData->LPCcoeffs_hi[(ORDERHI + 1)*SUBFRAMES * encData->startIdx + k] =
1174 0 : LPCCoef_hi[k];
1175 : }
1176 0 : }
1177 :
1178 :
1179 0 : int16_t WebRtcIsac_EncodeLpcUB(double* lpcVecs, Bitstr* streamdata,
1180 : double* interpolLPCCoeff,
1181 : int16_t bandwidth,
1182 : ISACUBSaveEncDataStruct* encData) {
1183 : double U[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
1184 : int idx[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
1185 : int interpolCntr;
1186 :
1187 0 : WebRtcIsac_Poly2LarUB(lpcVecs, bandwidth);
1188 0 : WebRtcIsac_RemoveLarMean(lpcVecs, bandwidth);
1189 0 : WebRtcIsac_DecorrelateIntraVec(lpcVecs, U, bandwidth);
1190 0 : WebRtcIsac_DecorrelateInterVec(U, lpcVecs, bandwidth);
1191 0 : WebRtcIsac_QuantizeUncorrLar(lpcVecs, idx, bandwidth);
1192 :
1193 0 : WebRtcIsac_CorrelateInterVec(lpcVecs, U, bandwidth);
1194 0 : WebRtcIsac_CorrelateIntraVec(U, lpcVecs, bandwidth);
1195 0 : WebRtcIsac_AddLarMean(lpcVecs, bandwidth);
1196 :
1197 0 : switch (bandwidth) {
1198 : case isac12kHz: {
1199 : /* Store the indices to be used for multiple encoding. */
1200 0 : memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER *
1201 : UB_LPC_VEC_PER_FRAME * sizeof(int));
1202 0 : WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb12,
1203 : UB_LPC_ORDER * UB_LPC_VEC_PER_FRAME);
1204 0 : for (interpolCntr = 0; interpolCntr < UB_INTERPOL_SEGMENTS;
1205 0 : interpolCntr++) {
1206 0 : WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, interpolLPCCoeff,
1207 : kLpcVecPerSegmentUb12 + 1);
1208 0 : lpcVecs += UB_LPC_ORDER;
1209 0 : interpolLPCCoeff += (kLpcVecPerSegmentUb12 * (UB_LPC_ORDER + 1));
1210 : }
1211 0 : break;
1212 : }
1213 : case isac16kHz: {
1214 : /* Store the indices to be used for multiple encoding. */
1215 0 : memcpy(encData->indexLPCShape, idx, UB_LPC_ORDER *
1216 : UB16_LPC_VEC_PER_FRAME * sizeof(int));
1217 0 : WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcShapeCdfMatUb16,
1218 : UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME);
1219 0 : for (interpolCntr = 0; interpolCntr < UB16_INTERPOL_SEGMENTS;
1220 0 : interpolCntr++) {
1221 0 : WebRtcIsac_Lar2PolyInterpolUB(lpcVecs, interpolLPCCoeff,
1222 : kLpcVecPerSegmentUb16 + 1);
1223 0 : lpcVecs += UB_LPC_ORDER;
1224 0 : interpolLPCCoeff += (kLpcVecPerSegmentUb16 * (UB_LPC_ORDER + 1));
1225 : }
1226 0 : break;
1227 : }
1228 : default:
1229 0 : return -1;
1230 : }
1231 0 : return 0;
1232 : }
1233 :
1234 0 : void WebRtcIsac_EncodeLpcGainLb(double* LPCCoef_lo, double* LPCCoef_hi,
1235 : Bitstr* streamdata,
1236 : IsacSaveEncoderData* encData) {
1237 : int j, k, n, pos, pos2, posg, offsg, offs2;
1238 : int index_g[KLT_ORDER_GAIN];
1239 : int index_ovr_g[KLT_ORDER_GAIN];
1240 : double tmpcoeffs_g[KLT_ORDER_GAIN];
1241 : double tmpcoeffs2_g[KLT_ORDER_GAIN];
1242 : double sum;
1243 : /* log gains, mean removal and scaling */
1244 0 : posg = 0;
1245 0 : for (k = 0; k < SUBFRAMES; k++) {
1246 0 : tmpcoeffs_g[posg] = log(LPCCoef_lo[(LPC_LOBAND_ORDER + 1) * k]);
1247 0 : tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg];
1248 0 : tmpcoeffs_g[posg] *= LPC_GAIN_SCALE;
1249 0 : posg++;
1250 0 : tmpcoeffs_g[posg] = log(LPCCoef_hi[(LPC_HIBAND_ORDER + 1) * k]);
1251 0 : tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg];
1252 0 : tmpcoeffs_g[posg] *= LPC_GAIN_SCALE;
1253 0 : posg++;
1254 : }
1255 :
1256 : /* KLT */
1257 :
1258 : /* Left transform. */
1259 0 : offsg = 0;
1260 0 : for (j = 0; j < SUBFRAMES; j++) {
1261 0 : posg = offsg;
1262 0 : for (k = 0; k < LPC_GAIN_ORDER; k++) {
1263 0 : sum = 0;
1264 0 : pos = offsg;
1265 0 : pos2 = k;
1266 0 : for (n = 0; n < LPC_GAIN_ORDER; n++) {
1267 0 : sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2];
1268 0 : pos2 += LPC_GAIN_ORDER;
1269 : }
1270 0 : tmpcoeffs2_g[posg++] = sum;
1271 : }
1272 0 : offsg += LPC_GAIN_ORDER;
1273 : }
1274 :
1275 : /* Right transform. */
1276 0 : offsg = 0;
1277 0 : offs2 = 0;
1278 0 : for (j = 0; j < SUBFRAMES; j++) {
1279 0 : posg = offsg;
1280 0 : for (k = 0; k < LPC_GAIN_ORDER; k++) {
1281 0 : sum = 0;
1282 0 : pos = k;
1283 0 : pos2 = offs2;
1284 0 : for (n = 0; n < SUBFRAMES; n++) {
1285 0 : sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2++];
1286 0 : pos += LPC_GAIN_ORDER;
1287 : }
1288 0 : tmpcoeffs_g[posg++] = sum;
1289 : }
1290 0 : offs2 += SUBFRAMES;
1291 0 : offsg += LPC_GAIN_ORDER;
1292 : }
1293 :
1294 : /* Quantize coefficients. */
1295 0 : for (k = 0; k < KLT_ORDER_GAIN; k++) {
1296 : /* Get index. */
1297 0 : pos2 = WebRtcIsac_lrint(tmpcoeffs_g[k] / KLT_STEPSIZE);
1298 0 : index_g[k] = (pos2) + WebRtcIsac_kQKltQuantMinGain[k];
1299 0 : if (index_g[k] < 0) {
1300 0 : index_g[k] = 0;
1301 0 : } else if (index_g[k] > WebRtcIsac_kQKltMaxIndGain[k]) {
1302 0 : index_g[k] = WebRtcIsac_kQKltMaxIndGain[k];
1303 : }
1304 0 : index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[k] + index_g[k];
1305 :
1306 : /* Find quantization levels for coefficients. */
1307 0 : tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[index_ovr_g[k]];
1308 :
1309 : /* Save data for creation of multiple bit streams. */
1310 0 : encData->LPCindex_g[KLT_ORDER_GAIN * encData->startIdx + k] = index_g[k];
1311 : }
1312 :
1313 : /* Entropy coding of quantization indices - gain. */
1314 0 : WebRtcIsac_EncHistMulti(streamdata, index_g, WebRtcIsac_kQKltCdfPtrGain,
1315 : KLT_ORDER_GAIN);
1316 :
1317 : /* Find quantization levels for coefficients. */
1318 : /* Left transform. */
1319 0 : offsg = 0;
1320 0 : posg = 0;
1321 0 : for (j = 0; j < SUBFRAMES; j++) {
1322 0 : offs2 = 0;
1323 0 : for (k = 0; k < LPC_GAIN_ORDER; k++) {
1324 0 : sum = 0;
1325 0 : pos = offsg;
1326 0 : pos2 = offs2;
1327 0 : for (n = 0; n < LPC_GAIN_ORDER; n++)
1328 0 : sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2++];
1329 0 : tmpcoeffs2_g[posg++] = sum;
1330 0 : offs2 += LPC_GAIN_ORDER;
1331 : }
1332 0 : offsg += LPC_GAIN_ORDER;
1333 : }
1334 :
1335 : /* Right transform, transpose matrix. */
1336 0 : offsg = 0;
1337 0 : posg = 0;
1338 0 : for (j = 0; j < SUBFRAMES; j++) {
1339 0 : posg = offsg;
1340 0 : for (k = 0; k < LPC_GAIN_ORDER; k++) {
1341 0 : sum = 0;
1342 0 : pos = k;
1343 0 : pos2 = j;
1344 0 : for (n = 0; n < SUBFRAMES; n++) {
1345 0 : sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2];
1346 0 : pos += LPC_GAIN_ORDER;
1347 0 : pos2 += SUBFRAMES;
1348 : }
1349 0 : tmpcoeffs_g[posg++] = sum;
1350 : }
1351 0 : offsg += LPC_GAIN_ORDER;
1352 : }
1353 :
1354 :
1355 : /* Scaling, mean addition, and gain restoration. */
1356 0 : posg = 0;
1357 0 : for (k = 0; k < SUBFRAMES; k++) {
1358 0 : sum = tmpcoeffs_g[posg] / LPC_GAIN_SCALE;
1359 0 : sum += WebRtcIsac_kLpcMeansGain[posg];
1360 0 : LPCCoef_lo[k * (LPC_LOBAND_ORDER + 1)] = exp(sum);
1361 0 : pos++;
1362 0 : posg++;
1363 0 : sum = tmpcoeffs_g[posg] / LPC_GAIN_SCALE;
1364 0 : sum += WebRtcIsac_kLpcMeansGain[posg];
1365 0 : LPCCoef_hi[k * (LPC_HIBAND_ORDER + 1)] = exp(sum);
1366 0 : pos++;
1367 0 : posg++;
1368 : }
1369 :
1370 0 : }
1371 :
1372 0 : void WebRtcIsac_EncodeLpcGainUb(double* lpGains, Bitstr* streamdata,
1373 : int* lpcGainIndex) {
1374 : double U[UB_LPC_GAIN_DIM];
1375 : int idx[UB_LPC_GAIN_DIM];
1376 0 : WebRtcIsac_ToLogDomainRemoveMean(lpGains);
1377 0 : WebRtcIsac_DecorrelateLPGain(lpGains, U);
1378 0 : WebRtcIsac_QuantizeLpcGain(U, idx);
1379 : /* Store the index for re-encoding for FEC. */
1380 0 : memcpy(lpcGainIndex, idx, UB_LPC_GAIN_DIM * sizeof(int));
1381 0 : WebRtcIsac_CorrelateLpcGain(U, lpGains);
1382 0 : WebRtcIsac_AddMeanToLinearDomain(lpGains);
1383 0 : WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcGainCdfMat,
1384 : UB_LPC_GAIN_DIM);
1385 0 : }
1386 :
1387 :
1388 0 : void WebRtcIsac_StoreLpcGainUb(double* lpGains, Bitstr* streamdata) {
1389 : double U[UB_LPC_GAIN_DIM];
1390 : int idx[UB_LPC_GAIN_DIM];
1391 0 : WebRtcIsac_ToLogDomainRemoveMean(lpGains);
1392 0 : WebRtcIsac_DecorrelateLPGain(lpGains, U);
1393 0 : WebRtcIsac_QuantizeLpcGain(U, idx);
1394 0 : WebRtcIsac_EncHistMulti(streamdata, idx, WebRtcIsac_kLpcGainCdfMat,
1395 : UB_LPC_GAIN_DIM);
1396 0 : }
1397 :
1398 :
1399 :
1400 0 : int16_t WebRtcIsac_DecodeLpcGainUb(double* lpGains, Bitstr* streamdata) {
1401 : double U[UB_LPC_GAIN_DIM];
1402 : int idx[UB_LPC_GAIN_DIM];
1403 : int err;
1404 0 : err = WebRtcIsac_DecHistOneStepMulti(idx, streamdata,
1405 : WebRtcIsac_kLpcGainCdfMat,
1406 : WebRtcIsac_kLpcGainEntropySearch,
1407 : UB_LPC_GAIN_DIM);
1408 0 : if (err < 0) {
1409 0 : return -1;
1410 : }
1411 0 : WebRtcIsac_DequantizeLpcGain(idx, U);
1412 0 : WebRtcIsac_CorrelateLpcGain(U, lpGains);
1413 0 : WebRtcIsac_AddMeanToLinearDomain(lpGains);
1414 0 : return 0;
1415 : }
1416 :
1417 :
1418 :
1419 : /* decode & dequantize RC */
1420 0 : int WebRtcIsac_DecodeRc(Bitstr* streamdata, int16_t* RCQ15) {
1421 : int k, err;
1422 : int index[AR_ORDER];
1423 :
1424 : /* entropy decoding of quantization indices */
1425 0 : err = WebRtcIsac_DecHistOneStepMulti(index, streamdata,
1426 : WebRtcIsac_kQArRcCdfPtr,
1427 : WebRtcIsac_kQArRcInitIndex, AR_ORDER);
1428 0 : if (err < 0)
1429 0 : return err;
1430 :
1431 : /* find quantization levels for reflection coefficients */
1432 0 : for (k = 0; k < AR_ORDER; k++) {
1433 0 : RCQ15[k] = *(WebRtcIsac_kQArRcLevelsPtr[k] + index[k]);
1434 : }
1435 0 : return 0;
1436 : }
1437 :
1438 :
1439 : /* quantize & code RC */
1440 0 : void WebRtcIsac_EncodeRc(int16_t* RCQ15, Bitstr* streamdata) {
1441 : int k;
1442 : int index[AR_ORDER];
1443 :
1444 : /* quantize reflection coefficients (add noise feedback?) */
1445 0 : for (k = 0; k < AR_ORDER; k++) {
1446 0 : index[k] = WebRtcIsac_kQArRcInitIndex[k];
1447 : // The safe-guards in following while conditions are to suppress gcc 4.8.3
1448 : // warnings, Issue 2888. Otherwise, first and last elements of
1449 : // |WebRtcIsac_kQArBoundaryLevels| are such that the following search
1450 : // *never* cause an out-of-boundary read.
1451 0 : if (RCQ15[k] > WebRtcIsac_kQArBoundaryLevels[index[k]]) {
1452 0 : while (index[k] + 1 < NUM_AR_RC_QUANT_BAUNDARY &&
1453 0 : RCQ15[k] > WebRtcIsac_kQArBoundaryLevels[index[k] + 1]) {
1454 0 : index[k]++;
1455 : }
1456 : } else {
1457 0 : while (index[k] > 0 &&
1458 0 : RCQ15[k] < WebRtcIsac_kQArBoundaryLevels[--index[k]]) ;
1459 : }
1460 0 : RCQ15[k] = *(WebRtcIsac_kQArRcLevelsPtr[k] + index[k]);
1461 : }
1462 :
1463 : /* entropy coding of quantization indices */
1464 0 : WebRtcIsac_EncHistMulti(streamdata, index, WebRtcIsac_kQArRcCdfPtr, AR_ORDER);
1465 0 : }
1466 :
1467 :
1468 : /* decode & dequantize squared Gain */
1469 0 : int WebRtcIsac_DecodeGain2(Bitstr* streamdata, int32_t* gainQ10) {
1470 : int index, err;
1471 :
1472 : /* entropy decoding of quantization index */
1473 0 : err = WebRtcIsac_DecHistOneStepMulti(&index, streamdata,
1474 : WebRtcIsac_kQGainCdf_ptr,
1475 : WebRtcIsac_kQGainInitIndex, 1);
1476 0 : if (err < 0) {
1477 0 : return err;
1478 : }
1479 : /* find quantization level */
1480 0 : *gainQ10 = WebRtcIsac_kQGain2Levels[index];
1481 0 : return 0;
1482 : }
1483 :
1484 :
1485 : /* quantize & code squared Gain */
1486 0 : int WebRtcIsac_EncodeGain2(int32_t* gainQ10, Bitstr* streamdata) {
1487 : int index;
1488 :
1489 : /* find quantization index */
1490 0 : index = WebRtcIsac_kQGainInitIndex[0];
1491 0 : if (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index]) {
1492 0 : while (*gainQ10 > WebRtcIsac_kQGain2BoundaryLevels[index + 1]) {
1493 0 : index++;
1494 : }
1495 : } else {
1496 0 : while (*gainQ10 < WebRtcIsac_kQGain2BoundaryLevels[--index]) ;
1497 : }
1498 : /* De-quantize */
1499 0 : *gainQ10 = WebRtcIsac_kQGain2Levels[index];
1500 :
1501 : /* entropy coding of quantization index */
1502 0 : WebRtcIsac_EncHistMulti(streamdata, &index, WebRtcIsac_kQGainCdf_ptr, 1);
1503 0 : return 0;
1504 : }
1505 :
1506 :
1507 : /* code and decode Pitch Gains and Lags functions */
1508 :
1509 : /* decode & dequantize Pitch Gains */
1510 0 : int WebRtcIsac_DecodePitchGain(Bitstr* streamdata,
1511 : int16_t* PitchGains_Q12) {
1512 : int index_comb, err;
1513 : const uint16_t* WebRtcIsac_kQPitchGainCdf_ptr[1];
1514 :
1515 : /* Entropy decoding of quantization indices */
1516 0 : *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf;
1517 0 : err = WebRtcIsac_DecHistBisectMulti(&index_comb, streamdata,
1518 : WebRtcIsac_kQPitchGainCdf_ptr,
1519 : WebRtcIsac_kQCdfTableSizeGain, 1);
1520 : /* Error check, Q_mean_Gain.. tables are of size 144 */
1521 0 : if ((err < 0) || (index_comb < 0) || (index_comb >= 144)) {
1522 0 : return -ISAC_RANGE_ERROR_DECODE_PITCH_GAIN;
1523 : }
1524 : /* De-quantize back to pitch gains by table look-up. */
1525 0 : PitchGains_Q12[0] = WebRtcIsac_kQMeanGain1Q12[index_comb];
1526 0 : PitchGains_Q12[1] = WebRtcIsac_kQMeanGain2Q12[index_comb];
1527 0 : PitchGains_Q12[2] = WebRtcIsac_kQMeanGain3Q12[index_comb];
1528 0 : PitchGains_Q12[3] = WebRtcIsac_kQMeanGain4Q12[index_comb];
1529 0 : return 0;
1530 : }
1531 :
1532 :
1533 : /* Quantize & code Pitch Gains. */
1534 0 : void WebRtcIsac_EncodePitchGain(int16_t* PitchGains_Q12,
1535 : Bitstr* streamdata,
1536 : IsacSaveEncoderData* encData) {
1537 : int k, j;
1538 : double C;
1539 : double S[PITCH_SUBFRAMES];
1540 : int index[3];
1541 : int index_comb;
1542 : const uint16_t* WebRtcIsac_kQPitchGainCdf_ptr[1];
1543 0 : double PitchGains[PITCH_SUBFRAMES] = {0, 0, 0, 0};
1544 :
1545 : /* Take the asin. */
1546 0 : for (k = 0; k < PITCH_SUBFRAMES; k++) {
1547 0 : PitchGains[k] = ((float)PitchGains_Q12[k]) / 4096;
1548 0 : S[k] = asin(PitchGains[k]);
1549 : }
1550 :
1551 : /* Find quantization index; only for the first three
1552 : * transform coefficients. */
1553 0 : for (k = 0; k < 3; k++) {
1554 : /* transform */
1555 0 : C = 0.0;
1556 0 : for (j = 0; j < PITCH_SUBFRAMES; j++) {
1557 0 : C += WebRtcIsac_kTransform[k][j] * S[j];
1558 : }
1559 : /* Quantize */
1560 0 : index[k] = WebRtcIsac_lrint(C / PITCH_GAIN_STEPSIZE);
1561 :
1562 : /* Check that the index is not outside the boundaries of the table. */
1563 0 : if (index[k] < WebRtcIsac_kIndexLowerLimitGain[k]) {
1564 0 : index[k] = WebRtcIsac_kIndexLowerLimitGain[k];
1565 0 : } else if (index[k] > WebRtcIsac_kIndexUpperLimitGain[k]) {
1566 0 : index[k] = WebRtcIsac_kIndexUpperLimitGain[k];
1567 : }
1568 0 : index[k] -= WebRtcIsac_kIndexLowerLimitGain[k];
1569 : }
1570 :
1571 : /* Calculate unique overall index. */
1572 0 : index_comb = WebRtcIsac_kIndexMultsGain[0] * index[0] +
1573 0 : WebRtcIsac_kIndexMultsGain[1] * index[1] + index[2];
1574 :
1575 : /* unquantize back to pitch gains by table look-up */
1576 0 : PitchGains_Q12[0] = WebRtcIsac_kQMeanGain1Q12[index_comb];
1577 0 : PitchGains_Q12[1] = WebRtcIsac_kQMeanGain2Q12[index_comb];
1578 0 : PitchGains_Q12[2] = WebRtcIsac_kQMeanGain3Q12[index_comb];
1579 0 : PitchGains_Q12[3] = WebRtcIsac_kQMeanGain4Q12[index_comb];
1580 :
1581 : /* entropy coding of quantization pitch gains */
1582 0 : *WebRtcIsac_kQPitchGainCdf_ptr = WebRtcIsac_kQPitchGainCdf;
1583 0 : WebRtcIsac_EncHistMulti(streamdata, &index_comb,
1584 : WebRtcIsac_kQPitchGainCdf_ptr, 1);
1585 0 : encData->pitchGain_index[encData->startIdx] = index_comb;
1586 0 : }
1587 :
1588 :
1589 :
1590 : /* Pitch LAG */
1591 : /* Decode & de-quantize Pitch Lags. */
1592 0 : int WebRtcIsac_DecodePitchLag(Bitstr* streamdata, int16_t* PitchGain_Q12,
1593 : double* PitchLags) {
1594 : int k, err;
1595 : double StepSize;
1596 : double C;
1597 : int index[PITCH_SUBFRAMES];
1598 : double mean_gain;
1599 : const double* mean_val2, *mean_val3, *mean_val4;
1600 : const int16_t* lower_limit;
1601 : const uint16_t* init_index;
1602 : const uint16_t* cdf_size;
1603 : const uint16_t** cdf;
1604 0 : double PitchGain[4] = {0, 0, 0, 0};
1605 :
1606 : /* compute mean pitch gain */
1607 0 : mean_gain = 0.0;
1608 0 : for (k = 0; k < 4; k++) {
1609 0 : PitchGain[k] = ((float)PitchGain_Q12[k]) / 4096;
1610 0 : mean_gain += PitchGain[k];
1611 : }
1612 0 : mean_gain /= 4.0;
1613 :
1614 : /* voicing classification. */
1615 0 : if (mean_gain < 0.2) {
1616 0 : StepSize = WebRtcIsac_kQPitchLagStepsizeLo;
1617 0 : cdf = WebRtcIsac_kQPitchLagCdfPtrLo;
1618 0 : cdf_size = WebRtcIsac_kQPitchLagCdfSizeLo;
1619 0 : mean_val2 = WebRtcIsac_kQMeanLag2Lo;
1620 0 : mean_val3 = WebRtcIsac_kQMeanLag3Lo;
1621 0 : mean_val4 = WebRtcIsac_kQMeanLag4Lo;
1622 0 : lower_limit = WebRtcIsac_kQIndexLowerLimitLagLo;
1623 0 : init_index = WebRtcIsac_kQInitIndexLagLo;
1624 0 : } else if (mean_gain < 0.4) {
1625 0 : StepSize = WebRtcIsac_kQPitchLagStepsizeMid;
1626 0 : cdf = WebRtcIsac_kQPitchLagCdfPtrMid;
1627 0 : cdf_size = WebRtcIsac_kQPitchLagCdfSizeMid;
1628 0 : mean_val2 = WebRtcIsac_kQMeanLag2Mid;
1629 0 : mean_val3 = WebRtcIsac_kQMeanLag3Mid;
1630 0 : mean_val4 = WebRtcIsac_kQMeanLag4Mid;
1631 0 : lower_limit = WebRtcIsac_kQIndexLowerLimitLagMid;
1632 0 : init_index = WebRtcIsac_kQInitIndexLagMid;
1633 : } else {
1634 0 : StepSize = WebRtcIsac_kQPitchLagStepsizeHi;
1635 0 : cdf = WebRtcIsac_kQPitchLagCdfPtrHi;
1636 0 : cdf_size = WebRtcIsac_kQPitchLagCdfSizeHi;
1637 0 : mean_val2 = WebRtcIsac_kQMeanLag2Hi;
1638 0 : mean_val3 = WebRtcIsac_kQMeanLag3Hi;
1639 0 : mean_val4 = WebRtcIsac_kQMeanLag4Hi;
1640 0 : lower_limit = WebRtcIsac_kQindexLowerLimitLagHi;
1641 0 : init_index = WebRtcIsac_kQInitIndexLagHi;
1642 : }
1643 :
1644 : /* Entropy decoding of quantization indices. */
1645 0 : err = WebRtcIsac_DecHistBisectMulti(index, streamdata, cdf, cdf_size, 1);
1646 0 : if ((err < 0) || (index[0] < 0)) {
1647 0 : return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG;
1648 : }
1649 0 : err = WebRtcIsac_DecHistOneStepMulti(index + 1, streamdata, cdf + 1,
1650 : init_index, 3);
1651 0 : if (err < 0) {
1652 0 : return -ISAC_RANGE_ERROR_DECODE_PITCH_LAG;
1653 : }
1654 :
1655 : /* Unquantize back to transform coefficients and do the inverse transform:
1656 : * S = T'*C. */
1657 0 : C = (index[0] + lower_limit[0]) * StepSize;
1658 0 : for (k = 0; k < PITCH_SUBFRAMES; k++) {
1659 0 : PitchLags[k] = WebRtcIsac_kTransformTranspose[k][0] * C;
1660 : }
1661 0 : C = mean_val2[index[1]];
1662 0 : for (k = 0; k < PITCH_SUBFRAMES; k++) {
1663 0 : PitchLags[k] += WebRtcIsac_kTransformTranspose[k][1] * C;
1664 : }
1665 0 : C = mean_val3[index[2]];
1666 0 : for (k = 0; k < PITCH_SUBFRAMES; k++) {
1667 0 : PitchLags[k] += WebRtcIsac_kTransformTranspose[k][2] * C;
1668 : }
1669 0 : C = mean_val4[index[3]];
1670 0 : for (k = 0; k < PITCH_SUBFRAMES; k++) {
1671 0 : PitchLags[k] += WebRtcIsac_kTransformTranspose[k][3] * C;
1672 : }
1673 0 : return 0;
1674 : }
1675 :
1676 :
1677 :
1678 : /* Quantize & code pitch lags. */
1679 0 : void WebRtcIsac_EncodePitchLag(double* PitchLags, int16_t* PitchGain_Q12,
1680 : Bitstr* streamdata,
1681 : IsacSaveEncoderData* encData) {
1682 : int k, j;
1683 : double StepSize;
1684 : double C;
1685 : int index[PITCH_SUBFRAMES];
1686 : double mean_gain;
1687 : const double* mean_val2, *mean_val3, *mean_val4;
1688 : const int16_t* lower_limit, *upper_limit;
1689 : const uint16_t** cdf;
1690 0 : double PitchGain[4] = {0, 0, 0, 0};
1691 :
1692 : /* compute mean pitch gain */
1693 0 : mean_gain = 0.0;
1694 0 : for (k = 0; k < 4; k++) {
1695 0 : PitchGain[k] = ((float)PitchGain_Q12[k]) / 4096;
1696 0 : mean_gain += PitchGain[k];
1697 : }
1698 0 : mean_gain /= 4.0;
1699 :
1700 : /* Save data for creation of multiple bit streams */
1701 0 : encData->meanGain[encData->startIdx] = mean_gain;
1702 :
1703 : /* Voicing classification. */
1704 0 : if (mean_gain < 0.2) {
1705 0 : StepSize = WebRtcIsac_kQPitchLagStepsizeLo;
1706 0 : cdf = WebRtcIsac_kQPitchLagCdfPtrLo;
1707 0 : mean_val2 = WebRtcIsac_kQMeanLag2Lo;
1708 0 : mean_val3 = WebRtcIsac_kQMeanLag3Lo;
1709 0 : mean_val4 = WebRtcIsac_kQMeanLag4Lo;
1710 0 : lower_limit = WebRtcIsac_kQIndexLowerLimitLagLo;
1711 0 : upper_limit = WebRtcIsac_kQIndexUpperLimitLagLo;
1712 0 : } else if (mean_gain < 0.4) {
1713 0 : StepSize = WebRtcIsac_kQPitchLagStepsizeMid;
1714 0 : cdf = WebRtcIsac_kQPitchLagCdfPtrMid;
1715 0 : mean_val2 = WebRtcIsac_kQMeanLag2Mid;
1716 0 : mean_val3 = WebRtcIsac_kQMeanLag3Mid;
1717 0 : mean_val4 = WebRtcIsac_kQMeanLag4Mid;
1718 0 : lower_limit = WebRtcIsac_kQIndexLowerLimitLagMid;
1719 0 : upper_limit = WebRtcIsac_kQIndexUpperLimitLagMid;
1720 : } else {
1721 0 : StepSize = WebRtcIsac_kQPitchLagStepsizeHi;
1722 0 : cdf = WebRtcIsac_kQPitchLagCdfPtrHi;
1723 0 : mean_val2 = WebRtcIsac_kQMeanLag2Hi;
1724 0 : mean_val3 = WebRtcIsac_kQMeanLag3Hi;
1725 0 : mean_val4 = WebRtcIsac_kQMeanLag4Hi;
1726 0 : lower_limit = WebRtcIsac_kQindexLowerLimitLagHi;
1727 0 : upper_limit = WebRtcIsac_kQindexUpperLimitLagHi;
1728 : }
1729 :
1730 : /* find quantization index */
1731 0 : for (k = 0; k < 4; k++) {
1732 : /* transform */
1733 0 : C = 0.0;
1734 0 : for (j = 0; j < PITCH_SUBFRAMES; j++) {
1735 0 : C += WebRtcIsac_kTransform[k][j] * PitchLags[j];
1736 : }
1737 : /* quantize */
1738 0 : index[k] = WebRtcIsac_lrint(C / StepSize);
1739 :
1740 : /* check that the index is not outside the boundaries of the table */
1741 0 : if (index[k] < lower_limit[k]) {
1742 0 : index[k] = lower_limit[k];
1743 0 : } else if (index[k] > upper_limit[k]) index[k] = upper_limit[k]; {
1744 0 : index[k] -= lower_limit[k];
1745 : }
1746 : /* Save data for creation of multiple bit streams */
1747 0 : encData->pitchIndex[PITCH_SUBFRAMES * encData->startIdx + k] = index[k];
1748 : }
1749 :
1750 : /* Un-quantize back to transform coefficients and do the inverse transform:
1751 : * S = T'*C */
1752 0 : C = (index[0] + lower_limit[0]) * StepSize;
1753 0 : for (k = 0; k < PITCH_SUBFRAMES; k++) {
1754 0 : PitchLags[k] = WebRtcIsac_kTransformTranspose[k][0] * C;
1755 : }
1756 0 : C = mean_val2[index[1]];
1757 0 : for (k = 0; k < PITCH_SUBFRAMES; k++) {
1758 0 : PitchLags[k] += WebRtcIsac_kTransformTranspose[k][1] * C;
1759 : }
1760 0 : C = mean_val3[index[2]];
1761 0 : for (k = 0; k < PITCH_SUBFRAMES; k++) {
1762 0 : PitchLags[k] += WebRtcIsac_kTransformTranspose[k][2] * C;
1763 : }
1764 0 : C = mean_val4[index[3]];
1765 0 : for (k = 0; k < PITCH_SUBFRAMES; k++) {
1766 0 : PitchLags[k] += WebRtcIsac_kTransformTranspose[k][3] * C;
1767 : }
1768 : /* entropy coding of quantization pitch lags */
1769 0 : WebRtcIsac_EncHistMulti(streamdata, index, cdf, PITCH_SUBFRAMES);
1770 0 : }
1771 :
1772 :
1773 :
1774 : /* Routines for in-band signaling of bandwidth estimation */
1775 : /* Histograms based on uniform distribution of indices */
1776 : /* Move global variables later! */
1777 :
1778 :
1779 : /* cdf array for frame length indicator */
1780 : const uint16_t WebRtcIsac_kFrameLengthCdf[4] = {
1781 : 0, 21845, 43690, 65535 };
1782 :
1783 : /* pointer to cdf array for frame length indicator */
1784 : const uint16_t* WebRtcIsac_kFrameLengthCdf_ptr[1] = {
1785 : WebRtcIsac_kFrameLengthCdf };
1786 :
1787 : /* initial cdf index for decoder of frame length indicator */
1788 : const uint16_t WebRtcIsac_kFrameLengthInitIndex[1] = { 1 };
1789 :
1790 :
1791 0 : int WebRtcIsac_DecodeFrameLen(Bitstr* streamdata, int16_t* framesamples) {
1792 : int frame_mode, err;
1793 0 : err = 0;
1794 : /* entropy decoding of frame length [1:30ms,2:60ms] */
1795 0 : err = WebRtcIsac_DecHistOneStepMulti(&frame_mode, streamdata,
1796 : WebRtcIsac_kFrameLengthCdf_ptr,
1797 : WebRtcIsac_kFrameLengthInitIndex, 1);
1798 0 : if (err < 0)
1799 0 : return -ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH;
1800 :
1801 0 : switch (frame_mode) {
1802 : case 1:
1803 0 : *framesamples = 480; /* 30ms */
1804 0 : break;
1805 : case 2:
1806 0 : *framesamples = 960; /* 60ms */
1807 0 : break;
1808 : default:
1809 0 : err = -ISAC_DISALLOWED_FRAME_MODE_DECODER;
1810 : }
1811 0 : return err;
1812 : }
1813 :
1814 0 : int WebRtcIsac_EncodeFrameLen(int16_t framesamples, Bitstr* streamdata) {
1815 : int frame_mode, status;
1816 :
1817 0 : status = 0;
1818 0 : frame_mode = 0;
1819 : /* entropy coding of frame length [1:480 samples,2:960 samples] */
1820 0 : switch (framesamples) {
1821 : case 480:
1822 0 : frame_mode = 1;
1823 0 : break;
1824 : case 960:
1825 0 : frame_mode = 2;
1826 0 : break;
1827 : default:
1828 0 : status = - ISAC_DISALLOWED_FRAME_MODE_ENCODER;
1829 : }
1830 :
1831 0 : if (status < 0)
1832 0 : return status;
1833 :
1834 0 : WebRtcIsac_EncHistMulti(streamdata, &frame_mode,
1835 : WebRtcIsac_kFrameLengthCdf_ptr, 1);
1836 0 : return status;
1837 : }
1838 :
1839 : /* cdf array for estimated bandwidth */
1840 : static const uint16_t kBwCdf[25] = {
1841 : 0, 2731, 5461, 8192, 10923, 13653, 16384, 19114, 21845, 24576, 27306, 30037,
1842 : 32768, 35498, 38229, 40959, 43690, 46421, 49151, 51882, 54613, 57343, 60074,
1843 : 62804, 65535 };
1844 :
1845 : /* pointer to cdf array for estimated bandwidth */
1846 : static const uint16_t* kBwCdfPtr[1] = { kBwCdf };
1847 :
1848 : /* initial cdf index for decoder of estimated bandwidth*/
1849 : static const uint16_t kBwInitIndex[1] = { 7 };
1850 :
1851 :
1852 0 : int WebRtcIsac_DecodeSendBW(Bitstr* streamdata, int16_t* BWno) {
1853 : int BWno32, err;
1854 :
1855 : /* entropy decoding of sender's BW estimation [0..23] */
1856 0 : err = WebRtcIsac_DecHistOneStepMulti(&BWno32, streamdata, kBwCdfPtr,
1857 : kBwInitIndex, 1);
1858 0 : if (err < 0) {
1859 0 : return -ISAC_RANGE_ERROR_DECODE_BANDWIDTH;
1860 : }
1861 0 : *BWno = (int16_t)BWno32;
1862 0 : return err;
1863 : }
1864 :
1865 0 : void WebRtcIsac_EncodeReceiveBw(int* BWno, Bitstr* streamdata) {
1866 : /* entropy encoding of receiver's BW estimation [0..23] */
1867 0 : WebRtcIsac_EncHistMulti(streamdata, BWno, kBwCdfPtr, 1);
1868 0 : }
1869 :
1870 :
1871 : /* estimate code length of LPC Coef */
1872 0 : void WebRtcIsac_TranscodeLPCCoef(double* LPCCoef_lo, double* LPCCoef_hi,
1873 : int* index_g) {
1874 : int j, k, n, pos, pos2, posg, offsg, offs2;
1875 : int index_ovr_g[KLT_ORDER_GAIN];
1876 : double tmpcoeffs_g[KLT_ORDER_GAIN];
1877 : double tmpcoeffs2_g[KLT_ORDER_GAIN];
1878 : double sum;
1879 :
1880 : /* log gains, mean removal and scaling */
1881 0 : posg = 0;
1882 0 : for (k = 0; k < SUBFRAMES; k++) {
1883 0 : tmpcoeffs_g[posg] = log(LPCCoef_lo[(LPC_LOBAND_ORDER + 1) * k]);
1884 0 : tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg];
1885 0 : tmpcoeffs_g[posg] *= LPC_GAIN_SCALE;
1886 0 : posg++;
1887 0 : tmpcoeffs_g[posg] = log(LPCCoef_hi[(LPC_HIBAND_ORDER + 1) * k]);
1888 0 : tmpcoeffs_g[posg] -= WebRtcIsac_kLpcMeansGain[posg];
1889 0 : tmpcoeffs_g[posg] *= LPC_GAIN_SCALE;
1890 0 : posg++;
1891 : }
1892 :
1893 : /* KLT */
1894 :
1895 : /* Left transform. */
1896 0 : offsg = 0;
1897 0 : for (j = 0; j < SUBFRAMES; j++) {
1898 0 : posg = offsg;
1899 0 : for (k = 0; k < LPC_GAIN_ORDER; k++) {
1900 0 : sum = 0;
1901 0 : pos = offsg;
1902 0 : pos2 = k;
1903 0 : for (n = 0; n < LPC_GAIN_ORDER; n++) {
1904 0 : sum += tmpcoeffs_g[pos++] * WebRtcIsac_kKltT1Gain[pos2];
1905 0 : pos2 += LPC_GAIN_ORDER;
1906 : }
1907 0 : tmpcoeffs2_g[posg++] = sum;
1908 : }
1909 0 : offsg += LPC_GAIN_ORDER;
1910 : }
1911 :
1912 : /* Right transform. */
1913 0 : offsg = 0;
1914 0 : offs2 = 0;
1915 0 : for (j = 0; j < SUBFRAMES; j++) {
1916 0 : posg = offsg;
1917 0 : for (k = 0; k < LPC_GAIN_ORDER; k++) {
1918 0 : sum = 0;
1919 0 : pos = k;
1920 0 : pos2 = offs2;
1921 0 : for (n = 0; n < SUBFRAMES; n++) {
1922 0 : sum += tmpcoeffs2_g[pos] * WebRtcIsac_kKltT2Gain[pos2++];
1923 0 : pos += LPC_GAIN_ORDER;
1924 : }
1925 0 : tmpcoeffs_g[posg++] = sum;
1926 : }
1927 0 : offs2 += SUBFRAMES;
1928 0 : offsg += LPC_GAIN_ORDER;
1929 : }
1930 :
1931 :
1932 : /* quantize coefficients */
1933 0 : for (k = 0; k < KLT_ORDER_GAIN; k++) {
1934 : /* Get index. */
1935 0 : pos2 = WebRtcIsac_lrint(tmpcoeffs_g[k] / KLT_STEPSIZE);
1936 0 : index_g[k] = (pos2) + WebRtcIsac_kQKltQuantMinGain[k];
1937 0 : if (index_g[k] < 0) {
1938 0 : index_g[k] = 0;
1939 0 : } else if (index_g[k] > WebRtcIsac_kQKltMaxIndGain[k]) {
1940 0 : index_g[k] = WebRtcIsac_kQKltMaxIndGain[k];
1941 : }
1942 0 : index_ovr_g[k] = WebRtcIsac_kQKltOffsetGain[k] + index_g[k];
1943 :
1944 : /* find quantization levels for coefficients */
1945 0 : tmpcoeffs_g[k] = WebRtcIsac_kQKltLevelsGain[index_ovr_g[k]];
1946 : }
1947 0 : }
1948 :
1949 :
1950 : /* Decode & de-quantize LPC Coefficients. */
1951 0 : int WebRtcIsac_DecodeLpcCoefUB(Bitstr* streamdata, double* lpcVecs,
1952 : double* percepFilterGains,
1953 : int16_t bandwidth) {
1954 : int index_s[KLT_ORDER_SHAPE];
1955 :
1956 : double U[UB_LPC_ORDER * UB16_LPC_VEC_PER_FRAME];
1957 : int err;
1958 :
1959 : /* Entropy decoding of quantization indices. */
1960 0 : switch (bandwidth) {
1961 : case isac12kHz: {
1962 0 : err = WebRtcIsac_DecHistOneStepMulti(
1963 : index_s, streamdata, WebRtcIsac_kLpcShapeCdfMatUb12,
1964 : WebRtcIsac_kLpcShapeEntropySearchUb12, UB_LPC_ORDER *
1965 : UB_LPC_VEC_PER_FRAME);
1966 0 : break;
1967 : }
1968 : case isac16kHz: {
1969 0 : err = WebRtcIsac_DecHistOneStepMulti(
1970 : index_s, streamdata, WebRtcIsac_kLpcShapeCdfMatUb16,
1971 : WebRtcIsac_kLpcShapeEntropySearchUb16, UB_LPC_ORDER *
1972 : UB16_LPC_VEC_PER_FRAME);
1973 0 : break;
1974 : }
1975 : default:
1976 0 : return -1;
1977 : }
1978 :
1979 0 : if (err < 0) {
1980 0 : return err;
1981 : }
1982 :
1983 0 : WebRtcIsac_DequantizeLpcParam(index_s, lpcVecs, bandwidth);
1984 0 : WebRtcIsac_CorrelateInterVec(lpcVecs, U, bandwidth);
1985 0 : WebRtcIsac_CorrelateIntraVec(U, lpcVecs, bandwidth);
1986 0 : WebRtcIsac_AddLarMean(lpcVecs, bandwidth);
1987 0 : WebRtcIsac_DecodeLpcGainUb(percepFilterGains, streamdata);
1988 :
1989 0 : if (bandwidth == isac16kHz) {
1990 : /* Decode another set of Gains. */
1991 0 : WebRtcIsac_DecodeLpcGainUb(&percepFilterGains[SUBFRAMES], streamdata);
1992 : }
1993 0 : return 0;
1994 : }
1995 :
1996 0 : int16_t WebRtcIsac_EncodeBandwidth(enum ISACBandwidth bandwidth,
1997 : Bitstr* streamData) {
1998 : int bandwidthMode;
1999 0 : switch (bandwidth) {
2000 : case isac12kHz: {
2001 0 : bandwidthMode = 0;
2002 0 : break;
2003 : }
2004 : case isac16kHz: {
2005 0 : bandwidthMode = 1;
2006 0 : break;
2007 : }
2008 : default:
2009 0 : return -ISAC_DISALLOWED_ENCODER_BANDWIDTH;
2010 : }
2011 0 : WebRtcIsac_EncHistMulti(streamData, &bandwidthMode, kOneBitEqualProbCdf_ptr,
2012 : 1);
2013 0 : return 0;
2014 : }
2015 :
2016 0 : int16_t WebRtcIsac_DecodeBandwidth(Bitstr* streamData,
2017 : enum ISACBandwidth* bandwidth) {
2018 : int bandwidthMode;
2019 0 : if (WebRtcIsac_DecHistOneStepMulti(&bandwidthMode, streamData,
2020 : kOneBitEqualProbCdf_ptr,
2021 : kOneBitEqualProbInitIndex, 1) < 0) {
2022 0 : return -ISAC_RANGE_ERROR_DECODE_BANDWITH;
2023 : }
2024 0 : switch (bandwidthMode) {
2025 : case 0: {
2026 0 : *bandwidth = isac12kHz;
2027 0 : break;
2028 : }
2029 : case 1: {
2030 0 : *bandwidth = isac16kHz;
2031 0 : break;
2032 : }
2033 : default:
2034 0 : return -ISAC_DISALLOWED_BANDWIDTH_MODE_DECODER;
2035 : }
2036 0 : return 0;
2037 : }
2038 :
2039 0 : int16_t WebRtcIsac_EncodeJitterInfo(int32_t jitterIndex,
2040 : Bitstr* streamData) {
2041 : /* This is to avoid LINUX warning until we change 'int' to 'Word32'. */
2042 : int intVar;
2043 :
2044 0 : if ((jitterIndex < 0) || (jitterIndex > 1)) {
2045 0 : return -1;
2046 : }
2047 0 : intVar = (int)(jitterIndex);
2048 : /* Use the same CDF table as for bandwidth
2049 : * both take two values with equal probability.*/
2050 0 : WebRtcIsac_EncHistMulti(streamData, &intVar, kOneBitEqualProbCdf_ptr, 1);
2051 0 : return 0;
2052 : }
2053 :
2054 0 : int16_t WebRtcIsac_DecodeJitterInfo(Bitstr* streamData,
2055 : int32_t* jitterInfo) {
2056 : int intVar;
2057 : /* Use the same CDF table as for bandwidth
2058 : * both take two values with equal probability. */
2059 0 : if (WebRtcIsac_DecHistOneStepMulti(&intVar, streamData,
2060 : kOneBitEqualProbCdf_ptr,
2061 : kOneBitEqualProbInitIndex, 1) < 0) {
2062 0 : return -ISAC_RANGE_ERROR_DECODE_BANDWITH;
2063 : }
2064 0 : *jitterInfo = (int16_t)(intVar);
2065 0 : return 0;
2066 : }
|