/*name, creator etc etc */
/***********************************************************/
-/*This is largely unmodified from the original (C code) FST vstinfofile module*/
-
-#include "ardour/vstfx.h"
+#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <errno.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <libgen.h>
-#define MAX_STRING_LEN 256
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "ardour/vstfx.h"
-#define FALSE 0
-#define TRUE !FALSE
+#define MAX_STRING_LEN 256
static char* read_string(FILE *fp)
{
char buf[MAX_STRING_LEN];
- fgets( buf, MAX_STRING_LEN, fp );
-
- if(strlen(buf) < MAX_STRING_LEN)
- {
- if(strlen(buf))
- buf[strlen(buf)-1] = 0;
-
- return strdup(buf);
+ if (!fgets( buf, MAX_STRING_LEN, fp )) {
+ return 0;
}
- else
- {
- return NULL;
+
+ if(strlen(buf) < MAX_STRING_LEN) {
+ if (strlen(buf)) {
+ buf[strlen(buf)-1] = 0;
+ }
+ return strdup(buf);
+ } else {
+ return 0;
}
}
-static VSTFXInfo* load_vstfx_info_file(char *filename)
+static VSTInfo *
+load_vstfx_info_file (FILE* fp)
{
- VSTFXInfo *info = (VSTFXInfo*) malloc(sizeof(VSTFXInfo));
- FILE *fp;
- int i;
+ VSTInfo *info;
+ int i;
- if(info == NULL)
- return NULL;
-
- fp = fopen(filename, "r");
-
- if(fp == NULL)
- {
- free( info );
- return NULL;
- }
+ if ((info = (VSTInfo*) malloc (sizeof (VSTInfo))) == 0) {
+ return 0;
+ }
- if((info->name = read_string(fp)) == NULL) goto error;
- if((info->creator = read_string(fp)) == NULL) goto error;
- if(1 != fscanf(fp, "%d\n", &info->UniqueID)) goto error;
- if((info->Category = read_string(fp)) == NULL) goto error;
- if(1 != fscanf(fp, "%d\n", &info->numInputs)) goto error;
- if(1 != fscanf(fp, "%d\n", &info->numOutputs)) goto error;
- if(1 != fscanf(fp, "%d\n", &info->numParams)) goto error;
- if(1 != fscanf(fp, "%d\n", &info->wantMidi)) goto error;
- if(1 != fscanf(fp, "%d\n", &info->hasEditor)) goto error;
- if(1 != fscanf(fp, "%d\n", &info->canProcessReplacing)) goto error;
-
- if((info->ParamNames = (char **) malloc(sizeof(char*)*info->numParams)) == NULL) goto error;
- for(i=0; i<info->numParams; i++)
- {
- if((info->ParamNames[i] = read_string(fp)) == NULL) goto error;
- }
- if((info->ParamLabels = (char **) malloc(sizeof(char*)*info->numParams)) == NULL) goto error;
-
- for(i=0; i < info->numParams; i++)
- {
- if((info->ParamLabels[i] = read_string(fp)) == NULL) goto error;
- }
+ if((info->name = read_string(fp)) == 0) goto error;
+ if((info->creator = read_string(fp)) == 0) goto error;
+ if(1 != fscanf(fp, "%d\n", &info->UniqueID)) goto error;
+ if((info->Category = read_string(fp)) == 0) goto error;
+ if(1 != fscanf(fp, "%d\n", &info->numInputs)) goto error;
+ if(1 != fscanf(fp, "%d\n", &info->numOutputs)) goto error;
+ if(1 != fscanf(fp, "%d\n", &info->numParams)) goto error;
+ if(1 != fscanf(fp, "%d\n", &info->wantMidi)) goto error;
+ if(1 != fscanf(fp, "%d\n", &info->hasEditor)) goto error;
+ if(1 != fscanf(fp, "%d\n", &info->canProcessReplacing)) goto error;
- fclose( fp );
- return info;
+ if((info->ParamNames = (char **) malloc(sizeof(char*)*info->numParams)) == 0) {
+ goto error;
+ }
+
+ for (i=0; i<info->numParams; i++) {
+ if((info->ParamNames[i] = read_string(fp)) == 0) goto error;
+ }
-error:
- fclose( fp );
- free( info );
- return NULL;
+ if ((info->ParamLabels = (char **) malloc(sizeof(char*)*info->numParams)) == 0) {
+ goto error;
+ }
+
+ for (i=0; i < info->numParams; i++) {
+ if((info->ParamLabels[i] = read_string(fp)) == 0) goto error;
+ }
+
+ return info;
+
+ error:
+ free( info );
+ return 0;
}
-static int save_vstfx_info_file(VSTFXInfo *info, char *filename)
+static int
+save_vstfx_info_file (VSTInfo *info, FILE* fp)
{
- FILE *fp;
int i;
- if(info == NULL)
- {
- vstfx_error("** ERROR ** VSTFXinfofile : info ptr is NULL\n");
- return TRUE;
+ if (info == 0) {
+ vstfx_error("** ERROR ** VSTFXinfofile : info ptr is 0\n");
+ return -1;
}
- fp = fopen(filename, "w");
-
- if(fp == NULL)
- {
- vstfx_error("** WARNING ** VSTFX : Can't write info file %s\n", filename);
- return TRUE;
+ if (fp == 0) {
+ vstfx_error("** ERROR ** VSTFXinfofile : file ptr is 0\n");
+ return -1;
}
-
+
fprintf( fp, "%s\n", info->name );
fprintf( fp, "%s\n", info->creator );
fprintf( fp, "%d\n", info->UniqueID );
fprintf( fp, "%d\n", info->hasEditor );
fprintf( fp, "%d\n", info->canProcessReplacing );
- for(i=0; i < info->numParams; i++)
- {
+ for (i=0; i < info->numParams; i++) {
fprintf(fp, "%s\n", info->ParamNames[i]);
}
- for(i=0; i < info->numParams; i++)
- {
+ for (i=0; i < info->numParams; i++) {
fprintf(fp, "%s\n", info->ParamLabels[i]);
}
- fclose( fp );
-
- return FALSE;
+ return 0;
}
-static char* vstfx_dllpath_to_infopath(char *dllpath)
+static char* vstfx_infofile_stat (char *dllpath, struct stat* statbuf, int personal)
{
- char* retval;
+ char* path;
char* dir_path;
- char* base_name;
-
- if(strstr(dllpath, ".so" ) == NULL)
- return NULL;
-
- /*Allocate space for the filename - need strlen + 1 for the terminating'0', +1 because .so is three
- chars, and .fsi is four chars and +1 because we have a '.' at the beginning*/
-
- retval = (char*)malloc(strlen(dllpath) + 3);
+ char* basename;
+ char* base;
+ size_t blen;
+
+ if (strstr (dllpath, ".so" ) == 0) {
+ return 0;
+ }
- dir_path = strdup(dllpath);
- base_name = strdup(dllpath);
+ if (personal) {
+ dir_path = g_build_filename (g_get_home_dir(), ".fst", NULL);
+ } else {
+ dir_path = g_path_get_dirname (dllpath);
+ }
- sprintf(retval, "%s/.%s", dirname(dir_path), basename(base_name));
- sprintf(retval + strlen(retval) - 3, ".fsi");
+ base = g_path_get_basename (dllpath);
+ blen = strlen (base) + 2; // null char and '.'
+ basename = (char*) g_malloc (blen);
+ snprintf (basename, blen, ".%s.fsi", base);
+ g_free (base);
- free(dir_path);
- free(base_name);
+ path = g_build_filename (dir_path, basename, NULL);
- return retval;
+ g_free (dir_path);
+ g_free (basename);
+
+
+ if (g_file_test (path, GFileTest (G_FILE_TEST_EXISTS|G_FILE_TEST_IS_REGULAR))) {
+
+ /* info file exists in same location as the shared object, so
+ check if its current and up to date
+ */
+
+
+ struct stat dllstat;
+
+ if (stat (dllpath, &dllstat) == 0) {
+ if (stat(path, statbuf) == 0) {
+ if (dllstat.st_mtime <= statbuf->st_mtime) {
+ /* plugin is older than info file */
+ return path;
+ }
+ }
+ }
+ }
+
+ g_free (path);
+
+ return 0;
}
-static int vstfx_info_file_is_valid(char *dllpath)
+
+static FILE* vstfx_infofile_for_read (char* dllpath)
{
- struct stat dllstat;
- struct stat vstfxstat;
+ struct stat own_statbuf;
+ struct stat sys_statbuf;
+ char *own_info;
+ char *sys_info;
- char *vstfxpath = vstfx_dllpath_to_infopath(dllpath);
+ own_info = vstfx_infofile_stat (dllpath, &own_statbuf, 1);
+ sys_info = vstfx_infofile_stat (dllpath, &sys_statbuf, 0);
+
+ if (own_info) {
+ if (sys_info) {
+ if (own_statbuf.st_mtime <= sys_statbuf.st_mtime) {
+ /* system info file is newer, use it */
+ return fopen (sys_info, "r");
+ }
+ } else {
+ return fopen (own_info, "r");
+ }
+ }
+
+ return 0;
+}
+
+static FILE* vstfx_infofile_create (char* dllpath, int personal)
+{
+ char* path;
+ char* dir_path;
+ char* basename;
+ char* base;
+ size_t blen;
+
+ if (strstr (dllpath, ".so" ) == 0) {
+ return 0;
+ }
- if(!vstfxpath)
- return FALSE;
-
- if(stat(dllpath, &dllstat))
- {
- vstfx_error( "** ERROR ** VSTFXinfofile : .so path %s invalid\n", dllpath );
- return TRUE;
+ if (personal) {
+ dir_path = g_build_filename (g_get_home_dir(), ".fst", NULL);
+
+ /* if the directory doesn't yet exist, try to create it */
+
+ if (!g_file_test (dir_path, G_FILE_TEST_IS_DIR)) {
+ if (g_mkdir (dir_path, 0700)) {
+ return 0;
+ }
+ }
+
+ } else {
+ dir_path = g_path_get_dirname (dllpath);
}
- if(stat(vstfxpath, &vstfxstat))
- return FALSE;
+ base = g_path_get_basename (dllpath);
+ blen = strlen (base) + 2; // null char and '.'
+ basename = (char*) g_malloc (blen);
+ snprintf (basename, blen, ".%s.fsi", base);
+ g_free (base);
+
+ path = g_build_filename (dir_path, basename, NULL);
+
+ g_free (dir_path);
+ g_free (basename);
- free(vstfxpath);
+ FILE* f = fopen (path, "w");
+ g_free (path);
+
+ return f;
+}
+
+static FILE* vstfx_infofile_for_write (char* dllpath)
+{
+ FILE* f;
+
+ if ((f = vstfx_infofile_create (dllpath, 0)) == 0) {
+ f = vstfx_infofile_create (dllpath, 1);
+ }
- if(dllstat.st_mtime > vstfxstat.st_mtime)
- return FALSE;
- else
- return TRUE;
+ return f;
}
-static int vstfx_can_midi(VSTFX *vstfx)
+static
+int vstfx_can_midi (VSTState* vstfx)
{
- struct AEffect *plugin = vstfx->plugin;
+ AEffect *plugin = vstfx->plugin;
- int vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, NULL, 0.0f);
+ int vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, 0, 0.0f);
if (vst_version >= 2)
{
/* should we send it VST events (i.e. MIDI) */
if ((plugin->flags & effFlagsIsSynth) || (plugin->dispatcher (plugin, effCanDo, 0, 0,(void*) "receiveVstEvents", 0.0f) > 0))
- return TRUE;
+ return -1;
}
- return FALSE;
+ return false;
}
-static VSTFXInfo* vstfx_info_from_plugin(VSTFX *vstfx)
+static VSTInfo *
+vstfx_info_from_plugin (VSTState* vstfx)
{
-
- VSTFXInfo* info = (VSTFXInfo*) malloc(sizeof(VSTFXInfo));
+ VSTInfo* info = (VSTInfo*) malloc (sizeof (VSTInfo));
+
+ AEffect *plugin;
+ int i;
- struct AEffect *plugin;
- int i;
-
/*We need to init the creator because some plugins
- fail to implement getVendorString, and so won't stuff the
- string with any name*/
+ fail to implement getVendorString, and so won't stuff the
+ string with any name*/
- char creator[65] = "Unknown\0";
-
- if(!vstfx)
+ char creator[65] = "Unknown\0";
+
+ if(!vstfx)
{
- vstfx_error( "** ERROR ** VSTFXinfofile : vstfx ptr is NULL\n" );
- return NULL;
- }
-
- if(!info)
- return NULL;
-
- plugin = vstfx->plugin;
+ vstfx_error( "** ERROR ** VSTFXinfofile : vstfx ptr is 0\n" );
+ return 0;
+ }
+
+ if(!info)
+ return 0;
- info->name = strdup(vstfx->handle->name );
+ plugin = vstfx->plugin;
+
+ info->name = strdup(vstfx->handle->name );
/*If the plugin doesn't bother to implement GetVendorString we will
- have pre-stuffed the string with 'Unkown' */
+ have pre-stuffed the string with 'Unkown' */
- plugin->dispatcher (plugin, effGetVendorString, 0, 0, creator, 0);
+ plugin->dispatcher (plugin, effGetVendorString, 0, 0, creator, 0);
/*Some plugins DO implement GetVendorString, but DON'T put a name in it
- so if its just a zero length string we replace it with 'Unknown' */
+ so if its just a zero length string we replace it with 'Unknown' */
- if (strlen(creator) == 0)
- {
- info->creator = strdup("Unknown");
- }
- else
- {
- info->creator = strdup (creator);
- }
-
-#if defined LXVST_64BIT && defined VESTIGE_HEADER
-
- /*On 64Bit the data alignment in AEffect struct is
- incorrect using vestige. see lxvst_plugin.cc*/
+ if (strlen(creator) == 0) {
+ info->creator = strdup("Unknown");
+ } else {
+ info->creator = strdup (creator);
+ }
- info->UniqueID = *((int32_t *) &((AEffect*)(((char*)(plugin)) + 12))->unused_id);
+ info->UniqueID = plugin->uniqueID;
-#elif defined LXVST_32BIT && defined VESTIGE_HEADER
-
- info->UniqueID = *((int32_t *) &plugin->unused_id);
-
-#else
-
- info->UniqueID = plugin->uniqueID;
-
-#endif
-
- info->Category = strdup("None"); // FIXME:
- info->numInputs = plugin->numInputs;
- info->numOutputs = plugin->numOutputs;
- info->numParams = plugin->numParams;
- info->wantMidi = vstfx_can_midi(vstfx);
- info->hasEditor = plugin->flags & effFlagsHasEditor ? TRUE : FALSE;
- info->canProcessReplacing = plugin->flags & effFlagsCanReplacing ? TRUE : FALSE;
- info->ParamNames = (char **) malloc(sizeof(char*)*info->numParams);
- info->ParamLabels = (char **) malloc(sizeof(char*)*info->numParams);
- for(i=0; i < info->numParams; i++)
- {
+ info->Category = strdup("None"); // FIXME:
+ info->numInputs = plugin->numInputs;
+ info->numOutputs = plugin->numOutputs;
+ info->numParams = plugin->numParams;
+ info->wantMidi = vstfx_can_midi(vstfx);
+ info->hasEditor = plugin->flags & effFlagsHasEditor ? true : false;
+ info->canProcessReplacing = plugin->flags & effFlagsCanReplacing ? true : false;
+ info->ParamNames = (char **) malloc(sizeof(char*)*info->numParams);
+ info->ParamLabels = (char **) malloc(sizeof(char*)*info->numParams);
+
+ for(i=0; i < info->numParams; i++) {
char name[64];
char label[64];
plugin->dispatcher (plugin, effGetParamName, i, 0, name, 0);
info->ParamNames[i] = strdup(name);
- plugin->dispatcher (plugin, effGetParamLabel, i, 0, label, 0);
+ //NOTE: 'effGetParamLabel' is no longer defined in vestige headers
+ //plugin->dispatcher (plugin, effGetParamLabel, i, 0, label, 0);
info->ParamLabels[i] = strdup(label);
- }
- return info;
+ }
+ return info;
}
/* A simple 'dummy' audiomaster callback which should be ok,
we will only be instantiating the plugin in order to get its info*/
-static long simple_master_callback(struct AEffect *fx, long opcode, long index, long value, void *ptr, float opt)
+static intptr_t
+simple_master_callback (AEffect *, int32_t opcode, int32_t, intptr_t, void *, float)
{
-
- if(opcode == audioMasterVersion)
+ if (opcode == audioMasterVersion)
return 2;
- else
+ else
return 0;
}
data, and if that doesn't exist, load the plugin, get its data and
then cache it for future ref*/
-VSTFXInfo *vstfx_get_info(char *dllpath)
+VSTInfo *
+vstfx_get_info (char* dllpath)
{
- if( vstfx_info_file_is_valid(dllpath))
- {
- VSTFXInfo *info;
- char *vstfxpath = vstfx_dllpath_to_infopath(dllpath);
-
- info = load_vstfx_info_file(vstfxpath);
- free(vstfxpath);
-
+ FILE* infofile;
+ VSTHandle* h;
+ VSTState* vstfx;
+ VSTInfo* info;
+
+ if ((infofile = vstfx_infofile_for_read (dllpath)) != 0) {
+ VSTInfo *info;
+ info = load_vstfx_info_file (infofile);
+ fclose (infofile);
return info;
- }
- else
- {
- VSTFXHandle *h;
- VSTFX *vstfx;
- VSTFXInfo *info;
-
- char *vstfxpath;
-
- if(!(h = vstfx_load(dllpath)))
- return NULL;
-
- if(!(vstfx = vstfx_instantiate(h, simple_master_callback, NULL)))
- {
+ }
+
+ if(!(h = vstfx_load(dllpath)))
+ return 0;
+
+ if(!(vstfx = vstfx_instantiate(h, simple_master_callback, 0))) {
vstfx_unload(h);
vstfx_error( "** ERROR ** VSTFXinfofile : Instantiate failed\n" );
- return NULL;
- }
-
- vstfxpath = vstfx_dllpath_to_infopath(dllpath);
-
- if(!vstfxpath)
- {
- vstfx_close(vstfx);
- vstfx_unload(h);
- vstfx_error( "** ERROR ** VSTFXinfofile : get vstfx filename failed\n" );
- return NULL;
- }
-
- info = vstfx_info_from_plugin(vstfx);
-
- save_vstfx_info_file(info, vstfxpath);
-
- free(vstfxpath);
-
+ return 0;
+ }
+
+ infofile = vstfx_infofile_for_write (dllpath);
+
+ if(!infofile) {
vstfx_close(vstfx);
vstfx_unload(h);
-
- return info;
- }
+ vstfx_error("cannot create new FST info file for plugin");
+ return 0;
+ }
+
+ info = vstfx_info_from_plugin(vstfx);
+
+ save_vstfx_info_file(info, infofile);
+ fclose (infofile);
+
+ vstfx_close(vstfx);
+ vstfx_unload(h);
+
+ return info;
}
-void vstfx_free_info(VSTFXInfo *info )
+void
+vstfx_free_info (VSTInfo *info)
{
- int i;
-
- for(i=0; i < info->numParams; i++)
- {
- free(info->ParamNames[i]);
- free(info->ParamLabels[i]);
- }
+ for (int i = 0; i < info->numParams; i++) {
+ free (info->ParamNames[i]);
+ free (info->ParamLabels[i]);
+ }
- free(info->name);
- free(info->creator);
- free(info->Category);
- free(info);
+ free (info->name);
+ free (info->creator);
+ free (info->Category);
+ free (info);
}