VirtualBox

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

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

Main/AudioDriver: Documentation.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.6 KB
Line 
1/* $Id: AudioDriver.cpp 70547 2018-01-11 18:14:10Z 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 * Does nothing if the audio driver already is attached.
76 *
77 * @returns IPRT status code.
78 * @param pThis Audio driver to detach.
79 * @param pCfg Audio driver configuration to use for the audio driver to attach.
80 */
81/* static */
82DECLCALLBACK(int) AudioDriver::Attach(AudioDriver *pThis, AudioDriverCfg *pCfg)
83{
84 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
85
86 Console::SafeVMPtrQuiet ptrVM(pThis->mpConsole);
87 Assert(ptrVM.isOk());
88
89 int vrc = VINF_SUCCESS;
90
91 if (pThis->mfAttached) /* Already attached? Bail out. */
92 return VINF_SUCCESS;
93
94 if (pCfg->uLUN == UINT8_MAX) /* No LUN assigned / configured yet? Retrieve it. */
95 pCfg->uLUN = pThis->getFreeLUN();
96
97 LogFunc(("strName=%s, strDevice=%s, uInst=%u, uLUN=%u\n",
98 pCfg->strName.c_str(), pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN));
99
100 vrc = pThis->Configure(pCfg, true /* Attach */);
101 if (RT_SUCCESS(vrc))
102 vrc = PDMR3DriverAttach(ptrVM.rawUVM(), pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN, 0 /* fFlags */, NULL /* ppBase */);
103
104 if (RT_SUCCESS(vrc))
105 {
106 pThis->mfAttached = true;
107 }
108 else
109 LogRel(("%s: Failed to attach audio driver, rc=%Rrc\n", pCfg->strName.c_str(), vrc));
110
111 return vrc;
112}
113
114/**
115 * Detaches an already attached audio driver from the audio chain.
116 * Does nothing if the audio driver already is detached or not attached.
117 *
118 * @returns IPRT status code.
119 * @param pThis Audio driver to detach.
120 */
121/* static */
122DECLCALLBACK(int) AudioDriver::Detach(AudioDriver *pThis)
123{
124 AssertPtrReturn(pThis, VERR_INVALID_POINTER);
125
126 Console::SafeVMPtrQuiet ptrVM(pThis->mpConsole);
127 Assert(ptrVM.isOk());
128
129 if (!pThis->mfAttached) /* Not attached? Bail out. */
130 return VINF_SUCCESS;
131
132 int vrc = VINF_SUCCESS;
133
134 AudioDriverCfg *pCfg = &pThis->mCfg;
135
136 LogFunc(("strName=%s, strDevice=%s, uInst=%u, uLUN=%u\n",
137 pCfg->strName.c_str(), pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN));
138
139 vrc = PDMR3DriverDetach(ptrVM.rawUVM(), pCfg->strDev.c_str(), pCfg->uInst, pCfg->uLUN, "AUDIO",
140 0 /* iOccurrence */, 0 /* fFlags */);
141 if (RT_SUCCESS(vrc))
142 vrc = pThis->Configure(pCfg, false /* Detach */);
143
144 if (RT_SUCCESS(vrc))
145 {
146 pCfg->uLUN = UINT8_MAX;
147
148 pThis->mfAttached = false;
149 }
150 else
151 LogRel(("%s: Failed to detach audio driver, rc=%Rrc\n", pCfg->strName.c_str(), vrc));
152
153 return vrc;
154}
155
156/**
157 * Configures the audio driver via CFGM.
158 *
159 * @returns VBox status code.
160 * @param pCfg Audio driver configuration to use.
161 * @param fAttach Whether to attach or detach the driver configuration to CFGM.
162 *
163 * @thread EMT
164 */
165int AudioDriver::Configure(AudioDriverCfg *pCfg, bool fAttach)
166{
167 if (pCfg->strDev.isEmpty()) /* No audio device configured. Bail out. */
168 return VINF_SUCCESS;
169
170 int rc = VINF_SUCCESS;
171
172 Console::SafeVMPtrQuiet ptrVM(mpConsole);
173 Assert(ptrVM.isOk());
174
175 /* Apply configuration. */
176 mCfg = *pCfg;
177
178 PUVM pUVM = ptrVM.rawUVM();
179 AssertPtr(pUVM);
180
181 PCFGMNODE pRoot = CFGMR3GetRootU(pUVM);
182 AssertPtr(pRoot);
183 PCFGMNODE pDev0 = CFGMR3GetChildF(pRoot, "Devices/%s/%u/", mCfg.strDev.c_str(), mCfg.uInst);
184 AssertPtr(pDev0);
185
186 PCFGMNODE pDevLun = CFGMR3GetChildF(pDev0, "LUN#%u/", mCfg.uLUN);
187
188 if (fAttach)
189 {
190 if (!pDevLun)
191 {
192 LogRel2(("%s: Configuring audio driver\n", mCfg.strName.c_str()));
193
194 PCFGMNODE pLunL0;
195 CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%RU8", mCfg.uLUN);
196 CFGMR3InsertString(pLunL0, "Driver", "AUDIO");
197
198 PCFGMNODE pLunCfg;
199 CFGMR3InsertNode(pLunL0, "Config", &pLunCfg);
200 CFGMR3InsertStringF(pLunCfg, "DriverName", "%s", mCfg.strName.c_str());
201 CFGMR3InsertInteger(pLunCfg, "InputEnabled", 0); /* Play safe by default. */
202 CFGMR3InsertInteger(pLunCfg, "OutputEnabled", 1);
203
204 PCFGMNODE pLunL1;
205 CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1);
206 CFGMR3InsertStringF(pLunL1, "Driver", "%s", mCfg.strName.c_str());
207
208 CFGMR3InsertNode(pLunL1, "Config", &pLunCfg);
209
210 /* Call the (virtual) method for driver-specific configuration. */
211 configureDriver(pLunCfg);
212 }
213 }
214 else /* Detach */
215 {
216 if (pDevLun)
217 {
218 LogRel2(("%s: Unconfiguring audio driver\n", mCfg.strName.c_str()));
219 CFGMR3RemoveNode(pDevLun);
220 }
221 }
222
223 AssertRC(rc);
224 return rc;
225}
226
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