| @@ -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; | ||||