X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=libs%2Fardour%2Fardour%2Faudio_unit.h;h=c5c5ed4a95a466ab93d800b86e1b17f15aa2fd5e;hb=efc2660fec0d01c4c47d3fffcc5443025b33afc0;hp=d1dd92dd3d140cd1025f7405d270535703273752;hpb=155338d168b362dd135597695aaa1e419831a277;p=ardour.git diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h index d1dd92dd3d..c5c5ed4a95 100644 --- a/libs/ardour/ardour/audio_unit.h +++ b/libs/ardour/ardour/audio_unit.h @@ -30,14 +30,14 @@ #include #include +#include "ardour/plugin.h" + #include -#include +#include +#include "AUParamInfo.h" #include -#include "ardour/plugin.h" -#include "ardour/chan_mapping.h" - class CAComponent; class CAAudioUnit; class CAComponentDescription; @@ -48,43 +48,49 @@ namespace ARDOUR { class AudioEngine; class Session; -struct AUParameterDescriptor : public Plugin::ParameterDescriptor { +struct LIBARDOUR_API AUParameterDescriptor : public ParameterDescriptor { // additional fields to make operations more efficient AudioUnitParameterID id; AudioUnitScope scope; AudioUnitElement element; - float default_value; bool automatable; - AudioUnitParameterUnit unit; + AudioUnitParameterUnit au_unit; }; -class AUPlugin : public ARDOUR::Plugin +class LIBARDOUR_API AUPlugin : public ARDOUR::Plugin { public: AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr comp); AUPlugin (const AUPlugin& other); virtual ~AUPlugin (); - std::string unique_id () const; + std::string unique_id () const; const char * label () const; const char * name () const { return _info->name.c_str(); } const char * maker () const { return _info->creator.c_str(); } uint32_t parameter_count () const; float default_value (uint32_t port); - nframes_t latency () const; + framecnt_t signal_latency() const; void set_parameter (uint32_t which, float val); float get_parameter (uint32_t which) const; + PluginOutputConfiguration possible_output () const { return _output_configs; } + int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const; uint32_t nth_parameter (uint32_t which, bool& ok) const; void activate (); void deactivate (); - void set_block_size (nframes_t nframes); - - int connect_and_run (vector& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, nframes_t nframes, nframes_t offset); - std::set automatable() const; - string describe_parameter (uint32_t); - string state_node_name () const { return "audiounit"; } + void flush (); + int set_block_size (pframes_t nframes); + + int connect_and_run (BufferSet& bufs, + framepos_t start, framepos_t end, double speed, + ChanMapping in, ChanMapping out, + pframes_t nframes, framecnt_t offset); + std::set automatable() const; + std::string describe_parameter (Evoral::Parameter); + IOPortDescription describe_io_port (DataType dt, bool input, uint32_t id) const; + std::string state_node_name () const { return "audiounit"; } void print_parameter (uint32_t, char*, uint32_t len) const; bool parameter_is_audio (uint32_t) const; @@ -92,30 +98,71 @@ class AUPlugin : public ARDOUR::Plugin bool parameter_is_input (uint32_t) const; bool parameter_is_output (uint32_t) const; - XMLNode& get_state(); - int set_state(const XMLNode& node); + void set_info (PluginInfoPtr); - bool save_preset (string name); - bool load_preset (const string preset_label); - std::vector get_presets (); + int set_state(const XMLNode& node, int); + + bool load_preset (PresetRecord); std::string current_preset() const; bool has_editor () const; - int32_t can_do (int32_t in, int32_t& out); - uint32_t output_streams() const; - uint32_t input_streams() const; - int32_t configure_io (int32_t in, int32_t out); + bool can_support_io_configuration (const ChanCount& in, ChanCount& out, ChanCount* imprecise); + ChanCount output_streams() const; + ChanCount input_streams() const; + bool configure_io (ChanCount in, ChanCount out); + bool requires_fixed_size_buffers() const; + + void set_fixed_size_buffers (bool yn) { + _requires_fixed_size_buffers = yn; + } boost::shared_ptr get_au () { return unit; } boost::shared_ptr get_comp () const { return comp; } OSStatus render_callback(AudioUnitRenderActionFlags *ioActionFlags, - const AudioTimeStamp *inTimeStamp, - UInt32 inBusNumber, - UInt32 inNumberFrames, - AudioBufferList* ioData); + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList* ioData); + + /* "host" callbacks */ + + OSStatus get_beat_and_tempo_callback (Float64* outCurrentBeat, + Float64* outCurrentTempo); + + OSStatus get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNextBeat, + Float32* outTimeSig_Numerator, + UInt32* outTimeSig_Denominator, + Float64* outCurrentMeasureDownBeat); + + OSStatus get_transport_state_callback (Boolean* outIsPlaying, + Boolean* outTransportStateChanged, + Float64* outCurrentSampleInTimeLine, + Boolean* outIsCycling, + Float64* outCycleStartBeat, + Float64* outCycleEndBeat); + + static std::string maybe_fix_broken_au_id (const std::string&); + + /* this MUST be called from thread in which you want to receive notifications + about parameter changes. + */ + int create_parameter_listener (AUEventListenerProc callback, void *arg, float interval_secs); + /* these can be called from any thread but SHOULD be called from the same thread + that will receive parameter change notifications. + */ + int listen_to_parameter (uint32_t param_id); + int end_listen_to_parameter (uint32_t param_id); + + + protected: + std::string do_save_preset (std::string name); + void do_remove_preset (std::string); + private: + void find_presets (); + boost::shared_ptr comp; boost::shared_ptr unit; @@ -123,69 +170,124 @@ class AUPlugin : public ARDOUR::Plugin int32_t input_channels; int32_t output_channels; std::vector > io_configs; + framecnt_t _last_nframes; + mutable volatile guint _current_latency; + bool _requires_fixed_size_buffers; AudioBufferList* buffers; + bool _has_midi_input; + bool _has_midi_output; + PluginOutputConfiguration _output_configs; + + /* despite all the cool work that apple did on their AU preset + system, they left factory presets and user presets as two + entirely different kinds of things, handled by two entirely + different parts of the API. Resolve this. + */ - /* XXX this should really be shared across all AUPlugin instances */ + /* XXX these two maps should really be shared across all instances of this AUPlugin */ - typedef std::map PresetMap; - PresetMap preset_map; + typedef std::map UserPresetMap; + UserPresetMap user_preset_map; + typedef std::map FactoryPresetMap; + FactoryPresetMap factory_preset_map; UInt32 global_elements; UInt32 output_elements; UInt32 input_elements; - int set_output_format (AudioStreamBasicDescription&); - int set_input_format (AudioStreamBasicDescription&); - int set_stream_format (int scope, uint32_t cnt, AudioStreamBasicDescription&); - int _set_block_size (nframes_t nframes); - void discover_parameters (); + bool variable_inputs; + bool variable_outputs; + + uint32_t configured_input_busses; + uint32_t configured_output_busses; - std::vector > parameter_map; - uint32_t current_maxbuf; - nframes_t current_offset; - nframes_t cb_offset; - vector* current_buffers; - nframes_t frames_processed; + uint32_t *bus_inputs; + uint32_t *bus_outputs; + std::vector _bus_name_in; + std::vector _bus_name_out; + + int set_stream_format (int scope, uint32_t bus, AudioStreamBasicDescription&); + void discover_parameters (); + void add_state (XMLNode *) const; + + typedef std::map ParameterMap; + ParameterMap parameter_map; + uint32_t input_maxbuf; + framecnt_t input_offset; + framecnt_t *cb_offsets; + BufferSet* input_buffers; + ChanMapping * input_map; + framecnt_t frames_processed; + uint32_t audio_input_cnt; std::vector descriptors; + AUEventListenerRef _parameter_listener; + void * _parameter_listener_arg; void init (); + + void discover_factory_presets (); + + framepos_t transport_frame; + float transport_speed; + float last_transport_speed; + + static void _parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value); + void parameter_change_listener (void* /*arg*/, void* /*src*/, const AudioUnitEvent* event, UInt64 host_time, Float32 new_value); }; typedef boost::shared_ptr AUPluginPtr; -struct AUPluginCachedInfo { +struct LIBARDOUR_API AUPluginCachedInfo { std::vector > io_configs; }; -class AUPluginInfo : public PluginInfo { +class LIBARDOUR_API AUPluginInfo : public PluginInfo { public: - AUPluginInfo (boost::shared_ptr); + AUPluginInfo (boost::shared_ptr); ~AUPluginInfo (); PluginPtr load (Session& session); + std::vector get_presets (bool user_only) const; + + bool needs_midi_input () const; + bool is_effect () const; + bool is_effect_without_midi_input () const; + bool is_effect_with_midi_input () const; + bool is_instrument () const; + AUPluginCachedInfo cache; - static PluginInfoList* discover (); - static void get_names (CAComponentDescription&, std::string& name, Glib::ustring& maker); - static std::string stringify_descriptor (const CAComponentDescription&); + bool reconfigurable_io() const { return true; } + + static void clear_cache (); + static PluginInfoList* discover (bool scan_only); + static bool au_get_crashlog (std::string &msg); + static std::string stringify_descriptor (const CAComponentDescription&); static int load_cached_info (); private: boost::shared_ptr descriptor; UInt32 version; + static FILE * _crashlog_fd; + static bool _scan_only; + + static void au_start_crashlog (void); + static void au_remove_crashlog (void); + static void au_crashlog (std::string); static void discover_music (PluginInfoList&); static void discover_fx (PluginInfoList&); static void discover_generators (PluginInfoList&); + static void discover_instruments (PluginInfoList&); static void discover_by_description (PluginInfoList&, CAComponentDescription&); static Glib::ustring au_cache_path (); typedef std::map CachedInfoMap; static CachedInfoMap cached_info; - static bool cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name); + static int cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name); static void add_cached_info (const std::string&, AUPluginCachedInfo&); static void save_cached_info (); };