Browse Source

Some bits added for lrdf in LADSPAInfo - progressing...

master
waxfrenzy 22 years ago
parent
commit
adb85fa84e
3 changed files with 584 additions and 491 deletions
  1. +456
    -380
      SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C
  2. +127
    -110
      SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.h
  3. +1
    -1
      SpiralSound/Plugins/LADSPAPlugin/Makefile.in

+ 456
- 380
SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.C View File

@@ -32,208 +32,259 @@
#include <dlfcn.h>

#include <ladspa.h>
#include <lrdf.h>
#include "LADSPAInfo.h"

using namespace std;

LADSPAInfo::LADSPAInfo(bool override, const char *path_list)
LADSPAInfo::LADSPAInfo(bool override,
const char *path_list)
{
if (strlen(path_list) > 0) {
m_ExtraPaths = strdup(path_list);
} else {
m_ExtraPaths = NULL;
}
m_LADSPAPathOverride = override;

RescanPlugins();
if (strlen(path_list) > 0) {
m_ExtraPaths = strdup(path_list);
} else {
m_ExtraPaths = NULL;
}
m_LADSPAPathOverride = override;

lrdf_init();
RescanPlugins();
}

LADSPAInfo::~LADSPAInfo()
{
CleanUp();
CleanUp();
}

void
LADSPAInfo::PrintInfo(void)
{
cout << "LADSPA Plugin Info" << endl;
cout << endl;
cout << " Paths:" << endl;
for (vector<string>::iterator p = m_Paths.begin(); p != m_Paths.end(); p++) {
cout << " " << *p << endl;
}
cout << endl;
cout << " Libraries:" << endl;
for (vector<LibraryInfo>::iterator l = m_Libraries.begin(); l != m_Libraries.end(); l++) {
cout << " " << m_Paths[l->PathIndex] << l->Basename << ": " << "Refs: " << l->RefCount << endl;
}
cout << endl;
cout << " Plugins:" << endl;
for (vector<PluginInfo>::iterator p = m_Plugins.begin(); p != m_Plugins.end(); p++) {
cout << " " << m_Paths[m_Libraries[p->LibraryIndex].PathIndex]
<< m_Libraries[p->LibraryIndex].Basename
<< ": " << p->Index << endl;
}
cout << endl;
cout << " RDF paths:" << endl;
for (vector<string>::iterator p = m_RDFPaths.begin(); p != m_RDFPaths.end(); p++) {
cout << " " << *p << endl;
}
cout << endl;
cout << " RDF files:" << endl;
for (vector<RDFFileInfo>::iterator f = m_RDFFiles.begin(); f != m_RDFFiles.end(); f++) {
cout << " " << m_RDFPaths[f->RDFPathIndex] << f->Basename << endl;
}
}

void
LADSPAInfo::RescanPlugins(void)
{
// Clear out what we've got
CleanUp();
CleanUp();

if (!m_LADSPAPathOverride) {
// Get $LADPSA_PATH, if available
char *ladspa_path = getenv("LADSPA_PATH");
if (!ladspa_path) {
if (!m_LADSPAPathOverride) {
// Get $LADPSA_PATH, if available
char *ladspa_path = getenv("LADSPA_PATH");
if (!ladspa_path) {

// Oops
cerr << "WARNING: No LADSPA Path Set" << endl;
}
// Oops
cerr << "WARNING: LADSPA_PATH environment variable not set" << endl;
}

// Extract path elements and add path
if (ladspa_path) {
ScanPathList(ladspa_path);
}
}
// Extract path elements and add path
if (ladspa_path) {
ScanPathList(ladspa_path, &LADSPAInfo::ExaminePluginLibrary);
}
}

// Check any supplied extra paths
if (m_ExtraPaths) {
ScanPathList(m_ExtraPaths);
}
if (m_ExtraPaths) {
ScanPathList(m_ExtraPaths, &LADSPAInfo::ExaminePluginLibrary);
}

// Do we have any plugins now?
if (m_Plugins.size() == 0) {
cerr << "WARNING: No plugins found" << endl;
} else {
cerr << m_Plugins.size() << " plugins found in " << m_Libraries.size() << " libraries" << endl;
}
if (m_Plugins.size() == 0) {
cerr << "WARNING: No plugins found" << endl;
} else {
cerr << m_Plugins.size() << " plugins found in " << m_Libraries.size() << " libraries" << endl;

// Got some plugins. Now search for RDF data
char *rdf_path = getenv("LADSPA_RDF_PATH");

if (!rdf_path) {
cerr << "WARNING: LADSPA_RDF_PATH environment variable set" << endl;
} else {

// Examine rdf info
ScanPathList(rdf_path, &LADSPAInfo::ExamineRDFFile);
}
}

// Sort list by name
sort(m_OrderedPluginList.begin(), m_OrderedPluginList.end(), PluginEntrySortAsc());
sort(m_OrderedPluginList.begin(), m_OrderedPluginList.end(), PluginEntrySortAsc());

// Deal with duplicates by numbering them
for (vector<PluginEntry>::iterator i = m_OrderedPluginList.begin();
i != m_OrderedPluginList.end(); ) {
string name = i->Name;

i++;
unsigned long n = 2;
while ((i != m_OrderedPluginList.end()) && (i->Name == name)) {
stringstream s;
s << n;
i->Name = name + " (" + s.str() + ")";
n++;
i++;
}
}
for (vector<PluginEntry>::iterator i = m_OrderedPluginList.begin();
i != m_OrderedPluginList.end(); ) {
string name = i->Name;
i++;
unsigned long n = 2;
while ((i != m_OrderedPluginList.end()) && (i->Name == name)) {
stringstream s;
s << n;
i->Name = name + " (" + s.str() + ")";
n++;
i++;
}
}
}

