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