7579bfd2ffe4b987736ea4aacfed113e8643efb4
[ardour.git] / libs / backends / wavesaudio / wavesapi / devicemanager / WCMRPortAudioDeviceManager.h
1 /*
2     Copyright (C) 2014 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 //
23 //! \file       WCMRPortAudioDeviceManager.h
24 //!
25 //! WCMRPortAudioDeviceManager and related class declarations
26 //!
27 //---------------------------------------------------------------------------------*/
28 #ifndef __WCMRPortAudioDeviceManager_h_
29         #define __WCMRPortAudioDeviceManager_h_
30
31 #include "WCMRAudioDeviceManager.h"
32 #include "WCMRNativeAudio.h"
33 #include "portaudio.h"
34
35 //forward decl.
36 class WCMRPortAudioDeviceManager;
37
38 //! Manages a port audio device, providing information
39 //! about the device, and managing audio callbacks.
40 class WCMRPortAudioDevice : public WCMRNativeAudioDevice
41 {
42 public:
43
44         WCMRPortAudioDevice (WCMRPortAudioDeviceManager *pManager, unsigned int  deviceID, bool useMultiThreading = true, bool bNoCopy = false);///<Constructor
45         virtual ~WCMRPortAudioDevice ();///<Destructor
46
47         virtual int CurrentSamplingRate(); ///<Current Sampling rate.?
48         virtual WTErr SetCurrentSamplingRate(int newRate);///<Change Current Sampling Rate : This is a requset, might not be successful at run time!
49
50         virtual int CurrentBufferSize();///<Current Buffer Size.? - note that this may change with change in sampling rate.
51         virtual WTErr SetCurrentBufferSize (int newSize);///<Change Current Buffer Size : This is a requset, might not be successful at run time!
52
53         virtual ConnectionStates ConnectionStatus();///< Connection Status - device available, gone, disconnected
54
55         virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
56         
57         virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!
58
59         virtual WTErr SetMonitorChannels (int leftChannel, int rightChannel);///<Set monitor channels. - optional, will not be available with AG
60         virtual WTErr SetMonitorGain (float newGain);///<Set monitor gain. - optional, will not be available with AG
61         
62         virtual WTErr ShowConfigPanel (void *pParam);///< Show Control Panel - in case of ASIO this will work only with Active device!
63
64         virtual int AudioCallback (const float *pInputBuffer, float *pOutputBuffer, unsigned long framesPerBuffe, bool dropsDetectedr);
65
66         virtual WTErr UpdateDeviceInfo ();
67
68         virtual WTErr ResetDevice();
69
70 #ifdef PLATFORM_WINDOWS
71         static long StaticASIOMessageHook (void *pRefCon, long selector, long value, void* message, double* opt);
72         long ASIOMessageHook (long selector, long value, void* message, double* opt);
73 #endif //PLATFORM_WINDOWS
74         
75 protected:
76         static DWORD WINAPI __DoIdle__(LPVOID lpThreadParameter);
77
78         // Methods which are executed by device processing thread
79         WTErr DoIdle();///<Do Idle Processing
80         void initDevice();
81         void terminateDevice();
82         void updateDeviceInfo(bool callerIsWaiting = false);
83         void activateDevice(bool callerIsWaiting = false);
84         void deactivateDevice(bool callerIsWaiting = false);
85         void startStreaming(bool callerIsWaiting = false);
86         void stopStreaming(bool callerIsWaiting = false);
87         void resetDevice (bool callerIsWaiting = false);///<Reset device - close and reopen stream, update device information!
88
89         PaError testStateValidness(int sampleRate, int bufferSize);
90         ///////////////////////////////////////////////////////////
91         
92         static int TheCallback (const void *pInputBuffer, void *pOutputBuffer, unsigned long framesPerBuffer,
93                                                         const PaStreamCallbackTimeInfo* /*pTimeInfo*/, PaStreamCallbackFlags /*statusFlags*/, void *pUserData );
94
95         unsigned int m_DeviceID; ///< The PA device id
96         PaStream* m_PortAudioStream; ///< Port audio stream, when the device is active!
97         bool m_StopRequested; ///< should be set to true when want to stop, set to false otherwise.
98         const float *m_pInputData; ///< This is what came in with the most recent callback.
99         int64_t m_SampleCounter; ///< The current running sample counter, updated by the audio callback.
100         int64_t m_SampleCountAtLastIdle;
101
102         int m_DropsDetected; ///< Number of times audio drops have been detected so far.
103         int m_DropsReported; ///< Number of times audio drops have been reported so far to the client.
104         bool m_IgnoreThisDrop; ///< Allows disregarding the first drop
105
106         int m_BufferSizeChangeRequested;
107         int m_BufferSizeChangeReported;
108         int m_ResetRequested;
109         int m_ResetReported;
110         int m_ResyncRequested;
111         int m_ResyncReported;
112
113         HANDLE m_hDeviceProcessingThread;
114         DWORD m_DeviceProcessingThreadID;
115
116         ///< Backend request events
117         HANDLE m_hResetRequestedEvent;
118         HANDLE m_hResetDone;
119
120         HANDLE m_hUpdateDeviceInfoRequestedEvent;
121         HANDLE m_hUpdateDeviceInfoDone;
122
123         HANDLE m_hActivateRequestedEvent;
124         HANDLE m_hActivationDone;
125
126         HANDLE m_hDeActivateRequestedEvent;
127         HANDLE m_hDeActivationDone;
128
129         HANDLE m_hStartStreamingRequestedEvent;
130         HANDLE m_hStartStreamingDone;
131
132         HANDLE m_hStopStreamingRequestedEvent;
133         HANDLE m_hStopStreamingDone;
134         /////////////////////////
135
136         ///< Device request events
137         HANDLE m_hResetFromDevRequestedEvent;
138         HANDLE m_hBufferSizeChangedEvent;
139         HANDLE m_hSampleRateChangedEvent;
140         /////////////////////////////
141
142         ///< Sync events
143         HANDLE m_hDeviceInitialized;
144         HANDLE m_hExitIdleThread;
145
146         //Should be set if the device connection status is "DeviceErrors"
147         WTErr m_lastErr;
148 };
149
150 //! WCMRPortAudioDeviceManager
151 /*! The PortAudio Device Manager class */
152 class WCMRPortAudioDeviceManager : public WCMRAudioDeviceManager
153 {
154 public:
155         WCMRPortAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
156                                                                 bool useMultithreading = true, bool bNocopy = false); ///< constructor
157         
158         virtual ~WCMRPortAudioDeviceManager(void); ///< destructor
159
160 protected:
161
162         virtual WCMRAudioDevice*        initNewCurrentDeviceImpl(const std::string & deviceName);
163         virtual void                            destroyCurrentDeviceImpl();
164         virtual WTErr                           generateDeviceListImpl(); // use this in derived class to fill device list
165         virtual WTErr                           updateDeviceListImpl() {return eNoErr; } // not supported
166         virtual WTErr                           getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& buffers) const;
167     virtual WTErr                               getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const;
168
169         bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
170     bool m_bNoCopyAudioBuffer;
171
172 private:
173         // helper functions for this class only
174     WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
175         WTErr getDeviceAvailableBufferSizes(DeviceID deviceId, std::vector<int>& buffers);
176
177         WCMRAudioDevice*                        m_NoneDevice;
178 };
179
180 #endif //#ifndef __WCMRPortAudioDeviceManager_h_