1 /*
2 Copyright (C) 2004-2008 Grame
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 #ifndef __JackCoreAudioDriver__
21 #define __JackCoreAudioDriver__
22 
23 #include <AudioToolbox/AudioConverter.h>
24 #include <CoreAudio/CoreAudio.h>
25 #include <AudioUnit/AudioUnit.h>
26 #include "JackAudioDriver.h"
27 #include "JackTime.h"
28 
29 #include <vector>
30 
31 using namespace std;
32 
33 namespace Jack
34 {
35 
36 #define kVersion 102
37 
38 typedef	UInt8	CAAudioHardwareDeviceSectionID;
39 #define	kAudioDeviceSectionInput	((CAAudioHardwareDeviceSectionID)0x01)
40 #define	kAudioDeviceSectionOutput	((CAAudioHardwareDeviceSectionID)0x00)
41 #define	kAudioDeviceSectionGlobal	((CAAudioHardwareDeviceSectionID)0x00)
42 #define	kAudioDeviceSectionWildcard	((CAAudioHardwareDeviceSectionID)0xFF)
43 
44 #define WAIT_COUNTER 60
45 #define WAIT_NOTIFICATION_COUNTER 30
46 
47 /*!
48 \brief The CoreAudio driver.
49 
50 \todo hardware monitoring
51 */
52 
53 class JackAC3Encoder;
54 
55 class JackCoreAudioDriver : public JackAudioDriver
56 {
57 
58     private:
59 
60         JackAC3Encoder* fAC3Encoder;
61 
62         AudioUnit fAUHAL;
63 
64         AudioBufferList* fJackInputData;
65         AudioBufferList* fDriverOutputData;
66 
67         AudioDeviceID fDeviceID;    // Used "duplex" device
68         AudioObjectID fPluginID;    // Used for aggregate device
69 
70         AudioUnitRenderActionFlags* fActionFags;
71         const AudioTimeStamp* fCurrentTime;
72 
73         bool fState;
74         bool fHogged;
75 
76         char fCaptureUID[256];
77         char fPlaybackUID[256];
78 
79         float fIOUsage;
80         float fComputationGrain;
81         bool fClockDriftCompensate;
82         bool fDigitalPlayback;
83 
84         static OSStatus Render(void *inRefCon,
85                                AudioUnitRenderActionFlags *ioActionFlags,
86                                const AudioTimeStamp *inTimeStamp,
87                                UInt32 inBusNumber,
88                                UInt32 inNumberFrames,
89                                AudioBufferList *ioData);
90 
91         static OSStatus AudioHardwareNotificationCallback(AudioHardwarePropertyID inPropertyID,void* inClientData);
92 
93         static OSStatus DeviceNotificationCallback(AudioDeviceID inDevice,
94                                                     UInt32 inChannel,
95                                                     Boolean	isInput,
96                                                     AudioDevicePropertyID inPropertyID,
97                                                     void* inClientData);
98 
99         static OSStatus SRNotificationCallback(AudioDeviceID inDevice,
100                                                UInt32 inChannel,
101                                                Boolean	isInput,
102                                                AudioDevicePropertyID inPropertyID,
103                                                void* inClientData);
104 
105         static OSStatus BSNotificationCallback(AudioDeviceID inDevice,
106                                                 UInt32 inChannel,
107                                                 Boolean	isInput,
108                                                 AudioDevicePropertyID inPropertyID,
109                                                 void* inClientData);
110 
111         OSStatus GetDeviceIDFromUID(const char* UID, AudioDeviceID* id);
112         OSStatus GetDefaultDevice(AudioDeviceID* id);
113         OSStatus GetDefaultInputDevice(AudioDeviceID* id);
114         OSStatus GetDefaultOutputDevice(AudioDeviceID* id);
115         OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name);
116         OSStatus GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput);
117         OSStatus GetStreamLatencies(AudioDeviceID device, bool isInput, vector<int>& latencies);
118 
119         // Setup
120         OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice);
121         OSStatus CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice);
122         OSStatus DestroyAggregateDevice();
123         bool IsAggregateDevice(AudioDeviceID device);
124 
125         int SetupDevices(const char* capture_driver_uid,
126                          const char* playback_driver_uid,
127                          char* capture_driver_name,
128                          char* playback_driver_name,
129                          jack_nframes_t samplerate,
130                          bool ac3_encoding);
131 
132         int SetupChannels(bool capturing,
133                           bool playing,
134                           int& inchannels,
135                           int& outchannels,
136                           int& in_nChannels,
137                           int& out_nChannels,
138                           bool strict);
139 
140         int SetupBuffers(int inchannels);
141         void DisposeBuffers();
142 
143         int SetupBufferSize(jack_nframes_t buffer_size);
144         int SetupSampleRate(jack_nframes_t samplerate);
145         int SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate);
146 
147         int OpenAUHAL(bool capturing,
148                       bool playing,
149                       int inchannels,
150                       int outchannels,
151                       int in_nChannels,
152                       int out_nChannels,
153                       const vector<int>& chan_in_list,
154                       const vector<int>& chan_out_list,
155                       jack_nframes_t nframes,
156                       jack_nframes_t samplerate);
157         void CloseAUHAL();
158 
159         int AddListeners();
160         void RemoveListeners();
161 
162         bool TakeHogAux(AudioDeviceID deviceID, bool isInput);
163         bool TakeHog();
164 
165         void UpdateLatencies();
166 
167         bool IsDigitalDevice(AudioDeviceID device);
168         OSStatus Render(AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp,  AudioBufferList* ioData);
169 
170     public:
171 
172         JackCoreAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table);
173         virtual ~JackCoreAudioDriver();
174 
175         int Open(jack_nframes_t buffer_size,
176                  jack_nframes_t samplerate,
177                  bool capturing,
178                  bool playing,
179                  int inchannels,
180                  int outchannels,
181                  const char* chan_in_list,
182                  const char* chan_out_list,
183                  bool monitor,
184                  const char* capture_driver_name,
185                  const char* playback_driver_name,
186                  jack_nframes_t capture_latency,
187                  jack_nframes_t playback_latency,
188                  int async_output_latency,
189                  int computation_grain,
190                  bool hogged,
191                  bool clock_drift,
192                  bool ac3_encoding,
193                  int ac3_bitrate,
194                  bool ac3_lfe);
195         int Close();
196 
197         int Attach();
198 
199         int Start();
200         int Stop();
201 
202         int Read();
203         int Write();
204 
205         // BufferSize can be changed
IsFixedBufferSize()206         bool IsFixedBufferSize()
207         {
208             return false;
209         }
210 
211         int SetBufferSize(jack_nframes_t buffer_size);
212 };
213 
214 } // end of namespace
215 
216 #endif
217