1 /* 2 * Copyright (C) 2015-2017 Robin Gareus <robin@gareus.org> 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 along 15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 */ 18 19 #ifndef __libbackend_coreaudio_pcmio_h__ 20 #define __libbackend_coreaudio_pcmio_h__ 21 22 #include <CoreServices/CoreServices.h> 23 #include <CoreAudio/CoreAudio.h> 24 #include <AudioUnit/AudioUnit.h> 25 26 #include <AudioUnit/AudioUnit.h> 27 #include <AudioToolbox/AudioToolbox.h> 28 29 #undef nil 30 31 #include <map> 32 #include <vector> 33 #include <string> 34 35 #define AUHAL_OUTPUT_ELEMENT 0 36 #define AUHAL_INPUT_ELEMENT 1 37 38 39 namespace PBD { 40 class Timing; 41 } 42 43 namespace ARDOUR { 44 45 class CoreAudioPCM { 46 public: 47 CoreAudioPCM (void); 48 ~CoreAudioPCM (void); 49 50 state(void)51 int state (void) const { return _state; } n_playback_channels(void)52 uint32_t n_playback_channels (void) const { return _playback_channels; } n_capture_channels(void)53 uint32_t n_capture_channels (void) const { return _capture_channels; } 54 55 void discover(); device_list(std::map<size_t,std::string> & devices)56 void device_list (std::map<size_t, std::string> &devices) const { devices = _devices;} input_device_list(std::map<size_t,std::string> & devices)57 void input_device_list (std::map<size_t, std::string> &devices) const { devices = _input_devices;} output_device_list(std::map<size_t,std::string> & devices)58 void output_device_list (std::map<size_t, std::string> &devices) const { devices = _output_devices;} duplex_device_list(std::map<size_t,std::string> & devices)59 void duplex_device_list (std::map<size_t, std::string> &devices) const { devices = _duplex_devices;} 60 61 int available_sample_rates (uint32_t device_id, std::vector<float>& sampleRates); 62 int available_buffer_sizes (uint32_t device_id, std::vector<uint32_t>& sampleRates); 63 uint32_t available_channels (uint32_t device_id, bool input); 64 float current_sample_rate (uint32_t device_id, bool input = false); 65 uint32_t get_latency (uint32_t device_id, bool input); 66 uint32_t get_latency (bool input); 67 68 std::string cached_port_name (uint32_t portnum, bool input) const; 69 70 float sample_rate (); samples_per_period()71 uint32_t samples_per_period () const { return _samples_per_period; }; 72 73 int set_samples_per_period (uint32_t); 74 75 void launch_control_app (uint32_t device_id); 76 77 void pcm_stop (void); 78 int pcm_start ( 79 uint32_t input_device, 80 uint32_t output_device, 81 uint32_t sample_rate, 82 uint32_t samples_per_period, 83 int (process_callback (void*, const uint32_t, const uint64_t)), 84 void * process_arg, 85 PBD::TimingStats& dsp_timer 86 ); 87 set_error_callback(void (error_callback (void *)),void * error_arg)88 void set_error_callback ( 89 void ( error_callback (void*)), 90 void * error_arg 91 ) { 92 _error_callback = error_callback; 93 _error_arg = error_arg; 94 } 95 set_hw_changed_callback(void (callback (void *)),void * arg)96 void set_hw_changed_callback ( 97 void ( callback (void*)), 98 void * arg 99 ) { 100 _hw_changed_callback = callback; 101 _hw_changed_arg = arg; 102 } 103 set_xrun_callback(void (callback (void *)),void * arg)104 void set_xrun_callback ( 105 void ( callback (void*)), 106 void * arg 107 ) { 108 _xrun_callback = callback; 109 _xrun_arg = arg; 110 } set_buffer_size_callback(void (callback (void *)),void * arg)111 void set_buffer_size_callback ( 112 void ( callback (void*)), 113 void * arg 114 ) { 115 _buffer_size_callback = callback; 116 _buffer_size_arg = arg; 117 } set_sample_rate_callback(void (callback (void *)),void * arg)118 void set_sample_rate_callback ( 119 void ( callback (void*)), 120 void * arg 121 ) { 122 _sample_rate_callback = callback; 123 _sample_rate_arg = arg; 124 } 125 126 // must be called from process_callback; 127 int get_capture_channel (uint32_t chn, float *input, uint32_t n_samples); 128 int set_playback_channel (uint32_t chn, const float *input, uint32_t n_samples); n_samples()129 uint32_t n_samples() const { return _cur_samples_per_period; }; 130 131 // really private 132 OSStatus render_callback ( 133 AudioUnitRenderActionFlags* ioActionFlags, 134 const AudioTimeStamp* inTimeStamp, 135 UInt32 inBusNumber, 136 UInt32 inNumberSamples, 137 AudioBufferList* ioData); 138 139 void xrun_callback (); 140 void buffer_size_callback (); 141 void sample_rate_callback (); 142 void hw_changed_callback (); 143 144 private: 145 float current_sample_rate_id (AudioDeviceID id, bool input); 146 uint32_t current_buffer_size_id (AudioDeviceID id); 147 int set_device_sample_rate_id (AudioDeviceID id, float rate, bool input); 148 int set_device_buffer_size_id (AudioDeviceID id, uint32_t samples_per_period); 149 int set_device_sample_rate (uint32_t device_id, float rate, bool input); 150 void get_stream_latencies (uint32_t device_id, bool input, std::vector<uint32_t>& latencies); 151 void cache_port_names (AudioDeviceID id, bool input); 152 153 void destroy_aggregate_device(); 154 int create_aggregate_device( 155 AudioDeviceID input_device_id, 156 AudioDeviceID output_device_id, 157 uint32_t sample_rate, 158 AudioDeviceID *created_device); 159 160 161 ::AudioUnit _auhal; 162 AudioDeviceID* _device_ids; 163 AudioBufferList* _input_audio_buffer_list; 164 AudioBufferList* _output_audio_buffer_list; 165 166 AudioDeviceID _active_device_id; 167 AudioDeviceID _aggregate_device_id; 168 AudioDeviceID _aggregate_plugin_id; 169 170 int _state; 171 172 uint32_t _samples_per_period; 173 uint32_t _cur_samples_per_period; 174 uint32_t _capture_channels; 175 uint32_t _playback_channels; 176 bool _in_process; 177 size_t _n_devices; 178 179 int (* _process_callback) (void*, const uint32_t, const uint64_t); 180 void * _process_arg; 181 182 PBD::TimingStats* _dsp_timer; 183 184 void (* _error_callback) (void*); 185 void * _error_arg; 186 187 void (* _hw_changed_callback) (void*); 188 void * _hw_changed_arg; 189 190 void (* _xrun_callback) (void*); 191 void * _xrun_arg; 192 193 void (* _buffer_size_callback) (void*); 194 void * _buffer_size_arg; 195 196 void (* _sample_rate_callback) (void*); 197 void * _sample_rate_arg; 198 199 200 // TODO proper device info struct 201 std::map<size_t, std::string> _devices; 202 std::map<size_t, std::string> _input_devices; 203 std::map<size_t, std::string> _output_devices; 204 std::map<size_t, std::string> _duplex_devices; 205 uint32_t * _device_ins; 206 uint32_t * _device_outs; 207 std::vector<std::string> _input_names; 208 std::vector<std::string> _output_names; 209 210 pthread_mutex_t _discovery_lock; 211 }; 212 213 } // namespace 214 215 #endif /* __libbackend_coreaudio_pcmio_h__ */ 216