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 //This will most likely be overridden, the base class simply
343 //changes the member.
344 m_IsStreaming = newState;
348 ///////////////////////////////////////////////////////////////////////////////////////////////////////
349 // IsProcessActive - returns true if process code is running.
350 // A normal audio device should return the Streaming() value
351 ///////////////////////////////////////////////////////////////////////////////////////////////////////
352 bool WCMRAudioDevice::IsProcessActive()
361 //**********************************************************************************************
362 // WCMRAudioDevice::DoIdle
364 //! A place for doing idle time processing. The derived classes will probably do something
369 //! \return eNoErr always.
371 //**********************************************************************************************
372 WTErr WCMRAudioDevice::DoIdle ()
374 //We don't need to do anything here...
375 //the derived classes may want to use this however.
382 //**********************************************************************************************
383 // WCMRAudioDevice::InputLevels
385 //! Retrieve current input levels.
389 //! \return A vector (the same size as input channels list) that contains current input levels.
391 //**********************************************************************************************
392 const std::vector<float>& WCMRAudioDevice::InputLevels ()
394 //The derived classes may override if they need to query
395 //the driver for the levels.
396 return (m_InputLevels);
401 //**********************************************************************************************
402 // WCMRAudioDevice::OutputLevels
404 //! Retrieve current output levels.
408 //! \return A vector (the same size as output channels list) that contains current output levels.
410 //**********************************************************************************************
411 const std::vector<float>& WCMRAudioDevice::OutputLevels ()
413 //The derived classes may override if they need to query
414 //the driver for the levels.
415 return (m_OutputLevels);
420 //**********************************************************************************************
421 // WCMRAudioDevice::GetMonitorInfo
423 //! Retrieves current monitoring information.
425 //! \param *pLeftChannel : Pointer to receive left monitor channel index.
426 //! \param *pRightChannel : Pointer to receive right monitor channel index.
427 //! \param *pGain : Pointer to receive the gain (linear) to be applied.
431 //**********************************************************************************************
432 void WCMRAudioDevice::GetMonitorInfo (int *pLeftChannel, int *pRightChannel, float *pGain)
435 *pLeftChannel = m_LeftMonitorChannel;
437 *pRightChannel = m_RightMonitorChannel;
439 *pGain = m_MonitorGain;
445 //**********************************************************************************************
446 // WCMRAudioDevice::SetMonitorChannels
448 //! Used to set the channels to be used for monitoring.
450 //! \param leftChannel : Left monitor channel index.
451 //! \param rightChannel : Right monitor channel index.
453 //! \return eNoErr always, the derived classes may return appropriate errors.
455 //**********************************************************************************************
456 WTErr WCMRAudioDevice::SetMonitorChannels (int leftChannel, int rightChannel)
458 //This will most likely be overridden, the base class simply
459 //changes the member.
460 m_LeftMonitorChannel = leftChannel;
461 m_RightMonitorChannel = rightChannel;
467 //**********************************************************************************************
468 // WCMRAudioDevice::SetMonitorGain
470 //! Used to set monitor gain (or atten).
472 //! \param newGain : The new gain or atten. value to use. Specified as a linear multiplier (not dB)
474 //! \return eNoErr always, the derived classes may return appropriate errors.
476 //**********************************************************************************************
477 WTErr WCMRAudioDevice::SetMonitorGain (float newGain)
479 //This will most likely be overridden, the base class simply
480 //changes the member.
481 m_MonitorGain = newGain;
488 //**********************************************************************************************
489 // WCMRAudioDevice::ShowConfigPanel
491 //! Used to show device specific config/control panel. Some interfaces may not support it.
492 //! Some interfaces may require the device to be active before it can display a panel.
494 //! \param pParam : A device/interface specific parameter - optional.
496 //! \return eNoErr always, the derived classes may return errors.
498 //**********************************************************************************************
499 WTErr WCMRAudioDevice::ShowConfigPanel (void *WCUNUSEDPARAM(pParam))
501 //This will most likely be overridden...
506 //**********************************************************************************************
507 // WCMRAudioDevice::SendCustomCommand
509 //! Used to Send a custom command to the audiodevice. Some interfaces may require the device
510 //! to be active before it can do anything in this.
512 //! \param customCommand : A device/interface specific command.
513 //! \param pCommandParam : A device/interface/command specific parameter - optional.
515 //! \return eNoErr always, the derived classes may return errors.
517 //**********************************************************************************************
518 WTErr WCMRAudioDevice::SendCustomCommand (int WCUNUSEDPARAM(customCommand), void *WCUNUSEDPARAM(pCommandParam))
520 //This will most likely be overridden...
524 //**********************************************************************************************
525 // WCMRAudioDevice::GetLatency
527 //! Get Latency for device.
529 //! Use 'kAudioDevicePropertyLatency' and 'kAudioDevicePropertySafetyOffset' + GetStreamLatencies
531 //! \param isInput : Return latency for the input if isInput is true, otherwise the output latency
532 //! wiil be returned.
533 //! \return Latency in samples.
535 //**********************************************************************************************
536 uint32_t WCMRAudioDevice::GetLatency (bool isInput)
538 //This will most likely be overridden...
543 //**********************************************************************************************
544 // WCMRAudioDeviceManager::WCMRAudioDeviceManager
546 //! The constructuor, most of the work will be done in the derived class' constructor.
548 //! \param *pTheClient :
552 //**********************************************************************************************
553 WCMRAudioDeviceManager::WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter)
554 : m_eAudioDeviceFilter(eCurAudioDeviceFilter)
556 , m_pTheClient (pTheClient)
561 //**********************************************************************************************
562 // WCMRAudioDeviceManager::~WCMRAudioDeviceManager
564 //! It clears the device list, releasing each of the device.
570 //**********************************************************************************************
571 WCMRAudioDeviceManager::~WCMRAudioDeviceManager()
575 std::cout << "API::Destroying AudioDeviceManager " << std::endl;
578 // clean up device info list
580 wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
581 while( m_DeviceInfoVec.size() )
583 DeviceInfo* devInfo = m_DeviceInfoVec.back();
584 m_DeviceInfoVec.pop_back();
588 delete m_CurrentDevice;
593 //destructors should absorb exceptions, no harm in logging though!!
594 DEBUG_MSG ("Exception during destructor");
599 WCMRAudioDevice* WCMRAudioDeviceManager::InitNewCurrentDevice(const std::string & deviceName)
601 return initNewCurrentDeviceImpl(deviceName);
605 void WCMRAudioDeviceManager::DestroyCurrentDevice()
607 return destroyCurrentDeviceImpl();
611 const DeviceInfoVec WCMRAudioDeviceManager::DeviceInfoList() const
613 wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
614 return m_DeviceInfoVec;
618 WTErr WCMRAudioDeviceManager::GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const
620 wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
621 DeviceInfoVecConstIter iter = m_DeviceInfoVec.begin();
622 for (; iter != m_DeviceInfoVec.end(); ++iter)
624 if (nameToMatch == (*iter)->m_DeviceName)
631 return eRMResNotFound;
635 WTErr WCMRAudioDeviceManager::GetDeviceBufferSizes(const std::string & nameToMatch, std::vector<int>& bufferSizes) const
637 return getDeviceBufferSizesImpl(nameToMatch, bufferSizes);
641 //**********************************************************************************************
642 // WCMRAudioDeviceManager::NotifyClient
644 //! A helper routine used to call the client for notification.
646 //! \param forReason : The reason for notification.
647 //! \param *pParam : A parameter (if required) for notification.
651 //**********************************************************************************************
652 void WCMRAudioDeviceManager::NotifyClient (WCMRAudioDeviceManagerClient::NotificationReason forReason, void *pParam)
655 m_pTheClient->AudioDeviceManagerNotification (forReason, pParam);