@@ -85,10 +85,6 @@ LADSPAInfo::RescanPlugins(void) | |||||
cerr << m_Plugins.size() << " plugins found in " << m_Libraries.size() << " libraries" << endl; | cerr << m_Plugins.size() << " plugins found in " << m_Libraries.size() << " libraries" << endl; | ||||
} | } | ||||
// No last loaded library or plugin | |||||
m_LastLoadedLibraryIndex = m_Libraries.size(); | |||||
m_LastLoadedPluginIndex = m_Plugins.size(); | |||||
// Sort list by name | // Sort list by name | ||||
sort(m_OrderedPluginList.begin(), m_OrderedPluginList.end(), PluginEntrySortAsc()); | sort(m_OrderedPluginList.begin(), m_OrderedPluginList.end(), PluginEntrySortAsc()); | ||||
@@ -115,29 +111,12 @@ LADSPAInfo::UnloadAllLibraries(void) | |||||
for (vector<LibraryInfo>::iterator i = m_Libraries.begin(); | for (vector<LibraryInfo>::iterator i = m_Libraries.begin(); | ||||
i != m_Libraries.end(); i++) { | i != m_Libraries.end(); i++) { | ||||
if (i->Handle) dlclose(i->Handle); | if (i->Handle) dlclose(i->Handle); | ||||
} | |||||
// No last loaded library or plugin | |||||
m_LastLoadedLibraryIndex = m_Libraries.size(); | |||||
m_LastLoadedPluginIndex = m_Plugins.size(); | |||||
} | |||||
void | |||||
LADSPAInfo::UnloadLibraryByID(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]; | |||||
UnloadLibraryByPlugin(plugin_index); | |||||
i->RefCount = 0; | |||||
} | } | ||||
} | } | ||||
const LADSPA_Descriptor * | const LADSPA_Descriptor * | ||||
LADSPAInfo::GetDescriptorByID(unsigned long unique_id, | |||||
bool unload_previous_library) | |||||
LADSPAInfo::GetDescriptorByID(unsigned long unique_id) | |||||
{ | { | ||||
if (m_IDLookup.find(unique_id) == m_IDLookup.end()) { | if (m_IDLookup.find(unique_id) == m_IDLookup.end()) { | ||||
cerr << "LADSPA Plugin ID " << unique_id << " not found!" << endl; | cerr << "LADSPA Plugin ID " << unique_id << " not found!" << endl; | ||||
@@ -148,20 +127,55 @@ LADSPAInfo::GetDescriptorByID(unsigned long unique_id, | |||||
unsigned long plugin_index = m_IDLookup[unique_id]; | unsigned long plugin_index = m_IDLookup[unique_id]; | ||||
PluginInfo *pi = &(m_Plugins[plugin_index]); | PluginInfo *pi = &(m_Plugins[plugin_index]); | ||||
LibraryInfo *li = &(m_Libraries[pi->LibraryIndex]); | |||||
if (!(pi->Descriptor)) { | if (!(pi->Descriptor)) { | ||||
LADSPA_Descriptor_Function desc_func = GetDescriptorFunctionForLibrary(pi->LibraryIndex); | LADSPA_Descriptor_Function desc_func = GetDescriptorFunctionForLibrary(pi->LibraryIndex); | ||||
if (desc_func) { | |||||
pi->Descriptor = desc_func(pi->Index); | |||||
if (desc_func) pi->Descriptor = desc_func(pi->Index); | |||||
} | |||||
if (pi->Descriptor) { | |||||
// Success, so increment ref counter for library | |||||
li->RefCount++; | |||||
} | |||||
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]; | |||||
// Unload previously loaded library (if different) | |||||
if ((m_LastLoadedLibraryIndex != m_Libraries.size()) && | |||||
(m_LastLoadedLibraryIndex != pi->LibraryIndex)) { | |||||
UnloadLibraryByPlugin(plugin_index); | |||||
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; | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
return pi->Descriptor; | |||||
} | } | ||||
unsigned long | unsigned long | ||||
@@ -503,25 +517,3 @@ LADSPAInfo::GetDescriptorFunctionForLibrary(unsigned long library_index) | |||||
return desc_func; | return desc_func; | ||||
} | } | ||||
void | |||||
LADSPAInfo::UnloadLibraryByPlugin(unsigned long plugin_index) | |||||
{ | |||||
// Unload library corresponding to given plugin index | |||||
PluginInfo *pi = &(m_Plugins[plugin_index]); | |||||
LibraryInfo *li = &(m_Libraries[pi->LibraryIndex]); | |||||
if (li->Handle) 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; | |||||
} | |||||
} |
@@ -38,22 +38,36 @@ public: | |||||
// Unload all loaded plugins and clean up | // Unload all loaded plugins and clean up | ||||
~LADSPAInfo(); | ~LADSPAInfo(); | ||||
// Rescan all paths in $LADSPA_PATH, as per constructor | |||||
// This will also unload all libraries | |||||
// ************************************************************************ | |||||
// 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); | void RescanPlugins(void); | ||||
// Unload all dlopened libraries | |||||
// Unload all dlopened libraries. This will make any descriptors that | |||||
// have not been discarded with DiscardDescriptorByID invalid. | |||||
void UnloadAllLibraries(void); | void UnloadAllLibraries(void); | ||||
// Unload library containing plugin id | |||||
void UnloadLibraryByID(unsigned long unique_id); | |||||
// Get descriptor of plugin with given ID. This increments the descriptor | |||||
// count for the corresponding library. | |||||
const LADSPA_Descriptor *GetDescriptorByID(unsigned long unique_id); | |||||
// Get descriptor of plugin in list, loading library if necessary | |||||
// and optionally unloading previously loaded library (if different | |||||
// from library containing requested plugin. Phew!) | |||||
const LADSPA_Descriptor *GetDescriptorByID(unsigned long unique_id, | |||||
bool unload_previous_library); | |||||
// 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, | unsigned long GetIDFromFilenameAndLabel(std::string filename, | ||||
std::string label); | std::string label); | ||||
@@ -81,12 +95,12 @@ private: | |||||
void ExaminePath(const char *path); | void ExaminePath(const char *path); | ||||
bool CheckPlugin(LADSPA_Descriptor_Function desc_func); | bool CheckPlugin(LADSPA_Descriptor_Function desc_func); | ||||
LADSPA_Descriptor_Function GetDescriptorFunctionForLibrary(unsigned long library_index); | LADSPA_Descriptor_Function GetDescriptorFunctionForLibrary(unsigned long library_index); | ||||
void UnloadLibraryByPlugin(unsigned long plugin_index); | |||||
struct LibraryInfo | struct LibraryInfo | ||||
{ | { | ||||
unsigned long PathIndex; // Index of path in m_Paths | unsigned long PathIndex; // Index of path in m_Paths | ||||
std::string Basename; // Filename | std::string Basename; // Filename | ||||
unsigned long RefCount; // Count of descriptors requested from library | |||||
void *Handle; // DLL Handle, NULL | void *Handle; // DLL Handle, NULL | ||||
}; | }; | ||||
@@ -121,9 +135,6 @@ private: | |||||
std::vector<LibraryInfo> m_Libraries; | std::vector<LibraryInfo> m_Libraries; | ||||
std::vector<PluginInfo> m_Plugins; | std::vector<PluginInfo> m_Plugins; | ||||
unsigned long m_LastLoadedLibraryIndex; | |||||
unsigned long m_LastLoadedPluginIndex; | |||||
IDMap m_IDLookup; | IDMap m_IDLookup; | ||||
StringMap m_FilenameLookup; | StringMap m_FilenameLookup; | ||||
@@ -767,13 +767,13 @@ bool LADSPAPlugin::SelectPlugin(unsigned long UniqueID) | |||||
// Reject trivial case | // Reject trivial case | ||||
if (UniqueID == 0) return false; | if (UniqueID == 0) return false; | ||||
m_PlugDesc = m_LADSPAInfo->GetDescriptorByID(UniqueID, true); | |||||
m_PlugDesc = m_LADSPAInfo->GetDescriptorByID(UniqueID); | |||||
if (m_PlugDesc) { | if (m_PlugDesc) { | ||||
// Create instance | // Create instance | ||||
if (!(m_PlugInstHandle = m_PlugDesc->instantiate(m_PlugDesc, m_HostInfo->SAMPLERATE))) { | if (!(m_PlugInstHandle = m_PlugDesc->instantiate(m_PlugDesc, m_HostInfo->SAMPLERATE))) { | ||||
cerr << "WARNING: Could not instantiate plugin " << UniqueID << endl; | cerr << "WARNING: Could not instantiate plugin " << UniqueID << endl; | ||||
m_LADSPAInfo->UnloadLibraryByID(UniqueID); | |||||
m_LADSPAInfo->DiscardDescriptorByID(UniqueID); | |||||
m_PlugDesc = 0; | m_PlugDesc = 0; | ||||
return false; | return false; | ||||
} | } | ||||
@@ -884,6 +884,8 @@ void LADSPAPlugin::ClearPlugin(void) | |||||
if (m_PlugDesc->deactivate) m_PlugDesc->deactivate(m_PlugInstHandle); | if (m_PlugDesc->deactivate) m_PlugDesc->deactivate(m_PlugInstHandle); | ||||
m_PlugDesc->cleanup(m_PlugInstHandle); | m_PlugDesc->cleanup(m_PlugInstHandle); | ||||
m_PlugDesc = NULL; | m_PlugDesc = NULL; | ||||
m_LADSPAInfo->DiscardDescriptorByID(m_UniqueID); | |||||
} | } | ||||
m_TabIndex = 1; | m_TabIndex = 1; | ||||