13
0
livetrax/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h
Paul Davis 000609901b add correct copyright statements to all files in Waves backend except those derived from portaudio/portmidi
This follows the letter sent from Waves Audio Ltd. to Paul Davis dated February 20th 2014 agreeing to release this code
under the GNU Public License, version 2, with copyright owned by Waves Audio Ltd
2014-10-07 16:17:34 -04:00

210 lines
8.8 KiB
C++

/*
Copyright (C) 2014 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.
*/
//----------------------------------------------------------------------------------
//
//
//! \file WCMRCoreAudioDeviceManager.h
//!
//! WCMRCoreAudioDeviceManager and related class declarations
//!
//---------------------------------------------------------------------------------*/
#ifndef __WCMRCoreAudioDeviceManager_h_
#define __WCMRCoreAudioDeviceManager_h_
#include "WCMRAudioDeviceManager.h"
#include "WCMRNativeAudio.h"
#include "Threads/WCThreadSafe.h"
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
#include <mach/mach.h>
#include <CoreAudio/CoreAudio.h>
//forward decl.
class WCMRCoreAudioDeviceManager;
#define WV_USE_TONE_GEN 0 ///! Set this to 1 to use a tone generator for input. See description at SetupToneGenerator for details.
// This enum is for choosing filter for audio devices scan
typedef enum eCABS_Method
{
eCABS_Simple = 0,
eCABS_DestructiveCache,
eCABS_CacheOnDeviceSet,
eCABS_MethodNum // Must be last
} eCABS_Method;
//! Manages a port audio device, providing information
//! about the device, and managing audio callbacks.
class WCMRCoreAudioDevice : public WCMRNativeAudioDevice
{
public:
WCMRCoreAudioDevice (WCMRCoreAudioDeviceManager *pManager, AudioDeviceID deviceID, bool useMultithreading = true, bool bNocopy = false);///<Constructor
virtual ~WCMRCoreAudioDevice ();///<Destructor
virtual const std::string& DeviceName() const;///<Name?
virtual const std::vector<std::string>& InputChannels();///<Current Input Channel List? - note that this may change with change in sampling rate.
virtual const std::vector<std::string>& OutputChannels();///<Current Output Channel List? - note that this may change with change in sampling rate.
virtual const std::vector<int>& SamplingRates();///<Supported Sampling Rate List?
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 const std::vector<int>& BufferSizes();///<Supported Buffer Size List? - note that this may change with change in sampling rate.
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 DoIdle();///<Do Idle Processing
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 (float *pOutputBuffer, unsigned long framesPerBuffer, uint32_t inSampleTime, uint64_t inCycleStartTime);
AudioDeviceID DeviceID () {return m_DeviceID;}
virtual uint32_t GetLatency (bool isInput); ///< Get latency.
virtual OSStatus GetStreamLatency(AudioDeviceID deviceID, bool isInput, std::vector<int>& latencies);
protected:
AudioDeviceID m_DeviceID; ///< The CoreAudio device id
bool m_StopRequested; ///< should be set to true when want to stop, set to false otherwise.
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; ///< What was the sample count last time we checked...
int m_StalledSampleCounter; ///< The number of idle calls with same sample count detected
int m_ChangeCheckCounter; ///< The number of idle calls passed since we checked the buffer size change.
wvNS::wvThread::timestamp m_LastCPULog; ///< The time when the last CPU details log was sent as a notification.
// unsigned int m_IOCyclesTimesTaken[MAX_IOCYCLE_TIMES]; ///< This stores the times taken by each IOCycle, in host-time units.
// int m_CurrentIOCycle; ///< The location in m_IOCyclesTymesTaken array, where the next cycle's value will go.
// int m_CyclesToAccumulate; ///< The number of cycles to accumulate the values for - maximum for last one second.
// unsigned int m_CyclePeriod; ///< The number of host time units for a cycle period - determined by buffer size and sampling rate
AudioUnit m_AUHALAudioUnit;///< The AUHAL AudioUnit
int m_BufferSizeChangeRequested;
int m_BufferSizeChangeReported;
int m_ResetRequested;
int m_ResetReported;
int m_ResyncRequested;
int m_ResyncReported;
int m_SRChangeRequested;
int m_SRChangeReported;
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
thread_t m_IOProcThreadPort; ///< Thread handle to calculate CPU consumption.
int m_CPUCount; ///< Number of processors/core to normalize cpu consumption calculation.
#if WV_USE_TONE_GEN
//The Tone Generator...
float_t *m_pToneData;
uint32_t m_ToneDataSamples;
uint32_t m_NextSampleToUse;
#endif //WV_USE_TONE_GEN
WTErr UpdateDeviceInfo ();
WTErr UpdateDeviceName();
WTErr UpdateDeviceInputs();
WTErr UpdateDeviceOutputs();
WTErr UpdateDeviceSampleRates();
WTErr UpdateDeviceBufferSizes();
WTErr SetWorkingBufferSize(int newSize);
OSStatus SetBufferSizesByIO(int newSize);
WTErr SetAndCheckCurrentSamplingRate (int newRate);
WTErr EnableAudioUnitIO();
WTErr virtual EnableListeners();
WTErr virtual DisableListeners();
WTErr SetupAUHAL();
WTErr TearDownAUHAL();
#if WV_USE_TONE_GEN
void SetupToneGenerator ();
#endif //WV_USE_TONE_GEN
static OSStatus StaticAudioIOProc(void *inRefCon, AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
OSStatus AudioIOProc(AudioUnitRenderActionFlags * ioActionFlags,
const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
static OSStatus StaticPropertyChangeProc (AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput,
AudioDevicePropertyID inPropertyID, void *inClientData);
void PropertyChangeProc (AudioDevicePropertyID inPropertyID);
void resetAudioDevice();
private:
};
//! WCMRCoreAudioDeviceManager
/*! The CoreAudio Device Manager class */
class WCMRCoreAudioDeviceManager : public WCMRAudioDeviceManager
{
public:
WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
bool useMultithreading = true, bool bNocopy = false); ///< constructor
virtual ~WCMRCoreAudioDeviceManager(void); ///< Destructor
protected:
static OSStatus HardwarePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData);
virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName);
virtual void destroyCurrentDeviceImpl();
virtual WTErr generateDeviceListImpl();
virtual WTErr updateDeviceListImpl();
virtual WTErr getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const;
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;
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_