From: <sag...@us...> - 2012-06-23 21:30:58
|
Revision: 1308 http://modplug.svn.sourceforge.net/modplug/?rev=1308&view=rev Author: saga-games Date: 2012-06-23 21:30:51 +0000 (Sat, 23 Jun 2012) Log Message: ----------- [New] VST: Plugin selection dialog categorizes plugins by their plugin type (as reported by the plugin). Modified Paths: -------------- trunk/OpenMPT/mptrack/SelectPluginDialog.cpp trunk/OpenMPT/mptrack/SelectPluginDialog.h trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h Modified: trunk/OpenMPT/mptrack/SelectPluginDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/SelectPluginDialog.cpp 2012-06-23 21:08:32 UTC (rev 1307) +++ trunk/OpenMPT/mptrack/SelectPluginDialog.cpp 2012-06-23 21:30:51 UTC (rev 1308) @@ -244,29 +244,55 @@ } -void CSelectPluginDlg::UpdatePluginsList(DWORD forceSelect /* = 0*/) -//------------------------------------------------------------------ +void CSelectPluginDlg::UpdatePluginsList(VstInt32 forceSelect /* = 0*/) +//--------------------------------------------------------------------- { CVstPluginManager *pManager = theApp.GetPluginManager(); - HTREEITEM cursel, hDmo, hVst, hSynth; + HTREEITEM curSelection, categoryFolders[VSTPluginLib::numCategories]; + vector<bool> categoryUsed(VSTPluginLib::numCategories, false); m_treePlugins.SetRedraw(FALSE); m_treePlugins.DeleteAllItems(); - hSynth = AddTreeItem("VST Instruments", IMAGE_FOLDER, false); - hDmo = AddTreeItem("DirectX Media Audio Effects", IMAGE_FOLDER, false); - hVst = AddTreeItem("VST Audio Effects", IMAGE_FOLDER, false); - cursel = AddTreeItem("No plugin (empty slot)", IMAGE_NOPLUGIN, false); + static const struct + { + VSTPluginLib::PluginCategory category; + const char *description; + } categories[] = + { + { VSTPluginLib::catEffect, "Audio Effects" }, + { VSTPluginLib::catGenerator, "Tone Generators" }, + { VSTPluginLib::catRestoration, "Audio Restauration" }, + { VSTPluginLib::catSurroundFx, "Surround Effects" }, + { VSTPluginLib::catRoomFx, "Room Effects" }, + { VSTPluginLib::catSpacializer, "Spacializers" }, + { VSTPluginLib::catMastering, "Mastering Plugins" }, + { VSTPluginLib::catAnalysis, "Analysis Plugins" }, + { VSTPluginLib::catOfflineProcess, "Offline Processing" }, + { VSTPluginLib::catShell, "Shell Plugins" }, + { VSTPluginLib::catUnknown, "Unsorted" }, + { VSTPluginLib::catDMO, "DirectX Media Audio Effects" }, + { VSTPluginLib::catSynth, "Instrument Plugins" }, + }; + + for(size_t i = CountOf(categories); i != 0; ) + { + i--; + categoryFolders[categories[i].category] = AddTreeItem(categories[i].description, IMAGE_FOLDER, false); + } + curSelection = AddTreeItem("No plugin (empty slot)", IMAGE_NOPLUGIN, false); - if (pManager) + if(pManager) { - VSTPluginLib *pCurrent = NULL; + const bool nameFilterActive = !m_sNameFilter.IsEmpty(); + + VSTPluginLib *pCurrent = nullptr; VSTPluginLib *p = pManager->GetFirstPlugin(); - while (p) + while(p) { - // Apply name filter - if (m_sNameFilter != "") + if(nameFilterActive) { + // Apply name filter CString displayName = p->szLibraryName; if (displayName.MakeLower().Find(m_sNameFilter) == -1) { @@ -275,95 +301,92 @@ } } - HTREEITEM hParent; - if (p->dwPluginId1 == kDmoMagic) + HTREEITEM h = AddTreeItem(p->szLibraryName, p->isInstrument ? IMAGE_PLUGININSTRUMENT : IMAGE_EFFECTPLUGIN, true, categoryFolders[p->category], reinterpret_cast<LPARAM>(p)); + categoryUsed[p->category] = true; + + if(nameFilterActive) { - hParent = hDmo; - } else - { - hParent = (p->isInstrument) ? hSynth : hVst; + // If filter is active, expand nodes. + m_treePlugins.EnsureVisible(h); } - HTREEITEM h = AddTreeItem(p->szLibraryName, p->isInstrument ? IMAGE_PLUGININSTRUMENT : IMAGE_EFFECTPLUGIN, true, hParent, (LPARAM)p); - - //If filter is active, expand nodes. - if (m_sNameFilter != "") m_treePlugins.EnsureVisible(h); - - //Which plugin should be selected? - if (m_pPlugin) + if(m_pPlugin) { + //Which plugin should be selected? - //forced selection (e.g. just after add plugin) - if (forceSelect != 0) + if(forceSelect != 0 && p->dwPluginId2 == forceSelect) { - if (p->dwPluginId2 == forceSelect) - { - pCurrent = p; - } - } - - //Current slot's plugin - else if (m_pPlugin->pMixPlugin) + //forced selection (e.g. just after add plugin) + pCurrent = p; + } else if(m_pPlugin->pMixPlugin) { + //Current slot's plugin CVstPlugin *pVstPlug = (CVstPlugin *)m_pPlugin->pMixPlugin; if (pVstPlug->GetPluginFactory() == p) pCurrent = p; - } - - //Plugin with matching ID to current slot's plug - else if (/* (!pCurrent) && */ m_pPlugin->Info.dwPluginId1 !=0 || m_pPlugin->Info.dwPluginId2 != 0) + } else if(m_pPlugin->Info.dwPluginId1 != 0 || m_pPlugin->Info.dwPluginId2 != 0) { - if ((p->dwPluginId1 == m_pPlugin->Info.dwPluginId1) - && (p->dwPluginId2 == m_pPlugin->Info.dwPluginId2)) + //Plugin with matching ID to current slot's plug + if(p->dwPluginId1 == m_pPlugin->Info.dwPluginId1 + && p->dwPluginId2 == m_pPlugin->Info.dwPluginId2) { pCurrent = p; } - } - - //Last selected plugin - else + } else { + //Last selected plugin if (p->dwPluginId2 == CMainFrame::GetSettings().gnPlugWindowLast) { pCurrent = p; } } } - if (pCurrent == p) cursel = h; + + if(pCurrent == p) + { + curSelection = h; + } + p = p->pNext; } } + + // Remove empty categories + for(size_t i = 0; i < CountOf(categoryFolders); i++) + { + if(!categoryUsed[i]) + { + m_treePlugins.DeleteItem(categoryFolders[i]); + } + } + m_treePlugins.SetRedraw(TRUE); - if (cursel) + if(curSelection) { - m_treePlugins.SelectItem(cursel); - m_treePlugins.SetItemState(cursel, TVIS_BOLD, TVIS_BOLD); - m_treePlugins.EnsureVisible(cursel); + m_treePlugins.SelectItem(curSelection); + m_treePlugins.SetItemState(curSelection, TVIS_BOLD, TVIS_BOLD); + m_treePlugins.EnsureVisible(curSelection); } } -HTREEITEM CSelectPluginDlg::AddTreeItem(LPSTR szTitle, int iImage, bool bSort, HTREEITEM hParent, LPARAM lParam) -//-------------------------------------------------------------------------------------------------------------- + +HTREEITEM CSelectPluginDlg::AddTreeItem(const char *title, int image, bool sort, HTREEITEM hParent, LPARAM lParam) +//---------------------------------------------------------------------------------------------------------------- { - TVINSERTSTRUCT tvis; - MemsetZero(tvis); - - tvis.hParent = hParent; - tvis.hInsertAfter = (bSort) ? TVI_SORT : TVI_FIRST; - tvis.item.mask = TVIF_IMAGE | TVIF_PARAM | TVIF_TEXT | TVIF_SELECTEDIMAGE | TVIF_TEXT; - tvis.item.pszText = szTitle; - tvis.item.iImage = tvis.item.iSelectedImage = iImage; - tvis.item.lParam = lParam; - return m_treePlugins.InsertItem(&tvis); + return m_treePlugins.InsertItem( + TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_TEXT, + title, + image, image, + 0, 0, + lParam, + hParent, + (sort ? TVI_SORT : TVI_FIRST)); } void CSelectPluginDlg::OnSelDblClk(NMHDR *, LRESULT *result) //---------------------------------------------------------- { - // -> CODE#0002 - // -> DESC="list box to choose VST plugin presets (programs)" - if(m_pPlugin == NULL) return; - // -! NEW_FEATURE#0002 + if(m_pPlugin == nullptr) return; HTREEITEM hSel = m_treePlugins.GetSelectedItem(); int nImage, nSelectedImage; @@ -390,34 +413,30 @@ } -struct PROBLEMATIC_PLUG -{ - DWORD id1; - DWORD id2; - DWORD version; - LPCSTR name; - LPCSTR problem; -}; - -//TODO: Check whether the list is still valid. -static const PROBLEMATIC_PLUG gProblemPlugs[] = -{ - { kEffectMagic, CCONST('N', 'i', '4', 'S'), 1, "Native Instruments B4", "* v1.1.1 hangs on playback. Do not proceed unless you have v1.1.5 or newer. *" }, - { kEffectMagic, CCONST('m', 'd', 'a', 'C'), 1, "MDA Degrade", "* Old versions of this plugin can crash OpenMPT.\nEnsure that you have the latest version of this plugin. *" }, - { kEffectMagic, CCONST('f', 'V', '2', 's'), 1, "Farbrausch V2", "* This plugin can cause OpenMPT to freeze if being used in a combination with various other plugins.\nIt is recommended to not use V2 in combination with any other plugins. *" }, - { kEffectMagic, CCONST('f', 'r', 'V', '2'), 1, "Farbrausch V2", "* This plugin can cause OpenMPT to freeze if being used in a combination with various other plugins.\nIt is recommended to not use V2 in combination with any other plugins. *" }, -}; - bool CSelectPluginDlg::VerifyPlug(VSTPluginLib *plug) //--------------------------------------------------- { - CString s; - for (size_t p = 0; p < CountOf(gProblemPlugs); p++) + // TODO: Keep this list up-to-date. + static const struct { - if ( (gProblemPlugs[p].id2 == plug->dwPluginId2) - /*&& (gProblemPlugs[p].id1 == plug->dwPluginId1)*/) + VstInt32 id1; + VstInt32 id2; + char *name; + char *problem; + } problemPlugs[] = + { + { kEffectMagic, CCONST('N', 'i', '4', 'S'), "Native Instruments B4", "* v1.1.1 hangs on playback. Do not proceed unless you have v1.1.5 or newer. *" }, + { kEffectMagic, CCONST('m', 'd', 'a', 'C'), "MDA Degrade", "* Old versions of this plugin can crash OpenMPT.\nEnsure that you have the latest version of this plugin. *" }, + { kEffectMagic, CCONST('f', 'V', '2', 's'), "Farbrausch V2", "* This plugin can cause OpenMPT to freeze if being used in a combination with various other plugins.\nIt is recommended to not use V2 in combination with any other plugins. *" }, + { kEffectMagic, CCONST('f', 'r', 'V', '2'), "Farbrausch V2", "* This plugin can cause OpenMPT to freeze if being used in a combination with various other plugins.\nIt is recommended to not use V2 in combination with any other plugins. *" }, + }; + + for(size_t p = 0; p < CountOf(problemPlugs); p++) + { + if(problemPlugs[p].id2 == plug->dwPluginId2 /*&& gProblemPlugs[p].id1 == plug->dwPluginId1*/) { - s.Format("WARNING: This plugin has been identified as %s,\nwhich is known to have the following problem with OpenMPT:\n\n%s\n\nWould you still like to add this plugin to the library?", gProblemPlugs[p].name, gProblemPlugs[p].problem); + CString s; + s.Format("WARNING: This plugin has been identified as %s,\nwhich is known to have the following problem with OpenMPT:\n\n%s\n\nWould you still like to add this plugin to the library?", problemPlugs[p].name, problemPlugs[p].problem); return (Reporting::Confirm(s) == cnfYes); } } @@ -448,7 +467,7 @@ if (pManager) { - plugLib = pManager->AddPlugin(sFilename, FALSE); + plugLib = pManager->AddPlugin(sFilename, false); if (plugLib) { bOk = true; Modified: trunk/OpenMPT/mptrack/SelectPluginDialog.h =================================================================== --- trunk/OpenMPT/mptrack/SelectPluginDialog.h 2012-06-23 21:08:32 UTC (rev 1307) +++ trunk/OpenMPT/mptrack/SelectPluginDialog.h 2012-06-23 21:30:51 UTC (rev 1308) @@ -26,13 +26,13 @@ CTreeCtrl m_treePlugins; CString m_sNameFilter; - HTREEITEM AddTreeItem(LPSTR szTitle, int iImage, bool bSort, HTREEITEM hParent = TVI_ROOT, LPARAM lParam = NULL); + HTREEITEM AddTreeItem(const char *title, int image, bool sort, HTREEITEM hParent = TVI_ROOT, LPARAM lParam = NULL); public: CSelectPluginDlg(CModDoc *pModDoc, int nPlugSlot, CWnd *parent); //rewbs.plugDocAware ~CSelectPluginDlg(); void DoClose(); - void UpdatePluginsList(DWORD forceSelect = 0); + void UpdatePluginsList(VstInt32 forceSelect = 0); bool VerifyPlug(VSTPluginLib *plug); virtual void DoDataExchange(CDataExchange* pDX); virtual BOOL OnInitDialog(); Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-06-23 21:08:32 UTC (rev 1307) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-06-23 21:30:51 UTC (rev 1308) @@ -161,6 +161,7 @@ p->pNext = m_pVstHead; p->dwPluginId1 = kDmoMagic; p->dwPluginId2 = clsid.Data1; + p->category = VSTPluginLib::catDMO; lstrcpyn(p->szLibraryName, s, sizeof(p->szLibraryName)); StringFixer::SetNullTerminator(p->szLibraryName); @@ -246,14 +247,32 @@ } } + +// Extract instrument and category information from plugin. +void GetPluginInformation(AEffect *effect, VSTPluginLib &library) +//--------------------------------------------------------------- +{ + library.category = static_cast<VSTPluginLib::PluginCategory>(effect->dispatcher(effect, effGetPlugCategory, 0, nullptr, nullptr, 0.0f)); + library.isInstrument = ((effect->flags & effFlagsIsSynth) || !effect->numInputs); + + if(library.isInstrument) + { + library.category = VSTPluginLib::catSynth; + } else if(library.category >= VSTPluginLib::numCategories) + { + library.category = VSTPluginLib::catUnknown; + } +} + + // // PluginCache format: // LibraryName = ID100000ID200000 // ID100000ID200000 = FullDllPath -// ID100000ID200000.Flags = Plugin Flags (for now, just isInstrument). +// ID100000ID200000.Flags = Plugin Flags (isInstrument + category). -VSTPluginLib *CVstPluginManager::AddPlugin(LPCSTR pszDllPath, BOOL bCache, const bool checkFileExistence, CString *const errStr) -//------------------------------------------------------------------------------------------------------------------------------ +VSTPluginLib *CVstPluginManager::AddPlugin(LPCSTR pszDllPath, bool fromCache, const bool checkFileExistence, CString *const errStr) +//--------------------------------------------------------------------------------------------------------------------------------- { TCHAR szPath[_MAX_PATH]; @@ -273,7 +292,7 @@ pDup = pDup->pNext; } // Look if the plugin info is stored in the PluginCache - if (bCache) + if(fromCache) { const CString cacheSection = "PluginCache"; const CString cacheFile = theApp.GetPluginCacheFileName(); @@ -313,16 +332,17 @@ n &= 0x0f; if (i < 8) { - p->dwPluginId1 = (p->dwPluginId1<<4) | n; + p->dwPluginId1 = (p->dwPluginId1 << 4) | n; } else { - p->dwPluginId2 = (p->dwPluginId2<<4) | n; + p->dwPluginId2 = (p->dwPluginId2 << 4) | n; } } + CString flagKey; flagKey.Format("%s.Flags", IDs); - int infoex = CMainFrame::GetPrivateProfileLong(cacheSection, flagKey, 0, cacheFile); - if (infoex & 1) p->isInstrument = true; + p->DecodeCacheFlags(CMainFrame::GetPrivateProfileLong(cacheSection, flagKey, 0, cacheFile)); + #ifdef VST_USE_ALTERNATIVE_MAGIC if( p->dwPluginId1 == kEffectMagic ) { @@ -378,8 +398,9 @@ p->dwPluginId1 = pEffect->magic; #endif // VST_USE_ALTERNATIVE_MAGIC p->dwPluginId2 = pEffect->uniqueID; - p->isInstrument = ((pEffect->flags & effFlagsIsSynth) || !pEffect->numInputs); + GetPluginInformation(pEffect, *p); + #ifdef VST_LOG int nver = pEffect->dispatcher(pEffect, effGetVstVersion, 0,0, nullptr, 0); if (!nver) nver = pEffect->version; @@ -423,7 +444,7 @@ WritePrivateProfileString(cacheSection, IDs, szPath, cacheFile); CMainFrame::WritePrivateProfileCString(cacheSection, IDs, pszDllPath, cacheFile); CMainFrame::WritePrivateProfileCString(cacheSection, p->szLibraryName, IDs, cacheFile); - CMainFrame::WritePrivateProfileLong(cacheSection, flagsKey, p->isInstrument, cacheFile); + CMainFrame::WritePrivateProfileLong(cacheSection, flagsKey, p->EncodeCacheFlags(), cacheFile); } return (validPlug ? m_pVstHead : nullptr); @@ -579,20 +600,21 @@ { validPlugin = true; - if(pEffect->flags & effFlagsIsSynth || !pEffect->numInputs) + const bool oldIsInstrument = pFound->isInstrument; + const VSTPluginLib::PluginCategory oldCategory = pFound->category; + + GetPluginInformation(pEffect, *pFound); + + if(oldIsInstrument != pFound->isInstrument || oldCategory != pFound->category) { - // Flag as instrument plugin - if (!pFound->isInstrument) - { - CString cacheSection = "PluginCache"; - CString cacheFile = theApp.GetPluginCacheFileName(); - //LPCSTR pszSection = "PluginCache"; - pFound->isInstrument = true; - CString flagsKey; - flagsKey.Format("%08X%08X.Flags", pFound->dwPluginId1, pFound->dwPluginId2); - CMainFrame::WritePrivateProfileLong(cacheSection, flagsKey, 1, cacheFile); - } + // Update cached information + CString cacheSection = "PluginCache"; + CString cacheFile = theApp.GetPluginCacheFileName(); + CString flagsKey; + flagsKey.Format("%08X%08X.Flags", pFound->dwPluginId1, pFound->dwPluginId2); + CMainFrame::WritePrivateProfileLong(cacheSection, flagsKey, pFound->EncodeCacheFlags(), cacheFile); } + CVstPlugin *pVstPlug = new CVstPlugin(hLibrary, pFound, pMixPlugin, pEffect); if (pVstPlug) pVstPlug->Initialize(pSndFile); } Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2012-06-23 21:08:32 UTC (rev 1307) +++ trunk/OpenMPT/mptrack/Vstplug.h 2012-06-23 21:30:51 UTC (rev 1308) @@ -37,10 +37,32 @@ struct VSTPluginLib { + enum PluginCategory + { + // Same plugin categories as defined in VST SDK + catUnknown = 0, + catEffect, // Simple Effect + catSynth, // VST Instrument (Synths, samplers,...) + catAnalysis, // Scope, Tuner, ... + catMastering, // Dynamics, ... + catSpacializer, // Panners, ... + catRoomFx, // Delays and Reverbs + catSurroundFx, // Dedicated surround processor + catRestoration, // Denoiser, ... + catOfflineProcess, // Offline Process + catShell, // Plug-in is container of other plug-ins + catGenerator, // Tone Generator, ... + // Custom categories + catDMO, // DirectX media object plugin + + numCategories, + }; + VSTPluginLib *pPrev, *pNext; VstInt32 dwPluginId1; VstInt32 dwPluginId2; bool isInstrument; + PluginCategory category; CVstPlugin *pPluginsList; CHAR szLibraryName[_MAX_FNAME]; CHAR szDllPath[_MAX_PATH]; @@ -51,12 +73,32 @@ dwPluginId1 = dwPluginId2 = 0; isInstrument = false; pPluginsList = nullptr; + category = catUnknown; if(dllPath != nullptr) { lstrcpyn(szDllPath, dllPath, CountOf(szDllPath)); StringFixer::SetNullTerminator(szDllPath); } } + + uint32 EncodeCacheFlags() + { + return (isInstrument ? 1 : 0) | (category << 1); + } + + void DecodeCacheFlags(uint32 flags) + { + category = static_cast<PluginCategory>(flags >> 1); + if(category >= numCategories) + { + category = catUnknown; + } + if(flags & 1) + { + isInstrument = true; + category = catSynth; + } + } }; @@ -281,7 +323,7 @@ public: VSTPluginLib *GetFirstPlugin() const { return m_pVstHead; } BOOL IsValidPlugin(const VSTPluginLib *pLib); - VSTPluginLib *AddPlugin(LPCSTR pszDllPath, BOOL bCache=TRUE, const bool checkFileExistence = false, CString* const errStr = 0); + VSTPluginLib *AddPlugin(LPCSTR pszDllPath, bool fromCache = true, const bool checkFileExistence = false, CString* const errStr = 0); bool RemovePlugin(VSTPluginLib *); BOOL CreateMixPlugin(SNDMIXPLUGIN *, CSoundFile *); void OnIdle(); @@ -305,7 +347,7 @@ #else // NO_VST public: - VSTPluginLib *AddPlugin(LPCSTR, BOOL =TRUE, const bool = false, CString* const = 0) {return 0;} + VSTPluginLib *AddPlugin(LPCSTR, bool = true, const bool = false, CString* const = 0) {return 0;} VSTPluginLib *GetFirstPlugin() const { return 0; } void OnIdle() {} #endif // NO_VST This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |