From 4d3e06f29d4f97b362fb1f69fde977cefd16cf9f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 22 Jun 2006 00:22:16 +0000 Subject: more details for VST support git-svn-id: svn://localhost/ardour2/trunk@630 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/fst/fstinfofile.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 libs/fst/fstinfofile.c (limited to 'libs/fst/fstinfofile.c') diff --git a/libs/fst/fstinfofile.c b/libs/fst/fstinfofile.c new file mode 100644 index 0000000000..9560053c7b --- /dev/null +++ b/libs/fst/fstinfofile.c @@ -0,0 +1,266 @@ + +#include "fst.h" +#include "vst/aeffectx.h" + +#include +#include +#include + +#include +#include +#include + + +#define MAX_STRING_LEN 256 + +#define FALSE 0 +#define TRUE !FALSE + +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 ); + } else { + return NULL; + } +} + +static FSTInfo *load_fst_info_file( char *filename ) { + + FSTInfo *info = (FSTInfo *) malloc( sizeof( FSTInfo ) ); + FILE *fp; + int i; + + + if( info == NULL ) + return NULL; + + fp = fopen( filename, "r" ); + + if( fp == NULL ) { + free( info ); + return NULL; + } + + if( (info->name = 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; inumParams; 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; inumParams; i++ ) { + if( (info->ParamLabels[i] = read_string( fp )) == NULL ) goto error; + } + + + fclose( fp ); + return info; + +error: + fclose( fp ); + free( info ); + return NULL; +} + +static int save_fst_info_file( FSTInfo *info, char *filename ) { + + FILE *fp; + int i; + + + if( info == NULL ) { + fst_error( "info is NULL\n" ); + return TRUE; + } + + fp = fopen( filename, "w" ); + + if( fp == NULL ) { + fst_error( "Cant write info file %s\n", filename ); + return TRUE; + } + + fprintf( fp, "%s\n", info->name ); + fprintf( fp, "%d\n", info->UniqueID ); + fprintf( fp, "%s\n", info->Category ); + fprintf( fp, "%d\n", info->numInputs ); + fprintf( fp, "%d\n", info->numOutputs ); + fprintf( fp, "%d\n", info->numParams ); + fprintf( fp, "%d\n", info->wantMidi ); + fprintf( fp, "%d\n", info->hasEditor ); + fprintf( fp, "%d\n", info->canProcessReplacing ); + + for( i=0; inumParams; i++ ) { + fprintf( fp, "%s\n", info->ParamNames[i] ); + } + for( i=0; inumParams; i++ ) { + fprintf( fp, "%s\n", info->ParamLabels[i] ); + } + + + fclose( fp ); + + return FALSE; +} + +static char *fst_dllpath_to_infopath( char *dllpath ) { + char *retval; + if( strstr( dllpath, ".dll" ) == NULL ) return NULL; + + retval = strdup( dllpath ); + sprintf( retval + strlen(retval) - 4, ".fst" ); + return retval; +} + +static int fst_info_file_is_valid( char *dllpath ) { + struct stat dllstat, fststat; + char *fstpath = fst_dllpath_to_infopath( dllpath ); + + if( !fstpath ) return FALSE; + + if( stat( dllpath, &dllstat ) ){ fst_error( "dll path %s invalid\n", dllpath ); return TRUE; } + if( stat( fstpath, &fststat ) ) return FALSE; + + free( fstpath ); + if( dllstat.st_mtime > fststat.st_mtime ) + return FALSE; + else + return TRUE; +} + +static int fst_can_midi( FST *fst ) { + AEffect *plugin = fst->plugin; + int vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, NULL, 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 FALSE; + +} +static FSTInfo *fst_info_from_plugin( FST *fst ) { + FSTInfo *info = (FSTInfo *) malloc( sizeof( FSTInfo ) ); + AEffect *plugin; + int i; + + if( ! fst ) { + fst_error( "fst is NULL\n" ); + return NULL; + } + + if( ! info ) return NULL; + + plugin = fst->plugin; + + + info->name = strdup(fst->handle->name ); + info->UniqueID = plugin->uniqueID; + info->Category = strdup( "None" ); // FIXME: + info->numInputs = plugin->numInputs; + info->numOutputs = plugin->numOutputs; + info->numParams = plugin->numParams; + info->wantMidi = fst_can_midi( fst ); + 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; inumParams; i++ ) { + char name[20]; + char label[9]; + plugin->dispatcher (plugin, + effGetParamName, + i, 0, name, 0); + + plugin->dispatcher (plugin, + effGetParamLabel, + i, 0, label, 0); + + info->ParamNames[i] = strdup( name ); + info->ParamLabels[i] = strdup( label ); + } + return info; +} + +// most simple one :) could be sufficient.... +static long simple_master_callback( AEffect *fx, long opcode, long index, long value, void *ptr, float opt ) { + if( opcode == audioMasterVersion ) + return 2; + else + return 0; +} + +FSTInfo *fst_get_info( char *dllpath ) { + + if( fst_info_file_is_valid( dllpath ) ) { + FSTInfo *info; + char *fstpath = fst_dllpath_to_infopath( dllpath ); + + info = load_fst_info_file( fstpath ); + free( fstpath ); + return info; + + } else { + + FSTHandle *h; + FST *fst; + FSTInfo *info; + char *fstpath; + + if( !(h = fst_load( dllpath )) ) return NULL; + if( !(fst = fst_instantiate( h, simple_master_callback, NULL )) ) { + fst_unload( h ); + fst_error( "instantiate failed\n" ); + return NULL; + } + fstpath = fst_dllpath_to_infopath( dllpath ); + if( !fstpath ) { + fst_close( fst ); + fst_unload( h ); + fst_error( "get fst filename failed\n" ); + return NULL; + } + info = fst_info_from_plugin( fst ); + save_fst_info_file( info, fstpath ); + + free( fstpath ); + fst_close( fst ); + fst_unload( h ); + return info; + } +} + +void fst_free_info( FSTInfo *info ) { + + int i; + + for( i=0; inumParams; i++ ) { + free( info->ParamNames[i] ); + free( info->ParamLabels[i] ); + } + free( info->name ); + free( info->Category ); + free( info ); +} + + -- cgit v1.2.3