VirtualBox

source: vbox/trunk/src/VBox/Main/AudioSnifferInterface.cpp@ 35061

Last change on this file since 35061 was 34906, checked in by vboxsync, 14 years ago

Initial audio filter implementation, which is used for audio input via remote desktop server.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1/* $Id: AudioSnifferInterface.cpp 34906 2010-12-09 16:29:49Z vboxsync $ */
2/** @file
3 * VirtualBox Driver Interface to Audio Sniffer device
4 */
5
6/*
7 * Copyright (C) 2006-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "AudioSnifferInterface.h"
19#include "ConsoleImpl.h"
20#include "ConsoleVRDPServer.h"
21
22#include "Logging.h"
23
24#include <VBox/pdmdrv.h>
25#include <VBox/RemoteDesktop/VRDE.h>
26#include <VBox/cfgm.h>
27#include <VBox/err.h>
28
29//
30// defines
31//
32
33
34//
35// globals
36//
37
38
39/**
40 * Audio Sniffer driver instance data.
41 *
42 * @extends PDMIAUDIOSNIFFERCONNECTOR
43 */
44typedef struct DRVAUDIOSNIFFER
45{
46 /** Pointer to the Audio Sniffer object. */
47 AudioSniffer *pAudioSniffer;
48
49 /** Pointer to the driver instance structure. */
50 PPDMDRVINS pDrvIns;
51
52 /** Pointer to the AudioSniffer port interface of the driver/device above us. */
53 PPDMIAUDIOSNIFFERPORT pUpPort;
54 /** Our VMM device connector interface. */
55 PDMIAUDIOSNIFFERCONNECTOR Connector;
56
57} DRVAUDIOSNIFFER, *PDRVAUDIOSNIFFER;
58
59/** Converts PDMIAUDIOSNIFFERCONNECTOR pointer to a DRVAUDIOSNIFFER pointer. */
60#define PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface) RT_FROM_MEMBER(pInterface, DRVAUDIOSNIFFER, Connector)
61
62
63//
64// constructor / destructor
65//
66AudioSniffer::AudioSniffer(Console *console)
67 : mpDrv(NULL),
68 mParent(console)
69{
70}
71
72AudioSniffer::~AudioSniffer()
73{
74 if (mpDrv)
75 {
76 mpDrv->pAudioSniffer = NULL;
77 mpDrv = NULL;
78 }
79}
80
81PPDMIAUDIOSNIFFERPORT AudioSniffer::getAudioSnifferPort()
82{
83 Assert(mpDrv);
84 return mpDrv->pUpPort;
85}
86
87
88
89//
90// public methods
91//
92
93DECLCALLBACK(void) iface_AudioSamplesOut (PPDMIAUDIOSNIFFERCONNECTOR pInterface, void *pvSamples, uint32_t cSamples,
94 int samplesPerSec, int nChannels, int bitsPerSample, bool fUnsigned)
95{
96 PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface);
97
98 /*
99 * Just call the VRDP server with the data.
100 */
101 VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(samplesPerSec, nChannels, bitsPerSample, !fUnsigned);
102 pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioSamples(pvSamples, cSamples, format);
103}
104
105DECLCALLBACK(void) iface_AudioVolumeOut (PPDMIAUDIOSNIFFERCONNECTOR pInterface, uint16_t left, uint16_t right)
106{
107 PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface);
108
109 /*
110 * Just call the VRDP server with the data.
111 */
112 pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioVolume(left, right);
113}
114
115DECLCALLBACK(int) iface_AudioInputBegin (PPDMIAUDIOSNIFFERCONNECTOR pInterface,
116 void **ppvUserCtx,
117 void *pvContext,
118 uint32_t cSamples,
119 uint32_t iSampleHz,
120 uint32_t cChannels,
121 uint32_t cBits)
122{
123 PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface);
124
125 return pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioInputBegin(ppvUserCtx,
126 pvContext,
127 cSamples,
128 iSampleHz,
129 cChannels,
130 cBits);
131}
132
133DECLCALLBACK(void) iface_AudioInputEnd (PPDMIAUDIOSNIFFERCONNECTOR pInterface,
134 void *pvUserCtx)
135{
136 PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface);
137
138 pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioInputEnd(pvUserCtx);
139}
140
141
142/**
143 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
144 */
145DECLCALLBACK(void *) AudioSniffer::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)
146{
147 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
148 PDRVAUDIOSNIFFER pDrv = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER);
149 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
150 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIAUDIOSNIFFERCONNECTOR, &pDrv->Connector);
151 return NULL;
152}
153
154
155/**
156 * Destruct a Audio Sniffer driver instance.
157 *
158 * @returns VBox status.
159 * @param pDrvIns The driver instance data.
160 */
161DECLCALLBACK(void) AudioSniffer::drvDestruct(PPDMDRVINS pDrvIns)
162{
163 PDRVAUDIOSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER);
164 LogFlow(("AudioSniffer::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
165 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
166
167 if (pThis->pAudioSniffer)
168 {
169 pThis->pAudioSniffer->mpDrv = NULL;
170 }
171}
172
173
174/**
175 * Construct a AudioSniffer driver instance.
176 *
177 * @copydoc FNPDMDRVCONSTRUCT
178 */
179DECLCALLBACK(int) AudioSniffer::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
180{
181 PDRVAUDIOSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER);
182
183 LogFlow(("AudioSniffer::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
184 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
185
186 /*
187 * Validate configuration.
188 */
189 if (!CFGMR3AreValuesValid(pCfg, "Object\0"))
190 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
191 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER,
192 ("Configuration error: Not possible to attach anything to this driver!\n"),
193 VERR_PDM_DRVINS_NO_ATTACH);
194
195 /*
196 * IBase.
197 */
198 pDrvIns->IBase.pfnQueryInterface = AudioSniffer::drvQueryInterface;
199
200 /* Audio Sniffer connector. */
201 pThis->Connector.pfnAudioSamplesOut = iface_AudioSamplesOut;
202 pThis->Connector.pfnAudioVolumeOut = iface_AudioVolumeOut;
203 pThis->Connector.pfnAudioInputBegin = iface_AudioInputBegin;
204 pThis->Connector.pfnAudioInputEnd = iface_AudioInputEnd;
205
206 /*
207 * Get the Audio Sniffer Port interface of the above driver/device.
208 */
209 pThis->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOSNIFFERPORT);
210 if (!pThis->pUpPort)
211 {
212 AssertMsgFailed(("Configuration error: No Audio Sniffer port interface above!\n"));
213 return VERR_PDM_MISSING_INTERFACE_ABOVE;
214 }
215
216 /*
217 * Get the Console object pointer and update the mpDrv member.
218 */
219 void *pv;
220 int rc = CFGMR3QueryPtr(pCfg, "Object", &pv);
221 if (RT_FAILURE(rc))
222 {
223 AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc));
224 return rc;
225 }
226 pThis->pAudioSniffer = (AudioSniffer *)pv; /** @todo Check this cast! */
227 pThis->pAudioSniffer->mpDrv = pThis;
228
229 return VINF_SUCCESS;
230}
231
232
233/**
234 * Audio Sniffer driver registration record.
235 */
236const PDMDRVREG AudioSniffer::DrvReg =
237{
238 /* u32Version */
239 PDM_DRVREG_VERSION,
240 /* szName */
241 "MainAudioSniffer",
242 /* szRCMod */
243 "",
244 /* szR0Mod */
245 "",
246 /* pszDescription */
247 "Main Audio Sniffer driver (Main as in the API).",
248 /* fFlags */
249 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
250 /* fClass. */
251 PDM_DRVREG_CLASS_AUDIO,
252 /* cMaxInstances */
253 ~0,
254 /* cbInstance */
255 sizeof(DRVAUDIOSNIFFER),
256 /* pfnConstruct */
257 AudioSniffer::drvConstruct,
258 /* pfnDestruct */
259 AudioSniffer::drvDestruct,
260 /* pfnRelocate */
261 NULL,
262 /* pfnIOCtl */
263 NULL,
264 /* pfnPowerOn */
265 NULL,
266 /* pfnReset */
267 NULL,
268 /* pfnSuspend */
269 NULL,
270 /* pfnResume */
271 NULL,
272 /* pfnAttach */
273 NULL,
274 /* pfnDetach */
275 NULL,
276 /* pfnPowerOff */
277 NULL,
278 /* pfnSoftReset */
279 NULL,
280 /* u32EndVersion */
281 PDM_DRVREG_VERSION
282};
283/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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