VirtualBox

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

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

SVN props.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 6.3 KB
Line 
1/* $Id: AudioDriver.cpp 70538 2018-01-11 14:08:14Z 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.215389.xyz. 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 pCfg Audio driver configuration to use.
157 * @param fAttach Whether to attach or detach the driver configuration to CFGM.
158 *
159 * @thread EMT
160 */
161int AudioDriver::Configure(AudioDriverCfg *pCfg, bool fAttach)
162{
163 if (pCfg->strDev.isEmpty()) /* No audio device configured. Bail out. */
164 return VINF_SUCCESS;
165
166 int rc = VINF_SUCCESS;
167
168 Console::SafeVMPtrQuiet ptrVM(mpConsole);
169 Assert(ptrVM.isOk());
170
171 /* Apply configuration. */
172 mCfg = *pCfg;
173
174 PUVM pUVM = ptrVM.rawUVM();
175 AssertPtr(pUVM);
176
177 PCFGMNODE pRoot = CFGMR3GetRootU(pUVM);
178 AssertPtr(pRoot);
179 PCFGMNODE pDev0 = CFGMR3GetChildF(pRoot, "Devices/%s/%u/", mCfg.strDev.c_str(), mCfg.uInst);
180 AssertPtr(pDev0);
181
182 PCFGMNODE pDevLun = CFGMR3GetChildF(pDev0, "LUN#%u/", mCfg.uLUN);
183
184 if (fAttach)
185 {
186 if (!pDevLun)
187 {
188 LogRel2(("VRDE: Configuring audio driver\n"));
189
190 PCFGMNODE pLunL0;
191 CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%RU8", mCfg.uLUN);
192 CFGMR3InsertString(pLunL0, "Driver", "AUDIO");
193
194 PCFGMNODE pLunCfg;
195 CFGMR3InsertNode(pLunL0, "Config", &pLunCfg);
196 CFGMR3InsertString (pLunCfg, "DriverName", "AudioVRDE");
197 CFGMR3InsertInteger(pLunCfg, "InputEnabled", 0); /* Play safe by default. */
198 CFGMR3InsertInteger(pLunCfg, "OutputEnabled", 1);
199
200 PCFGMNODE pLunL1;
201 CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1);
202 CFGMR3InsertString(pLunL1, "Driver", "AudioVRDE");
203
204 CFGMR3InsertNode(pLunL1, "Config", &pLunCfg);
205
206 /* Call the (virtual) method for driver-specific configuration. */
207 configureDriver(pLunCfg);
208 }
209 }
210 else /* Detach */
211 {
212 if (pDevLun)
213 {
214 LogRel2(("VRDE: Unconfiguring audio driver\n"));
215 CFGMR3RemoveNode(pDevLun);
216 }
217 }
218
219 AssertRC(rc);
220 return rc;
221}
222
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