2 Copyright (C) 2014 Waves Audio Ltd.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //----------------------------------------------------------------------------------
23 //! \file WCMRCoreAudioDeviceManager.h
25 //! WCMRCoreAudioDeviceManager and related class declarations
27 //---------------------------------------------------------------------------------*/
28 #ifndef __WCMRCoreAudioDeviceManager_h_
29 #define __WCMRCoreAudioDeviceManager_h_
31 #include "WCMRAudioDeviceManager.h"
32 #include "WCMRNativeAudio.h"
33 #include "Threads/WCThreadSafe.h"
35 #include <AudioUnit/AudioUnit.h>
36 #include <AudioToolbox/AudioToolbox.h>
38 #include <mach/mach.h>
40 #include <CoreAudio/CoreAudio.h>
43 class WCMRCoreAudioDeviceManager;
45 #define WV_USE_TONE_GEN 0 ///! Set this to 1 to use a tone generator for input. See description at SetupToneGenerator for details.
47 // This enum is for choosing filter for audio devices scan
48 typedef enum eCABS_Method
51 eCABS_DestructiveCache,
52 eCABS_CacheOnDeviceSet,
53 eCABS_MethodNum // Must be last
56 //! Manages a port audio device, providing information
57 //! about the device, and managing audio callbacks.
58 class WCMRCoreAudioDevice : public WCMRNativeAudioDevice
62 WCMRCoreAudioDevice (WCMRCoreAudioDeviceManager *pManager, AudioDeviceID deviceID, bool useMultithreading = true, bool bNocopy = false);///<Constructor
63 virtual ~WCMRCoreAudioDevice ();///<Destructor
65 virtual const std::string& DeviceName() const;///<Name?
66 virtual const std::vector<std::string>& InputChannels();///<Current Input Channel List? - note that this may change with change in sampling rate.
67 virtual const std::vector<std::string>& OutputChannels();///<Current Output Channel List? - note that this may change with change in sampling rate.
70 virtual const std::vector<int>& SamplingRates();///<Supported Sampling Rate List?
71 virtual int CurrentSamplingRate(); ///<Current Sampling rate.?
72 virtual WTErr SetCurrentSamplingRate(int newRate);///<Change Current Sampling Rate : This is a requset, might not be successful at run time!
74 virtual const std::vector<int>& BufferSizes();///<Supported Buffer Size List? - note that this may change with change in sampling rate.
75 virtual int CurrentBufferSize();///<Current Buffer Size.? - note that this may change with change in sampling rate.
76 virtual WTErr SetCurrentBufferSize (int newSize);///<Change Current Buffer Size : This is a requset, might not be successful at run time!
78 virtual ConnectionStates ConnectionStatus();///< Connection Status - device available, gone, disconnected
80 virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
81 virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
83 virtual WTErr DoIdle();///<Do Idle Processing
85 virtual WTErr SetMonitorChannels (int leftChannel, int rightChannel);///<Set monitor channels. - optional, will not be available with AG
86 virtual WTErr SetMonitorGain (float newGain);///<Set monitor gain. - optional, will not be available with AG
88 virtual WTErr ShowConfigPanel (void *pParam);///< Show Control Panel - in case of ASIO this will work only with Active device!
90 virtual int AudioCallback (float *pOutputBuffer, unsigned long framesPerBuffer, int64_t inSampleTime, uint64_t inCycleStartTime);
92 AudioDeviceID DeviceID () {return m_DeviceID;}
94 virtual uint32_t GetLatency (bool isInput); ///< Get latency.
95 virtual OSStatus GetStreamLatency(AudioDeviceID deviceID, bool isInput, std::vector<int>& latencies);
100 AudioDeviceID m_DeviceID; ///< The CoreAudio device id
101 bool m_StopRequested; ///< should be set to true when want to stop, set to false otherwise.
102 float *m_pInputData; ///< This is what came in with the most recent callback.
103 int64_t m_SampleCounter; ///< The current running sample counter, updated by the audio callback.
104 int64_t m_SampleCountAtLastIdle; ///< What was the sample count last time we checked...
105 int m_StalledSampleCounter; ///< The number of idle calls with same sample count detected
106 int m_ChangeCheckCounter; ///< The number of idle calls passed since we checked the buffer size change.
108 wvNS::wvThread::timestamp m_LastCPULog; ///< The time when the last CPU details log was sent as a notification.
109 // unsigned int m_IOCyclesTimesTaken[MAX_IOCYCLE_TIMES]; ///< This stores the times taken by each IOCycle, in host-time units.
110 // int m_CurrentIOCycle; ///< The location in m_IOCyclesTymesTaken array, where the next cycle's value will go.
111 // int m_CyclesToAccumulate; ///< The number of cycles to accumulate the values for - maximum for last one second.
112 // unsigned int m_CyclePeriod; ///< The number of host time units for a cycle period - determined by buffer size and sampling rate
115 AudioUnit m_AUHALAudioUnit;///< The AUHAL AudioUnit
117 int m_BufferSizeChangeRequested;
118 int m_BufferSizeChangeReported;
119 int m_ResetRequested;
121 int m_ResyncRequested;
122 int m_ResyncReported;
123 int m_SRChangeRequested;
124 int m_SRChangeReported;
126 int m_DropsDetected; ///< Number of times audio drops have been detected so far.
127 int m_DropsReported; ///< Number of times audio drops have been reported so far to the client.
128 bool m_IgnoreThisDrop; ///< Allows disregarding the first drop
130 thread_t m_IOProcThreadPort; ///< Thread handle to calculate CPU consumption.
131 int m_CPUCount; ///< Number of processors/core to normalize cpu consumption calculation.
134 //The Tone Generator...
135 float_t *m_pToneData;
136 uint32_t m_ToneDataSamples;
137 uint32_t m_NextSampleToUse;
138 #endif //WV_USE_TONE_GEN
140 WTErr UpdateDeviceInfo ();
141 WTErr UpdateDeviceId ();
142 WTErr UpdateDeviceName();
143 WTErr UpdateDeviceInputs();
144 WTErr UpdateDeviceOutputs();
145 WTErr UpdateDeviceSampleRates();
146 WTErr UpdateDeviceBufferSizes();
147 WTErr SetWorkingBufferSize(int newSize);
148 OSStatus SetBufferSizesByIO(int newSize);
149 WTErr SetAndCheckCurrentSamplingRate (int newRate);
151 WTErr EnableAudioUnitIO();
152 WTErr virtual EnableListeners();
153 WTErr virtual DisableListeners();
155 WTErr TearDownAUHAL();
158 void SetupToneGenerator ();
159 #endif //WV_USE_TONE_GEN
161 static OSStatus StaticAudioIOProc(void *inRefCon, AudioUnitRenderActionFlags * ioActionFlags,
162 const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
163 AudioBufferList *ioData);
164 OSStatus AudioIOProc(AudioUnitRenderActionFlags * ioActionFlags,
165 const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
166 AudioBufferList *ioData);
168 static OSStatus StaticPropertyChangeProc (AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput,
169 AudioDevicePropertyID inPropertyID, void *inClientData);
170 void PropertyChangeProc (AudioDevicePropertyID inPropertyID);
177 //! WCMRCoreAudioDeviceManager
178 /*! The CoreAudio Device Manager class */
179 class WCMRCoreAudioDeviceManager : public WCMRAudioDeviceManager
183 WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
184 bool useMultithreading = true, bool bNocopy = false); ///< constructor
185 virtual ~WCMRCoreAudioDeviceManager(void); ///< Destructor
188 static OSStatus HardwarePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData);
190 virtual WCMRAudioDevice* initNewCurrentDeviceImpl(const std::string & deviceName);
191 virtual void destroyCurrentDeviceImpl();
192 virtual WTErr generateDeviceListImpl();
193 virtual WTErr updateDeviceListImpl();
194 virtual WTErr getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const;
195 virtual WTErr getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const;
197 bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
198 bool m_bNoCopyAudioBuffer;
201 // helper functions for this class only
202 WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
203 WTErr getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels);
204 WTErr getDeviceMaxOutputChannels(DeviceID deviceId, unsigned int& outputChannels);
206 WCMRAudioDevice* m_NoneDevice;
209 #endif //#ifndef __WCMRCoreAudioDeviceManager_h_