void
LADSPAInfo::UnloadAllLibraries(void)
{
for (vector<LibraryInfo>::iterator i = m_Libraries.begin();
i != m_Libraries.end(); i++) {
if (i->Handle) dlclose(i->Handle);
i->RefCount = 0;
}
for (vector<LibraryInfo>::iterator i = m_Libraries.begin();
i != m_Libraries.end(); i++) {
if (i->Handle) dlclose(i->Handle);
i->RefCount = 0;
}
}

const LADSPA_Descriptor *
LADSPAInfo::GetDescriptorByID(unsigned long unique_id)
{
if (m_IDLookup.find(unique_id) == m_IDLookup.end()) {
cerr << "LADSPA Plugin ID " << unique_id << " not found!" << endl;
return NULL;
}
if (m_IDLookup.find(unique_id) == m_IDLookup.end()) {
cerr << "LADSPA Plugin ID " << unique_id << " not found!" << endl;
return NULL;
}

// Got plugin index
unsigned long plugin_index = m_IDLookup[unique_id];
unsigned long plugin_index = m_IDLookup[unique_id];

PluginInfo *pi = &(m_Plugins[plugin_index]);
LibraryInfo *li = &(m_Libraries[pi->LibraryIndex]);

if (!(pi->Descriptor)) {
LADSPA_Descriptor_Function desc_func = GetDescriptorFunctionForLibrary(pi->LibraryIndex);

PluginInfo *pi = &(m_Plugins[plugin_index]);
LibraryInfo *li = &(m_Libraries[pi->LibraryIndex]);
if (desc_func) pi->Descriptor = desc_func(pi->Index);
}

if (!(pi->Descriptor)) {
LADSPA_Descriptor_Function desc_func = GetDescriptorFunctionForLibrary(pi->LibraryIndex);
if (pi->Descriptor) {

if (desc_func) pi->Descriptor = desc_func(pi->Index);
}
if (pi->Descriptor) {
// Success, so increment ref counter for library
li->RefCount++;
}
// Success, so increment ref counter for library
li->RefCount++;
}

return pi->Descriptor;
return pi->Descriptor;
}

void
LADSPAInfo::DiscardDescriptorByID(unsigned long unique_id)
{
if (m_IDLookup.find(unique_id) == m_IDLookup.end()) {
cerr << "LADSPA Plugin ID " << unique_id << " not found!" << endl;
} else {

// Get plugin index
unsigned long plugin_index = m_IDLookup[unique_id];

PluginInfo *pi = &(m_Plugins[plugin_index]);
LibraryInfo *li = &(m_Libraries[pi->LibraryIndex]);

// Decrement reference counter for library, and unload if last
if (li->RefCount > 0) {
li->RefCount--;
if (li->RefCount == 0) {
dlclose(li->Handle);
// Need to unset all plugin descriptors that may have been
// set from this library
// Plugins in library will be a contiguous block, so we
// just check each direction from given plugin
unsigned long i = plugin_index - 1;
while (m_Plugins[i].LibraryIndex == pi->LibraryIndex) {
m_Plugins[i--].Descriptor = NULL;
}
i = plugin_index + 1;
while (m_Plugins[i].LibraryIndex == pi->LibraryIndex) {
m_Plugins[i++].Descriptor = NULL;
}
}
}
}
if (m_IDLookup.find(unique_id) == m_IDLookup.end()) {
cerr << "LADSPA Plugin ID " << unique_id << " not found!" << endl;
} else {

// Get plugin index
unsigned long plugin_index = m_IDLookup[unique_id];

PluginInfo *pi = &(m_Plugins[plugin_index]);
LibraryInfo *li = &(m_Libraries[pi->LibraryIndex]);

// Decrement reference counter for library, and unload if last
if (li->RefCount > 0) {
li->RefCount--;
if (li->RefCount == 0) {
dlclose(li->Handle);

// Need to unset all plugin descriptors that may have been
// set from this library
// Plugins in library will be a contiguous block, so we
// just check each direction from given plugin
unsigned long i = plugin_index - 1;
while (m_Plugins[i].LibraryIndex == pi->LibraryIndex) {
m_Plugins[i--].Descriptor = NULL;
}
i = plugin_index + 1;
while (m_Plugins[i].LibraryIndex == pi->LibraryIndex) {
m_Plugins[i++].Descriptor = NULL;
}
}
}
}
}

