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 conversation 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 "debug.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 void 371 Resampler::float_to_int16(const void *_src, int32 src_sample_offset, int32 src_sample_count, 372 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 373 { 374 register const char * src = (const char *) _src; 375 register char * dst = (char *) _dst; 376 register int32 count = dst_sample_count; 377 register float gain = _gain * 32767.0; 378 379 if (src_sample_count == dst_sample_count) { 380 // optimized case for no resampling 381 while (count--) { 382 register float sample = *(const float *)src * gain; 383 if (sample > 32767.0f) 384 *(int16 *)dst = 32767; 385 else if (sample < -32767.0f) 386 *(int16 *)dst = -32767; 387 else 388 *(int16 *)dst = (int16)sample; 389 src += src_sample_offset; 390 dst += dst_sample_offset; 391 } 392 return; 393 } 394 395 register float delta = float(src_sample_count) / float(dst_sample_count); 396 register float current = 0.0f; 397 398 if (delta < 1.0) { 399 // upsample 400 while (count--) { 401 register float sample = *(const float *)src * gain; 402 if (sample > 32767.0f) 403 *(int16 *)dst = 32767; 404 else if (sample < -32767.0f) 405 *(int16 *)dst = -32767; 406 else 407 *(int16 *)dst = (int16)sample; 408 dst += dst_sample_offset; 409 current += delta; 410 if (current >= 1.0f) { 411 current -= 1.0f; 412 src += src_sample_offset; 413 } 414 } 415 } else { 416 // downsample 417 while (count--) { 418 register float sample = *(const float *)src * gain; 419 if (sample > 32767.0f) 420 *(int16 *)dst = 32767; 421 else if (sample < -32767.0f) 422 *(int16 *)dst = -32767; 423 else 424 *(int16 *)dst = (int16)sample; 425 dst += dst_sample_offset; 426 current += delta; 427 register int32 skipcount = (int32)current; 428 current -= skipcount; 429 src += skipcount * src_sample_offset; 430 } 431 } 432 } 433 434 void 435 Resampler::float_to_int8(const void *_src, int32 src_sample_offset, int32 src_sample_count, 436 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 437 { 438 register const char * src = (const char *) _src; 439 register char * dst = (char *) _dst; 440 register int32 count = dst_sample_count; 441 register float gain = _gain * 127.0; 442 443 if (src_sample_count == dst_sample_count) { 444 // optimized case for no resampling 445 while (count--) { 446 register float sample = *(const float *)src * gain; 447 if (sample > 127.0f) 448 *(int8 *)dst = 127; 449 else if (sample < -127.0f) 450 *(int8 *)dst = -127; 451 else 452 *(int8 *)dst = (int8)sample; 453 src += src_sample_offset; 454 dst += dst_sample_offset; 455 } 456 return; 457 } 458 459 register float delta = float(src_sample_count) / float(dst_sample_count); 460 register float current = 0.0f; 461 462 if (delta < 1.0) { 463 // upsample 464 while (count--) { 465 register float sample = *(const float *)src * gain; 466 if (sample > 127.0f) 467 *(int8 *)dst = 127; 468 else if (sample < -127.0f) 469 *(int8 *)dst = -127; 470 else 471 *(int8 *)dst = (int8)sample; 472 dst += dst_sample_offset; 473 current += delta; 474 if (current >= 1.0f) { 475 current -= 1.0f; 476 src += src_sample_offset; 477 } 478 } 479 } else { 480 // downsample 481 while (count--) { 482 register float sample = *(const float *)src * gain; 483 if (sample > 127.0f) 484 *(int8 *)dst = 127; 485 else if (sample < -127.0f) 486 *(int8 *)dst = -127; 487 else 488 *(int8 *)dst = (int8)sample; 489 dst += dst_sample_offset; 490 current += delta; 491 register int32 skipcount = (int32)current; 492 current -= skipcount; 493 src += skipcount * src_sample_offset; 494 } 495 } 496 } 497 498 void 499 Resampler::float_to_uint8(const void *_src, int32 src_sample_offset, int32 src_sample_count, 500 void *_dst, int32 dst_sample_offset, int32 dst_sample_count, float _gain) 501 { 502 register const char * src = (const char *) _src; 503 register char * dst = (char *) _dst; 504 register int32 count = dst_sample_count; 505 register float gain = _gain * 127.0; 506 507 if (src_sample_count == dst_sample_count) { 508 // optimized case for no resampling 509 while (count--) { 510 register float sample = 128.0f + *(const float *)src * gain; 511 if (sample > 255.0f) 512 *(uint8 *)dst = 255; 513 else if (sample < 1.0f) 514 *(uint8 *)dst = 1; 515 else 516 *(uint8 *)dst = (uint8)sample; 517 src += src_sample_offset; 518 dst += dst_sample_offset; 519 } 520 return; 521 } 522 523 register float delta = float(src_sample_count) / float(dst_sample_count); 524 register float current = 0.0f; 525 526 if (delta < 1.0) { 527 // upsample 528 while (count--) { 529 register float sample = 128.0f + *(const float *)src * gain; 530 if (sample > 255.0f) 531 *(uint8 *)dst = 255; 532 else if (sample < 1.0f) 533 *(uint8 *)dst = 1; 534 else 535 *(uint8 *)dst = (uint8)sample; 536 dst += dst_sample_offset; 537 current += delta; 538 if (current >= 1.0f) { 539 current -= 1.0f; 540 src += src_sample_offset; 541 } 542 } 543 } else { 544 // downsample 545 while (count--) { 546 register float sample = 128.0f + *(const float *)src * gain; 547 if (sample > 255.0f) 548 *(uint8 *)dst = 255; 549 else if (sample < 1.0f) 550 *(uint8 *)dst = 1; 551 else 552 *(uint8 *)dst = (uint8)sample; 553 dst += dst_sample_offset; 554 current += delta; 555 register int32 skipcount = (int32)current; 556 current -= skipcount; 557 src += skipcount * src_sample_offset; 558 } 559 } 560 } 561