3 Free software by Richard W.E. Furse. Do with as you will. No
6 /*****************************************************************************/
12 /*****************************************************************************/
16 #include "ladspa-utils.h"
18 /*****************************************************************************/
20 /* includes for galan : */
32 #include "generator.h"
39 /* On Win32, these headers seem to need to follow glib.h */
40 #include <sys/types.h>
44 #define GENERATOR_CLASS_NAME "vsttest1"
45 #define GENERATOR_CLASS_PATH "Misc/VST"
46 #define GENERATOR_CLASS_PIXMAP "template.xpm"
52 #define NUM_EVENT_INPUTS 1
55 #define NUM_EVENT_OUTPUTS 1
59 typedef AEffect
*(*AEMainFunc
)( audioMasterCallback cb
);
61 //typedef struct VPluginData {
62 // GList *insig, *outsig, *inevent, *outevent;
70 //LADSPA_Handle instance_handle;
83 PRIVATE GHashTable
*MainFuncIndex
= NULL
;
84 PRIVATE GHashTable
*VPluginIndex
= NULL
;
86 long master_callback( AEffect
*fx
, long opcode
, long index
, long value
, void *ptr
, float opt
) {
91 PRIVATE
void run_plugin( Generator
*g
, int buflen
) {
95 for( i
=0; i
<data
->aeff
->numInputs
; i
++ ) {
98 // SAMPLE buf[MAXIMUM_REALTIME_STEP];
100 // if( gen_read_realtime_input( g, i, -1, buf, buflen ) ) {
102 // for( j=0; j<buflen; j++ )
103 // data->insignals[i][j] = buf[j];
106 if( gen_read_realtime_input( g
, i
, -1, data
->insignals
[i
], buflen
) ) {
112 for( j
=0; j
<buflen
; j
++ )
113 data
->insignals
[i
][j
] = 0.0;
118 data
->aeff
->processReplacing( data
->aeff
, data
->insignals
, data
->outsignals
, buflen
);
119 data
->lastrun
= gen_get_sampletime();
122 for( i
=0; i
<outecount
; i
++ ) {
124 //printf( "oev: %f", data->outevents[i] );
125 if( data
->oldoutevents
[i
] != data
->outevents
[i
] ) {
131 gen_init_aevent(&event
, AE_NUMBER
, NULL
, 0, NULL
, 0, gen_get_sampletime() );
134 event
.d
.number
= data
->outevents
[i
];
136 if( isnan(data
->outevents
[i
]) || isinf( data
->outevents
[i
]) ) {
137 printf( "nan ... \n" );
138 event
.d
.number
= 0.0;
140 event
.d
.number
= data
->outevents
[i
];
144 gen_send_events(g
, i
, -1, &event
);
146 //printf( "sending ev: %f on %d \n", event.d.number, i );
150 data
->oldoutevents
[i
] = data
->outevents
[i
];
156 PRIVATE
void realtime_handler(Generator
*g
, AEvent
*event
) {
158 //Data *data = g->data;
164 run_plugin( g
, event
->d
.integer
);
169 g_warning("vst module doesn't care for events of kind %d.", event
->kind
);
175 PRIVATE LADSPA_Data
get_default( ControlDescriptor
*control
, LADSPA_PortRangeHintDescriptor hint
) {
177 if( LADSPA_IS_HINT_HAS_DEFAULT( hint
) ) {
179 if( LADSPA_IS_HINT_DEFAULT_MINIMUM( hint
) )
181 if( LADSPA_IS_HINT_DEFAULT_LOW( hint
) )
182 return control
->min
* 0.75 + control
->max
* 0.25;
183 if( LADSPA_IS_HINT_DEFAULT_MIDDLE( hint
) )
184 return control
->min
* 0.5 + control
->max
* 0.5;
185 if( LADSPA_IS_HINT_DEFAULT_HIGH( hint
) )
186 return control
->min
* 0.25 + control
->max
* 0.75;
187 if( LADSPA_IS_HINT_DEFAULT_MAXIMUM( hint
) )
189 if( LADSPA_IS_HINT_DEFAULT_0( hint
) )
191 if( LADSPA_IS_HINT_DEFAULT_1( hint
) )
193 if( LADSPA_IS_HINT_DEFAULT_100( hint
) )
195 if( LADSPA_IS_HINT_DEFAULT_440( hint
) )
198 printf( "plugins says it has default... but i cant find out.\n" );
207 PRIVATE gboolean
init_instance(Generator
*g
) {
208 Data
*data
= safe_malloc(sizeof(Data
));
209 int inecount
, inscount
, outscount
, i
;
219 data
->main_func
= g_hash_table_lookup( MainFuncIndex
, g
->klass
->tag
);
220 //printf( "retrieved: %s %x\n", g->klass->name, data->ladspa_descriptor );
221 data
->aeff
= data
->main_func( &master_callback
);
222 //printf( "got instancehandle: %x\n", data->instance_handle );
224 // Connect the ports ... pre: alloc memory for the controls...
225 // connect wird erst vor dem laufen mit outpu_generator gemacht...
227 inecount
= data
->aeff
->numParams
;
228 inscount
= data
->aeff
->numInputs
;
229 outscount
= data
->aeff
->numOutputs
;
231 data
->inevents
= safe_malloc( sizeof( float ) * inecount
);
232 //data->outevents = safe_malloc( sizeof( LADSPA_Data ) * outecount );
233 //data->oldoutevents = safe_malloc( sizeof( LADSPA_Data ) * outecount );
234 data
->insignals
= safe_malloc( sizeof( float * ) * inscount
);
235 data
->outsignals
= safe_malloc( sizeof( float * ) * outscount
);
237 for( i
=0; i
<inecount
; i
++ ) {
238 data
->inevents
[i
] = data
->aeff
->getParameter( data
->aeff
, i
);
242 // for( i=0; i<outecount; i++ ) {
243 // data->outevents[i] = 0.0;
244 // data->oldoutevents[i] = 0.0;
246 // data->ladspa_descriptor->connect_port(
247 // data->instance_handle,
248 // (int) g_list_nth_data( data->lpdat->outevent, i ),
249 // &(data->outevents[i]) );
253 for( i
=0; i
<outscount
; i
++ ) {
254 data
->outsignals
[i
] = safe_malloc( sizeof( float ) * MAXIMUM_REALTIME_STEP
);
257 for( i
=0; i
<inscount
; i
++ ) {
258 data
->insignals
[i
] = safe_malloc( sizeof( float ) * MAXIMUM_REALTIME_STEP
);
261 data
->aeff
->dispatcher( data
->aeff
, effOpen
, 0, 0, NULL
, 0 );
262 data
->aeff
->dispatcher( data
->aeff
, effSetSampleRate
, 0, 0, NULL
, (float) SAMPLE_RATE
);
263 data
->aeff
->dispatcher( data
->aeff
, effSetBlockSize
, 0, MAXIMUM_REALTIME_STEP
, NULL
, 0 );
264 data
->aeff
->dispatcher( data
->aeff
, effMainsChanged
, 0, 1, NULL
, 0 );
269 gen_register_realtime_fn(g
, realtime_handler
);
274 PRIVATE
void destroy_instance(Generator
*g
) {
275 Data
*data
= g
->data
;
276 gen_deregister_realtime_fn(g
, realtime_handler
);
277 data
->aeff
->dispatcher( data
->aeff
, effClose
, 0, 0, 0, 0 );
278 // TODO: what a mess free it all ....
283 PRIVATE
void unpickle_instance(Generator
*g
, ObjectStoreItem
*item
, ObjectStore
*db
) {
284 Data
*data
= safe_malloc(sizeof(Data
));
285 int inecount
, outecount
, inscount
, outscount
, i
;
286 ObjectStoreDatum
*inarray
, *outarray
;
289 data
->ladspa_descriptor
= g_hash_table_lookup( DescriptorIndex
, g
->klass
->tag
);
290 data
->lpdat
= g_hash_table_lookup( LPluginIndex
, g
->klass
->tag
);
291 data
->instance_handle
= data
->ladspa_descriptor
->instantiate( data
->ladspa_descriptor
, SAMPLE_RATE
);
295 inarray
= objectstore_item_get(item
, "ladspa_inarray");
296 outarray
= objectstore_item_get(item
, "ladspa_oldoutarray");
298 inecount
= g_list_length( data
->lpdat
->inevent
);
299 outecount
= g_list_length( data
->lpdat
->outevent
);
300 inscount
= g_list_length( data
->lpdat
->insig
);
301 outscount
= g_list_length( data
->lpdat
->outsig
);
303 data
->inevents
= safe_malloc( sizeof( LADSPA_Data
) * inecount
);
304 data
->outevents
= safe_malloc( sizeof( LADSPA_Data
) * outecount
);
305 data
->oldoutevents
= safe_malloc( sizeof( LADSPA_Data
) * outecount
);
306 data
->insignals
= safe_malloc( sizeof( LADSPA_Data
* ) * inscount
);
307 data
->outsignals
= safe_malloc( sizeof( LADSPA_Data
* ) * outscount
);
309 for( i
=0; i
<inecount
; i
++ ) {
311 ObjectStoreDatum
*field
= objectstore_datum_array_get(inarray
, i
);
313 data
->inevents
[i
] = objectstore_datum_double_value( field
);
316 unsigned long portindex
= (unsigned long) g_list_nth_data( data
->lpdat
->inevent
, i
);
317 LADSPA_PortRangeHintDescriptor hint
= data
->ladspa_descriptor
->PortRangeHints
[portindex
].HintDescriptor
;
318 ControlDescriptor
*control
= &(g
->klass
->controls
[i
]);
320 data
->inevents
[i
] = get_default( control
, hint
);
323 data
->ladspa_descriptor
->connect_port(
324 data
->instance_handle
,
325 (int) g_list_nth_data( data
->lpdat
->inevent
, i
),
326 &(data
->inevents
[i
]) );
328 for( i
=0; i
<outecount
; i
++ ) {
329 ObjectStoreDatum
*field
= objectstore_datum_array_get(outarray
, i
);
331 data
->oldoutevents
[i
] = objectstore_datum_double_value( field
);
333 data
->oldoutevents
[i
] = 0;
335 data
->ladspa_descriptor
->connect_port(
336 data
->instance_handle
,
337 (int) g_list_nth_data( data
->lpdat
->outevent
, i
),
338 &(data
->outevents
[i
]) );
340 for( i
=0; i
<outscount
; i
++ ) {
341 data
->outsignals
[i
] = safe_malloc( sizeof( LADSPA_Data
) * MAXIMUM_REALTIME_STEP
);
343 data
->ladspa_descriptor
->connect_port(
344 data
->instance_handle
,
345 (int) g_list_nth_data( data
->lpdat
->outsig
, i
),
346 data
->outsignals
[i
] );
348 for( i
=0; i
<inscount
; i
++ ) {
349 data
->insignals
[i
] = safe_malloc( sizeof( LADSPA_Data
) * MAXIMUM_REALTIME_STEP
);
351 data
->ladspa_descriptor
->connect_port(
352 data
->instance_handle
,
353 (int) g_list_nth_data( data
->lpdat
->insig
, i
),
354 data
->insignals
[i
] );
357 if( data
->ladspa_descriptor
->activate
)
358 data
->ladspa_descriptor
->activate( data
->instance_handle
);
363 gen_register_realtime_fn(g
, realtime_handler
);
366 PRIVATE
void pickle_instance(Generator
*g
, ObjectStoreItem
*item
, ObjectStore
*db
) {
367 Data
*data
= g
->data
;
368 int incount
= g_list_length( data
->lpdat
->inevent
);
369 int outcount
= g_list_length( data
->lpdat
->outevent
);
372 //objectstore_item_set_integer(item, "TEMPLATE_dummy", data->dummy);
373 ObjectStoreDatum
*inarray
= objectstore_datum_new_array( incount
);
374 ObjectStoreDatum
*outarray
= objectstore_datum_new_array( outcount
);
375 objectstore_item_set(item
, "ladspa_inarray", inarray
);
376 objectstore_item_set(item
, "ladspa_oldoutarray", outarray
);
378 for( i
=0; i
<incount
; i
++ )
379 objectstore_datum_array_set(inarray
, i
, objectstore_datum_new_double( data
->inevents
[i
] ) );
380 for( i
=0; i
<outcount
; i
++ )
381 objectstore_datum_array_set(outarray
, i
, objectstore_datum_new_double( data
->oldoutevents
[i
] ) );
387 PRIVATE gboolean
output_generator0(Generator
*g
, SAMPLE
*buf
, int buflen
) {
388 Data
*data
= g
->data
;
391 if( data
->lastrun
!= gen_get_sampletime() )
392 run_plugin( g
, buflen
);
394 for( i
=0; i
<buflen
; i
++ )
395 buf
[i
] = data
->outsignals
[0][i
];
399 PRIVATE gboolean
output_generator1(Generator
*g
, SAMPLE
*buf
, int buflen
) {
400 Data
*data
= g
->data
;
403 if( data
->lastrun
!= gen_get_sampletime() )
404 run_plugin( g
, buflen
);
406 for( i
=0; i
<buflen
; i
++ )
407 buf
[i
] = data
->outsignals
[1][i
];
411 PRIVATE gboolean
output_generator2(Generator
*g
, SAMPLE
*buf
, int buflen
) {
412 Data
*data
= g
->data
;
415 if( data
->lastrun
!= gen_get_sampletime() )
416 run_plugin( g
, buflen
);
418 for( i
=0; i
<buflen
; i
++ )
419 buf
[i
] = data
->outsignals
[2][i
];
423 PRIVATE gboolean
output_generator3(Generator
*g
, SAMPLE
*buf
, int buflen
) {
424 Data
*data
= g
->data
;
427 if( data
->lastrun
!= gen_get_sampletime() )
428 run_plugin( g
, buflen
);
430 for( i
=0; i
<buflen
; i
++ )
431 buf
[i
] = data
->outsignals
[3][i
];
435 PRIVATE gboolean
output_generator4(Generator
*g
, SAMPLE
*buf
, int buflen
) {
436 Data
*data
= g
->data
;
439 if( data
->lastrun
!= gen_get_sampletime() )
440 run_plugin( g
, buflen
);
442 for( i
=0; i
<buflen
; i
++ )
443 buf
[i
] = data
->outsignals
[4][i
];
447 PRIVATE gboolean
output_generator5(Generator
*g
, SAMPLE
*buf
, int buflen
) {
448 Data
*data
= g
->data
;
451 if( data
->lastrun
!= gen_get_sampletime() )
452 run_plugin( g
, buflen
);
454 for( i
=0; i
<buflen
; i
++ )
455 buf
[i
] = data
->outsignals
[5][i
];
459 PRIVATE gboolean
output_generator6(Generator
*g
, SAMPLE
*buf
, int buflen
) {
460 Data
*data
= g
->data
;
463 if( data
->lastrun
!= gen_get_sampletime() )
464 run_plugin( g
, buflen
);
466 for( i
=0; i
<buflen
; i
++ )
467 buf
[i
] = data
->outsignals
[6][i
];
471 PRIVATE gboolean
output_generator7(Generator
*g
, SAMPLE
*buf
, int buflen
) {
472 Data
*data
= g
->data
;
475 if( data
->lastrun
!= gen_get_sampletime() )
476 run_plugin( g
, buflen
);
478 for( i
=0; i
<buflen
; i
++ )
479 buf
[i
] = data
->outsignals
[7][i
];
484 PRIVATE
void evt_input_handler(Generator
*g
, AEvent
*event
) {
485 /* handle incoming events on queue EVT_INPUT */
486 Data
*data
= g
->data
;
487 data
->inevents
[event
->dst_q
] = event
->d
.number
;
489 data
->aeff
->setParameter( data
->aeff
, event
->dst_q
, event
->d
.number
);
491 gen_update_controls( g
, event
->dst_q
);
498 /*****************************************************************************/
500 PRIVATE AGenerator_t output_generators
[] = { output_generator0
, output_generator1
, output_generator2
, output_generator3
,
501 output_generator4
, output_generator5
, output_generator6
, output_generator7
};
502 PRIVATE
int plugin_count
=0;
504 PUBLIC
void control_VST_Data_updater(Control
*c
) {
505 Data
*data
=c
->g
->data
;
507 control_set_value(c
, (data
->inevents
[(int) c
->desc
->refresh_data
]));
510 PRIVATE
void setup_one_class( char *dllname
) {
513 //LPluginData *plugindata = safe_malloc( sizeof( LPluginData ) );
515 AEMainFunc main_func
;
517 InputSignalDescriptor
*inputdescr
;
518 OutputSignalDescriptor
*outputdescr
;
519 ControlDescriptor
*controls
;
524 char *basename
= g_path_get_basename( dllname
);
525 basename
[strlen(basename
)-4] = 0;
527 dll_handle
= WineLoadLibrary( dllname
);
528 main_func
= WineGetProcAddress( dll_handle
, "main" );
531 tmp_effect
= main_func( &master_callback
);
536 // for( i=0; i<psDescriptor->PortCount; i++ ) {
538 // LADSPA_PortDescriptor PortDescriptor=psDescriptor->PortDescriptors[i];
540 // if( LADSPA_IS_PORT_INPUT( PortDescriptor ) )
542 // if( LADSPA_IS_PORT_CONTROL(PortDescriptor) )
543 // plugindata->inevent = g_list_append( plugindata->inevent, (gpointer) i );
545 // plugindata->insig = g_list_append( plugindata->insig, (gpointer) i );
549 // if( LADSPA_IS_PORT_CONTROL( PortDescriptor ) )
550 // plugindata->outevent = g_list_append( plugindata->outevent, (gpointer) i );
552 // plugindata->outsig = g_list_append( plugindata->outsig, (gpointer) i );
555 // Add 1 for NULL termination
556 inputdescr
= safe_malloc( sizeof( InputSignalDescriptor
) * (tmp_effect
->numInputs
+ 1) );
557 outputdescr
= safe_malloc( sizeof( OutputSignalDescriptor
) * (tmp_effect
->numOutputs
+ 1) );
558 controls
= safe_malloc( sizeof( ControlDescriptor
) * (tmp_effect
->numParams
+ 1) );
562 //printf( "Input Signals:\n" );
563 for( i
=0; i
<tmp_effect
->numInputs
; i
++ )
565 inputdescr
[i
].name
= g_strdup_printf( "input_%d", (int)i
);
566 inputdescr
[i
].flags
= SIG_FLAG_REALTIME
;
568 inputdescr
[i
].name
= NULL
;
570 //printf( "Output Signals:\n" );
571 for( i
=0; i
<tmp_effect
->numOutputs
; i
++ )
573 outputdescr
[i
].name
= g_strdup_printf( "output_%d", (int)i
);
574 outputdescr
[i
].flags
= SIG_FLAG_REALTIME
;
575 outputdescr
[i
].d
.realtime
= output_generators
[i
];
577 outputdescr
[i
].name
= NULL
;
579 for( i
=0; i
<tmp_effect
->numParams
; i
++ )
581 controls
[i
].kind
= CONTROL_KIND_KNOB
;
583 controls
[i
].name
= safe_malloc( 30 );
585 tmp_effect
->dispatcher( tmp_effect
, effGetParamName
, i
, 0, controls
[i
].name
, 0 );
587 controls
[i
].min
= 0.0;
589 controls
[i
].max
= 1.0;
591 controls
[i
].step
= 0.01;
592 controls
[i
].page
= 0.01;
594 controls
[i
].size
= 0;
595 controls
[i
].allow_direct_edit
= TRUE
;
596 controls
[i
].is_dst_gen
= TRUE
;
597 controls
[i
].queue_number
= i
;
600 controls
[i
].initialize
= NULL
;
601 controls
[i
].destroy
= NULL
;
602 controls
[i
].refresh
= control_VST_Data_updater
;
603 controls
[i
].refresh_data
= (void *)i
;
606 controls
[i
].kind
= CONTROL_KIND_NONE
;
608 //printf( "Menu : %s\n", get_lrdf_menuname( psDescriptor->UniqueID ) );
609 k
= gen_new_generatorclass_with_different_tag( basename
,
610 g_strdup_printf( "vst-%d", (int) tmp_effect
->uniqueID
), FALSE
,
611 tmp_effect
->numParams
, 0,
612 inputdescr
, outputdescr
, controls
,
613 init_instance
, destroy_instance
,
614 init_instance
, NULL
);
616 for( i
=0; i
<tmp_effect
->numParams
; i
++ ) {
618 gen_configure_event_input(k
, i
, controls
[i
].name
, evt_input_handler
);
621 //printf( "Output Events:\n" );
624 //printf( "inserting: %s %x\n", psDescriptor->Label, psDescriptor );
625 //XXX: Is it necessary to add both tags ? Should be handled by the generator resolution.
627 g_hash_table_insert(MainFuncIndex
, k
->tag
, main_func
);
630 generatorpath
= g_strdup_printf( "VST%2d/%s", (plugin_count
++) / 20, basename
);
634 gencomp_register_generatorclass(k
, FALSE
, generatorpath
,
635 PIXMAPDIRIFY(GENERATOR_CLASS_PIXMAP
),
638 free( generatorpath
);
640 //printf("Plugin Name: \"%s\"\n", psDescriptor->Name);
641 //printf("Plugin Label: \"%s\"\n", psDescriptor->Label);
642 //printf("Plugin Unique ID: %lu\n", psDescriptor->UniqueID);
643 //printf("Maker: \"%s\"\n", psDescriptor->Maker);
644 //printf("Copyright: \"%s\"\n", psDescriptor->Copyright);
651 PRIVATE
void setup_all( void ) {
653 //setup_one_class( "Z:/home/torbenh/xxx/vst/cesSynth1.dll" );
655 char *vst_path
= getenv( "GALAN_VST_DIR" );
658 GDir
*dir
= g_dir_open( vst_path
, 0, NULL
);
659 const char *filename
;
661 while( filename
= g_dir_read_name( dir
) ) {
663 if( strcmp(filename
+(strlen(filename
)-4), ".dll" ) )
666 winname
= g_strdup_printf( "Z:%s/%s", vst_path
,filename
);
668 printf( "loading plugin %s\n", winname
);
669 setup_one_class( winname
);
676 g_print( "GALAN_VST_DIR is no set !!!\n" );
681 PRIVATE
void setup_globals( void ) {
684 MainFuncIndex
= g_hash_table_new(g_str_hash
, g_str_equal
);
688 PUBLIC
void init_plugin(void) {
693 /*****************************************************************************/