2 Copyright (C) 2006 Paul Davis
3 Written by Taybin Rutkin
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.
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.
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.
21 #ifndef __ardour_audio_unit_h__
22 #define __ardour_audio_unit_h__
25 #include <boost/shared_ptr.hpp>
33 #include "ardour/plugin.h"
35 #include <AudioUnit/AudioUnit.h>
36 #include <AudioUnit/AudioUnitProperties.h>
37 #include "AUParamInfo.h"
39 #include <boost/shared_ptr.hpp>
43 class CAComponentDescription;
44 struct AudioBufferList;
51 struct LIBARDOUR_API AUParameterDescriptor : public ParameterDescriptor {
52 // additional fields to make operations more efficient
53 AudioUnitParameterID id;
55 AudioUnitElement element;
57 AudioUnitParameterUnit au_unit;
60 class LIBARDOUR_API AUPlugin : public ARDOUR::Plugin
63 AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> comp);
64 AUPlugin (const AUPlugin& other);
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;
77 PluginOutputConfiguration possible_output () const { return _output_configs; }
79 int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
80 uint32_t nth_parameter (uint32_t which, bool& ok) const;
84 int set_block_size (pframes_t nframes);
86 int connect_and_run (BufferSet& bufs,
87 framepos_t start, framepos_t end, double speed,
88 ChanMapping in, ChanMapping out,
89 pframes_t nframes, framecnt_t offset);
90 std::set<Evoral::Parameter> automatable() const;
91 std::string describe_parameter (Evoral::Parameter);
92 IOPortDescription describe_io_port (DataType dt, bool input, uint32_t id) const;
93 std::string state_node_name () const { return "audiounit"; }
94 void print_parameter (uint32_t, char*, uint32_t len) const;
96 bool parameter_is_audio (uint32_t) const;
97 bool parameter_is_control (uint32_t) const;
98 bool parameter_is_input (uint32_t) const;
99 bool parameter_is_output (uint32_t) const;
101 void set_info (PluginInfoPtr);
103 int set_state(const XMLNode& node, int);
105 bool load_preset (PresetRecord);
106 std::string current_preset() const;
108 bool has_editor () const;
110 bool can_support_io_configuration (const ChanCount& in, ChanCount& out, ChanCount* imprecise);
111 ChanCount output_streams() const;
112 ChanCount input_streams() const;
113 bool configure_io (ChanCount in, ChanCount out);
114 bool requires_fixed_size_buffers() const;
116 void set_fixed_size_buffers (bool yn) {
117 _requires_fixed_size_buffers = yn;
120 boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
121 boost::shared_ptr<CAComponent> get_comp () const { return comp; }
123 OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
124 const AudioTimeStamp *inTimeStamp,
126 UInt32 inNumberFrames,
127 AudioBufferList* ioData);
129 /* "host" callbacks */
131 OSStatus get_beat_and_tempo_callback (Float64* outCurrentBeat,
132 Float64* outCurrentTempo);
134 OSStatus get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNextBeat,
135 Float32* outTimeSig_Numerator,
136 UInt32* outTimeSig_Denominator,
137 Float64* outCurrentMeasureDownBeat);
139 OSStatus get_transport_state_callback (Boolean* outIsPlaying,
140 Boolean* outTransportStateChanged,
141 Float64* outCurrentSampleInTimeLine,
142 Boolean* outIsCycling,
143 Float64* outCycleStartBeat,
144 Float64* outCycleEndBeat);
146 static std::string maybe_fix_broken_au_id (const std::string&);
148 /* this MUST be called from thread in which you want to receive notifications
149 about parameter changes.
151 int create_parameter_listener (AUEventListenerProc callback, void *arg, float interval_secs);
152 /* these can be called from any thread but SHOULD be called from the same thread
153 that will receive parameter change notifications.
155 int listen_to_parameter (uint32_t param_id);
156 int end_listen_to_parameter (uint32_t param_id);
160 std::string do_save_preset (std::string name);
161 void do_remove_preset (std::string);
164 void find_presets ();
166 boost::shared_ptr<CAComponent> comp;
167 boost::shared_ptr<CAAudioUnit> unit;
170 int32_t input_channels;
171 int32_t output_channels;
172 std::vector<std::pair<int,int> > io_configs;
173 pframes_t _current_block_size;
174 framecnt_t _last_nframes;
175 framepos_t _transport_frame;
176 framepos_t _transport_speed;
177 bool _requires_fixed_size_buffers;
178 AudioBufferList* buffers;
179 bool _has_midi_input;
180 bool _has_midi_output;
181 PluginOutputConfiguration _output_configs;
183 /* despite all the cool work that apple did on their AU preset
184 system, they left factory presets and user presets as two
185 entirely different kinds of things, handled by two entirely
186 different parts of the API. Resolve this.
189 /* XXX these two maps should really be shared across all instances of this AUPlugin */
191 typedef std::map<std::string,std::string> UserPresetMap;
192 UserPresetMap user_preset_map;
193 typedef std::map<std::string,int> FactoryPresetMap;
194 FactoryPresetMap factory_preset_map;
196 UInt32 global_elements;
197 UInt32 output_elements;
198 UInt32 input_elements;
200 bool variable_inputs;
201 bool variable_outputs;
203 uint32_t configured_input_busses;
204 uint32_t configured_output_busses;
206 uint32_t *bus_inputs;
207 uint32_t *bus_outputs;
208 std::vector <std::string> _bus_name_in;
209 std::vector <std::string> _bus_name_out;
211 int set_stream_format (int scope, uint32_t bus, AudioStreamBasicDescription&);
212 void discover_parameters ();
213 void add_state (XMLNode *) const;
215 typedef std::map<uint32_t, uint32_t> ParameterMap;
216 ParameterMap parameter_map;
217 uint32_t input_maxbuf;
218 framecnt_t input_offset;
219 framecnt_t *cb_offsets;
220 BufferSet* input_buffers;
221 ChanMapping * input_map;
222 framecnt_t frames_processed;
223 uint32_t audio_input_cnt;
225 std::vector<AUParameterDescriptor> descriptors;
226 AUEventListenerRef _parameter_listener;
227 void * _parameter_listener_arg;
230 void discover_factory_presets ();
232 framepos_t transport_frame;
233 float transport_speed;
234 float last_transport_speed;
236 static void _parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value);
237 void parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value);
240 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
242 struct LIBARDOUR_API AUPluginCachedInfo {
243 std::vector<std::pair<int,int> > io_configs;
246 class LIBARDOUR_API AUPluginInfo : public PluginInfo {
248 AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
251 PluginPtr load (Session& session);
253 std::vector<Plugin::PresetRecord> get_presets (bool user_only) const;
255 bool needs_midi_input () const;
256 bool is_effect () const;
257 bool is_effect_without_midi_input () const;
258 bool is_effect_with_midi_input () const;
259 bool is_instrument () const;
261 AUPluginCachedInfo cache;
263 bool reconfigurable_io() const { return true; }
265 static void clear_cache ();
266 static PluginInfoList* discover (bool scan_only);
267 static bool au_get_crashlog (std::string &msg);
268 static std::string stringify_descriptor (const CAComponentDescription&);
270 static int load_cached_info ();
273 boost::shared_ptr<CAComponentDescription> descriptor;
275 static FILE * _crashlog_fd;
276 static bool _scan_only;
278 static void au_start_crashlog (void);
279 static void au_remove_crashlog (void);
280 static void au_crashlog (std::string);
282 static void discover_music (PluginInfoList&);
283 static void discover_fx (PluginInfoList&);
284 static void discover_generators (PluginInfoList&);
285 static void discover_instruments (PluginInfoList&);
286 static void discover_by_description (PluginInfoList&, CAComponentDescription&);
287 static Glib::ustring au_cache_path ();
289 typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
290 static CachedInfoMap cached_info;
292 static int cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
293 static void add_cached_info (const std::string&, AUPluginCachedInfo&);
294 static void save_cached_info ();
297 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
299 } // namespace ARDOUR
301 #endif // __ardour_audio_unit_h__