VirtualBox

source: vbox/trunk/src/VBox/Main/src-client/AudioDriver.cpp@ 70533

Last change on this file since 70533 was 70533, checked in by vboxsync, 7 years ago

Audio/VRDE: Implemented audio driver base class for Main audio drivers for dynamically attaching / detaching on runtime.

  • Property svn:executable set to *
File size: 6.5 KB
Line 
1/* $Id$ */
2/** @file
3 * VirtualBox audio base class for Main audio drivers.
4 */
5
6/*
7 * Copyright (C) 2018 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
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO
23#include "LoggingNew.h"
24
25#include <VBox/log.h>
26#include <VBox/vmm/cfgm.h>
27#include <VBox/vmm/pdmaudioifs.h>
28#include <VBox/vmm/pdmapi.h>
29#include <VBox/vmm/pdmdrv.h>
30
31#include "AudioDriver.h"
32#include "ConsoleImpl.h"
33
34AudioDriver::AudioDriver(Console *pConsole)
35 : mpConsole(pConsole)
36 , mfAttached(false)
37{
38}
39
40AudioDriver::~AudioDriver(void)
41{
42}
43
44/**
45 * Returns the next free LUN of the audio device driver
46 * chain.
47 *
48 * @return unsigned Next free LUN in audio device driver chain.
49 */
50unsigned AudioDriver::getFreeLUN(void)
51{
52 Console::SafeVMPtrQuiet ptrVM(mpConsole);
53 Assert(ptrVM.isOk());
54
55 PUVM pUVM = ptrVM.rawUVM();
56 AssertPtr(pUVM);
57
58 unsigned uLUN = 0;
59
60 /* First check if the LUN already exists. */
61 PCFGMNODE pDevLUN;
62 for (;;)
63 {
64 pDevLUN = CFGMR3GetChildF(CFGMR3GetRootU(pUVM), "Devices/%s/%u/LUN#%u/", mCfg.strDev.c_str(), mCfg.uInst, uLUN);
65 if (!pDevLUN)
66 break;
67 uLUN++;
68 }
69
70 return uLUN;
71}
72
73/**
74 * Configures the audio driver (to CFGM) and attaches it to the audio chain.
75 *
76 * @returns IPRT status code.
77 * @param pThis Audio driver to detach.
78 * @param pCfg Audio driver configuration to use for the audio driver to attach.
79 */
80/* static */
81DECLCALLBACK(int) AudioDriver::Attach(AudioDriver *pThis, AudioDriverCfg *pCfg)
82{
83 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
84
85 Console::SafeVMPtrQuiet ptrVM(pThis->mpConsole);
86 Assert(ptrVM.isOk());
87
88 int vrc = VINF_SUCCESS;
89
90 if (pThis->mfAttached) /* Already attached? Bail out. */
91 return VINF_SUCCESS;
92
93 if (pCfg->uLUN == UINT8_MAX) /* No LUN assigned / configured yet? Retrieve it. */
94 pCfg->uLUN = pThis->getFreeLUN();
95
96 LogFunc(("strDevice=%s, uInst=%u, uLUN=%u\n", pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN));
97
98 vrc = pThis->Configure(pCfg, true /* Attach */);
99 if (RT_SUCCESS(vrc))
100 vrc = PDMR3DriverAttach(ptrVM.rawUVM(), pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN, 0 /* fFlags */, NULL /* ppBase */);
101
102 if (RT_SUCCESS(vrc))
103 {
104 pThis->mfAttached = true;
105 }
106 else
107 LogRel(("VRDE: Failed to attach audio driver, rc=%Rrc\n", vrc));
108
109 return vrc;
110}
111
112/**
113 * Detaches an already attached audio driver from the audio chain.
114 *
115 * @returns IPRT status code.
116 * @param pThis Audio driver to detach.
117 */
118/* static */
119DECLCALLBACK(int) AudioDriver::Detach(AudioDriver *pThis)
120{
121 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
122
123 Console::SafeVMPtrQuiet ptrVM(pThis->mpConsole);
124 Assert(ptrVM.isOk());
125
126 if (!pThis->mfAttached) /* Not attached? Bail out. */
127 return VINF_SUCCESS;
128
129 int vrc = VINF_SUCCESS;
130
131 AudioDriverCfg *pCfg = &pThis->mCfg;
132
133 LogFunc(("strDevice=%s, uInst=%u, uLUN=%u\n", pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN));
134
135 vrc = PDMR3DriverDetach(ptrVM.rawUVM(), pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN, "AUDIO",
136 0 /* iOccurrence */, 0 /* fFlags */);
137 if (RT_SUCCESS(vrc))
138 vrc = pThis->Configure(pCfg, false /* Detach */);
139
140 if (RT_SUCCESS(vrc))
141 {
142 pCfg->uLUN = UINT8_MAX;
143
144 pThis->mfAttached = false;
145 }
146 else
147 LogRel(("VRDE: Failed to detach audio driver, rc=%Rrc\n", vrc));
148
149 return vrc;
150}
151
152/**
153 * Configures the audio driver via CFGM.
154 *
155 * @returns VBox status code.
156 * @param strDevice The PDM device name.
157 * @param uInstance The PDM device instance.
158 * @param uLUN The PDM LUN number of the driver.
159 * @param fAttach Whether to attach or detach the driver configuration to CFGM.
160 *
161 * @thread EMT
162 */
163int AudioDriver::Configure(AudioDriverCfg *pCfg, bool fAttach)
164{
165 if (pCfg->strDev.isEmpty()) /* No audio device configured. Bail out. */
166 return VINF_SUCCESS;
167
168 int rc = VINF_SUCCESS;
169
170 Console::SafeVMPtrQuiet ptrVM(mpConsole);
171 Assert(ptrVM.isOk());
172
173 /* Apply configuration. */
174 mCfg = *pCfg;
175
176 PUVM pUVM = ptrVM.rawUVM();
177 AssertPtr(pUVM);
178
179 PCFGMNODE pRoot = CFGMR3GetRootU(pUVM);
180 AssertPtr(pRoot);
181 PCFGMNODE pDev0 = CFGMR3GetChildF(pRoot, "Devices/%s/%u/", mCfg.strDev.c_str(), mCfg.uInst);
182 AssertPtr(pDev0);
183
184 PCFGMNODE pDevLun = CFGMR3GetChildF(pDev0, "LUN#%u/", mCfg.uLUN);
185
186 if (fAttach)
187 {
188 if (!pDevLun)
189 {
190 LogRel2(("VRDE: Configuring audio driver\n"));
191
192 PCFGMNODE pLunL0;
193 CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%RU8", mCfg.uLUN);
194 CFGMR3InsertString(pLunL0, "Driver", "AUDIO");
195
196 PCFGMNODE pLunCfg;
197 CFGMR3InsertNode(pLunL0, "Config", &pLunCfg);
198 CFGMR3InsertString (pLunCfg, "DriverName", "AudioVRDE");
199 CFGMR3InsertInteger(pLunCfg, "InputEnabled", 0); /* Play safe by default. */
200 CFGMR3InsertInteger(pLunCfg, "OutputEnabled", 1);
201
202 PCFGMNODE pLunL1;
203 CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1);
204 CFGMR3InsertString(pLunL1, "Driver", "AudioVRDE");
205
206 CFGMR3InsertNode(pLunL1, "Config", &pLunCfg);
207
208 /* Call the (virtual) method for driver-specific configuration. */
209 configureDriver(pLunCfg);
210 }
211 }
212 else /* Detach */
213 {
214 if (pDevLun)
215 {
216 LogRel2(("VRDE: Unconfiguring audio driver\n"));
217 CFGMR3RemoveNode(pDevLun);
218 }
219 }
220
221 AssertRC(rc);
222 return rc;
223}
224
Note: See TracBrowser for help on using the repository browser.

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