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