VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1/* $Id: DrvHostAudioNull.cpp 106061 2024-09-16 14:03:52Z 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-2024 Oracle and/or its affiliates.
10 *
11 * This file is part of VirtualBox base platform packages, as
12 * available from https://www.virtualbox.org.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation, in version 3 of the
17 * License.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see <https://www.gnu.org/licenses>.
26 *
27 * SPDX-License-Identifier: GPL-3.0-only
28 */
29
30
31/*********************************************************************************************************************************
32* Header Files *
33*********************************************************************************************************************************/
34#include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */
35
36#define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO
37#include <VBox/log.h>
38#include <VBox/vmm/pdmaudioifs.h>
39#include <VBox/vmm/pdmaudioinline.h>
40
41#include "VBoxDD.h"
42
43
44/*********************************************************************************************************************************
45* Structures and Typedefs *
46*********************************************************************************************************************************/
47/** Null audio stream. */
48typedef struct DRVHSTAUDNULLSTREAM
49{
50 /** Common part. */
51 PDMAUDIOBACKENDSTREAM Core;
52 /** The stream's acquired configuration. */
53 PDMAUDIOSTREAMCFG Cfg;
54} DRVHSTAUDNULLSTREAM;
55/** Pointer to a null audio stream. */
56typedef DRVHSTAUDNULLSTREAM *PDRVHSTAUDNULLSTREAM;
57
58
59
60/**
61 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetConfig}
62 */
63static DECLCALLBACK(int) drvHstAudNullHA_GetConfig(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pBackendCfg)
64{
65 NOREF(pInterface);
66 AssertPtrReturn(pBackendCfg, VERR_INVALID_POINTER);
67
68 /*
69 * Fill in the config structure.
70 */
71 RTStrCopy(pBackendCfg->szName, sizeof(pBackendCfg->szName), "NULL audio");
72 pBackendCfg->cbStream = sizeof(DRVHSTAUDNULLSTREAM);
73 pBackendCfg->fFlags = 0;
74 pBackendCfg->cMaxStreamsOut = 1; /* Output */
75 pBackendCfg->cMaxStreamsIn = 2; /* Line input + microphone input. */
76
77 return VINF_SUCCESS;
78}
79
80
81/**
82 * @interface_method_impl{PDMIHOSTAUDIO,pfnGetStatus}
83 */
84static DECLCALLBACK(PDMAUDIOBACKENDSTS) drvHstAudNullHA_GetStatus(PPDMIHOSTAUDIO pInterface, PDMAUDIODIR enmDir)
85{
86 RT_NOREF(pInterface, enmDir);
87 return PDMAUDIOBACKENDSTS_RUNNING;
88}
89
90
91/**
92 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
93 */
94static DECLCALLBACK(int) drvHstAudNullHA_StreamCreate(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
95 PCPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
96{
97 RT_NOREF(pInterface);
98 PDRVHSTAUDNULLSTREAM pStreamNull = (PDRVHSTAUDNULLSTREAM)pStream;
99 AssertPtrReturn(pStreamNull, VERR_INVALID_POINTER);
100 AssertPtrReturn(pCfgReq, VERR_INVALID_POINTER);
101 AssertPtrReturn(pCfgAcq, VERR_INVALID_POINTER);
102
103 PDMAudioStrmCfgCopy(&pStreamNull->Cfg, pCfgAcq);
104 return VINF_SUCCESS;
105}
106
107
108/**
109 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamDestroy}
110 */
111static DECLCALLBACK(int) drvHstAudNullHA_StreamDestroy(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream, bool fImmediate)
112{
113 RT_NOREF(pInterface, pStream, fImmediate);
114 return VINF_SUCCESS;
115}
116
117
118/**
119 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamEnable}
120 */
121static DECLCALLBACK(int) drvHstAudNullHA_StreamControlStub(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
122{
123 RT_NOREF(pInterface, pStream);
124 return VINF_SUCCESS;
125}
126
127
128/**
129 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
130 */
131static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHstAudNullHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
132 PPDMAUDIOBACKENDSTREAM pStream)
133{
134 RT_NOREF(pInterface);
135 AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
136#if 0
137 /* Bit bucket appraoch where we ignore the output and silence the input buffers. */
138 return PDMHOSTAUDIOSTREAMSTATE_OKAY;
139#else
140 /* Approach where the mixer in the devices skips us and saves a few CPU cycles. */
141 return PDMHOSTAUDIOSTREAMSTATE_INACTIVE;
142#endif
143}
144
145
146/**
147 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetPending}
148 */
149static DECLCALLBACK(uint32_t) drvHstAudNullHA_StreamGetPending(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
150{
151 RT_NOREF(pInterface, pStream);
152 return 0;
153}
154
155
156/**
157 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable}
158 */
159static DECLCALLBACK(uint32_t) drvHstAudNullHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
160{
161 RT_NOREF(pInterface, pStream);
162 return UINT32_MAX;
163}
164
165
166/**
167 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
168 */
169static DECLCALLBACK(int) drvHstAudNullHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
170 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
171{
172 RT_NOREF(pInterface, pStream, pvBuf);
173
174 /* The bitbucket never overflows. */
175 *pcbWritten = cbBuf;
176 return VINF_SUCCESS;
177}
178
179
180/**
181 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable}
182 */
183static DECLCALLBACK(uint32_t) drvHstAudNullHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
184{
185 RT_NOREF(pInterface, pStream);
186 /** @todo rate limit this? */
187 return UINT32_MAX;
188}
189
190
191/**
192 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
193 */
194static DECLCALLBACK(int) drvHstAudNullHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
195 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
196{
197 RT_NOREF(pInterface);
198 PDRVHSTAUDNULLSTREAM pStreamNull = (PDRVHSTAUDNULLSTREAM)pStream;
199
200 /** @todo rate limit this? */
201
202 /* Return silence. */
203 PDMAudioPropsClearBuffer(&pStreamNull->Cfg.Props, pvBuf, cbBuf,
204 PDMAudioPropsBytesToFrames(&pStreamNull->Cfg.Props, cbBuf));
205 *pcbRead = cbBuf;
206 return VINF_SUCCESS;
207}
208
209
210/**
211 * This is used directly by DrvAudio when a backend fails to initialize in a
212 * non-fatal manner.
213 */
214DECL_HIDDEN_CONST(PDMIHOSTAUDIO) const g_DrvHostAudioNull =
215{
216 /* .pfnGetConfig =*/ drvHstAudNullHA_GetConfig,
217 /* .pfnGetDevices =*/ NULL,
218 /* .pfnSetDevice =*/ NULL,
219 /* .pfnGetStatus =*/ drvHstAudNullHA_GetStatus,
220 /* .pfnDoOnWorkerThread =*/ NULL,
221 /* .pfnStreamConfigHint =*/ NULL,
222 /* .pfnStreamCreate =*/ drvHstAudNullHA_StreamCreate,
223 /* .pfnStreamInitAsync =*/ NULL,
224 /* .pfnStreamDestroy =*/ drvHstAudNullHA_StreamDestroy,
225 /* .pfnStreamNotifyDeviceChanged =*/ NULL,
226 /* .pfnStreamEnable =*/ drvHstAudNullHA_StreamControlStub,
227 /* .pfnStreamDisable =*/ drvHstAudNullHA_StreamControlStub,
228 /* .pfnStreamPause =*/ drvHstAudNullHA_StreamControlStub,
229 /* .pfnStreamResume =*/ drvHstAudNullHA_StreamControlStub,
230 /* .pfnStreamDrain =*/ drvHstAudNullHA_StreamControlStub,
231 /* .pfnStreamGetState =*/ drvHstAudNullHA_StreamGetState,
232 /* .pfnStreamGetPending =*/ drvHstAudNullHA_StreamGetPending,
233 /* .pfnStreamGetWritable =*/ drvHstAudNullHA_StreamGetWritable,
234 /* .pfnStreamPlay =*/ drvHstAudNullHA_StreamPlay,
235 /* .pfnStreamGetReadable =*/ drvHstAudNullHA_StreamGetReadable,
236 /* .pfnStreamCapture =*/ drvHstAudNullHA_StreamCapture,
237};
238
239
240/**
241 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
242 */
243static DECLCALLBACK(void *) drvHstAudNullQueryInterface(PPDMIBASE pInterface, const char *pszIID)
244{
245 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
246 PPDMIHOSTAUDIO pThis = PDMINS_2_DATA(pDrvIns, PPDMIHOSTAUDIO);
247
248 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
249 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, pThis);
250 return NULL;
251}
252
253
254/**
255 * Constructs a Null audio driver instance.
256 *
257 * @copydoc FNPDMDRVCONSTRUCT
258 */
259static DECLCALLBACK(int) drvHstAudNullConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
260{
261 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
262 PPDMIHOSTAUDIO pThis = PDMINS_2_DATA(pDrvIns, PPDMIHOSTAUDIO);
263 RT_NOREF(pCfg, fFlags);
264 LogRel(("Audio: Initializing NULL driver\n"));
265
266 /*
267 * Init the static parts.
268 */
269 /* IBase */
270 pDrvIns->IBase.pfnQueryInterface = drvHstAudNullQueryInterface;
271 /* IHostAudio */
272 *pThis = g_DrvHostAudioNull;
273
274 return VINF_SUCCESS;
275}
276
277
278/**
279 * Char driver registration record.
280 */
281const PDMDRVREG g_DrvHostNullAudio =
282{
283 /* u32Version */
284 PDM_DRVREG_VERSION,
285 /* szName */
286 "NullAudio",
287 /* szRCMod */
288 "",
289 /* szR0Mod */
290 "",
291 /* pszDescription */
292 "NULL audio host driver",
293 /* fFlags */
294 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
295 /* fClass. */
296 PDM_DRVREG_CLASS_AUDIO,
297 /* cMaxInstances */
298 ~0U,
299 /* cbInstance */
300 sizeof(PDMIHOSTAUDIO),
301 /* pfnConstruct */
302 drvHstAudNullConstruct,
303 /* pfnDestruct */
304 NULL,
305 /* pfnRelocate */
306 NULL,
307 /* pfnIOCtl */
308 NULL,
309 /* pfnPowerOn */
310 NULL,
311 /* pfnReset */
312 NULL,
313 /* pfnSuspend */
314 NULL,
315 /* pfnResume */
316 NULL,
317 /* pfnAttach */
318 NULL,
319 /* pfnDetach */
320 NULL,
321 /* pfnPowerOff */
322 NULL,
323 /* pfnSoftReset */
324 NULL,
325 /* u32EndVersion */
326 PDM_DRVREG_VERSION
327};
328
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