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