Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1598)

Side by Side Diff: webrtc/modules/audio_processing/agc/legacy/digital_agc.c

Issue 1999653002: Fix UBSan errors (left shift on negative value) (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: refinement Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 { 110 {
111 assert(0); 111 assert(0);
112 return -1; 112 return -1;
113 } 113 }
114 114
115 // Calculate the limiter level and index: 115 // Calculate the limiter level and index:
116 // limiterLvlX = analogTarget - limiterOffset 116 // limiterLvlX = analogTarget - limiterOffset
117 // limiterLvl = targetLevelDbfs + limiterOffset/compRatio 117 // limiterLvl = targetLevelDbfs + limiterOffset/compRatio
118 limiterLvlX = analogTarget - limiterOffset; 118 limiterLvlX = analogTarget - limiterOffset;
119 limiterIdx = 119 limiterIdx =
120 2 + WebRtcSpl_DivW32W16ResW16((int32_t)limiterLvlX << 13, kLog10_2 / 2); 120 2 + WebRtcSpl_DivW32W16ResW16((int32_t)limiterLvlX * (1 << 13),
121 kLog10_2 / 2);
121 tmp16no1 = WebRtcSpl_DivW32W16ResW16(limiterOffset + (kCompRatio >> 1), kCom pRatio); 122 tmp16no1 = WebRtcSpl_DivW32W16ResW16(limiterOffset + (kCompRatio >> 1), kCom pRatio);
122 limiterLvl = targetLevelDbfs + tmp16no1; 123 limiterLvl = targetLevelDbfs + tmp16no1;
123 124
124 // Calculate (through table lookup): 125 // Calculate (through table lookup):
125 // constMaxGain = log2(1+2^(log2(e)*diffGain)); (in Q8) 126 // constMaxGain = log2(1+2^(log2(e)*diffGain)); (in Q8)
126 constMaxGain = kGenFuncTable[diffGain]; // in Q8 127 constMaxGain = kGenFuncTable[diffGain]; // in Q8
127 128
128 // Calculate a parameter used to approximate the fractional part of 2^x with a 129 // Calculate a parameter used to approximate the fractional part of 2^x with a
129 // piecewise linear function in Q14: 130 // piecewise linear function in Q14:
130 // constLinApprox = round(3/2*(4*(3-2*sqrt(2))/(log(2)^2)-0.5)*2^14); 131 // constLinApprox = round(3/2*(4*(3-2*sqrt(2))/(log(2)^2)-0.5)*2^14);
131 constLinApprox = 22817; // in Q14 132 constLinApprox = 22817; // in Q14
132 133
133 // Calculate a denominator used in the exponential part to convert from dB t o linear scale: 134 // Calculate a denominator used in the exponential part to convert from dB t o linear scale:
134 // den = 20*constMaxGain (in Q8) 135 // den = 20*constMaxGain (in Q8)
135 den = WEBRTC_SPL_MUL_16_U16(20, constMaxGain); // in Q8 136 den = WEBRTC_SPL_MUL_16_U16(20, constMaxGain); // in Q8
136 137
137 for (i = 0; i < 32; i++) 138 for (i = 0; i < 32; i++)
138 { 139 {
139 // Calculate scaled input level (compressor): 140 // Calculate scaled input level (compressor):
140 // inLevel = fix((-constLog10_2*(compRatio-1)*(1-i)+fix(compRatio/2))/c ompRatio) 141 // inLevel = fix((-constLog10_2*(compRatio-1)*(1-i)+fix(compRatio/2))/c ompRatio)
141 tmp16 = (int16_t)((kCompRatio - 1) * (i - 1)); // Q0 142 tmp16 = (int16_t)((kCompRatio - 1) * (i - 1)); // Q0
142 tmp32 = WEBRTC_SPL_MUL_16_U16(tmp16, kLog10_2) + 1; // Q14 143 tmp32 = WEBRTC_SPL_MUL_16_U16(tmp16, kLog10_2) + 1; // Q14
143 inLevel = WebRtcSpl_DivW32W16(tmp32, kCompRatio); // Q14 144 inLevel = WebRtcSpl_DivW32W16(tmp32, kCompRatio); // Q14
144 145
145 // Calculate diffGain-inLevel, to map using the genFuncTable 146 // Calculate diffGain-inLevel, to map using the genFuncTable
146 inLevel = ((int32_t)diffGain << 14) - inLevel; // Q14 147 inLevel = (int32_t)diffGain * (1 << 14) - inLevel; // Q14
147 148
148 // Make calculations on abs(inLevel) and compensate for the sign afterwa rds. 149 // Make calculations on abs(inLevel) and compensate for the sign afterwa rds.
149 absInLevel = (uint32_t)WEBRTC_SPL_ABS_W32(inLevel); // Q14 150 absInLevel = (uint32_t)WEBRTC_SPL_ABS_W32(inLevel); // Q14
150 151
151 // LUT with interpolation 152 // LUT with interpolation
152 intPart = (uint16_t)(absInLevel >> 14); 153 intPart = (uint16_t)(absInLevel >> 14);
153 fracPart = (uint16_t)(absInLevel & 0x00003FFF); // extract the fractiona l part 154 fracPart = (uint16_t)(absInLevel & 0x00003FFF); // extract the fractiona l part
154 tmpU16 = kGenFuncTable[intPart + 1] - kGenFuncTable[intPart]; // Q8 155 tmpU16 = kGenFuncTable[intPart + 1] - kGenFuncTable[intPart]; // Q8
155 tmpU32no1 = tmpU16 * fracPart; // Q22 156 tmpU32no1 = tmpU16 * fracPart; // Q22
156 tmpU32no1 += (uint32_t)kGenFuncTable[intPart] << 14; // Q22 157 tmpU32no1 += (uint32_t)kGenFuncTable[intPart] << 14; // Q22
(...skipping 21 matching lines...) Expand all
178 { 179 {
179 tmpU32no2 = WEBRTC_SPL_UMUL_32_16(absInLevel, kLogE_1); // Q28 180 tmpU32no2 = WEBRTC_SPL_UMUL_32_16(absInLevel, kLogE_1); // Q28
180 tmpU32no2 >>= 6; // Q22 181 tmpU32no2 >>= 6; // Q22
181 } 182 }
182 logApprox = 0; 183 logApprox = 0;
183 if (tmpU32no2 < tmpU32no1) 184 if (tmpU32no2 < tmpU32no1)
184 { 185 {
185 logApprox = (tmpU32no1 - tmpU32no2) >> (8 - zerosScale); //Q14 186 logApprox = (tmpU32no1 - tmpU32no2) >> (8 - zerosScale); //Q14
186 } 187 }
187 } 188 }
188 numFIX = (maxGain * constMaxGain) << 6; // Q14 189 numFIX = (maxGain * constMaxGain) * (1 << 6); // Q14
189 numFIX -= (int32_t)logApprox * diffGain; // Q14 190 numFIX -= (int32_t)logApprox * diffGain; // Q14
190 191
191 // Calculate ratio 192 // Calculate ratio
192 // Shift |numFIX| as much as possible. 193 // Shift |numFIX| as much as possible.
193 // Ensure we avoid wrap-around in |den| as well. 194 // Ensure we avoid wrap-around in |den| as well.
194 if (numFIX > (den >> 8)) // |den| is Q8. 195 if (numFIX > (den >> 8)) // |den| is Q8.
195 { 196 {
196 zeros = WebRtcSpl_NormW32(numFIX); 197 zeros = WebRtcSpl_NormW32(numFIX);
197 } else 198 } else
198 { 199 {
199 zeros = WebRtcSpl_NormW32(den) + 8; 200 zeros = WebRtcSpl_NormW32(den) + 8;
200 } 201 }
201 numFIX <<= zeros; // Q(14+zeros) 202 numFIX *= 1 << zeros; // Q(14+zeros)
202 203
203 // Shift den so we end up in Qy1 204 // Shift den so we end up in Qy1
204 tmp32no1 = WEBRTC_SPL_SHIFT_W32(den, zeros - 8); // Q(zeros) 205 tmp32no1 = WEBRTC_SPL_SHIFT_W32(den, zeros - 8); // Q(zeros)
205 if (numFIX < 0) 206 if (numFIX < 0)
206 { 207 {
207 numFIX -= tmp32no1 / 2; 208 numFIX -= tmp32no1 / 2;
208 } else 209 } else
209 { 210 {
210 numFIX += tmp32no1 / 2; 211 numFIX += tmp32no1 / 2;
211 } 212 }
212 y32 = numFIX / tmp32no1; // in Q14 213 y32 = numFIX / tmp32no1; // in Q14
213 if (limiterEnable && (i < limiterIdx)) 214 if (limiterEnable && (i < limiterIdx))
214 { 215 {
215 tmp32 = WEBRTC_SPL_MUL_16_U16(i - 1, kLog10_2); // Q14 216 tmp32 = WEBRTC_SPL_MUL_16_U16(i - 1, kLog10_2); // Q14
216 tmp32 -= limiterLvl << 14; // Q14 217 tmp32 -= limiterLvl * (1 << 14); // Q14
217 y32 = WebRtcSpl_DivW32W16(tmp32 + 10, 20); 218 y32 = WebRtcSpl_DivW32W16(tmp32 + 10, 20);
218 } 219 }
219 if (y32 > 39000) 220 if (y32 > 39000)
220 { 221 {
221 tmp32 = (y32 >> 1) * kLog10 + 4096; // in Q27 222 tmp32 = (y32 >> 1) * kLog10 + 4096; // in Q27
222 tmp32 >>= 13; // In Q14. 223 tmp32 >>= 13; // In Q14.
223 } else 224 } else
224 { 225 {
225 tmp32 = y32 * kLog10 + 8192; // in Q28 226 tmp32 = y32 * kLog10 + 8192; // in Q28
226 tmp32 >>= 14; // In Q14. 227 tmp32 >>= 14; // In Q14.
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 if (gains[k] > gains[k + 1]) 553 if (gains[k] > gains[k + 1])
553 { 554 {
554 gains[k] = gains[k + 1]; 555 gains[k] = gains[k + 1];
555 } 556 }
556 } 557 }
557 // save start gain for next frame 558 // save start gain for next frame
558 stt->gain = gains[10]; 559 stt->gain = gains[10];
559 560
560 // Apply gain 561 // Apply gain
561 // handle first sub frame separately 562 // handle first sub frame separately
562 delta = (gains[1] - gains[0]) << (4 - L2); 563 delta = (gains[1] - gains[0]) * (1 << (4 - L2));
563 gain32 = gains[0] << 4; 564 gain32 = gains[0] * (1 << 4);
564 // iterate over samples 565 // iterate over samples
565 for (n = 0; n < L; n++) 566 for (n = 0; n < L; n++)
566 { 567 {
567 for (i = 0; i < num_bands; ++i) 568 for (i = 0; i < num_bands; ++i)
568 { 569 {
569 tmp32 = out[i][n] * ((gain32 + 127) >> 7); 570 tmp32 = out[i][n] * ((gain32 + 127) >> 7);
570 out_tmp = tmp32 >> 16; 571 out_tmp = tmp32 >> 16;
571 if (out_tmp > 4095) 572 if (out_tmp > 4095)
572 { 573 {
573 out[i][n] = (int16_t)32767; 574 out[i][n] = (int16_t)32767;
574 } else if (out_tmp < -4096) 575 } else if (out_tmp < -4096)
575 { 576 {
576 out[i][n] = (int16_t)-32768; 577 out[i][n] = (int16_t)-32768;
577 } else 578 } else
578 { 579 {
579 tmp32 = out[i][n] * (gain32 >> 4); 580 tmp32 = out[i][n] * (gain32 >> 4);
580 out[i][n] = (int16_t)(tmp32 >> 16); 581 out[i][n] = (int16_t)(tmp32 >> 16);
581 } 582 }
582 } 583 }
583 // 584 //
584 585
585 gain32 += delta; 586 gain32 += delta;
586 } 587 }
587 // iterate over subframes 588 // iterate over subframes
588 for (k = 1; k < 10; k++) 589 for (k = 1; k < 10; k++)
589 { 590 {
590 delta = (gains[k+1] - gains[k]) << (4 - L2); 591 delta = (gains[k+1] - gains[k]) * (1 << (4 - L2));
591 gain32 = gains[k] << 4; 592 gain32 = gains[k] * (1 << 4);
592 // iterate over samples 593 // iterate over samples
593 for (n = 0; n < L; n++) 594 for (n = 0; n < L; n++)
594 { 595 {
595 for (i = 0; i < num_bands; ++i) 596 for (i = 0; i < num_bands; ++i)
596 { 597 {
597 tmp32 = out[i][k * L + n] * (gain32 >> 4); 598 tmp32 = out[i][k * L + n] * (gain32 >> 4);
598 out[i][k * L + n] = (int16_t)(tmp32 >> 16); 599 out[i][k * L + n] = (int16_t)(tmp32 >> 16);
599 } 600 }
600 gain32 += delta; 601 gain32 += delta;
601 } 602 }
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 { 764 {
764 state->logRatio = 2048; 765 state->logRatio = 2048;
765 } 766 }
766 if (state->logRatio < -2048) 767 if (state->logRatio < -2048)
767 { 768 {
768 state->logRatio = -2048; 769 state->logRatio = -2048;
769 } 770 }
770 771
771 return state->logRatio; // Q10 772 return state->logRatio; // Q10
772 } 773 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698