Changeset 88456 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Apr 12, 2021 8:16:24 AM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 143708
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvHostAudioNull.cpp
r88390 r88456 1 1 /* $Id$ */ 2 2 /** @file 3 * Host audio driver - NULL .3 * Host audio driver - NULL (bitbucket). 4 4 * 5 5 * This also acts as a fallback if no other backend is available. … … 16 16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the 17 17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 18 * --------------------------------------------------------------------19 *20 * This code is based on: noaudio.c QEMU based code.21 *22 * QEMU Timer based audio emulation23 *24 * Copyright (c) 2004-2005 Vassili Karpov (malc)25 *26 * Permission is hereby granted, free of charge, to any person obtaining a copy27 * of this software and associated documentation files (the "Software"), to deal28 * in the Software without restriction, including without limitation the rights29 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell30 * copies of the Software, and to permit persons to whom the Software is31 * furnished to do so, subject to the following conditions:32 *33 * The above copyright notice and this permission notice shall be included in34 * all copies or substantial portions of the Software.35 *36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR37 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,38 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL39 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER40 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,41 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN42 * THE SOFTWARE.43 18 */ 44 19 … … 61 36 * Structures and Typedefs * 62 37 *********************************************************************************************************************************/ 38 /** Null audio stream. */ 63 39 typedef struct NULLAUDIOSTREAM 64 40 { 65 41 /** The stream's acquired configuration. */ 66 PPDMAUDIOSTREAMCFG pCfg; 67 } NULLAUDIOSTREAM, *PNULLAUDIOSTREAM; 42 PDMAUDIOSTREAMCFG Cfg; 43 } NULLAUDIOSTREAM; 44 /** Pointer to a null audio stream. */ 45 typedef NULLAUDIOSTREAM *PNULLAUDIOSTREAM; 68 46 69 47 /** … … 77 55 /** Pointer to host audio interface. */ 78 56 PDMIHOSTAUDIO IHostAudio; 79 } DRVHOSTNULLAUDIO, *PDRVHOSTNULLAUDIO; 57 } DRVHOSTNULLAUDIO; 58 /** Pointer to the instance data for a null audio host driver. */ 59 typedef DRVHOSTNULLAUDIO *PDRVHOSTNULLAUDIO; 80 60 81 61 … … 89 69 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER); 90 70 91 RTStr Printf2(pBackendCfg->szName, sizeof(pBackendCfg->szName), "NULL audio");71 RTStrCopy(pBackendCfg->szName, sizeof(pBackendCfg->szName), "NULL audio"); 92 72 93 73 pBackendCfg->cbStreamOut = sizeof(NULLAUDIOSTREAM); … … 106 86 static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostNullAudioHA_GetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir) 107 87 { 108 RT_NOREF(enmDir); 109 AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN); 110 88 RT_NOREF(pInterface, enmDir); 111 89 return PDMAUDIOBACKENDSTS_RUNNING; 90 } 91 92 93 /** 94 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 95 */ 96 static DECLCALLBACK(int) drvHostNullAudioHA_StreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 97 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 98 { 99 RT_NOREF(pInterface); 100 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream; 101 AssertPtrReturn(pStreamNull, VERR_INVALID_POINTER); 102 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 103 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 104 105 PDMAudioStrmCfgCopy(&pStreamNull->Cfg, pCfgAcq); 106 return VINF_SUCCESS; 107 } 108 109 110 /** 111 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 112 */ 113 static DECLCALLBACK(int) drvHostNullAudioHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 114 { 115 RT_NOREF(pInterface, pStream); 116 return VINF_SUCCESS; 117 } 118 119 120 /** 121 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 122 */ 123 static DECLCALLBACK(int) drvHostNullAudioHA_StreamControl(PPDMIHOSTAUDIO pInterface, 124 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 125 { 126 RT_NOREF(pInterface, pStream, enmStreamCmd); 127 return VINF_SUCCESS; 128 } 129 130 131 /** 132 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable} 133 */ 134 static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 135 { 136 RT_NOREF(pInterface, pStream); 137 /** @todo rate limit this? */ 138 return UINT32_MAX; 139 } 140 141 142 /** 143 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable} 144 */ 145 static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 146 { 147 RT_NOREF(pInterface, pStream); 148 return UINT32_MAX; 149 } 150 151 152 /** 153 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetPending} 154 */ 155 static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetPending(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 156 { 157 RT_NOREF(pInterface, pStream); 158 return 0; 159 } 160 161 162 /** 163 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 164 */ 165 static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostNullAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 166 { 167 RT_NOREF(pInterface, pStream); 168 return PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED | PDMAUDIOSTREAMSTS_FLAGS_ENABLED; 112 169 } 113 170 … … 131 188 */ 132 189 static DECLCALLBACK(int) drvHostNullAudioHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 133 void *pvBuf, uint32_t uBufSize, uint32_t *puRead) 134 { 135 RT_NOREF(pInterface, pStream); 136 190 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 191 { 192 RT_NOREF(pInterface); 137 193 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream; 138 194 195 /** @todo rate limit this? */ 196 139 197 /* Return silence. */ 140 Assert(pStreamNull->pCfg); 141 PDMAudioPropsClearBuffer(&pStreamNull->pCfg->Props, pvBuf, uBufSize, PDMAUDIOPCMPROPS_B2F(&pStreamNull->pCfg->Props, uBufSize)); 142 143 if (puRead) 144 *puRead = uBufSize; 145 146 return VINF_SUCCESS; 147 } 148 149 150 static int nullCreateStreamIn(PNULLAUDIOSTREAM pStreamNull, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 151 { 152 RT_NOREF(pStreamNull, pCfgReq, pCfgAcq); 153 154 return VINF_SUCCESS; 155 } 156 157 158 static int nullCreateStreamOut(PNULLAUDIOSTREAM pStreamNull, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 159 { 160 RT_NOREF(pStreamNull, pCfgReq, pCfgAcq); 161 162 return VINF_SUCCESS; 163 } 164 165 166 /** 167 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate} 168 */ 169 static DECLCALLBACK(int) drvHostNullAudioHA_StreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 170 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 171 { 172 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 173 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 174 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 175 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 176 177 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream; 178 179 int rc; 180 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 181 rc = nullCreateStreamIn( pStreamNull, pCfgReq, pCfgAcq); 182 else 183 rc = nullCreateStreamOut(pStreamNull, pCfgReq, pCfgAcq); 184 185 if (RT_SUCCESS(rc)) 186 { 187 pStreamNull->pCfg = PDMAudioStrmCfgDup(pCfgAcq); 188 if (!pStreamNull->pCfg) 189 rc = VERR_NO_MEMORY; 190 } 191 192 return rc; 193 } 194 195 196 static int nullDestroyStreamIn(void) 197 { 198 LogFlowFuncLeaveRC(VINF_SUCCESS); 199 return VINF_SUCCESS; 200 } 201 202 203 static int nullDestroyStreamOut(PNULLAUDIOSTREAM pStreamNull) 204 { 205 RT_NOREF(pStreamNull); 206 return VINF_SUCCESS; 207 } 208 209 210 /** 211 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 212 */ 213 static DECLCALLBACK(int) drvHostNullAudioHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 214 { 215 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 216 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 217 218 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream; 219 220 if (!pStreamNull->pCfg) /* Not (yet) configured? Skip. */ 221 return VINF_SUCCESS; 222 223 int rc; 224 if (pStreamNull->pCfg->enmDir == PDMAUDIODIR_IN) 225 rc = nullDestroyStreamIn(); 226 else 227 rc = nullDestroyStreamOut(pStreamNull); 228 229 if (RT_SUCCESS(rc)) 230 { 231 PDMAudioStrmCfgFree(pStreamNull->pCfg); 232 pStreamNull->pCfg = NULL; 233 } 234 235 return rc; 236 } 237 238 239 /** 240 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 241 */ 242 static DECLCALLBACK(int) drvHostNullAudioHA_StreamControl(PPDMIHOSTAUDIO pInterface, 243 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 244 { 245 RT_NOREF(pInterface, pStream, enmStreamCmd); 246 return VINF_SUCCESS; 247 } 248 249 250 /** 251 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable} 252 */ 253 static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 254 { 255 RT_NOREF(pInterface, pStream); 256 257 return UINT32_MAX; 258 } 259 260 261 /** 262 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable} 263 */ 264 static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 265 { 266 RT_NOREF(pInterface, pStream); 267 268 return UINT32_MAX; 269 } 270 271 272 /** 273 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 274 */ 275 static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostNullAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 276 { 277 RT_NOREF(pInterface, pStream); 278 return PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED | PDMAUDIOSTREAMSTS_FLAGS_ENABLED; 198 PDMAudioPropsClearBuffer(&pStreamNull->Cfg.Props, pvBuf, cbBuf, 199 PDMAudioPropsBytesToFrames(&pStreamNull->Cfg.Props, cbBuf)); 200 *pcbRead = cbBuf; 201 return VINF_SUCCESS; 279 202 } 280 203 … … 301 224 static DECLCALLBACK(int) drvHostNullAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) 302 225 { 226 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); 227 PDRVHOSTNULLAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTNULLAUDIO); 303 228 RT_NOREF(pCfg, fFlags); 304 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);305 AssertPtrReturn(pDrvIns, VERR_INVALID_POINTER);306 /* pCfg is optional. */307 308 PDRVHOSTNULLAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTNULLAUDIO);309 229 LogRel(("Audio: Initializing NULL driver\n")); 310 230 … … 317 237 /* IHostAudio */ 318 238 pThis->IHostAudio.pfnGetConfig = drvHostNullAudioHA_GetConfig; 239 pThis->IHostAudio.pfnGetDevices = NULL; 319 240 pThis->IHostAudio.pfnGetStatus = drvHostNullAudioHA_GetStatus; 320 241 pThis->IHostAudio.pfnStreamCreate = drvHostNullAudioHA_StreamCreate; … … 323 244 pThis->IHostAudio.pfnStreamGetReadable = drvHostNullAudioHA_StreamGetReadable; 324 245 pThis->IHostAudio.pfnStreamGetWritable = drvHostNullAudioHA_StreamGetWritable; 246 pThis->IHostAudio.pfnStreamGetPending = drvHostNullAudioHA_StreamGetPending; 325 247 pThis->IHostAudio.pfnStreamGetStatus = drvHostNullAudioHA_StreamGetStatus; 326 248 pThis->IHostAudio.pfnStreamPlay = drvHostNullAudioHA_StreamPlay; 327 249 pThis->IHostAudio.pfnStreamCapture = drvHostNullAudioHA_StreamCapture; 328 pThis->IHostAudio.pfnGetDevices = NULL;329 pThis->IHostAudio.pfnStreamGetPending = NULL;330 250 331 251 return VINF_SUCCESS; -
trunk/src/VBox/Devices/Audio/DrvHostAudioValidationKit.cpp
r88394 r88456 16 16 */ 17 17 18 #include <iprt/alloc.h> 18 19 /********************************************************************************************************************************* 20 * Defined Constants And Macros * 21 *********************************************************************************************************************************/ 22 #define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO 23 #include <iprt/env.h> 24 #include <iprt/mem.h> 25 #include <iprt/path.h> 26 #include <iprt/stream.h> 19 27 #include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */ 20 28 21 #define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO22 29 #include <VBox/log.h> 23 30 #include <VBox/vmm/pdmaudioifs.h> … … 28 35 29 36 30 /** 31 * Structure for keeping a VAKIT input/output stream. 37 /********************************************************************************************************************************* 38 * Structures and Typedefs * 39 *********************************************************************************************************************************/ 40 /** 41 * Structure for keeping a validation kit input/output stream. 32 42 */ 33 43 typedef struct VAKITAUDIOSTREAM 34 44 { 35 45 /** The stream's acquired configuration. */ 36 PPDMAUDIOSTREAMCFG pCfg;46 PPDMAUDIOSTREAMCFG pCfg; 37 47 /** Audio file to dump output to or read input from. */ 38 P PDMAUDIOFILEpFile;48 PAUDIOHLPFILE pFile; 39 49 /** Text file to store timing of audio buffers submittions. */ 40 RTFILE hFileTiming;50 PRTSTREAM pFileTiming; 41 51 /** Timestamp of the first play or record request. */ 42 uint64_t tsStarted;52 uint64_t tsStarted; 43 53 /** Total number of frames played or recorded so far. */ 44 uint32_t cFramesSinceStarted;54 uint32_t cFramesSinceStarted; 45 55 union 46 56 { … … 48 58 { 49 59 /** Timestamp of last captured samples. */ 50 uint64_t tsLastCaptured;60 uint64_t tsLastCaptured; 51 61 } In; 52 62 struct 53 63 { 54 64 /** Timestamp of last played samples. */ 55 uint64_t tsLastPlayed;56 uint8_t *pu8PlayBuffer;57 uint32_t cbPlayBuffer;65 uint64_t tsLastPlayed; 66 uint8_t *pbPlayBuffer; 67 uint32_t cbPlayBuffer; 58 68 } Out; 59 69 }; 60 } VAKITAUDIOSTREAM, *PVAKITAUDIOSTREAM; 61 62 /** 63 * VAKIT audio driver instance data. 70 } VAKITAUDIOSTREAM; 71 /** Pointer to a validation kit stream. */ 72 typedef VAKITAUDIOSTREAM *PVAKITAUDIOSTREAM; 73 74 /** 75 * Validation kit audio driver instance data. 64 76 * @implements PDMIAUDIOCONNECTOR 65 77 */ … … 67 79 { 68 80 /** Pointer to the driver instance structure. */ 69 PPDMDRVINS pDrvIns;81 PPDMDRVINS pDrvIns; 70 82 /** Pointer to host audio interface. */ 71 PDMIHOSTAUDIO IHostAudio; 72 } DRVHOSTVAKITAUDIO, *PDRVHOSTVAKITAUDIO; 73 74 /*******************************************PDM_AUDIO_DRIVER******************************/ 83 PDMIHOSTAUDIO IHostAudio; 84 } DRVHOSTVAKITAUDIO; 85 /** Pointer to a validation kit host audio driver instance. */ 86 typedef DRVHOSTVAKITAUDIO *PDRVHOSTVAKITAUDIO; 87 75 88 76 89 … … 107 120 108 121 109 static int drvHostValKitAudioCreateStreamIn(PDRVHOSTVAKITAUDIO p Drv, PVAKITAUDIOSTREAM pStreamDbg,122 static int drvHostValKitAudioCreateStreamIn(PDRVHOSTVAKITAUDIO pThis, PVAKITAUDIOSTREAM pStreamDbg, 110 123 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 111 124 { 112 RT_NOREF(p Drv, pStreamDbg, pCfgReq, pCfgAcq);113 114 return VINF_SUCCESS; 115 } 116 117 118 static int drvHostValKitAudioCreateStreamOut(PDRVHOSTVAKITAUDIO p Drv, PVAKITAUDIOSTREAM pStreamDbg,125 RT_NOREF(pThis, pStreamDbg, pCfgReq, pCfgAcq); 126 127 return VINF_SUCCESS; 128 } 129 130 131 static int drvHostValKitAudioCreateStreamOut(PDRVHOSTVAKITAUDIO pThis, PVAKITAUDIOSTREAM pStreamDbg, 119 132 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 120 133 { 121 RT_NOREF(pDrv, pCfgAcq); 122 123 pStreamDbg->tsStarted = 0; 134 RT_NOREF(pThis, pCfgAcq); 135 136 /* Use the test box scratch dir if we're running in such an 137 environment, otherwise just dump the output in the temp 138 directory. */ 139 char szTemp[RTPATH_MAX]; 140 int rc = RTEnvGetEx(RTENV_DEFAULT, "TESTBOX_PATH_SCRATCH", szTemp, sizeof(szTemp), NULL); 141 if (RT_FAILURE(rc)) 142 { 143 rc = RTPathTemp(szTemp, sizeof(szTemp)); 144 if (RT_SUCCESS(rc)) 145 rc = RTPathAppend(szTemp, sizeof(szTemp), "VBoxAudioValKit"); 146 AssertRCReturn(rc, rc); 147 } 148 149 /* Get down to things that may fail and need cleanup. */ 150 pStreamDbg->tsStarted = 0; 124 151 pStreamDbg->cFramesSinceStarted = 0; 125 pStreamDbg->Out.tsLastPlayed = 0; 126 pStreamDbg->Out.cbPlayBuffer = PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize); 127 pStreamDbg->Out.pu8PlayBuffer = (uint8_t *)RTMemAlloc(pStreamDbg->Out.cbPlayBuffer); 128 AssertReturn(pStreamDbg->Out.pu8PlayBuffer, VERR_NO_MEMORY); 129 130 char szTemp[RTPATH_MAX]; 131 int rc = RTPathTemp(szTemp, sizeof(szTemp)); 152 pStreamDbg->Out.tsLastPlayed = 0; 153 pStreamDbg->Out.cbPlayBuffer = PDMAudioPropsFramesToBytes(&pCfgReq->Props, pCfgReq->Backend.cFramesBufferSize); 154 pStreamDbg->Out.pbPlayBuffer = (uint8_t *)RTMemAlloc(pStreamDbg->Out.cbPlayBuffer); 155 AssertReturn(pStreamDbg->Out.pbPlayBuffer, VERR_NO_MEMORY); 156 157 rc = AudioHlpFileCreateAndOpenEx(&pStreamDbg->pFile, AUDIOHLPFILETYPE_WAV, szTemp, "ValKit", 158 pThis->pDrvIns->iInstance, AUDIOHLPFILENAME_FLAGS_NONE, AUDIOHLPFILE_FLAGS_NONE, 159 &pCfgReq->Props, AUDIOHLPFILE_DEFAULT_OPEN_FLAGS); 132 160 if (RT_SUCCESS(rc)) 133 rc = RTPathAppend(szTemp, sizeof(szTemp), "VBoxTestTmp\\VBoxAudioValKit"); 134 if (RT_SUCCESS(rc)) 135 { 136 char szFile[RTPATH_MAX]; 137 rc = AudioHlpFileNameGet(szFile, sizeof(szFile), szTemp, "VaKit", 138 0 /* Instance */, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAGS_NONE); 161 { 162 rc = RTPathAppend(szTemp, sizeof(szTemp), "ValKitTimings.txt"); 139 163 if (RT_SUCCESS(rc)) 140 164 { 141 rc = AudioHlpFileCreate(PDMAUDIOFILETYPE_WAV, szFile, PDMAUDIOFILE_FLAGS_NONE, &pStreamDbg->pFile);165 rc = RTStrmOpen(szTemp, "w", &pStreamDbg->pFileTiming); 142 166 if (RT_SUCCESS(rc)) 143 rc = AudioHlpFileOpen(pStreamDbg->pFile, PDMAUDIOFILE_DEFAULT_OPEN_FLAGS, &pCfgReq->Props); 167 { 168 RTStrmPrintf(pStreamDbg->pFileTiming, "# %uHz %uch %ubit\n", 169 PDMAudioPropsHz(&pCfgReq->Props), 170 PDMAudioPropsChannels(&pCfgReq->Props), 171 PDMAudioPropsSampleBits(&pCfgReq->Props)); 172 return VINF_SUCCESS; 173 } 174 175 LogRel(("ValKitAudio: Opening output file '%s' failed: %Rrc\n", szTemp, rc)); 144 176 } 145 146 if (RT_FAILURE(rc))147 LogRel(("VaKitAudio: Creating output file '%s' failed with %Rrc\n", szFile, rc));148 177 else 149 { 150 size_t cch; 151 char szTimingInfo[128]; 152 cch = RTStrPrintf(szTimingInfo, sizeof(szTimingInfo), "# %uHz %uch %ubit\n", 153 pCfgReq->Props.uHz, pCfgReq->Props.cChannels, pCfgReq->Props.cbSample * 8); 154 155 RTFileWrite(pStreamDbg->hFileTiming, szTimingInfo, cch, NULL); 156 } 178 LogRel(("ValKitAudio: Constructing timing file path: %Rrc\n", rc)); 179 180 AudioHlpFileDestroy(pStreamDbg->pFile); 181 pStreamDbg->pFile = NULL; 157 182 } 158 183 else 159 LogRel(("VaKitAudio: Unable to retrieve temp dir: %Rrc\n", rc)); 184 LogRel(("ValKitAudio: Creating output file 'ValKit' in '%s' failed: %Rrc\n", szTemp, rc)); 185 186 RTMemFree(pStreamDbg->Out.pbPlayBuffer); 187 pStreamDbg->Out.pbPlayBuffer = NULL; 160 188 return rc; 161 189 } … … 168 196 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq) 169 197 { 170 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 171 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 172 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 173 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 174 175 PDRVHOSTVAKITAUDIO pDrv = RT_FROM_MEMBER(pInterface, DRVHOSTVAKITAUDIO, IHostAudio); 198 PDRVHOSTVAKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVAKITAUDIO, IHostAudio); 176 199 PVAKITAUDIOSTREAM pStreamDbg = (PVAKITAUDIOSTREAM)pStream; 200 AssertPtrReturn(pStreamDbg, VERR_INVALID_POINTER); 201 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER); 202 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER); 177 203 178 204 int rc; 179 205 if (pCfgReq->enmDir == PDMAUDIODIR_IN) 180 rc = drvHostValKitAudioCreateStreamIn( p Drv, pStreamDbg, pCfgReq, pCfgAcq);206 rc = drvHostValKitAudioCreateStreamIn( pThis, pStreamDbg, pCfgReq, pCfgAcq); 181 207 else 182 rc = drvHostValKitAudioCreateStreamOut(pDrv, pStreamDbg, pCfgReq, pCfgAcq); 183 208 rc = drvHostValKitAudioCreateStreamOut(pThis, pStreamDbg, pCfgReq, pCfgAcq); 184 209 if (RT_SUCCESS(rc)) 185 210 { … … 190 215 191 216 return rc; 217 } 218 219 220 /** 221 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy} 222 */ 223 static DECLCALLBACK(int) drvHostValKitAudioHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 224 { 225 RT_NOREF(pInterface); //PDRVHOSTVAKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVAKITAUDIO, IHostAudio); 226 PVAKITAUDIOSTREAM pStreamDbg = (PVAKITAUDIOSTREAM)pStream; 227 AssertPtrReturn(pStreamDbg, VERR_INVALID_POINTER); 228 229 if ( pStreamDbg->pCfg->enmDir == PDMAUDIODIR_OUT 230 && pStreamDbg->Out.pbPlayBuffer) 231 { 232 RTMemFree(pStreamDbg->Out.pbPlayBuffer); 233 pStreamDbg->Out.pbPlayBuffer = NULL; 234 } 235 236 if (pStreamDbg->pFile) 237 { 238 size_t cbDataSize = AudioHlpFileGetDataSize(pStreamDbg->pFile); 239 if (cbDataSize) 240 LogRel(("ValKitAudio: Created output file '%s' (%zu bytes)\n", pStreamDbg->pFile->szName, cbDataSize)); 241 242 AudioHlpFileDestroy(pStreamDbg->pFile); 243 pStreamDbg->pFile = NULL; 244 } 245 246 if (pStreamDbg->pFileTiming) 247 { 248 RTStrmClose(pStreamDbg->pFileTiming); 249 pStreamDbg->pFileTiming = NULL; 250 } 251 252 if (pStreamDbg->pCfg) 253 { 254 PDMAudioStrmCfgFree(pStreamDbg->pCfg); 255 pStreamDbg->pCfg = NULL; 256 } 257 258 return VINF_SUCCESS; 259 } 260 261 262 /** 263 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl} 264 */ 265 static DECLCALLBACK(int) drvHostValKitAudioHA_StreamControl(PPDMIHOSTAUDIO pInterface, 266 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 267 { 268 RT_NOREF(pInterface, enmStreamCmd); 269 PVAKITAUDIOSTREAM pStreamDbg = (PVAKITAUDIOSTREAM)pStream; 270 AssertPtrReturn(pStreamDbg, VERR_INVALID_POINTER); 271 272 if (pStreamDbg->pFileTiming) 273 RTStrmFlush(pStreamDbg->pFileTiming); 274 275 return VINF_SUCCESS; 276 } 277 278 279 /** 280 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable} 281 */ 282 static DECLCALLBACK(uint32_t) drvHostValKitAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 283 { 284 RT_NOREF(pInterface, pStream); 285 return UINT32_MAX; 286 } 287 288 289 /** 290 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable} 291 */ 292 static DECLCALLBACK(uint32_t) drvHostValKitAudioHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 293 { 294 RT_NOREF(pInterface, pStream); 295 return UINT32_MAX; 296 } 297 298 299 /** 300 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus} 301 */ 302 static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostValKitAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, 303 PPDMAUDIOBACKENDSTREAM pStream) 304 { 305 RT_NOREF(pInterface, pStream); 306 return PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED | PDMAUDIOSTREAMSTS_FLAGS_ENABLED; 192 307 } 193 308 … … 214 329 // Microseconds are used everythere below 215 330 uint32_t const cFrames = PDMAudioPropsBytesToFrames(&pStreamDbg->pCfg->Props, cbBuf); 216 char szTimingInfo[128]; 217 size_t cch = RTStrPrintf(szTimingInfo, sizeof(szTimingInfo), "%d %d %d %d\n", 218 // Host time elapsed since Guest submitted the first buffer for playback: 219 (uint32_t)(cNsSinceStart / 1000), 220 // how long all the samples submitted previously were played: 221 (uint32_t)(pStreamDbg->cFramesSinceStarted * 1.0E6 / pStreamDbg->pCfg->Props.uHz), 222 // how long a new uSamplesReady samples should/will be played: 223 (uint32_t)(cFrames * 1.0E6 / pStreamDbg->pCfg->Props.uHz), 224 cFrames); 225 RTFileWrite(pStreamDbg->hFileTiming, szTimingInfo, cch, NULL); 331 RTStrmPrintf(pStreamDbg->pFileTiming, "%d %d %d %d\n", 332 // Host time elapsed since Guest submitted the first buffer for playback: 333 (uint32_t)(cNsSinceStart / 1000), 334 // how long all the samples submitted previously were played: 335 (uint32_t)(pStreamDbg->cFramesSinceStarted * 1.0E6 / pStreamDbg->pCfg->Props.uHz), 336 // how long a new uSamplesReady samples should/will be played: 337 (uint32_t)(cFrames * 1.0E6 / pStreamDbg->pCfg->Props.uHz), 338 cFrames); 339 226 340 pStreamDbg->cFramesSinceStarted += cFrames; 227 341 228 342 /* Remember when samples were consumed. */ 229 // pStreamDbg->Out.tsLastPlayed = PDMDrvHlpTMGetVirtualTime(pThis->pDrvIns);343 // pStreamDbg->Out.tsLastPlayed = PDMDrvHlpTMGetVirtualTime(pThis->pDrvIns); 230 344 231 345 int rc2 = AudioHlpFileWrite(pStreamDbg->pFile, pvBuf, cbBuf, 0 /* fFlags */); 232 346 if (RT_FAILURE(rc2)) 233 LogRel(("Va KitAudio: Writing output failed with %Rrc\n", rc2));347 LogRel(("ValKitAudio: Writing output failed with %Rrc\n", rc2)); 234 348 235 349 *pcbWritten = cbBuf; 236 237 350 return VINF_SUCCESS; 238 351 } … … 243 356 */ 244 357 static DECLCALLBACK(int) drvHostValKitAudioHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, 245 void *pvBuf, uint32_t uBufSize, uint32_t *puRead)246 { 247 RT_NOREF(pInterface, pStream, pvBuf, uBufSize);358 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead) 359 { 360 RT_NOREF(pInterface, pStream, pvBuf, cbBuf); 248 361 249 362 /* Never capture anything. */ 250 if (puRead) 251 *puRead = 0; 252 253 return VINF_SUCCESS; 254 } 255 256 257 static int vakitDestroyStreamIn(PDRVHOSTVAKITAUDIO pDrv, PVAKITAUDIOSTREAM pStreamDbg) 258 { 259 RT_NOREF(pDrv, pStreamDbg); 260 return VINF_SUCCESS; 261 } 262 263 264 static int vakitDestroyStreamOut(PDRVHOSTVAKITAUDIO pDrv, PVAKITAUDIOSTREAM pStreamDbg) 265 { 266 RT_NOREF(pDrv); 267 268 if (pStreamDbg->Out.pu8PlayBuffer) 269 { 270 RTMemFree(pStreamDbg->Out.pu8PlayBuffer); 271 pStreamDbg->Out.pu8PlayBuffer = NULL; 272 } 273 274 if (pStreamDbg->pFile) 275 { 276 size_t cbDataSize = AudioHlpFileGetDataSize(pStreamDbg->pFile); 277 if (cbDataSize) 278 LogRel(("VaKitAudio: Created output file '%s' (%zu bytes)\n", pStreamDbg->pFile->szName, cbDataSize)); 279 280 AudioHlpFileDestroy(pStreamDbg->pFile); 281 pStreamDbg->pFile = NULL; 282 } 283 284 return VINF_SUCCESS; 285 } 286 287 288 static DECLCALLBACK(int) drvHostValKitAudioHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 289 { 290 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 291 292 PDRVHOSTVAKITAUDIO pDrv = RT_FROM_MEMBER(pInterface, DRVHOSTVAKITAUDIO, IHostAudio); 293 PVAKITAUDIOSTREAM pStreamDbg = (PVAKITAUDIOSTREAM)pStream; 294 295 if (!pStreamDbg->pCfg) /* Not (yet) configured? Skip. */ 296 return VINF_SUCCESS; 297 298 int rc; 299 if (pStreamDbg->pCfg->enmDir == PDMAUDIODIR_IN) 300 rc = vakitDestroyStreamIn (pDrv, pStreamDbg); 301 else 302 rc = vakitDestroyStreamOut(pDrv, pStreamDbg); 303 304 if (RT_SUCCESS(rc)) 305 { 306 PDMAudioStrmCfgFree(pStreamDbg->pCfg); 307 pStreamDbg->pCfg = NULL; 308 } 309 310 return rc; 311 } 312 313 static DECLCALLBACK(int) drvHostValKitAudioHA_StreamControl(PPDMIHOSTAUDIO pInterface, 314 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd) 315 { 316 RT_NOREF(enmStreamCmd); 317 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 318 AssertPtrReturn(pStream, VERR_INVALID_POINTER); 319 320 return VINF_SUCCESS; 321 } 322 323 /** 324 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable} 325 */ 326 static DECLCALLBACK(uint32_t) drvHostValKitAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 327 { 328 RT_NOREF(pInterface, pStream); 329 330 return UINT32_MAX; 331 } 332 333 334 /** 335 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable} 336 */ 337 static DECLCALLBACK(uint32_t) drvHostValKitAudioHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream) 338 { 339 RT_NOREF(pInterface, pStream); 340 341 return UINT32_MAX; 342 } 343 344 static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostValKitAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, 345 PPDMAUDIOBACKENDSTREAM pStream) 346 { 347 RT_NOREF(pInterface, pStream); 348 349 return PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED | PDMAUDIOSTREAMSTS_FLAGS_ENABLED; 350 } 363 *pcbRead = 0; 364 return VINF_SUCCESS; 365 } 366 351 367 352 368 /** … … 374 390 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); 375 391 PDRVHOSTVAKITAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTVAKITAUDIO); 376 LogRel(("Audio: Initializing VA KIT driver\n"));392 LogRel(("Audio: Initializing VALKIT driver\n")); 377 393 378 394 /* … … 384 400 /* IHostAudio */ 385 401 pThis->IHostAudio.pfnGetConfig = drvHostValKitAudioHA_GetConfig; 402 pThis->IHostAudio.pfnGetDevices = NULL; 386 403 pThis->IHostAudio.pfnGetStatus = drvHostValKitAudioHA_GetStatus; 387 404 pThis->IHostAudio.pfnStreamCreate = drvHostValKitAudioHA_StreamCreate; … … 390 407 pThis->IHostAudio.pfnStreamGetReadable = drvHostValKitAudioHA_StreamGetReadable; 391 408 pThis->IHostAudio.pfnStreamGetWritable = drvHostValKitAudioHA_StreamGetWritable; 409 pThis->IHostAudio.pfnStreamGetPending = NULL; 392 410 pThis->IHostAudio.pfnStreamGetStatus = drvHostValKitAudioHA_StreamGetStatus; 393 411 pThis->IHostAudio.pfnStreamPlay = drvHostValKitAudioHA_StreamPlay; 394 412 pThis->IHostAudio.pfnStreamCapture = drvHostValKitAudioHA_StreamCapture; 395 pThis->IHostAudio.pfnGetDevices = NULL;396 pThis->IHostAudio.pfnStreamGetPending = NULL;397 413 398 414 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.