X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Faudio_unit.cc;h=6879123ff1a24398d14a89293b49bdd36361af20;hb=e956252b3d860b30b07c434ff3ff4fe45d667c05;hp=52cfc187afe20d7bfe941ef0bffa1587419e7e30;hpb=14f461218121d2b0d68158d7061cbaa375d827e8;p=ardour.git diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index 52cfc187af..6879123ff1 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -18,95 +18,368 @@ */ +#include +#include + +#include #include +#include #include +#include + #include #include +#include "i18n.h" + +using namespace std; +using namespace PBD; using namespace ARDOUR; -PluginInfoList -AUPluginInfo::discover () +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 () { - PluginInfoList plugs; + 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; + } +} - int numTypes = 2; // this magic number was retrieved from the apple AUHost example. +uint32_t +AUPlugin::unique_id () const +{ + return 0; +} - ComponentDescription desc; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - desc.componentSubType = 0; - desc.componentManufacturer = 0; +const char * +AUPlugin::label () const +{ + return "AUPlugin label"; +} - vector vCompDescs; +const char * +AUPlugin::maker () const +{ + return "AUplugin maker"; +} - for (int i = 0; i < numTypes; ++i) { - if (i == 1) { - desc.componentType = kAudioUnitType_MusicEffect; - } else { - desc.componentType = kAudioUnitType_Effect; - } +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& 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 +AUPlugin::automatable() const +{ + set 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; +} - Component comp = 0; +int +AUPlugin::set_state(const XMLNode& node) +{ + return -1; +} - comp = FindNextComponent (NULL, &desc); - while (comp != NULL) { - ComponentDescription temp; - GetComponentInfo (comp, &temp, NULL, NULL, NULL); - vCompDescs.push_back(temp); - comp = FindNextComponent (comp, &desc); +bool +AUPlugin::save_preset (string name) +{ + return false; +} + +bool +AUPlugin::load_preset (const string preset_label) +{ + return false; +} + +vector +AUPlugin::get_presets () +{ + vector 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; } - for (unsigned int i = 0; i < vCompDescs.size(); ++i) { - - // the following large block is just for determining the name of the plugin. - CFStringRef itemName = NULL; - // Marc Poirier -style item name - Component auComponent = FindNextComponent (0, &(vCompDescs[i])); - 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()); - } - } - DisposeHandle(nameHandle); - } - } + catch (failed_constructor &err) { + return PluginPtr ((Plugin*) 0); + } +} - // if Marc-style fails, do the original way - if (itemName == NULL) { - CFStringRef compTypeString = UTCreateStringForOSType(vCompDescs[i].componentType); - CFStringRef compSubTypeString = UTCreateStringForOSType(vCompDescs[i].componentSubType); - CFStringRef compManufacturerString = UTCreateStringForOSType(vCompDescs[i].componentManufacturer); - - itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"), - compTypeString, compManufacturerString, compSubTypeString); - - if (compTypeString != NULL) - CFRelease(compTypeString); - if (compSubTypeString != NULL) - CFRelease(compSubTypeString); - if (compManufacturerString != NULL) - CFRelease(compManufacturerString); - } - string realname = CFStringRefToStdString(itemName); +PluginInfoList +AUPluginInfo::discover () +{ + PluginInfoList plugs; + CAComponentDescription desc; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + desc.componentSubType = 0; + desc.componentManufacturer = 0; + desc.componentType = kAudioUnitType_Effect; + + Component comp = 0; + + comp = FindNextComponent (NULL, &desc); + while (comp != NULL) { + CAComponentDescription temp; + GetComponentInfo (comp, &temp, NULL, NULL, NULL); + AUPluginInfoPtr plug(new AUPluginInfo); - plug->name = realname; - plug->type = PluginInfo::AudioUnit; + 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; } + +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); + } + } + + // 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); + } +} +