VirtualBox

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

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

Audio: Added PDMIHOSTAUDIO::pfnSetDevice with implementation for CoreAudio. Added CoreAudio config values OutputDeviceID and InputDeviceID for the same purpose. bugref:9890

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1/* $Id: DrvHostAudioNull.cpp 89258 2021-05-25 09:58:08Z 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 bool fImmediate)
103{
104 RT_NOREF(pInterface, pStream, fImmediate);
105 return VINF_SUCCESS;
106}
107
108
109/**
110 * @ interface_method_impl{PDMIHOSTAUDIO,pfnStreamEnable}
111 */
112static DECLCALLBACK(int) drvHostNullAudioHA_StreamControlStub(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
113{
114 RT_NOREF(pInterface, pStream);
115 return VINF_SUCCESS;
116}
117
118
119/**
120 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamControl}
121 */
122static DECLCALLBACK(int) drvHostNullAudioHA_StreamControl(PPDMIHOSTAUDIO pInterface,
123 PPDMAUDIOBACKENDSTREAM pStream, PDMAUDIOSTREAMCMD enmStreamCmd)
124{
125 /** @todo r=bird: I'd like to get rid of this pfnStreamControl method,
126 * replacing it with individual StreamXxxx methods. That would save us
127 * potentally huge switches and more easily see which drivers implement
128 * which operations (grep for pfnStreamXxxx). */
129 switch (enmStreamCmd)
130 {
131 case PDMAUDIOSTREAMCMD_ENABLE:
132 return drvHostNullAudioHA_StreamControlStub(pInterface, pStream);
133 case PDMAUDIOSTREAMCMD_DISABLE:
134 return drvHostNullAudioHA_StreamControlStub(pInterface, pStream);
135 case PDMAUDIOSTREAMCMD_PAUSE:
136 return drvHostNullAudioHA_StreamControlStub(pInterface, pStream);
137 case PDMAUDIOSTREAMCMD_RESUME:
138 return drvHostNullAudioHA_StreamControlStub(pInterface, pStream);
139 case PDMAUDIOSTREAMCMD_DRAIN:
140 return drvHostNullAudioHA_StreamControlStub(pInterface, pStream);
141
142 case PDMAUDIOSTREAMCMD_END:
143 case PDMAUDIOSTREAMCMD_32BIT_HACK:
144 case PDMAUDIOSTREAMCMD_INVALID:
145 /* no default*/
146 break;
147 }
148 return VERR_NOT_SUPPORTED;
149}
150
151
152/**
153 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetReadable}
154 */
155static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
156{
157 RT_NOREF(pInterface, pStream);
158 /** @todo rate limit this? */
159 return UINT32_MAX;
160}
161
162
163/**
164 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetWritable}
165 */
166static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetWritable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
167{
168 RT_NOREF(pInterface, pStream);
169 return UINT32_MAX;
170}
171
172
173/**
174 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetPending}
175 */
176static DECLCALLBACK(uint32_t) drvHostNullAudioHA_StreamGetPending(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
177{
178 RT_NOREF(pInterface, pStream);
179 return 0;
180}
181
182
183/**
184 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamGetState}
185 */
186static DECLCALLBACK(PDMHOSTAUDIOSTREAMSTATE) drvHostNullAudioHA_StreamGetState(PPDMIHOSTAUDIO pInterface,
187 PPDMAUDIOBACKENDSTREAM pStream)
188{
189 RT_NOREF(pInterface);
190 AssertPtrReturn(pStream, PDMHOSTAUDIOSTREAMSTATE_INVALID);
191#if 0
192 /* Bit bucket appraoch where we ignore the output and silence the input buffers. */
193 return PDMHOSTAUDIOSTREAMSTATE_OKAY;
194#else
195 /* Approach where the mixer in the devices skips us and saves a few CPU cycles. */
196 return PDMHOSTAUDIOSTREAMSTATE_INACTIVE;
197#endif
198}
199
200
201/**
202 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamPlay}
203 */
204static DECLCALLBACK(int) drvHostNullAudioHA_StreamPlay(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
205 const void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
206{
207 RT_NOREF(pInterface, pStream, pvBuf);
208
209 /* The bitbucket never overflows. */
210 *pcbWritten = cbBuf;
211 return VINF_SUCCESS;
212}
213
214
215/**
216 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCapture}
217 */
218static DECLCALLBACK(int) drvHostNullAudioHA_StreamCapture(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream,
219 void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
220{
221 RT_NOREF(pInterface);
222 PNULLAUDIOSTREAM pStreamNull = (PNULLAUDIOSTREAM)pStream;
223
224 /** @todo rate limit this? */
225
226 /* Return silence. */
227 PDMAudioPropsClearBuffer(&pStreamNull->Cfg.Props, pvBuf, cbBuf,
228 PDMAudioPropsBytesToFrames(&pStreamNull->Cfg.Props, cbBuf));
229 *pcbRead = cbBuf;
230 return VINF_SUCCESS;
231}
232
233
234/**
235 * This is used directly by DrvAudio when a backend fails to initialize in a
236 * non-fatal manner.
237 */
238DECL_HIDDEN_CONST(PDMIHOSTAUDIO) const g_DrvHostAudioNull =
239{
240 /* .pfnGetConfig =*/ drvHostNullAudioHA_GetConfig,
241 /* .pfnGetDevices =*/ NULL,
242 /* .pfnSetDevice =*/ NULL,
243 /* .pfnGetStatus =*/ drvHostNullAudioHA_GetStatus,
244 /* .pfnDoOnWorkerThread =*/ NULL,
245 /* .pfnStreamConfigHint =*/ NULL,
246 /* .pfnStreamCreate =*/ drvHostNullAudioHA_StreamCreate,
247 /* .pfnStreamInitAsync =*/ NULL,
248 /* .pfnStreamDestroy =*/ drvHostNullAudioHA_StreamDestroy,
249 /* .pfnStreamNotifyDeviceChanged =*/ NULL,
250 /* .pfnStreamControl =*/ drvHostNullAudioHA_StreamControl,
251 /* .pfnStreamGetReadable =*/ drvHostNullAudioHA_StreamGetReadable,
252 /* .pfnStreamGetWritable =*/ drvHostNullAudioHA_StreamGetWritable,
253 /* .pfnStreamGetPending =*/ drvHostNullAudioHA_StreamGetPending,
254 /* .pfnStreamGetState =*/ drvHostNullAudioHA_StreamGetState,
255 /* .pfnStreamPlay =*/ drvHostNullAudioHA_StreamPlay,
256 /* .pfnStreamCapture =*/ drvHostNullAudioHA_StreamCapture,
257};
258
259
260/**
261 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
262 */
263static DECLCALLBACK(void *) drvHostNullAudioQueryInterface(PPDMIBASE pInterface, const char *pszIID)
264{
265 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
266 PPDMIHOSTAUDIO pThis = PDMINS_2_DATA(pDrvIns, PPDMIHOSTAUDIO);
267
268 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
269 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, pThis);
270 return NULL;
271}
272
273
274/**
275 * Constructs a Null audio driver instance.
276 *
277 * @copydoc FNPDMDRVCONSTRUCT
278 */
279static DECLCALLBACK(int) drvHostNullAudioConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
280{
281 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
282 PPDMIHOSTAUDIO pThis = PDMINS_2_DATA(pDrvIns, PPDMIHOSTAUDIO);
283 RT_NOREF(pCfg, fFlags);
284 LogRel(("Audio: Initializing NULL driver\n"));
285
286 /*
287 * Init the static parts.
288 */
289 /* IBase */
290 pDrvIns->IBase.pfnQueryInterface = drvHostNullAudioQueryInterface;
291 /* IHostAudio */
292 *pThis = g_DrvHostAudioNull;
293
294 return VINF_SUCCESS;
295}
296
297
298/**
299 * Char driver registration record.
300 */
301const PDMDRVREG g_DrvHostNullAudio =
302{
303 /* u32Version */
304 PDM_DRVREG_VERSION,
305 /* szName */
306 "NullAudio",
307 /* szRCMod */
308 "",
309 /* szR0Mod */
310 "",
311 /* pszDescription */
312 "NULL audio host driver",
313 /* fFlags */
314 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
315 /* fClass. */
316 PDM_DRVREG_CLASS_AUDIO,
317 /* cMaxInstances */
318 ~0U,
319 /* cbInstance */
320 sizeof(PDMIHOSTAUDIO),
321 /* pfnConstruct */
322 drvHostNullAudioConstruct,
323 /* pfnDestruct */
324 NULL,
325 /* pfnRelocate */
326 NULL,
327 /* pfnIOCtl */
328 NULL,
329 /* pfnPowerOn */
330 NULL,
331 /* pfnReset */
332 NULL,
333 /* pfnSuspend */
334 NULL,
335 /* pfnResume */
336 NULL,
337 /* pfnAttach */
338 NULL,
339 /* pfnDetach */
340 NULL,
341 /* pfnPowerOff */
342 NULL,
343 /* pfnSoftReset */
344 NULL,
345 /* u32EndVersion */
346 PDM_DRVREG_VERSION
347};
348
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