// Provisional program/patch accessor. bool qtractorDssiPlugin::getProgram ( int iIndex, Program& program ) const { if (m_phInstances == NULL) return false; const DSSI_Descriptor *pDssiDescriptor = dssi_descriptor(); if (pDssiDescriptor == NULL) return false; if (pDssiDescriptor->get_program == NULL) return false; // Only first one instance should matter... const DSSI_Program_Descriptor *pDssiProgram = (*pDssiDescriptor->get_program)(m_phInstances[0], iIndex); if (pDssiProgram == NULL) return false; // Map this to that... program.bank = pDssiProgram->Bank; program.prog = pDssiProgram->Program; program.name = pDssiProgram->Name; return true; }
// Configuration (CLOB) stuff. void qtractorDssiPlugin::configure ( const QString& sKey, const QString& sValue ) { if (m_phInstances == NULL) return; const DSSI_Descriptor *pDssiDescriptor = dssi_descriptor(); if (pDssiDescriptor == NULL) return; if (pDssiDescriptor->configure == NULL) return; #ifdef CONFIG_DEBUG qDebug("qtractorDssiPlugin[%p]::configure(\"%s\", \"%s\")", this, sKey.toUtf8().constData(), sValue.toUtf8().constData()); #endif // For each plugin instance... const unsigned short iInstances = instances(); for (unsigned short i = 0; i < iInstances; ++i) { (*pDssiDescriptor->configure)(m_phInstances[i], sKey.toUtf8().constData(), sValue.toUtf8().constData()); } #ifdef CONFIG_LIBLO if (m_pDssiEditor) { osc_send_configure(m_pDssiEditor, sKey.toUtf8().constData(), sValue.toUtf8().constData()); } #endif }
// Derived methods. bool qtractorDssiPluginType::open (void) { // Do we have a descriptor already? if (m_pDssiDescriptor == NULL) m_pDssiDescriptor = dssi_descriptor(file(), index()); if (m_pDssiDescriptor == NULL) return false; // We're also a LADSPA one... m_pLadspaDescriptor = m_pDssiDescriptor->LADSPA_Plugin; // Let's get the it's own LADSPA stuff... if (!qtractorLadspaPluginType::open()) { m_pLadspaDescriptor = NULL; m_pDssiDescriptor = NULL; return false; } #ifdef CONFIG_DEBUG qDebug("qtractorDssiPluginType[%p]::open() filename=\"%s\" index=%lu", this, filename().toUtf8().constData(), index()); #endif // Things we have now for granted... m_bConfigure = (m_pDssiDescriptor->configure != NULL); m_iMidiIns = 1; #ifdef CONFIG_LIBLO // Check for GUI editor exacutable... const QFileInfo fi(filename()); QFileInfo gi(fi.dir(), fi.baseName()); if (gi.isDir()) { QDir dir(gi.absoluteFilePath()); const QString sMask("%1_*"); QStringList names; names.append(sMask.arg(fi.baseName())); names.append(sMask.arg(m_pLadspaDescriptor->Label)); dir.setNameFilters(names); QStringList guis = dir.entryList(QDir::Files | QDir::Executable); if (!guis.isEmpty()) { gi.setFile(dir, guis.first()); // FIXME: Only the first? m_sDssiEditor = gi.absoluteFilePath(); m_bEditor = gi.isExecutable(); } } #endif return true; }
// Factory method (static) qtractorDssiPluginType *qtractorDssiPluginType::createType ( qtractorPluginFile *pFile, unsigned long iIndex ) { // Sanity check... if (pFile == NULL) return NULL; // Retrieve DSSI descriptor if any... const DSSI_Descriptor *pDssiDescriptor = dssi_descriptor(pFile, iIndex); if (pDssiDescriptor == NULL) return NULL; // Yep, most probably its a valid plugin descriptor... return new qtractorDssiPluginType(pFile, iIndex, pDssiDescriptor); }
// Bank/program selector. void qtractorDssiPlugin::selectProgram ( int iBank, int iProg ) { if (iBank < 0 || iProg < 0) return; // HACK: We don't change program-preset when // we're supposed to be multi-timbral... if (list()->isMidiBus()) return; if (m_phInstances == NULL) return; const DSSI_Descriptor *pDssiDescriptor = dssi_descriptor(); if (pDssiDescriptor == NULL) return; if (pDssiDescriptor->select_program == NULL) return; #ifdef CONFIG_DEBUG qDebug("qtractorDssiPlugin[%p]::selectProgram(%d, %d)", this, iBank, iProg); #endif // For each plugin instance... const unsigned short iInstances = instances(); for (unsigned short i = 0; i < iInstances; ++i) (*pDssiDescriptor->select_program)(m_phInstances[i], iBank, iProg); #ifdef CONFIG_LIBLO // And update the editor too... if (m_pDssiEditor) osc_send_program(m_pDssiEditor, iBank, iProg); #endif // Reset parameters default value... 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(); pParam->setDefaultValue(pParam->value()); } }
// Post-(re)initializer. void qtractorDssiPlugin::resetChannels (void) { // (Re)initialize controller port map, anyway. ::memset(m_apControllerMap, 0, 128 * sizeof(qtractorPluginParam *)); // Check how many instances are about there... const unsigned short iInstances = instances(); if (iInstances < 1) return; #ifdef CONFIG_DEBUG qDebug("qtractorDssiPlugin[%p]::resetChannels() instances=%u", this, iInstances); #endif // (Re)set according to existing instances... if (m_pDssiMulti) m_pDssiMulti->addPlugin(this); // Map all existing input control ports... const DSSI_Descriptor *pDssiDescriptor = dssi_descriptor(); if (pDssiDescriptor && pDssiDescriptor->get_midi_controller_for_port) { // Only the first one instance should matter... LADSPA_Handle handle = m_phInstances[0]; 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(); const int iController = (*pDssiDescriptor->get_midi_controller_for_port)( handle, pParam->index()); if (iController > 0 && DSSI_IS_CC(iController)) m_apControllerMap[DSSI_CC_NUMBER(iController)] = pParam; } } }
// 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 } }
/** * ags_play_dssi_audio_load: * @play_dssi_audio: the #AgsPlayDssiAudio * * Set up DSSI handle. * * Since: 2.0.0 */ void ags_play_dssi_audio_load(AgsPlayDssiAudio *play_dssi_audio) { AgsDssiPlugin *dssi_plugin; gchar *filename, *effect; guint effect_index; void *plugin_so; DSSI_Descriptor_Function dssi_descriptor; DSSI_Descriptor *plugin_descriptor; pthread_mutex_t *recall_mutex; if(!AGS_IS_PLAY_DSSI_AUDIO(play_dssi_audio)){ return; } /* get recall mutex */ pthread_mutex_lock(ags_recall_get_class_mutex()); recall_mutex = AGS_RECALL(play_dssi_audio)->obj_mutex; pthread_mutex_unlock(ags_recall_get_class_mutex()); /* get filename and effect */ pthread_mutex_lock(recall_mutex); filename = g_strdup(AGS_RECALL(play_dssi_audio)->filename); effect = g_strdup(AGS_RECALL(play_dssi_audio)->effect); pthread_mutex_unlock(recall_mutex); /* find AgsDssiPlugin */ dssi_plugin = ags_dssi_manager_find_dssi_plugin(ags_dssi_manager_get_instance(), filename, effect); /* get some fields */ g_object_get(play_dssi_audio, "effect-index", &effect_index, NULL); play_dssi_audio->plugin = dssi_plugin; g_object_get(dssi_plugin, "plugin-so", &plugin_so, NULL); /* dssi descriptor function - dlsym */ if(plugin_so){ dssi_descriptor = (DSSI_Descriptor_Function) dlsym(plugin_so, "dssi_descriptor"); if(dlerror() == NULL && dssi_descriptor){ pthread_mutex_lock(recall_mutex); play_dssi_audio->plugin_descriptor = plugin_descriptor = dssi_descriptor((unsigned long) effect_index); pthread_mutex_unlock(recall_mutex); } } /* free */ g_free(filename); g_free(effect); }
/** * ags_recall_dssi_load: * @recall_dssi: the #AgsRecallDssi * * Set up DSSI handle. * * Since: 2.0.0 */ void ags_recall_dssi_load(AgsRecallDssi *recall_dssi) { AgsDssiPlugin *dssi_plugin; gchar *filename; gchar *effect; guint effect_index; void *plugin_so; DSSI_Descriptor_Function dssi_descriptor; DSSI_Descriptor *plugin_descriptor; pthread_mutex_t *recall_mutex; if(!AGS_IS_RECALL_DSSI(recall_dssi)){ return; } /* get recall mutex */ pthread_mutex_lock(ags_recall_get_class_mutex()); recall_mutex = AGS_RECALL(recall_dssi)->obj_mutex; pthread_mutex_unlock(ags_recall_get_class_mutex()); /* get some fields */ pthread_mutex_lock(recall_mutex); filename = g_strdup(AGS_RECALL(recall_dssi)->filename); effect = g_strdup(AGS_RECALL(recall_dssi)->effect); effect_index = AGS_RECALL(recall_dssi)->effect_index; pthread_mutex_unlock(recall_mutex); /* find dssi plugin */ dssi_plugin = ags_dssi_manager_find_dssi_plugin(ags_dssi_manager_get_instance(), filename, effect); g_free(filename); g_free(effect); g_object_get(dssi_plugin, "plugin-so", &plugin_so, NULL); if(plugin_so){ dssi_descriptor = (DSSI_Descriptor_Function) dlsym(plugin_so, "dssi_descriptor"); if(dlerror() == NULL && dssi_descriptor){ pthread_mutex_lock(recall_mutex); recall_dssi->plugin_descriptor = plugin_descriptor = dssi_descriptor((unsigned long) effect_index); pthread_mutex_unlock(recall_mutex); } } }
//============================================================================== DemoJuceFilter::DemoJuceFilter() : current_patch_num(0), ptrPlug (0), ladspa (0), plugin (0), emptyBuffer (1,32), samplingRate (44100.0f) { gain = 1.0f; lastUIWidth = 400; lastUIHeight = 140; zeromem (&lastPosInfo, sizeof (lastPosInfo)); lastPosInfo.timeSigNumerator = 4; lastPosInfo.timeSigDenominator = 4; lastPosInfo.bpm = 120; // init stuff based on plugin (as if it were generic) for (uint32 iPluginIndex = 0;; iPluginIndex++) { ptrPlug = dssi_descriptor (iPluginIndex); if (ptrPlug != NULL) break; } if (ptrPlug != 0) { ladspa = ptrPlug->LADSPA_Plugin; // version = ptrPlug->DSSI_API_Version; plugin = ladspa->instantiate (ladspa, (unsigned int) samplingRate); // count ports ins.clear (); outs.clear (); pars.clear (); for (uint i = 0; i < ladspa->PortCount; i++) { LADSPA_PortDescriptor pod = ladspa->PortDescriptors[i]; if (pod & LADSPA_PORT_AUDIO) { if (pod & LADSPA_PORT_INPUT) ins.add (i); else if (pod & LADSPA_PORT_OUTPUT) outs.add (i); } else if (pod & LADSPA_PORT_CONTROL) { pars.add (i); } } // create ports numParams = pars.size (); params = new float [numParams]; normalized = new float [numParams]; memset (params, 0, numParams * sizeof (float)); memset (normalized, 0, numParams * sizeof (float)); // connect ports if (ladspa->connect_port) { for (int i = 0; i < pars.size (); i++) { setParameter(i, DefaultPatch[i]); ladspa->connect_port (plugin, pars [i], &normalized[i]); } for (int i = 0; i < ins.size (); i++) ladspa->connect_port (plugin, ins [i], emptyBuffer.getSampleData (0)); for (int i = 0; i < outs.size (); i++) ladspa->connect_port (plugin, outs [i], emptyBuffer.getSampleData (0)); } } }