VirtualBox

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

Last change on this file since 93435 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
Line 
1/* $Id: DrvHostAudioNull.cpp 93115 2022-01-01 11:31:46Z 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-2022 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 DRVHSTAUDNULLSTREAM
39{
40 /** Common part. */
41 PDMAUDIOBACKENDSTREAM Core;
42 /** The stream's acquired configuration. */
43 PDMAUDIOSTREAMCFG Cfg;
44} DRVHSTAUDNULLSTREAM;
45/** Pointer to a null audio stream. */
46typedef DRVHSTAUDNULLSTREAM *PDRVHSTAUDNULLSTREAM;
47
48
49
50/**
51 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetConfig}
52 */
53static DECLCALLBACK(int) drvHstAudNullHA_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(DRVHSTAUDNULLSTREAM);
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) drvHstAudNullHA_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) drvHstAudNullHA_StreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
85 PCPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
86{
87 RT_NOREF(pInterface);
88 PDRVHSTAUDNULLSTREAM pStreamNull = (PDRVHSTAUDNULLSTREAM)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) drvHstAudNullHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, bool fImmediate)
102{
103 RT_NOREF(pInterface, pStream, fImmediate);
104 return VINF_SUCCESS;
105}
106
107
108/**
109 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamEnable}
110 */
111static DECLCALLBACK(int) drvHstAudNullHA_StreamControlStub(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
112{
113 RT_NOREF(pInterface, pStream);
114 return VINF_SUCCESS;
115}
116
117
118/**
119 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
120 */
121static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHstAudNullHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
122 PPDMAUDIOBACKENDSTREAM pStream)
123{
124 RT_NOREF(pInterface);
125 AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
126#if 0
127 /* Bit bucket appraoch where we ignore the output and silence the input buffers. */
128 return PDMHOSTAUDIOSTREAMSTATE_OKAY;
129#else
130 /* Approach where the mixer in the devices skips us and saves a few CPU cycles. */
131 return PDMHOSTAUDIOSTREAMSTATE_INACTIVE;
132#endif
133}
134
135
136/**
137 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetPending}
138 */
139static DECLCALLBACK(uint32_t) drvHstAudNullHA_StreamGetPending(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
140{
141 RT_NOREF(pInterface, pStream);
142 return 0;
143}
144
145
146/**
147 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable}
148 */
149static DECLCALLBACK(uint32_t) drvHstAudNullHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
150{
151 RT_NOREF(pInterface, pStream);
152 return UINT32_MAX;
153}
154
155
156/**
157 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
158 */
159static DECLCALLBACK(int) drvHstAudNullHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
160 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
161{
162 RT_NOREF(pInterface, pStream, pvBuf);
163
164 /* The bitbucket never overflows. */
165 *pcbWritten = cbBuf;
166 return VINF_SUCCESS;
167}
168
169
170/**
171 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable}
172 */
173static DECLCALLBACK(uint32_t) drvHstAudNullHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
174{
175 RT_NOREF(pInterface, pStream);
176 /** @todo rate limit this? */
177 return UINT32_MAX;
178}
179
180
181/**
182 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
183 */
184static DECLCALLBACK(int) drvHstAudNullHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
185 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
186{
187 RT_NOREF(pInterface);
188 PDRVHSTAUDNULLSTREAM pStreamNull = (PDRVHSTAUDNULLSTREAM)pStream;
189
190 /** @todo rate limit this? */
191
192 /* Return silence. */
193 PDMAudioPropsClearBuffer(&pStreamNull->Cfg.Props, pvBuf, cbBuf,
194 PDMAudioPropsBytesToFrames(&pStreamNull->Cfg.Props, cbBuf));
195 *pcbRead = cbBuf;
196 return VINF_SUCCESS;
197}
198
199
200/**
201 * This is used directly by DrvAudio when a backend fails to initialize in a
202 * non-fatal manner.
203 */
204DECL_HIDDEN_CONST(PDMIHOSTAUDIO) const g_DrvHostAudioNull =
205{
206 /* .pfnGetConfig =*/ drvHstAudNullHA_GetConfig,
207 /* .pfnGetDevices =*/ NULL,
208 /* .pfnSetDevice =*/ NULL,
209 /* .pfnGetStatus =*/ drvHstAudNullHA_GetStatus,
210 /* .pfnDoOnWorkerThread =*/ NULL,
211 /* .pfnStreamConfigHint =*/ NULL,
212 /* .pfnStreamCreate =*/ drvHstAudNullHA_StreamCreate,
213 /* .pfnStreamInitAsync =*/ NULL,
214 /* .pfnStreamDestroy =*/ drvHstAudNullHA_StreamDestroy,
215 /* .pfnStreamNotifyDeviceChanged =*/ NULL,
216 /* .pfnStreamEnable =*/ drvHstAudNullHA_StreamControlStub,
217 /* .pfnStreamDisable =*/ drvHstAudNullHA_StreamControlStub,
218 /* .pfnStreamPause =*/ drvHstAudNullHA_StreamControlStub,
219 /* .pfnStreamResume =*/ drvHstAudNullHA_StreamControlStub,
220 /* .pfnStreamDrain =*/ drvHstAudNullHA_StreamControlStub,
221 /* .pfnStreamGetState =*/ drvHstAudNullHA_StreamGetState,
222 /* .pfnStreamGetPending =*/ drvHstAudNullHA_StreamGetPending,
223 /* .pfnStreamGetWritable =*/ drvHstAudNullHA_StreamGetWritable,
224 /* .pfnStreamPlay =*/ drvHstAudNullHA_StreamPlay,
225 /* .pfnStreamGetReadable =*/ drvHstAudNullHA_StreamGetReadable,
226 /* .pfnStreamCapture =*/ drvHstAudNullHA_StreamCapture,
227};
228
229
230/**
231 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
232 */
233static DECLCALLBACK(void *) drvHstAudNullQueryInterface(PPDMIBASE pInterface, const char *pszIID)
234{
235 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
236 PPDMIHOSTAUDIO pThis = PDMINS_2_DATA(pDrvIns, PPDMIHOSTAUDIO);
237
238 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
239 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, pThis);
240 return NULL;
241}
242
243
244/**
245 * Constructs a Null audio driver instance.
246 *
247 * @copydoc FNPDMDRVCONSTRUCT
248 */
249static DECLCALLBACK(int) drvHstAudNullConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
250{
251 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
252 PPDMIHOSTAUDIO pThis = PDMINS_2_DATA(pDrvIns, PPDMIHOSTAUDIO);
253 RT_NOREF(pCfg, fFlags);
254 LogRel(("Audio: Initializing NULL driver\n"));
255
256 /*
257 * Init the static parts.
258 */
259 /* IBase */
260 pDrvIns->IBase.pfnQueryInterface = drvHstAudNullQueryInterface;
261 /* IHostAudio */
262 *pThis = g_DrvHostAudioNull;
263
264 return VINF_SUCCESS;
265}
266
267
268/**
269 * Char driver registration record.
270 */
271const PDMDRVREG g_DrvHostNullAudio =
272{
273 /* u32Version */
274 PDM_DRVREG_VERSION,
275 /* szName */
276 "NullAudio",
277 /* szRCMod */
278 "",
279 /* szR0Mod */
280 "",
281 /* pszDescription */
282 "NULL audio host driver",
283 /* fFlags */
284 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
285 /* fClass. */
286 PDM_DRVREG_CLASS_AUDIO,
287 /* cMaxInstances */
288 ~0U,
289 /* cbInstance */
290 sizeof(PDMIHOSTAUDIO),
291 /* pfnConstruct */
292 drvHstAudNullConstruct,
293 /* pfnDestruct */
294 NULL,
295 /* pfnRelocate */
296 NULL,
297 /* pfnIOCtl */
298 NULL,
299 /* pfnPowerOn */
300 NULL,
301 /* pfnReset */
302 NULL,
303 /* pfnSuspend */
304 NULL,
305 /* pfnResume */
306 NULL,
307 /* pfnAttach */
308 NULL,
309 /* pfnDetach */
310 NULL,
311 /* pfnPowerOff */
312 NULL,
313 /* pfnSoftReset */
314 NULL,
315 /* u32EndVersion */
316 PDM_DRVREG_VERSION
317};
318
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