CVST2KSPIPlugIn::CVST2KSPIPlugIn(CVST2KSPIModule* pModule, const std::string& sEffectPathName) : CBasePlugIn(dynamic_cast<CBaseModule*>(pModule), giAudioMaxBufferSize, dynamic_cast<CBaseDSPEngine*>(new CEcho()), 0, COMPANY_NAME, PRODUCT_NAME), mbUpdateGUISettings(true), mbBypass(false), mbShowDemoExpiredDialog(false), mbRegistered(false), miNoiseMode(0), miNoiseCounter(0), msEffectPathName(sEffectPathName), mpVSTEffect(NULL) { dynamic_cast<CEcho*>(mpDSPEngine)->SetChannels(2); mpDezipper->SetCallback(dynamic_cast<IBaseDezipperCallback*>(this)); mbCanProcess = true; muiTimeWhenStarted = ITime::GetTimeMS(); miRandom = 0x123456; #ifdef WIN32 { HMODULE hDLL; // Load plug-in std::string s2 = msEffectPathName; ModifyPathName(s2); hDLL = LoadLibrary(s2.c_str()); if (hDLL == NULL) { } VSTMainFunc mainFunc = (VSTMainFunc)(void*)GetProcAddress(hDLL, "VSTPluginMain"); if (mainFunc == NULL) { } try { mpVSTEffect = mainFunc(audioMasterCallbackPlugIn); mpVSTEffect->dispatcher(mpVSTEffect, effOpen, 0, 0, 0, 0.0); mpVSTEffect->dispatcher(mpVSTEffect, effSetSampleRate, 0, 0, 0, 44100.0f); mpVSTEffect->dispatcher(mpVSTEffect, effSetBlockSize, 0, 32, 0, 0.0); } catch(...) { // Plug-in crashed mpVSTEffect = NULL; } } #else // WIN32 { CFBundleRef BundleRef; // Make a CFURLRef from the CFString representation of the bundle's path. tchar pszPathName[1024]; strcpy(pszPathName, msEffectPathName.c_str()); ToUnix(pszPathName); CFURLRef bundleURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, __CFStringMakeConstantString(pszPathName), kCFURLPOSIXPathStyle, true ); if ( !bundleURL ) { } // Make a bundle instance using the URLRef. BundleRef = CFBundleCreate( kCFAllocatorDefault, bundleURL ); // We don't need the URL anymore CFRelease( bundleURL ); if ( !BundleRef ) { } if ( !CFBundleLoadExecutable( BundleRef ) ) { CFRelease( BundleRef ); BundleRef = NULL; } VSTMainFunc mainFunc = (VSTMainFunc)CFBundleGetFunctionPointerForName( BundleRef, CFSTR("VSTPluginMain") ); if (mainFunc == NULL) { } try { mpVSTEffect = mainFunc(audioMasterCallbackPlugIn); mpVSTEffect->dispatcher(mpVSTEffect, effOpen, 0, 0, 0, 0.0); mpVSTEffect->dispatcher(mpVSTEffect, effSetSampleRate, 0, 0, 0, 44100.0f); mpVSTEffect->dispatcher(mpVSTEffect, effSetBlockSize, 0, 32, 0, 0.0); } catch(...) { // Plug-in crashed mpVSTEffect = NULL; } } #endif // WIN32 / else }
void CPlugInManager::Init() { CAutoLock Lock(gpApplication->GetMeterMutex()); #ifdef _Mac // Get the path to the plug-in folder tchar pszPlugInPath[1024]; IFile::GetSystemDirectory(IFile::SystemDirApplicationSupport, pszPlugInPath); std::string sPlugInPath(pszPlugInPath); sPlugInPath += std::string("Koblo:KSPI:Plug-Ins:"); // Scan the system for plug-ins CAutoDelete<IFileSearch> pFileSearch(IFileSearch::Create()); // Lasse, modified 2008-04-15 - don't crash if folder missing //pFileSearch->Init(sPlugInPath.c_str()); pFileSearch->Init2(sPlugInPath.c_str()); // .. Lasse tchar pszName[256]; tbool bDirectory; while (pFileSearch->GetNext(pszName, bDirectory)) { std::string sName(pszName); std::string sPathName = sPlugInPath + sName; // Load the plug-in to get info { CFBundleRef BundleRef; kspi::IModule* pModule; kspi::IPlugIn* pPlugIn; // Make a CFURLRef from the CFString representation of the bundle's path. tchar pszPathName[1024]; strcpy(pszPathName, sPathName.c_str()); ToUnix(pszPathName); CFURLRef bundleURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, __CFStringMakeConstantString(pszPathName), kCFURLPOSIXPathStyle, true ); if ( !bundleURL ) continue; // Make a bundle instance using the URLRef. BundleRef = CFBundleCreate( kCFAllocatorDefault, bundleURL ); // We don't need the URL anymore CFRelease( bundleURL ); if ( !BundleRef ) { continue; } if ( !CFBundleLoadExecutable( BundleRef ) ) { CFRelease( BundleRef ); BundleRef = NULL; continue; } kspi::kspiMainFunc mainFunc = (kspi::kspiMainFunc)(void*)CFBundleGetFunctionPointerForName( BundleRef, CFSTR("kspiMain") ); if (mainFunc == NULL) { continue; } tuint32 uiKSPIVersionNumber; void* pDispatcher = NULL; void* hModule = mainFunc(&kspi::kspiCCallbackDispatcher, dynamic_cast<kspi::IHost*>(this), &uiKSPIVersionNumber, &pDispatcher); if (hModule == NULL) { continue; } kspi::kspiCDispatcherFunc CFunc = (kspi::kspiCDispatcherFunc)pDispatcher; if (CFunc == NULL) { continue; } pModule = kspi::kspiModule::Create(CFunc, hModule, &uiKSPIVersionNumber, false); // Get the number of plug-ins in the module tint32 iPlugIns = pModule->GetNrOfPlugIns(); tint32 iPlugIn; for (iPlugIn = 0; iPlugIn < iPlugIns; iPlugIn++) { SPlugInInfo* pInfo = new SPlugInInfo(); pInfo->PlugInType = SPlugInInfo::PlugInTypeEffect; pInfo->sPathName = sPathName; pInfo->iPlugInIndex = iPlugIn; pInfo->puiInputs = new tuint32[1024]; pInfo->puiOutputs = new tuint32[1024]; pInfo->puiSideChains = new tuint32[1024]; pPlugIn = pModule->CreateProcess(iPlugIn); if (pPlugIn == NULL) { // No plugin with given index continue; } // Get the channel configurations pPlugIn->GetChannelConfigurations(&(pInfo->uiChannelConfigurations), pInfo->puiInputs, pInfo->puiOutputs, pInfo->puiSideChains); // Get the ids and names tchar pszTmp[256]; pInfo->uiCompanyID = pModule->GetCompanyID(); pModule->GetCompanyName(pszTmp); pInfo->sCompanyName = std::string(pszTmp); pInfo->uiProductID = pPlugIn->GetProductID(); pPlugIn->GetProductName(pszTmp); pInfo->sProductName = std::string(pszTmp); mPlugIns.push_back(pInfo); pPlugIn->Destroy(); } pModule->Destroy(); } } #endif // _Mac #ifdef WIN32 // Get the path to the plug-in folder tchar pszPlugInPath[1024]; ::CoInitialize(NULL); // This only works with NT-based Windows versions ::SHGetSpecialFolderPath(NULL, (LPSTR)pszPlugInPath, CSIDL_PROGRAM_FILES_COMMON, FALSE); ::CoUninitialize(); std::string sPlugInPath(pszPlugInPath); sPlugInPath += std::string("\\Koblo\\KSPI\\Plug-Ins\\"); // Scan the system for plug-ins CAutoDelete<IFileSearch> pFileSearch(IFileSearch::Create()); // Lasse, modified 2008-04-15 - don't crash if folder missing //pFileSearch->Init(sPlugInPath.c_str()); pFileSearch->Init2(sPlugInPath.c_str()); // .. Lasse tchar pszName[256]; tbool bDirectory; while (pFileSearch->GetNext(pszName, bDirectory)) { std::string sName(pszName); std::string sPathName = sPlugInPath + sName; // Load the plug-in to get info { HMODULE hDLL; kspi::IModule* pModule; kspi::IPlugIn* pPlugIn; hDLL = LoadLibrary(sPathName.c_str()); if (hDLL == NULL) { continue; } kspi::kspiMainFunc mainFunc = (kspi::kspiMainFunc)(void*)GetProcAddress(hDLL, "kspiMain"); if (mainFunc == NULL) { continue; } tuint32 uiKSPIVersionNumber; void* pDispatcher = NULL; void* hModule = mainFunc(&kspi::kspiCCallbackDispatcher, dynamic_cast<kspi::IHost*>(this), &uiKSPIVersionNumber, &pDispatcher); if (hModule == NULL) { continue; } kspi::kspiCDispatcherFunc CFunc = (kspi::kspiCDispatcherFunc)pDispatcher; if (CFunc == NULL) { continue; } pModule = kspi::kspiModule::Create(CFunc, hModule, &uiKSPIVersionNumber, false); // Get the number of plug-ins in the module tint32 iPlugIns = pModule->GetNrOfPlugIns(); tint32 iPlugIn; for (iPlugIn = 0; iPlugIn < iPlugIns; iPlugIn++) { SPlugInInfo* pInfo = new SPlugInInfo(); pInfo->PlugInType = SPlugInInfo::PlugInTypeEffect; pInfo->sPathName = sPathName; pInfo->iPlugInIndex = iPlugIn; pInfo->puiInputs = new tuint32[1024]; pInfo->puiOutputs = new tuint32[1024]; pInfo->puiSideChains = new tuint32[1024]; pPlugIn = pModule->CreateProcess(iPlugIn); if (pPlugIn == NULL) { // No plugin with given index continue; } // Get the channel configurations pPlugIn->GetChannelConfigurations(&(pInfo->uiChannelConfigurations), pInfo->puiInputs, pInfo->puiOutputs, pInfo->puiSideChains); // Get the ids and names tchar pszTmp[256]; pInfo->uiCompanyID = pModule->GetCompanyID(); pModule->GetCompanyName(pszTmp); pInfo->sCompanyName = std::string(pszTmp); pInfo->uiProductID = pPlugIn->GetProductID(); pPlugIn->GetProductName(pszTmp); pInfo->sProductName = std::string(pszTmp); mPlugIns.push_back(pInfo); pPlugIn->Destroy(); } pModule->Destroy(); } } #endif // WIN32 }
void CVST2KSPIModule::DoScanDirectory(const std::string& sPathName) { // Scan the system for plug-ins CAutoDelete<IFileSearch> pFileSearch(IFileSearch::Create()); pFileSearch->Init(sPathName.c_str()); tchar pszName[256]; tbool bDirectory; while (pFileSearch->GetNext(pszName, bDirectory)) { std::string sPlugInPath = sPathName; std::string sName(pszName); #ifdef WIN32 if (bDirectory) { #else // WIN32 std::string sEnding = sName.substr(sName.size() - 4); if (sEnding != ".vst" && sEnding != ".VST" && sName.size() > 4) { #endif sPlugInPath += sName; sPlugInPath += ":"; DoScanDirectory(sPlugInPath); continue; } std::string sPathName = sPlugInPath + sName; #ifdef WIN32 // Load the plug-in to get info { HMODULE hDLL; std::string sEnding = sName.substr(sName.size() - 4); if (sEnding != ".dll" && sEnding != ".DLL" && sEnding != ".Dll" && sName.size() > 4) { continue; } // Load plug-in std::string s2 = sPathName; ModifyPathName(s2); hDLL = LoadLibrary(s2.c_str()); if (hDLL == NULL) { continue; } VSTMainFunc mainFunc = (VSTMainFunc)(void*)GetProcAddress(hDLL, "VSTPluginMain"); // VSTMainFunc mainFunc = (VSTMainFunc)CFBundleGetFunctionPointerForName(BundleRef, CFSTR("main") ); if (mainFunc == NULL) { continue; } AEffect* pEffect = NULL; try { pEffect = mainFunc(audioMasterCallbackModule); // Note: Call setSampleRate and setBlockSize also (part of initialization sequence). pEffect->dispatcher(pEffect, effOpen, 0, 0, 0, 0.0); // We don't really need the name now, but we want to just try something to see if it crashes. Would be better to get some info about VST version and required host VST version. char pszProductName[1042]; pEffect->dispatcher(pEffect, effGetEffectName, 0, 0, pszProductName, 0.0); } catch(...) { // Plug-in crashed // CFBundleUnloadExecutable(BundleRef); // CFRelease(BundleRef); continue; } // Effect appears ok, put it in list msEffectPathNames.push_back(sPathName); // Unload it pEffect->dispatcher(pEffect, effClose, 0, 0, 0, 0.0); // CFBundleUnloadExecutable(BundleRef); // CFRelease(BundleRef); } #else // WIN32 // Load the plug-in to get info { CFBundleRef BundleRef; // Make a CFURLRef from the CFString representation of the bundle's path. tchar pszPathName[1024]; strcpy(pszPathName, sPathName.c_str()); ToUnix(pszPathName); CFURLRef bundleURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, __CFStringMakeConstantString(pszPathName), kCFURLPOSIXPathStyle, true ); if ( !bundleURL ) continue; // Make a bundle instance using the URLRef. BundleRef = CFBundleCreate( kCFAllocatorDefault, bundleURL ); // We don't need the URL anymore CFRelease( bundleURL ); if ( !BundleRef ) { continue; } if ( !CFBundleLoadExecutable( BundleRef ) ) { CFRelease( BundleRef ); BundleRef = NULL; continue; } VSTMainFunc mainFunc = (VSTMainFunc)CFBundleGetFunctionPointerForName(BundleRef, CFSTR("VSTPluginMain") ); // VSTMainFunc mainFunc = (VSTMainFunc)CFBundleGetFunctionPointerForName(BundleRef, CFSTR("main") ); if (mainFunc == NULL) { continue; } AEffect* pEffect = NULL; try { pEffect = mainFunc(audioMasterCallbackModule); // Note: Call setSampleRate and setBlockSize also (part of initialization sequence). pEffect->dispatcher(pEffect, effOpen, 0, 0, 0, 0.0); // We don't really need the name now, but we want to just try something to see if it crashes. Would be better to get some info about VST version and required host VST version. char pszProductName[1042]; pEffect->dispatcher(pEffect, effGetEffectName, 0, 0, pszProductName, 0.0); } catch(...) { // Plug-in crashed // CFBundleUnloadExecutable(BundleRef); // CFRelease(BundleRef); continue; } // Effect appears ok, put it in list msEffectPathNames.push_back(sPathName); // Unload it pEffect->dispatcher(pEffect, effClose, 0, 0, 0, 0.0); // CFBundleUnloadExecutable(BundleRef); // CFRelease(BundleRef); } #endif // WIN32 / else } } void CVST2KSPIModule::Init() { /* short sVolRef; long lDirID; tchar pszPlugInPath[1024]; ::FindFolder(kOnSystemDisk, kVolumeRootFolderType, kDontCreateFolder, &sVolRef, &lDirID); PathNameFromDirID(lDirID, sVolRef, (char*)pszPlugInPath); std::string sPlugInPath(pszPlugInPath); sPlugInPath += std::string("Library:Audio:Plug-Ins:VST:");*/ // Note: This is hardcoded, and needs to change #ifdef WIN32 std::string sPlugInPath(":C:VSTPlugIns:"); DoScanDirectory(sPlugInPath); #else // WIN32 // std::string sPlugInPath(":Macintosh HD:Library:Audio:Plug-Ins:VST:"); tchar pszPath[1024]; IFile::GetSystemDirectory(IFile::SystemDirLibrary, pszPath); strcat(pszPath, "Audio:Plug-Ins:VST:"); std::string sPlugInPath(pszPath); DoScanDirectory(sPlugInPath); IFile::GetSystemDirectory(IFile::SystemDirUser, pszPath); strcat(pszPath, "Library:Audio:Plug-Ins:VST:"); sPlugInPath = std::string(pszPath); DoScanDirectory(sPlugInPath); #endif // WIN32 / else }
CPlugInManager::PlugInHandle CPlugInManager::LoadPlugIn(tint32 iIndex, tint32 iChannel, tint32 iInsertIndex) { CAutoLock Lock(gpApplication->GetMeterMutex()); if (iIndex >= (tint32)mPlugIns.size()) { throw IException::Create(IException::TypeCode, IException::ReasonCodeInvalidArgument, EXCEPTION_INFO, "Invalid Index / Unknown plug-in"); } // Locate the plug-in std::list<SPlugInInfo*>::const_iterator it = mPlugIns.begin(); for (; iIndex; it++, iIndex--) { } SPlugInInfo* pInfo = *it; #ifdef _Mac CFBundleRef BundleRef; kspi::IModule* pModule; kspi::IPlugIn* pPlugIn; // Make a CFURLRef from the CFString representation of the bundle's path. tchar pszPathName[1024]; strcpy(pszPathName, pInfo->sPathName.c_str()); ToUnix(pszPathName); CFURLRef bundleURL = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, __CFStringMakeConstantString(pszPathName), kCFURLPOSIXPathStyle, true ); if ( !bundleURL ) { } // Make a bundle instance using the URLRef. BundleRef = CFBundleCreate( kCFAllocatorDefault, bundleURL ); // We don't need the URL anymore CFRelease( bundleURL ); if (!BundleRef) { } if (!CFBundleLoadExecutable(BundleRef)) { CFRelease( BundleRef ); BundleRef = NULL; } kspi::kspiMainFunc mainFunc = (kspi::kspiMainFunc)(void*)CFBundleGetFunctionPointerForName( BundleRef, CFSTR("kspiMain") ); if (mainFunc == NULL) { } tuint32 uiKSPIVersionNumber; void* pDispatcher = NULL; void* hModule = mainFunc(&kspi::kspiCCallbackDispatcher, dynamic_cast<kspi::IHost*>(this), &uiKSPIVersionNumber, &pDispatcher); if (hModule == NULL) { } kspi::kspiCDispatcherFunc CFunc = (kspi::kspiCDispatcherFunc)pDispatcher; if (CFunc == NULL) { } pModule = kspi::kspiModule::Create(CFunc, hModule, &uiKSPIVersionNumber, false); pPlugIn = pModule->CreateProcess(pInfo->iPlugInIndex); if (pPlugIn == NULL) { // No plugin with given index } tint32 iLoadedPlugs = mLoadedPlugIns.size(); mLoadedPlugIns.push_back(pPlugIn); pPlugIn->PreInitialize(); pPlugIn->SetSampleRate(44100); pPlugIn->SetMaxBufferSize(32); pPlugIn->Initialize(); pPlugIn->Start(); CBaseGUI* pBaseGUI = gpMainApplication->CreateExtraWindow(giPlug_In_Window, (void*)CFSTR("PlugInWnd")); CKSPlugInGUI* pPlugInGUI = dynamic_cast<CKSPlugInGUI*>(pBaseGUI); kspi::IGUI* pGUI = pPlugIn->CreateGUI(0); pPlugInGUI->SetInfo(iChannel, iInsertIndex); pPlugInGUI->SetGUI(pGUI); SLoadedPlugInInfo LoadedInfo; LoadedInfo.pPlugIn = pPlugIn; LoadedInfo.bGUILoaded = true; LoadedInfo.pBaseGUI = pBaseGUI; LoadedInfo.pPlugInGUI = pPlugInGUI; LoadedInfo.pGUI = pGUI; mPlugInMap.insert(std::pair<tint32, SLoadedPlugInInfo>(iChannel << 16 | iInsertIndex, LoadedInfo)); // return (PlugInHandle)iLoadedPlugs; return (PlugInHandle)pPlugIn; #endif // _Mac #ifdef WIN32 HMODULE hDLL; kspi::IModule* pModule; kspi::IPlugIn* pPlugIn; hDLL = LoadLibrary(pInfo->sPathName.c_str()); if (hDLL == NULL) { } kspi::kspiMainFunc mainFunc = (kspi::kspiMainFunc)(void*)GetProcAddress(hDLL, "kspiMain"); if (mainFunc == NULL) { } tuint32 uiKSPIVersionNumber; void* pDispatcher = NULL; void* hModule = mainFunc(&kspi::kspiCCallbackDispatcher, dynamic_cast<kspi::IHost*>(this), &uiKSPIVersionNumber, &pDispatcher); if (hModule == NULL) { } kspi::kspiCDispatcherFunc CFunc = (kspi::kspiCDispatcherFunc)pDispatcher; if (CFunc == NULL) { } pModule = kspi::kspiModule::Create(CFunc, hModule, &uiKSPIVersionNumber, false); pPlugIn = pModule->CreateProcess(pInfo->iPlugInIndex); if (pPlugIn == NULL) { // No plugin with given index } tint32 iLoadedPlugs = mLoadedPlugIns.size(); mLoadedPlugIns.push_back(pPlugIn); pPlugIn->PreInitialize(); pPlugIn->SetSampleRate(44100); pPlugIn->SetMaxBufferSize(32); pPlugIn->Initialize(); pPlugIn->Start(); CBaseGUI* pBaseGUI = gpMainApplication->CreateExtraWindow(giPlug_In_Window, (void*)"PlugInWnd", true); CKSPlugInGUI* pPlugInGUI = dynamic_cast<CKSPlugInGUI*>(pBaseGUI); kspi::IGUI* pGUI = pPlugIn->CreateGUI(0); pPlugInGUI->SetInfo(iChannel, iInsertIndex); pPlugInGUI->SetGUI(pGUI); SLoadedPlugInInfo LoadedInfo; LoadedInfo.pPlugIn = pPlugIn; LoadedInfo.bGUILoaded = true; LoadedInfo.pBaseGUI = pBaseGUI; LoadedInfo.pPlugInGUI = pPlugInGUI; LoadedInfo.pGUI = pGUI; mPlugInMap.insert(std::pair<tint32, SLoadedPlugInInfo>(iChannel << 16 | iInsertIndex, LoadedInfo)); // return (PlugInHandle)iLoadedPlugs; return (PlugInHandle)pPlugIn; #endif // WIN32 }