/* PdVst v0.0.2 - VST - Pd bridging plugin ** Copyright (C) 2004 Joseph A. Sarlo ** ** This program is free software; you can redistribute it and/orsig ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation; either version 2 ** of the License, or (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** jsarlo@ucsd.edu */ #include #include #include "pdvst.hpp" #include static AudioEffect *effect = 0; bool oome = false; //HINSTANCE hInstance; bool globalIsASynth = false; bool globalDebug = false; int globalNChannels = 0; int globalNPrograms = 0; int globalNParams = 0; int globalNExternalLibs = 0; long globalPluginId = 'pdvp'; char globalExternalLib[MAXEXTERNS][MAXSTRLEN]; char globalVstParamName[MAXPARAMS][MAXSTRLEN]; char globalPluginPath[MAXFILENAMELEN]; char globalVstPluginPath[MAXFILENAMELEN]; char globalPluginName[MAXSTRLEN]; char globalPdFile[MAXFILENAMELEN]; char globalPureDataPath[MAXFILENAMELEN]; char globalHostPdvstPath[MAXFILENAMELEN]; bool globalCustomGui = false; int globalCustomGuiWidth= 320; int globalCustomGuiHeight= 150; pdvstProgram globalProgram[MAXPROGRAMS]; char *trimWhitespace(char *str); void parseSetupFile(); #include "audioeffect.h" //------------------------------------------------------------------------ /** Must be implemented externally. */ extern AudioEffect* createEffectInstance (audioMasterCallback audioMaster); extern "C" { #if defined (__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) #define VST_EXPORT __attribute__ ((visibility ("default"))) #else #define VST_EXPORT #endif VST_EXPORT AEffect *VSTPluginMain(audioMasterCallback audioMaster) { // get vst version if (!audioMaster(0, audioMasterVersion, 0, 0, 0, 0)) return 0; // old version // Create the AudioEffect AudioEffect* effect = createEffectInstance (audioMaster); if (!effect) return 0; return effect->getAeffect(); } // support for old hosts not looking for VSTPluginMain #if (TARGET_API_MAC_CARBON && __ppc__) VST_EXPORT AEffect* main_macho (audioMasterCallback audioMaster) { return VSTPluginMain (audioMaster); } #elif WIN32 VST_EXPORT AEffect* MAIN (audioMasterCallback audioMaster) { return VSTPluginMain (audioMaster); } #elif BEOS VST_EXPORT AEffect* main_plugin (audioMasterCallback audioMaster) { return VSTPluginMain (audioMaster); } #endif } // extern "C" #if WIN32 #include void* hInstance; extern "C" { BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved) { hInstance = hInst; parseSetupFile(); return 1; } } // extern "C" #endif char *trimWhitespace(char *str) { char *buf; if (strlen(str) > 0) { buf = str; while (isspace(*buf) && (buf - str) <= (int)strlen(str)) buf++; memmove(str, buf, (strlen(buf) + 1) * sizeof(char)); if (strlen(str) > 0) { buf = str + strlen(str) - 1; while (isspace(*buf) && (buf >= str)) { *buf = 0; buf--; } } } return (str); } void parseSetupFile() { FILE *setupFile; char setupFileName[MAXFILENAMELEN]; char tFileName[MAXFILENAMELEN]; char line[MAXSTRLEN]; char param[MAXSTRLEN]; char value[MAXSTRLEN]; char vstDataPath[MAXSTRLEN]; char vstSetupFileName[MAXSTRLEN]; // path to setup file if it is located in vst subdir int i, equalPos, progNum = -1; // find filepaths GetModuleFileName((HMODULE)hInstance, (LPTSTR)tFileName, (DWORD)MAXFILENAMELEN); if (strrchr(tFileName, '\\')) { strcpy(globalPluginName, strrchr(tFileName, '\\') + 1); } else { strcpy(globalPluginName, tFileName); } // alternate setup file path in vst plugins folder if (strrchr(tFileName, '\\')) { strcpy(vstDataPath, tFileName); *(strrchr(vstDataPath, '\\') + 1) = 0; sprintf(vstDataPath, "%s%s\\", vstDataPath,globalPluginName); // remove .dll extension (from globalPluginName) if (strstr(vstDataPath, ".dll")) *(strstr(vstDataPath, ".dll")) = 0; if (strstr(vstDataPath, ".DLL")) *(strstr(vstDataPath, ".DLL")) = 0; sprintf(vstDataPath, "%s\\", vstDataPath); // // path to alternate setup file sprintf(vstSetupFileName,"%s%s",vstDataPath,globalPluginName); // remove .dll extension if (strstr(vstSetupFileName, ".dll")) *(strstr(vstSetupFileName, ".dll")) = 0; if (strstr(vstSetupFileName, ".DLL")) *(strstr(vstSetupFileName, ".DLL")) = 0; // add SETUPFILEEXT extension sprintf(vstSetupFileName,"%s%s",vstSetupFileName,SETUPFILEEXT); //MessageBox(NULL, vstDataPath,"vstDataPath",MB_OK) ; //MessageBox(NULL, vstSetupFileName,"vstSetupFileName",MB_OK) ; } GetModuleFileName(NULL, (LPTSTR)tFileName, (DWORD)MAXFILENAMELEN); if (strrchr(tFileName, '\\')) { strcpy(globalPluginPath, tFileName); *(strrchr(globalPluginPath, '\\') + 1) = 0; sprintf(globalPluginPath, "%spdvst\\", globalPluginPath); } else { strcpy(globalPluginPath, tFileName); } strcpy(globalHostPdvstPath,globalPluginPath); // remove .dll extension if (strstr(strlwr(globalPluginName), ".dll")) *(strstr(strlwr(globalPluginName), ".dll")) = 0; sprintf(setupFileName, "%s%s%s", globalPluginPath, globalPluginName, SETUPFILEEXT); // initialize program info strcpy(globalProgram[0].name, "Default"); memset(globalProgram[0].paramValue, 0, MAXPARAMS * sizeof(float)); // initialize parameter info globalNParams = 0; for (i = 0; i < MAXPARAMS; i++) strcpy(globalVstParamName[i], ""); globalNPrograms = 1; // check existence of setup file in vst-subfolder if( access(vstSetupFileName, F_OK ) != -1 ) // if exists choose this alternate file { setupFile = fopen(vstSetupFileName, "r"); //strcpy(setupFileName,vstSetupFileName); strcpy(globalPluginPath,vstDataPath); } else setupFile = fopen(setupFileName, "r"); // parse the setup file if (setupFile) { while (fgets(line, sizeof(line), setupFile)) { equalPos = strchr(line, '=') - line; if (equalPos > 0 && line[0] != '#') { strcpy(param, line); param[equalPos] = 0; strcpy(value, line + equalPos + 1); strcpy(param, trimWhitespace(strlwr(param))); strcpy(value, trimWhitespace(value)); // number of channels if (strcmp(param, "channels") == 0) globalNChannels = atoi(value); // main PD patch if (strcmp(param, "main") == 0) { // strcpy(globalPdFile, strlwr(value)); strcpy(globalPdFile, value); } if (strcmp(param, "pdpath") == 0) { // strcpy(globalPureDataPath, strlwr(value)); strcpy(globalPureDataPath, value); } // vst plugin ID if (strcmp(param, "id") == 0) { globalPluginId = 0; for (i = 0; i < 4; i++) globalPluginId += (long)pow((double)16,(int) (i * 2)) * value[3 - i]; } // is vst instrument if (strcmp(param, "synth") == 0) { if (strcmp(strlwr(value), "true") == 0) { globalIsASynth = true; } else if (strcmp(strlwr(value), "false") == 0) { globalIsASynth = false; } } // external libraries if (strcmp(param, "lib") == 0) { while (strlen(value) > 0) { if (strchr(value, ',') == NULL) { strcpy(globalExternalLib[globalNExternalLibs], value); value[0] = 0; } else { int commaIndex = strchr(value, ',') - value; strncpy(globalExternalLib[globalNExternalLibs], value, commaIndex); memmove(value, value + commaIndex + 1, (strlen(value) - commaIndex) * sizeof(char)); strcpy(value, trimWhitespace(value)); } globalNExternalLibs++; } } // has custom gui if (strcmp(param, "customgui") == 0) { if (strcmp(strlwr(value), "true") == 0) { globalCustomGui = true; } else if (strcmp(strlwr(value), "false") == 0) { globalCustomGui = false; } } // custom gui height if (strcmp(param, "guiheight") == 0) globalCustomGuiHeight = atoi(value); // custom gui width if (strcmp(param, "guiwidth") == 0) { globalCustomGuiWidth = atoi(value); } // debug (show Pd GUI) if (strcmp(param, "debug") == 0) { if (strcmp(strlwr(value), "true") == 0) { globalDebug = true; } else if (strcmp(strlwr(value), "false") == 0) { globalDebug = false; } } // number of parameters if (strcmp(param, "parameters") == 0) { int numParams = atoi(value); if (numParams >= 0 && numParams < MAXPARAMS) globalNParams = numParams; } // parameters names if (strstr(param, "nameparameter") == \ param && globalNPrograms < MAXPARAMS) { int paramNum = atoi(param + strlen("nameparameter")); if (paramNum < MAXPARAMS && paramNum >= 0) strcpy(globalVstParamName[paramNum], value); } // program name if (strcmp(param, "program") == 0 && \ globalNPrograms < MAXPROGRAMS) { progNum++; strcpy(globalProgram[progNum].name, value); globalNPrograms = progNum + 1; } // program parameters if (strstr(param, "parameter") == \ param && globalNPrograms < MAXPROGRAMS && !isalpha(param[strlen("parameter")])) { int paramNum = atoi(param + strlen("parameter")); if (paramNum < MAXPARAMS && paramNum >= 0) globalProgram[progNum].paramValue[paramNum] = \ (float)atof(value); } } } } fclose(setupFile); }