summaryrefslogtreecommitdiff
path: root/libs/backends/wavesaudio/wavesapi/devicemanager/WCMRCoreAudioDeviceManager.h
blob: 8bbd7d8effb6396ff3687ac94df3d23bc8c7521c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
    Copyright (C) 2014 Waves Audio Ltd.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

//----------------------------------------------------------------------------------
//
//
//! \file	WCMRCoreAudioDeviceManager.h
//!
//! WCMRCoreAudioDeviceManager and related class declarations
//!
//---------------------------------------------------------------------------------*/
#ifndef __WCMRCoreAudioDeviceManager_h_
	#define __WCMRCoreAudioDeviceManager_h_

#include "WCMRAudioDeviceManager.h"
#include "WCMRNativeAudio.h"
#include "Threads/WCThreadSafe.h"

#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>

#include <mach/mach.h>

#include <CoreAudio/CoreAudio.h> 

//forward decl.
class WCMRCoreAudioDeviceManager;

#define WV_USE_TONE_GEN 0 ///! Set this to 1 to use a tone generator for input. See description at SetupToneGenerator for details.

// This enum is for choosing filter for audio devices scan
typedef enum eCABS_Method
{
	eCABS_Simple = 0,       
	eCABS_DestructiveCache,
	eCABS_CacheOnDeviceSet,    
	eCABS_MethodNum // Must be last
}	eCABS_Method;

//! Manages a port audio device, providing information
//! about the device, and managing audio callbacks.
class WCMRCoreAudioDevice : public WCMRNativeAudioDevice
{
public:

	WCMRCoreAudioDevice (WCMRCoreAudioDeviceManager *pManager, AudioDeviceID deviceID, bool useMultithreading = true, bool bNocopy = false);///<Constructor
	virtual ~WCMRCoreAudioDevice ();///<Destructor

	virtual const std::string& DeviceName() const;///<Name?
	virtual const std::vector<std::string>& InputChannels();///<Current Input Channel List? - note that this may change with change in sampling rate.
	virtual const std::vector<std::string>& OutputChannels();///<Current Output Channel List? - note that this may change with change in sampling rate.
    
    
	virtual const std::vector<int>& SamplingRates();///<Supported Sampling Rate List?
	virtual int CurrentSamplingRate(); ///<Current Sampling rate.?
	virtual WTErr SetCurrentSamplingRate(int newRate);///<Change Current Sampling Rate : This is a requset, might not be successful at run time!

	virtual const std::vector<int>& BufferSizes();///<Supported Buffer Size List? - note that this may change with change in sampling rate.
	virtual int CurrentBufferSize();///<Current Buffer Size.? - note that this may change with change in sampling rate.
	virtual WTErr SetCurrentBufferSize (int newSize);///<Change Current Buffer Size : This is a requset, might not be successful at run time!

	virtual ConnectionStates ConnectionStatus();///< Connection Status - device available, gone, disconnected

	virtual WTErr SetActive (bool newState);///<Prepare/Activate device.
	virtual WTErr SetStreaming (bool newState);///<Start/Stop Streaming - should reconnect connections when streaming starts!

	virtual WTErr DoIdle();///<Do Idle Processing
	
	virtual WTErr SetMonitorChannels (int leftChannel, int rightChannel);///<Set monitor channels. - optional, will not be available with AG
	virtual WTErr SetMonitorGain (float newGain);///<Set monitor gain. - optional, will not be available with AG
	
	virtual WTErr ShowConfigPanel (void *pParam);///< Show Control Panel - in case of ASIO this will work only with Active device!

	virtual int AudioCallback (float *pOutputBuffer, unsigned long framesPerBuffer, int64_t inSampleTime, uint64_t inCycleStartTime);
	
	AudioDeviceID DeviceID () {return m_DeviceID;}
    
    virtual uint32_t GetLatency (bool isInput); ///< Get latency.
    virtual OSStatus GetStreamLatency(AudioDeviceID deviceID, bool isInput, std::vector<int>& latencies);

    
protected:

	AudioDeviceID m_DeviceID; ///< The CoreAudio device id
	bool m_StopRequested; ///< should be set to true when want to stop, set to false otherwise.
    float *m_pInputData; ///< This is what came in with the most recent callback.
	int64_t m_SampleCounter; ///< The current running sample counter, updated by the audio callback.
	int64_t m_SampleCountAtLastIdle; ///< What was the sample count last time we checked...
	int m_StalledSampleCounter; ///< The number of idle calls with same sample count detected
	int m_ChangeCheckCounter; ///< The number of idle calls passed since we checked the buffer size change.

