VST omnibus commit edition: use wine_pthread_create() everywhere instead of pthread_c...
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 24 Mar 2009 15:48:34 +0000 (15:48 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 24 Mar 2009 15:48:34 +0000 (15:48 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@4889 d708f5d6-7413-0410-9779-e7cbd77b26cf

21 files changed:
gtk2_ardour/editor_ops.cc
gtk2_ardour/plugin_ui.cc
gtk2_ardour/plugin_ui.h
gtk2_ardour/redirect_box.cc
gtk2_ardour/route_time_axis.cc
gtk2_ardour/vst_pluginui.cc
libs/ardour/audioengine.cc
libs/ardour/globals.cc
libs/ardour/insert.cc
libs/ardour/osc.cc
libs/ardour/plugin_manager.cc
libs/ardour/route.cc
libs/ardour/session_vst.cc
libs/ardour/vst_plugin.cc
libs/fst/fst.h
libs/fst/thread.c
libs/fst/vestige/aeffectx.h
libs/fst/vstwin.c
libs/pbd/SConscript
libs/pbd/pthread_utils.cc
vst/ardevst

index 2e546268da851c3a0b643e27cb0c179932a06add..fb331eafc5c74af0f8d509d20b02b2497155eb6f 100644 (file)
@@ -3666,7 +3666,7 @@ Editor::freeze_route ()
        pthread_attr_init(&attr);
        pthread_attr_setstacksize(&attr, 500000);
 
-       pthread_create (&itt.thread, &attr, _freeze_thread, this);
+       pthread_create_and_store (X_("freezer"), &itt.thread, &attr, _freeze_thread, this);
 
        pthread_attr_destroy(&attr);
 
index 9dc27154faca928184f381b3f89aadf99231e48d..874abea0d6c48dec8cbbb77c102507d394d628fb 100644 (file)
@@ -122,7 +122,7 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert
        add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
 
        signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window*> (this)), false);
-       insert->GoingAway.connect (mem_fun(*this, &PluginUIWindow::plugin_going_away));
+       death_connection = insert->GoingAway.connect (mem_fun(*this, &PluginUIWindow::plugin_going_away));
 
        gint h = _pluginui->get_preferred_height ();
        gint w = _pluginui->get_preferred_width ();
@@ -141,6 +141,7 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert
 
 PluginUIWindow::~PluginUIWindow ()
 {
+       delete _pluginui;
 }
 
 void
@@ -315,10 +316,13 @@ void
 PluginUIWindow::plugin_going_away ()
 {
        ENSURE_GUI_THREAD(mem_fun(*this, &PluginUIWindow::plugin_going_away));
-       
+
        if (_pluginui) {
                _pluginui->stop_updating(0);
        }
+       
+       death_connection.disconnect ();
+
        delete_when_idle (this);
 }
 
@@ -359,6 +363,10 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
        ARDOUR_UI::instance()->set_tip (&bypass_button, _("Click to enable/disable this plugin"), "");
 }
 
