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 LIBARDOUR_API AudioBufferList;
51 struct LIBARDOUR_API AUParameterDescriptor : public Plugin::ParameterDescriptor {
52 // additional fields to make operations more efficient
53 AudioUnitParameterID id;
55 AudioUnitElement element;
58 AudioUnitParameterUnit unit;
61 class LIBARDOUR_API 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 can_support_io_configuration (const ChanCount& in, ChanCount& out);
108 ChanCount output_streams() const;
109 ChanCount input_streams() const;
110 bool configure_io (ChanCount in, ChanCount out);
111 bool requires_fixed_size_buffers() const;
113 void set_fixed_size_buffers (bool yn) {
114 _requires_fixed_size_buffers = yn;
117 boost::shared_ptr<CAAudioUnit> get_au () { return unit; }
118 boost::shared_ptr<CAComponent> get_comp () const { return comp; }
120 OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags,
121 const AudioTimeStamp *inTimeStamp,
123 UInt32 inNumberFrames,
124 AudioBufferList* ioData);
126 /* "host" callbacks */
128 OSStatus get_beat_and_tempo_callback (Float64* outCurrentBeat,
129 Float64* outCurrentTempo);
131 OSStatus get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNextBeat,
132 Float32* outTimeSig_Numerator,
133 UInt32* outTimeSig_Denominator,
134 Float64* outCurrentMeasureDownBeat);
136 OSStatus get_transport_state_callback (Boolean* outIsPlaying,
137 Boolean* outTransportStateChanged,
138 Float64* outCurrentSampleInTimeLine,
139 Boolean* outIsCycling,
140 Float64* outCycleStartBeat,
141 Float64* outCycleEndBeat);
143 static std::string maybe_fix_broken_au_id (const std::string&);
145 /* this MUST be called from thread in which you want to receive notifications
146 about parameter changes.
148 int create_parameter_listener (AUEventListenerProc callback, void *arg, float interval_secs);
149 /* these can be called from any thread but SHOULD be called from the same thread
150 that will receive parameter change notifications.
152 int listen_to_parameter (uint32_t param_id);
153 int end_listen_to_parameter (uint32_t param_id);
157 std::string do_save_preset (std::string name);
158 void do_remove_preset (std::string);
161 void find_presets ();
163 boost::shared_ptr<CAComponent> comp;
164 boost::shared_ptr<CAAudioUnit> unit;
167 int32_t input_channels;
168 int32_t output_channels;
169 std::vector<std::pair<int,int> > io_configs;
170 pframes_t _current_block_size;
171 framecnt_t _last_nframes;
172 bool _requires_fixed_size_buffers;
173 AudioBufferList* buffers;
174 bool _has_midi_input;
175 bool _has_midi_output;
177 /* despite all the cool work that apple did on their AU preset
178 system, they left factory presets and user presets as two
179 entirely different kinds of things, handled by two entirely
180 different parts of the API. Resolve this.
183 /* XXX these two maps should really be shared across all instances of this AUPlugin */
185 typedef std::map<std::string,std::string> UserPresetMap;
186 UserPresetMap user_preset_map;
187 typedef std::map<std::string,int> FactoryPresetMap;
188 FactoryPresetMap factory_preset_map;
190 UInt32 global_elements;
191 UInt32 output_elements;
192 UInt32 input_elements;
194 int set_output_format (AudioStreamBasicDescription&);
195 int set_input_format (AudioStreamBasicDescription&);
196 int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&);
197 void discover_parameters ();
198 void add_state (XMLNode *) const;
200 typedef std::map<uint32_t, uint32_t> ParameterMap;
201 ParameterMap parameter_map;
202 uint32_t input_maxbuf;
203 framecnt_t input_offset;
204 framecnt_t cb_offset;
205 BufferSet* input_buffers;
206 framecnt_t frames_processed;
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 bool needs_midi_input ();
236 bool is_effect () const;
237 bool is_effect_without_midi_input () const;
238 bool is_effect_with_midi_input () const;
239 bool is_instrument () const;
241 AUPluginCachedInfo cache;
243 bool reconfigurable_io() const { return true; }
245 static PluginInfoList* discover ();
246 static void get_names (CAComponentDescription&, std::string& name, std::string& maker);
247 static std::string stringify_descriptor (const CAComponentDescription&);
249 static int load_cached_info ();
252 boost::shared_ptr<CAComponentDescription> descriptor;
255 static void discover_music (PluginInfoList&);
256 static void discover_fx (PluginInfoList&);
257 static void discover_generators (PluginInfoList&);
258 static void discover_instruments (PluginInfoList&);
259 static void discover_by_description (PluginInfoList&, CAComponentDescription&);
260 static Glib::ustring au_cache_path ();
262 typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
263 static CachedInfoMap cached_info;
265 static bool cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
266 static void add_cached_info (const std::string&, AUPluginCachedInfo&);
267 static void save_cached_info ();
270 typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
272 } // namespace ARDOUR
274 #endif // __ardour_audio_unit_h__