1 // AudioAdapterOp.cpp 2 3 #include "AudioAdapterOp.h" 4 #include "IAudioOp.h" 5 6 #include "AudioAdapterParams.h" 7 8 #include "audio_buffer_tools.h" 9 10 #include <Debug.h> 11 #include <ParameterWeb.h> 12 13 14 //// empty parameter-set implementation 15 //// +++++ move to IParameterSet.h! 16 // 17 //class _EmptyParameterSet : 18 // public IParameterSet { 19 //public: 20 // status_t store( 21 // int32 parameterID, 22 // void* data, 23 // size_t size) { return B_ERROR; } 24 // 25 // status_t retrieve( 26 // int32 parameterID, 27 // void* data, 28 // size_t* ioSize) { return B_ERROR; } 29 // 30 // void populateGroup( 31 // BParameterGroup* group) {} 32 //}; 33 34 // -------------------------------------------------------- // 35 // _AudioAdapterOp_base 36 // -------------------------------------------------------- // 37 38 class _AudioAdapterOp_base : 39 public IAudioOp { 40 public: 41 _AudioAdapterOp_base( 42 IAudioOpHost* _host) : 43 IAudioOp(_host) {} 44 45 void replace( 46 IAudioOp* oldOp) { 47 delete oldOp; 48 } 49 }; 50 51 // -------------------------------------------------------- // 52 // _AudioAdapterOp implementations 53 // -------------------------------------------------------- // 54 55 // direct conversion: 56 // - source and destination channel_count must be identical 57 // - source and destination must be host-endian 58 59 template <class in_t, class out_t> 60 class _AudioAdapterOp_direct : 61 public _AudioAdapterOp_base { 62 63 public: 64 _AudioAdapterOp_direct( 65 IAudioOpHost* _host) : 66 _AudioAdapterOp_base(_host) { 67 68 PRINT(("### _AudioAdapterOp_direct()\n")); 69 } 70 71 uint32 process( 72 const AudioBuffer& source, 73 AudioBuffer& destination, 74 double& sourceFrame, 75 uint32& destinationFrame, 76 uint32 framesRequired, 77 bigtime_t performanceTime) { 78 79 int32 inChannels = source.format().channel_count; 80 ASSERT(inChannels <= 2); 81 int32 outChannels = destination.format().channel_count; 82 ASSERT(outChannels == inChannels); 83 84 bool stereo = (inChannels == 2); 85 86 in_t* inBuffer = 87 ((in_t*)source.data()) + (uint32)sourceFrame*inChannels; 88 89 out_t* outBuffer = 90 ((out_t*)destination.data()) + destinationFrame*outChannels; 91 92 uint32 frame = framesRequired; 93 while(frame--) { 94 95 float val; 96 convert_sample( 97 *inBuffer, 98 val); 99 convert_sample( 100 val, 101 *outBuffer); 102 103 ++inBuffer; 104 ++outBuffer; 105 106 if(stereo) { 107 convert_sample( 108 *inBuffer, 109 val); 110 convert_sample( 111 val, 112 *outBuffer); 113 ++inBuffer; 114 ++outBuffer; 115 } 116 117 sourceFrame += 1.0; 118 destinationFrame++; 119 } 120 121 return framesRequired; 122 } 123 }; 124 125 // direct conversion + incoming data byteswapped 126 // - source and destination channel_count must be identical 127 // - destination must be host-endian 128 129 template <class in_t, class out_t> 130 class _AudioAdapterOp_swap_direct : 131 public _AudioAdapterOp_base { 132 133 public: 134 _AudioAdapterOp_swap_direct( 135 IAudioOpHost* _host) : 136 _AudioAdapterOp_base(_host) { 137 138 PRINT(("### _AudioAdapterOp_swap_direct()\n")); 139 } 140 141 uint32 process( 142 const AudioBuffer& source, 143 AudioBuffer& destination, 144 double& sourceFrame, 145 uint32& destinationFrame, 146 uint32 framesRequired, 147 bigtime_t performanceTime) { 148 149 int32 inChannels = source.format().channel_count; 150 ASSERT(inChannels <= 2); 151 int32 outChannels = destination.format().channel_count; 152 ASSERT(outChannels == inChannels); 153 154 bool stereo = (inChannels == 2); 155 156 in_t* inBuffer = 157 ((in_t*)source.data()) + (uint32)sourceFrame*inChannels; 158 159 out_t* outBuffer = 160 ((out_t*)destination.data()) + destinationFrame*outChannels; 161 162 uint32 frame = framesRequired; 163 while(frame--) { 164 165 float val; 166 swap_convert_sample( 167 *inBuffer, 168 val); 169 convert_sample( 170 val, 171 *outBuffer); 172 173 ++inBuffer; 174 ++outBuffer; 175 176 if(stereo) { 177 swap_convert_sample( 178 *inBuffer, 179 val); 180 convert_sample( 181 val, 182 *outBuffer); 183 ++inBuffer; 184 ++outBuffer; 185 } 186 187 sourceFrame += 1.0; 188 destinationFrame++; 189 } 190 191 return framesRequired; 192 } 193 }; 194 195 template <class in_t, class out_t> 196 class _AudioAdapterOp_split : 197 public _AudioAdapterOp_base { 198 public: 199 _AudioAdapterOp_split( 200 IAudioOpHost* _host) : 201 _AudioAdapterOp_base(_host) { 202 203 PRINT(("### _AudioAdapterOp_split()\n")); 204 } 205 206 uint32 process( 207 const AudioBuffer& source, 208 AudioBuffer& destination, 209 double& sourceFrame, 210 uint32& destinationFrame, 211 uint32 framesRequired, 212 bigtime_t performanceTime) { 213 214 int32 inChannels = source.format().channel_count; 215 ASSERT(inChannels == 1); 216 int32 outChannels = destination.format().channel_count; 217 ASSERT(outChannels == 2); 218 219 in_t* inBuffer = 220 ((in_t*)source.data()) + (uint32)sourceFrame*inChannels; 221 222 out_t* outBuffer = 223 ((out_t*)destination.data()) + destinationFrame*outChannels; 224 225 uint32 frame = framesRequired; 226 while(frame--) { 227 228 float val; 229 convert_sample( 230 *inBuffer, 231 val); 232 // write channel 0 233 convert_sample( 234 val, 235 *outBuffer); 236 237 // write channel 1 238 ++outBuffer; 239 convert_sample( 240 val, 241 *outBuffer); 242 243 ++inBuffer; 244 ++outBuffer; 245 246 sourceFrame += 1.0; 247 destinationFrame++; 248 } 249 250 return framesRequired; 251 } 252 }; 253 254 template <class in_t, class out_t> 255 class _AudioAdapterOp_swap_split : 256 public _AudioAdapterOp_base { 257 public: 258 _AudioAdapterOp_swap_split( 259 IAudioOpHost* _host) : 260 _AudioAdapterOp_base(_host) { 261 262 PRINT(("### _AudioAdapterOp_swap_split()\n")); 263 } 264 265 uint32 process( 266 const AudioBuffer& source, 267 AudioBuffer& destination, 268 double& sourceFrame, 269 uint32& destinationFrame, 270 uint32 framesRequired, 271 bigtime_t performanceTime) { 272 273 int32 inChannels = source.format().channel_count; 274 ASSERT(inChannels == 1); 275 int32 outChannels = destination.format().channel_count; 276 ASSERT(outChannels == 2); 277 278 in_t* inBuffer = 279 ((in_t*)source.data()) + (uint32)sourceFrame*inChannels; 280 281 out_t* outBuffer = 282 ((out_t*)destination.data()) + destinationFrame*outChannels; 283 284 uint32 frame = framesRequired; 285 while(frame--) { 286 287 float val; 288 swap_convert_sample( 289 *inBuffer, 290 val); 291 // write channel 0 292 convert_sample( 293 val, 294 *outBuffer); 295 296 // write channel 1 297 ++outBuffer; 298 convert_sample( 299 val, 300 *outBuffer); 301 302 ++inBuffer; 303 ++outBuffer; 304 305 sourceFrame += 1.0; 306 destinationFrame++; 307 } 308 309 return framesRequired; 310 } 311 }; 312 313 314 template <class in_t, class out_t> 315 class _AudioAdapterOp_mix : 316 public _AudioAdapterOp_base { 317 public: 318 _AudioAdapterOp_mix( 319 IAudioOpHost* _host) : 320 _AudioAdapterOp_base(_host) { 321 322 PRINT(("### _AudioAdapterOp_mix()\n")); 323 } 324 325 uint32 process( 326 const AudioBuffer& source, 327 AudioBuffer& destination, 328 double& sourceFrame, 329 uint32& destinationFrame, 330 uint32 framesRequired, 331 bigtime_t performanceTime) { 332 333 int32 inChannels = source.format().channel_count; 334 ASSERT(inChannels == 2); 335 int32 outChannels = destination.format().channel_count; 336 ASSERT(outChannels == 1); 337 338 in_t* inBuffer = 339 ((in_t*)source.data()) + (uint32)sourceFrame*inChannels; 340 341 out_t* outBuffer = 342 ((out_t*)destination.data()) + destinationFrame*outChannels; 343 344 uint32 frame = framesRequired; 345 while(frame--) { 346 347 float out, in; 348 convert_sample( 349 *inBuffer, 350 in); 351 352 out = in * 0.5; 353 ++inBuffer; 354 355 convert_sample( 356 *inBuffer, 357 in); 358 359 out += (in * 0.5); 360 361 // write channel 0 362 convert_sample( 363 out, 364 *outBuffer); 365 366 ++inBuffer; 367 ++outBuffer; 368 369 sourceFrame += 1.0; 370 destinationFrame++; 371 } 372 373 return framesRequired; 374 } 375 }; 376 377 template <class in_t, class out_t> 378 class _AudioAdapterOp_swap_mix : 379 public _AudioAdapterOp_base { 380 public: 381 _AudioAdapterOp_swap_mix( 382 IAudioOpHost* _host) : 383 _AudioAdapterOp_base(_host) { 384 385 PRINT(("### _AudioAdapterOp_swap_mix()\n")); 386 } 387 388 uint32 process( 389 const AudioBuffer& source, 390 AudioBuffer& destination, 391 double& sourceFrame, 392 uint32& destinationFrame, 393 uint32 framesRequired, 394 bigtime_t performanceTime) { 395 396 int32 inChannels = source.format().channel_count; 397 ASSERT(inChannels == 2); 398 int32 outChannels = destination.format().channel_count; 399 ASSERT(outChannels == 1); 400 401 in_t* inBuffer = 402 ((in_t*)source.data()) + (uint32)sourceFrame*inChannels; 403 404 out_t* outBuffer = 405 ((out_t*)destination.data()) + destinationFrame*outChannels; 406 407 uint32 frame = framesRequired; 408 while(frame--) { 409 410 float out, in; 411 swap_convert_sample( 412 *inBuffer, 413 in); 414 415 out = in * 0.5; 416 ++inBuffer; 417 418 swap_convert_sample( 419 *inBuffer, 420 in); 421 422 out += (in * 0.5); 423 424 // write channel 0 425 convert_sample( 426 out, 427 *outBuffer); 428 429 ++inBuffer; 430 ++outBuffer; 431 432 sourceFrame += 1.0; 433 destinationFrame++; 434 } 435 436 return framesRequired; 437 } 438 }; 439 440 // -------------------------------------------------------- // 441 // AudioAdapterOpFactory impl. 442 // -------------------------------------------------------- // 443 444 // [8sep99] yeeechk! 445 // [16sep99] now handles pre-conversion byteswapping 446 447 IAudioOp* AudioAdapterOpFactory::createOp( 448 IAudioOpHost* host, 449 const media_raw_audio_format& inputFormat, 450 const media_raw_audio_format& outputFormat) { 451 452 // [16sep99] ensure fully-specified input & output formats 453 ASSERT( 454 inputFormat.frame_rate && 455 inputFormat.byte_order && 456 inputFormat.channel_count && 457 inputFormat.format && 458 inputFormat.buffer_size); 459 ASSERT( 460 outputFormat.frame_rate && 461 outputFormat.byte_order && 462 outputFormat.channel_count && 463 outputFormat.format && 464 outputFormat.buffer_size); 465 466 int32 inChannels = inputFormat.channel_count; 467 int32 outChannels = outputFormat.channel_count; 468 469 // char fmt_buffer[256]; 470 // media_format f; 471 // f.type = B_MEDIA_RAW_AUDIO; 472 // f.u.raw_audio = inputFormat; 473 // string_for_format(f, fmt_buffer, 255); 474 475 bool swapBefore = (inputFormat.byte_order != 476 ((B_HOST_IS_BENDIAN) ? B_MEDIA_BIG_ENDIAN : B_MEDIA_LITTLE_ENDIAN)); 477 478 // PRINT(("### swapBefore: '%s'\n", fmt_buffer)); 479 480 bool split = outChannels > inChannels; 481 bool mix = outChannels < inChannels; 482 483 switch(inputFormat.format) { 484 case media_raw_audio_format::B_AUDIO_UCHAR: 485 switch(outputFormat.format) { 486 case media_raw_audio_format::B_AUDIO_UCHAR: 487 return 488 split ? (IAudioOp*)new _AudioAdapterOp_split < uint8, uint8>(host) : 489 mix ? (IAudioOp*)new _AudioAdapterOp_mix < uint8, uint8>(host) : 490 (IAudioOp*)new _AudioAdapterOp_direct < uint8, uint8>(host); 491 break; 492 case media_raw_audio_format::B_AUDIO_SHORT: 493 if(swapBefore) return 494 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< uint8, short>(host) : 495 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < uint8, short>(host) : 496 (IAudioOp*)new _AudioAdapterOp_swap_direct < uint8, short>(host); 497 else return 498 split ? (IAudioOp*)new _AudioAdapterOp_split < uint8, short>(host) : 499 mix ? (IAudioOp*)new _AudioAdapterOp_mix < uint8, short>(host) : 500 (IAudioOp*)new _AudioAdapterOp_direct < uint8, short>(host); 501 break; 502 case media_raw_audio_format::B_AUDIO_FLOAT: 503 if(swapBefore) return 504 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< uint8, float>(host) : 505 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < uint8, float>(host) : 506 (IAudioOp*)new _AudioAdapterOp_swap_direct < uint8, float>(host); 507 else return 508 split ? (IAudioOp*)new _AudioAdapterOp_split < uint8, float>(host) : 509 mix ? (IAudioOp*)new _AudioAdapterOp_mix < uint8, float>(host) : 510 (IAudioOp*)new _AudioAdapterOp_direct < uint8, float>(host); 511 break; 512 case media_raw_audio_format::B_AUDIO_INT: 513 if(swapBefore) return 514 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< uint8, int32>(host) : 515 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < uint8, int32>(host) : 516 (IAudioOp*)new _AudioAdapterOp_swap_direct < uint8, int32>(host); 517 else return 518 split ? (IAudioOp*)new _AudioAdapterOp_split < uint8, int32>(host) : 519 mix ? (IAudioOp*)new _AudioAdapterOp_mix < uint8, int32>(host) : 520 (IAudioOp*)new _AudioAdapterOp_direct < uint8, int32>(host); 521 break; 522 } 523 break; 524 525 case media_raw_audio_format::B_AUDIO_SHORT: 526 switch(outputFormat.format) { 527 case media_raw_audio_format::B_AUDIO_UCHAR: 528 if(swapBefore) return 529 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< short, uint8>(host) : 530 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < short, uint8>(host) : 531 (IAudioOp*)new _AudioAdapterOp_swap_direct < short, uint8>(host); 532 else return 533 split ? (IAudioOp*)new _AudioAdapterOp_split < short, uint8>(host) : 534 mix ? (IAudioOp*)new _AudioAdapterOp_mix < short, uint8>(host) : 535 (IAudioOp*)new _AudioAdapterOp_direct < short, uint8>(host); 536 break; 537 case media_raw_audio_format::B_AUDIO_SHORT: 538 if(swapBefore) return 539 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< short, short>(host) : 540 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < short, short>(host) : 541 (IAudioOp*)new _AudioAdapterOp_swap_direct < short, short>(host); 542 else return 543 split ? (IAudioOp*)new _AudioAdapterOp_split < short, short>(host) : 544 mix ? (IAudioOp*)new _AudioAdapterOp_mix < short, short>(host) : 545 (IAudioOp*)new _AudioAdapterOp_direct < short, short>(host); 546 break; 547 case media_raw_audio_format::B_AUDIO_FLOAT: 548 if(swapBefore) return 549 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< short, float>(host) : 550 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < short, float>(host) : 551 (IAudioOp*)new _AudioAdapterOp_swap_direct < short, float>(host); 552 else return 553 split ? (IAudioOp*)new _AudioAdapterOp_split < short, float>(host) : 554 mix ? (IAudioOp*)new _AudioAdapterOp_mix < short, float>(host) : 555 (IAudioOp*)new _AudioAdapterOp_direct < short, float>(host); 556 break; 557 case media_raw_audio_format::B_AUDIO_INT: 558 if(swapBefore) return 559 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< short, int32>(host) : 560 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < short, int32>(host) : 561 (IAudioOp*)new _AudioAdapterOp_swap_direct < short, int32>(host); 562 else return 563 split ? (IAudioOp*)new _AudioAdapterOp_split < short, int32>(host) : 564 mix ? (IAudioOp*)new _AudioAdapterOp_mix < short, int32>(host) : 565 (IAudioOp*)new _AudioAdapterOp_direct < short, int32>(host); 566 break; 567 } 568 break; 569 570 case media_raw_audio_format::B_AUDIO_FLOAT: 571 switch(outputFormat.format) { 572 case media_raw_audio_format::B_AUDIO_UCHAR: 573 if(swapBefore) return 574 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< float, uint8>(host) : 575 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < float, uint8>(host) : 576 (IAudioOp*)new _AudioAdapterOp_swap_direct < float, uint8>(host); 577 else return 578 split ? (IAudioOp*)new _AudioAdapterOp_split < float, uint8>(host) : 579 mix ? (IAudioOp*)new _AudioAdapterOp_mix < float, uint8>(host) : 580 (IAudioOp*)new _AudioAdapterOp_direct < float, uint8>(host); 581 break; 582 case media_raw_audio_format::B_AUDIO_SHORT: 583 if(swapBefore) return 584 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< float, short>(host) : 585 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < float, short>(host) : 586 (IAudioOp*)new _AudioAdapterOp_swap_direct < float, short>(host); 587 else return 588 split ? (IAudioOp*)new _AudioAdapterOp_split < float, short>(host) : 589 mix ? (IAudioOp*)new _AudioAdapterOp_mix < float, short>(host) : 590 (IAudioOp*)new _AudioAdapterOp_direct < float, short>(host); 591 break; 592 case media_raw_audio_format::B_AUDIO_FLOAT: 593 if(swapBefore) return 594 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< float, float>(host) : 595 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < float, float>(host) : 596 (IAudioOp*)new _AudioAdapterOp_swap_direct < float, float>(host); 597 else return 598 split ? (IAudioOp*)new _AudioAdapterOp_split < float, float>(host) : 599 mix ? (IAudioOp*)new _AudioAdapterOp_mix < float, float>(host) : 600 (IAudioOp*)new _AudioAdapterOp_direct < float, float>(host); 601 break; 602 case media_raw_audio_format::B_AUDIO_INT: 603 if(swapBefore) return 604 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< float, int32>(host) : 605 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < float, int32>(host) : 606 (IAudioOp*)new _AudioAdapterOp_swap_direct < float, int32>(host); 607 else return 608 split ? (IAudioOp*)new _AudioAdapterOp_split < float, int32>(host) : 609 mix ? (IAudioOp*)new _AudioAdapterOp_mix < float, int32>(host) : 610 (IAudioOp*)new _AudioAdapterOp_direct < float, int32>(host); 611 break; 612 } 613 break; 614 615 case media_raw_audio_format::B_AUDIO_INT: 616 switch(outputFormat.format) { 617 case media_raw_audio_format::B_AUDIO_UCHAR: 618 if(swapBefore) return 619 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< int32, uint8>(host) : 620 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < int32, uint8>(host) : 621 (IAudioOp*)new _AudioAdapterOp_swap_direct < int32, uint8>(host); 622 else return 623 split ? (IAudioOp*)new _AudioAdapterOp_split < int32, uint8>(host) : 624 mix ? (IAudioOp*)new _AudioAdapterOp_mix < int32, uint8>(host) : 625 (IAudioOp*)new _AudioAdapterOp_direct < int32, uint8>(host); 626 break; 627 case media_raw_audio_format::B_AUDIO_SHORT: 628 if(swapBefore) return 629 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< int32, short>(host) : 630 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < int32, short>(host) : 631 (IAudioOp*)new _AudioAdapterOp_swap_direct < int32, short>(host); 632 else return 633 split ? (IAudioOp*)new _AudioAdapterOp_split < int32, short>(host) : 634 mix ? (IAudioOp*)new _AudioAdapterOp_mix < int32, short>(host) : 635 (IAudioOp*)new _AudioAdapterOp_direct < int32, short>(host); 636 break; 637 case media_raw_audio_format::B_AUDIO_FLOAT: 638 if(swapBefore) return 639 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< int32, float>(host) : 640 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < int32, float>(host) : 641 (IAudioOp*)new _AudioAdapterOp_swap_direct < int32, float>(host); 642 else return 643 split ? (IAudioOp*)new _AudioAdapterOp_split < int32, float>(host) : 644 mix ? (IAudioOp*)new _AudioAdapterOp_mix < int32, float>(host) : 645 (IAudioOp*)new _AudioAdapterOp_direct < int32, float>(host); 646 break; 647 case media_raw_audio_format::B_AUDIO_INT: 648 if(swapBefore) return 649 split ? (IAudioOp*)new _AudioAdapterOp_swap_split< int32, int32>(host) : 650 mix ? (IAudioOp*)new _AudioAdapterOp_swap_mix < int32, int32>(host) : 651 (IAudioOp*)new _AudioAdapterOp_swap_direct < int32, int32>(host); 652 else return 653 split ? (IAudioOp*)new _AudioAdapterOp_split < int32, int32>(host) : 654 mix ? (IAudioOp*)new _AudioAdapterOp_mix < int32, int32>(host) : 655 (IAudioOp*)new _AudioAdapterOp_direct < int32, int32>(host); 656 break; 657 } 658 break; 659 } 660 661 return 0; 662 } 663 664 IParameterSet* AudioAdapterOpFactory::createParameterSet() { 665 return new _AudioAdapterParams(); 666 } 667 668 669 // END -- AudioAdapterOp.cpp -- 670