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 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |