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 * lattice.c | 12 * lattice.c |
13 * | 13 * |
14 * Contains the normalized lattice filter routines (MA and AR) for iSAC codec | 14 * Contains the normalized lattice filter routines (MA and AR) for iSAC codec |
15 * | 15 * |
16 */ | 16 */ |
17 | 17 |
18 #include "codec.h" | 18 #include "codec.h" |
19 #include "settings.h" | 19 #include "settings.h" |
| 20 #include "webrtc/base/sanitizer.h" |
20 | 21 |
21 #define LATTICE_MUL_32_32_RSFT16(a32a, a32b, b32) \ | 22 #define LATTICE_MUL_32_32_RSFT16(a32a, a32b, b32) \ |
22 ((int32_t)(WEBRTC_SPL_MUL(a32a, b32) + (WEBRTC_SPL_MUL_16_32_RSFT16(a32b, b32)
))) | 23 ((int32_t)(WEBRTC_SPL_MUL(a32a, b32) + (WEBRTC_SPL_MUL_16_32_RSFT16(a32b, b32)
))) |
23 /* This macro is FORBIDDEN to use elsewhere than in a function in this file and | 24 /* This macro is FORBIDDEN to use elsewhere than in a function in this file and |
24 its corresponding neon version. It might give unpredictable results, since a | 25 its corresponding neon version. It might give unpredictable results, since a |
25 general int32_t*int32_t multiplication results in a 64 bit value. | 26 general int32_t*int32_t multiplication results in a 64 bit value. |
26 The result is then shifted just 16 steps to the right, giving need for 48 | 27 The result is then shifted just 16 steps to the right, giving need for 48 |
27 bits, i.e. in the generel case, it will NOT fit in a int32_t. In the | 28 bits, i.e. in the generel case, it will NOT fit in a int32_t. In the |
28 cases used in here, the int32_t will be enough, since (for a good | 29 cases used in here, the int32_t will be enough, since (for a good |
29 reason) the involved multiplicands aren't big enough to overflow a | 30 reason) the involved multiplicands aren't big enough to overflow a |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 for (i=0;i<ord_1;i++) | 199 for (i=0;i<ord_1;i++) |
199 { | 200 { |
200 stateGQ15[i] = gQ15[i][HALF_SUBFRAMELEN-1]; | 201 stateGQ15[i] = gQ15[i][HALF_SUBFRAMELEN-1]; |
201 } | 202 } |
202 //process next frame | 203 //process next frame |
203 } | 204 } |
204 | 205 |
205 return; | 206 return; |
206 } | 207 } |
207 | 208 |
208 | 209 // Left shift of an int32_t that's allowed to overflow. (It's still undefined |
209 | 210 // behavior, so not a good idea; this just makes UBSan ignore the violation, so |
210 | 211 // that our old code can continue to do what it's always been doing.) |
| 212 static inline int32_t OverflowingLShiftS32(int32_t x, int shift) |
| 213 RTC_NO_SANITIZE("shift") { |
| 214 return x << shift; |
| 215 } |
211 | 216 |
212 /* ----------------AR filter-------------------------*/ | 217 /* ----------------AR filter-------------------------*/ |
213 /* filter the signal using normalized lattice filter */ | 218 /* filter the signal using normalized lattice filter */ |
214 void WebRtcIsacfix_NormLatticeFilterAr(size_t orderCoef, | 219 void WebRtcIsacfix_NormLatticeFilterAr(size_t orderCoef, |
215 int16_t *stateGQ0, | 220 int16_t *stateGQ0, |
216 int32_t *lat_inQ25, | 221 int32_t *lat_inQ25, |
217 int16_t *filt_coefQ15, | 222 int16_t *filt_coefQ15, |
218 int32_t *gain_lo_hiQ17, | 223 int32_t *gain_lo_hiQ17, |
219 int16_t lo_hi, | 224 int16_t lo_hi, |
220 int16_t *lat_outQ0) | 225 int16_t *lat_outQ0) |
(...skipping 24 matching lines...) Expand all Loading... |
245 //set the denominator and numerator of the Direct Form | 250 //set the denominator and numerator of the Direct Form |
246 temp2 = (int16_t)(u * orderCoef); | 251 temp2 = (int16_t)(u * orderCoef); |
247 temp3 = (int16_t)(2 * u + lo_hi); | 252 temp3 = (int16_t)(2 * u + lo_hi); |
248 | 253 |
249 for (ii=0; ii<orderCoef; ii++) { | 254 for (ii=0; ii<orderCoef; ii++) { |
250 sthQ15[ii] = filt_coefQ15[temp2+ii]; | 255 sthQ15[ii] = filt_coefQ15[temp2+ii]; |
251 } | 256 } |
252 | 257 |
253 WebRtcSpl_SqrtOfOneMinusXSquared(sthQ15, orderCoef, cthQ15); | 258 WebRtcSpl_SqrtOfOneMinusXSquared(sthQ15, orderCoef, cthQ15); |
254 | 259 |
255 /* Simulation of the 25 files shows that maximum value in | 260 // Originally, this line was assumed to never overflow, since "[s]imulation |
256 the vector gain_lo_hiQ17[] is 441344, which means that | 261 // of the 25 files shows that maximum value in the vector gain_lo_hiQ17[] |
257 it is log2((2^31)/441344) = 12.2 shifting bits from | 262 // is 441344, which means that it is log2((2^31)/441344) = 12.2 shifting |
258 saturation. Therefore, it should be safe to use Q27 instead | 263 // bits from saturation. Therefore, it should be safe to use Q27 instead of |
259 of Q17. */ | 264 // Q17." However, a fuzzer test succeeded in provoking an overflow here, |
260 | 265 // which we ignore on the theory that only "abnormal" inputs cause |
261 tmp32 = gain_lo_hiQ17[temp3] << 10; // Q27 | 266 // overflow. |
| 267 tmp32 = OverflowingLShiftS32(gain_lo_hiQ17[temp3], 10); // Q27 |
262 | 268 |
263 for (k=0;k<orderCoef;k++) { | 269 for (k=0;k<orderCoef;k++) { |
264 tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[k], tmp32); // Q15*Q27>>15 = Q2
7 | 270 tmp32 = WEBRTC_SPL_MUL_16_32_RSFT15(cthQ15[k], tmp32); // Q15*Q27>>15 = Q2
7 |
265 } | 271 } |
266 | 272 |
267 sh = WebRtcSpl_NormW32(tmp32); // tmp32 is the gain | 273 sh = WebRtcSpl_NormW32(tmp32); // tmp32 is the gain |
268 den16 = (int16_t) WEBRTC_SPL_SHIFT_W32(tmp32, sh-16); //Q(27+sh-16) = Q(sh+1
1) (all 16 bits are value bits) | 274 den16 = (int16_t) WEBRTC_SPL_SHIFT_W32(tmp32, sh-16); //Q(27+sh-16) = Q(sh+1
1) (all 16 bits are value bits) |
269 inv_gain32 = WebRtcSpl_DivW32W16((int32_t)2147483647, den16); // 1/gain in Q
31/Q(sh+11) = Q(20-sh) | 275 inv_gain32 = WebRtcSpl_DivW32W16((int32_t)2147483647, den16); // 1/gain in Q
31/Q(sh+11) = Q(20-sh) |
270 | 276 |
271 //initial conditions | 277 //initial conditions |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 /* cannot use memcpy in the following */ | 313 /* cannot use memcpy in the following */ |
308 | 314 |
309 for (i=0;i<ord_1;i++) | 315 for (i=0;i<ord_1;i++) |
310 { | 316 { |
311 stateGQ0[i] = ARgQ0vec[i]; | 317 stateGQ0[i] = ARgQ0vec[i]; |
312 } | 318 } |
313 } | 319 } |
314 | 320 |
315 return; | 321 return; |
316 } | 322 } |
OLD | NEW |