Commit read-only stack security fix for 64bit processors.
[ardour.git] / libs / ardour / audio_unit.cc
index 4cc97a510e929b296165b45c09c1cd8e51dd6da2..6879123ff1a24398d14a89293b49bdd36361af20 100644 (file)
 
 */
 
+#include <pbd/transmitter.h>
+#include <pbd/xml++.h>
+
+#include <ardour/audioengine.h>
 #include <ardour/audio_unit.h>
+#include <ardour/session.h>
 #include <ardour/utils.h>
 
+#include <appleutility/CAAudioUnit.h>
+
 #include <CoreServices/CoreServices.h>
 #include <AudioUnit/AudioUnit.h>
 
+#include "i18n.h"
+
+using namespace std;
+using namespace PBD;
 using namespace ARDOUR;
 
+AUPlugin::AUPlugin (AudioEngine& engine, Session& session, CAComponent* _comp)
+       :
+       Plugin (engine, session),
+       comp (_comp),
+       unit (new CAAudioUnit)
+{                      
+       OSErr err = CAAudioUnit::Open (*comp, *unit);
+       if (err != noErr) {
+               error << _("AudioUnit: Could not convert CAComponent to CAAudioUnit") << endmsg;
+               delete unit;
+               delete comp;
+               throw failed_constructor ();
+       }
+       
+       unit->Initialize ();
+}
+
+AUPlugin::~AUPlugin ()
+{
+       if (unit) {
+               unit->Uninitialize ();
+               delete unit;
+       }
+       
+       if (comp) {
+               delete comp;
+       }
+       
+       if (in_list) {
+               delete in_list;
+       }
+       
+       if (out_list) {
+               delete out_list;
+       }
+}
+
+AUPluginInfo::~AUPluginInfo ()
+{
+       if (desc) {
+               delete desc;
+       }
+}
+
+uint32_t
+AUPlugin::unique_id () const
+{
+       return 0;
+}
+
+const char *
+AUPlugin::label () const
+{
+       return "AUPlugin label";
+}
+
+const char *
+AUPlugin::maker () const
+{
+       return "AUplugin maker";
+}
+
+uint32_t
+AUPlugin::parameter_count () const
+{
+       return 0;
+}
+
+float
+AUPlugin::default_value (uint32_t port)
+{
+       // AudioUnits don't have default values.  Maybe presets though?
+       return 0;
+}
+
+nframes_t
+AUPlugin::latency () const
+{
+       return unit->Latency ();
+}
+
+void
+AUPlugin::set_parameter (uint32_t which, float val)
+{
+       unit->SetParameter (parameter_map[which].first, parameter_map[which].second, 0, val);
+}
+
+float
+AUPlugin::get_parameter (uint32_t which) const
+{
+       float outValue = 0.0;
+       
+       unit->GetParameter(parameter_map[which].first, parameter_map[which].second, 0, outValue);
+       
+       return outValue;
+}
+
+int
+AUPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const
+{
+       return 0;
+}
+
+uint32_t
+AUPlugin::nth_parameter (uint32_t which, bool& ok) const
+{
+       return 0;
+}
+
+void
+AUPlugin::activate ()
+{
+       unit->GlobalReset ();
+}
+
+void
+AUPlugin::deactivate ()
+{
+       // not needed.  GlobalReset () takes care of it.
+}
+
+void
+AUPlugin::set_block_size (nframes_t nframes)
+{
+       
+}
+
+int
+AUPlugin::connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, nframes_t nframes, nframes_t offset)
+{
+       AudioUnitRenderActionFlags flags = 0;
+       AudioTimeStamp ts;
+       
+       AudioBufferList abl;
+       abl.mNumberBuffers = 1;
+       abl.mBuffers[0].mNumberChannels = 1;
+       abl.mBuffers[0].mDataByteSize = nframes * sizeof(Sample);
+       abl.mBuffers[0].mData = &bufs[0];
+       
+       
+       unit->Render (&flags, &ts, 0, 0, &abl);
+       
+       return 0;
+}
+
+set<uint32_t>
+AUPlugin::automatable() const
+{
+       set<uint32_t> automates;
+       
+       return automates;
+}
+
+string
+AUPlugin::describe_parameter (uint32_t)
+{
+       return "";
+}
+
+void
+AUPlugin::print_parameter (uint32_t, char*, uint32_t len) const
+{
+       
+}
+
+bool
+AUPlugin::parameter_is_audio (uint32_t) const
+{
+       return false;
+}
+
+bool
+AUPlugin::parameter_is_control (uint32_t) const
+{
+       return false;
+}
+
+bool
+AUPlugin::parameter_is_input (uint32_t) const
+{
+       return false;
+}
+
+bool
+AUPlugin::parameter_is_output (uint32_t) const
+{
+       return false;
+}
+
+XMLNode&
+AUPlugin::get_state()
+{
+       XMLNode* root = new XMLNode (state_node_name());
+       
+       return *root;
+}
+
+int
+AUPlugin::set_state(const XMLNode& node)
+{
+       return -1;
+}
+
+bool
+AUPlugin::save_preset (string name)
+{
+       return false;
+}
+
+bool
+AUPlugin::load_preset (const string preset_label)
+{
+       return false;
+}
+
+vector<string>
+AUPlugin::get_presets ()
+{
+       vector<string> presets;
+       
+       return presets;
+}
+
+bool
+AUPlugin::has_editor () const
+{
+       return false;
+}
+
+PluginPtr
+AUPluginInfo::load (Session& session)
+{
+       try {
+               PluginPtr plugin;
+
+               CAComponent* comp = new CAComponent(*desc);
+               
+               if (!comp->IsValid()) {
+                       error << ("AudioUnit: not a valid Component") << endmsg;
+               } else {
+                       plugin.reset (new AUPlugin (session.engine(), session, comp));
+               }
+               
+               plugin->set_info(PluginInfoPtr(new AUPluginInfo(*this)));
+               return plugin;
+       }
+
+       catch (failed_constructor &err) {
+               return PluginPtr ((Plugin*) 0);
+       }
+}
+
 PluginInfoList
 AUPluginInfo::discover ()
 {
        PluginInfoList plugs;
 
-       int numTypes = 2;    // this magic number was retrieved from the apple AUHost example.
-
-       ComponentDescription desc;
+       CAComponentDescription desc;
        desc.componentFlags = 0;
        desc.componentFlagsMask = 0;
        desc.componentSubType = 0;
        desc.componentManufacturer = 0;
+       desc.componentType = kAudioUnitType_Effect;
 
-       for (int i = 0; i < numTypes; ++i) {
-               if (i == 1) {
-                       desc.componentType = kAudioUnitType_MusicEffect;
-               } else {
-                       desc.componentType = kAudioUnitType_Effect;
-               }
+       Component comp = 0;
 
-               Component comp = 0;
-
-               comp = FindNextComponent (NULL, &desc);
-               while (comp != NULL) {
-                       ComponentDescription temp;
-                       GetComponentInfo (comp, &temp, NULL, NULL, NULL);
-                       
-                       AUPluginInfoPtr plug(new AUPluginInfo);
-                       plug->name = AUPluginInfo::get_name (temp);
-                       plug->type = PluginInfo::AudioUnit;
-                       plug->n_inputs = 0;
-                       plug->n_outputs = 0;
-                       plug->category = "AudioUnit";
-                       plug->desc = CompDescPtr(new ComponentDescription(temp));
-
-                       plugs.push_back(plug);
-                       
-                       comp = FindNextComponent (comp, &desc);
-               }
+       comp = FindNextComponent (NULL, &desc);
+       while (comp != NULL) {
+               CAComponentDescription temp;
+               GetComponentInfo (comp, &temp, NULL, NULL, NULL);
+               
+               AUPluginInfoPtr plug(new AUPluginInfo);
+               plug->name = AUPluginInfo::get_name (temp);
+               plug->type = ARDOUR::AudioUnit;
+               plug->n_inputs = 0;
+               plug->n_outputs = 0;
+               // plug->setup_nchannels (temp);
+               plug->category = "AudioUnit";
+               plug->desc = new CAComponentDescription(temp);
+
+               plugs.push_back(plug);
+               
+               comp = FindNextComponent (comp, &desc);
        }
 
        return plugs;
 }
 
-std::string
-AUPluginInfo::get_name (ComponentDescription& comp_desc)
-{
-               CFStringRef itemName = NULL;
-               // Marc Poirier -style item name
-               Component auComponent = FindNextComponent (0, &comp_desc);
-               if (auComponent != NULL) {
-                       ComponentDescription dummydesc;
-                       Handle nameHandle = NewHandle(sizeof(void*));
-                       if (nameHandle != NULL) {
-                               OSErr err = GetComponentInfo(auComponent, &dummydesc, nameHandle, NULL, NULL);
-                               if (err == noErr) {
-                                       ConstStr255Param nameString = (ConstStr255Param) (*nameHandle);
-                                       if (nameString != NULL) {
-                                               itemName = CFStringCreateWithPascalString(kCFAllocatorDefault, nameString, CFStringGetSystemEncoding());
-                                       }
+string
+AUPluginInfo::get_name (CAComponentDescription& comp_desc)
+{
+       CFStringRef itemName = NULL;
+       // Marc Poirier -style item name
+       CAComponent auComponent (comp_desc);
+       if (auComponent.IsValid()) {
+               CAComponentDescription dummydesc;
+               Handle nameHandle = NewHandle(sizeof(void*));
+               if (nameHandle != NULL) {
+                       OSErr err = GetComponentInfo(auComponent.Comp(), &dummydesc, nameHandle, NULL, NULL);
+                       if (err == noErr) {
+                               ConstStr255Param nameString = (ConstStr255Param) (*nameHandle);
+                               if (nameString != NULL) {
+                                       itemName = CFStringCreateWithPascalString(kCFAllocatorDefault, nameString, CFStringGetSystemEncoding());
                                }
-                               DisposeHandle(nameHandle);
                        }
+                       DisposeHandle(nameHandle);
                }
+       }
+    
+       // if Marc-style fails, do the original way
+       if (itemName == NULL) {
+               CFStringRef compTypeString = UTCreateStringForOSType(comp_desc.componentType);
+               CFStringRef compSubTypeString = UTCreateStringForOSType(comp_desc.componentSubType);
+               CFStringRef compManufacturerString = UTCreateStringForOSType(comp_desc.componentManufacturer);
+    
+               itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"), 
+                       compTypeString, compManufacturerString, compSubTypeString);
+    
+               if (compTypeString != NULL)
+                       CFRelease(compTypeString);
+               if (compSubTypeString != NULL)
+                       CFRelease(compSubTypeString);
+               if (compManufacturerString != NULL)
+                       CFRelease(compManufacturerString);
+       }
+       
+       return CFStringRefToStdString(itemName);
+}
 
-               // if Marc-style fails, do the original way
-               if (itemName == NULL) {
-                       CFStringRef compTypeString = UTCreateStringForOSType(comp_desc.componentType);
-                       CFStringRef compSubTypeString = UTCreateStringForOSType(comp_desc.componentSubType);
-                       CFStringRef compManufacturerString = UTCreateStringForOSType(comp_desc.componentManufacturer);
-
-                       itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"), 
-                               compTypeString, compManufacturerString, compSubTypeString);
-
-                       if (compTypeString != NULL)
-                               CFRelease(compTypeString);
-                       if (compSubTypeString != NULL)
-                               CFRelease(compSubTypeString);
-                       if (compManufacturerString != NULL)
-                               CFRelease(compManufacturerString);
-               }
-               
-               return CFStringRefToStdString(itemName);
+void
+AUPluginInfo::setup_nchannels (CAComponentDescription& comp_desc)
+{
+       CAAudioUnit unit;
+       
+       CAAudioUnit::Open (comp_desc, unit);
+       
+       if (unit.SupportsNumChannels()) {
+               n_inputs = n_outputs = 0;
+       } else {
+               AUChannelInfo cinfo;
+               size_t info_size = sizeof(cinfo);
+               OSStatus err = AudioUnitGetProperty (unit.AU(), kAudioUnitProperty_SupportedNumChannels, kAudioUnitScope_Global,
+                                             0, &cinfo, &info_size);
+       }
 }
+