├── CMakeLists.txt ├── LICENSE ├── README.md ├── cng.cpp ├── cng.h ├── dr_wav.h └── main.cpp /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9) 2 | project(cng) 3 | add_compile_options(-std=c++11) 4 | add_executable(cng main.cpp 5 | cng.cpp 6 | ) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ============================ 2 | Copyright (c) 2011, The WebRTC project authors. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in 13 | the documentation and/or other materials provided with the 14 | distribution. 15 | 16 | * Neither the name of Google nor the names of its contributors may 17 | be used to endorse or promote products derived from this software 18 | without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WebRTC_CNG 2 | Comfort Noise Generator Module Port From WebRTC 3 | 4 | # Donating 5 | 6 | If you found this project useful, consider buying me a coffee 7 | 8 | Buy Me A Coffee 9 | -------------------------------------------------------------------------------- /cng.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 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 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #include "cng.h" 12 | #include 13 | 14 | #define WEBRTC_SPL_ABS_W16(a) \ 15 | (((int16_t)a >= 0) ? ((int16_t)a) : -((int16_t)a)) 16 | #define WEBRTC_SPL_MUL(a, b) \ 17 | ((int32_t) ((int32_t)(a) * (int32_t)(b))) 18 | #define WEBRTC_SPL_MUL_16_16(a, b) \ 19 | ((int32_t) (((int16_t)(a)) * ((int16_t)(b)))) 20 | #define WEBRTC_SPL_MUL_16_16_RSFT(a, b, c) \ 21 | (WEBRTC_SPL_MUL_16_16(a, b) >> (c)) 22 | #define WEBRTC_SPL_ABS_W32(a) \ 23 | (((int32_t)a >= 0) ? ((int32_t)a) : -((int32_t)a)) 24 | 25 | // Shifting with negative numbers not allowed 26 | // We cannot do casting here due to signed/unsigned problem 27 | #define WEBRTC_SPL_LSHIFT_W32(x, c) ((x) << (c)) 28 | 29 | int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den) { 30 | // Guard against division with 0 31 | if (den != 0) { 32 | return (int32_t) (num / den); 33 | } else { 34 | return (int32_t) 0x7FFFFFFF; 35 | } 36 | } 37 | 38 | void WebRtcSpl_ScaleVector(const int16_t *in_vector, int16_t *out_vector, 39 | int16_t gain, size_t in_vector_length, 40 | int16_t right_shifts) { 41 | // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts 42 | size_t i; 43 | const int16_t *inptr; 44 | int16_t *outptr; 45 | 46 | inptr = in_vector; 47 | outptr = out_vector; 48 | 49 | for (i = 0; i < in_vector_length; i++) { 50 | *outptr++ = (int16_t) ((*inptr++ * gain) >> right_shifts); 51 | } 52 | } 53 | 54 | static const uint32_t kMaxSeedUsed = 0x80000000; 55 | 56 | static const int16_t kRandNTable[] = { 57 | 9178, -7260, 40, 10189, 4894, -3531, -13779, 14764, 58 | -4008, -8884, -8990, 1008, 7368, 5184, 3251, -5817, 59 | -9786, 5963, 1770, 8066, -7135, 10772, -2298, 1361, 60 | 6484, 2241, -8633, 792, 199, -3344, 6553, -10079, 61 | -15040, 95, 11608, -12469, 14161, -4176, 2476, 6403, 62 | 13685, -16005, 6646, 2239, 10916, -3004, -602, -3141, 63 | 2142, 14144, -5829, 5305, 8209, 4713, 2697, -5112, 64 | 16092, -1210, -2891, -6631, -5360, -11878, -6781, -2739, 65 | -6392, 536, 10923, 10872, 5059, -4748, -7770, 5477, 66 | 38, -1025, -2892, 1638, 6304, 14375, -11028, 1553, 67 | -1565, 10762, -393, 4040, 5257, 12310, 6554, -4799, 68 | 4899, -6354, 1603, -1048, -2220, 8247, -186, -8944, 69 | -12004, 2332, 4801, -4933, 6371, 131, 8614, -5927, 70 | -8287, -22760, 4033, -15162, 3385, 3246, 3153, -5250, 71 | 3766, 784, 6494, -62, 3531, -1582, 15572, 662, 72 | -3952, -330, -3196, 669, 7236, -2678, -6569, 23319, 73 | -8645, -741, 14830, -15976, 4903, 315, -11342, 10311, 74 | 1858, -7777, 2145, 5436, 5677, -113, -10033, 826, 75 | -1353, 17210, 7768, 986, -1471, 8291, -4982, 8207, 76 | -14911, -6255, -2449, -11881, -7059, -11703, -4338, 8025, 77 | 7538, -2823, -12490, 9470, -1613, -2529, -10092, -7807, 78 | 9480, 6970, -12844, 5123, 3532, 4816, 4803, -8455, 79 | -5045, 14032, -4378, -1643, 5756, -11041, -2732, -16618, 80 | -6430, -18375, -3320, 6098, 5131, -4269, -8840, 2482, 81 | -7048, 1547, -21890, -6505, -7414, -424, -11722, 7955, 82 | 1653, -17299, 1823, 473, -9232, 3337, 1111, 873, 83 | 4018, -8982, 9889, 3531, -11763, -3799, 7373, -4539, 84 | 3231, 7054, -8537, 7616, 6244, 16635, 447, -2915, 85 | 13967, 705, -2669, -1520, -1771, -16188, 5956, 5117, 86 | 6371, -9936, -1448, 2480, 5128, 7550, -8130, 5236, 87 | 8213, -6443, 7707, -1950, -13811, 7218, 7031, -3883, 88 | 67, 5731, -2874, 13480, -3743, 9298, -3280, 3552, 89 | -4425, -18, -3785, -9988, -5357, 5477, -11794, 2117, 90 | 1416, -9935, 3376, 802, -5079, -8243, 12652, 66, 91 | 3653, -2368, 6781, -21895, -7227, 2487, 7839, -385, 92 | 6646, -7016, -4658, 5531, -1705, 834, 129, 3694, 93 | -1343, 2238, -22640, -6417, -11139, 11301, -2945, -3494, 94 | -5626, 185, -3615, -2041, -7972, -3106, -60, -23497, 95 | -1566, 17064, 3519, 2518, 304, -6805, -10269, 2105, 96 | 1936, -426, -736, -8122, -1467, 4238, -6939, -13309, 97 | 360, 7402, -7970, 12576, 3287, 12194, -6289, -16006, 98 | 9171, 4042, -9193, 9123, -2512, 6388, -4734, -8739, 99 | 1028, -5406, -1696, 5889, -666, -4736, 4971, 3565, 100 | 9362, -6292, 3876, -3652, -19666, 7523, -4061, 391, 101 | -11773, 7502, -3763, 4929, -9478, 13278, 2805, 4496, 102 | 7814, 16419, 12455, -14773, 2127, -2746, 3763, 4847, 103 | 3698, 6978, 4751, -6957, -3581, -45, 6252, 1513, 104 | -4797, -7925, 11270, 16188, -2359, -5269, 9376, -10777, 105 | 7262, 20031, -6515, -2208, -5353, 8085, -1341, -1303, 106 | 7333, 5576, 3625, 5763, -7931, 9833, -3371, -10305, 107 | 6534, -13539, -9971, 997, 8464, -4064, -1495, 1857, 108 | 13624, 5458, 9490, -11086, -4524, 12022, -550, -198, 109 | 408, -8455, -7068, 10289, 9712, -3366, 9028, -7621, 110 | -5243, 2362, 6909, 4672, -4933, -1799, 4709, -4563, 111 | -62, -566, 1624, -7010, 14730, -17791, -3697, -2344, 112 | -1741, 7099, -9509, -6855, -1989, 3495, -2289, 2031, 113 | 12784, 891, 14189, -3963, -5683, 421, -12575, 1724, 114 | -12682, -5970, -8169, 3143, -1824, -5488, -5130, 8536, 115 | 12799, 794, 5738, 3459, -11689, -258, -3738, -3775, 116 | -8742, 2333, 8312, -9383, 10331, 13119, 8398, 10644, 117 | -19433, -6446, -16277, -11793, 16284, 9345, 15222, 15834, 118 | 2009, -7349, 130, -14547, 338, -5998, 3337, 21492, 119 | 2406, 7703, -951, 11196, -564, 3406, 2217, 4806, 120 | 2374, -5797, 11839, 8940, -11874, 18213, 2855, 10492 121 | }; 122 | 123 | static uint32_t IncreaseSeed(uint32_t *seed) { 124 | seed[0] = (seed[0] * ((int32_t) 69069) + 1) & (kMaxSeedUsed - 1); 125 | return seed[0]; 126 | } 127 | 128 | int16_t WebRtcSpl_RandN(uint32_t *seed) { 129 | return kRandNTable[IncreaseSeed(seed) >> 23]; 130 | } 131 | 132 | 133 | #define WEBRTC_SPL_MEMCPY_W16(v1, v2, length) \ 134 | memcpy(v1, v2, (length) * sizeof(int16_t)) 135 | 136 | void WebRtcSpl_CopyFromEndW16(const int16_t *vector_in, 137 | size_t length, 138 | size_t samples, 139 | int16_t *vector_out) { 140 | // Copy the last of the input vector to vector_out 141 | WEBRTC_SPL_MEMCPY_W16(vector_out, &vector_in[length - samples], samples); 142 | } 143 | 144 | size_t WebRtcSpl_FilterAR(const int16_t *a, 145 | size_t a_length, 146 | const int16_t *x, 147 | size_t x_length, 148 | int16_t *state, 149 | size_t state_length, 150 | int16_t *state_low, 151 | size_t state_low_length, 152 | int16_t *filtered, 153 | int16_t *filtered_low, 154 | size_t filtered_low_length) { 155 | int64_t o; 156 | int32_t oLOW; 157 | size_t i, j, stop; 158 | const int16_t *x_ptr = &x[0]; 159 | int16_t *filteredFINAL_ptr = filtered; 160 | int16_t *filteredFINAL_LOW_ptr = filtered_low; 161 | 162 | for (i = 0; i < x_length; i++) { 163 | // Calculate filtered[i] and filtered_low[i] 164 | const int16_t *a_ptr = &a[1]; 165 | // The index can become negative, but the arrays will never be indexed 166 | // with it when negative. Nevertheless, the index cannot be a size_t 167 | // because of this. 168 | int filtered_ix = (int) i - 1; 169 | int16_t *state_ptr = &state[state_length - 1]; 170 | int16_t *state_low_ptr = &state_low[state_length - 1]; 171 | 172 | o = (int32_t) (*x_ptr++) * (1 << 12); 173 | oLOW = (int32_t) 0; 174 | 175 | stop = (i < a_length) ? i + 1 : a_length; 176 | for (j = 1; j < stop; j++) { 177 | // RTC_DCHECK_GE(filtered_ix, 0); 178 | o -= *a_ptr * filtered[filtered_ix]; 179 | oLOW -= *a_ptr++ * filtered_low[filtered_ix]; 180 | --filtered_ix; 181 | } 182 | for (j = i + 1; j < a_length; j++) { 183 | o -= *a_ptr * *state_ptr--; 184 | oLOW -= *a_ptr++ * *state_low_ptr--; 185 | } 186 | 187 | o += (oLOW >> 12); 188 | *filteredFINAL_ptr = (int16_t) ((o + (int32_t) 2048) >> 12); 189 | *filteredFINAL_LOW_ptr++ = 190 | (int16_t) (o - ((int32_t) (*filteredFINAL_ptr++) * (1 << 12))); 191 | } 192 | 193 | // Save the filter state 194 | if (x_length >= state_length) { 195 | WebRtcSpl_CopyFromEndW16(filtered, x_length, a_length - 1, state); 196 | WebRtcSpl_CopyFromEndW16(filtered_low, x_length, a_length - 1, state_low); 197 | } else { 198 | for (i = 0; i < state_length - x_length; i++) { 199 | state[i] = state[i + x_length]; 200 | state_low[i] = state_low[i + x_length]; 201 | } 202 | for (i = 0; i < x_length; i++) { 203 | state[state_length - x_length + i] = filtered[i]; 204 | state[state_length - x_length + i] = filtered_low[i]; 205 | } 206 | } 207 | 208 | return x_length; 209 | } 210 | 211 | 212 | const size_t kCngMaxOutsizeOrder = 640; 213 | 214 | // TODO(ossu): Rename the left-over WebRtcCng according to style guide. 215 | void WebRtcCng_K2a16(int16_t *k, int useOrder, int16_t *a); 216 | 217 | const int32_t WebRtcCng_kDbov[94] = { 218 | 1081109975, 858756178, 682134279, 541838517, 430397633, 341876992, 219 | 271562548, 215709799, 171344384, 136103682, 108110997, 85875618, 220 | 68213428, 54183852, 43039763, 34187699, 27156255, 21570980, 221 | 17134438, 13610368, 10811100, 8587562, 6821343, 5418385, 222 | 4303976, 3418770, 2715625, 2157098, 1713444, 1361037, 223 | 1081110, 858756, 682134, 541839, 430398, 341877, 224 | 271563, 215710, 171344, 136104, 108111, 85876, 225 | 68213, 54184, 43040, 34188, 27156, 21571, 226 | 17134, 13610, 10811, 8588, 6821, 5418, 227 | 4304, 3419, 2716, 2157, 1713, 1361, 228 | 1081, 859, 682, 542, 430, 342, 229 | 272, 216, 171, 136, 108, 86, 230 | 68, 54, 43, 34, 27, 22, 231 | 17, 14, 11, 9, 7, 5, 232 | 4, 3, 3, 2, 2, 1, 233 | 1, 1, 1, 1 234 | }; 235 | 236 | const int16_t WebRtcCng_kCorrWindow[WEBRTC_CNG_MAX_LPC_ORDER] = { 237 | 32702, 32636, 32570, 32505, 32439, 32374, 238 | 32309, 32244, 32179, 32114, 32049, 31985 239 | }; 240 | 241 | ComfortNoiseDecoder::ComfortNoiseDecoder() { 242 | /* Needed to get the right function pointers in SPLIB. */ 243 | Reset(); 244 | } 245 | 246 | void ComfortNoiseDecoder::Reset() { 247 | dec_seed_ = 7777; /* For debugging only. */ 248 | dec_target_energy_ = 0; 249 | dec_used_energy_ = 0; 250 | for (auto &c : dec_target_reflCoefs_) 251 | c = 0; 252 | for (auto &c : dec_used_reflCoefs_) 253 | c = 0; 254 | for (auto &c : dec_filtstate_) 255 | c = 0; 256 | for (auto &c : dec_filtstateLow_) 257 | c = 0; 258 | dec_order_ = 5; 259 | dec_target_scale_factor_ = 0; 260 | dec_used_scale_factor_ = 0; 261 | } 262 | 263 | void ComfortNoiseDecoder::UpdateSid(ArrayView sid) { 264 | int16_t refCs[WEBRTC_CNG_MAX_LPC_ORDER]; 265 | int32_t targetEnergy; 266 | size_t length = sid.size(); 267 | /* Throw away reflection coefficients of higher order than we can handle. */ 268 | if (length > (WEBRTC_CNG_MAX_LPC_ORDER + 1)) 269 | length = WEBRTC_CNG_MAX_LPC_ORDER + 1; 270 | 271 | dec_order_ = static_cast(length - 1); 272 | 273 | uint8_t sid0 = std::min(sid[0], 93); 274 | targetEnergy = WebRtcCng_kDbov[sid0]; 275 | /* Take down target energy to 75%. */ 276 | targetEnergy = targetEnergy >> 1; 277 | targetEnergy += targetEnergy >> 2; 278 | 279 | dec_target_energy_ = targetEnergy; 280 | 281 | /* Reconstruct coeffs with tweak for WebRtc implementation of RFC3389. */ 282 | if (dec_order_ == WEBRTC_CNG_MAX_LPC_ORDER) { 283 | for (size_t i = 0; i < (dec_order_); i++) { 284 | refCs[i] = sid[i + 1] << 8; /* Q7 to Q15*/ 285 | dec_target_reflCoefs_[i] = refCs[i]; 286 | } 287 | } else { 288 | for (size_t i = 0; i < (dec_order_); i++) { 289 | refCs[i] = (sid[i + 1] - 127) * (1 << 8); /* Q7 to Q15. */ 290 | dec_target_reflCoefs_[i] = refCs[i]; 291 | } 292 | } 293 | 294 | for (size_t i = (dec_order_); i < WEBRTC_CNG_MAX_LPC_ORDER; i++) { 295 | refCs[i] = 0; 296 | dec_target_reflCoefs_[i] = refCs[i]; 297 | } 298 | } 299 | 300 | bool ComfortNoiseDecoder::Generate(ArrayView out_data, 301 | bool new_period) { 302 | int16_t excitation[kCngMaxOutsizeOrder]; 303 | int16_t low[kCngMaxOutsizeOrder]; 304 | int16_t lpPoly[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 305 | int16_t ReflBetaStd = 26214; /* 0.8 in q15. */ 306 | int16_t ReflBetaCompStd = 6553; /* 0.2 in q15. */ 307 | int16_t ReflBetaNewP = 19661; /* 0.6 in q15. */ 308 | int16_t ReflBetaCompNewP = 13107; /* 0.4 in q15. */ 309 | int16_t Beta, BetaC; /* These are in Q15. */ 310 | int32_t targetEnergy; 311 | int16_t En; 312 | int16_t temp16; 313 | const size_t num_samples = out_data.size(); 314 | 315 | if (num_samples > kCngMaxOutsizeOrder) { 316 | return false; 317 | } 318 | 319 | if (new_period) { 320 | dec_used_scale_factor_ = dec_target_scale_factor_; 321 | Beta = ReflBetaNewP; 322 | BetaC = ReflBetaCompNewP; 323 | } else { 324 | Beta = ReflBetaStd; 325 | BetaC = ReflBetaCompStd; 326 | } 327 | 328 | /* Calculate new scale factor in Q13 */ 329 | dec_used_scale_factor_ = (int16_t) ( 330 | WEBRTC_SPL_MUL_16_16_RSFT(dec_used_scale_factor_, Beta >> 2, 13) + 331 | WEBRTC_SPL_MUL_16_16_RSFT(dec_target_scale_factor_, BetaC >> 2, 13)); 332 | 333 | dec_used_energy_ = dec_used_energy_ >> 1; 334 | dec_used_energy_ += dec_target_energy_ >> 1; 335 | 336 | /* Do the same for the reflection coeffs, albeit in Q15. */ 337 | for (size_t i = 0; i < WEBRTC_CNG_MAX_LPC_ORDER; i++) { 338 | dec_used_reflCoefs_[i] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( 339 | dec_used_reflCoefs_[i], Beta, 15); 340 | dec_used_reflCoefs_[i] += (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( 341 | dec_target_reflCoefs_[i], BetaC, 15); 342 | } 343 | 344 | /* Compute the polynomial coefficients. */ 345 | WebRtcCng_K2a16(dec_used_reflCoefs_, WEBRTC_CNG_MAX_LPC_ORDER, lpPoly); 346 | 347 | 348 | targetEnergy = dec_used_energy_; 349 | 350 | /* Calculate scaling factor based on filter energy. */ 351 | En = 8192; /* 1.0 in Q13. */ 352 | for (size_t i = 0; i < (WEBRTC_CNG_MAX_LPC_ORDER); i++) { 353 | /* Floating point value for reference. 354 | E *= 1.0 - (dec_used_reflCoefs_[i] / 32768.0) * 355 | (dec_used_reflCoefs_[i] / 32768.0); 356 | */ 357 | 358 | /* Same in fixed point. */ 359 | /* K(i).^2 in Q15. */ 360 | temp16 = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( 361 | dec_used_reflCoefs_[i], dec_used_reflCoefs_[i], 15); 362 | /* 1 - K(i).^2 in Q15. */ 363 | temp16 = 0x7fff - temp16; 364 | En = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(En, temp16, 15); 365 | } 366 | 367 | /* float scaling= sqrt(E * dec_target_energy_ / (1 << 24)); */ 368 | 369 | /* Calculate sqrt(En * target_energy / excitation energy) */ 370 | targetEnergy = sqrtf(dec_used_energy_); 371 | 372 | En = (int16_t) sqrtf(En) << 6; 373 | En = (En * 3) >> 1; /* 1.5 estimates sqrt(2). */ 374 | dec_used_scale_factor_ = (int16_t) ((En * targetEnergy) >> 12); 375 | 376 | /* Generate excitation. */ 377 | /* Excitation energy per sample is 2.^24 - Q13 N(0,1). */ 378 | for (size_t i = 0; i < num_samples; i++) { 379 | excitation[i] = WebRtcSpl_RandN(&dec_seed_) >> 1; 380 | } 381 | 382 | /* Scale to correct energy. */ 383 | WebRtcSpl_ScaleVector(excitation, excitation, dec_used_scale_factor_, 384 | num_samples, 13); 385 | 386 | /* |lpPoly| - Coefficients in Q12. 387 | * |excitation| - Speech samples. 388 | * |nst->dec_filtstate| - State preservation. 389 | * |out_data| - Filtered speech samples. */ 390 | WebRtcSpl_FilterAR(lpPoly, WEBRTC_CNG_MAX_LPC_ORDER + 1, excitation, 391 | num_samples, dec_filtstate_, WEBRTC_CNG_MAX_LPC_ORDER, 392 | dec_filtstateLow_, WEBRTC_CNG_MAX_LPC_ORDER, 393 | out_data.data(), low, num_samples); 394 | 395 | return true; 396 | } 397 | 398 | ComfortNoiseEncoder::ComfortNoiseEncoder(int fs, int interval, int quality) 399 | : enc_nrOfCoefs_(quality), 400 | enc_sampfreq_(fs), 401 | enc_interval_(interval), 402 | enc_msSinceSid_(0), 403 | enc_Energy_(0), 404 | enc_reflCoefs_{0}, 405 | enc_corrVector_{0}, 406 | enc_seed_(7777) /* For debugging only. */ { 407 | RTC_CHECK_GT(quality, 0); 408 | RTC_CHECK_LE(quality, WEBRTC_CNG_MAX_LPC_ORDER); 409 | /* Needed to get the right function pointers in SPLIB. */ 410 | 411 | } 412 | 413 | void ComfortNoiseEncoder::Reset(int fs, int interval, int quality) { 414 | RTC_CHECK_GT(quality, 0); 415 | RTC_CHECK_LE(quality, WEBRTC_CNG_MAX_LPC_ORDER); 416 | enc_nrOfCoefs_ = quality; 417 | enc_sampfreq_ = fs; 418 | enc_interval_ = interval; 419 | enc_msSinceSid_ = 0; 420 | enc_Energy_ = 0; 421 | for (auto &c : enc_reflCoefs_) 422 | c = 0; 423 | for (auto &c : enc_corrVector_) 424 | c = 0; 425 | enc_seed_ = 7777; /* For debugging only. */ 426 | } 427 | 428 | const int8_t kWebRtcSpl_CountLeadingZeros32_Table[64] = { 429 | 32, 8, 17, -1, -1, 14, -1, -1, -1, 20, -1, -1, -1, 28, -1, 18, 430 | -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 26, 25, 24, 431 | 4, 11, 23, 31, 3, 7, 10, 16, 22, 30, -1, -1, 2, 6, 13, 9, 432 | -1, 15, -1, 21, -1, 29, 19, -1, -1, -1, -1, -1, 1, 27, 5, 12, 433 | }; 434 | 435 | 436 | // Don't call this directly except in tests! 437 | static __inline int WebRtcSpl_CountLeadingZeros32_NotBuiltin(uint32_t n) { 438 | // Normalize n by rounding up to the nearest number that is a sequence of 0 439 | // bits followed by a sequence of 1 bits. This number has the same number of 440 | // leading zeros as the original n. There are exactly 33 such values. 441 | n |= n >> 1; 442 | n |= n >> 2; 443 | n |= n >> 4; 444 | n |= n >> 8; 445 | n |= n >> 16; 446 | 447 | // Multiply the modified n with a constant selected (by exhaustive search) 448 | // such that each of the 33 possible values of n give a product whose 6 most 449 | // significant bits are unique. Then look up the answer in the table. 450 | return kWebRtcSpl_CountLeadingZeros32_Table[(n * 0x8c0b2891) >> 26]; 451 | } 452 | 453 | // Don't call this directly except in tests! 454 | static __inline int WebRtcSpl_CountLeadingZeros64_NotBuiltin(uint64_t n) { 455 | const int leading_zeros = n >> 32 == 0 ? 32 : 0; 456 | return leading_zeros + WebRtcSpl_CountLeadingZeros32_NotBuiltin( 457 | (uint32_t) (n >> (32 - leading_zeros))); 458 | } 459 | 460 | // Returns the number of leading zero bits in the argument. 461 | static __inline int WebRtcSpl_CountLeadingZeros32(uint32_t n) { 462 | return WebRtcSpl_CountLeadingZeros32_NotBuiltin(n); 463 | } 464 | 465 | static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) { 466 | return 32 - WebRtcSpl_CountLeadingZeros32(n); 467 | } 468 | 469 | // Return the number of steps a can be left-shifted without overflow, 470 | // or 0 if a == 0. 471 | static __inline int16_t WebRtcSpl_NormW32(int32_t a) { 472 | return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a : a) - 1; 473 | } 474 | 475 | int16_t WebRtcSpl_GetScalingSquare(int16_t *in_vector, 476 | size_t in_vector_length, 477 | size_t times) { 478 | int16_t nbits = WebRtcSpl_GetSizeInBits((uint32_t) times); 479 | size_t i; 480 | int16_t smax = -1; 481 | int16_t sabs; 482 | int16_t *sptr = in_vector; 483 | int16_t t; 484 | size_t looptimes = in_vector_length; 485 | 486 | for (i = looptimes; i > 0; i--) { 487 | sabs = (*sptr > 0 ? *sptr++ : -*sptr++); 488 | smax = (sabs > smax ? sabs : smax); 489 | } 490 | t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); 491 | 492 | if (smax == 0) { 493 | return 0; // Since norm(0) returns 0 494 | } else { 495 | return (t > nbits) ? 0 : nbits - t; 496 | } 497 | } 498 | 499 | int32_t WebRtcSpl_Energy(int16_t *vector, 500 | size_t vector_length, 501 | int *scale_factor) { 502 | int32_t en = 0; 503 | size_t i; 504 | int scaling = 505 | WebRtcSpl_GetScalingSquare(vector, vector_length, vector_length); 506 | size_t looptimes = vector_length; 507 | int16_t *vectorptr = vector; 508 | 509 | for (i = 0; i < looptimes; i++) { 510 | en += (*vectorptr * *vectorptr) >> scaling; 511 | vectorptr++; 512 | } 513 | *scale_factor = scaling; 514 | 515 | return en; 516 | } 517 | 518 | // Hanning table with 256 entries 519 | static const int16_t kHanningTable[] = { 520 | 1, 2, 6, 10, 15, 22, 30, 39, 521 | 50, 62, 75, 89, 104, 121, 138, 157, 522 | 178, 199, 222, 246, 271, 297, 324, 353, 523 | 383, 413, 446, 479, 513, 549, 586, 624, 524 | 663, 703, 744, 787, 830, 875, 920, 967, 525 | 1015, 1064, 1114, 1165, 1218, 1271, 1325, 1381, 526 | 1437, 1494, 1553, 1612, 1673, 1734, 1796, 1859, 527 | 1924, 1989, 2055, 2122, 2190, 2259, 2329, 2399, 528 | 2471, 2543, 2617, 2691, 2765, 2841, 2918, 2995, 529 | 3073, 3152, 3232, 3312, 3393, 3475, 3558, 3641, 530 | 3725, 3809, 3895, 3980, 4067, 4154, 4242, 4330, 531 | 4419, 4509, 4599, 4689, 4781, 4872, 4964, 5057, 532 | 5150, 5244, 5338, 5432, 5527, 5622, 5718, 5814, 533 | 5910, 6007, 6104, 6202, 6299, 6397, 6495, 6594, 534 | 6693, 6791, 6891, 6990, 7090, 7189, 7289, 7389, 535 | 7489, 7589, 7690, 7790, 7890, 7991, 8091, 8192, 536 | 8293, 8393, 8494, 8594, 8694, 8795, 8895, 8995, 537 | 9095, 9195, 9294, 9394, 9493, 9593, 9691, 9790, 538 | 9889, 9987, 10085, 10182, 10280, 10377, 10474, 10570, 539 | 10666, 10762, 10857, 10952, 11046, 11140, 11234, 11327, 540 | 11420, 11512, 11603, 11695, 11785, 11875, 11965, 12054, 541 | 12142, 12230, 12317, 12404, 12489, 12575, 12659, 12743, 542 | 12826, 12909, 12991, 13072, 13152, 13232, 13311, 13389, 543 | 13466, 13543, 13619, 13693, 13767, 13841, 13913, 13985, 544 | 14055, 14125, 14194, 14262, 14329, 14395, 14460, 14525, 545 | 14588, 14650, 14711, 14772, 14831, 14890, 14947, 15003, 546 | 15059, 15113, 15166, 15219, 15270, 15320, 15369, 15417, 547 | 15464, 15509, 15554, 15597, 15640, 15681, 15721, 15760, 548 | 15798, 15835, 15871, 15905, 15938, 15971, 16001, 16031, 549 | 16060, 16087, 16113, 16138, 16162, 16185, 16206, 16227, 550 | 16246, 16263, 16280, 16295, 16309, 16322, 16334, 16345, 551 | 16354, 16362, 16369, 16374, 16378, 16382, 16383, 16384 552 | }; 553 | 554 | void WebRtcSpl_GetHanningWindow(int16_t *v, size_t size) { 555 | size_t jj; 556 | int16_t *vptr1; 557 | 558 | int32_t index; 559 | int32_t factor = ((int32_t) 0x40000000); 560 | 561 | factor = WebRtcSpl_DivW32W16(factor, (int16_t) size); 562 | if (size < 513) 563 | index = (int32_t) -0x200000; 564 | else 565 | index = (int32_t) -0x100000; 566 | vptr1 = v; 567 | 568 | for (jj = 0; jj < size; jj++) { 569 | index += factor; 570 | (*vptr1++) = kHanningTable[index >> 22]; 571 | } 572 | 573 | } 574 | 575 | int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t *vector, size_t length) { 576 | size_t i = 0; 577 | int absolute = 0, maximum = 0; 578 | 579 | RTC_DCHECK_GT(length, 0); 580 | 581 | for (i = 0; i < length; i++) { 582 | absolute = abs((int) vector[i]); 583 | 584 | if (absolute > maximum) { 585 | maximum = absolute; 586 | } 587 | } 588 | 589 | // Guard the case for abs(-32768). 590 | if (maximum > WEBRTC_SPL_WORD16_MAX) { 591 | maximum = WEBRTC_SPL_WORD16_MAX; 592 | } 593 | 594 | return (int16_t) maximum; 595 | } 596 | 597 | void WebRtcSpl_ElementwiseVectorMult(int16_t *out, const int16_t *in, 598 | const int16_t *win, size_t vector_length, 599 | int16_t right_shifts) { 600 | size_t i; 601 | int16_t *outptr = out; 602 | const int16_t *inptr = in; 603 | const int16_t *winptr = win; 604 | for (i = 0; i < vector_length; i++) { 605 | *outptr++ = (int16_t) ((*inptr++ * *winptr++) >> right_shifts); 606 | } 607 | } 608 | 609 | size_t WebRtcSpl_AutoCorrelation(const int16_t *in_vector, 610 | size_t in_vector_length, 611 | size_t order, 612 | int32_t *result, 613 | int *scale) { 614 | int32_t sum = 0; 615 | size_t i = 0, j = 0; 616 | int16_t smax = 0; 617 | int scaling = 0; 618 | 619 | RTC_DCHECK_LE(order, in_vector_length); 620 | 621 | // Find the maximum absolute value of the samples. 622 | smax = WebRtcSpl_MaxAbsValueW16C(in_vector, in_vector_length); 623 | 624 | // In order to avoid overflow when computing the sum we should scale the 625 | // samples so that (in_vector_length * smax * smax) will not overflow. 626 | if (smax == 0) { 627 | scaling = 0; 628 | } else { 629 | // Number of bits in the sum loop. 630 | int nbits = WebRtcSpl_GetSizeInBits((uint32_t) in_vector_length); 631 | // Number of bits to normalize smax. 632 | int t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax)); 633 | 634 | if (t > nbits) { 635 | scaling = 0; 636 | } else { 637 | scaling = nbits - t; 638 | } 639 | } 640 | 641 | // Perform the actual correlation calculation. 642 | for (i = 0; i < order + 1; i++) { 643 | sum = 0; 644 | /* Unroll the loop to improve performance. */ 645 | for (j = 0; i + j + 3 < in_vector_length; j += 4) { 646 | sum += (in_vector[j + 0] * in_vector[i + j + 0]) >> scaling; 647 | sum += (in_vector[j + 1] * in_vector[i + j + 1]) >> scaling; 648 | sum += (in_vector[j + 2] * in_vector[i + j + 2]) >> scaling; 649 | sum += (in_vector[j + 3] * in_vector[i + j + 3]) >> scaling; 650 | } 651 | for (; j < in_vector_length - i; j++) { 652 | sum += (in_vector[j] * in_vector[i + j]) >> scaling; 653 | } 654 | *result++ = sum; 655 | } 656 | 657 | *scale = scaling; 658 | return order + 1; 659 | } 660 | 661 | int WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low) { 662 | int16_t approx, tmp_hi, tmp_low, num_hi, num_low; 663 | int32_t tmpW32; 664 | 665 | approx = (int16_t) WebRtcSpl_DivW32W16((int32_t) 0x1FFFFFFF, den_hi); 666 | // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30) 667 | 668 | // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30) 669 | tmpW32 = (den_hi * approx << 1) + ((den_low * approx >> 15) << 1); 670 | // tmpW32 = den * approx 671 | 672 | tmpW32 = (int32_t) 0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx)) 673 | // UBSan: 2147483647 - -2 cannot be represented in type 'int' 674 | 675 | // Store tmpW32 in hi and low format 676 | tmp_hi = (int16_t) (tmpW32 >> 16); 677 | tmp_low = (int16_t) ((tmpW32 - ((int32_t) tmp_hi << 16)) >> 1); 678 | 679 | // tmpW32 = 1/den in Q29 680 | tmpW32 = (tmp_hi * approx + (tmp_low * approx >> 15)) << 1; 681 | 682 | // 1/den in hi and low format 683 | tmp_hi = (int16_t) (tmpW32 >> 16); 684 | tmp_low = (int16_t) ((tmpW32 - ((int32_t) tmp_hi << 16)) >> 1); 685 | 686 | // Store num in hi and low format 687 | num_hi = (int16_t) (num >> 16); 688 | num_low = (int16_t) ((num - ((int32_t) num_hi << 16)) >> 1); 689 | 690 | // num * (1/den) by 32 bit multiplication (result in Q28) 691 | 692 | tmpW32 = num_hi * tmp_hi + (num_hi * tmp_low >> 15) + 693 | (num_low * tmp_hi >> 15); 694 | 695 | // Put result in Q31 (convert from Q28) 696 | tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3); 697 | 698 | return tmpW32; 699 | } 700 | 701 | #define SPL_LEVINSON_MAXORDER 20 702 | 703 | 704 | WebRtcSpl_LevinsonDurbin(const int32_t *R, int16_t *A, int16_t *K, 705 | size_t order) { 706 | size_t i, j; 707 | // Auto-correlation coefficients in high precision 708 | int16_t R_hi[SPL_LEVINSON_MAXORDER + 1], R_low[SPL_LEVINSON_MAXORDER + 1]; 709 | // LPC coefficients in high precision 710 | int16_t A_hi[SPL_LEVINSON_MAXORDER + 1], A_low[SPL_LEVINSON_MAXORDER + 1]; 711 | // LPC coefficients for next iteration 712 | int16_t A_upd_hi[SPL_LEVINSON_MAXORDER + 1], A_upd_low[SPL_LEVINSON_MAXORDER + 1]; 713 | // Reflection coefficient in high precision 714 | int16_t K_hi, K_low; 715 | // Prediction gain Alpha in high precision and with scale factor 716 | int16_t Alpha_hi, Alpha_low, Alpha_exp; 717 | int16_t tmp_hi, tmp_low; 718 | int32_t temp1W32, temp2W32, temp3W32; 719 | int16_t norm; 720 | 721 | // Normalize the autocorrelation R[0]...R[order+1] 722 | 723 | norm = WebRtcSpl_NormW32(R[0]); 724 | 725 | for (i = 0; i <= order; ++i) { 726 | temp1W32 = R[i] * (1 << norm); 727 | // UBSan: 12 * 268435456 cannot be represented in type 'int' 728 | 729 | // Put R in hi and low format 730 | R_hi[i] = (int16_t) (temp1W32 >> 16); 731 | R_low[i] = (int16_t) ((temp1W32 - ((int32_t) R_hi[i] * 65536)) >> 1); 732 | } 733 | 734 | // K = A[1] = -R[1] / R[0] 735 | 736 | temp2W32 = R[1] * (1 << norm); // R[1] in Q31 737 | temp3W32 = WEBRTC_SPL_ABS_W32(temp2W32); // abs R[1] 738 | temp1W32 = WebRtcSpl_DivW32HiLow(temp3W32, R_hi[0], R_low[0]); // abs(R[1])/R[0] in Q31 739 | // Put back the sign on R[1] 740 | if (temp2W32 > 0) { 741 | temp1W32 = -temp1W32; 742 | } 743 | 744 | // Put K in hi and low format 745 | K_hi = (int16_t) (temp1W32 >> 16); 746 | K_low = (int16_t) ((temp1W32 - ((int32_t) K_hi * 65536)) >> 1); 747 | 748 | // Store first reflection coefficient 749 | K[0] = K_hi; 750 | 751 | temp1W32 >>= 4; // A[1] in Q27. 752 | 753 | // Put A[1] in hi and low format 754 | A_hi[1] = (int16_t) (temp1W32 >> 16); 755 | A_low[1] = (int16_t) ((temp1W32 - ((int32_t) A_hi[1] * 65536)) >> 1); 756 | 757 | // Alpha = R[0] * (1-K^2) 758 | 759 | temp1W32 = ((K_hi * K_low >> 14) + K_hi * K_hi) * 2; // = k^2 in Q31 760 | 761 | temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0 762 | temp1W32 = (int32_t) 0x7fffffffL - temp1W32; // temp1W32 = (1 - K[0]*K[0]) in Q31 763 | 764 | // Store temp1W32 = 1 - K[0]*K[0] on hi and low format 765 | tmp_hi = (int16_t) (temp1W32 >> 16); 766 | tmp_low = (int16_t) ((temp1W32 - ((int32_t) tmp_hi << 16)) >> 1); 767 | 768 | // Calculate Alpha in Q31 769 | temp1W32 = (R_hi[0] * tmp_hi + (R_hi[0] * tmp_low >> 15) + 770 | (R_low[0] * tmp_hi >> 15)) << 1; 771 | 772 | // Normalize Alpha and put it in hi and low format 773 | 774 | Alpha_exp = WebRtcSpl_NormW32(temp1W32); 775 | temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, Alpha_exp); 776 | Alpha_hi = (int16_t) (temp1W32 >> 16); 777 | Alpha_low = (int16_t) ((temp1W32 - ((int32_t) Alpha_hi << 16)) >> 1); 778 | 779 | // Perform the iterative calculations in the Levinson-Durbin algorithm 780 | 781 | for (i = 2; i <= order; i++) { 782 | /* ---- 783 | temp1W32 = R[i] + > R[j]*A[i-j] 784 | / 785 | ---- 786 | j=1..i-1 787 | */ 788 | 789 | temp1W32 = 0; 790 | 791 | for (j = 1; j < i; j++) { 792 | // temp1W32 is in Q31 793 | temp1W32 += (R_hi[j] * A_hi[i - j] * 2) + 794 | (((R_hi[j] * A_low[i - j] >> 15) + 795 | (R_low[j] * A_hi[i - j] >> 15)) * 2); 796 | } 797 | 798 | temp1W32 = temp1W32 * 16; 799 | temp1W32 += ((int32_t) R_hi[i] * 65536) 800 | + WEBRTC_SPL_LSHIFT_W32((int32_t) R_low[i], 1); 801 | 802 | // K = -temp1W32 / Alpha 803 | temp2W32 = WEBRTC_SPL_ABS_W32(temp1W32); // abs(temp1W32) 804 | temp3W32 = WebRtcSpl_DivW32HiLow(temp2W32, Alpha_hi, Alpha_low); // abs(temp1W32)/Alpha 805 | 806 | // Put the sign of temp1W32 back again 807 | if (temp1W32 > 0) { 808 | temp3W32 = -temp3W32; 809 | } 810 | 811 | // Use the Alpha shifts from earlier to de-normalize 812 | norm = WebRtcSpl_NormW32(temp3W32); 813 | if ((Alpha_exp <= norm) || (temp3W32 == 0)) { 814 | temp3W32 = temp3W32 * (1 << Alpha_exp); 815 | } else { 816 | if (temp3W32 > 0) { 817 | temp3W32 = (int32_t) 0x7fffffffL; 818 | } else { 819 | temp3W32 = (int32_t) 0x80000000L; 820 | } 821 | } 822 | 823 | // Put K on hi and low format 824 | K_hi = (int16_t) (temp3W32 >> 16); 825 | K_low = (int16_t) ((temp3W32 - ((int32_t) K_hi * 65536)) >> 1); 826 | 827 | // Store Reflection coefficient in Q15 828 | K[i - 1] = K_hi; 829 | 830 | // Test for unstable filter. 831 | // If unstable return 0 and let the user decide what to do in that case 832 | 833 | if ((int32_t) WEBRTC_SPL_ABS_W16(K_hi) > (int32_t) 32750) { 834 | return 0; // Unstable filter 835 | } 836 | 837 | /* 838 | Compute updated LPC coefficient: Anew[i] 839 | Anew[j]= A[j] + K*A[i-j] for j=1..i-1 840 | Anew[i]= K 841 | */ 842 | 843 | for (j = 1; j < i; j++) { 844 | // temp1W32 = A[j] in Q27 845 | temp1W32 = (int32_t) A_hi[j] * 65536 846 | + WEBRTC_SPL_LSHIFT_W32((int32_t) A_low[j], 1); 847 | 848 | // temp1W32 += K*A[i-j] in Q27 849 | temp1W32 += (K_hi * A_hi[i - j] + (K_hi * A_low[i - j] >> 15) + 850 | (K_low * A_hi[i - j] >> 15)) * 2; 851 | 852 | // Put Anew in hi and low format 853 | A_upd_hi[j] = (int16_t) (temp1W32 >> 16); 854 | A_upd_low[j] = (int16_t) ( 855 | (temp1W32 - ((int32_t) A_upd_hi[j] * 65536)) >> 1); 856 | } 857 | 858 | // temp3W32 = K in Q27 (Convert from Q31 to Q27) 859 | temp3W32 >>= 4; 860 | 861 | // Store Anew in hi and low format 862 | A_upd_hi[i] = (int16_t) (temp3W32 >> 16); 863 | A_upd_low[i] = (int16_t) ( 864 | (temp3W32 - ((int32_t) A_upd_hi[i] * 65536)) >> 1); 865 | 866 | // Alpha = Alpha * (1-K^2) 867 | 868 | temp1W32 = ((K_hi * K_low >> 14) + K_hi * K_hi) * 2; // K*K in Q31 869 | 870 | temp1W32 = WEBRTC_SPL_ABS_W32(temp1W32); // Guard against <0 871 | temp1W32 = (int32_t) 0x7fffffffL - temp1W32; // 1 - K*K in Q31 872 | 873 | // Convert 1- K^2 in hi and low format 874 | tmp_hi = (int16_t) (temp1W32 >> 16); 875 | tmp_low = (int16_t) ((temp1W32 - ((int32_t) tmp_hi << 16)) >> 1); 876 | 877 | // Calculate Alpha = Alpha * (1-K^2) in Q31 878 | temp1W32 = (Alpha_hi * tmp_hi + (Alpha_hi * tmp_low >> 15) + 879 | (Alpha_low * tmp_hi >> 15)) << 1; 880 | 881 | // Normalize Alpha and store it on hi and low format 882 | 883 | norm = WebRtcSpl_NormW32(temp1W32); 884 | temp1W32 = WEBRTC_SPL_LSHIFT_W32(temp1W32, norm); 885 | 886 | Alpha_hi = (int16_t) (temp1W32 >> 16); 887 | Alpha_low = (int16_t) ((temp1W32 - ((int32_t) Alpha_hi << 16)) >> 1); 888 | 889 | // Update the total normalization of Alpha 890 | Alpha_exp = Alpha_exp + norm; 891 | 892 | // Update A[] 893 | 894 | for (j = 1; j <= i; j++) { 895 | A_hi[j] = A_upd_hi[j]; 896 | A_low[j] = A_upd_low[j]; 897 | } 898 | } 899 | 900 | /* 901 | Set A[0] to 1.0 and store the A[i] i=1...order in Q12 902 | (Convert from Q27 and use rounding) 903 | */ 904 | 905 | A[0] = 4096; 906 | 907 | for (i = 1; i <= order; i++) { 908 | // temp1W32 in Q27 909 | temp1W32 = (int32_t) A_hi[i] * 65536 910 | + WEBRTC_SPL_LSHIFT_W32((int32_t) A_low[i], 1); 911 | // Round and store upper word 912 | A[i] = (int16_t) (((temp1W32 * 2) + 32768) >> 16); 913 | } 914 | return 1; // Stable filters 915 | } 916 | 917 | size_t ComfortNoiseEncoder::Encode(ArrayView speech, 918 | bool force_sid, 919 | Buffer *output) { 920 | int16_t arCoefs[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 921 | int32_t corrVector[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 922 | int16_t refCs[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 923 | int16_t hanningW[kCngMaxOutsizeOrder]; 924 | int16_t ReflBeta = 19661; /* 0.6 in q15. */ 925 | int16_t ReflBetaComp = 13107; /* 0.4 in q15. */ 926 | int32_t outEnergy; 927 | int outShifts; 928 | size_t i; 929 | int stab; 930 | int acorrScale; 931 | size_t index; 932 | size_t ind, factor; 933 | int32_t *bptr; 934 | int32_t blo, bhi; 935 | int16_t negate; 936 | const int16_t *aptr; 937 | int16_t speechBuf[kCngMaxOutsizeOrder]; 938 | 939 | const size_t num_samples = speech.size(); 940 | RTC_CHECK_LE(num_samples, kCngMaxOutsizeOrder); 941 | 942 | for (i = 0; i < num_samples; i++) { 943 | speechBuf[i] = speech[i]; 944 | } 945 | 946 | factor = num_samples; 947 | 948 | /* Calculate energy and a coefficients. */ 949 | outEnergy = WebRtcSpl_Energy(speechBuf, num_samples, &outShifts); 950 | while (outShifts > 0) { 951 | /* We can only do 5 shifts without destroying accuracy in 952 | * division factor. */ 953 | if (outShifts > 5) { 954 | outEnergy <<= (outShifts - 5); 955 | outShifts = 5; 956 | } else { 957 | factor /= 2; 958 | outShifts--; 959 | } 960 | } 961 | outEnergy = WebRtcSpl_DivW32W16(outEnergy, (int16_t) factor); 962 | 963 | if (outEnergy > 1) { 964 | /* Create Hanning Window. */ 965 | WebRtcSpl_GetHanningWindow(hanningW, num_samples / 2); 966 | for (i = 0; i < (num_samples / 2); i++) 967 | hanningW[num_samples - i - 1] = hanningW[i]; 968 | 969 | WebRtcSpl_ElementwiseVectorMult(speechBuf, hanningW, speechBuf, num_samples, 970 | 14); 971 | 972 | WebRtcSpl_AutoCorrelation(speechBuf, num_samples, enc_nrOfCoefs_, 973 | corrVector, &acorrScale); 974 | 975 | if (*corrVector == 0) 976 | *corrVector = WEBRTC_SPL_WORD16_MAX; 977 | 978 | /* Adds the bandwidth expansion. */ 979 | aptr = WebRtcCng_kCorrWindow; 980 | bptr = corrVector; 981 | 982 | /* (zzz) lpc16_1 = 17+1+820+2+2 = 842 (ordo2=700). */ 983 | for (ind = 0; ind < enc_nrOfCoefs_; ind++) { 984 | /* The below code multiplies the 16 b corrWindow values (Q15) with 985 | * the 32 b corrvector (Q0) and shifts the result down 15 steps. */ 986 | negate = *bptr < 0; 987 | if (negate) 988 | *bptr = -*bptr; 989 | 990 | blo = (int32_t) *aptr * (*bptr & 0xffff); 991 | bhi = ((blo >> 16) & 0xffff) 992 | + ((int32_t) (*aptr++) * ((*bptr >> 16) & 0xffff)); 993 | blo = (blo & 0xffff) | ((bhi & 0xffff) << 16); 994 | 995 | *bptr = (((bhi >> 16) & 0x7fff) << 17) | ((uint32_t) blo >> 15); 996 | if (negate) 997 | *bptr = -*bptr; 998 | bptr++; 999 | } 1000 | /* End of bandwidth expansion. */ 1001 | 1002 | stab = WebRtcSpl_LevinsonDurbin(corrVector, arCoefs, refCs, 1003 | enc_nrOfCoefs_); 1004 | 1005 | if (!stab) { 1006 | /* Disregard from this frame */ 1007 | return 0; 1008 | } 1009 | 1010 | } else { 1011 | for (i = 0; i < enc_nrOfCoefs_; i++) 1012 | refCs[i] = 0; 1013 | } 1014 | 1015 | if (force_sid) { 1016 | /* Read instantaneous values instead of averaged. */ 1017 | for (i = 0; i < enc_nrOfCoefs_; i++) 1018 | enc_reflCoefs_[i] = refCs[i]; 1019 | enc_Energy_ = outEnergy; 1020 | } else { 1021 | /* Average history with new values. */ 1022 | for (i = 0; i < enc_nrOfCoefs_; i++) { 1023 | enc_reflCoefs_[i] = (int16_t) WEBRTC_SPL_MUL_16_16_RSFT( 1024 | enc_reflCoefs_[i], ReflBeta, 15); 1025 | enc_reflCoefs_[i] += 1026 | (int16_t) WEBRTC_SPL_MUL_16_16_RSFT(refCs[i], ReflBetaComp, 15); 1027 | } 1028 | enc_Energy_ = 1029 | (outEnergy >> 2) + (enc_Energy_ >> 1) + (enc_Energy_ >> 2); 1030 | } 1031 | 1032 | if (enc_Energy_ < 1) { 1033 | enc_Energy_ = 1; 1034 | } 1035 | 1036 | if ((enc_msSinceSid_ > (enc_interval_ - 1)) || force_sid) { 1037 | /* Search for best dbov value. */ 1038 | index = 0; 1039 | for (i = 1; i < 93; i++) { 1040 | /* Always round downwards. */ 1041 | if ((enc_Energy_ - WebRtcCng_kDbov[i]) > 0) { 1042 | index = i; 1043 | break; 1044 | } 1045 | } 1046 | if ((i == 93) && (index == 0)) 1047 | index = 94; 1048 | 1049 | const size_t output_coefs = enc_nrOfCoefs_ + 1; 1050 | output->AppendData(output_coefs, [&](ArrayView output) { 1051 | output[0] = (uint8_t) index; 1052 | 1053 | /* Quantize coefficients with tweak for WebRtc implementation of 1054 | * RFC3389. */ 1055 | if (enc_nrOfCoefs_ == WEBRTC_CNG_MAX_LPC_ORDER) { 1056 | for (i = 0; i < enc_nrOfCoefs_; i++) { 1057 | /* Q15 to Q7 with rounding. */ 1058 | output[i + 1] = ((enc_reflCoefs_[i] + 128) >> 8); 1059 | } 1060 | } else { 1061 | for (i = 0; i < enc_nrOfCoefs_; i++) { 1062 | /* Q15 to Q7 with rounding. */ 1063 | output[i + 1] = (127 + ((enc_reflCoefs_[i] + 128) >> 8)); 1064 | } 1065 | } 1066 | 1067 | return output_coefs; 1068 | }); 1069 | 1070 | enc_msSinceSid_ = 1071 | static_cast((1000 * num_samples) / enc_sampfreq_); 1072 | return output_coefs; 1073 | } else { 1074 | enc_msSinceSid_ += 1075 | static_cast((1000 * num_samples) / enc_sampfreq_); 1076 | return 0; 1077 | } 1078 | } 1079 | 1080 | #define WEBRTC_SPL_MAX_LPC_ORDER 14 1081 | 1082 | /* Values in |k| are Q15, and |a| Q12. */ 1083 | void WebRtcCng_K2a16(int16_t *k, int useOrder, int16_t *a) { 1084 | int16_t any[WEBRTC_SPL_MAX_LPC_ORDER + 1]; 1085 | int16_t *aptr; 1086 | int16_t *aptr2; 1087 | int16_t *anyptr; 1088 | const int16_t *kptr; 1089 | int m, i; 1090 | 1091 | kptr = k; 1092 | *a = 4096; /* i.e., (Word16_MAX >> 3) + 1 */ 1093 | *any = *a; 1094 | a[1] = (*k + 4) >> 3; 1095 | for (m = 1; m < useOrder; m++) { 1096 | kptr++; 1097 | aptr = a; 1098 | aptr++; 1099 | aptr2 = &a[m]; 1100 | anyptr = any; 1101 | anyptr++; 1102 | 1103 | any[m + 1] = (*kptr + 4) >> 3; 1104 | for (i = 0; i < m; i++) { 1105 | *anyptr++ = 1106 | (*aptr++) + 1107 | (int16_t) ((((int32_t) (*aptr2--) * (int32_t) *kptr) + 16384) >> 15); 1108 | } 1109 | 1110 | aptr = a; 1111 | anyptr = any; 1112 | for (i = 0; i < (m + 2); i++) { 1113 | *aptr++ = *anyptr++; 1114 | } 1115 | } 1116 | } 1117 | -------------------------------------------------------------------------------- /cng.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 | * 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 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | #ifndef MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_ 11 | #define MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #define WEBRTC_SPL_WORD16_MAX 32767 18 | #ifdef __cplusplus 19 | extern "C" { 20 | #endif 21 | static void rtc_FatalMessage(const char *file, int line, const char *msg) { 22 | printf("file:%s line %d: %s", file, line, msg); 23 | } 24 | #ifdef __cplusplus 25 | } // extern "C" 26 | #endif 27 | #if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) 28 | #define RTC_DCHECK_IS_ON 1 29 | #else 30 | #define RTC_DCHECK_IS_ON 0 31 | #endif 32 | #define RTC_CHECK(condition) \ 33 | do { \ 34 | if (!(condition)) { \ 35 | rtc_FatalMessage(__FILE__, __LINE__, "CHECK failed: " #condition); \ 36 | } \ 37 | } while (0) 38 | 39 | #define RTC_DCHECK(condition) \ 40 | do { \ 41 | if (RTC_DCHECK_IS_ON && !(condition)) { \ 42 | rtc_FatalMessage(__FILE__, __LINE__, "DCHECK failed: " #condition); \ 43 | } \ 44 | } while (0) 45 | #define RTC_DCHECK_LT(a, b) RTC_DCHECK((a) < (b)) 46 | #define RTC_CHECK_EQ(a, b) RTC_CHECK((a) == (b)) 47 | #define RTC_DCHECK_EQ(v1, v2) RTC_CHECK_EQ(v1, v2) 48 | #define RTC_CHECK_LE(a, b) RTC_CHECK((a) <= (b)) 49 | #define RTC_DCHECK_LE(a, b) RTC_DCHECK((a) <= (b)) 50 | #define RTC_CHECK_GT(a, b) RTC_CHECK((a) > (b)) 51 | #define RTC_DCHECK_GT(v1, v2) RTC_CHECK_GT(v1, v2) 52 | 53 | #include 54 | 55 | #include // NOLINT(build/include) 56 | 57 | #define WEBRTC_CNG_MAX_LPC_ORDER 12 58 | #ifndef API_ARRAY_VIEW_H_ 59 | #define API_ARRAY_VIEW_H_ 60 | 61 | #include 62 | #include 63 | 64 | 65 | #ifndef RTC_BASE_TYPE_TRAITS_H_ 66 | #define RTC_BASE_TYPE_TRAITS_H_ 67 | 68 | #include 69 | #include 70 | 71 | 72 | // Determines if the given class has zero-argument .data() and .size() methods 73 | // whose return values are convertible to T* and size_t, respectively. 74 | template 75 | class HasDataAndSize { 76 | private: 77 | template< 78 | typename C, 79 | typename std::enable_if< 80 | std::is_convertible().data()), T *>::value && 81 | std::is_convertible().size()), 82 | std::size_t>::value>::type * = nullptr> 83 | static int Test(int); 84 | 85 | template 86 | static char Test(...); 87 | 88 | public: 89 | static constexpr bool value = std::is_same(0)), int>::value; 90 | }; 91 | 92 | namespace test_has_data_and_size { 93 | 94 | template 95 | struct Test1 { 96 | DR data(); 97 | 98 | SR size(); 99 | }; 100 | 101 | static_assert(HasDataAndSize, int>::value, ""); 102 | static_assert(HasDataAndSize, const int>::value, ""); 103 | static_assert(HasDataAndSize, const int>::value, ""); 104 | static_assert(!HasDataAndSize, int>::value, 105 | "implicit cast of const int* to int*"); 106 | static_assert(!HasDataAndSize, int>::value, 107 | "implicit cast of char* to int*"); 108 | 109 | struct Test2 { 110 | int *data; 111 | size_t size; 112 | }; 113 | static_assert(!HasDataAndSize::value, 114 | ".data and .size aren't functions"); 115 | 116 | struct Test3 { 117 | int *data(); 118 | }; 119 | 120 | static_assert(!HasDataAndSize::value, ".size() is missing"); 121 | 122 | class Test4 { 123 | int *data(); 124 | 125 | size_t size(); 126 | }; 127 | 128 | static_assert(!HasDataAndSize::value, 129 | ".data() and .size() are private"); 130 | 131 | } // namespace test_has_data_and_size 132 | 133 | namespace type_traits_impl { 134 | 135 | // Determines if the given type is an enum that converts implicitly to 136 | // an integral type. 137 | template 138 | struct IsIntEnum { 139 | private: 140 | // This overload is used if the type is an enum, and unary plus 141 | // compiles and turns it into an integral type. 142 | template::value && 145 | std::is_integral())>::value>::type * = 146 | nullptr> 147 | static int Test(int); 148 | 149 | // Otherwise, this overload is used. 150 | template 151 | static char Test(...); 152 | 153 | public: 154 | static constexpr bool value = 155 | std::is_same::type>(0)), 156 | int>::value; 157 | }; 158 | 159 | } // namespace type_traits_impl 160 | 161 | // Determines if the given type is integral, or an enum that 162 | // converts implicitly to an integral type. 163 | template 164 | struct IsIntlike { 165 | private: 166 | using X = typename std::remove_reference::type; 167 | 168 | public: 169 | static constexpr bool value = 170 | std::is_integral::value || type_traits_impl::IsIntEnum::value; 171 | }; 172 | 173 | namespace test_enum_intlike { 174 | 175 | enum E1 { 176 | e1 177 | }; 178 | enum { 179 | e2 180 | }; 181 | enum class E3 { 182 | e3 183 | }; 184 | struct S { 185 | }; 186 | 187 | static_assert(type_traits_impl::IsIntEnum::value, ""); 188 | static_assert(type_traits_impl::IsIntEnum::value, ""); 189 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 190 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 191 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 192 | static_assert(!type_traits_impl::IsIntEnum::value, ""); 193 | 194 | static_assert(IsIntlike::value, ""); 195 | static_assert(IsIntlike::value, ""); 196 | static_assert(!IsIntlike::value, ""); 197 | static_assert(IsIntlike::value, ""); 198 | static_assert(!IsIntlike::value, ""); 199 | static_assert(!IsIntlike::value, ""); 200 | 201 | } // test_enum_intlike 202 | 203 | 204 | #endif // RTC_BASE_TYPE_TRAITS_H_ 205 | 206 | 207 | // tl;dr: ArrayView is the same thing as gsl::span from the Guideline 208 | // Support Library. 209 | // 210 | // Many functions read from or write to arrays. The obvious way to do this is 211 | // to use two arguments, a pointer to the first element and an element count: 212 | // 213 | // bool Contains17(const int* arr, size_t size) { 214 | // for (size_t i = 0; i < size; ++i) { 215 | // if (arr[i] == 17) 216 | // return true; 217 | // } 218 | // return false; 219 | // } 220 | // 221 | // This is flexible, since it doesn't matter how the array is stored (C array, 222 | // std::vector, Buffer, ...), but it's error-prone because the caller has 223 | // to correctly specify the array length: 224 | // 225 | // Contains17(arr, arraysize(arr)); // C array 226 | // Contains17(arr.data(), arr.size()); // std::vector 227 | // Contains17(arr, size); // pointer + size 228 | // ... 229 | // 230 | // It's also kind of messy to have two separate arguments for what is 231 | // conceptually a single thing. 232 | // 233 | // Enter ArrayView. It contains a T pointer (to an array it doesn't 234 | // own) and a count, and supports the basic things you'd expect, such as 235 | // indexing and iteration. It allows us to write our function like this: 236 | // 237 | // bool Contains17(ArrayView arr) { 238 | // for (auto e : arr) { 239 | // if (e == 17) 240 | // return true; 241 | // } 242 | // return false; 243 | // } 244 | // 245 | // And even better, because a bunch of things will implicitly convert to 246 | // ArrayView, we can call it like this: 247 | // 248 | // Contains17(arr); // C array 249 | // Contains17(arr); // std::vector 250 | // Contains17(ArrayView(arr, size)); // pointer + size 251 | // Contains17(nullptr); // nullptr -> empty ArrayView 252 | // ... 253 | // 254 | // ArrayView stores both a pointer and a size, but you may also use 255 | // ArrayView, which has a size that's fixed at compile time (which means 256 | // it only has to store the pointer). 257 | // 258 | // One important point is that ArrayView and ArrayView are 259 | // different types, which allow and don't allow mutation of the array elements, 260 | // respectively. The implicit conversions work just like you'd hope, so that 261 | // e.g. vector will convert to either ArrayView or ArrayView, but const vector will convert only to ArrayView. 263 | // (ArrayView itself can be the source type in such conversions, so 264 | // ArrayView will convert to ArrayView.) 265 | // 266 | // Note: ArrayView is tiny (just a pointer and a count if variable-sized, just 267 | // a pointer if fix-sized) and trivially copyable, so it's probably cheaper to 268 | // pass it by value than by const reference. 269 | 270 | namespace impl { 271 | 272 | // Magic constant for indicating that the size of an ArrayView is variable 273 | // instead of fixed. 274 | enum : std::ptrdiff_t { 275 | kArrayViewVarSize = -4711 276 | }; 277 | 278 | // Base class for ArrayViews of fixed nonzero size. 279 | template 280 | class ArrayViewBase { 281 | static_assert(Size > 0, "ArrayView size must be variable or non-negative"); 282 | 283 | public: 284 | ArrayViewBase(T *data, size_t size) : data_(data) {} 285 | 286 | static constexpr size_t size() { return Size; } 287 | 288 | static constexpr bool empty() { return false; } 289 | 290 | T *data() const { return data_; } 291 | 292 | protected: 293 | static constexpr bool fixed_size() { return true; } 294 | 295 | private: 296 | T *data_; 297 | }; 298 | 299 | // Specialized base class for ArrayViews of fixed zero size. 300 | template 301 | class ArrayViewBase { 302 | public: 303 | explicit ArrayViewBase(T *data, size_t size) {} 304 | 305 | static constexpr size_t size() { return 0; } 306 | 307 | static constexpr bool empty() { return true; } 308 | 309 | T *data() const { return nullptr; } 310 | 311 | protected: 312 | static constexpr bool fixed_size() { return true; } 313 | }; 314 | 315 | // Specialized base class for ArrayViews of variable size. 316 | template 317 | class ArrayViewBase { 318 | public: 319 | ArrayViewBase(T *data, size_t size) 320 | : data_(size == 0 ? nullptr : data), size_(size) {} 321 | 322 | size_t size() const { return size_; } 323 | 324 | bool empty() const { return size_ == 0; } 325 | 326 | T *data() const { return data_; } 327 | 328 | protected: 329 | static constexpr bool fixed_size() { return false; } 330 | 331 | private: 332 | T *data_; 333 | size_t size_; 334 | }; 335 | 336 | } // namespace impl 337 | 338 | template 339 | class ArrayView final : public impl::ArrayViewBase { 340 | public: 341 | using value_type = T; 342 | using const_iterator = const T *; 343 | 344 | // Construct an ArrayView from a pointer and a length. 345 | template 346 | ArrayView(U *data, size_t size) 347 | : impl::ArrayViewBase::ArrayViewBase(data, size) { 348 | RTC_DCHECK_EQ(size == 0 ? nullptr : data, this->data()); 349 | RTC_DCHECK_EQ(size, this->size()); 350 | RTC_DCHECK_EQ(!this->data(), 351 | this->size() == 0); // data is null iff size == 0. 352 | } 353 | 354 | // Construct an empty ArrayView. Note that fixed-size ArrayViews of size > 0 355 | // cannot be empty. 356 | ArrayView() : ArrayView(nullptr, 0) {} 357 | 358 | ArrayView(std::nullptr_t) // NOLINT 359 | : ArrayView() {} 360 | 361 | ArrayView(std::nullptr_t, size_t size) 362 | : ArrayView(static_cast(nullptr), size) { 363 | static_assert(Size == 0 || Size == impl::kArrayViewVarSize, ""); 364 | RTC_DCHECK_EQ(0, size); 365 | } 366 | 367 | // Construct an ArrayView from an array. 368 | template 369 | ArrayView(U (&array)[N]) // NOLINT 370 | : ArrayView(array, N) { 371 | static_assert(Size == N || Size == impl::kArrayViewVarSize, 372 | "Array size must match ArrayView size"); 373 | } 374 | 375 | // (Only if size is fixed.) Construct an ArrayView from any type U that has a 376 | // static constexpr size() method whose return value is equal to Size, and a 377 | // data() method whose return value converts implicitly to T*. In particular, 378 | // this means we allow conversion from ArrayView to ArrayView, but not the other way around. We also don't allow conversion from 380 | // ArrayView to ArrayView, or from ArrayView to ArrayView when M != N. 382 | template< 383 | typename U, 384 | typename std::enable_if::value>::type * = nullptr> 386 | ArrayView(U &u) // NOLINT 387 | : ArrayView(u.data(), u.size()) { 388 | static_assert(U::size() == Size, "Sizes must match exactly"); 389 | } 390 | 391 | // (Only if size is variable.) Construct an ArrayView from any type U that 392 | // has a size() method whose return value converts implicitly to size_t, and 393 | // a data() method whose return value converts implicitly to T*. In 394 | // particular, this means we allow conversion from ArrayView to 395 | // ArrayView, but not the other way around. Other allowed 396 | // conversions include 397 | // ArrayView to ArrayView or ArrayView, 398 | // std::vector to ArrayView or ArrayView, 399 | // const std::vector to ArrayView, 400 | // Buffer to ArrayView or ArrayView, and 401 | // const Buffer to ArrayView. 402 | template< 403 | typename U, 404 | typename std::enable_if::value>::type * = nullptr> 406 | ArrayView(U &u) // NOLINT 407 | : ArrayView(u.data(), u.size()) {} 408 | 409 | // Indexing and iteration. These allow mutation even if the ArrayView is 410 | // const, because the ArrayView doesn't own the array. (To prevent mutation, 411 | // use a const element type.) 412 | T &operator[](size_t idx) const { 413 | RTC_DCHECK_LT(idx, this->size()); 414 | RTC_DCHECK(this->data()); 415 | return this->data()[idx]; 416 | } 417 | 418 | T *begin() const { return this->data(); } 419 | 420 | T *end() const { return this->data() + this->size(); } 421 | 422 | const T *cbegin() const { return this->data(); } 423 | 424 | const T *cend() const { return this->data() + this->size(); } 425 | 426 | ArrayView subview(size_t offset, size_t size) const { 427 | return offset < this->size() 428 | ? ArrayView(this->data() + offset, 429 | std::min(size, this->size() - offset)) 430 | : ArrayView(); 431 | } 432 | 433 | ArrayView subview(size_t offset) const { 434 | return subview(offset, this->size()); 435 | } 436 | }; 437 | 438 | // Comparing two ArrayViews compares their (pointer,size) pairs; it does *not* 439 | // dereference the pointers. 440 | template 441 | bool operator==(const ArrayView &a, const ArrayView &b) { 442 | return a.data() == b.data() && a.size() == b.size(); 443 | } 444 | 445 | template 446 | bool operator!=(const ArrayView &a, const ArrayView &b) { 447 | return !(a == b); 448 | } 449 | 450 | // Variable-size ArrayViews are the size of two pointers; fixed-size ArrayViews 451 | // are the size of one pointer. (And as a special case, fixed-size ArrayViews 452 | // of size 0 require no storage.) 453 | static_assert(sizeof(ArrayView) == 2 * sizeof(int *), ""); 454 | static_assert(sizeof(ArrayView) == sizeof(int *), ""); 455 | static_assert(std::is_empty>::value, ""); 456 | 457 | template 458 | inline ArrayView MakeArrayView(T *data, size_t size) { 459 | return ArrayView(data, size); 460 | } 461 | 462 | 463 | #endif // API_ARRAY_VIEW_H_ 464 | 465 | #ifndef RTC_BASE_ZERO_MEMORY_H_ 466 | #define RTC_BASE_ZERO_MEMORY_H_ 467 | 468 | 469 | // Fill memory with zeros in a way that the compiler doesn't optimize it away 470 | // even if the pointer is not used afterwards. 471 | void ExplicitZeroMemory(void *ptr, size_t len); 472 | 473 | template::value && 475 | std::is_trivial::value>::type * = nullptr> 476 | void ExplicitZeroMemory(ArrayView a) { 477 | ExplicitZeroMemory(a.data(), a.size()); 478 | } 479 | 480 | #endif // RTC_BASE_ZERO_MEMORY_H_ 481 | 482 | /* 483 | * Copyright 2004 The WebRTC Project Authors. All rights reserved. 484 | * 485 | * Use of this source code is governed by a BSD-style license 486 | * that can be found in the LICENSE file in the root of the source 487 | * tree. An additional intellectual property rights grant can be found 488 | * in the file PATENTS. All contributing project authors may 489 | * be found in the AUTHORS file in the root of the source tree. 490 | */ 491 | 492 | #ifndef RTC_BASE_BUFFER_H_ 493 | #define RTC_BASE_BUFFER_H_ 494 | 495 | #include 496 | #include 497 | #include 498 | #include 499 | #include 500 | 501 | 502 | // (Internal; please don't use outside this file.) Determines if elements of 503 | // type U are compatible with a BufferT. For most types, we just ignore 504 | // top-level const and forbid top-level volatile and require T and U to be 505 | // otherwise equal, but all byte-sized integers (notably char, int8_t, and 506 | // uint8_t) are compatible with each other. (Note: We aim to get rid of this 507 | // behavior, and treat all types the same.) 508 | template 509 | struct BufferCompat { 510 | static constexpr bool value = 511 | !std::is_volatile::value && 512 | ((std::is_integral::value && sizeof(T) == 1) 513 | ? (std::is_integral::value && sizeof(U) == 1) 514 | : (std::is_same::type>::value)); 515 | }; 516 | 517 | 518 | // Basic buffer class, can be grown and shrunk dynamically. 519 | // Unlike std::string/vector, does not initialize data when increasing size. 520 | // If "ZeroOnFree" is true, any memory is explicitly cleared before releasing. 521 | // The type alias "ZeroOnFreeBuffer" below should be used instead of setting 522 | // "ZeroOnFree" in the template manually to "true". 523 | template 524 | class BufferT { 525 | // We want T's destructor and default constructor to be trivial, i.e. perform 526 | // no action, so that we don't have to touch the memory we allocate and 527 | // deallocate. And we want T to be trivially copyable, so that we can copy T 528 | // instances with std::memcpy. This is precisely the definition of a trivial 529 | // type. 530 | static_assert(std::is_trivial::value, "T must be a trivial type."); 531 | 532 | // This class relies heavily on being able to mutate its data. 533 | static_assert(!std::is_const::value, "T may not be const"); 534 | 535 | public: 536 | using value_type = T; 537 | 538 | // An empty BufferT. 539 | BufferT() : size_(0), capacity_(0), data_(nullptr) { 540 | RTC_DCHECK(IsConsistent()); 541 | } 542 | 543 | // Disable copy construction and copy assignment, since copying a buffer is 544 | // expensive enough that we want to force the user to be explicit about it. 545 | BufferT(const BufferT &) = delete; 546 | 547 | BufferT &operator=(const BufferT &) = delete; 548 | 549 | BufferT(BufferT &&buf) 550 | : size_(buf.size()), 551 | capacity_(buf.capacity()), 552 | data_(std::move(buf.data_)) { 553 | RTC_DCHECK(IsConsistent()); 554 | buf.OnMovedFrom(); 555 | } 556 | 557 | // Construct a buffer with the specified number of uninitialized elements. 558 | explicit BufferT(size_t size) : BufferT(size, size) {} 559 | 560 | BufferT(size_t size, size_t capacity) 561 | : size_(size), 562 | capacity_(std::max(size, capacity)), 563 | data_(new T[capacity_]) { 564 | RTC_DCHECK(IsConsistent()); 565 | } 566 | 567 | // Construct a buffer and copy the specified number of elements into it. 568 | template::value>::type * = nullptr> 571 | BufferT(const U *data, size_t size) : BufferT(data, size, size) {} 572 | 573 | template::value>::type * = nullptr> 576 | BufferT(U *data, size_t size, size_t capacity) : BufferT(size, capacity) { 577 | static_assert(sizeof(T) == sizeof(U), ""); 578 | std::memcpy(data_.get(), data, size * sizeof(U)); 579 | } 580 | 581 | // Construct a buffer from the contents of an array. 582 | template::value>::type * = nullptr> 586 | BufferT(U (&array)[N]) : BufferT(array, N) {} 587 | 588 | ~BufferT() { MaybeZeroCompleteBuffer(); } 589 | 590 | // Get a pointer to the data. Just .data() will give you a (const) T*, but if 591 | // T is a byte-sized integer, you may also use .data() for any other 592 | // byte-sized integer U. 593 | template::value>::type * = nullptr> 596 | const U *data() const { 597 | RTC_DCHECK(IsConsistent()); 598 | return reinterpret_cast(data_.get()); 599 | } 600 | 601 | template::value>::type * = nullptr> 604 | U *data() { 605 | RTC_DCHECK(IsConsistent()); 606 | return reinterpret_cast(data_.get()); 607 | } 608 | 609 | bool empty() const { 610 | RTC_DCHECK(IsConsistent()); 611 | return size_ == 0; 612 | } 613 | 614 | size_t size() const { 615 | RTC_DCHECK(IsConsistent()); 616 | return size_; 617 | } 618 | 619 | size_t capacity() const { 620 | RTC_DCHECK(IsConsistent()); 621 | return capacity_; 622 | } 623 | 624 | BufferT &operator=(BufferT &&buf) { 625 | RTC_DCHECK(IsConsistent()); 626 | RTC_DCHECK(buf.IsConsistent()); 627 | size_ = buf.size_; 628 | capacity_ = buf.capacity_; 629 | data_ = std::move(buf.data_); 630 | buf.OnMovedFrom(); 631 | return *this; 632 | } 633 | 634 | bool operator==(const BufferT &buf) const { 635 | RTC_DCHECK(IsConsistent()); 636 | if (size_ != buf.size_) { 637 | return false; 638 | } 639 | if (std::is_integral::value) { 640 | // Optimization. 641 | return std::memcmp(data_.get(), buf.data_.get(), size_ * sizeof(T)) == 0; 642 | } 643 | for (size_t i = 0; i < size_; ++i) { 644 | if (data_[i] != buf.data_[i]) { 645 | return false; 646 | } 647 | } 648 | return true; 649 | } 650 | 651 | bool operator!=(const BufferT &buf) const { return !(*this == buf); } 652 | 653 | T &operator[](size_t index) { 654 | RTC_DCHECK_LT(index, size_); 655 | return data()[index]; 656 | } 657 | 658 | T operator[](size_t index) const { 659 | RTC_DCHECK_LT(index, size_); 660 | return data()[index]; 661 | } 662 | 663 | T *begin() { return data(); } 664 | 665 | T *end() { return data() + size(); } 666 | 667 | const T *begin() const { return data(); } 668 | 669 | const T *end() const { return data() + size(); } 670 | 671 | const T *cbegin() const { return data(); } 672 | 673 | const T *cend() const { return data() + size(); } 674 | 675 | // The SetData functions replace the contents of the buffer. They accept the 676 | // same input types as the constructors. 677 | template::value>::type * = nullptr> 680 | void SetData(const U *data, size_t size) { 681 | RTC_DCHECK(IsConsistent()); 682 | const size_t old_size = size_; 683 | size_ = 0; 684 | AppendData(data, size); 685 | if (ZeroOnFree && size_ < old_size) { 686 | ZeroTrailingData(old_size - size_); 687 | } 688 | } 689 | 690 | template::value>::type * = nullptr> 694 | void SetData(const U (&array)[N]) { 695 | SetData(array, N); 696 | } 697 | 698 | template::value>::type * = nullptr> 701 | void SetData(const W &w) { 702 | SetData(w.data(), w.size()); 703 | } 704 | 705 | // Replaces the data in the buffer with at most |max_elements| of data, using 706 | // the function |setter|, which should have the following signature: 707 | // 708 | // size_t setter(ArrayView view) 709 | // 710 | // |setter| is given an appropriately typed ArrayView of length exactly 711 | // |max_elements| that describes the area where it should write the data; it 712 | // should return the number of elements actually written. (If it doesn't fill 713 | // the whole ArrayView, it should leave the unused space at the end.) 714 | template::value>::type * = nullptr> 718 | size_t SetData(size_t max_elements, F &&setter) { 719 | RTC_DCHECK(IsConsistent()); 720 | const size_t old_size = size_; 721 | size_ = 0; 722 | const size_t written = AppendData(max_elements, std::forward(setter)); 723 | if (ZeroOnFree && size_ < old_size) { 724 | ZeroTrailingData(old_size - size_); 725 | } 726 | return written; 727 | } 728 | 729 | // The AppendData functions add data to the end of the buffer. They accept 730 | // the same input types as the constructors. 731 | template::value>::type * = nullptr> 734 | void AppendData(const U *data, size_t size) { 735 | RTC_DCHECK(IsConsistent()); 736 | const size_t new_size = size_ + size; 737 | EnsureCapacityWithHeadroom(new_size, true); 738 | static_assert(sizeof(T) == sizeof(U), ""); 739 | std::memcpy(data_.get() + size_, data, size * sizeof(U)); 740 | size_ = new_size; 741 | RTC_DCHECK(IsConsistent()); 742 | } 743 | 744 | template::value>::type * = nullptr> 748 | void AppendData(const U (&array)[N]) { 749 | AppendData(array, N); 750 | } 751 | 752 | template::value>::type * = nullptr> 755 | void AppendData(const W &w) { 756 | AppendData(w.data(), w.size()); 757 | } 758 | 759 | template::value>::type * = nullptr> 762 | void AppendData(const U &item) { 763 | AppendData(&item, 1); 764 | } 765 | 766 | // Appends at most |max_elements| to the end of the buffer, using the function 767 | // |setter|, which should have the following signature: 768 | // 769 | // size_t setter(ArrayView view) 770 | // 771 | // |setter| is given an appropriately typed ArrayView of length exactly 772 | // |max_elements| that describes the area where it should write the data; it 773 | // should return the number of elements actually written. (If it doesn't fill 774 | // the whole ArrayView, it should leave the unused space at the end.) 775 | template::value>::type * = nullptr> 779 | size_t AppendData(size_t max_elements, F &&setter) { 780 | RTC_DCHECK(IsConsistent()); 781 | const size_t old_size = size_; 782 | SetSize(old_size + max_elements); 783 | U *base_ptr = data() + old_size; 784 | size_t written_elements = setter(ArrayView(base_ptr, max_elements)); 785 | 786 | RTC_CHECK_LE(written_elements, max_elements); 787 | size_ = old_size + written_elements; 788 | RTC_DCHECK(IsConsistent()); 789 | return written_elements; 790 | } 791 | 792 | // Sets the size of the buffer. If the new size is smaller than the old, the 793 | // buffer contents will be kept but truncated; if the new size is greater, 794 | // the existing contents will be kept and the new space will be 795 | // uninitialized. 796 | void SetSize(size_t size) { 797 | const size_t old_size = size_; 798 | EnsureCapacityWithHeadroom(size, true); 799 | size_ = size; 800 | if (ZeroOnFree && size_ < old_size) { 801 | ZeroTrailingData(old_size - size_); 802 | } 803 | } 804 | 805 | // Ensure that the buffer size can be increased to at least capacity without 806 | // further reallocation. (Of course, this operation might need to reallocate 807 | // the buffer.) 808 | void EnsureCapacity(size_t capacity) { 809 | // Don't allocate extra headroom, since the user is asking for a specific 810 | // capacity. 811 | EnsureCapacityWithHeadroom(capacity, false); 812 | } 813 | 814 | // Resets the buffer to zero size without altering capacity. Works even if the 815 | // buffer has been moved from. 816 | void Clear() { 817 | MaybeZeroCompleteBuffer(); 818 | size_ = 0; 819 | RTC_DCHECK(IsConsistent()); 820 | } 821 | 822 | // Swaps two buffers. Also works for buffers that have been moved from. 823 | friend void swap(BufferT &a, BufferT &b) { 824 | using std::swap; 825 | swap(a.size_, b.size_); 826 | swap(a.capacity_, b.capacity_); 827 | swap(a.data_, b.data_); 828 | } 829 | 830 | private: 831 | void EnsureCapacityWithHeadroom(size_t capacity, bool extra_headroom) { 832 | RTC_DCHECK(IsConsistent()); 833 | if (capacity <= capacity_) 834 | return; 835 | 836 | // If the caller asks for extra headroom, ensure that the new capacity is 837 | // >= 1.5 times the old capacity. Any constant > 1 is sufficient to prevent 838 | // quadratic behavior; as to why we pick 1.5 in particular, see 839 | // https://github.com/facebook/folly/blob/master/folly/docs/FBVector.md and 840 | // http://www.gahcep.com/cpp-internals-stl-vector-part-1/. 841 | const size_t new_capacity = 842 | extra_headroom ? std::max(capacity, capacity_ + capacity_ / 2) 843 | : capacity; 844 | 845 | std::unique_ptr new_data(new T[new_capacity]); 846 | std::memcpy(new_data.get(), data_.get(), size_ * sizeof(T)); 847 | MaybeZeroCompleteBuffer(); 848 | data_ = std::move(new_data); 849 | capacity_ = new_capacity; 850 | RTC_DCHECK(IsConsistent()); 851 | } 852 | 853 | // Zero the complete buffer if template argument "ZeroOnFree" is true. 854 | void MaybeZeroCompleteBuffer() { 855 | if (ZeroOnFree && capacity_) { 856 | // It would be sufficient to only zero "size_" elements, as all other 857 | // methods already ensure that the unused capacity contains no sensitive 858 | // data - but better safe than sorry. 859 | ExplicitZeroMemory(data_.get(), capacity_ * sizeof(T)); 860 | } 861 | } 862 | 863 | // Zero the first "count" elements of unused capacity. 864 | void ZeroTrailingData(size_t count) { 865 | RTC_DCHECK(IsConsistent()); 866 | RTC_DCHECK_LE(count, capacity_ - size_); 867 | ExplicitZeroMemory(data_.get() + size_, count * sizeof(T)); 868 | } 869 | 870 | // Precondition for all methods except Clear and the destructor. 871 | // Postcondition for all methods except move construction and move 872 | // assignment, which leave the moved-from object in a possibly inconsistent 873 | // state. 874 | bool IsConsistent() const { 875 | return (data_ || capacity_ == 0) && capacity_ >= size_; 876 | } 877 | 878 | // Called when *this has been moved from. Conceptually it's a no-op, but we 879 | // can mutate the state slightly to help subsequent sanity checks catch bugs. 880 | void OnMovedFrom() { 881 | #if RTC_DCHECK_IS_ON 882 | // Make *this consistent and empty. Shouldn't be necessary, but better safe 883 | // than sorry. 884 | size_ = 0; 885 | capacity_ = 0; 886 | #else 887 | // Ensure that *this is always inconsistent, to provoke bugs. 888 | size_ = 1; 889 | capacity_ = 0; 890 | #endif 891 | } 892 | 893 | size_t size_; 894 | size_t capacity_; 895 | std::unique_ptr data_; 896 | }; 897 | 898 | // By far the most common sort of buffer. 899 | using Buffer = BufferT; 900 | 901 | // A buffer that zeros memory before releasing it. 902 | template 903 | using ZeroOnFreeBuffer = BufferT; 904 | 905 | 906 | #endif // RTC_BASE_BUFFER_H_ 907 | 908 | 909 | class ComfortNoiseDecoder { 910 | public: 911 | ComfortNoiseDecoder(); 912 | 913 | ~ComfortNoiseDecoder() = default; 914 | 915 | ComfortNoiseDecoder(const ComfortNoiseDecoder &) = delete; 916 | 917 | ComfortNoiseDecoder &operator=(const ComfortNoiseDecoder &) = delete; 918 | 919 | void Reset(); 920 | 921 | // Updates the CN state when a new SID packet arrives. 922 | // |sid| is a view of the SID packet without the headers. 923 | void UpdateSid(ArrayView sid); 924 | 925 | // Generates comfort noise. 926 | // |out_data| will be filled with samples - its size determines the number of 927 | // samples generated. When |new_period| is true, CNG history will be reset 928 | // before any audio is generated. Returns |false| if outData is too large - 929 | // currently 640 bytes (equalling 10ms at 64kHz). 930 | // TODO(ossu): Specify better limits for the size of out_data. Either let it 931 | // be unbounded or limit to 10ms in the current sample rate. 932 | bool Generate(ArrayView out_data, bool new_period); 933 | 934 | private: 935 | uint32_t dec_seed_; 936 | int32_t dec_target_energy_; 937 | int32_t dec_used_energy_; 938 | int16_t dec_target_reflCoefs_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 939 | int16_t dec_used_reflCoefs_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 940 | int16_t dec_filtstate_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 941 | int16_t dec_filtstateLow_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 942 | uint16_t dec_order_; 943 | int16_t dec_target_scale_factor_; /* Q29 */ 944 | int16_t dec_used_scale_factor_; /* Q29 */ 945 | }; 946 | 947 | class ComfortNoiseEncoder { 948 | public: 949 | // Creates a comfort noise encoder. 950 | // |fs| selects sample rate: 8000 for narrowband or 16000 for wideband. 951 | // |interval| sets the interval at which to generate SID data (in ms). 952 | // |quality| selects the number of refl. coeffs. Maximum allowed is 12. 953 | ComfortNoiseEncoder(int fs, int interval, int quality); 954 | 955 | ~ComfortNoiseEncoder() = default; 956 | 957 | ComfortNoiseEncoder(const ComfortNoiseEncoder &) = delete; 958 | 959 | ComfortNoiseEncoder &operator=(const ComfortNoiseEncoder &) = delete; 960 | 961 | // Resets the comfort noise encoder to its initial state. 962 | // Parameters are set as during construction. 963 | void Reset(int fs, int interval, int quality); 964 | 965 | // Analyzes background noise from |speech| and appends coefficients to 966 | // |output|. Returns the number of coefficients generated. If |force_sid| is 967 | // true, a SID frame is forced and the internal sid interval counter is reset. 968 | // Will fail if the input size is too large (> 640 samples, see 969 | // ComfortNoiseDecoder::Generate). 970 | size_t Encode(ArrayView speech, 971 | bool force_sid, 972 | Buffer *output); 973 | 974 | private: 975 | size_t enc_nrOfCoefs_; 976 | int enc_sampfreq_; 977 | int16_t enc_interval_; 978 | int16_t enc_msSinceSid_; 979 | int32_t enc_Energy_; 980 | int16_t enc_reflCoefs_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 981 | int32_t enc_corrVector_[WEBRTC_CNG_MAX_LPC_ORDER + 1]; 982 | uint32_t enc_seed_; 983 | }; 984 | 985 | 986 | #endif // MODULES_AUDIO_CODING_CODECS_CNG_WEBRTC_CNG_H_ 987 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | //采用https://github.com/mackron/dr_libs/blob/master/dr_wav.h 解码 5 | #define DR_WAV_IMPLEMENTATION 6 | 7 | #include "dr_wav.h" 8 | #include "cng.h" 9 | 10 | #ifndef nullptr 11 | #define nullptr 0 12 | #endif 13 | 14 | #ifndef MIN 15 | #define MIN(A, B) ((A) < (B) ? (A) : (B)) 16 | #endif 17 | 18 | //写wav文件 19 | void wavWrite_int16(char *filename, int16_t *buffer, size_t sampleRate, size_t totalSampleCount) { 20 | drwav_data_format format = {}; 21 | format.container = drwav_container_riff; // <-- drwav_container_riff = normal WAV files, drwav_container_w64 = Sony Wave64. 22 | format.format = DR_WAVE_FORMAT_PCM; // <-- Any of the DR_WAVE_FORMAT_* codes. 23 | format.channels = 1; 24 | format.sampleRate = (drwav_uint32) sampleRate; 25 | format.bitsPerSample = 16; 26 | drwav *pWav = drwav_open_file_write(filename, &format); 27 | if (pWav) { 28 | drwav_uint64 samplesWritten = drwav_write(pWav, totalSampleCount, buffer); 29 | drwav_uninit(pWav); 30 | if (samplesWritten != totalSampleCount) { 31 | fprintf(stderr, "ERROR\n"); 32 | exit(1); 33 | } 34 | } 35 | } 36 | 37 | 38 | //分割路径函数 39 | void splitpath(const char *path, char *drv, char *dir, char *name, char *ext) { 40 | const char *end; 41 | const char *p; 42 | const char *s; 43 | if (path[0] && path[1] == ':') { 44 | if (drv) { 45 | *drv++ = *path++; 46 | *drv++ = *path++; 47 | *drv = '\0'; 48 | } 49 | } else if (drv) 50 | *drv = '\0'; 51 | for (end = path; *end && *end != ':';) 52 | end++; 53 | for (p = end; p > path && *--p != '\\' && *p != '/';) 54 | if (*p == '.') { 55 | end = p; 56 | break; 57 | } 58 | if (ext) 59 | for (s = end; (*ext = *s++);) 60 | ext++; 61 | for (p = end; p > path;) 62 | if (*--p == '\\' || *p == '/') { 63 | p++; 64 | break; 65 | } 66 | if (name) { 67 | for (s = p; s < end;) 68 | *name++ = *s++; 69 | *name = '\0'; 70 | } 71 | if (dir) { 72 | for (s = path; s < p;) 73 | *dir++ = *s++; 74 | *dir = '\0'; 75 | } 76 | } 77 | 78 | enum { 79 | kSidShortIntervalUpdate = 1, 80 | kSidNormalIntervalUpdate = 100, 81 | kSidLongIntervalUpdate = 10000 82 | }; 83 | 84 | enum : size_t { 85 | kCNGNumParamsLow = 0, 86 | kCNGNumParamsNormal = 8, 87 | kCNGNumParamsHigh = WEBRTC_CNG_MAX_LPC_ORDER, 88 | kCNGNumParamsTooHigh = WEBRTC_CNG_MAX_LPC_ORDER + 1 89 | }; 90 | 91 | enum { 92 | kNoSid, 93 | kForceSid 94 | }; 95 | 96 | int main(int argc, char *argv[]) { 97 | printf("WebRtc Comfort Noise Generator\n"); 98 | printf("博客:http://cpuimage.cnblogs.com/\n"); 99 | printf("舒适噪音生成器\n"); 100 | int sample_rate_hz = 8000;// 8000, 16000, 32000, 48000, 64000 101 | int16_t speech_data_[640]; // Max size of CNG internal buffers. 102 | const size_t num_samples_10ms = (sample_rate_hz / 100); 103 | Buffer sid_data; 104 | int quality = kCNGNumParamsNormal; 105 | ComfortNoiseEncoder cng_encoder(sample_rate_hz, kSidNormalIntervalUpdate, 106 | quality); 107 | size_t ret = cng_encoder.Encode(ArrayView( 108 | speech_data_, num_samples_10ms), 109 | kNoSid, &sid_data); 110 | if (ret == 0) { 111 | size_t size = cng_encoder.Encode(ArrayView(speech_data_, num_samples_10ms), 112 | kForceSid, &sid_data); 113 | if (size == (quality + 1)) 114 | printf("done \n"); 115 | wavWrite_int16("cng.wav", speech_data_, sample_rate_hz, num_samples_10ms); 116 | } 117 | printf("按任意键退出程序 \n"); 118 | getchar(); 119 | return 0; 120 | } 121 | --------------------------------------------------------------------------------