Changeset 61668 in vbox
- Timestamp:
- Jun 13, 2016 7:35:56 AM (9 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioMixer.cpp
r61609 r61668 427 427 else if (pMixStream) 428 428 { 429 RTStrFree(pMixStream->pszName); 430 pMixStream->pszName = NULL; 429 if (pMixStream->pszName) 430 { 431 RTStrFree(pMixStream->pszName); 432 pMixStream->pszName = NULL; 433 } 431 434 432 435 RTMemFree(pMixStream); … … 471 474 } 472 475 473 /* Remove dirty bit in any case. */474 pSink->fStatus &= ~AUDMIXSINK_STS_DIRTY;475 476 476 if (enmSinkCmd == AUDMIXSINKCMD_ENABLE) 477 { 477 478 pSink->fStatus |= AUDMIXSINK_STS_RUNNING; 479 } 478 480 else if (enmSinkCmd == AUDMIXSINKCMD_DISABLE) 479 pSink->fStatus &= ~AUDMIXSINK_STS_RUNNING; 481 { 482 /* Set the sink in a pending disable state first. 483 * The final status (disabled) will be set in the sink's iteration. */ 484 pSink->fStatus |= AUDMIXSINK_STS_PENDING_DISABLE; 485 } 480 486 481 487 /* Not running anymore? Reset. */ … … 794 800 #endif 795 801 } 802 803 /* Reset status. */ 804 pSink->fStatus = AUDMIXSINK_STS_NONE; 796 805 } 797 806 … … 874 883 int rc = VINF_SUCCESS; 875 884 876 Log3Func(("[%s]\n", pSink->pszName)); 885 Log3Func(("[%s] fStatus=0x%x\n", pSink->pszName, pSink->fStatus)); 886 887 /* Sink disabled? Take a shortcut. */ 888 if (!(pSink->fStatus & AUDMIXSINK_STS_RUNNING)) 889 return rc; 890 891 /* Number of detected disabled streams of this sink. */ 892 uint8_t cStreamsDisabled = 0; 877 893 878 894 /* Update last updated timestamp. */ 879 895 pSink->tsLastUpdatedNS = RTTimeNanoTS(); 880 896 881 PAUDMIXSTREAM pMixStream ;882 RTListForEach (&pSink->lstStreams, pMixStream, AUDMIXSTREAM, Node)897 PAUDMIXSTREAM pMixStream, pMixStreamNext; 898 RTListForEachSafe(&pSink->lstStreams, pMixStream, pMixStreamNext, AUDMIXSTREAM, Node) 883 899 { 884 900 PPDMAUDIOSTREAM pStream = pMixStream->pStream; … … 934 950 } 935 951 952 PDMAUDIOSTRMSTS strmSts = pConn->pfnStreamGetStatus(pConn, pMixStream->pStream); 953 954 /* Is the stream not enabled and also is not in a pending disable state anymore? */ 955 if ( !(strmSts & PDMAUDIOSTRMSTS_FLAG_ENABLED) 956 && !(strmSts & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE)) 957 { 958 cStreamsDisabled++; 959 } 960 936 961 if (pSink->enmDir == AUDMIXSINKDIR_INPUT) 937 962 { … … 955 980 } 956 981 982 /* All streams disabled and the sink is in pending disable mode? */ 983 if ( cStreamsDisabled == pSink->cStreams 984 && (pSink->fStatus & AUDMIXSINK_STS_PENDING_DISABLE)) 985 { 986 audioMixerSinkReset(pSink); 987 } 988 957 989 if (RT_FAILURE(rc)) 958 990 LogFlowFunc(("Failed with rc=%Rrc\n", rc)); … … 1073 1105 /** @todo Validate fCtl. */ 1074 1106 1075 int rc = pMixStream->pConn->pfnStreamControl(pMixStream->pConn, pMixStream->pStream, enmCmd);1076 1077 return rc;1107 LogFlowFunc(("[%s] enmCmd=%ld\n", pMixStream->pszName, enmCmd)); 1108 1109 return pMixStream->pConn->pfnStreamControl(pMixStream->pConn, pMixStream->pStream, enmCmd); 1078 1110 } 1079 1111 -
trunk/src/VBox/Devices/Audio/AudioMixer.h
r61609 r61668 75 75 /** The sink is active and running. */ 76 76 #define AUDMIXSINK_STS_RUNNING RT_BIT(0) 77 /** The sink is in a pending disable state. */ 78 #define AUDMIXSINK_STS_PENDING_DISABLE RT_BIT(1) 77 79 /** Dirty flag. 78 80 * For output sinks this means that there is data in the … … 81 83 * sink which has been recorded but not transferred to the 82 84 * destination yet. */ 83 #define AUDMIXSINK_STS_DIRTY RT_BIT( 1)85 #define AUDMIXSINK_STS_DIRTY RT_BIT(2) 84 86 85 87 /** -
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r61613 r61668 60 60 #endif /* DEBUG_andy */ 61 61 62 #define AC97_SSM_VERSION 1 63 64 #define AC97_TIMER_HZ 50 62 /** Current saved state version. */ 63 #define AC97_SSM_VERSION 1 64 65 /** Timer frequency (in Hz) */ 66 #define AC97_TIMER_HZ 200 65 67 66 68 /** @todo Use AC97_ prefixes! */ … … 536 538 bool fActive = RT_BOOL(AudioMixerSinkGetStatus(pSink) & AUDMIXSINK_STS_RUNNING); 537 539 538 LogFlowFunc((" SD=%RU8,fActive=%RTbool\n", pStream->u8Strm, fActive));540 LogFlowFunc(("[SD%RU8] fActive=%RTbool\n", pStream->u8Strm, fActive)); 539 541 return fActive; 540 542 } … … 565 567 fActive ? AUDMIXSINKCMD_ENABLE : AUDMIXSINKCMD_DISABLE); 566 568 567 LogFlowFunc((" SD=%RU8,fActive=%RTbool, cStreamsActive=%RU8, rc=%Rrc\n",569 LogFlowFunc(("[SD%RU8] fActive=%RTbool, cStreamsActive=%RU8, rc=%Rrc\n", 568 570 pStream->u8Strm, fActive, pThis->cStreamsActive, rc)); 569 571 … … 576 578 AssertPtrReturnVoid(pStream); 577 579 578 LogFlowFunc Enter();580 LogFlowFunc(("[SD%RU8]\n", pStream->u8Strm)); 579 581 580 582 PAC97BMREGS pRegs = &pStream->Regs; … … 598 600 static void ichac97StreamDestroy(PAC97STREAM pStream) 599 601 { 600 LogFlowFunc((" SD=%RU8\n", pStream->u8Strm));602 LogFlowFunc(("[SD%RU8]\n", pStream->u8Strm)); 601 603 602 604 if (pStream->State.au8FIFOW) … … 926 928 } 927 929 928 LogFlowFunc((" SD=%RU8,rc=%Rrc\n", u8Strm, rc));930 LogFlowFunc(("[SD%RU8] rc=%Rrc\n", u8Strm, rc)); 929 931 return rc; 930 932 } … … 940 942 AssertPtrReturnVoid(pStrm); 941 943 942 LogFlowFunc((" SD=%RU8\n", pStrm->u8Strm));944 LogFlowFunc(("[SD%RU8]\n", pStrm->u8Strm)); 943 945 944 946 if (pStrm->State.au8FIFOW) … … 1153 1155 PAC97BMREGS pRegs = &pStream->Regs; 1154 1156 1155 uint32_t addr = pRegs->bd.addr; 1157 uint32_t uAddr = pRegs->bd.addr; 1158 1156 1159 uint32_t cbWrittenTotal = 0; 1157 1160 1158 Log3Func(("PICB=%RU16, cb Max=%RU32\n", pRegs->picb, cbToWrite));1159 1160 cbToWrite= RT_MIN((uint32_t)(pRegs->picb << 1), cbToWrite); /** @todo r=andy Assumes 16bit sample size. */1161 if (!cb ToWrite)1161 Log3Func(("PICB=%RU16, cbToWrite=%RU32\n", pRegs->picb, cbToWrite)); 1162 1163 uint32_t cbLeft = RT_MIN((uint32_t)(pRegs->picb << 1), cbToWrite); /** @todo r=andy Assumes 16bit sample size. */ 1164 if (!cbLeft) 1162 1165 { 1163 1166 if (pcbWritten) … … 1168 1171 int rc = VINF_SUCCESS; 1169 1172 1170 LogFlowFunc(("pRegs=%p, cbMax=%RU32, cbToWrite=%RU32\n", pRegs, cbToWrite, cbToWrite));1171 1172 1173 Assert(pStream->State.offFIFOW <= pStream->State.cbFIFOW); 1173 1174 uint32_t cbFIFOW = pStream->State.cbFIFOW - pStream->State.offFIFOW; 1174 1175 uint8_t *pu8FIFOW = &pStream->State.au8FIFOW[pStream->State.offFIFOW]; 1175 1176 1176 uint32_t cbToRead; 1177 while (cbToWrite) 1178 { 1179 cbToRead = RT_MIN(cbToWrite, cbFIFOW); 1180 PDMDevHlpPhysRead(pDevIns, addr, pu8FIFOW, cbToRead); /** @todo r=andy Check rc? */ 1177 uint32_t cbWritten = 0; 1178 1179 while (cbLeft) 1180 { 1181 uint32_t cbToRead = RT_MIN(cbLeft, cbFIFOW); 1182 1183 PDMDevHlpPhysRead(pDevIns, uAddr, pu8FIFOW, cbToRead); /** @todo r=andy Check rc? */ 1181 1184 1182 1185 #ifdef AC97_DEBUG_DUMP_PCM_DATA … … 1190 1193 * Write data to the mixer sink. 1191 1194 */ 1192 uint32_t cbWritten;1193 1195 rc = AudioMixerSinkWrite(pThis->pSinkOutput, AUDMIXOP_COPY, pu8FIFOW, cbToRead, &cbWritten); 1194 1195 LogFlowFunc(("\tcbToRead=%RU32, cbToWrite=%RU32, cbWritten=%RU32, cbLeft=%RU32, rc=%Rrc\n",1196 cbToRead, cbToWrite, cbWritten, cbToWrite - cbWrittenTotal, rc));1197 1198 1196 if (RT_FAILURE(rc)) 1199 1197 break; 1200 1198 1201 1199 /* Advance. */ 1202 Assert(cbToWrite >= cbToRead); 1203 cbToWrite -= cbToRead; 1204 addr += cbToRead; 1205 cbWrittenTotal += cbToRead; 1200 Assert(cbLeft >= cbWritten); 1201 cbLeft -= cbWritten; 1202 cbWrittenTotal += cbWritten; 1203 uAddr += cbWritten; 1204 Assert(cbWrittenTotal <= cbToWrite); 1205 1206 LogFlowFunc(("%RU32 / %RU32\n", cbWrittenTotal, cbToWrite)); 1206 1207 } 1207 1208 1208 1209 /* Set new buffer descriptor address. */ 1209 pRegs->bd.addr = addr;1210 pRegs->bd.addr = uAddr; 1210 1211 1211 1212 if (RT_SUCCESS(rc)) 1212 1213 { 1213 if (!cb ToWrite) /* All data written? */1214 { 1215 if (cb ToRead< 4)1214 if (!cbLeft) /* All data written? */ 1215 { 1216 if (cbWritten < 4) 1216 1217 { 1217 AssertMsgFailed(("Unable to save last written sample, cb ToRead < 4 (is %RU32)\n", cbToRead));1218 AssertMsgFailed(("Unable to save last written sample, cbWritten < 4 (is %RU32)\n", cbWritten)); 1218 1219 pThis->last_samp = 0; 1219 1220 } 1220 1221 else 1221 pThis->last_samp = *(uint32_t *)&pStream->State.au8FIFOW[pStream->State.offFIFOW + cb ToRead- 4];1222 pThis->last_samp = *(uint32_t *)&pStream->State.au8FIFOW[pStream->State.offFIFOW + cbWritten - 4]; 1222 1223 } 1223 1224 … … 1226 1227 } 1227 1228 1228 LogFlowFunc(("cbWrittenTotal=%RU32, rc=%Rrc\n", cbWrittenTotal, rc)); 1229 if (RT_FAILURE(rc)) 1230 LogFlowFunc(("Failed with %Rrc\n", rc)); 1231 1229 1232 return rc; 1230 1233 } … … 1328 1331 return; 1329 1332 1333 if (ASMAtomicReadBool(&pThis->fTimerActive) == true) /* Alredy started? */ 1334 return; 1335 1330 1336 LogFlowFunc(("Starting timer\n")); 1331 1337 … … 1346 1352 1347 1353 if (!pThis->pTimer) 1354 return; 1355 1356 if (ASMAtomicReadBool(&pThis->fTimerActive) == false) /* Already stopped? */ 1348 1357 return; 1349 1358 … … 1382 1391 cbToProcess = AudioMixerSinkGetReadable(pThis->pSinkLineIn); 1383 1392 if (cbToProcess) 1384 {1385 1393 rc = ichac97TransferAudio(pThis, &pThis->StreamLineIn, cbToProcess, NULL /* pcbProcessed */); 1386 fKickTimer |= RT_SUCCESS(rc); 1387 }1394 1395 fKickTimer |= AudioMixerSinkGetStatus(pThis->pSinkLineIn) & AUDMIXSINK_STS_DIRTY; 1388 1396 } 1389 1397 … … 1393 1401 cbToProcess = AudioMixerSinkGetReadable(pThis->pSinkMicIn); 1394 1402 if (cbToProcess) 1395 {1396 1403 rc = ichac97TransferAudio(pThis, &pThis->StreamMicIn, cbToProcess, NULL /* pcbProcessed */); 1397 fKickTimer |= RT_SUCCESS(rc); 1398 }1404 1405 fKickTimer |= AudioMixerSinkGetStatus(pThis->pSinkMicIn) & AUDMIXSINK_STS_DIRTY; 1399 1406 } 1400 1407 … … 1404 1411 cbToProcess = AudioMixerSinkGetWritable(pThis->pSinkOutput); 1405 1412 if (cbToProcess) 1406 {1407 1413 rc = ichac97TransferAudio(pThis, &pThis->StreamOut, cbToProcess, NULL /* pcbProcessed */); 1408 fKickTimer |= RT_SUCCESS(rc); 1409 }1414 1415 fKickTimer |= AudioMixerSinkGetStatus(pThis->pSinkOutput) & AUDMIXSINK_STS_DIRTY; 1410 1416 } 1411 1417 … … 1430 1436 /* pcbProcessed is optional. */ 1431 1437 1432 Log3Func((" SD=%RU8\n", pStream->u8Strm));1438 Log3Func(("[SD%RU8] cbToProcess=%RU32\n", pStream->u8Strm, cbToProcess)); 1433 1439 1434 1440 PAC97BMREGS pRegs = &pStream->Regs; … … 1457 1463 if (pRegs->sr & SR_BCIS) 1458 1464 { 1465 Log3Func(("[SD%RU8] BCIS set\n", pStream->u8Strm)); 1459 1466 if (pcbProcessed) 1460 1467 *pcbProcessed = 0; … … 1464 1471 int rc = VINF_SUCCESS; 1465 1472 1466 uint32_t cbLeft = cbToProcess;1473 uint32_t cbLeft = RT_MIN((uint32_t)(pRegs->picb << 1), cbToProcess); 1467 1474 uint32_t cbTotal = 0; 1475 1476 Log3Func(("[SD%RU8] cbLeft=%RU32\n", pStream->u8Strm, cbLeft)); 1468 1477 1469 1478 while (cbLeft) … … 1501 1510 case PO_INDEX: 1502 1511 { 1503 cbToTransfer = (uint32_t)(pRegs->picb << 1);1512 cbToTransfer = RT_MIN((uint32_t)(pRegs->picb << 1), cbLeft); /** @todo r=andy Assumes 16bit samples. */ 1504 1513 1505 1514 rc = ichac97WriteAudio(pThis, pStream, cbToTransfer, &cbTransferred); … … 1519 1528 case MC_INDEX: 1520 1529 { 1521 cbToTransfer = (uint32_t)(pRegs->picb << 1);1530 cbToTransfer = RT_MIN((uint32_t)(pRegs->picb << 1), cbLeft); /** @todo r=andy Assumes 16bit samples. */ 1522 1531 1523 1532 rc = ichac97ReadAudio(pThis, pStream, cbToTransfer, &cbTransferred); -
trunk/src/VBox/Devices/Audio/DevIchHda.cpp
r61609 r61668 4132 4132 { 4133 4133 rc = hdaTransfer(pThis, pStreamLineIn, cbToProcess, NULL /* pcbProcessed */); 4134 fKickTimer = RT_SUCCESS(rc);4134 fKickTimer |= RT_SUCCESS(rc); 4135 4135 } 4136 4136 } … … 4144 4144 { 4145 4145 rc = hdaTransfer(pThis, pStreamMicIn, cbToProcess, NULL /* pcbProcessed */); 4146 fKickTimer = RT_SUCCESS(rc);4146 fKickTimer |= RT_SUCCESS(rc); 4147 4147 } 4148 4148 } … … 4176 4176 { 4177 4177 rc = hdaTransfer(pThis, pStreamFront, cbToProcess, NULL /* pcbProcessed */); 4178 fKickTimer = RT_SUCCESS(rc);4178 fKickTimer |= RT_SUCCESS(rc); 4179 4179 } 4180 4180 } … … 4264 4264 return rc; 4265 4265 4266 Log3Func(("[SD%RU8] fActive=%RTbool \n", pStream->u8SD, pStream->State.fActive));4266 Log3Func(("[SD%RU8] fActive=%RTbool, cbToProcess=%RU32\n", pStream->u8SD, pStream->State.fActive, cbToProcess)); 4267 4267 4268 4268 /* Stop request received? */ -
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r61615 r61668 583 583 int rc; 584 584 585 /* Whether to try closing a pending to close stream. */ 586 bool fTryClosePending = false; 587 585 588 do 586 589 { … … 609 612 } 610 613 } 614 else 615 { 616 fTryClosePending = true; 617 } 611 618 } 612 619 else if (pHstStream->enmDir == PDMAUDIODIR_OUT) … … 630 637 LogFlowFunc(("[%s] %RU32 live samples\n", pHstStream->szName, cSamplesLive)); 631 638 632 if (!cSamplesLive) /* No live samples at the moment? */ 633 { 634 /* Has the host stream marked as disabled but there still were guest streams relying 635 * on it? Check if the stream now can be closed and do so, if possible. */ 636 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE) 637 { 638 LogFunc(("[%s] Closing pending stream\n", pHstStream->szName)); 639 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 640 if (RT_SUCCESS(rc)) 641 { 642 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE; 643 } 644 else 645 LogFunc(("%s: Backend vetoed against closing output stream, rc=%Rrc\n", pHstStream->szName, rc)); 646 } 647 648 break; 639 if (!cSamplesLive) /* No live samples (anymore)? */ 640 { 641 fTryClosePending = true; 649 642 } 650 643 } 651 644 else 652 645 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED); 646 647 if (fTryClosePending) 648 { 649 /* Has the host stream marked as disabled but there still were guest streams relying 650 * on it? Check if the stream now can be closed and do so, if possible. */ 651 if (pHstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE) 652 { 653 LogFunc(("[%s] Closing pending stream\n", pHstStream->szName)); 654 rc = drvAudioStreamControlInternalBackend(pThis, pHstStream, PDMAUDIOSTREAMCMD_DISABLE); 655 if (RT_SUCCESS(rc)) 656 { 657 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_PENDING_DISABLE; 658 } 659 else 660 LogFunc(("%s: Backend vetoed against closing output stream, rc=%Rrc\n", pHstStream->szName, rc)); 661 } 662 } 653 663 654 664 } while (0); … … 1385 1395 } 1386 1396 1387 uint32_t c bReadable = 0;1397 uint32_t cReadable = 0; 1388 1398 1389 1399 PPDMAUDIOSTREAM pGstStream = pHstStream->pPair; 1390 1400 if (pGstStream) 1391 c bReadable = AudioMixBufLive(&pGstStream->MixBuf);1392 1393 LogFlowFunc(("[%s] cbReadable=%RU32\n", pHstStream->szName, c bReadable));1401 cReadable = AudioMixBufLive(&pGstStream->MixBuf); 1402 1403 LogFlowFunc(("[%s] cbReadable=%RU32\n", pHstStream->szName, cReadable)); 1394 1404 1395 1405 rc2 = RTCritSectLeave(&pThis->CritSect); 1396 1406 AssertRC(rc2); 1397 1407 1398 return cbReadable; 1408 /* Return bytes instead of audio samples. */ 1409 return AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cReadable); 1399 1410 } 1400 1411 … … 1422 1433 PPDMAUDIOSTREAM pGstStream = pHstStream->pPair; 1423 1434 1424 uint32_t c bWritable = 0;1435 uint32_t cWritable = 0; 1425 1436 1426 1437 if (AudioMixBufLive(&pHstStream->MixBuf) == 0) 1427 c bWritable = AudioMixBufFreeBytes(&pGstStream->MixBuf);1428 1429 LogFlowFunc(("[%s] cWritable=%RU32\n", pHstStream->szName, c bWritable));1438 cWritable = AudioMixBufFreeBytes(&pGstStream->MixBuf); 1439 1440 LogFlowFunc(("[%s] cWritable=%RU32\n", pHstStream->szName, cWritable)); 1430 1441 1431 1442 rc2 = RTCritSectLeave(&pThis->CritSect); 1432 1443 AssertRC(rc2); 1433 1444 1434 return cbWritable; 1445 /* Return bytes instead of audio samples. */ 1446 return AUDIOMIXBUF_S2B(&pGstStream->MixBuf, cWritable); 1435 1447 } 1436 1448
Note:
See TracChangeset
for help on using the changeset viewer.