Changeset 89398 in vbox for trunk/src/VBox
- Timestamp:
- May 31, 2021 12:36:23 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
r89382 r89398 303 303 #endif 304 304 305 /** 306 * Macro for generating the conversion routines from/to different formats. 307 * Be careful what to pass in/out, as most of the macros are optimized for speed and 308 * thus don't do any bounds checking! 309 * 310 * @note Currently does not handle any endianness conversion yet! 311 */ 312 #define AUDMIXBUF_CONVERT(a_Name, a_Type, _aMin, _aMax, _aSigned, _aShift) \ 313 /* Clips a specific output value to a single sample value. */ \ 314 DECLINLINE(int32_t) audioMixBufSampleFrom##a_Name(a_Type aVal) \ 315 { \ 316 /* left shifting of signed values is not defined, therefore the intermediate uint64_t cast */ \ 317 if (_aSigned) \ 318 return (int32_t) (((uint32_t) ((int32_t) aVal )) << (32 - _aShift)); \ 319 return (int32_t) (((uint32_t) ((int32_t) aVal - ((_aMax >> 1) + 1))) << (32 - _aShift)); \ 320 } \ 321 \ 322 /* Clips a single sample value to a specific output value. */ \ 323 DECLINLINE(a_Type) audioMixBufSampleTo##a_Name(int32_t iVal) \ 324 { \ 325 if (_aSigned) \ 326 return (a_Type) (iVal >> (32 - _aShift)); \ 327 return (a_Type) ((iVal >> (32 - _aShift)) + ((_aMax >> 1) + 1)); \ 328 } \ 329 \ 330 /* Encoders for peek: */ \ 331 \ 332 /* Generic */ \ 333 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncodeGeneric,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \ 334 PAUDIOMIXBUFPEEKSTATE pState) \ 335 { \ 336 RT_NOREF_PV(pState); \ 337 uintptr_t const cSrcChannels = pState->cSrcChannels; \ 338 uintptr_t const cDstChannels = pState->cDstChannels; \ 339 a_Type *pDst = (a_Type *)pvDst; \ 340 while (cFrames-- > 0) \ 341 { \ 342 uintptr_t idxDst = cDstChannels; \ 343 while (idxDst-- > 0) \ 344 { \ 345 int8_t idxSrc = pState->aidxChannelMap[idxDst]; \ 346 if (idxSrc >= 0) \ 347 pDst[idxDst] = audioMixBufSampleTo##a_Name(pi32Src[idxSrc]); \ 348 else if (idxSrc != -2) \ 349 pDst[idxDst] = (_aSigned) ? 0 : (_aMax >> 1); \ 350 else \ 351 pDst[idxDst] = 0; \ 352 } \ 353 pDst += cDstChannels; \ 354 pi32Src += cSrcChannels; \ 355 } \ 356 } \ 357 \ 358 /* 2ch -> 2ch */ \ 359 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo2Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \ 360 PAUDIOMIXBUFPEEKSTATE pState) \ 361 { \ 362 RT_NOREF_PV(pState); \ 363 a_Type *pDst = (a_Type *)pvDst; \ 364 while (cFrames-- > 0) \ 365 { \ 366 pDst[0] = audioMixBufSampleTo##a_Name(pi32Src[0]); \ 367 pDst[1] = audioMixBufSampleTo##a_Name(pi32Src[1]); \ 368 AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \ 369 &pi32Src[0], pi32Src[0], pi32Src[1], (int32_t)pDst[0], (int32_t)pDst[1])); \ 370 pDst += 2; \ 371 pi32Src += 2; \ 372 } \ 373 } \ 374 \ 375 /* 2ch -> 1ch */ \ 376 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode2ChTo1Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \ 377 PAUDIOMIXBUFPEEKSTATE pState) \ 378 { \ 379 RT_NOREF_PV(pState); \ 380 a_Type *pDst = (a_Type *)pvDst; \ 381 while (cFrames-- > 0) \ 382 { \ 383 pDst[0] = audioMixBufSampleTo##a_Name(audioMixBufBlendSampleRet(pi32Src[0], pi32Src[1])); \ 384 pDst += 1; \ 385 pi32Src += 2; \ 386 } \ 387 } \ 388 \ 389 /* 1ch -> 2ch */ \ 390 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo2Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \ 391 PAUDIOMIXBUFPEEKSTATE pState) \ 392 { \ 393 RT_NOREF_PV(pState); \ 394 a_Type *pDst = (a_Type *)pvDst; \ 395 while (cFrames-- > 0) \ 396 { \ 397 pDst[0] = pDst[1] = audioMixBufSampleTo##a_Name(pi32Src[0]); \ 398 pDst += 2; \ 399 pi32Src += 1; \ 400 } \ 401 } \ 402 /* 1ch -> 1ch */ \ 403 static DECLCALLBACK(void) RT_CONCAT(audioMixBufEncode1ChTo1Ch,a_Name)(void *pvDst, int32_t const *pi32Src, uint32_t cFrames, \ 404 PAUDIOMIXBUFPEEKSTATE pState) \ 405 { \ 406 RT_NOREF_PV(pState); \ 407 a_Type *pDst = (a_Type *)pvDst; \ 408 while (cFrames-- > 0) \ 409 { \ 410 pDst[0] = audioMixBufSampleTo##a_Name(pi32Src[0]); \ 411 pDst += 1; \ 412 pi32Src += 1; \ 413 } \ 414 } \ 415 \ 416 /* Decoders for write: */ \ 417 \ 418 /* Generic */ \ 419 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecodeGeneric,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \ 420 PAUDIOMIXBUFWRITESTATE pState) \ 421 { \ 422 RT_NOREF_PV(pState); \ 423 uintptr_t const cSrcChannels = pState->cSrcChannels; \ 424 uintptr_t const cDstChannels = pState->cDstChannels; \ 425 a_Type const *pSrc = (a_Type const *)pvSrc; \ 426 while (cFrames-- > 0) \ 427 { \ 428 uintptr_t idxDst = cDstChannels; \ 429 while (idxDst-- > 0) \ 430 { \ 431 int8_t idxSrc = pState->aidxChannelMap[idxDst]; \ 432 if (idxSrc >= 0) \ 433 pi32Dst[idxDst] = audioMixBufSampleTo##a_Name(pSrc[idxSrc]); \ 434 else if (idxSrc != -2) \ 435 pi32Dst[idxDst] = (_aSigned) ? 0 : (_aMax >> 1); \ 436 else \ 437 pi32Dst[idxDst] = 0; \ 438 } \ 439 pi32Dst += cDstChannels; \ 440 pSrc += cSrcChannels; \ 441 } \ 442 } \ 443 \ 444 /* 2ch -> 2ch */ \ 445 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo2Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \ 446 PAUDIOMIXBUFWRITESTATE pState) \ 447 { \ 448 RT_NOREF_PV(pState); \ 449 a_Type const *pSrc = (a_Type const *)pvSrc; \ 450 while (cFrames-- > 0) \ 451 { \ 452 pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \ 453 pi32Dst[1] = audioMixBufSampleFrom##a_Name(pSrc[1]); \ 454 AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \ 455 &pSrc[0], (int32_t)pSrc[0], (int32_t)pSrc[1], pi32Dst[0], pi32Dst[1])); \ 456 pi32Dst += 2; \ 457 pSrc += 2; \ 458 } \ 459 } \ 460 \ 461 /* 2ch -> 1ch */ \ 462 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode2ChTo1Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \ 463 PAUDIOMIXBUFWRITESTATE pState) \ 464 { \ 465 RT_NOREF_PV(pState); \ 466 a_Type const *pSrc = (a_Type const *)pvSrc; \ 467 while (cFrames-- > 0) \ 468 { \ 469 pi32Dst[0] = audioMixBufBlendSampleRet(audioMixBufSampleFrom##a_Name(pSrc[0]), audioMixBufSampleFrom##a_Name(pSrc[1])); \ 470 pi32Dst += 1; \ 471 pSrc += 2; \ 472 } \ 473 } \ 474 \ 475 /* 1ch -> 2ch */ \ 476 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo2Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \ 477 PAUDIOMIXBUFWRITESTATE pState) \ 478 { \ 479 RT_NOREF_PV(pState); \ 480 a_Type const *pSrc = (a_Type const *)pvSrc; \ 481 while (cFrames-- > 0) \ 482 { \ 483 pi32Dst[1] = pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \ 484 pi32Dst += 2; \ 485 pSrc += 1; \ 486 } \ 487 } \ 488 \ 489 /* 1ch -> 1ch */ \ 490 static DECLCALLBACK(void) RT_CONCAT(audioMixBufDecode1ChTo1Ch,a_Name)(int32_t *pi32Dst, void const *pvSrc, uint32_t cFrames, \ 491 PAUDIOMIXBUFWRITESTATE pState) \ 492 { \ 493 RT_NOREF_PV(pState); \ 494 a_Type const *pSrc = (a_Type const *)pvSrc; \ 495 while (cFrames-- > 0) \ 496 { \ 497 pi32Dst[0] = audioMixBufSampleFrom##a_Name(pSrc[0]); \ 498 pi32Dst += 1; \ 499 pSrc += 1; \ 500 } \ 501 } \ 502 \ 503 /* Decoders for blending: */ \ 504 \ 505 /* Generic */ \ 506 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecodeGeneric,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \ 507 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \ 508 { \ 509 RT_NOREF_PV(pState); \ 510 uintptr_t const cSrcChannels = pState->cSrcChannels; \ 511 uintptr_t const cDstChannels = pState->cDstChannels; \ 512 a_Type const *pSrc = (a_Type const *)pvSrc; \ 513 while (cFrames-- > 0) \ 514 { \ 515 uintptr_t idxDst = cDstChannels; \ 516 while (idxDst-- > 0) \ 517 { \ 518 int8_t idxSrc = pState->aidxChannelMap[idxDst]; \ 519 if (idxSrc >= 0) \ 520 audioMixBufBlendSample(&pi32Dst[idxDst], audioMixBufSampleTo##a_Name(pSrc[idxSrc])); \ 521 } \ 522 pi32Dst += cDstChannels; \ 523 pSrc += cSrcChannels; \ 524 } \ 525 } \ 526 \ 527 /* 2ch -> 2ch */ \ 528 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo2Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \ 529 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \ 530 { \ 531 RT_NOREF_PV(pState); \ 532 a_Type const *pSrc = (a_Type const *)pvSrc; \ 533 while (cFrames-- > 0) \ 534 { \ 535 audioMixBufBlendSample(&pi32Dst[0], audioMixBufSampleFrom##a_Name(pSrc[0])); \ 536 audioMixBufBlendSample(&pi32Dst[1], audioMixBufSampleFrom##a_Name(pSrc[1])); \ 537 AUDMIXBUF_MACRO_LOG(("%p: %RI32 / %RI32 => %RI32 / %RI32\n", \ 538 &pSrc[0], (int32_t)pSrc[0], (int32_t)pSrc[1], pi32Dst[0], pi32Dst[1])); \ 539 pi32Dst += 2; \ 540 pSrc += 2; \ 541 } \ 542 } \ 543 \ 544 /* 2ch -> 1ch */ \ 545 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode2ChTo1Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \ 546 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \ 547 { \ 548 RT_NOREF_PV(pState); \ 549 a_Type const *pSrc = (a_Type const *)pvSrc; \ 550 while (cFrames-- > 0) \ 551 { \ 552 audioMixBufBlendSample(&pi32Dst[0], audioMixBufBlendSampleRet(audioMixBufSampleFrom##a_Name(pSrc[0]), \ 553 audioMixBufSampleFrom##a_Name(pSrc[1]))); \ 554 pi32Dst += 1; \ 555 pSrc += 2; \ 556 } \ 557 } \ 558 \ 559 /* 1ch -> 2ch */ \ 560 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo2Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \ 561 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \ 562 { \ 563 RT_NOREF_PV(pState); \ 564 a_Type const *pSrc = (a_Type const *)pvSrc; \ 565 while (cFrames-- > 0) \ 566 { \ 567 int32_t const i32Src = audioMixBufSampleFrom##a_Name(pSrc[0]); \ 568 audioMixBufBlendSample(&pi32Dst[0], i32Src); \ 569 audioMixBufBlendSample(&pi32Dst[1], i32Src); \ 570 pi32Dst += 2; \ 571 pSrc += 1; \ 572 } \ 573 } \ 574 \ 575 /* 1ch -> 1ch */ \ 576 static DECLCALLBACK(void) RT_CONCAT3(audioMixBufDecode1ChTo1Ch,a_Name,Blend)(int32_t *pi32Dst, void const *pvSrc, \ 577 uint32_t cFrames, PAUDIOMIXBUFWRITESTATE pState) \ 578 { \ 579 RT_NOREF_PV(pState); \ 580 a_Type const *pSrc = (a_Type const *)pvSrc; \ 581 while (cFrames-- > 0) \ 582 { \ 583 audioMixBufBlendSample(&pi32Dst[0], audioMixBufSampleFrom##a_Name(pSrc[0])); \ 584 pi32Dst += 1; \ 585 pSrc += 1; \ 586 } \ 587 } 588 305 /* 306 * Instantiate format conversion (in and out of the mixer buffer.) 307 */ 308 /** @todo Currently does not handle any endianness conversion yet! */ 309 310 #include "AudioMixBuffer-Convert.cpp.h" 589 311 590 312 /* audioMixBufConvXXXS8: 8-bit, signed. */
Note:
See TracChangeset
for help on using the changeset viewer.