- Timestamp:
- Nov 4, 2016 12:32:36 PM (8 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioMixer.cpp
r64532 r64566 780 780 # error "Implement me!" 781 781 #else 782 cbReadable = pSink->In.cbReadable; 782 /* Get the time delta and calculate the bytes that need to be processed. 783 * 784 * Example for 16 bit, 44.1KhZ, stereo: 785 * 16 bits per sample x 44.100 samples per second = 705.600 bits per second x 2 channels 786 * = 1.411.200 bits per second of stereo. 787 */ 788 uint64_t tsDeltaMS = RTTimeMilliTS() - pSink->tsLastUpdatedMS; 789 790 cbReadable = (pSink->PCMProps.cbBitrate / 1000 /* s to ms */) * tsDeltaMS; 791 792 Log3Func(("[%s] Bitrate is %RU32 bytes/s -> %RU64ms / %RU32 bytes elapsed\n", 793 pSink->pszName, pSink->PCMProps.cbBitrate, tsDeltaMS, cbReadable)); 783 794 #endif 784 795 … … 810 821 uint32_t cbWritable; 811 822 823 if ( !(pSink->fStatus & AUDMIXSINK_STS_RUNNING) 824 || pSink->fStatus & AUDMIXSINK_STS_PENDING_DISABLE) 825 { 826 cbWritable = 0; 827 } 828 else 829 { 812 830 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF 813 831 # error "Implement me!" 814 832 #else 815 cbWritable = pSink->Out.cbWritable; 833 /* Get the time delta and calculate the bytes that need to be processed. 834 * 835 * Example for 16 bit, 44.1KhZ, stereo: 836 * 16 bits per sample x 44.100 samples per second = 705.600 bits per second x 2 channels 837 * = 1.411.200 bits per second of stereo. 838 */ 839 uint64_t tsDeltaMS = RTTimeMilliTS() - pSink->tsLastUpdatedMS; 840 841 cbWritable = (pSink->PCMProps.cbBitrate / 1000 /* s to ms */) * tsDeltaMS; 842 843 Log3Func(("[%s] Bitrate is %RU32 bytes/s -> %RU64ms / %RU32 bytes elapsed\n", 844 pSink->pszName, pSink->PCMProps.cbBitrate, tsDeltaMS, cbWritable)); 816 845 #endif 846 } 817 847 818 848 Log3Func(("[%s] cbWritable=%RU32\n", pSink->pszName, cbWritable)); … … 896 926 return AUDMIXSINK_STS_NONE; 897 927 898 LogFlowFunc(("[%s]: fStatus=0x%x\n", pSink->pszName, pSink->fStatus));899 900 928 /* If the dirty flag is set, there is unprocessed data in the sink. */ 901 929 AUDMIXSINKSTS stsSink = pSink->fStatus; … … 928 956 929 957 return cStreams; 958 } 959 960 /** 961 * Returns whether the sink is in an active state or not. 962 * Note: The pending disable state also counts as active. 963 * 964 * @returns True if active, false if not. 965 * @param pSink Sink to return active state for. 966 */ 967 bool AudioMixerSinkIsActive(PAUDMIXSINK pSink) 968 { 969 if (!pSink) 970 return false; 971 972 int rc2 = RTCritSectEnter(&pSink->CritSect); 973 if (RT_FAILURE(rc2)) 974 return 0; 975 976 bool fIsActive = (pSink->fStatus & AUDMIXSINK_STS_RUNNING); 977 978 rc2 = RTCritSectLeave(&pSink->CritSect); 979 AssertRC(rc2); 980 981 return fIsActive; 930 982 } 931 983 … … 1184 1236 1185 1237 /** 1238 * Resets a sink. This will immediately stop all processing. 1239 * 1240 * @param pSink Sink to reset. 1241 */ 1242 void AudioMixerSinkReset(PAUDMIXSINK pSink) 1243 { 1244 if (!pSink) 1245 return; 1246 1247 int rc2 = RTCritSectEnter(&pSink->CritSect); 1248 AssertRC(rc2); 1249 1250 audioMixerSinkReset(pSink); 1251 1252 rc2 = RTCritSectLeave(&pSink->CritSect); 1253 AssertRC(rc2); 1254 } 1255 1256 /** 1186 1257 * Sets the audio format of a mixer sink. 1187 1258 * … … 1287 1358 /* Number of detected disabled streams of this sink. */ 1288 1359 uint8_t cStreamsDisabled = 0; 1289 1290 /* Get the time delta and calculate the bytes that need to be processed. */1291 uint64_t tsDeltaMS = RTTimeMilliTS() - pSink->tsLastUpdatedMS;1292 uint32_t cbDelta = (pSink->PCMProps.cbBitrate / 1000 /* s to ms */) * tsDeltaMS;1293 1294 Log3Func(("[%s] Bitrate is %RU32 bytes/s -> %RU64ms / %RU32 bytes elapsed\n",1295 pSink->pszName, pSink->PCMProps.cbBitrate, tsDeltaMS, cbDelta));1296 1297 if (pSink->enmDir == AUDMIXSINKDIR_INPUT)1298 {1299 pSink->In.cbReadable = cbDelta;1300 }1301 else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT)1302 {1303 pSink->Out.cbWritable = cbDelta;1304 }1305 1306 uint8_t uCurLUN = 0;1307 1360 1308 1361 PAUDMIXSTREAM pMixStream, pMixStreamNext; … … 1325 1378 if (RT_FAILURE(rc2)) 1326 1379 { 1327 LogF lowFunc(("%s: Failed capturing stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2));1380 LogFunc(("%s: Failed capturing stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2)); 1328 1381 if (RT_SUCCESS(rc)) 1329 1382 rc = rc2; … … 1339 1392 if (RT_FAILURE(rc2)) 1340 1393 { 1341 LogF lowFunc(("%s: Failed playing stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2));1394 LogFunc(("%s: Failed playing stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2)); 1342 1395 if (RT_SUCCESS(rc)) 1343 1396 rc = rc2; … … 1354 1407 if (RT_FAILURE(rc2)) 1355 1408 { 1356 LogF lowFunc(("%s: Failed re-iterating stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2));1409 LogFunc(("%s: Failed re-iterating stream '%s', rc=%Rrc\n", pSink->pszName, pStream->szName, rc2)); 1357 1410 if (RT_SUCCESS(rc)) 1358 1411 rc = rc2; … … 1368 1421 cStreamsDisabled++; 1369 1422 } 1370 1371 if (pSink->enmDir == AUDMIXSINKDIR_INPUT)1372 {1373 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF1374 # error "Implement me!"1375 #else1376 if (uCurLUN == 0)1377 {1378 pSink->In.cbReadable = pConn->pfnStreamGetReadable(pConn, pStream);1379 Log3Func(("\t%s: cbReadable=%RU32\n", pStream->szName, pSink->In.cbReadable));1380 uCurLUN++;1381 }1382 #endif1383 }1384 else if (pSink->enmDir == AUDMIXSINKDIR_OUTPUT)1385 {1386 #ifdef VBOX_AUDIO_MIXER_WITH_MIXBUF1387 # error "Implement me!"1388 #else1389 if (uCurLUN == 0)1390 {1391 pSink->Out.cbWritable = pConn->pfnStreamGetWritable(pConn, pStream);1392 Log3Func(("\t%s: cbWritable=%RU32\n", pStream->szName, pSink->Out.cbWritable));1393 uCurLUN++;1394 }1395 #endif1396 }1397 1423 } 1398 1424 1399 Log3Func(("\t%s: cP roc=%RU32, rc2=%Rrc\n", pStream->szName, cProc, rc2));1425 Log3Func(("\t%s: cPlayed/cCaptured=%RU32, rc2=%Rrc\n", pStream->szName, cProc, rc2)); 1400 1426 } 1401 1427 … … 1432 1458 if (RT_FAILURE(rc)) 1433 1459 return rc; 1434 1435 /*1436 * Note: Hz elapsed = cTicksElapsed / cTimerTicks1437 * Bytes / second = Sample rate (Hz) * Audio channels * Bytes per sample1438 */1439 // uint32_t cSamples = (int)((pSink->PCMProps.cChannels * cTicksElapsed * pSink->PCMProps.uHz + cTimerTicks) / cTimerTicks / pSink->PCMProps.cChannels);1440 1441 // LogFlowFunc(("[%s]: cTimerTicks=%RU64, cTicksElapsed=%RU64\n", pSink->pszName, cTimerTicks, cTicksElapsed));1442 // LogFlowFunc(("\t%zuHz elapsed, %RU32 samples (%RU32 bytes)\n", cTicksElapsed / cTimerTicks, cSamples, cSamples << 1));1443 1460 1444 1461 rc = audioMixerSinkUpdateInternal(pSink); … … 1518 1535 return rc; 1519 1536 1520 AssertMsg(pSink-> enmDir == AUDMIXSINKDIR_OUTPUT,1521 1537 AssertMsg(pSink->fStatus & AUDMIXSINK_STS_RUNNING, ("Can't write to a sink which is not running (anymore)\n")); 1538 AssertMsg(pSink->enmDir == AUDMIXSINKDIR_OUTPUT, ("Can't write to a sink which is not an output sink\n")); 1522 1539 1523 1540 Log3Func(("[%s] enmOp=%d, cbBuf=%RU32\n", pSink->pszName, enmOp, cbBuf)); 1524 1541 1525 uint32_t cb Processed;1542 uint32_t cbWritten = 0; 1526 1543 1527 1544 PAUDMIXSTREAM pMixStream; … … 1530 1547 if (!(pMixStream->pConn->pfnStreamGetStatus(pMixStream->pConn, pMixStream->pStream) & PDMAUDIOSTRMSTS_FLAG_ENABLED)) 1531 1548 { 1532 Log3Func(("\t%s: Stream '%s' disabled, skipping ...\n", pMixStream->pszName, pMixStream->p Stream->szName));1549 Log3Func(("\t%s: Stream '%s' disabled, skipping ...\n", pMixStream->pszName, pMixStream->pszName)); 1533 1550 continue; 1534 1551 } 1535 1552 1553 uint32_t cbProcessed = 0; 1536 1554 int rc2 = pMixStream->pConn->pfnStreamWrite(pMixStream->pConn, pMixStream->pStream, pvBuf, cbBuf, &cbProcessed); 1537 1555 if (RT_FAILURE(rc2)) 1538 LogF lowFunc(("[%s] Failed writing to stream '%s': %Rrc\n", pSink->pszName, pMixStream->pStream->szName, rc2));1556 LogFunc(("[%s] Failed writing to stream '%s': %Rrc\n", pSink->pszName, pMixStream->pszName, rc2)); 1539 1557 1540 1558 if (cbProcessed < cbBuf) 1559 LogFunc(("[%s] Only written %RU32/%RU32 bytes for stream '%s', rc=%Rrc\n", 1560 pSink->pszName, cbProcessed, cbBuf, pMixStream->pszName, rc2)); 1561 1562 if (cbProcessed) 1541 1563 { 1542 Log3Func(("[%s] Only written %RU32/%RU32 bytes for stream '%s'\n",1543 pSink->pszName, cbProcessed, cbBuf, pMixStream->pStream->szName));1564 /* Set dirty bit. */ 1565 pSink->fStatus |= AUDMIXSINK_STS_DIRTY; 1544 1566 } 1545 } 1546 1547 if (cbBuf) 1548 { 1549 /* Set dirty bit. */ 1550 pSink->fStatus |= AUDMIXSINK_STS_DIRTY; 1567 1568 Log3Func(("\t%s: cbProcessed=%RU32\n", pMixStream->pszName, cbBuf, cbProcessed)); 1569 1570 /* 1571 * Return the maximum bytes processed by all connected streams. 1572 * Streams which have processed less than the current maximum have to deal with 1573 * this themselves. 1574 */ 1575 cbWritten = RT_MAX(cbWritten, cbProcessed); 1551 1576 } 1552 1577 1553 1578 if (pcbWritten) 1554 *pcbWritten = cb Buf; /* Always report back a complete write for now. */1579 *pcbWritten = cbWritten; 1555 1580 1556 1581 int rc2 = RTCritSectLeave(&pSink->CritSect); -
trunk/src/VBox/Devices/Audio/AudioMixer.h
r63615 r64566 232 232 AUDMIXSINKSTS AudioMixerSinkGetStatus(PAUDMIXSINK pSink); 233 233 uint8_t AudioMixerSinkGetStreamCount(PAUDMIXSINK pSink); 234 bool AudioMixerSinkIsActive(PAUDMIXSINK pSink); 234 235 int AudioMixerSinkRead(PAUDMIXSINK pSink, AUDMIXOP enmOp, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead); 235 236 void AudioMixerSinkRemoveStream(PAUDMIXSINK pSink, PAUDMIXSTREAM pStream); 236 237 void AudioMixerSinkRemoveAllStreams(PAUDMIXSINK pSink); 238 void AudioMixerSinkReset(PAUDMIXSINK pSink); 237 239 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PPDMAUDIOPCMPROPS pPCMProps); 238 240 int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PPDMAUDIOVOLUME pVol);
Note:
See TracChangeset
for help on using the changeset viewer.