Changeset 65565 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Feb 1, 2017 2:11:10 PM (8 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r65100 r65565 633 633 /* No sample buffer size hint given by the backend? Default to some sane value. */ 634 634 if (!CfgHostAcq.cSampleBufferSize) 635 { 635 636 CfgHostAcq.cSampleBufferSize = _1K; /** @todo Make this configurable? */ 637 } 636 638 637 639 PDMAUDIOPCMPROPS PCMProps; … … 642 644 AudioMixBufDestroy(&pHstStream->MixBuf); 643 645 644 LogFlowFunc(("[%s] cSamples=%RU32\n", pHstStream->szName, CfgHostAcq.cSampleBufferSize * 4)); 645 646 rc2 = AudioMixBufInit(&pHstStream->MixBuf, pHstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize * 10); 646 CfgHostAcq.cSampleBufferSize *= 10; /** @todo Make this configurable. */ 647 648 LogFlowFunc(("[%s] cSamples=%RU32\n", pHstStream->szName, CfgHostAcq.cSampleBufferSize)); 649 650 rc2 = AudioMixBufInit(&pHstStream->MixBuf, pHstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize); 647 651 AssertRC(rc2); 648 652 … … 661 665 AudioMixBufDestroy(&pGstStream->MixBuf); 662 666 663 LogFlowFunc(("[%s] cSamples=%RU32\n", pGstStream->szName, CfgHostAcq.cSampleBufferSize * 2)); 664 665 rc2 = AudioMixBufInit(&pGstStream->MixBuf, pGstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize * 20); 667 CfgHostAcq.cSampleBufferSize *= 20; /** @todo Make this configurable. */ 668 669 LogFlowFunc(("[%s] cSamples=%RU32\n", pGstStream->szName, CfgHostAcq.cSampleBufferSize)); 670 671 rc2 = AudioMixBufInit(&pGstStream->MixBuf, pGstStream->szName, &PCMProps, CfgHostAcq.cSampleBufferSize); 666 672 AssertRC(rc2); 667 673 … … 852 858 #endif 853 859 860 #ifdef LOG_ENABLED 861 char *pszGstSts = NULL; 862 char *pszHstSts = NULL; 863 #endif 864 854 865 do 855 866 { … … 869 880 } 870 881 882 #ifdef LOG_ENABLED 883 pszHstSts = dbgAudioStreamStatusToStr(pHstStream->fStatus); 884 AssertPtr(pszHstSts); 885 #endif 871 886 PPDMAUDIOSTREAM pGstStream = pHstStream->pPair; 872 887 AssertPtr(pGstStream); 873 888 874 889 #ifdef LOG_ENABLED 875 char *pszGstSts = dbgAudioStreamStatusToStr(pGstStream->fStatus); 890 pszGstSts = dbgAudioStreamStatusToStr(pGstStream->fStatus); 891 AssertPtr(pszGstSts); 892 #endif 893 894 #ifdef LOG_ENABLED 876 895 AssertMsg(pGstStream->fStatus & PDMAUDIOSTRMSTS_FLAG_ENABLED, 877 ("Writing to disabled guest output stream \"%s\" not possible (status is %s)\n", 878 pGstStream->szName, pszGstSts)); 879 RTStrFree(pszGstSts); 896 ("Writing to disabled guest output stream \"%s\" not possible (status is %s, host status %s)\n", 897 pGstStream->szName, pszGstSts, pszHstSts)); 880 898 #endif 881 899 pGstStream->Out.tsLastWriteMS = RTTimeMilliTS(); … … 884 902 { 885 903 LogRel2(("Audio: Guest stream '%s' full, expect stuttering audio output\n", pGstStream->szName)); 904 886 905 #ifdef DEBUG_andy 887 AssertMsgFailed(("%s: Guest stream full: cbBuf=%RU32\n", pGstStream->szName, cbBuf)); 906 AssertMsgFailed(("[%s] Failed because guest stream full (guest status %s, host status %s): cbBuf=%RU32\n", 907 pGstStream->szName, pszGstSts, pszHstSts, cbBuf)); 888 908 #endif 889 909 break; … … 903 923 || !csWritten) 904 924 { 905 AssertMsgFailed((" %s: Write failed: cbBuf=%RU32, csWritten=%RU32, rc=%Rrc\n",906 pGstStream->szName, cbBuf, csWritten, rc));925 AssertMsgFailed(("[%s] Write failed (guest status %s, host status %s): cbBuf=%RU32, csWritten=%RU32, rc=%Rrc\n", 926 pGstStream->szName, pszGstSts, pszHstSts, cbBuf, csWritten, rc)); 907 927 } 908 928 #endif … … 925 945 || csMixed < csWritten) 926 946 { 927 AssertMsgFailed((" %s: Mixing failed: cbBuf=%RU32, csWritten=%RU32, csMixed=%RU32, rc=%Rrc\n",928 pGstStream->szName, cbBuf, csWritten, csMixed, rc2));947 AssertMsgFailed(("[%s] Mixing failed (guest status %s, host status %s): cbBuf=%RU32, csWritten=%RU32, csMixed=%RU32, rc=%Rrc\n", 948 pGstStream->szName, pszGstSts, pszHstSts, cbBuf, csWritten, csMixed, rc2)); 929 949 } 930 950 #endif … … 948 968 949 969 } while (0); 970 971 #ifdef LOG_ENABLED 972 RTStrFree(pszHstSts); 973 RTStrFree(pszGstSts); 974 #endif 950 975 951 976 int rc2 = RTCritSectLeave(&pThis->CritSect); … … 1102 1127 else 1103 1128 LogRel2(("Audio: Mixing to guest input stream '%s' failed: %Rrc\n", pGstStream->szName, rc)); 1104 #ifdef DEBUG_andy 1129 #ifdef DEBUG_andy_disabled 1105 1130 AssertFailed(); 1106 1131 #endif … … 1225 1250 1226 1251 AssertReleaseMsgBreakStmt(pHstStream != NULL, 1227 (" %s:Host stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",1252 ("[%s] Host stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n", 1228 1253 pStream->szName, pStream->cRefs, pStream->fStatus, pStream->enmCtx), 1229 1254 rc = VERR_NOT_AVAILABLE); 1230 1255 AssertReleaseMsgBreakStmt(pGstStream != NULL, 1231 (" %s:Guest stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",1256 ("[%s] Guest stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n", 1232 1257 pStream->szName, pStream->cRefs, pStream->fStatus, pStream->enmCtx), 1233 1258 rc = VERR_NOT_AVAILABLE); … … 1249 1274 && (stsBackend & PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE)) 1250 1275 { 1276 uint8_t u8Buf[_1K]; 1277 1278 uint32_t cRead = 0; 1279 int rc2 = AudioMixBufReadCirc(&pHstStream->MixBuf, u8Buf, sizeof(u8Buf), &cRead); 1280 AssertRC(rc2); 1281 1282 uint32_t cbBuf = AUDIOMIXBUF_S2B(&pHstStream->MixBuf, cRead); 1283 uint32_t cbPlayed = 0; 1284 1251 1285 AssertPtr(pThis->pHostDrvAudio->pfnStreamPlay); 1252 rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, NULL /* pvBuf */, 0 /* cbBuf */, 1253 &csPlayed); 1286 rc = pThis->pHostDrvAudio->pfnStreamPlay(pThis->pHostDrvAudio, pHstStream, u8Buf, cbBuf, &cbPlayed); 1254 1287 if (RT_SUCCESS(rc)) 1255 1288 { 1289 csPlayed = AUDIOMIXBUF_B2S(&pHstStream->MixBuf, cbPlayed); 1290 1291 AudioMixBufFinish(&pHstStream->MixBuf, csPlayed); 1292 1256 1293 #ifdef VBOX_WITH_STATISTICS 1257 1294 STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesOut, csPlayed); … … 1331 1368 1332 1369 AssertReleaseMsgBreakStmt(pHstStream != NULL, 1333 (" %s:Host stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",1370 ("[%s] Host stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n", 1334 1371 pStream->szName, pStream->cRefs, pStream->fStatus, pStream->enmCtx), 1335 1372 rc = VERR_NOT_AVAILABLE); 1336 1373 AssertReleaseMsgBreakStmt(pGstStream != NULL, 1337 (" %s:Guest stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n",1374 ("[%s] Guest stream is NULL (cRefs=%RU32, fStatus=%x, enmCtx=%ld)\n", 1338 1375 pStream->szName, pStream->cRefs, pStream->fStatus, pStream->enmCtx), 1339 1376 rc = VERR_NOT_AVAILABLE); … … 1348 1385 && (stsBackend & PDMAUDIOSTRMSTS_FLAG_DATA_READABLE)) 1349 1386 { 1350 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream, NULL /* pvBuf */, 0 /* cbBuf */, 1351 &csCaptured); 1387 uint8_t auBuf[_1K]; 1388 uint32_t cbCaptured; 1389 1390 rc = pThis->pHostDrvAudio->pfnStreamCapture(pThis->pHostDrvAudio, pHstStream, auBuf, sizeof(auBuf), &cbCaptured); 1352 1391 if (RT_FAILURE(rc)) 1353 1392 { … … 1357 1396 else 1358 1397 { 1398 Assert(cbCaptured <= sizeof(auBuf)); 1399 rc = AudioMixBufWriteCirc(&pHstStream->MixBuf, auBuf, cbCaptured, &csCaptured); 1400 if (RT_SUCCESS(rc)) 1401 { 1359 1402 #ifdef VBOX_WITH_STATISTICS 1360 STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesIn, csCaptured); 1361 STAM_COUNTER_ADD(&pHstStream->In.StatSamplesCaptured, csCaptured); 1362 #endif 1363 Log3Func(("[%s] %RU32 samples captured\n", pHstStream->szName, csCaptured)); 1403 STAM_COUNTER_ADD(&pThis->Stats.TotalSamplesIn, csCaptured); 1404 STAM_COUNTER_ADD(&pHstStream->In.StatSamplesCaptured, csCaptured); 1405 #endif 1406 Log3Func(("[%s] %RU32 samples captured\n", pHstStream->szName, csCaptured)); 1407 } 1364 1408 } 1365 1409 } … … 2277 2321 AssertPtrReturn(pVol, VERR_INVALID_POINTER); 2278 2322 2279 LogFlowFunc((" %s:volL=%RU32, volR=%RU32, fMute=%RTbool\n", pStream->szName, pVol->uLeft, pVol->uRight, pVol->fMuted));2323 LogFlowFunc(("[%s] volL=%RU32, volR=%RU32, fMute=%RTbool\n", pStream->szName, pVol->uLeft, pVol->uRight, pVol->fMuted)); 2280 2324 2281 2325 PPDMAUDIOSTREAM pHstStream = drvAudioGetHostStream(pStream); … … 2302 2346 PDMAUDIODIR enmDir = pStream->enmDir; 2303 2347 2304 LogFlowFunc((" %s:cRefs=%RU32\n", pStream->szName, pStream->cRefs));2348 LogFlowFunc(("[%s] cRefs=%RU32\n", pStream->szName, pStream->cRefs)); 2305 2349 if (pStream->cRefs > 1) 2306 2350 rc = VERR_WRONG_ORDER; … … 2469 2513 #ifdef LOG_ENABLED 2470 2514 char *pszHstSts = dbgAudioStreamStatusToStr(pHstStream->fStatus); 2471 LogFunc((" %s:fStatus=%s\n", pHstStream->szName, pszHstSts));2515 LogFunc(("[%s] fStatus=%s\n", pHstStream->szName, pszHstSts)); 2472 2516 RTStrFree(pszHstSts); 2473 2517 #endif /* LOG_ENABLED */ … … 2480 2524 rc = pThis->pHostDrvAudio->pfnStreamDestroy(pThis->pHostDrvAudio, pHstStream); 2481 2525 if (RT_SUCCESS(rc)) 2526 { 2482 2527 pHstStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED; 2483 } 2484 2485 LogFlowFunc(("%s: Returning %Rrc\n", pHstStream->szName, rc)); 2528 Assert(pHstStream->fStatus == PDMAUDIOSTRMSTS_FLAG_NONE); 2529 } 2530 } 2531 2532 LogFlowFunc(("[%s] Returning %Rrc\n", pHstStream->szName, rc)); 2486 2533 return rc; 2487 2534 } … … 2499 2546 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 2500 2547 2501 LogFlowFunc((" %s:cRefs=%RU32\n", pStream->szName, pStream->cRefs));2548 LogFlowFunc(("[%s] cRefs=%RU32\n", pStream->szName, pStream->cRefs)); 2502 2549 2503 2550 if (pStream->cRefs > 1) … … 2512 2559 rc = drvAudioStreamControlInternal(pThis, pStream, PDMAUDIOSTREAMCMD_DISABLE); 2513 2560 if (RT_SUCCESS(rc)) 2561 { 2514 2562 pStream->fStatus &= ~PDMAUDIOSTRMSTS_FLAG_INITIALIZED; 2563 Assert(pStream->fStatus == PDMAUDIOSTRMSTS_FLAG_NONE); 2564 } 2515 2565 } 2516 2566 } -
trunk/src/VBox/Devices/Audio/DrvHostALSAAudio.cpp
r65100 r65565 5 5 6 6 /* 7 * Copyright (C) 2006-201 6Oracle Corporation7 * Copyright (C) 2006-2017 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 60 60 61 61 #include "DrvAudio.h" 62 #include "AudioMixBuffer.h"63 64 62 #include "VBoxDD.h" 65 63 … … 83 81 * Note: Always must come first! */ 84 82 PDMAUDIOSTREAM Stream; 83 /** The PCM properties of this stream. */ 84 PDMAUDIOPCMPROPS Props; 85 85 snd_pcm_t *phPCM; 86 86 void *pvBuf; … … 93 93 * Note: Always must come first! */ 94 94 PDMAUDIOSTREAM Stream; 95 /** The PCM properties of this stream. */ 96 PDMAUDIOPCMPROPS Props; 95 97 snd_pcm_t *phPCM; 96 98 void *pvBuf; … … 1015 1017 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture} 1016 1018 */ 1017 static DECLCALLBACK(int) drvHostALSAAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)1018 { 1019 RT_NOREF(pvBuf, cbBuf); 1019 static DECLCALLBACK(int) drvHostALSAAudioStreamCapture(PPDMIHOSTAUDIO pInterface, 1020 PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 1021 { 1020 1022 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1021 1023 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1024 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 1025 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 1022 1026 /* pcbRead is optional. */ 1023 1027 1024 PALSAAUDIOSTREAMIN p ThisStream= (PALSAAUDIOSTREAMIN)pStream;1028 PALSAAUDIOSTREAMIN pStreamALSA = (PALSAAUDIOSTREAMIN)pStream; 1025 1029 1026 1030 snd_pcm_sframes_t cAvail; 1027 int rc = alsaStreamGetAvail(p ThisStream->phPCM, &cAvail);1031 int rc = alsaStreamGetAvail(pStreamALSA->phPCM, &cAvail); 1028 1032 if (RT_FAILURE(rc)) 1029 1033 { … … 1034 1038 if (!cAvail) /* No data yet? */ 1035 1039 { 1036 snd_pcm_state_t state = snd_pcm_state(p ThisStream->phPCM);1040 snd_pcm_state_t state = snd_pcm_state(pStreamALSA->phPCM); 1037 1041 switch (state) 1038 1042 { 1039 1043 case SND_PCM_STATE_PREPARED: 1040 cAvail = AudioMixBufFree(&pStream->MixBuf);1044 cAvail = PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, cbBuf); 1041 1045 break; 1042 1046 1043 1047 case SND_PCM_STATE_SUSPENDED: 1044 1048 { 1045 rc = alsaStreamResume(p ThisStream->phPCM);1049 rc = alsaStreamResume(pStreamALSA->phPCM); 1046 1050 if (RT_FAILURE(rc)) 1047 1051 break; … … 1068 1072 * the mixer buffer. 1069 1073 */ 1070 Assert(cAvail); 1071 size_t cbMixFree = AudioMixBufFreeBytes(&pStream->MixBuf); 1072 size_t cbToRead = RT_MIN((size_t)AUDIOMIXBUF_S2B(&pStream->MixBuf, cAvail), cbMixFree); 1074 size_t cbToRead = RT_MIN((size_t)PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, cAvail), cbBuf); 1073 1075 1074 1076 LogFlowFunc(("cbToRead=%zu, cAvail=%RI32\n", cbToRead, cAvail)); 1075 1077 1076 uint32_t cWrittenTotal = 0; 1078 uint32_t cbReadTotal = 0; 1079 1077 1080 snd_pcm_uframes_t cToRead; 1078 1081 snd_pcm_sframes_t cRead; … … 1081 1084 && RT_SUCCESS(rc)) 1082 1085 { 1083 cToRead = RT_MIN( AUDIOMIXBUF_B2S(&pStream->MixBuf, cbToRead),1084 AUDIOMIXBUF_B2S(&pStream->MixBuf, pThisStream->cbBuf));1086 cToRead = RT_MIN(PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, cbToRead), 1087 PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, pStreamALSA->cbBuf)); 1085 1088 AssertBreakStmt(cToRead, rc = VERR_NO_DATA); 1086 cRead = snd_pcm_readi(p ThisStream->phPCM, pThisStream->pvBuf, cToRead);1089 cRead = snd_pcm_readi(pStreamALSA->phPCM, pStreamALSA->pvBuf, cToRead); 1087 1090 if (cRead <= 0) 1088 1091 { … … 1109 1112 case -EPIPE: 1110 1113 { 1111 rc = alsaStreamRecover(p ThisStream->phPCM);1114 rc = alsaStreamRecover(pStreamALSA->phPCM); 1112 1115 if (RT_FAILURE(rc)) 1113 1116 break; … … 1127 1130 else 1128 1131 { 1129 uint32_t cWritten;1130 rc = AudioMixBufWriteCirc(&pStream->MixBuf,1131 pThisStream->pvBuf, AUDIOMIXBUF_S2B(&pStream->MixBuf, cRead),1132 &cWritten);1133 if (RT_FAILURE(rc))1134 break;1135 1136 1132 /* 1137 1133 * We should not run into a full mixer buffer or we loose samples and … … 1139 1135 * capture device for example). 1140 1136 */ 1141 AssertLogRelMsgBreakStmt(cWritten > 0, ("Mixer buffer shouldn't be full at this point!\n"),1142 rc = VERR_INTERNAL_ERROR); 1143 uint32_t cbWritten = AUDIOMIXBUF_S2B(&pStream->MixBuf, cWritten);1144 1145 Assert(cbToRead >= cb Written);1146 cbToRead -= cbWritten;1147 c WrittenTotal += cWritten;1137 uint32_t cbRead = PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, cRead); 1138 1139 memcpy(pvBuf, pStreamALSA->pvBuf, cbRead); 1140 1141 Assert(cbToRead >= cbRead); 1142 cbToRead -= cbRead; 1143 cbReadTotal += cbRead; 1148 1144 } 1149 1145 } … … 1151 1147 if (RT_SUCCESS(rc)) 1152 1148 { 1153 uint32_t cProcessed = 0;1154 if (cWrittenTotal)1155 rc = AudioMixBufMixToParent(&pStream->MixBuf, cWrittenTotal,1156 &cProcessed);1157 1158 1149 if (pcbRead) 1159 *pcbRead = cWrittenTotal; 1160 1161 LogFlowFunc(("cWrittenTotal=%RU32 (%RU32 processed), rc=%Rrc\n", 1162 cWrittenTotal, cProcessed, rc)); 1150 *pcbRead = cbReadTotal; 1163 1151 } 1164 1152 … … 1170 1158 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 1171 1159 */ 1172 static DECLCALLBACK(int) drvHostALSAAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)1173 { 1174 RT_NOREF(pvBuf, cbBuf); 1160 static DECLCALLBACK(int) drvHostALSAAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, 1161 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 1162 { 1175 1163 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1176 1164 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1165 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 1166 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 1177 1167 /* pcbWritten is optional. */ 1178 1168 1179 PALSAAUDIOSTREAMOUT p ThisStream= (PALSAAUDIOSTREAMOUT)pStream;1169 PALSAAUDIOSTREAMOUT pStreamALSA = (PALSAAUDIOSTREAMOUT)pStream; 1180 1170 1181 1171 int rc = VINF_SUCCESS; 1182 uint32_t cbReadTotal = 0; 1172 1173 uint32_t cbWrittenTotal = 0; 1183 1174 1184 1175 do 1185 1176 { 1186 1177 snd_pcm_sframes_t cAvail; 1187 rc = alsaStreamGetAvail(p ThisStream->phPCM, &cAvail);1178 rc = alsaStreamGetAvail(pStreamALSA->phPCM, &cAvail); 1188 1179 if (RT_FAILURE(rc)) 1189 1180 { … … 1192 1183 } 1193 1184 1194 size_t cbToRead = RT_MIN(AUDIOMIXBUF_S2B(&pStream->MixBuf, 1195 (uint32_t)cAvail), /* cAvail is always >= 0 */ 1196 AUDIOMIXBUF_S2B(&pStream->MixBuf, 1197 AudioMixBufLive(&pStream->MixBuf))); 1198 LogFlowFunc(("cbToRead=%zu, cbAvail=%zu\n", 1199 cbToRead, AUDIOMIXBUF_S2B(&pStream->MixBuf, cAvail))); 1200 1201 uint32_t cRead, cbRead; 1202 snd_pcm_sframes_t cWritten; 1203 while (cbToRead) 1204 { 1205 rc = AudioMixBufReadCirc(&pStream->MixBuf, pThisStream->pvBuf, cbToRead, &cRead); 1206 if (RT_FAILURE(rc)) 1207 break; 1208 1209 cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, cRead); 1210 AssertBreak(cbRead); 1211 1212 /* Don't try infinitely on recoverable errors. */ 1213 unsigned iTry; 1214 for (iTry = 0; iTry < ALSA_RECOVERY_TRIES_MAX; iTry++) 1185 size_t cbToRead = RT_MIN(PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, cAvail), cbBuf); 1186 if (!cbToRead) 1187 break; 1188 1189 memcpy(pStreamALSA->pvBuf, pvBuf, cbToRead); 1190 1191 snd_pcm_sframes_t cWritten = 0; 1192 1193 /* Don't try infinitely on recoverable errors. */ 1194 unsigned iTry; 1195 for (iTry = 0; iTry < ALSA_RECOVERY_TRIES_MAX; iTry++) 1196 { 1197 cWritten = snd_pcm_writei(pStreamALSA->phPCM, pStreamALSA->pvBuf, 1198 PDMAUDIOPCMPROPS_B2S(&pStreamALSA->Props, cbToRead)); 1199 if (cWritten <= 0) 1215 1200 { 1216 cWritten = snd_pcm_writei(pThisStream->phPCM, pThisStream->pvBuf, cRead); 1217 if (cWritten <= 0) 1201 switch (cWritten) 1218 1202 { 1219 switch (cWritten)1203 case 0: 1220 1204 { 1221 case 0: 1205 LogFunc(("Failed to write %zu bytes\n", cbToRead)); 1206 rc = VERR_ACCESS_DENIED; 1207 break; 1208 } 1209 1210 case -EPIPE: 1211 { 1212 rc = alsaStreamRecover(pStreamALSA->phPCM); 1213 if (RT_FAILURE(rc)) 1214 break; 1215 1216 LogFlowFunc(("Recovered from playback\n")); 1217 continue; 1218 } 1219 1220 case -ESTRPIPE: 1221 { 1222 /* Stream was suspended and waiting for a recovery. */ 1223 rc = alsaStreamResume(pStreamALSA->phPCM); 1224 if (RT_FAILURE(rc)) 1222 1225 { 1223 LogFunc(("Failed to write %RU32 samples\n", cRead)); 1224 rc = VERR_ACCESS_DENIED; 1226 LogRel(("ALSA: Failed to resume output stream\n")); 1225 1227 break; 1226 1228 } 1227 1229 1228 case -EPIPE: 1229 { 1230 rc = alsaStreamRecover(pThisStream->phPCM); 1231 if (RT_FAILURE(rc)) 1232 break; 1233 1234 LogFlowFunc(("Recovered from playback\n")); 1235 continue; 1236 } 1237 1238 case -ESTRPIPE: 1239 { 1240 /* Stream was suspended and waiting for a recovery. */ 1241 rc = alsaStreamResume(pThisStream->phPCM); 1242 if (RT_FAILURE(rc)) 1243 { 1244 LogRel(("ALSA: Failed to resume output stream\n")); 1245 break; 1246 } 1247 1248 LogFlowFunc(("Resumed suspended output stream\n")); 1249 continue; 1250 } 1251 1252 default: 1253 LogFlowFunc(("Failed to write %RI32 output frames, rc=%Rrc\n", 1254 cRead, rc)); 1255 rc = VERR_GENERAL_FAILURE; /** @todo */ 1256 break; 1230 LogFlowFunc(("Resumed suspended output stream\n")); 1231 continue; 1257 1232 } 1233 1234 default: 1235 LogFlowFunc(("Failed to write %RU32 bytes, error unknown\n", cbToRead)); 1236 rc = VERR_GENERAL_FAILURE; /** @todo */ 1237 break; 1258 1238 } 1259 else 1260 break; 1261 } /* For number of tries. */ 1262 1263 if ( iTry == ALSA_RECOVERY_TRIES_MAX 1264 && cWritten <= 0) 1265 rc = VERR_BROKEN_PIPE; 1266 1267 if (RT_FAILURE(rc)) 1239 } 1240 else 1268 1241 break; 1269 1270 Assert(cbToRead >= cbRead); 1271 cbToRead -= cbRead; 1272 cbReadTotal += cbRead; 1273 } 1274 } 1275 while (0); 1242 } /* For number of tries. */ 1243 1244 if ( iTry == ALSA_RECOVERY_TRIES_MAX 1245 && cWritten <= 0) 1246 rc = VERR_BROKEN_PIPE; 1247 1248 if (RT_FAILURE(rc)) 1249 break; 1250 1251 cbWrittenTotal = cbToRead; 1252 1253 } while (0); 1276 1254 1277 1255 if (RT_SUCCESS(rc)) 1278 1256 { 1279 uint32_t cReadTotal = AUDIOMIXBUF_B2S(&pStream->MixBuf, cbReadTotal);1280 if (cReadTotal)1281 AudioMixBufFinish(&pStream->MixBuf, cReadTotal);1282 1283 1257 if (pcbWritten) 1284 *pcbWritten = cReadTotal; 1285 1286 LogFlowFunc(("cReadTotal=%RU32 (%RU32 bytes), rc=%Rrc\n", 1287 cReadTotal, cbReadTotal, rc)); 1258 *pcbWritten = cbWrittenTotal; 1288 1259 } 1289 1260 … … 1333 1304 static int alsaCreateStreamOut(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 1334 1305 { 1335 PALSAAUDIOSTREAMOUT p ThisStream= (PALSAAUDIOSTREAMOUT)pStream;1306 PALSAAUDIOSTREAMOUT pStreamALSA = (PALSAAUDIOSTREAMOUT)pStream; 1336 1307 1337 1308 snd_pcm_t *phPCM = NULL; … … 1365 1336 pCfgAcq->cSampleBufferSize = obt.samples * 4; 1366 1337 1367 PDMAUDIOPCMPROPS Props; 1368 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &Props); 1338 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamALSA->Props); 1369 1339 if (RT_FAILURE(rc)) 1370 1340 break; 1371 1341 1372 1342 AssertBreakStmt(obt.samples, rc = VERR_INVALID_PARAMETER); 1373 size_t cbBuf = obt.samples * (1 << Props.cShift); /** @todo Get rid of using Props! */ 1343 1344 size_t cbBuf = obt.samples * PDMAUDIOPCMPROPS_S2B(&pStreamALSA->Props, 1); 1374 1345 AssertBreakStmt(cbBuf, rc = VERR_INVALID_PARAMETER); 1375 pThisStream->pvBuf = RTMemAlloc(cbBuf); 1376 if (!pThisStream->pvBuf)1377 {1378 LogRel(("ALSA: Not enough memory for output DAC buffer (%RU32 samples, each %d bytes)\n",1379 obt.samples, 1 << Props.cShift));1346 1347 pStreamALSA->pvBuf = RTMemAlloc(cbBuf); 1348 if (!pStreamALSA->pvBuf) 1349 { 1350 LogRel(("ALSA: Not enough memory for output DAC buffer (%RU32 samples, %zu bytes)\n", obt.samples, cbBuf)); 1380 1351 rc = VERR_NO_MEMORY; 1381 1352 break; 1382 1353 } 1383 1354 1384 p ThisStream->cbBuf = cbBuf;1385 p ThisStream->phPCM = phPCM;1355 pStreamALSA->cbBuf = cbBuf; 1356 pStreamALSA->phPCM = phPCM; 1386 1357 } 1387 1358 while (0); -
trunk/src/VBox/Devices/Audio/DrvHostCoreAudio.cpp
r65100 r65565 5 5 6 6 /* 7 * Copyright (C) 2010-201 6Oracle Corporation7 * Copyright (C) 2010-2017 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 23 23 24 24 #include "DrvAudio.h" 25 #include "AudioMixBuffer.h"26 27 25 #include "VBoxDD.h" 28 26 -
trunk/src/VBox/Devices/Audio/DrvHostDSound.cpp
r63714 r65565 28 28 #include <iprt/uuid.h> 29 29 30 #include "AudioMixBuffer.h"31 30 #include "DrvAudio.h" 32 31 #include "VBoxDD.h" … … 114 113 LPDIRECTSOUNDBUFFER8 pDSB; 115 114 DWORD offPlayWritePos; 116 DWORD c MaxSamplesInBuffer;115 DWORD cbPlayBuf; 117 116 bool fEnabled; 118 117 bool fRestartPlayback; … … 128 127 LPDIRECTSOUNDCAPTURE8 pDSC; 129 128 LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB; 130 DWORD idxSampleCaptureReadPos;131 DWORD c MaxSamplesInBuffer;129 DWORD offCaptureBufRead; 130 DWORD cbCaptureBuf; 132 131 HRESULT hrLastCapture; 133 132 PDMAUDIORECSOURCE enmRecSource; … … 284 283 if (SUCCEEDED(hr)) 285 284 { 286 DWORD const cbBuffer = AUDIOMIXBUF_S2B(&pDSoundStream->Stream.MixBuf, pDSoundStream->cMaxSamplesInBuffer);285 DWORD const cbBuffer = pDSoundStream->cbPlayBuf; 287 286 if (pdwBuffer) 288 287 *pdwBuffer = cbBuffer; … … 604 603 * 605 604 * Instead we're specifying DSBCAPS_LOCSOFTWARE, as this fits the bill 606 * of copying own buffer data (from AudioMixBuf)to our secondary's Direct Sound buffer.605 * of copying own buffer data to our secondary's Direct Sound buffer. 607 606 */ 608 607 bd.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCSOFTWARE; … … 681 680 * playback buffer position. 682 681 */ 683 pDSoundStream->c MaxSamplesInBuffer = bc.dwBufferBytes >> pDSoundStream->Props.cShift;684 DSLOG(("DSound: cMaxSamplesInBuffer=%RU32\n", pDSoundStream->c MaxSamplesInBuffer));682 pDSoundStream->cbPlayBuf = bc.dwBufferBytes; 683 DSLOG(("DSound: cMaxSamplesInBuffer=%RU32\n", pDSoundStream->cbPlayBuf)); 685 684 686 685 #ifdef VBOX_WITH_AUDIO_DEVICE_CALLBACKS … … 745 744 AssertPtrReturnVoid(pDSoundStream); 746 745 747 PPDMAUDIOSTREAM pStream = &pDSoundStream->Stream;748 749 746 PVOID pv1, pv2; 750 747 DWORD cb1, cb2; 751 748 HRESULT hr = directSoundPlayLock(pThis, pDSoundStream->pDSB, &pDSoundStream->Props, 752 0 /* dwOffset */, AUDIOMIXBUF_S2B(&pStream->MixBuf, pDSoundStream->cMaxSamplesInBuffer), 749 0 /* dwOffset */, 750 &pDSoundStream->Props, pDSoundStream->cbPlayBuf, 753 751 &pv1, &pv2, &cb1, &cb2, DSBLOCK_ENTIREBUFFER); 754 752 if (SUCCEEDED(hr)) 755 753 { 756 DWORD len1 = AUDIOMIXBUF_B2S(&pStream->MixBuf, cb1);757 DWORD len2 = AUDIOMIXBUF_B2S(&pStream->MixBuf, cb2);754 DWORD len1 = PDMAUDIOPCMPROPS_B2S(&pDSoundStream->Props, cb1); 755 DWORD len2 = PDMAUDIOPCMPROPS_B2S(&pDSoundStream->Props, cb2); 758 756 759 757 if (pv1 && len1) … … 1148 1146 1149 1147 /* Initial state: reading at the initial capture position, no error. */ 1150 pDSoundStream->idxSampleCaptureReadPos = offByteReadPos >> pDSoundStream->Props.cShift; 1151 pDSoundStream->cMaxSamplesInBuffer = bc.dwBufferBytes >> pDSoundStream->Props.cShift; 1152 pDSoundStream->hrLastCapture = S_OK; 1153 1154 DSLOG(("DSound: idxSampleCaptureReadPos=%RU32, cMaxSamplesInBuffer=%RU32\n", 1155 pDSoundStream->idxSampleCaptureReadPos, pDSoundStream->cMaxSamplesInBuffer)); 1148 pDSoundStream->offCaptureBufRead = offByteReadPos; 1149 pDSoundStream->cbCaptureBuf = bc.dwBufferBytes; 1150 1151 pDSoundStream->hrLastCapture = S_OK; 1152 1153 DSLOG(("DSound: offCaptureBufRead=%RU32, cbCaptureBuf=%RU32\n", 1154 pDSoundStream->offCaptureBufRead, pDSoundStream->cbCaptureBuf)); 1156 1155 1157 1156 } while (0); … … 1457 1456 pDSoundStream->offPlayWritePos = 0; 1458 1457 pDSoundStream->fRestartPlayback = true; 1459 pDSoundStream->c MaxSamplesInBuffer= 0;1458 pDSoundStream->cbPlayBuf = 0; 1460 1459 1461 1460 if (pCfgAcq) … … 1528 1527 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 1529 1528 */ 1530 int drvHostDSoundStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 1531 { 1532 RT_NOREF2(pvBuf, cbBuf); 1533 1529 int drvHostDSoundStreamPlay(PPDMIHOSTAUDIO pInterface, 1530 PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 1531 { 1534 1532 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1535 1533 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1534 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 1535 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 1536 1536 /* pcbRead is optional. */ 1537 1537 … … 1540 1540 1541 1541 int rc = VINF_SUCCESS; 1542 uint32_t cReadTotal = 0; 1542 1543 uint32_t cbWrittenTotal = 0; 1543 1544 1544 1545 #ifdef DEBUG_andy … … 1557 1558 * i.e. always leave a free space for 1 audio sample. 1558 1559 */ 1559 const DWORD cbSample = AUDIOMIXBUF_S2B(&pStream->MixBuf, 1);1560 const DWORD cbSample = PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, 1); 1560 1561 if (cbFree <= cbSample) 1561 1562 break; 1562 1563 cbFree -= cbSample; 1563 1564 1564 uint32_t cLive = AudioMixBufLive(&pStream->MixBuf); 1565 uint32_t cbLive = AUDIOMIXBUF_S2B(&pStream->MixBuf, cLive); 1565 uint32_t cbLive = cbBuf; 1566 1566 1567 1567 /* Do not write more than available space in the DirectSound playback buffer. */ … … 1589 1589 1590 1590 /** @todo r=bird: Can pv1/cb1 really be NULL? Docs says they're always set 1591 * and pv2/cb2 only used when there is a buffer wrap ar aound. */1592 1593 DWORD cSamplesIn1 = AUDIOMIXBUF_B2S(&pStream->MixBuf, cb1);1591 * and pv2/cb2 only used when there is a buffer wrap around. */ 1592 1593 DWORD cSamplesIn1 = PDMAUDIOPCMPROPS_B2S(&pDSoundStream->Props, cb1); 1594 1594 uint32_t cRead = 0; 1595 1595 1596 1596 if (pv1 && cb1) 1597 1597 { 1598 rc = AudioMixBufReadCirc(&pStream->MixBuf, pv1, cb1, &cRead); 1599 if (RT_SUCCESS(rc)) 1600 cReadTotal += cRead; 1601 } 1602 1603 if ( RT_SUCCESS(rc) 1604 && cReadTotal == cSamplesIn1 1605 && pv2 && cb2) 1606 { 1607 rc = AudioMixBufReadCirc(&pStream->MixBuf, pv2, cb2, &cRead); 1608 if (RT_SUCCESS(rc)) 1609 cReadTotal += cRead; 1598 memcpy(pv1, pvBuf, cb1); 1599 cbWrittenTotal += cb1; 1600 } 1601 1602 if (pv2 && cb2) 1603 { 1604 memcpy(pv2, (uint8_t *)pvBuf + cb1, cb2); 1605 cbWrittenTotal += cb2; 1610 1606 } 1611 1607 1612 1608 directSoundPlayUnlock(pThis, pDSB, pv1, pv2, cb1, cb2); 1613 1609 1614 pDSoundStream->offPlayWritePos = (pDSoundStream->offPlayWritePos + AUDIOMIXBUF_S2B(&pStream->MixBuf, cReadTotal))1610 pDSoundStream->offPlayWritePos = (pDSoundStream->offPlayWritePos + PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, cbWrittenTotal)) 1615 1611 % cbBuffer; 1616 1612 1617 DSLOGF(("DSound: %RU32 (%RU32 samples) out of %RU32%s, buffer write pos %ld, rc=%Rrc\n", 1618 AUDIOMIXBUF_S2B(&pStream->MixBuf, cReadTotal), cReadTotal, cbLive, 1619 cbLive != AUDIOMIXBUF_S2B(&pStream->MixBuf, cReadTotal) ? " !!!": "", 1613 DSLOGF(("DSound: %RU32/%RU32, buffer write pos %ld, rc=%Rrc\n", 1614 PDMAUDIOPCMPROPS_S2B(&pDSoundStream->Props, cbWrittenTotal), cbLive, 1620 1615 pDSoundStream->offPlayWritePos, rc)); 1621 1622 if (cReadTotal)1623 {1624 AudioMixBufFinish(&pStream->MixBuf, cReadTotal);1625 rc = VINF_SUCCESS; /* Played something. */1626 }1627 1628 if (RT_FAILURE(rc))1629 break;1630 1616 1631 1617 if (pDSoundStream->fRestartPlayback) … … 1668 1654 dsoundUpdateStatusInternal(pThis); 1669 1655 else if (pcbWritten) 1670 *pcbWritten = cReadTotal; 1671 1672 LogFlowFuncLeaveRC(rc); 1656 *pcbWritten = cbWrittenTotal; 1657 1673 1658 return rc; 1674 1659 } … … 1681 1666 directSoundPlayClose(pThis, pDSoundStream); 1682 1667 1683 pDSoundStream->offPlayWritePos 1684 pDSoundStream->fRestartPlayback 1685 pDSoundStream->c MaxSamplesInBuffer= 0;1668 pDSoundStream->offPlayWritePos = 0; 1669 pDSoundStream->fRestartPlayback = true; 1670 pDSoundStream->cbPlayBuf = 0; 1686 1671 1687 1672 RT_ZERO(pDSoundStream->streamCfg); … … 1704 1689 { 1705 1690 /* Init the stream structure and save relevant information to it. */ 1706 pDSoundStream-> idxSampleCaptureReadPos= 0;1707 pDSoundStream->c MaxSamplesInBuffer= 0;1691 pDSoundStream->offCaptureBufRead = 0; 1692 pDSoundStream->cbPlayBuf = 0; 1708 1693 pDSoundStream->pDSC = NULL; 1709 1694 pDSoundStream->pDSCB = NULL; … … 1781 1766 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture} 1782 1767 */ 1783 int drvHostDSoundStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 1784 { 1785 RT_NOREF2(pvBuf, cbBuf); 1768 int drvHostDSoundStreamCapture(PPDMIHOSTAUDIO pInterface, 1769 PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 1770 { 1771 1772 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 1773 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 1774 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 1775 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 1786 1776 1787 1777 PDRVHOSTDSOUND pThis = PDMIHOSTAUDIO_2_DRVHOSTDSOUND(pInterface); … … 1792 1782 int rc = VINF_SUCCESS; 1793 1783 1794 uint32_t c SamplesProcessed= 0;1784 uint32_t cbReadTotal = 0; 1795 1785 1796 1786 do … … 1803 1793 1804 1794 /* Get DirectSound capture position in bytes. */ 1805 DWORD off ByteReadPos;1806 HRESULT hr = IDirectSoundCaptureBuffer_GetCurrentPosition(pDSCB, NULL, &off ByteReadPos);1795 DWORD offCurPos; 1796 HRESULT hr = IDirectSoundCaptureBuffer_GetCurrentPosition(pDSCB, NULL, &offCurPos); 1807 1797 if (FAILED(hr)) 1808 1798 { … … 1819 1809 pDSoundStream->hrLastCapture = hr; 1820 1810 1821 if (offByteReadPos & pDSoundStream->Props.uAlign) 1822 DSLOGF(("DSound: Misaligned capture read position %ld (alignment: %RU32)\n", offByteReadPos, pDSoundStream->Props.uAlign)); 1823 1824 /* Capture position in samples. */ 1825 DWORD idxSampleReadPos = offByteReadPos >> pDSoundStream->Props.cShift; 1811 if (offCurPos & pDSoundStream->Props.uAlign) 1812 DSLOGF(("DSound: Misaligned capture read position %ld (alignment: %RU32)\n", offCurPos, pDSoundStream->Props.uAlign)); 1826 1813 1827 1814 /* Number of samples available in the DirectSound capture buffer. */ 1828 DWORD cSamplesToCapture = dsoundRingDistance(idxSampleReadPos, pDSoundStream->idxSampleCaptureReadPos, 1829 pDSoundStream->cMaxSamplesInBuffer); 1830 if (cSamplesToCapture == 0) 1831 break; 1832 1833 /* Get number of free samples in the mix buffer and check that is has free space */ 1834 uint32_t cFreeMixSamples = AudioMixBufFree(&pStream->MixBuf); 1835 if (cFreeMixSamples == 0) 1815 DWORD cbToCapture = dsoundRingDistance(offCurPos, pDSoundStream->offCaptureBufRead, pDSoundStream->cbCaptureBuf); 1816 if (cbToCapture == 0) 1817 break; 1818 1819 if (cbBuf == 0) 1836 1820 { 1837 1821 DSLOGF(("DSound: Capture buffer full\n")); … … 1839 1823 } 1840 1824 1841 DSLOGF(("DSound: Capture c FreeMixSamples=%RU32, idxSampleReadPos=%u, idxSampleCaptureReadPos=%u, cSamplesToCapture=%u\n",1842 c FreeMixSamples, idxSampleReadPos, pDSoundStream->idxSampleCaptureReadPos, cSamplesToCapture));1825 DSLOGF(("DSound: Capture cbBuf=%RU32, offCurPos=%ld, offCaptureBufRead=%ld, cbToCapture=%ld\n", 1826 cbBuf, offCurPos, pDSoundStream->offCaptureBufRead, cbToCapture)); 1843 1827 1844 1828 /* No need to fetch more samples than mix buffer can receive. */ 1845 c SamplesToCapture = RT_MIN(cSamplesToCapture, cFreeMixSamples);1829 cbToCapture = RT_MIN(cbToCapture, cbBuf); 1846 1830 1847 1831 /* Lock relevant range in the DirectSound capture buffer. */ … … 1849 1833 DWORD cb1, cb2; 1850 1834 hr = directSoundCaptureLock(pDSCB, &pDSoundStream->Props, 1851 AUDIOMIXBUF_S2B(&pStream->MixBuf, pDSoundStream->idxSampleCaptureReadPos), /* dwOffset */1852 AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesToCapture), /* dwBytes */1835 pDSoundStream->offCaptureBufRead, /* dwOffset */ 1836 cbToCapture, /* dwBytes */ 1853 1837 &pv1, &pv2, &cb1, &cb2, 1854 0 /* dwFlags */);1838 0 /* dwFlags */); 1855 1839 if (FAILED(hr)) 1856 1840 { … … 1859 1843 } 1860 1844 1861 DWORD len1 = AUDIOMIXBUF_B2S(&pStream->MixBuf, cb1); 1862 DWORD len2 = AUDIOMIXBUF_B2S(&pStream->MixBuf, cb2); 1863 1864 uint32_t cSamplesWrittenTotal = 0; 1865 uint32_t cSamplesWritten; 1866 if (pv1 && len1) 1867 { 1868 rc = AudioMixBufWriteCirc(&pStream->MixBuf, pv1, cb1, &cSamplesWritten); 1869 if (RT_SUCCESS(rc)) 1870 cSamplesWrittenTotal += cSamplesWritten; 1871 } 1872 1873 if ( RT_SUCCESS(rc) 1874 && cSamplesWrittenTotal == len1 1875 && pv2 && len2) 1876 { 1877 rc = AudioMixBufWriteCirc(&pStream->MixBuf, pv2, cb2, &cSamplesWritten); 1878 if (RT_SUCCESS(rc)) 1879 cSamplesWrittenTotal += cSamplesWritten; 1845 if (pv1 && cb1) 1846 { 1847 memcpy((uint8_t *)pvBuf + cbReadTotal, pv1, cb1); 1848 cbReadTotal += cb1; 1849 } 1850 1851 if (pv2 && cb2) 1852 { 1853 memcpy((uint8_t *)pvBuf + cbReadTotal, pv2, cb2); 1854 cbReadTotal += cb2; 1880 1855 } 1881 1856 1882 1857 directSoundCaptureUnlock(pDSCB, pv1, pv2, cb1, cb2); 1883 1858 1884 if (cSamplesWrittenTotal) /* Captured something? */1885 rc = AudioMixBufMixToParent(&pStream->MixBuf, cSamplesWrittenTotal, &cSamplesProcessed);1886 1887 1859 if (RT_SUCCESS(rc)) 1888 1860 { 1889 pDSoundStream->idxSampleCaptureReadPos = (pDSoundStream->idxSampleCaptureReadPos + cSamplesProcessed) 1890 % pDSoundStream->cMaxSamplesInBuffer; 1891 DSLOGF(("DSound: Capture %u (%u+%u), processed %RU32/%RU32\n", 1892 cSamplesToCapture, len1, len2, cSamplesProcessed, cSamplesWrittenTotal)); 1861 pDSoundStream->offCaptureBufRead = (pDSoundStream->offCaptureBufRead + cbReadTotal) 1862 % pDSoundStream->cbCaptureBuf; 1863 DSLOGF(("DSound: Captured %ld bytes (%RU32 total)\n", cbToCapture, cbReadTotal)); 1893 1864 } 1894 1865 1895 1866 } while (0); 1896 1867 1897 if (RT_FAILURE(rc)) 1868 if (RT_SUCCESS(rc)) 1869 { 1870 if (pcbRead) 1871 *pcbRead = cbReadTotal; 1872 } 1873 else 1898 1874 dsoundUpdateStatusInternal(pThis); 1899 else if (pcbRead) 1900 *pcbRead = cSamplesProcessed; 1901 1902 LogFlowFuncLeaveRC(rc); 1875 1903 1876 return rc; 1904 1877 } … … 1910 1883 directSoundCaptureClose(pDSoundStream); 1911 1884 1912 pDSoundStream->idxSampleCaptureReadPos = 0; 1913 pDSoundStream->cMaxSamplesInBuffer = 0; 1885 pDSoundStream->offCaptureBufRead = 0; 1886 pDSoundStream->cbCaptureBuf = 0; 1887 1914 1888 RT_ZERO(pDSoundStream->streamCfg); 1915 1889 -
trunk/src/VBox/Devices/Audio/DrvHostDebugAudio.cpp
r63711 r65565 6 6 7 7 /* 8 * Copyright (C) 2016 Oracle Corporation8 * Copyright (C) 2016-2017 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 26 26 27 27 #include "DrvAudio.h" 28 #include "AudioMixBuffer.h"29 28 #include "VBoxDD.h" 30 29 … … 50 49 /** Timestamp of last played samples. */ 51 50 uint64_t tsLastPlayed; 52 uint64_t cMaxSamplesInPlayBuffer;53 51 uint8_t *pu8PlayBuffer; 52 size_t cbPlayBuffer; 54 53 } Out; 55 54 }; 55 PDMAUDIOPCMPROPS Props; 56 56 57 57 } DEBUGAUDIOSTREAM, *PDEBUGAUDIOSTREAM; … … 128 128 RT_NOREF(pInterface, pStream); 129 129 130 PDEBUGAUDIOSTREAM pDbgStream = (PDEBUGAUDIOSTREAM)pStream; 131 130 132 /* Just adopt the wanted stream configuration. */ 131 PDMAUDIOPCMPROPS Props; 132 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &Props); 133 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pDbgStream->Props); 133 134 if (RT_SUCCESS(rc)) 134 135 { … … 145 146 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 146 147 { 147 NOREF(pInterface);148 RT_NOREF(pInterface); 148 149 149 150 PDEBUGAUDIOSTREAM pDbgStream = (PDEBUGAUDIOSTREAM)pStream; 150 151 151 152 /* Just adopt the wanted stream configuration. */ 152 PDMAUDIOPCMPROPS Props; 153 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &Props); 153 int rc = DrvAudioHlpStreamCfgToProps(pCfgReq, &pDbgStream->Props); 154 154 if (RT_SUCCESS(rc)) 155 155 { 156 pDbgStream->Out.tsLastPlayed 157 pDbgStream->Out.c MaxSamplesInPlayBuffer = _1K;158 pDbgStream->Out.pu8PlayBuffer = (uint8_t *)RTMemAlloc(pDbgStream->Out.cMaxSamplesInPlayBuffer << Props.cShift);156 pDbgStream->Out.tsLastPlayed = 0; 157 pDbgStream->Out.cbPlayBuffer = _1K * PDMAUDIOPCMPROPS_S2B(&pDbgStream->Props, 1); /** @todo Make this configurable? */ 158 pDbgStream->Out.pu8PlayBuffer = (uint8_t *)RTMemAlloc(pDbgStream->Out.cbPlayBuffer); 159 159 if (!pDbgStream->Out.pu8PlayBuffer) 160 160 rc = VERR_NO_MEMORY; … … 174 174 rc = DrvAudioHlpWAVFileOpen(&pDbgStream->File, szFile, 175 175 RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE, 176 & Props, PDMAUDIOFILEFLAG_NONE);176 &pDbgStream->Props, PDMAUDIOFILEFLAG_NONE); 177 177 if (RT_FAILURE(rc)) 178 178 LogRel(("DebugAudio: Creating output file '%s' failed with %Rrc\n", szFile, rc)); … … 188 188 { 189 189 if (pCfgAcq) 190 pCfgAcq->cSampleBufferSize = pDbgStream->Out.cMaxSamplesInPlayBuffer;190 pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pDbgStream->Props, pDbgStream->Out.cbPlayBuffer); 191 191 } 192 192 … … 247 247 cSamplesPlayed = cLive;*/ 248 248 249 uint32_t cSamplesPlayed = 0; 250 uint32_t cSamplesAvail = RT_MIN(AudioMixBufUsed(&pStream->MixBuf), pDbgStream->Out.cMaxSamplesInPlayBuffer); 251 while (cSamplesAvail) 252 { 253 uint32_t cSamplesRead = 0; 254 int rc2 = AudioMixBufReadCirc(&pStream->MixBuf, pDbgStream->Out.pu8PlayBuffer, 255 AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesAvail), &cSamplesRead); 256 257 if (RT_FAILURE(rc2)) 258 LogRel(("DebugAudio: Reading output failed with %Rrc\n", rc2)); 259 260 if (!cSamplesRead) 261 break; 249 uint32_t cbWritten = 0; 250 251 uint32_t cbAvail = RT_MIN(cbBuf, pDbgStream->Out.cbPlayBuffer); 252 while (cbAvail) 253 { 254 uint32_t cbChunk = cbAvail; /** @todo Use chunks? */ 255 256 memcpy(pDbgStream->Out.pu8PlayBuffer, pvBuf, cbChunk); 262 257 #if 0 263 258 RTFILE fh; 264 259 RTFileOpen(&fh, "/tmp/AudioDebug-Output.pcm", 265 260 RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 266 RTFileWrite(fh, pDbgStream->Out.pu8PlayBuffer, AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesRead), NULL);261 RTFileWrite(fh, pDbgStream->Out.pu8PlayBuffer, cbChunk, NULL); 267 262 RTFileClose(fh); 268 263 #endif 269 rc2 = DrvAudioHlpWAVFileWrite(&pDbgStream->File, 270 pDbgStream->Out.pu8PlayBuffer, AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesRead), 271 0 /* fFlags */); 264 int rc2 = DrvAudioHlpWAVFileWrite(&pDbgStream->File, 265 pDbgStream->Out.pu8PlayBuffer, cbChunk, 0 /* fFlags */); 272 266 if (RT_FAILURE(rc2)) 267 { 273 268 LogRel(("DebugAudio: Writing output failed with %Rrc\n", rc2)); 274 275 AudioMixBufFinish(&pStream->MixBuf, cSamplesRead);276 277 Assert(c SamplesAvail >= cSamplesRead);278 c SamplesAvail -= cSamplesRead;279 280 c SamplesPlayed += cSamplesRead;269 break; 270 } 271 272 Assert(cbAvail >= cbAvail); 273 cbAvail -= cbChunk; 274 275 cbWritten += cbChunk; 281 276 } 282 277 … … 285 280 286 281 if (pcbWritten) 287 *pcbWritten = c SamplesPlayed;282 *pcbWritten = cbWritten; 288 283 289 284 return VINF_SUCCESS; -
trunk/src/VBox/Devices/Audio/DrvHostNullAudio.cpp
r63711 r65565 6 6 7 7 /* 8 * Copyright (C) 2006-201 6Oracle Corporation8 * Copyright (C) 2006-2017 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 54 54 55 55 #include "DrvAudio.h" 56 #include "AudioMixBuffer.h"57 56 #include "VBoxDD.h" 58 57 … … 68 67 PDMAUDIOPCMPROPS Props; 69 68 uint64_t u64TicksLast; 70 uint64_t cMaxSamplesInPlayBuffer;71 uint8_t *pbPlayBuffer;72 69 } NULLAUDIOSTREAMOUT; 73 70 typedef NULLAUDIOSTREAMOUT *PNULLAUDIOSTREAMOUT; … … 150 147 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 151 148 */ 152 static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 149 static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, 150 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten) 153 151 { 154 152 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 155 153 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 156 157 RT_NOREF2(pvBuf, cbBuf);154 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 155 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 158 156 159 157 PDRVHOSTNULLAUDIO pDrv = RT_FROM_MEMBER(pInterface, DRVHOSTNULLAUDIO, IHostAudio); … … 161 159 162 160 /* Consume as many samples as would be played at the current frequency since last call. */ 163 uint32_t c Live = AudioMixBufLive(&pStream->MixBuf);161 uint32_t csLive = PDMAUDIOPCMPROPS_B2S(&pNullStream->Props, cbBuf); 164 162 165 163 uint64_t u64TicksNow = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); … … 174 172 * If rounding is not taken into account then the playback rate will be consistently lower that expected. 175 173 */ 176 uint64_t c SamplesPlayed = (2 * u64TicksElapsed * pNullStream->Props.uHz + u64TicksFreq) / u64TicksFreq / 2;174 uint64_t csPlayed = (2 * u64TicksElapsed * pNullStream->Props.uHz + u64TicksFreq) / u64TicksFreq / 2; 177 175 178 176 /* Don't play more than available. */ 179 if (cSamplesPlayed > cLive) 180 cSamplesPlayed = cLive; 181 182 cSamplesPlayed = RT_MIN(cSamplesPlayed, pNullStream->cMaxSamplesInPlayBuffer); 183 184 uint32_t cSamplesToRead = 0; 185 AudioMixBufReadCirc(&pStream->MixBuf, pNullStream->pbPlayBuffer, 186 AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesPlayed), &cSamplesToRead); 187 AudioMixBufFinish(&pStream->MixBuf, cSamplesToRead); 177 if (csPlayed > csLive) 178 csPlayed = csLive; 179 180 /* Note: No copying of samples needed here, as this a NULL backend. */ 188 181 189 182 if (pcbWritten) 190 *pcbWritten = cSamplesToRead;183 *pcbWritten = PDMAUDIOPCMPROPS_S2B(&pNullStream->Props, csPlayed); 191 184 192 185 return VINF_SUCCESS; … … 197 190 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture} 198 191 */ 199 static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 200 { 201 RT_NOREF4(pInterface, pStream, pvBuf, cbBuf); 202 203 /* Never capture anything. */ 192 static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, 193 PPDMAUDIOSTREAM pStream, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 194 { 195 RT_NOREF(pInterface, pStream); 196 197 RT_BZERO(pvBuf, cbBuf); 198 199 /* Return silent audio. */ 204 200 if (pcbRead) 205 *pcbRead = 0;201 *pcbRead = cbBuf; 206 202 207 203 return VINF_SUCCESS; … … 221 217 } 222 218 223 LogFlowFuncLeaveRC(rc);224 219 return rc; 225 220 } … … 235 230 { 236 231 pNullStream->u64TicksLast = 0; 237 pNullStream->cMaxSamplesInPlayBuffer = _1K; 238 239 pNullStream->pbPlayBuffer = (uint8_t *)RTMemAlloc(_1K << pNullStream->Props.cShift); 240 if (pNullStream->pbPlayBuffer) 241 { 242 if (pCfgAcq) 243 pCfgAcq->cSampleBufferSize = pNullStream->cMaxSamplesInPlayBuffer; 244 } 245 else 246 rc = VERR_NO_MEMORY; 232 233 if (pCfgAcq) 234 pCfgAcq->cSampleBufferSize = _1K; /** @todo Make this configurable. */ 247 235 } 248 236 249 LogFlowFuncLeaveRC(rc);250 237 return rc; 251 238 } … … 255 242 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 256 243 */ 257 static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 244 static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, 245 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 258 246 { 259 247 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); … … 281 269 static int nullDestroyStreamOut(PPDMAUDIOSTREAM pStream) 282 270 { 283 PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream); 284 if ( pNullStream 285 && pNullStream->pbPlayBuffer) 286 { 287 RTMemFree(pNullStream->pbPlayBuffer); 288 pNullStream->pbPlayBuffer = NULL; 289 } 290 291 LogFlowFuncLeaveRC(VINF_SUCCESS); 271 RT_NOREF(pStream); 292 272 return VINF_SUCCESS; 293 273 } -
trunk/src/VBox/Devices/Audio/DrvHostOSSAudio.cpp
r65037 r65565 5 5 6 6 /* 7 * Copyright (C) 2014-201 6Oracle Corporation7 * Copyright (C) 2014-2017 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 31 31 32 32 #include "DrvAudio.h" 33 #include "AudioMixBuffer.h"34 35 33 #include "VBoxDD.h" 36 34 … … 373 371 { 374 372 DrvAudioHlpClearBuf(&pStreamOut->Props, pStreamOut->pvBuf, pStreamOut->cbBuf, 375 AUDIOMIXBUF_B2S(&pStream->MixBuf, pStreamOut->cbBuf));373 PDMAUDIOPCMPROPS_B2S(&pStreamOut->Props, pStreamOut->cbBuf)); 376 374 377 375 int mask = PCM_ENABLE_OUTPUT; … … 431 429 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 432 430 433 POSSAUDIOSTREAMIN pStr m= (POSSAUDIOSTREAMIN)pStream;431 POSSAUDIOSTREAMIN pStreamOSS = (POSSAUDIOSTREAMIN)pStream; 434 432 435 433 int rc = VINF_SUCCESS; 436 size_t cbToRead = RT_MIN(pStrm->cbBuf, 437 AudioMixBufFreeBytes(&pStream->MixBuf));438 439 LogFlowFunc(("cbToRead=%z u\n", cbToRead));440 441 uint32_t c WrittenTotal = 0;434 435 size_t cbToRead = RT_MIN(pStreamOSS->cbBuf, cbBuf); 436 437 LogFlowFunc(("cbToRead=%zi\n", cbToRead)); 438 439 uint32_t cbReadTotal = 0; 442 440 uint32_t cbTemp; 443 441 ssize_t cbRead; … … 446 444 while (cbToRead) 447 445 { 448 cbTemp = RT_MIN(cbToRead, pStr m->cbBuf);446 cbTemp = RT_MIN(cbToRead, pStreamOSS->cbBuf); 449 447 AssertBreakStmt(cbTemp, rc = VERR_NO_DATA); 450 cbRead = read(pStr m->hFile, (uint8_t *)pStrm->pvBuf + offWrite, cbTemp);448 cbRead = read(pStreamOSS->hFile, (uint8_t *)pStreamOSS->pvBuf, cbTemp); 451 449 452 450 LogFlowFunc(("cbRead=%zi, cbTemp=%RU32, cbToRead=%zu\n", cbRead, cbTemp, cbToRead)); … … 479 477 else if (cbRead) 480 478 { 481 uint32_t cWritten; 482 rc = AudioMixBufWriteCirc(&pStream->MixBuf, pStrm->pvBuf, cbRead, &cWritten); 483 if (RT_FAILURE(rc)) 484 break; 485 486 uint32_t cbWritten = AUDIOMIXBUF_S2B(&pStream->MixBuf, cWritten); 487 488 Assert(cbToRead >= cbWritten); 489 cbToRead -= cbWritten; 490 offWrite += cbWritten; 491 cWrittenTotal += cWritten; 479 memcpy((uint8_t *)pvBuf + offWrite, pStreamOSS->pvBuf, cbRead); 480 481 Assert((ssize_t)cbToRead >= cbRead); 482 cbToRead -= cbRead; 483 offWrite += cbRead; 484 cbReadTotal += cbRead; 492 485 } 493 486 else /* No more data, try next round. */ … … 500 493 if (RT_SUCCESS(rc)) 501 494 { 502 uint32_t cProcessed = 0;503 if (cWrittenTotal)504 rc = AudioMixBufMixToParent(&pStream->MixBuf, cWrittenTotal, &cProcessed);505 506 495 if (pcbRead) 507 *pcbRead = cWrittenTotal; 508 509 LogFlowFunc(("cWrittenTotal=%RU32 (%RU32 processed), rc=%Rrc\n", 510 cWrittenTotal, cProcessed, rc)); 511 } 512 513 LogFlowFuncLeaveRC(rc); 496 *pcbRead = cbReadTotal; 497 } 498 514 499 return rc; 515 500 } … … 859 844 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 860 845 861 POSSAUDIOSTREAMOUT pStr m= (POSSAUDIOSTREAMOUT)pStream;846 POSSAUDIOSTREAMOUT pStreamOSS = (POSSAUDIOSTREAMOUT)pStream; 862 847 863 848 int rc = VINF_SUCCESS; … … 870 855 do 871 856 { 872 size_t cbBufSize = AudioMixBufSizeBytes(&pStream->MixBuf); 873 874 uint32_t csLive = AudioMixBufLive(&pStream->MixBuf); 875 uint32_t csToRead; 857 uint32_t cbAvail = PDMAUDIOPCMPROPS_S2B(&pStreamOSS->Props, cbBuf); 858 uint32_t cbToRead; 876 859 877 860 #ifndef RT_OS_L4 878 if (pStr m->fMMIO)861 if (pStreamOSS->fMMIO) 879 862 { 880 863 /* Get current playback pointer. */ 881 int rc2 = ioctl(pStr m->hFile, SNDCTL_DSP_GETOPTR, &cntinfo);864 int rc2 = ioctl(pStreamOSS->hFile, SNDCTL_DSP_GETOPTR, &cntinfo); 882 865 if (!rc2) 883 866 { … … 888 871 889 872 /* Nothing to play? */ 890 if (cntinfo.ptr == pStr m->old_optr)873 if (cntinfo.ptr == pStreamOSS->old_optr) 891 874 break; 892 875 893 876 int cbData; 894 if (cntinfo.ptr > pStr m->old_optr)895 cbData = cntinfo.ptr - pStr m->old_optr;877 if (cntinfo.ptr > pStreamOSS->old_optr) 878 cbData = cntinfo.ptr - pStreamOSS->old_optr; 896 879 else 897 cbData = cbBufSize + cntinfo.ptr - pStrm->old_optr; 898 Assert(cbData); 899 900 csToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, cbData), 901 csLive); 880 cbData = cbBuf + cntinfo.ptr - pStreamOSS->old_optr; 881 Assert(cbData >= 0); 882 883 cbToRead = RT_MIN((unsigned)cbData, cbAvail); 902 884 } 903 885 else … … 905 887 #endif 906 888 audio_buf_info abinfo; 907 int rc2 = ioctl(pStr m->hFile, SNDCTL_DSP_GETOSPACE, &abinfo);889 int rc2 = ioctl(pStreamOSS->hFile, SNDCTL_DSP_GETOSPACE, &abinfo); 908 890 if (rc2 < 0) 909 891 { … … 913 895 } 914 896 915 if ((size_t)abinfo.bytes > cbBuf Size)916 { 917 LogRel2(("OSS: Warning: Too big output size (%d > % zu), limiting to %zu\n", abinfo.bytes, cbBufSize, cbBufSize));918 abinfo.bytes = cbBuf Size;897 if ((size_t)abinfo.bytes > cbBuf) 898 { 899 LogRel2(("OSS: Warning: Too big output size (%d > %RU32), limiting to %RU32\n", abinfo.bytes, cbBuf, cbBuf)); 900 abinfo.bytes = cbBuf; 919 901 /* Keep going. */ 920 902 } … … 922 904 if (abinfo.bytes < 0) 923 905 { 924 LogRel2(("OSS: Warning: Invalid available size (%d vs. % zu)\n", abinfo.bytes, cbBufSize));906 LogRel2(("OSS: Warning: Invalid available size (%d vs. %RU32)\n", abinfo.bytes, cbBuf)); 925 907 rc = VERR_INVALID_PARAMETER; 926 908 break; 927 909 } 928 910 929 csToRead = RT_MIN((uint32_t)AUDIOMIXBUF_B2S(&pStream->MixBuf, abinfo.fragments * abinfo.fragsize), csLive); 930 if (!csToRead) 931 break; 911 cbToRead = RT_MIN(unsigned(abinfo.fragments * abinfo.fragsize), cbAvail); 932 912 #ifndef RT_OS_L4 933 913 } 934 914 #endif 935 size_t cbToRead = RT_MIN(AUDIOMIXBUF_S2B(&pStream->MixBuf, csToRead), pStrm->cbBuf);936 937 uint32_t csRead, cbRead;938 915 while (cbToRead) 939 916 { 940 rc = AudioMixBufReadCirc(&pStream->MixBuf, pStrm->pvBuf, cbToRead, &csRead); 941 if (RT_FAILURE(rc)) 942 break; 943 944 cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, csRead); 917 uint32_t cbRead = cbToRead; 918 919 memcpy(pStreamOSS->pvBuf, pvBuf, cbRead); 945 920 946 921 uint32_t cbChunk = cbRead; … … 948 923 while (cbChunk) 949 924 { 950 ssize_t cbChunkWritten = write(pStr m->hFile, (uint8_t *)pStrm->pvBuf + cbChunkOff,925 ssize_t cbChunkWritten = write(pStreamOSS->hFile, (uint8_t *)pStreamOSS->pvBuf + cbChunkOff, 951 926 RT_MIN(cbChunk, (unsigned)s_OSSConf.fragsize)); 952 927 if (cbChunkWritten < 0) … … 957 932 } 958 933 959 if (cbChunkWritten & pStr m->Props.uAlign)934 if (cbChunkWritten & pStreamOSS->Props.uAlign) 960 935 { 961 936 LogRel(("OSS: Misaligned write (written %z, expected %RU32)\n", cbChunkWritten, cbChunk)); … … 976 951 #ifndef RT_OS_L4 977 952 /* Update read pointer. */ 978 if (pStr m->fMMIO)979 pStr m->old_optr = cntinfo.ptr;953 if (pStreamOSS->fMMIO) 954 pStreamOSS->old_optr = cntinfo.ptr; 980 955 #endif 981 956 … … 984 959 if (RT_SUCCESS(rc)) 985 960 { 986 uint32_t cWrittenTotal = AUDIOMIXBUF_B2S(&pStream->MixBuf, cbWrittenTotal);987 if (cWrittenTotal)988 AudioMixBufFinish(&pStream->MixBuf, cWrittenTotal);989 990 961 if (pcbWritten) 991 962 *pcbWritten = cbWrittenTotal; 992 963 } 993 964 994 LogFlowFuncLeaveRC(rc);995 965 return rc; 996 966 } -
trunk/src/VBox/Devices/Audio/DrvHostPulseAudio.cpp
r65147 r65565 5 5 6 6 /* 7 * Copyright (C) 2006-201 6Oracle Corporation7 * Copyright (C) 2006-2017 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 38 38 39 39 #include "DrvAudio.h" 40 #include "AudioMixBuffer.h"41 42 40 #include "VBoxDD.h" 43 41 … … 101 99 * Note: Always must come first! */ 102 100 PDMAUDIOSTREAM Stream; 101 PDMAUDIOPCMPROPS Props; 103 102 /** Pointer to driver instance. */ 104 103 PDRVHOSTPULSEAUDIO pDrv; 105 /** DAC/ADC buffer. */106 void *pvPCMBuf;107 /** Size (in bytes) of DAC/ADC buffer. */108 uint32_t cbPCMBuf;109 104 /** Pointer to opaque PulseAudio stream. */ 110 105 pa_stream *pPAStream; … … 657 652 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 658 653 { 659 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);660 PPULSEAUDIOSTREAM pStr m= (PPULSEAUDIOSTREAM)pStream;654 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 655 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 661 656 662 657 LogFlowFuncEnter(); 663 658 664 pStr m->pDrainOp = NULL;665 666 pStr m->SampleSpec.format = paFmtToPulse(pCfgReq->enmFormat);667 pStr m->SampleSpec.rate = pCfgReq->uHz;668 pStr m->SampleSpec.channels = pCfgReq->cChannels;659 pStreamPA->pDrainOp = NULL; 660 661 pStreamPA->SampleSpec.format = paFmtToPulse(pCfgReq->enmFormat); 662 pStreamPA->SampleSpec.rate = pCfgReq->uHz; 663 pStreamPA->SampleSpec.channels = pCfgReq->cChannels; 669 664 670 665 /* Note that setting maxlength to -1 does not work on PulseAudio servers 671 666 * older than 0.9.10. So use the suggested value of 3/2 of tlength */ 672 pStr m->BufAttr.tlength = (pa_bytes_per_second(&pStrm->SampleSpec)667 pStreamPA->BufAttr.tlength = (pa_bytes_per_second(&pStreamPA->SampleSpec) 673 668 * s_pulseCfg.buffer_msecs_out) / 1000; 674 pStr m->BufAttr.maxlength = (pStrm->BufAttr.tlength * 3) / 2;675 pStr m->BufAttr.prebuf = -1; /* Same as tlength */676 pStr m->BufAttr.minreq = -1;669 pStreamPA->BufAttr.maxlength = (pStreamPA->BufAttr.tlength * 3) / 2; 670 pStreamPA->BufAttr.prebuf = -1; /* Same as tlength */ 671 pStreamPA->BufAttr.minreq = -1; 677 672 678 673 /* Note that the struct BufAttr is updated to the obtained values after this call! */ 679 int rc = paStreamOpen(pThis, false /* fIn */, "PulseAudio (Out)", &pStr m->SampleSpec, &pStrm->BufAttr, &pStrm->pPAStream);674 int rc = paStreamOpen(pThis, false /* fIn */, "PulseAudio (Out)", &pStreamPA->SampleSpec, &pStreamPA->BufAttr, &pStreamPA->pPAStream); 680 675 if (RT_FAILURE(rc)) 681 676 return rc; 682 677 683 rc = paPulseToFmt(pStr m->SampleSpec.format,678 rc = paPulseToFmt(pStreamPA->SampleSpec.format, 684 679 &pCfgAcq->enmFormat, &pCfgAcq->enmEndianness); 685 680 if (RT_FAILURE(rc)) 686 681 { 687 LogRel(("PulseAudio: Cannot find audio output format %ld\n", pStr m->SampleSpec.format));682 LogRel(("PulseAudio: Cannot find audio output format %ld\n", pStreamPA->SampleSpec.format)); 688 683 return rc; 689 684 } 690 685 691 pCfgAcq->uHz = pStrm->SampleSpec.rate; 692 pCfgAcq->cChannels = pStrm->SampleSpec.channels; 693 694 PDMAUDIOPCMPROPS Props; 695 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &Props); 686 pCfgAcq->uHz = pStreamPA->SampleSpec.rate; 687 pCfgAcq->cChannels = pStreamPA->SampleSpec.channels; 688 689 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamPA->Props); 696 690 if (RT_SUCCESS(rc)) 697 691 { 698 uint32_t cbBuf = RT_MIN(pStr m->BufAttr.tlength * 2,699 pStr m->BufAttr.maxlength); /** @todo Make this configurable! */692 uint32_t cbBuf = RT_MIN(pStreamPA->BufAttr.tlength * 2, 693 pStreamPA->BufAttr.maxlength); /** @todo Make this configurable! */ 700 694 if (cbBuf) 701 695 { 702 pStrm->pvPCMBuf = RTMemAllocZ(cbBuf); 703 if (pStrm->pvPCMBuf) 704 { 705 pStrm->cbPCMBuf = cbBuf; 706 pStrm->pDrv = pThis; 707 708 pCfgAcq->cSampleBufferSize = cbBuf >> Props.cShift; 709 } 710 else 711 rc = VERR_NO_MEMORY; 696 pStreamPA->pDrv = pThis; 697 698 pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pStreamPA->Props, cbBuf); 712 699 } 713 700 else … … 723 710 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 724 711 { 725 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);726 PPULSEAUDIOSTREAM p PAStrm= (PPULSEAUDIOSTREAM)pStream;727 728 p PAStrm->SampleSpec.format = paFmtToPulse(pCfgReq->enmFormat);729 p PAStrm->SampleSpec.rate = pCfgReq->uHz;730 p PAStrm->SampleSpec.channels = pCfgReq->cChannels;712 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 713 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 714 715 pStreamPA->SampleSpec.format = paFmtToPulse(pCfgReq->enmFormat); 716 pStreamPA->SampleSpec.rate = pCfgReq->uHz; 717 pStreamPA->SampleSpec.channels = pCfgReq->cChannels; 731 718 732 719 /** @todo Check these values! */ 733 p PAStrm->BufAttr.fragsize = (pa_bytes_per_second(&pPAStrm->SampleSpec) * s_pulseCfg.buffer_msecs_in) / 1000;734 p PAStrm->BufAttr.maxlength = (pPAStrm->BufAttr.fragsize * 3) / 2;720 pStreamPA->BufAttr.fragsize = (pa_bytes_per_second(&pStreamPA->SampleSpec) * s_pulseCfg.buffer_msecs_in) / 1000; 721 pStreamPA->BufAttr.maxlength = (pStreamPA->BufAttr.fragsize * 3) / 2; 735 722 736 723 /* Note: Other members of BufAttr are ignored for record streams. */ 737 int rc = paStreamOpen(pThis, true /* fIn */, "PulseAudio (In)", &p PAStrm->SampleSpec, &pPAStrm->BufAttr,738 &p PAStrm->pPAStream);724 int rc = paStreamOpen(pThis, true /* fIn */, "PulseAudio (In)", &pStreamPA->SampleSpec, &pStreamPA->BufAttr, 725 &pStreamPA->pPAStream); 739 726 if (RT_FAILURE(rc)) 740 727 return rc; 741 728 742 rc = paPulseToFmt(pPAStrm->SampleSpec.format, &pCfgAcq->enmFormat, 743 &pCfgAcq->enmEndianness); 729 rc = paPulseToFmt(pStreamPA->SampleSpec.format, &pCfgAcq->enmFormat, &pCfgAcq->enmEndianness); 744 730 if (RT_FAILURE(rc)) 745 731 { 746 LogRel(("PulseAudio: Cannot find audio capture format %ld\n", p PAStrm->SampleSpec.format));732 LogRel(("PulseAudio: Cannot find audio capture format %ld\n", pStreamPA->SampleSpec.format)); 747 733 return rc; 748 734 } 749 735 750 PDMAUDIOPCMPROPS Props; 751 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &Props); 736 rc = DrvAudioHlpStreamCfgToProps(pCfgAcq, &pStreamPA->Props); 752 737 if (RT_SUCCESS(rc)) 753 738 { 754 pPAStrm->pDrv = pThis; 755 pPAStrm->pu8PeekBuf = NULL; 756 757 pCfgAcq->uHz = pPAStrm->SampleSpec.rate; 758 pCfgAcq->cChannels = pPAStrm->SampleSpec.channels; 759 pCfgAcq->cSampleBufferSize = RT_MIN(pPAStrm->BufAttr.fragsize * 10, pPAStrm->BufAttr.maxlength) >> Props.cShift; 739 pStreamPA->pDrv = pThis; 740 pStreamPA->pu8PeekBuf = NULL; 741 742 pCfgAcq->uHz = pStreamPA->SampleSpec.rate; 743 pCfgAcq->cChannels = pStreamPA->SampleSpec.channels; 744 pCfgAcq->cSampleBufferSize = PDMAUDIOPCMPROPS_B2S(&pStreamPA->Props, 745 RT_MIN(pStreamPA->BufAttr.fragsize * 10, pStreamPA->BufAttr.maxlength)); 760 746 } 761 747 … … 774 760 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 775 761 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 762 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 763 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 776 764 /* pcbRead is optional. */ 777 765 778 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface);779 PPULSEAUDIOSTREAM pStr m= (PPULSEAUDIOSTREAM)pStream;766 PDRVHOSTPULSEAUDIO pThis = PDMIHOSTAUDIO_2_DRVHOSTPULSEAUDIO(pInterface); 767 PPULSEAUDIOSTREAM pStreamPA = (PPULSEAUDIOSTREAM)pStream; 780 768 781 769 /* We should only call pa_stream_readable_size() once and trust the first value. */ 782 770 pa_threaded_mainloop_lock(pThis->pMainLoop); 783 size_t cbAvail = pa_stream_readable_size(pStr m->pPAStream);771 size_t cbAvail = pa_stream_readable_size(pStreamPA->pPAStream); 784 772 pa_threaded_mainloop_unlock(pThis->pMainLoop); 785 773 786 774 if (cbAvail == (size_t)-1) 787 return paError(pStr m->pDrv, "Failed to determine input data size");775 return paError(pStreamPA->pDrv, "Failed to determine input data size"); 788 776 789 777 /* If the buffer was not dropped last call, add what remains. */ 790 if (pStr m->pu8PeekBuf)791 { 792 Assert(pStr m->cbPeekBuf >= pStrm->offPeekBuf);793 cbAvail += (pStr m->cbPeekBuf - pStrm->offPeekBuf);778 if (pStreamPA->pu8PeekBuf) 779 { 780 Assert(pStreamPA->cbPeekBuf >= pStreamPA->offPeekBuf); 781 cbAvail += (pStreamPA->cbPeekBuf - pStreamPA->offPeekBuf); 794 782 } 795 783 … … 805 793 int rc = VINF_SUCCESS; 806 794 807 size_t cbToRead = RT_MIN(cbAvail, AudioMixBufFreeBytes(&pStream->MixBuf));795 size_t cbToRead = RT_MIN(cbAvail, cbBuf); 808 796 809 797 Log3Func(("cbToRead=%zu, cbAvail=%zu, offPeekBuf=%zu, cbPeekBuf=%zu\n", 810 cbToRead, cbAvail, pStr m->offPeekBuf, pStrm->cbPeekBuf));811 812 uint32_t c WrittenTotal = 0;798 cbToRead, cbAvail, pStreamPA->offPeekBuf, pStreamPA->cbPeekBuf)); 799 800 uint32_t cbReadTotal = 0; 813 801 814 802 while (cbToRead) 815 803 { 816 804 /* If there is no data, do another peek. */ 817 if (!pStr m->pu8PeekBuf)805 if (!pStreamPA->pu8PeekBuf) 818 806 { 819 807 pa_threaded_mainloop_lock(pThis->pMainLoop); 820 pa_stream_peek(pStr m->pPAStream,821 (const void**)&pStr m->pu8PeekBuf, &pStrm->cbPeekBuf);808 pa_stream_peek(pStreamPA->pPAStream, 809 (const void**)&pStreamPA->pu8PeekBuf, &pStreamPA->cbPeekBuf); 822 810 pa_threaded_mainloop_unlock(pThis->pMainLoop); 823 811 824 pStr m->offPeekBuf = 0;812 pStreamPA->offPeekBuf = 0; 825 813 826 814 /* No data anymore? 827 815 * Note: If there's a data hole (cbPeekBuf then contains the length of the hole) 828 816 * we need to drop the stream lateron. */ 829 if ( !pStr m->pu8PeekBuf830 && !pStr m->cbPeekBuf)817 if ( !pStreamPA->pu8PeekBuf 818 && !pStreamPA->cbPeekBuf) 831 819 { 832 820 break; … … 834 822 } 835 823 836 Assert(pStr m->cbPeekBuf >= pStrm->offPeekBuf);837 size_t cbToWrite = RT_MIN(pStr m->cbPeekBuf - pStrm->offPeekBuf, cbToRead);824 Assert(pStreamPA->cbPeekBuf >= pStreamPA->offPeekBuf); 825 size_t cbToWrite = RT_MIN(pStreamPA->cbPeekBuf - pStreamPA->offPeekBuf, cbToRead); 838 826 839 827 Log3Func(("cbToRead=%zu, cbToWrite=%zu, offPeekBuf=%zu, cbPeekBuf=%zu, pu8PeekBuf=%p\n", 840 828 cbToRead, cbToWrite, 841 pStr m->offPeekBuf, pStrm->cbPeekBuf, pStrm->pu8PeekBuf));829 pStreamPA->offPeekBuf, pStreamPA->cbPeekBuf, pStreamPA->pu8PeekBuf)); 842 830 843 831 if (cbToWrite) 844 832 { 845 uint32_t cWritten; 846 rc = AudioMixBufWriteCirc(&pStream->MixBuf, 847 pStrm->pu8PeekBuf + pStrm->offPeekBuf, 848 cbToWrite, &cWritten); 849 if (RT_FAILURE(rc)) 850 break; 851 852 uint32_t cbWritten = AUDIOMIXBUF_S2B(&pStream->MixBuf, cWritten); 853 854 Assert(cbToRead >= cbWritten); 855 cbToRead -= cbWritten; 856 cWrittenTotal += cWritten; 857 pStrm->offPeekBuf += cbWritten; 833 memcpy((uint8_t *)pvBuf + cbReadTotal, pStreamPA->pu8PeekBuf + pStreamPA->offPeekBuf, cbToWrite); 834 835 Assert(cbToRead >= cbToWrite); 836 cbToRead -= cbToWrite; 837 cbReadTotal += cbToWrite; 838 839 pStreamPA->offPeekBuf += cbToWrite; 840 Assert(pStreamPA->offPeekBuf <= pStreamPA->cbPeekBuf); 858 841 } 859 842 … … 861 844 !cbToWrite 862 845 /* Was there a hole in the peeking buffer? Drop it. */ 863 || !pStr m->pu8PeekBuf846 || !pStreamPA->pu8PeekBuf 864 847 /* If the buffer is done, drop it. */ 865 || pStr m->offPeekBuf == pStrm->cbPeekBuf)848 || pStreamPA->offPeekBuf == pStreamPA->cbPeekBuf) 866 849 { 867 850 pa_threaded_mainloop_lock(pThis->pMainLoop); 868 pa_stream_drop(pStr m->pPAStream);851 pa_stream_drop(pStreamPA->pPAStream); 869 852 pa_threaded_mainloop_unlock(pThis->pMainLoop); 870 853 871 pStr m->pu8PeekBuf = NULL;854 pStreamPA->pu8PeekBuf = NULL; 872 855 } 873 856 } … … 875 858 if (RT_SUCCESS(rc)) 876 859 { 877 uint32_t cProcessed = 0;878 if (cWrittenTotal)879 rc = AudioMixBufMixToParent(&pStream->MixBuf, cWrittenTotal, &cProcessed);880 881 860 if (pcbRead) 882 *pcbRead = cWrittenTotal; 883 884 Log3Func(("cWrittenTotal=%RU32 (%RU32 processed), rc=%Rrc\n", 885 cWrittenTotal, cProcessed, rc)); 886 } 887 888 if (RT_FAILURE(rc)) 889 LogFunc(("Failed with %Rrc\n", rc)); 861 *pcbRead = cbReadTotal; 862 } 890 863 891 864 return rc; … … 903 876 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 904 877 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 878 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 879 AssertReturn(cbBuf, VERR_INVALID_PARAMETER); 905 880 /* pcbWritten is optional. */ 906 881 … … 909 884 910 885 int rc = VINF_SUCCESS; 911 uint32_t cbReadTotal = 0; 912 913 uint32_t cLive = AudioMixBufUsed(&pStream->MixBuf); 914 if (!cLive) 915 { 916 Log3Func(("No live samples, skipping\n")); 917 if (pcbWritten) 918 *pcbWritten = 0; 919 return VINF_SUCCESS; 920 } 886 887 uint32_t cbWrittenTotal = 0; 921 888 922 889 pa_threaded_mainloop_lock(pThis->pMainLoop); … … 931 898 } 932 899 933 size_t cbLive = AUDIOMIXBUF_S2B(&pStream->MixBuf, cLive); 934 size_t cbToRead = RT_MIN(cbWriteable, cbLive); 935 936 Log3Func(("cbToRead=%zu, cbWriteable=%zu, cbLive=%zu\n", 937 cbToRead, cbWriteable, cbLive)); 938 939 uint32_t cRead, cbRead; 940 while (cbToRead) 941 { 942 rc = AudioMixBufReadCirc(&pStream->MixBuf, pPAStream->pvPCMBuf, 943 RT_MIN(cbToRead, pPAStream->cbPCMBuf), &cRead); 944 if ( !cRead 945 || RT_FAILURE(rc)) 946 { 947 break; 948 } 949 950 cbRead = AUDIOMIXBUF_S2B(&pStream->MixBuf, cRead); 951 if (pa_stream_write(pPAStream->pPAStream, pPAStream->pvPCMBuf, cbRead, NULL /* Cleanup callback */, 900 size_t cbToWrite = RT_MIN(cbWriteable, cbBuf); 901 902 uint32_t cbWritten; 903 while (cbToWrite) 904 { 905 cbWritten = cbToWrite; 906 if (pa_stream_write(pPAStream->pPAStream, (uint8_t *)pvBuf + cbWrittenTotal, cbWritten, NULL /* Cleanup callback */, 952 907 0, PA_SEEK_RELATIVE) < 0) 953 908 { … … 956 911 } 957 912 958 Assert(cbToRead >= cbRead); 959 cbToRead -= cbRead; 960 cbReadTotal += cbRead; 961 962 Log3Func(("\tcRead=%RU32 (%zu bytes) cbReadTotal=%RU32, cbToRead=%RU32\n", 963 cRead, AUDIOMIXBUF_S2B(&pStream->MixBuf, cRead), cbReadTotal, cbToRead)); 913 Assert(cbToWrite >= cbWritten); 914 cbToWrite -= cbWritten; 915 cbWrittenTotal += cbWritten; 964 916 } 965 917 … … 970 922 if (RT_SUCCESS(rc)) 971 923 { 972 uint32_t cReadTotal = AUDIOMIXBUF_B2S(&pStream->MixBuf, cbReadTotal);973 if (cReadTotal)974 AudioMixBufFinish(&pStream->MixBuf, cReadTotal);975 976 924 if (pcbWritten) 977 *pcbWritten = cReadTotal; 978 979 Log3Func(("cReadTotal=%RU32 (%RU32 bytes), rc=%Rrc\n", cReadTotal, cbReadTotal, rc)); 980 } 981 982 if (RT_FAILURE(rc)) 983 LogFunc(("Failed with %Rrc\n", rc)); 925 *pcbWritten = cbWrittenTotal; 926 } 984 927 985 928 return rc; … … 1230 1173 1231 1174 pa_threaded_mainloop_unlock(pThis->pMainLoop); 1232 }1233 1234 if (pStrm->pvPCMBuf)1235 {1236 RTMemFree(pStrm->pvPCMBuf);1237 pStrm->pvPCMBuf = NULL;1238 pStrm->cbPCMBuf = 0;1239 1175 } 1240 1176 -
trunk/src/VBox/Devices/Audio/DrvHostValidationKit.cpp
r64510 r65565 5 5 6 6 /* 7 * Copyright (C) 2016 Oracle Corporation7 * Copyright (C) 2016-2017 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 25 25 26 26 #include "DrvAudio.h" 27 #include "AudioMixBuffer.h"28 27 #include "VBoxDD.h" 29 28
Note:
See TracChangeset
for help on using the changeset viewer.