13 #include "ardour/linux_vst_support.h"
14 #include "pbd/error.h"
16 /***********************************************************/
17 /* VSTFX - A set of modules for managing linux VST plugins */
18 /* vstfx.cc, vstfxwin.cc and vstfxinfofile.cc */
19 /***********************************************************/
21 /*Simple error handler stuff for VSTFX*/
23 void vstfx_error (const char *fmt, ...)
29 vsnprintf (buffer, sizeof(buffer), fmt, ap);
30 vstfx_error_callback (buffer);
34 /*default error handler callback*/
36 void default_vstfx_error_callback (const char *desc)
38 PBD::error << desc << endmsg;
41 void (*vstfx_error_callback)(const char *desc) = &default_vstfx_error_callback;
45 /*Create and return a pointer to a new VSTFX handle*/
50 VSTHandle* vstfx = (VSTHandle *) calloc (1, sizeof (VSTHandle));
54 /*Create and return a pointer to a new vstfx instance*/
59 VSTState* vstfx = (VSTState *) calloc (1, sizeof (VSTState));
63 pthread_mutex_init (&vstfx->lock, NULL);
64 pthread_cond_init (&vstfx->window_status_change, NULL);
65 pthread_cond_init (&vstfx->plugin_dispatcher_called, NULL);
66 pthread_cond_init (&vstfx->window_created, NULL);
70 vstfx->want_program = -1;
71 vstfx->want_chunk = 0;
72 vstfx->n_pending_keys = 0;
73 vstfx->has_editor = 0;
74 vstfx->program_set_without_editor = 0;
75 vstfx->linux_window = 0;
76 vstfx->linux_plugin_ui_window = 0;
77 vstfx->eventProc = NULL;
78 vstfx->extra_data = NULL;
79 vstfx->want_resize = 0;
84 /*This loads the plugin shared library*/
86 void* vstfx_load_vst_library(const char* path)
95 /*Try and load the shared library pointed to by the path -
96 NOTE: You have to give RTLD_LAZY or RTLD_NOW to dlopen or
97 you get some occasional failures to load - dlerror reports
100 if ((dll = dlopen (path, RTLD_LOCAL | RTLD_LAZY)) != NULL)
103 /*We didn't find the library so try and get the path specified in the
104 env variable LXVST_PATH*/
106 envdup = getenv ("LXVST_PATH");
108 /*Path not specified - not much more we can do*/
113 /*Copy the path into envdup*/
115 envdup = strdup (envdup);
122 /*Try all the possibilities in the path - deliminated by : */
124 lxvst_path = strtok (envdup, ":");
126 while (lxvst_path != NULL)
128 vstfx_error ("\"%s\"", lxvst_path);
129 len1 = strlen(lxvst_path);
131 full_path = (char*)malloc(len1 + 1 + len2 + 1);
132 memcpy(full_path, lxvst_path, len1);
133 full_path[len1] = '/';
134 memcpy(full_path + len1 + 1, path, len2);
135 full_path[len1 + 1 + len2] = '\0';
137 /*Try and load the library*/
139 if ((dll = dlopen(full_path, RTLD_LOCAL | RTLD_LAZY)) != NULL)
147 lxvst_path = strtok (NULL, ":");
157 /*This loads up a plugin, given the path to its .so file and
158 finds its main entry point etc*/
161 vstfx_load (const char *path)
167 /*Create a new handle we can use to reference the plugin*/
169 fhandle = vstfx_handle_new();
171 /*See if we have .so appended to the path - if not we need to make sure it is added*/
173 if (strstr (path, ".so") == NULL)
176 /*Append the .so to the path - Make sure the path has enough space*/
178 buf = (char *)malloc(strlen(path) + 4); //The .so and a terminating zero
180 sprintf (buf, "%s.so", path);
182 fhandle->nameptr = strdup (path);
187 /*We already have .so appened to the filename*/
191 fhandle->nameptr = strdup (path);
194 /*Use basename to shorten the path and then strip off the .so - the old VST problem,
195 we don't know anything about its name until we load and instantiate the plugin
196 which we don't want to do at this point*/
198 for(i=0; i < (int)strlen(fhandle->nameptr); i++)
200 if(fhandle->nameptr[i] == '.')
201 fhandle->nameptr[i] = 0;
205 fhandle->name = basename (fhandle->nameptr);
207 /*call load_vstfx_library to actually load the .so into memory*/
209 if ((fhandle->dll = vstfx_load_vst_library (buf)) == NULL)
211 vstfx_unload (fhandle);
218 /*Find the main entry point into the plugin*/
220 if ((fhandle->main_entry = (main_entry_t) dlsym(fhandle->dll, "main")) == NULL)
222 /*If it can't be found, unload the plugin and return a NULL handle*/
224 vstfx_unload (fhandle);
233 /*return the handle of the plugin*/
238 /*This unloads a plugin*/
241 vstfx_unload (VSTHandle* fhandle)
243 if (fhandle->plugincnt)
245 /*Still have plugin instances - can't unload the library
246 - actually dlclose keeps an instance count anyway*/
251 /*Valid plugin loaded?*/
255 dlclose(fhandle->dll);
259 if (fhandle->nameptr)
261 free (fhandle->nameptr);
262 fhandle->name = NULL;
265 /*Don't need the plugin handle any more*/
271 /*This instantiates a plugin*/
274 vstfx_instantiate (VSTHandle* fhandle, audioMasterCallback amc, void* userptr)
276 VSTState* vstfx = vstfx_new ();
280 vstfx_error( "** ERROR ** VSTFX : The handle was NULL\n" );
284 if ((vstfx->plugin = fhandle->main_entry (amc)) == NULL)
286 vstfx_error ("** ERROR ** VSTFX : %s could not be instantiated :(\n", fhandle->name);
291 vstfx->handle = fhandle;
292 vstfx->plugin->user = userptr;
294 if (vstfx->plugin->magic != kEffectMagic)
296 vstfx_error ("** ERROR ** VSTFX : %s is not a VST plugin\n", fhandle->name);
301 vstfx->plugin->dispatcher (vstfx->plugin, effOpen, 0, 0, 0, 0);
303 /*May or May not need to 'switch the plugin on' here - unlikely
304 since FST doesn't and most plugins start up 'On' by default - I think this is the least of our worries*/
306 //vstfx->plugin->dispatcher (vstfx->plugin, effMainsChanged, 0, 1, NULL, 0);
308 vstfx->vst_version = vstfx->plugin->dispatcher (vstfx->plugin, effGetVstVersion, 0, 0, 0, 0);
310 vstfx->handle->plugincnt++;
316 /*Close a vstfx instance*/
318 void vstfx_close (VSTState* vstfx)
320 vstfx_destroy_editor(vstfx);
324 vstfx->plugin->dispatcher (vstfx->plugin, effMainsChanged, 0, 0, NULL, 0);
326 /*Calling dispatcher with effClose will cause the plugin's destructor to
327 be called, which will also remove the editor if it exists*/
329 vstfx->plugin->dispatcher (vstfx->plugin, effClose, 0, 0, 0, 0);
332 if (vstfx->handle->plugincnt)
333 vstfx->handle->plugincnt--;
335 /*vstfx_unload will unload the dll if the instance count allows -
336 we need to do this because some plugins keep their own instance count
337 and (JUCE) manages the plugin UI in its own thread. When the plugins
338 internal instance count reaches zero, JUCE stops the UI thread and won't
339 restart it until the next time the library is loaded. If we don't unload
340 the lib JUCE will never restart*/
343 if (vstfx->handle->plugincnt)
348 /*Valid plugin loaded - so we can unload it and NULL the pointer
349 to it. We can't free the handle here because we don't know what else
350 might need it. It should be / is freed when the plugin is deleted*/
352 if (vstfx->handle->dll)
354 dlclose(vstfx->handle->dll); //dlclose keeps its own reference count
355 vstfx->handle->dll = NULL;
361 vstfx_save_state (VSTState* vstfx, char * filename)
363 FILE* f = fopen (filename, "wb");
367 int numParams = vstfx->plugin->numParams;
369 char productString[64];
371 char vendorString[64];
376 fprintf(f, "<plugin_state>\n");
378 success = vstfx_call_dispatcher(vstfx, effGetProductString, 0, 0, productString, 0);
382 fprintf (f, " <check field=\"productString\" value=\"%s\"/>\n", productString);
386 printf ("No product string\n");
389 success = vstfx_call_dispatcher(vstfx, effGetEffectName, 0, 0, effectName, 0);
393 fprintf (f, " <check field=\"effectName\" value=\"%s\"/>\n", effectName);
394 printf ("Effect name: %s\n", effectName);
398 printf ("No effect name\n");
401 success = vstfx_call_dispatcher(vstfx, effGetVendorString, 0, 0, vendorString, 0);
405 fprintf (f, " <check field=\"vendorString\" value=\"%s\"/>\n", vendorString);
406 printf ("Vendor string: %s\n", vendorString);
410 printf ("No vendor string\n");
414 if(vstfx->plugin->flags & 32 )
419 for(i=0; i < numParams; i++)
423 pthread_mutex_lock( &vstfx->lock );
424 val = vstfx->plugin->getParameter(vstfx->plugin, i );
425 pthread_mutex_unlock( &vstfx->lock );
426 fprintf( f, " <param index=\"%d\" value=\"%f\"/>\n", i, val );
429 if(vstfx->plugin->flags & 32 )
431 printf( "getting chunk...\n" );
433 bytelen = vstfx_call_dispatcher(vstfx, 23, 0, 0, &chunk, 0 );
434 printf( "got tha chunk..\n" );
439 printf( "Chunke len < 0 !!! Not saving chunk.\n" );
443 //char *encoded = g_base64_encode( chunk, bytelen );
444 //fprintf( f, " <chunk size=\"%d\">\n %s\n </chunk>\n", bytelen, encoded );
450 fprintf( f, "</plugin_state>\n" );
455 printf ("Could not open state file\n");
461 /*Set up a call to the plugins 'dispatcher' function*/
463 int vstfx_call_dispatcher (VSTState* vstfx, int opcode, int index, int val, void *ptr, float opt)
465 pthread_mutex_lock (&vstfx->lock);
467 /*Set up the opcode and parameters*/
469 vstfx->dispatcher_opcode = opcode;
470 vstfx->dispatcher_index = index;
471 vstfx->dispatcher_val = val;
472 vstfx->dispatcher_ptr = ptr;
473 vstfx->dispatcher_opt = opt;
475 /*Signal that we want the call to happen*/
477 vstfx->dispatcher_wantcall = 1;
479 /*Wait for the call to happen*/
481 pthread_cond_wait (&vstfx->plugin_dispatcher_called, &vstfx->lock);
482 pthread_mutex_unlock (&vstfx->lock);
484 /*Return the result*/
486 return vstfx->dispatcher_retval;