儲存庫 vbox 的更動 62966
- 時間撮記:
- 2016-8-4 上午10:15:55 (8 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Devices/Audio/DrvHostNullAudio.cpp
r61924 r62966 41 41 * THE SOFTWARE. 42 42 */ 43 #include <iprt/alloc.h> 43 44 /********************************************************************************************************************************* 45 * Header Files * 46 *********************************************************************************************************************************/ 47 #include <iprt/mem.h> 44 48 #include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */ 45 49 … … 53 57 54 58 59 /********************************************************************************************************************************* 60 * Structures and Typedefs * 61 *********************************************************************************************************************************/ 55 62 typedef struct NULLAUDIOSTREAMOUT 56 63 { 57 /** Note: Always must come first! */58 PDMAUDIOSTREAM Stream;59 uint64_t u64TicksLast;60 uint 64_t csPlayBuffer;61 uint8_t *pu8PlayBuffer;62 } NULLAUDIOSTREAMOUT,*PNULLAUDIOSTREAMOUT;64 PDMAUDIOSTREAM Stream; 65 uint64_t u64TicksLast; 66 uint64_t csPlayBuffer; 67 uint8_t *pu8PlayBuffer; 68 } NULLAUDIOSTREAMOUT; 69 typedef NULLAUDIOSTREAMOUT *PNULLAUDIOSTREAMOUT; 63 70 64 71 typedef struct NULLAUDIOSTREAMIN 65 72 { 66 /** Note: Always must come first! */ 67 PDMAUDIOSTREAM Stream; 68 } NULLAUDIOSTREAMIN, *PNULLAUDIOSTREAMIN; 73 /** @note Always must come first! */ 74 PDMAUDIOSTREAM Stream; 75 } NULLAUDIOSTREAMIN; 76 typedef NULLAUDIOSTREAMIN *PNULLAUDIOSTREAMIN; 69 77 70 78 /** … … 75 83 { 76 84 /** Pointer to the driver instance structure. */ 77 PPDMDRVINS pDrvIns;85 PPDMDRVINS pDrvIns; 78 86 /** Pointer to host audio interface. */ 79 PDMIHOSTAUDIO IHostAudio;87 PDMIHOSTAUDIO IHostAudio; 80 88 } DRVHOSTNULLAUDIO, *PDRVHOSTNULLAUDIO; 81 89 82 /*******************************************PDM_AUDIO_DRIVER******************************/ 83 84 90 91 92 /** 93 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetConfig} 94 */ 85 95 static DECLCALLBACK(int) drvHostNullAudioGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pCfg) 86 96 { … … 101 111 } 102 112 113 114 /** 115 * @interface_method_impl{PDMIHOSTAUDIO,pfnInit} 116 */ 103 117 static DECLCALLBACK(int) drvHostNullAudioInit(PPDMIHOSTAUDIO pInterface) 104 118 { … … 109 123 } 110 124 111 static int nullCreateStreamIn(PPDMIHOSTAUDIO pInterface, 112 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples) 113 { 114 NOREF(pInterface); 115 125 126 /** 127 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay} 128 */ 129 static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, uint32_t *pcSamplesPlayed) 130 { 131 PDRVHOSTNULLAUDIO pDrv = RT_FROM_MEMBER(pInterface, DRVHOSTNULLAUDIO, IHostAudio); 132 PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream); 133 134 /* Consume as many samples as would be played at the current frequency since last call. */ 135 uint32_t cLive = AudioMixBufLive(&pStream->MixBuf); 136 137 uint64_t u64TicksNow = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); 138 uint64_t u64TicksElapsed = u64TicksNow - pNullStream->u64TicksLast; 139 uint64_t u64TicksFreq = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns); 140 141 /* Remember when samples were consumed. */ 142 pNullStream->u64TicksLast = u64TicksNow; 143 144 /* 145 * Minimize the rounding error by adding 0.5: samples = int((u64TicksElapsed * samplesFreq) / u64TicksFreq + 0.5). 146 * If rounding is not taken into account then the playback rate will be consistently lower that expected. 147 */ 148 uint64_t cSamplesPlayed = (2 * u64TicksElapsed * pStream->Props.uHz + u64TicksFreq) / u64TicksFreq / 2; 149 150 /* Don't play more than available. */ 151 if (cSamplesPlayed > cLive) 152 cSamplesPlayed = cLive; 153 154 cSamplesPlayed = RT_MIN(cSamplesPlayed, pNullStream->csPlayBuffer); 155 156 uint32_t csRead = 0; 157 AudioMixBufReadCirc(&pStream->MixBuf, pNullStream->pu8PlayBuffer, AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesPlayed), &csRead); 158 AudioMixBufFinish(&pStream->MixBuf, csRead); 159 160 if (pcSamplesPlayed) 161 *pcSamplesPlayed = csRead; 162 163 return VINF_SUCCESS; 164 } 165 166 167 /** 168 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture} 169 */ 170 static DECLCALLBACK(int) 171 drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, uint32_t *pcSamplesCaptured) 172 { 173 RT_NOREF(pInterface, pStream); 174 175 /* Never capture anything. */ 176 if (pcSamplesCaptured) 177 *pcSamplesCaptured = 0; 178 179 return VINF_SUCCESS; 180 } 181 182 183 /** 184 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus} 185 */ 186 static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostNullAudioGetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir) 187 { 188 RT_NOREF(enmDir); 189 AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN); 190 191 return PDMAUDIOBACKENDSTS_RUNNING; 192 } 193 194 195 static int nullCreateStreamIn(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples) 196 { 116 197 /* Just adopt the wanted stream configuration. */ 117 198 int rc = DrvAudioHlpStreamCfgToProps(pCfg, &pStream->Props); … … 126 207 } 127 208 128 static int nullCreateStreamOut(PPDMIHOSTAUDIO pInterface, 129 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, 130 uint32_t *pcSamples) 131 { 132 NOREF(pInterface); 133 209 210 static int nullCreateStreamOut(PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples) 211 { 134 212 /* Just adopt the wanted stream configuration. */ 135 213 int rc = DrvAudioHlpStreamCfgToProps(pCfg, &pStream->Props); 136 214 if (RT_SUCCESS(rc)) 137 215 { 138 PNULLAUDIOSTREAMOUT pNullStream = (PNULLAUDIOSTREAMOUT)pStream;216 PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream); 139 217 pNullStream->u64TicksLast = 0; 140 218 pNullStream->csPlayBuffer = _1K; … … 153 231 } 154 232 155 static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, 156 uint32_t *pcSamplesPlayed) 157 { 158 PDRVHOSTNULLAUDIO pDrv = RT_FROM_MEMBER(pInterface, DRVHOSTNULLAUDIO, IHostAudio); 159 PNULLAUDIOSTREAMOUT pNullStream = (PNULLAUDIOSTREAMOUT)pStream; 160 161 /* Consume as many samples as would be played at the current frequency since last call. */ 162 uint32_t cLive = AudioMixBufLive(&pStream->MixBuf); 163 164 uint64_t u64TicksNow = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); 165 uint64_t u64TicksElapsed = u64TicksNow - pNullStream->u64TicksLast; 166 uint64_t u64TicksFreq = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns); 167 168 /* Remember when samples were consumed. */ 169 pNullStream->u64TicksLast = u64TicksNow; 170 171 /* 172 * Minimize the rounding error by adding 0.5: samples = int((u64TicksElapsed * samplesFreq) / u64TicksFreq + 0.5). 173 * If rounding is not taken into account then the playback rate will be consistently lower that expected. 174 */ 175 uint64_t cSamplesPlayed = (2 * u64TicksElapsed * pStream->Props.uHz + u64TicksFreq) / u64TicksFreq / 2; 176 177 /* Don't play more than available. */ 178 if (cSamplesPlayed > cLive) 179 cSamplesPlayed = cLive; 180 181 cSamplesPlayed = RT_MIN(cSamplesPlayed, pNullStream->csPlayBuffer); 182 183 uint32_t csRead = 0; 184 AudioMixBufReadCirc(&pStream->MixBuf, pNullStream->pu8PlayBuffer, 185 AUDIOMIXBUF_S2B(&pStream->MixBuf, cSamplesPlayed), &csRead); 186 AudioMixBufFinish(&pStream->MixBuf, csRead); 187 188 if (pcSamplesPlayed) 189 *pcSamplesPlayed = csRead; 190 191 return VINF_SUCCESS; 192 } 193 194 static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, 195 uint32_t *pcSamplesCaptured) 196 { 197 /* Never capture anything. */ 198 if (pcSamplesCaptured) 199 *pcSamplesCaptured = 0; 200 201 return VINF_SUCCESS; 202 } 203 204 static int nullDestroyStreamIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 233 234 /** 235 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 236 */ 237 static DECLCALLBACK(int) 238 drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples) 239 { 240 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 241 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 242 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 243 244 int rc; 245 if (pCfg->enmDir == PDMAUDIODIR_IN) 246 rc = nullCreateStreamIn( pStream, pCfg, pcSamples); 247 else 248 rc = nullCreateStreamOut(pStream, pCfg, pcSamples); 249 250 LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc)); 251 return rc; 252 } 253 254 255 static int nullDestroyStreamIn(void) 205 256 { 206 257 LogFlowFuncLeaveRC(VINF_SUCCESS); … … 208 259 } 209 260 210 static int nullDestroyStreamOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 211 { 212 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface); 213 214 PNULLAUDIOSTREAMOUT pNullStream = (PNULLAUDIOSTREAMOUT)pStream; 261 262 static int nullDestroyStreamOut(PPDMAUDIOSTREAM pStream) 263 { 264 PNULLAUDIOSTREAMOUT pNullStream = RT_FROM_MEMBER(pStream, NULLAUDIOSTREAMOUT, Stream); 215 265 if ( pNullStream 216 266 && pNullStream->pu8PlayBuffer) … … 224 274 } 225 275 226 static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostNullAudioGetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir) 227 { 228 AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN); 229 230 return PDMAUDIOBACKENDSTS_RUNNING; 231 } 232 233 static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, 234 PPDMAUDIOSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg, uint32_t *pcSamples) 276 277 /** 278 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 279 */ 280 static DECLCALLBACK(int) drvHostNullAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 235 281 { 236 282 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 237 283 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 238 AssertPtrReturn(pCfg, VERR_INVALID_POINTER);239 284 240 285 int rc; 241 if (p Cfg->enmDir == PDMAUDIODIR_IN)242 rc = null CreateStreamIn(pInterface, pStream, pCfg, pcSamples);286 if (pStream->enmDir == PDMAUDIODIR_IN) 287 rc = nullDestroyStreamIn(); 243 288 else 244 rc = nullCreateStreamOut(pInterface, pStream, pCfg, pcSamples); 245 246 LogFlowFunc(("%s: rc=%Rrc\n", pStream->szName, rc)); 289 rc = nullDestroyStreamOut(pStream); 290 247 291 return rc; 248 292 } 249 293 250 static DECLCALLBACK(int) drvHostNullAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 251 { 294 295 /** 296 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 297 */ 298 static DECLCALLBACK(int) 299 drvHostNullAudioStreamControl(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 300 { 301 RT_NOREF(enmStreamCmd); 252 302 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 253 303 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 254 304 255 int rc;256 if (pStream->enmDir == PDMAUDIODIR_IN)257 rc = nullDestroyStreamIn(pInterface, pStream);258 else259 rc = nullDestroyStreamOut(pInterface, pStream);260 261 return rc;262 }263 264 static DECLCALLBACK(int) drvHostNullAudioStreamControl(PPDMIHOSTAUDIO pInterface,265 PPDMAUDIOSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)266 {267 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);268 AssertPtrReturn(pStream, VERR_INVALID_POINTER);269 270 305 Assert(pStream->enmCtx == PDMAUDIOSTREAMCTX_HOST); 271 306 … … 273 308 } 274 309 310 311 /** 312 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 313 */ 275 314 static DECLCALLBACK(PDMAUDIOSTRMSTS) drvHostNullAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 315 { 316 RT_NOREF(pInterface, pStream); 317 return PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED 318 | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE; 319 } 320 321 322 /** 323 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate} 324 */ 325 static DECLCALLBACK(int) drvHostNullAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 276 326 { 277 327 NOREF(pInterface); 278 328 NOREF(pStream); 279 329 280 return ( PDMAUDIOSTRMSTS_FLAG_INITIALIZED | PDMAUDIOSTRMSTS_FLAG_ENABLED 281 | PDMAUDIOSTRMSTS_FLAG_DATA_READABLE | PDMAUDIOSTRMSTS_FLAG_DATA_WRITABLE); 282 } 283 284 static DECLCALLBACK(int) drvHostNullAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOSTREAM pStream) 285 { 286 NOREF(pInterface); 287 NOREF(pStream); 288 289 return VINF_SUCCESS; 290 } 330 return VINF_SUCCESS; 331 } 332 333 334 /** 335 * @interface_method_impl{PDMIHOSTAUDIO,pfnShutdown} 336 */ 337 static DECLCALLBACK(void) drvHostNullAudioShutdown(PPDMIHOSTAUDIO pInterface) 338 { 339 RT_NOREF(pInterface); 340 } 341 291 342 292 343 /** … … 303 354 } 304 355 305 static DECLCALLBACK(void) drvHostNullAudioShutdown(PPDMIHOSTAUDIO pInterface)306 {307 NOREF(pInterface);308 }309 356 310 357 /** … … 315 362 static DECLCALLBACK(int) drvHostNullAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) 316 363 { 364 RT_NOREF(pCfg, fFlags); 365 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); 317 366 AssertPtrReturn(pDrvIns, VERR_INVALID_POINTER); 318 367 /* pCfg is optional. */
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器