mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 00:34:59 +01:00
update wavesaudio backend, now supports Windows (ASIO) as well as OS X (CoreAudio)
This commit is contained in:
parent
152935e736
commit
f374ce69a6
82 changed files with 11259 additions and 7632 deletions
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __WCFourCC_h__
|
||||
#define __WCFourCC_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#if !defined(__WTByteOrder_h__)
|
||||
#define __WTByteOrder_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __WUComPtr_h__
|
||||
#define __WUComPtr_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __WUDefines_h__
|
||||
#define __WUDefines_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __WUMathConsts_h__
|
||||
#define __WUMathConsts_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __WUTypes_h__
|
||||
#define __WUTypes_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,49 +1,31 @@
|
|||
/*
|
||||
Copyright (C) 2013 Waves Audio Ltd.
|
||||
#ifndef __IncludeWindows_h__
|
||||
#define __IncludeWindows_h__
|
||||
|
||||
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.
|
||||
#ifdef _WINDOWS
|
||||
|
||||
/* Copy to include
|
||||
#include "IncludeWindows.h"
|
||||
*/
|
||||
#ifndef __IncludeWindows_h__
|
||||
#define __IncludeWindows_h__
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
/* Copy to include
|
||||
#include "IncludeWindows.h"
|
||||
*/
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0601 // Windows 7
|
||||
#endif
|
||||
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0601 // Windows 7
|
||||
#endif
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX // DO NOT REMOVE NOMINMAX - DOING SO CAUSES CONFLICTS WITH STD INCLUDES (<limits> ...)
|
||||
#endif
|
||||
|
||||
#include <WinSock2.h>
|
||||
#include <Windows.h>
|
||||
#include <objbase.h>
|
||||
#endif // #if _WINDOWS
|
||||
#endif // #ifndef __IncludeWindows_h__
|
||||
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0601 // Windows 7
|
||||
#endif
|
||||
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0601 // Windows 7
|
||||
#endif
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX // DO NOT REMOVE NOMINMAX - DOING SO CAUSES CONFLICTS WITH STD INCLUDES (<limits> ...)
|
||||
#endif
|
||||
|
||||
#include <WinSock2.h>
|
||||
#include <Windows.h>
|
||||
#include <objbase.h>
|
||||
#endif // #if _WINDOWS
|
||||
#endif // #ifndef __IncludeWindows_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +1,6 @@
|
|||
/*
|
||||
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
|
||||
//!
|
||||
|
|
@ -27,10 +10,6 @@
|
|||
#include "WCMRAudioDeviceManager.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// WCMRAudioDevice::WCMRAudioDevice
|
||||
//
|
||||
|
|
@ -39,27 +18,21 @@
|
|||
//! 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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -565,6 +538,7 @@ uint32_t WCMRAudioDevice::GetLatency (bool isInput)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// WCMRAudioDeviceManager::WCMRAudioDeviceManager
|
||||
//
|
||||
|
|
@ -576,15 +550,13 @@ uint32_t WCMRAudioDevice::GetLatency (bool isInput)
|
|||
//!
|
||||
//**********************************************************************************************
|
||||
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
|
||||
//
|
||||
|
|
@ -599,19 +571,21 @@ 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 (...)
|
||||
{
|
||||
|
|
@ -621,109 +595,48 @@ WCMRAudioDeviceManager::~WCMRAudioDeviceManager()
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// 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++)
|
||||
return initNewCurrentDeviceImpl(deviceName);
|
||||
}
|
||||
|
||||
|
||||
void WCMRAudioDeviceManager::DestroyCurrentDevice()
|
||||
{
|
||||
return destroyCurrentDeviceImpl();
|
||||
}
|
||||
|
||||
|
||||
const DeviceInfoVec WCMRAudioDeviceManager::DeviceInfoList() const
|
||||
{
|
||||
wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
|
||||
return m_DeviceInfoVec;
|
||||
}
|
||||
|
||||
|
||||
WTErr WCMRAudioDeviceManager::GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const
|
||||
{
|
||||
wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
|
||||
DeviceInfoVecConstIter iter = m_DeviceInfoVec.begin();
|
||||
for (; iter != m_DeviceInfoVec.end(); ++iter)
|
||||
{
|
||||
WTErr thisDeviceErr = (*deviceIter)->DoIdle();
|
||||
|
||||
if (thisDeviceErr != eNoErr)
|
||||
retVal = thisDeviceErr;
|
||||
if (nameToMatch == (*iter)->m_DeviceName)
|
||||
{
|
||||
devInfo = *(*iter);
|
||||
return eNoErr;
|
||||
}
|
||||
}
|
||||
|
||||
return (retVal);
|
||||
|
||||
return eRMResNotFound;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// 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
|
||||
WTErr WCMRAudioDeviceManager::GetDeviceBufferSizes(const std::string & nameToMatch, std::vector<int>& bufferSizes) const
|
||||
{
|
||||
return (m_Devices);
|
||||
return getDeviceBufferSizesImpl(nameToMatch, bufferSizes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// *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
|
||||
{
|
||||
//Need to check all our devices...
|
||||
WCMRAudioDevice *pRetVal = NULL;
|
||||
|
||||
WCMRAudioDeviceListConstIter deviceIter;
|
||||
for (deviceIter = m_Devices.begin(); deviceIter != m_Devices.end(); deviceIter++)
|
||||
{
|
||||
if ((*deviceIter)->DeviceName() == nameToMatch)
|
||||
{
|
||||
pRetVal = *deviceIter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (pRetVal);
|
||||
}
|
||||
|
||||
//**********************************************************************************************
|
||||
// *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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// WCMRAudioDeviceManager::NotifyClient
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,23 +1,6 @@
|
|||
/*
|
||||
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.h
|
||||
//!
|
||||
|
|
@ -42,19 +25,35 @@
|
|||
#include "WCRefManager.h"
|
||||
#include "BasicTypes/WUTypes.h"
|
||||
#include "WUErrors.h"
|
||||
#include "WCThreadSafe.h"
|
||||
|
||||
#define WCUNUSEDPARAM(a)
|
||||
|
||||
//forward decl.
|
||||
class WCMRAudioConnection;
|
||||
class WCMRAudioDevice;
|
||||
class WCMRAudioDeviceManager;
|
||||
|
||||
typedef std::vector<WCMRAudioDevice *> WCMRAudioDeviceList; ///< Vector for audio devices
|
||||
typedef std::vector<WCMRAudioDevice *>::iterator WCMRAudioDeviceListIter; ///< Vector iterator for audio devices
|
||||
typedef std::vector<WCMRAudioDevice *>::const_iterator WCMRAudioDeviceListConstIter; ///< Vector iterator for audio devices
|
||||
typedef std::vector<WCMRAudioConnection *> WCMRAudioConnectionsList; ///< Vector for audio devices
|
||||
typedef unsigned int DeviceID;
|
||||
|
||||
struct DeviceInfo
|
||||
{
|
||||
DeviceID m_DeviceId;
|
||||
std::string m_DeviceName;
|
||||
std::vector<int> m_AvailableSampleRates;
|
||||
unsigned int m_MaxInputChannels;
|
||||
unsigned int m_MaxOutputChannels;
|
||||
|
||||
DeviceInfo():
|
||||
m_DeviceId(-1), m_DeviceName("Unknown"), m_MaxInputChannels(0), m_MaxOutputChannels(0)
|
||||
{};
|
||||
|
||||
DeviceInfo(unsigned int deviceID, const std::string & deviceName):
|
||||
m_DeviceId(deviceID), m_DeviceName(deviceName), m_MaxInputChannels(0), m_MaxOutputChannels(0)
|
||||
{};
|
||||
};
|
||||
|
||||
typedef std::vector<DeviceInfo*> DeviceInfoVec;
|
||||
typedef DeviceInfoVec::iterator DeviceInfoVecIter;
|
||||
typedef DeviceInfoVec::const_iterator DeviceInfoVecConstIter;
|
||||
|
||||
/// for notification... A client must derive it's class from us.
|
||||
class WCMRAudioDeviceManagerClient
|
||||
|
|
@ -71,6 +70,7 @@ class WCMRAudioDeviceManagerClient
|
|||
BufferSizeChanged,
|
||||
ClockSourceChanged,
|
||||
DeviceStoppedStreaming,
|
||||
DeviceStartsStreaming,
|
||||
DeviceDroppedSamples,
|
||||
DeviceConnectionLost,
|
||||
DeviceGenericError,
|
||||
|
|
@ -123,7 +123,7 @@ public:
|
|||
{
|
||||
DeviceAvailable,
|
||||
DeviceDisconnected,
|
||||
DeviceError
|
||||
DeviceErrors
|
||||
};
|
||||
|
||||
WCMRAudioDevice (WCMRAudioDeviceManager *pManager);///<Constructor
|
||||
|
|
@ -167,6 +167,8 @@ public:
|
|||
virtual WTErr SendCustomCommand (int customCommand, void *pCommandParam); ///< Send a custom command to the audiodevice...
|
||||
|
||||
virtual uint32_t GetLatency (bool isInput); ///Get latency.
|
||||
|
||||
virtual WTErr UpdateDeviceInfo () = 0;
|
||||
|
||||
protected:
|
||||
WCMRAudioDeviceManager *m_pMyManager; ///< The manager who's managing this device, can be used for sending notifications!
|
||||
|
|
@ -191,6 +193,7 @@ protected:
|
|||
float m_MonitorGain; ///< Amount of gain to apply for monitoring signal.
|
||||
};
|
||||
|
||||
|
||||
// This enum is for choosing filter for audio devices scan
|
||||
typedef enum eAudioDeviceFilter
|
||||
{
|
||||
|
|
@ -202,65 +205,44 @@ typedef enum eAudioDeviceFilter
|
|||
eAudioDeviceFilterNum // Number of enums
|
||||
} eAudioDeviceFilter;
|
||||
|
||||
//! WCMRAudioDeviceManager
|
||||
/*! The Audio Device Manager class */
|
||||
|
||||
class WCMRAudioDeviceManager : public WCRefManager
|
||||
{
|
||||
private://< Private version of class functions which will be called by class's public function after mutex lock acquistion.
|
||||
WCMRAudioDevice* GetDefaultDevice_Private();
|
||||
WTErr DoIdle_Private();
|
||||
const WCMRAudioDeviceList& Devices_Private() const;
|
||||
WCMRAudioDevice* GetDeviceByName_Private(const std::string & nameToMatch) const;
|
||||
|
||||
public://< Public functions for the class.
|
||||
WCMRAudioDevice* GetDefaultDevice()
|
||||
{
|
||||
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
|
||||
return GetDefaultDevice_Private();
|
||||
}
|
||||
|
||||
WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter); ///< constructor
|
||||
virtual ~WCMRAudioDeviceManager(void); ///< Destructor
|
||||
|
||||
virtual WTErr DoIdle()
|
||||
{
|
||||
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
|
||||
return DoIdle_Private();
|
||||
}
|
||||
//interfaces
|
||||
WCMRAudioDevice* InitNewCurrentDevice(const std::string & deviceName);
|
||||
void DestroyCurrentDevice();
|
||||
const DeviceInfoVec DeviceInfoList () const;
|
||||
WTErr GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const;
|
||||
WTErr GetDeviceBufferSizes(const std::string & nameToMatch, std::vector<int>& bufferSizes) const;
|
||||
|
||||
const WCMRAudioDeviceList& Devices() const
|
||||
{
|
||||
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
|
||||
return Devices_Private();
|
||||
}
|
||||
//virtual void EnableVerboseLogging(bool /*bEnable*/, const std::string& /*logFilePath*/) { };
|
||||
|
||||
WCMRAudioDevice* GetDeviceByName(const std::string & nameToMatch) const
|
||||
{
|
||||
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
|
||||
return GetDeviceByName_Private(nameToMatch);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter
|
||||
); ///< constructor
|
||||
virtual ~WCMRAudioDeviceManager(void); ///< Destructor
|
||||
|
||||
virtual WTErr UpdateDeviceList () = 0; //has to be overridden!
|
||||
|
||||
|
||||
//This is primarily for use by WCMRAudioDevice and it's descendants... We could have made it
|
||||
//protected and made WCMRAudioDevice a friend, and then in some way found a way to extend
|
||||
//the friendship to WCMRAudioDevice's descendants, but that would require a lot of extra
|
||||
//effort!
|
||||
void NotifyClient (WCMRAudioDeviceManagerClient::NotificationReason forReason, void *pParam = NULL);
|
||||
virtual void EnableVerboseLogging(bool /*bEnable*/, const std::string& /*logFilePath*/) { };
|
||||
//notify backend
|
||||
void NotifyClient (WCMRAudioDeviceManagerClient::NotificationReason forReason, void *pParam = NULL);
|
||||
|
||||
protected:
|
||||
|
||||
//< NOTE : Mutex protection is commented, but wrapper classes are still there, in case they are required in future.
|
||||
//wvNS::wvThread::ThreadMutex m_AudioDeviceManagerMutex; ///< Mutex for Audio device manager class function access.
|
||||
WCMRAudioDeviceManagerClient *m_pTheClient; ///< The device manager's client, used to send notifications.
|
||||
mutable wvNS::wvThread::ThreadMutex m_AudioDeviceInfoVecMutex; // mutex to lock device info list
|
||||
DeviceInfoVec m_DeviceInfoVec;
|
||||
|
||||
WCMRAudioDeviceList m_Devices; ///< List of all relevant devices devices
|
||||
eAudioDeviceFilter m_eAudioDeviceFilter; // filter of 'm_Devices'
|
||||
eAudioDeviceFilter m_eAudioDeviceFilter;
|
||||
WCMRAudioDevice* m_CurrentDevice;
|
||||
|
||||
private:
|
||||
// override in derived classes
|
||||
// made private to avoid pure virtual function call
|
||||
virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName) = 0;
|
||||
virtual void destroyCurrentDeviceImpl() = 0;
|
||||
virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const = 0;
|
||||
virtual WTErr generateDeviceListImpl() = 0;
|
||||
virtual WTErr updateDeviceListImpl() = 0;
|
||||
|
||||
WCMRAudioDeviceManagerClient *m_pTheClient; ///< The device manager's client, used to send notifications.
|
||||
};
|
||||
|
||||
#endif //#ifndef __WCMRAudioDeviceManager_h_
|
||||
|
|
|
|||
|
|
@ -1,23 +1,6 @@
|
|||
/*
|
||||
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 WCMRCoreAudioDeviceManager.cpp
|
||||
//!
|
||||
|
|
@ -58,6 +41,8 @@ static const int DEFAULT_SR = 44100;
|
|||
///< The default buffer size.
|
||||
static const int DEFAULT_BUFFERSIZE = 128;
|
||||
|
||||
static const int NONE_DEVICE_ID = -1;
|
||||
|
||||
///< Number of stalls to wait before notifying user...
|
||||
static const int NUM_STALLS_FOR_NOTIFICATION = 2 * 50; // 2*50 corresponds to 2 * 50 x 42 ms idle timer - about 4 seconds.
|
||||
static const int CHANGE_CHECK_COUNTER_PERIOD = 100; // 120 corresponds to 120 x 42 ms idle timer - about 4 seconds.
|
||||
|
|
@ -166,7 +151,7 @@ WCMRCoreAudioDevice::WCMRCoreAudioDevice (WCMRCoreAudioDeviceManager *pManager,
|
|||
m_CurrentBufferSize = (int)bufferSize;
|
||||
|
||||
|
||||
UpdateDeviceInfo(true /*updateSRSupported*/, true /* updateBufferSizes */);
|
||||
UpdateDeviceInfo();
|
||||
|
||||
//should use a valid current SR...
|
||||
if (m_SamplingRates.size())
|
||||
|
|
@ -252,14 +237,11 @@ WCMRCoreAudioDevice::~WCMRCoreAudioDevice ()
|
|||
// WCMRCoreAudioDevice::UpdateDeviceInfo
|
||||
//
|
||||
//! Updates Device Information about channels, sampling rates, buffer sizes.
|
||||
//!
|
||||
//! \param updateSRSupported : Is Sampling Rate support needs to be updated.
|
||||
//! \param updateBufferSizes : Is buffer size support needs to be updated.
|
||||
//!
|
||||
//! \return WTErr.
|
||||
//!
|
||||
//**********************************************************************************************
|
||||
WTErr WCMRCoreAudioDevice::UpdateDeviceInfo (bool updateSRSupported, bool updateBufferSizes)
|
||||
WTErr WCMRCoreAudioDevice::UpdateDeviceInfo ()
|
||||
{
|
||||
AUTO_FUNC_DEBUG;
|
||||
|
||||
|
|
@ -272,17 +254,8 @@ WTErr WCMRCoreAudioDevice::UpdateDeviceInfo (bool updateSRSupported, bool update
|
|||
WTErr errSR = eNoErr;
|
||||
WTErr errBS = eNoErr;
|
||||
|
||||
if (updateSRSupported)
|
||||
{
|
||||
errSR = UpdateDeviceSampleRates();
|
||||
}
|
||||
|
||||
//update SR list... This is done conditionally, because some devices may not like
|
||||
//changing the SR later on, just to check on things.
|
||||
if (updateBufferSizes)
|
||||
{
|
||||
errBS = UpdateDeviceBufferSizes();
|
||||
}
|
||||
errSR = UpdateDeviceSampleRates();
|
||||
errBS = UpdateDeviceBufferSizes();
|
||||
|
||||
if(errName != eNoErr || errIn != eNoErr || errOut != eNoErr || errSR != eNoErr || errBS != eNoErr)
|
||||
{
|
||||
|
|
@ -786,7 +759,7 @@ WTErr WCMRCoreAudioDevice::SetCurrentSamplingRate (int newRate)
|
|||
retVal = SetAndCheckCurrentSamplingRate (newRate);
|
||||
if(retVal == eNoErr)
|
||||
{
|
||||
retVal = UpdateDeviceInfo (false/*updateSRSupported*/, true/*updateBufferSizes*/);
|
||||
retVal = UpdateDeviceInfo ();
|
||||
}
|
||||
|
||||
//reactivate it.
|
||||
|
|
@ -1759,7 +1732,7 @@ WTErr WCMRCoreAudioDevice::SetActive (bool newState)
|
|||
m_DropsReported = 0;
|
||||
m_IgnoreThisDrop = true;
|
||||
|
||||
UpdateDeviceInfo(true /*updateSRSupported */, true /* updateBufferSizes#*/);
|
||||
UpdateDeviceInfo();
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -2317,14 +2290,10 @@ OSStatus WCMRCoreAudioDevice::GetStreamLatency(AudioDeviceID device, bool isInpu
|
|||
//! \return Nothing.
|
||||
//!
|
||||
//**********************************************************************************************
|
||||
WCMRCoreAudioDeviceManager::WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter
|
||||
, bool useMultithreading, eCABS_Method eCABS_method, bool bNocopy)
|
||||
: WCMRAudioDeviceManager (pTheClient, eCurAudioDeviceFilter
|
||||
)
|
||||
, m_UpdateDeviceListRequested(0)
|
||||
, m_UpdateDeviceListProcessed(0)
|
||||
WCMRCoreAudioDeviceManager::WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient,
|
||||
eAudioDeviceFilter eCurAudioDeviceFilter, bool useMultithreading, bool bNocopy)
|
||||
: WCMRAudioDeviceManager (pTheClient, eCurAudioDeviceFilter)
|
||||
, m_UseMultithreading (useMultithreading)
|
||||
, m_eCABS_Method(eCABS_method)
|
||||
, m_bNoCopyAudioBuffer(bNocopy)
|
||||
{
|
||||
AUTO_FUNC_DEBUG;
|
||||
|
|
@ -2347,13 +2316,13 @@ WCMRCoreAudioDeviceManager::WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerCli
|
|||
}
|
||||
|
||||
//add a listener to find out when devices change...
|
||||
AudioHardwareAddPropertyListener (kAudioHardwarePropertyDevices, StaticPropertyChangeProc, this);
|
||||
|
||||
AudioHardwareAddPropertyListener (kAudioHardwarePropertyDevices, DevicePropertyChangeCallback, this);
|
||||
|
||||
//Always add the None device first...
|
||||
m_Devices.push_back (new WCMRNativeAudioNoneDevice(this));
|
||||
m_NoneDevice = new WCMRNativeAudioNoneDevice(this);
|
||||
|
||||
//prepare our initial list...
|
||||
UpdateDeviceList_Private();
|
||||
generateDeviceListImpl();
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -2376,25 +2345,7 @@ WCMRCoreAudioDeviceManager::~WCMRCoreAudioDeviceManager()
|
|||
|
||||
try
|
||||
{
|
||||
AudioHardwareRemovePropertyListener (kAudioHardwarePropertyDevices, StaticPropertyChangeProc);
|
||||
|
||||
//Note: We purposely release the device list here, instead of
|
||||
//depending on the superclass to do it, as by the time the superclass'
|
||||
//destructor executes, we will have called Pa_Terminate()!
|
||||
|
||||
//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();
|
||||
|
||||
SAFE_RELEASE (pDeviceToRelease);
|
||||
}
|
||||
|
||||
|
||||
//The derived classes may want to do additional de-int!
|
||||
|
||||
delete m_NoneDevice;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
|
@ -2405,313 +2356,511 @@ WCMRCoreAudioDeviceManager::~WCMRCoreAudioDeviceManager()
|
|||
}
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// WCMRCoreAudioDeviceManager::StaticPropertyChangeProc
|
||||
//
|
||||
//! The property change listener for the Audio Device Manager. It calls upon (non-static) PropertyChangeProc
|
||||
//! to do the actual work.
|
||||
//!
|
||||
//! \param iPropertyID : the property that has changed.
|
||||
//! \param inClientData : What was supplied at init time.
|
||||
//!
|
||||
//! \return if parameters are incorrect, or the value returned by PropertyChangeProc.
|
||||
//!
|
||||
//**********************************************************************************************
|
||||
OSStatus WCMRCoreAudioDeviceManager::StaticPropertyChangeProc (AudioHardwarePropertyID inPropertyID, void* inClientData)
|
||||
WCMRAudioDevice* WCMRCoreAudioDeviceManager::initNewCurrentDeviceImpl(const std::string & deviceName)
|
||||
{
|
||||
WCMRCoreAudioDeviceManager *pMyManager = (WCMRCoreAudioDeviceManager *)inClientData;
|
||||
destroyCurrentDeviceImpl();
|
||||
|
||||
if (pMyManager)
|
||||
return pMyManager->PropertyChangeProc (inPropertyID);
|
||||
|
||||
return 0;
|
||||
std::cout << "API::PortAudioDeviceManager::initNewCurrentDevice " << deviceName << std::endl;
|
||||
if (deviceName == m_NoneDevice->DeviceName() )
|
||||
{
|
||||
m_CurrentDevice = m_NoneDevice;
|
||||
return m_CurrentDevice;
|
||||
}
|
||||
|
||||
DeviceInfo devInfo;
|
||||
WTErr err = GetDeviceInfoByName(deviceName, devInfo);
|
||||
|
||||
if (eNoErr == err)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::cout << "API::PortAudioDeviceManager::Creating PA device: " << devInfo.m_DeviceId << ", Device Name: " << devInfo.m_DeviceName << std::endl;
|
||||
TRACE_MSG ("API::PortAudioDeviceManager::Creating PA device: " << devInfo.m_DeviceId << ", Device Name: " << devInfo.m_DeviceName);
|
||||
|
||||
m_CurrentDevice = new WCMRCoreAudioDevice (this, devInfo.m_DeviceId, m_UseMultithreading, m_bNoCopyAudioBuffer);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "Unabled to create PA Device: " << devInfo.m_DeviceId << std::endl;
|
||||
DEBUG_MSG ("Unabled to create PA Device: " << devInfo.m_DeviceId);
|
||||
}
|
||||
}
|
||||
|
||||
return m_CurrentDevice;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// WCMRCoreAudioDeviceManager::PropertyChangeProc
|
||||
//
|
||||
//! The property change listener for the Audio Device Manager. Currently we only listen for the
|
||||
//! device list change (device arrival/removal, and accordingly cause an update to the device list.
|
||||
//! Note that the actual update happens from the DoIdle() call to prevent multi-threading related issues.
|
||||
//!
|
||||
//! \param
|
||||
//!
|
||||
//! \return Nothing.
|
||||
//!
|
||||
//**********************************************************************************************
|
||||
OSStatus WCMRCoreAudioDeviceManager::PropertyChangeProc (AudioHardwarePropertyID inPropertyID)
|
||||
void WCMRCoreAudioDeviceManager::destroyCurrentDeviceImpl()
|
||||
{
|
||||
OSStatus retVal = 0;
|
||||
switch (inPropertyID)
|
||||
if (m_CurrentDevice != m_NoneDevice)
|
||||
delete m_CurrentDevice;
|
||||
|
||||
m_CurrentDevice = 0;
|
||||
}
|
||||
|
||||
|
||||
WTErr WCMRCoreAudioDeviceManager::getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates)
|
||||
{
|
||||
AUTO_FUNC_DEBUG;
|
||||
|
||||
WTErr retVal = eNoErr;
|
||||
OSStatus err = kAudioHardwareNoError;
|
||||
UInt32 propSize = 0;
|
||||
|
||||
sampleRates.clear();
|
||||
|
||||
//! 1. Get sample rate property size.
|
||||
err = AudioDeviceGetPropertyInfo(deviceId, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, NULL);
|
||||
if (err == kAudioHardwareNoError)
|
||||
{
|
||||
case kAudioHardwarePropertyDevices:
|
||||
m_UpdateDeviceListRequested++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
//! 2. Get property: cannels output.
|
||||
|
||||
// Allocate size accrding to the number of audio values
|
||||
int numRates = propSize / sizeof(AudioValueRange);
|
||||
AudioValueRange* supportedRates = new AudioValueRange[numRates];
|
||||
|
||||
// Get sampling rates from Audio device
|
||||
err = AudioDeviceGetProperty(deviceId, 0, 0, kAudioDevicePropertyAvailableNominalSampleRates, &propSize, supportedRates);
|
||||
if (err == kAudioHardwareNoError)
|
||||
{
|
||||
//! 3. Update sample rates
|
||||
|
||||
// now iterate through our standard SRs
|
||||
for(int ourSR=0; gAllSampleRates[ourSR] > 0; ourSR++)
|
||||
{
|
||||
//check to see if our SR is in the supported rates...
|
||||
for (int deviceSR = 0; deviceSR < numRates; deviceSR++)
|
||||
{
|
||||
if ((supportedRates[deviceSR].mMinimum <= gAllSampleRates[ourSR]) &&
|
||||
(supportedRates[deviceSR].mMaximum >= gAllSampleRates[ourSR]))
|
||||
{
|
||||
sampleRates.push_back ((int)gAllSampleRates[ourSR]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eCoreAudioFailed;
|
||||
DEBUG_MSG("Failed to get device Sample rates. Device Name: " << m_DeviceName.c_str());
|
||||
}
|
||||
|
||||
delete [] supportedRates;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eCoreAudioFailed;
|
||||
DEBUG_MSG("Failed to get device Sample rates property size. Device Name: " << m_DeviceName.c_str());
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//**********************************************************************************************
|
||||
// WCMRCoreAudioDeviceManager::remove_pattern
|
||||
//
|
||||
//! remove a substring from a given string
|
||||
//!
|
||||
//! \param original_str - original string
|
||||
//! \param pattern_str - pattern to find
|
||||
//! \param return_str - the return string - without the pattern substring
|
||||
//!
|
||||
//! \return Nothing.
|
||||
//!
|
||||
//**********************************************************************************************
|
||||
void WCMRCoreAudioDeviceManager::remove_pattern(const std::string& original_str, const std::string& pattern_str, std::string& return_str)
|
||||
{
|
||||
char *orig_c_str = new char[original_str.size() + 1];
|
||||
char* strSavePtr;
|
||||
strcpy(orig_c_str, original_str.c_str());
|
||||
char *p_splited_orig_str = strtok_r(orig_c_str," ", &strSavePtr);
|
||||
|
||||
std::ostringstream stream_str;
|
||||
while (p_splited_orig_str != 0)
|
||||
|
||||
WTErr WCMRCoreAudioDeviceManager::getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels)
|
||||
{
|
||||
AUTO_FUNC_DEBUG;
|
||||
WTErr retVal = eNoErr;
|
||||
OSStatus err = kAudioHardwareNoError;
|
||||
UInt32 propSize = 0;
|
||||
inputChannels = 0;
|
||||
|
||||
// 1. Get property cannels input size.
|
||||
err = AudioDeviceGetPropertyInfo (deviceId, 0, 1/* Input */, kAudioDevicePropertyStreamConfiguration, &propSize, NULL);
|
||||
if (err == kAudioHardwareNoError)
|
||||
{
|
||||
int cmp_res = strcmp(p_splited_orig_str, pattern_str.c_str()); // might need Ignore case ( stricmp OR strcasecmp)
|
||||
if ( cmp_res != 0)
|
||||
stream_str << p_splited_orig_str << " ";
|
||||
p_splited_orig_str = strtok_r(NULL," ", &strSavePtr);
|
||||
//! 2. Get property: cannels input.
|
||||
|
||||
// Allocate size according to the property size. Note that this is a variable sized struct...
|
||||
AudioBufferList *pStreamBuffers = (AudioBufferList *)malloc(propSize);
|
||||
|
||||
if (pStreamBuffers)
|
||||
{
|
||||
memset (pStreamBuffers, 0, propSize);
|
||||
|
||||
// Get the Input channels
|
||||
err = AudioDeviceGetProperty (deviceId, 0, 1/* Input */, kAudioDevicePropertyStreamConfiguration, &propSize, pStreamBuffers);
|
||||
if (err == kAudioHardwareNoError)
|
||||
{
|
||||
// Calculate the number of input channels
|
||||
for (UInt32 streamIndex = 0; streamIndex < pStreamBuffers->mNumberBuffers; streamIndex++)
|
||||
{
|
||||
inputChannels += pStreamBuffers->mBuffers[streamIndex].mNumberChannels;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eCoreAudioFailed;
|
||||
DEBUG_MSG("Failed to get device Input channels. Device Name: " << m_DeviceName.c_str());
|
||||
}
|
||||
|
||||
free (pStreamBuffers);
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eMemOutOfMemory;
|
||||
DEBUG_MSG("Faild to allocate memory. Device Name: " << m_DeviceName.c_str());
|
||||
}
|
||||
}
|
||||
delete[] orig_c_str;
|
||||
return_str = stream_str.str();
|
||||
else
|
||||
{
|
||||
retVal = eCoreAudioFailed;
|
||||
DEBUG_MSG("Failed to get device Input channels property size. Device Name: " << m_DeviceName.c_str());
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// WCMRCoreAudioDeviceManager::UpdateDeviceList_Private
|
||||
//
|
||||
//! Updates the list of devices maintained by the manager. If devices have gone away, they are removed
|
||||
//! if new devices have been connected, they are added to the list.
|
||||
//!
|
||||
//! \param none
|
||||
//!
|
||||
//! \return eNoErr on success, an error code on failure.
|
||||
//!
|
||||
//**********************************************************************************************
|
||||
WTErr WCMRCoreAudioDeviceManager::UpdateDeviceList_Private()
|
||||
WTErr WCMRCoreAudioDeviceManager::getDeviceMaxOutputChannels(DeviceID deviceId, unsigned int& outputChannels)
|
||||
{
|
||||
AUTO_FUNC_DEBUG;
|
||||
|
||||
WTErr retVal = eNoErr;
|
||||
OSStatus err = kAudioHardwareNoError;
|
||||
UInt32 propSize = 0;
|
||||
outputChannels = 0;
|
||||
|
||||
//! 1. Get property cannels output size.
|
||||
err = AudioDeviceGetPropertyInfo (deviceId, 0, 0/* Output */, kAudioDevicePropertyStreamConfiguration, &propSize, NULL);
|
||||
if (err == kAudioHardwareNoError)
|
||||
{
|
||||
//! 2. Get property: cannels output.
|
||||
|
||||
// Allocate size according to the property size. Note that this is a variable sized struct...
|
||||
AudioBufferList *pStreamBuffers = (AudioBufferList *)malloc(propSize);
|
||||
if (pStreamBuffers)
|
||||
{
|
||||
memset (pStreamBuffers, 0, propSize);
|
||||
|
||||
// Get the Output channels
|
||||
err = AudioDeviceGetProperty (deviceId, 0, 0/* Output */, kAudioDevicePropertyStreamConfiguration, &propSize, pStreamBuffers);
|
||||
if (err == kAudioHardwareNoError)
|
||||
{
|
||||
// Calculate the number of output channels
|
||||
for (UInt32 streamIndex = 0; streamIndex < pStreamBuffers->mNumberBuffers; streamIndex++)
|
||||
{
|
||||
outputChannels += pStreamBuffers->mBuffers[streamIndex].mNumberChannels;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eCoreAudioFailed;
|
||||
DEBUG_MSG("Failed to get device Output channels. Device Name: " << m_DeviceName.c_str());
|
||||
}
|
||||
free (pStreamBuffers);
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eMemOutOfMemory;
|
||||
DEBUG_MSG("Faild to allocate memory. Device Name: " << m_DeviceName.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eCoreAudioFailed;
|
||||
DEBUG_MSG("Failed to get device Output channels property size. Device Name: " << m_DeviceName.c_str());
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
WTErr WCMRCoreAudioDeviceManager::generateDeviceListImpl()
|
||||
{
|
||||
AUTO_FUNC_DEBUG;
|
||||
|
||||
// lock the list first
|
||||
wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
|
||||
m_DeviceInfoVec.clear();
|
||||
|
||||
//First, get info from None device which is always present
|
||||
if (m_NoneDevice)
|
||||
{
|
||||
DeviceInfo *pDevInfo = new DeviceInfo(NONE_DEVICE_ID, m_NoneDevice->DeviceName() );
|
||||
pDevInfo->m_AvailableSampleRates = m_NoneDevice->SamplingRates();
|
||||
m_DeviceInfoVec.push_back(pDevInfo);
|
||||
}
|
||||
|
||||
WTErr retVal = eNoErr;
|
||||
OSStatus osErr = noErr;
|
||||
AudioDeviceID* deviceIDs = 0;
|
||||
size_t reportedDeviceIndex = 0;
|
||||
|
||||
openlog("WCMRCoreAudioDeviceManager", LOG_PID | LOG_CONS, LOG_USER);
|
||||
|
||||
try
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// Define 2 vectors for input and output - only for eMatchedDuplexDevices case
|
||||
WCMRAudioDeviceList adOnlyIn;
|
||||
WCMRAudioDeviceList adOnlyOut;
|
||||
|
||||
//Get device count...
|
||||
UInt32 propSize = 0;
|
||||
osErr = AudioHardwareGetPropertyInfo (kAudioHardwarePropertyDevices, &propSize, NULL);
|
||||
ASSERT_ERROR(osErr, "AudioHardwareGetProperty 1");
|
||||
if (WUIsError(osErr))
|
||||
throw osErr;
|
||||
|
||||
|
||||
size_t numDevices = propSize / sizeof (AudioDeviceID);
|
||||
deviceIDs = new AudioDeviceID[numDevices];
|
||||
|
||||
|
||||
//retrieve the device IDs
|
||||
propSize = numDevices * sizeof (AudioDeviceID);
|
||||
osErr = AudioHardwareGetProperty (kAudioHardwarePropertyDevices, &propSize, deviceIDs);
|
||||
ASSERT_ERROR(osErr, "Error while getting audio devices: AudioHardwareGetProperty 2");
|
||||
if (WUIsError(osErr))
|
||||
throw osErr;
|
||||
|
||||
//first go through our list of devices, remove the ones that are no longer present...
|
||||
std::vector<WCMRAudioDevice*>::iterator deviceIter;
|
||||
for (deviceIter = m_Devices.begin(); deviceIter != m_Devices.end(); /*This is purposefully blank*/)
|
||||
{
|
||||
WCMRCoreAudioDevice *pDeviceToWorkUpon = dynamic_cast<WCMRCoreAudioDevice *>(*deviceIter);
|
||||
|
||||
//it's possible that the device is actually not a core audio device - perhaps a none device...
|
||||
if (!pDeviceToWorkUpon)
|
||||
{
|
||||
deviceIter++;
|
||||
continue;
|
||||
}
|
||||
|
||||
AudioDeviceID myDeviceID = pDeviceToWorkUpon->DeviceID();
|
||||
bool deviceFound = false;
|
||||
for (reportedDeviceIndex = 0; reportedDeviceIndex < numDevices; reportedDeviceIndex++)
|
||||
{
|
||||
if (myDeviceID == deviceIDs[reportedDeviceIndex])
|
||||
{
|
||||
deviceFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!deviceFound)
|
||||
//now add the ones that are not there...
|
||||
for (size_t deviceIndex = 0; deviceIndex < numDevices; deviceIndex++)
|
||||
{
|
||||
DeviceInfo* pDevInfo = 0;
|
||||
|
||||
//Get device name and create new DeviceInfo entry
|
||||
//Get property name size.
|
||||
osErr = AudioDeviceGetPropertyInfo(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL);
|
||||
if (osErr == kAudioHardwareNoError)
|
||||
{
|
||||
//it's no longer there, need to remove it!
|
||||
WCMRAudioDevice *pTheDeviceToErase = *deviceIter;
|
||||
deviceIter = m_Devices.erase (deviceIter);
|
||||
if (pTheDeviceToErase->Active())
|
||||
//Get property: name.
|
||||
char* deviceName = new char[propSize];
|
||||
osErr = AudioDeviceGetProperty(deviceIDs[deviceIndex], 0, 0, kAudioDevicePropertyDeviceName, &propSize, deviceName);
|
||||
if (osErr == kAudioHardwareNoError)
|
||||
{
|
||||
NotifyClient (WCMRAudioDeviceManagerClient::DeviceConnectionLost);
|
||||
pDevInfo = new DeviceInfo(deviceIDs[deviceIndex], deviceName);
|
||||
}
|
||||
SAFE_RELEASE (pTheDeviceToErase);
|
||||
else
|
||||
{
|
||||
retVal = eCoreAudioFailed;
|
||||
DEBUG_MSG("Failed to get device name. Device ID: " << m_DeviceID);
|
||||
}
|
||||
|
||||
delete [] deviceName;
|
||||
}
|
||||
else
|
||||
deviceIter++;
|
||||
}
|
||||
|
||||
//now add the ones that are not there...
|
||||
for (reportedDeviceIndex = 0; reportedDeviceIndex < numDevices; reportedDeviceIndex++)
|
||||
{
|
||||
bool deviceFound = false;
|
||||
for (deviceIter = m_Devices.begin(); deviceIter != m_Devices.end(); deviceIter++)
|
||||
{
|
||||
WCMRCoreAudioDevice *pDeviceToWorkUpon = dynamic_cast<WCMRCoreAudioDevice *>(*deviceIter);
|
||||
//it's possible that the device is actually not a core audio device - perhaps a none device...
|
||||
if (!pDeviceToWorkUpon)
|
||||
continue;
|
||||
|
||||
if (pDeviceToWorkUpon->DeviceID() == deviceIDs[reportedDeviceIndex])
|
||||
{
|
||||
deviceFound = true;
|
||||
break;
|
||||
}
|
||||
retVal = eCoreAudioFailed;
|
||||
DEBUG_MSG("Failed to get device name property size. Device ID: " << m_DeviceID);
|
||||
}
|
||||
|
||||
if (!deviceFound)
|
||||
|
||||
if (pDevInfo)
|
||||
{
|
||||
//add it to our list...
|
||||
//build a device object...
|
||||
WCMRCoreAudioDevice *pNewDevice = new WCMRCoreAudioDevice (this, deviceIDs[reportedDeviceIndex], m_UseMultithreading, m_bNoCopyAudioBuffer);
|
||||
bool bDeleteNewDevice = true;
|
||||
//Retrieve all the information we need for the device
|
||||
WTErr wErr = eNoErr;
|
||||
|
||||
if (pNewDevice)
|
||||
//Get available sample rates for the device
|
||||
std::vector<int> availableSampleRates;
|
||||
wErr = getDeviceAvailableSampleRates(pDevInfo->m_DeviceId, availableSampleRates);
|
||||
|
||||
if (wErr != eNoErr)
|
||||
{
|
||||
DEBUG_MSG ("Failed to get device available sample rates. Device ID: " << m_DeviceID);
|
||||
delete pDevInfo;
|
||||
continue; //proceed to the next device
|
||||
}
|
||||
|
||||
pDevInfo->m_AvailableSampleRates = availableSampleRates;
|
||||
|
||||
//Get max input channels
|
||||
uint32 maxInputChannels;
|
||||
wErr = getDeviceMaxInputChannels(pDevInfo->m_DeviceId, maxInputChannels);
|
||||
|
||||
if (wErr != eNoErr)
|
||||
{
|
||||
DEBUG_MSG ("Failed to get device max input channels count. Device ID: " << m_DeviceID);
|
||||
delete pDevInfo;
|
||||
continue; //proceed to the next device
|
||||
}
|
||||
|
||||
pDevInfo->m_MaxInputChannels = maxInputChannels;
|
||||
|
||||
//Get max output channels
|
||||
uint32 maxOutputChannels;
|
||||
wErr = getDeviceMaxOutputChannels(pDevInfo->m_DeviceId, maxOutputChannels);
|
||||
|
||||
if (wErr != eNoErr)
|
||||
{
|
||||
DEBUG_MSG ("Failed to get device max output channels count. Device ID: " << m_DeviceID);
|
||||
delete pDevInfo;
|
||||
continue; //proceed to the next device
|
||||
}
|
||||
|
||||
pDevInfo->m_MaxOutputChannels = maxOutputChannels;
|
||||
|
||||
//Now check if this device is acceptable according to current input/output settings
|
||||
bool bRejectDevice = false;
|
||||
switch(m_eAudioDeviceFilter)
|
||||
{
|
||||
|
||||
// Don't delete the new device by default, since most cases use it
|
||||
bDeleteNewDevice = false;
|
||||
|
||||
// Insert the new device to the device list according to its enum
|
||||
switch(m_eAudioDeviceFilter)
|
||||
{
|
||||
case eInputOnlyDevices:
|
||||
if ((int) pNewDevice->InputChannels().size() != 0)
|
||||
if (pDevInfo->m_MaxInputChannels != 0)
|
||||
{
|
||||
m_Devices.push_back (pNewDevice);
|
||||
m_DeviceInfoVec.push_back(pDevInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete unnecesarry device
|
||||
bDeleteNewDevice = true;
|
||||
bRejectDevice = true;
|
||||
}
|
||||
break;
|
||||
case eOutputOnlyDevices:
|
||||
if ((int) pNewDevice->OutputChannels().size() != 0)
|
||||
if (pDevInfo->m_MaxOutputChannels != 0)
|
||||
{
|
||||
m_Devices.push_back (pNewDevice);
|
||||
m_DeviceInfoVec.push_back(pDevInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete unnecesarry device
|
||||
bDeleteNewDevice = true;
|
||||
bRejectDevice = true;
|
||||
}
|
||||
break;
|
||||
case eFullDuplexDevices:
|
||||
if ((int) pNewDevice->InputChannels().size() != 0 && (int) pNewDevice->OutputChannels().size() != 0)
|
||||
if (pDevInfo->m_MaxInputChannels != 0 && pDevInfo->m_MaxOutputChannels != 0)
|
||||
{
|
||||
m_Devices.push_back (pNewDevice);
|
||||
m_DeviceInfoVec.push_back(pDevInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delete unnecesarry device
|
||||
bDeleteNewDevice = true;
|
||||
bRejectDevice = true;
|
||||
}
|
||||
break;
|
||||
case eAllDevices:
|
||||
default:
|
||||
m_Devices.push_back (pNewDevice);
|
||||
m_DeviceInfoVec.push_back(pDevInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(bDeleteNewDevice)
|
||||
if(bRejectDevice)
|
||||
{
|
||||
syslog (LOG_NOTICE, "%s rejected, In Channels = %d, Out Channels = %d\n",
|
||||
pNewDevice->DeviceName().c_str(), (int) pNewDevice->InputChannels().size(),
|
||||
(int) pNewDevice->OutputChannels().size());
|
||||
pDevInfo->m_DeviceName.c_str(), pDevInfo->m_MaxInputChannels, pDevInfo->m_MaxOutputChannels);
|
||||
// In case of Input and Output both channels being Zero, we will release memory; since we created CoreAudioDevice but we are Not adding it in list.
|
||||
SAFE_RELEASE(pNewDevice);
|
||||
delete pDevInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//If no devices were found, that's not a good thing!
|
||||
if (m_Devices.empty())
|
||||
if (m_DeviceInfoVec.empty())
|
||||
{
|
||||
DEBUG_MSG ("No matching CoreAudio devices were found\n");
|
||||
}
|
||||
|
||||
|
||||
m_UpdateDeviceListRequested = m_UpdateDeviceListProcessed = 0;
|
||||
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (WUNoError(retVal))
|
||||
retVal = eCoreAudioFailed;
|
||||
}
|
||||
|
||||
safe_delete_array(deviceIDs);
|
||||
|
||||
delete[] deviceIDs;
|
||||
closelog();
|
||||
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**********************************************************************************************
|
||||
// WCMRCoreAudioDeviceManager::DoIdle
|
||||
//
|
||||
//! Used for idle time processing. This calls each device's DoIdle so that it can perform it's own idle processing.
|
||||
//! Also, if a device list change is detected, it updates the device list.
|
||||
//!
|
||||
//! \param none
|
||||
//!
|
||||
//! \return noErr if no devices have returned an error. An error code if any of the devices returned error.
|
||||
//!
|
||||
//**********************************************************************************************
|
||||
WTErr WCMRCoreAudioDeviceManager::DoIdle()
|
||||
WTErr WCMRCoreAudioDeviceManager::updateDeviceListImpl()
|
||||
{
|
||||
//WTErr retVal = eNoErr;
|
||||
wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
|
||||
WTErr err = generateDeviceListImpl();
|
||||
|
||||
if (eNoErr != err)
|
||||
{
|
||||
//wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
|
||||
|
||||
//If there's something specific to CoreAudio manager idle handling do it here...
|
||||
if (m_UpdateDeviceListRequested != m_UpdateDeviceListProcessed)
|
||||
std::cout << "API::PortAudioDeviceManager::updateDeviceListImpl: Device list update error: "<< err << std::endl;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (m_CurrentDevice)
|
||||
{
|
||||
// if we have device initialized we should find out if this device is still connected
|
||||
DeviceInfo devInfo;
|
||||
WTErr deviceLookUpErr = GetDeviceInfoByName(m_CurrentDevice->DeviceName(), devInfo );
|
||||
|
||||
if (eNoErr != deviceLookUpErr)
|
||||
{
|
||||
m_UpdateDeviceListProcessed = m_UpdateDeviceListRequested;
|
||||
UpdateDeviceList_Private();
|
||||
NotifyClient (WCMRAudioDeviceManagerClient::DeviceListChanged);
|
||||
NotifyClient (WCMRAudioDeviceManagerClient::IODeviceDisconnected);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
//Note that the superclass is going to call all the devices' DoIdle() anyway...
|
||||
return (WCMRAudioDeviceManager::DoIdle());
|
||||
}
|
||||
|
||||
NotifyClient (WCMRAudioDeviceManagerClient::DeviceListChanged);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
WTErr WCMRCoreAudioDeviceManager::getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const
|
||||
{
|
||||
AUTO_FUNC_DEBUG;
|
||||
|
||||
WTErr retVal = eNoErr;
|
||||
OSStatus err = kAudioHardwareNoError;
|
||||
UInt32 propSize = 0;
|
||||
|
||||
bufferSizes.clear();
|
||||
|
||||
//first check if the request has been made for None device
|
||||
if (deviceName == m_NoneDevice->DeviceName() )
|
||||
{
|
||||
bufferSizes = m_NoneDevice->BufferSizes();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
DeviceInfo devInfo;
|
||||
retVal = GetDeviceInfoByName(deviceName, devInfo);
|
||||
|
||||
if (eNoErr == retVal)
|
||||
{
|
||||
// 1. Get buffer size range
|
||||
AudioValueRange bufferSizesRange;
|
||||
propSize = sizeof (AudioValueRange);
|
||||
err = AudioDeviceGetProperty (devInfo.m_DeviceId, 0, 0, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &bufferSizesRange);
|
||||
if(err == kAudioHardwareNoError)
|
||||
{
|
||||
// 2. Run on all ranges and add them to the list
|
||||
for(int bsize=0; gAllBufferSizes[bsize] > 0; bsize++)
|
||||
{
|
||||
if ((bufferSizesRange.mMinimum <= gAllBufferSizes[bsize]) && (bufferSizesRange.mMaximum >= gAllBufferSizes[bsize]))
|
||||
{
|
||||
bufferSizes.push_back (gAllBufferSizes[bsize]);
|
||||
}
|
||||
}
|
||||
|
||||
//if we didn't get a single hit, let's simply add the min. and the max...
|
||||
if (bufferSizes.empty())
|
||||
{
|
||||
bufferSizes.push_back ((int)bufferSizesRange.mMinimum);
|
||||
bufferSizes.push_back ((int)bufferSizesRange.mMaximum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eCoreAudioFailed;
|
||||
DEBUG_MSG("Failed to get device buffer sizes range. Device Name: " << m_DeviceName.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = eRMResNotFound;
|
||||
std::cout << "API::PortAudioDeviceManager::GetBufferSizes: Device not found: "<< deviceName << std::endl;
|
||||
}
|
||||
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
OSStatus WCMRCoreAudioDeviceManager::DevicePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData)
|
||||
{
|
||||
switch (inPropertyID)
|
||||
{
|
||||
case kAudioHardwarePropertyDevices:
|
||||
{
|
||||
WCMRCoreAudioDeviceManager* pManager = (WCMRCoreAudioDeviceManager*)inClientData;
|
||||
if (pManager)
|
||||
pManager->updateDeviceListImpl();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,6 @@
|
|||
/*
|
||||
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 WCMRCoreAudioDeviceManager.h
|
||||
//!
|
||||
|
|
@ -138,7 +121,7 @@ protected:
|
|||
uint32_t m_NextSampleToUse;
|
||||
#endif //WV_USE_TONE_GEN
|
||||
|
||||
WTErr UpdateDeviceInfo (bool updateSRSupported, bool updateBufferSizes);
|
||||
WTErr UpdateDeviceInfo ();
|
||||
WTErr UpdateDeviceName();
|
||||
WTErr UpdateDeviceInputs();
|
||||
WTErr UpdateDeviceOutputs();
|
||||
|
|
@ -181,40 +164,28 @@ class WCMRCoreAudioDeviceManager : public WCMRAudioDeviceManager
|
|||
public:
|
||||
|
||||
WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
|
||||
bool useMultithreading = true, eCABS_Method eCABS_method = eCABS_Simple, bool bNocopy = false); ///< constructor
|
||||
bool useMultithreading = true, bool bNocopy = false); ///< constructor
|
||||
virtual ~WCMRCoreAudioDeviceManager(void); ///< Destructor
|
||||
|
||||
|
||||
virtual WTErr UpdateDeviceList() //has to be overridden!
|
||||
{
|
||||
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
|
||||
return UpdateDeviceList_Private();
|
||||
}
|
||||
|
||||
virtual eCABS_Method GetBufferSizeMethod()
|
||||
{
|
||||
//wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
|
||||
return GetBufferSizeMethod_Private();
|
||||
}
|
||||
|
||||
virtual WTErr DoIdle();
|
||||
|
||||
private:
|
||||
WTErr UpdateDeviceList_Private();
|
||||
eCABS_Method GetBufferSizeMethod_Private() { return m_eCABS_Method; }
|
||||
|
||||
protected:
|
||||
|
||||
int m_UpdateDeviceListRequested; ///< Number of times device list change has been detected.
|
||||
int m_UpdateDeviceListProcessed; ///< Number of times device list change has been processed.
|
||||
static OSStatus DevicePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData);
|
||||
|
||||
virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName);
|
||||
virtual void destroyCurrentDeviceImpl();
|
||||
virtual WTErr generateDeviceListImpl();
|
||||
virtual WTErr updateDeviceListImpl();
|
||||
virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const;
|
||||
|
||||
bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
|
||||
bool m_bNoCopyAudioBuffer;
|
||||
eCABS_Method m_eCABS_Method; // Type of core audio buffer size list method
|
||||
|
||||
static OSStatus StaticPropertyChangeProc (AudioHardwarePropertyID inPropertyID, void* inClientData);
|
||||
OSStatus PropertyChangeProc (AudioHardwarePropertyID inPropertyID);
|
||||
|
||||
void remove_pattern(const std::string& original_str, const std::string& pattern_str, std::string& return_str);
|
||||
|
||||
private:
|
||||
// helper functions for this class only
|
||||
WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
|
||||
WTErr getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels);
|
||||
WTErr getDeviceMaxOutputChannels(DeviceID deviceId, unsigned int& outputChannels);
|
||||
|
||||
WCMRAudioDevice* m_NoneDevice;
|
||||
};
|
||||
|
||||
#endif //#ifndef __WCMRCoreAudioDeviceManager_h_
|
||||
|
|
|
|||
|
|
@ -1,23 +1,6 @@
|
|||
/*
|
||||
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 WCMRNativeAudio.cpp
|
||||
//!
|
||||
|
|
@ -136,6 +119,12 @@ WTErr WCMRNativeAudioNoneDevice::SetCurrentBufferSize (int newSize)
|
|||
}
|
||||
|
||||
|
||||
WTErr WCMRNativeAudioNoneDevice::UpdateDeviceInfo ()
|
||||
{
|
||||
return eNoErr;
|
||||
}
|
||||
|
||||
|
||||
WTErr WCMRNativeAudioNoneDevice::SetStreaming (bool newState)
|
||||
{
|
||||
if (Streaming() == newState)
|
||||
|
|
@ -144,7 +133,8 @@ WTErr WCMRNativeAudioNoneDevice::SetStreaming (bool newState)
|
|||
}
|
||||
|
||||
WCMRAudioDevice::SetStreaming(newState);
|
||||
if(Streaming())
|
||||
|
||||
if (Streaming())
|
||||
{
|
||||
if (m_SilenceThread)
|
||||
std::cerr << "\t\t\t\t\t !!!!!!!!!!!!!!! Warning: the inactive NONE-DEVICE was streaming!" << std::endl;
|
||||
|
|
|
|||
|
|
@ -1,23 +1,6 @@
|
|||
/*
|
||||
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 WCMRNativeAudio.h
|
||||
//!
|
||||
|
|
@ -42,9 +25,10 @@ class WCMRNativeAudioDevice : public WCMRAudioDevice
|
|||
{
|
||||
public:
|
||||
|
||||
WCMRNativeAudioDevice (WCMRAudioDeviceManager *pManager, bool useMultithreading = true, bool bNoCopy = false) : WCMRAudioDevice (pManager),
|
||||
m_UseMultithreading (useMultithreading),
|
||||
m_bNoCopyAudioBuffer(bNoCopy)
|
||||
WCMRNativeAudioDevice (WCMRAudioDeviceManager *pManager, bool useMultithreading = true, bool bNoCopy = false) :
|
||||
WCMRAudioDevice (pManager)
|
||||
, m_UseMultithreading (useMultithreading)
|
||||
, m_bNoCopyAudioBuffer(bNoCopy)
|
||||
{}
|
||||
virtual ~WCMRNativeAudioDevice () {}
|
||||
|
||||
|
|
@ -52,7 +36,6 @@ protected:
|
|||
bool m_UseMultithreading;
|
||||
bool m_bNoCopyAudioBuffer; ///< This flag determines whether the audio callback performs a copy of audio, or the source/sink perform the copy. It should be true to let source/sink do the copies.
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -65,6 +48,7 @@ public:
|
|||
virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
|
||||
virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
|
||||
virtual WTErr SetCurrentBufferSize (int newSize);///<Change Current Buffer Size : This is a requset, might not be successful at run time!
|
||||
virtual WTErr UpdateDeviceInfo ();
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -75,11 +59,11 @@ private:
|
|||
#else
|
||||
inline void _usleep(uint64_t usec) { ::usleep(usec); }
|
||||
#endif
|
||||
static const size_t __m_NumInputChannels = 32;
|
||||
static const size_t __m_NumOutputChannels = 32;
|
||||
static const size_t __m_NumInputChannels = 0;
|
||||
static const size_t __m_NumOutputChannels = 0;
|
||||
pthread_t m_SilenceThread;
|
||||
float *_m_inputBuffer;
|
||||
float *_m_outputBuffer;
|
||||
float *_m_inputBuffer;
|
||||
float *_m_outputBuffer;
|
||||
static uint64_t __get_time_nanos ();
|
||||
#if defined (_WINDOWS)
|
||||
HANDLE _waitableTimerForUsleep;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,160 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
|
||||
//
|
||||
//! \file WCMRPortAudioDeviceManager.h
|
||||
//!
|
||||
//! WCMRPortAudioDeviceManager and related class declarations
|
||||
//!
|
||||
//---------------------------------------------------------------------------------*/
|
||||
#ifndef __WCMRPortAudioDeviceManager_h_
|
||||
#define __WCMRPortAudioDeviceManager_h_
|
||||
|
||||
#include "WCMRAudioDeviceManager.h"
|
||||
#include "WCMRNativeAudio.h"
|
||||
#include "portaudio.h"
|
||||
|
||||
//forward decl.
|
||||
class WCMRPortAudioDeviceManager;
|
||||
|
||||
//! Manages a port audio device, providing information
|
||||
//! about the device, and managing audio callbacks.
|
||||
class WCMRPortAudioDevice : public WCMRNativeAudioDevice
|
||||
{
|
||||
public:
|
||||
|
||||
WCMRPortAudioDevice (WCMRPortAudioDeviceManager *pManager, unsigned int deviceID, bool useMultiThreading = true, bool bNoCopy = false);///<Constructor
|
||||
virtual ~WCMRPortAudioDevice ();///<Destructor
|
||||
|
||||
virtual int CurrentSamplingRate(); ///<Current Sampling rate.?
|
||||
virtual WTErr SetCurrentSamplingRate(int newRate);///<Change Current Sampling Rate : This is a requset, might not be successful at run time!
|
||||
|
||||
virtual int CurrentBufferSize();///<Current Buffer Size.? - note that this may change with change in sampling rate.
|
||||
virtual WTErr SetCurrentBufferSize (int newSize);///<Change Current Buffer Size : This is a requset, might not be successful at run time!
|
||||
|
||||
virtual ConnectionStates ConnectionStatus();///< Connection Status - device available, gone, disconnected
|
||||
|
||||
virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
|
||||
|
||||
virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
|
||||
|
||||
virtual WTErr SetMonitorChannels (int leftChannel, int rightChannel);///<Set monitor channels. - optional, will not be available with AG
|
||||
virtual WTErr SetMonitorGain (float newGain);///<Set monitor gain. - optional, will not be available with AG
|
||||
|
||||
virtual WTErr ShowConfigPanel (void *pParam);///< Show Control Panel - in case of ASIO this will work only with Active device!
|
||||
|
||||
virtual int AudioCallback (const float *pInputBuffer, float *pOutputBuffer, unsigned long framesPerBuffe, bool dropsDetectedr);
|
||||
|
||||
virtual WTErr UpdateDeviceInfo ();
|
||||
|
||||
virtual WTErr ResetDevice();
|
||||
|
||||
#ifdef _WINDOWS
|
||||
static long StaticASIOMessageHook (void *pRefCon, long selector, long value, void* message, double* opt);
|
||||
long ASIOMessageHook (long selector, long value, void* message, double* opt);
|
||||
#endif //_WINDOWS
|
||||
|
||||
protected:
|
||||
static DWORD WINAPI __DoIdle__(LPVOID lpThreadParameter);
|
||||
|
||||
// Methods which are executed by device processing thread
|
||||
WTErr DoIdle();///<Do Idle Processing
|
||||
void initDevice();
|
||||
void terminateDevice();
|
||||
void updateDeviceInfo(bool callerIsWaiting = false);
|
||||
void activateDevice(bool callerIsWaiting = false);
|
||||
void deactivateDevice(bool callerIsWaiting = false);
|
||||
void startStreaming(bool callerIsWaiting = false);
|
||||
void stopStreaming(bool callerIsWaiting = false);
|
||||
void resetDevice (bool callerIsWaiting = false);///<Reset device - close and reopen stream, update device information!
|
||||
|
||||
PaError testStateValidness(int sampleRate, int bufferSize);
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
static int TheCallback (const void *pInputBuffer, void *pOutputBuffer, unsigned long framesPerBuffer,
|
||||
const PaStreamCallbackTimeInfo* /*pTimeInfo*/, PaStreamCallbackFlags /*statusFlags*/, void *pUserData );
|
||||
|
||||
unsigned int m_DeviceID; ///< The PA device id
|
||||
PaStream* m_PortAudioStream; ///< Port audio stream, when the device is active!
|
||||
bool m_StopRequested; ///< should be set to true when want to stop, set to false otherwise.
|
||||
const float *m_pInputData; ///< This is what came in with the most recent callback.
|
||||
int m_SampleCounter; ///< The current running sample counter, updated by the audio callback.
|
||||
int m_SampleCountAtLastIdle;
|
||||
|
||||
int m_DropsDetected; ///< Number of times audio drops have been detected so far.
|
||||
int m_DropsReported; ///< Number of times audio drops have been reported so far to the client.
|
||||
bool m_IgnoreThisDrop; ///< Allows disregarding the first drop
|
||||
|
||||
int m_BufferSizeChangeRequested;
|
||||
int m_BufferSizeChangeReported;
|
||||
int m_ResetRequested;
|
||||
int m_ResetReported;
|
||||
int m_ResyncRequested;
|
||||
int m_ResyncReported;
|
||||
|
||||
HANDLE m_hDeviceProcessingThread;
|
||||
DWORD m_DeviceProcessingThreadID;
|
||||
|
||||
///< Backend request events
|
||||
HANDLE m_hResetRequestedEvent;
|
||||
HANDLE m_hResetDone;
|
||||
|
||||
HANDLE m_hUpdateDeviceInfoRequestedEvent;
|
||||
HANDLE m_hUpdateDeviceInfoDone;
|
||||
|
||||
HANDLE m_hActivateRequestedEvent;
|
||||
HANDLE m_hActivationDone;
|
||||
|
||||
HANDLE m_hDeActivateRequestedEvent;
|
||||
HANDLE m_hDeActivationDone;
|
||||
|
||||
HANDLE m_hStartStreamingRequestedEvent;
|
||||
HANDLE m_hStartStreamingDone;
|
||||
|
||||
HANDLE m_hStopStreamingRequestedEvent;
|
||||
HANDLE m_hStopStreamingDone;
|
||||
/////////////////////////
|
||||
|
||||
///< Device request events
|
||||
HANDLE m_hResetFromDevRequestedEvent;
|
||||
HANDLE m_hBufferSizeChangedEvent;
|
||||
HANDLE m_hSampleRateChangedEvent;
|
||||
/////////////////////////////
|
||||
|
||||
///< Sync events
|
||||
HANDLE m_hDeviceInitialized;
|
||||
HANDLE m_hExitIdleThread;
|
||||
|
||||
//Should be set if the device connection status is "DeviceErrors"
|
||||
WTErr m_lastErr;
|
||||
};
|
||||
|
||||
//! WCMRPortAudioDeviceManager
|
||||
/*! The PortAudio Device Manager class */
|
||||
class WCMRPortAudioDeviceManager : public WCMRAudioDeviceManager
|
||||
{
|
||||
public:
|
||||
WCMRPortAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
|
||||
bool useMultithreading = true, bool bNocopy = false); ///< constructor
|
||||
|
||||
virtual ~WCMRPortAudioDeviceManager(void); ///< destructor
|
||||
|
||||
protected:
|
||||
|
||||
virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName);
|
||||
virtual void destroyCurrentDeviceImpl();
|
||||
virtual WTErr generateDeviceListImpl(); // use this in derived class to fill device list
|
||||
virtual WTErr updateDeviceListImpl() {return eNoErr; } // not supported
|
||||
virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& buffers) const;
|
||||
|
||||
bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
|
||||
bool m_bNoCopyAudioBuffer;
|
||||
|
||||
private:
|
||||
// helper functions for this class only
|
||||
WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
|
||||
|
||||
WCMRAudioDevice* m_NoneDevice;
|
||||
};
|
||||
|
||||
#endif //#ifndef __WCMRPortAudioDeviceManager_h_
|
||||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __MinMaxUtilities_h__
|
||||
#define __MinMaxUtilities_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,87 +1,69 @@
|
|||
#ifdef _WINDOWS
|
||||
#include "IncludeWindows.h"
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__MACOS__)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "UMicroseconds.h"
|
||||
|
||||
namespace wvNS {
|
||||
UMicroseconds& UMicroseconds::ReadTime()
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
LARGE_INTEGER Frequency, Count ;
|
||||
|
||||
QueryPerformanceFrequency(&Frequency) ;
|
||||
QueryPerformanceCounter(&Count);
|
||||
theTime = uint64_t((Count.QuadPart * 1000000.0 / Frequency.QuadPart));
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__MACOS__)
|
||||
// Mac code replaced by posix calls, to reduce Carbon dependency.
|
||||
timeval buf;
|
||||
|
||||
gettimeofday(&buf,NULL);
|
||||
|
||||
// micro sec
|
||||
theTime = uint64_t(buf.tv_sec) * 1000*1000 + buf.tv_usec;
|
||||
#endif
|
||||
|
||||
return *this;
|
||||
}
|
||||
/*
|
||||
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.
|
||||
|
||||
Removed in favor of the posix implementation.
|
||||
#ifdef __MACOS__
|
||||
uint32_t UMicroseconds::hi() {return reinterpret_cast<UnsignedWide*>(&theTime)->hi;}
|
||||
uint32_t UMicroseconds::lo() {return reinterpret_cast<UnsignedWide*>(&theTime)->lo;}
|
||||
#endif
|
||||
*/
|
||||
#ifdef _WINDOWS
|
||||
#include "IncludeWindows.h"
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__MACOS__)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "UMicroseconds.h"
|
||||
|
||||
namespace wvNS {
|
||||
UMicroseconds& UMicroseconds::ReadTime()
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
LARGE_INTEGER Frequency, Count ;
|
||||
|
||||
QueryPerformanceFrequency(&Frequency) ;
|
||||
QueryPerformanceCounter(&Count);
|
||||
theTime = uint64_t((Count.QuadPart * 1000000.0 / Frequency.QuadPart));
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__MACOS__)
|
||||
// Mac code replaced by posix calls, to reduce Carbon dependency.
|
||||
timeval buf;
|
||||
|
||||
gettimeofday(&buf,NULL);
|
||||
|
||||
// micro sec
|
||||
theTime = uint64_t(buf.tv_sec) * 1000*1000 + buf.tv_usec;
|
||||
#endif
|
||||
|
||||
return *this;
|
||||
}
|
||||
/*
|
||||
Removed in favor of the posix implementation.
|
||||
#ifdef __MACOS__
|
||||
uint32_t UMicroseconds::hi() {return reinterpret_cast<UnsignedWide*>(&theTime)->hi;}
|
||||
uint32_t UMicroseconds::lo() {return reinterpret_cast<UnsignedWide*>(&theTime)->lo;}
|
||||
#endif
|
||||
*/
|
||||
void UMicrosecondsAccumulator::Start()
|
||||
{
|
||||
m_start_time.ReadTime();
|
||||
}
|
||||
|
||||
void UMicrosecondsAccumulator::Stop()
|
||||
{
|
||||
UMicroseconds stop_time;
|
||||
|
||||
m_accumulator += stop_time.GetNativeTime() - m_start_time.GetNativeTime();
|
||||
}
|
||||
|
||||
void UMicrosecondsAccumulator::Clear()
|
||||
{
|
||||
m_start_time = 0;
|
||||
m_accumulator = 0;
|
||||
}
|
||||
|
||||
UMicroseconds UMicrosecondsAccumulator::GetAccumulatedTime() const
|
||||
{
|
||||
return m_accumulator;
|
||||
}
|
||||
|
||||
UMicrosecondsAccumulator& UMicrosecondsAccumulator::operator+=(const UMicrosecondsAccumulator& inaccum_to_add)
|
||||
{
|
||||
m_accumulator += inaccum_to_add.GetAccumulatedTime();
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace wvNS {
|
||||
void UMicrosecondsAccumulator::Start()
|
||||
{
|
||||
m_start_time.ReadTime();
|
||||
}
|
||||
|
||||
void UMicrosecondsAccumulator::Stop()
|
||||
{
|
||||
UMicroseconds stop_time;
|
||||
|
||||
m_accumulator += stop_time.GetNativeTime() - m_start_time.GetNativeTime();
|
||||
}
|
||||
|
||||
void UMicrosecondsAccumulator::Clear()
|
||||
{
|
||||
m_start_time = 0;
|
||||
m_accumulator = 0;
|
||||
}
|
||||
|
||||
UMicroseconds UMicrosecondsAccumulator::GetAccumulatedTime() const
|
||||
{
|
||||
return m_accumulator;
|
||||
}
|
||||
|
||||
UMicrosecondsAccumulator& UMicrosecondsAccumulator::operator+=(const UMicrosecondsAccumulator& inaccum_to_add)
|
||||
{
|
||||
m_accumulator += inaccum_to_add.GetAccumulatedTime();
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace wvNS {
|
||||
|
|
|
|||
|
|
@ -1,123 +1,105 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
#ifndef __UMicroseconds_h__
|
||||
#define __UMicroseconds_h__
|
||||
|
||||
/* Copy to include
|
||||
#include "UMicroseconds.h"
|
||||
*/
|
||||
#ifndef __UMicroseconds_h__
|
||||
#define __UMicroseconds_h__
|
||||
|
||||
/* Copy to include
|
||||
#include "UMicroseconds.h"
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "BasicTypes/WUDefines.h"
|
||||
#include "BasicTypes/WUTypes.h"
|
||||
|
||||
namespace wvNS {
|
||||
// a wraper for Microseconds function from Timer.h
|
||||
class DllExport UMicroseconds
|
||||
{
|
||||
public:
|
||||
|
||||
#ifdef _WINDOWS
|
||||
typedef int64_t TimeKeeper;
|
||||
#endif
|
||||
#ifdef __MACOS__
|
||||
typedef uint64_t TimeKeeper;
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
typedef uint64_t TimeKeeper;
|
||||
#endif
|
||||
|
||||
private:
|
||||
TimeKeeper theTime;
|
||||
|
||||
public:
|
||||
|
||||
UMicroseconds()
|
||||
{
|
||||
ReadTime();
|
||||
}
|
||||
|
||||
UMicroseconds(const TimeKeeper in_initVal) : theTime(in_initVal) {}
|
||||
|
||||
UMicroseconds(const UMicroseconds& inUM) : theTime(inUM.theTime) {}
|
||||
UMicroseconds& operator=(const UMicroseconds& inUM) {theTime = inUM.theTime; return *this;}
|
||||
UMicroseconds& operator+=(const TimeKeeper in_timeToAdd) {theTime += in_timeToAdd; return *this;}
|
||||
|
||||
UMicroseconds& ReadTime();
|
||||
|
||||
TimeKeeper GetNativeTime() const {return theTime;}
|
||||
operator uint64_t () {return static_cast<uint64_t>(theTime);}
|
||||
operator double () const {return static_cast<const double>(theTime);}
|
||||
|
||||
double Seconds() const {return static_cast<double>(theTime) / double(1000000);}
|
||||
double MilliSeconds() const {return static_cast<double>(theTime) / double(1000);}
|
||||
double MicroSeconds() const {return static_cast<double>(theTime);}
|
||||
|
||||
#ifdef __MACOS__
|
||||
uint32_t hi();
|
||||
uint32_t lo();
|
||||
#endif
|
||||
};
|
||||
|
||||
inline UMicroseconds operator-(const UMicroseconds& in_one, const UMicroseconds& in_two)
|
||||
{
|
||||
UMicroseconds retVal(in_one.GetNativeTime() - in_two.GetNativeTime());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
class UMicrosecondsAccumulator
|
||||
{
|
||||
public:
|
||||
UMicrosecondsAccumulator() : m_start_time(0), m_accumulator(0) {}
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
void Clear();
|
||||
|
||||
UMicroseconds GetAccumulatedTime() const;
|
||||
|
||||
UMicrosecondsAccumulator& operator+=(const UMicrosecondsAccumulator&);
|
||||
|
||||
protected:
|
||||
UMicroseconds m_start_time;
|
||||
UMicroseconds m_accumulator;
|
||||
};
|
||||
|
||||
inline UMicroseconds operator-(const UMicrosecondsAccumulator& in_one, const UMicrosecondsAccumulator& in_two)
|
||||
{
|
||||
UMicroseconds retVal(in_one.GetAccumulatedTime() - in_two.GetAccumulatedTime());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//=========================================================================================//
|
||||
inline void MicrosecondDelay(double amt)
|
||||
//=========================================================================================//
|
||||
{
|
||||
UMicroseconds than;
|
||||
UMicroseconds now;
|
||||
|
||||
do
|
||||
{
|
||||
now.ReadTime();
|
||||
} while ((now.MicroSeconds() - than.MicroSeconds()) < amt);
|
||||
}
|
||||
|
||||
} // namespace wvNS {
|
||||
#endif //#ifndef __UMicroseconds_h__
|
||||
|
||||
|
||||
|
||||
#include "BasicTypes/WUDefines.h"
|
||||
#include "BasicTypes/WUTypes.h"
|
||||
|
||||
namespace wvNS {
|
||||
// a wraper for Microseconds function from Timer.h
|
||||
class DllExport UMicroseconds
|
||||
{
|
||||
public:
|
||||
|
||||
#ifdef _WINDOWS
|
||||
typedef int64_t TimeKeeper;
|
||||
#endif
|
||||
#ifdef __MACOS__
|
||||
typedef uint64_t TimeKeeper;
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
typedef uint64_t TimeKeeper;
|
||||
#endif
|
||||
|
||||
private:
|
||||
TimeKeeper theTime;
|
||||
|
||||
public:
|
||||
|
||||
UMicroseconds()
|
||||
{
|
||||
ReadTime();
|
||||
}
|
||||
|
||||
UMicroseconds(const TimeKeeper in_initVal) : theTime(in_initVal) {}
|
||||
|
||||
UMicroseconds(const UMicroseconds& inUM) : theTime(inUM.theTime) {}
|
||||
UMicroseconds& operator=(const UMicroseconds& inUM) {theTime = inUM.theTime; return *this;}
|
||||
UMicroseconds& operator+=(const TimeKeeper in_timeToAdd) {theTime += in_timeToAdd; return *this;}
|
||||
|
||||
UMicroseconds& ReadTime();
|
||||
|
||||
TimeKeeper GetNativeTime() const {return theTime;}
|
||||
operator uint64_t () {return static_cast<uint64_t>(theTime);}
|
||||
operator double () const {return static_cast<const double>(theTime);}
|
||||
|
||||
double Seconds() const {return static_cast<double>(theTime) / double(1000000);}
|
||||
double MilliSeconds() const {return static_cast<double>(theTime) / double(1000);}
|
||||
double MicroSeconds() const {return static_cast<double>(theTime);}
|
||||
|
||||
#ifdef __MACOS__
|
||||
uint32_t hi();
|
||||
uint32_t lo();
|
||||
#endif
|
||||
};
|
||||
|
||||
inline UMicroseconds operator-(const UMicroseconds& in_one, const UMicroseconds& in_two)
|
||||
{
|
||||
UMicroseconds retVal(in_one.GetNativeTime() - in_two.GetNativeTime());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
class UMicrosecondsAccumulator
|
||||
{
|
||||
public:
|
||||
UMicrosecondsAccumulator() : m_start_time(0), m_accumulator(0) {}
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
void Clear();
|
||||
|
||||
UMicroseconds GetAccumulatedTime() const;
|
||||
|
||||
UMicrosecondsAccumulator& operator+=(const UMicrosecondsAccumulator&);
|
||||
|
||||
protected:
|
||||
UMicroseconds m_start_time;
|
||||
UMicroseconds m_accumulator;
|
||||
};
|
||||
|
||||
inline UMicroseconds operator-(const UMicrosecondsAccumulator& in_one, const UMicrosecondsAccumulator& in_two)
|
||||
{
|
||||
UMicroseconds retVal(in_one.GetAccumulatedTime() - in_two.GetAccumulatedTime());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
//=========================================================================================//
|
||||
inline void MicrosecondDelay(double amt)
|
||||
//=========================================================================================//
|
||||
{
|
||||
UMicroseconds than;
|
||||
UMicroseconds now;
|
||||
|
||||
do
|
||||
{
|
||||
now.ReadTime();
|
||||
} while ((now.MicroSeconds() - than.MicroSeconds()) < amt);
|
||||
}
|
||||
|
||||
} // namespace wvNS {
|
||||
#endif //#ifndef __UMicroseconds_h__
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __WCFixedString_h__
|
||||
#define __WCFixedString_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __WUErrors_h__
|
||||
#define __WUErrors_h__
|
||||
|
||||
|
|
@ -53,6 +35,7 @@ const WTErr eAppTerminateFailed = -23; //!< failed to terminate an appl
|
|||
const WTErr eAppReturnedError = -24; //!< Non zero exit code from application
|
||||
const WTErr eNotImplemented = -25; //!< Function is not implmemented
|
||||
const WTErr eNotEmpty = -26; //!< Something was expected to be empty but is not
|
||||
const WTErr eAsioFailed = -27;
|
||||
|
||||
// File Manager errors
|
||||
const WTErr eFMNoSuchVolume = -1001;
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __safe_delete_h__
|
||||
#define __safe_delete_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#include "WCRefManager.h"
|
||||
|
||||
/// Construcotr.
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef WCREFMANAGER_H
|
||||
#define WCREFMANAGER_H
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#include "Threads/WCThreadSafe.h"
|
||||
|
||||
#if XPLATFORMTHREADS_WINDOWS
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __WCThreadSafe_h_
|
||||
#define __WCThreadSafe_h_
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __WavesPublicAPI_Defines_h__
|
||||
#define __WavesPublicAPI_Defines_h__
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,5 @@
|
|||
/*
|
||||
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) 2011 Waves Audio Ltd. All rights reserved.
|
||||
// \file WTErr.h, defines basic error type and "No Error" code
|
||||
// All users may use their own error codes with this type, as long as eNoErr remains defined here
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
#ifndef __stdint_h__
|
||||
#define __stdint_h__
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue