Changeset 88320 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Mar 29, 2021 8:58:59 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 143539
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
r88307 r88320 543 543 (uint32_t)(pRate->offDst >> 32), (uint32_t)(pRate->uDstInc >> 32))); \ 544 544 \ 545 if (pRate->uDstInc == (UINT64_C(1) + UINT32_MAX)) /* No conversion needed? */ \545 if (pRate->uDstInc == RT_BIT_64(32)) /* No conversion needed? */ \ 546 546 { \ 547 547 uint32_t cFrames = RT_MIN(cSrcFrames, cDstFrames); \ … … 560 560 } \ 561 561 \ 562 PPDMAUDIOFRAME paSrcStart = paSrc; \ 563 PPDMAUDIOFRAME paSrcEnd = paSrc + cSrcFrames; \ 564 PPDMAUDIOFRAME paDstStart = paDst; \ 565 PPDMAUDIOFRAME paDstEnd = paDst + cDstFrames; \ 566 PDMAUDIOFRAME frameCur = { 0 }; \ 567 PDMAUDIOFRAME frameOut; \ 568 PDMAUDIOFRAME frameLast = pRate->SrcFrameLast; \ 562 PPDMAUDIOFRAME pSrc = paSrc; \ 563 PPDMAUDIOFRAME pSrcEnd = &paSrc[cSrcFrames]; \ 564 PPDMAUDIOFRAME pDst = paDst; \ 565 PPDMAUDIOFRAME pDstEnd = &paDst[cDstFrames]; \ 566 PDMAUDIOFRAME frameLast = pRate->SrcFrameLast; \ 569 567 \ 570 while ( paDst < paDstEnd) \568 while ((uintptr_t)pDst < (uintptr_t)pDstEnd) \ 571 569 { \ 572 Assert(paSrc <= paSrcEnd); \ 573 Assert(paDst <= paDstEnd); \ 574 if (paSrc >= paSrcEnd) \ 570 Assert((uintptr_t)pSrc <= (uintptr_t)pSrcEnd); \ 571 if ((uintptr_t)pSrc >= (uintptr_t)pSrcEnd) \ 575 572 break; \ 576 573 \ 577 574 while (pRate->offSrc <= (pRate->offDst >> 32)) \ 578 575 { \ 579 Assert( paSrc <= paSrcEnd); \580 frameLast = *p aSrc++; \576 Assert((uintptr_t)pSrc < (uintptr_t)pSrcEnd); \ 577 frameLast = *pSrc++; \ 581 578 pRate->offSrc++; \ 582 if (p aSrc == paSrcEnd) \579 if (pSrc == pSrcEnd) \ 583 580 break; \ 584 581 } \ 585 582 \ 586 Assert( paSrc <= paSrcEnd); \587 if (p aSrc == paSrcEnd) \583 Assert((uintptr_t)pSrc <= (uintptr_t)pSrcEnd); \ 584 if (pSrc == pSrcEnd) \ 588 585 break; \ 589 586 \ 590 frameCur = *paSrc; \587 PDMAUDIOFRAME frameCur = *pSrc; \ 591 588 \ 592 589 /* Interpolate. */ \ 593 int64_t iDstOffInt= pRate->offDst & UINT32_MAX; \590 int64_t offDstLow = pRate->offDst & UINT32_MAX; \ 594 591 \ 595 frameOut.i64LSample = (frameLast.i64LSample * ((int64_t) (INT64_C(1) << 32) - iDstOffInt) + frameCur.i64LSample * iDstOffInt) >> 32; \ 596 frameOut.i64RSample = (frameLast.i64RSample * ((int64_t) (INT64_C(1) << 32) - iDstOffInt) + frameCur.i64RSample * iDstOffInt) >> 32; \ 592 PDMAUDIOFRAME frameOut; \ 593 frameOut.i64LSample = ( frameLast.i64LSample * ((int64_t)_4G - offDstLow) \ 594 + frameCur.i64LSample * offDstLow) >> 32; \ 595 frameOut.i64RSample = ( frameLast.i64RSample * ((int64_t)_4G - offDstLow) \ 596 + frameCur.i64RSample * offDstLow) >> 32; \ 597 597 \ 598 p aDst->i64LSample _aOp frameOut.i64LSample; \599 p aDst->i64RSample _aOp frameOut.i64RSample; \598 pDst->i64LSample _aOp frameOut.i64LSample; \ 599 pDst->i64RSample _aOp frameOut.i64RSample; \ 600 600 \ 601 AUDMIXBUF_MACRO_LOG(("\tiDstOffInt=%RI64, l=%RI64, r=%RI64 (cur l=%RI64, r=%RI64)\n", \ 602 iDstOffInt, \ 603 paDst->i64LSample >> 32, paDst->i64RSample >> 32, \ 604 frameCur.i64LSample >> 32, frameCur.i64RSample >> 32)); \ 605 \ 606 paDst++; \ 601 pDst++; \ 607 602 pRate->offDst += pRate->uDstInc; \ 608 603 \ 609 AUDMIXBUF_MACRO_LOG(("\t\tpRate->offDst=%RU32\n", pRate->offDst >> 32)); \ 610 \ 604 AUDMIXBUF_MACRO_LOG((" offDstLow=%RI64, l=%RI64, r=%RI64 (cur l=%RI64, r=%RI64); offDst=%#'RX64\n", offDstLow, \ 605 pDst->i64LSample >> 32, pDst->i64RSample >> 32, \ 606 frameCur.i64LSample >> 32, frameCur.i64RSample >> 32, \ 607 pRate->offDst)); \ 611 608 } \ 612 609 \ 613 AUDMIXBUF_MACRO_LOG(("%zu source frames -> %zu dest frames\n", paSrc - paSrcStart, paDst - paDstStart)); \ 610 pRate->SrcFrameLast = frameLast; \ 611 if (pcDstWritten) \ 612 *pcDstWritten = pDst - paDst; \ 613 if (pcSrcRead) \ 614 *pcSrcRead = pSrc - paSrc; \ 614 615 \ 615 pRate->SrcFrameLast = frameLast; \ 616 \ 616 AUDMIXBUF_MACRO_LOG(("%zu source frames -> %zu dest frames\n", pSrc - paSrc, pDst - paDst)); \ 617 617 AUDMIXBUF_MACRO_LOG(("pRate->srcSampleLast l=%RI64, r=%RI64\n", \ 618 618 pRate->SrcFrameLast.i64LSample, pRate->SrcFrameLast.i64RSample)); \ 619 \620 if (pcDstWritten) \621 *pcDstWritten = paDst - paDstStart; \622 if (pcSrcRead) \623 *pcSrcRead = paSrc - paSrcStart; \624 619 } 625 620 … … 885 880 static int64_t audioMixBufCalcFreqRatio(PPDMAUDIOMIXBUF pMixBufA, PPDMAUDIOMIXBUF pMixBufB) 886 881 { 887 int64_t iRatio = ((int64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBufA->uAudioFmt) << 32) 888 / AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBufB->uAudioFmt); 889 890 if (iRatio == 0) /* Catch division by zero. */ 891 iRatio = 1 << 20; /* Do a 1:1 conversion instead. */ 892 882 int64_t iRatio = (int64_t)((uint64_t)PDMAudioPropsHz(&pMixBufA->Props) << 32) / PDMAudioPropsHz(&pMixBufB->Props); 883 AssertStmt(iRatio, iRatio = RT_BIT_64(32) /*1:1*/); 893 884 return iRatio; 894 885 } 895 886 896 887 /** 897 * Links an audio mixing buffer to a parent mixing buffer. A parent mixing 898 * buffer can have multiple children mixing buffers [1:N], whereas a child only can 899 * have one parent mixing buffer [N:1]. 888 * Links an audio mixing buffer to a parent mixing buffer. 889 * 890 * A parent mixing buffer can have multiple children mixing buffers [1:N], 891 * whereas a child only can have one parent mixing buffer [N:1]. 900 892 * 901 893 * The mixing direction always goes from the child/children buffer(s) to the 902 894 * parent buffer. 903 895 * 904 * For guest audio output the host backend ownsthe parent mixing buffer, the905 * device emulation ownsthe child/children.896 * For guest audio output the host backend "owns" the parent mixing buffer, the 897 * device emulation "owns" the child/children. 906 898 * 907 899 * The audio format of each mixing buffer can vary; the internal mixing code … … 977 969 if (!pMixBuf->pRate) 978 970 { 979 /* Create rate conversion. */980 971 pMixBuf->pRate = (PPDMAUDIOSTREAMRATE)RTMemAllocZ(sizeof(PDMAUDIOSTREAMRATE)); 981 if (!pMixBuf->pRate) 982 return VERR_NO_MEMORY; 972 AssertReturn(pMixBuf->pRate, VERR_NO_MEMORY); 983 973 } 984 974 else 985 975 RT_BZERO(pMixBuf->pRate, sizeof(PDMAUDIOSTREAMRATE)); 986 976 987 pMixBuf->pRate->uDstInc = ((uint64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->uAudioFmt) << 32) 988 / AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->uAudioFmt); 989 990 AUDMIXBUF_LOG(("uThisHz=%RU32, uParentHz=%RU32, iFreqRatio=0x%RX64 (%RI64), uRateInc=0x%RX64 (%RU64), cFrames=%RU32 (%RU32 parent)\n", 991 AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->uAudioFmt), 992 AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->uAudioFmt), 993 pMixBuf->iFreqRatio, pMixBuf->iFreqRatio, 994 pMixBuf->pRate->uDstInc, pMixBuf->pRate->uDstInc, 995 pMixBuf->cFrames, 996 pParent->cFrames)); 997 AUDMIXBUF_LOG(("%s (%RU32Hz) -> %s (%RU32Hz)\n", 998 pMixBuf->pszName, AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->uAudioFmt), 999 pMixBuf->pParent->pszName, AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->uAudioFmt))); 977 /* 978 * Some examples to get an idea of what uDstInc holds: 979 * 44100 to 44100 -> (44100<<32) / 44100 = 0x01'00000000 (4294967296) 980 * 22050 to 44100 -> (22050<<32) / 44100 = 0x00'80000000 (2147483648) 981 * 44100 to 22050 -> (44100<<32) / 22050 = 0x02'00000000 (8589934592) 982 * 44100 to 48000 -> (44100<<32) / 48000 = 0x00'EB333333 (3946001203.2) 983 * 48000 to 44100 -> (48000<<32) / 44100 = 0x01'16A3B35F (4674794335.7823129251700680272109) 984 * 985 * Note! The iFreqRatio is the same but with the frequencies switched. 986 */ 987 pMixBuf->pRate->uDstInc = ((uint64_t)PDMAudioPropsHz(&pMixBuf->Props) << 32) / PDMAudioPropsHz(&pParent->Props); 988 989 AUDMIXBUF_LOG(("%RU32 Hz vs parent %RU32 Hz => iFreqRatio=0x%'RX64 uDstInc=0x%'RX64; cFrames=%RU32 (%RU32 parent); name: %s, parent: %s\n", 990 PDMAudioPropsHz(&pMixBuf->Props), PDMAudioPropsHz(&pParent->Props), pMixBuf->iFreqRatio, 991 pMixBuf->pRate->uDstInc, pMixBuf->cFrames, pParent->cFrames, pMixBuf->pszName, pMixBuf->pParent->pszName)); 1000 992 } 1001 993 … … 1109 1101 cDstToWrite = RT_MIN(cDstAvail, pDst->cFrames - offDstWrite); 1110 1102 1111 AUDMIXBUF_LOG((" \tSource: %RU32 @ %RU32 -> reading %RU32\n", cSrcAvail, offSrcRead, cSrcToRead));1112 AUDMIXBUF_LOG((" \tDest: %RU32 @ %RU32 -> writing %RU32\n", cDstAvail, offDstWrite, cDstToWrite));1103 AUDMIXBUF_LOG((" Src: %RU32 @ %RU32 -> reading %RU32\n", cSrcAvail, offSrcRead, cSrcToRead)); 1104 AUDMIXBUF_LOG((" Dst: %RU32 @ %RU32 -> writing %RU32\n", cDstAvail, offDstWrite, cDstToWrite)); 1113 1105 1114 1106 if ( !cDstToWrite … … 1144 1136 cDstAvail -= cDstWritten; 1145 1137 1146 AUDMIXBUF_LOG((" \t%RU32 read (%RU32 left @ %RU32), %RU32 written (%RU32 left @ %RU32)\n",1138 AUDMIXBUF_LOG((" %RU32 read (%RU32 left @ %RU32), %RU32 written (%RU32 left @ %RU32)\n", 1147 1139 cSrcRead, cSrcAvail, offSrcRead, 1148 1140 cDstWritten, cDstAvail, offDstWrite)); -
trunk/src/VBox/Devices/Audio/AudioMixer.cpp
r88313 r88320 187 187 RTCritSectLeave(&pMixer->CritSect); 188 188 189 char szPrefix[128]; 190 RTStrPrintf(szPrefix, sizeof(szPrefix), "MixerSink-%s/", pSink->pszName); 191 PDMDevHlpSTAMRegisterF(pDevIns, &pSink->MixBuf.cFrames, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE, 192 "Sink mixer buffer size in frames.", "%sMixBufSize", szPrefix); 193 PDMDevHlpSTAMRegisterF(pDevIns, &pSink->MixBuf.cUsed, STAMTYPE_U32, STAMVISIBILITY_USED, STAMUNIT_NONE, 194 "Sink mixer buffer fill size in frames.", "%sMixBufUsed", szPrefix); 195 PDMDevHlpSTAMRegisterF(pDevIns, &pSink->cStreams, STAMTYPE_U8, STAMVISIBILITY_USED, STAMUNIT_NONE, 196 "Number of streams attached to the sink.", "%sStreams", szPrefix); 197 189 198 if (ppSink) 190 199 *ppSink = pSink; … … 588 597 /* Assign the backend's name to the mixer stream's name for easier identification in the (release) log. */ 589 598 pMixStream->pszName = RTStrAPrintf2("[%s] %s", pCfg->szName, BackendCfg.szName); 590 pMixStream->pszStatPrefix = RTStrAPrintf2("Mix -%s/[%s] %s/", pSink->pszName, pCfg->szName, BackendCfg.szName);599 pMixStream->pszStatPrefix = RTStrAPrintf2("MixerSink-%s/%s/", pSink->pszName, BackendCfg.szName); 591 600 if (pMixStream->pszName && pMixStream->pszStatPrefix) 592 601 { … … 923 932 } 924 933 934 char szPrefix[128]; 935 RTStrPrintf(szPrefix, sizeof(szPrefix), "MixerSink-%s/", pSink->pszName); 936 PDMDevHlpSTAMDeregisterByPrefix(pDevIns, szPrefix); 937 925 938 RTStrFree(pSink->pszName); 926 939 pSink->pszName = NULL; … … 1453 1466 * 1454 1467 * @returns VBox status code. 1455 * @param pSink Sink to set audio format for.1456 * @param pPCMProps 1457 */ 1458 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, P PDMAUDIOPCMPROPS pPCMProps)1468 * @param pSink The sink to set audio format for. 1469 * @param pPCMProps Audio format (PCM properties) to set. 1470 */ 1471 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pPCMProps) 1459 1472 { 1460 1473 AssertPtrReturn(pSink, VERR_INVALID_POINTER); -
trunk/src/VBox/Devices/Audio/AudioMixer.h
r88309 r88320 291 291 void AudioMixerSinkReset(PAUDMIXSINK pSink); 292 292 void AudioMixerSinkGetFormat(PAUDMIXSINK pSink, PPDMAUDIOPCMPROPS pPCMProps); 293 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, P PDMAUDIOPCMPROPS pPCMProps);293 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pPCMProps); 294 294 int AudioMixerSinkSetRecordingSource(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream); 295 295 int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PPDMAUDIOVOLUME pVol);
Note:
See TracChangeset
for help on using the changeset viewer.