/** * ags_recall_ladspa_load: * @recall_ladspa: an #AgsRecallLadspa * * Set up LADSPA handle. * * Since: 0.4.2 */ void ags_recall_ladspa_load(AgsRecallLadspa *recall_ladspa) { AgsLadspaPlugin *ladspa_plugin; void *plugin_so; LADSPA_Descriptor_Function ladspa_descriptor; LADSPA_Descriptor *plugin_descriptor; /* */ ags_ladspa_manager_load_file(recall_ladspa->filename); ladspa_plugin = ags_ladspa_manager_find_ladspa_plugin(recall_ladspa->filename); plugin_so = ladspa_plugin->plugin_so; if(plugin_so != NULL){ ladspa_descriptor = (LADSPA_Descriptor_Function) dlsym(plugin_so, "ladspa_descriptor\0"); if(dlerror() == NULL && ladspa_descriptor){ recall_ladspa->plugin_descriptor = plugin_descriptor = ladspa_descriptor(recall_ladspa->effect_index); } } }
CAMLprim value ocaml_ladspa_descriptor(value handle, value n) { LADSPA_Descriptor_Function ladspa_descriptor = (LADSPA_Descriptor_Function)dlsym((void*)handle, "ladspa_descriptor"); const LADSPA_Descriptor *d = ladspa_descriptor(Int_val(n)); if (!d) caml_raise_constant(*caml_named_value("ocaml_ladspa_exn_not_found")); return Val_LADSPA_descr(d); }
// Do the actual deactivation. void qtractorLadspaPlugin::deactivate (void) { const LADSPA_Descriptor *pLadspaDescriptor = ladspa_descriptor(); if (pLadspaDescriptor == NULL) return; if (m_phInstances && pLadspaDescriptor->deactivate) { for (unsigned short i = 0; i < instances(); ++i) (*pLadspaDescriptor->deactivate)(m_phInstances[i]); } }
// 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; }
// Factory method (static) qtractorLadspaPluginType *qtractorLadspaPluginType::createType ( qtractorPluginFile *pFile, unsigned long iIndex ) { // Sanity check... if (pFile == NULL) return NULL; // Retrieve descriptor if any... const LADSPA_Descriptor *pLadspaDescriptor = ladspa_descriptor(pFile, iIndex); if (pLadspaDescriptor == NULL) return NULL; // Yep, most probably its a valid plugin descriptor... return new qtractorLadspaPluginType(pFile, iIndex, qtractorPluginType::Ladspa, pLadspaDescriptor); }
// The main plugin processing procedure. void qtractorLadspaPlugin::process ( float **ppIBuffer, float **ppOBuffer, unsigned int nframes ) { if (m_phInstances == NULL) return; const LADSPA_Descriptor *pLadspaDescriptor = ladspa_descriptor(); if (pLadspaDescriptor == NULL) return; // We'll cross channels over instances... const unsigned short iInstances = instances(); const unsigned short iChannels = channels(); const unsigned short iAudioIns = audioIns(); const unsigned short iAudioOuts = audioOuts(); unsigned short iIChannel = 0; unsigned short iOChannel = 0; unsigned short i, j; // For each plugin instance... for (i = 0; i < iInstances; ++i) { LADSPA_Handle handle = m_phInstances[i]; // For each instance audio input port... for (j = 0; j < iAudioIns; ++j) { (*pLadspaDescriptor->connect_port)(handle, m_piAudioIns[j], ppIBuffer[iIChannel]); if (++iIChannel >= iChannels) iIChannel = 0; } // For each instance audio output port... for (j = 0; j < iAudioOuts; ++j) { (*pLadspaDescriptor->connect_port)(handle, m_piAudioOuts[j], ppOBuffer[iOChannel]); if (++iOChannel >= iChannels) iOChannel = 0; } // Make it run... (*pLadspaDescriptor->run)(handle, nframes); // Wrap channels?... if (iIChannel < iChannels - 1) ++iIChannel; if (iOChannel < iChannels - 1) ++iOChannel; } }
// The main plugin processing procedure. void qtractorDssiPlugin::process ( float **ppIBuffer, float **ppOBuffer, unsigned int nframes ) { // Get MIDI manager access... qtractorMidiManager *pMidiManager = list()->midiManager(); if (pMidiManager == NULL) { qtractorLadspaPlugin::process(ppIBuffer, ppOBuffer, nframes); return; } if (m_phInstances == NULL) return; const LADSPA_Descriptor *pLadspaDescriptor = ladspa_descriptor(); if (pLadspaDescriptor == NULL) return; const DSSI_Descriptor *pDssiDescriptor = dssi_descriptor(); if (pDssiDescriptor == NULL) return; // We'll cross channels over instances... const unsigned short iInstances = instances(); const unsigned short iChannels = channels(); const unsigned short iAudioIns = audioIns(); const unsigned short iAudioOuts = audioOuts(); unsigned short iIChannel = 0; unsigned short iOChannel = 0; unsigned short i, j; // For each plugin instance... for (i = 0; i < iInstances; ++i) { LADSPA_Handle handle = m_phInstances[i]; // For each instance audio input port... for (j = 0; j < iAudioIns; ++j) { (*pLadspaDescriptor->connect_port)(handle, m_piAudioIns[j], ppIBuffer[iIChannel]); if (++iIChannel >= iChannels) iIChannel = 0; } // For each instance audio output port... for (j = 0; j < iAudioOuts; ++j) { if (iOChannel < iChannels) { (*pLadspaDescriptor->connect_port)(handle, m_piAudioOuts[j], ppOBuffer[iOChannel++]); } else { (*pLadspaDescriptor->connect_port)(handle, m_piAudioOuts[j], m_pfXBuffer); // dummy output! } } // Care of multiple instances here... if (m_pDssiMulti) m_pDssiMulti->process(pDssiDescriptor, nframes); // Make it run... else if (pDssiDescriptor->run_synth) { (*pDssiDescriptor->run_synth)(handle, nframes, pMidiManager->events(), pMidiManager->count()); } else (*pLadspaDescriptor->run)(handle, nframes); #if 0 // Wrap channels?... if (iIChannel < iChannels - 1) ++iIChannel; if (iOChannel < iChannels - 1) ++iOChannel; #endif } }
// Channel/instance number accessors. void qtractorLadspaPlugin::setChannels ( unsigned short iChannels ) { // Check our type... qtractorPluginType *pType = type(); if (pType == NULL) return; // Estimate the (new) number of instances... unsigned short iOldInstances = instances(); unsigned short iInstances = pType->instances(iChannels, list()->isMidi()); // Now see if instance count changed anyhow... if (iInstances == iOldInstances) return; const LADSPA_Descriptor *pLadspaDescriptor = ladspa_descriptor(); if (pLadspaDescriptor == NULL) return; // Gotta go for a while... bool bActivated = isActivated(); setActivated(false); // Set new instance number... setInstances(iInstances); if (m_phInstances) { if (pLadspaDescriptor->cleanup) { for (unsigned short i = 0; i < iOldInstances; ++i) (*pLadspaDescriptor->cleanup)(m_phInstances[i]); } delete [] m_phInstances; m_phInstances = NULL; } // Bail out, if none are about to be created... if (iInstances < 1) { setActivated(bActivated); return; } #ifdef CONFIG_DEBUG qDebug("qtractorLadspaPlugin[%p]::setChannels(%u) instances=%u", this, iChannels, iInstances); #endif // We'll need output control (not dummy anymore) port indexes... unsigned short iControlOuts = pType->controlOuts(); // Allocate new instances... m_phInstances = new LADSPA_Handle [iInstances]; for (unsigned short i = 0; i < iInstances; ++i) { // Instantiate them properly first... LADSPA_Handle handle = (*pLadspaDescriptor->instantiate)(pLadspaDescriptor, sampleRate()); // Connect all existing input control ports... const qtractorPlugin::Params& params = qtractorPlugin::params(); qtractorPlugin::Params::ConstIterator param = params.constBegin(); const qtractorPlugin::Params::ConstIterator& param_end = params.constEnd(); for ( ; param != param_end; ++param) { qtractorPluginParam *pParam = param.value(); // Just in case the plugin decides // to set the port value at this time... float *pfValue = pParam->subject()->data(); float fValue = *pfValue; (*pLadspaDescriptor->connect_port)(handle, pParam->index(), pfValue); // Make new one the default and restore port value... pParam->setDefaultValue(*pfValue); *pfValue = fValue; } // Connect all existing output control ports... for (unsigned short j = 0; j < iControlOuts; ++j) { (*pLadspaDescriptor->connect_port)(handle, m_piControlOuts[j], &m_pfControlOuts[j]); } // This is it... m_phInstances[i] = handle; } // (Re)issue all configuration as needed... realizeConfigs(); realizeValues(); // But won't need it anymore. releaseConfigs(); releaseValues(); // (Re)activate instance if necessary... setActivated(bActivated); }
/** * ags_recall_ladspa_load_ports: * @recall_ladspa: an #AgsRecallLadspa * * Set up LADSPA ports. * * Returns: a #GList containing #AgsPort. * * Since: 0.4.2 */ GList* ags_recall_ladspa_load_ports(AgsRecallLadspa *recall_ladspa) { AgsLadspaPlugin *ladspa_plugin; AgsPort *current; GList *port; unsigned long port_count; unsigned long i; void *plugin_so; LADSPA_Descriptor_Function ladspa_descriptor; LADSPA_Descriptor *plugin_descriptor; LADSPA_PortDescriptor *port_descriptor; LADSPA_PortRangeHintDescriptor hint_descriptor; ags_ladspa_manager_load_file(recall_ladspa->filename); ladspa_plugin = ags_ladspa_manager_find_ladspa_plugin(recall_ladspa->filename); port = NULL; plugin_so = ladspa_plugin->plugin_so; if(plugin_so != NULL){ ladspa_descriptor = (LADSPA_Descriptor_Function) dlsym(plugin_so, "ladspa_descriptor\0"); if(dlerror() == NULL && ladspa_descriptor){ recall_ladspa->plugin_descriptor = plugin_descriptor = ladspa_descriptor(recall_ladspa->effect_index); port_count = plugin_descriptor->PortCount; port_descriptor = plugin_descriptor->PortDescriptors; for(i = 0; i < port_count; i++){ if(LADSPA_IS_PORT_CONTROL(port_descriptor[i])){ if(LADSPA_IS_PORT_INPUT(port_descriptor[i]) || LADSPA_IS_PORT_OUTPUT(port_descriptor[i])){ gchar *plugin_name; gchar *specifier; hint_descriptor = plugin_descriptor->PortRangeHints[i].HintDescriptor; plugin_name = g_strdup_printf("ladspa-%lu\0", plugin_descriptor->UniqueID); specifier = g_strdup(plugin_descriptor->PortNames[i]); current = g_object_new(AGS_TYPE_PORT, "plugin-name\0", plugin_name, "specifier\0", specifier, "control-port\0", g_strdup_printf("%d/%d\0", i, port_count), "port-value-is-pointer\0", FALSE, "port-value-type\0", G_TYPE_FLOAT, NULL); current->port_value.ags_port_float = plugin_descriptor->PortRangeHints[i].LowerBound; g_message("connecting port: %d/%d\0", i, port_count); port = g_list_prepend(port, current); } }else if(LADSPA_IS_PORT_AUDIO(port_descriptor[i])){ if(LADSPA_IS_PORT_INPUT(port_descriptor[i])){ if(recall_ladspa->input_port == NULL){ recall_ladspa->input_port = (unsigned long *) malloc(sizeof(unsigned long)); recall_ladspa->input_port[0] = i; }else{ recall_ladspa->input_port = (unsigned long *) realloc(recall_ladspa->input_port, (recall_ladspa->input_lines + 1) * sizeof(unsigned long)); recall_ladspa->input_port[recall_ladspa->input_lines] = i; } recall_ladspa->input_lines += 1; }else if(LADSPA_IS_PORT_OUTPUT(port_descriptor[i])){ if(recall_ladspa->output_port == NULL){ recall_ladspa->output_port = (unsigned long *) malloc(sizeof(unsigned long)); recall_ladspa->output_port[0] = i; }else{ recall_ladspa->output_port = (unsigned long *) realloc(recall_ladspa->output_port, (recall_ladspa->output_lines + 1) * sizeof(unsigned long)); recall_ladspa->output_port[recall_ladspa->output_lines] = i; } recall_ladspa->output_lines += 1; } } } AGS_RECALL(recall_ladspa)->port = g_list_reverse(port); } } return(AGS_RECALL(recall_ladspa)->port); }
void ags_recall_ladspa_set_ports(AgsPlugin *plugin, GList *port) { AgsRecallLadspa *recall_ladspa; AgsLadspaPlugin *ladspa_plugin; AgsPort *current; GList *list; unsigned long port_count; unsigned long i; void *plugin_so; LADSPA_Descriptor_Function ladspa_descriptor; LADSPA_Descriptor *plugin_descriptor; LADSPA_PortDescriptor *port_descriptor; LADSPA_PortRangeHintDescriptor hint_descriptor; recall_ladspa = AGS_RECALL_LADSPA(plugin); ags_ladspa_manager_load_file(recall_ladspa->filename); ladspa_plugin = ags_ladspa_manager_find_ladspa_plugin(recall_ladspa->filename); plugin_so = ladspa_plugin->plugin_so; if(plugin_so != NULL){ ladspa_descriptor = (LADSPA_Descriptor_Function) dlsym(plugin_so, "ladspa_descriptor\0"); if(dlerror() == NULL && ladspa_descriptor){ recall_ladspa->plugin_descriptor = plugin_descriptor = ladspa_descriptor(recall_ladspa->effect_index); port_count = plugin_descriptor->PortCount; port_descriptor = plugin_descriptor->PortDescriptors; for(i = 0; i < port_count; i++){ if(LADSPA_IS_PORT_CONTROL(port_descriptor[i])){ if(LADSPA_IS_PORT_INPUT(port_descriptor[i]) || LADSPA_IS_PORT_OUTPUT(port_descriptor[i])){ gchar *plugin_name; gchar *specifier; hint_descriptor = plugin_descriptor->PortRangeHints[i].HintDescriptor; plugin_name = g_strdup_printf("ladspa-%lu\0", plugin_descriptor->UniqueID); specifier = g_strdup(plugin_descriptor->PortNames[i]); list = port; current = NULL; while(list != NULL){ if(!g_strcmp0(specifier, AGS_PORT(list->data)->specifier)){ current = list->data; break; } list = list->next; } current->port_value.ags_port_float = plugin_descriptor->PortRangeHints[i].LowerBound; g_message("connecting port: %d/%d\0", i, port_count); } }else if(LADSPA_IS_PORT_AUDIO(port_descriptor[i])){ if(LADSPA_IS_PORT_INPUT(port_descriptor[i])){ if(recall_ladspa->input_port == NULL){ recall_ladspa->input_port = (unsigned long *) malloc(sizeof(unsigned long)); recall_ladspa->input_port[0] = i; }else{ recall_ladspa->input_port = (unsigned long *) realloc(recall_ladspa->input_port, (recall_ladspa->input_lines + 1) * sizeof(unsigned long)); recall_ladspa->input_port[recall_ladspa->input_lines] = i; } recall_ladspa->input_lines += 1; }else if(LADSPA_IS_PORT_OUTPUT(port_descriptor[i])){ if(recall_ladspa->output_port == NULL){ recall_ladspa->output_port = (unsigned long *) malloc(sizeof(unsigned long)); recall_ladspa->output_port[0] = i; }else{ recall_ladspa->output_port = (unsigned long *) realloc(recall_ladspa->output_port, (recall_ladspa->output_lines + 1) * sizeof(unsigned long)); recall_ladspa->output_port[recall_ladspa->output_lines] = i; } recall_ladspa->output_lines += 1; } } } AGS_RECALL(recall_ladspa)->port = g_list_reverse(port); } } }