From: <sag...@us...> - 2014-03-19 02:06:13
|
Revision: 3905 http://sourceforge.net/p/modplug/code/3905 Author: saga-games Date: 2014-03-19 02:06:01 +0000 (Wed, 19 Mar 2014) Log Message: ----------- [New] Officially integrated VST bridge into OpenMPT now. It surely requires a bit more work, but is mostly usable by now. It can be force-enabled with BridgeAllPlugins=1 in the [VST Plugins] section of mptrack.ini. [Mod] OpenMPT: Version is now 1.22.07.31 Modified Paths: -------------- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp trunk/OpenMPT/mptrack/AbstractVstEditor.h trunk/OpenMPT/mptrack/DefaultVstEditor.h trunk/OpenMPT/mptrack/MPTRACK_10.sln trunk/OpenMPT/mptrack/SelectPluginDialog.cpp trunk/OpenMPT/mptrack/SelectPluginDialog.h trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/TrackerSettings.h trunk/OpenMPT/mptrack/VSTEditor.cpp trunk/OpenMPT/mptrack/VSTEditor.h trunk/OpenMPT/mptrack/VstPresets.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2014-03-19 02:06:01 UTC (rev 3905) @@ -58,7 +58,7 @@ ON_COMMAND_RANGE(ID_LEARN_MACRO_FROM_PLUGGUI, ID_LEARN_MACRO_FROM_PLUGGUI + NUM_MACROS, PrepareToLearnMacro) END_MESSAGE_MAP() -CAbstractVstEditor::CAbstractVstEditor(CVstPlugin &plugin) : m_VstPlugin(plugin) +CAbstractVstEditor::CAbstractVstEditor(CVstPlugin &plugin) : m_VstPlugin(plugin), updateDisplay(false) { m_nCurProg = -1; @@ -450,7 +450,7 @@ if(m_VstPlugin.CanRecieveMidiEvents()) { if(!m_VstPlugin.isInstrument() || m_VstPlugin.GetSoundFile().GetModSpecifications().instrumentsMax == 0 || - Reporting::Confirm(_T("You need to assign an instrument to this plugin before you can play notes from here.\nCreate a new instrument and assign this plugin to the instrument?"), false, false) == cnfNo) + Reporting::Confirm(_T("You need to assign an instrument to this plugin before you can play notes from here.\nCreate a new instrument and assign this plugin to the instrument?"), false, false, false, this) == cnfNo) { return false; } else Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.h =================================================================== --- trunk/OpenMPT/mptrack/AbstractVstEditor.h 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/AbstractVstEditor.h 2014-03-19 02:06:01 UTC (rev 3905) @@ -29,6 +29,7 @@ CMenu m_OptionsMenu; static UINT clipboardFormat; int32 currentPresetMenu; + bool updateDisplay; public: CVstPlugin &m_VstPlugin; @@ -69,13 +70,15 @@ virtual void OnCancel() = 0; virtual bool OpenEditor(CWnd *parent) = 0; virtual void DoClose() = 0; - virtual void UpdateParamDisplays() = 0; + virtual void UpdateParamDisplays() { if(updateDisplay) { SetupMenu(true); updateDisplay = false; } } virtual afx_msg void OnClose() = 0; virtual void OnActivate(UINT nState, CWnd *pWndOther, BOOL bMinimized); virtual bool IsResizable() const = 0; virtual bool SetSize(int contentWidth, int contentHeight) = 0; + void UpdateDisplay() { updateDisplay = true; } + DECLARE_MESSAGE_MAP() protected: Modified: trunk/OpenMPT/mptrack/DefaultVstEditor.h =================================================================== --- trunk/OpenMPT/mptrack/DefaultVstEditor.h 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/DefaultVstEditor.h 2014-03-19 02:06:01 UTC (rev 3905) @@ -67,7 +67,7 @@ CDefaultVstEditor(CVstPlugin &plugin); virtual ~CDefaultVstEditor(); - void UpdateParamDisplays() { UpdateControls(false); }; + virtual void UpdateParamDisplays() { CAbstractVstEditor::UpdateParamDisplays(); UpdateControls(false); }; virtual void OnOK(); virtual void OnCancel(); Modified: trunk/OpenMPT/mptrack/MPTRACK_10.sln =================================================================== --- trunk/OpenMPT/mptrack/MPTRACK_10.sln 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/MPTRACK_10.sln 2014-03-19 02:06:01 UTC (rev 3905) @@ -22,6 +22,8 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnRAR", "..\build\gen\UnRAR.vcxproj", "{95CC809B-03FC-4EDB-BB20-FD07A698C05F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginBridge", "..\pluginBridge\PluginBridge.vcxproj", "{8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -164,6 +166,17 @@ {95CC809B-03FC-4EDB-BB20-FD07A698C05F}.ReleaseNoLTCG|Win32.Build.0 = ReleaseNoLTCG|Win32 {95CC809B-03FC-4EDB-BB20-FD07A698C05F}.ReleaseNoLTCG|x64.ActiveCfg = ReleaseNoLTCG|x64 {95CC809B-03FC-4EDB-BB20-FD07A698C05F}.ReleaseNoLTCG|x64.Build.0 = ReleaseNoLTCG|x64 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.Debug|Win32.ActiveCfg = Debug|Win32 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.Debug|Win32.Build.0 = Debug|Win32 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.Debug|x64.ActiveCfg = Debug|x64 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.Debug|x64.Build.0 = Debug|x64 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.Release|Win32.ActiveCfg = Release|Win32 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.Release|Win32.Build.0 = Release|Win32 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.Release|x64.ActiveCfg = Release|x64 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.Release|x64.Build.0 = Release|x64 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.ReleaseNoLTCG|Win32.ActiveCfg = Release|x64 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.ReleaseNoLTCG|x64.ActiveCfg = Release|x64 + {8D55AB6B-DAB3-4EFB-9169-7EAF995D5C10}.ReleaseNoLTCG|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE Modified: trunk/OpenMPT/mptrack/SelectPluginDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/SelectPluginDialog.cpp 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/SelectPluginDialog.cpp 2014-03-19 02:06:01 UTC (rev 3905) @@ -14,9 +14,11 @@ #include "Mainfrm.h" #include "InputHandler.h" #include "Moddoc.h" -#include "SelectPluginDialog.h" #include "../common/StringFixer.h" #include "FileDialog.h" +#include "Vstplug.h" +#include "SelectPluginDialog.h" +#include "../pluginBridge/BridgeWrapper.h" #ifndef NO_VST @@ -31,6 +33,8 @@ ON_COMMAND(IDC_BUTTON1, OnAddPlugin) ON_COMMAND(IDC_BUTTON3, OnScanFolder) ON_COMMAND(IDC_BUTTON2, OnRemovePlugin) + ON_COMMAND(IDC_CHECK1, OnSetBridge) + ON_COMMAND(IDC_CHECK2, OnSetBridge) ON_EN_CHANGE(IDC_NAMEFILTER, OnNameFilterChanged) ON_WM_SIZE() ON_WM_GETMINMAXINFO() @@ -42,6 +46,8 @@ { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_TREE1, m_treePlugins); + DDX_Control(pDX, IDC_CHECK1, m_chkBridge); + DDX_Control(pDX, IDC_CHECK2, m_chkShare); } @@ -52,6 +58,9 @@ m_pModDoc = pModDoc; m_nPlugSlot = nPlugSlot; + hasBridge32 = Util::sdOs::IsPathFileAvailable(theApp.GetAppDirPath() + MPT_PATHSTRING("PluginBridge32.exe"), Util::sdOs::FileModeExists); + hasBridge64 = Util::sdOs::IsPathFileAvailable(theApp.GetAppDirPath() + MPT_PATHSTRING("PluginBridge64.exe"), Util::sdOs::FileModeExists); + if(m_pModDoc) { if(0 <= m_nPlugSlot && m_nPlugSlot < MAX_MIXPLUGINS) @@ -110,7 +119,7 @@ bool changed = false; CVstPluginManager *pManager = theApp.GetPluginManager(); - VSTPluginLib *pNewPlug = (VSTPluginLib *)m_treePlugins.GetItemData(m_treePlugins.GetSelectedItem()); + VSTPluginLib *pNewPlug = GetSelectedPlugin(); VSTPluginLib *pFactory = nullptr; CVstPlugin *pCurrentPlugin = nullptr; if (m_pPlugin) pCurrentPlugin = dynamic_cast<CVstPlugin *>(m_pPlugin->pMixPlugin); @@ -157,6 +166,9 @@ { mpt::String::Copy(m_pPlugin->Info.szName, s); } + } else + { + MemsetZero(m_pPlugin->Info); } } changed = true; @@ -418,22 +430,47 @@ //----------------------------------------------------------- { CVstPluginManager *pManager = theApp.GetPluginManager(); - VSTPluginLib *pPlug = (VSTPluginLib *)m_treePlugins.GetItemData(m_treePlugins.GetSelectedItem()); + VSTPluginLib *pPlug = GetSelectedPlugin(); + int showBoxes = SW_HIDE; if ((pManager) && (pManager->IsValidPlugin(pPlug))) { SetDlgItemTextW(m_hWnd, IDC_TEXT_CURRENT_VSTPLUG, pPlug->dllPath.ToWide().c_str()); + if(pPlug->pluginId1 == kEffectMagic) + { + bool isBridgeAvailable = (hasBridge32 && pPlug->GetDllBits() == 32) || (hasBridge64 && pPlug->GetDllBits() == 64); + if(TrackerSettings::Instance().bridgeAllPlugins || !isBridgeAvailable) + { + m_chkBridge.EnableWindow(FALSE); + m_chkBridge.SetCheck(isBridgeAvailable ? BST_CHECKED : BST_UNCHECKED); + } else + { + bool native = pPlug->IsNative(); + + m_chkBridge.EnableWindow(native ? TRUE : FALSE); + m_chkBridge.SetCheck((pPlug->useBridge || !native) ? BST_CHECKED : BST_UNCHECKED); + } + + m_chkShare.SetCheck(pPlug->shareBridgeInstance ? BST_CHECKED : BST_UNCHECKED); + m_chkShare.EnableWindow(m_chkBridge.GetCheck() != BST_UNCHECKED); + + showBoxes = SW_SHOW; + } else + { + } } else { SetDlgItemText(IDC_TEXT_CURRENT_VSTPLUG, ""); } + m_chkBridge.ShowWindow(showBoxes); + m_chkShare.ShowWindow(showBoxes); if (result) *result = 0; } -bool CSelectPluginDlg::VerifyPlug(const VSTPluginLib *plug) -//--------------------------------------------------------- +bool CSelectPluginDlg::VerifyPlug(VSTPluginLib *plug) +//--------------------------------------------------- { - // TODO: Keep this list up-to-date. + // TODO: Keep these lists up-to-date. static const struct { VstInt32 id1; @@ -444,20 +481,49 @@ { { 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. *" }, + { 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 or use it brigded mode only. *" }, + { 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 or use it brigded mode only. *" }, }; + // Plugins that should always be bridged. + static const struct + { + VstInt32 id1; + VstInt32 id2; + bool useBridge; + bool shareInstance; + } bridgedPlugs[] = + { + { kEffectMagic, CCONST('f', 'V', '2', 's'), true, true }, // Single instances of V2 can communicate (I think) + { kEffectMagic, CCONST('f', 'r', 'V', '2'), true, false }, + { kEffectMagic, CCONST('S', 'K', 'V', '3'), false, true }, // SideKick v3 always has to run in a shared instance + }; + for(size_t p = 0; p < CountOf(problemPlugs); p++) { if(problemPlugs[p].id2 == plug->pluginId2 && problemPlugs[p].id1 == plug->pluginId1) { 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, false, false, this) == cnfYes); + if(Reporting::Confirm(s, false, false, this) == cnfNo) + { + return false; + } + break; } } + for(size_t p = 0; p < CountOf(bridgedPlugs); p++) + { + if(bridgedPlugs[p].id2 == plug->pluginId2 && bridgedPlugs[p].id1 == plug->pluginId1) + { + plug->useBridge = bridgedPlugs[p].useBridge; + plug->shareBridgeInstance = bridgedPlugs[p].shareInstance; + plug->WriteToCache(); + break; + } + } + return true; } @@ -583,7 +649,7 @@ //------------------------------------- { const HTREEITEM pluginToDelete = m_treePlugins.GetSelectedItem(); - VSTPluginLib *pPlug = (VSTPluginLib *)m_treePlugins.GetItemData(pluginToDelete); + VSTPluginLib *pPlug = GetSelectedPlugin(); CVstPluginManager *pManager = theApp.GetPluginManager(); if ((pManager) && (pPlug)) @@ -596,6 +662,25 @@ } +void CSelectPluginDlg::OnSetBridge() +//---------------------------------- +{ + VSTPluginLib *plug = GetSelectedPlugin(); + if(plug) + { + if(m_chkBridge.IsWindowEnabled()) + { + // Only update this setting if the current setting isn't an enforced setting (e.g. because plugin isn't native). + // This has the advantage that plugins don't get force-checked when switching between 32-bit and 64-bit versions of OpenMPT. + plug->useBridge = m_chkBridge.GetCheck() != BST_UNCHECKED; + } + m_chkShare.EnableWindow(m_chkBridge.GetCheck() != BST_UNCHECKED); + plug->shareBridgeInstance = m_chkShare.GetCheck() != BST_UNCHECKED; + plug->WriteToCache(); + } +} + + void CSelectPluginDlg::OnSize(UINT nType, int cx, int cy) //------------------------------------------------------- { @@ -603,17 +688,19 @@ if (m_treePlugins) { - m_treePlugins.MoveWindow(8, 36, cx - 104, cy - 63, FALSE); + m_treePlugins.MoveWindow(8, 36, cx - 104, cy - 88, FALSE); GetDlgItem(IDC_STATIC_VSTNAMEFILTER)->MoveWindow(8, 11, 40, 21, FALSE); GetDlgItem(IDC_NAMEFILTER)->MoveWindow(40, 8, cx - 136, 21, FALSE); - GetDlgItem(IDC_TEXT_CURRENT_VSTPLUG)->MoveWindow(8, cy - 20, cx - 22, 25, FALSE); + GetDlgItem(IDC_TEXT_CURRENT_VSTPLUG)->MoveWindow(8, cy - 45, cx - 22, 20, FALSE); + m_chkBridge.MoveWindow(8, cy - 25, 110, 20, FALSE); + m_chkShare.MoveWindow(120, cy - 25, cx - 128, 20, FALSE); const int rightOff = cx - 85; // Offset of right button column GetDlgItem(IDOK)->MoveWindow( rightOff, 8, 75, 23, FALSE); GetDlgItem(IDCANCEL)->MoveWindow( rightOff, 39, 75, 23, FALSE); - GetDlgItem(IDC_BUTTON1)->MoveWindow(rightOff, cy - 108, 75, 23, FALSE); - GetDlgItem(IDC_BUTTON3)->MoveWindow(rightOff, cy - 80, 75, 23, FALSE); - GetDlgItem(IDC_BUTTON2)->MoveWindow(rightOff, cy - 52, 75, 23, FALSE); + GetDlgItem(IDC_BUTTON1)->MoveWindow(rightOff, cy - 133, 75, 23, FALSE); + GetDlgItem(IDC_BUTTON3)->MoveWindow(rightOff, cy - 105, 75, 23, FALSE); + GetDlgItem(IDC_BUTTON2)->MoveWindow(rightOff, cy - 77, 75, 23, FALSE); Invalidate(); } } @@ -621,7 +708,7 @@ void CSelectPluginDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) //------------------------------------------------------- { - lpMMI->ptMinTrackSize.x = 300; + lpMMI->ptMinTrackSize.x = 350; lpMMI->ptMinTrackSize.y = 270; CDialog::OnGetMinMaxInfo(lpMMI); } Modified: trunk/OpenMPT/mptrack/SelectPluginDialog.h =================================================================== --- trunk/OpenMPT/mptrack/SelectPluginDialog.h 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/SelectPluginDialog.h 2014-03-19 02:06:01 UTC (rev 3905) @@ -13,9 +13,12 @@ #ifndef SELECTPLUGINDIALOG_H #define SELECTPLUGINDIALOG_H -#include "Vstplug.h" #include "CTreeCtrl.h" +class CModDoc; +struct SNDMIXPLUGIN; +struct VSTPluginLib; + //==================================== class CSelectPluginDlg: public CDialog //==================================== @@ -25,29 +28,36 @@ SNDMIXPLUGIN *m_pPlugin; CModDoc *m_pModDoc; CTreeCtrlW m_treePlugins; + CButton m_chkBridge, m_chkShare; std::wstring m_nameFilter; + bool hasBridge32, hasBridge64; HTREEITEM AddTreeItem(const WCHAR *title, int image, bool sort, HTREEITEM hParent = TVI_ROOT, LPARAM lParam = NULL); public: CSelectPluginDlg(CModDoc *pModDoc, int nPlugSlot, CWnd *parent); ~CSelectPluginDlg(); + +protected: + VSTPluginLib *GetSelectedPlugin() { return reinterpret_cast<VSTPluginLib *>(m_treePlugins.GetItemData(m_treePlugins.GetSelectedItem())); } + void DoClose(); void UpdatePluginsList(VstInt32 forceSelect = 0); - bool VerifyPlug(const VSTPluginLib *plug); + bool VerifyPlug(VSTPluginLib *plug); virtual void DoDataExchange(CDataExchange* pDX); virtual BOOL OnInitDialog(); virtual void OnOK(); virtual void OnCancel(); virtual BOOL PreTranslateMessage(MSG *pMsg); + DECLARE_MESSAGE_MAP() afx_msg void OnAddPlugin(); afx_msg void OnScanFolder(); afx_msg void OnRemovePlugin(); afx_msg void OnNameFilterChanged(); + afx_msg void OnSetBridge(); afx_msg void OnSelChanged(NMHDR *pNotifyStruct, LRESULT *result); afx_msg void OnSelDblClk(NMHDR *pNotifyStruct, LRESULT *result); - DECLARE_MESSAGE_MAP() afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); }; Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2014-03-19 02:06:01 UTC (rev 3905) @@ -216,6 +216,8 @@ , defaultTemplateFile(conf, "Paths", "DefaultTemplate", mpt::PathString()) // MRU List , mruListLength(conf, "Misc", "MRUListLength", 10) + // Plugins + , bridgeAllPlugins(conf, "VST Plugins", "BridgeAllPlugins", false) { // Effects #ifndef NO_DSP Modified: trunk/OpenMPT/mptrack/TrackerSettings.h =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.h 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/TrackerSettings.h 2014-03-19 02:06:01 UTC (rev 3905) @@ -471,6 +471,9 @@ // Chords MPTChords Chords; + // Plugins + Setting<bool> bridgeAllPlugins; + public: TrackerSettings(SettingsContainer &conf); Modified: trunk/OpenMPT/mptrack/VSTEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/VSTEditor.cpp 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/VSTEditor.cpp 2014-03-19 02:06:01 UTC (rev 3905) @@ -18,6 +18,7 @@ BEGIN_MESSAGE_MAP(COwnerVstEditor, CAbstractVstEditor) ON_WM_ERASEBKGND() + ON_WM_PAINT() END_MESSAGE_MAP() @@ -35,6 +36,24 @@ } +void COwnerVstEditor::OnPaint() +//----------------------------- +{ + CAbstractVstEditor::OnPaint(); + if(m_VstPlugin.isBridged) + { + // Instantly redraw bridged plugins so that we don't have to wait for their periodic refresh. + // This usually makes the timer used in the bridge unnecessary, but not always. + CRect rect; + if(plugWindow.GetUpdateRect(&rect, FALSE)) + { + CWnd *child = plugWindow.GetWindow(GW_CHILD | GW_HWNDFIRST); + if(child) child->RedrawWindow(&rect, nullptr, RDW_INVALIDATE | RDW_ALLCHILDREN); + } + } +} + + bool COwnerVstEditor::OpenEditor(CWnd *parent) //-------------------------------------------- { @@ -46,14 +65,18 @@ SetupMenu(); // Set editor window size + ERect rect; + MemsetZero(rect); ERect *pRect = nullptr; m_VstPlugin.Dispatch(effEditGetRect, 0, 0, &pRect, 0); + if(pRect) rect = *pRect; m_VstPlugin.Dispatch(effEditOpen, 0, 0, plugWindow.m_hWnd, 0); m_VstPlugin.Dispatch(effEditGetRect, 0, 0, &pRect, 0); - if((pRect) && (pRect->right > pRect->left) && (pRect->bottom > pRect->top)) + if(pRect) rect = *pRect; + if(rect.right > rect.left && rect.bottom > rect.top) { // Plugin provided valid window size. - SetSize(pRect->right - pRect->left, pRect->bottom - pRect->top); + SetSize(rect.right - rect.left, rect.bottom - rect.top); } // Restore previous editor position Modified: trunk/OpenMPT/mptrack/VSTEditor.h =================================================================== --- trunk/OpenMPT/mptrack/VSTEditor.h 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/VSTEditor.h 2014-03-19 02:06:01 UTC (rev 3905) @@ -29,13 +29,14 @@ DECLARE_MESSAGE_MAP() afx_msg BOOL OnEraseBkgnd(CDC *) { return TRUE; } + afx_msg void OnPaint(); // Plugins may request to change the GUI size. virtual bool IsResizable() const { return true; }; virtual bool SetSize(int contentWidth, int contentHeight); //Overridden: - void UpdateParamDisplays() { m_VstPlugin.Dispatch(effEditIdle, 0, 0, nullptr, 0.0f); }; //we trust that the plugin GUI can update its display with a bit of idle time. + virtual void UpdateParamDisplays() { CAbstractVstEditor::UpdateParamDisplays(); m_VstPlugin.Dispatch(effEditIdle, 0, 0, nullptr, 0.0f); }; //we trust that the plugin GUI can update its display with a bit of idle time. afx_msg void OnClose(); bool OpenEditor(CWnd *parent); void DoClose(); Modified: trunk/OpenMPT/mptrack/VstPresets.cpp =================================================================== --- trunk/OpenMPT/mptrack/VstPresets.cpp 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/VstPresets.cpp 2014-03-19 02:06:01 UTC (rev 3905) @@ -60,6 +60,16 @@ { // Program PlugParamIndex numParams = file.ReadUint32BE(); + + VstPatchChunkInfo info; + info.version = 1; + info.pluginUniqueID = header.fxID; + info.pluginVersion = header.fxVersion; + info.numElements = numParams; + MemsetZero(info.future); + plugin.Dispatch(effBeginLoadProgram, 0, 0, &info, 0.0f); + plugin.Dispatch(effBeginSetProgram, 0, 0, nullptr, 0.0f); + char prgName[28]; file.ReadString<mpt::String::maybeNullTerminated>(prgName, 28); plugin.Dispatch(effSetProgramName, 0, 0, prgName, 0.0f); @@ -79,6 +89,7 @@ FileReader chunk = file.ReadChunk(file.ReadUint32BE()); plugin.Dispatch(effSetChunk, 1, chunk.GetLength(), const_cast<char *>(chunk.GetRawData()), 0); } + plugin.Dispatch(effEndSetProgram, 0, 0, nullptr, 0.0f); } else if((header.fxMagic == bankMagic || header.fxMagic == chunkBankMagic) && firstChunk) { // Bank - only read if it's the first chunk in the file, not if it's a sub chunk. @@ -86,17 +97,27 @@ uint32 currentProgram = file.ReadUint32BE(); file.Skip(124); + VstPatchChunkInfo info; + info.version = 1; + info.pluginUniqueID = header.fxID; + info.pluginVersion = header.fxVersion; + info.numElements = numProgs; + MemsetZero(info.future); + plugin.Dispatch(effBeginLoadBank, 0, 0, &info, 0.0f); + if(header.fxMagic == bankMagic) { VstInt32 oldCurrentProgram = plugin.GetCurrentProgram(); for(uint32 p = 0; p < numProgs; p++) { - plugin.SetCurrentProgram(p); + plugin.Dispatch(effBeginSetProgram, 0, 0, nullptr, 0.0f); + plugin.Dispatch(effSetProgram, 0, 0, nullptr, 0.0f); ErrorCode retVal = LoadFile(file, plugin); if(retVal != noError) { return retVal; } + plugin.Dispatch(effEndSetProgram, 0, 0, nullptr, 0.0f); } plugin.SetCurrentProgram(oldCurrentProgram); } else Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2014-03-19 02:06:01 UTC (rev 3905) @@ -412,7 +412,7 @@ CAbstractVstEditor *pVstEditor = pVstPlugin->GetEditor(); if(pVstEditor && ::IsWindow(pVstEditor->m_hWnd)) { - pVstEditor->SetupMenu(true); + pVstEditor->UpdateDisplay(); } } return 0; @@ -652,8 +652,9 @@ // CVstPlugin // -CVstPlugin::CVstPlugin(HMODULE hLibrary, VSTPluginLib &factory, SNDMIXPLUGIN &mixStruct, AEffect &effect, CSoundFile &sndFile) : m_SndFile(sndFile), m_Factory(factory), m_Effect(effect) -//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +CVstPlugin::CVstPlugin(HMODULE hLibrary, VSTPluginLib &factory, SNDMIXPLUGIN &mixStruct, AEffect &effect, CSoundFile &sndFile) + : m_SndFile(sndFile), m_Factory(factory), m_Effect(effect), isBridged(!memcmp(&effect.resvd2, "OMPT", 4)) +//----------------------------------------------------------------------------------------------------------- { m_hLibrary = hLibrary; m_nRefCount = 1; @@ -709,8 +710,7 @@ m_bPassKeypressesToPlug = false; m_bRecordMIDIOut = false; - //rewbs.VSTcompliance - //Store a pointer so we can get the CVstPlugin object from the basic VST effect object. + // Store a pointer so we can get the CVstPlugin object from the basic VST effect object. m_Effect.resvd1 = ToVstPtr(this); m_nSlot = FindSlot(); m_nSampleRate = m_SndFile.GetSampleRate(); @@ -815,7 +815,8 @@ //------------------------------------ { // Input pointer array size must be >= 2 for now - the input buffer assignment might write to non allocated mem. otherwise - bool result = mixBuffer.Initialize(MAX(m_Effect.numInputs, 2), m_Effect.numOutputs); + // In case of a bridged plugin, the AEffect struct has been updated before calling this opcode, so we don't have to worry about it being up-to-date. + bool result = mixBuffer.Initialize(std::max<size_t>(m_Effect.numInputs, 2), m_Effect.numOutputs); m_MixState.pOutBufferL = mixBuffer.GetInputBuffer(0); m_MixState.pOutBufferR = mixBuffer.GetInputBuffer(1); @@ -1487,7 +1488,10 @@ } float **outputBuffers = mixBuffer.GetOutputBufferArray(); - mixBuffer.ClearOutputBuffers(nSamples); + if(!isBridged) + { + mixBuffer.ClearOutputBuffers(nSamples); + } // Do the VST processing magic try @@ -1533,7 +1537,10 @@ } } - ProcessMixOps(pOutL, pOutR, nSamples); + if(m_Effect.numOutputs != 0) + { + ProcessMixOps(pOutL, pOutR, outputBuffers[0], outputBuffers[m_Effect.numOutputs > 1 ? 1 : 0], nSamples); + } // If dry mix is ticked, we add the unprocessed buffer, // except if this is an instrument since this it has already been done: @@ -1551,10 +1558,10 @@ } -void CVstPlugin::ProcessMixOps(float *pOutL, float *pOutR, size_t nSamples) -//------------------------------------------------------------------------- +void CVstPlugin::ProcessMixOps(float *pOutL, float *pOutR, float *leftPlugOutput, float *rightPlugOutput, size_t nSamples) +//------------------------------------------------------------------------------------------------------------------------ { - float *leftPlugOutput; +/* float *leftPlugOutput; float *rightPlugOutput; if(m_Effect.numOutputs == 1) @@ -1569,7 +1576,7 @@ } else { return; - } + }*/ // -> mixop == 0 : normal processing // -> mixop == 1 : MIX += DRY - WET * wetRatio Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/Vstplug.h 2014-03-19 02:06:01 UTC (rev 3905) @@ -33,6 +33,7 @@ struct VSTPluginLib { +public: enum PluginCategory { // Same plugin categories as defined in VST SDK @@ -54,6 +55,7 @@ numCategories, }; +public: CVstPlugin *pPluginsList; // Pointer to first plugin instance (this instance carries pointers to other instances) mpt::PathString libraryName; // Display name mpt::PathString dllPath; // Full path name @@ -61,24 +63,36 @@ VstInt32 pluginId2; // Plugin unique ID PluginCategory category; bool isInstrument; + bool useBridge, shareBridgeInstance; +protected: + int8 dllBits; +public: VSTPluginLib(const mpt::PathString &dllPath, const mpt::PathString &libraryName) : pPluginsList(nullptr), libraryName(libraryName), dllPath(dllPath), pluginId1(0), pluginId2(0), category(catUnknown), - isInstrument(false) + isInstrument(false), useBridge(false), shareBridgeInstance(false), + dllBits(-1) { } + // Check whether a plugin can be hosted inside OpenMPT or requires bridging + int8 GetDllBits(); + bool IsNative() { return GetDllBits() == sizeof(void *); } + + void WriteToCache() const; + uint32 EncodeCacheFlags() const { - return (isInstrument ? 1 : 0) | (category << 1); + // Format: 00000000.00000000.000000SB.CCCCCCCI + return (isInstrument ? 1 : 0) | (category << 1) | (useBridge ? 0x100 : 0) | (shareBridgeInstance ? 0x200 : 0); } void DecodeCacheFlags(uint32 flags) { - category = static_cast<PluginCategory>(flags >> 1); + category = static_cast<PluginCategory>((flags & 0xFF) >> 1); if(category >= numCategories) { category = catUnknown; @@ -88,6 +102,14 @@ isInstrument = true; category = catSynth; } + if(flags & 0x100) + { + useBridge = true; + } + if(flags & 0x200) + { + shareBridgeInstance = true; + } } }; @@ -159,6 +181,7 @@ bool m_bRecordAutomation; bool m_bPassKeypressesToPlug; bool m_bRecordMIDIOut; + const bool isBridged; // True if our built-in plugin bridge is being used. public: CVstPlugin(HINSTANCE hLibrary, VSTPluginLib &factory, SNDMIXPLUGIN &mixPlugin, AEffect &effect, CSoundFile &sndFile); @@ -238,11 +261,11 @@ void MidiPitchBend(uint8 nMidiCh, int32 increment, int8 pwd); void MidiVibrato(uint8 nMidiCh, int32 depth, int8 pwd); void MidiCommand(uint8 nMidiCh, uint8 nMidiProg, uint16 wMidiBank, uint16 note, uint16 vol, CHANNELINDEX trackChannel); - void HardAllNotesOff(); //rewbs.VSTiNoteHoldonStopFix - bool isPlaying(UINT note, UINT midiChn, UINT trackerChn); //rewbs.instroVST - bool MoveNote(UINT note, UINT midiChn, UINT sourceTrackerChn, UINT destTrackerChn); //rewbs.instroVST - void NotifySongPlaying(bool playing); //rewbs.VSTCompliance - bool IsSongPlaying() {return m_bSongPlaying;} //rewbs.VSTCompliance + void HardAllNotesOff(); + bool isPlaying(UINT note, UINT midiChn, UINT trackerChn); + bool MoveNote(UINT note, UINT midiChn, UINT sourceTrackerChn, UINT destTrackerChn); + void NotifySongPlaying(bool playing); + bool IsSongPlaying() const { return m_bSongPlaying; } bool IsResumed() {return m_bPlugResumed;} void Resume(); void Suspend(); @@ -276,7 +299,7 @@ void ProcessVSTEvents(); void ReceiveVSTEvents(const VstEvents *events) const; - void ProcessMixOps(float *pOutL, float *pOutR, size_t nSamples); + void ProcessMixOps(float *pOutL, float *pOutR, float *leftPlugOutput, float *rightPlugOutput, size_t nSamples); void ReportPlugException(std::wstring text) const; @@ -310,6 +333,7 @@ void UpdateMixStructPtr(void*) {} void Bypass(bool = true) { } bool IsBypassed() const { return false; } + bool IsSongPlaying() const { return false; } #endif // NO_VST }; @@ -347,12 +371,14 @@ protected: void EnumerateDirectXDMOs(); - AEffect *LoadPlugin(const mpt::PathString &pluginPath, HINSTANCE &library); + AEffect *LoadPlugin(const VSTPluginLib &plugin, HINSTANCE &library, bool forceBridge); +public: + static VstIntPtr VSTCALLBACK MasterCallBack(AEffect *effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void *ptr, float opt); + protected: VstIntPtr VstCallback(AEffect *effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void *ptr, float opt); VstIntPtr VstFileSelector(bool destructor, VstFileSelect *fileSel, const CVstPlugin *plugin); - static VstIntPtr VSTCALLBACK MasterCallBack(AEffect *effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void *ptr, float opt); static bool CreateMixPluginProc(SNDMIXPLUGIN &, CSoundFile &); VstTimeInfo timeInfo; Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/mptrack.rc 2014-03-19 02:06:01 UTC (rev 3905) @@ -1444,20 +1444,22 @@ RTEXT "--",IDC_TEXT2,260,89,22,8 END -IDD_SELECTMIXPLUGIN DIALOGEX 0, 0, 249, 220 +IDD_SELECTMIXPLUGIN DIALOGEX 0, 0, 250, 231 STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME CAPTION "Plugin Manager" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - LTEXT "Filter:",IDC_STATIC_VSTNAMEFILTER,6,9,18,8 + LTEXT "&Filter:",IDC_STATIC_VSTNAMEFILTER,6,9,18,8 EDITTEXT IDC_NAMEFILTER,30,6,150,14,ES_AUTOHSCROLL + DEFPUSHBUTTON "&Add to Song",IDOK,187,6,53,14 + PUSHBUTTON "&Cancel",IDCANCEL,186,24,54,14 CONTROL "Tree1",IDC_TREE1,"SysTreeView32",TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | WS_HSCROLL | WS_TABSTOP,6,24,174,180,WS_EX_CLIENTEDGE - DEFPUSHBUTTON "Add to Song",IDOK,187,6,53,14 + EDITTEXT IDC_TEXT_CURRENT_VSTPLUG,7,206,235,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER + CONTROL "Use Plugin &Bridge",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,216,72,12 + CONTROL "Share Bridge between all &Instances",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,78,216,129,12 PUSHBUTTON "&New plugin...",IDC_BUTTON1,186,150,52,14,BS_MULTILINE + PUSHBUTTON "&Scan folder...",IDC_BUTTON3,186,168,52,14,BS_MULTILINE PUSHBUTTON "&Remove",IDC_BUTTON2,186,186,52,14 - PUSHBUTTON "&Cancel",IDCANCEL,186,24,54,14 - PUSHBUTTON "&Scan folder...",IDC_BUTTON3,186,168,52,14,BS_MULTILINE - EDITTEXT IDC_TEXT_CURRENT_VSTPLUG,7,206,235,14,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER END IDD_PLUGINEDITOR DIALOGEX 0, 0, 485, 153 @@ -1818,9 +1820,9 @@ IDD_SELECTMIXPLUGIN, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 242 + RIGHTMARGIN, 243 TOPMARGIN, 7 - BOTTOMMARGIN, 213 + BOTTOMMARGIN, 224 END IDD_PLUGINEDITOR, DIALOG Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2014-03-19 02:06:01 UTC (rev 3905) @@ -349,7 +349,7 @@ > </File> <File - RelativePath="..\soundlib\plugins\JBridge.cpp" + RelativePath="..\pluginBridge\BridgeWrapper.cpp" > </File> <File @@ -999,10 +999,14 @@ > </File> <File - RelativePath=".\soundlib\plugins\JBridge.h" + RelativePath="..\pluginBridge\BridgeWrapper.h" > </File> <File + RelativePath="..\pluginBridge\BridgeCommon.h" + > + </File> + <File RelativePath="..\common\Logging.h" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2014-03-19 02:06:01 UTC (rev 3905) @@ -453,6 +453,7 @@ <ClCompile Include="..\common\serialization_utils.cpp" /> <ClCompile Include="..\common\typedefs.cpp" /> <ClCompile Include="..\common\version.cpp" /> + <ClCompile Include="..\pluginBridge\BridgeWrapper.cpp" /> <ClCompile Include="..\sounddev\SoundDevice.cpp" /> <ClCompile Include="..\sounddev\SoundDeviceASIO.cpp" /> <ClCompile Include="..\sounddev\SoundDeviceDirectSound.cpp" /> @@ -491,7 +492,6 @@ <ClCompile Include="..\soundlib\pattern.cpp" /> <ClCompile Include="..\soundlib\patternContainer.cpp" /> <ClCompile Include="..\soundlib\plugins\DmoToVst.cpp" /> - <ClCompile Include="..\soundlib\plugins\JBridge.cpp" /> <ClCompile Include="..\soundlib\plugins\PluginManager.cpp" /> <ClCompile Include="..\soundlib\RowVisitor.cpp" /> <ClCompile Include="..\soundlib\S3MTools.cpp" /> @@ -654,6 +654,9 @@ <ClInclude Include="..\common\typedefs.h" /> <ClInclude Include="..\common\version.h" /> <ClInclude Include="..\common\versionNumber.h" /> + <ClInclude Include="..\pluginBridge\AEffectWrapper.h" /> + <ClInclude Include="..\pluginBridge\BridgeCommon.h" /> + <ClInclude Include="..\pluginBridge\BridgeWrapper.h" /> <ClInclude Include="..\sounddev\SoundDevice.h" /> <ClInclude Include="..\sounddev\SoundDeviceASIO.h" /> <ClInclude Include="..\sounddev\SoundDeviceDirectSound.h" /> @@ -690,7 +693,6 @@ <ClInclude Include="..\soundlib\mod_specifications.h" /> <ClInclude Include="..\soundlib\pattern.h" /> <ClInclude Include="..\soundlib\patternContainer.h" /> - <ClInclude Include="..\soundlib\plugins\JBridge.h" /> <ClInclude Include="..\soundlib\plugins\PluginEventQueue.h" /> <ClInclude Include="..\soundlib\plugins\PluginMixBuffer.h" /> <ClInclude Include="..\soundlib\plugins\PlugInterface.h" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2014-03-19 01:17:34 UTC (rev 3904) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2014-03-19 02:06:01 UTC (rev 3905) @@ -169,9 +169,6 @@ <ClCompile Include="..\common\stdafx.cpp"> <Filter>Source Files\common</Filter> </ClCompile> - <ClCompile Include="..\soundlib\plugins\JBridge.cpp"> - <Filter>Source Files\soundlib\plugins</Filter> - </ClCompile> <ClCompile Include="..\soundlib\Dlsbank.cpp"> <Filter>Source Files\soundlib</Filter> </ClCompile> @@ -511,6 +508,9 @@ <ClCompile Include="AppendModule.cpp"> <Filter>Header Files\mptrack</Filter> </ClCompile> + <ClCompile Include="..\pluginBridge\BridgeWrapper.cpp"> + <Filter>Source Files\pluginBridgeWrapper</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\soundlib\Loaders.h"> @@ -606,9 +606,6 @@ <ClInclude Include="..\common\stdafx.h"> <Filter>Header Files\common</Filter> </ClInclude> - <ClInclude Include="..\soundlib\plugins\JBridge.h"> - <Filter>Header Files\soundlib\plugins</Filter> - </ClInclude> <ClInclude Include="..\soundlib\plugins\PlugInterface.h"> <Filter>Header Files\soundlib\plugins</Filter> </ClInclude> @@ -996,6 +993,15 @@ <ClInclude Include="..\sounddev\SoundDeviceThread.h"> <Filter>Header Files\sounddev</Filter> </ClInclude> + <ClInclude Include="..\pluginBridge\AEffectWrapper.h"> + <Filter>Header Files\pluginBridgeWrapper</Filter> + </ClInclude> + <ClInclude Include="..\pluginBridge\BridgeCommon.h"> + <Filter>Header Files\pluginBridgeWrapper</Filter> + </ClInclude> + <ClInclude Include="..\pluginBridge\BridgeWrapper.h"> + <Filter>Header Files\pluginBridgeWrapper</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="res\bitmap1.bmp"> @@ -1150,6 +1156,12 @@ <Filter Include="Source Files\unarchiver"> <UniqueIdentifier>{2e5a8242-6eec-48cd-93b3-5880bee8b740}</UniqueIdentifier> </Filter> + <Filter Include="Header Files\pluginBridgeWrapper"> + <UniqueIdentifier>{d5f79087-1086-472a-a35b-402923a7f138}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\pluginBridgeWrapper"> + <UniqueIdentifier>{c5ca412e-0120-4e25-a6c0-945eedd7a0de}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <ResourceCompile Include="mptrack.rc"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |