1 /* 2 Copyright (C) 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 __JackCoreAudioAdapter__ 21 #define __JackCoreAudioAdapter__ 22 23 #include "JackAudioAdapterInterface.h" 24 #include "jack.h" 25 #include "jslist.h" 26 #include <AudioToolbox/AudioConverter.h> 27 #include <CoreAudio/CoreAudio.h> 28 #include <AudioUnit/AudioUnit.h> 29 30 #include <vector> 31 32 using namespace std; 33 34 namespace Jack 35 { 36 37 typedef UInt8 CAAudioHardwareDeviceSectionID; 38 #define kAudioDeviceSectionInput ((CAAudioHardwareDeviceSectionID)0x01) 39 #define kAudioDeviceSectionOutput ((CAAudioHardwareDeviceSectionID)0x00) 40 #define kAudioDeviceSectionGlobal ((CAAudioHardwareDeviceSectionID)0x00) 41 #define kAudioDeviceSectionWildcard ((CAAudioHardwareDeviceSectionID)0xFF) 42 43 #define WAIT_COUNTER 60 44 45 /*! 46 \brief Audio adapter using CoreAudio API. 47 */ 48 49 class JackCoreAudioAdapter : public JackAudioAdapterInterface 50 { 51 52 private: 53 54 AudioUnit fAUHAL; 55 AudioBufferList* fInputData; 56 57 char fCaptureUID[256]; 58 char fPlaybackUID[256]; 59 60 bool fCapturing; 61 bool fPlaying; 62 63 AudioDeviceID fDeviceID; // Used "duplex" device 64 AudioObjectID fPluginID; // Used for aggregate device 65 66 vector<int> fInputLatencies; 67 vector<int> fOutputLatencies; 68 69 bool fState; 70 71 AudioUnitRenderActionFlags* fActionFags; 72 AudioTimeStamp* fCurrentTime; 73 bool fClockDriftCompensate; 74 75 static OSStatus Render(void *inRefCon, 76 AudioUnitRenderActionFlags *ioActionFlags, 77 const AudioTimeStamp *inTimeStamp, 78 UInt32 inBusNumber, 79 UInt32 inNumberFrames, 80 AudioBufferList *ioData); 81 82 static OSStatus AudioHardwareNotificationCallback(AudioHardwarePropertyID inPropertyID,void* inClientData); 83 84 static OSStatus SRNotificationCallback(AudioDeviceID inDevice, 85 UInt32 inChannel, 86 Boolean isInput, 87 AudioDevicePropertyID inPropertyID, 88 void* inClientData); 89 static OSStatus DeviceNotificationCallback(AudioDeviceID inDevice, 90 UInt32 inChannel, 91 Boolean isInput, 92 AudioDevicePropertyID inPropertyID, 93 void* inClientData); 94 95 OSStatus GetDefaultDevice(AudioDeviceID* id); 96 OSStatus GetTotalChannels(AudioDeviceID device, int& channelCount, bool isInput); 97 OSStatus GetDeviceIDFromUID(const char* UID, AudioDeviceID* id); 98 OSStatus GetDefaultInputDevice(AudioDeviceID* id); 99 OSStatus GetDefaultOutputDevice(AudioDeviceID* id); 100 OSStatus GetDeviceNameFromID(AudioDeviceID id, char* name); 101 AudioDeviceID GetDeviceIDFromName(const char* name); 102 103 // Setup 104 OSStatus CreateAggregateDevice(AudioDeviceID captureDeviceID, AudioDeviceID playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); 105 OSStatus CreateAggregateDeviceAux(vector<AudioDeviceID> captureDeviceID, vector<AudioDeviceID> playbackDeviceID, jack_nframes_t samplerate, AudioDeviceID* outAggregateDevice); 106 OSStatus DestroyAggregateDevice(); 107 bool IsAggregateDevice(AudioDeviceID device); 108 109 int SetupDevices(const char* capture_driver_uid, 110 const char* playback_driver_uid, 111 char* capture_driver_name, 112 char* playback_driver_name, 113 jack_nframes_t samplerate); 114 115 int SetupChannels(bool capturing, 116 bool playing, 117 int& inchannels, 118 int& outchannels, 119 int& in_nChannels, 120 int& out_nChannels, 121 bool strict); 122 123 int OpenAUHAL(bool capturing, 124 bool playing, 125 int inchannels, 126 int outchannels, 127 int in_nChannels, 128 int out_nChannels, 129 jack_nframes_t buffer_size, 130 jack_nframes_t samplerate); 131 132 int SetupBufferSize(jack_nframes_t buffer_size); 133 int SetupSampleRate(jack_nframes_t samplerate); 134 int SetupSampleRateAux(AudioDeviceID inDevice, jack_nframes_t samplerate); 135 136 int SetupBuffers(int inchannels); 137 void DisposeBuffers(); 138 void CloseAUHAL(); 139 140 int AddListeners(); 141 void RemoveListeners(); 142 143 int GetLatency(int port_index, bool input); 144 OSStatus GetStreamLatencies(AudioDeviceID device, bool isInput, vector<int>& latencies); 145 146 OSStatus Render(AudioUnitRenderActionFlags *ioActionFlags, 147 const AudioTimeStamp *inTimeStamp, 148 UInt32 inNumberFrames, 149 AudioBufferList *ioData); 150 151 public: 152 153 JackCoreAudioAdapter(jack_nframes_t buffer_size, jack_nframes_t sample_rate, const JSList* params); ~JackCoreAudioAdapter()154 ~JackCoreAudioAdapter() 155 {} 156 157 virtual int Open(); 158 virtual int Close(); 159 160 virtual int SetSampleRate(jack_nframes_t sample_rate); 161 virtual int SetBufferSize(jack_nframes_t buffer_size); 162 163 virtual int GetInputLatency(int port_index); 164 virtual int GetOutputLatency(int port_index); 165 }; 166 167 168 } // end of namespace 169 170 #ifdef __cplusplus 171 extern "C" 172 { 173 #endif 174 175 #include "JackCompilerDeps.h" 176 #include "driver_interface.h" 177 178 SERVER_EXPORT jack_driver_desc_t* jack_get_descriptor(); 179 180 #ifdef __cplusplus 181 } 182 #endif 183 184 #endif 185