rename Session::add_session_range_location() to ::set_session_range_location()
[ardour.git] / libs / ardour / ardour / audio_unit.h
1 /*
2     Copyright (C) 2006 Paul Davis
3     Written by Taybin Rutkin
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #ifndef __ardour_audio_unit_h__
22 #define __ardour_audio_unit_h__
23
24 #include <stdint.h>
25 #include <boost/shared_ptr.hpp>
26
27 #include <list>
28 #include <set>
29 #include <string>
30 #include <vector>
31 #include <map>
32
33 #include "ardour/plugin.h"
34
35 #include <AudioUnit/AudioUnit.h>
36 #include <AudioUnit/AudioUnitProperties.h>
37 #include "appleutility/AUParamInfo.h"
38
39 #include <boost/shared_ptr.hpp>
40
41 class CAComponent;
42 class CAAudioUnit;
43 class CAComponentDescription;
44 struct AudioBufferList;
45
46 namespace ARDOUR {
47
48 class AudioEngine;
49 class Session;
50
51 struct LIBARDOUR_API AUParameterDescriptor : public ParameterDescriptor {
52         // additional fields to make operations more efficient
53         AudioUnitParameterID id;
54         AudioUnitScope scope;
55         AudioUnitElement element;
56         bool automatable;
57         AudioUnitParameterUnit au_unit;
58 };
59
60 class LIBARDOUR_API AUPlugin : public ARDOUR::Plugin
61 {
62   public:
63         AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> comp);
64         AUPlugin (const AUPlugin& other);
65         virtual ~AUPlugin ();
66
67         std::string unique_id () const;
68         const char * label () const;
69         const char * name () const { return _info->name.c_str(); }
70         const char * maker () const { return _info->creator.c_str(); }
71         uint32_t parameter_count () const;
72         float default_value (uint32_t port);
73         framecnt_t signal_latency() const;
74         void set_parameter (uint32_t which, float val);
75         float get_parameter (uint32_t which) const;
76
77         int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
78         uint32_t nth_parameter (uint32_t which, bool& ok) const;
79         void activate ();
80         void deactivate ();
81         void flush ();
82         int set_block_size (pframes_t nframes);
83
84         int connect_and_run (BufferSet& bufs,
85                              ChanMapping in, ChanMapping out,
86                              pframes_t nframes, framecnt_t offset);
87         std::set<Evoral::Parameter> automatable() const;
88         std::string describe_parameter (Evoral::Parameter);
89         std::string state_node_name () const { return "audiounit"; }
90         void print_parameter (uint32_t, char*, uint32_t len) const;
91
92         bool parameter_is_audio (uint32_t) const;
93         bool parameter_is_control (uint32_t) const;
94         bool parameter_is_input (uint32_t) const;
95         bool parameter_is_output (uint32_t) const;
96         
97         void set_info (PluginInfoPtr);
98
99         int set_state(const XMLNode& node, int);
100
101         bool load_preset (PresetRecord);
102         std::string current_preset() const;
103
104         bool has_editor () const;
105
106         bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
107         ChanCount output_streams() const;
108         ChanCount input_streams() const;
109         bool configure_io (ChanCount in, ChanCount out);
110         bool requires_fixed_size_buffers() const;
111
112         void set_fixed_size_buffers (bool yn) {
113                 _requires_fixed_size_buffers = yn;
114         }
115
116         boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
117         boost::shared_ptr<CAComponent> get_comp () const { return comp; }
118
119         OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
120                                  const AudioTimeStamp       *inTimeStamp,
121                                  UInt32                      inBusNumber,
122                                  UInt32                      inNumberFrames,
123                                  AudioBufferList*            ioData);
124
125         /* "host" callbacks */
126
127         OSStatus get_beat_and_tempo_callback (Float64* outCurrentBeat,
128                                               Float64* outCurrentTempo);
129
130         OSStatus get_musical_time_location_callback (UInt32*  outDeltaSampleOffsetToNextBeat,
131                                                      Float32*  outTimeSig_Numerator,
132                                                      UInt32*   outTimeSig_Denominator,
133                                                      Float64*  outCurrentMeasureDownBeat);
134
135         OSStatus get_transport_state_callback (Boolean*  outIsPlaying,
136                                                Boolean*  outTransportStateChanged,
137                                                Float64*  outCurrentSampleInTimeLine,
138                                                Boolean*  outIsCycling,
139                                                Float64*  outCycleStartBeat,
140                                                Float64*  outCycleEndBeat);
141
142         static std::string maybe_fix_broken_au_id (const std::string&);
143
144         /* this MUST be called from thread in which you want to receive notifications
145            about parameter changes.
146         */
147         int create_parameter_listener (AUEventListenerProc callback, void *arg, float interval_secs);
148         /* these can be called from any thread but SHOULD be called from the same thread
149            that will receive parameter change notifications.
150         */
151         int listen_to_parameter (uint32_t param_id);
152         int end_listen_to_parameter (uint32_t param_id);
153
154
155   protected:
156         std::string do_save_preset (std::string name);
157         void do_remove_preset (std::string);
158
159   private:
160         void find_presets ();
161
162         boost::shared_ptr<CAComponent> comp;
163         boost::shared_ptr<CAAudioUnit> unit;
164
165         bool initialized;
166         int32_t input_channels;
167         int32_t output_channels;
168         std::vector<std::pair<int,int> > io_configs;
169         pframes_t _current_block_size;
170         framecnt_t _last_nframes;
171         bool _requires_fixed_size_buffers;
172         AudioBufferList* buffers;
173         bool _has_midi_input;
174         bool _has_midi_output;
175
176         /* despite all the cool work that apple did on their AU preset
177            system, they left factory presets and user presets as two
178            entirely different kinds of things, handled by two entirely
179            different parts of the API. Resolve this.
180         */
181
182         /* XXX these two maps should really be shared across all instances of this AUPlugin */
183
184         typedef std::map<std::string,std::string> UserPresetMap;
185         UserPresetMap user_preset_map;
186         typedef std::map<std::string,int> FactoryPresetMap;
187         FactoryPresetMap factory_preset_map;
188
189         UInt32 global_elements;
190         UInt32 output_elements;
191         UInt32 input_elements;
192
193         int set_output_format (AudioStreamBasicDescription&);
194         int set_input_format (AudioStreamBasicDescription&);
195         int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
196         void discover_parameters ();
197         void add_state (XMLNode *) const;
198
199         typedef std::map<uint32_t, uint32_t> ParameterMap;
200         ParameterMap parameter_map;
201         uint32_t   input_maxbuf;
202         framecnt_t input_offset;
203         framecnt_t cb_offset;
204         BufferSet* input_buffers;
205         framecnt_t frames_processed;
206
207         std::vector<AUParameterDescriptor> descriptors;
208         AUEventListenerRef _parameter_listener;
209         void * _parameter_listener_arg;
210         void init ();
211
212         void discover_factory_presets ();
213
214         bool      last_transport_rolling;
215         float     last_transport_speed;
216
217         static void _parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value);
218         void parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value);
219 };
220
221 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
222
223 struct LIBARDOUR_API AUPluginCachedInfo {
224         std::vector<std::pair<int,int> > io_configs;
225 };
226
227 class LIBARDOUR_API AUPluginInfo : public PluginInfo {
228   public:
229          AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
230         ~AUPluginInfo ();
231
232         PluginPtr load (Session& session);
233
234         bool needs_midi_input ();
235         bool is_effect () const;
236         bool is_effect_without_midi_input () const;
237         bool is_effect_with_midi_input () const;
238         bool is_instrument () const;
239
240         AUPluginCachedInfo cache;
241
242         bool reconfigurable_io() const { return true; }
243
244         static PluginInfoList* discover ();
245         static bool au_get_crashlog (std::string &msg);
246         static void get_names (CAComponentDescription&, std::string& name, std::string& maker);
247         static std::string stringify_descriptor (const CAComponentDescription&);
248
249         static int load_cached_info ();
250
251   private:
252         boost::shared_ptr<CAComponentDescription> descriptor;
253         UInt32 version;
254         static FILE * _crashlog_fd;
255
256         static void au_start_crashlog (void);
257         static void au_remove_crashlog (void);
258         static void au_crashlog (std::string);
259
260         static void discover_music (PluginInfoList&);
261         static void discover_fx (PluginInfoList&);
262         static void discover_generators (PluginInfoList&);
263         static void discover_instruments (PluginInfoList&);
264         static void discover_by_description (PluginInfoList&, CAComponentDescription&);
265         static Glib::ustring au_cache_path ();
266
267         typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
268         static CachedInfoMap cached_info;
269
270         static bool cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
271         static void add_cached_info (const std::string&, AUPluginCachedInfo&);
272         static void save_cached_info ();
273 };
274
275 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
276
277 } // namespace ARDOUR
278
279 #endif // __ardour_audio_unit_h__