OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 /* | 11 /* |
12 * entropy_coding.c | 12 * entropy_coding.c |
13 * | 13 * |
14 * This file contains all functions used to arithmetically | 14 * This file contains all functions used to arithmetically |
15 * encode the iSAC bistream. | 15 * encode the iSAC bistream. |
16 * | 16 * |
17 */ | 17 */ |
18 | 18 |
19 #include <stddef.h> | 19 #include <stddef.h> |
20 | 20 |
21 #include "arith_routins.h" | 21 #include "arith_routins.h" |
22 #include "spectrum_ar_model_tables.h" | 22 #include "spectrum_ar_model_tables.h" |
23 #include "pitch_gain_tables.h" | 23 #include "pitch_gain_tables.h" |
24 #include "pitch_lag_tables.h" | 24 #include "pitch_lag_tables.h" |
25 #include "entropy_coding.h" | 25 #include "entropy_coding.h" |
26 #include "lpc_tables.h" | 26 #include "lpc_tables.h" |
27 #include "settings.h" | 27 #include "settings.h" |
28 #include "signal_processing_library.h" | 28 #include "signal_processing_library.h" |
29 #include "webrtc/base/checks.h" | 29 #include "webrtc/base/sanitizer.h" |
30 | 30 |
31 /* | 31 /* |
32 * Eenumerations for arguments to functions WebRtcIsacfix_MatrixProduct1() | 32 * Eenumerations for arguments to functions WebRtcIsacfix_MatrixProduct1() |
33 * and WebRtcIsacfix_MatrixProduct2(). | 33 * and WebRtcIsacfix_MatrixProduct2(). |
34 */ | 34 */ |
35 | 35 |
36 enum matrix_index_factor { | 36 enum matrix_index_factor { |
37 kTIndexFactor1 = 1, | 37 kTIndexFactor1 = 1, |
38 kTIndexFactor2 = 2, | 38 kTIndexFactor2 = 2, |
39 kTIndexFactor3 = SUBFRAMES, | 39 kTIndexFactor3 = SUBFRAMES, |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
182 } | 182 } |
183 | 183 |
184 for (k=1; k<AR_ORDER; k+=2) { | 184 for (k=1; k<AR_ORDER; k+=2) { |
185 sum = 0; | 185 sum = 0; |
186 for (n = 0; n < FRAMESAMPLES/8; n++) | 186 for (n = 0; n < FRAMESAMPLES/8; n++) |
187 sum += (WebRtcIsacfix_kCos[k][n] * summ[n] + 256) >> 9; | 187 sum += (WebRtcIsacfix_kCos[k][n] * summ[n] + 256) >> 9; |
188 CorrQ7[k+1] = sum; | 188 CorrQ7[k+1] = sum; |
189 } | 189 } |
190 } | 190 } |
191 | 191 |
192 // Some arithmetic operations that are allowed to overflow. (It's still | |
193 // undefined behavior, so not a good idea; this just makes UBSan ignore the | |
194 // violations, so that our old code can continue to do what it's always been | |
195 // doing.) | |
196 static inline int32_t OverflowingMulS16S32ToS32(int16_t a, int32_t b) | |
197 RTC_NO_SANITIZE("signed-integer-overflow") { | |
198 return a * b; | |
199 } | |
200 static inline int32_t OverflowingAddS32S32ToS32(int32_t a, int32_t b) | |
201 RTC_NO_SANITIZE("signed-integer-overflow") { | |
202 return a + b; | |
203 } | |
204 static inline int32_t OverflowingSubS32S32ToS32(int32_t a, int32_t b) | |
205 RTC_NO_SANITIZE("signed-integer-overflow") { | |
206 return a - b; | |
207 } | |
192 | 208 |
193 /* compute inverse AR power spectrum */ | 209 /* compute inverse AR power spectrum */ |
194 static void CalcInvArSpec(const int16_t *ARCoefQ12, | 210 static void CalcInvArSpec(const int16_t *ARCoefQ12, |
195 const int32_t gainQ10, | 211 const int32_t gainQ10, |
196 int32_t *CurveQ16) | 212 int32_t *CurveQ16) |
197 { | 213 { |
198 int32_t CorrQ11[AR_ORDER+1]; | 214 int32_t CorrQ11[AR_ORDER+1]; |
199 int32_t sum, tmpGain; | 215 int32_t sum, tmpGain; |
200 int32_t diffQ16[FRAMESAMPLES/8]; | 216 int32_t diffQ16[FRAMESAMPLES/8]; |
201 const int16_t *CS_ptrQ9; | 217 const int16_t *CS_ptrQ9; |
(...skipping 22 matching lines...) Expand all Loading... | |
224 for (n = k; n < AR_ORDER+1; n++) | 240 for (n = k; n < AR_ORDER+1; n++) |
225 sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ | 241 sum += WEBRTC_SPL_MUL(ARCoefQ12[n-k], ARCoefQ12[n]); /* Q24 */ |
226 sum >>= 15; | 242 sum >>= 15; |
227 CorrQ11[k] = (sum * tmpGain + round) >> shftVal; | 243 CorrQ11[k] = (sum * tmpGain + round) >> shftVal; |
228 } | 244 } |
229 sum = CorrQ11[0] << 7; | 245 sum = CorrQ11[0] << 7; |
230 for (n = 0; n < FRAMESAMPLES/8; n++) | 246 for (n = 0; n < FRAMESAMPLES/8; n++) |
231 CurveQ16[n] = sum; | 247 CurveQ16[n] = sum; |
232 | 248 |
233 for (k = 1; k < AR_ORDER; k += 2) { | 249 for (k = 1; k < AR_ORDER; k += 2) { |
234 for (n = 0; n < FRAMESAMPLES/8; n++) { | 250 for (n = 0; n < FRAMESAMPLES/8; n++) |
235 const int64_t p = | 251 CurveQ16[n] += |
236 (WebRtcIsacfix_kCos[k][n] * (int64_t)CorrQ11[k + 1] + 2) >> 2; | 252 (OverflowingMulS16S32ToS32(WebRtcIsacfix_kCos[k][n], CorrQ11[k + 1]) + |
237 CurveQ16[n] += WebRtcSpl_SatW64ToW32(p); | 253 2) >> |
238 } | 254 2; |
239 } | 255 } |
240 | 256 |
241 CS_ptrQ9 = WebRtcIsacfix_kCos[0]; | 257 CS_ptrQ9 = WebRtcIsacfix_kCos[0]; |
242 | 258 |
243 /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shi fting */ | 259 /* If CorrQ11[1] too large we avoid getting overflow in the calculation by shi fting */ |
244 sh=WebRtcSpl_NormW32(CorrQ11[1]); | 260 sh=WebRtcSpl_NormW32(CorrQ11[1]); |
245 if (CorrQ11[1]==0) /* Use next correlation */ | 261 if (CorrQ11[1]==0) /* Use next correlation */ |
246 sh=WebRtcSpl_NormW32(CorrQ11[2]); | 262 sh=WebRtcSpl_NormW32(CorrQ11[2]); |
247 | 263 |
248 if (sh<9) | 264 if (sh<9) |
249 shftVal = 9 - sh; | 265 shftVal = 9 - sh; |
250 else | 266 else |
251 shftVal = 0; | 267 shftVal = 0; |
252 | 268 |
253 for (n = 0; n < FRAMESAMPLES/8; n++) | 269 for (n = 0; n < FRAMESAMPLES/8; n++) |
254 diffQ16[n] = (CS_ptrQ9[n] * (CorrQ11[1] >> shftVal) + 2) >> 2; | 270 diffQ16[n] = (CS_ptrQ9[n] * (CorrQ11[1] >> shftVal) + 2) >> 2; |
255 for (k = 2; k < AR_ORDER; k += 2) { | 271 for (k = 2; k < AR_ORDER; k += 2) { |
256 CS_ptrQ9 = WebRtcIsacfix_kCos[k]; | 272 CS_ptrQ9 = WebRtcIsacfix_kCos[k]; |
257 for (n = 0; n < FRAMESAMPLES/8; n++) | 273 for (n = 0; n < FRAMESAMPLES/8; n++) |
258 diffQ16[n] += (CS_ptrQ9[n] * (CorrQ11[k + 1] >> shftVal) + 2) >> 2; | 274 diffQ16[n] += (CS_ptrQ9[n] * (CorrQ11[k + 1] >> shftVal) + 2) >> 2; |
259 } | 275 } |
260 | 276 |
261 for (k=0; k<FRAMESAMPLES/8; k++) { | 277 for (k=0; k<FRAMESAMPLES/8; k++) { |
262 int32_t diff_q16 = diffQ16[k] * (1 << shftVal); | 278 int32_t diff_q16 = diffQ16[k] * (1 << shftVal); |
263 CurveQ16[FRAMESAMPLES / 4 - 1 - k] = | 279 CurveQ16[FRAMESAMPLES / 4 - 1 - k] = |
264 WebRtcSpl_SubSatW32(CurveQ16[k], diff_q16); | 280 OverflowingSubS32S32ToS32(CurveQ16[k], diff_q16); |
265 CurveQ16[k] = WebRtcSpl_AddSatW32(CurveQ16[k], diff_q16); | 281 CurveQ16[k] = OverflowingAddS32S32ToS32(CurveQ16[k], diff_q16); |
266 } | 282 } |
267 } | 283 } |
268 | 284 |
269 static void CalcRootInvArSpec(const int16_t *ARCoefQ12, | 285 static void CalcRootInvArSpec(const int16_t *ARCoefQ12, |
270 const int32_t gainQ10, | 286 const int32_t gainQ10, |
271 uint16_t *CurveQ8) | 287 uint16_t *CurveQ8) |
272 { | 288 { |
273 int32_t CorrQ11[AR_ORDER+1]; | 289 int32_t CorrQ11[AR_ORDER+1]; |
274 int32_t sum, tmpGain; | 290 int32_t sum, tmpGain; |
275 int32_t summQ16[FRAMESAMPLES/8]; | 291 int32_t summQ16[FRAMESAMPLES/8]; |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
490 len = WebRtcIsacfix_DecLogisticMulti2(data, streamdata, invARSpec2_Q16, (int16 _t)FRAMESAMPLES); | 506 len = WebRtcIsacfix_DecLogisticMulti2(data, streamdata, invARSpec2_Q16, (int16 _t)FRAMESAMPLES); |
491 | 507 |
492 if (len<1) | 508 if (len<1) |
493 return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; | 509 return -ISAC_RANGE_ERROR_DECODE_SPECTRUM; |
494 | 510 |
495 /* subtract dither and scale down spectral samples with low SNR */ | 511 /* subtract dither and scale down spectral samples with low SNR */ |
496 if (AvgPitchGain_Q12 <= 614) | 512 if (AvgPitchGain_Q12 <= 614) |
497 { | 513 { |
498 for (k = 0; k < FRAMESAMPLES; k += 4) | 514 for (k = 0; k < FRAMESAMPLES; k += 4) |
499 { | 515 { |
500 gainQ10 = WebRtcSpl_DivW32W16ResW16( | 516 gainQ10 = WebRtcSpl_DivW32W16ResW16(30 << 10, |
hlundin-webrtc
2017/04/10 07:44:30
This seems just like an exact revert to the old be
kwiberg-webrtc
2017/04/10 08:13:29
No---without the change higher up in this file, th
| |
501 30 << 10, (int16_t)((uint32_t)(WebRtcSpl_AddSatW32( | 517 (int16_t)((uint32_t)(invARSpec2_Q16[k >> 2] + 2195456) >> 16)); |
502 invARSpec2_Q16[k >> 2], 2195456)) >> | |
503 16)); | |
504 *frQ7++ = (int16_t)((data[k] * gainQ10 + 512) >> 10); | 518 *frQ7++ = (int16_t)((data[k] * gainQ10 + 512) >> 10); |
505 *fiQ7++ = (int16_t)((data[k + 1] * gainQ10 + 512) >> 10); | 519 *fiQ7++ = (int16_t)((data[k + 1] * gainQ10 + 512) >> 10); |
506 *frQ7++ = (int16_t)((data[k + 2] * gainQ10 + 512) >> 10); | 520 *frQ7++ = (int16_t)((data[k + 2] * gainQ10 + 512) >> 10); |
507 *fiQ7++ = (int16_t)((data[k + 3] * gainQ10 + 512) >> 10); | 521 *fiQ7++ = (int16_t)((data[k + 3] * gainQ10 + 512) >> 10); |
508 } | 522 } |
509 } | 523 } |
510 else | 524 else |
511 { | 525 { |
512 for (k = 0; k < FRAMESAMPLES; k += 4) | 526 for (k = 0; k < FRAMESAMPLES; k += 4) |
513 { | 527 { |
514 gainQ10 = WebRtcSpl_DivW32W16ResW16( | 528 gainQ10 = WebRtcSpl_DivW32W16ResW16(36 << 10, |
hlundin-webrtc
2017/04/10 07:44:30
Same question as above.
kwiberg-webrtc
2017/04/10 08:13:29
Same answer.
| |
515 36 << 10, (int16_t)((uint32_t)(WebRtcSpl_AddSatW32( | 529 (int16_t)((uint32_t)(invARSpec2_Q16[k >> 2] + 2654208) >> 16)); |
516 invARSpec2_Q16[k >> 2], 2654208)) >> | |
517 16)); | |
518 *frQ7++ = (int16_t)((data[k] * gainQ10 + 512) >> 10); | 530 *frQ7++ = (int16_t)((data[k] * gainQ10 + 512) >> 10); |
519 *fiQ7++ = (int16_t)((data[k + 1] * gainQ10 + 512) >> 10); | 531 *fiQ7++ = (int16_t)((data[k + 1] * gainQ10 + 512) >> 10); |
520 *frQ7++ = (int16_t)((data[k + 2] * gainQ10 + 512) >> 10); | 532 *frQ7++ = (int16_t)((data[k + 2] * gainQ10 + 512) >> 10); |
521 *fiQ7++ = (int16_t)((data[k + 3] * gainQ10 + 512) >> 10); | 533 *fiQ7++ = (int16_t)((data[k + 3] * gainQ10 + 512) >> 10); |
522 } | 534 } |
523 } | 535 } |
524 | 536 |
525 return len; | 537 return len; |
526 } | 538 } |
527 | 539 |
(...skipping 1507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2035 | 2047 |
2036 index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? | 2048 index_gQQ[k] = pos2QQ + WebRtcIsacfix_kQuantMinGain[k]; //ATTN: ok? |
2037 if (index_gQQ[k] < 0) { | 2049 if (index_gQQ[k] < 0) { |
2038 index_gQQ[k] = 0; | 2050 index_gQQ[k] = 0; |
2039 } | 2051 } |
2040 else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { | 2052 else if (index_gQQ[k] > WebRtcIsacfix_kMaxIndGain[k]) { |
2041 index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; | 2053 index_gQQ[k] = WebRtcIsacfix_kMaxIndGain[k]; |
2042 } | 2054 } |
2043 } | 2055 } |
2044 } | 2056 } |
OLD | NEW |