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 samplecnt_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 samplepos_t start, samplepos_t end, double speed,
88 ChanMapping in, ChanMapping out,
89 pframes_t nframes, samplecnt_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 inNumberSamples,
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 samplecnt_t _last_nframes;
174 mutable volatile guint _current_latency;
175 bool _requires_fixed_size_buffers;
176 AudioBufferList* buffers;
177 bool _has_midi_input;
178 bool _has_midi_output;
179 PluginOutputConfiguration _output_configs;
181 /* despite all the cool work that apple did on their AU preset
182 system, they left factory presets and user presets as two
183 entirely different kinds of things, handled by two entirely
184 different parts of the API. Resolve this.
187 /* XXX these two maps should really be shared across all instances of this AUPlugin */
189 typedef std::map<std::string,std::string> UserPresetMap;
190 UserPresetMap user_preset_map;
191 typedef std::map<std::string,int> FactoryPresetMap;
192 FactoryPresetMap factory_preset_map;
194 UInt32 global_elements;
195 UInt32 output_elements;
196 UInt32 input_elements;
198 bool variable_inputs;
199 bool variable_outputs;
201 uint32_t configured_input_busses;
202 uint32_t configured_output_busses;
204 uint32_t *bus_inputs;
205 uint32_t *bus_outputs;
206 std::vector <std::string> _bus_name_in;
207 std::vector <std::string> _bus_name_out;
209 int set_stream_format (int scope, uint32_t bus, AudioStreamBasicDescription&);
210 void discover_parameters ();
211 void add_state (XMLNode *) const;
213 typedef std::map<uint32_t, uint32_t> ParameterMap;
214 ParameterMap parameter_map;
215 uint32_t input_maxbuf;
216 samplecnt_t input_offset;
217 samplecnt_t *cb_offsets;
218 BufferSet* input_buffers;
219 ChanMapping * input_map;
220 samplecnt_t samples_processed;
221 uint32_t audio_input_cnt;
223 std::vector<AUParameterDescriptor> descriptors;
224 AUEventListenerRef _parameter_listener;
225 void * _parameter_listener_arg;
228 void discover_factory_presets ();
230 samplepos_t transport_sample;
231 float transport_speed;
232 float last_transport_speed;
234 static void _parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value);
235 void parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value);
238 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
240 struct LIBARDOUR_API AUPluginCachedInfo {
241 std::vector<std::pair<int,int> > io_configs;
244 class LIBARDOUR_API AUPluginInfo : public PluginInfo {
246 AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
249 PluginPtr load (Session& session);
251 std::vector<Plugin::PresetRecord> get_presets (bool user_only) const;
253 bool needs_midi_input () const;
254 bool is_effect_without_midi_input () const;
255 bool is_effect_with_midi_input () const;
257 /* note: AU's have an explicit way to prompt for instrument/fx category */
258 bool is_effect () const;
259 bool is_instrument () const;
260 bool is_utility () const;
262 AUPluginCachedInfo cache;
264 bool reconfigurable_io() const { return true; }
266 static void clear_cache ();
267 static PluginInfoList* discover (bool scan_only);
268 static bool au_get_crashlog (std::string &msg);
269 static std::string stringify_descriptor (const CAComponentDescription&);
271 static int load_cached_info ();
274 boost::shared_ptr<CAComponentDescription> descriptor;
276 static FILE * _crashlog_fd;
277 static bool _scan_only;
279 static void au_start_crashlog (void);
280 static void au_remove_crashlog (void);
281 static void au_crashlog (std::string);
283 static void discover_music (PluginInfoList&);
284 static void discover_fx (PluginInfoList&);
285 static void discover_generators (PluginInfoList&);
286 static void discover_instruments (PluginInfoList&);
287 static void discover_by_description (PluginInfoList&, CAComponentDescription&);
288 static Glib::ustring au_cache_path ();
290 typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
291 static CachedInfoMap cached_info;
293 static int cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
294 static void add_cached_info (const std::string&, AUPluginCachedInfo&);
295 static void save_cached_info ();
298 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
300 } // namespace ARDOUR
302 #endif // __ardour_audio_unit_h__