unsigned long
LADSPAInfo::GetIDFromFilenameAndLabel(std::string filename,
std::string label)
{
bool library_loaded = false;
bool library_loaded = false;

if (m_FilenameLookup.find(filename) == m_FilenameLookup.end()) {
cerr << "LADSPA Library " << filename << " not found!" << endl;
return 0;
}
if (m_FilenameLookup.find(filename) == m_FilenameLookup.end()) {
cerr << "LADSPA Library " << filename << " not found!" << endl;
return 0;
}

unsigned long library_index = m_FilenameLookup[filename];
unsigned long library_index = m_FilenameLookup[filename];

if (!(m_Libraries[library_index].Handle)) library_loaded = true;
if (!(m_Libraries[library_index].Handle)) library_loaded = true;

LADSPA_Descriptor_Function desc_func = GetDescriptorFunctionForLibrary(library_index);
LADSPA_Descriptor_Function desc_func = GetDescriptorFunctionForLibrary(library_index);

if (!desc_func) {
return 0;
}
if (!desc_func) {
return 0;
}

// Search for label in library
const LADSPA_Descriptor *desc;
for (unsigned long i = 0; (desc = desc_func(i)) != NULL; i++) {
string l = desc->Label;
if (l == label) {
// If we had to load the library, unload it
unsigned long id = desc->UniqueID;
if (library_loaded) {
dlclose(m_Libraries[library_index].Handle);
m_Libraries[library_index].Handle = NULL;
}
return id;
}
}

cerr << "Plugin " << label << " not found in library " << filename << endl;
return 0;
const LADSPA_Descriptor *desc;
for (unsigned long i = 0; (desc = desc_func(i)) != NULL; i++) {
string l = desc->Label;
if (l == label) {

// If we had to load the library, unload it
unsigned long id = desc->UniqueID;
if (library_loaded) {
dlclose(m_Libraries[library_index].Handle);
m_Libraries[library_index].Handle = NULL;
}
return id;
}
}

cerr << "Plugin " << label << " not found in library " << filename << endl;
return 0;
}

const vector<LADSPAInfo::PluginEntry>
LADSPAInfo::GetPluginList(void)
{
return m_OrderedPluginList;
return m_OrderedPluginList;
}

unsigned long
LADSPAInfo::GetPluginListEntryByID(unsigned long unique_id)
{
unsigned long j = 0;
for (vector<PluginEntry>::iterator i = m_OrderedPluginList.begin();
i != m_OrderedPluginList.end(); i++, j++) {
if (i->UniqueID == unique_id) return j;
}
return m_OrderedPluginList.size();
unsigned long j = 0;
for (vector<PluginEntry>::iterator i = m_OrderedPluginList.begin();
i != m_OrderedPluginList.end(); i++, j++) {
if (i->UniqueID == unique_id) return j;
}
return m_OrderedPluginList.size();
}

// ****************************************************************************
@@ -244,282 +295,307 @@ LADSPAInfo::GetPluginListEntryByID(unsigned long unique_id)
void
LADSPAInfo::CleanUp(void)
{
m_IDLookup.clear();
m_FilenameLookup.clear();
m_Plugins.clear();
m_IDLookup.clear();
m_FilenameLookup.clear();
m_Plugins.clear();

// Unload loaded dlls
for (vector<LibraryInfo>::iterator i = m_Libraries.begin();
i != m_Libraries.end(); i++) {
if (i->Handle) dlclose(i->Handle);
}
for (vector<LibraryInfo>::iterator i = m_Libraries.begin();
i != m_Libraries.end(); i++) {
if (i->Handle) dlclose(i->Handle);
}

m_Libraries.clear();
m_Paths.clear();
m_Libraries.clear();
m_Paths.clear();

m_OrderedPluginList.clear();
m_MaxInputPortCount = 0;
m_RDFFiles.clear();
m_RDFPaths.clear();

if (m_ExtraPaths) {
free(m_ExtraPaths);
m_ExtraPaths = NULL;
}
lrdf_cleanup();

m_OrderedPluginList.clear();
m_MaxInputPortCount = 0;

if (m_ExtraPaths) {
free(m_ExtraPaths);
m_ExtraPaths = NULL;
}
}

