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 int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
78 uint32_t nth_parameter (uint32_t which, bool& ok) const;
82 int set_block_size (pframes_t nframes);
84 int connect_and_run (BufferSet& bufs,
85 ChanMapping in, ChanMapping out,
86 pframes_t nframes, framecnt_t offset);
87 std::set<Evoral::Parameter> automatable() const;
88 std::string describe_parameter (Evoral::Parameter);
89 std::string state_node_name () const { return "audiounit"; }
90 void print_parameter (uint32_t, char*, uint32_t len) const;
92 bool parameter_is_audio (uint32_t) const;
93 bool parameter_is_control (uint32_t) const;
94 bool parameter_is_input (uint32_t) const;
95 bool parameter_is_output (uint32_t) const;
97 void set_info (PluginInfoPtr);
99 int set_state(const XMLNode& node, int);
101 bool load_preset (PresetRecord);
102 std::string current_preset() const;
104 bool has_editor () const;
106 bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
107 ChanCount output_streams() const;
108 ChanCount input_streams() const;
109 bool configure_io (ChanCount in, ChanCount out);
110 bool requires_fixed_size_buffers() const;
112 void set_fixed_size_buffers (bool yn) {
113 _requires_fixed_size_buffers = yn;
116 boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
117 boost::shared_ptr<CAComponent> get_comp () const { return comp; }
119 OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
120 const AudioTimeStamp *inTimeStamp,
122 UInt32 inNumberFrames,
123 AudioBufferList* ioData);
125 /* "host" callbacks */
127 OSStatus get_beat_and_tempo_callback (Float64* outCurrentBeat,
128 Float64* outCurrentTempo);
130 OSStatus get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNextBeat,
131 Float32* outTimeSig_Numerator,
132 UInt32* outTimeSig_Denominator,
133 Float64* outCurrentMeasureDownBeat);
135 OSStatus get_transport_state_callback (Boolean* outIsPlaying,
136 Boolean* outTransportStateChanged,
137 Float64* outCurrentSampleInTimeLine,
138 Boolean* outIsCycling,
139 Float64* outCycleStartBeat,
140 Float64* outCycleEndBeat);
142 static std::string maybe_fix_broken_au_id (const std::string&);
144 /* this MUST be called from thread in which you want to receive notifications
145 about parameter changes.
147 int create_parameter_listener (AUEventListenerProc callback, void *arg, float interval_secs);
148 /* these can be called from any thread but SHOULD be called from the same thread
149 that will receive parameter change notifications.
151 int listen_to_parameter (uint32_t param_id);
152 int end_listen_to_parameter (uint32_t param_id);
156 std::string do_save_preset (std::string name);
157 void do_remove_preset (std::string);
160 void find_presets ();
162 boost::shared_ptr<CAComponent> comp;
163 boost::shared_ptr<CAAudioUnit> unit;
166 int32_t input_channels;
167 int32_t output_channels;
168 std::vector<std::pair<int,int> > io_configs;
169 pframes_t _current_block_size;
170 framecnt_t _last_nframes;
171 bool _requires_fixed_size_buffers;
172 AudioBufferList* buffers;
173 bool _has_midi_input;
174 bool _has_midi_output;
176 /* despite all the cool work that apple did on their AU preset
177 system, they left factory presets and user presets as two
178 entirely different kinds of things, handled by two entirely
179 different parts of the API. Resolve this.
182 /* XXX these two maps should really be shared across all instances of this AUPlugin */
184 typedef std::map<std::string,std::string> UserPresetMap;
185 UserPresetMap user_preset_map;
186 typedef std::map<std::string,int> FactoryPresetMap;
187 FactoryPresetMap factory_preset_map;
189 UInt32 global_elements;
190 UInt32 output_elements;
191 UInt32 input_elements;
193 int set_output_format (AudioStreamBasicDescription&);
194 int set_input_format (AudioStreamBasicDescription&);
195 int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
196 void discover_parameters ();
197 void add_state (XMLNode *) const;
199 typedef std::map<uint32_t, uint32_t> ParameterMap;
200 ParameterMap parameter_map;
201 uint32_t input_maxbuf;
202 framecnt_t input_offset;
203 framecnt_t cb_offset;
204 BufferSet* input_buffers;
205 framecnt_t frames_processed;
206 uint32_t audio_input_cnt;
208 std::vector<AUParameterDescriptor> descriptors;
209 AUEventListenerRef _parameter_listener;
210 void * _parameter_listener_arg;
213 void discover_factory_presets ();
215 bool last_transport_rolling;
216 float last_transport_speed;
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);
222 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
224 struct LIBARDOUR_API AUPluginCachedInfo {
225 std::vector<std::pair<int,int> > io_configs;
228 class LIBARDOUR_API AUPluginInfo : public PluginInfo {
230 AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
233 PluginPtr load (Session& session);
235 std::vector<Plugin::PresetRecord> get_presets (bool user_only) const;
237 bool needs_midi_input ();
238 bool is_effect () const;
239 bool is_effect_without_midi_input () const;
240 bool is_effect_with_midi_input () const;
241 bool is_instrument () const;
243 AUPluginCachedInfo cache;
245 bool reconfigurable_io() const { return true; }
247 static PluginInfoList* discover (bool scan_only);
248 static bool au_get_crashlog (std::string &msg);
249 static std::string stringify_descriptor (const CAComponentDescription&);
251 static int load_cached_info ();
254 boost::shared_ptr<CAComponentDescription> descriptor;
256 static FILE * _crashlog_fd;
257 static bool _scan_only;
259 static void au_start_crashlog (void);
260 static void au_remove_crashlog (void);
261 static void au_crashlog (std::string);
263 static void discover_music (PluginInfoList&);
264 static void discover_fx (PluginInfoList&);
265 static void discover_generators (PluginInfoList&);
266 static void discover_instruments (PluginInfoList&);
267 static void discover_by_description (PluginInfoList&, CAComponentDescription&);
268 static Glib::ustring au_cache_path ();
270 typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
271 static CachedInfoMap cached_info;
273 static int cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
274 static void add_cached_info (const std::string&, AUPluginCachedInfo&);
275 static void save_cached_info ();
278 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
280 } // namespace ARDOUR
282 #endif // __ardour_audio_unit_h__