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 "appleutility/AUParamInfo.h"
39 #include <boost/shared_ptr.hpp>
43 class CAComponentDescription;
44 struct AudioBufferList;
51 struct AUParameterDescriptor : public Plugin::ParameterDescriptor {
52 // additional fields to make operations more efficient
53 AudioUnitParameterID id;
55 AudioUnitElement element;
58 AudioUnitParameterUnit unit;
61 class AUPlugin : public ARDOUR::Plugin
64 AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAComponent> comp);
65 AUPlugin (const AUPlugin& other);
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;
78 int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
79 uint32_t nth_parameter (uint32_t which, bool& ok) const;
83 int set_block_size (pframes_t nframes);
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;
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;
98 void set_info (PluginInfoPtr);
100 int set_state(const XMLNode& node, int);
102 bool load_preset (PresetRecord);
103 std::string current_preset() const;
105 bool has_editor () const;
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;
114 void set_fixed_size_buffers (bool yn) {
115 _requires_fixed_size_buffers = yn;
118 boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
119 boost::shared_ptr<CAComponent> get_comp () const { return comp; }
121 OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
122 const AudioTimeStamp *inTimeStamp,
124 UInt32 inNumberFrames,
125 AudioBufferList* ioData);
127 /* "host" callbacks */
129 OSStatus get_beat_and_tempo_callback (Float64* outCurrentBeat,
130 Float64* outCurrentTempo);
132 OSStatus get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNextBeat,
133 Float32* outTimeSig_Numerator,
134 UInt32* outTimeSig_Denominator,
135 Float64* outCurrentMeasureDownBeat);
137 OSStatus get_transport_state_callback (Boolean* outIsPlaying,
138 Boolean* outTransportStateChanged,
139 Float64* outCurrentSampleInTimeLine,
140 Boolean* outIsCycling,
141 Float64* outCycleStartBeat,
142 Float64* outCycleEndBeat);
144 static std::string maybe_fix_broken_au_id (const std::string&);
147 std::string do_save_preset (std::string name);
148 void do_remove_preset (std::string);
151 void find_presets ();
153 boost::shared_ptr<CAComponent> comp;
154 boost::shared_ptr<CAAudioUnit> unit;
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;
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.
173 /* XXX these two maps should really be shared across all instances of this AUPlugin */
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;
180 UInt32 global_elements;
181 UInt32 output_elements;
182 UInt32 input_elements;
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;
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;
197 std::vector<AUParameterDescriptor> descriptors;
200 void discover_factory_presets ();
202 bool last_transport_rolling;
203 float last_transport_speed;
206 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
208 struct AUPluginCachedInfo {
209 std::vector<std::pair<int,int> > io_configs;
212 class AUPluginInfo : public PluginInfo {
214 AUPluginInfo (boost::shared_ptr<CAComponentDescription>);
217 PluginPtr load (Session& session);
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;
225 AUPluginCachedInfo cache;
227 static PluginInfoList* discover ();
228 static void get_names (CAComponentDescription&, std::string& name, std::string& maker);
229 static std::string stringify_descriptor (const CAComponentDescription&);
231 static int load_cached_info ();
234 boost::shared_ptr<CAComponentDescription> descriptor;
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 ();
244 typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
245 static CachedInfoMap cached_info;
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 ();
252 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
254 } // namespace ARDOUR
256 #endif // __ardour_audio_unit_h__