cont’d work on the coreaudio backend & cleanup
[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 #include <CoreServices/CoreServices.h>
20 #include <CoreAudio/CoreAudio.h>
21 #include <AudioUnit/AudioUnit.h>
22
23 #include <AudioUnit/AudioUnit.h>
24 #include <AudioToolbox/AudioToolbox.h>
25
26 #include <map>
27 #include <vector>
28 #include <string>
29
30 #define AUHAL_OUTPUT_ELEMENT 0
31 #define AUHAL_INPUT_ELEMENT 1
32
33
34 class CoreAudioPCM {
35 public:
36         CoreAudioPCM (void);
37         ~CoreAudioPCM (void);
38
39
40         int      state (void) const { return _state; }
41         uint32_t n_playback_channels (void) const { return _playback_channels; }
42         uint32_t n_capture_channels (void) const { return _capture_channels; }
43
44         void     discover();
45         void     device_list(std::map<size_t, std::string> &devices) const { devices = _devices;}
46
47         int      available_sample_rates (uint32_t device_id, std::vector<float>& sampleRates);
48         int      available_buffer_sizes (uint32_t device_id, std::vector<uint32_t>& sampleRates);
49         uint32_t available_channels (uint32_t device_id, bool input);
50         float    current_sample_rate(uint32 device_id, bool input = false);
51         uint32_t get_latency(uint32 device_id, bool input);
52
53         std::string cached_port_name(uint32_t portnum, bool input) const;
54
55         void     launch_control_app (uint32_t device_id);
56
57         void     pcm_stop (void);
58         int      pcm_start (
59                         uint32_t input_device,
60                         uint32_t output_device,
61                         uint32_t sample_rate,
62                         uint32_t samples_per_period,
63                         int (process_callback (void*)),
64                         void * process_arg
65                         );
66
67         // TODO: combine callbacks below, add a enum type
68         void     set_error_callback (
69                         void ( error_callback (void*)),
70                         void * error_arg
71                         ) {
72                 _error_callback = error_callback;
73                 _error_arg = error_arg;
74         }
75
76         void     set_hw_changed_callback (
77                         void ( callback (void*)),
78                         void * arg
79                         ) {
80                 _hw_changed_callback = callback;
81                 _hw_changed_arg = arg;
82         }
83
84         // must be called from process_callback;
85         int      get_capture_channel (uint32_t chn, float *input, uint32_t n_samples);
86         int      set_playback_channel (uint32_t chn, const float *input, uint32_t n_samples);
87         uint32_t n_samples() const { return _cur_samples_per_period; };
88
89         // really private
90         OSStatus render_callback (
91                         AudioUnitRenderActionFlags* ioActionFlags,
92                         const AudioTimeStamp* inTimeStamp,
93                         UInt32 inBusNumber,
94                         UInt32 inNumberFrames,
95                         AudioBufferList* ioData);
96
97         void hwPropertyChange();
98
99 private:
100         int set_device_sample_rate (uint32 device_id, float rate, bool input);
101         void get_stream_latencies(uint32 device_id, bool input, std::vector<uint32>& latencies);
102         void cache_port_names(uint32 device_id, bool input);
103
104         AudioUnit _auhal;
105         AudioDeviceID* _device_ids;
106         AudioBufferList* _input_audio_buffer_list;
107         AudioBufferList* _output_audio_buffer_list;
108
109         int _state;
110
111         uint32_t _max_samples_per_period;
112         uint32_t _cur_samples_per_period;
113         uint32_t _capture_channels;
114         uint32_t _playback_channels;
115         bool     _in_process;
116         size_t   _n_devices;
117
118         int (* _process_callback) (void*);
119         void * _process_arg;
120
121         void (* _error_callback) (void*);
122         void  * _error_arg;
123
124         void (* _hw_changed_callback) (void*);
125         void  * _hw_changed_arg;
126
127         // TODO proper device info struct
128         std::map<size_t, std::string> _devices;
129         uint32_t * _device_ins;
130         uint32_t * _device_outs;
131         std::vector<std::string> _input_names;
132         std::vector<std::string> _output_names;
133
134         pthread_mutex_t _discovery_lock;
135 };