VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/DrvHostAudioNull.cpp@ 88401

Last change on this file since 88401 was 88390, checked in by vboxsync, 4 years ago

Audio: Removed the pfnInit and pfnShutdown methods from PDMIHOSTAUDIO. These methods duplicates PDMDRVREG callbacks and were therefore superfluous. bugref:9890

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.7 KB
Line 
1/* $Id: DrvHostAudioNull.cpp 88390 2021-04-07 10:35:06Z vboxsync $ */
2/** @file
3 * Host audio driver - NULL.
4 *
5 * This also acts as a fallback if no other backend is available.
6 */
7
8/*
9 * Copyright (C) 2006-2020 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#include <VBox/vmm/pdmaudioinline.h>
56
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) drvHostNullAudioHA_GetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
87{
88 NOREF(pInterface);
89 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
90
91 RTStrPrintf2(pBackendCfg->szName, sizeof(pBackendCfg->szName), "NULL audio");
92
93 pBackendCfg->cbStreamOut = sizeof(NULLAUDIOSTREAM);
94 pBackendCfg->cbStreamIn = sizeof(NULLAUDIOSTREAM);
95
96 pBackendCfg->cMaxStreamsOut = 1; /* Output */
97 pBackendCfg->cMaxStreamsIn = 2; /* Line input + microphone input. */
98
99 return VINF_SUCCESS;
100}
101
102
103/**
104 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus}
105 */
106static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostNullAudioHA_GetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
107{
108 RT_NOREF(enmDir);
109 AssertPtrReturn(pInterface, PDMAUDIOBACKENDSTS_UNKNOWN);
110
111 return PDMAUDIOBACKENDSTS_RUNNING;
112}
113
114
115/**
116 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
117 */
118static DECLCALLBACK(int) drvHostNullAudioHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
119 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
120{
121 RT_NOREF(pInterface, pStream, pvBuf);
122
123 /* The bitbucket never overflows. */
124 *pcbWritten = cbBuf;
125 return VINF_SUCCESS;
126}
127
128
129/**
130 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
131 */
132static DECLCALLBACK(int) drvHostNullAudioHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
133 void *pvBuf, uint32_t uBufSize, uint32_t *puRead)
134{
135 RT_NOREF(pInterface, pStream);
136
137 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream;
138
139 /* 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
150static int nullCreateStreamIn(PNULLAUDIOSTREAM pStreamNull, PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
151{
152 RT_NOREF(pStreamNull, pCfgReq, pCfgAcq);
153
154 return VINF_SUCCESS;
155}
156
157
158static 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 */
169static 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
196static int nullDestroyStreamIn(void)
197{
198 LogFlowFuncLeaveRC(VINF_SUCCESS);
199 return VINF_SUCCESS;
200}
201
202
203static int nullDestroyStreamOut(PNULLAUDIOSTREAM pStreamNull)
204{
205 RT_NOREF(pStreamNull);
206 return VINF_SUCCESS;
207}
208
209
210/**
211 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
212 */
213static 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 */
242static 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 */
253static 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 */
264static 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 */
275static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostNullAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
276{
277 RT_NOREF(pInterface, pStream);
278 return PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED | PDMAUDIOSTREAMSTS_FLAGS_ENABLED;
279}
280
281
282/**
283 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
284 */
285static DECLCALLBACK(void *) drvHostNullAudioQueryInterface(PPDMIBASE pInterface, const char *pszIID)
286{
287 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
288 PDRVHOSTNULLAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTNULLAUDIO);
289
290 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
291 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, &pThis->IHostAudio);
292 return NULL;
293}
294
295
296/**
297 * Constructs a Null audio driver instance.
298 *
299 * @copydoc FNPDMDRVCONSTRUCT
300 */
301static DECLCALLBACK(int) drvHostNullAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
302{
303 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 LogRel(("Audio: Initializing NULL driver\n"));
310
311 /*
312 * Init the static parts.
313 */
314 pThis->pDrvIns = pDrvIns;
315 /* IBase */
316 pDrvIns->IBase.pfnQueryInterface = drvHostNullAudioQueryInterface;
317 /* IHostAudio */
318 pThis->IHostAudio.pfnGetConfig = drvHostNullAudioHA_GetConfig;
319 pThis->IHostAudio.pfnGetStatus = drvHostNullAudioHA_GetStatus;
320 pThis->IHostAudio.pfnStreamCreate = drvHostNullAudioHA_StreamCreate;
321 pThis->IHostAudio.pfnStreamDestroy = drvHostNullAudioHA_StreamDestroy;
322 pThis->IHostAudio.pfnStreamControl = drvHostNullAudioHA_StreamControl;
323 pThis->IHostAudio.pfnStreamGetReadable = drvHostNullAudioHA_StreamGetReadable;
324 pThis->IHostAudio.pfnStreamGetWritable = drvHostNullAudioHA_StreamGetWritable;
325 pThis->IHostAudio.pfnStreamGetStatus = drvHostNullAudioHA_StreamGetStatus;
326 pThis->IHostAudio.pfnStreamPlay = drvHostNullAudioHA_StreamPlay;
327 pThis->IHostAudio.pfnStreamCapture = drvHostNullAudioHA_StreamCapture;
328 pThis->IHostAudio.pfnGetDevices = NULL;
329 pThis->IHostAudio.pfnStreamGetPending = NULL;
330
331 return VINF_SUCCESS;
332}
333
334
335/**
336 * Char driver registration record.
337 */
338const PDMDRVREG g_DrvHostNullAudio =
339{
340 /* u32Version */
341 PDM_DRVREG_VERSION,
342 /* szName */
343 "NullAudio",
344 /* szRCMod */
345 "",
346 /* szR0Mod */
347 "",
348 /* pszDescription */
349 "NULL audio host driver",
350 /* fFlags */
351 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
352 /* fClass. */
353 PDM_DRVREG_CLASS_AUDIO,
354 /* cMaxInstances */
355 ~0U,
356 /* cbInstance */
357 sizeof(DRVHOSTNULLAUDIO),
358 /* pfnConstruct */
359 drvHostNullAudioConstruct,
360 /* pfnDestruct */
361 NULL,
362 /* pfnRelocate */
363 NULL,
364 /* pfnIOCtl */
365 NULL,
366 /* pfnPowerOn */
367 NULL,
368 /* pfnReset */
369 NULL,
370 /* pfnSuspend */
371 NULL,
372 /* pfnResume */
373 NULL,
374 /* pfnAttach */
375 NULL,
376 /* pfnDetach */
377 NULL,
378 /* pfnPowerOff */
379 NULL,
380 /* pfnSoftReset */
381 NULL,
382 /* u32EndVersion */
383 PDM_DRVREG_VERSION
384};
385
Note: See TracBrowser for help on using the repository browser.

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