// Given a colon-separated list of paths, examine the contents of each
// path, examining any regular files using the given member function,
// which currently can be:
//
// ExaminePluginLibrary - add plugin library info from plugins
// ExamineRDFFile - add plugin information from .rdf/.rdfs files
void
LADSPAInfo::ScanPathList(const char *path_list)
LADSPAInfo::ScanPathList(const char *path_list,
void (LADSPAInfo::*ExamineFunc)(const string,
const string))
{
const char *start;
const char *end;
int extra;
char *temp;

start = path_list;
while (*start != '\0') {
while (*start == ':') start++;
end = start;
while (*end != ':' && *end != '\0') end++;

if (end - start > 0) {
extra = (*(end - 1) == '/') ? 0 : 1;
temp = (char *)malloc(end - start + 1 + extra);
if (temp) {
strncpy(temp, start, end - start);
if (extra == 1) temp[end - start] = '/';
temp[end - start + extra] = '\0';

ExaminePath(temp);

free(temp);
}
}
start = end;
}
const char *start;
const char *end;
int extra;
char *path;
string basename;
DIR *dp;
struct dirent *ep;
struct stat sb;

// This does the same kind of thing as strtok, but strtok won't
// like the const
start = path_list;
while (*start != '\0') {
while (*start == ':') start++;
end = start;
while (*end != ':' && *end != '\0') end++;

if (end - start > 0) {
extra = (*(end - 1) == '/') ? 0 : 1;
path = (char *)malloc(end - start + 1 + extra);
if (path) {
strncpy(path, start, end - start);
if (extra == 1) path[end - start] = '/';
path[end - start + extra] = '\0';

dp = opendir(path);
if (!dp) {
cerr << "WARNING: Could not open path " << path << endl;
} else {
while ((ep = readdir(dp))) {

// Stat file to get type
basename = ep->d_name;
if (!stat((path + basename).c_str(), &sb)) {

// We only want regular files
if (S_ISREG(sb.st_mode)) (*this.*ExamineFunc)(path, basename);
}
}
closedir(dp);
}
free(path);
}
}
start = end;
}
}

// Check given path:
// 1. Exists
// 2. Is a directory
// 3. Contains at least one LADSPA Plugin library
// Check given file is a valid LADSPA Plugin library
//
// If so, add the path to the Paths vector, and examine
// contents, adding all valid LADSPA plugin library info
// to the Libraries and Plugins vectors.
// If so, add path, library and plugin info
// to the m_Paths, m_Libraries and m_Plugins vectors.
void
LADSPAInfo::ExaminePath(const char *path)
LADSPAInfo::ExaminePluginLibrary(const string path,
const string basename)
{
DIR *dp;
struct dirent *ep;
struct stat sb;
void *handle;
LADSPA_Descriptor_Function desc_func;
const LADSPA_Descriptor *desc;
bool path_added;
unsigned long path_index;
bool library_added;
string fullpath;
vector<string> temp_names;
vector<string>::iterator p = find(m_Paths.begin(), m_Paths.end(), path);

path_added = !(p == m_Paths.end());
path_index = p - m_Paths.begin();

dp = opendir(path);
if (!dp) {
cerr << "WARNING: Could not open path " << path << endl;
} else {
while ((ep = readdir(dp))) {

// Need full path
fullpath = path;
fullpath.append(ep->d_name);

// Stat file to get type
if (!stat(fullpath.c_str(), &sb)) {

// We only want regular files
if (S_ISREG(sb.st_mode)) {

// We're not fussed about resolving symbols yet, since we are just
// checking libraries.
handle = dlopen(fullpath.c_str(), RTLD_LAZY);

if (!handle) {
cerr << "WARNING: File " << path << ep->d_name
<< " could not be examined" << endl;
cerr << "dlerror() output:" << endl;
cerr << dlerror() << endl;
} else {

// It's a DLL, so now see if it's a LADSPA plugin library
desc_func = (LADSPA_Descriptor_Function)dlsym(handle,
"ladspa_descriptor");
if (!desc_func) {

// Is DLL, but not a LADSPA one
cerr << "WARNING: DLL " << path << ep->d_name
<< " has no ladspa_descriptor function" << endl;
cerr << "dleror() output:" << endl;
cerr << dlerror() << endl;
} else {

// Got ladspa_descriptor, so we can now get plugin info
library_added = false;
unsigned long i = 0;
desc = desc_func(i);
while (desc) {

// First, check that it's not a dupe
if (m_IDLookup.find(desc->UniqueID) != m_IDLookup.end()) {
unsigned long plugin_index;
unsigned long library_index;

cerr << "WARNING: Duplicated Plugin ID ("
<< desc->UniqueID << ") found:" << endl;

plugin_index = m_IDLookup[desc->UniqueID];
library_index = m_Plugins[plugin_index].LibraryIndex;
path_index = m_Libraries[library_index].PathIndex;

cerr << " Plugin " << m_Plugins[plugin_index].Index
<< " in library: " << m_Paths[path_index]
<< m_Libraries[library_index].Basename
<< " [First instance found]" << endl;
cerr << " Plugin " << i << " in library: " << path << ep->d_name
<< " [Duplicate not added]" << endl;
} else {
if (CheckPlugin(desc_func)) {
if (!path_added) {

// Add path
m_Paths.push_back(path);
path_added = true;
}
if (!library_added) {

// Add library info
LibraryInfo li;
li.PathIndex = path_index;
li.Basename = ep->d_name;
li.RefCount = 0;
li.Handle = NULL;
m_Libraries.push_back(li);

// Add filename to lookup
m_FilenameLookup[fullpath] = m_Libraries.size() - 1;

library_added = true;
}

// Add plugin info
PluginInfo pi;
pi.LibraryIndex = m_Libraries.size() - 1;
pi.Index = i;
pi.Descriptor = NULL;
m_Plugins.push_back(pi);

// Add to index
m_IDLookup[desc->UniqueID] = m_Plugins.size() - 1;

// Add to ordered list
PluginEntry pe;
pe.UniqueID = desc->UniqueID;
pe.Name = desc->Name;
m_OrderedPluginList.push_back(pe);

// Find number of input ports
unsigned long in_port_count = 0;
for (unsigned long p = 0; p < desc->PortCount; p++) {
if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[p])) {
in_port_count++;
}
}
if (in_port_count > m_MaxInputPortCount) {
m_MaxInputPortCount = in_port_count;
}
} else {
cerr << "WARNING: Plugin " << desc->UniqueID << " not added" << endl;
}
}

desc = desc_func(++i);
}
}
dlclose(handle);
}
}
}
}
closedir(dp);
}
void *handle;
LADSPA_Descriptor_Function desc_func;
const LADSPA_Descriptor *desc;
string fullpath = path + basename;

