VirtualBox

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

最後變更 在這個檔案從89504是 89504,由 vboxsync 提交於 4 年 前

Audio: Re-ordering some methods, no real change. bugref:9890

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 10.9 KB
 
1/* $Id: DrvHostAudioNull.cpp 89504 2021-06-04 11:30: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-2020 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.alldomusa.eu.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,pfnStreamControl}
120 */
121static DECLCALLBACK(int) drvHstAudNullHA_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 drvHstAudNullHA_StreamControlStub(pInterface, pStream);
132 case PDMAUDIOSTREAMCMD_DISABLE:
133 return drvHstAudNullHA_StreamControlStub(pInterface, pStream);
134 case PDMAUDIOSTREAMCMD_PAUSE:
135 return drvHstAudNullHA_StreamControlStub(pInterface, pStream);
136 case PDMAUDIOSTREAMCMD_RESUME:
137 return drvHstAudNullHA_StreamControlStub(pInterface, pStream);
138 case PDMAUDIOSTREAMCMD_DRAIN:
139 return drvHstAudNullHA_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,pfnStreamGetState}
153 */
154static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHstAudNullHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
155 PPDMAUDIOBACKENDSTREAM pStream)
156{
157 RT_NOREF(pInterface);
158 AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
159#if 0
160 /* Bit bucket appraoch where we ignore the output and silence the input buffers. */
161 return PDMHOSTAUDIOSTREAMSTATE_OKAY;
162#else
163 /* Approach where the mixer in the devices skips us and saves a few CPU cycles. */
164 return PDMHOSTAUDIOSTREAMSTATE_INACTIVE;
165#endif
166}
167
168
169/**
170 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetPending}
171 */
172static DECLCALLBACK(uint32_t) drvHstAudNullHA_StreamGetPending(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
173{
174 RT_NOREF(pInterface, pStream);
175 return 0;
176}
177
178
179/**
180 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable}
181 */
182static DECLCALLBACK(uint32_t) drvHstAudNullHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
183{
184 RT_NOREF(pInterface, pStream);
185 return UINT32_MAX;
186}
187
188
189/**
190 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
191 */
192static DECLCALLBACK(int) drvHstAudNullHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
193 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
194{
195 RT_NOREF(pInterface, pStream, pvBuf);
196
197 /* The bitbucket never overflows. */
198 *pcbWritten = cbBuf;
199 return VINF_SUCCESS;
200}
201
202
203/**
204 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable}
205 */
206static DECLCALLBACK(uint32_t) drvHstAudNullHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
207{
208 RT_NOREF(pInterface, pStream);
209 /** @todo rate limit this? */
210 return UINT32_MAX;
211}
212
213
214/**
215 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
216 */
217static DECLCALLBACK(int) drvHstAudNullHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
218 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
219{
220 RT_NOREF(pInterface);
221 PDRVHSTAUDNULLSTREAM pStreamNull = (PDRVHSTAUDNULLSTREAM)pStream;
222
223 /** @todo rate limit this? */
224
225 /* Return silence. */
226 PDMAudioPropsClearBuffer(&pStreamNull->Cfg.Props, pvBuf, cbBuf,
227 PDMAudioPropsBytesToFrames(&pStreamNull->Cfg.Props, cbBuf));
228 *pcbRead = cbBuf;
229 return VINF_SUCCESS;
230}
231
232
233/**
234 * This is used directly by DrvAudio when a backend fails to initialize in a
235 * non-fatal manner.
236 */
237DECL_HIDDEN_CONST(PDMIHOSTAUDIO) const g_DrvHostAudioNull =
238{
239 /* .pfnGetConfig =*/ drvHstAudNullHA_GetConfig,
240 /* .pfnGetDevices =*/ NULL,
241 /* .pfnSetDevice =*/ NULL,
242 /* .pfnGetStatus =*/ drvHstAudNullHA_GetStatus,
243 /* .pfnDoOnWorkerThread =*/ NULL,
244 /* .pfnStreamConfigHint =*/ NULL,
245 /* .pfnStreamCreate =*/ drvHstAudNullHA_StreamCreate,
246 /* .pfnStreamInitAsync =*/ NULL,
247 /* .pfnStreamDestroy =*/ drvHstAudNullHA_StreamDestroy,
248 /* .pfnStreamNotifyDeviceChanged =*/ NULL,
249 /* .pfnStreamControl =*/ drvHstAudNullHA_StreamControl,
250 /* .pfnStreamGetState =*/ drvHstAudNullHA_StreamGetState,
251 /* .pfnStreamGetPending =*/ drvHstAudNullHA_StreamGetPending,
252 /* .pfnStreamGetWritable =*/ drvHstAudNullHA_StreamGetWritable,
253 /* .pfnStreamPlay =*/ drvHstAudNullHA_StreamPlay,
254 /* .pfnStreamGetReadable =*/ drvHstAudNullHA_StreamGetReadable,
255 /* .pfnStreamCapture =*/ drvHstAudNullHA_StreamCapture,
256};
257
258
259/**
260 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
261 */
262static DECLCALLBACK(void *) drvHstAudNullQueryInterface(PPDMIBASE pInterface, const char *pszIID)
263{
264 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
265 PPDMIHOSTAUDIO pThis = PDMINS_2_DATA(pDrvIns, PPDMIHOSTAUDIO);
266
267 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
268 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, pThis);
269 return NULL;
270}
271
272
273/**
274 * Constructs a Null audio driver instance.
275 *
276 * @copydoc FNPDMDRVCONSTRUCT
277 */
278static DECLCALLBACK(int) drvHstAudNullConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
279{
280 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
281 PPDMIHOSTAUDIO pThis = PDMINS_2_DATA(pDrvIns, PPDMIHOSTAUDIO);
282 RT_NOREF(pCfg, fFlags);
283 LogRel(("Audio: Initializing NULL driver\n"));
284
285 /*
286 * Init the static parts.
287 */
288 /* IBase */
289 pDrvIns->IBase.pfnQueryInterface = drvHstAudNullQueryInterface;
290 /* IHostAudio */
291 *pThis = g_DrvHostAudioNull;
292
293 return VINF_SUCCESS;
294}
295
296
297/**
298 * Char driver registration record.
299 */
300const PDMDRVREG g_DrvHostNullAudio =
301{
302 /* u32Version */
303 PDM_DRVREG_VERSION,
304 /* szName */
305 "NullAudio",
306 /* szRCMod */
307 "",
308 /* szR0Mod */
309 "",
310 /* pszDescription */
311 "NULL audio host driver",
312 /* fFlags */
313 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
314 /* fClass. */
315 PDM_DRVREG_CLASS_AUDIO,
316 /* cMaxInstances */
317 ~0U,
318 /* cbInstance */
319 sizeof(PDMIHOSTAUDIO),
320 /* pfnConstruct */
321 drvHstAudNullConstruct,
322 /* pfnDestruct */
323 NULL,
324 /* pfnRelocate */
325 NULL,
326 /* pfnIOCtl */
327 NULL,
328 /* pfnPowerOn */
329 NULL,
330 /* pfnReset */
331 NULL,
332 /* pfnSuspend */
333 NULL,
334 /* pfnResume */
335 NULL,
336 /* pfnAttach */
337 NULL,
338 /* pfnDetach */
339 NULL,
340 /* pfnPowerOff */
341 NULL,
342 /* pfnSoftReset */
343 NULL,
344 /* u32EndVersion */
345 PDM_DRVREG_VERSION
346};
347
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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