resample_by_2_internal.c (18990B)
1 /* 2 * Copyright (c) 2011 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 /* 12 * This header file contains some internal resampling functions. 13 * 14 */ 15 16 #include "common_audio/signal_processing/resample_by_2_internal.h" 17 18 #include "rtc_base/sanitizer.h" 19 20 // allpass filter coefficients. 21 static const int16_t kResampleAllpass[2][3] = {{821, 6110, 12382}, 22 {3050, 9368, 15063}}; 23 24 // 25 // decimator 26 // input: int32_t (shifted 15 positions to the left, + offset 16384) 27 // OVERWRITTEN! output: int16_t (saturated) (of length len/2) state: filter 28 // state array; length = 8 29 30 void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486 31 WebRtcSpl_DownBy2IntToShort(int32_t* in, 32 int32_t len, 33 int16_t* out, 34 int32_t* state) { 35 int32_t tmp0, tmp1, diff; 36 int32_t i; 37 38 len >>= 1; 39 40 // lower allpass filter (operates on even input samples) 41 for (i = 0; i < len; i++) { 42 tmp0 = in[i << 1]; 43 diff = tmp0 - state[1]; 44 // UBSan: -1771017321 - 999586185 cannot be represented in type 'int' 45 46 // scale down and round 47 diff = (diff + (1 << 13)) >> 14; 48 tmp1 = state[0] + diff * kResampleAllpass[1][0]; 49 state[0] = tmp0; 50 diff = tmp1 - state[2]; 51 // scale down and truncate 52 diff = diff >> 14; 53 if (diff < 0) 54 diff += 1; 55 tmp0 = state[1] + diff * kResampleAllpass[1][1]; 56 state[1] = tmp1; 57 diff = tmp0 - state[3]; 58 // scale down and truncate 59 diff = diff >> 14; 60 if (diff < 0) 61 diff += 1; 62 state[3] = state[2] + diff * kResampleAllpass[1][2]; 63 state[2] = tmp0; 64 65 // divide by two and store temporarily 66 in[i << 1] = (state[3] >> 1); 67 } 68 69 in++; 70 71 // upper allpass filter (operates on odd input samples) 72 for (i = 0; i < len; i++) { 73 tmp0 = in[i << 1]; 74 diff = tmp0 - state[5]; 75 // scale down and round 76 diff = (diff + (1 << 13)) >> 14; 77 tmp1 = state[4] + diff * kResampleAllpass[0][0]; 78 state[4] = tmp0; 79 diff = tmp1 - state[6]; 80 // scale down and round 81 diff = diff >> 14; 82 if (diff < 0) 83 diff += 1; 84 tmp0 = state[5] + diff * kResampleAllpass[0][1]; 85 state[5] = tmp1; 86 diff = tmp0 - state[7]; 87 // scale down and truncate 88 diff = diff >> 14; 89 if (diff < 0) 90 diff += 1; 91 state[7] = state[6] + diff * kResampleAllpass[0][2]; 92 state[6] = tmp0; 93 94 // divide by two and store temporarily 95 in[i << 1] = (state[7] >> 1); 96 } 97 98 in--; 99 100 // combine allpass outputs 101 for (i = 0; i < len; i += 2) { 102 // divide by two, add both allpass outputs and round 103 tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15; 104 tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15; 105 if (tmp0 > (int32_t)0x00007FFF) 106 tmp0 = 0x00007FFF; 107 if (tmp0 < (int32_t)0xFFFF8000) 108 tmp0 = 0xFFFF8000; 109 out[i] = (int16_t)tmp0; 110 if (tmp1 > (int32_t)0x00007FFF) 111 tmp1 = 0x00007FFF; 112 if (tmp1 < (int32_t)0xFFFF8000) 113 tmp1 = 0xFFFF8000; 114 out[i + 1] = (int16_t)tmp1; 115 } 116 } 117 118 // 119 // decimator 120 // input: int16_t 121 // output: int32_t (shifted 15 positions to the left, + offset 16384) (of length 122 // len/2) state: filter state array; length = 8 123 124 void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486 125 WebRtcSpl_DownBy2ShortToInt(const int16_t* in, 126 int32_t len, 127 int32_t* out, 128 int32_t* state) { 129 int32_t tmp0, tmp1, diff; 130 int32_t i; 131 132 len >>= 1; 133 134 // lower allpass filter (operates on even input samples) 135 for (i = 0; i < len; i++) { 136 tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); 137 diff = tmp0 - state[1]; 138 // scale down and round 139 diff = (diff + (1 << 13)) >> 14; 140 tmp1 = state[0] + diff * kResampleAllpass[1][0]; 141 state[0] = tmp0; 142 diff = tmp1 - state[2]; 143 // UBSan: -1379909682 - 834099714 cannot be represented in type 'int' 144 145 // scale down and truncate 146 diff = diff >> 14; 147 if (diff < 0) 148 diff += 1; 149 tmp0 = state[1] + diff * kResampleAllpass[1][1]; 150 state[1] = tmp1; 151 diff = tmp0 - state[3]; 152 // scale down and truncate 153 diff = diff >> 14; 154 if (diff < 0) 155 diff += 1; 156 state[3] = state[2] + diff * kResampleAllpass[1][2]; 157 state[2] = tmp0; 158 159 // divide by two and store temporarily 160 out[i] = (state[3] >> 1); 161 } 162 163 in++; 164 165 // upper allpass filter (operates on odd input samples) 166 for (i = 0; i < len; i++) { 167 tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); 168 diff = tmp0 - state[5]; 169 // scale down and round 170 diff = (diff + (1 << 13)) >> 14; 171 tmp1 = state[4] + diff * kResampleAllpass[0][0]; 172 state[4] = tmp0; 173 diff = tmp1 - state[6]; 174 // scale down and round 175 diff = diff >> 14; 176 if (diff < 0) 177 diff += 1; 178 tmp0 = state[5] + diff * kResampleAllpass[0][1]; 179 state[5] = tmp1; 180 diff = tmp0 - state[7]; 181 // scale down and truncate 182 diff = diff >> 14; 183 if (diff < 0) 184 diff += 1; 185 state[7] = state[6] + diff * kResampleAllpass[0][2]; 186 state[6] = tmp0; 187 188 // divide by two and store temporarily 189 out[i] += (state[7] >> 1); 190 } 191 192 in--; 193 } 194 195 // 196 // interpolator 197 // input: int16_t 198 // output: int32_t (normalized, not saturated) (of length len*2) 199 // state: filter state array; length = 8 200 void WebRtcSpl_UpBy2ShortToInt(const int16_t* in, 201 int32_t len, 202 int32_t* out, 203 int32_t* state) { 204 int32_t tmp0, tmp1, diff; 205 int32_t i; 206 207 // upper allpass filter (generates odd output samples) 208 for (i = 0; i < len; i++) { 209 tmp0 = ((int32_t)in[i] << 15) + (1 << 14); 210 diff = tmp0 - state[5]; 211 // scale down and round 212 diff = (diff + (1 << 13)) >> 14; 213 tmp1 = state[4] + diff * kResampleAllpass[0][0]; 214 state[4] = tmp0; 215 diff = tmp1 - state[6]; 216 // scale down and truncate 217 diff = diff >> 14; 218 if (diff < 0) 219 diff += 1; 220 tmp0 = state[5] + diff * kResampleAllpass[0][1]; 221 state[5] = tmp1; 222 diff = tmp0 - state[7]; 223 // scale down and truncate 224 diff = diff >> 14; 225 if (diff < 0) 226 diff += 1; 227 state[7] = state[6] + diff * kResampleAllpass[0][2]; 228 state[6] = tmp0; 229 230 // scale down, round and store 231 out[i << 1] = state[7] >> 15; 232 } 233 234 out++; 235 236 // lower allpass filter (generates even output samples) 237 for (i = 0; i < len; i++) { 238 tmp0 = ((int32_t)in[i] << 15) + (1 << 14); 239 diff = tmp0 - state[1]; 240 // scale down and round 241 diff = (diff + (1 << 13)) >> 14; 242 tmp1 = state[0] + diff * kResampleAllpass[1][0]; 243 state[0] = tmp0; 244 diff = tmp1 - state[2]; 245 // scale down and truncate 246 diff = diff >> 14; 247 if (diff < 0) 248 diff += 1; 249 tmp0 = state[1] + diff * kResampleAllpass[1][1]; 250 state[1] = tmp1; 251 diff = tmp0 - state[3]; 252 // scale down and truncate 253 diff = diff >> 14; 254 if (diff < 0) 255 diff += 1; 256 state[3] = state[2] + diff * kResampleAllpass[1][2]; 257 state[2] = tmp0; 258 259 // scale down, round and store 260 out[i << 1] = state[3] >> 15; 261 } 262 } 263 264 // 265 // interpolator 266 // input: int32_t (shifted 15 positions to the left, + offset 16384) 267 // output: int32_t (shifted 15 positions to the left, + offset 16384) (of length 268 // len*2) state: filter state array; length = 8 269 void WebRtcSpl_UpBy2IntToInt(const int32_t* in, 270 int32_t len, 271 int32_t* out, 272 int32_t* state) { 273 int32_t tmp0, tmp1, diff; 274 int32_t i; 275 276 // upper allpass filter (generates odd output samples) 277 for (i = 0; i < len; i++) { 278 tmp0 = in[i]; 279 diff = tmp0 - state[5]; 280 // scale down and round 281 diff = (diff + (1 << 13)) >> 14; 282 tmp1 = state[4] + diff * kResampleAllpass[0][0]; 283 state[4] = tmp0; 284 diff = tmp1 - state[6]; 285 // scale down and truncate 286 diff = diff >> 14; 287 if (diff < 0) 288 diff += 1; 289 tmp0 = state[5] + diff * kResampleAllpass[0][1]; 290 state[5] = tmp1; 291 diff = tmp0 - state[7]; 292 // scale down and truncate 293 diff = diff >> 14; 294 if (diff < 0) 295 diff += 1; 296 state[7] = state[6] + diff * kResampleAllpass[0][2]; 297 state[6] = tmp0; 298 299 // scale down, round and store 300 out[i << 1] = state[7]; 301 } 302 303 out++; 304 305 // lower allpass filter (generates even output samples) 306 for (i = 0; i < len; i++) { 307 tmp0 = in[i]; 308 diff = tmp0 - state[1]; 309 // scale down and round 310 diff = (diff + (1 << 13)) >> 14; 311 tmp1 = state[0] + diff * kResampleAllpass[1][0]; 312 state[0] = tmp0; 313 diff = tmp1 - state[2]; 314 // scale down and truncate 315 diff = diff >> 14; 316 if (diff < 0) 317 diff += 1; 318 tmp0 = state[1] + diff * kResampleAllpass[1][1]; 319 state[1] = tmp1; 320 diff = tmp0 - state[3]; 321 // scale down and truncate 322 diff = diff >> 14; 323 if (diff < 0) 324 diff += 1; 325 state[3] = state[2] + diff * kResampleAllpass[1][2]; 326 state[2] = tmp0; 327 328 // scale down, round and store 329 out[i << 1] = state[3]; 330 } 331 } 332 333 // 334 // interpolator 335 // input: int32_t (shifted 15 positions to the left, + offset 16384) 336 // output: int16_t (saturated) (of length len*2) 337 // state: filter state array; length = 8 338 void WebRtcSpl_UpBy2IntToShort(const int32_t* in, 339 int32_t len, 340 int16_t* out, 341 int32_t* state) { 342 int32_t tmp0, tmp1, diff; 343 int32_t i; 344 345 // upper allpass filter (generates odd output samples) 346 for (i = 0; i < len; i++) { 347 tmp0 = in[i]; 348 diff = tmp0 - state[5]; 349 // scale down and round 350 diff = (diff + (1 << 13)) >> 14; 351 tmp1 = state[4] + diff * kResampleAllpass[0][0]; 352 state[4] = tmp0; 353 diff = tmp1 - state[6]; 354 // scale down and round 355 diff = diff >> 14; 356 if (diff < 0) 357 diff += 1; 358 tmp0 = state[5] + diff * kResampleAllpass[0][1]; 359 state[5] = tmp1; 360 diff = tmp0 - state[7]; 361 // scale down and truncate 362 diff = diff >> 14; 363 if (diff < 0) 364 diff += 1; 365 state[7] = state[6] + diff * kResampleAllpass[0][2]; 366 state[6] = tmp0; 367 368 // scale down, saturate and store 369 tmp1 = state[7] >> 15; 370 if (tmp1 > (int32_t)0x00007FFF) 371 tmp1 = 0x00007FFF; 372 if (tmp1 < (int32_t)0xFFFF8000) 373 tmp1 = 0xFFFF8000; 374 out[i << 1] = (int16_t)tmp1; 375 } 376 377 out++; 378 379 // lower allpass filter (generates even output samples) 380 for (i = 0; i < len; i++) { 381 tmp0 = in[i]; 382 diff = tmp0 - state[1]; 383 // scale down and round 384 diff = (diff + (1 << 13)) >> 14; 385 tmp1 = state[0] + diff * kResampleAllpass[1][0]; 386 state[0] = tmp0; 387 diff = tmp1 - state[2]; 388 // scale down and truncate 389 diff = diff >> 14; 390 if (diff < 0) 391 diff += 1; 392 tmp0 = state[1] + diff * kResampleAllpass[1][1]; 393 state[1] = tmp1; 394 diff = tmp0 - state[3]; 395 // scale down and truncate 396 diff = diff >> 14; 397 if (diff < 0) 398 diff += 1; 399 state[3] = state[2] + diff * kResampleAllpass[1][2]; 400 state[2] = tmp0; 401 402 // scale down, saturate and store 403 tmp1 = state[3] >> 15; 404 if (tmp1 > (int32_t)0x00007FFF) 405 tmp1 = 0x00007FFF; 406 if (tmp1 < (int32_t)0xFFFF8000) 407 tmp1 = 0xFFFF8000; 408 out[i << 1] = (int16_t)tmp1; 409 } 410 } 411 412 // lowpass filter 413 // input: int16_t 414 // output: int32_t (normalized, not saturated) 415 // state: filter state array; length = 8 416 void WebRtcSpl_LPBy2ShortToInt(const int16_t* in, 417 int32_t len, 418 int32_t* out, 419 int32_t* state) { 420 int32_t tmp0, tmp1, diff; 421 int32_t i; 422 423 len >>= 1; 424 425 // lower allpass filter: odd input -> even output samples 426 in++; 427 // initial state of polyphase delay element 428 tmp0 = state[12]; 429 for (i = 0; i < len; i++) { 430 diff = tmp0 - state[1]; 431 // scale down and round 432 diff = (diff + (1 << 13)) >> 14; 433 tmp1 = state[0] + diff * kResampleAllpass[1][0]; 434 state[0] = tmp0; 435 diff = tmp1 - state[2]; 436 // scale down and truncate 437 diff = diff >> 14; 438 if (diff < 0) 439 diff += 1; 440 tmp0 = state[1] + diff * kResampleAllpass[1][1]; 441 state[1] = tmp1; 442 diff = tmp0 - state[3]; 443 // scale down and truncate 444 diff = diff >> 14; 445 if (diff < 0) 446 diff += 1; 447 state[3] = state[2] + diff * kResampleAllpass[1][2]; 448 state[2] = tmp0; 449 450 // scale down, round and store 451 out[i << 1] = state[3] >> 1; 452 tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); 453 } 454 in--; 455 456 // upper allpass filter: even input -> even output samples 457 for (i = 0; i < len; i++) { 458 tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); 459 diff = tmp0 - state[5]; 460 // scale down and round 461 diff = (diff + (1 << 13)) >> 14; 462 tmp1 = state[4] + diff * kResampleAllpass[0][0]; 463 state[4] = tmp0; 464 diff = tmp1 - state[6]; 465 // scale down and round 466 diff = diff >> 14; 467 if (diff < 0) 468 diff += 1; 469 tmp0 = state[5] + diff * kResampleAllpass[0][1]; 470 state[5] = tmp1; 471 diff = tmp0 - state[7]; 472 // scale down and truncate 473 diff = diff >> 14; 474 if (diff < 0) 475 diff += 1; 476 state[7] = state[6] + diff * kResampleAllpass[0][2]; 477 state[6] = tmp0; 478 479 // average the two allpass outputs, scale down and store 480 out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15; 481 } 482 483 // switch to odd output samples 484 out++; 485 486 // lower allpass filter: even input -> odd output samples 487 for (i = 0; i < len; i++) { 488 tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); 489 diff = tmp0 - state[9]; 490 // scale down and round 491 diff = (diff + (1 << 13)) >> 14; 492 tmp1 = state[8] + diff * kResampleAllpass[1][0]; 493 state[8] = tmp0; 494 diff = tmp1 - state[10]; 495 // scale down and truncate 496 diff = diff >> 14; 497 if (diff < 0) 498 diff += 1; 499 tmp0 = state[9] + diff * kResampleAllpass[1][1]; 500 state[9] = tmp1; 501 diff = tmp0 - state[11]; 502 // scale down and truncate 503 diff = diff >> 14; 504 if (diff < 0) 505 diff += 1; 506 state[11] = state[10] + diff * kResampleAllpass[1][2]; 507 state[10] = tmp0; 508 509 // scale down, round and store 510 out[i << 1] = state[11] >> 1; 511 } 512 513 // upper allpass filter: odd input -> odd output samples 514 in++; 515 for (i = 0; i < len; i++) { 516 tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14); 517 diff = tmp0 - state[13]; 518 // scale down and round 519 diff = (diff + (1 << 13)) >> 14; 520 tmp1 = state[12] + diff * kResampleAllpass[0][0]; 521 state[12] = tmp0; 522 diff = tmp1 - state[14]; 523 // scale down and round 524 diff = diff >> 14; 525 if (diff < 0) 526 diff += 1; 527 tmp0 = state[13] + diff * kResampleAllpass[0][1]; 528 state[13] = tmp1; 529 diff = tmp0 - state[15]; 530 // scale down and truncate 531 diff = diff >> 14; 532 if (diff < 0) 533 diff += 1; 534 state[15] = state[14] + diff * kResampleAllpass[0][2]; 535 state[14] = tmp0; 536 537 // average the two allpass outputs, scale down and store 538 out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; 539 } 540 } 541 542 // lowpass filter 543 // input: int32_t (shifted 15 positions to the left, + offset 16384) 544 // output: int32_t (normalized, not saturated) 545 // state: filter state array; length = 8 546 void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486 547 WebRtcSpl_LPBy2IntToInt(const int32_t* in, 548 int32_t len, 549 int32_t* out, 550 int32_t* state) { 551 int32_t tmp0, tmp1, diff; 552 int32_t i; 553 554 len >>= 1; 555 556 // lower allpass filter: odd input -> even output samples 557 in++; 558 // initial state of polyphase delay element 559 tmp0 = state[12]; 560 for (i = 0; i < len; i++) { 561 diff = tmp0 - state[1]; 562 // scale down and round 563 diff = (diff + (1 << 13)) >> 14; 564 tmp1 = state[0] + diff * kResampleAllpass[1][0]; 565 state[0] = tmp0; 566 diff = tmp1 - state[2]; 567 // scale down and truncate 568 diff = diff >> 14; 569 if (diff < 0) 570 diff += 1; 571 tmp0 = state[1] + diff * kResampleAllpass[1][1]; 572 state[1] = tmp1; 573 diff = tmp0 - state[3]; 574 // scale down and truncate 575 diff = diff >> 14; 576 if (diff < 0) 577 diff += 1; 578 state[3] = state[2] + diff * kResampleAllpass[1][2]; 579 state[2] = tmp0; 580 581 // scale down, round and store 582 out[i << 1] = state[3] >> 1; 583 tmp0 = in[i << 1]; 584 } 585 in--; 586 587 // upper allpass filter: even input -> even output samples 588 for (i = 0; i < len; i++) { 589 tmp0 = in[i << 1]; 590 diff = tmp0 - state[5]; 591 // UBSan: -794814117 - 1566149201 cannot be represented in type 'int' 592 593 // scale down and round 594 diff = (diff + (1 << 13)) >> 14; 595 tmp1 = state[4] + diff * kResampleAllpass[0][0]; 596 state[4] = tmp0; 597 diff = tmp1 - state[6]; 598 // scale down and round 599 diff = diff >> 14; 600 if (diff < 0) 601 diff += 1; 602 tmp0 = state[5] + diff * kResampleAllpass[0][1]; 603 state[5] = tmp1; 604 diff = tmp0 - state[7]; 605 // scale down and truncate 606 diff = diff >> 14; 607 if (diff < 0) 608 diff += 1; 609 state[7] = state[6] + diff * kResampleAllpass[0][2]; 610 state[6] = tmp0; 611 612 // average the two allpass outputs, scale down and store 613 out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15; 614 } 615 616 // switch to odd output samples 617 out++; 618 619 // lower allpass filter: even input -> odd output samples 620 for (i = 0; i < len; i++) { 621 tmp0 = in[i << 1]; 622 diff = tmp0 - state[9]; 623 // scale down and round 624 diff = (diff + (1 << 13)) >> 14; 625 tmp1 = state[8] + diff * kResampleAllpass[1][0]; 626 state[8] = tmp0; 627 diff = tmp1 - state[10]; 628 // scale down and truncate 629 diff = diff >> 14; 630 if (diff < 0) 631 diff += 1; 632 tmp0 = state[9] + diff * kResampleAllpass[1][1]; 633 state[9] = tmp1; 634 diff = tmp0 - state[11]; 635 // scale down and truncate 636 diff = diff >> 14; 637 if (diff < 0) 638 diff += 1; 639 state[11] = state[10] + diff * kResampleAllpass[1][2]; 640 state[10] = tmp0; 641 642 // scale down, round and store 643 out[i << 1] = state[11] >> 1; 644 } 645 646 // upper allpass filter: odd input -> odd output samples 647 in++; 648 for (i = 0; i < len; i++) { 649 tmp0 = in[i << 1]; 650 diff = tmp0 - state[13]; 651 // scale down and round 652 diff = (diff + (1 << 13)) >> 14; 653 tmp1 = state[12] + diff * kResampleAllpass[0][0]; 654 state[12] = tmp0; 655 diff = tmp1 - state[14]; 656 // scale down and round 657 diff = diff >> 14; 658 if (diff < 0) 659 diff += 1; 660 tmp0 = state[13] + diff * kResampleAllpass[0][1]; 661 state[13] = tmp1; 662 diff = tmp0 - state[15]; 663 // scale down and truncate 664 diff = diff >> 14; 665 if (diff < 0) 666 diff += 1; 667 state[15] = state[14] + diff * kResampleAllpass[0][2]; 668 state[14] = tmp0; 669 670 // average the two allpass outputs, scale down and store 671 out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15; 672 } 673 }