+PlugUIBase::~PlugUIBase ()
+{
+}
+
 void
 PlugUIBase::redirect_active_changed (Redirect* r, void* src)
 {
index 7bd7ffc91008080206b59def01a06f84f8860e82..4c14224a58a8b6d90f0b19b17629c567dc001353 100644 (file)
@@ -70,7 +70,7 @@ class PlugUIBase : public virtual sigc::trackable
 {
   public:
        PlugUIBase (boost::shared_ptr<ARDOUR::PluginInsert>);
-       virtual ~PlugUIBase() {}
+       virtual ~PlugUIBase();
 
        virtual gint get_preferred_height () = 0;
        virtual gint get_preferred_width () = 0;
@@ -231,6 +231,7 @@ class PluginUIWindow : public Gtk::Window
 
   private:
        PlugUIBase* _pluginui;
+       sigc::connection death_connection;
        Gtk::Window* parent;
        Gtk::VBox vbox;
        bool non_gtk_gui;
index 477a2240351a66d988af0389eb88bad44f306c1c..e743be2212b881b02aadd75c1d3b21718e9ca36c 100644 (file)
@@ -1153,7 +1153,7 @@ RedirectBox::edit_redirect (boost::shared_ptr<Redirect> redirect)
                                plugin_ui->set_title (title.get_string());
                                
                                plugin_insert->set_gui (plugin_ui);
-                               
+
                        } else {
                                plugin_ui = reinterpret_cast<PluginUIWindow *> (plugin_insert->get_gui());
                                plugin_ui->set_parent (win);
index c42448d31f4df870a36f17e67b1f7b4c4b3f902e..303a697bfd90b939cbf4f015ff2cf3491a87592b 100644 (file)
@@ -1461,7 +1461,6 @@ RouteTimeAxisView::use_playlist (boost::weak_ptr<Playlist> wpl)
 
                                Track *track = dynamic_cast<Track *>(*i);
                                if (!track) {
-                                       std::cerr << "route " << (*i)->name() << " is not a Track" << std::endl;
                                        continue;
                                }
 
@@ -1884,7 +1883,7 @@ RouteTimeAxisView::redirects_changed (void *src)
                ++tmp;
 
                if (!(*i)->valid) {
-
+                       
                        delete *i;
                        redirect_automation.erase (i);
 
index 2b6961c6a83f6b5d4324e011040c59cd666b1ee1..aed9fb73373bbd3079162e183db10c0ac0a8de25 100644 (file)
@@ -55,16 +55,15 @@ VSTPluginUI::VSTPluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<
 
 VSTPluginUI::~VSTPluginUI ()
 {
-       // nothing to do here - plugin destructor destroys the GUI
+       // plugin destructor destroys the custom GUI, via Windows fun-and-games,
+       // and then our PluginUIWindow does the rest
 }
 
 void
 VSTPluginUI::preset_chosen ()
 {
-       int program = vst_preset_combo.get_active_row_number ();
-       // cant be done here. plugin only expects one GUI thread.
-       //jvst->fst->plugin->dispatcher( jvst->fst->plugin, effSetProgram, 0, program, NULL, 0.0 );
-       vst->fst()->want_program = program;
+       // we can't dispatch directly here, too many plugins only expects one GUI thread.
+       vst->fst()->want_program = vst_preset_combo.get_active_row_number ();
        socket.grab_focus ();
 }
 
index cba634ccbf2cd01cc254f8142b4418848166692a..001a4d4568927cd2218cb628f6ee307dd0cfe325 100644 (file)
@@ -450,7 +450,7 @@ AudioEngine::set_session (Session *s)
                /* page in as much of the session process code as we
                   can before we really start running.
                */
-               
+
                session->process (blocksize);
                session->process (blocksize);
                session->process (blocksize);
index 9ae697fd3bb8f5692e598a1ac838cf802db25db9..65740d5a5d0ec8430901f6b3af3bff21eaeb1baa 100644 (file)
@@ -378,6 +378,9 @@ ARDOUR::cleanup ()
        delete Library;
        lrdf_cleanup ();
        delete &ControlProtocolManager::instance();
+#ifdef VST_SUPPORT
+       fst_exit ();
+#endif
        return 0;
 }
 
index be4de27b018a934ad96d600b8557ea4cc1cb383f..dee63944c06ee15178617e328325485a98fc7d6d 100644 (file)
@@ -281,6 +281,8 @@ PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, nframes_t
           be able to handle in-place processing.
        */
 
+       // cerr << "Connect and run for " << _plugins[0]->name() << " auto ? " << with_auto << endl;
+
        if (with_auto) {
 
                vector<AutomationList*>::iterator li;
@@ -293,11 +295,11 @@ PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, nframes_t
                        if (alist && alist->automation_playback()) {
                                bool valid;
 
-                               float val = alist->rt_safe_eval (now, valid);                           
+                               // float val = alist->rt_safe_eval (now, valid);                                
 
                                if (valid) {
                                        /* set the first plugin, the others will be set via signals */
-                                       _plugins[0]->set_parameter (n, val);
+                                       // _plugins[0]->set_parameter (n, val);
                                }
 
                        } 
@@ -309,6 +311,7 @@ PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, nframes_t
        }
 
        /* leave remaining channel buffers alone */
+       // cerr << "--- and out\n";
 }
 
 void
@@ -679,8 +682,7 @@ PluginInsert::set_state(const XMLNode& node)
                 */
                
                if (type == ARDOUR::VST) {
-                       if (prop = node.property ("id")) {
-                       }
+                       prop = node.property ("id");
                }
 #endif         
                /* recheck  */
index 384e77aa3d77e6599b2928a71e440050a91a1098..ab611d0ee79562182424a6b8e0c69e2955c43fa2 100644 (file)
@@ -241,7 +241,7 @@ OSC::init_osc_thread ()
        pthread_attr_init(&attr);
        pthread_attr_setstacksize(&attr, 500000);
 
-       pthread_create (&_osc_thread, &attr, &OSC::_osc_receiver, this);
+       pthread_create_and_store (X_("OSC"), &_osc_thread, &attr, &OSC::_osc_receiver, this);
        if (!_osc_thread) {
                return false;
        }
index 7a3caf44c43339f665634650d4e6c1aeb149fe62..a069dd17626ec1d9078a9f968beb37c953b55f7a 100644 (file)
@@ -309,7 +309,6 @@ PluginManager::ladspa_discover (string path)
        const LADSPA_Descriptor *descriptor;
        LADSPA_Descriptor_Function dfunc;
        const char *errstr;
-       bool first = true;
 
        if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
                error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg;
index 47b94432e4981b44c0f8f88d0c83164e27442653..91c3423388e569144f50e87746eb62f479bf2b60 100644 (file)
@@ -1152,8 +1152,8 @@ Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_
        }
 
        redirect->drop_references ();
