VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/DrvHostNullAudio.cpp@ 73585

Last change on this file since 73585 was 73572, checked in by vboxsync, 6 years ago

Audio/DrvHostNullAudio: Use DrvAudioHlpClearBuf() instead of RT_BZERO in drvHostNullAudioStreamCapture().

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 KB
Line 
1/* $Id: DrvHostNullAudio.cpp 73572 2018-08-08 16:10:51Z vboxsync $ */
2/** @file
3 * NULL audio driver.
4 *
5 * This also acts as a fallback if no other backend is available.
6 */
7
8/*
9 * Copyright (C) 2006-2017 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
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 emulation
23 *
24 * Copyright (c) 2004-2005 Vassili Karpov (malc)
25 *
26 * Permission is hereby granted, free of charge, to any person obtaining a copy
27 * of this software and associated documentation files (the "Software"), to deal
28 * in the Software without restriction, including without limitation the rights
29 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30 * copies of the Software, and to permit persons to whom the Software is
31 * furnished to do so, subject to the following conditions:
32 *
33 * The above copyright notice and this permission notice shall be included in
34 * all copies or substantial portions of the Software.
35 *
36 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
39 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40 * 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 IN
42 * THE SOFTWARE.
43 */
44
45
46/*********************************************************************************************************************************
47* Header Files *
48*********************************************************************************************************************************/
49#include <iprt/mem.h>
50#include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */
51
52#define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO
53#include <VBox/log.h>
54#include <VBox/vmm/pdmaudioifs.h>
55
56#include "DrvAudio.h"
57#include "VBoxDD.h"
58
59
60/*********************************************************************************************************************************
61* Structures and Typedefs *
62*********************************************************************************************************************************/
63typedef struct NULLAUDIOSTREAM
64{
65 /** The stream's acquired configuration. */
66 PPDMAUDIOSTREAMCFG pCfg;
67} NULLAUDIOSTREAM, *PNULLAUDIOSTREAM;
68
69/**
70 * NULL audio driver instance data.
71 * @implements PDMIAUDIOCONNECTOR
72 */
73typedef struct DRVHOSTNULLAUDIO
74{
75 /** Pointer to the driver instance structure. */
76 PPDMDRVINS pDrvIns;
77 /** Pointer to host audio interface. */
78 PDMIHOSTAUDIO IHostAudio;
79} DRVHOSTNULLAUDIO, *PDRVHOSTNULLAUDIO;
80
81
82
83/**
84 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetConfig}
85 */
86static DECLCALLBACK(int) drvHostNullAudioGetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
87{
88 NOREF(pInterface);
89 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
90
91 pBackendCfg->cbStreamOut = sizeof(NULLAUDIOSTREAM);
92 pBackendCfg->cbStreamIn = sizeof(NULLAUDIOSTREAM);
93
94 pBackendCfg->cMaxStreamsOut = 1; /* Output */
95 pBackendCfg->cMaxStreamsIn = 2; /* Line input + microphone input. */
96
97 return VINF_SUCCESS;
98}
99
100
101/**
102 * @interface_method_impl{PDMIHOSTAUDIO,pfnInit}
103 */
104static DECLCALLBACK(int) drvHostNullAudioInit(PPDMIHOSTAUDIO pInterface)
105{
106 NOREF(pInterface);
107
108 LogFlowFuncLeaveRC(VINF_SUCCESS);
109 return VINF_SUCCESS;
110}
111
112
113/**
114 * @interface_method_impl{PDMIHOSTAUDIO,pfnShutdown}
115 */
116static DECLCALLBACK(void) drvHostNullAudioShutdown(PPDMIHOSTAUDIO pInterface)
117{
118 RT_NOREF(pInterface);
119}
120
121
122/**
123 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus}
124 */
125static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostNullAudioGetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
126{
127 RT_NOREF(enmDir);
128 AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN);
129
130 return PDMAUDIOBACKENDSTS_RUNNING;
131}
132
133
134/**
135 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
136 */
137static DECLCALLBACK(int) drvHostNullAudioStreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
138 const void *pvBuf, uint32_t cxBuf, uint32_t *pcxWritten)
139{
140 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
141 AssertPtrReturn(pStream, VERR_INVALID_POINTER);
142 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
143 AssertReturn(cxBuf, VERR_INVALID_PARAMETER);
144
145 RT_NOREF(pInterface, pStream, pvBuf);
146
147 /* Note: No copying of samples needed here, as this a NULL backend. */
148
149 if (pcxWritten)
150 *pcxWritten = cxBuf; /* Return all bytes as written. */
151
152 return VINF_SUCCESS;
153}
154
155
156/**
157 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
158 */
159static DECLCALLBACK(int) drvHostNullAudioStreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
160 void *pvBuf, uint32_t cxBuf, uint32_t *pcxRead)
161{
162 RT_NOREF(pInterface, pStream);
163
164 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream;
165
166 /* Return silence. */
167 Assert(pStreamNull->pCfg);
168 DrvAudioHlpClearBuf(&pStreamNull->pCfg->Props, pvBuf, cxBuf, PDMAUDIOPCMPROPS_B2F(&pStreamNull->pCfg->Props, cxBuf));
169
170 if (pcxRead)
171 *pcxRead = cxBuf;
172
173 return VINF_SUCCESS;
174}
175
176
177static int nullCreateStreamIn(PNULLAUDIOSTREAM pStreamNull, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
178{
179 RT_NOREF(pStreamNull, pCfgReq, pCfgAcq);
180
181 return VINF_SUCCESS;
182}
183
184
185static int nullCreateStreamOut(PNULLAUDIOSTREAM pStreamNull, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
186{
187 RT_NOREF(pStreamNull, pCfgReq, pCfgAcq);
188
189 return VINF_SUCCESS;
190}
191
192
193/**
194 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
195 */
196static DECLCALLBACK(int) drvHostNullAudioStreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
197 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
198{
199 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
200 AssertPtrReturn(pStream, VERR_INVALID_POINTER);
201 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER);
202 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER);
203
204 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream;
205
206 int rc;
207 if (pCfgReq->enmDir == PDMAUDIODIR_IN)
208 rc = nullCreateStreamIn( pStreamNull, pCfgReq, pCfgAcq);
209 else
210 rc = nullCreateStreamOut(pStreamNull, pCfgReq, pCfgAcq);
211
212 if (RT_SUCCESS(rc))
213 {
214 pStreamNull->pCfg = DrvAudioHlpStreamCfgDup(pCfgAcq);
215 if (!pStreamNull->pCfg)
216 rc = VERR_NO_MEMORY;
217 }
218
219 return rc;
220}
221
222
223static int nullDestroyStreamIn(void)
224{
225 LogFlowFuncLeaveRC(VINF_SUCCESS);
226 return VINF_SUCCESS;
227}
228
229
230static int nullDestroyStreamOut(PNULLAUDIOSTREAM pStreamNull)
231{
232 RT_NOREF(pStreamNull);
233 return VINF_SUCCESS;
234}
235
236
237/**
238 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
239 */
240static DECLCALLBACK(int) drvHostNullAudioStreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
241{
242 AssertPtrReturn(pInterface, VERR_INVALID_POINTER);
243 AssertPtrReturn(pStream, VERR_INVALID_POINTER);
244
245 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream;
246
247 if (!pStreamNull->pCfg) /* Not (yet) configured? Skip. */
248 return VINF_SUCCESS;
249
250 int rc;
251 if (pStreamNull->pCfg->enmDir == PDMAUDIODIR_IN)
252 rc = nullDestroyStreamIn();
253 else
254 rc = nullDestroyStreamOut(pStreamNull);
255
256 if (RT_SUCCESS(rc))
257 {
258 DrvAudioHlpStreamCfgFree(pStreamNull->pCfg);
259 pStreamNull->pCfg = NULL;
260 }
261
262 return rc;
263}
264
265
266/**
267 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
268 */
269static DECLCALLBACK(int) drvHostNullAudioStreamControl(PPDMIHOSTAUDIO pInterface,
270 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
271{
272 RT_NOREF(pInterface, pStream, enmStreamCmd);
273 return VINF_SUCCESS;
274}
275
276
277/**
278 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable}
279 */
280static DECLCALLBACK(uint32_t) drvHostNullAudioStreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
281{
282 RT_NOREF(pInterface, pStream);
283
284 return UINT32_MAX;
285}
286
287
288/**
289 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable}
290 */
291static DECLCALLBACK(uint32_t) drvHostNullAudioStreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
292{
293 RT_NOREF(pInterface, pStream);
294
295 return UINT32_MAX;
296}
297
298
299/**
300 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
301 */
302static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostNullAudioStreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
303{
304 RT_NOREF(pInterface, pStream);
305 return PDMAUDIOSTREAMSTS_FLAG_INITIALIZED | PDMAUDIOSTREAMSTS_FLAG_ENABLED;
306}
307
308
309/**
310 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamIterate}
311 */
312static DECLCALLBACK(int) drvHostNullAudioStreamIterate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
313{
314 NOREF(pInterface);
315 NOREF(pStream);
316
317 return VINF_SUCCESS;
318}
319
320
321/**
322 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
323 */
324static DECLCALLBACK(void *) drvHostNullAudioQueryInterface(PPDMIBASE pInterface, const char *pszIID)
325{
326 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
327 PDRVHOSTNULLAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTNULLAUDIO);
328
329 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
330 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, &pThis->IHostAudio);
331 return NULL;
332}
333
334
335/**
336 * Constructs a Null audio driver instance.
337 *
338 * @copydoc FNPDMDRVCONSTRUCT
339 */
340static DECLCALLBACK(int) drvHostNullAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
341{
342 RT_NOREF(pCfg, fFlags);
343 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
344 AssertPtrReturn(pDrvIns, VERR_INVALID_POINTER);
345 /* pCfg is optional. */
346
347 PDRVHOSTNULLAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTNULLAUDIO);
348 LogRel(("Audio: Initializing NULL driver\n"));
349
350 /*
351 * Init the static parts.
352 */
353 pThis->pDrvIns = pDrvIns;
354 /* IBase */
355 pDrvIns->IBase.pfnQueryInterface = drvHostNullAudioQueryInterface;
356 /* IHostAudio */
357 PDMAUDIO_IHOSTAUDIO_CALLBACKS(drvHostNullAudio);
358
359 return VINF_SUCCESS;
360}
361
362
363/**
364 * Char driver registration record.
365 */
366const PDMDRVREG g_DrvHostNullAudio =
367{
368 /* u32Version */
369 PDM_DRVREG_VERSION,
370 /* szName */
371 "NullAudio",
372 /* szRCMod */
373 "",
374 /* szR0Mod */
375 "",
376 /* pszDescription */
377 "NULL audio host driver",
378 /* fFlags */
379 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
380 /* fClass. */
381 PDM_DRVREG_CLASS_AUDIO,
382 /* cMaxInstances */
383 ~0U,
384 /* cbInstance */
385 sizeof(DRVHOSTNULLAUDIO),
386 /* pfnConstruct */
387 drvHostNullAudioConstruct,
388 /* pfnDestruct */
389 NULL,
390 /* pfnRelocate */
391 NULL,
392 /* pfnIOCtl */
393 NULL,
394 /* pfnPowerOn */
395 NULL,
396 /* pfnReset */
397 NULL,
398 /* pfnSuspend */
399 NULL,
400 /* pfnResume */
401 NULL,
402 /* pfnAttach */
403 NULL,
404 /* pfnDetach */
405 NULL,
406 /* pfnPowerOff */
407 NULL,
408 /* pfnSoftReset */
409 NULL,
410 /* u32EndVersion */
411 PDM_DRVREG_VERSION
412};
413
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette