Changeset 89779 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Jun 18, 2021 2:02:38 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 145232
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioMixer.cpp
r89768 r89779 945 945 * 946 946 * @returns VBox status code. 947 * @param pSink The sink to set audio format for. 948 * @param pProps The properties of the new audio format (guest side). 949 */ 950 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pProps) 947 * @param pSink The sink to set audio format for. 948 * @param pProps The properties of the new audio format (guest side). 949 * @param cMsSchedulingHint Scheduling hint for mixer buffer sizing. 950 */ 951 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pProps, uint32_t cMsSchedulingHint) 951 952 { 952 953 AssertPtrReturn(pSink, VERR_INVALID_POINTER); … … 955 956 AssertReturn(AudioHlpPcmPropsAreValid(pProps), VERR_INVALID_PARAMETER); 956 957 958 /* 959 * Calculate the mixer buffer size so we can force a recreation if it changes. 960 * 961 * This used to be fixed at 100ms, however that's usually too generous and can 962 * in theory be too small. Generally, we size the buffer at 3 DMA periods as 963 * that seems reasonable. Now, since the we don't quite trust the scheduling 964 * hint we're getting, make sure we're got a minimum of 30ms buffer space, but 965 * no more than 500ms. 966 */ 967 if (cMsSchedulingHint <= 10) 968 cMsSchedulingHint = 30; 969 else 970 { 971 cMsSchedulingHint *= 3; 972 if (cMsSchedulingHint > 500) 973 cMsSchedulingHint = 500; 974 } 975 uint32_t const cBufferFrames = PDMAudioPropsMilliToFrames(pProps, cMsSchedulingHint); 976 /** @todo configuration override on the buffer size? */ 977 957 978 int rc = RTCritSectEnter(&pSink->CritSect); 958 979 AssertRCReturn(rc, rc); … … 960 981 /* 961 982 * Do nothing unless the format actually changed. 962 */ 963 if (!PDMAudioPropsAreEqual(&pSink->PCMProps, pProps)) 983 * The buffer size must not match exactly, within +/- 2% is okay. 984 */ 985 uint32_t cOldBufferFrames; 986 if ( !PDMAudioPropsAreEqual(&pSink->PCMProps, pProps) 987 || ( cBufferFrames != (cOldBufferFrames = AudioMixBufSize(&pSink->MixBuf)) 988 && (uint32_t)RT_ABS((int32_t)(cBufferFrames - cOldBufferFrames)) > cBufferFrames / 50) ) 964 989 { 965 990 #ifdef LOG_ENABLED … … 967 992 #endif 968 993 if (PDMAudioPropsHz(&pSink->PCMProps) != 0) 969 LogFlowFunc(("[%s] Old format: %s\n", pSink->pszName, PDMAudioPropsToString(&pSink->PCMProps, szTmp, sizeof(szTmp)) )); 994 LogFlowFunc(("[%s] Old format: %s; buffer: %u frames\n", pSink->pszName, 995 PDMAudioPropsToString(&pSink->PCMProps, szTmp, sizeof(szTmp)), AudioMixBufSize(&pSink->MixBuf) )); 970 996 pSink->PCMProps = *pProps; 971 LogFlowFunc(("[%s] New format: %s\n", pSink->pszName, PDMAudioPropsToString(&pSink->PCMProps, szTmp, sizeof(szTmp)) )); 997 LogFlowFunc(("[%s] New format: %s; buffer: %u frames\n", pSink->pszName, 998 PDMAudioPropsToString(&pSink->PCMProps, szTmp, sizeof(szTmp)), cBufferFrames )); 972 999 973 1000 /* … … 976 1003 AudioMixBufTerm(&pSink->MixBuf); 977 1004 978 /** @todo r=bird: Make sure we've got more room here than what's expected to 979 * be moved in one guest DMA period. */ 980 rc = AudioMixBufInit(&pSink->MixBuf, pSink->pszName, &pSink->PCMProps, 981 PDMAudioPropsMilliToFrames(&pSink->PCMProps, 100 /*ms*/)); /** @todo Make this configurable? */ 1005 rc = AudioMixBufInit(&pSink->MixBuf, pSink->pszName, &pSink->PCMProps, cBufferFrames); 982 1006 if (RT_SUCCESS(rc)) 983 1007 { -
trunk/src/VBox/Devices/Audio/AudioMixer.h
r89371 r89779 298 298 bool AudioMixerSinkIsActive(PAUDMIXSINK pSink); 299 299 void AudioMixerSinkReset(PAUDMIXSINK pSink); 300 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pPCMProps );300 int AudioMixerSinkSetFormat(PAUDMIXSINK pSink, PCPDMAUDIOPCMPROPS pPCMProps, uint32_t cMsSchedulingHint); 301 301 int AudioMixerSinkSetVolume(PAUDMIXSINK pSink, PCPDMAUDIOVOLUME pVol); 302 302 int AudioMixerSinkUpdate(PAUDMIXSINK pSink, uint32_t cbDmaUsed, uint32_t cbDmaPeriod); -
trunk/src/VBox/Devices/Audio/DevHda.cpp
r89768 r89779 2348 2348 LogFunc(("Sink=%s, Stream=%s\n", pMixSink->pszName, pCfg->szName)); 2349 2349 2350 if (!AudioHlpStreamCfgIsValid(pCfg)) 2351 return VERR_INVALID_PARAMETER; 2352 2353 int rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props); 2354 if (RT_SUCCESS(rc)) 2355 { 2356 PHDADRIVER pDrv; 2357 RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node) 2358 { 2359 /* We ignore failures here because one non-working driver shouldn't 2360 be allowed to spoil it for everyone else. */ 2361 int rc2 = hdaR3MixerAddDrvStream(pDevIns, pMixSink, pCfg, pDrv); 2362 if (RT_FAILURE(rc2)) 2363 LogFunc(("Attaching stream failed with %Rrc (ignored)\n", rc2)); 2364 } 2365 } 2350 int rc; 2351 if (AudioHlpStreamCfgIsValid(pCfg)) 2352 { 2353 rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props, pCfg->Device.cMsSchedulingHint); 2354 if (RT_SUCCESS(rc)) 2355 { 2356 PHDADRIVER pDrv; 2357 RTListForEach(&pThisCC->lstDrv, pDrv, HDADRIVER, Node) 2358 { 2359 /* We ignore failures here because one non-working driver shouldn't 2360 be allowed to spoil it for everyone else. */ 2361 int rc2 = hdaR3MixerAddDrvStream(pDevIns, pMixSink, pCfg, pDrv); 2362 if (RT_FAILURE(rc2)) 2363 LogFunc(("Attaching stream failed with %Rrc (ignored)\n", rc2)); 2364 } 2365 } 2366 } 2367 else 2368 rc = VERR_INVALID_PARAMETER; 2366 2369 return rc; 2367 2370 } -
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r89778 r89779 1839 1839 if (AudioHlpStreamCfgIsValid(pCfg)) 1840 1840 { 1841 rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props );1841 rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props, pCfg->Device.cMsSchedulingHint); 1842 1842 if (RT_SUCCESS(rc)) 1843 1843 { -
trunk/src/VBox/Devices/Audio/DevSB16.cpp
r89768 r89779 1795 1795 AssertPtrReturn(pMixSink, VERR_INVALID_POINTER); 1796 1796 1797 if (!AudioHlpStreamCfgIsValid(pCfg)) 1798 return VERR_INVALID_PARAMETER; 1799 1800 int rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props); 1801 if (RT_FAILURE(rc)) 1802 return rc; 1803 1804 PSB16DRIVER pDrv; 1805 RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node) 1806 { 1807 int rc2 = sb16AddDrvStream(pDevIns, pMixSink, pCfg, pDrv); 1808 if (RT_FAILURE(rc2)) 1809 LogFunc(("Attaching stream failed with %Rrc\n", rc2)); 1810 1811 /* Do not pass failure to rc here, as there might be drivers which aren't 1812 * configured / ready yet. */ 1813 } 1797 int rc; 1798 if (AudioHlpStreamCfgIsValid(pCfg)) 1799 { 1800 rc = AudioMixerSinkSetFormat(pMixSink, &pCfg->Props, pCfg->Device.cMsSchedulingHint); 1801 if (RT_SUCCESS(rc)) 1802 { 1803 PSB16DRIVER pDrv; 1804 RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node) 1805 { 1806 int rc2 = sb16AddDrvStream(pDevIns, pMixSink, pCfg, pDrv); 1807 if (RT_FAILURE(rc2)) 1808 LogFunc(("Attaching stream failed with %Rrc\n", rc2)); 1809 1810 /* Do not pass failure to rc here, as there might be drivers which aren't 1811 * configured / ready yet. */ 1812 } 1813 } 1814 } 1815 else 1816 rc = VERR_INVALID_PARAMETER; 1814 1817 1815 1818 LogFlowFuncLeaveRC(rc);
Note:
See TracChangeset
for help on using the changeset viewer.