VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/audiosniffer.c@ 26100

Last change on this file since 26100 was 26001, checked in by vboxsync, 15 years ago

PDM,*: Redid the PDM structure versions. Check the instance and helper versions in every device and driver constructor.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.7 KB
Line 
1/* $Id: audiosniffer.c 26001 2010-01-25 14:21:13Z vboxsync $ */
2/** @file
3 * VBox audio device: Audio sniffer device
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#define LOG_GROUP LOG_GROUP_DEV_AUDIO
23#define AUDIO_CAP "sniffer"
24#include <VBox/pdm.h>
25#include <VBox/err.h>
26
27#include <VBox/log.h>
28#include <iprt/assert.h>
29#include <iprt/uuid.h>
30#include <iprt/string.h>
31#include <iprt/alloc.h>
32
33#include "Builtins.h"
34#include "../../vl_vbox.h"
35
36#include "audio.h"
37#include "audio_int.h"
38
39typedef struct _AUDIOSNIFFERSTATE
40{
41 /** If the device is enabled. */
42 bool fEnabled;
43
44 /** Whether audio should reach the host driver too. */
45 bool fKeepHostAudio;
46
47 /** Pointer to device instance. */
48 PPDMDEVINS pDevIns;
49
50 /** Audio Sniffer port base interface. */
51 PDMIBASE IBase;
52 /** Audio Sniffer port interface. */
53 PDMIAUDIOSNIFFERPORT IPort;
54
55 /** Pointer to base interface of the driver. */
56 PPDMIBASE pDrvBase;
57 /** Audio Sniffer connector interface */
58 PPDMIAUDIOSNIFFERCONNECTOR pDrv;
59
60} AUDIOSNIFFERSTATE;
61
62static AUDIOSNIFFERSTATE *g_pData = NULL;
63
64/*
65 * Public sniffer callbacks to be called from audio driver.
66 */
67
68/* *** Subject to change ***
69 * Process audio output. The function is called when an audio output
70 * driver is about to play audio samples.
71 *
72 * It is expected that there is only one audio data flow,
73 * i.e. one voice.
74 *
75 * @param hw Audio samples information.
76 * @param pvSamples Pointer to audio samples.
77 * @param cSamples Number of audio samples in the buffer.
78 * @returns 'true' if audio also to be played back by the output driver.
79 * 'false' if audio should not be played.
80 */
81DECLCALLBACK(bool) sniffer_run_out (HWVoiceOut *hw, void *pvSamples, unsigned cSamples)
82{
83 int samplesPerSec;
84 int nChannels;
85 int bitsPerSample;
86 bool fUnsigned;
87
88 if (!g_pData || !g_pData->pDrv || !g_pData->fEnabled)
89 {
90 return true;
91 }
92
93 samplesPerSec = hw->info.freq;
94 nChannels = hw->info.nchannels;
95 bitsPerSample = hw->info.bits;
96 fUnsigned = (hw->info.sign == 0);
97
98 g_pData->pDrv->pfnAudioSamplesOut (g_pData->pDrv, pvSamples, cSamples,
99 samplesPerSec, nChannels, bitsPerSample, fUnsigned);
100
101 return g_pData->fKeepHostAudio;
102}
103
104
105/*
106 * Audio Sniffer PDM device.
107 */
108
109static DECLCALLBACK(int) iface_Setup (PPDMIAUDIOSNIFFERPORT pInterface, bool fEnable, bool fKeepHostAudio)
110{
111 AUDIOSNIFFERSTATE *pThis = RT_FROM_MEMBER(pInterface, AUDIOSNIFFERSTATE, IPort);
112
113 Assert(g_pData == pThis);
114
115 pThis->fEnabled = fEnable;
116 pThis->fKeepHostAudio = fKeepHostAudio;
117
118 return VINF_SUCCESS;
119}
120
121/**
122 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
123 */
124static DECLCALLBACK(void *) iface_QueryInterface(PPDMIBASE pInterface, const char *pszIID)
125{
126 AUDIOSNIFFERSTATE *pThis = RT_FROM_MEMBER(pInterface, AUDIOSNIFFERSTATE, IBase);
127 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase);
128 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIAUDIOSNIFFERPORT, &pThis->IPort);
129 return NULL;
130}
131
132/**
133 * Destruct a device instance.
134 *
135 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
136 * resources can be freed correctly.
137 *
138 * @returns VBox status.
139 * @param pDevIns The device instance data.
140 */
141static DECLCALLBACK(int) audioSnifferR3Destruct(PPDMDEVINS pDevIns)
142{
143 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
144
145 /* Zero the global pointer. */
146 g_pData = NULL;
147
148 return VINF_SUCCESS;
149}
150
151/**
152 * Construct a device instance for a VM.
153 *
154 * @returns VBox status.
155 * @param pDevIns The device instance data.
156 * If the registration structure is needed, pDevIns->pDevReg points to it.
157 * @param iInstance Instance number. Use this to figure out which registers and such to use.
158 * The device number is also found in pDevIns->iInstance, but since it's
159 * likely to be freqently used PDM passes it as parameter.
160 * @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
161 * of the device instance. It's also found in pDevIns->pCfgHandle, but like
162 * iInstance it's expected to be used a bit in this function.
163 */
164static DECLCALLBACK(int) audioSnifferR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
165{
166 int rc = VINF_SUCCESS;
167 AUDIOSNIFFERSTATE *pThis = PDMINS_2_DATA(pDevIns, AUDIOSNIFFERSTATE *);
168
169 Assert(iInstance == 0);
170 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
171
172 /*
173 * Validate configuration.
174 */
175 if (!CFGMR3AreValuesValid(pCfgHandle, "\0"))
176 {
177 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
178 }
179
180 /*
181 * Initialize data.
182 */
183 pThis->fEnabled = false;
184 pThis->fKeepHostAudio = true;
185 pThis->pDrv = NULL;
186
187 /*
188 * Interfaces
189 */
190 /* Base */
191 pThis->IBase.pfnQueryInterface = iface_QueryInterface;
192
193 /* Audio Sniffer port */
194 pThis->IPort.pfnSetup = iface_Setup;
195
196 /*
197 * Get the corresponding connector interface
198 */
199 rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Audio Sniffer Port");
200
201 if (RT_SUCCESS(rc))
202 {
203 pThis->pDrv = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOSNIFFERCONNECTOR);
204 AssertMsgStmt(pThis->pDrv, ("LUN #0 doesn't have a Audio Sniffer connector interface rc=%Rrc\n", rc),
205 rc = VERR_PDM_MISSING_INTERFACE);
206 }
207 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
208 {
209 Log(("%s/%d: warning: no driver attached to LUN #0.\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
210 rc = VINF_SUCCESS;
211 }
212 else
213 {
214 AssertMsgFailed(("Failed to attach LUN #0. rc=%Rrc\n", rc));
215 }
216
217 if (RT_SUCCESS (rc))
218 {
219 /* Save PDM device instance data for future reference. */
220 pThis->pDevIns = pDevIns;
221
222 /* Save the pointer to created instance in the global variable, so other
223 * functions could reach it.
224 */
225 g_pData = pThis;
226 }
227
228 return rc;
229}
230
231/**
232 * The Audio Sniffer device registration structure.
233 */
234const PDMDEVREG g_DeviceAudioSniffer =
235{
236 /* u32Version */
237 PDM_DEVREG_VERSION,
238 /* szDeviceName */
239 "AudioSniffer",
240 /* szRCMod */
241 "",
242 /* szR0Mod */
243 "",
244 /* pszDescription */
245 "Audio Sniffer device. Redirects audio data to sniffer driver.",
246 /* fFlags */
247 PDM_DEVREG_FLAGS_DEFAULT_BITS,
248 /* fClass */
249 PDM_DEVREG_CLASS_AUDIO,
250 /* cMaxInstances */
251 1,
252 /* cbInstance */
253 sizeof(AUDIOSNIFFERSTATE),
254 /* pfnConstruct */
255 audioSnifferR3Construct,
256 /* pfnDestruct */
257 audioSnifferR3Destruct,
258 /* pfnRelocate */
259 NULL,
260 /* pfnIOCtl */
261 NULL,
262 /* pfnPowerOn */
263 NULL,
264 /* pfnReset */
265 NULL,
266 /* pfnSuspend */
267 NULL,
268 /* pfnResume */
269 NULL,
270 /* pfnAttach */
271 NULL,
272 /* pfnDetach */
273 NULL,
274 /* pfnQueryInterface */
275 NULL,
276 /* pfnInitComplete */
277 NULL,
278 /* pfnPowerOff */
279 NULL,
280 /* pfnSoftReset */
281 NULL,
282 PDM_DEVREG_VERSION
283};
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