changes for OS X support: change waf config define to COREAUDIO_SUPPORT, remove Plugi...
[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 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 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 reconfigurable_io() const { return true; }
108         bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
109         ChanCount output_streams() const;
110         ChanCount input_streams() const;
111         bool configure_io (ChanCount in, ChanCount out);
112         bool requires_fixed_size_buffers() const;
113
114         void set_fixed_size_buffers (bool yn) {
115                 _requires_fixed_size_buffers = yn;
116         }
117
118         boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
119         boost::shared_ptr<CAComponent> get_comp () const { return comp; }
120
121         OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
122                                  const AudioTimeStamp       *inTimeStamp,
123                                  UInt32                      inBusNumber,
124                                  UInt32                      inNumberFrames,
125                                  AudioBufferList*            ioData);
126
127         /* "host" callbacks */
128
129         OSStatus get_beat_and_tempo_callback (Float64* outCurrentBeat,
130                                               Float64* outCurrentTempo);
131
132         OSStatus get_musical_time_location_callback (UInt32*  outDeltaSampleOffsetToNextBeat,
133                                                      Float32*  outTimeSig_Numerator,
134                                                      UInt32*   outTimeSig_Denominator,
135                                                      Float64*  outCurrentMeasureDownBeat);
136
137         OSStatus get_transport_state_callback (Boolean*  outIsPlaying,
138                                                Boolean*  outTransportStateChanged,
139                                                Float64*  outCurrentSampleInTimeLine,
140                                                Boolean*  outIsCycling,
141                                                Float64*  outCycleStartBeat,
142                                                Float64*  outCycleEndBeat);
143
144         static std::string maybe_fix_broken_au_id (const std::string&);
145
146   protected:
147         std::string do_save_preset (std::string name);
148         void do_remove_preset (std::string);
149
150   private:
151         void find_presets ();
152
153         boost::shared_ptr<CAComponent> comp;
154         boost::shared_ptr<CAAudioUnit> unit;
155
156         bool initialized;
157         int32_t input_channels;
158         int32_t output_channels;
159         std::vector<std::pair<int,int> > io_configs;
160         pframes_t _current_block_size;
161         framecnt_t _last_nframes;
162         bool _requires_fixed_size_buffers;
163         AudioBufferList* buffers;
164         bool _has_midi_input;
165         bool _has_midi_output;
166
167         /* despite all the cool work that apple did on their AU preset
168            system, they left factory presets and user presets as two
169            entirely different kinds of things, handled by two entirely
170            different parts of the API. Resolve this.
171         */
172
173         /* XXX these two maps should really be shared across all instances of this AUPlugin */
174
175         typedef std::map<std::string,std::string> UserPresetMap;
176         UserPresetMap user_preset_map;
177         typedef std::map<std::string,int> FactoryPresetMap;
178         FactoryPresetMap factory_preset_map;
179
180         UInt32 global_elements;
181         UInt32 output_elements;
182         UInt32 input_elements;
183
184         int set_output_format (AudioStreamBasicDescription&);
185         int set_input_format (AudioStreamBasicDescription&);
186         int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
187         void discover_parameters ();
188         void add_state (XMLNode *) const;
189
190         std::vector<std::pair<uint32_t, uint32_t> > parameter_map;
191         uint32_t current_maxbuf;
192         framecnt_t current_offset;
193         framecnt_t cb_offset;
194         BufferSet* current_buffers;
195         framecnt_t frames_processed;
196
197         std::vector<AUParameterDescriptor> descriptors;
198         void init ();
199
200         void discover_factory_presets ();
201
202         bool      last_transport_rolling;
203         float     last_transport_speed;
204 };
205
206 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
207
208 struct AUPluginCachedInfo {
209         std::vector<std::pair<int,int> > io_configs;
210 };
211
212 class AUPluginInfo : public PluginInfo {
213   public:
214          AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
215         ~AUPluginInfo ();
216
217         PluginPtr load (Session& session);
218
219         bool needs_midi_input ();
220         bool is_effect () const;
221         bool is_effect_without_midi_input () const;
222         bool is_effect_with_midi_input () const;
223         bool is_instrument () const;
224
225         AUPluginCachedInfo cache;
226
227         static PluginInfoList* discover ();
228         static void get_names (CAComponentDescription&, std::string& name, std::string& maker);
229         static std::string stringify_descriptor (const CAComponentDescription&);
230
231         static int load_cached_info ();
232
233   private:
234         boost::shared_ptr<CAComponentDescription> descriptor;
235         UInt32 version;
236
237         static void discover_music (PluginInfoList&);
238         static void discover_fx (PluginInfoList&);
239         static void discover_generators (PluginInfoList&);
240         static void discover_instruments (PluginInfoList&);
241         static void discover_by_description (PluginInfoList&, CAComponentDescription&);
242         static Glib::ustring au_cache_path ();
243
244         typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
245         static CachedInfoMap cached_info;
246
247         static bool cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
248         static void add_cached_info (const std::string&, AUPluginCachedInfo&);
249         static void save_cached_info ();
250 };
251
252 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
253
254 } // namespace ARDOUR
255
256 #endif // __ardour_audio_unit_h__