1 //----------------------------------------------------------------------------------
3 // Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
5 //! \file WCMRCoreAudioDeviceManager.h
7 //! WCMRCoreAudioDeviceManager and related class declarations
9 //---------------------------------------------------------------------------------*/
10 #ifndef __WCMRCoreAudioDeviceManager_h_
11 #define __WCMRCoreAudioDeviceManager_h_
13 #include "WCMRAudioDeviceManager.h"
14 #include "WCMRNativeAudio.h"
15 #include "Threads/WCThreadSafe.h"
17 #include <AudioUnit/AudioUnit.h>
18 #include <AudioToolbox/AudioToolbox.h>
20 #include <mach/mach.h>
22 #include <CoreAudio/CoreAudio.h>
25 class WCMRCoreAudioDeviceManager;
27 #define WV_USE_TONE_GEN 0 ///! Set this to 1 to use a tone generator for input. See description at SetupToneGenerator for details.
29 // This enum is for choosing filter for audio devices scan
30 typedef enum eCABS_Method
33 eCABS_DestructiveCache,
34 eCABS_CacheOnDeviceSet,
35 eCABS_MethodNum // Must be last
38 //! Manages a port audio device, providing information
39 //! about the device, and managing audio callbacks.
40 class WCMRCoreAudioDevice : public WCMRNativeAudioDevice
44 WCMRCoreAudioDevice (WCMRCoreAudioDeviceManager *pManager, AudioDeviceID deviceID, bool useMultithreading = true, bool bNocopy = false);///<Constructor
45 virtual ~WCMRCoreAudioDevice ();///<Destructor
47 virtual const std::string& DeviceName() const;///<Name?
48 virtual const std::vector<std::string>& InputChannels();///<Current Input Channel List? - note that this may change with change in sampling rate.
49 virtual const std::vector<std::string>& OutputChannels();///<Current Output Channel List? - note that this may change with change in sampling rate.
52 virtual const std::vector<int>& SamplingRates();///<Supported Sampling Rate List?
53 virtual int CurrentSamplingRate(); ///<Current Sampling rate.?
54 virtual WTErr SetCurrentSamplingRate(int newRate);///<Change Current Sampling Rate : This is a requset, might not be successful at run time!
56 virtual const std::vector<int>& BufferSizes();///<Supported Buffer Size List? - note that this may change with change in sampling rate.
57 virtual int CurrentBufferSize();///<Current Buffer Size.? - note that this may change with change in sampling rate.
58 virtual WTErr SetCurrentBufferSize (int newSize);///<Change Current Buffer Size : This is a requset, might not be successful at run time!
60 virtual ConnectionStates ConnectionStatus();///< Connection Status - device available, gone, disconnected
62 virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
63 virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
65 virtual WTErr DoIdle();///<Do Idle Processing
67 virtual WTErr SetMonitorChannels (int leftChannel, int rightChannel);///<Set monitor channels. - optional, will not be available with AG
68 virtual WTErr SetMonitorGain (float newGain);///<Set monitor gain. - optional, will not be available with AG
70 virtual WTErr ShowConfigPanel (void *pParam);///< Show Control Panel - in case of ASIO this will work only with Active device!
72 virtual int AudioCallback (float *pOutputBuffer, unsigned long framesPerBuffer, uint32_t inSampleTime, uint64_t inCycleStartTime);
74 AudioDeviceID DeviceID () {return m_DeviceID;}
76 virtual uint32_t GetLatency (bool isInput); ///< Get latency.
77 virtual OSStatus GetStreamLatency(AudioDeviceID deviceID, bool isInput, std::vector<int>& latencies);
82 AudioDeviceID m_DeviceID; ///< The CoreAudio device id
83 bool m_StopRequested; ///< should be set to true when want to stop, set to false otherwise.
84 float *m_pInputData; ///< This is what came in with the most recent callback.
85 int m_SampleCounter; ///< The current running sample counter, updated by the audio callback.
86 int m_SampleCountAtLastIdle; ///< What was the sample count last time we checked...
87 int m_StalledSampleCounter; ///< The number of idle calls with same sample count detected
88 int m_ChangeCheckCounter; ///< The number of idle calls passed since we checked the buffer size change.
90 wvNS::wvThread::timestamp m_LastCPULog; ///< The time when the last CPU details log was sent as a notification.
91 // unsigned int m_IOCyclesTimesTaken[MAX_IOCYCLE_TIMES]; ///< This stores the times taken by each IOCycle, in host-time units.
92 // int m_CurrentIOCycle; ///< The location in m_IOCyclesTymesTaken array, where the next cycle's value will go.
93 // int m_CyclesToAccumulate; ///< The number of cycles to accumulate the values for - maximum for last one second.
94 // unsigned int m_CyclePeriod; ///< The number of host time units for a cycle period - determined by buffer size and sampling rate
98 AudioBufferList m_InputAudioBufferList; ///< The buffer list used to get AHHAL to render input to.
99 AudioUnit m_AUHALAudioUnit;///< The AUHAL AudioUnit
101 int m_BufferSizeChangeRequested;
102 int m_BufferSizeChangeReported;
103 int m_ResetRequested;
105 int m_ResyncRequested;
106 int m_ResyncReported;
107 int m_SRChangeRequested;
108 int m_SRChangeReported;
110 int m_DropsDetected; ///< Number of times audio drops have been detected so far.
111 int m_DropsReported; ///< Number of times audio drops have been reported so far to the client.
112 bool m_IgnoreThisDrop; ///< Allows disregarding the first drop
114 thread_t m_IOProcThreadPort; ///< Thread handle to calculate CPU consumption.
115 int m_CPUCount; ///< Number of processors/core to normalize cpu consumption calculation.
118 //The Tone Generator...
119 float_t *m_pToneData;
120 uint32_t m_ToneDataSamples;
121 uint32_t m_NextSampleToUse;
122 #endif //WV_USE_TONE_GEN
124 WTErr UpdateDeviceInfo ();
125 WTErr UpdateDeviceName();
126 WTErr UpdateDeviceInputs();
127 WTErr UpdateDeviceOutputs();
128 WTErr UpdateDeviceSampleRates();
129 WTErr UpdateDeviceBufferSizes();
130 WTErr SetWorkingBufferSize(int newSize);
131 OSStatus SetBufferSizesByIO(int newSize);
132 WTErr SetAndCheckCurrentSamplingRate (int newRate);
134 WTErr EnableAudioUnitIO();
135 WTErr virtual EnableListeners();
136 WTErr virtual DisableListeners();
138 WTErr TearDownAUHAL();
141 void SetupToneGenerator ();
142 #endif //WV_USE_TONE_GEN
144 static OSStatus StaticAudioIOProc(void *inRefCon, AudioUnitRenderActionFlags * ioActionFlags,
145 const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
146 AudioBufferList *ioData);
147 OSStatus AudioIOProc(AudioUnitRenderActionFlags * ioActionFlags,
148 const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
149 AudioBufferList *ioData);
151 static OSStatus StaticPropertyChangeProc (AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput,
152 AudioDevicePropertyID inPropertyID, void *inClientData);
153 void PropertyChangeProc (AudioDevicePropertyID inPropertyID);
160 //! WCMRCoreAudioDeviceManager
161 /*! The CoreAudio Device Manager class */
162 class WCMRCoreAudioDeviceManager : public WCMRAudioDeviceManager
166 WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
167 bool useMultithreading = true, bool bNocopy = false); ///< constructor
168 virtual ~WCMRCoreAudioDeviceManager(void); ///< Destructor
171 static OSStatus DevicePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData);
173 virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName);
174 virtual void destroyCurrentDeviceImpl();
175 virtual WTErr generateDeviceListImpl();
176 virtual WTErr updateDeviceListImpl();
177 virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const;
179 bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
180 bool m_bNoCopyAudioBuffer;
183 // helper functions for this class only
184 WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
185 WTErr getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels);
186 WTErr getDeviceMaxOutputChannels(DeviceID deviceId, unsigned int& outputChannels);
188 WCMRAudioDevice* m_NoneDevice;
191 #endif //#ifndef __WCMRCoreAudioDeviceManager_h_