consolidate lxVST & winVST file-info code into libardour
authorRobin Gareus <robin@gareus.org>
Sun, 23 Feb 2014 04:51:58 +0000 (05:51 +0100)
committerRobin Gareus <robin@gareus.org>
Sun, 23 Feb 2014 04:51:58 +0000 (05:51 +0100)
first step and clennup before adding support for
VST shell-plugins (collections) and external scanner app...

12 files changed:
gtk2_ardour/wscript
libs/ardour/ardour/linux_vst_support.h
libs/ardour/ardour/vst_info_file.h [new file with mode: 0644]
libs/ardour/linux_vst_info_file.cc [deleted file]
libs/ardour/plugin_manager.cc
libs/ardour/vst_info_file.cc [new file with mode: 0644]
libs/ardour/wscript
libs/fst/fst.h
libs/fst/fstinfofile.c [deleted file]
libs/fst/jackvst.h [deleted file]
libs/fst/vsti.c [deleted file]
libs/fst/vstwin.c

index 621a763ea55b58705c9d3ccc59fcb3420af7c147..24349d928d38d10d3c3fff61daab103bb042a6d3 100644 (file)
@@ -363,8 +363,6 @@ def build(bld):
         obj = bld (features = 'cxx c cxxprogram wine')
         obj.source = (
             '../libs/fst/fst.c',
-            '../libs/fst/fstinfofile.c',
-            '../libs/fst/vsti.c',
             '../libs/fst/vstwin.c',
             '../vst/winmain.c',
             )
index cb18a0b1d40c3faf4d775bbb9610ef4fc39ee413..8575e2a72a6367c8953409ac9b4e0eca2c632344 100644 (file)
@@ -53,8 +53,6 @@ LIBARDOUR_API extern int          vstfx_create_editor (VSTState *);
 LIBARDOUR_API extern int          vstfx_run_editor (VSTState *);
 LIBARDOUR_API extern void         vstfx_destroy_editor (VSTState *);
 
-LIBARDOUR_API extern VSTInfo *    vstfx_get_info (char *);
-LIBARDOUR_API extern void         vstfx_free_info (VSTInfo *);
 LIBARDOUR_API extern void         vstfx_event_loop_remove_plugin (VSTState *);
 LIBARDOUR_API extern int          vstfx_call_dispatcher (VSTState *, int, int, int, void *, float);
 
@@ -66,5 +64,4 @@ LIBARDOUR_API extern int vstfx_load_state (VSTState* vstfx, char * filename);
 
 LIBARDOUR_API extern bool vstfx_save_state (VSTState* vstfx, char * filename);
 
-
 #endif /* __vstfx_h__ */
