summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2015-01-15 19:49:29 +0000
committerDavid Robillard <d@drobilla.net>2015-01-15 19:49:29 +0000
commit4326f8ba71f4af1f3e3c48c9f3a02d8e3e0590f7 (patch)
tree15d37aa76d390385e847fad8160bd22df52dfe2c /src
parent81df927a7faa49fd7057276df6dc67e386ca565c (diff)
downloadingen-4326f8ba71f4af1f3e3c48c9f3a02d8e3e0590f7.tar.gz
ingen-4326f8ba71f4af1f3e3c48c9f3a02d8e3e0590f7.tar.bz2
ingen-4326f8ba71f4af1f3e3c48c9f3a02d8e3e0590f7.zip
Node bypass.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5515 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/gui/NodeMenu.cpp14
-rw-r--r--src/gui/NodeMenu.hpp2
-rw-r--r--src/gui/NodeModule.cpp6
-rw-r--r--src/gui/ingen_gui.ui10
-rw-r--r--src/server/BlockImpl.cpp34
-rw-r--r--src/server/BlockImpl.hpp11
-rw-r--r--src/server/PortType.hpp4
-rw-r--r--src/server/events/Delta.cpp22
8 files changed, 94 insertions, 9 deletions
diff --git a/src/gui/NodeMenu.cpp b/src/gui/NodeMenu.cpp
index 5434f6be..08524ade 100644
--- a/src/gui/NodeMenu.cpp
+++ b/src/gui/NodeMenu.cpp
@@ -46,6 +46,7 @@ NodeMenu::NodeMenu(BaseObjectType* cobject,
{
xml->get_widget("node_popup_gui_menuitem", _popup_gui_menuitem);
xml->get_widget("node_embed_gui_menuitem", _embed_gui_menuitem);
+ xml->get_widget("node_enabled_menuitem", _enabled_menuitem);
xml->get_widget("node_randomize_menuitem", _randomize_menuitem);
}
@@ -60,6 +61,8 @@ NodeMenu::init(App& app, SPtr<const Client::BlockModel> block)
sigc::mem_fun(signal_popup_gui, &sigc::signal<void>::emit));
_embed_gui_menuitem->signal_toggled().connect(
sigc::mem_fun(this, &NodeMenu::on_menu_embed_gui));
+ _enabled_menuitem->signal_toggled().connect(
+ sigc::mem_fun(this, &NodeMenu::on_menu_enabled));
_randomize_menuitem->signal_activate().connect(
sigc::mem_fun(this, &NodeMenu::on_menu_randomize));
@@ -76,6 +79,9 @@ NodeMenu::init(App& app, SPtr<const Client::BlockModel> block)
_embed_gui_menuitem->hide();
}
+ const Atom& enabled = block->get_property(_app->uris().ingen_enabled);
+ _enabled_menuitem->set_active(!enabled.is_valid() || enabled.get<int32_t>());
+
if (plugin && plugin->type() == PluginModel::LV2) {
LilvNode* pset_Preset = lilv_new_uri(plugin->lilv_world(),
@@ -159,6 +165,14 @@ NodeMenu::on_menu_embed_gui()
}
void
+NodeMenu::on_menu_enabled()
+{
+ _app->set_property(_object->uri(),
+ _app->uris().ingen_enabled,
+ _app->forge().make(bool(_enabled_menuitem->get_active())));
+}
+
+void
NodeMenu::on_menu_randomize()
{
_app->interface()->bundle_begin();
diff --git a/src/gui/NodeMenu.hpp b/src/gui/NodeMenu.hpp
index 969afecf..d84bc84f 100644
--- a/src/gui/NodeMenu.hpp
+++ b/src/gui/NodeMenu.hpp
@@ -50,12 +50,14 @@ public:
protected:
void on_menu_disconnect();
void on_menu_embed_gui();
+ void on_menu_enabled();
void on_menu_randomize();
void on_preset_activated(const std::string& uri);
bool on_preset_clicked(const std::string& uri, GdkEventButton* ev);
Gtk::MenuItem* _popup_gui_menuitem;
Gtk::CheckMenuItem* _embed_gui_menuitem;
+ Gtk::CheckMenuItem* _enabled_menuitem;
Gtk::MenuItem* _randomize_menuitem;
Gtk::Menu* _presets_menu;
};
diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp
index 722cfa83..40303ad7 100644
--- a/src/gui/NodeModule.cpp
+++ b/src/gui/NodeModule.cpp
@@ -438,6 +438,12 @@ NodeModule::property_changed(const Raul::URI& key, const Atom& value)
} else if (!value.get<int32_t>() && _gui_widget) {
embed_gui(false);
}
+ } else if (key == uris.ingen_enabled) {
+ if (value.get<int32_t>()) {
+ set_dash_length(0.0);
+ } else {
+ set_dash_length(5.0);
+ }
}
} else if (value.type() == uris.forge.String) {
if (key == uris.lv2_name
diff --git a/src/gui/ingen_gui.ui b/src/gui/ingen_gui.ui
index eb3f2684..2b711ce0 100644
--- a/src/gui/ingen_gui.ui
+++ b/src/gui/ingen_gui.ui
@@ -2082,6 +2082,16 @@ Contributors:
</object>
</child>
<child>
+ <object class="GtkCheckMenuItem" id="node_enabled_menuitem">
+ <property name="visible">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="can_focus">False</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Enabled</property>
+ <property name="active">True</property>
+ </object>
+ </child>
+ <child>
<object class="GtkImageMenuItem" id="node_randomize_menuitem">
<property name="label" translatable="yes">Randomi_ze</property>
<property name="use_action_appearance">False</property>
diff --git a/src/server/BlockImpl.cpp b/src/server/BlockImpl.cpp
index 069ecdfa..3d684e6c 100644
--- a/src/server/BlockImpl.cpp
+++ b/src/server/BlockImpl.cpp
@@ -45,6 +45,7 @@ BlockImpl::BlockImpl(PluginImpl* plugin,
, _polyphony((polyphonic && parent) ? parent->internal_poly() : 1)
, _polyphonic(polyphonic)
, _activated(false)
+ , _enabled(true)
, _traversed(false)
{
assert(_plugin);
@@ -144,6 +145,21 @@ BlockImpl::set_buffer_size(Context& context,
}
}
+PortImpl*
+BlockImpl::nth_port_by_type(uint32_t n, bool input, PortType type)
+{
+ uint32_t count = 0;
+ for (uint32_t i = 0; _ports && i < _ports->size(); ++i) {
+ PortImpl* const port = _ports->at(i);
+ if (port->is_input() == input && port->type() == type) {
+ if (count++ == n) {
+ return port;
+ }
+ }
+ }
+ return NULL;
+}
+
void
BlockImpl::pre_process(ProcessContext& context)
{
@@ -160,6 +176,24 @@ BlockImpl::process(ProcessContext& context)
{
pre_process(context);
+ if (!_enabled) {
+ for (PortType t : { PortType::AUDIO, PortType::CV, PortType::ATOM }) {
+ for (uint32_t i = 0;; ++i) {
+ PortImpl* in = nth_port_by_type(i, true, t);
+ PortImpl* out;
+ if (in && (out = nth_port_by_type(i, false, t))) {
+ for (uint32_t v = 0; v < _polyphony; ++v) {
+ out->buffer(v)->copy(context, in->buffer(v).get());
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ post_process(context);
+ return;
+ }
+
ProcessContext subcontext(context);
for (SampleCount offset = 0; offset < context.nframes();) {
// Find earliest offset of a value change
diff --git a/src/server/BlockImpl.hpp b/src/server/BlockImpl.hpp
index 58ced1fe..845cd7df 100644
--- a/src/server/BlockImpl.hpp
+++ b/src/server/BlockImpl.hpp
@@ -84,7 +84,13 @@ public:
virtual void deactivate();
/** Return true iff this block is activated */
- bool activated() { return _activated; }
+ bool activated() const { return _activated; }
+
+ /** Return true iff this block is enabled (not bypassed). */
+ bool enabled() const { return _enabled; }
+
+ /** Enable or disable (bypass) this block. */
+ void set_enabled(bool e) { _enabled = e; }
/** Learn the next incoming MIDI event (for internals) */
virtual void learn() {}
@@ -157,6 +163,8 @@ public:
void traversed(bool b) { _traversed = b; }
protected:
+ PortImpl* nth_port_by_type(uint32_t n, bool input, PortType type);
+
PluginImpl* _plugin;
Raul::Array<PortImpl*>* _ports; ///< Access in audio thread only
Context::ID _context; ///< Context this block runs in
@@ -165,6 +173,7 @@ protected:
std::list<BlockImpl*> _dependants; ///< Blocks this one's output ports are connected to
bool _polyphonic;
bool _activated;
+ bool _enabled;
bool _traversed; ///< Flag for process order algorithm
};
diff --git a/src/server/PortType.hpp b/src/server/PortType.hpp
index b1719e3b..8371bd2c 100644
--- a/src/server/PortType.hpp
+++ b/src/server/PortType.hpp
@@ -58,8 +58,8 @@ public:
PortType(ID id) : _id(id) {}
- inline const Raul::URI& uri() const { return type_uri(_id); }
- inline ID id() const { return _id; }
+ inline const Raul::URI& uri() const { return type_uri(_id); }
+ inline ID id() const { return _id; }
inline bool operator==(const ID& id) const { return (_id == id); }
inline bool operator!=(const ID& id) const { return (_id != id); }
diff --git a/src/server/events/Delta.cpp b/src/server/events/Delta.cpp
index c3d4e458..f1acbdc2 100644
--- a/src/server/events/Delta.cpp
+++ b/src/server/events/Delta.cpp
@@ -209,6 +209,12 @@ Delta::pre_process()
} else if ((block = dynamic_cast<BlockImpl*>(_object))) {
if (key == uris.midi_binding && value == uris.patch_wildcard) {
op = SpecialType::CONTROL_BINDING; // Internal block learn
+ } else if (key == uris.ingen_enabled) {
+ if (value.type() == uris.forge.Bool) {
+ op = SpecialType::ENABLE;
+ } else {
+ _status = Status::BAD_VALUE_TYPE;
+ }
}
}
@@ -316,13 +322,17 @@ Delta::execute(ProcessContext& context)
}
break;
case SpecialType::ENABLE:
- if (value.get<int32_t>()) {
- if (_compiled_graph) {
- _graph->set_compiled_graph(_compiled_graph);
+ if (_graph) {
+ if (value.get<int32_t>()) {
+ if (_compiled_graph) {
+ _graph->set_compiled_graph(_compiled_graph);
+ }
+ _graph->enable();
+ } else {
+ _graph->disable(context);
}
- _graph->enable();
- } else {
- _graph->disable(context);
+ } else if (block) {
+ block->set_enabled(value.get<int32_t>());
}
break;
case SpecialType::POLYPHONIC: {