summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2011-10-29 14:36:13 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2011-10-29 14:36:13 +0000
commitac86e338feb914ef6c331e682de8e0fc42f6d9c4 (patch)
treec6d756e9bd2ff96eee9b3ff9c3f2e476e52974f7 /libs
parentb86ac1c8f7fb6d0353524ad5567ad4bb700c6546 (diff)
change internal API used by native VST support to read/write info files, so that users can generate .fsi files in ~/.fst if is not writable by them
git-svn-id: svn://localhost/ardour2/branches/3.0@10334 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rwxr-xr-xlibs/ardour/vstfxinfofile.cc428
1 files changed, 241 insertions, 187 deletions
diff --git a/libs/ardour/vstfxinfofile.cc b/libs/ardour/vstfxinfofile.cc
index 670ba95661..c81e0636c2 100755
--- a/libs/ardour/vstfxinfofile.cc
+++ b/libs/ardour/vstfxinfofile.cc
@@ -4,13 +4,12 @@
/*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>
@@ -18,10 +17,12 @@
#include <string.h>
#include <libgen.h>
-#define MAX_STRING_LEN 256
+#include <glib.h>
+#include <glib/gstdio.h>
-#define FALSE 0
-#define TRUE !FALSE
+#include "ardour/vstfx.h"
+
+#define MAX_STRING_LEN 256
static char* read_string(FILE *fp)
{
@@ -42,74 +43,63 @@ static char* read_string(FILE *fp)
}
}
-static VSTFXInfo* load_vstfx_info_file(char *filename)
+static VSTFXInfo* load_vstfx_info_file(FILE* fp)
{
- VSTFXInfo *info = (VSTFXInfo*) malloc(sizeof(VSTFXInfo));
- FILE *fp;
- int i;
+ VSTFXInfo *info;
+ int i;
- if(info == NULL)
+ if ((info = (VSTFXInfo*) malloc(sizeof(VSTFXInfo))) == NULL) {
return NULL;
+ }
- fp = fopen(filename, "r");
-
- if(fp == NULL)
- {
- free( info );
- return NULL;
- }
+ 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;
+ }
- 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++)
- {
+ 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 = (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;
- }
+ }
- fclose( fp );
- return info;
-
-error:
- fclose( fp );
- free( info );
- return NULL;
+ return info;
+
+ error:
+ free( info );
+ return NULL;
}
-static int save_vstfx_info_file(VSTFXInfo *info, char *filename)
+static int save_vstfx_info_file(VSTFXInfo *info, FILE* fp)
{
- FILE *fp;
int i;
- if(info == NULL)
- {
- vstfx_error("** ERROR ** VSTFXinfofile : info ptr is NULL\n");
- return TRUE;
+ if (info == NULL) {
+ vstfx_error("** ERROR ** VSTFXinfofile : info ptr is NULL\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 == NULL) {
+ vstfx_error("** ERROR ** VSTFXinfofile : file ptr is NULL\n");
+ return -1;
}
-
+
fprintf( fp, "%s\n", info->name );
fprintf( fp, "%s\n", info->creator );
fprintf( fp, "%d\n", info->UniqueID );
@@ -121,72 +111,149 @@ static int save_vstfx_info_file(VSTFXInfo *info, char *filename)
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)
+ char* basename;
+ char* base;
+ size_t blen;
+
+ 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);
-
- dir_path = strdup(dllpath);
- base_name = strdup(dllpath);
-
- sprintf(retval, "%s/.%s", dirname(dir_path), basename(base_name));
- sprintf(retval + strlen(retval) - 3, ".fsi");
+ }
- free(dir_path);
- free(base_name);
+ if (personal) {
+ dir_path = g_build_filename (g_get_home_dir(), ".fst", NULL);
+ } else {
+ dir_path = g_path_get_dirname (dllpath);
+ }
- return retval;
+ 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);
+
+
+ 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 NULL;
}
-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 NULL;
+}
+
+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" ) == NULL) {
+ return NULL;
+ }
- 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 NULL;
+ }
+ }
+
+ } 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);
+
+ FILE* f = fopen (path, "w");
+ g_free (path);
+
+ return f;
+}
+
+static FILE* vstfx_infofile_for_write (char* dllpath)
+{
+ FILE* f;
- free(vstfxpath);
+ if ((f = vstfx_infofile_create (dllpath, 0)) == NULL) {
+ 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)
@@ -200,9 +267,9 @@ static int vstfx_can_midi(VSTFX *vstfx)
/* 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)
@@ -210,58 +277,55 @@ static VSTFXInfo* vstfx_info_from_plugin(VSTFX *vstfx)
VSTFXInfo* info = (VSTFXInfo*) malloc(sizeof(VSTFXInfo));
- struct 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)
+ }
+
+ if(!info)
return NULL;
-
- plugin = vstfx->plugin;
- 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);
- }
-
- info->UniqueID = plugin->uniqueID;
-
- 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++)
- {
+ if (strlen(creator) == 0) {
+ info->creator = strdup("Unknown");
+ } else {
+ info->creator = strdup (creator);
+ }
+
+ info->UniqueID = plugin->uniqueID;
+
+ 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];
@@ -276,8 +340,8 @@ static VSTFXInfo* vstfx_info_from_plugin(VSTFX *vstfx)
//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,
@@ -297,55 +361,45 @@ then cache it for future ref*/
VSTFXInfo *vstfx_get_info(char *dllpath)
{
- if( vstfx_info_file_is_valid(dllpath))
- {
- VSTFXInfo *info;
- char *vstfxpath = vstfx_dllpath_to_infopath(dllpath);
+ FILE* infofile;
+ VSTFXHandle *h;
+ VSTFX *vstfx;
+ VSTFXInfo *info;
- info = load_vstfx_info_file(vstfxpath);
- free(vstfxpath);
-
- return info;
- }
- else
- {
- VSTFXHandle *h;
- VSTFX *vstfx;
+ if ((infofile = vstfx_infofile_for_read (dllpath)) != NULL) {
VSTFXInfo *info;
-
- char *vstfxpath;
-
- if(!(h = vstfx_load(dllpath)))
- return NULL;
-
- if(!(vstfx = vstfx_instantiate(h, simple_master_callback, NULL)))
- {
+ info = load_vstfx_info_file (infofile);
+ fclose (infofile);
+ return info;
+ }
+
+ if(!(h = vstfx_load(dllpath)))
+ return NULL;
+
+ if(!(vstfx = vstfx_instantiate(h, simple_master_callback, NULL))) {
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);
-
+ }
+
+ 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 NULL;
+ }
+
+ 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 )