	wvNS::wvThread::timestamp m_LastCPULog; ///< The time when the last CPU details log was sent as a notification.
//	unsigned int m_IOCyclesTimesTaken[MAX_IOCYCLE_TIMES]; ///< This stores the times taken by each IOCycle, in host-time units.
//	int m_CurrentIOCycle; ///< The location in m_IOCyclesTymesTaken array, where the next cycle's value will go.
//	int m_CyclesToAccumulate; ///< The number of cycles to accumulate the values for - maximum for last one second.
//	unsigned int m_CyclePeriod; ///< The number of host time units for a cycle period - determined by buffer size and sampling rate
	

	AudioUnit m_AUHALAudioUnit;///< The AUHAL AudioUnit

	int m_BufferSizeChangeRequested;
	int m_BufferSizeChangeReported;
	int m_ResetRequested;
	int m_ResetReported;
	int m_ResyncRequested;
	int m_ResyncReported;
	int m_SRChangeRequested;
	int m_SRChangeReported;

	int m_DropsDetected; ///< Number of times audio drops have been detected so far.
	int m_DropsReported; ///< Number of times audio drops have been reported so far to the client.
	bool m_IgnoreThisDrop; ///< Allows disregarding the first drop

	thread_t m_IOProcThreadPort; ///< Thread handle to calculate CPU consumption.
	int m_CPUCount; ///< Number of processors/core to normalize cpu consumption calculation.

#if WV_USE_TONE_GEN
	//The Tone Generator...
	float_t *m_pToneData;
	uint32_t m_ToneDataSamples;
	uint32_t m_NextSampleToUse;
#endif //WV_USE_TONE_GEN
	
	WTErr UpdateDeviceInfo ();
    WTErr UpdateDeviceId ();
	WTErr UpdateDeviceName();
	WTErr UpdateDeviceInputs();
	WTErr UpdateDeviceOutputs();
	WTErr UpdateDeviceSampleRates();
	WTErr UpdateDeviceBufferSizes();
	WTErr SetWorkingBufferSize(int newSize);
	OSStatus SetBufferSizesByIO(int newSize);
	WTErr SetAndCheckCurrentSamplingRate (int newRate);

	WTErr EnableAudioUnitIO();
	WTErr virtual EnableListeners();
	WTErr virtual DisableListeners();
	WTErr SetupAUHAL();
	WTErr TearDownAUHAL();

#if WV_USE_TONE_GEN
	void SetupToneGenerator ();
#endif //WV_USE_TONE_GEN
	
	static OSStatus StaticAudioIOProc(void *inRefCon, AudioUnitRenderActionFlags *	ioActionFlags,
		const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
		AudioBufferList *ioData);
	OSStatus AudioIOProc(AudioUnitRenderActionFlags *	ioActionFlags,
		const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames,
		AudioBufferList *ioData);
		
	static OSStatus StaticPropertyChangeProc (AudioDeviceID inDevice, UInt32 inChannel, Boolean isInput,
	AudioDevicePropertyID inPropertyID, void *inClientData);
	void PropertyChangeProc (AudioDevicePropertyID inPropertyID);

private:

};


//! WCMRCoreAudioDeviceManager
/*! The CoreAudio Device Manager class */
class WCMRCoreAudioDeviceManager : public WCMRAudioDeviceManager
{
public:

	WCMRCoreAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter,
		bool useMultithreading = true, bool bNocopy = false); ///< constructor
	virtual ~WCMRCoreAudioDeviceManager(void); ///< Destructor

protected:
    static OSStatus HardwarePropertyChangeCallback (AudioHardwarePropertyID inPropertyID, void* inClientData);
    
    virtual WCMRAudioDevice*	initNewCurrentDeviceImpl(const std::string & deviceName);
	virtual void				destroyCurrentDeviceImpl();
	virtual WTErr				generateDeviceListImpl();
    virtual WTErr				updateDeviceListImpl();
    virtual WTErr               getDeviceSampleRatesImpl(const std::string & deviceName, std::vector<int>& sampleRates) const;
	virtual WTErr				getDeviceBufferSizesImpl(const std::string & deviceName, std::vector<int>& bufferSizes) const;
    
	bool m_UseMultithreading; ///< Flag indicates whether to use multi-threading for audio processing.
    bool m_bNoCopyAudioBuffer;
	    
private:
    // helper functions for this class only
    WTErr getDeviceAvailableSampleRates(DeviceID deviceId, std::vector<int>& sampleRates);
    WTErr getDeviceMaxInputChannels(DeviceID deviceId, unsigned int& inputChannels);
    WTErr getDeviceMaxOutputChannels(DeviceID deviceId, unsigned int& outputChannels);
    
    WCMRAudioDevice*			m_NoneDevice;
};

#endif //#ifndef __WCMRCoreAudioDeviceManager_h_