// We're not fussed about resolving symbols yet, since we are just
// checking libraries.
handle = dlopen(fullpath.c_str(), RTLD_LAZY);

if (!handle) {
cerr << "WARNING: File " << fullpath
<< " could not be examined" << endl;
cerr << "dlerror() output:" << endl;
cerr << dlerror() << endl;
} else {

// It's a DLL, so now see if it's a LADSPA plugin library
desc_func = (LADSPA_Descriptor_Function)dlsym(handle,
"ladspa_descriptor");
if (!desc_func) {

// Is DLL, but not a LADSPA one
cerr << "WARNING: DLL " << fullpath
<< " has no ladspa_descriptor function" << endl;
cerr << "dlerror() output:" << endl;
cerr << dlerror() << endl;
} else {

// Got ladspa_descriptor, so we can now get plugin info
bool library_added = false;
unsigned long i = 0;
desc = desc_func(i);
while (desc) {

// First, check that it's not a dupe
if (m_IDLookup.find(desc->UniqueID) != m_IDLookup.end()) {
unsigned long plugin_index = m_IDLookup[desc->UniqueID];
unsigned long library_index = m_Plugins[plugin_index].LibraryIndex;
unsigned long path_index = m_Libraries[library_index].PathIndex;

cerr << "WARNING: Duplicated Plugin ID ("
<< desc->UniqueID << ") found:" << endl;

cerr << " Plugin " << m_Plugins[plugin_index].Index
<< " in library: " << m_Paths[path_index]
<< m_Libraries[library_index].Basename
<< " [First instance found]" << endl;
cerr << " Plugin " << i << " in library: " << fullpath
<< " [Duplicate not added]" << endl;
} else {
if (CheckPlugin(desc)) {

// Add path if not already added
unsigned long path_index;
vector<string>::iterator p = find(m_Paths.begin(), m_Paths.end(), path);
if (p == m_Paths.end()) {
path_index = m_Paths.size();
m_Paths.push_back(path);
} else {
path_index = p - m_Paths.begin();
}

// Add library info if not already added
if (!library_added) {
LibraryInfo li;
li.PathIndex = path_index;
li.Basename = basename;
li.RefCount = 0;
li.Handle = NULL;
m_Libraries.push_back(li);

library_added = true;
}

// Add filename to lookup
m_FilenameLookup[fullpath] = m_Libraries.size() - 1;

// Add plugin info
PluginInfo pi;
pi.LibraryIndex = m_Libraries.size() - 1;
pi.Index = i;
pi.Descriptor = NULL;
m_Plugins.push_back(pi);

// Add to index
m_IDLookup[desc->UniqueID] = m_Plugins.size() - 1;

// Add to ordered list
PluginEntry pe;
pe.UniqueID = desc->UniqueID;
pe.Name = desc->Name;
m_OrderedPluginList.push_back(pe);

// Find number of input ports
unsigned long in_port_count = 0;
for (unsigned long p = 0; p < desc->PortCount; p++) {
if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[p])) {
in_port_count++;
}
}
if (in_port_count > m_MaxInputPortCount) {
m_MaxInputPortCount = in_port_count;
}
} else {
cerr << "WARNING: Plugin " << desc->UniqueID << " not added" << endl;
}
}

desc = desc_func(++i);
}
}
dlclose(handle);
}
}

