00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "DSSIPluginFactory.h"
00022 #include <iostream>
00023
00024 #include <QString>
00025
00026 #include "DSSIPluginInstance.h"
00027 #include "PluginIdentifier.h"
00028
00030 #include "plugin/plugins/SamplePlayer.h"
00031
00032 #include "system/System.h"
00033
00034 #ifdef HAVE_LRDF
00035 #include "lrdf.h"
00036 #endif // HAVE_LRDF
00037
00038
00039 DSSIPluginFactory::DSSIPluginFactory() :
00040 LADSPAPluginFactory()
00041 {
00042 m_hostDescriptor.DSSI_API_Version = 2;
00043 m_hostDescriptor.request_transport_information = NULL;
00044 m_hostDescriptor.request_midi_send = DSSIPluginInstance::requestMidiSend;
00045 m_hostDescriptor.request_non_rt_thread = DSSIPluginInstance::requestNonRTThread;
00046 m_hostDescriptor.midi_send = DSSIPluginInstance::midiSend;
00047 }
00048
00049 DSSIPluginFactory::~DSSIPluginFactory()
00050 {
00051
00052 }
00053
00054 void
00055 DSSIPluginFactory::enumeratePlugins(std::vector<QString> &list)
00056 {
00057 for (std::vector<QString>::iterator i = m_identifiers.begin();
00058 i != m_identifiers.end(); ++i) {
00059
00060 const DSSI_Descriptor *ddesc = getDSSIDescriptor(*i);
00061 if (!ddesc) continue;
00062
00063 const LADSPA_Descriptor *descriptor = ddesc->LADSPA_Plugin;
00064 if (!descriptor) continue;
00065
00066
00067
00068 list.push_back(*i);
00069 list.push_back(descriptor->Name);
00070 list.push_back(QString("%1").arg(descriptor->UniqueID));
00071 list.push_back(descriptor->Label);
00072 list.push_back(descriptor->Maker);
00073 list.push_back(descriptor->Copyright);
00074 list.push_back((ddesc->run_synth || ddesc->run_multiple_synths) ? "true" : "false");
00075 list.push_back(ddesc->run_multiple_synths ? "true" : "false");
00076 list.push_back(m_taxonomy[*i]);
00077 list.push_back(QString("%1").arg(descriptor->PortCount));
00078
00079 for (unsigned long p = 0; p < descriptor->PortCount; ++p) {
00080
00081 int type = 0;
00082 if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[p])) {
00083 type |= PortType::Control;
00084 } else {
00085 type |= PortType::Audio;
00086 }
00087 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[p])) {
00088 type |= PortType::Input;
00089 } else {
00090 type |= PortType::Output;
00091 }
00092
00093 list.push_back(QString("%1").arg(p));
00094 list.push_back(descriptor->PortNames[p]);
00095 list.push_back(QString("%1").arg(type));
00096 list.push_back(QString("%1").arg(getPortDisplayHint(descriptor, p)));
00097 list.push_back(QString("%1").arg(getPortMinimum(descriptor, p)));
00098 list.push_back(QString("%1").arg(getPortMaximum(descriptor, p)));
00099 list.push_back(QString("%1").arg(getPortDefault(descriptor, p)));
00100 }
00101 }
00102
00103 unloadUnusedLibraries();
00104 }
00105
00106 RealTimePluginInstance *
00107 DSSIPluginFactory::instantiatePlugin(QString identifier,
00108 int instrument,
00109 int position,
00110 unsigned int sampleRate,
00111 unsigned int blockSize,
00112 unsigned int channels)
00113 {
00114 const DSSI_Descriptor *descriptor = getDSSIDescriptor(identifier);
00115
00116 if (descriptor) {
00117
00118 DSSIPluginInstance *instance =
00119 new DSSIPluginInstance
00120 (this, instrument, identifier, position, sampleRate, blockSize, channels,
00121 descriptor);
00122
00123 m_instances.insert(instance);
00124
00125 return instance;
00126 }
00127
00128 return 0;
00129 }
00130
00131 const DSSI_Descriptor *
00132 DSSIPluginFactory::getDSSIDescriptor(QString identifier)
00133 {
00134 QString type, soname, label;
00135 PluginIdentifier::parseIdentifier(identifier, type, soname, label);
00136
00137 if (soname == PluginIdentifier::BUILTIN_PLUGIN_SONAME) {
00138 if (label == "sample_player") {
00139 const DSSI_Descriptor *descriptor = SamplePlayer::getDescriptor(0);
00140 if (descriptor) {
00141 descriptor->receive_host_descriptor(&m_hostDescriptor);
00142 }
00143 return descriptor;
00144 } else {
00145 return 0;
00146 }
00147 }
00148
00149 bool firstInLibrary = false;
00150
00151 if (m_libraryHandles.find(soname) == m_libraryHandles.end()) {
00152 loadLibrary(soname);
00153 if (m_libraryHandles.find(soname) == m_libraryHandles.end()) {
00154 std::cerr << "WARNING: DSSIPluginFactory::getDSSIDescriptor: loadLibrary failed for " << soname.toStdString() << std::endl;
00155 return 0;
00156 }
00157 firstInLibrary = true;
00158 }
00159
00160 void *libraryHandle = m_libraryHandles[soname];
00161
00162 DSSI_Descriptor_Function fn = (DSSI_Descriptor_Function)
00163 DLSYM(libraryHandle, "dssi_descriptor");
00164
00165 if (!fn) {
00166 std::cerr << "WARNING: DSSIPluginFactory::getDSSIDescriptor: No descriptor function in library " << soname.toStdString() << std::endl;
00167 return 0;
00168 }
00169
00170 const DSSI_Descriptor *descriptor = 0;
00171
00172 int index = 0;
00173 while ((descriptor = fn(index))) {
00174 if (descriptor->LADSPA_Plugin->Label == label) {
00175 if (firstInLibrary && (descriptor->DSSI_API_Version >= 2)) {
00176 descriptor->receive_host_descriptor(&m_hostDescriptor);
00177 }
00178 return descriptor;
00179 }
00180 ++index;
00181 }
00182
00183 std::cerr << "WARNING: DSSIPluginFactory::getDSSIDescriptor: No such plugin as " << label.toStdString() << " in library " << soname.toStdString() << std::endl;
00184
00185 return 0;
00186 }
00187
00188 const LADSPA_Descriptor *
00189 DSSIPluginFactory::getLADSPADescriptor(QString identifier)
00190 {
00191 const DSSI_Descriptor *dssiDescriptor = getDSSIDescriptor(identifier);
00192 if (dssiDescriptor) return dssiDescriptor->LADSPA_Plugin;
00193 else return 0;
00194 }
00195
00196
00197 std::vector<QString>
00198 DSSIPluginFactory::getPluginPath()
00199 {
00200 std::vector<QString> pathList;
00201 std::string path;
00202
00203 char *cpath = getenv("DSSI_PATH");
00204 if (cpath) path = cpath;
00205
00206 if (path == "") {
00207
00208 path = DEFAULT_DSSI_PATH;
00209
00210 char *home = getenv("HOME");
00211 if (home) {
00212 std::string::size_type f;
00213 while ((f = path.find("$HOME")) != std::string::npos &&
00214 f < path.length()) {
00215 path.replace(f, 5, home);
00216 }
00217 }
00218
00219 #ifdef _WIN32
00220 char *pfiles = getenv("ProgramFiles");
00221 if (!pfiles) pfiles = "C:\\Program Files";
00222 {
00223 std::string::size_type f;
00224 while ((f = path.find("%ProgramFiles%")) != std::string::npos &&
00225 f < path.length()) {
00226 path.replace(f, 14, pfiles);
00227 }
00228 }
00229 #endif
00230 }
00231
00232 std::string::size_type index = 0, newindex = 0;
00233
00234 while ((newindex = path.find(PATH_SEPARATOR, index)) < path.size()) {
00235 pathList.push_back(path.substr(index, newindex - index).c_str());
00236 index = newindex + 1;
00237 }
00238
00239 pathList.push_back(path.substr(index).c_str());
00240
00241 return pathList;
00242 }
00243
00244
00245 std::vector<QString>
00246 DSSIPluginFactory::getLRDFPath(QString &baseUri)
00247 {
00248 std::vector<QString> lrdfPaths;
00249
00250 #ifdef HAVE_LRDF
00251 std::vector<QString> pathList = getPluginPath();
00252
00253 lrdfPaths.push_back("/usr/local/share/dssi/rdf");
00254 lrdfPaths.push_back("/usr/share/dssi/rdf");
00255
00256 lrdfPaths.push_back("/usr/local/share/ladspa/rdf");
00257 lrdfPaths.push_back("/usr/share/ladspa/rdf");
00258
00259 for (std::vector<QString>::iterator i = pathList.begin();
00260 i != pathList.end(); ++i) {
00261 lrdfPaths.push_back(*i + "/rdf");
00262 }
00263
00264 #ifdef DSSI_BASE
00265 baseUri = DSSI_BASE;
00266 #else
00267 baseUri = "http://dssi.sourceforge.net/ontology#";
00268 #endif
00269 #endif
00270
00271 return lrdfPaths;
00272 }
00273
00274
00275 void
00276 DSSIPluginFactory::discoverPlugins(QString soname)
00277 {
00278
00279
00280
00281 void *libraryHandle = DLOPEN(soname, RTLD_LAZY);
00282
00283 if (!libraryHandle) {
00284 std::cerr << "WARNING: DSSIPluginFactory::discoverPlugins: couldn't load plugin library "
00285 << soname.toStdString() << " - " << DLERROR() << std::endl;
00286 return;
00287 }
00288
00289 DSSI_Descriptor_Function fn = (DSSI_Descriptor_Function)
00290 DLSYM(libraryHandle, "dssi_descriptor");
00291
00292 if (!fn) {
00293 std::cerr << "WARNING: DSSIPluginFactory::discoverPlugins: No descriptor function in " << soname.toStdString() << std::endl;
00294 return;
00295 }
00296
00297 const DSSI_Descriptor *descriptor = 0;
00298
00299 int index = 0;
00300 while ((descriptor = fn(index))) {
00301
00302 const LADSPA_Descriptor *ladspaDescriptor = descriptor->LADSPA_Plugin;
00303 if (!ladspaDescriptor) {
00304 std::cerr << "WARNING: DSSIPluginFactory::discoverPlugins: No LADSPA descriptor for plugin " << index << " in " << soname.toStdString() << std::endl;
00305 ++index;
00306 continue;
00307 }
00308
00309 RealTimePluginDescriptor *rtd = new RealTimePluginDescriptor;
00310 rtd->name = ladspaDescriptor->Name;
00311 rtd->label = ladspaDescriptor->Label;
00312 rtd->maker = ladspaDescriptor->Maker;
00313 rtd->copyright = ladspaDescriptor->Copyright;
00314 rtd->category = "";
00315 rtd->isSynth = (descriptor->run_synth ||
00316 descriptor->run_multiple_synths);
00317 rtd->parameterCount = 0;
00318 rtd->audioInputPortCount = 0;
00319 rtd->audioOutputPortCount = 0;
00320 rtd->controlOutputPortCount = 0;
00321
00322 QString identifier = PluginIdentifier::createIdentifier
00323 ("dssi", soname, ladspaDescriptor->Label);
00324
00325 #ifdef HAVE_LRDF
00326 char *def_uri = 0;
00327 lrdf_defaults *defs = 0;
00328
00329 QString category = m_taxonomy[identifier];
00330
00331 if (category == "" && m_lrdfTaxonomy[ladspaDescriptor->UniqueID] != "") {
00332 m_taxonomy[identifier] = m_lrdfTaxonomy[ladspaDescriptor->UniqueID];
00333 category = m_taxonomy[identifier];
00334 }
00335
00336 if (category == "" && ladspaDescriptor->Name != 0) {
00337 std::string name = ladspaDescriptor->Name;
00338 if (name.length() > 4 &&
00339 name.substr(name.length() - 4) == " VST") {
00340 if (descriptor->run_synth || descriptor->run_multiple_synths) {
00341 category = "VST instruments";
00342 } else {
00343 category = "VST effects";
00344 }
00345 m_taxonomy[identifier] = category;
00346 }
00347 }
00348
00349 rtd->category = category.toStdString();
00350
00351
00352
00353
00354
00355
00356
00357
00358 def_uri = lrdf_get_default_uri(ladspaDescriptor->UniqueID);
00359 if (def_uri) {
00360 defs = lrdf_get_setting_values(def_uri);
00361 }
00362
00363 unsigned int controlPortNumber = 1;
00364
00365 for (unsigned long i = 0; i < ladspaDescriptor->PortCount; i++) {
00366
00367 if (LADSPA_IS_PORT_CONTROL(ladspaDescriptor->PortDescriptors[i])) {
00368
00369 if (def_uri && defs) {
00370
00371 for (unsigned int j = 0; j < defs->count; j++) {
00372 if (defs->items[j].pid == controlPortNumber) {
00373
00374 m_portDefaults[ladspaDescriptor->UniqueID][i] =
00375 defs->items[j].value;
00376 }
00377 }
00378 }
00379
00380 ++controlPortNumber;
00381 }
00382 }
00383 #endif // HAVE_LRDF
00384
00385 for (unsigned long i = 0; i < ladspaDescriptor->PortCount; i++) {
00386 if (LADSPA_IS_PORT_CONTROL(ladspaDescriptor->PortDescriptors[i])) {
00387 if (LADSPA_IS_PORT_INPUT(ladspaDescriptor->PortDescriptors[i])) {
00388 ++rtd->parameterCount;
00389 } else {
00390 if (strcmp(ladspaDescriptor->PortNames[i], "latency") &&
00391 strcmp(ladspaDescriptor->PortNames[i], "_latency")) {
00392 ++rtd->controlOutputPortCount;
00393 rtd->controlOutputPortNames.push_back
00394 (ladspaDescriptor->PortNames[i]);
00395 }
00396 }
00397 } else {
00398 if (LADSPA_IS_PORT_INPUT(ladspaDescriptor->PortDescriptors[i])) {
00399 ++rtd->audioInputPortCount;
00400 } else if (LADSPA_IS_PORT_OUTPUT(ladspaDescriptor->PortDescriptors[i])) {
00401 ++rtd->audioOutputPortCount;
00402 }
00403 }
00404 }
00405
00406 m_identifiers.push_back(identifier);
00407
00408 m_rtDescriptors[identifier] = rtd;
00409
00410 ++index;
00411 }
00412
00413 if (DLCLOSE(libraryHandle) != 0) {
00414 std::cerr << "WARNING: DSSIPluginFactory::discoverPlugins - can't unload " << libraryHandle << std::endl;
00415 return;
00416 }
00417 }
00418
00419
00420