diff --git a/libs/ardour/ardour/vst_info_file.h b/libs/ardour/ardour/vst_info_file.h
new file mode 100644 (file)
index 0000000..2da203a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    Copyright (C) 2012-2014 Paul Davis
+    Author: Robin Gareus <robin@gareus.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __vst_info_file_h__
+#define __vst_info_file_h__
+
+#include "ardour/libardour_visibility.h"
+#include "ardour/vst_types.h"
+
+LIBARDOUR_API extern void         vstfx_free_info (VSTInfo *);
+
+#ifdef LXVST_SUPPORT
+LIBARDOUR_API extern VSTInfo *    vstfx_get_info_lx (char *);
+#endif
+
+#ifdef WINDOWS_VST_SUPPORT
+LIBARDOUR_API extern VSTInfo *    vstfx_get_info_fst (char *);
+#endif
+
+#endif /* __vstfx_h__ */
+
diff --git a/libs/ardour/linux_vst_info_file.cc b/libs/ardour/linux_vst_info_file.cc
deleted file mode 100644 (file)
index 581bcca..0000000
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
-    Copyright (C) 2012 Paul Davis 
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** @file libs/ardour/vst_info_file.cc
- *  @brief Code to manage info files containing cached information about a plugin.
- *  e.g. its name, creator etc.
- */
-
-#include <iostream>
-#include <cassert>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <libgen.h>
-
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <glibmm.h>
-
-#include "pbd/error.h"
-
-#include "ardour/linux_vst_support.h"
-
-#define MAX_STRING_LEN 256
-
-using namespace std;
-
-static char *
-read_string (FILE *fp)
-{
-       char buf[MAX_STRING_LEN];
-
-       if (!fgets (buf, MAX_STRING_LEN, fp)) {
-               return 0;
-       }
-       
-       if (strlen(buf) < MAX_STRING_LEN) {
-               if (strlen (buf)) {
-                       buf[strlen(buf)-1] = 0;
-               }
-               return strdup (buf);
-       } else {
-               return 0;
-       }
-}
-
-/** Read an integer value from a line in fp into n,
- *  @return true on failure, false on success.
- */
-static bool
-read_int (FILE* fp, int* n)
-{
-       char buf[MAX_STRING_LEN];
-
-       char* p = fgets (buf, MAX_STRING_LEN, fp);
-       if (p == 0) {
-               return true;
-       }
-
-       return (sscanf (p, "%d", n) != 1);
-}
-
-static VSTInfo *
-load_vstfx_info_file (FILE* fp)
-{
-       VSTInfo *info;
-       
-       if ((info = (VSTInfo*) malloc (sizeof (VSTInfo))) == 0) {
-               return 0;
-       }
-
-       if ((info->name = read_string(fp)) == 0) goto error;
-       if ((info->creator = read_string(fp)) == 0) goto error;
-       if (read_int (fp, &info->UniqueID)) goto error;
-       if ((info->Category = read_string(fp)) == 0) goto error;
-       if (read_int (fp, &info->numInputs)) goto error;
-       if (read_int (fp, &info->numOutputs)) goto error;
-       if (read_int (fp, &info->numParams)) goto error;
-       if (read_int (fp, &info->wantMidi)) goto error;
-       if (read_int (fp, &info->hasEditor)) goto error;
-       if (read_int (fp, &info->canProcessReplacing)) goto error;
-
-       if ((info->ParamNames = (char **) malloc(sizeof(char*)*info->numParams)) == 0) {
-               goto error;
-       }
-
-       for (int i = 0; i < info->numParams; ++i) {
-               if ((info->ParamNames[i] = read_string(fp)) == 0) goto error;
-       }
-
-       if ((info->ParamLabels = (char **) malloc(sizeof(char*)*info->numParams)) == 0) {
-               goto error;
-       }
-       
-       for (int i = 0; i < info->numParams; ++i) {
-               if ((info->ParamLabels[i] = read_string(fp)) == 0) goto error;
-       }
-       
-       return info;
-       
-  error:
-       free (info);
-       return 0;
-}
-
-static int
-save_vstfx_info_file (VSTInfo *info, FILE* fp)
-{
-       assert (info);
-       assert (fp);
-    
-       fprintf (fp, "%s\n", info->name);
-       fprintf (fp, "%s\n", info->creator);
-       fprintf (fp, "%d\n", info->UniqueID);
-       fprintf (fp, "%s\n", info->Category);
-       fprintf (fp, "%d\n", info->numInputs);
-       fprintf (fp, "%d\n", info->numOutputs);
-       fprintf (fp, "%d\n", info->numParams);
-       fprintf (fp, "%d\n", info->wantMidi);
-       fprintf (fp, "%d\n", info->hasEditor);
-       fprintf (fp, "%d\n", info->canProcessReplacing);
-
-       for (int i = 0; i < info->numParams; i++) {
-               fprintf (fp, "%s\n", info->ParamNames[i]);
-       }
-       
-       for (int i = 0; i < info->numParams; i++) {
-               fprintf (fp, "%s\n", info->ParamLabels[i]);
-       }
-       
-    return 0;
-}
-
-static string
-vstfx_infofile_path (char* dllpath, int personal)
-{
-       string dir;
-       if (personal) {
-               dir = Glib::build_filename (Glib::get_home_dir (), ".fst");
-
-               /* If the directory doesn't exist, try to create it */
-               if (!Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
-                       if (g_mkdir (dir.c_str (), 0700)) {
-                               return 0;
-                       }
-               }
-               
-       } else {
-               dir = Glib::path_get_dirname (std::string(dllpath));
-       }
-
-       stringstream s;
-       s << "." << Glib::path_get_basename (dllpath) << ".fsi";
-       return Glib::build_filename (dir, s.str ());
-}
-
-static char *
-vstfx_infofile_stat (char *dllpath, struct stat* statbuf, int personal)
-{
-       if (strstr (dllpath, ".so" ) == 0) {
-               return 0;
-       }
-
-       string const path = vstfx_infofile_path (dllpath, personal);
-
-       if (Glib::file_test (path, Glib::FileTest (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR))) {
-
-               /* info file exists in same location as the shared object, so
-                  check if its current and up to date
-               */
-
-
-               struct stat dllstat;
-               
-               if (stat (dllpath, &dllstat) == 0) {
-                       if (stat (path.c_str(), statbuf) == 0) {
-                               if (dllstat.st_mtime <= statbuf->st_mtime) {
-                                       /* plugin is older than info file */
-                                       return strdup (path.c_str ());
-                               }
-                       }
-               } 
-       }
-
-       return 0;
-}
-
-
-static FILE *
-vstfx_infofile_for_read (char* dllpath)
-{
-       struct stat own_statbuf;
-       struct stat sys_statbuf;
-       FILE *rv = NULL;
-       
-       char* own_info = vstfx_infofile_stat (dllpath, &own_statbuf, 1);
-       char* sys_info = vstfx_infofile_stat (dllpath, &sys_statbuf, 0);
-
-       if (own_info) {
-               if (sys_info) {
-                       if (own_statbuf.st_mtime <= sys_statbuf.st_mtime) {
-                               /* system info file is newer, use it */
-                               rv = g_fopen (sys_info, "rb");
-                       }
-               } else {
-                       rv = g_fopen (own_info, "rb");
-               }
-       }
-       free(own_info);
-       free(sys_info);
-
-       return rv;
-}
-
-static FILE *
-vstfx_infofile_create (char* dllpath, int personal)
-{
-       if (strstr (dllpath, ".so" ) == 0) {
-               return 0;
-       }
-
-       string const path = vstfx_infofile_path (dllpath, personal);
-       return fopen (path.c_str(), "w");
-}
-
-static FILE *
-vstfx_infofile_for_write (char* dllpath)
-{
-       FILE* f;
-
-       if ((f = vstfx_infofile_create (dllpath, 0)) == 0) {
-               f = vstfx_infofile_create (dllpath, 1);
-       }
-       
-       return f;
-}
-
-static
-int vstfx_can_midi (VSTState* vstfx)
-{
-       AEffect* plugin = vstfx->plugin;
-       
-       int const vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, 0, 0.0f);
-
-       if (vst_version >= 2) {
-               /* should we send it VST events (i.e. MIDI) */
-               
-               if ((plugin->flags & effFlagsIsSynth) || (plugin->dispatcher (plugin, effCanDo, 0, 0,(void*) "receiveVstEvents", 0.0f) > 0)) {
-                       return -1;
-               }
-       }
-       
-       return false;
-}
-
-static VSTInfo *
-vstfx_info_from_plugin (VSTState* vstfx)
-{
-       assert (vstfx);
-       
-       VSTInfo* info = (VSTInfo*) malloc (sizeof (VSTInfo));
-       if (!info) {
-               return 0;
-       }
-       
-       /*We need to init the creator because some plugins
-         fail to implement getVendorString, and so won't stuff the
-         string with any name*/
-       
-       char creator[65] = "Unknown\0";
-       
-       AEffect* plugin = vstfx->plugin;
-       
-       info->name = strdup (vstfx->handle->name); 
-       
-       /*If the plugin doesn't bother to implement GetVendorString we will
-         have pre-stuffed the string with 'Unkown' */
-       
-       plugin->dispatcher (plugin, effGetVendorString, 0, 0, creator, 0);
-       
-       /*Some plugins DO implement GetVendorString, but DON'T put a name in it
-         so if its just a zero length string we replace it with 'Unknown' */
-       
-       if (strlen(creator) == 0) {
-               info->creator = strdup ("Unknown");
-       } else {
-               info->creator = strdup (creator);
-       }
-       
-       info->UniqueID = plugin->uniqueID;
-       
-       info->Category = strdup("None"); /* XXX */
-       info->numInputs = plugin->numInputs;
-       info->numOutputs = plugin->numOutputs;
-       info->numParams = plugin->numParams;
-       info->wantMidi = vstfx_can_midi(vstfx); 
-       info->hasEditor = plugin->flags & effFlagsHasEditor ? true : false;
-       info->canProcessReplacing = plugin->flags & effFlagsCanReplacing ? true : false;
-       info->ParamNames = (char **) malloc(sizeof(char*)*info->numParams);
-       info->ParamLabels = (char **) malloc(sizeof(char*)*info->numParams);
-
-       for (int i = 0; i < info->numParams; ++i) {
-               char name[64];
-               char label[64];
-               
-               /* Not all plugins give parameters labels as well as names */
-               
-               strcpy (name, "No Name");
-               strcpy (label, "No Label");
-               
-               plugin->dispatcher (plugin, effGetParamName, i, 0, name, 0);
-               info->ParamNames[i] = strdup(name);
-               
-               //NOTE: 'effGetParamLabel' is no longer defined in vestige headers
-               //plugin->dispatcher (plugin, effGetParamLabel, i, 0, label, 0);
-               info->ParamLabels[i] = strdup(label);
-       }
-       return info;
-}
-
-/* A simple 'dummy' audiomaster callback which should be ok,
-   we will only be instantiating the plugin in order to get its info
-*/
-
-static intptr_t
-simple_master_callback (AEffect *, int32_t opcode, int32_t, intptr_t, void *, float)
-{
-       if (opcode == audioMasterVersion) {
-               return 2;
-       } else {
-               return 0;
-       }
-}
-
-/** Try to get plugin info - first by looking for a .fsi cache of the
-    data, and if that doesn't exist, load the plugin, get its data and
-    then cache it for future ref
-*/
-
-VSTInfo *
-vstfx_get_info (char* dllpath)
-{
-       FILE* infofile;
-       VSTHandle* h;
-       VSTState* vstfx;
-
-       if ((infofile = vstfx_infofile_for_read (dllpath)) != 0) {
-               VSTInfo *info;
-               info = load_vstfx_info_file (infofile);
-               fclose (infofile);
-               if (info == 0) {
-                       PBD::warning << "Cannot get LinuxVST information form " << dllpath << ": info file load failed." << endmsg;
-               }
-               return info;
-       } 
-       
-       if (!(h = vstfx_load(dllpath))) {
-               PBD::warning << "Cannot get LinuxVST information from " << dllpath << ": load failed." << endmsg;
-               return 0;
-       }
-       
-       if (!(vstfx = vstfx_instantiate(h, simple_master_callback, 0))) {
-               vstfx_unload(h);
-               PBD::warning << "Cannot get LinuxVST information from " << dllpath << ": instantiation failed." << endmsg;
-               return 0;
-       }
-       
-       infofile = vstfx_infofile_for_write (dllpath);
-       
-       if (!infofile) {
-               vstfx_close(vstfx);
-               vstfx_unload(h);
-               PBD::warning << "Cannot get LinuxVST information from " << dllpath << ": cannot create new FST info file." << endmsg;
-               return 0;
-       }
-       
-       VSTInfo* info = vstfx_info_from_plugin (vstfx);
-       
-       save_vstfx_info_file (info, infofile);
-       fclose (infofile);
-       
-       vstfx_close (vstfx);
-       vstfx_unload (h);
-       
-       return info;
-}
-
-void
-vstfx_free_info (VSTInfo *info)
-{
-       for (int i = 0; i < info->numParams; i++) {
-               free (info->ParamNames[i]);
-               free (info->ParamLabels[i]);
-       }
-       
-       free (info->name);
-       free (info->creator);
-       free (info->Category);
-       free (info->ParamNames);
-       free (info->ParamLabels);
-       free (info);
-}
-
-
index 6d68df688f4e152781c672cd1836cb4eb444d039..6e9aa4fc18eb89edc57ff03a273fa148f9219d36 100644 (file)
 #endif
 
 #ifdef WINDOWS_VST_SUPPORT
