Merge branch 'master' into cairocanvas
[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 LIBARDOUR_API AudioBufferList;
45
46 namespace ARDOUR {
47
48 class AudioEngine;
49 class Session;
50
51 struct LIBARDOUR_API AUParameterDescriptor : public Plugin::ParameterDescriptor {
52         // additional fields to make operations more efficient
53         AudioUnitParameterID id;
54         AudioUnitScope scope;
55         AudioUnitElement element;
56         float default_value;
57         bool automatable;
58         AudioUnitParameterUnit unit;
59 };
60
61 class LIBARDOUR_API AUPlugin : public ARDOUR::Plugin
62 {
63   public:
64         AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> comp);
65         AUPlugin (const AUPlugin& other);
66         virtual ~AUPlugin ();
67
68         std::string unique_id () const;
69         const char * label () const;
70         const char * name () const { return _info->name.c_str(); }
71         const char * maker () const { return _info->creator.c_str(); }
72         uint32_t parameter_count () const;
73         float default_value (uint32_t port);
74         framecnt_t signal_latency() const;
75         void set_parameter (uint32_t which, float val);
76         float get_parameter (uint32_t which) const;
77
78         int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
79         uint32_t nth_parameter (uint32_t which, bool& ok) const;
80         void activate ();
81         void deactivate ();
82         void flush ();
83         int set_block_size (pframes_t nframes);
84
85         int connect_and_run (BufferSet& bufs,
86                              ChanMapping in, ChanMapping out,
87                              pframes_t nframes, framecnt_t offset);
88         std::set<Evoral::Parameter> automatable() const;
89         std::string describe_parameter (Evoral::Parameter);
90         std::string state_node_name () const { return "audiounit"; }
91         void print_parameter (uint32_t, char*, uint32_t len) const;
92
93         bool parameter_is_audio (uint32_t) const;
94         bool parameter_is_control (uint32_t) const;
95         bool parameter_is_input (uint32_t) const;
96         bool parameter_is_output (uint32_t) const;
97         
98         void set_info (PluginInfoPtr);
99
100         int set_state(const XMLNode& node, int);
101
102         bool load_preset (PresetRecord);
103         std::string current_preset() const;
104
105         bool has_editor () const;
106
107         bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
108         ChanCount output_streams() const;
109         ChanCount input_streams() const;
110         bool configure_io (ChanCount in, ChanCount out);
111         bool requires_fixed_size_buffers() const;
112
113         void set_fixed_size_buffers (bool yn) {
114                 _requires_fixed_size_buffers = yn;
115         }
116
117         boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
118         boost::shared_ptr<CAComponent> get_comp () const { return comp; }
119
120         OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
121                                  const AudioTimeStamp       *inTimeStamp,
122                                  UInt32                      inBusNumber,
123                                  UInt32                      inNumberFrames,
124                                  AudioBufferList*            ioData);
125
126         /* "host" callbacks */
127
128         OSStatus get_beat_and_tempo_callback (Float64* outCurrentBeat,
129                                               Float64* outCurrentTempo);
130
131         OSStatus get_musical_time_location_callback (UInt32*  outDeltaSampleOffsetToNextBeat,
132                                                      Float32*  outTimeSig_Numerator,
133                                                      UInt32*   outTimeSig_Denominator,
134                                                      Float64*  outCurrentMeasureDownBeat);
135
136         OSStatus get_transport_state_callback (Boolean*  outIsPlaying,
137                                                Boolean*  outTransportStateChanged,
138                                                Float64*  outCurrentSampleInTimeLine,
139                                                Boolean*  outIsCycling,
140                                                Float64*  outCycleStartBeat,
141                                                Float64*  outCycleEndBeat);
142
143         static std::string maybe_fix_broken_au_id (const std::string&);
144
145         /* this MUST be called from thread in which you want to receive notifications
146            about parameter changes.
147         */
148         int create_parameter_listener (AUEventListenerProc callback, void *arg, float interval_secs);
149         /* these can be called from any thread but SHOULD be called from the same thread
150            that will receive parameter change notifications.
151         */
152         int listen_to_parameter (uint32_t param_id);
153         int end_listen_to_parameter (uint32_t param_id);
154
155
156   protected:
157         std::string do_save_preset (std::string name);
158         void do_remove_preset (std::string);
159
160   private:
161         void find_presets ();
162
163         boost::shared_ptr<CAComponent> comp;
164         boost::shared_ptr<CAAudioUnit> unit;
165
166         bool initialized;
167         int32_t input_channels;
168         int32_t output_channels;
169         std::vector<std::pair<int,int> > io_configs;
170         pframes_t _current_block_size;
171         framecnt_t _last_nframes;
172         bool _requires_fixed_size_buffers;
173         AudioBufferList* buffers;
174         bool _has_midi_input;
175         bool _has_midi_output;
176
177         /* despite all the cool work that apple did on their AU preset
178            system, they left factory presets and user presets as two
179            entirely different kinds of things, handled by two entirely
180            different parts of the API. Resolve this.
181         */
182
183         /* XXX these two maps should really be shared across all instances of this AUPlugin */
184
185         typedef std::map<std::string,std::string> UserPresetMap;
186         UserPresetMap user_preset_map;
187         typedef std::map<std::string,int> FactoryPresetMap;
188         FactoryPresetMap factory_preset_map;
189
190         UInt32 global_elements;
191         UInt32 output_elements;
192         UInt32 input_elements;
193
194         int set_output_format (AudioStreamBasicDescription&);
195         int set_input_format (AudioStreamBasicDescription&);
196         int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
197         void discover_parameters ();
198         void add_state (XMLNode *) const;
199
200         typedef std::map<uint32_t, uint32_t> ParameterMap;
201         ParameterMap parameter_map;
202         uint32_t   input_maxbuf;
203         framecnt_t input_offset;
204         framecnt_t cb_offset;
205         BufferSet* input_buffers;
206         framecnt_t frames_processed;
207
208         std::vector<AUParameterDescriptor> descriptors;
209         AUEventListenerRef _parameter_listener;
210         void * _parameter_listener_arg;
211         void init ();
212
213         void discover_factory_presets ();
214
215         bool      last_transport_rolling;
216         float     last_transport_speed;
217
218         static void _parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value);
219         void parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value);
220 };
221
222 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
223
224 struct LIBARDOUR_API AUPluginCachedInfo {
225         std::vector<std::pair<int,int> > io_configs;
226 };
227
228 class LIBARDOUR_API AUPluginInfo : public PluginInfo {
229   public:
230          AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
231         ~AUPluginInfo ();
232
233         PluginPtr load (Session& session);
234
235         bool needs_midi_input ();
236         bool is_effect () const;
237         bool is_effect_without_midi_input () const;
238         bool is_effect_with_midi_input () const;
239         bool is_instrument () const;
240
241         AUPluginCachedInfo cache;
242
243         bool reconfigurable_io() const { return true; }
244
245         static PluginInfoList* discover ();
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
255         static void discover_music (PluginInfoList&);
256         static void discover_fx (PluginInfoList&);
257         static void discover_generators (PluginInfoList&);
258         static void discover_instruments (PluginInfoList&);
259         static void discover_by_description (PluginInfoList&, CAComponentDescription&);
260         static Glib::ustring au_cache_path ();
261
262         typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
263         static CachedInfoMap cached_info;
264
265         static bool cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
266         static void add_cached_info (const std::string&, AUPluginCachedInfo&);
267         static void save_cached_info ();
268 };
269
270 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
271
272 } // namespace ARDOUR
273
274 #endif // __ardour_audio_unit_h__