| 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 |