static void ladspa_count_ports (const LADSPA_Descriptor * descriptor, guint * audio_in, guint * audio_out, guint * control_in, guint * control_out) { guint i; *audio_in = *audio_out = *control_in = *control_out = 0; for (i = 0; i < descriptor->PortCount; i++) { LADSPA_PortDescriptor p = descriptor->PortDescriptors[i]; if (LADSPA_IS_PORT_AUDIO (p)) { if (LADSPA_IS_PORT_INPUT (p)) (*audio_in)++; else (*audio_out)++; } else if (LADSPA_IS_PORT_CONTROL (p)) { if (LADSPA_IS_PORT_INPUT (p)) (*control_in)++; else (*control_out)++; } } }
LadspaEffect::LadspaEffect(const LADSPA_Descriptor *data) { mData = data; pluginName = data->Name; buffer = NULL; fInBuffer = NULL; fOutBuffer = NULL; inputs = 0; outputs = 0; numInputControls = 0; unsigned long p; inputPorts = new unsigned long [mData->PortCount]; outputPorts = new unsigned long [mData->PortCount]; inputControls = new float [mData->PortCount]; outputControls = new float [mData->PortCount]; for(p=0; p<mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (LADSPA_IS_PORT_AUDIO(d)) { if (LADSPA_IS_PORT_INPUT(d)) { inputPorts[inputs] = p; inputs++; } else if (LADSPA_IS_PORT_OUTPUT(d)) { outputPorts[outputs] = p; outputs++; } } if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_INPUT(d)) { numInputControls++; float val = 1.0; LADSPA_PortRangeHint hint = mData->PortRangeHints[p]; if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) && val < hint.LowerBound) val = hint.LowerBound; if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) && val > hint.UpperBound) val = hint.UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(hint.HintDescriptor)) val *= 44100; inputControls[p] = val; } } }
static void plugin_tilde_ladspa_connect_control_ports (Pd_Plugin_Tilde* x) { unsigned port_index = 0; unsigned input_count = 0; unsigned output_count = 0; input_count = 0; output_count = 0; for (port_index = 0; port_index < x->plugin.ladspa.type->PortCount; port_index++) { LADSPA_PortDescriptor port_type; port_type = x->plugin.ladspa.type->PortDescriptors[port_index]; if (LADSPA_IS_PORT_CONTROL (port_type)) { if (LADSPA_IS_PORT_INPUT (port_type)) { x->plugin.ladspa.type->connect_port (x->plugin.ladspa.instance, port_index, &x->plugin.ladspa.control_input_values[input_count]); x->plugin.ladspa.control_input_ports[input_count] = port_index; input_count++; } else if (LADSPA_IS_PORT_OUTPUT (port_type)) { x->plugin.ladspa.type->connect_port (x->plugin.ladspa.instance, port_index, &x->plugin.ladspa.control_output_values[output_count]); x->plugin.ladspa.control_output_ports[output_count] = port_index; output_count++; } } } }
static PluginData * open_plugin (const char * path, const LADSPA_Descriptor * desc) { const char * slash = strrchr (path, G_DIR_SEPARATOR); g_return_val_if_fail (slash && slash[1], NULL); g_return_val_if_fail (desc->Label && desc->Name, NULL); PluginData * plugin = g_slice_new (PluginData); plugin->path = g_strdup (slash + 1); plugin->desc = desc; plugin->controls = index_new (); plugin->in_ports = g_array_new (0, 0, sizeof (int)); plugin->out_ports = g_array_new (0, 0, sizeof (int)); plugin->selected = 0; for (int i = 0; i < desc->PortCount; i ++) { if (LADSPA_IS_PORT_CONTROL (desc->PortDescriptors[i])) { ControlData * control = parse_control (desc, i); if (control) index_append (plugin->controls, control); } else if (LADSPA_IS_PORT_AUDIO (desc->PortDescriptors[i]) && LADSPA_IS_PORT_INPUT (desc->PortDescriptors[i])) g_array_append_val (plugin->in_ports, i); else if (LADSPA_IS_PORT_AUDIO (desc->PortDescriptors[i]) && LADSPA_IS_PORT_OUTPUT (desc->PortDescriptors[i])) g_array_append_val (plugin->out_ports, i); } return plugin; }
LADSPA_Handle LadspaEffect::InitInstance(float sampleRate) { /* Instantiate the plugin */ LADSPA_Handle handle = mData->instantiate(mData, sampleRate); if (!handle) { return NULL; } for (unsigned long p = 0; p < mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (LADSPA_IS_PORT_CONTROL(d)) { if (LADSPA_IS_PORT_INPUT(d)) { mData->connect_port(handle, p, &mInputControls[p]); } else { mData->connect_port(handle, p, &mOutputControls[p]); } } } if (mData->activate) { mData->activate(handle); } return handle; }
LadspaPluginInfo::LadspaPluginInfo (const QString &path, const LADSPA_Descriptor *desc) : PluginInfo(), m_path(path), m_descriptor(desc) { printf("PATH %s %s\n",qPrintable(path), desc->Name); setName(desc->Name); setAuthorName(desc->Maker); setUniqueId(QString("%1%2").arg( UriRoot ).arg( m_descriptor->UniqueID )); int inCnt = 0, outCnt = 0; for (unsigned long i=0; i < desc->PortCount; ++i) { LADSPA_PortDescriptor p = desc->PortDescriptors[i]; if (LADSPA_IS_PORT_AUDIO(p)) { if (LADSPA_IS_PORT_INPUT(p)) { ++inCnt; } else if (LADSPA_IS_PORT_OUTPUT(p)) { ++outCnt; } } } setAudioInputCount(inCnt); setAudioOutputCount(outCnt); }
void PluginAClientLAD::read_data(KeyFrame *keyframe) { FileXML input; char string[BCTEXTLEN]; input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data())); config.initialize(server); while(! input.read_tag() ) { //printf("PluginAClientLAD::read_data %s\n", input.tag.get_title()); if(! input.tag.title_is(lad_to_upper(string, plugin_title())) ) continue; const LADSPA_Descriptor *lad_desc = server->lad_descriptor; const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors; int port_count = lad_desc->PortCount; for(int port = 0, i = 0; i < port_count; i++) { if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue; if( !LADSPA_IS_PORT_CONTROL(port_desc[i]) ) continue; PluginAClientLAD::lad_to_upper(string, (char*)lad_desc->PortNames[i]); config.port_data[port] = input.tag.get_property(string, config.port_data[port]); //printf("PluginAClientLAD::read_data %d %f\n", port, config.port_data[port]); port++; } } }
void PluginAClientLAD::save_data(KeyFrame *keyframe) { FileXML output; char string[BCTEXTLEN]; if( !config.port_data ) config.initialize(server); // cause data to be stored directly in text output.set_shared_output(keyframe->get_data(), MESSAGESIZE); output.tag.set_title(lad_to_upper(string, plugin_title())); const LADSPA_Descriptor *lad_desc = server->lad_descriptor; const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors; //printf("PluginAClientLAD::save_data %d\n", lad_desc->PortCount); int port_count = lad_desc->PortCount; for(int port = 0, i = 0; i < port_count; i++) { if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue; if( !LADSPA_IS_PORT_CONTROL(port_desc[i]) ) continue; // Convert LAD port name to default title PluginAClientLAD::lad_to_upper(string, (char*)lad_desc->PortNames[i]); output.tag.set_property(string, config.port_data[port]); //printf("PluginAClientLAD::save_data %d %f\n", port, config.port_data[port]); ++port; } output.append_tag(); output.terminate_string(); }
static void listControlsForPlugin(const LADSPA_Descriptor * psDescriptor) { int bFound; unsigned long lIndex; LADSPA_PortRangeHintDescriptor iHintDescriptor; LADSPA_Data fBound; fprintf(stderr, "Plugin \"%s\" has the following control inputs:\n", psDescriptor->Name); bFound = 0; for (lIndex = 0; lIndex < psDescriptor->PortCount; lIndex++) if (LADSPA_IS_PORT_INPUT(psDescriptor->PortDescriptors[lIndex]) && LADSPA_IS_PORT_CONTROL(psDescriptor->PortDescriptors[lIndex])) { fprintf(stderr, "\t%s", psDescriptor->PortNames[lIndex]); bFound = 1; iHintDescriptor = psDescriptor->PortRangeHints[lIndex].HintDescriptor; if (LADSPA_IS_HINT_BOUNDED_BELOW(iHintDescriptor) || LADSPA_IS_HINT_BOUNDED_ABOVE(iHintDescriptor)) { fprintf(stderr, " ("); if (LADSPA_IS_HINT_BOUNDED_BELOW(iHintDescriptor)) { fBound = psDescriptor->PortRangeHints[lIndex].LowerBound; if (LADSPA_IS_HINT_SAMPLE_RATE(iHintDescriptor)) { if (fBound == 0) fprintf(stderr, "0"); else fprintf(stderr, "%g * sample rate", fBound); } else fprintf(stderr, "%g", fBound); } else fprintf(stderr, "..."); fprintf(stderr, " to "); if (LADSPA_IS_HINT_BOUNDED_ABOVE(iHintDescriptor)) { fBound = psDescriptor->PortRangeHints[lIndex].UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(iHintDescriptor)) { if (fBound == 0) fprintf(stderr, "0"); else fprintf(stderr, "%g * sample rate", fBound); } else fprintf(stderr, "%g", fBound); } else fprintf(stderr, "..."); fprintf(stderr, ")\n"); } else fprintf(stderr, "\n"); } if (!bFound) fprintf(stderr, "\tnone\n"); }
void plugin_tilde_ladspa_set_control_input_by_name (Pd_Plugin_Tilde* x, const char* name, float value) { unsigned port_index = 0; unsigned ctrl_input_index = 0; int found_port = 0; /* boolean */ if (name == NULL || strlen (name) == 0) { pd_error(x, "plugin~: no control port name specified"); return; } if(NULL==x->plugin.ladspa.type) { error("plugin~: unable to determine LADSPA type"); return; } /* compare control name to LADSPA control input ports' names case-insensitively */ found_port = 0; ctrl_input_index = 0; for (port_index = 0; port_index < x->plugin.ladspa.type->PortCount; port_index++) { LADSPA_PortDescriptor port_type; port_type = x->plugin.ladspa.type->PortDescriptors[port_index]; if (LADSPA_IS_PORT_CONTROL (port_type) && LADSPA_IS_PORT_INPUT (port_type)) { const char* port_name = NULL; unsigned cmp_length = 0; port_name = x->plugin.ladspa.type->PortNames[port_index]; cmp_length = MIN (strlen (name), strlen (port_name)); if (cmp_length != 0 && strncasecmp (name, port_name, cmp_length) == 0) { /* found the first port to match */ found_port = 1; break; } ctrl_input_index++; } } if (!found_port) { error("plugin~: plugin doesn't have a control input port named \"%s\"", name); return; } plugin_tilde_ladspa_set_control_input_by_index (x, ctrl_input_index, value); }
static void plugin_tilde_ladspa_count_ports (Pd_Plugin_Tilde* x) { unsigned i = 0; x->num_audio_inputs = 0; x->num_audio_outputs = 0; x->num_control_inputs = 0; x->num_control_outputs = 0; for (i = 0; i < x->plugin.ladspa.type->PortCount; i++) { LADSPA_PortDescriptor port_type; port_type = x->plugin.ladspa.type->PortDescriptors[i]; if (LADSPA_IS_PORT_AUDIO (port_type)) { if (LADSPA_IS_PORT_INPUT (port_type)) { x->num_audio_inputs++; } else if (LADSPA_IS_PORT_OUTPUT (port_type)) { x->num_audio_outputs++; } } else if (LADSPA_IS_PORT_CONTROL (port_type)) { if (LADSPA_IS_PORT_INPUT (port_type)) { x->num_control_inputs++; } else if (LADSPA_IS_PORT_OUTPUT (port_type)) { x->num_control_outputs++; } } } verbose(1, "plugin~: plugin ports: audio %d/%d ctrl %d/%d", x->num_audio_inputs, x->num_audio_outputs, x->num_control_inputs, x->num_control_outputs); }
// Derived methods. bool qtractorLadspaPluginType::open (void) { // Do we have a descriptor already? if (m_pLadspaDescriptor == NULL) m_pLadspaDescriptor = ladspa_descriptor(file(), index()); if (m_pLadspaDescriptor == NULL) return false; #ifdef CONFIG_DEBUG qDebug("qtractorLadspaPluginType[%p]::open() filename=\"%s\" index=%lu", this, filename().toUtf8().constData(), index()); #endif // Retrieve plugin type names. m_sName = m_pLadspaDescriptor->Name; m_sLabel = m_pLadspaDescriptor->Label; // Retrieve plugin unique identifier. m_iUniqueID = m_pLadspaDescriptor->UniqueID; // Compute and cache port counts... m_iControlIns = 0; m_iControlOuts = 0; m_iAudioIns = 0; m_iAudioOuts = 0; m_iMidiIns = 0; m_iMidiOuts = 0; for (unsigned long i = 0; i < m_pLadspaDescriptor->PortCount; ++i) { const LADSPA_PortDescriptor portType = m_pLadspaDescriptor->PortDescriptors[i]; if (LADSPA_IS_PORT_INPUT(portType)) { if (LADSPA_IS_PORT_AUDIO(portType)) ++m_iAudioIns; else if (LADSPA_IS_PORT_CONTROL(portType)) ++m_iControlIns; } else if (LADSPA_IS_PORT_OUTPUT(portType)) { if (LADSPA_IS_PORT_AUDIO(portType)) ++m_iAudioOuts; else if (LADSPA_IS_PORT_CONTROL(portType)) ++m_iControlOuts; } } // Cache flags. m_bRealtime = LADSPA_IS_HARD_RT_CAPABLE(m_pLadspaDescriptor->Properties); // Done. return true; }
// Constructors. qtractorLadspaPlugin::qtractorLadspaPlugin ( qtractorPluginList *pList, qtractorLadspaPluginType *pLadspaType ) : qtractorPlugin(pList, pLadspaType), m_phInstances(NULL), m_piControlOuts(NULL), m_pfControlOuts(NULL), m_piAudioIns(NULL), m_piAudioOuts(NULL) { #ifdef CONFIG_DEBUG qDebug("qtractorLadspaPlugin[%p] filename=\"%s\" index=%lu typeHint=%d", this, type()->filename().toUtf8().constData(), type()->index(), int(type()->typeHint())); #endif // Get some structural data first... const LADSPA_Descriptor *pLadspaDescriptor = pLadspaType->ladspa_descriptor(); if (pLadspaDescriptor) { unsigned short iControlOuts = pLadspaType->controlOuts(); unsigned short iAudioIns = pLadspaType->audioIns(); unsigned short iAudioOuts = pLadspaType->audioOuts(); if (iAudioIns > 0) m_piAudioIns = new unsigned long [iAudioIns]; if (iAudioOuts > 0) m_piAudioOuts = new unsigned long [iAudioOuts]; if (iControlOuts > 0) { m_piControlOuts = new unsigned long [iControlOuts]; m_pfControlOuts = new float [iControlOuts]; } iControlOuts = iAudioIns = iAudioOuts = 0; for (unsigned long i = 0; i < pLadspaDescriptor->PortCount; ++i) { const LADSPA_PortDescriptor portType = pLadspaDescriptor->PortDescriptors[i]; if (LADSPA_IS_PORT_INPUT(portType)) { if (LADSPA_IS_PORT_AUDIO(portType)) m_piAudioIns[iAudioIns++] = i; else if (LADSPA_IS_PORT_CONTROL(portType)) addParam(new qtractorLadspaPluginParam(this, i)); } else if (LADSPA_IS_PORT_OUTPUT(portType)) { if (LADSPA_IS_PORT_AUDIO(portType)) m_piAudioOuts[iAudioOuts++] = i; else if (LADSPA_IS_PORT_CONTROL(portType)) { m_piControlOuts[iControlOuts] = i; m_pfControlOuts[iControlOuts] = 0.0f; ++iControlOuts; } } } // FIXME: instantiate each instance properly... qtractorLadspaPlugin::setChannels(channels()); } }
static int ladspa_open(void *arg) { struct lp *plu = arg; void *dl_handle; LADSPA_Descriptor_Function pfDescriptorFunction; const LADSPA_Descriptor *psDescriptor; int i; struct lads *lad = &ladspas[num_ladspas]; assert(plu->plugin && plu->name); dl_handle = loadLADSPAPluginLibrary(plu->plugin); if (!dl_handle) { error("ladspa: failed to load %s\n", plu->plugin); return 0; } pfDescriptorFunction = (LADSPA_Descriptor_Function) dlsym(dl_handle, "ladspa_descriptor"); if (!pfDescriptorFunction) { error("ladspa: %s: %s\n", plu->plugin, dlerror()); goto out_err; } for (i = 0;; i++) { psDescriptor = pfDescriptorFunction(i); if (!psDescriptor) break; if (strcmp(plu->name, psDescriptor->Label) == 0) break; } if (!psDescriptor) { error("ladspa: failed to find %s\n", plu->name); goto out_err; } assert(num_ladspas < MAX_LADSPAS); for (i = 0; i < psDescriptor->PortCount; i++) { if (LADSPA_IS_PORT_INPUT(psDescriptor->PortDescriptors[i]) && LADSPA_IS_PORT_AUDIO(psDescriptor->PortDescriptors[i])) lad->in = i; else if (LADSPA_IS_PORT_OUTPUT(psDescriptor->PortDescriptors[i]) && LADSPA_IS_PORT_AUDIO(psDescriptor->PortDescriptors[i])) lad->out = i; else if (LADSPA_IS_PORT_CONTROL(psDescriptor->PortDescriptors[i])) lad->ctrl = i; } lad->descriptor = psDescriptor; lad->dl_handle = dl_handle; lad->link = arg; num_ladspas++; return 1; out_err: dlclose(dl_handle); return 0; }
int PluginAClientLAD::get_inchannels() { int result = 0; const LADSPA_Descriptor *lad_desc = server->lad_descriptor; const LADSPA_PortDescriptor *port_desc = lad_desc->PortDescriptors; int port_count = lad_desc->PortCount; for( int i = 0; i < port_count; ++i ) { if( !LADSPA_IS_PORT_INPUT(port_desc[i]) ) continue; if( !LADSPA_IS_PORT_AUDIO(port_desc[i]) ) continue; ++result; } return result; }
unsigned long lp_ladspa_audio_ports::get_lad_input_pos(int pos) { int in_count = 0; unsigned long i; for(i=0; i<pv_descriptor->PortCount; i++){ if((LADSPA_IS_PORT_AUDIO(pv_descriptor->PortDescriptors[i]))&&(LADSPA_IS_PORT_INPUT(pv_descriptor->PortDescriptors[i]))){ if(in_count == pos){ return i; } in_count++; } } return -1; }
int lp_ladspa_ctl_port::init_port(const LADSPA_Descriptor *descriptor, unsigned long port, int samplerate , QGridLayout *layout, int _row, int _col) { if(descriptor == 0){ std::cerr << "lp_ladspa_ctl_port::" << __FUNCTION__ << ": descriptor is Null\n"; return -1; } pv_descriptor = descriptor; if(layout == 0){ std::cerr << "lp_ladspa_ctl_port::" << __FUNCTION__ << ": layout is Null\n"; return -1; } if(samplerate == 0){ std::cerr << "lp_ladspa_ctl_port::" << __FUNCTION__ << ": samplerate is not set\n"; return -1; } LADSPA_PortRangeHintDescriptor hints; hints = descriptor->PortRangeHints[port].HintDescriptor; // Setup the ctl_port if(descriptor->PortDescriptors[port] == 0){ // std::cout << "TEST------\n"; } int row = 0; // Search for custom row, col and widget type row = custom_layout.get_row(pv_descriptor->UniqueID, port, _row); int col = 0; col = custom_layout.get_col(pv_descriptor->UniqueID, port, _col); int type = 0; type = custom_layout.get_ctl_type(pv_descriptor->UniqueID, port); std::cout << "ADDING ctl port: col " << col << " row " << row << "\n"; if((LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[port])) && (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[port]))){ if(LADSPA_IS_HINT_INTEGER(hints)){ int_slider = new lp_ladspa_slider_int; connect(int_slider, SIGNAL(val_changed(float)), this, SLOT(set_value(float))); layout->addWidget(int_slider, row, col); int_slider->init(descriptor, port, samplerate); std::cerr << "lp_ladspa_ctl_port::" << __FUNCTION__ << ": int slider ctl for port " << port << "\n"; }else if(LADSPA_IS_HINT_TOGGLED(hints)){ toggel = new lp_ladspa_toggel; connect(toggel, SIGNAL(val_changed(float)), this, SLOT(set_value(float))); layout->addWidget(toggel, row, col); toggel->init(descriptor, port, samplerate); std::cerr << "lp_ladspa_ctl_port::" << __FUNCTION__ << ": toggel ctl for port " << port << "\n"; }else{ if((type == LP_LADSPA_TYPE_SLIDER) || (type == 0)){
void plugin_tilde_ladspa_connect_audio (Pd_Plugin_Tilde* x, float** audio_inputs, float** audio_outputs, unsigned long num_samples) { unsigned port_index = 0; unsigned input_count = 0; unsigned output_count = 0; if(!plugin_tilde_have_plugin(x))return; /* Allocate out-of-place memory if needed */ if (plugin_tilde_ladspa_alloc_outofplace_memory (x, num_samples)) { error("plugin~: out of memory"); return; } if (x->plugin.ladspa.outofplace_audio_outputs != NULL) { x->plugin.ladspa.actual_audio_outputs = audio_outputs; audio_outputs = x->plugin.ladspa.outofplace_audio_outputs; } input_count = 0; output_count = 0; for (port_index = 0; port_index < x->plugin.ladspa.type->PortCount; port_index++) { LADSPA_PortDescriptor port_type; port_type = x->plugin.ladspa.type->PortDescriptors[port_index]; if (LADSPA_IS_PORT_AUDIO (port_type)) { if (LADSPA_IS_PORT_INPUT (port_type)) { x->plugin.ladspa.type->connect_port (x->plugin.ladspa.instance, port_index, (LADSPA_Data*)audio_inputs[input_count]); input_count++; } else if (LADSPA_IS_PORT_OUTPUT (port_type)) { x->plugin.ladspa.type->connect_port (x->plugin.ladspa.instance, port_index, (LADSPA_Data*)audio_outputs[output_count]); output_count++; } } } x->plugin.ladspa.num_samples = num_samples; }
static void plugin_tilde_info (Pd_Plugin_Tilde* x) { unsigned port_index = 0; t_atom at[5]; LADSPA_PortDescriptor port_type; LADSPA_PortRangeHintDescriptor iHintDescriptor; if(!plugin_tilde_have_plugin(x))return; for (port_index = 0; port_index < x->plugin.ladspa.type->PortCount; port_index++) { port_type = x->plugin.ladspa.type->PortDescriptors[port_index]; iHintDescriptor = x->plugin.ladspa.type->PortRangeHints[port_index].HintDescriptor; t_symbol*xlet=gensym("unknown"); t_symbol*type=gensym("unknown"); t_symbol*name=gensym("unknown"); t_float bound_lo=0.; t_float bound_hi=1.; if(LADSPA_IS_PORT_INPUT (port_type)) xlet=gensym("in"); else if (LADSPA_IS_PORT_OUTPUT (port_type)) xlet=gensym("out"); if (LADSPA_IS_PORT_CONTROL (port_type)) type=gensym("control"); else if (LADSPA_IS_PORT_AUDIO (port_type)) type=gensym("audio"); name=gensym(x->plugin.ladspa.type->PortNames[port_index]); if (LADSPA_IS_HINT_BOUNDED_BELOW(iHintDescriptor)) bound_lo=x->plugin.ladspa.type->PortRangeHints[port_index].LowerBound; if (LADSPA_IS_HINT_BOUNDED_ABOVE(iHintDescriptor)) bound_hi=x->plugin.ladspa.type->PortRangeHints[port_index].UpperBound; // post("port#%d: %s %s %s %f..%f", port_index, xlet->s_name, type->s_name, name->s_name, bound_lo, bound_hi); SETSYMBOL(at+0, xlet); SETSYMBOL(at+1, type); SETSYMBOL(at+2, name); SETFLOAT (at+3, bound_lo); SETFLOAT (at+4, bound_hi); outlet_anything (x->control_outlet, gensym ("port"), 5, at); } }
void LADSPA_Ctor(LADSPA *unit) { LADSPA_Descriptor key, *keyp = &key; const LADSPA_Descriptor **found; unit->desc = NULL; unit->handle = NULL; unit->requested_channels = (int) IN0(0); if(unit->requested_channels < 1) { Print("LADSPA: Must request more than 0 channels\n"); unit->mDone = true; SETCALC(ClearUnitOutputs); return; } key.UniqueID = (unsigned long) IN0(1); found = (const LADSPA_Descriptor**) bsearch(&keyp, &plugins[0], plugins_index, sizeof(LADSPA_Descriptor*), desc_cmp); if(!found) { Print("LADSPA: ERROR, plugin %lu not found!\n",key.UniqueID); unit->mDone = true; SETCALC(ClearUnitOutputs); return; } else { unit->desc = *found; } unit->handle = unit->desc->instantiate(unit->desc,SAMPLERATE); int in_index = 2, out_index = 0; for(unsigned long i = 0; i < unit->desc->PortCount; i++) { if(LADSPA_IS_PORT_INPUT(unit->desc->PortDescriptors[i])) { unit->desc->connect_port(unit->handle,i,IN(in_index++)); } else if(LADSPA_IS_PORT_OUTPUT(unit->desc->PortDescriptors[i])) { if(out_index<unit->requested_channels && LADSPA_IS_PORT_AUDIO(unit->desc->PortDescriptors[i])) unit->desc->connect_port(unit->handle,i,OUT(out_index++)); } } unit->plugin_channels = out_index; // printf("output channels: ladspa: %d ugen: %d\n",unit->plugin_channels,unit->requested_channels); if(unit->desc->activate) unit->desc->activate(unit->handle); SETCALC(LADSPA_next); }
bool LadspaEffect::GetAutomationParameters(EffectAutomationParameters & parms) { for (unsigned long p = 0; p < mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_INPUT(d)) { if (!parms.Write(LAT1CTOWX(mData->PortNames[p]), mInputControls[p])) { return false; } } } return true; }
static void count_ports(const LADSPA_Descriptor *desc, unsigned long *nb_inputs, unsigned long *nb_outputs) { LADSPA_PortDescriptor pd; int i; for (i = 0; i < desc->PortCount; i++) { pd = desc->PortDescriptors[i]; if (LADSPA_IS_PORT_AUDIO(pd)) { if (LADSPA_IS_PORT_INPUT(pd)) { (*nb_inputs)++; } else if (LADSPA_IS_PORT_OUTPUT(pd)) { (*nb_outputs)++; } } } }
void WiredLADSPAInstance::LoadPorts() { unsigned long pos; t_ladspa_port CurrentPort; UnLoadPorts(); for (pos = 0, CurrentPort.Descriptor = 0, CurrentPort.Id = 0, CurrentPort.RangeHint.LowerBound = 0, CurrentPort.RangeHint.UpperBound = 0, CurrentPort.RangeHint.HintDescriptor = 0; pos < _Descriptor->PortCount; pos ++, CurrentPort.Descriptor = 0, CurrentPort.Id = 0, CurrentPort.RangeHint.LowerBound = 0, CurrentPort.RangeHint.UpperBound = 0, CurrentPort.RangeHint.HintDescriptor = 0) { CurrentPort.Descriptor = _Descriptor->PortDescriptors[pos]; CurrentPort.RangeHint = _Descriptor->PortRangeHints[pos]; CurrentPort.Id = pos; CurrentPort.Name = wxString(_Descriptor->PortNames[pos], *wxConvCurrent); if (LADSPA_IS_PORT_INPUT(CurrentPort.Descriptor)) { if (LADSPA_IS_PORT_CONTROL(CurrentPort.Descriptor)) { _InputDataPluginsPorts.insert(_InputDataPluginsPorts.end(), CurrentPort); AddGuiControl(&CurrentPort); } else if (LADSPA_IS_PORT_AUDIO(CurrentPort.Descriptor)) { _InputAudioPluginsPorts.insert(_InputAudioPluginsPorts.end(), CurrentPort); _Type |= TYPE_PLUGINS_EFFECT; } } else if (LADSPA_IS_PORT_OUTPUT(CurrentPort.Descriptor)) { if (LADSPA_IS_PORT_CONTROL(CurrentPort.Descriptor)) { ConnectMonoOutput((float *) new LADSPA_Data, pos); _OutputDataPluginsPorts.insert(_OutputDataPluginsPorts.end(), CurrentPort); } else if (LADSPA_IS_PORT_AUDIO(CurrentPort.Descriptor)) _OutputAudioPluginsPorts.insert(_OutputAudioPluginsPorts.end(), CurrentPort); } } if (!(_Type & TYPE_PLUGINS_EFFECT)) _Type |= TYPE_PLUGINS_INSTR; //DumpPorts(); }
bool LadspaManager::isPortInput( const ladspa_key_t & _plugin, uint32_t _port ) { if( m_ladspaManagerMap.contains( _plugin ) && _port < getPortCount( _plugin ) ) { LADSPA_Descriptor_Function descriptorFunction = m_ladspaManagerMap[_plugin]->descriptorFunction; const LADSPA_Descriptor * descriptor = descriptorFunction( m_ladspaManagerMap[_plugin]->index ); return( LADSPA_IS_PORT_INPUT ( descriptor->PortDescriptors[_port] ) ); } else { return( false ); } }
bool LadspaEffect::SetAutomationParameters(EffectAutomationParameters & parms) { for (unsigned long p = 0; p < mData->PortCount; p++) { LADSPA_PortDescriptor d = mData->PortDescriptors[p]; if (LADSPA_IS_PORT_CONTROL(d) && LADSPA_IS_PORT_INPUT(d)) { wxString labelText = LAT1CTOWX(mData->PortNames[p]); double d = 0.0; if (!parms.Read(labelText, &d)) { return false; } mInputControls[p] = d; } } return true; }
uint16_t LadspaManager::getPluginInputs( const LADSPA_Descriptor * _descriptor ) { uint16_t inputs = 0; for( uint16_t port = 0; port < _descriptor->PortCount; port++ ) { if( LADSPA_IS_PORT_INPUT( _descriptor->PortDescriptors[port] ) && LADSPA_IS_PORT_AUDIO( _descriptor->PortDescriptors[port] ) ) { QString name = QString( _descriptor->PortNames[port] ); if( name.toUpper().contains( "IN" ) ) { inputs++; } } } return inputs; }
static gboolean plugin_is_valid (const LADSPA_Descriptor * descriptor) { unsigned long i; unsigned long icount = 0; unsigned long ocount = 0; for (i = 0; i < descriptor->PortCount; i++) { if (!LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[i])) continue; if (LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[i])) icount++; else ocount++; } if (ocount == 0) return FALSE; return TRUE; }
CAMLprim value ocaml_ladspa_port_is_input(value d, value n) { return Val_bool(LADSPA_IS_PORT_INPUT(LADSPA_descr_val(d)->PortDescriptors[Int_val(n)])); }
static af_data_t* play(struct af_instance_s *af, af_data_t *data) { af_ladspa_t *setup = af->setup; const LADSPA_Descriptor *pdes = setup->plugin_descriptor; float *audio = (float*)data->audio; int nsamples = data->len/4; /* /4 because it's 32-bit float */ int nch = data->nch; int rate = data->rate; int i, p; if (setup->status !=AF_OK) return data; /* See if it's the first call. If so, setup inbufs/outbufs, instantiate * plugin, connect ports and activate plugin */ /* 2004-12-07: Also check if the buffersize has to be changed! * data->len is not constant per se! re-init buffers. */ if ( (setup->bufsize != nsamples/nch) || (setup->nch != nch) ) { /* if setup->nch==0, it's the first call, if not, something has * changed and all previous mallocs have to be freed */ if (setup->nch != 0) { mp_msg(MSGT_AFILTER, MSGL_DBG3, "%s: bufsize change; free old buffer\n", setup->myname); if(setup->inbufs) { for(i=0; i<setup->nch; i++) free(setup->inbufs[i]); free(setup->inbufs); } if(setup->outbufs) { for(i=0; i<setup->nch; i++) free(setup->outbufs[i]); free(setup->outbufs); } } /* everything is freed */ setup->bufsize = nsamples/nch; setup->nch = nch; setup->inbufs = calloc(nch, sizeof(float*)); setup->outbufs = calloc(nch, sizeof(float*)); mp_msg(MSGT_AFILTER, MSGL_DBG3, "%s: bufsize = %d\n", setup->myname, setup->bufsize); for(i=0; i<nch; i++) { setup->inbufs[i] = calloc(setup->bufsize, sizeof(float)); setup->outbufs[i] = calloc(setup->bufsize, sizeof(float)); } /* only on the first call, there are no handles. */ if (!setup->chhandles) { setup->chhandles = calloc(nch, sizeof(LADSPA_Handle)); /* create handles * for stereo effects, create one handle for two channels */ for(i=0; i<nch; i++) { if (i % setup->ninputs) { /* stereo effect */ /* copy the handle from previous channel */ setup->chhandles[i] = setup->chhandles[i-1]; continue; } setup->chhandles[i] = pdes->instantiate(pdes, rate); } } /* connect input/output ports for each channel/filter instance * * always (re)connect ports */ for(i=0; i<nch; i++) { pdes->connect_port(setup->chhandles[i], setup->inputs[i % setup->ninputs], setup->inbufs[i]); pdes->connect_port(setup->chhandles[i], setup->outputs[i % setup->ninputs], setup->outbufs[i]); /* connect (input) controls */ for (p=0; p<setup->nports; p++) { LADSPA_PortDescriptor d = pdes->PortDescriptors[p]; if (LADSPA_IS_PORT_CONTROL(d)) { if (LADSPA_IS_PORT_INPUT(d)) { pdes->connect_port(setup->chhandles[i], p, &(setup->inputcontrols[p]) ); } else { pdes->connect_port(setup->chhandles[i], p, &(setup->outputcontrols[p]) ); } } } /* Activate filter (if it isn't already :) ) */ if (pdes->activate && !setup->activated && i % setup->ninputs == 0) pdes->activate(setup->chhandles[i]); } /* All channels/filters done! except for... */ setup->activated = 1; /* Stereo effect with one channel left. Use same buffer for left * and right. connect it to the second port. */ for (p = i; p % setup->ninputs; p++) { pdes->connect_port(setup->chhandles[i-1], setup->inputs[p % setup->ninputs], setup->inbufs[i-1]); pdes->connect_port(setup->chhandles[i-1], setup->outputs[p % setup->ninputs], setup->outbufs[i-1]); } /* done! */ } /* setup for first call/change of bufsize is done. * normal playing routine follows... */ /* Right now, I use a separate input and output buffer. * I could change this to in-place processing (inbuf==outbuf), but some * ladspa filters are broken and are not able to handle that. This seems * fast enough, so unless somebody complains, it stays this way :) */ /* Fill inbufs */ for (p=0; p<setup->bufsize; p++) { for (i=0; i<nch; i++) { setup->inbufs[i][p] = audio[p*nch + i]; } } /* Run filter(s) */ for (i=0; i<nch; i+=setup->ninputs) { pdes->run(setup->chhandles[i], setup->bufsize); } /* Extract outbufs */ for (p=0; p<setup->bufsize; p++) { for (i=0; i<nch; i++) { audio[p*nch + i] = setup->outbufs[i][p]; } } /* done */ return data; }
static int af_ladspa_parse_plugin(af_ladspa_t *setup) { int p, i; const LADSPA_Descriptor *pdes = setup->plugin_descriptor; LADSPA_PortDescriptor d; LADSPA_PortRangeHint hint; if (!setup->libhandle) return AF_ERROR; /* only call parse after a succesful load */ if (!setup->plugin_descriptor) return AF_ERROR; /* same as above */ /* let's do it */ setup->nports = pdes->PortCount; /* allocate memory for all inputs/outputs/controls */ setup->inputs = calloc(setup->nports, sizeof(int)); if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname); setup->outputs = calloc(setup->nports, sizeof(int)); if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname); setup->inputcontrolsmap = calloc(setup->nports, sizeof(int)); if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname); setup->inputcontrols = calloc(setup->nports, sizeof(float)); if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname); setup->outputcontrolsmap = calloc(setup->nports, sizeof(int)); if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname); setup->outputcontrols = calloc(setup->nports, sizeof(float)); if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname); /* set counts to zero */ setup->ninputs = 0; setup->noutputs = 0; setup->ninputcontrols = 0; setup->noutputcontrols = 0; /* check all ports, see what type it is and set variables according to * what we have found */ for (p=0; p<setup->nports; p++) { d = pdes->PortDescriptors[p]; if (LADSPA_IS_PORT_AUDIO(d)) { if (LADSPA_IS_PORT_INPUT(d)) { setup->inputs[setup->ninputs] = p; setup->ninputs++; } else if (LADSPA_IS_PORT_OUTPUT(d)) { setup->outputs[setup->noutputs] = p; setup->noutputs++; } } if (LADSPA_IS_PORT_CONTROL(d)) { if (LADSPA_IS_PORT_INPUT(d)) { setup->inputcontrolsmap[setup->ninputcontrols] = p; setup->ninputcontrols++; /* set control to zero. set values after reading the rest * of the suboptions and check LADSPA_?_HINT's later. */ setup->inputcontrols[p] = 0.0f; } else if (LADSPA_IS_PORT_OUTPUT(d)) { /* read and handle these too, otherwise filters that have them * will sig11 */ setup->outputcontrolsmap[setup->noutputcontrols]=p; setup->noutputcontrols++; setup->outputcontrols[p] = 0.0f; } } } if (setup->ninputs == 0) { mp_msg(MSGT_AFILTER, MSGL_WARN, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_WarnNoInputs); } else if (setup->ninputs == 1) { mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a mono effect\n", setup->myname); } else if (setup->ninputs == 2) { mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a stereo effect\n", setup->myname); } else { mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a %i-channel effect, " "support is experimental\n", setup->myname, setup->ninputs); } if (setup->noutputs == 0) { mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_ErrNoOutputs); return AF_ERROR; } if (setup->noutputs != setup->ninputs ) { mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname, MSGTR_AF_LADSPA_ErrInOutDiff); return AF_ERROR; } mp_msg(MSGT_AFILTER, MSGL_V, "%s: this plugin has %d input control(s)\n", setup->myname, setup->ninputcontrols); /* Print list of controls and its range of values it accepts */ for (i=0; i<setup->ninputcontrols; i++) { p = setup->inputcontrolsmap[i]; hint = pdes->PortRangeHints[p]; mp_msg(MSGT_AFILTER, MSGL_V, " --- %d %s [", i, pdes->PortNames[p]); if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) { mp_msg(MSGT_AFILTER, MSGL_V, "%0.2f , ", hint.LowerBound); } else { mp_msg(MSGT_AFILTER, MSGL_V, "... , "); } if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) { mp_msg(MSGT_AFILTER, MSGL_V, "%0.2f]\n", hint.UpperBound); } else { mp_msg(MSGT_AFILTER, MSGL_V, "...]\n"); } } return AF_OK; }