bool
LADSPAInfo::CheckPlugin(const LADSPA_Descriptor_Function desc_func)
// Examine given RDF plugin meta-data file, adding any information found
void
LADSPAInfo::ExamineRDFFile(const std::string path,
const std::string basename)
{
const LADSPA_Descriptor *desc;
// Add path if not already added
string fileuri = "file://" + path + basename;

if (!lrdf_read_file(fileuri.c_str())) {
unsigned long path_index;
vector<string>::iterator p = find(m_RDFPaths.begin(), m_RDFPaths.end(), path);
if (p == m_RDFPaths.end()) {
path_index = m_RDFPaths.size();
m_RDFPaths.push_back(path);
} else {
path_index = p - m_RDFPaths.begin();
}

// Add file info to our rdf database
RDFFileInfo ri;
ri.RDFPathIndex = path_index;
ri.Basename = basename;
m_RDFFiles.push_back(ri);

} else {
cerr << "WARNING: File " << path + basename << " could not be parsed [Ignored]" << endl;
}
}

bool
LADSPAInfo::CheckPlugin(const LADSPA_Descriptor *desc)
{
#define test(t, m) { \
if (!(t)) { \
cerr << m << endl; \
return false; \
} \
if (!(t)) { \
cerr << m << endl; \
return false; \
} \
}
for (unsigned long i = 0; (desc = desc_func(i)) != NULL; i++) {
test(!LADSPA_IS_REALTIME(desc->Properties), "WARNING: Plugin must run real time");
test(desc->instantiate, "WARNING: Plugin has no instatiate function");
test(desc->connect_port, "WARNING: Warning: Plugin has no connect_port funciton");
test(desc->run, "WARNING: Plugin has no run function");
test(!(desc->run_adding != 0 && desc->set_run_adding_gain == 0),
"WARNING: Plugin has run_adding but no set_run_adding_gain");
test(!(desc->run_adding == 0 && desc->set_run_adding_gain != 0),
"WARNING: Plugin has set_run_adding_gain but no run_adding");
test(desc->cleanup, "WARNING: Plugin has no cleanup function");
test(!LADSPA_IS_INPLACE_BROKEN(desc->Properties),
"WARNING: Plugin cannot use in place processing");
test(desc->PortCount, "WARNING: Plugin has no ports");
}
return true;
test(!LADSPA_IS_REALTIME(desc->Properties), "WARNING: Plugin must run real time");
test(desc->instantiate, "WARNING: Plugin has no instatiate function");
test(desc->connect_port, "WARNING: Warning: Plugin has no connect_port funciton");
test(desc->run, "WARNING: Plugin has no run function");
test(!(desc->run_adding != 0 && desc->set_run_adding_gain == 0),
"WARNING: Plugin has run_adding but no set_run_adding_gain");
test(!(desc->run_adding == 0 && desc->set_run_adding_gain != 0),
"WARNING: Plugin has set_run_adding_gain but no run_adding");
test(desc->cleanup, "WARNING: Plugin has no cleanup function");
test(!LADSPA_IS_INPLACE_BROKEN(desc->Properties),
"WARNING: Plugin cannot use in place processing");
test(desc->PortCount, "WARNING: Plugin has no ports");

return true;
}

