3 #include "vestige/aeffectx.h"
14 #define MAX_STRING_LEN 256
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;
34 static FSTInfo
*load_fst_info_file( char *filename
) {
36 FSTInfo
*info
= (FSTInfo
*) malloc( sizeof( FSTInfo
) );
44 fp
= fopen( filename
, "r" );
51 if( (info
->name
= read_string( fp
)) == NULL
) goto error
;
52 if( 1 != fscanf( fp
, "%d\n", &info
->UniqueID
) ) goto error
;
53 if( (info
->Category
= read_string( fp
)) == NULL
) goto error
;
54 if( 1 != fscanf( fp
, "%d\n", &info
->numInputs
) ) goto error
;
55 if( 1 != fscanf( fp
, "%d\n", &info
->numOutputs
) ) goto error
;
56 if( 1 != fscanf( fp
, "%d\n", &info
->numParams
) ) goto error
;
57 if( 1 != fscanf( fp
, "%d\n", &info
->wantMidi
) ) goto error
;
58 if( 1 != fscanf( fp
, "%d\n", &info
->hasEditor
) ) goto error
;
59 if( 1 != fscanf( fp
, "%d\n", &info
->canProcessReplacing
) ) goto error
;
61 if( (info
->ParamNames
= (char **) malloc( sizeof( char * ) * info
->numParams
)) == NULL
) goto error
;
62 for( i
=0; i
<info
->numParams
; i
++ ) {
63 if( (info
->ParamNames
[i
] = read_string( fp
)) == NULL
) goto error
;
65 if( (info
->ParamLabels
= (char **) malloc( sizeof( char * ) * info
->numParams
)) == NULL
) goto error
;
66 for( i
=0; i
<info
->numParams
; i
++ ) {
67 if( (info
->ParamLabels
[i
] = read_string( fp
)) == NULL
) goto error
;
80 static int save_fst_info_file( FSTInfo
*info
, char *filename
) {
87 fst_error( "info is NULL\n" );
91 fp
= fopen( filename
, "w" );
94 fst_error( "Cant write info file %s\n", filename
);
98 fprintf( fp
, "%s\n", info
->name
);
99 fprintf( fp
, "%d\n", info
->UniqueID
);
100 fprintf( fp
, "%s\n", info
->Category
);
101 fprintf( fp
, "%d\n", info
->numInputs
);
102 fprintf( fp
, "%d\n", info
->numOutputs
);
103 fprintf( fp
, "%d\n", info
->numParams
);
104 fprintf( fp
, "%d\n", info
->wantMidi
);
105 fprintf( fp
, "%d\n", info
->hasEditor
);
106 fprintf( fp
, "%d\n", info
->canProcessReplacing
);
108 for( i
=0; i
<info
->numParams
; i
++ ) {
109 fprintf( fp
, "%s\n", info
->ParamNames
[i
] );
111 for( i
=0; i
<info
->numParams
; i
++ ) {
112 fprintf( fp
, "%s\n", info
->ParamLabels
[i
] );
121 static char *fst_dllpath_to_infopath( char *dllpath
) {
123 if( strstr( dllpath
, ".dll" ) == NULL
) return NULL
;
125 retval
= strdup( dllpath
);
126 sprintf( retval
+ strlen(retval
) - 4, ".fst" );
130 static int fst_info_file_is_valid( char *dllpath
) {
131 struct stat dllstat
, fststat
;
132 char *fstpath
= fst_dllpath_to_infopath( dllpath
);
134 if( !fstpath
) return FALSE
;
136 if( stat( dllpath
, &dllstat
) ){ fst_error( "dll path %s invalid\n", dllpath
); return TRUE
; }
137 if( stat( fstpath
, &fststat
) ) return FALSE
;
140 if( dllstat
.st_mtime
> fststat
.st_mtime
)
146 static int fst_can_midi( FST
*fst
) {
147 struct AEffect
*plugin
= fst
->plugin
;
148 int vst_version
= plugin
->dispatcher (plugin
, effGetVstVersion
, 0, 0, NULL
, 0.0f
);
150 if (vst_version
>= 2) {
152 /* should we send it VST events (i.e. MIDI) */
154 if ((plugin
->flags
& effFlagsIsSynth
) ||
155 (plugin
->dispatcher (plugin
, effCanDo
, 0, 0,(void*) "receiveVstEvents", 0.0f
) > 0))
161 static FSTInfo
*fst_info_from_plugin( FST
*fst
) {
162 FSTInfo
*info
= (FSTInfo
*) malloc( sizeof( FSTInfo
) );
163 struct AEffect
*plugin
;
167 fst_error( "fst is NULL\n" );
171 if( ! info
) return NULL
;
173 plugin
= fst
->plugin
;
176 info
->name
= strdup(fst
->handle
->name
);
177 //info->UniqueID = plugin->uniqueID;
178 info
->Category
= strdup( "None" ); // FIXME:
179 info
->numInputs
= plugin
->numInputs
;
180 info
->numOutputs
= plugin
->numOutputs
;
181 info
->numParams
= plugin
->numParams
;
182 info
->wantMidi
= fst_can_midi( fst
);
183 info
->hasEditor
= plugin
->flags
& effFlagsHasEditor
? TRUE
: FALSE
;
184 info
->canProcessReplacing
= plugin
->flags
& effFlagsCanReplacing
? TRUE
: FALSE
;
186 info
->ParamNames
= (char **) malloc( sizeof( char * ) * info
->numParams
);
187 info
->ParamLabels
= (char **) malloc( sizeof( char * ) * info
->numParams
);
188 for( i
=0; i
<info
->numParams
; i
++ ) {
191 plugin
->dispatcher (plugin
,
194 info
->ParamNames
[i
] = strdup( name
);
196 plugin
->dispatcher (plugin
,
200 info
->ParamLabels
[i
] = strdup( label
);
202 info
->ParamLabels
[i
] = strdup( name
);
208 // most simple one :) could be sufficient....
209 static long simple_master_callback( struct AEffect
*fx
, long opcode
, long index
, long value
, void *ptr
, float opt
) {
210 if( opcode
== audioMasterVersion
)
216 FSTInfo
*fst_get_info( char *dllpath
) {
218 if( fst_info_file_is_valid( dllpath
) ) {
220 char *fstpath
= fst_dllpath_to_infopath( dllpath
);
222 info
= load_fst_info_file( fstpath
);
233 if( !(h
= fst_load( dllpath
)) ) return NULL
;
234 if( !(fst
= fst_instantiate( h
, simple_master_callback
, NULL
)) ) {
236 fst_error( "instantiate failed\n" );
239 fstpath
= fst_dllpath_to_infopath( dllpath
);
243 fst_error( "get fst filename failed\n" );
246 info
= fst_info_from_plugin( fst
);
247 save_fst_info_file( info
, fstpath
);
256 void fst_free_info( FSTInfo
*info
) {
260 for( i
=0; i
<info
->numParams
; i
++ ) {
261 free( info
->ParamNames
[i
] );
262 free( info
->ParamLabels
[i
] );
265 free( info
->Category
);