913b4af5cbf988f2154cb8347e560281223b848f
[ardour.git] / libs / backends / wavesaudio / wavesapi / devicemanager / WCMRCoreAudioDeviceManager.h
1 //----------------------------------------------------------------------------------
2 //
3 // Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
4 //
5 //! \file       WCMRCoreAudioDeviceManager.h
6 //!
7 //! WCMRCoreAudioDeviceManager and related class declarations
8 //!
9 //---------------------------------------------------------------------------------*/
10 #ifndef __WCMRCoreAudioDeviceManager_h_
11         #define __WCMRCoreAudioDeviceManager_h_
12
13 #include "WCMRAudioDeviceManager.h"
14 #include "WCMRNativeAudio.h"
15 #include "Threads/WCThreadSafe.h"
16
17 #include <AudioUnit/AudioUnit.h>
18 #include <AudioToolbox/AudioToolbox.h>
19
20 #include <mach/mach.h>
21
22 #include <CoreAudio/CoreAudio.h> 
23
24 //forward decl.
25 class WCMRCoreAudioDeviceManager;
26
27 #define WV_USE_TONE_GEN 0 ///! Set this to 1 to use a tone generator for input. See description at SetupToneGenerator for details.
28
29 // This enum is for choosing filter for audio devices scan
30 typedef enum eCABS_Method
31 {
32         eCABS_Simple = 0,       
33         eCABS_DestructiveCache,
34         eCABS_CacheOnDeviceSet,    
35         eCABS_MethodNum // Must be last
36 }       eCABS_Method;
37
38 //! Manages a port audio device, providing information
39 //! about the device, and managing audio callbacks.
40 class WCMRCoreAudioDevice : public WCMRNativeAudioDevice
41 {
42 public:
43
44         WCMRCoreAudioDevice (WCMRCoreAudioDeviceManager *pManager, AudioDeviceID deviceID, bool useMultithreading = true, bool bNocopy = false);///<Constructor
45         virtual ~WCMRCoreAudioDevice ();///<Destructor
46
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.
50     
51     
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!
55
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!
59
60         virtual ConnectionStates ConnectionStatus();///< Connection Status - device available, gone, disconnected
61
62         virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
63         virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
64
65         virtual WTErr DoIdle();///<Do Idle Processing
66         
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
69         
70         virtual WTErr ShowConfigPanel (void *pParam);///< Show Control Panel - in case of ASIO this will work only with Active device!
71
72         virtual int AudioCallback (float *pOutputBuffer, unsigned long framesPerBuffer, uint32_t inSampleTime, uint64_t inCycleStartTime);
73         
74         AudioDeviceID DeviceID () {return m_DeviceID;}
75     
76     virtual uint32_t GetLatency (bool isInput); ///< Get latency.
77     virtual OSStatus GetStreamLatency(AudioDeviceID deviceID, bool isInput, std::vector<int>& latencies);
78
79     
80 protected:
81
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.
89
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
95         
96
97         AudioUnit m_AUHALAudioUnit;///< The AUHAL AudioUnit
98
99         int m_BufferSizeChangeRequested;
100         int m_BufferSizeChangeReported;
101         int m_ResetRequested;
102         int m_ResetReported;
103         int m_ResyncRequested;
104         int m_ResyncReported;
105         int m_SRChangeRequested;
106         int m_SRChangeReported;
107
108         int m_DropsDetected; ///< Number of times audio drops have been detected so far.
109         int m_DropsReported; ///< Number of times audio drops have been reported so far to the client.
110         bool m_IgnoreThisDrop; ///< Allows disregarding the first drop
111
112         thread_t m_IOProcThreadPort; ///< Thread handle to calculate CPU consumption.
113         int m_CPUCount; ///< Number of processors/core to normalize cpu consumption calculation.
114
115 #if WV_USE_TONE_GEN
116         //The Tone Generator...
117         float_t *m_pToneData;
118         uint32_t m_ToneDataSamples;
119         uint32_t m_NextSampleToUse;
120 #endif //WV_USE_TONE_GEN
121         
122         WTErr UpdateDeviceInfo ();
123         WTErr UpdateDeviceName();
124         WTErr UpdateDeviceInputs();
125         WTErr UpdateDeviceOutputs();
126         WTErr UpdateDeviceSampleRates();
127         WTErr UpdateDeviceBufferSizes();
128         WTErr SetWorkingBufferSize(int newSize);
129         OSStatus SetBufferSizesByIO(int newSize);
130         WTErr SetAndCheckCurrentSamplingRate (int newRate);
131
132         WTErr EnableAudioUnitIO();
133         WTErr virtual EnableListeners();
134         WTErr virtual DisableListeners();
135         WTErr SetupAUHAL();
136         WTErr TearDownAUHAL();
137
138 #if WV_USE_TONE_GEN
139         void SetupToneGenerator ();
140 #endif //WV_USE_TONE_GEN
141         
142         static OSStatus StaticAudioIOProc(void *inRefCon, AudioUnitRenderActionFlags *  ioActionFlags,
143                 const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
144                 AudioBufferList *ioData);
145         OSStatus AudioIOProc(AudioUnitRenderActionFlags *       ioActionFlags,
146                 const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
147                 AudioBufferList *ioData);
148                 
149         static OSStatus StaticPropertyChangeProc (AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput,
150         AudioDevicePropertyID inPropertyID, void *inClientData);
151         void PropertyChangeProc (AudioDevicePropertyID inPropertyID);
152     
153     void resetAudioDevice();
154 private:
155
156 };
157
158
159 //! WCMRCoreAudioDeviceManager
160 /*! The CoreAudio Device Manager class */
161 class WCMRCoreAudioDeviceManager : public WCMRAudioDeviceManager
162 {
163 public:
164
165         WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
166                 bool useMultithreading = true, bool bNocopy = false); ///< constructor
167         virtual ~WCMRCoreAudioDeviceManager(void); ///< Destructor
168
169 protected:
170     static OSStatus HardwarePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData);
171     
172     virtual WCMRAudioDevice*    initNewCurrentDeviceImpl(const std::string & deviceName);
173         virtual void                            destroyCurrentDeviceImpl();
174         virtual WTErr                           generateDeviceListImpl();
175     virtual WTErr                               updateDeviceListImpl();
176     virtual WTErr               getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const;
177         virtual WTErr                           getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const;
178     
179         bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
180     bool m_bNoCopyAudioBuffer;
181             
182 private:
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);
187     
188     WCMRAudioDevice*                    m_NoneDevice;
189 };
190
191 #endif //#ifndef __WCMRCoreAudioDeviceManager_h_