From 1acb6f23f15b7628ceda35e58028439a01aaa643 Mon Sep 17 00:00:00 2001 From: locpham Date: Tue, 1 Sep 2026 18:08:10 +0700 Subject: [PATCH] =?UTF-8?q?fix(bridge):=200x7E=20iZotope=20=E2=80=94=20app?= =?UTF-8?q?end=20core=20DLL=20dirs=20(Program=20Files/iZotope/*/Cores)=20v?= =?UTF-8?q?ao=20PATH=20truoc=20Module::create?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iZotope VST3 single-file (Ozone 11.vst3) reference core DLL (iZOzone11Core.dll) dat rieng o C:\Program Files\iZotope\\Cores, khong canh .vst3. SetDllDirectoryW chi phu dir canh plugin -> LoadLibraryW fail ERROR_MOD_NOT_FOUND (0x7E) -> Windows dialog khi app load plugin. VstDllSearch.h quet cac dir Cores co dinh + append vao PATH (process-global, bridge load 1 plugin 1 luc). Ap dung ca RenderFxJob (FX chain + scan) va Vst3Instrument (VSTi). --- native_bridge/include/VstDllSearch.h | 71 ++++++++++++++++++++++++++++ native_bridge/src/RenderFxJob.cpp | 5 ++ native_bridge/src/Vst3Instrument.cpp | 6 +++ 3 files changed, 82 insertions(+) create mode 100644 native_bridge/include/VstDllSearch.h diff --git a/native_bridge/include/VstDllSearch.h b/native_bridge/include/VstDllSearch.h new file mode 100644 index 0000000..d2420a7 --- /dev/null +++ b/native_bridge/include/VstDllSearch.h @@ -0,0 +1,71 @@ +// native_bridge/include/VstDllSearch.h +// iZotope VST3 (Ozone 11, Nectar, Neutron...) là single-file .vst3 — core +// DLL (vd iZOzone11Core.dll) nằm RIÊNG ở +// C:\Program Files\iZotope\\Cores +// KHÔNG cạnh plugin → LoadLibraryW của VST3 SDK fail ERROR_MOD_NOT_FOUND +// (0x7E) dù setPluginSearchPath đã trỏ dir cạnh plugin. Helper này quét các +// dir Cores cố định và thêm vào PATH (process-global — bridge load 1 plugin +// 1 lúc, giống SetDllDirectoryW hiện có). +#ifndef VST_DLL_SEARCH_H +#define VST_DLL_SEARCH_H + +#include +#ifdef _WIN32 +#include +#endif + +#ifdef _WIN32 +inline std::string vstDllSearchExtras() { + std::string extras; + const char* bases[] = { + "C:\\Program Files\\iZotope", + "C:\\Program Files\\Common Files\\iZotope", + }; + for (const char* base : bases) { + std::string pat = std::string(base) + "\\*"; + WIN32_FIND_DATAA fd; + HANDLE h = FindFirstFileA(pat.c_str(), &fd); + if (h == INVALID_HANDLE_VALUE) continue; + do { + if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) continue; + if (fd.cFileName[0] == '.') continue; + std::string cores = std::string(base) + "\\" + fd.cFileName + "\\Cores"; + if (GetFileAttributesA(cores.c_str()) != INVALID_FILE_ATTRIBUTES) { + if (!extras.empty()) extras += ";"; + extras += cores; + } + } while (FindNextFileA(h, &fd)); + FindClose(h); + } + return extras; +} + +// Append extras vào PATH (bỏ dir đã có). Gọi TRƯỚC Module::create. +inline void vstAddDllSearchPath(const std::string& extras) { + if (extras.empty()) return; + char buf[32768]; + DWORD n = GetEnvironmentVariableA("PATH", buf, sizeof(buf)); + std::string path = n ? std::string(buf) : ""; + std::string toAdd; + size_t start = 0; + while (start <= extras.size()) { + size_t end = extras.find(';', start); + std::string dir = extras.substr(start, end == std::string::npos ? std::string::npos : end - start); + if (!dir.empty() && path.find(dir) == std::string::npos) { + if (!toAdd.empty()) toAdd += ";"; + toAdd += dir; + } + if (end == std::string::npos) break; + start = end + 1; + } + if (toAdd.empty()) return; + if (!path.empty()) path += ";"; + path += toAdd; + SetEnvironmentVariableA("PATH", path.c_str()); +} +#else +inline std::string vstDllSearchExtras() { return std::string(); } +inline void vstAddDllSearchPath(const std::string&) {} +#endif + +#endif // VST_DLL_SEARCH_H diff --git a/native_bridge/src/RenderFxJob.cpp b/native_bridge/src/RenderFxJob.cpp index 8d029bc..21279f1 100644 --- a/native_bridge/src/RenderFxJob.cpp +++ b/native_bridge/src/RenderFxJob.cpp @@ -10,6 +10,7 @@ // MIDI/GUI — component + controller, audio buses, processData with input // buffers copied directly (setChannelBuffers is unusable: prepare() owns them). #include "RenderFxJob.h" +#include "VstDllSearch.h" // sheredom/json.h (public domain) — vendored copy; SDK copy as fallback. #if __has_include("sheredom_json.h") @@ -443,6 +444,10 @@ static void setPluginSearchPath(const std::string& path) { // at a time (render slots serial; realtime chain loads on its own thread). std::wstring wdir(dir.begin(), dir.end()); SetDllDirectoryW(wdir.c_str()); + // iZotope core DLLs sống ở C:\Program Files\iZotope\\Cores (KHÔNG + // cạnh .vst3) — SetDllDirectoryW chỉ phủ dir cạnh plugin, core vẫn 0x7E. + // Append Cores dirs vào PATH (LoadLibraryW search PATH sau app/system dirs). + vstAddDllSearchPath(vstDllSearchExtras()); std::cerr << "[RenderFx] dll search dir: " << dir << std::endl; } #endif diff --git a/native_bridge/src/Vst3Instrument.cpp b/native_bridge/src/Vst3Instrument.cpp index f2ac0cf..e562417 100644 --- a/native_bridge/src/Vst3Instrument.cpp +++ b/native_bridge/src/Vst3Instrument.cpp @@ -8,6 +8,7 @@ // connect them, process MIDI events + audio blocks, and attach the editor // view to a native HWND (openGUI) for the floating GUI (B9). #include "Vst3Instrument.h" +#include "VstDllSearch.h" #ifdef HAVE_VST3SDK #ifdef _WIN32 @@ -254,6 +255,11 @@ bool Vst3Instrument::loadPlugin(const std::string& path, double sampleRate) { using namespace VST3::Hosting; std::string err; +#ifdef _WIN32 + // iZotope VST3 core DLLs (vd iZOzone11Core.dll) nằm ở + // C:\Program Files\iZotope\\Cores — không cạnh .vst3, cần PATH. + vstAddDllSearchPath(vstDllSearchExtras()); +#endif Module::Ptr module = Module::create(path, err); if (!module) { std::cerr << "[Vst3Instrument] Module::create failed: " << err << std::endl;