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