summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ingen/shared/URIMap.hpp2
-rw-r--r--src/gui/NodeModule.cpp24
-rw-r--r--src/gui/NodeModule.hpp1
-rw-r--r--src/server/Context.cpp52
-rw-r--r--src/server/Context.hpp14
-rw-r--r--src/server/ControlBindings.cpp48
-rw-r--r--src/server/ControlBindings.hpp7
-rw-r--r--src/server/InputPort.cpp6
-rw-r--r--src/server/LV2Node.hpp2
-rw-r--r--src/server/Notification.cpp91
-rw-r--r--src/server/Notification.hpp61
-rw-r--r--src/server/PortImpl.cpp28
-rw-r--r--src/server/PostProcessor.cpp1
-rw-r--r--src/server/Worker.cpp2
-rw-r--r--src/server/internals/Controller.cpp1
-rw-r--r--src/server/wscript1
-rw-r--r--src/shared/URIMap.cpp2
17 files changed, 147 insertions, 196 deletions
diff --git a/ingen/shared/URIMap.hpp b/ingen/shared/URIMap.hpp
index 952d67ce..bb3e55be 100644
--- a/ingen/shared/URIMap.hpp
+++ b/ingen/shared/URIMap.hpp
@@ -37,7 +37,7 @@ public:
virtual ~URIMap() {}
uint32_t map_uri(const char* uri);
- const char* unmap_uri(uint32_t urid);
+ const char* unmap_uri(uint32_t urid) const;
class Feature : public LV2Features::Feature {
public:
diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp
index 5ee75584..1d3f6801 100644
--- a/src/gui/NodeModule.cpp
+++ b/src/gui/NodeModule.cpp
@@ -19,6 +19,8 @@
#include <gtkmm/eventbox.h>
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
+
#include "ingen/Interface.hpp"
#include "ingen/client/NodeModel.hpp"
#include "ingen/client/PatchModel.hpp"
@@ -182,6 +184,24 @@ NodeModule::value_changed(uint32_t index, const Atom& value)
}
void
+NodeModule::port_activity(uint32_t index, const Atom& value)
+{
+ if (!_plugin_ui)
+ return;
+
+ const URIs& uris = app().uris();
+
+ // FIXME: Well, this sucks...
+ LV2_Atom* atom = (LV2_Atom*)malloc(sizeof(LV2_Atom) + value.size());
+ atom->type = value.type();
+ atom->size = value.type();
+ memcpy(LV2_ATOM_BODY(atom), value.get_body(), value.size());
+ _plugin_ui->port_event(
+ index, lv2_atom_total_size(atom), uris.atom_eventTransfer, atom);
+ free(atom);
+}
+
+void
NodeModule::plugin_changed()
{
for (iterator p = begin(); p !=end(); ++p)
@@ -252,6 +272,10 @@ NodeModule::new_port_view(SharedPtr<const PortModel> port)
port->signal_value_changed().connect(
sigc::bind<0>(sigc::mem_fun(this, &NodeModule::value_changed),
port->index()));
+
+ port->signal_activity().connect(
+ sigc::bind<0>(sigc::mem_fun(this, &NodeModule::port_activity),
+ port->index()));
}
Port*
diff --git a/src/gui/NodeModule.hpp b/src/gui/NodeModule.hpp
index 0cfa4ec8..3ec72f6d 100644
--- a/src/gui/NodeModule.hpp
+++ b/src/gui/NodeModule.hpp
@@ -83,6 +83,7 @@ protected:
void new_port_view(SharedPtr<const Client::PortModel> port);
void value_changed(uint32_t index, const Raul::Atom& value);
+ void port_activity(uint32_t index, const Raul::Atom& value);
void plugin_changed();
void set_control_values();
diff --git a/src/server/Context.cpp b/src/server/Context.cpp
index 9979415b..0736b451 100644
--- a/src/server/Context.cpp
+++ b/src/server/Context.cpp
@@ -14,20 +14,45 @@
along with Ingen. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "ingen/shared/Forge.hpp"
+#include "ingen/shared/URIMap.hpp"
+#include "raul/log.hpp"
+
#include "Context.hpp"
+#include "Engine.hpp"
+#include "Broadcaster.hpp"
+#include "PortImpl.hpp"
namespace Ingen {
namespace Server {
+struct Notification
+{
+ inline Notification(PortImpl* p = 0,
+ FrameTime f = 0,
+ LV2_URID k = 0,
+ uint32_t s = 0,
+ Raul::Atom::TypeID t = 0)
+ : port(p), key(k), size(s), type(t)
+ {}
+
+ PortImpl* port;
+ LV2_URID key;
+ uint32_t size;
+ Raul::Atom::TypeID type;
+};
+
void
-Context::notify(Notification::Type type,
- FrameTime time,
- PortImpl* port,
- const Raul::Atom& value,
- const ControlBindings::Type btype)
+Context::notify(LV2_URID key,
+ FrameTime time,
+ PortImpl* port,
+ uint32_t size,
+ Raul::Atom::TypeID type,
+ const void* body)
{
- const Notification n = Notification::make(type, time, port, value, btype);
+ const Notification n(port, time, key, size, type);
_event_sink.write(sizeof(n), &n);
+ _event_sink.write(size, body);
}
void
@@ -37,7 +62,20 @@ Context::emit_notifications()
Notification note;
for (uint32_t i = 0; i < read_space; i += sizeof(note)) {
if (_event_sink.read(sizeof(note), &note) == sizeof(note)) {
- Notification::post_process(note, _engine);
+ Raul::Atom value = _engine.world()->forge().alloc(
+ note.size, note.type, NULL);
+ if (_event_sink.read(note.size, value.get_body()) == note.size) {
+ i += note.size;
+ const char* key = _engine.world()->uri_map().unmap_uri(note.key);
+ if (key) {
+ _engine.broadcaster()->set_property(
+ note.port->path(), key, value);
+ } else {
+ Raul::error("Error unmapping notification key URI\n");
+ }
+ } else {
+ Raul::error("Error reading from notification ring\n");
+ }
}
}
}
diff --git a/src/server/Context.hpp b/src/server/Context.hpp
index 8afe1caa..7bcfb136 100644
--- a/src/server/Context.hpp
+++ b/src/server/Context.hpp
@@ -22,12 +22,12 @@
#include "ingen/shared/World.hpp"
#include "types.hpp"
-#include "Notification.hpp"
namespace Ingen {
namespace Server {
class Engine;
+class PortImpl;
/** Graph execution context.
*
@@ -63,12 +63,12 @@ public:
virtual ~Context() {}
/** Send a notification from this run context. */
- void notify(
- Notification::Type type = Notification::NIL,
- FrameTime time = 0,
- PortImpl* port = 0,
- const Raul::Atom& value = Raul::Atom(),
- const ControlBindings::Type btype = ControlBindings::NULL_CONTROL);
+ void notify(LV2_URID key = 0,
+ FrameTime time = 0,
+ PortImpl* port = 0,
+ uint32_t size = 0,
+ Raul::Atom::TypeID type = 0,
+ const void* body = NULL);
/** Emit pending notifications in some other non-realtime thread. */
void emit_notifications();
diff --git a/src/server/ControlBindings.cpp b/src/server/ControlBindings.cpp
index 844568d8..32d99c52 100644
--- a/src/server/ControlBindings.cpp
+++ b/src/server/ControlBindings.cpp
@@ -17,7 +17,6 @@
#include <math.h>
#include "ingen/shared/URIMap.hpp"
-
#include "ingen/shared/URIs.hpp"
#include "ingen/shared/World.hpp"
#include "lv2/lv2plug.in/ns/ext/atom/util.h"
@@ -27,7 +26,6 @@
#include "AudioBuffer.hpp"
#include "ControlBindings.hpp"
#include "Engine.hpp"
-#include "Notification.hpp"
#include "PortImpl.hpp"
#include "ProcessContext.hpp"
#include "ThreadManager.hpp"
@@ -47,6 +45,8 @@ ControlBindings::ControlBindings(Engine& engine)
engine.world()->uris().atom_Sequence,
4096)) // FIXME: capacity?
{
+ lv2_atom_forge_init(
+ &_forge, &engine.world()->uri_map().urid_map_feature()->urid_map);
}
ControlBindings::~ControlBindings()
@@ -263,6 +263,37 @@ ControlBindings::port_value_to_control(PortImpl* port,
}
}
+static void
+forge_binding(const Shared::URIs& uris,
+ LV2_Atom_Forge* forge,
+ ControlBindings::Type binding_type,
+ int32_t value)
+{
+ LV2_Atom_Forge_Frame frame;
+ switch (binding_type) {
+ case ControlBindings::MIDI_CC:
+ lv2_atom_forge_blank(forge, &frame, 0, uris.midi_Controller);
+ lv2_atom_forge_property_head(forge, uris.midi_controllerNumber, 0);
+ lv2_atom_forge_int(forge, value);
+ break;
+ case ControlBindings::MIDI_BENDER:
+ lv2_atom_forge_blank(forge, &frame, 0, uris.midi_Bender);
+ break;
+ case ControlBindings::MIDI_CHANNEL_PRESSURE:
+ lv2_atom_forge_blank(forge, &frame, 0, uris.midi_ChannelPressure);
+ break;
+ case ControlBindings::MIDI_NOTE:
+ lv2_atom_forge_blank(forge, &frame, 0, uris.midi_NoteOn);
+ lv2_atom_forge_property_head(forge, uris.midi_noteNumber, 0);
+ lv2_atom_forge_int(forge, value);
+ break;
+ case ControlBindings::MIDI_RPN: // TODO
+ case ControlBindings::MIDI_NRPN: // TODO
+ case ControlBindings::NULL_CONTROL:
+ break;
+ }
+}
+
void
ControlBindings::set_port_value(ProcessContext& context,
PortImpl* port,
@@ -281,7 +312,9 @@ ControlBindings::set_port_value(ProcessContext& context,
reinterpret_cast<AudioBuffer*>(port->buffer(v).get())->set_value(
port_value.get_float(), context.start(), context.start());
- context.notify(Notification::PORT_VALUE, context.start(), port, port_value);
+ Shared::URIs& uris = context.engine().world()->uris();
+ context.notify(uris.ingen_value, context.start(), port,
+ port_value.size(), port_value.type(), port_value.get_body());
}
bool
@@ -297,11 +330,14 @@ ControlBindings::bind(ProcessContext& context, Key key)
_bindings->insert(make_pair(key, _learn_port));
- context.notify(Notification::PORT_BINDING,
+ uint8_t buf[128];
+ lv2_atom_forge_set_buffer(&_forge, buf, sizeof(buf));
+ forge_binding(uris, &_forge, key.type, key.num);
+ const LV2_Atom* atom = (const LV2_Atom*)buf;
+ context.notify(uris.ingen_controlBinding,
context.start(),
_learn_port,
- context.engine().world()->forge().make(key.num),
- key.type);
+ atom->size, atom->type, LV2_ATOM_BODY(atom));
_learn_port = NULL;
return true;
diff --git a/src/server/ControlBindings.hpp b/src/server/ControlBindings.hpp
index 2a107dfc..c98175ab 100644
--- a/src/server/ControlBindings.hpp
+++ b/src/server/ControlBindings.hpp
@@ -20,6 +20,7 @@
#include <map>
#include <stdint.h>
+#include "lv2/lv2plug.in/ns/ext/atom/forge.h"
#include "raul/Atom.hpp"
#include "raul/Path.hpp"
#include "raul/SharedPtr.hpp"
@@ -106,11 +107,11 @@ private:
const Raul::Atom& min,
const Raul::Atom& max) const;
- Engine& _engine;
- PortImpl* _learn_port;
-
+ Engine& _engine;
+ PortImpl* _learn_port;
SharedPtr<Bindings> _bindings;
BufferRef _feedback;
+ LV2_Atom_Forge _forge;
};
} // namespace Server
diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp
index d94a971b..70d3662c 100644
--- a/src/server/InputPort.cpp
+++ b/src/server/InputPort.cpp
@@ -24,7 +24,6 @@
#include "Engine.hpp"
#include "InputPort.hpp"
#include "NodeImpl.hpp"
-#include "Notification.hpp"
#include "OutputPort.hpp"
#include "ProcessContext.hpp"
#include "ingen/shared/URIs.hpp"
@@ -154,10 +153,11 @@ InputPort::remove_edge(ProcessContext& context, const OutputPort* tail)
if (_edges.empty()) {
if (is_a(PortType::AUDIO)) {
// Send an update peak of 0.0 to reset to silence
- context.notify(Notification::PORT_ACTIVITY,
+ const Raul::Atom z = context.engine().world()->forge().make(0.0f);
+ context.notify(context.engine().world()->uris().ingen_activity,
context.start(),
this,
- context.engine().world()->forge().make(0.0f));
+ z.size(), z.type(), z.get_body());
}
_broadcast = false;
}
diff --git a/src/server/LV2Node.hpp b/src/server/LV2Node.hpp
index 18d96dc8..b588de78 100644
--- a/src/server/LV2Node.hpp
+++ b/src/server/LV2Node.hpp
@@ -88,7 +88,7 @@ protected:
~Response() {
free(data);
}
-
+
const uint32_t size;
void* const data;
};
diff --git a/src/server/Notification.cpp b/src/server/Notification.cpp
deleted file mode 100644
index d3298f8e..00000000
--- a/src/server/Notification.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2012 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen 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 Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "lv2/lv2plug.in/ns/ext/atom/forge.h"
-
-#include "ingen/shared/URIMap.hpp"
-#include "ingen/shared/URIs.hpp"
-
-#include "Broadcaster.hpp"
-#include "Engine.hpp"
-#include "Notification.hpp"
-#include "PortImpl.hpp"
-
-namespace Ingen {
-namespace Server {
-
-void
-Notification::post_process(Notification& note,
- Engine& engine)
-{
- const Ingen::Shared::URIs& uris = engine.world()->uris();
- LV2_Atom_Forge forge;
- uint8_t buf[128];
- switch (note.type) {
- case PORT_VALUE:
- engine.broadcaster()->set_property(note.port->path(),
- uris.ingen_value,
- note.value);
- break;
- case PORT_ACTIVITY:
- engine.broadcaster()->set_property(note.port->path(),
- uris.ingen_activity,
- note.value);
- break;
- case PORT_BINDING: {
- lv2_atom_forge_init(
- &forge, &engine.world()->uri_map().urid_map_feature()->urid_map);
- lv2_atom_forge_set_buffer(&forge, buf, sizeof(buf));
- LV2_Atom_Forge_Frame frame;
- switch (note.binding_type) {
- case ControlBindings::MIDI_CC:
- lv2_atom_forge_blank(&forge, &frame, 0, uris.midi_Controller);
- lv2_atom_forge_property_head(&forge, uris.midi_controllerNumber, 0);
- lv2_atom_forge_int(&forge, note.value.get_int32());
- break;
- case ControlBindings::MIDI_BENDER:
- lv2_atom_forge_blank(&forge, &frame, 0, uris.midi_Bender);
- break;
- case ControlBindings::MIDI_CHANNEL_PRESSURE:
- lv2_atom_forge_blank(&forge, &frame, 0, uris.midi_ChannelPressure);
- break;
- case ControlBindings::MIDI_NOTE:
- lv2_atom_forge_blank(&forge, &frame, 0, uris.midi_NoteOn);
- lv2_atom_forge_property_head(&forge, uris.midi_noteNumber, 0);
- lv2_atom_forge_int(&forge, note.value.get_int32());
- break;
- case ControlBindings::MIDI_RPN: // TODO
- case ControlBindings::MIDI_NRPN: // TODO
- case ControlBindings::NULL_CONTROL:
- break;
- }
- LV2_Atom* atom = (LV2_Atom*)buf;
- // FIXME: not thread-safe
- const Raul::Atom dict_atom = engine.world()->forge().alloc(
- atom->size, atom->type, LV2_ATOM_BODY(atom));
- note.port->set_property(uris.ingen_controlBinding, dict_atom);
- engine.broadcaster()->set_property(note.port->path(),
- uris.ingen_controlBinding,
- dict_atom);
- break;
- }
- case NIL:
- break;
- }
-}
-
-} // namespace Server
-} // namespace Ingen
diff --git a/src/server/Notification.hpp b/src/server/Notification.hpp
deleted file mode 100644
index d24a523d..00000000
--- a/src/server/Notification.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2012 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen 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 Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef INGEN_ENGINE_NOTIFICATION_HPP
-#define INGEN_ENGINE_NOTIFICATION_HPP
-
-#include "ControlBindings.hpp"
-#include "types.hpp"
-
-namespace Ingen {
-namespace Server {
-
-class Engine;
-class PortImpl;
-
-struct Notification
-{
- enum Type {
- NIL,
- PORT_VALUE,
- PORT_ACTIVITY,
- PORT_BINDING
- };
-
- static inline Notification make(
- Type type = NIL,
- FrameTime time = 0,
- PortImpl* port = 0,
- const Raul::Atom& value = Raul::Atom(),
- const ControlBindings::Type btype = ControlBindings::NULL_CONTROL)
- {
- const Notification note = { port, type, btype, value };
- return note;
- }
-
- static void post_process(Notification& note,
- Engine& engine);
-
- PortImpl* port;
- Type type;
- ControlBindings::Type binding_type;
- Raul::Atom value;
-};
-
-} // namespace Server
-} // namespace Ingen
-
-#endif // INGEN_ENGINE_NOTIFICATION_HPP
diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp
index d4fcb6c8..6920198c 100644
--- a/src/server/PortImpl.cpp
+++ b/src/server/PortImpl.cpp
@@ -15,6 +15,7 @@
*/
#include "ingen/shared/URIs.hpp"
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
#include "raul/Array.hpp"
#include "raul/Maid.hpp"
@@ -22,7 +23,6 @@
#include "BufferFactory.hpp"
#include "Engine.hpp"
#include "NodeImpl.hpp"
-#include "Notification.hpp"
#include "PortImpl.hpp"
#include "PortType.hpp"
#include "ThreadManager.hpp"
@@ -218,28 +218,33 @@ PortImpl::clear_buffers()
void
PortImpl::broadcast_value(Context& context, bool force)
{
- Shared::Forge& forge = context.engine().world()->forge();
- Notification::Type ntype = Notification::PORT_VALUE;
- Raul::Atom val;
+ Shared::Forge& forge = context.engine().world()->forge();
+ Shared::URIs& uris = context.engine().world()->uris();
+ LV2_URID key = 0;
+ Raul::Atom val;
switch (_type.symbol()) {
case PortType::UNKNOWN:
break;
case PortType::AUDIO:
- val = forge.make(((AudioBuffer*)buffer(0).get())->peak(context));
- ntype = Notification::PORT_ACTIVITY;
+ key = uris.ingen_activity;
+ val = forge.make(((AudioBuffer*)buffer(0).get())->peak(context));
break;
case PortType::CONTROL:
case PortType::CV:
+ key = uris.ingen_value;
val = forge.make(((AudioBuffer*)buffer(0).get())->value_at(0));
break;
case PortType::ATOM:
if (_buffer_type == _bufs.uris().atom_Sequence) {
LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)buffer(0)->atom();
- if (seq->atom.size > sizeof(LV2_Atom_Sequence_Body)) {
- context.notify(Notification::PORT_ACTIVITY,
- context.start(),
+ // TODO: Filter events, or only send one activity for blinkenlights
+ LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
+ context.notify(uris.ingen_activity,
+ context.start() + ev->time.frames,
this,
- forge.make(true));
+ ev->body.size,
+ ev->body.type,
+ LV2_ATOM_BODY(&ev->body));
}
}
break;
@@ -247,7 +252,8 @@ PortImpl::broadcast_value(Context& context, bool force)
if (val.is_valid() && (force || val != _last_broadcasted_value)) {
_last_broadcasted_value = val;
- context.notify(ntype, context.start(), this, val);
+ context.notify(key, context.start(), this,
+ val.size(), val.type(), val.get_body());
}
}
diff --git a/src/server/PostProcessor.cpp b/src/server/PostProcessor.cpp
index df83cc7b..16b0317d 100644
--- a/src/server/PostProcessor.cpp
+++ b/src/server/PostProcessor.cpp
@@ -18,7 +18,6 @@
#include "Engine.hpp"
#include "Event.hpp"
-#include "Notification.hpp"
#include "PostProcessor.hpp"
#include "ProcessContext.hpp"
diff --git a/src/server/Worker.cpp b/src/server/Worker.cpp
index c3cebffd..006b45d4 100644
--- a/src/server/Worker.cpp
+++ b/src/server/Worker.cpp
@@ -66,7 +66,7 @@ Worker::request(LV2Node* node,
Raul::error("Error writing body to work request ring\n");
return LV2_WORKER_ERR_UNKNOWN;
}
-
+
_sem.post();
return LV2_WORKER_SUCCESS;
diff --git a/src/server/internals/Controller.cpp b/src/server/internals/Controller.cpp
index 41b56a77..76183e85 100644
--- a/src/server/internals/Controller.cpp
+++ b/src/server/internals/Controller.cpp
@@ -27,7 +27,6 @@
#include "Engine.hpp"
#include "InputPort.hpp"
#include "InternalPlugin.hpp"
-#include "Notification.hpp"
#include "OutputPort.hpp"
#include "PostProcessor.hpp"
#include "ProcessContext.hpp"
diff --git a/src/server/wscript b/src/server/wscript
index 1c5e57bd..fbdf78fa 100644
--- a/src/server/wscript
+++ b/src/server/wscript
@@ -23,7 +23,6 @@ def build(bld):
MessageContext.cpp
NodeFactory.cpp
NodeImpl.cpp
- Notification.cpp
OutputPort.cpp
PatchImpl.cpp
PortImpl.cpp
diff --git a/src/shared/URIMap.cpp b/src/shared/URIMap.cpp
index f9bf7072..b8981fd3 100644
--- a/src/shared/URIMap.cpp
+++ b/src/shared/URIMap.cpp
@@ -88,7 +88,7 @@ URIMap::map_uri(const char* uri)
}
const char*
-URIMap::unmap_uri(uint32_t urid)
+URIMap::unmap_uri(uint32_t urid) const
{
return _urid_unmap_feature->unmap(urid);
}