LADSPA_Descriptor_Function
LADSPAInfo::GetDescriptorFunctionForLibrary(unsigned long library_index)
{
LibraryInfo *li = &(m_Libraries[library_index]);
if (!(li->Handle)) {
LibraryInfo *li = &(m_Libraries[library_index]);
if (!(li->Handle)) {

// Need full path
string fullpath = m_Paths[li->PathIndex];
fullpath.append(li->Basename);
// Need full path
string fullpath = m_Paths[li->PathIndex];
fullpath.append(li->Basename);

li->Handle = dlopen(fullpath.c_str(), RTLD_NOW);
if (!(li->Handle)) {
li->Handle = dlopen(fullpath.c_str(), RTLD_NOW);
if (!(li->Handle)) {

// Plugin library changed since last path scan
cerr << "WARNING: Plugin library " << fullpath << " cannot be loaded" << endl;
cerr << "Rescan of plugins recommended" << endl;
cerr << "dleror() output:" << endl;
cerr << dlerror() << endl;
return NULL;
}
}
// Plugin library changed since last path scan
cerr << "WARNING: Plugin library " << fullpath << " cannot be loaded" << endl;
cerr << "Rescan of plugins recommended" << endl;
cerr << "dlerror() output:" << endl;
cerr << dlerror() << endl;
return NULL;
}
}

// Got handle so now verify that it's a LADSPA plugin library
const LADSPA_Descriptor_Function desc_func = (LADSPA_Descriptor_Function)dlsym(li->Handle,
"ladspa_descriptor");
if (!desc_func) {
// Is DLL, but not a LADSPA one (changed since last path scan?)
cerr << "WARNING: DLL " << m_Paths[li->PathIndex] << li->Basename
<< " has no ladspa_descriptor function" << endl;
cerr << "Rescan of plugins recommended" << endl;
cerr << "dleror() output:" << endl;
cerr << dlerror() << endl;
// Unload library
dlclose(li->Handle);
return NULL;
}
return desc_func;
const LADSPA_Descriptor_Function desc_func = (LADSPA_Descriptor_Function)dlsym(li->Handle,
"ladspa_descriptor");
if (!desc_func) {
// Is DLL, but not a LADSPA one (changed since last path scan?)
cerr << "WARNING: DLL " << m_Paths[li->PathIndex] << li->Basename
<< " has no ladspa_descriptor function" << endl;
cerr << "Rescan of plugins recommended" << endl;
cerr << "dlerror() output:" << endl;
cerr << dlerror() << endl;
// Unload library
dlclose(li->Handle);
return NULL;
}
return desc_func;
}

+ 127
- 110
SpiralSound/Plugins/LADSPAPlugin/LADSPAInfo.h View File

