new audio engine backend for native CoreAudio audio I/O, and PortMIDI for MIDI.
[ardour.git] / libs / backends / wavesaudio / wavesapi / devicemanager / WCMRCoreAudioDeviceManager.h
1 /*
2     Copyright (C) 2013 Waves Audio Ltd.
3
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.
8
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.
13
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.
17
18 */
19 //----------------------------------------------------------------------------------
20 //
21 //
22 //! \file       WCMRCoreAudioDeviceManager.h
23 //!
24 //! WCMRCoreAudioDeviceManager and related class declarations
25 //!
26 //---------------------------------------------------------------------------------*/
27 #ifndef __WCMRCoreAudioDeviceManager_h_
28         #define __WCMRCoreAudioDeviceManager_h_
29
30 #include "WCMRAudioDeviceManager.h"
31 #include "WCMRNativeAudio.h"
32 #include "Threads/WCThreadSafe.h"
33
34 #include <AudioUnit/AudioUnit.h>
35 #include <AudioToolbox/AudioToolbox.h>
36
37 #include <mach/mach.h>
38
39 #include <CoreAudio/CoreAudio.h> 
40
41 //forward decl.
42 class WCMRCoreAudioDeviceManager;
43
44 #define WV_USE_TONE_GEN 0 ///! Set this to 1 to use a tone generator for input. See description at SetupToneGenerator for details.
45
46 // This enum is for choosing filter for audio devices scan
47 typedef enum eCABS_Method
48 {
49         eCABS_Simple = 0,       
50         eCABS_DestructiveCache,
51         eCABS_CacheOnDeviceSet,    
52         eCABS_MethodNum // Must be last
53 }       eCABS_Method;
54
55 //! Manages a port audio device, providing information
56 //! about the device, and managing audio callbacks.
57 class WCMRCoreAudioDevice : public WCMRNativeAudioDevice
58 {
59 public:
60
61         WCMRCoreAudioDevice (WCMRCoreAudioDeviceManager *pManager, AudioDeviceID deviceID, bool useMultithreading = true, bool bNocopy = false);///<Constructor
62         virtual ~WCMRCoreAudioDevice ();///<Destructor
63
64         virtual const std::string& DeviceName() const;///<Name?
65         virtual const std::vector<std::string>& InputChannels();///<Current Input Channel List? - note that this may change with change in sampling rate.
66         virtual const std::vector<std::string>& OutputChannels();///<Current Output Channel List? - note that this may change with change in sampling rate.
67     
68     
69         virtual const std::vector<int>& SamplingRates();///<Supported Sampling Rate List?
70         virtual int CurrentSamplingRate(); ///<Current Sampling rate.?
71         virtual WTErr SetCurrentSamplingRate(int newRate);///<Change Current Sampling Rate : This is a requset, might not be successful at run time!
72
73         virtual const std::vector<int>& BufferSizes();///<Supported Buffer Size List? - note that this may change with change in sampling rate.
74         virtual int CurrentBufferSize();///<Current Buffer Size.? - note that this may change with change in sampling rate.
75         virtual WTErr SetCurrentBufferSize (int newSize);///<Change Current Buffer Size : This is a requset, might not be successful at run time!
76
77         virtual ConnectionStates ConnectionStatus();///< Connection Status - device available, gone, disconnected
78
79         virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
80         virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
81
82         virtual WTErr DoIdle();///<Do Idle Processing
83         
84         virtual WTErr SetMonitorChannels (int leftChannel, int rightChannel);///<Set monitor channels. - optional, will not be available with AG
85         virtual WTErr SetMonitorGain (float newGain);///<Set monitor gain. - optional, will not be available with AG
86         
87         virtual WTErr ShowConfigPanel (void *pParam);///< Show Control Panel - in case of ASIO this will work only with Active device!
88
89         virtual int AudioCallback (float *pOutputBuffer, unsigned long framesPerBuffer, uint32_t inSampleTime, uint64_t inCycleStartTime);
90         
91         AudioDeviceID DeviceID () {return m_DeviceID;}
92     
93     virtual uint32_t GetLatency (bool isInput); ///< Get latency.
94     virtual OSStatus GetStreamLatency(AudioDeviceID deviceID, bool isInput, std::vector<int>& latencies);
95
96     
97 protected:
98
99         AudioDeviceID m_DeviceID; ///< The CoreAudio device id
100         bool m_StopRequested; ///< should be set to true when want to stop, set to false otherwise.
101         float *m_pInputData; ///< This is what came in with the most recent callback.
102         int m_SampleCounter; ///< The current running sample counter, updated by the audio callback.
103         int m_SampleCountAtLastIdle; ///< What was the sample count last time we checked...
104         int m_StalledSampleCounter; ///< The number of idle calls with same sample count detected
105         int m_ChangeCheckCounter; ///< The number of idle calls passed since we checked the buffer size change.
106
107         wvNS::wvThread::timestamp m_LastCPULog; ///< The time when the last CPU details log was sent as a notification.
108 //      unsigned int m_IOCyclesTimesTaken[MAX_IOCYCLE_TIMES]; ///< This stores the times taken by each IOCycle, in host-time units.
109 //      int m_CurrentIOCycle; ///< The location in m_IOCyclesTymesTaken array, where the next cycle's value will go.
110 //      int m_CyclesToAccumulate; ///< The number of cycles to accumulate the values for - maximum for last one second.
111 //      unsigned int m_CyclePeriod; ///< The number of host time units for a cycle period - determined by buffer size and sampling rate
112         
113         
114         
115         AudioBufferList m_InputAudioBufferList; ///< The buffer list used to get AHHAL to render input to.
116         AudioUnit m_AUHALAudioUnit;///< The AUHAL AudioUnit
117
118         int m_BufferSizeChangeRequested;
119         int m_BufferSizeChangeReported;
120         int m_ResetRequested;
121         int m_ResetReported;
122         int m_ResyncRequested;
123         int m_ResyncReported;
124         int m_SRChangeRequested;
125         int m_SRChangeReported;
126
127         int m_DropsDetected; ///< Number of times audio drops have been detected so far.
128         int m_DropsReported; ///< Number of times audio drops have been reported so far to the client.
129         bool m_IgnoreThisDrop; ///< Allows disregarding the first drop
130
131         thread_t m_IOProcThreadPort; ///< Thread handle to calculate CPU consumption.
132         int m_CPUCount; ///< Number of processors/core to normalize cpu consumption calculation.
133
134 #if WV_USE_TONE_GEN
135         //The Tone Generator...
136         float_t *m_pToneData;
137         uint32_t m_ToneDataSamples;
138         uint32_t m_NextSampleToUse;
139 #endif //WV_USE_TONE_GEN
140         
141         WTErr UpdateDeviceInfo (bool updateSRSupported, bool updateBufferSizes);
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);
150
151         WTErr EnableAudioUnitIO();
152         WTErr virtual EnableListeners();
153         WTErr virtual DisableListeners();
154         WTErr SetupAUHAL();
155         WTErr TearDownAUHAL();
156
157 #if WV_USE_TONE_GEN
158         void SetupToneGenerator ();
159 #endif //WV_USE_TONE_GEN
160         
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);
167                 
168         static OSStatus StaticPropertyChangeProc (AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput,
169         AudioDevicePropertyID inPropertyID, void *inClientData);
170         void PropertyChangeProc (AudioDevicePropertyID inPropertyID);
171     
172 private:
173
174 };
175
176
177 //! WCMRCoreAudioDeviceManager
178 /*! The CoreAudio Device Manager class */
179 class WCMRCoreAudioDeviceManager : public WCMRAudioDeviceManager
180 {
181 public:
182
183         WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
184                 bool useMultithreading = true, eCABS_Method eCABS_method = eCABS_Simple, bool bNocopy = false); ///< constructor
185         virtual ~WCMRCoreAudioDeviceManager(void); ///< Destructor
186         
187
188         virtual WTErr UpdateDeviceList() //has to be overridden!
189     {
190                         //wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
191         return UpdateDeviceList_Private();
192     }
193
194         virtual eCABS_Method GetBufferSizeMethod()
195     { 
196                         //wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceManagerMutex);
197         return GetBufferSizeMethod_Private();
198     }
199         
200         virtual WTErr DoIdle();
201         
202 private:
203     WTErr UpdateDeviceList_Private();
204     eCABS_Method GetBufferSizeMethod_Private() { return m_eCABS_Method; }
205
206 protected:
207
208         int m_UpdateDeviceListRequested; ///< Number of times device list change has been detected.
209         int m_UpdateDeviceListProcessed; ///< Number of times device list change has been processed.
210         bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
211     bool m_bNoCopyAudioBuffer;
212         eCABS_Method m_eCABS_Method; // Type of core audio buffer size list method
213
214         static OSStatus StaticPropertyChangeProc (AudioHardwarePropertyID inPropertyID, void* inClientData);
215         OSStatus PropertyChangeProc (AudioHardwarePropertyID inPropertyID);
216
217         void remove_pattern(const std::string& original_str, const std::string& pattern_str, std::string& return_str);
218 };
219
220 #endif //#ifndef __WCMRCoreAudioDeviceManager_h_