1 /* Copyright (C) 2003 Marcus Overhagen 2 * Released under terms of the MIT license. 3 * 4 * A simple resampling class for the audio mixer. 5 * You pick the conversion function on object creation, 6 * and then call the Resample() function, specifying data pointer, 7 * offset (in bytes) to the next sample, and count of samples for 8 * both source and destination. 9 * 10 */ 11 12 #include <MediaDefs.h> 13 #include "Resampler.h" 14 #include "MixerDebug.h" 15 16 Resampler::Resampler(uint32 src_format, uint32 dst_format, int16 dst_valid_bits) 17 : fFunc(0) 18 { 19 if (dst_format == media_raw_audio_format::B_AUDIO_FLOAT) { 20 switch (src_format) { 21 case media_raw_audio_format::B_AUDIO_FLOAT: 22 fFunc = &Resampler::float_to_float; 23 return; 24 case media_raw_audio_format::B_AUDIO_INT: 25 fFunc = &Resampler::int32_to_float; 26 return; 27 case media_raw_audio_format::B_AUDIO_SHORT: 28 fFunc = &Resampler::int16_to_float; 29 return; 30 case media_raw_audio_format::B_AUDIO_CHAR: 31 fFunc = &Resampler::int8_to_float; 32 return; 33 case media_raw_audio_format::B_AUDIO_UCHAR: 34 fFunc = &Resampler::uint8_to_float; 35 return; 36 default: 37 ERROR("Resampler::Resampler: unknown source format 0x%x\n", src_format); 38 return; 39 } 40 } 41 42 if (src_format == media_raw_audio_format::B_AUDIO_FLOAT) { 43 switch (dst_format) { 44 // float=>float already handled above 45 case media_raw_audio_format::B_AUDIO_INT: 46 fFunc = &Resampler::float_to_int32_32; 47 if (dst_valid_bits == 24) 48 fFunc = &Resampler::float_to_int32_24; 49 else if (dst_valid_bits == 20) 50 fFunc = &Resampler::float_to_int32_20; 51 return; 52 case media_raw_audio_format::B_AUDIO_SHORT: 53 fFunc = &Resampler::float_to_int16; 54 return; 55 case media_raw_audio_format::B_AUDIO_CHAR: 56 fFunc = &Resampler::float_to_int8; 57 return; 58 case media_raw_audio_format::B_AUDIO_UCHAR: 59 fFunc = &Resampler::float_to_uint8; 60 return; 61 default: 62 ERROR("Resampler::Resampler: unknown destination format 0x%x\n", dst_format); 63 return; 64 } 65 } 66 67 ERROR("Resampler::Resampler: source or destination format must be B_AUDIO_FLOAT\n"); 68 } 69 70 Resampler::~Resampler() 71 { 72 } 73 74 status_t 75 Resampler::InitCheck() 76 { 77 return (fFunc != 0) ? B_OK : B_ERROR; 78 } 79 80 void 81 Resampler::float_to_float(const void *_src, int32 src_sample_offset, int32 src_sample_count, 82 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 83 { 84 register const char * src = (const char *) _src; 85 register char * dst = (char *) _dst; 86 register int32 count = dst_sample_count; 87 register float gain = _gain; 88 89 if (src_sample_count == dst_sample_count) { 90 // optimized case for no resampling 91 while (count--) { 92 *(float *)dst = *(const float *)src * gain; 93 src += src_sample_offset; 94 dst += dst_sample_offset; 95 } 96 return; 97 } 98 99 register float delta = float(src_sample_count) / float(dst_sample_count); 100 register float current = 0.0f; 101 102 if (delta < 1.0) { 103 // upsample 104 while (count--) { 105 *(float *)dst = *(const float *)src * gain; 106 dst += dst_sample_offset; 107 current += delta; 108 if (current >= 1.0f) { 109 current -= 1.0f; 110 src += src_sample_offset; 111 } 112 } 113 } else { 114 // downsample 115 while (count--) { 116 *(float *)dst = *(const float *)src * gain; 117 dst += dst_sample_offset; 118 current += delta; 119 register int32 skipcount = (int32)current; 120 current -= skipcount; 121 src += skipcount * src_sample_offset; 122 } 123 } 124 } 125 126 void 127 Resampler::int32_to_float(const void *_src, int32 src_sample_offset, int32 src_sample_count, 128 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 129 { 130 register const char * src = (const char *) _src; 131 register char * dst = (char *) _dst; 132 register int32 count = dst_sample_count; 133 register float gain = _gain / 2147483647.0; 134 135 if (src_sample_count == dst_sample_count) { 136 // optimized case for no resampling 137 while (count--) { 138 *(float *)dst = *(const int32 *)src * gain; 139 src += src_sample_offset; 140 dst += dst_sample_offset; 141 } 142 return; 143 } 144 145 register float delta = float(src_sample_count) / float(dst_sample_count); 146 register float current = 0.0f; 147 148 if (delta < 1.0) { 149 // upsample 150 while (count--) { 151 *(float *)dst = *(const int32 *)src * gain; 152 dst += dst_sample_offset; 153 current += delta; 154 if (current >= 1.0f) { 155 current -= 1.0f; 156 src += src_sample_offset; 157 } 158 } 159 } else { 160 // downsample 161 while (count--) { 162 *(float *)dst = *(const int32 *)src * gain; 163 dst += dst_sample_offset; 164 current += delta; 165 register int32 skipcount = (int32)current; 166 current -= skipcount; 167 src += skipcount * src_sample_offset; 168 } 169 } 170 } 171 172 void 173 Resampler::int16_to_float(const void *_src, int32 src_sample_offset, int32 src_sample_count, 174 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 175 { 176 register const char * src = (const char *) _src; 177 register char * dst = (char *) _dst; 178 register int32 count = dst_sample_count; 179 register float gain = _gain / 32767.0; 180 181 if (src_sample_count == dst_sample_count) { 182 // optimized case for no resampling 183 while (count--) { 184 *(float *)dst = *(const int16 *)src * gain; 185 src += src_sample_offset; 186 dst += dst_sample_offset; 187 } 188 return; 189 } 190 191 register float delta = float(src_sample_count) / float(dst_sample_count); 192 register float current = 0.0f; 193 194 if (delta < 1.0) { 195 // upsample 196 while (count--) { 197 *(float *)dst = *(const int16 *)src * gain; 198 dst += dst_sample_offset; 199 current += delta; 200 if (current >= 1.0f) { 201 current -= 1.0f; 202 src += src_sample_offset; 203 } 204 } 205 } else { 206 // downsample 207 while (count--) { 208 *(float *)dst = *(const int16 *)src * gain; 209 dst += dst_sample_offset; 210 current += delta; 211 register int32 skipcount = (int32)current; 212 current -= skipcount; 213 src += skipcount * src_sample_offset; 214 } 215 } 216 } 217 218 void 219 Resampler::int8_to_float(const void *_src, int32 src_sample_offset, int32 src_sample_count, 220 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 221 { 222 register const char * src = (const char *) _src; 223 register char * dst = (char *) _dst; 224 register int32 count = dst_sample_count; 225 register float gain = _gain / 127.0; 226 227 if (src_sample_count == dst_sample_count) { 228 // optimized case for no resampling 229 while (count--) { 230 *(float *)dst = *(const int8 *)src * gain; 231 src += src_sample_offset; 232 dst += dst_sample_offset; 233 } 234 return; 235 } 236 237 register float delta = float(src_sample_count) / float(dst_sample_count); 238 register float current = 0.0f; 239 240 if (delta < 1.0) { 241 // upsample 242 while (count--) { 243 *(float *)dst = *(const int8 *)src * gain; 244 dst += dst_sample_offset; 245 current += delta; 246 if (current >= 1.0f) { 247 current -= 1.0f; 248 src += src_sample_offset; 249 } 250 } 251 } else { 252 // downsample 253 while (count--) { 254 *(float *)dst = *(const int8 *)src * gain; 255 dst += dst_sample_offset; 256 current += delta; 257 register int32 skipcount = (int32)current; 258 current -= skipcount; 259 src += skipcount * src_sample_offset; 260 } 261 } 262 } 263 264 void 265 Resampler::uint8_to_float(const void *_src, int32 src_sample_offset, int32 src_sample_count, 266 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 267 { 268 register const char * src = (const char *) _src; 269 register char * dst = (char *) _dst; 270 register int32 count = dst_sample_count; 271 register float gain = _gain / 127.0; 272 273 if (src_sample_count == dst_sample_count) { 274 // optimized case for no resampling 275 while (count--) { 276 *(float *)dst = (((int32) *(const uint8 *)src) - 128) * gain; 277 src += src_sample_offset; 278 dst += dst_sample_offset; 279 } 280 return; 281 } 282 283 register float delta = float(src_sample_count) / float(dst_sample_count); 284 register float current = 0.0f; 285 286 if (delta < 1.0) { 287 // upsample 288 while (count--) { 289 *(float *)dst = (((int32) *(const uint8 *)src) - 128) * gain; 290 dst += dst_sample_offset; 291 current += delta; 292 if (current >= 1.0f) { 293 current -= 1.0f; 294 src += src_sample_offset; 295 } 296 } 297 } else { 298 // downsample 299 while (count--) { 300 *(float *)dst = (((int32) *(const uint8 *)src) - 128) * gain; 301 dst += dst_sample_offset; 302 current += delta; 303 register int32 skipcount = (int32)current; 304 current -= skipcount; 305 src += skipcount * src_sample_offset; 306 } 307 } 308 } 309 310 void 311 Resampler::float_to_int32_32(const void *_src, int32 src_sample_offset, int32 src_sample_count, 312 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 313 { 314 register const char * src = (const char *) _src; 315 register char * dst = (char *) _dst; 316 register int32 count = dst_sample_count; 317 register float gain = _gain * 2147483647.0; 318 319 if (src_sample_count == dst_sample_count) { 320 // optimized case for no resampling 321 while (count--) { 322 register float sample = *(const float *)src * gain; 323 if (sample > 2147483647.0f) 324 *(int32 *)dst = 2147483647L; 325 else if (sample < -2147483647.0f) 326 *(int32 *)dst = -2147483647L; 327 else 328 *(int32 *)dst = (int32)sample; 329 src += src_sample_offset; 330 dst += dst_sample_offset; 331 } 332 return; 333 } 334 335 register float delta = float(src_sample_count) / float(dst_sample_count); 336 register float current = 0.0f; 337 338 if (delta < 1.0) { 339 // upsample 340 while (count--) { 341 register float sample = *(const float *)src * gain; 342 if (sample > 2147483647.0f) 343 *(int32 *)dst = 2147483647L; 344 else if (sample < -2147483647.0f) 345 *(int32 *)dst = -2147483647L; 346 else 347 *(int32 *)dst = (int32)sample; 348 dst += dst_sample_offset; 349 current += delta; 350 if (current >= 1.0f) { 351 current -= 1.0f; 352 src += src_sample_offset; 353 } 354 } 355 } else { 356 // downsample 357 while (count--) { 358 register float sample = *(const float *)src * gain; 359 if (sample > 2147483647.0f) 360 *(int32 *)dst = 2147483647L; 361 else if (sample < -2147483647.0f) 362 *(int32 *)dst = -2147483647L; 363 else 364 *(int32 *)dst = (int32)sample; 365 dst += dst_sample_offset; 366 current += delta; 367 register int32 skipcount = (int32)current; 368 current -= skipcount; 369 src += skipcount * src_sample_offset; 370 } 371 } 372 } 373 374 375 void 376 Resampler::float_to_int32_24(const void *_src, int32 src_sample_offset, int32 src_sample_count, 377 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 378 { 379 register const char * src = (const char *) _src; 380 register char * dst = (char *) _dst; 381 register int32 count = dst_sample_count; 382 register float gain = _gain * 8388607.0; 383 384 if (src_sample_count == dst_sample_count) { 385 // optimized case for no resampling 386 while (count--) { 387 register float sample = *(const float *)src * gain; 388 if (sample > 8388607.0f) 389 *(int32 *)dst = 8388607L; 390 else if (sample < -8388607.0f) 391 *(int32 *)dst = -8388607L; 392 else 393 *(int32 *)dst = (int32)sample; 394 src += src_sample_offset; 395 dst += dst_sample_offset; 396 } 397 return; 398 } 399 400 register float delta = float(src_sample_count) / float(dst_sample_count); 401 register float current = 0.0f; 402 403 if (delta < 1.0) { 404 // upsample 405 while (count--) { 406 register float sample = *(const float *)src * gain; 407 if (sample > 8388607.0f) 408 *(int32 *)dst = 8388607L; 409 else if (sample < -8388607.0f) 410 *(int32 *)dst = -8388607L; 411 else 412 *(int32 *)dst = (int32)sample; 413 dst += dst_sample_offset; 414 current += delta; 415 if (current >= 1.0f) { 416 current -= 1.0f; 417 src += src_sample_offset; 418 } 419 } 420 } else { 421 // downsample 422 while (count--) { 423 register float sample = *(const float *)src * gain; 424 if (sample > 8388607.0f) 425 *(int32 *)dst = 8388607L; 426 else if (sample < -8388607.0f) 427 *(int32 *)dst = -8388607L; 428 else 429 *(int32 *)dst = (int32)sample; 430 dst += dst_sample_offset; 431 current += delta; 432 register int32 skipcount = (int32)current; 433 current -= skipcount; 434 src += skipcount * src_sample_offset; 435 } 436 } 437 } 438 439 440 void 441 Resampler::float_to_int32_20(const void *_src, int32 src_sample_offset, int32 src_sample_count, 442 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 443 { 444 register const char * src = (const char *) _src; 445 register char * dst = (char *) _dst; 446 register int32 count = dst_sample_count; 447 register float gain = _gain * 524287.0; 448 449 if (src_sample_count == dst_sample_count) { 450 // optimized case for no resampling 451 while (count--) { 452 register float sample = *(const float *)src * gain; 453 if (sample > 524287.0f) 454 *(int32 *)dst = 524287L; 455 else if (sample < -524287.0f) 456 *(int32 *)dst = -524287L; 457 else 458 *(int32 *)dst = (int32)sample; 459 src += src_sample_offset; 460 dst += dst_sample_offset; 461 } 462 return; 463 } 464 465 register float delta = float(src_sample_count) / float(dst_sample_count); 466 register float current = 0.0f; 467 468 if (delta < 1.0) { 469 // upsample 470 while (count--) { 471 register float sample = *(const float *)src * gain; 472 if (sample > 524287.0f) 473 *(int32 *)dst = 524287L; 474 else if (sample < -524287.0f) 475 *(int32 *)dst = -524287L; 476 else 477 *(int32 *)dst = (int32)sample; 478 dst += dst_sample_offset; 479 current += delta; 480 if (current >= 1.0f) { 481 current -= 1.0f; 482 src += src_sample_offset; 483 } 484 } 485 } else { 486 // downsample 487 while (count--) { 488 register float sample = *(const float *)src * gain; 489 if (sample > 524287.0f) 490 *(int32 *)dst = 524287L; 491 else if (sample < -524287.0f) 492 *(int32 *)dst = -524287L; 493 else 494 *(int32 *)dst = (int32)sample; 495 dst += dst_sample_offset; 496 current += delta; 497 register int32 skipcount = (int32)current; 498 current -= skipcount; 499 src += skipcount * src_sample_offset; 500 } 501 } 502 } 503 504 505 void 506 Resampler::float_to_int16(const void *_src, int32 src_sample_offset, int32 src_sample_count, 507 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 508 { 509 register const char * src = (const char *) _src; 510 register char * dst = (char *) _dst; 511 register int32 count = dst_sample_count; 512 register float gain = _gain * 32767.0; 513 514 if (src_sample_count == dst_sample_count) { 515 // optimized case for no resampling 516 while (count--) { 517 register float sample = *(const float *)src * gain; 518 if (sample > 32767.0f) 519 *(int16 *)dst = 32767; 520 else if (sample < -32767.0f) 521 *(int16 *)dst = -32767; 522 else 523 *(int16 *)dst = (int16)sample; 524 src += src_sample_offset; 525 dst += dst_sample_offset; 526 } 527 return; 528 } 529 530 register float delta = float(src_sample_count) / float(dst_sample_count); 531 register float current = 0.0f; 532 533 if (delta < 1.0) { 534 // upsample 535 while (count--) { 536 register float sample = *(const float *)src * gain; 537 if (sample > 32767.0f) 538 *(int16 *)dst = 32767; 539 else if (sample < -32767.0f) 540 *(int16 *)dst = -32767; 541 else 542 *(int16 *)dst = (int16)sample; 543 dst += dst_sample_offset; 544 current += delta; 545 if (current >= 1.0f) { 546 current -= 1.0f; 547 src += src_sample_offset; 548 } 549 } 550 } else { 551 // downsample 552 while (count--) { 553 register float sample = *(const float *)src * gain; 554 if (sample > 32767.0f) 555 *(int16 *)dst = 32767; 556 else if (sample < -32767.0f) 557 *(int16 *)dst = -32767; 558 else 559 *(int16 *)dst = (int16)sample; 560 dst += dst_sample_offset; 561 current += delta; 562 register int32 skipcount = (int32)current; 563 current -= skipcount; 564 src += skipcount * src_sample_offset; 565 } 566 } 567 } 568 569 void 570 Resampler::float_to_int8(const void *_src, int32 src_sample_offset, int32 src_sample_count, 571 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 572 { 573 register const char * src = (const char *) _src; 574 register char * dst = (char *) _dst; 575 register int32 count = dst_sample_count; 576 register float gain = _gain * 127.0; 577 578 if (src_sample_count == dst_sample_count) { 579 // optimized case for no resampling 580 while (count--) { 581 register float sample = *(const float *)src * gain; 582 if (sample > 127.0f) 583 *(int8 *)dst = 127; 584 else if (sample < -127.0f) 585 *(int8 *)dst = -127; 586 else 587 *(int8 *)dst = (int8)sample; 588 src += src_sample_offset; 589 dst += dst_sample_offset; 590 } 591 return; 592 } 593 594 register float delta = float(src_sample_count) / float(dst_sample_count); 595 register float current = 0.0f; 596 597 if (delta < 1.0) { 598 // upsample 599 while (count--) { 600 register float sample = *(const float *)src * gain; 601 if (sample > 127.0f) 602 *(int8 *)dst = 127; 603 else if (sample < -127.0f) 604 *(int8 *)dst = -127; 605 else 606 *(int8 *)dst = (int8)sample; 607 dst += dst_sample_offset; 608 current += delta; 609 if (current >= 1.0f) { 610 current -= 1.0f; 611 src += src_sample_offset; 612 } 613 } 614 } else { 615 // downsample 616 while (count--) { 617 register float sample = *(const float *)src * gain; 618 if (sample > 127.0f) 619 *(int8 *)dst = 127; 620 else if (sample < -127.0f) 621 *(int8 *)dst = -127; 622 else 623 *(int8 *)dst = (int8)sample; 624 dst += dst_sample_offset; 625 current += delta; 626 register int32 skipcount = (int32)current; 627 current -= skipcount; 628 src += skipcount * src_sample_offset; 629 } 630 } 631 } 632 633 void 634 Resampler::float_to_uint8(const void *_src, int32 src_sample_offset, int32 src_sample_count, 635 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 636 { 637 register const char * src = (const char *) _src; 638 register char * dst = (char *) _dst; 639 register int32 count = dst_sample_count; 640 register float gain = _gain * 127.0; 641 642 if (src_sample_count == dst_sample_count) { 643 // optimized case for no resampling 644 while (count--) { 645 register float sample = 128.0f + *(const float *)src * gain; 646 if (sample > 255.0f) 647 *(uint8 *)dst = 255; 648 else if (sample < 1.0f) 649 *(uint8 *)dst = 1; 650 else 651 *(uint8 *)dst = (uint8)sample; 652 src += src_sample_offset; 653 dst += dst_sample_offset; 654 } 655 return; 656 } 657 658 register float delta = float(src_sample_count) / float(dst_sample_count); 659 register float current = 0.0f; 660 661 if (delta < 1.0) { 662 // upsample 663 while (count--) { 664 register float sample = 128.0f + *(const float *)src * gain; 665 if (sample > 255.0f) 666 *(uint8 *)dst = 255; 667 else if (sample < 1.0f) 668 *(uint8 *)dst = 1; 669 else 670 *(uint8 *)dst = (uint8)sample; 671 dst += dst_sample_offset; 672 current += delta; 673 if (current >= 1.0f) { 674 current -= 1.0f; 675 src += src_sample_offset; 676 } 677 } 678 } else { 679 // downsample 680 while (count--) { 681 register float sample = 128.0f + *(const float *)src * gain; 682 if (sample > 255.0f) 683 *(uint8 *)dst = 255; 684 else if (sample < 1.0f) 685 *(uint8 *)dst = 1; 686 else 687 *(uint8 *)dst = (uint8)sample; 688 dst += dst_sample_offset; 689 current += delta; 690 register int32 skipcount = (int32)current; 691 current -= skipcount; 692 src += skipcount * src_sample_offset; 693 } 694 } 695 } 696