@@ -29,118 +29,135 @@
class LADSPAInfo
{
public:
// If override is false, examine $LADSPA_PATH
// Also examine supplied path list
// For all paths, add basic plugin information for later lookup,
// instantiation and so on.
LADSPAInfo(bool override, const char *path_list);

// Unload all loaded plugins and clean up
~LADSPAInfo();

// ************************************************************************
// Loading/Unloading plugin libraries
//
// At first, no library dlls are loaded.
//
// Each library has an associated reference count, which is initially 0.
// As descriptors are requested, using GetDescriptorByID, this count
// is incremented. The library dll is loaded on the first request.
// At descriptors are discarded, the count is decremented, and when this
// reaches 0, the library is unloaded.

// Rescan all paths in $LADSPA_PATH, as per constructor.
// This will also unload all libraries, and make any descriptors that
// have not been discarded with DiscardDescriptorByID invalid.
void RescanPlugins(void);

// Unload all dlopened libraries. This will make any descriptors that
// have not been discarded with DiscardDescriptorByID invalid.
void UnloadAllLibraries(void);

// Get descriptor of plugin with given ID. This increments the descriptor
// count for the corresponding library.
const LADSPA_Descriptor *GetDescriptorByID(unsigned long unique_id);

// Notify that a descriptor corresponding to the given ID has been
// discarded. This decrements the descriptor count for the corresponding
// library.
void DiscardDescriptorByID(unsigned long unique_id);

// Get unique ID of plugin identified by given library filename and label.
unsigned long GetIDFromFilenameAndLabel(std::string filename,
std::string label);

struct PluginEntry
{
unsigned long UniqueID;
std::string Name;
};

// Get a list of plugins ordered by name (duplicate names are
// appended with a (number)
const std::vector<PluginEntry> GetPluginList(void);

// Get the index in the above list for given Unique ID
// If not found, this returns the size of the above list
unsigned long GetPluginListEntryByID(unsigned long unique_id);

// Get the number of input ports for the plugin with the most
// input ports
unsigned long GetMaxInputPortCount(void) { return m_MaxInputPortCount; }
// If override is false, examine $LADSPA_PATH
// Also examine supplied path list
// For all paths, add basic plugin information for later lookup,
// instantiation and so on.
LADSPAInfo(bool override, const char *path_list);

// Unload all loaded plugins and clean up
~LADSPAInfo();

// ************************************************************************
// Loading/Unloading plugin libraries
//
// At first, no library dlls are loaded.
//
// Each library has an associated reference count, which is initially 0.
// As descriptors are requested, using GetDescriptorByID, this count
// is incremented. The library dll is loaded on the first request.
// At descriptors are discarded, the count is decremented, and when this
// reaches 0, the library is unloaded.

// Rescan all paths in $LADSPA_PATH, as per constructor.
// This will also unload all libraries, and make any descriptors that
// have not been discarded with DiscardDescriptorByID invalid.
void RescanPlugins(void);

// Unload all dlopened libraries. This will make any descriptors that
// have not been discarded with DiscardDescriptorByID invalid.
void UnloadAllLibraries(void);

// Get descriptor of plugin with given ID. This increments the descriptor
// count for the corresponding library.
const LADSPA_Descriptor *GetDescriptorByID(unsigned long unique_id);

// Notify that a descriptor corresponding to the given ID has been
// discarded. This decrements the descriptor count for the corresponding
// library.
void DiscardDescriptorByID(unsigned long unique_id);

// Get unique ID of plugin identified by given library filename and label.
unsigned long GetIDFromFilenameAndLabel(std::string filename,
std::string label);

struct PluginEntry
{
unsigned long UniqueID;
std::string Name;
};

// Get a list of plugins ordered by name (duplicate names are
// appended with a (number)
const std::vector<PluginEntry> GetPluginList(void);

// Get the index in the above list for given Unique ID
// If not found, this returns the size of the above list
unsigned long GetPluginListEntryByID(unsigned long unique_id);

// Get the number of input ports for the plugin with the most
// input ports
unsigned long GetMaxInputPortCount(void) { return m_MaxInputPortCount; }

void PrintInfo(void);

private:
void CleanUp(void);
void ScanPathList(const char *path_list);
void ExaminePath(const char *path);
bool CheckPlugin(LADSPA_Descriptor_Function desc_func);
LADSPA_Descriptor_Function GetDescriptorFunctionForLibrary(unsigned long library_index);

struct LibraryInfo
{
unsigned long PathIndex; // Index of path in m_Paths
std::string Basename; // Filename
unsigned long RefCount; // Count of descriptors requested from library
void *Handle; // DLL Handle, NULL
};

struct PluginInfo
{
unsigned long LibraryIndex; // Index of library in m_Libraries
unsigned long Index; // Plugin index in library
const LADSPA_Descriptor *Descriptor; // Descriptor, NULL
};

typedef std::map<unsigned long,
unsigned long,
std::less<unsigned long> > IDMap;

typedef std::map<std::string,
unsigned long,
std::less<std::string> > StringMap;

// For sorting vectors of PluginEntries
struct PluginEntrySortAsc
{
bool operator()(const PluginEntry &begin, const PluginEntry &end)
{
return begin.Name < end.Name;
}
};

bool m_LADSPAPathOverride;
char *m_ExtraPaths;

std::vector<std::string> m_Paths;
std::vector<LibraryInfo> m_Libraries;
std::vector<PluginInfo> m_Plugins;

IDMap m_IDLookup;
StringMap m_FilenameLookup;

std::vector<PluginEntry> m_OrderedPluginList;

unsigned long m_MaxInputPortCount;
void CleanUp(void);
void ScanPathList(const char *path_list,
void (LADSPAInfo::*ExamineFunc)(const std::string,
const std::string));
void ExaminePluginLibrary(const std::string path,
const std::string basename);
void ExamineRDFFile(const std::string path,
const std::string basename);

bool CheckPlugin(const LADSPA_Descriptor *desc);
LADSPA_Descriptor_Function GetDescriptorFunctionForLibrary(unsigned long library_index);

struct LibraryInfo
{
unsigned long PathIndex; // Index of path in m_Paths
std::string Basename; // Filename
unsigned long RefCount; // Count of descriptors requested from library
void *Handle; // DLL Handle, NULL
};

struct PluginInfo
{
unsigned long LibraryIndex; // Index of library in m_Libraries
unsigned long Index; // Plugin index in library
const LADSPA_Descriptor *Descriptor; // Descriptor, NULL
};

struct RDFFileInfo
{
unsigned long RDFPathIndex; // Index of path in m_RDFPaths
std::string Basename; // Filename
};

typedef std::map<unsigned long,
unsigned long,
std::less<unsigned long> > IDMap;

typedef std::map<std::string,
unsigned long,
std::less<std::string> > StringMap;

// For sorting vectors of PluginEntries
struct PluginEntrySortAsc
{
bool operator()(const PluginEntry &begin, const PluginEntry &end)
{
return begin.Name < end.Name;
}
};

bool m_LADSPAPathOverride;
char *m_ExtraPaths;

std::vector<std::string> m_Paths;
std::vector<LibraryInfo> m_Libraries;
std::vector<PluginInfo> m_Plugins;

std::vector<std::string> m_RDFPaths;
std::vector<RDFFileInfo> m_RDFFiles;

IDMap m_IDLookup;
StringMap m_FilenameLookup;

std::vector<PluginEntry> m_OrderedPluginList;

unsigned long m_MaxInputPortCount;
};

#endif // __ladspa_info_h__

+ 1
- 1
SpiralSound/Plugins/LADSPAPlugin/Makefile.in View File

@@ -14,7 +14,7 @@ CXXFLAGS= @CXXFLAGS@
INCPATH = -I/usr/X11R6/include
LINK = g++ -shared
LFLAGS =
LIBS = @FLTK_LIBS@ -L/usr/X11R6/lib -lGL -lXext -lX11 -ldl
LIBS = @FLTK_LIBS@ -L/usr/X11R6/lib -lGL -lXext -lX11 -ldl -llrdf
MOC = moc
UIC =



Loading…
Cancel
Save