Changeset 54980 in vbox
- Timestamp:
- Mar 27, 2015 7:00:47 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioMixBuffer.cpp
r54861 r54980 17 17 */ 18 18 19 /* 20 * DEBUG_DUMP_PCM_DATA enables dumping the raw PCM data 21 * to a file on the host. Be sure to adjust the dumping path 22 * to your needs before using this! 23 */ 24 #ifdef DEBUG 25 //# define DEBUG_DUMP_PCM_DATA 26 #endif 27 19 28 #include <iprt/asm-math.h> 20 29 #include <iprt/assert.h> … … 64 73 #endif 65 74 66 static int audioMixBufInitCommon(PPDMAUDIOMIXBUF pMixBuf, const char *pszName, PPDMPCMPROPS pProps);67 75 static void audioMixBufFreeBuf(PPDMAUDIOMIXBUF pMixBuf); 68 76 static inline void audioMixBufPrint(PPDMAUDIOMIXBUF pMixBuf); … … 232 240 233 241 #ifdef DEBUG_MACROS 234 # define AUDMIXBUF_MACRO_LOG(x) AUDMIXBUF_LOG( (x))242 # define AUDMIXBUF_MACRO_LOG(x) AUDMIXBUF_LOG(x) 235 243 #elif defined(TESTCASE) 236 244 # define AUDMIXBUF_MACRO_LOG(x) RTPrintf x … … 349 357 uint32_t *pcDstWritten, uint32_t *pcSrcRead) \ 350 358 { \ 351 AUDMIXBUF_MACRO_LOG(("pRate=%p: srcOffset=%RU32, dstOffset=%RU64, dstInc=%RU64\n", \ 352 pRate, pRate->srcOffset, pRate->dstOffset, pRate->dstInc)); \ 359 AUDMIXBUF_MACRO_LOG(("cSrcSamples=%RU32, cDstSamples=%RU32\n", cSrcSamples, cDstSamples)); \ 360 AUDMIXBUF_MACRO_LOG(("pRate=%p: srcOffset=0x%x (%RU32), dstOffset=0x%x (%RU32), dstInc=0x%x (%RU64)\n", \ 361 pRate, pRate->srcOffset, pRate->srcOffset, pRate->dstOffset >> 32, pRate->dstOffset >> 32, \ 362 pRate->dstInc, pRate->dstInc)); \ 353 363 \ 354 if (pRate->dstInc == ( 1ULL + UINT32_MAX))\364 if (pRate->dstInc == (UINT64_C(1) + UINT32_MAX)) /* No conversion needed? */ \ 355 365 { \ 356 uint32_t cSamples = cSrcSamples > cDstSamples ? cDstSamples : cSrcSamples; \366 uint32_t cSamples = RT_MIN(cSrcSamples, cDstSamples); \ 357 367 AUDMIXBUF_MACRO_LOG(("cSamples=%RU32\n", cSamples)); \ 358 368 for (uint32_t i = 0; i < cSamples; i++) \ … … 373 383 PPDMAUDIOSAMPLE paDstStart = paDst; \ 374 384 PPDMAUDIOSAMPLE paDstEnd = paDst + cDstSamples; \ 375 PDMAUDIOSAMPLE samCur, samOut; \ 385 PDMAUDIOSAMPLE samCur = { 0 }; \ 386 PDMAUDIOSAMPLE samOut; \ 376 387 PDMAUDIOSAMPLE samLast = pRate->srcSampleLast; \ 377 uint64_t l = 0; \388 uint64_t lDelta; \ 378 389 \ 379 390 AUDMIXBUF_MACRO_LOG(("Start: paDstEnd=%p - paDstStart=%p -> %zu\n", paDstEnd, paDst, paDstEnd - paDstStart)); \ … … 382 393 while (paDst < paDstEnd) \ 383 394 { \ 395 Assert(paSrc <= paSrcEnd); \ 396 Assert(paDst <= paDstEnd); \ 397 if (paSrc == paSrcEnd) \ 398 break; \ 399 \ 400 lDelta = 0; \ 384 401 while (pRate->srcOffset <= (pRate->dstOffset >> 32)) \ 385 402 { \ 403 Assert(paSrc <= paSrcEnd); \ 386 404 samLast = *paSrc++; \ 387 405 pRate->srcOffset++; \ 388 l ++; \389 if (paSrc >= paSrcEnd) \406 lDelta++; \ 407 if (paSrc == paSrcEnd) \ 390 408 break; \ 391 409 } \ 410 \ 411 Assert(paSrc <= paSrcEnd); \ 412 if (paSrc == paSrcEnd) \ 413 break; \ 392 414 \ 393 415 samCur = *paSrc; \ 394 416 \ 395 417 /* Interpolate. */ \ 396 int64_t t = pRate->dstOffset & 0xffffffff; \418 int64_t iDstOffInt = pRate->dstOffset & UINT32_MAX; \ 397 419 \ 398 samOut.u64LSample = (samLast.u64LSample * ((int64_t) UINT32_MAX - t) + samCur.u64LSample *t) >> 32; \399 samOut.u64RSample = (samLast.u64RSample * ((int64_t) UINT32_MAX - t) + samCur.u64RSample *t) >> 32; \420 samOut.u64LSample = (samLast.u64LSample * ((int64_t) UINT32_MAX - iDstOffInt) + samCur.u64LSample * iDstOffInt) >> 32; \ 421 samOut.u64RSample = (samLast.u64RSample * ((int64_t) UINT32_MAX - iDstOffInt) + samCur.u64RSample * iDstOffInt) >> 32; \ 400 422 \ 401 423 paDst->u64LSample _aOp samOut.u64LSample; \ … … 403 425 paDst++; \ 404 426 \ 405 AUDMIXBUF_MACRO_LOG(("\tt=%RI64, l=%RI64, r=%RI64 (cur l=%RI64, r=%RI64)\n", t, \ 427 AUDMIXBUF_MACRO_LOG(("\tlDelta=0x%x (%RU64), iDstOffInt=0x%x (%RI64), l=%RI64, r=%RI64 (cur l=%RI64, r=%RI64)\n", \ 428 lDelta, lDelta, iDstOffInt, iDstOffInt, \ 406 429 paDst->u64LSample, paDst->u64RSample, \ 407 430 samCur.u64LSample, samCur.u64RSample)); \ … … 409 432 pRate->dstOffset += pRate->dstInc; \ 410 433 \ 411 AUDMIXBUF_MACRO_LOG(("\t\tpRate->dstOffset=%RU64\n", pRate->dstOffset)); \ 412 \ 413 if (paSrc >= paSrcEnd) \ 414 break; \ 434 AUDMIXBUF_MACRO_LOG(("\t\tpRate->dstOffset=0x%x (%RU32)\n", pRate->dstOffset, pRate->dstOffset >> 32)); \ 415 435 \ 416 436 } \ … … 421 441 pRate->srcSampleLast = samLast; \ 422 442 \ 423 AUDMIXBUF_MACRO_LOG((" l=%RU64, pRate->srcSampleLast l=%RI64, r=%RI64\n", \424 l, pRate->srcSampleLast.u64LSample, pRate->srcSampleLast.u64RSample)); \443 AUDMIXBUF_MACRO_LOG(("pRate->srcSampleLast l=%RI64, r=%RI64, lDelta=0x%x (%RU64)\n", \ 444 pRate->srcSampleLast.u64LSample, pRate->srcSampleLast.u64RSample, lDelta, lDelta)); \ 425 445 \ 426 446 if (pcDstWritten) \ … … 689 709 pMixBuf->pParent = pParent; 690 710 691 /** @todo Only handles ADC (and not DAC) conversion for now. If you692 * want DAC conversion, link the buffers the other way around. */693 694 711 /* Calculate the frequency ratio. */ 695 pMixBuf->iFreqRatio = 696 ( (int64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt) << 32) 697 / AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt); 712 pMixBuf->iFreqRatio = ((int64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt) << 32) 713 / AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt); 698 714 699 715 if (pMixBuf->iFreqRatio == 0) /* Catch division by zero. */ … … 712 728 pMixBuf->pszName, pMixBuf->cSamples, cSamples)); 713 729 714 pMixBuf->pSamples = (PPDMAUDIOSAMPLE)RTMemRealloc(pMixBuf->pSamples, 715 cSamples * sizeof(PDMAUDIOSAMPLE)); 730 uint32_t cbSamples = cSamples * sizeof(PDMAUDIOSAMPLE); 731 Assert(cbSamples); 732 pMixBuf->pSamples = (PPDMAUDIOSAMPLE)RTMemRealloc(pMixBuf->pSamples, cbSamples); 716 733 if (!pMixBuf->pSamples) 717 734 rc = VERR_NO_MEMORY; 718 735 719 736 if (RT_SUCCESS(rc)) 737 { 720 738 pMixBuf->cSamples = cSamples; 739 740 /* Make sure to zero the reallocated buffer so that it can be 741 * used properly when blending with another buffer later. */ 742 RT_BZERO(pMixBuf->pSamples, cbSamples); 743 } 721 744 } 722 745 … … 733 756 RT_BZERO(pMixBuf->pRate, sizeof(PDMAUDIOSTRMRATE)); 734 757 735 pMixBuf->pRate->dstInc = 736 ( (uint64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt) << 32) 737 / AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt); 738 739 AUDMIXBUF_LOG(("uThisHz=%RU32, uParentHz=%RU32, iFreqRatio=%RI64, uRateInc=%RU64, cSamples=%RU32 (%RU32 parent)\n", 758 pMixBuf->pRate->dstInc = ((uint64_t)AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt) << 32) 759 / AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt); 760 761 AUDMIXBUF_LOG(("uThisHz=%RU32, uParentHz=%RU32, iFreqRatio=0x%x (%RI64), uRateInc=0x%x (%RU64), cSamples=%RU32 (%RU32 parent)\n", 740 762 AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt), 741 763 AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt), 742 pMixBuf->iFreqRatio, 743 pMixBuf->pRate->dstInc, 764 pMixBuf->iFreqRatio, pMixBuf->iFreqRatio, 765 pMixBuf->pRate->dstInc, pMixBuf->pRate->dstInc, 744 766 pMixBuf->cSamples, 745 767 pParent->cSamples)); 768 AUDMIXBUF_LOG(("%s (%RU32Hz) -> %s (%RU32Hz)\n", 769 pMixBuf->pszName, AUDMIXBUF_FMT_SAMPLE_FREQ(pMixBuf->AudioFmt), 770 pMixBuf->pParent->pszName, AUDMIXBUF_FMT_SAMPLE_FREQ(pParent->AudioFmt))); 746 771 } 747 772 … … 800 825 if (!cToWrite) 801 826 { 802 AUDMIXBUF_LOG((" Destination buffer \"%s\" full\n", pDst->pszName));827 AUDMIXBUF_LOG(("Warning: Destination buffer \"%s\" full\n", pDst->pszName)); 803 828 break; 804 829 } … … 807 832 Assert(offRead + cToRead <= pSrc->cSamples); 808 833 834 AUDMIXBUF_LOG(("\t%RU32Hz -> %RU32Hz\n", AUDMIXBUF_FMT_SAMPLE_FREQ(pSrc->AudioFmt), AUDMIXBUF_FMT_SAMPLE_FREQ(pDst->AudioFmt))); 809 835 AUDMIXBUF_LOG(("\tcDead=%RU32, offWrite=%RU32, cToWrite=%RU32, offRead=%RU32, cToRead=%RU32\n", 810 836 cDead, offWrite, cToWrite, offRead, cToRead)); … … 1043 1069 if (RT_SUCCESS(rc)) 1044 1070 { 1071 #ifdef DEBUG_DUMP_PCM_DATA 1072 RTFILE fh; 1073 rc = RTFileOpen(&fh, "c:\\temp\\mixbuf_readcirc.pcm", 1074 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1075 if (RT_SUCCESS(rc)) 1076 { 1077 RTFileWrite(fh, pvBuf, AUDIOMIXBUF_S2B(pMixBuf, cLenSrc1 + cLenSrc2), NULL); 1078 RTFileClose(fh); 1079 } 1080 #endif 1045 1081 pMixBuf->offReadWrite = offRead % pMixBuf->cSamples; 1046 1082 pMixBuf->cProcessed -= RT_MIN(cLenSrc1 + cLenSrc2, pMixBuf->cProcessed); … … 1068 1104 pMixBuf->cProcessed = 0; 1069 1105 1070 RT_BZERO(pMixBuf->pSamples, AUDIOMIXBUF_S2B(pMixBuf, pMixBuf->cSamples)); 1106 if (pMixBuf->cSamples) 1107 RT_BZERO(pMixBuf->pSamples, pMixBuf->cSamples * sizeof(PDMAUDIOSAMPLE)); 1071 1108 } 1072 1109 … … 1120 1157 } 1121 1158 1122 pMixBuf->iFreqRatio = 0;1123 1124 1159 if (pMixBuf->pRate) 1125 1160 { 1126 RTMemFree(pMixBuf->pRate); 1127 pMixBuf->pRate = NULL; 1128 } 1161 pMixBuf->pRate->dstOffset = pMixBuf->pRate->srcOffset = 0; 1162 pMixBuf->pRate->dstInc = 0; 1163 } 1164 1165 pMixBuf->iFreqRatio = 1; /* Prevent division by zero. */ 1129 1166 } 1130 1167 … … 1178 1215 #ifdef DEBUG_DUMP_PCM_DATA 1179 1216 RTFILE fh; 1180 rc = RTFileOpen(&fh, "c:\\temp\\ test_writeat.pcm",1217 rc = RTFileOpen(&fh, "c:\\temp\\mixbuf_writeat.pcm", 1181 1218 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1182 1219 if (RT_SUCCESS(rc)) … … 1296 1333 #ifdef DEBUG_DUMP_PCM_DATA 1297 1334 RTFILE fh; 1298 RTFileOpen(&fh, "c:\\temp\\ test_writeex.pcm",1335 RTFileOpen(&fh, "c:\\temp\\mixbuf_writeex.pcm", 1299 1336 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 1300 1337 RTFileWrite(fh, pSamplesDst1, AUDIOMIXBUF_S2B(pMixBuf, cLenDst1), NULL);
Note:
See TracChangeset
for help on using the changeset viewer.