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