+#include "ardour/vst_info_file.h"
 #include "fst.h"
 #include "pbd/basename.h"
 #include <cstring>
 #endif // WINDOWS_VST_SUPPORT
 
 #ifdef LXVST_SUPPORT
+#include "ardour/vst_info_file.h"
 #include "ardour/linux_vst_support.h"
 #include "pbd/basename.h"
 #include <cstring>
@@ -558,7 +560,7 @@ PluginManager::windows_vst_discover (string path)
        VSTInfo* finfo;
        char buf[32];
 
-       if ((finfo = fst_get_info (const_cast<char *> (path.c_str()))) == 0) {
+       if ((finfo = vstfx_get_info_fst (const_cast<char *> (path.c_str()))) == 0) {
                warning << "Cannot get Windows VST information from " << path << endmsg;
                return -1;
        }
@@ -592,7 +594,7 @@ PluginManager::windows_vst_discover (string path)
        info->type = ARDOUR::Windows_VST;
 
        _windows_vst_plugin_info->push_back (info);
-       fst_free_info (finfo);
+       vstfx_free_info(finfo);
 
        return 0;
 }
@@ -672,7 +674,7 @@ PluginManager::lxvst_discover (string path)
 
        DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
 
-       if ((finfo = vstfx_get_info (const_cast<char *> (path.c_str()))) == 0) {
+       if ((finfo = vstfx_get_info_lx (const_cast<char *> (path.c_str()))) == 0) {
                return -1;
        }
 
diff --git a/libs/ardour/vst_info_file.cc b/libs/ardour/vst_info_file.cc
new file mode 100644 (file)
index 0000000..7d5aaf3
--- /dev/null
@@ -0,0 +1,492 @@
+/*
+    Copyright (C) 2012-2014 Paul Davis
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/** @file libs/ardour/vst_info_file.cc
+ *  @brief Code to manage info files containing cached information about a plugin.
+ *  e.g. its name, creator etc.
+ */
+
+#include <iostream>
+#include <cassert>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <libgen.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glibmm.h>
+
+#include "pbd/error.h"
+
+#include "ardour/linux_vst_support.h"
+#include "ardour/vst_info_file.h"
+
+#define MAX_STRING_LEN 256
+
+using namespace std;
+
+static char *
+read_string (FILE *fp)
+{
+       char buf[MAX_STRING_LEN];
+
+       if (!fgets (buf, MAX_STRING_LEN, fp)) {
+               return 0;
+       }
+
+       if (strlen(buf) < MAX_STRING_LEN) {
+               if (strlen (buf)) {
+                       buf[strlen(buf)-1] = 0;
+               }
+               return strdup (buf);
+       } else {
+               return 0;
+       }
+}
+
+/** Read an integer value from a line in fp into n,
+ *  @return true on failure, false on success.
+ */
+static bool
+read_int (FILE* fp, int* n)
+{
+       char buf[MAX_STRING_LEN];
+
+       char* p = fgets (buf, MAX_STRING_LEN, fp);
+       if (p == 0) {
+               return true;
+       }
+
+       return (sscanf (p, "%d", n) != 1);
+}
+
+static VSTInfo *
+load_vstfx_info_file (FILE* fp)
+{
+       VSTInfo *info;
+
+       if ((info = (VSTInfo*) malloc (sizeof (VSTInfo))) == 0) {
+               return 0;
+       }
+
+       if ((info->name = read_string(fp)) == 0) goto error;
+       if ((info->creator = read_string(fp)) == 0) goto error;
+       if (read_int (fp, &info->UniqueID)) goto error;
+       if ((info->Category = read_string(fp)) == 0) goto error;
+       if (read_int (fp, &info->numInputs)) goto error;
+       if (read_int (fp, &info->numOutputs)) goto error;
+       if (read_int (fp, &info->numParams)) goto error;
+       if (read_int (fp, &info->wantMidi)) goto error;
+       if (read_int (fp, &info->hasEditor)) goto error;
+       if (read_int (fp, &info->canProcessReplacing)) goto error;
+
+       if ((info->ParamNames = (char **) malloc(sizeof(char*)*info->numParams)) == 0) {
+               goto error;
+       }
+
+       for (int i = 0; i < info->numParams; ++i) {
+               if ((info->ParamNames[i] = read_string(fp)) == 0) goto error;
+       }
+
+       if ((info->ParamLabels = (char **) malloc(sizeof(char*)*info->numParams)) == 0) {
+               goto error;
+       }
+
+       for (int i = 0; i < info->numParams; ++i) {
+               if ((info->ParamLabels[i] = read_string(fp)) == 0) goto error;
+       }
+
+       return info;
+
+error:
+       free (info);
+       return 0;
+}
+
+static int
+save_vstfx_info_file (VSTInfo *info, FILE* fp)
+{
+       assert (info);
+       assert (fp);
+
+       fprintf (fp, "%s\n", info->name);
+       fprintf (fp, "%s\n", info->creator);
+       fprintf (fp, "%d\n", info->UniqueID);
+       fprintf (fp, "%s\n", info->Category);
+       fprintf (fp, "%d\n", info->numInputs);
+       fprintf (fp, "%d\n", info->numOutputs);
+       fprintf (fp, "%d\n", info->numParams);
+       fprintf (fp, "%d\n", info->wantMidi);
+       fprintf (fp, "%d\n", info->hasEditor);
+       fprintf (fp, "%d\n", info->canProcessReplacing);
+
+       for (int i = 0; i < info->numParams; i++) {
+               fprintf (fp, "%s\n", info->ParamNames[i]);
+       }
+
+       for (int i = 0; i < info->numParams; i++) {
+               fprintf (fp, "%s\n", info->ParamLabels[i]);
+       }
+
+       return 0;
+}
+
+static string
+vstfx_infofile_path (char* dllpath, int personal)
+{
+       string dir;
+       if (personal) {
+               dir = Glib::build_filename (Glib::get_home_dir (), ".fst");
+
+               /* If the directory doesn't exist, try to create it */
+               if (!Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
+                       if (g_mkdir (dir.c_str (), 0700)) {
+                               return 0;
+                       }
+               }
+
+       } else {
+               dir = Glib::path_get_dirname (std::string(dllpath));
+       }
+
+       stringstream s;
+       s << "." << Glib::path_get_basename (dllpath) << ".fsi";
+       return Glib::build_filename (dir, s.str ());
+}
+
+static char *
+vstfx_infofile_stat (char *dllpath, struct stat* statbuf, int personal)
+{
+       if (strstr (dllpath, ".so" ) == 0 && strstr(dllpath, ".dll") == 0) {
+               return 0;
+       }
+
+       string const path = vstfx_infofile_path (dllpath, personal);
+
+       if (Glib::file_test (path, Glib::FileTest (Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR))) {
+
+               /* info file exists in same location as the shared object, so
+                  check if its current and up to date
+               */
+
+
+               struct stat dllstat;
+
+               if (stat (dllpath, &dllstat) == 0) {
+                       if (stat (path.c_str(), statbuf) == 0) {
+                               if (dllstat.st_mtime <= statbuf->st_mtime) {
+                                       /* plugin is older than info file */
+                                       return strdup (path.c_str ());
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
+
+
+static FILE *
+vstfx_infofile_for_read (char* dllpath)
+{
+       struct stat own_statbuf;
+       struct stat sys_statbuf;
+       FILE *rv = NULL;
+
+       char* own_info = vstfx_infofile_stat (dllpath, &own_statbuf, 1);
+       char* sys_info = vstfx_infofile_stat (dllpath, &sys_statbuf, 0);
+
+       if (own_info) {
+               if (sys_info) {
+                       if (own_statbuf.st_mtime <= sys_statbuf.st_mtime) {
+                               /* system info file is newer, use it */
+                               rv = g_fopen (sys_info, "rb");
+                       }
+               } else {
+                       rv = g_fopen (own_info, "rb");
+               }
+       } else if (sys_info) {
+               rv = g_fopen (sys_info, "rb");
+       }
+       free(own_info);
+       free(sys_info);
+
+       return rv;
+}
+
+static FILE *
+vstfx_infofile_create (char* dllpath, int personal)
+{
+       if (strstr (dllpath, ".so" ) == 0 && strstr(dllpath, ".dll") == 0) {
+               return 0;
+       }
+
+       string const path = vstfx_infofile_path (dllpath, personal);
+       return fopen (path.c_str(), "w");
+}
+
+static FILE *
+vstfx_infofile_for_write (char* dllpath)
+{
+       FILE* f;
+
+       if ((f = vstfx_infofile_create (dllpath, 0)) == 0) {
+               f = vstfx_infofile_create (dllpath, 1);
+       }
+
+       return f;
+}
+
+static
+int vstfx_can_midi (VSTState* vstfx)
+{
+       AEffect* plugin = vstfx->plugin;
+
+       int const vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, 0, 0.0f);
+
+       if (vst_version >= 2) {
+               /* should we send it VST events (i.e. MIDI) */
+
+               if ((plugin->flags & effFlagsIsSynth) || (plugin->dispatcher (plugin, effCanDo, 0, 0,(void*) "receiveVstEvents", 0.0f) > 0)) {
+                       return -1;
+               }
+       }
+
+       return false;
+}
+
+static VSTInfo *
+vstfx_info_from_plugin (VSTState* vstfx)
+{
+       assert (vstfx);
+
+       VSTInfo* info = (VSTInfo*) malloc (sizeof (VSTInfo));
+       if (!info) {
+               return 0;
+       }
+
+       /*We need to init the creator because some plugins
+         fail to implement getVendorString, and so won't stuff the
+         string with any name*/
+
+       char creator[65] = "Unknown\0";
+
+       AEffect* plugin = vstfx->plugin;
+
+       info->name = strdup (vstfx->handle->name);
+
+       /*If the plugin doesn't bother to implement GetVendorString we will
+         have pre-stuffed the string with 'Unkown' */
+
+       plugin->dispatcher (plugin, effGetVendorString, 0, 0, creator, 0);
+
+       /*Some plugins DO implement GetVendorString, but DON'T put a name in it
+         so if its just a zero length string we replace it with 'Unknown' */
+
+       if (strlen(creator) == 0) {
+               info->creator = strdup ("Unknown");
+       } else {
+               info->creator = strdup (creator);
+       }
+
+       info->UniqueID = plugin->uniqueID;
+
+       info->Category = strdup("None"); /* XXX */
+       info->numInputs = plugin->numInputs;
+       info->numOutputs = plugin->numOutputs;
+       info->numParams = plugin->numParams;
+       info->wantMidi = vstfx_can_midi(vstfx);
+       info->hasEditor = plugin->flags & effFlagsHasEditor ? true : false;
+       info->canProcessReplacing = plugin->flags & effFlagsCanReplacing ? true : false;
+       info->ParamNames = (char **) malloc(sizeof(char*)*info->numParams);
+       info->ParamLabels = (char **) malloc(sizeof(char*)*info->numParams);
+
+       for (int i = 0; i < info->numParams; ++i) {
+               char name[64];
+               char label[64];
+
+               /* Not all plugins give parameters labels as well as names */
+
+               strcpy (name, "No Name");
+               strcpy (label, "No Label");
+
+               plugin->dispatcher (plugin, effGetParamName, i, 0, name, 0);
+               info->ParamNames[i] = strdup(name);
+
+               //NOTE: 'effGetParamLabel' is no longer defined in vestige headers
+               //plugin->dispatcher (plugin, effGetParamLabel, i, 0, label, 0);
+               info->ParamLabels[i] = strdup(label);
+       }
+       return info;
+}
+
+/* A simple 'dummy' audiomaster callback which should be ok,
+   we will only be instantiating the plugin in order to get its info
+*/
+
+static intptr_t
+simple_master_callback (AEffect *, int32_t opcode, int32_t, intptr_t, void *, float)
+{
+       if (opcode == audioMasterVersion) {
+               return 2;
+       } else {
+               return 0;
+       }
+}
+
+static VSTInfo *
+vstfx_get_info_from_file(char* dllpath, bool &found)
+{
+       FILE* infofile;
+       VSTInfo *info = 0;
+       found = false;
+       if ((infofile = vstfx_infofile_for_read (dllpath)) != 0) {
+               found = true;
+               info = load_vstfx_info_file (infofile);
+               fclose (infofile);
+               if (info == 0) {
+                       PBD::warning << "Cannot get LinuxVST information form " << dllpath << ": info file load failed." << endmsg;
+               }
+       }
+       return info;
+}
+
+void
+vstfx_free_info (VSTInfo *info)
+{
+       for (int i = 0; i < info->numParams; i++) {
+               free (info->ParamNames[i]);
+               free (info->ParamLabels[i]);
+       }
+
+       free (info->name);
+       free (info->creator);
+       free (info->Category);
+       free (info->ParamNames);
+       free (info->ParamLabels);
+       free (info);
+}
+
+#ifdef LXVST_SUPPORT
+/** Try to get plugin info - first by looking for a .fsi cache of the
+    data, and if that doesn't exist, load the plugin, get its data and
+    then cache it for future ref
+*/
+
+VSTInfo *
+vstfx_get_info_lx (char* dllpath)
+{
+       FILE* infofile;
+       VSTHandle* h;
+       VSTState* vstfx;
+
+       bool used_cache;
+       VSTInfo* info = vstfx_get_info_from_file(dllpath, used_cache);
+       if (used_cache) {
+               PBD::info << "using cache for LinuxVST plugin '" << dllpath << "'" << endmsg;
+               return info;
+       }
+
+       if (!(h = vstfx_load(dllpath))) {
+               PBD::warning << "Cannot get LinuxVST information from " << dllpath << ": load failed." << endmsg;
+               return 0;
+       }
+
+       if (!(vstfx = vstfx_instantiate(h, simple_master_callback, 0))) {
+               vstfx_unload(h);
+               PBD::warning << "Cannot get LinuxVST information from " << dllpath << ": instantiation failed." << endmsg;
+               return 0;
+       }
+
+       infofile = vstfx_infofile_for_write (dllpath);
+
+       if (!infofile) {
+               vstfx_close(vstfx);
+               vstfx_unload(h);
+               PBD::warning << "Cannot get LinuxVST information from " << dllpath << ": cannot create new FST info file." << endmsg;
+               return 0;
+       }
+
+       info = vstfx_info_from_plugin (vstfx);
+
+       save_vstfx_info_file (info, infofile);
+       fclose (infofile);
+
+       vstfx_close (vstfx);
+       vstfx_unload (h);
+
+       return info;
+}
+#endif
+
+#ifdef WINDOWS_VST_SUPPORT
+#include <fst.h>
+
+VSTInfo *
+vstfx_get_info_fst (char* dllpath)
+{
+       FILE* infofile;
+       VSTHandle* h;
+       VSTState* vstfx;
+
+       bool used_cache;
+       VSTInfo* info = vstfx_get_info_from_file(dllpath, used_cache);
+       if (used_cache) {
+               PBD::info << "using cache for VST plugin '" << dllpath << "'" << endmsg;
+               return info;
+       }
+
+       if(!(h = fst_load(dllpath))) {
+               PBD::warning << "Cannot get VST information from " << dllpath << ": load failed." << endmsg;
+               return 0;
+       }
+
+       if(!(vstfx = fst_instantiate(h, simple_master_callback, 0))) {
+               fst_unload(&h);
+               PBD::warning << "Cannot get VST information from " << dllpath << ": instantiation failed." << endmsg;
+               return 0;
+       }
+
+       infofile = vstfx_infofile_for_write (dllpath);
+
+       if (!infofile) {
+               fst_close(vstfx);
+               //fst_unload(&h); // XXX -> fst_close()
+               PBD::warning << "Cannot get VST information from " << dllpath << ": cannot create new FST info file." << endmsg;
+               return 0;
+       }
+
+       info = vstfx_info_from_plugin(vstfx);
+       save_vstfx_info_file (info, infofile);
+       fclose (infofile);
+
+       fst_close(vstfx);
+       //fst_unload(&h); // XXX -> fst_close()
+
+       return info;
+}
+#endif
index 56c864ca509cb97b01b3ded6c3f13b74797edad1..24a4590d08ef9db519c15885140692f53c0e39a3 100644 (file)
@@ -375,13 +375,15 @@ def build(bld):
         obj.source += [ 'windows_vst_plugin.cc']
         obj.includes += [ '../fst' ]
         obj.defines += [ 'WINDOWS_VST_SUPPORT' ]
+        if bld.env['build_target'] == 'mingw':
+            obj.source += [ '../fst/vstwin.c']
 
     if bld.is_defined('LXVST_SUPPORT'):
-        obj.source += [ 'lxvst_plugin.cc', 'linux_vst_support.cc', 'linux_vst_info_file.cc' ]
+        obj.source += [ 'lxvst_plugin.cc', 'linux_vst_support.cc' ]
         obj.defines += [ 'LXVST_SUPPORT' ]
 
     if bld.is_defined('WINDOWS_VST_SUPPORT') or bld.is_defined('LXVST_SUPPORT'):
-        obj.source += [ 'session_vst.cc', 'vst_plugin.cc' ]
+        obj.source += [ 'session_vst.cc', 'vst_plugin.cc', 'vst_info_file.cc' ]
 
     if bld.is_defined('HAVE_COREAUDIO'):
         obj.source += [ 'coreaudiosource.cc', 'caimportable.cc' ]
index 10ccda4d41d7a0bbd0e5360fea234095954d7487..ba7fb42c0f09782d582c5be632ead01671be0b6b 100644 (file)
@@ -45,8 +45,6 @@ extern int  fst_run_editor (VSTState *, void* window_parent);
 extern void fst_destroy_editor (VSTState *);
 extern void fst_move_window_into_view (VSTState *);
 
-extern VSTInfo *fst_get_info (char *dllpathname);
-extern void fst_free_info (VSTInfo *info);
 extern void fst_event_loop_remove_plugin (VSTState* fst);
 extern void fst_start_threading(void);
 extern void fst_stop_threading(void);
diff --git a/libs/fst/fstinfofile.c b/libs/fst/fstinfofile.c
deleted file mode 100644 (file)
index acfefbe..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-#include "fst.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-
-#define MAX_STRING_LEN 256
-
-#define FALSE 0
-#define TRUE !FALSE
-
-extern char * strdup (const char *);
-
-static char *read_string( FILE *fp ) {
-    char buf[MAX_STRING_LEN];
-
-    fgets( buf, MAX_STRING_LEN, fp );
-    if( strlen( buf ) < MAX_STRING_LEN ) {
-       
-       if( strlen(buf) )
-           buf[strlen(buf)-1] = 0;
-
-       return strdup( buf );
-    } else {
-       return NULL;
-    }
-}
-
-static VSTInfo *
-load_fst_info_file (char* filename)
-{
-       VSTInfo *info = (VSTInfo *) malloc (sizeof (VSTInfo));
-       FILE *fp;
-       int i;
-       
-       if (info == NULL) {
-               return NULL;
-       }
-
-       fp = fopen( filename, "r" );
-       
-       if (fp == NULL) {
-               free (info);
-               return NULL;
-       }
-
-    if( (info->name = read_string( fp )) == NULL ) goto error;
-    if( (info->creator = read_string( fp )) == NULL ) goto error;
-    if( 1 != fscanf( fp, "%d\n", &info->UniqueID ) ) goto error;
-    if( (info->Category = read_string( fp )) == NULL ) goto error;
-    if( 1 != fscanf( fp, "%d\n", &info->numInputs ) ) goto error;
-    if( 1 != fscanf( fp, "%d\n", &info->numOutputs ) ) goto error;
-    if( 1 != fscanf( fp, "%d\n", &info->numParams ) ) goto error;
-    if( 1 != fscanf( fp, "%d\n", &info->wantMidi ) ) goto error;
-    if( 1 != fscanf( fp, "%d\n", &info->hasEditor ) ) goto error;
-    if( 1 != fscanf( fp, "%d\n", &info->canProcessReplacing ) ) goto error;
-
-    if( (info->ParamNames = (char **) malloc( sizeof( char * ) * info->numParams )) == NULL ) goto error;
-    for( i=0; i<info->numParams; i++ ) {
-       if( (info->ParamNames[i] = read_string( fp )) == NULL ) goto error;
-    }
-    if( (info->ParamLabels = (char **) malloc( sizeof( char * ) * info->numParams )) == NULL ) goto error;
-    for( i=0; i<info->numParams; i++ ) {
-       if( (info->ParamLabels[i] = read_string( fp )) == NULL ) goto error;
-    }
-       
-
-    fclose( fp );
-    return info;
-
-error:
-    fclose( fp );
-    free( info );
-    return NULL;
-}
-
-static int
-save_fst_info_file (VSTInfo* info, char* filename)
-{
-    FILE *fp;
-    int i;
-
-
-    if( info == NULL ) {
-       fst_error( "info is NULL\n" );
-       return TRUE;
-    }
-
-    fp = fopen( filename, "w" );
-    
-    if( fp == NULL ) {
-       fst_error( "Cant write info file %s\n", filename );
-       return TRUE;
-    }
-
-    fprintf( fp, "%s\n", info->name );
-    fprintf( fp, "%s\n", info->creator );
-    fprintf( fp, "%d\n", info->UniqueID );
-    fprintf( fp, "%s\n", info->Category );
-    fprintf( fp, "%d\n", info->numInputs );
-    fprintf( fp, "%d\n", info->numOutputs );
-    fprintf( fp, "%d\n", info->numParams );
-    fprintf( fp, "%d\n", info->wantMidi );
-    fprintf( fp, "%d\n", info->hasEditor );
-    fprintf( fp, "%d\n", info->canProcessReplacing );
-
-    for( i=0; i<info->numParams; i++ ) {
-       fprintf( fp, "%s\n", info->ParamNames[i] );
-    }
-    for( i=0; i<info->numParams; i++ ) {
-       fprintf( fp, "%s\n", info->ParamLabels[i] );
-    }
-       
-
-    fclose( fp );
-
-    return FALSE;
-}
-
-static char *fst_dllpath_to_infopath( char *dllpath ) {
-    char *retval;
-    if( strstr( dllpath, ".dll" ) == NULL ) return NULL;
-    
-    retval = strdup( dllpath );
-    sprintf( retval + strlen(retval) - 4, ".fsi" );
-    return retval;
-}
-
-static int fst_info_file_is_valid( char *dllpath ) {
-    struct stat dllstat, fststat;
-    char *fstpath = fst_dllpath_to_infopath( dllpath );
-
-    if( !fstpath ) return FALSE;
-    
-    if( stat( dllpath, &dllstat ) ){ fst_error( "dll path %s invalid\n", dllpath );  return TRUE; }
-    if( stat( fstpath, &fststat ) ) return FALSE;
-
-    free( fstpath );
-    if( dllstat.st_mtime > fststat.st_mtime )
-       return FALSE;
-    else 
-       return TRUE;
-}
-
-static int
-fst_can_midi (VSTState* fst)
-{
-       AEffect* plugin = fst->plugin;
-       int vst_version = plugin->dispatcher (plugin, effGetVstVersion, 0, 0, NULL, 0.0f);
-
-       if (vst_version >= 2) {
-               
-                /* should we send it VST events (i.e. MIDI) */
-               
-               if ((plugin->flags & effFlagsIsSynth) ||
-                   (plugin->dispatcher (plugin, effCanDo, 0, 0,(void*) "receiveVstEvents", 0.0f) > 0))
-                   return TRUE;
-       }
-       return FALSE;
-
-}
-static VSTInfo *
-fst_info_from_plugin (VSTState* fst)
-{
-       VSTInfo* info = (VSTInfo *) malloc (sizeof (VSTInfo));
-       AEffect* plugin;
-       int i;
-       char creator[65];
-
-    if( ! fst ) {
-       fst_error( "fst is NULL\n" );
-       return NULL;
-    }
-
-    if( ! info ) return NULL;
-    
-    plugin = fst->plugin;
-    
-
-    info->name = strdup(fst->handle->name ); 
-    plugin->dispatcher (plugin, 47 /* effGetVendorString */, 0, 0, creator, 0);
-    if (strlen (creator) == 0) {
-      info->creator = strdup ("Unknown");
-    } else {
-      info->creator = strdup (creator);
-    }
-
-    info->UniqueID = *((int32_t *) &plugin->uniqueID);
-
-    info->Category = strdup( "None" );          // FIXME:  
-    info->numInputs = plugin->numInputs;
-    info->numOutputs = plugin->numOutputs;
-    info->numParams = plugin->numParams;
-    info->wantMidi = fst_can_midi( fst ); 
-    info->hasEditor = plugin->flags & effFlagsHasEditor ? TRUE : FALSE;
-    info->canProcessReplacing = plugin->flags & effFlagsCanReplacing ? TRUE : FALSE;
-
-    info->ParamNames = (char **) malloc( sizeof( char * ) * info->numParams );
-    info->ParamLabels = (char **) malloc( sizeof( char * ) * info->numParams );
-    for( i=0; i<info->numParams; i++ ) {
-       char name[20];
-       char label[9];
-       plugin->dispatcher (plugin,
-                           effGetParamName,
-                           i, 0, name, 0);
-       info->ParamNames[i] = strdup( name );
-       plugin->dispatcher (plugin,
-                           6 /* effGetParamLabel */,
-                           i, 0, label, 0);
-       info->ParamLabels[i] = strdup( label );
-    }
-    return info;
-}
-
-// most simple one :) could be sufficient.... 
-static intptr_t
-simple_master_callback (AEffect *fx, int32_t opcode, int32_t index, intptr_t value, void *ptr, float opt)
-{
-       if (opcode == audioMasterVersion) {
-               return 2;
-       } else {
-               return 0;
-       }
-}
-
-VSTInfo *
-fst_get_info (char* dllpath)
-{
-       if( fst_info_file_is_valid( dllpath ) ) {
-               VSTInfo *info;
-               char *fstpath = fst_dllpath_to_infopath( dllpath );
-               
-               info = load_fst_info_file( fstpath );
-               free( fstpath );
-               return info;
-
-    } else {
-
-       VSTHandle* h;
-       VSTState* fst;
-       VSTInfo* info;
-       char* fstpath;
-
-       if( !(h = fst_load( dllpath )) ) return NULL;
-       if( !(fst = fst_instantiate( h, simple_master_callback, NULL )) ) {
-           fst_unload( &h );
-           fst_error( "instantiate failed\n" );
-           return NULL;
-       }
-       fstpath = fst_dllpath_to_infopath( dllpath );
-       if( !fstpath ) {
-           fst_close( fst );
-           fst_unload( &h );
-           fst_error( "get fst filename failed\n" );
-           return NULL;
-       }
-       info = fst_info_from_plugin( fst );
-       save_fst_info_file( info, fstpath );
-
-       free( fstpath );
-       fst_close( fst );
-       fst_unload( &h );
-       return info;
-    }
-}
-
-void
-fst_free_info (VSTInfo *info)
-{
-    int i;
-
-    for( i=0; i<info->numParams; i++ ) {
-       free( info->ParamNames[i] );
-       free( info->ParamLabels[i] );
-    }
-    free( info->name );
-    free( info->creator );
-    free( info->Category );
-    free( info );
-}
-
-
diff --git a/libs/fst/jackvst.h b/libs/fst/jackvst.h
deleted file mode 100644 (file)
index 7b7e35f..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef __jack_vst_h__
-#define __jack_vst_h__
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <jack/jack.h>
-#include <jack/ringbuffer.h>
-#include <fst.h>
-#ifdef HAVE_ALSA
-#include <alsa/asoundlib.h>
-#endif
-
-typedef struct _JackVST JackVST;
-
-struct _JackVST {
-    jack_client_t *client;
-    VSTHandle *    handle;
-    VSTState *     fst;
-    float        **ins;
-    float        **outs;
-    jack_port_t  *midi_port;
-    jack_port_t  **inports;
-    jack_port_t  **outports;
-    void*          userdata;
-    int            bypassed;
-    int            muted;
-    int                   current_program;
-
-    /* For VST/i support */
-
-    int want_midi;
-    pthread_t          midi_thread;
-#ifdef HAVE_ALSA
-    snd_seq_t*         seq;
-#endif
-    int                midiquit;
-    jack_ringbuffer_t* event_queue;
-    struct VstEvents*  events;
-};
-
-#define MIDI_EVENT_MAX 1024
-
-#endif /* __jack_vst_h__ */
diff --git a/libs/fst/vsti.c b/libs/fst/vsti.c
deleted file mode 100644 (file)
index a1a9a8b..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- *   VST instrument support
- *
- *   Derived from code that was marked:
- *   Copyright (C) Kjetil S. Matheussen 2004 (k.s.matheussen@notam02.no)
- *   Alsa-seq midi-code made by looking at the jack-rack source made by Bob Ham.
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *   $Id: vsti.c,v 1.2 2004/04/07 01:56:23 pauld Exp $
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <memory.h>
-#include <fcntl.h>
-#include <stdbool.h>
-#include <jackvst.h>
-#include <pthread.h>
-#include <sched.h>
-#include "ardour/vestige/aeffectx.h"
-
-#ifdef HAVE_ALSAMIDIVSTIXXX // not used in ardour 3
-
-snd_seq_t *
-create_sequencer (const char* client_name, bool isinput)
-{
-       snd_seq_t * seq;
-       int err;
-
-       if ((err = snd_seq_open (&seq, "default", SND_SEQ_OPEN_DUPLEX, 0)) != 0) {
-               fst_error ("Could not open ALSA sequencer, aborting\n\n%s\n\n"
-                          "Make sure you have configure ALSA properly and that\n"
-                          "/proc/asound/seq/clients exists and contains relevant\n"
-                          "devices (%s).",
-                               snd_strerror (err));
-               return NULL;
-       }
-
-       snd_seq_set_client_name (seq, client_name);
-
-       if ((err = snd_seq_create_simple_port (seq, isinput? "Input" : "Output",
-                                       (isinput? SND_SEQ_PORT_CAP_WRITE: SND_SEQ_PORT_CAP_READ)| SND_SEQ_PORT_CAP_DUPLEX |
-                                       SND_SEQ_PORT_CAP_SUBS_READ|SND_SEQ_PORT_CAP_SUBS_WRITE,
-                                       SND_SEQ_PORT_TYPE_APPLICATION|SND_SEQ_PORT_TYPE_SPECIFIC)) != 0) {
-               fst_error ("Could not create ALSA port: %s", snd_strerror (err));
-               snd_seq_close(seq);
-               return NULL;
-       }
-
-       return seq;
-}
-
-static void
-queue_midi (JackVST *jvst, int val1, int val2, int val3)
-{
-       VstMidiEvent *pevent;
-       jack_ringbuffer_data_t vec[2];
-
-       jack_ringbuffer_get_write_vector (jvst->event_queue, vec);
-
-       if (vec[0].len < sizeof (VstMidiEvent)) {
-               fst_error ("event queue has no write space");
-               return;
-       }
-
-       pevent = (VstMidiEvent *) vec[0].buf;
-
-       //  printf("note: %d\n",note);
-
-       pevent->type = kVstMidiType;
-       pevent->byteSize = 24;
-       pevent->deltaFrames = 0;
-       pevent->flags = 0;
-       pevent->detune = 0;
-       pevent->noteLength = 0;
-       pevent->noteOffset = 0;
-       pevent->reserved1 = 0;
-       pevent->reserved2 = 0;
-       pevent->noteOffVelocity = 0;
-       pevent->midiData[0] = val1;
-       pevent->midiData[1] = val2;
-       pevent->midiData[2] = val3;
-       pevent->midiData[3] = 0;
-
-       //printf("Sending: %x %x %x\n",val1,val2,val3);
-
-       jack_ringbuffer_write_advance (jvst->event_queue, sizeof (VstMidiEvent));
-}
-
-void *midireceiver(void *arg)
-{
-       snd_seq_event_t *event;
-       JackVST *jvst = (JackVST* )arg;
-       int val;
-
-       struct sched_param scp;
-       scp.sched_priority = 50;
-
-       // Try to set fifo priority...
-       // this works, if we are root or newe sched-cap manegment is used...
-       pthread_setschedparam( pthread_self(), SCHED_FIFO, &scp );
-
-       while (1) {
-
-               snd_seq_event_input (jvst->seq, &event);
-
-               if (jvst->midiquit) {
-                       break;
-               }
-
-               switch(event->type){
-               case SND_SEQ_EVENT_NOTEON:
-                       queue_midi(jvst,0x90+event->data.note.channel,event->data.note.note,event->data.note.velocity);
-                       //printf("Noteon, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
-                       break;
-               case SND_SEQ_EVENT_NOTEOFF:
-                       queue_midi(jvst,0x80+event->data.note.channel,event->data.note.note,0);
-                       //printf("Noteoff, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
-                       break;
-               case SND_SEQ_EVENT_KEYPRESS:
-                       //printf("Keypress, channel: %d note: %d vol: %d\n",event->data.note.channel,event->data.note.note,event->data.note.velocity);
-                       queue_midi(jvst,0xa0+event->data.note.channel,event->data.note.note,event->data.note.velocity);
-                       break;
-               case SND_SEQ_EVENT_CONTROLLER:
-                       queue_midi(jvst,0xb0+event->data.control.channel,event->data.control.param,event->data.control.value);
-                       //printf("Control: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
-                       break;
-               case SND_SEQ_EVENT_PITCHBEND:
-                       val=event->data.control.value + 0x2000;
-                       queue_midi(jvst,0xe0+event->data.control.channel,val&127,val>>7);
-                       //printf("Pitch: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
-                       break;
-               case SND_SEQ_EVENT_CHANPRESS:
-                       //printf("chanpress: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
-                       queue_midi(jvst,0xd0+event->data.control.channel,event->data.control.value,0);
-                       break;
-               case SND_SEQ_EVENT_PGMCHANGE:
-                       //printf("pgmchange: %d %d %d\n",event->data.control.channel,event->data.control.param,event->data.control.value);
-                       queue_midi(jvst,0xc0+event->data.control.channel,event->data.control.value,0);
-                       break;
-               default:
-                       //printf("Unknown type: %d\n",event->type);
-                       break;
-               }
-       }
-
-       return NULL;
-}
-
-void stop_midireceiver (JackVST *jvst)
-{
-       int err;
-       snd_seq_event_t event;
-       snd_seq_t *seq2 = create_sequencer ("jfstquit", true);
-
-       jvst->midiquit = 1;
-
-       snd_seq_connect_to (seq2, 0, snd_seq_client_id (jvst->seq),0);
-       snd_seq_ev_clear      (&event);
-       snd_seq_ev_set_direct (&event);
-       snd_seq_ev_set_subs   (&event);
-       snd_seq_ev_set_source (&event, 0);
-       snd_seq_ev_set_controller (&event,1,0x80,50);
-
-       if ((err = snd_seq_event_output (seq2, &event)) < 0) {
-               fst_error ("cannot send stop event to midi thread: %s\n",
-                               snd_strerror (err));
-       }
-
-       snd_seq_drain_output (seq2);
-       snd_seq_close (seq2);
-       pthread_join (jvst->midi_thread,NULL);
-       snd_seq_close (jvst->seq);
-}
-#endif
-
-
index 58ce0fd235e0419cc1bf1566b12bd1c06d441d89..d37c5dffbbc58ebb5ad2ec85a06bd51a323c0210 100644 (file)
@@ -608,7 +608,7 @@ fst_close (VSTState* fst)
                        if (fst->handle->plugincnt && --fst->handle->plugincnt == 0) {
 
                                fst->handle->main_entry = NULL;
-                               fst_unload (&fst->handle);
+                               fst_unload (&fst->handle); // XXX
                        }
                }