048e6b978b203914a1091f3f4dab763920e1c594
[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         nframes_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 (nframes_t nframes);
84     
85         int connect_and_run (BufferSet& bufs,
86                              ChanMapping in, ChanMapping out,
87                              nframes_t nframes, nframes_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         XMLNode& get_state();
99         int set_state(const XMLNode& node, int);
100         
101         bool save_preset (std::string name);
102         bool load_preset (const std::string& preset_label);
103         std::vector<PresetRecord> get_presets ();
104         std::string current_preset() const;
105
106         bool has_editor () const;
107         
108         bool reconfigurable_io() const { return true; }
109         bool can_support_io_configuration (const ChanCount& in, ChanCount& out) 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   private:
146         boost::shared_ptr<CAComponent> comp;
147         boost::shared_ptr<CAAudioUnit> unit;
148         
149         bool initialized;
150         int32_t input_channels;
151         int32_t output_channels;
152         std::vector<std::pair<int,int> > io_configs;
153         nframes_t _current_block_size;
154         nframes_t _last_nframes;
155         bool _requires_fixed_size_buffers;
156         AudioBufferList* buffers;
157         bool _has_midi_input;
158         bool _has_midi_output;
159
160         /* despite all the cool work that apple did on their AU preset
161            system, they left factory presets and user presets as two
162            entirely different kinds of things, handled by two entirely
163            different parts of the API. Resolve this.
164         */
165
166         /* XXX these two maps should really be shared across all instances of this AUPlugin */
167
168         typedef std::map<std::string,std::string> UserPresetMap;
169         UserPresetMap user_preset_map;
170         typedef std::map<std::string,int> FactoryPresetMap;
171         FactoryPresetMap factory_preset_map;
172
173         UInt32 global_elements;
174         UInt32 output_elements;
175         UInt32 input_elements;
176         
177         int set_output_format (AudioStreamBasicDescription&);
178         int set_input_format (AudioStreamBasicDescription&);
179         int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
180         void discover_parameters ();
181
182         std::vector<std::pair<uint32_t, uint32_t> > parameter_map;
183         uint32_t current_maxbuf;
184         nframes_t current_offset;
185         nframes_t cb_offset;
186         BufferSet* current_buffers;
187         nframes_t frames_processed;
188         
189         std::vector<AUParameterDescriptor> descriptors;
190         void init ();
191
192         void discover_factory_presets ();
193
194         bool      last_transport_rolling;
195         float     last_transport_speed;
196 };
197         
198 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
199
200 struct AUPluginCachedInfo { 
201         std::vector<std::pair<int,int> > io_configs;
202 };
203
204 class AUPluginInfo : public PluginInfo {
205   public:       
206          AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
207         ~AUPluginInfo ();
208
209         PluginPtr load (Session& session);
210
211         bool needs_midi_input ();
212         bool is_effect () const;
213         bool is_effect_without_midi_input () const;
214         bool is_effect_with_midi_input () const;
215         bool is_instrument () const;
216
217         AUPluginCachedInfo cache;
218
219         static PluginInfoList* discover ();
220         static void get_names (CAComponentDescription&, std::string& name, std::string& maker);
221         static std::string stringify_descriptor (const CAComponentDescription&);
222
223         static int load_cached_info ();
224
225   private:
226         boost::shared_ptr<CAComponentDescription> descriptor;
227         UInt32 version;
228         
229         static void discover_music (PluginInfoList&);
230         static void discover_fx (PluginInfoList&);
231         static void discover_generators (PluginInfoList&);
232         static void discover_instruments (PluginInfoList&);
233         static void discover_by_description (PluginInfoList&, CAComponentDescription&);
234         static Glib::ustring au_cache_path ();
235
236         typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
237         static CachedInfoMap cached_info;
238         
239         static bool cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
240         static void add_cached_info (const std::string&, AUPluginCachedInfo&);
241         static void save_cached_info ();        
242 };
243
244 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
245
246 } // namespace ARDOUR
247
248 #endif // __ardour_audio_unit_h__