VirtualBox

source: vbox/trunk/src/VBox/Main/AudioAdapterImpl.cpp@ 28292

Last change on this file since 28292 was 27607, checked in by vboxsync, 15 years ago

Main: remove templates for 'weak' com pointers which do nothing anyway

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