VirtualBox

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

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

Audio/Main: Also added the driver name to the AudioDriver base class.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1/* $Id: AudioDriver.cpp 70544 2018-01-11 16:20:27Z vboxsync $ */
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(("strName=%s, strDevice=%s, uInst=%u, uLUN=%u\n",
97 pCfg->strName.c_str(), pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN));
98
99 vrc = pThis->Configure(pCfg, true /* Attach */);
100 if (RT_SUCCESS(vrc))
101 vrc = PDMR3DriverAttach(ptrVM.rawUVM(), pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN, 0 /* fFlags */, NULL /* ppBase */);
102
103 if (RT_SUCCESS(vrc))
104 {
105 pThis->mfAttached = true;
106 }
107 else
108 LogRel(("%s: Failed to attach audio driver, rc=%Rrc\n", pCfg->strName.c_str(), vrc));
109
110 return vrc;
111}
112
113/**
114 * Detaches an already attached audio driver from the audio chain.
115 *
116 * @returns IPRT status code.
117 * @param pThis Audio driver to detach.
118 */
119/* static */
120DECLCALLBACK(int) AudioDriver::Detach(AudioDriver *pThis)
121{
122 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
123
124 Console::SafeVMPtrQuiet ptrVM(pThis->mpConsole);
125 Assert(ptrVM.isOk());
126
127 if (!pThis->mfAttached) /* Not attached? Bail out. */
128 return VINF_SUCCESS;
129
130 int vrc = VINF_SUCCESS;
131
132 AudioDriverCfg *pCfg = &pThis->mCfg;
133
134 LogFunc(("strName=%s, strDevice=%s, uInst=%u, uLUN=%u\n",
135 pCfg->strName.c_str(), pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN));
136
137 vrc = PDMR3DriverDetach(ptrVM.rawUVM(), pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN, "AUDIO",
138 0 /* iOccurrence */, 0 /* fFlags */);
139 if (RT_SUCCESS(vrc))
140 vrc = pThis->Configure(pCfg, false /* Detach */);
141
142 if (RT_SUCCESS(vrc))
143 {
144 pCfg->uLUN = UINT8_MAX;
145
146 pThis->mfAttached = false;
147 }
148 else
149 LogRel(("%s: Failed to detach audio driver, rc=%Rrc\n", pCfg->strName.c_str(), vrc));
150
151 return vrc;
152}
153
154/**
155 * Configures the audio driver via CFGM.
156 *
157 * @returns VBox status code.
158 * @param pCfg Audio driver configuration to use.
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(("%s: Configuring audio driver\n", mCfg.strName.c_str()));
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 CFGMR3InsertStringF(pLunCfg, "DriverName", "%s", mCfg.strName.c_str());
199 CFGMR3InsertInteger(pLunCfg, "InputEnabled", 0); /* Play safe by default. */
200 CFGMR3InsertInteger(pLunCfg, "OutputEnabled", 1);
201
202 PCFGMNODE pLunL1;
203 CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1);
204 CFGMR3InsertStringF(pLunL1, "Driver", "%s", mCfg.strName.c_str());
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(("%s: Unconfiguring audio driver\n", mCfg.strName.c_str()));
217 CFGMR3RemoveNode(pDevLun);
218 }
219 }
220
221 AssertRC(rc);
222 return rc;
223}
224
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