VirtualBox

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

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

Audio: Changed PPDMAUDIOBACKENDSTREAM from opaque to a common base-structure which the backends can extend with their own data. bugref:9890

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.3 KB
Line 
1/* $Id: DrvHostAudioNull.cpp 88718 2021-04-26 21:21:24Z vboxsync $ */
2/** @file
3 * Host audio driver - NULL (bitbucket).
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
21/*********************************************************************************************************************************
22* Header Files *
23*********************************************************************************************************************************/
24#include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */
25
26#define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO
27#include <VBox/log.h>
28#include <VBox/vmm/pdmaudioifs.h>
29#include <VBox/vmm/pdmaudioinline.h>
30
31#include "VBoxDD.h"
32
33
34/*********************************************************************************************************************************
35* Structures and Typedefs *
36*********************************************************************************************************************************/
37/** Null audio stream. */
38typedef struct NULLAUDIOSTREAM
39{
40 /** Common part. */
41 PDMAUDIOBACKENDSTREAM Core;
42 /** The stream's acquired configuration. */
43 PDMAUDIOSTREAMCFG Cfg;
44} NULLAUDIOSTREAM;
45/** Pointer to a null audio stream. */
46typedef NULLAUDIOSTREAM *PNULLAUDIOSTREAM;
47
48
49
50/**
51 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetConfig}
52 */
53static DECLCALLBACK(int) drvHostNullAudioHA_GetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
54{
55 NOREF(pInterface);
56 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
57
58 /*
59 * Fill in the config structure.
60 */
61 RTStrCopy(pBackendCfg->szName, sizeof(pBackendCfg->szName), "NULL audio");
62 pBackendCfg->cbStream = sizeof(NULLAUDIOSTREAM);
63 pBackendCfg->fFlags = 0;
64 pBackendCfg->cMaxStreamsOut = 1; /* Output */
65 pBackendCfg->cMaxStreamsIn = 2; /* Line input + microphone input. */
66
67 return VINF_SUCCESS;
68}
69
70
71/**
72 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus}
73 */
74static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHostNullAudioHA_GetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
75{
76 RT_NOREF(pInterface, enmDir);
77 return PDMAUDIOBACKENDSTS_RUNNING;
78}
79
80
81/**
82 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
83 */
84static DECLCALLBACK(int) drvHostNullAudioHA_StreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
85 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
86{
87 RT_NOREF(pInterface);
88 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream;
89 AssertPtrReturn(pStreamNull, VERR_INVALID_POINTER);
90 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER);
91 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER);
92
93 PDMAudioStrmCfgCopy(&pStreamNull->Cfg, pCfgAcq);
94 return VINF_SUCCESS;
95}
96
97
98/**
99 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
100 */
101static DECLCALLBACK(int) drvHostNullAudioHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
102{
103 RT_NOREF(pInterface, pStream);
104 return VINF_SUCCESS;
105}
106
107
108/**
109 * @ interface_method_impl{PDMIHOSTAUDIO,pfnStreamEnable}
110 */
111static DECLCALLBACK(int) drvHostNullAudioHA_StreamControlStub(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
112{
113 RT_NOREF(pInterface, pStream);
114 return VINF_SUCCESS;
115}
116
117
118/**
119 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
120 */
121static DECLCALLBACK(int) drvHostNullAudioHA_StreamControl(PPDMIHOSTAUDIO pInterface,
122 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
123{
124 /** @todo r=bird: I'd like to get rid of this pfnStreamControl method,
125 * replacing it with individual StreamXxxx methods. That would save us
126 * potentally huge switches and more easily see which drivers implement
127 * which operations (grep for pfnStreamXxxx). */
128 switch (enmStreamCmd)
129 {
130 case PDMAUDIOSTREAMCMD_ENABLE:
131 return drvHostNullAudioHA_StreamControlStub(pInterface, pStream);
132 case PDMAUDIOSTREAMCMD_DISABLE:
133 return drvHostNullAudioHA_StreamControlStub(pInterface, pStream);
134 case PDMAUDIOSTREAMCMD_PAUSE:
135 return drvHostNullAudioHA_StreamControlStub(pInterface, pStream);
136 case PDMAUDIOSTREAMCMD_RESUME:
137 return drvHostNullAudioHA_StreamControlStub(pInterface, pStream);
138 case PDMAUDIOSTREAMCMD_DRAIN:
139 return drvHostNullAudioHA_StreamControlStub(pInterface, pStream);
140
141 case PDMAUDIOSTREAMCMD_END:
142 case PDMAUDIOSTREAMCMD_32BIT_HACK:
143 case PDMAUDIOSTREAMCMD_INVALID:
144 /* no default*/
145 break;
146 }
147 return VERR_NOT_SUPPORTED;
148}
149
150
151/**
152 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable}
153 */
154static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
155{
156 RT_NOREF(pInterface, pStream);
157 /** @todo rate limit this? */
158 return UINT32_MAX;
159}
160
161
162/**
163 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable}
164 */
165static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
166{
167 RT_NOREF(pInterface, pStream);
168 return UINT32_MAX;
169}
170
171
172/**
173 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetPending}
174 */
175static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetPending(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
176{
177 RT_NOREF(pInterface, pStream);
178 return 0;
179}
180
181
182/**
183 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetStatus}
184 */
185static DECLCALLBACK(PDMAUDIOSTREAMSTS) drvHostNullAudioHA_StreamGetStatus(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
186{
187 RT_NOREF(pInterface, pStream);
188 return PDMAUDIOSTREAMSTS_FLAGS_INITIALIZED | PDMAUDIOSTREAMSTS_FLAGS_ENABLED;
189}
190
191
192/**
193 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
194 */
195static DECLCALLBACK(int) drvHostNullAudioHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
196 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
197{
198 RT_NOREF(pInterface, pStream, pvBuf);
199
200 /* The bitbucket never overflows. */
201 *pcbWritten = cbBuf;
202 return VINF_SUCCESS;
203}
204
205
206/**
207 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
208 */
209static DECLCALLBACK(int) drvHostNullAudioHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
210 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
211{
212 RT_NOREF(pInterface);
213 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream;
214
215 /** @todo rate limit this? */
216
217 /* Return silence. */
218 PDMAudioPropsClearBuffer(&pStreamNull->Cfg.Props, pvBuf, cbBuf,
219 PDMAudioPropsBytesToFrames(&pStreamNull->Cfg.Props, cbBuf));
220 *pcbRead = cbBuf;
221 return VINF_SUCCESS;
222}
223
224
225/**
226 * This is used directly by DrvAudio when a backend fails to initialize in a
227 * non-fatal manner.
228 */
229DECL_HIDDEN_CONST(PDMIHOSTAUDIO) const g_DrvHostAudioNull =
230{
231 /* .pfnGetConfig =*/ drvHostNullAudioHA_GetConfig,
232 /* .pfnGetDevices =*/ NULL,
233 /* .pfnGetStatus =*/ drvHostNullAudioHA_GetStatus,
234 /* .pfnStreamConfigHint =*/ NULL,
235 /* .pfnStreamCreate =*/ drvHostNullAudioHA_StreamCreate,
236 /* .pfnStreamDestroy =*/ drvHostNullAudioHA_StreamDestroy,
237 /* .pfnStreamControl =*/ drvHostNullAudioHA_StreamControl,
238 /* .pfnStreamGetReadable =*/ drvHostNullAudioHA_StreamGetReadable,
239 /* .pfnStreamGetWritable =*/ drvHostNullAudioHA_StreamGetWritable,
240 /* .pfnStreamGetPending =*/ drvHostNullAudioHA_StreamGetPending,
241 /* .pfnStreamGetStatus =*/ drvHostNullAudioHA_StreamGetStatus,
242 /* .pfnStreamPlay =*/ drvHostNullAudioHA_StreamPlay,
243 /* .pfnStreamCapture =*/ drvHostNullAudioHA_StreamCapture,
244};
245
246
247/**
248 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
249 */
250static DECLCALLBACK(void *) drvHostNullAudioQueryInterface(PPDMIBASE pInterface, const char *pszIID)
251{
252 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
253 PPDMIHOSTAUDIO pThis = PDMINS_2_DATA(pDrvIns, PPDMIHOSTAUDIO);
254
255 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
256 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, pThis);
257 return NULL;
258}
259
260
261/**
262 * Constructs a Null audio driver instance.
263 *
264 * @copydoc FNPDMDRVCONSTRUCT
265 */
266static DECLCALLBACK(int) drvHostNullAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
267{
268 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
269 PPDMIHOSTAUDIO pThis = PDMINS_2_DATA(pDrvIns, PPDMIHOSTAUDIO);
270 RT_NOREF(pCfg, fFlags);
271 LogRel(("Audio: Initializing NULL driver\n"));
272
273 /*
274 * Init the static parts.
275 */
276 /* IBase */
277 pDrvIns->IBase.pfnQueryInterface = drvHostNullAudioQueryInterface;
278 /* IHostAudio */
279 *pThis = g_DrvHostAudioNull;
280
281 return VINF_SUCCESS;
282}
283
284
285/**
286 * Char driver registration record.
287 */
288const PDMDRVREG g_DrvHostNullAudio =
289{
290 /* u32Version */
291 PDM_DRVREG_VERSION,
292 /* szName */
293 "NullAudio",
294 /* szRCMod */
295 "",
296 /* szR0Mod */
297 "",
298 /* pszDescription */
299 "NULL audio host driver",
300 /* fFlags */
301 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
302 /* fClass. */
303 PDM_DRVREG_CLASS_AUDIO,
304 /* cMaxInstances */
305 ~0U,
306 /* cbInstance */
307 sizeof(PDMIHOSTAUDIO),
308 /* pfnConstruct */
309 drvHostNullAudioConstruct,
310 /* pfnDestruct */
311 NULL,
312 /* pfnRelocate */
313 NULL,
314 /* pfnIOCtl */
315 NULL,
316 /* pfnPowerOn */
317 NULL,
318 /* pfnReset */
319 NULL,
320 /* pfnSuspend */
321 NULL,
322 /* pfnResume */
323 NULL,
324 /* pfnAttach */
325 NULL,
326 /* pfnDetach */
327 NULL,
328 /* pfnPowerOff */
329 NULL,
330 /* pfnSoftReset */
331 NULL,
332 /* u32EndVersion */
333 PDM_DRVREG_VERSION
334};
335
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