VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/AudioAdapterImpl.cpp@ 55548

Last change on this file since 55548 was 55548, checked in by vboxsync, 10 years ago

AudioAdapterImpl: shut up gcc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.4 KB
Line 
1/* $Id: AudioAdapterImpl.cpp 55548 2015-04-30 12:03:31Z vboxsync $ */
2/** @file
3 *
4 * VirtualBox COM class implementation
5 */
6
7/*
8 * Copyright (C) 2006-2015 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "AudioAdapterImpl.h"
20#include "MachineImpl.h"
21
22#include <iprt/cpp/utils.h>
23
24#include <VBox/settings.h>
25
26#include "AutoStateDep.h"
27#include "AutoCaller.h"
28#include "Logging.h"
29
30struct AudioAdapterData
31{
32 AudioAdapterData() :
33 mEnabled(false),
34 mAudioDriver(AudioDriverType_Null),
35 mAudioController(AudioControllerType_AC97)
36 {}
37
38 BOOL mEnabled;
39 AudioDriverType_T mAudioDriver;
40 AudioControllerType_T mAudioController;
41};
42
43struct AudioAdapter::Data
44{
45 Backupable<AudioAdapterData> m;
46};
47
48// constructor / destructor
49/////////////////////////////////////////////////////////////////////////////
50
51AudioAdapter::AudioAdapter()
52 : mParent(NULL),
53 mData(NULL)
54{
55}
56
57AudioAdapter::~AudioAdapter()
58{
59}
60
61HRESULT AudioAdapter::FinalConstruct()
62{
63 return BaseFinalConstruct();
64}
65
66void AudioAdapter::FinalRelease()
67{
68 uninit();
69 BaseFinalRelease();
70}
71
72// public initializer/uninitializer for internal purposes only
73/////////////////////////////////////////////////////////////////////////////
74
75/**
76 * Initializes the audio adapter object.
77 *
78 * @param aParent Handle of the parent object.
79 */
80HRESULT AudioAdapter::init (Machine *aParent)
81{
82 LogFlowThisFunc(("aParent=%p\n", aParent));
83
84 ComAssertRet(aParent, E_INVALIDARG);
85
86 /* Enclose the state transition NotReady->InInit->Ready */
87 AutoInitSpan autoInitSpan(this);
88 AssertReturn(autoInitSpan.isOk(), E_FAIL);
89
90 /* Get the default audio driver out of the system properties */
91 ComPtr<IVirtualBox> VBox;
92 HRESULT rc = aParent->COMGETTER(Parent)(VBox.asOutParam());
93 if (FAILED(rc)) return rc;
94 ComPtr<ISystemProperties> sysProps;
95 rc = VBox->COMGETTER(SystemProperties)(sysProps.asOutParam());
96 if (FAILED(rc)) return rc;
97 AudioDriverType_T defaultAudioDriver;
98 rc = sysProps->COMGETTER(DefaultAudioDriver)(&defaultAudioDriver);
99 if (FAILED(rc)) return rc;
100
101 unconst(mParent) = aParent;
102 /* mPeer is left null */
103
104 mData = new Data();
105 mData->m.allocate();
106 mData->m->mAudioDriver = defaultAudioDriver;
107
108 /* Confirm a successful initialization */
109 autoInitSpan.setSucceeded();
110
111 return S_OK;
112}
113
114/**
115 * Initializes the audio adapter object given another audio adapter object
116 * (a kind of copy constructor). This object shares data with
117 * the object passed as an argument.
118 *
119 * @note This object must be destroyed before the original object
120 * it shares data with is destroyed.
121 *
122 * @note Locks @a aThat object for reading.
123 */
124HRESULT AudioAdapter::init (Machine *aParent, AudioAdapter *aThat)
125{
126 LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
127
128 ComAssertRet(aParent && aThat, E_INVALIDARG);
129
130 /* Enclose the state transition NotReady->InInit->Ready */
131 AutoInitSpan autoInitSpan(this);
132 AssertReturn(autoInitSpan.isOk(), E_FAIL);
133
134 unconst(mParent) = aParent;
135 unconst(mPeer) = aThat;
136
137 AutoCaller thatCaller (aThat);
138 AssertComRCReturnRC(thatCaller.rc());
139
140 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
141 mData = new Data();
142 mData->m.share (aThat->mData->m);
143
144 /* Confirm a successful initialization */
145 autoInitSpan.setSucceeded();
146
147 return S_OK;
148}
149
150/**
151 * Initializes the guest object given another guest object
152 * (a kind of copy constructor). This object makes a private copy of data
153 * of the original object passed as an argument.
154 *
155 * @note Locks @a aThat object for reading.
156 */
157HRESULT AudioAdapter::initCopy (Machine *aParent, AudioAdapter *aThat)
158{
159 LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
160
161 ComAssertRet(aParent && aThat, E_INVALIDARG);
162
163 /* Enclose the state transition NotReady->InInit->Ready */
164 AutoInitSpan autoInitSpan(this);
165 AssertReturn(autoInitSpan.isOk(), E_FAIL);
166
167 unconst(mParent) = aParent;
168 /* mPeer is left null */
169
170 AutoCaller thatCaller (aThat);
171 AssertComRCReturnRC(thatCaller.rc());
172
173 AutoReadLock thatLock(aThat COMMA_LOCKVAL_SRC_POS);
174 mData = new Data();
175 mData->m.attachCopy (aThat->mData->m);
176
177 /* Confirm a successful initialization */
178 autoInitSpan.setSucceeded();
179
180 return S_OK;
181}
182
183/**
184 * Uninitializes the instance and sets the ready flag to FALSE.
185 * Called either from FinalRelease() or by the parent when it gets destroyed.
186 */
187void AudioAdapter::uninit()
188{
189 LogFlowThisFunc(("\n"));
190
191 /* Enclose the state transition Ready->InUninit->NotReady */
192 AutoUninitSpan autoUninitSpan(this);
193 if (autoUninitSpan.uninitDone())
194 return;
195
196 mData->m.free();
197 delete mData;
198 mData = NULL;
199
200 unconst(mPeer) = NULL;
201 unconst(mParent) = NULL;
202}
203
204// IAudioAdapter properties
205/////////////////////////////////////////////////////////////////////////////
206
207HRESULT AudioAdapter::getEnabled(BOOL *aEnabled)
208{
209 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
210
211 *aEnabled = mData->m->mEnabled;
212
213 return S_OK;
214}
215
216HRESULT AudioAdapter::setEnabled(BOOL aEnabled)
217{
218 /* the machine needs to be mutable */
219 AutoMutableStateDependency adep(mParent);
220 if (FAILED(adep.rc())) return adep.rc();
221
222 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
223
224 if (mData->m->mEnabled != aEnabled)
225 {
226 mData->m.backup();
227 mData->m->mEnabled = aEnabled;
228
229 alock.release();
230 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
231 mParent->i_setModified(Machine::IsModified_AudioAdapter);
232 }
233
234 return S_OK;
235}
236
237HRESULT AudioAdapter::getEnabledIn(BOOL *aEnabled)
238{
239 NOREF(aEnabled);
240 return E_NOTIMPL;
241}
242
243HRESULT AudioAdapter::setEnabledIn(BOOL aEnabled)
244{
245 NOREF(aEnabled);
246 return E_NOTIMPL;
247}
248
249HRESULT AudioAdapter::getEnabledOut(BOOL *aEnabled)
250{
251 NOREF(aEnabled);
252 return E_NOTIMPL;
253}
254
255HRESULT AudioAdapter::setEnabledOut(BOOL aEnabled)
256{
257 NOREF(aEnabled);
258 return E_NOTIMPL;
259}
260
261HRESULT AudioAdapter::getAudioDriver(AudioDriverType_T *aAudioDriver)
262{
263 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
264
265 *aAudioDriver = mData->m->mAudioDriver;
266
267 return S_OK;
268}
269
270HRESULT AudioAdapter::setAudioDriver(AudioDriverType_T aAudioDriver)
271{
272
273 /* the machine needs to be mutable */
274 AutoMutableOrSavedStateDependency adep(mParent);
275 if (FAILED(adep.rc())) return adep.rc();
276
277 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
278
279 HRESULT rc = S_OK;
280
281 if (mData->m->mAudioDriver != aAudioDriver)
282 {
283 if (settings::MachineConfigFile::isAudioDriverAllowedOnThisHost(aAudioDriver))
284 {
285 mData->m.backup();
286 mData->m->mAudioDriver = aAudioDriver;
287 alock.release();
288 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
289 mParent->i_setModified(Machine::IsModified_AudioAdapter);
290 }
291 else
292 {
293 AssertMsgFailed(("Wrong audio driver type %d\n", aAudioDriver));
294 rc = E_FAIL;
295 }
296 }
297
298 return rc;
299}
300
301HRESULT AudioAdapter::getAudioController(AudioControllerType_T *aAudioController)
302{
303 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
304
305 *aAudioController = mData->m->mAudioController;
306
307 return S_OK;
308}
309
310HRESULT AudioAdapter::setAudioController(AudioControllerType_T aAudioController)
311{
312 /* the machine needs to be mutable */
313 AutoMutableStateDependency adep(mParent);
314 if (FAILED(adep.rc())) return adep.rc();
315
316 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
317
318 HRESULT rc = S_OK;
319
320 if (mData->m->mAudioController != aAudioController)
321 {
322 /*
323 * which audio hardware type are we supposed to use?
324 */
325 switch (aAudioController)
326 {
327 case AudioControllerType_AC97:
328 case AudioControllerType_SB16:
329 case AudioControllerType_HDA:
330 {
331 mData->m.backup();
332 mData->m->mAudioController = aAudioController;
333 alock.release();
334 AutoWriteLock mlock(mParent COMMA_LOCKVAL_SRC_POS); // mParent is const, needs no locking
335 mParent->i_setModified(Machine::IsModified_AudioAdapter);
336 break;
337 }
338
339 default:
340 AssertMsgFailed (("Wrong audio controller type %d\n",
341 aAudioController));
342 rc = E_FAIL;
343 }
344 }
345
346 return rc;
347}
348
349// IAudioAdapter methods
350/////////////////////////////////////////////////////////////////////////////
351
352// public methods only for internal purposes
353/////////////////////////////////////////////////////////////////////////////
354
355/**
356 * Loads settings from the given machine node.
357 * May be called once right after this object creation.
358 *
359 * @param aMachineNode <Machine> node.
360 *
361 * @note Locks this object for writing.
362 */
363HRESULT AudioAdapter::i_loadSettings(const settings::AudioAdapter &data)
364{
365 AutoCaller autoCaller(this);
366 AssertComRCReturnRC(autoCaller.rc());
367
368 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
369
370 /* Note: we assume that the default values for attributes of optional
371 * nodes are assigned in the Data::Data() constructor and don't do it
372 * here. It implies that this method may only be called after constructing
373 * a new AudioAdapter object while all its data fields are in the default
374 * values. Exceptions are fields whose creation time defaults don't match
375 * values that should be applied when these fields are not explicitly set
376 * in the settings file (for backwards compatibility reasons). This takes
377 * place when a setting of a newly created object must default to A while
378 * the same setting of an object loaded from the old settings file must
379 * default to B. */
380
381 mData->m->mEnabled = data.fEnabled;
382 mData->m->mAudioController = data.controllerType;
383 mData->m->mAudioDriver = data.driverType;
384
385 return S_OK;
386}
387
388/**
389 * Saves settings to the given machine node.
390 *
391 * @param aMachineNode <Machine> node.
392 *
393 * @note Locks this object for reading.
394 */
395HRESULT AudioAdapter::i_saveSettings(settings::AudioAdapter &data)
396{
397 AutoCaller autoCaller(this);
398 AssertComRCReturnRC(autoCaller.rc());
399
400 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
401
402 data.fEnabled = !!mData->m->mEnabled;
403 data.controllerType = mData->m->mAudioController;
404 data.driverType = mData->m->mAudioDriver;
405 return S_OK;
406}
407
408/**
409 * @note Locks this object for writing.
410 */
411void AudioAdapter::i_rollback()
412{
413 /* sanity */
414 AutoCaller autoCaller(this);
415 AssertComRCReturnVoid(autoCaller.rc());
416
417 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
418
419 mData->m.rollback();
420}
421
422/**
423 * @note Locks this object for writing, together with the peer object (also
424 * for writing) if there is one.
425 */
426void AudioAdapter::i_commit()
427{
428 /* sanity */
429 AutoCaller autoCaller(this);
430 AssertComRCReturnVoid (autoCaller.rc());
431
432 /* sanity too */
433 AutoCaller peerCaller (mPeer);
434 AssertComRCReturnVoid (peerCaller.rc());
435
436 /* lock both for writing since we modify both (mPeer is "master" so locked
437 * first) */
438 AutoMultiWriteLock2 alock(mPeer, this COMMA_LOCKVAL_SRC_POS);
439
440 if (mData->m.isBackedUp())
441 {
442 mData->m.commit();
443 if (mPeer)
444 {
445 /* attach new data to the peer and reshare it */
446 mPeer->mData->m.attach (mData->m);
447 }
448 }
449}
450
451/**
452 * @note Locks this object for writing, together with the peer object
453 * represented by @a aThat (locked for reading).
454 */
455void AudioAdapter::i_copyFrom(AudioAdapter *aThat)
456{
457 AssertReturnVoid (aThat != NULL);
458
459 /* sanity */
460 AutoCaller autoCaller(this);
461 AssertComRCReturnVoid (autoCaller.rc());
462
463 /* sanity too */
464 AutoCaller thatCaller (aThat);
465 AssertComRCReturnVoid (thatCaller.rc());
466
467 /* peer is not modified, lock it for reading (aThat is "master" so locked
468 * first) */
469 AutoReadLock rl(aThat COMMA_LOCKVAL_SRC_POS);
470 AutoWriteLock wl(this COMMA_LOCKVAL_SRC_POS);
471
472 /* this will back up current data */
473 mData->m.assignCopy(aThat->mData->m);
474}
475/* vi: set tabstop=4 shiftwidth=4 expandtab: */
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