Changeset 88312 in vbox
- Timestamp:
- Mar 29, 2021 1:03:54 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 143531
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/testcase/tstAudioMixBuffer.cpp
r88269 r88312 32 32 #include "../AudioMixBuffer.h" 33 33 #include "../AudioHlp.h" 34 35 #include <math.h> /* sin, M_PI */ 34 36 35 37 … … 305 307 static int tstParentChild(RTTEST hTest) 306 308 { 309 RTTestSub(hTest, "2 Children -> Parent (AudioMixBufWriteAt)"); 310 307 311 uint32_t cParentBufSize = RTRandU32Ex(_1K /* Min */, _16K /* Max */); /* Enough room for random sizes */ 308 312 … … 374 378 * Using AudioMixBufWriteAt for writing to children. 375 379 */ 376 RTTestSub(hTest, "2 Children -> Parent (AudioMixBufWriteAt)");377 378 380 uint32_t cChildrenSamplesMixedTotal = 0; 379 381 … … 444 446 } 445 447 448 449 static void tstDownsampling(RTTEST hTest, uint32_t uFromHz, uint32_t uToHz) 450 { 451 RTTestSubF(hTest, "Downsampling %u to %u Hz (S16)", uFromHz, uToHz); 452 453 struct { int16_t l, r; } 454 aSrcFrames[4096], 455 aDstFrames[4096]; 456 457 /* Parent (destination) buffer is xxxHz 2ch S16 */ 458 uint32_t const cFramesParent = RTRandU32Ex(16, RT_ELEMENTS(aDstFrames)); 459 PDMAUDIOPCMPROPS const CfgDst = PDMAUDIOPCMPROPS_INITIALIZER(2 /*cbSample*/, true /*fSigned*/, 2 /*ch*/, uToHz, false /*fSwap*/); 460 RTTESTI_CHECK(AudioHlpPcmPropsAreValid(&CfgDst)); 461 PDMAUDIOMIXBUF Parent; 462 RTTESTI_CHECK_RC_OK_RETV(AudioMixBufInit(&Parent, "ParentDownsampling", &CfgDst, cFramesParent)); 463 464 /* Child (source) buffer is yyykHz 2ch S16 */ 465 PDMAUDIOPCMPROPS const CfgSrc = PDMAUDIOPCMPROPS_INITIALIZER(2 /*cbSample*/, true /*fSigned*/, 2 /*ch*/, uFromHz, false /*fSwap*/); 466 RTTESTI_CHECK(AudioHlpPcmPropsAreValid(&CfgSrc)); 467 uint32_t const cFramesChild = RTRandU32Ex(32, RT_ELEMENTS(aSrcFrames)); 468 PDMAUDIOMIXBUF Child; 469 RTTESTI_CHECK_RC_OK_RETV(AudioMixBufInit(&Child, "ChildDownsampling", &CfgSrc, cFramesChild)); 470 RTTESTI_CHECK_RC_OK_RETV(AudioMixBufLinkTo(&Child, &Parent)); 471 472 /* 473 * Test parameters. 474 */ 475 uint32_t const cMaxSrcFrames = RT_MIN(cFramesParent * uFromHz / uToHz - 1, cFramesChild); 476 uint32_t const cIterations = RTRandU32Ex(4, 128); 477 RTTestErrContext(hTest, "cFramesParent=%RU32 cFramesChild=%RU32 cMaxSrcFrames=%RU32 cIterations=%RU32", 478 cFramesParent, cFramesChild, cMaxSrcFrames, cIterations); 479 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "cFramesParent=%RU32 cFramesChild=%RU32 cMaxSrcFrames=%RU32 cIterations=%RU32\n", 480 cFramesParent, cFramesChild, cMaxSrcFrames, cIterations); 481 482 /* 483 * We generate a simple "A" sine wave as input. 484 */ 485 uint32_t iSrcFrame = 0; 486 uint32_t iDstFrame = 0; 487 double rdFixed = 2.0 * M_PI * 440.0 /* A */ / PDMAudioPropsHz(&CfgSrc); /* Fixed sin() input. */ 488 for (uint32_t i = 0; i < cIterations; i++) 489 { 490 RTTestPrintf(hTest, RTTESTLVL_DEBUG, "i=%RU32\n", i); 491 492 /* 493 * Generate source frames and write them. 494 */ 495 uint32_t const cSrcFrames = i < cIterations / 2 496 ? RTRandU32Ex(2, cMaxSrcFrames) & ~(uint32_t)1 497 : RTRandU32Ex(1, cMaxSrcFrames - 1) | 1; 498 for (uint32_t j = 0; j < cSrcFrames; j++, iSrcFrame++) 499 aSrcFrames[j].r = aSrcFrames[j].l = 32760 /*Amplitude*/ * sin(rdFixed * iSrcFrame); 500 501 uint32_t cSrcFramesWritten = UINT32_MAX / 2; 502 RTTESTI_CHECK_RC_OK_BREAK(AudioMixBufWriteAt(&Child, 0, &aSrcFrames, cSrcFrames * sizeof(aSrcFrames[0]), 503 &cSrcFramesWritten)); 504 RTTESTI_CHECK_MSG_BREAK(cSrcFrames == cSrcFramesWritten, 505 ("cSrcFrames=%RU32 vs cSrcFramesWritten=%RU32\n", cSrcFrames, cSrcFramesWritten)); 506 507 /* 508 * Mix them. 509 */ 510 uint32_t cSrcFramesMixed = UINT32_MAX / 2; 511 RTTESTI_CHECK_RC_OK_BREAK(AudioMixBufMixToParent(&Child, cSrcFramesWritten, &cSrcFramesMixed)); 512 RTTESTI_CHECK_MSG(AudioMixBufUsed(&Child) == 0, ("%RU32\n", AudioMixBufUsed(&Child))); 513 RTTESTI_CHECK_MSG_BREAK(cSrcFramesWritten == cSrcFramesMixed, 514 ("cSrcFramesWritten=%RU32 cSrcFramesMixed=%RU32\n", cSrcFramesWritten, cSrcFramesMixed)); 515 RTTESTI_CHECK_MSG_BREAK(AudioMixBufUsed(&Child) == 0, ("%RU32\n", AudioMixBufUsed(&Child))); 516 517 /* 518 * Read out the parent buffer. 519 */ 520 uint32_t cDstFrames = AudioMixBufUsed(&Parent); 521 while (cDstFrames > 0) 522 { 523 uint32_t cFramesRead = UINT32_MAX / 2; 524 RTTESTI_CHECK_RC_OK_BREAK(AudioMixBufAcquireReadBlock(&Parent, aDstFrames, sizeof(aDstFrames), &cFramesRead)); 525 RTTESTI_CHECK_MSG(cFramesRead > 0 && cFramesRead <= cDstFrames, 526 ("cFramesRead=%RU32 cDstFrames=%RU32\n", cFramesRead, cDstFrames)); 527 528 AudioMixBufReleaseReadBlock(&Parent, cFramesRead); 529 AudioMixBufFinish(&Parent, cFramesRead); 530 531 iDstFrame += cFramesRead; 532 cDstFrames -= cFramesRead; 533 RTTESTI_CHECK(AudioMixBufUsed(&Parent) == cDstFrames); 534 } 535 } 536 537 RTTESTI_CHECK(AudioMixBufUsed(&Parent) == 0); 538 RTTESTI_CHECK(AudioMixBufLive(&Child) == 0); 539 uint32_t const cDstMinExpect = (uint64_t)iSrcFrame * uToHz / uFromHz; 540 uint32_t const cDstMaxExpect = ((uint64_t)iSrcFrame * uToHz + uFromHz - 1) / uFromHz; 541 RTTESTI_CHECK_MSG(iDstFrame == cDstMinExpect || iDstFrame == cDstMaxExpect, 542 ("iSrcFrame=%#x -> %#x,%#x; iDstFrame=%#x\n", iSrcFrame, cDstMinExpect, cDstMaxExpect, iDstFrame)); 543 544 AudioMixBufDestroy(&Parent); 545 AudioMixBufDestroy(&Child); 546 } 547 548 446 549 /* Test 8-bit sample conversion (8-bit -> internal -> 8-bit). */ 447 550 static int tstConversion8(RTTEST hTest) 448 551 { 552 RTTestSub(hTest, "Convert 22kHz/U8 to 44.1kHz/S16 (mono)"); 449 553 unsigned i; 450 554 uint32_t cBufSize = 256; 451 555 452 RTTestSub(hTest, "Sample conversion (U8)");453 556 454 557 /* 44100Hz, 1 Channel, U8 */ … … 550 653 static int tstConversion16(RTTEST hTest) 551 654 { 655 RTTestSub(hTest, "Convert 22kHz/S16 to 44.1kHz/S16 (mono)"); 552 656 unsigned i; 553 657 uint32_t cBufSize = 256; 554 555 RTTestSub(hTest, "Sample conversion (S16)");556 658 557 659 /* 44100Hz, 1 Channel, S16 */ … … 644 746 static int tstVolume(RTTEST hTest) 645 747 { 646 unsigned i;748 RTTestSub(hTest, "Volume control (44.1kHz S16 2ch)"); 647 749 uint32_t cBufSize = 256; 648 649 RTTestSub(hTest, "Volume control");650 750 651 751 /* Same for parent/child. */ … … 713 813 pDst16 = (int16_t *)achBuf; 714 814 715 for ( i = 0; i < cFramesParent * 2 /* stereo */; ++i)815 for (unsigned i = 0; i < cFramesParent * 2 /* stereo */; ++i) 716 816 { 717 817 RTTESTI_CHECK_MSG(*pSrc16 == *pDst16, ("index %u: Dst=%d, Src=%d\n", i, *pDst16, *pSrc16)); … … 745 845 pDst16 = (int16_t *)achBuf; 746 846 747 for ( i = 0; i < cFramesParent * 2 /* stereo */; ++i)847 for (unsigned i = 0; i < cFramesParent * 2 /* stereo */; ++i) 748 848 { 749 849 /* Watch out! For negative values, x >> 1 is not the same as x / 2. */ … … 778 878 tstConversion16(hTest); 779 879 tstVolume(hTest); 880 tstDownsampling(hTest, 44100, 22050); 881 tstDownsampling(hTest, 48000, 44100); 882 tstDownsampling(hTest, 48000, 22050); 883 tstDownsampling(hTest, 48000, 11000); 780 884 781 885 /*
Note:
See TracChangeset
for help on using the changeset viewer.