summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-07-11 21:55:11 +0000
committerCarl Hetherington <carl@carlh.net>2010-07-11 21:55:11 +0000
commit6f5ee7c4293c43486d48bac00fdcdba90dabb17d (patch)
tree9468080d65f78d36c187403e581ccdd17a07be40
parent2578d5da0ef6e7256d25fc737a53bb0294bc19a3 (diff)
Fix up VST build and add basic support for VSTi
git-svn-id: svn://localhost/ardour2/branches/3.0@7403 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/plugin_ui.h15
-rw-r--r--gtk2_ardour/vst_pluginui.cc2
-rw-r--r--gtk2_ardour/wscript42
-rw-r--r--libs/ardour/ardour/buffer_set.h35
-rw-r--r--libs/ardour/ardour/vst_plugin.h2
-rw-r--r--libs/ardour/buffer_set.cc101
-rw-r--r--libs/ardour/plugin_manager.cc1
-rw-r--r--libs/ardour/session_vst.cc9
-rw-r--r--libs/ardour/vst_plugin.cc13
-rw-r--r--libs/ardour/wscript4
-rwxr-xr-xvst/ardevst4
11 files changed, 213 insertions, 15 deletions
diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h
index 7b5e77ec18..bfd23fab6b 100644
--- a/gtk2_ardour/plugin_ui.h
+++ b/gtk2_ardour/plugin_ui.h
@@ -298,9 +298,24 @@ class VSTPluginUI : public PlugUIBase, public Gtk::VBox
Gtk::Socket socket;
Gtk::HBox preset_box;
Gtk::VBox vpacker;
+ Gtk::ComboBoxText vst_preset_combo;
+ Glib::RefPtr<Gtk::ListStore> preset_model;
+
+ struct PresetModelColumns : public Gtk::TreeModel::ColumnRecord {
+ PresetModelColumns() {
+ add (name);
+ add (number);
+ }
+ Gtk::TreeModelColumn<Glib::ustring> name;
+ Gtk::TreeModelColumn<int> number;
+ };
+
+ PresetModelColumns preset_columns;
bool configure_handler (GdkEventConfigure*, Gtk::Socket*);
void save_plugin_setting ();
+ void create_preset_store ();
+ void preset_chosen ();
};
#endif // VST_SUPPORT
diff --git a/gtk2_ardour/vst_pluginui.cc b/gtk2_ardour/vst_pluginui.cc
index bd678dd72d..6c1b359fd4 100644
--- a/gtk2_ardour/vst_pluginui.cc
+++ b/gtk2_ardour/vst_pluginui.cc
@@ -20,7 +20,7 @@
#include <fst.h>
#include <gtk/gtk.h>
#include <gtk/gtksocket.h>
-#include "ardour/insert.h"
+#include "ardour/plugin_insert.h"
#include "ardour/vst_plugin.h"
#include "plugin_ui.h"
diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript
index ddae851127..940d43d5b4 100644
--- a/gtk2_ardour/wscript
+++ b/gtk2_ardour/wscript
@@ -237,13 +237,29 @@ def configure(conf):
autowaf.check_header(conf, 'boost/shared_ptr.hpp')
autowaf.check_header(conf, 'boost/weak_ptr.hpp')
+# Add a waf `feature' to allow compilation of things using winegcc
+from TaskGen import feature
+@feature("wine")
+def set_winegcc(self):
+ self.env.LINK_CXX = self.env.LINK_CC = 'wineg++'
+ self.env.CC = 'winegcc'
+
def build(bld):
- # Program
- obj = bld.new_task_gen(features = 'cxx cc cprogram')
+ # GTK front-end; if we're using VST we build this as a shared library, otherwise
+ # it's a normal executabale
+ if bld.env['VST_SUPPORT']:
+ obj = bld.new_task_gen(features = 'cxx cc cshlib')
+ else:
+ obj = bld.new_task_gen(features = 'cxx cc cprogram')
+
obj.includes = ['.']
obj.source = gtk2_ardour_sources
obj.name = 'gtk2_ardour'
- obj.target = 'ardour-3.0'
+ if bld.env['VST_SUPPORT']:
+ obj.target = 'gtk2_ardour'
+ obj.includes += ['../libs/fst']
+ else:
+ obj.target = 'ardour-3.0'
obj.install_path = os.path.join(bld.env['LIBDIR'], 'ardour3')
obj.uselib = 'UUID FLAC GLIBMM GTHREAD GTK GNOMECANVAS OGG ALSA'
obj.uselib += ' GTKMM GNOMECANVASMM OSX GTKOSX COREAUDIO'
@@ -266,7 +282,7 @@ def build(bld):
if bld.env['FREESOUND']:
obj.source += [ 'sfdb_freesound_mootcher.cc' ]
- if bld.env['VST']:
+ if bld.env['VST_SUPPORT']:
obj.source += [ 'vst_pluginui.cc' ]
obj.cxxflags += [ '-DVST_SUPPORT' ]
@@ -281,6 +297,24 @@ def build(bld):
else:
obj.source += [ 'x11.cc' ]
+ if bld.env['VST_SUPPORT']:
+ # If we require VST support we build a stub main() and the FST library here using
+ # winegcc, and link it to the GTK front-end library
+ obj = bld.new_task_gen (features = 'cxx cc cprogram wine')
+ obj.source = '''
+ ../libs/fst/fst.c
+ ../libs/fst/fstinfofile.c
+ ../libs/fst/vsti.c
+ ../libs/fst/vstwin.c
+ ../vst/winmain.c
+ '''
+ obj.includes = '../libs/fst'
+ obj.target = 'ardour-3.0-vst'
+ obj.linkflags = ['-mwindows', '-Wl,--export-dynamic']
+ obj.defines = ['_POSIX_SOURCE', 'USE_WS_PREFIX']
+ obj.uselib = 'ALSA'
+ obj.uselib_local = '''libpbd libmidipp libtaglib libardour libardour_cp libgtkmm2ext libtaglib gtk2_ardour'''
+
# Wrappers
wrapper_subst_dict = {
diff --git a/libs/ardour/ardour/buffer_set.h b/libs/ardour/ardour/buffer_set.h
index 278496ffbc..711e2350fd 100644
--- a/libs/ardour/ardour/buffer_set.h
+++ b/libs/ardour/ardour/buffer_set.h
@@ -29,6 +29,12 @@
#include "ardour/data_type.h"
#include "ardour/types.h"
+#ifdef VST_SUPPORT
+#include "evoral/MIDIEvent.hpp"
+struct VstEvents;
+struct VstMidiEvent;
+#endif
+
namespace ARDOUR {
class Buffer;
@@ -105,6 +111,10 @@ public:
void flush_lv2_midi(bool input, size_t i);
#endif
+#ifdef VST_SUPPORT
+ VstEvents* get_vst_midi (size_t);
+#endif
+
void read_from(const BufferSet& in, nframes_t nframes);
void merge_from(const BufferSet& in, nframes_t nframes);
@@ -159,6 +169,31 @@ private:
LV2Buffers _lv2_buffers;
#endif
+#ifdef VST_SUPPORT
+ class VSTBuffer {
+ public:
+ VSTBuffer (size_t);
+ ~VSTBuffer ();
+
+ void clear ();
+ void push_back (Evoral::MIDIEvent<nframes_t> const &);
+ VstEvents* events () const {
+ return _events;
+ }
+
+ private:
+ /* prevent copy construction */
+ VSTBuffer (VSTBuffer const &);
+
+ VstEvents* _events; /// the parent VSTEvents struct
+ VstMidiEvent* _midi_events; ///< storage area for VSTMidiEvents
+ size_t _capacity;
+ };
+
+ typedef std::vector<VSTBuffer*> VSTBuffers;
+ VSTBuffers _vst_buffers;
+#endif
+
/// Use counts (there may be more actual buffers than this)
ChanCount _count;
diff --git a/libs/ardour/ardour/vst_plugin.h b/libs/ardour/ardour/vst_plugin.h
index cfc5a117a0..07417baa81 100644
--- a/libs/ardour/ardour/vst_plugin.h
+++ b/libs/ardour/ardour/vst_plugin.h
@@ -85,7 +85,7 @@ class VSTPlugin : public ARDOUR::Plugin
bool has_editor () const;
XMLNode& get_state();
- int set_state(const XMLNode& node);
+ int set_state (XMLNode const &, int);
AEffect* plugin() const { return _plugin; }
FST* fst() const { return _fst; }
diff --git a/libs/ardour/buffer_set.cc b/libs/ardour/buffer_set.cc
index c97a47e42b..b0f5563564 100644
--- a/libs/ardour/buffer_set.cc
+++ b/libs/ardour/buffer_set.cc
@@ -33,6 +33,9 @@
#include "ardour/lv2_plugin.h"
#include "ardour/lv2_event_buffer.h"
#endif
+#ifdef VST_SUPPORT
+#include "vestige/aeffectx.h"
+#endif
namespace ARDOUR {
@@ -69,6 +72,14 @@ BufferSet::clear()
_buffers.clear();
_count.reset();
_available.reset();
+
+#ifdef VST_SUPPORT
+ for (VSTBuffers::iterator i = _vst_buffers.begin(); i != _vst_buffers.end(); ++i) {
+ delete *i;
+ }
+
+ _vst_buffers.clear ();
+#endif
}
/** Make this BufferSet a direct mirror of a PortSet's buffers.
@@ -147,6 +158,15 @@ BufferSet::ensure_buffers(DataType type, size_t num_buffers, size_t buffer_capac
}
#endif
+#ifdef VST_SUPPORT
+ // As above but for VST
+ if (type == DataType::MIDI) {
+ while (_vst_buffers.size() < _buffers[type].size()) {
+ _vst_buffers.push_back (new VSTBuffer (buffer_capacity));
+ }
+ }
+#endif
+
// Post-conditions
assert(bufs[0]->type() == type);
assert(bufs.size() >= num_buffers);
@@ -288,7 +308,86 @@ BufferSet::flush_lv2_midi(bool input, size_t i)
}
}
-#endif
+#endif /* HAVE_SLV2 */
+
+#ifdef VST_SUPPORT
+
+VstEvents*
+BufferSet::get_vst_midi (size_t b)
+{
+ MidiBuffer& m = get_midi (b);
+ VSTBuffer* vst = _vst_buffers[b];
+
+ vst->clear ();
+
+ for (MidiBuffer::iterator i = m.begin(); i != m.end(); ++i) {
+ vst->push_back (*i);
+ }
+
+ return vst->events();
+}
+
+BufferSet::VSTBuffer::VSTBuffer (size_t c)
+ : _capacity (c)
+{
+ _events = static_cast<VstEvents*> (malloc (sizeof (VstEvents) + _capacity * sizeof (VstEvent *)));
+ _midi_events = static_cast<VstMidiEvent*> (malloc (sizeof (VstMidiEvent) * _capacity));
+
+ if (_events == 0 || _midi_events == 0) {
+ free (_events);
+ free (_midi_events);
+ throw failed_constructor ();
+ }
+
+ _events->numEvents = 0;
+ _events->reserved = 0;
+}
+
+BufferSet::VSTBuffer::~VSTBuffer ()
+{
+ free (_events);
+ free (_midi_events);
+}
+
+void
+BufferSet::VSTBuffer::clear ()
+{
+ _events->numEvents = 0;
+}
+
+void
+BufferSet::VSTBuffer::push_back (Evoral::MIDIEvent<nframes_t> const & ev)
+{
+ if (ev.size() > 3) {
+ /* XXX: this will silently drop MIDI messages longer than 3 bytes, so
+ they won't be passed to VST plugins or VSTis
+ */
+ return;
+ }
+ int const n = _events->numEvents;
+ assert (n < (int) _capacity);
+
+ _events->events[n] = reinterpret_cast<VstEvent*> (_midi_events + n);
+ VstMidiEvent* v = reinterpret_cast<VstMidiEvent*> (_events->events[n]);
+
+ v->type = kVstMidiType;
+ v->byteSize = sizeof (VstMidiEvent);
+ v->deltaFrames = ev.time ();
+
+ v->flags = 0;
+ v->detune = 0;
+ v->noteLength = 0;
+ v->noteOffset = 0;
+ v->reserved1 = 0;
+ v->reserved2 = 0;
+ v->noteOffVelocity = 0;
+ memcpy (v->midiData, ev.buffer(), ev.size());
+ v->midiData[3] = 0;
+
+ _events->numEvents++;
+}
+
+#endif /* VST_SUPPORT */
void
BufferSet::read_from (const BufferSet& in, nframes_t nframes)
diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc
index ebf0ecab3c..5597fac9e8 100644
--- a/libs/ardour/plugin_manager.cc
+++ b/libs/ardour/plugin_manager.cc
@@ -558,6 +558,7 @@ PluginManager::vst_discover (string path)
info->index = 0;
info->n_inputs.set_audio (finfo->numInputs);
info->n_outputs.set_audio (finfo->numOutputs);
+ info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
info->type = ARDOUR::VST;
_vst_plugin_info->push_back (info);
diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc
index 7f13d3e18b..85b5f13c4c 100644
--- a/libs/ardour/session_vst.cc
+++ b/libs/ardour/session_vst.cc
@@ -58,11 +58,11 @@ long Session::vst_callback (AEffect* effect,
if (effect && effect->user) {
plug = (VSTPlugin*) (effect->user);
session = &plug->session();
- SHOW_CALLBACK ("am callback 0x%x, opcode = %ld, plugin = \"%s\" ", pthread_self(), opcode, plug->name());
+ SHOW_CALLBACK ("am callback 0x%x, opcode = %ld, plugin = \"%s\" ", (int) pthread_self(), opcode, plug->name());
} else {
plug = 0;
session = 0;
- SHOW_CALLBACK ("am callback 0x%x, opcode = %ld", pthread_self(), opcode);
+ SHOW_CALLBACK ("am callback 0x%x, opcode = %ld", (int) pthread_self(), opcode);
}
switch(opcode){
@@ -107,6 +107,9 @@ long Session::vst_callback (AEffect* effect,
case audioMasterWantMidi:
SHOW_CALLBACK ("amc: audioMasterWantMidi\n");
// <value> is a filter which is currently ignored
+ if (plug) {
+ plug->get_info()->n_inputs.set_midi (1);
+ }
return 0;
case audioMasterGetTime:
@@ -345,7 +348,7 @@ long Session::vst_callback (AEffect* effect,
return 0;
default:
- SHOW_CALLBACK ("VST master dispatcher: undefed: %d\n", opcode);
+ SHOW_CALLBACK ("VST master dispatcher: undefed: %ld\n", opcode);
break;
}
diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc
index 7fb5289f9c..a270c5ba91 100644
--- a/libs/ardour/vst_plugin.cc
+++ b/libs/ardour/vst_plugin.cc
@@ -49,12 +49,14 @@
#include "ardour/vst_plugin.h"
#include "ardour/buffer_set.h"
#include "ardour/audio_buffer.h"
+#include "ardour/midi_buffer.h"
#include "pbd/stl_delete.h"
#include "i18n.h"
#include <locale.h>
+using namespace std;
using namespace ARDOUR;
using namespace PBD;
using std::min;
@@ -192,7 +194,7 @@ VSTPlugin::get_state()
}
int
-VSTPlugin::set_state(const XMLNode& node)
+VSTPlugin::set_state(const XMLNode& node, int)
{
LocaleGuard lg (X_("POSIX"));
@@ -204,7 +206,7 @@ VSTPlugin::set_state(const XMLNode& node)
const XMLProperty* prop;
if ((prop = node.property ("current-program")) != 0) {
- _fst->current_program = atoi (prop->value());
+ _fst->current_program = atoi (prop->value().c_str());
}
XMLNode* child;
@@ -392,11 +394,13 @@ VSTPlugin::connect_and_run (BufferSet& bufs,
const uint32_t nbufs = bufs.count().n_audio();
+ int in_index = 0;
for (i = 0; i < (int32_t) _plugin->numInputs; ++i) {
ins[i] = bufs.get_audio(min((uint32_t) in_index, nbufs - 1)).data() + offset;
in_index++;
}
+ int out_index = 0;
for (i = 0; i < (int32_t) _plugin->numOutputs; ++i) {
outs[i] = bufs.get_audio(min((uint32_t) out_index, nbufs - 1)).data() + offset;
@@ -410,6 +414,11 @@ VSTPlugin::connect_and_run (BufferSet& bufs,
}
+ if (bufs.count().n_midi() > 0) {
+ VstEvents* v = bufs.get_vst_midi (0);
+ _plugin->dispatcher (_plugin, effProcessEvents, 0, 0, v, 0);
+ }
+
/* we already know it can support processReplacing */
_plugin->processReplacing (_plugin, ins, outs, nframes);
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index e9bdd644ba..c859a2e88d 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -312,8 +312,10 @@ def build(bld):
obj.source += [ 'lv2_plugin.cc', 'lv2_event_buffer.cc', 'uri_map.cc' ]
obj.uselib += ' SLV2 '
- if bld.env['VST']:
+ if bld.env['VST_SUPPORT']:
obj.source += [ 'vst_plugin.cc', 'session_vst.cc' ]
+ obj.includes += [ '../fst' ]
+ obj.cxxflags += [ '-DVST_SUPPORT' ]
if bld.env['HAVE_COREAUDIO'] and bld.env['COREAUDIO']:
obj.source += [ 'coreaudiosource.cc', 'caimportable.cc' ]
diff --git a/vst/ardevst b/vst/ardevst
index f254f908c7..bb7474b8fb 100755
--- a/vst/ardevst
+++ b/vst/ardevst
@@ -1,5 +1,5 @@
#!/bin/sh
. `dirname "$0"`/../build/default/gtk2_ardour/ardev_common_waf.sh
-export LD_LIBRARY_PATH=$TOP/gtk2_ardour:$LD_LIBRARY_PATH
-exec wine $TOP/vst/ardour_vst.exe.so "$@"
+export LD_LIBRARY_PATH=$libs/../gtk2_ardour:$LD_LIBRARY_PATH
+exec wine $libs/../gtk2_ardour/ardour-3.0-vst.so "$@"