-
        redirects_changed (src); /* EMIT SIGNAL */
+
        return 0;
 }
 
index 87930d993417b23c7544d09855fbae3375d15d23..b70b75a40302d6f1c394c5f8a01dce8a175e8f69 100644 (file)
 
 #include "i18n.h"
 
-#undef DEBUG_CALLBACKS
+#define DEBUG_CALLBACKS
+static int debug_callbacks = -1;
 
 #ifdef DEBUG_CALLBACKS
-#define SHOW_CALLBACK printf
+#define SHOW_CALLBACK if (debug_callbacks) printf
 #else
 #define SHOW_CALLBACK(...)
 #endif
@@ -50,15 +51,18 @@ long Session::vst_callback (AEffect* effect,
        VSTPlugin* plug;
        Session* session;
 
+       if (debug_callbacks < 0) {
+               debug_callbacks = (getenv ("ARDOUR_DEBUG_VST_CALLBACKS") != 0);
+       }
        
        if (effect && effect->user) {
                plug = (VSTPlugin*) (effect->user);
                session = &plug->session();
-               SHOW_CALLBACK ("am callback %d, opcode = %ld, plugin = \"%s\" ", pthread_self(), opcode, plug->name());
+               SHOW_CALLBACK ("am callback 0x%x, opcode = %ld, plugin = \"%s\" ", pthread_self(), opcode, plug->name());
        } else {
                plug = 0;
                session = 0;
-               SHOW_CALLBACK ("am callback %d, opcode = %ld", pthread_self(), opcode);
+               SHOW_CALLBACK ("am callback 0x%x, opcode = %ld", pthread_self(), opcode);
        }
 
        switch(opcode){
@@ -174,7 +178,10 @@ long Session::vst_callback (AEffect* effect,
 
        case audioMasterNeedIdle:
                SHOW_CALLBACK ("amc: audioMasterNeedIdle\n");
-              // plug needs idle calls (outside its editor window)
+               // plug needs idle calls (outside its editor window)
+               if (plug) {
+                       plug->fst()->wantIdle = 1;
+               }
                return 0;
 
        case audioMasterSizeWindow:
@@ -184,10 +191,16 @@ long Session::vst_callback (AEffect* effect,
 
        case audioMasterGetSampleRate:
                SHOW_CALLBACK ("amc: audioMasterGetSampleRate\n");
+               if (session) {
+                       return session->frame_rate();
+               }
                return 0;
 
        case audioMasterGetBlockSize:
                SHOW_CALLBACK ("amc: audioMasterGetBlockSize\n");
+               if (session) {
+                       return session->get_block_size();
+               }
                return 0;
 
        case audioMasterGetInputLatency:
index ec30087ee15df19e1a624a4536f0f27adaa9c87a..7fcb65e4454ceab3e5beac7a08359a6007873c38 100644 (file)
@@ -70,13 +70,16 @@ VSTPlugin::VSTPlugin (AudioEngine& e, Session& session, FSTHandle* h)
 
        /* set rate and blocksize */
 
+       //cerr << "Dispatch " <<  "effSetSampleRate" << " for " << name() << endl;
        _plugin->dispatcher (_plugin, effSetSampleRate, 0, 0, NULL, 
                             (float) session.frame_rate());
+       //cerr << "Dispatch " << "effSetBlockSize" << " for " << name() << endl;
        _plugin->dispatcher (_plugin, effSetBlockSize, 0, 
                             session.get_block_size(), NULL, 0.0f);
        
        /* set program to zero */
 
+       //cerr << "Dispatch " << "effSetProgram" << " for " << name() << endl;
        _plugin->dispatcher (_plugin, effSetProgram, 0, 0, NULL, 0.0f);
        
        Plugin::setup_controls ();
@@ -106,6 +109,7 @@ void
 VSTPlugin::set_block_size (nframes_t nframes)
 {
        deactivate ();
+       //cerr << "Dispatch effSetBlockSize for " << name() << endl;
        _plugin->dispatcher (_plugin, effSetBlockSize, 0, nframes, NULL, 0.0f);
        activate ();
 }
@@ -119,13 +123,17 @@ VSTPlugin::default_value (uint32_t port)
 void
 VSTPlugin::set_parameter (uint32_t which, float val)
 {
+       // cerr << "SetParameter for " << name() << endl;
        _plugin->setParameter (_plugin, which, val);
+       // cerr << "signal param change\n";
        ParameterChanged (which, val); /* EMIT SIGNAL */
+       // cerr << "change done\n";
 }
 
 float
 VSTPlugin::get_parameter (uint32_t which) const
 {
+       // cerr << "GetParameter for " << name() << endl;
        return _plugin->getParameter (_plugin, which);
        
 }
@@ -150,6 +158,7 @@ VSTPlugin::get_state()
                guchar* data;
                long  data_size;
                
+               //cerr << "Dispatch getChunk for " << name() << endl;
                if ((data_size = _plugin->dispatcher (_plugin, 23 /* effGetChunk */, 0, 0, &data, false)) == 0) {
                        return *root;
                }
@@ -202,6 +211,7 @@ VSTPlugin::set_state(const XMLNode& node)
                        if ((*n)->is_content ()) {
                                gsize chunk_size = 0;
                                guchar * data = g_base64_decode ((*n)->content ().c_str (), &chunk_size);
+                               //cerr << "Dispatch setChunk for " << name() << endl;
                                if (_plugin->dispatcher (_plugin, 24 /* effSetChunk */, 0, chunk_size, data, 0) == 0) {
                                        g_free (data);
                                        return 0;
@@ -224,6 +234,7 @@ VSTPlugin::set_state(const XMLNode& node)
                        sscanf ((*i)->name().c_str(), "param_%ld", &param);
                        sscanf ((*i)->value().c_str(), "%f", &val);
 
+                       // cerr << "setParameter for " << name() << endl;
                        _plugin->setParameter (_plugin, param, val);
                }
 
@@ -241,9 +252,9 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc)
        desc.min_unbound = false;
        desc.max_unbound = false;
 
+       //cerr << "Dispatch getParameterProperties for " << name() << endl;
        if (_plugin->dispatcher (_plugin, effGetParameterProperties, which, 0, &prop, 0)) {
 
-#ifdef VESTIGE_COMPLETE
                /* i have yet to find or hear of a VST plugin that uses this */
 
                if (prop.flags & kVstParameterUsesIntegerMinMax) {
@@ -279,7 +290,6 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc)
                desc.logarithmic = false;
                desc.sr_dependent = false;
                desc.label = prop.label;
-#endif
 
        } else {
 
@@ -288,6 +298,7 @@ VSTPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& desc)
                char label[64];
                label[0] = '\0';
 
+               // cerr << "Dispatch paramName for " << name() << endl;
                _plugin->dispatcher (_plugin, effGetParamName, which, 0, label, 0);
 
                desc.label = label;
@@ -333,6 +344,7 @@ string
 VSTPlugin::describe_parameter (uint32_t param)
 {
        char name[64];
+       // cerr << "Dispatch effGetParamName for " << this->name() << endl;
        _plugin->dispatcher (_plugin, effGetParamName, param, 0, name, 0);
        return name;
 }
@@ -390,6 +402,7 @@ VSTPlugin::connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in_
 
        /* we already know it can support processReplacing */
 
+       // cerr << "!ProcessReplacing for " << name() << endl;
        _plugin->processReplacing (_plugin, ins, outs, nframes);
 
        return 0;
@@ -398,12 +411,14 @@ VSTPlugin::connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in_
 void
 VSTPlugin::deactivate ()
 {
+       //cerr << "Dispatch effMainsChanged for " << name() << endl;
        _plugin->dispatcher (_plugin, effMainsChanged, 0, 0, NULL, 0.0f);
 }
 
 void
 VSTPlugin::activate ()
 {
+       //cerr << "Dispatch effMainsChanged for " << name() << endl;
        _plugin->dispatcher (_plugin, effMainsChanged, 0, 1, NULL, 0.0f);
 }
 
@@ -455,6 +470,7 @@ VSTPlugin::print_parameter (uint32_t param, char *buf, uint32_t len) const
 {
        char *first_nonws;
 
+       //cerr << "Dispatch getParamDisplay for " << name() << endl;
        _plugin->dispatcher (_plugin, 7 /* effGetParamDisplay */, param, 0, buf, 0);
 
        if (buf[0] == '\0') {
index 463d022640c76b464dd7032556c2ff73851374e3..7e2cfec08b8c729fd96954e2f6f07a099d0c7a98 100644 (file)
@@ -105,6 +105,7 @@ extern "C" {
 #endif
 
 extern int        fst_init (void* possible_hmodule);
+extern void       fst_exit ();
 
 extern FSTHandle* fst_load (const char*);
 extern int        fst_unload (FSTHandle*);
index 5be37b7a77d5b1c0dff50865d1181eb768bd57e7..22a278e614af260bed18fac22b5ff157bbccf31c 100644 (file)
@@ -15,6 +15,7 @@ typedef struct {
 static DWORD WINAPI
 fake_thread_proxy (LPVOID parameter) 
 {
+       DWORD retval;
        real_thread_info_t* rti = (real_thread_info_t*) parameter;
 
        pthread_mutex_lock (&rti->init_lock);
@@ -35,7 +36,10 @@ fake_thread_proxy (LPVOID parameter)
           uses a 1:1 thread design.
        */
 
-       return (DWORD) rti->thread_function (rti->thread_arg);
+       retval = (DWORD) rti->thread_function (rti->thread_arg);
+       free (rti);
+
+       return retval;
 }
 
 int
index 4389ce70ec6c1101698eb3a0369167390182cb03..dda128f45eeb4837d1467c299bc7fe7172f1a84f 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef _AEFFECTX_H
 #define _AEFFECTX_H
 
+#include <stdint.h>
 
 #define audioMasterAutomate 0
 #define audioMasterVersion 1
 #define kVstLangEnglish 1
 #define kVstMidiType 1
 #define kVstTransportPlaying (1 << 1)
-#define kVstParameterUsesFloatStep (1 << 2)
 
 /* validity flags for a VstTimeINfo structure this info comes from the web */
 
@@ -192,27 +192,49 @@ typedef struct VstEvents
        VstEvent * events[];
 } VstEvents;
 
+/* constants from http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=3740&sid=183f74631fee71a493316735e2b9f28b */
 
-
-
-// Not finished, neither really used
-typedef struct VstParameterProperties
+enum Vestige2StringConstants
 {
-       float stepFloat;
-       char label[64];
-       int flags;
-       int minInteger;
-       int maxInteger;
-       int stepInteger;
-       char shortLabel[8];
-       int category;
-       char categoryLabel[24];
-       char empty[128];
-
-} VstParameterProperties;
-
-
-
+       VestigeMaxNameLen       = 64,
+       VestigeMaxLabelLen      = 64,
+       VestigeMaxShortLabelLen = 8,
+       VestigeMaxCategLabelLen = 24,
+       VestigeMaxFileNameLen   = 100
+}; 
+
+/* this struct taken from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
+struct VstParameterProperties
+{
+    float stepFloat;              /* float step */
+    float smallStepFloat;         /* small float step */
+    float largeStepFloat;         /* large float step */
+    char label[VestigeMaxLabelLen];  /* parameter label */
+    int32_t flags;               /* @see VstParameterFlags */
+    int32_t minInteger;          /* integer minimum */
+    int32_t maxInteger;          /* integer maximum */
+    int32_t stepInteger;         /* integer step */
+    int32_t largeStepInteger;    /* large integer step */
+    char shortLabel[VestigeMaxShortLabelLen]; /* short label, recommended: 6 + delimiter */
+    int16_t displayIndex;        /* index where this parameter should be displayed (starting with 0) */
+    int16_t category;            /* 0: no category, else group index + 1 */
+    int16_t numParametersInCategory; /* number of parameters in category */
+    int16_t reserved;            /* zero */
+    char categoryLabel[VestigeMaxCategLabelLen]; /* category label, e.g. "Osc 1"  */
+    char future[16];              /* reserved for future use */
+};
+
+/* this enum taken from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
+enum VstParameterFlags
+{
+       kVstParameterIsSwitch                = 1 << 0,  /* parameter is a switch (on/off) */
+       kVstParameterUsesIntegerMinMax       = 1 << 1,  /* minInteger, maxInteger valid */
+       kVstParameterUsesFloatStep           = 1 << 2,  /* stepFloat, smallStepFloat, largeStepFloat valid */
+       kVstParameterUsesIntStep             = 1 << 3,  /* stepInteger, largeStepInteger valid */
+       kVstParameterSupportsDisplayIndex    = 1 << 4,  /* displayIndex valid */
+       kVstParameterSupportsDisplayCategory = 1 << 5,  /* category, etc. valid */
+       kVstParameterCanRamp                 = 1 << 6   /* set if parameter value can ramp up/down */
+};
 
 typedef struct AEffect
 {
index 72c578fe42393e4f02f98cf2dc2969bf611d63f8..151eedcbdb2569bf8556f75feb344f9b98ae320a 100644 (file)
@@ -26,11 +26,7 @@ static FST* fst_first = NULL;
 const char magic[] = "FST Plugin State v002";
 
 DWORD  gui_thread_id = 0;
-
-extern boolean g_quit;
-
-
-
+static int gui_quit = 0;
 
 #define DELAYED_WINDOW 1
 
@@ -38,12 +34,11 @@ extern boolean g_quit;
 static LRESULT WINAPI 
 my_window_proc (HWND w, UINT msg, WPARAM wp, LPARAM lp)
 {
-       FST* fst=NULL;
-       LRESULT result;
-
-//     if (msg != WM_TIMER) {
-//             fst_error ("window callback handler, msg = 0x%x win=%p\n", msg, w);
-//     }
+#if 0
+       if (msg != WM_TIMER) {
+               fst_error ("window callback handler, msg = 0x%x win=%p\n", msg, w);
+       }
+#endif
 
        switch (msg) {
        case WM_KEYUP:
@@ -51,47 +46,21 @@ my_window_proc (HWND w, UINT msg, WPARAM wp, LPARAM lp)
                break;
 
        case WM_CLOSE:
-               //printf("wtf.\n" );
-               PostQuitMessage (0);
-       case WM_DESTROY:
-       case WM_NCDESTROY:
-               /* we should never get these */
-               //return 0;
-               break;
-#if 0
-       case WM_PAINT:
-                       if ((fst = GetPropA (w, "fst_ptr")) != NULL) {
-                               if (fst->window && !fst->been_activated) {
-                                       fst->been_activated = TRUE;
-                                       pthread_cond_signal (&fst->window_status_change);
-                                       pthread_mutex_unlock (&fst->lock);
-                               }
-                       }
+               /* we don't care about windows closing ... */
+               return 0;
                break;
-#endif
-
-#if 0  
-       case WM_TIMER:
-               fst = GetPropA( w, "fst_ptr" );
-               if( !fst ) {
-                   printf( "Timer without fst_ptr Prop :(\n" );
-                   return 0;
-               }
 
-               fst->plugin->dispatcher(fst->plugin, effEditIdle, 0, 0, NULL, 0.0f);
-               if( fst->wantIdle )
-                   fst->plugin->dispatcher(fst->plugin, 53, 0, 0, NULL, 0.0f);
+       case WM_DESTROY:
+       case WM_NCDESTROY:
+               /* we don't care about windows being destroyed ... */
                return 0;
-#endif
-
-
+               break;
 
        default:
                break;
        }
 
        return DefWindowProcA (w, msg, wp, lp );
-       //return 0;
 }
 
 static FST* 
@@ -116,7 +85,6 @@ DWORD WINAPI gui_event_loop (LPVOID param)
 {
        MSG msg;
        FST* fst;
-       char c;
        HMODULE hInst;
        HWND window;
 
@@ -143,74 +111,88 @@ DWORD WINAPI gui_event_loop (LPVOID param)
                fst_error ("cannot set timer on dummy window");
        }
 
-       while (GetMessageA (&msg, NULL, 0,0)) {
+       while (!gui_quit) {
+
+               if (!GetMessageA (&msg, NULL, 0,0)) {
+                       if (!gui_quit) {
+                               fprintf (stderr, "QUIT message received by Windows GUI thread - ignored\n");
+                               continue;
+                       } else {
+                               break;
+                       }
+               }
+
                TranslateMessage( &msg );
                DispatchMessageA (&msg);
 
                /* handle window creation requests, destroy requests, 
                   and run idle callbacks 
                */
-               
-               if( msg.message == WM_TIMER  ) {
-                   pthread_mutex_lock (&plugin_mutex);
-again:
-                   for (fst = fst_first; fst; fst = fst->next) {
-
-                       if (fst->destroy) {
-                           if (fst->window) {
-                               fst->plugin->dispatcher( fst->plugin, effEditClose, 0, 0, NULL, 0.0 );
-                               CloseWindow (fst->window);
-                               fst->window = NULL;
-                               fst->destroy = FALSE;
-                           }
-                           fst_event_loop_remove_plugin (fst);
-                           fst->been_activated = FALSE;
-                           pthread_mutex_lock (&fst->lock);
-                           pthread_cond_signal (&fst->window_status_change);
-                           pthread_mutex_unlock (&fst->lock);
-                           goto again;
-                       } 
-
-                       if (fst->window == NULL) {
-                           pthread_mutex_lock (&fst->lock);
-                           fst_error ("Creating window for FST plugin %s", fst->handle->name);
-                           if (fst_create_editor (fst)) {
-                               fst_error ("cannot create editor for plugin %s", fst->handle->name);
-                               fst_event_loop_remove_plugin (fst);
-                               pthread_cond_signal (&fst->window_status_change);
-                               pthread_mutex_unlock (&fst->lock);
-                               goto again;
-                           }
-                           /* condition/unlock: it was signalled & unlocked in fst_create_editor()   */
-                       }
-                       if(fst->want_program != -1 ) {
-                               fst->plugin->dispatcher (fst->plugin, effSetProgram, 0, fst->want_program, NULL, 0);
-                               fst->want_program = -1; 
-                       }
-                       
-                       if(fst->dispatcher_wantcall) {
 
+               if (msg.message == WM_TIMER) {
+                       pthread_mutex_lock (&plugin_mutex);
+                   
+again:
+                       for (fst = fst_first; fst; fst = fst->next) {
+                               
                                pthread_mutex_lock (&fst->lock);
-                               fst->dispatcher_retval = fst->plugin->dispatcher( fst->plugin, fst->dispatcher_opcode,
-                                                                                 fst->dispatcher_index,
-                                                                                 fst->dispatcher_val,
-                                                                                 fst->dispatcher_ptr,
-                                                                                 fst->dispatcher_opt );
-                               fst->dispatcher_wantcall = 0;
-                               pthread_cond_signal (&fst->plugin_dispatcher_called);
-                               pthread_mutex_unlock (&fst->lock);
-                       }
 
-                       pthread_mutex_lock (&fst->lock);
-                       fst->plugin->dispatcher (fst->plugin, effEditIdle, 0, 0, NULL, 0);
-                       if( fst->wantIdle ) {
-                               fst->plugin->dispatcher (fst->plugin, 53, 0, 0, NULL, 0);
+                               if (fst->destroy) {
+                                       fprintf (stderr, "%s scheduled for destroy\n", fst->handle->name);
+                                       if (fst->window) {
+                                               fst->plugin->dispatcher( fst->plugin, effEditClose, 0, 0, NULL, 0.0 );
+                                               CloseWindow (fst->window);
+                                               fst->window = NULL;
+                                               fst->destroy = FALSE;
+                                       }
+                                       fst_event_loop_remove_plugin (fst);
+                                       fst->been_activated = FALSE;
+                                       pthread_cond_signal (&fst->window_status_change);
+                                       pthread_mutex_unlock (&fst->lock);
+                                       goto again;
+                               } 
+                               
+                               if (fst->window == NULL) {
+                                       if (fst_create_editor (fst)) {
+                                               fst_error ("cannot create editor for plugin %s", fst->handle->name);
+                                               fst_event_loop_remove_plugin (fst);
+                                               pthread_cond_signal (&fst->window_status_change);
+                                               pthread_mutex_unlock (&fst->lock);
+                                               goto again;
+                                       } else {
+                                               /* condition/unlock: it was signalled & unlocked in fst_create_editor()   */
+                                       }
+                               }
+
+                               if (fst->want_program != -1 ) {
+                                       fst->plugin->dispatcher (fst->plugin, effSetProgram, 0, fst->want_program, NULL, 0);
+                                       fst->want_program = -1; 
+                               }
+                               
+                               if(fst->dispatcher_wantcall) {
+                                       fst->dispatcher_retval = fst->plugin->dispatcher( fst->plugin, 
+                                                                                         fst->dispatcher_opcode,
+                                                                                         fst->dispatcher_index,
+                                                                                         fst->dispatcher_val,
+                                                                                         fst->dispatcher_ptr,
+                                                                                         fst->dispatcher_opt );
+                                       fst->dispatcher_wantcall = 0;
+                                       pthread_cond_signal (&fst->plugin_dispatcher_called);
+                               }
+                               
+                               fst->plugin->dispatcher (fst->plugin, effEditIdle, 0, 0, NULL, 0);
+
+                               if( fst->wantIdle ) {
+                                       fst->plugin->dispatcher (fst->plugin, 53, 0, 0, NULL, 0);
+                               }
+
+                               pthread_mutex_unlock (&fst->lock);
                        }
-                       pthread_mutex_unlock (&fst->lock);
-                   }
-                   pthread_mutex_unlock (&plugin_mutex);
+                       pthread_mutex_unlock (&plugin_mutex);
+                       
                }
        }
+
        return 0;
 }
 
@@ -221,37 +203,25 @@ fst_init (void* possible_hmodule)
        HMODULE hInst;
        
        if (possible_hmodule) {
-         hInst = (HMODULE) possible_hmodule;
+               hInst = (HMODULE) possible_hmodule;
        } else if ((hInst = GetModuleHandleA (NULL)) == NULL) {
-         fst_error ("can't get module handle");
-         return -1;
-       }
-    wclass.cbSize = sizeof(WNDCLASSEX);
-    wclass.style = 0;
-    wclass.lpfnWndProc = my_window_proc;
-    wclass.cbClsExtra = 0;
-    wclass.cbWndExtra = 0;
-    wclass.hInstance = hInst;
-    wclass.hIcon = LoadIcon(hInst, "FST");
-    wclass.hCursor = LoadCursor(0, IDI_APPLICATION);
+               fst_error ("can't get module handle");
+               return -1;
+       }
+
+       wclass.cbSize = sizeof(WNDCLASSEX);
+       wclass.style = 0;
+       wclass.lpfnWndProc = my_window_proc;
+       wclass.cbClsExtra = 0;
+       wclass.cbWndExtra = 0;
+       wclass.hInstance = hInst;
+       wclass.hIcon = LoadIcon(hInst, "FST");
+       wclass.hCursor = LoadCursor(0, IDI_APPLICATION);
 //    wclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
-    wclass.lpszMenuName = "MENU_FST";
-    wclass.lpszClassName = "FST";
-    wclass.hIconSm = 0;
+       wclass.lpszMenuName = "MENU_FST";
+       wclass.lpszClassName = "FST";
+       wclass.hIconSm = 0;
 
-#if 0
-       wc.style = 0;
-       wc.lpfnWndProc = my_window_proc;
-       wc.cbClsExtra = 0;
-       wc.cbWndExtra = 0;
-       wc.hInstance = hInst;
-       wc.hIcon = LoadIconA( hInst, "FST");
-       wc.hCursor = LoadCursorA( NULL, IDI_APPLICATION );
-       wc.hbrBackground = GetStockObject( BLACK_BRUSH );
-       wc.lpszMenuName = "FSTMENU";
-       wc.lpszClassName = "FST";
-       //wc.hIconSm = 0;
-#endif
 
        if (!RegisterClassExA(&wclass)){
                printf( "Class register failed :(\n" );
@@ -272,6 +242,13 @@ fst_init (void* possible_hmodule)
        return 0;
 }
 
+void
+fst_exit ()
+{
+       gui_quit = 1;
+       PostQuitMessage (0);
+}
+
 int
 fst_run_editor (FST* fst)
 {
@@ -325,7 +302,6 @@ int
 fst_create_editor (FST* fst)
 {
        HMODULE hInst;
-       char class[20];
        HWND window;
        struct ERect* er;
 
@@ -397,17 +373,16 @@ fst_move_window_into_view (FST* fst)
 void
 fst_destroy_editor (FST* fst)
 {
-       FST* p;
-       FST* prev;
-
        pthread_mutex_lock (&fst->lock);
        if (fst->window) {
+               fprintf (stderr, "mark %s for destroy\n", fst->handle->name);
                fst->destroy = TRUE;
                //if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) {
                //if (!PostThreadMessageA (gui_thread_id, WM_QUIT, 0, 0)) {
                //      fst_error ("could not post message to gui thread");
                //}
                pthread_cond_wait (&fst->window_status_change, &fst->lock);
+               fprintf (stderr, "%s editor destroyed\n", fst->handle->name);
 
        }
        pthread_mutex_unlock (&fst->lock);
@@ -485,7 +460,7 @@ fst_load_vst_library(const char * path)
 FSTHandle*
 fst_load (const char *path)
 {
-       char* buf, *buf2;
+       char* buf;
        FSTHandle* fhandle;
        char* period;
 
@@ -746,7 +721,6 @@ int fst_save_state (FST * fst, char * filename)
                char effectName[64];
                char vendorString[64];
                int success;
-               unsigned length;
 
                // write header
                fprintf( f, "<plugin_state>\n" );
index f51ddd5a3636a063fc2d9237be2f46ee0eaa85c9..96d1a772b5f2017165cad732e296545f5f4e263b 100644 (file)
@@ -60,6 +60,10 @@ pbd.Merge ([ libraries['sigc2'],
              libraries['glibmm2'],
              libraries['glib2'] ])
 
+
+if pbd['VST']:
+    pbd.Append(CCFLAGS="-DWINE_THREAD_SUPPORT", CPPPATH="#libs/fst")
+
 pbd.VersionBuild(['version.cc','pbd/version.h'], [])
 
 libpbd = pbd.SharedLibrary('pbd', pbd_files)
index c63f988af32ceca1556ebae8a8e3f31d07974303..2c43282451828bd47c8f4ed0382cd5c6fb5e6749 100644 (file)
@@ -24,6 +24,9 @@
 #include <stdint.h>
 
 #include <pbd/pthread_utils.h>
+#ifdef WINE_THREAD_SUPPORT
+#include <fst.h>
+#endif
 
 using namespace std;
 
@@ -39,6 +42,15 @@ namespace PBD {
 
 using namespace PBD;
 
+static int thread_creator (pthread_t* thread_id, const pthread_attr_t* attr, void *(*function)(void*), void* arg) 
+{
+#ifdef WINE_THREAD_SUPPORT
+       return wine_pthread_create (thread_id, attr, function, arg);
+#else  
+       return pthread_create (thread_id, attr, function, arg);
+#endif
+}
+
 void
 PBD::notify_gui_about_thread_creation (pthread_t thread, std::string str, int request_count)
 {
@@ -70,7 +82,7 @@ pthread_create_and_store (string name, pthread_t  *thread, pthread_attr_t *attr,
                attr = &default_attr;
        }
 
-       if ((ret = pthread_create (thread, attr, start_routine, arg)) == 0) {
+       if ((ret = thread_creator (thread, attr, start_routine, arg)) == 0) {
                std::pair<string,pthread_t> newpair;
                newpair.first = name;
                newpair.second = *thread;
index 223646af9b1a2d9ef013323403b27dd85a0030da..fe3337356c6dac5fb460fdaea7e182f736a8666a 100755 (executable)
@@ -3,4 +3,4 @@
 . ../gtk2_ardour/ardev_common.sh
 
 export LD_LIBRARY_PATH=gtk2_ardour:$LD_LIBRARY_PATH
-wine-pthread ./vst/ardour_vst.exe.so "$@"
+wine ./vst/ardour_vst.exe.so "$@"