-/*
- Copyright (C) 2013 Waves Audio Ltd.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
//----------------------------------------------------------------------------------
//
+// Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
//
//! \file WCMRAudioDeviceManager.cpp
//!
//! WCMRAudioDeviceManager and related class declarations
//!
//---------------------------------------------------------------------------------*/
+#include <iostream>
#include "WCMRAudioDeviceManager.h"
-
-
-
-
//**********************************************************************************************
-// WCMRAudioDevice::WCMRAudioDevice
+// WCMRAudioDevice::WCMRAudioDevice
//
//! Constructor for the audio device. The derived classes will need to do more actual work, such
//! as determining supported sampling rates, buffer sizes, and channel counts. Connection
//! and streaming will also be provided by the derived implementations.
//!
//! \param *pManager : The audio device manager that's managing this device.
-//!
//! \return Nothing.
-//!
+//!
//**********************************************************************************************
-WCMRAudioDevice::WCMRAudioDevice (WCMRAudioDeviceManager *pManager)
+WCMRAudioDevice::WCMRAudioDevice (WCMRAudioDeviceManager *pManager) :
+ m_pMyManager (pManager)
+ , m_ConnectionStatus (DeviceDisconnected)
+ , m_IsActive (false)
+ , m_IsStreaming (false)
+ , m_CurrentSamplingRate (-1)
+ , m_CurrentBufferSize (0)
+ , m_LeftMonitorChannel (-1)
+ , m_RightMonitorChannel (-1)
+ , m_MonitorGain (1.0f)
{
- m_pMyManager = pManager;
m_DeviceName = "Unknown";
-
- m_ConnectionStatus = DeviceDisconnected;
- m_IsActive = false;
- m_IsStreaming = false;
-
- m_CurrentSamplingRate = -1;
- m_CurrentBufferSize = 0;
-
- m_LeftMonitorChannel = -1;
- m_RightMonitorChannel = -1;
- m_MonitorGain = 1.0f;
-
-
}
//**********************************************************************************************
-// WCMRAudioDevice::~WCMRAudioDevice
+// WCMRAudioDevice::~WCMRAudioDevice
//
//! Destructor for the audio device. It release all the connections that were created.
//!
//! \param none
-//!
+//!
//! \return Nothing.
-//!
+//!
//**********************************************************************************************
WCMRAudioDevice::~WCMRAudioDevice ()
{
AUTO_FUNC_DEBUG;
- try
+ try
{
}
catch (...)
//**********************************************************************************************
-// WCMRAudioDevice::DeviceName
+// WCMRAudioDevice::DeviceName
//
//! Retrieves Device's name.
//!
//! \param none
-//!
+//!
//! \return The device name.
-//!
+//!
//**********************************************************************************************
const std::string& WCMRAudioDevice::DeviceName () const
{
return (m_DeviceName);
-
+
}
//**********************************************************************************************
-// WCMRAudioDevice::InputChannels
+// WCMRAudioDevice::InputChannels
//
//! Retrieves Input Channel information. Note that the list may be changed at run-time.
//!
//! \param none
-//!
+//!
//! \return A vector with Input Channel Names.
-//!
+//!
//**********************************************************************************************
const std::vector<std::string>& WCMRAudioDevice::InputChannels ()
{
return (m_InputChannels);
-
+
}
//**********************************************************************************************
-// WCMRAudioDevice::OutputChannels
+// WCMRAudioDevice::OutputChannels
//
//! Retrieves Output Channel Information. Note that the list may be changed at run-time.
//!
//! \param none
-//!
+//!
//! \return A vector with Output Channel Names.
-//!
+//!
//**********************************************************************************************
const std::vector<std::string>& WCMRAudioDevice::OutputChannels ()
{
//**********************************************************************************************
-// WCMRAudioDevice::SamplingRates
+// WCMRAudioDevice::SamplingRates
//
//! Retrieves supported sampling rate information.
//!
//! \param none
-//!
+//!
//! \return A vector with supported sampling rates.
-//!
+//!
//**********************************************************************************************
const std::vector<int>& WCMRAudioDevice::SamplingRates ()
{
//**********************************************************************************************
-// WCMRAudioDevice::CurrentSamplingRate
+// WCMRAudioDevice::CurrentSamplingRate
//
-//! The device's current sampling rate. This may be overridden, if the device needs to
+//! The device's current sampling rate. This may be overridden, if the device needs to
//! query the driver for the current rate.
//!
//! \param none
-//!
+//!
//! \return The device's current sampling rate. -1 on error.
-//!
+//!
//**********************************************************************************************
int WCMRAudioDevice::CurrentSamplingRate ()
{
//**********************************************************************************************
-// WCMRAudioDevice::SetCurrentSamplingRate
+// WCMRAudioDevice::SetCurrentSamplingRate
//
-//! Change the sampling rate to be used by the device. This will most likely be overridden,
+//! Change the sampling rate to be used by the device. This will most likely be overridden,
//! the base class simply updates the member variable.
//!
//! \param newRate : The rate to use (samples per sec).
-//!
+//!
//! \return eNoErr always. The derived classes may return error codes.
-//!
+//!
//**********************************************************************************************
WTErr WCMRAudioDevice::SetCurrentSamplingRate (int newRate)
{
//**********************************************************************************************
-// WCMRAudioDevice::BufferSizes
+// WCMRAudioDevice::BufferSizes
//
//! Retrieves supported buffer size information.
//!
//! \param none
-//!
+//!
//! \return A vector with supported buffer sizes.
-//!
+//!
//**********************************************************************************************
const std::vector<int>& WCMRAudioDevice::BufferSizes ()
{
//**********************************************************************************************
// WCMRAudioDevice::CurrentBufferSize
//
-//! The device's current buffer size in use. This may be overridden, if the device needs to
+//! The device's current buffer size in use. This may be overridden, if the device needs to
//! query the driver for the current size.
//!
//! \param none
-//!
+//!
//! \return The device's current buffer size. 0 on error.
-//!
+//!
//**********************************************************************************************
int WCMRAudioDevice::CurrentBufferSize ()
{
//
//! Device's block size we use for holding the audio samples.
//! Usually this is equal to the buffer size, but in some cases the buffer size holds additional
-//! data other then the audio buffers, like frames info in SG, so it can be overriden
+//! data other then the audio buffers, like frames info in SG, so it can be overridden
//!
//! \param none
-//!
+//!
//! \return The device's current block size. 0 on error.
-//!
+//!
//**********************************************************************************************
int WCMRAudioDevice::CurrentBlockSize()
{
//**********************************************************************************************
// WCMRAudioDevice::SetCurrentBufferSize
//
-//! Change the buffer size to be used by the device. This will most likely be overridden,
+//! Change the buffer size to be used by the device. This will most likely be overridden,
//! the base class simply updates the member variable.
//!
//! \param newSize : The buffer size to use (in sample-frames)
-//!
+//!
//! \return eNoErr always. The derived classes may return error codes.
-//!
+//!
//**********************************************************************************************
WTErr WCMRAudioDevice::SetCurrentBufferSize (int newSize)
{
//**********************************************************************************************
-// WCMRAudioDevice::ConnectionStatus
+// WCMRAudioDevice::ConnectionStatus
//
//! Retrieves the device's current connection status. This will most likely be overridden,
//! in case some driver communication is required to query the status.
//!
//! \param none
-//!
+//!
//! \return A ConnectionStates value.
-//!
+//!
//**********************************************************************************************
WCMRAudioDevice::ConnectionStates WCMRAudioDevice::ConnectionStatus ()
{
return (m_ConnectionStatus);
-
+
}
//**********************************************************************************************
-// WCMRAudioDevice::Active
+// WCMRAudioDevice::Active
//
//! Retrieves Device activation status.
//!
//! \param none
-//!
+//!
//! \return true if device is active, false otherwise.
-//!
+//!
//**********************************************************************************************
bool WCMRAudioDevice::Active ()
{
return (m_IsActive);
-
+
}
//**********************************************************************************************
-// WCMRAudioDevice::SetActive
+// WCMRAudioDevice::SetActive
//
//! Sets the device's activation status.
//!
//! \param newState : Should be true to activate, false to deactivate. This roughly corresponds
//! to opening and closing the device handle/stream/audio unit.
-//!
+//!
//! \return eNoErr always, the derived classes may return appropriate error code.
-//!
+//!
//**********************************************************************************************
WTErr WCMRAudioDevice::SetActive (bool newState)
{
//**********************************************************************************************
-// WCMRAudioDevice::Streaming
+// WCMRAudioDevice::Streaming
//
//! Retrieves Device streaming status.
//!
//! \param none
-//!
+//!
//! \return true if device is streaming, false otherwise.
-//!
+//!
//**********************************************************************************************
bool WCMRAudioDevice::Streaming ()
{
//!
//! \param newState : Should be true to start streaming, false to stop streaming. This roughly
//! corresponds to calling Start/Stop on the lower level interface.
-//!
+//!
//! \return eNoErr always, the derived classes may return appropriate error code.
-//!
+//!
//**********************************************************************************************
WTErr WCMRAudioDevice::SetStreaming (bool newState)
{
+ // We must notify angine about our intention to start streming
+ // so Engine will provide all the initializations in the first audio callback
+ if (newState) {
+ m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
+ }
+
//This will most likely be overridden, the base class simply
//changes the member.
m_IsStreaming = newState;
return (eNoErr);
}
+
+WTErr WCMRAudioDevice::ResetDevice ()
+{
+ // Keep device sates
+ bool wasStreaming = Streaming();
+ bool wasActive = Active();
+
+ WTErr err = SetStreaming(false);
+
+ if (err == eNoErr)
+ err = SetActive(false);
+
+ if (err == eNoErr && wasActive)
+ err = SetActive(true);
+
+ if (err == eNoErr && wasStreaming)
+ SetStreaming(true);
+
+ return err;
+}
+
+
///////////////////////////////////////////////////////////////////////////////////////////////////////
// IsProcessActive - returns true if process code is running.
// A normal audio device should return the Streaming() value
//**********************************************************************************************
-// WCMRAudioDevice::DoIdle
+// WCMRAudioDevice::DoIdle
//
//! A place for doing idle time processing. The derived classes will probably do something
//! meaningful.
//!
//! \param none
-//!
+//!
//! \return eNoErr always.
-//!
+//!
//**********************************************************************************************
WTErr WCMRAudioDevice::DoIdle ()
{
//**********************************************************************************************
-// WCMRAudioDevice::InputLevels
+// WCMRAudioDevice::InputLevels
//
//! Retrieve current input levels.
//!
//! \param none
-//!
+//!
//! \return A vector (the same size as input channels list) that contains current input levels.
-//!
+//!
//**********************************************************************************************
const std::vector<float>& WCMRAudioDevice::InputLevels ()
{
//**********************************************************************************************
-// WCMRAudioDevice::OutputLevels
+// WCMRAudioDevice::OutputLevels
//
//! Retrieve current output levels.
//!
//! \param none
-//!
+//!
//! \return A vector (the same size as output channels list) that contains current output levels.
-//!
+//!
//**********************************************************************************************
const std::vector<float>& WCMRAudioDevice::OutputLevels ()
{
//**********************************************************************************************
-// WCMRAudioDevice::GetMonitorInfo
+// WCMRAudioDevice::GetMonitorInfo
//
//! Retrieves current monitoring information.
//!
//! \param *pLeftChannel : Pointer to receive left monitor channel index.
//! \param *pRightChannel : Pointer to receive right monitor channel index.
//! \param *pGain : Pointer to receive the gain (linear) to be applied.
-//!
+//!
//! \return Nothing.
-//!
+//!
//**********************************************************************************************
void WCMRAudioDevice::GetMonitorInfo (int *pLeftChannel, int *pRightChannel, float *pGain)
{
if (pLeftChannel)
*pLeftChannel = m_LeftMonitorChannel;
- if (pRightChannel)
+ if (pRightChannel)
*pRightChannel = m_RightMonitorChannel;
- if (pGain)
+ if (pGain)
*pGain = m_MonitorGain;
- return;
+ return;
}
//**********************************************************************************************
-// WCMRAudioDevice::SetMonitorChannels
+// WCMRAudioDevice::SetMonitorChannels
//
//! Used to set the channels to be used for monitoring.
//!
//! \param leftChannel : Left monitor channel index.
//! \param rightChannel : Right monitor channel index.
-//!
+//!
//! \return eNoErr always, the derived classes may return appropriate errors.
-//!
+//!
//**********************************************************************************************
WTErr WCMRAudioDevice::SetMonitorChannels (int leftChannel, int rightChannel)
{
//**********************************************************************************************
-// WCMRAudioDevice::SetMonitorGain
+// WCMRAudioDevice::SetMonitorGain
//
//! Used to set monitor gain (or atten).
//!
-//! \param newGain : The new gain or atten. value to use. Specified as a linear multiplier (not dB)
-//!
+//! \param newGain : The new gain or atten. value to use. Specified as a linear multiplier (not dB)
+//!
//! \return eNoErr always, the derived classes may return appropriate errors.
-//!
+//!
//**********************************************************************************************
WTErr WCMRAudioDevice::SetMonitorGain (float newGain)
{
//**********************************************************************************************
-// WCMRAudioDevice::ShowConfigPanel
+// WCMRAudioDevice::ShowConfigPanel
//
//! Used to show device specific config/control panel. Some interfaces may not support it.
//! Some interfaces may require the device to be active before it can display a panel.
//!
//! \param pParam : A device/interface specific parameter - optional.
-//!
+//!
//! \return eNoErr always, the derived classes may return errors.
-//!
+//!
//**********************************************************************************************
WTErr WCMRAudioDevice::ShowConfigPanel (void *WCUNUSEDPARAM(pParam))
{
//**********************************************************************************************
-// WCMRAudioDevice::SendCustomCommand
+// WCMRAudioDevice::SendCustomCommand
//
-//! Used to Send a custom command to the audiodevice. Some interfaces may require the device
+//! Used to Send a custom command to the audiodevice. Some interfaces may require the device
//! to be active before it can do anything in this.
//!
//! \param customCommand : A device/interface specific command.
//! \param pCommandParam : A device/interface/command specific parameter - optional.
-//!
+//!
//! \return eNoErr always, the derived classes may return errors.
-//!
+//!
//**********************************************************************************************
WTErr WCMRAudioDevice::SendCustomCommand (int WCUNUSEDPARAM(customCommand), void *WCUNUSEDPARAM(pCommandParam))
{
return 0;
}
+
//**********************************************************************************************
// WCMRAudioDeviceManager::WCMRAudioDeviceManager
//
//! The constructuor, most of the work will be done in the derived class' constructor.
//!
-//! \param *pTheClient :
-//!
+//! \param *pTheClient :
+//!
//! \return Nothing.
-//!
+//!
//**********************************************************************************************
WCMRAudioDeviceManager::WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter)
- : m_pTheClient (pTheClient)
- , m_eAudioDeviceFilter(eCurAudioDeviceFilter)
+ : m_eAudioDeviceFilter(eCurAudioDeviceFilter)
+ , m_CurrentDevice(0)
+ , m_pTheClient (pTheClient)
{
- //The derived classes will do lot more init!
- return;
}
-
//**********************************************************************************************
// WCMRAudioDeviceManager::~WCMRAudioDeviceManager
//
//! It clears the device list, releasing each of the device.
//!
//! \param none
-//!
+//!
//! \return Nothing.
-//!
+//!
//**********************************************************************************************
WCMRAudioDeviceManager::~WCMRAudioDeviceManager()
{
AUTO_FUNC_DEBUG;
+ std::cout << "API::Destroying AudioDeviceManager " << std::endl;
try
{
- //Need to call release on our devices, and erase them from list
- std::vector<WCMRAudioDevice*>::iterator deviceIter;
- while (m_Devices.size())
- {
- WCMRAudioDevice *pDeviceToRelease = m_Devices.back();
- m_Devices.pop_back();
- if (pDeviceToRelease)
- SAFE_RELEASE (pDeviceToRelease);
- }
-
- //The derived classes may want to do additional de-int!
+ // clean up device info list
+ {
+ wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
+ while( m_DeviceInfoVec.size() )
+ {
+ DeviceInfo* devInfo = m_DeviceInfoVec.back();
+ m_DeviceInfoVec.pop_back();
+ delete devInfo;
+ }
+ }
+ delete m_CurrentDevice;
+
}
catch (...)
{
}
-
-
-//**********************************************************************************************
-// WCMRAudioDeviceManager::DoIdle_Private
-//
-//! Used for idle time processing. This calls each device's DoIdle so that it can perform it's own idle processing.
-//!
-//! \param none
-//!
-//! \return noErr if no devices have returned an error. An error code if any of the devices returned error.
-//!
-//**********************************************************************************************
-WTErr WCMRAudioDeviceManager::DoIdle_Private()
+WCMRAudioDevice* WCMRAudioDeviceManager::InitNewCurrentDevice(const std::string & deviceName)
{
- WTErr retVal = eNoErr;
-
- //Need to call DoIdle of all our devices...
- std::vector<WCMRAudioDevice*>::iterator deviceIter;
- for (deviceIter = m_Devices.begin(); deviceIter != m_Devices.end(); deviceIter++)
- {
- WTErr thisDeviceErr = (*deviceIter)->DoIdle();
-
- if (thisDeviceErr != eNoErr)
- retVal = thisDeviceErr;
- }
-
- return (retVal);
+ return initNewCurrentDeviceImpl(deviceName);
}
+void WCMRAudioDeviceManager::DestroyCurrentDevice()
+{
+ return destroyCurrentDeviceImpl();
+}
-//**********************************************************************************************
-// WCMRAudioDeviceManager::Devices_Private
-//
-//! Retrieve list of devices managed by this manager.
-//!
-//! \param none
-//!
-//! \return A vector containing the list of devices.
-//!
-//**********************************************************************************************
-const WCMRAudioDeviceList& WCMRAudioDeviceManager::Devices_Private() const
+const DeviceInfoVec WCMRAudioDeviceManager::DeviceInfoList() const
{
- return (m_Devices);
+ wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
+ return m_DeviceInfoVec;
}
-
-//**********************************************************************************************
-// *WCMRAudioDeviceManager::GetDeviceByName_Private
-//
-//! Locates a device based on device name.
-//!
-//! \param nameToMatch : Device to look for.
-//!
-//! \return Pointer to the device object if found, NULL otherwise.
-//!
-//**********************************************************************************************
-WCMRAudioDevice *WCMRAudioDeviceManager::GetDeviceByName_Private(const std::string& nameToMatch) const
+WTErr WCMRAudioDeviceManager::GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const
{
- //Need to check all our devices...
- WCMRAudioDevice *pRetVal = NULL;
-
- WCMRAudioDeviceListConstIter deviceIter;
- for (deviceIter = m_Devices.begin(); deviceIter != m_Devices.end(); deviceIter++)
+ wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
+ DeviceInfoVecConstIter iter = m_DeviceInfoVec.begin();
+ for (; iter != m_DeviceInfoVec.end(); ++iter)
{
- if ((*deviceIter)->DeviceName() == nameToMatch)
- {
- pRetVal = *deviceIter;
- break;
- }
+ if (nameToMatch == (*iter)->m_DeviceName)
+ {
+ devInfo = *(*iter);
+ return eNoErr;
+ }
}
-
- return (pRetVal);
+
+ return eRMResNotFound;
}
-//**********************************************************************************************
-// *WCMRAudioDeviceManager::GetDefaultDevice
-//
-//! Locates a device based on device name.
-//!
-//! \param nameToMatch : Device to look for.
-//!
-//! \return Pointer to the device object if found, NULL otherwise.
-//!
-//**********************************************************************************************
-WCMRAudioDevice *WCMRAudioDeviceManager::GetDefaultDevice_Private()
-{
- //Need to check all our devices...
- WCMRAudioDevice *pRetVal = NULL;
-
- WCMRAudioDeviceListIter deviceIter = m_Devices.begin();
- if(deviceIter != m_Devices.end())
- {
- pRetVal = *deviceIter;
- }
- return (pRetVal);
+
+WTErr WCMRAudioDeviceManager::GetDeviceSampleRates(const std::string & nameToMatch, std::vector<int>& sampleRates) const
+{
+ return getDeviceSampleRatesImpl(nameToMatch, sampleRates);
}
+WTErr WCMRAudioDeviceManager::GetDeviceBufferSizes(const std::string & nameToMatch, std::vector<int>& bufferSizes) const
+{
+ return getDeviceBufferSizesImpl(nameToMatch, bufferSizes);
+}
+
//**********************************************************************************************
-// WCMRAudioDeviceManager::NotifyClient
+// WCMRAudioDeviceManager::NotifyClient
//
//! A helper routine used to call the client for notification.
//!
//! \param forReason : The reason for notification.
//! \param *pParam : A parameter (if required) for notification.
-//!
+//!
//! \return Nothing.
-//!
+//!
//**********************************************************************************************
void WCMRAudioDeviceManager::NotifyClient (WCMRAudioDeviceManagerClient::NotificationReason forReason, void *pParam)
{
if (m_pTheClient)
m_pTheClient->AudioDeviceManagerNotification (forReason, pParam);
- return;
+ return;
}