1 //----------------------------------------------------------------------------------
3 // Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
5 //! \file WCMRAudioDeviceManager.cpp
7 //! WCMRAudioDeviceManager and related class declarations
9 //---------------------------------------------------------------------------------*/
11 #include "WCMRAudioDeviceManager.h"
14 //**********************************************************************************************
15 // WCMRAudioDevice::WCMRAudioDevice
17 //! Constructor for the audio device. The derived classes will need to do more actual work, such
18 //! as determining supported sampling rates, buffer sizes, and channel counts. Connection
19 //! and streaming will also be provided by the derived implementations.
21 //! \param *pManager : The audio device manager that's managing this device.
24 //**********************************************************************************************
25 WCMRAudioDevice::WCMRAudioDevice (WCMRAudioDeviceManager *pManager) :
26 m_pMyManager (pManager)
27 , m_ConnectionStatus (DeviceDisconnected)
29 , m_IsStreaming (false)
30 , m_CurrentSamplingRate (-1)
31 , m_CurrentBufferSize (0)
32 , m_LeftMonitorChannel (-1)
33 , m_RightMonitorChannel (-1)
34 , m_MonitorGain (1.0f)
36 m_DeviceName = "Unknown";
41 //**********************************************************************************************
42 // WCMRAudioDevice::~WCMRAudioDevice
44 //! Destructor for the audio device. It release all the connections that were created.
50 //**********************************************************************************************
51 WCMRAudioDevice::~WCMRAudioDevice ()
59 //destructors should absorb exceptions, no harm in logging though!!
60 DEBUG_MSG ("Exception during destructor");
67 //**********************************************************************************************
68 // WCMRAudioDevice::DeviceName
70 //! Retrieves Device's name.
74 //! \return The device name.
76 //**********************************************************************************************
77 const std::string& WCMRAudioDevice::DeviceName () const
79 return (m_DeviceName);
85 //**********************************************************************************************
86 // WCMRAudioDevice::InputChannels
88 //! Retrieves Input Channel information. Note that the list may be changed at run-time.
92 //! \return A vector with Input Channel Names.
94 //**********************************************************************************************
95 const std::vector<std::string>& WCMRAudioDevice::InputChannels ()
97 return (m_InputChannels);
103 //**********************************************************************************************
104 // WCMRAudioDevice::OutputChannels
106 //! Retrieves Output Channel Information. Note that the list may be changed at run-time.
110 //! \return A vector with Output Channel Names.
112 //**********************************************************************************************
113 const std::vector<std::string>& WCMRAudioDevice::OutputChannels ()
115 return (m_OutputChannels);
121 //**********************************************************************************************
122 // WCMRAudioDevice::SamplingRates
124 //! Retrieves supported sampling rate information.
128 //! \return A vector with supported sampling rates.
130 //**********************************************************************************************
131 const std::vector<int>& WCMRAudioDevice::SamplingRates ()
133 return (m_SamplingRates);
138 //**********************************************************************************************
139 // WCMRAudioDevice::CurrentSamplingRate
141 //! The device's current sampling rate. This may be overridden, if the device needs to
142 //! query the driver for the current rate.
146 //! \return The device's current sampling rate. -1 on error.
148 //**********************************************************************************************
149 int WCMRAudioDevice::CurrentSamplingRate ()
151 return (m_CurrentSamplingRate);
157 //**********************************************************************************************
158 // WCMRAudioDevice::SetCurrentSamplingRate
160 //! Change the sampling rate to be used by the device. This will most likely be overridden,
161 //! the base class simply updates the member variable.
163 //! \param newRate : The rate to use (samples per sec).
165 //! \return eNoErr always. The derived classes may return error codes.
167 //**********************************************************************************************
168 WTErr WCMRAudioDevice::SetCurrentSamplingRate (int newRate)
170 //changes the status.
171 m_CurrentSamplingRate = newRate;
178 //**********************************************************************************************
179 // WCMRAudioDevice::BufferSizes
181 //! Retrieves supported buffer size information.
185 //! \return A vector with supported buffer sizes.
187 //**********************************************************************************************
188 const std::vector<int>& WCMRAudioDevice::BufferSizes ()
190 return (m_BufferSizes);
195 //**********************************************************************************************
196 // WCMRAudioDevice::CurrentBufferSize
198 //! The device's current buffer size in use. This may be overridden, if the device needs to
199 //! query the driver for the current size.
203 //! \return The device's current buffer size. 0 on error.
205 //**********************************************************************************************
206 int WCMRAudioDevice::CurrentBufferSize ()
208 return (m_CurrentBufferSize);
211 //**********************************************************************************************
212 // WCMRAudioDevice::CurrentBlockSize
214 //! Device's block size we use for holding the audio samples.
215 //! Usually this is equal to the buffer size, but in some cases the buffer size holds additional
216 //! data other then the audio buffers, like frames info in SG, so it can be overriden
220 //! \return The device's current block size. 0 on error.
222 //**********************************************************************************************
223 int WCMRAudioDevice::CurrentBlockSize()
225 // By default - return the buffer size
226 return CurrentBufferSize();
230 //**********************************************************************************************
231 // WCMRAudioDevice::SetCurrentBufferSize
233 //! Change the buffer size to be used by the device. This will most likely be overridden,
234 //! the base class simply updates the member variable.
236 //! \param newSize : The buffer size to use (in sample-frames)
238 //! \return eNoErr always. The derived classes may return error codes.
240 //**********************************************************************************************
241 WTErr WCMRAudioDevice::SetCurrentBufferSize (int newSize)
243 //This will most likely be overridden, the base class simply
244 //changes the member.
245 m_CurrentBufferSize = newSize;
252 //**********************************************************************************************
253 // WCMRAudioDevice::ConnectionStatus
255 //! Retrieves the device's current connection status. This will most likely be overridden,
256 //! in case some driver communication is required to query the status.
260 //! \return A ConnectionStates value.
262 //**********************************************************************************************
263 WCMRAudioDevice::ConnectionStates WCMRAudioDevice::ConnectionStatus ()
265 return (m_ConnectionStatus);
272 //**********************************************************************************************
273 // WCMRAudioDevice::Active
275 //! Retrieves Device activation status.
279 //! \return true if device is active, false otherwise.
281 //**********************************************************************************************
282 bool WCMRAudioDevice::Active ()
290 //**********************************************************************************************
291 // WCMRAudioDevice::SetActive
293 //! Sets the device's activation status.
295 //! \param newState : Should be true to activate, false to deactivate. This roughly corresponds
296 //! to opening and closing the device handle/stream/audio unit.
298 //! \return eNoErr always, the derived classes may return appropriate error code.
300 //**********************************************************************************************
301 WTErr WCMRAudioDevice::SetActive (bool newState)
303 //This will most likely be overridden, the base class simply
304 //changes the member.
305 m_IsActive = newState;
312 //**********************************************************************************************
313 // WCMRAudioDevice::Streaming
315 //! Retrieves Device streaming status.
319 //! \return true if device is streaming, false otherwise.
321 //**********************************************************************************************
322 bool WCMRAudioDevice::Streaming ()
324 return (m_IsStreaming);
329 //**********************************************************************************************
330 // WCMRAudioDevice::SetStreaming
332 //! Sets the device's streaming status.
334 //! \param newState : Should be true to start streaming, false to stop streaming. This roughly
335 //! corresponds to calling Start/Stop on the lower level interface.
337 //! \return eNoErr always, the derived classes may return appropriate error code.
339 //**********************************************************************************************
340 WTErr WCMRAudioDevice::SetStreaming (bool newState)
342 // We must notify angine about our intention to start streming
343 // so Engine will provide all the initializations in the first audio callback
345 m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
348 //This will most likely be overridden, the base class simply
349 //changes the member.
350 m_IsStreaming = newState;
355 WTErr WCMRAudioDevice::ResetDevice ()
358 bool wasStreaming = Streaming();
359 bool wasActive = Active();
361 WTErr err = SetStreaming(false);
366 if (err == eNoErr && wasActive)
369 if (err == eNoErr && wasStreaming)
376 ///////////////////////////////////////////////////////////////////////////////////////////////////////
377 // IsProcessActive - returns true if process code is running.
378 // A normal audio device should return the Streaming() value
379 ///////////////////////////////////////////////////////////////////////////////////////////////////////
380 bool WCMRAudioDevice::IsProcessActive()
389 //**********************************************************************************************
390 // WCMRAudioDevice::DoIdle
392 //! A place for doing idle time processing. The derived classes will probably do something
397 //! \return eNoErr always.
399 //**********************************************************************************************
400 WTErr WCMRAudioDevice::DoIdle ()
402 //We don't need to do anything here...
403 //the derived classes may want to use this however.
410 //**********************************************************************************************
411 // WCMRAudioDevice::InputLevels
413 //! Retrieve current input levels.
417 //! \return A vector (the same size as input channels list) that contains current input levels.
419 //**********************************************************************************************
420 const std::vector<float>& WCMRAudioDevice::InputLevels ()
422 //The derived classes may override if they need to query
423 //the driver for the levels.
424 return (m_InputLevels);
429 //**********************************************************************************************
430 // WCMRAudioDevice::OutputLevels
432 //! Retrieve current output levels.
436 //! \return A vector (the same size as output channels list) that contains current output levels.
438 //**********************************************************************************************
439 const std::vector<float>& WCMRAudioDevice::OutputLevels ()
441 //The derived classes may override if they need to query
442 //the driver for the levels.
443 return (m_OutputLevels);
448 //**********************************************************************************************
449 // WCMRAudioDevice::GetMonitorInfo
451 //! Retrieves current monitoring information.
453 //! \param *pLeftChannel : Pointer to receive left monitor channel index.
454 //! \param *pRightChannel : Pointer to receive right monitor channel index.
455 //! \param *pGain : Pointer to receive the gain (linear) to be applied.
459 //**********************************************************************************************
460 void WCMRAudioDevice::GetMonitorInfo (int *pLeftChannel, int *pRightChannel, float *pGain)
463 *pLeftChannel = m_LeftMonitorChannel;
465 *pRightChannel = m_RightMonitorChannel;
467 *pGain = m_MonitorGain;
473 //**********************************************************************************************
474 // WCMRAudioDevice::SetMonitorChannels
476 //! Used to set the channels to be used for monitoring.
478 //! \param leftChannel : Left monitor channel index.
479 //! \param rightChannel : Right monitor channel index.
481 //! \return eNoErr always, the derived classes may return appropriate errors.
483 //**********************************************************************************************
484 WTErr WCMRAudioDevice::SetMonitorChannels (int leftChannel, int rightChannel)
486 //This will most likely be overridden, the base class simply
487 //changes the member.
488 m_LeftMonitorChannel = leftChannel;
489 m_RightMonitorChannel = rightChannel;
495 //**********************************************************************************************
496 // WCMRAudioDevice::SetMonitorGain
498 //! Used to set monitor gain (or atten).
500 //! \param newGain : The new gain or atten. value to use. Specified as a linear multiplier (not dB)
502 //! \return eNoErr always, the derived classes may return appropriate errors.
504 //**********************************************************************************************
505 WTErr WCMRAudioDevice::SetMonitorGain (float newGain)
507 //This will most likely be overridden, the base class simply
508 //changes the member.
509 m_MonitorGain = newGain;
516 //**********************************************************************************************
517 // WCMRAudioDevice::ShowConfigPanel
519 //! Used to show device specific config/control panel. Some interfaces may not support it.
520 //! Some interfaces may require the device to be active before it can display a panel.
522 //! \param pParam : A device/interface specific parameter - optional.
524 //! \return eNoErr always, the derived classes may return errors.
526 //**********************************************************************************************
527 WTErr WCMRAudioDevice::ShowConfigPanel (void *WCUNUSEDPARAM(pParam))
529 //This will most likely be overridden...
534 //**********************************************************************************************
535 // WCMRAudioDevice::SendCustomCommand
537 //! Used to Send a custom command to the audiodevice. Some interfaces may require the device
538 //! to be active before it can do anything in this.
540 //! \param customCommand : A device/interface specific command.
541 //! \param pCommandParam : A device/interface/command specific parameter - optional.
543 //! \return eNoErr always, the derived classes may return errors.
545 //**********************************************************************************************
546 WTErr WCMRAudioDevice::SendCustomCommand (int WCUNUSEDPARAM(customCommand), void *WCUNUSEDPARAM(pCommandParam))
548 //This will most likely be overridden...
552 //**********************************************************************************************
553 // WCMRAudioDevice::GetLatency
555 //! Get Latency for device.
557 //! Use 'kAudioDevicePropertyLatency' and 'kAudioDevicePropertySafetyOffset' + GetStreamLatencies
559 //! \param isInput : Return latency for the input if isInput is true, otherwise the output latency
560 //! wiil be returned.
561 //! \return Latency in samples.
563 //**********************************************************************************************
564 uint32_t WCMRAudioDevice::GetLatency (bool isInput)
566 //This will most likely be overridden...
571 //**********************************************************************************************
572 // WCMRAudioDeviceManager::WCMRAudioDeviceManager
574 //! The constructuor, most of the work will be done in the derived class' constructor.
576 //! \param *pTheClient :
580 //**********************************************************************************************
581 WCMRAudioDeviceManager::WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter)
582 : m_eAudioDeviceFilter(eCurAudioDeviceFilter)
584 , m_pTheClient (pTheClient)
589 //**********************************************************************************************
590 // WCMRAudioDeviceManager::~WCMRAudioDeviceManager
592 //! It clears the device list, releasing each of the device.
598 //**********************************************************************************************
599 WCMRAudioDeviceManager::~WCMRAudioDeviceManager()
603 std::cout << "API::Destroying AudioDeviceManager " << std::endl;
606 // clean up device info list
608 wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
609 while( m_DeviceInfoVec.size() )
611 DeviceInfo* devInfo = m_DeviceInfoVec.back();
612 m_DeviceInfoVec.pop_back();
616 delete m_CurrentDevice;
621 //destructors should absorb exceptions, no harm in logging though!!
622 DEBUG_MSG ("Exception during destructor");
627 WCMRAudioDevice* WCMRAudioDeviceManager::InitNewCurrentDevice(const std::string & deviceName)
629 return initNewCurrentDeviceImpl(deviceName);
633 void WCMRAudioDeviceManager::DestroyCurrentDevice()
635 return destroyCurrentDeviceImpl();
639 const DeviceInfoVec WCMRAudioDeviceManager::DeviceInfoList() const
641 wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
642 return m_DeviceInfoVec;
646 WTErr WCMRAudioDeviceManager::GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const
648 wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
649 DeviceInfoVecConstIter iter = m_DeviceInfoVec.begin();
650 for (; iter != m_DeviceInfoVec.end(); ++iter)
652 if (nameToMatch == (*iter)->m_DeviceName)
659 return eRMResNotFound;
663 WTErr WCMRAudioDeviceManager::GetDeviceSampleRates(const std::string & nameToMatch, std::vector<int>& sampleRates) const
665 return getDeviceSampleRatesImpl(nameToMatch, sampleRates);
670 WTErr WCMRAudioDeviceManager::GetDeviceBufferSizes(const std::string & nameToMatch, std::vector<int>& bufferSizes) const
672 return getDeviceBufferSizesImpl(nameToMatch, bufferSizes);
676 //**********************************************************************************************
677 // WCMRAudioDeviceManager::NotifyClient
679 //! A helper routine used to call the client for notification.
681 //! \param forReason : The reason for notification.
682 //! \param *pParam : A parameter (if required) for notification.
686 //**********************************************************************************************
687 void WCMRAudioDeviceManager::NotifyClient (WCMRAudioDeviceManagerClient::NotificationReason forReason, void *pParam)
690 m_pTheClient->AudioDeviceManagerNotification (forReason, pParam);