fix crash when copy'ing latent plugins
[ardour.git] / libs / ardour / linux_vst_support.cc
1 /*
2     Copyright (C) 2012 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <pthread.h>
24 #include <signal.h>
25 #include <dlfcn.h>
26 #include <string.h>
27 #include <time.h>
28 #include <unistd.h>
29 #include <pthread.h>
30
31 #include <glib.h>
32 #include "pbd/gstdio_compat.h"
33 #include <glibmm/miscutils.h>
34 #include <glibmm/fileutils.h>
35
36 #include "ardour/linux_vst_support.h"
37 #include "pbd/basename.h"
38 #include "pbd/error.h"
39
40 #include "pbd/i18n.h"
41
42 /***********************************************************/
43 /* VSTFX - A set of modules for managing linux VST plugins */
44 /* vstfx.cc, vstfxwin.cc and vstfxinfofile.cc              */
45 /***********************************************************/
46
47 /*Simple error handler stuff for VSTFX*/
48
49 void vstfx_error (const char *fmt, ...)
50 {
51         va_list ap;
52         char buffer[512];
53
54         va_start (ap, fmt);
55         vsnprintf (buffer, sizeof(buffer), fmt, ap);
56         vstfx_error_callback (buffer);
57         va_end (ap);
58 }
59
60 /*default error handler callback*/
61
62 void default_vstfx_error_callback (const char *desc)
63 {
64         PBD::error << desc << endmsg;
65 }
66
67 void (*vstfx_error_callback)(const char *desc) = &default_vstfx_error_callback;
68
69 /* --- */
70
71 /*Create and return a pointer to a new VSTFX handle*/
72
73 VSTHandle *
74 vstfx_handle_new ()
75 {
76         VSTHandle* vstfx = (VSTHandle *) calloc (1, sizeof (VSTHandle));
77         return vstfx;
78 }
79
80 /*Create and return a pointer to a new vstfx instance*/
81
82 VSTState *
83 vstfx_new ()
84 {
85         VSTState* vstfx = (VSTState *) calloc (1, sizeof (VSTState));
86
87         /*Mutexes*/
88
89         pthread_mutex_init (&vstfx->lock, 0);
90         pthread_cond_init (&vstfx->window_status_change, 0);
91         pthread_cond_init (&vstfx->plugin_dispatcher_called, 0);
92         pthread_cond_init (&vstfx->window_created, 0);
93
94         /*Safe values*/
95
96         vstfx->want_program = -1;
97         vstfx->want_chunk = 0;
98         vstfx->n_pending_keys = 0;
99         vstfx->has_editor = 0;
100         vstfx->program_set_without_editor = 0;
101         vstfx->linux_window = 0;
102         vstfx->linux_plugin_ui_window = 0;
103         vstfx->eventProc = 0;
104         vstfx->extra_data = 0;
105         vstfx->want_resize = 0;
106
107         return vstfx;
108 }
109
110 /*This loads the plugin shared library*/
111
112 void* vstfx_load_vst_library(const char* path)
113 {
114         void* dll;
115         char* full_path = NULL;
116         char* envdup;
117         char* lxvst_path;
118         size_t len1;
119         size_t len2;
120
121         /*Try and load the shared library pointed to by the path -
122         NOTE: You have to give RTLD_LAZY or RTLD_NOW to dlopen or
123         you get some occasional failures to load - dlerror reports
124         invalid arguments*/
125
126         if ((dll = dlopen (path, RTLD_LOCAL | RTLD_LAZY)) != 0) {
127                 return dll;
128         }
129
130         if (Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
131                 PBD::error << string_compose (_("Could not open existing LXVST plugin: %1"), dlerror()) << endmsg;
132                 return 0;
133         }
134
135         /*We didn't find the library so try and get the path specified in the
136         env variable LXVST_PATH*/
137
138         envdup = getenv ("LXVST_PATH");
139
140         /*Path not specified - not much more we can do*/
141
142         if (envdup == 0)
143                 return 0;
144
145         /*Copy the path into envdup*/
146
147         envdup = strdup (envdup);
148
149         if (envdup == 0)
150                 return 0;
151
152         len2 = strlen(path);
153
154         /*Try all the possibilities in the path - deliminated by : */
155         char *saveptr;
156         lxvst_path = strtok_r (envdup, ":", &saveptr);
157
158         while (lxvst_path != 0)
159         {
160                 vstfx_error ("\"%s\"", lxvst_path);
161                 len1 = strlen(lxvst_path);
162
163                 if (full_path) free(full_path);
164                 full_path = (char*)malloc(len1 + 1 + len2 + 1);
165                 memcpy(full_path, lxvst_path, len1);
166                 full_path[len1] = '/';
167                 memcpy(full_path + len1 + 1, path, len2);
168                 full_path[len1 + 1 + len2] = '\0';
169
170                 /*Try and load the library*/
171
172                 if ((dll = dlopen(full_path, RTLD_LOCAL | RTLD_LAZY)) != 0)
173                 {
174                         /*Succeeded */
175                         break;
176                 }
177
178                 /*Try again*/
179
180                 lxvst_path = strtok_r (0, ":", &saveptr);
181         }
182
183         /*Free the path*/
184         if (full_path) free(full_path);
185         free(envdup);
186
187         return dll;
188 }
189
190 /*This loads up a plugin, given the path to its .so file and
191  finds its main entry point etc*/
192
193 VSTHandle *
194 vstfx_load (const char *path)
195 {
196         char* buf = 0;
197         VSTHandle* fhandle;
198
199         /*Create a new handle we can use to reference the plugin*/
200
201         fhandle = vstfx_handle_new();
202
203         /*See if we have .so appended to the path - if not we need to make sure it is added*/
204
205         if (strstr (path, ".so") == 0)
206         {
207
208                 /*Append the .so to the path - Make sure the path has enough space*/
209
210                 buf = (char *)malloc(strlen(path) + 4); //The .so and a terminating zero
211
212                 sprintf (buf, "%s.so", path);
213
214         }
215         else
216         {
217                 /*We already have .so appened to the filename*/
218
219                 buf = strdup(path);
220         }
221
222         /* get a name for the plugin based on the path: ye old VST problem where
223            we don't know anything about its name until we load and instantiate the plugin
224            which we don't want to do at this point
225         */
226
227         fhandle->name = strdup (PBD::basename_nosuffix (path).c_str());
228
229         /*call load_vstfx_library to actually load the .so into memory*/
230
231         if ((fhandle->dll = vstfx_load_vst_library (buf)) == 0)
232         {
233                 vstfx_unload (fhandle);
234
235                 free(buf);
236
237                 return 0;
238         }
239
240         /*Find the main entry point into the plugin*/
241
242         fhandle->main_entry = (main_entry_t) dlsym(fhandle->dll, "main");
243
244         if (fhandle->main_entry == 0) {
245                 if ((fhandle->main_entry = (main_entry_t) dlsym(fhandle->dll, "VSTPluginMain")) != 0) {
246                         PBD::warning << path << _(": is a VST >= 2.4 - this plugin may or may not function correctly with this version of Ardour.") << endmsg;
247                 }
248         }
249
250         if (fhandle->main_entry == 0)
251         {
252                 /*If it can't be found, unload the plugin and return a 0 handle*/
253
254                 vstfx_unload (fhandle);
255
256                 free(buf);
257
258                 return 0;
259         }
260
261         free(buf);
262
263         /*return the handle of the plugin*/
264
265         return fhandle;
266 }
267
268 /*This unloads a plugin*/
269
270 int
271 vstfx_unload (VSTHandle* fhandle)
272 {
273         if (fhandle->plugincnt)
274         {
275                 /*Still have plugin instances - can't unload the library
276                 - actually dlclose keeps an instance count anyway*/
277
278                 return -1;
279         }
280
281         /*Valid plugin loaded?*/
282
283         if (fhandle->dll)
284         {
285                 dlclose(fhandle->dll);
286                 fhandle->dll = 0;
287         }
288
289         if (fhandle->name)
290         {
291                 free (fhandle->name);
292         }
293
294         /*Don't need the plugin handle any more*/
295
296         free (fhandle);
297         return 0;
298 }
299
300 /*This instantiates a plugin*/
301
302 VSTState *
303 vstfx_instantiate (VSTHandle* fhandle, audioMasterCallback amc, void* userptr)
304 {
305         VSTState* vstfx = vstfx_new ();
306
307         if(fhandle == 0)
308         {
309                 vstfx_error( "** ERROR ** VSTFX : The handle was 0\n" );
310                 free (vstfx);
311                 return 0;
312         }
313
314         if ((vstfx->plugin = fhandle->main_entry (amc)) == 0)
315         {
316                 vstfx_error ("** ERROR ** VSTFX : %s could not be instantiated :(\n", fhandle->name);
317                 free (vstfx);
318                 return 0;
319         }
320
321         vstfx->handle = fhandle;
322         vstfx->plugin->user = userptr;
323
324         if (vstfx->plugin->magic != kEffectMagic)
325         {
326                 vstfx_error ("** ERROR ** VSTFX : %s is not a VST plugin\n", fhandle->name);
327                 free (vstfx);
328                 return 0;
329         }
330
331         vstfx->plugin->dispatcher (vstfx->plugin, effOpen, 0, 0, 0, 0);
332
333         /*May or May not need to 'switch the plugin on' here - unlikely
334         since FST doesn't and most plugins start up 'On' by default - I think this is the least of our worries*/
335
336         //vstfx->plugin->dispatcher (vstfx->plugin, effMainsChanged, 0, 1, 0, 0);
337
338         vstfx->vst_version = vstfx->plugin->dispatcher (vstfx->plugin, effGetVstVersion, 0, 0, 0, 0);
339
340         vstfx->handle->plugincnt++;
341         vstfx->wantIdle = 0;
342
343         return vstfx;
344 }
345
346 /*Close a vstfx instance*/
347
348 void vstfx_close (VSTState* vstfx)
349 {
350         vstfx_destroy_editor(vstfx);
351
352         if(vstfx->plugin)
353         {
354                 vstfx->plugin->dispatcher (vstfx->plugin, effMainsChanged, 0, 0, 0, 0);
355
356                 /*Calling dispatcher with effClose will cause the plugin's destructor to
357                 be called, which will also remove the editor if it exists*/
358
359                 vstfx->plugin->dispatcher (vstfx->plugin, effClose, 0, 0, 0, 0);
360         }
361
362         if (vstfx->handle->plugincnt)
363                         vstfx->handle->plugincnt--;
364
365         /*vstfx_unload will unload the dll if the instance count allows -
366         we need to do this because some plugins keep their own instance count
367         and (JUCE) manages the plugin UI in its own thread.  When the plugins
368         internal instance count reaches zero, JUCE stops the UI thread and won't
369         restart it until the next time the library is loaded.  If we don't unload
370         the lib JUCE will never restart*/
371
372
373         if (vstfx->handle->plugincnt)
374         {
375                 return;
376         }
377
378         /*Valid plugin loaded - so we can unload it and 0 the pointer
379         to it.  We can't free the handle here because we don't know what else
380         might need it.  It should be / is freed when the plugin is deleted*/
381
382         if (vstfx->handle->dll)
383         {
384                 dlclose(vstfx->handle->dll); //dlclose keeps its own reference count
385                 vstfx->handle->dll = 0;
386         }
387         free(vstfx);
388 }
389
390
391 bool
392 vstfx_save_state (VSTState* vstfx, char * filename)
393 {
394         FILE* f = g_fopen (filename, "wb");
395         if (f)
396         {
397                 int bytelen;
398                 int numParams = vstfx->plugin->numParams;
399                 int i;
400                 char productString[64];
401                 char effectName[64];
402                 char vendorString[64];
403                 int success;
404
405                 /* write header */
406
407                 fprintf(f, "<plugin_state>\n");
408
409                 success = vstfx_call_dispatcher(vstfx, effGetProductString, 0, 0, productString, 0);
410
411                 if(success == 1)
412                 {
413                         fprintf (f, "  <check field=\"productString\" value=\"%s\"/>\n", productString);
414                 }
415                 else
416                 {
417                         printf ("No product string\n");
418                 }
419
420                 success = vstfx_call_dispatcher(vstfx, effGetEffectName, 0, 0, effectName, 0);
421
422                 if(success == 1)
423                 {
424                         fprintf (f, "  <check field=\"effectName\" value=\"%s\"/>\n", effectName);
425                         printf ("Effect name: %s\n", effectName);
426                 }
427                 else
428                 {
429                         printf ("No effect name\n");
430                 }
431
432                 success = vstfx_call_dispatcher(vstfx, effGetVendorString, 0, 0, vendorString, 0);
433
434                 if( success == 1 )
435                 {
436                         fprintf (f, "  <check field=\"vendorString\" value=\"%s\"/>\n", vendorString);
437                         printf ("Vendor string: %s\n", vendorString);
438                 }
439                 else
440                 {
441                         printf ("No vendor string\n");
442                 }
443
444
445                 if(vstfx->plugin->flags & 32 )
446                 {
447                         numParams = 0;
448                 }
449
450                 for(i=0; i < numParams; i++)
451                 {
452                         float val;
453
454                         pthread_mutex_lock( &vstfx->lock );
455                         val = vstfx->plugin->getParameter(vstfx->plugin, i );
456                         pthread_mutex_unlock( &vstfx->lock );
457                         fprintf( f, "  <param index=\"%d\" value=\"%f\"/>\n", i, val );
458                 }
459
460                 if(vstfx->plugin->flags & 32 )
461                 {
462                         printf( "getting chunk...\n" );
463                         void * chunk;
464                         bytelen = vstfx_call_dispatcher(vstfx, 23, 0, 0, &chunk, 0 );
465                         printf( "got tha chunk..\n" );
466                         if( bytelen )
467                         {
468                                 if( bytelen < 0 )
469                                 {
470                                         printf( "Chunke len < 0 !!! Not saving chunk.\n" );
471                                 }
472                                 else
473                                 {
474                                         //char *encoded = g_base64_encode( chunk, bytelen );
475                                         //fprintf( f, "  <chunk size=\"%d\">\n    %s\n  </chunk>\n", bytelen, encoded );
476                                         //g_free( encoded );
477                                 }
478                         }
479                 }
480
481                 fprintf( f, "</plugin_state>\n" );
482                 fclose( f );
483         }
484         else
485         {
486                 printf ("Could not open state file\n");
487                 return false;
488         }
489         return true;
490 }
491
492 /*Set up a call to the plugins 'dispatcher' function*/
493
494 int vstfx_call_dispatcher (VSTState* vstfx, int opcode, int index, int val, void *ptr, float opt)
495 {
496         pthread_mutex_lock (&vstfx->lock);
497
498         /*Set up the opcode and parameters*/
499
500         vstfx->dispatcher_opcode = opcode;
501         vstfx->dispatcher_index = index;
502         vstfx->dispatcher_val = val;
503         vstfx->dispatcher_ptr = ptr;
504         vstfx->dispatcher_opt = opt;
505
506         /*Signal that we want the call to happen*/
507
508         vstfx->dispatcher_wantcall = 1;
509
510         /*Wait for the call to happen*/
511
512         pthread_cond_wait (&vstfx->plugin_dispatcher_called, &vstfx->lock);
513         pthread_mutex_unlock (&vstfx->lock);
514
515         /*Return the result*/
516
517         return vstfx->dispatcher_retval;
518 }