mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-25 16:07:49 +01:00
Embedded LV2 GTK GUI support.
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3678 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
a35abc0528
commit
daf91bc21d
10 changed files with 262 additions and 9 deletions
|
|
@ -1072,9 +1072,9 @@ if env['SYSLIBS']:
|
|||
|
||||
# libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
|
||||
libraries['soundtouch'] = LibraryInfo()
|
||||
#libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
|
||||
# Comment the previous line and uncomment this for Debian:
|
||||
libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
|
||||
libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
|
||||
# Comment the previous line and uncomment this for old versions of Debian:
|
||||
#libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
|
||||
|
||||
libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
|
||||
LIBPATH='#libs/appleutility',
|
||||
|
|
|
|||
|
|
@ -283,8 +283,11 @@ if env['VST']:
|
|||
extra_sources += vst_files
|
||||
gtkardour.Append (CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst")
|
||||
|
||||
lv2_files = [ 'lv2_plugin_ui.cc' ]
|
||||
|
||||
if env['LV2']:
|
||||
gtkardour.Append (CCFLAGS="-DHAVE_SLV2")
|
||||
extra_sources += lv2_files
|
||||
gtkardour.Append (CCFLAGS="-DHAVE_LV2")
|
||||
gtkardour.Merge ([libraries['slv2']])
|
||||
|
||||
|
||||
|
|
|
|||
113
gtk2_ardour/lv2_plugin_ui.cc
Normal file
113
gtk2_ardour/lv2_plugin_ui.cc
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Copyright (C) 2008 Paul Davis
|
||||
Author: Dave Robillard
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#include <ardour/insert.h>
|
||||
#include <ardour/lv2_plugin.h>
|
||||
|
||||
#include "lv2_plugin_ui.h"
|
||||
|
||||
using namespace Gtk;
|
||||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
void
|
||||
LV2PluginUI::lv2_ui_write(LV2UI_Controller controller,
|
||||
uint32_t port_index,
|
||||
uint32_t buffer_size,
|
||||
uint32_t format,
|
||||
const void* buffer)
|
||||
{
|
||||
LV2PluginUI* me = (LV2PluginUI*)controller;
|
||||
if (*(float*)buffer != me->_values[port_index])
|
||||
me->_lv2->set_parameter(port_index, *(float*)buffer);
|
||||
}
|
||||
|
||||
void
|
||||
LV2PluginUI::parameter_changed (uint32_t port_index, float val)
|
||||
{
|
||||
if (val != _values[port_index]) {
|
||||
const LV2UI_Descriptor* ui_desc = slv2_ui_instance_get_descriptor(_inst);
|
||||
LV2UI_Handle ui_handle = slv2_ui_instance_get_handle(_inst);
|
||||
if (ui_desc->port_event)
|
||||
ui_desc->port_event(ui_handle, port_index, 4, 0, &val);
|
||||
_values[port_index] = val;
|
||||
}
|
||||
}
|
||||
|
||||
LV2PluginUI::LV2PluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<LV2Plugin> lv2p)
|
||||
: PlugUIBase (pi)
|
||||
, _lv2(lv2p)
|
||||
{
|
||||
_inst = slv2_ui_instantiate(
|
||||
_lv2->slv2_plugin(), _lv2->slv2_ui(), LV2PluginUI::lv2_ui_write, this,
|
||||
/* FEATURES */ NULL);
|
||||
|
||||
GtkWidget* c_widget = (GtkWidget*)slv2_ui_instance_get_widget(_inst);
|
||||
_gui_widget = Glib::wrap(c_widget);
|
||||
_gui_widget->show_all();
|
||||
pack_start(*_gui_widget, true, true);
|
||||
|
||||
uint32_t num_ports = slv2_plugin_get_num_ports(lv2p->slv2_plugin());
|
||||
_values = new float[num_ports];
|
||||
for (uint32_t i = 0; i < num_ports; ++i) {
|
||||
bool ok;
|
||||
_values[i] = lv2p->nth_parameter(i, ok);
|
||||
if (ok)
|
||||
lv2_ui_write(this, i, 4, /* FIXME: format */0, &_values[i]);
|
||||
}
|
||||
|
||||
_lv2->ParameterChanged.connect(mem_fun(*this, &LV2PluginUI::parameter_changed));
|
||||
}
|
||||
|
||||
LV2PluginUI::~LV2PluginUI ()
|
||||
{
|
||||
delete[] _values;
|
||||
// plugin destructor destroys the GUI
|
||||
}
|
||||
|
||||
int
|
||||
LV2PluginUI::get_preferred_height ()
|
||||
{
|
||||
Gtk::Requisition r = size_request();
|
||||
return r.height;
|
||||
}
|
||||
|
||||
int
|
||||
LV2PluginUI::get_preferred_width ()
|
||||
{
|
||||
Gtk::Requisition r = size_request();
|
||||
return r.width;
|
||||
}
|
||||
|
||||
int
|
||||
LV2PluginUI::package (Gtk::Window& win)
|
||||
{
|
||||
/* forward configure events to plugin window */
|
||||
win.signal_configure_event().connect (mem_fun (*this, &LV2PluginUI::configure_handler));
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
LV2PluginUI::configure_handler (GdkEventConfigure* ev)
|
||||
{
|
||||
cout << "CONFIGURE" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
76
gtk2_ardour/lv2_plugin_ui.h
Normal file
76
gtk2_ardour/lv2_plugin_ui.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright (C) 2008 Paul Davis
|
||||
Author: Dave Robillard
|
||||
|
||||
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 __ardour_lv2_plugin_ui_h__
|
||||
#define __ardour_lv2_plugin_ui_h__
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
#include <gtkmm/widget.h>
|
||||
|
||||
#include <ardour_dialog.h>
|
||||
#include <ardour/types.h>
|
||||
#include "plugin_ui.h"
|
||||
|
||||
#ifdef HAVE_LV2
|
||||
|
||||
namespace ARDOUR {
|
||||
class PluginInsert;
|
||||
class LV2Plugin;
|
||||
}
|
||||
|
||||
class LV2PluginUI : public PlugUIBase, public Gtk::VBox
|
||||
{
|
||||
public:
|
||||
LV2PluginUI (boost::shared_ptr<ARDOUR::PluginInsert>, boost::shared_ptr<ARDOUR::LV2Plugin>);
|
||||
~LV2PluginUI ();
|
||||
|
||||
gint get_preferred_height ();
|
||||
gint get_preferred_width ();
|
||||
bool start_updating(GdkEventAny*) {return false;}
|
||||
bool stop_updating(GdkEventAny*) {return false;}
|
||||
|
||||
int package (Gtk::Window&);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<ARDOUR::LV2Plugin> _lv2;
|
||||
|
||||
Gtk::Widget* _gui_widget;
|
||||
SLV2UIInstance _inst;
|
||||
float* _values;
|
||||
|
||||
static void lv2_ui_write(
|
||||
LV2UI_Controller controller,
|
||||
uint32_t port_index,
|
||||
uint32_t buffer_size,
|
||||
uint32_t format,
|
||||
const void* buffer);
|
||||
|
||||
void parameter_changed(uint32_t, float);
|
||||
bool configure_handler (GdkEventConfigure*);
|
||||
void save_plugin_setting ();
|
||||
};
|
||||
#endif // HAVE_LV2
|
||||
|
||||
#endif /* __ardour_lv2_plugin_ui_h__ */
|
||||
|
||||
|
|
@ -306,7 +306,7 @@ PluginSelector::ladspa_refiller (const std::string& filterstr)
|
|||
void
|
||||
PluginSelector::lv2_refiller (const std::string& filterstr)
|
||||
{
|
||||
#ifdef HAVE_SLV2
|
||||
#ifdef HAVE_LV2
|
||||
refiller (manager->lv2_plugin_info(), filterstr, "LV2");
|
||||
#endif
|
||||
}
|
||||
|
|
@ -512,7 +512,7 @@ PluginSelector::plugin_menu()
|
|||
#ifdef HAVE_AUDIOUNITS
|
||||
all_plugs.insert (all_plugs.end(), manager->au_plugin_info().begin(), manager->au_plugin_info().end());
|
||||
#endif
|
||||
#ifdef HAVE_SLV2
|
||||
#ifdef HAVE_LV2
|
||||
all_plugs.insert (all_plugs.end(), manager->lv2_plugin_info().begin(), manager->lv2_plugin_info().end());
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@
|
|||
#ifdef VST_SUPPORT
|
||||
#include <ardour/vst_plugin.h>
|
||||
#endif
|
||||
#ifdef HAVE_LV2
|
||||
#include <ardour/lv2_plugin.h>
|
||||
#include "lv2_plugin_ui.h"
|
||||
#endif
|
||||
|
||||
#include <lrdf.h>
|
||||
|
||||
|
|
@ -83,6 +87,10 @@ PluginUIWindow::PluginUIWindow (Gtk::Window* win, boost::shared_ptr<PluginInsert
|
|||
error << _("Eh? LADSPA plugins don't have editors!") << endmsg;
|
||||
break;
|
||||
|
||||
case ARDOUR::LV2:
|
||||
have_gui = create_lv2_editor (insert);
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifndef VST_SUPPORT
|
||||
error << _("unknown type of editor-supplying plugin (note: no VST support in this version of ardour)")
|
||||
|
|
@ -247,6 +255,30 @@ PluginUIWindow::app_activated (bool yn)
|
|||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginUIWindow::create_lv2_editor(boost::shared_ptr<PluginInsert> insert)
|
||||
{
|
||||
#ifndef HAVE_LV2
|
||||
return false;
|
||||
#else
|
||||
|
||||
boost::shared_ptr<LV2Plugin> vp;
|
||||
|
||||
if ((vp = boost::dynamic_pointer_cast<LV2Plugin> (insert->plugin())) == 0) {
|
||||
error << _("create_lv2_editor called on non-LV2 plugin") << endmsg;
|
||||
throw failed_constructor ();
|
||||
} else {
|
||||
LV2PluginUI* lpu = new LV2PluginUI (insert, vp);
|
||||
_pluginui = lpu;
|
||||
add (*lpu);
|
||||
lpu->package (*this);
|
||||
}
|
||||
|
||||
non_gtk_gui = false;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
PluginUIWindow::on_key_press_event (GdkEventKey* event)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ class PluginUIWindow : public Gtk::Window
|
|||
|
||||
bool create_vst_editor (boost::shared_ptr<ARDOUR::PluginInsert>);
|
||||
bool create_audiounit_editor (boost::shared_ptr<ARDOUR::PluginInsert>);
|
||||
bool create_lv2_editor (boost::shared_ptr<ARDOUR::PluginInsert>);
|
||||
};
|
||||
|
||||
#ifdef VST_SUPPORT
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ class LV2Plugin : public ARDOUR::Plugin
|
|||
uint32_t nth_parameter (uint32_t port, bool& ok) const;
|
||||
|
||||
SLV2Plugin slv2_plugin() { return _plugin; }
|
||||
SLV2UI slv2_ui() { return _ui; }
|
||||
SLV2Port slv2_port(uint32_t i) { return slv2_plugin_get_port_by_index(_plugin, i); }
|
||||
|
||||
std::set<uint32_t> automatable() const;
|
||||
|
|
@ -103,14 +104,13 @@ class LV2Plugin : public ARDOUR::Plugin
|
|||
int set_state(const XMLNode& node);
|
||||
bool save_preset(std::string name);
|
||||
|
||||
bool has_editor() const { return false; }
|
||||
bool has_editor() const;
|
||||
|
||||
int require_output_streams (uint32_t);
|
||||
|
||||
private:
|
||||
void* _module;
|
||||
LV2World& _world;
|
||||
SLV2Plugin _plugin;
|
||||
SLV2UI _ui;
|
||||
SLV2Value _name;
|
||||
SLV2Value _author;
|
||||
SLV2Instance _instance;
|
||||
|
|
@ -146,6 +146,7 @@ struct LV2World {
|
|||
SLV2Value integer;
|
||||
SLV2Value toggled;
|
||||
SLV2Value srate;
|
||||
SLV2Value gtk_gui;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -844,6 +844,9 @@ PluginInsert::type ()
|
|||
#ifdef HAVE_AUDIOUNITS
|
||||
boost::shared_ptr<AUPlugin> ap;
|
||||
#endif
|
||||
#ifdef HAVE_LV2
|
||||
boost::shared_ptr<LV2Plugin> lv2p;
|
||||
#endif
|
||||
|
||||
PluginPtr other = plugin ();
|
||||
|
||||
|
|
@ -856,8 +859,13 @@ PluginInsert::type ()
|
|||
#ifdef HAVE_AUDIOUNITS
|
||||
} else if ((ap = boost::dynamic_pointer_cast<AUPlugin> (other)) != 0) {
|
||||
return ARDOUR::AudioUnit;
|
||||
#endif
|
||||
#ifdef HAVE_LV2
|
||||
} else if ((lv2p = boost::dynamic_pointer_cast<LV2Plugin> (other)) != 0) {
|
||||
return ARDOUR::LV2;
|
||||
#endif
|
||||
} else {
|
||||
error << "Unknown plugin type" << endmsg;
|
||||
/* NOT REACHED */
|
||||
return (ARDOUR::PluginType) 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ LV2Plugin::init (LV2World& world, SLV2Plugin plugin, nframes_t rate)
|
|||
{
|
||||
_world = world;
|
||||
_plugin = plugin;
|
||||
_ui = NULL;
|
||||
_control_data = 0;
|
||||
_shadow_data = 0;
|
||||
_latency_control_port = 0;
|
||||
|
|
@ -124,6 +125,17 @@ LV2Plugin::init (LV2World& world, SLV2Plugin plugin, nframes_t rate)
|
|||
_defaults[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
SLV2UIs uis = slv2_plugin_get_uis(_plugin);
|
||||
if (slv2_uis_size(uis) > 0) {
|
||||
for (unsigned i=0; i < slv2_uis_size(uis); ++i) {
|
||||
SLV2UI ui = slv2_uis_get_at(uis, i);
|
||||
if (slv2_ui_is_a(ui, _world.gtk_gui)) {
|
||||
_ui = ui;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Plugin::setup_controls ();
|
||||
|
||||
|
|
@ -243,6 +255,12 @@ LV2Plugin::save_preset (string name)
|
|||
{
|
||||
return Plugin::save_preset (name, "lv2");
|
||||
}
|
||||
|
||||
bool
|
||||
LV2Plugin::has_editor() const
|
||||
{
|
||||
return (_ui != NULL);
|
||||
}
|
||||
|
||||
int
|
||||
LV2Plugin::set_state(const XMLNode& node)
|
||||
|
|
@ -505,6 +523,7 @@ LV2World::LV2World()
|
|||
integer = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "integer");
|
||||
toggled = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "toggled");
|
||||
srate = slv2_value_new_uri(world, SLV2_NAMESPACE_LV2 "sampleRate");
|
||||
gtk_gui = slv2_value_new_uri(world, "http://lv2plug.in/ns/extensions/ui#GtkUI");
|
||||
}
|
||||
|
||||
LV2World::~LV2World()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue