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;