12 #define MAX_STRING_LEN 256
17 extern char * strdup (const char *);
19 static char *read_string( FILE *fp ) {
20 char buf[MAX_STRING_LEN];
22 fgets( buf, MAX_STRING_LEN, fp );
23 if( strlen( buf ) < MAX_STRING_LEN ) {
26 buf[strlen(buf)-1] = 0;
35 load_fst_info_file (char* filename)
37 VSTInfo *info = (VSTInfo *) malloc (sizeof (VSTInfo));
45 fp = fopen( filename, "r" );
52 if( (info->name = read_string( fp )) == NULL ) goto error;
53 if( (info->creator = read_string( fp )) == NULL ) goto error;
54 if( 1 != fscanf( fp, "%d\n", &info->UniqueID ) ) goto error;
55 if( (info->Category = read_string( fp )) == NULL ) goto error;
56 if( 1 != fscanf( fp, "%d\n", &info->numInputs ) ) goto error;
57 if( 1 != fscanf( fp, "%d\n", &info->numOutputs ) ) goto error;
58 if( 1 != fscanf( fp, "%d\n", &info->numParams ) ) goto error;
59 if( 1 != fscanf( fp, "%d\n", &info->wantMidi ) ) goto error;
60 if( 1 != fscanf( fp, "%d\n", &info->hasEditor ) ) goto error;
61 if( 1 != fscanf( fp, "%d\n", &info->canProcessReplacing ) ) goto error;
63 if( (info->ParamNames = (char **) malloc( sizeof( char * ) * info->numParams )) == NULL ) goto error;
64 for( i=0; i<info->numParams; i++ ) {
65 if( (info->ParamNames[i] = read_string( fp )) == NULL ) goto error;
67 if( (info->ParamLabels = (char **) malloc( sizeof( char * ) * info->numParams )) == NULL ) goto error;
68 for( i=0; i<info->numParams; i++ ) {
69 if( (info->ParamLabels[i] = read_string( fp )) == NULL ) goto error;
83 save_fst_info_file (VSTInfo* info, char* filename)
90 fst_error( "info is NULL\n" );
94 fp = fopen( filename, "w" );
97 fst_error( "Cant write info file %s\n", filename );
101 fprintf( fp, "%s\n", info->name );
102 fprintf( fp, "%s\n", info->creator );
103 fprintf( fp, "%d\n", info->UniqueID );
104 fprintf( fp, "%s\n", info->Category );
105 fprintf( fp, "%d\n", info->numInputs );
106 fprintf( fp, "%d\n", info->numOutputs );
107 fprintf( fp, "%d\n", info->numParams );
108 fprintf( fp, "%d\n", info->wantMidi );
109 fprintf( fp, "%d\n", info->hasEditor );
110 fprintf( fp, "%d\n", info->canProcessReplacing );
112 for( i=0; i<info->numParams; i++ ) {
113 fprintf( fp, "%s\n", info->ParamNames[i] );
115 for( i=0; i<info->numParams; i++ ) {
116 fprintf( fp, "%s\n", info->ParamLabels[i] );
125 static char *fst_dllpath_to_infopath( char *dllpath ) {
127 if( strstr( dllpath, ".dll" ) == NULL ) return NULL;
129 retval = strdup( dllpath );
130 sprintf( retval + strlen(retval) - 4, ".fsi" );
134 static int fst_info_file_is_valid( char *dllpath ) {
135 struct stat dllstat, fststat;
136 char *fstpath = fst_dllpath_to_infopath( dllpath );
138 if( !fstpath ) return FALSE;
140 if( stat( dllpath, &dllstat ) ){ fst_error( "dll path %s invalid\n", dllpath ); return TRUE; }
141 if( stat( fstpath, &fststat ) ) return FALSE;
144 if( dllstat.st_mtime > fststat.st_mtime )
151 fst_can_midi (VSTState* fst)
153 AEffect* plugin = fst->plugin;
154 int vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, NULL, 0.0f);
156 if (vst_version >= 2) {
158 /* should we send it VST events (i.e. MIDI) */
160 if ((plugin->flags & effFlagsIsSynth) ||
161 (plugin->dispatcher (plugin, effCanDo, 0, 0,(void*) "receiveVstEvents", 0.0f) > 0))
168 fst_info_from_plugin (VSTState* fst)
170 VSTInfo* info = (VSTInfo *) malloc (sizeof (VSTInfo));
176 fst_error( "fst is NULL\n" );
180 if( ! info ) return NULL;
182 plugin = fst->plugin;
185 info->name = strdup(fst->handle->name );
186 plugin->dispatcher (plugin, 47 /* effGetVendorString */, 0, 0, creator, 0);
187 if (strlen (creator) == 0) {
188 info->creator = strdup ("Unknown");
190 info->creator = strdup (creator);
193 info->UniqueID = *((int32_t *) &plugin->uniqueID);
195 info->Category = strdup( "None" ); // FIXME:
196 info->numInputs = plugin->numInputs;
197 info->numOutputs = plugin->numOutputs;
198 info->numParams = plugin->numParams;
199 info->wantMidi = fst_can_midi( fst );
200 info->hasEditor = plugin->flags & effFlagsHasEditor ? TRUE : FALSE;
201 info->canProcessReplacing = plugin->flags & effFlagsCanReplacing ? TRUE : FALSE;
203 info->ParamNames = (char **) malloc( sizeof( char * ) * info->numParams );
204 info->ParamLabels = (char **) malloc( sizeof( char * ) * info->numParams );
205 for( i=0; i<info->numParams; i++ ) {
208 plugin->dispatcher (plugin,
211 info->ParamNames[i] = strdup( name );
212 plugin->dispatcher (plugin,
213 6 /* effGetParamLabel */,
215 info->ParamLabels[i] = strdup( label );
220 // most simple one :) could be sufficient....
222 simple_master_callback (AEffect *fx, int32_t opcode, int32_t index, intptr_t value, void *ptr, float opt)
224 if (opcode == audioMasterVersion) {
232 fst_get_info (char* dllpath)
234 if( fst_info_file_is_valid( dllpath ) ) {
236 char *fstpath = fst_dllpath_to_infopath( dllpath );
238 info = load_fst_info_file( fstpath );
249 if( !(h = fst_load( dllpath )) ) return NULL;
250 if( !(fst = fst_instantiate( h, simple_master_callback, NULL )) ) {
252 fst_error( "instantiate failed\n" );
255 fstpath = fst_dllpath_to_infopath( dllpath );
259 fst_error( "get fst filename failed\n" );
262 info = fst_info_from_plugin( fst );
263 save_fst_info_file( info, fstpath );
273 fst_free_info (VSTInfo *info)
277 for( i=0; i<info->numParams; i++ ) {
278 free( info->ParamNames[i] );
279 free( info->ParamLabels[i] );
282 free( info->creator );
283 free( info->Category );