summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-03-24 15:48:34 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-03-24 15:48:34 +0000
commitdfe26ae407b199b23d010c9cb4f9b616b5fb1e0d (patch)
treebd8134347c55914258f60cb1ddcd448bb1eb314f
parent21571906411af0f88344a3baf306ecfda408e15d (diff)
VST omnibus commit edition: use wine_pthread_create() everywhere instead of pthread_create; properly handle events when editor windows are closed, thus avoiding deadlock when deleting a VST plugin; actually delete plugins (of any kind) when requested to do so and there is an editor - this was a bug that has been around for quite a long time in 2.X; some extensions to the vestige header that might be legally dubious
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@4889 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/editor_ops.cc2
-rw-r--r--gtk2_ardour/plugin_ui.cc12
-rw-r--r--gtk2_ardour/plugin_ui.h3
-rw-r--r--gtk2_ardour/redirect_box.cc2
-rw-r--r--gtk2_ardour/route_time_axis.cc3
-rw-r--r--gtk2_ardour/vst_pluginui.cc9
-rw-r--r--libs/ardour/audioengine.cc2
-rw-r--r--libs/ardour/globals.cc3
-rw-r--r--libs/ardour/insert.cc10
-rw-r--r--libs/ardour/osc.cc2
-rw-r--r--libs/ardour/plugin_manager.cc1
-rw-r--r--libs/ardour/route.cc2
-rw-r--r--libs/ardour/session_vst.cc23
-rw-r--r--libs/ardour/vst_plugin.cc20
-rw-r--r--libs/fst/fst.h1
-rw-r--r--libs/fst/thread.c6
-rw-r--r--libs/fst/vestige/aeffectx.h62
-rw-r--r--libs/fst/vstwin.c242
-rw-r--r--libs/pbd/SConscript4
-rw-r--r--libs/pbd/pthread_utils.cc14
-rwxr-xr-xvst/ardevst2
21 files changed, 241 insertions, 184 deletions
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 2e546268da..fb331eafc5 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -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);
diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc
index 9dc27154fa..874abea0d6 100644
--- a/gtk2_ardour/plugin_ui.cc
+++ b/gtk2_ardour/plugin_ui.cc
@@ -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)
{
diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h
index 7bd7ffc910..4c14224a58 100644
--- a/gtk2_ardour/plugin_ui.h
+++ b/gtk2_ardour/plugin_ui.h
@@ -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;
diff --git a/gtk2_ardour/redirect_box.cc b/gtk2_ardour/redirect_box.cc
index 477a224035..e743be2212 100644
--- a/gtk2_ardour/redirect_box.cc
+++ b/gtk2_ardour/redirect_box.cc
@@ -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);
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index c42448d31f..303a697bfd 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -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);
diff --git a/gtk2_ardour/vst_pluginui.cc b/gtk2_ardour/vst_pluginui.cc
index 2b6961c6a8..aed9fb7337 100644
--- a/gtk2_ardour/vst_pluginui.cc
+++ b/gtk2_ardour/vst_pluginui.cc
@@ -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 ();
}
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index cba634ccbf..001a4d4568 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -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);
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index 9ae697fd3b..65740d5a5d 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -378,6 +378,9 @@ ARDOUR::cleanup ()
delete Library;
lrdf_cleanup ();
delete &ControlProtocolManager::instance();
+#ifdef VST_SUPPORT
+ fst_exit ();
+#endif
return 0;
}
diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc
index be4de27b01..dee63944c0 100644
--- a/libs/ardour/insert.cc
+++ b/libs/ardour/insert.cc
@@ -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 */
diff --git a/libs/ardour/osc.cc b/libs/ardour/osc.cc
index 384e77aa3d..ab611d0ee7 100644
--- a/libs/ardour/osc.cc
+++ b/libs/ardour/osc.cc
@@ -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;
}
diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc
index 7a3caf44c4..a069dd1762 100644
--- a/libs/ardour/plugin_manager.cc
+++ b/libs/ardour/plugin_manager.cc
@@ -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;
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 47b94432e4..91c3423388 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -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;
}
diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc
index 87930d9934..b70b75a403 100644
--- a/libs/ardour/session_vst.cc
+++ b/libs/ardour/session_vst.cc
@@ -29,10 +29,11 @@
#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:
diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc
index ec30087ee1..7fcb65e445 100644
--- a/libs/ardour/vst_plugin.cc
+++ b/libs/ardour/vst_plugin.cc
@@ -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') {
diff --git a/libs/fst/fst.h b/libs/fst/fst.h
index 463d022640..7e2cfec08b 100644
--- a/libs/fst/fst.h
+++ b/libs/fst/fst.h
@@ -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*);
diff --git a/libs/fst/thread.c b/libs/fst/thread.c
index 5be37b7a77..22a278e614 100644
--- a/libs/fst/thread.c
+++ b/libs/fst/thread.c
@@ -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
diff --git a/libs/fst/vestige/aeffectx.h b/libs/fst/vestige/aeffectx.h
index 4389ce70ec..dda128f45e 100644
--- a/libs/fst/vestige/aeffectx.h
+++ b/libs/fst/vestige/aeffectx.h
@@ -26,6 +26,7 @@
#ifndef _AEFFECTX_H
#define _AEFFECTX_H
+#include <stdint.h>
#define audioMasterAutomate 0
#define audioMasterVersion 1
@@ -128,7 +129,6 @@
#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
{
diff --git a/libs/fst/vstwin.c b/libs/fst/vstwin.c
index 72c578fe42..151eedcbdb 100644
--- a/libs/fst/vstwin.c
+++ b/libs/fst/vstwin.c
@@ -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" );
diff --git a/libs/pbd/SConscript b/libs/pbd/SConscript
index f51ddd5a36..96d1a772b5 100644
--- a/libs/pbd/SConscript
+++ b/libs/pbd/SConscript
@@ -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)
diff --git a/libs/pbd/pthread_utils.cc b/libs/pbd/pthread_utils.cc
index c63f988af3..2c43282451 100644
--- a/libs/pbd/pthread_utils.cc
+++ b/libs/pbd/pthread_utils.cc
@@ -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;
diff --git a/vst/ardevst b/vst/ardevst
index 223646af9b..fe3337356c 100755
--- a/vst/ardevst
+++ b/vst/ardevst
@@ -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 "$@"