summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-09-29 18:19:17 +0000
committerDavid Robillard <d@drobilla.net>2008-09-29 18:19:17 +0000
commit3168e388d0a951cf665696b970eb5bb354fbb740 (patch)
treeaa2eb0c1887d2d315085944607b66ec8470a4a65 /src
parent95b1e3fe89477fbb6710d30ac183fab7d8238c14 (diff)
downloadingen-3168e388d0a951cf665696b970eb5bb354fbb740.tar.gz
ingen-3168e388d0a951cf665696b970eb5bb354fbb740.tar.bz2
ingen-3168e388d0a951cf665696b970eb5bb354fbb740.zip
More context extension work.
Clicking the input port on bang in ingen while in edit mode will now send a message to the bang plugin in the message context. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1537 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/libs/engine/Context.hpp51
-rw-r--r--src/libs/engine/Engine.cpp3
-rw-r--r--src/libs/engine/Engine.hpp5
-rw-r--r--src/libs/engine/LV2Node.cpp31
-rw-r--r--src/libs/engine/LV2Node.hpp4
-rw-r--r--src/libs/engine/LV2Plugin.hpp2
-rw-r--r--src/libs/engine/Makefile.am1
-rw-r--r--src/libs/engine/MessageContext.hpp10
-rw-r--r--src/libs/engine/OSCEngineReceiver.cpp2
-rw-r--r--src/libs/engine/PortImpl.cpp1
-rw-r--r--src/libs/engine/PortImpl.hpp5
-rw-r--r--src/libs/engine/ProcessContext.hpp7
-rw-r--r--src/libs/engine/events/SetPortValueEvent.cpp12
l---------src/libs/engine/lv2_contexts.h1
14 files changed, 117 insertions, 18 deletions
diff --git a/src/libs/engine/Context.hpp b/src/libs/engine/Context.hpp
new file mode 100644
index 00000000..2e000fb1
--- /dev/null
+++ b/src/libs/engine/Context.hpp
@@ -0,0 +1,51 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *
+ * Ingen 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.
+ *
+ * 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 General Public License for 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef CONTEXT_H
+#define CONTEXT_H
+
+namespace Ingen {
+
+class Engine;
+
+class Context
+{
+public:
+ enum ID {
+ AUDIO,
+ MESSAGE
+ };
+
+ Context(Engine& engine, ID id)
+ : _id(id)
+ , _engine(engine)
+ {}
+
+ virtual ~Context() {}
+
+ inline Engine& engine() const { return _engine; }
+
+protected:
+ ID _id; ///< Fast ID for this context
+ Engine& _engine; ///< Engine we're running in
+};
+
+
+} // namespace Ingen
+
+#endif // CONTEXT_H
+
diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp
index ac71a820..a08a37ca 100644
--- a/src/libs/engine/Engine.cpp
+++ b/src/libs/engine/Engine.cpp
@@ -45,6 +45,8 @@
#endif
#include "PostProcessor.hpp"
#include "ProcessSlave.hpp"
+#include "ProcessContext.hpp"
+#include "MessageContext.hpp"
#include "ThreadManager.hpp"
#ifdef HAVE_JACK_MIDI
#include "JackMidiDriver.hpp"
@@ -62,6 +64,7 @@ Engine::Engine(Ingen::Shared::World* world)
, _post_processor(new PostProcessor(*this, /**_maid, */post_processor_queue_size))
, _broadcaster(new ClientBroadcaster())
, _node_factory(new NodeFactory(world))
+ , _message_context(new MessageContext(*this))
, _quit_flag(false)
, _activated(false)
{
diff --git a/src/libs/engine/Engine.hpp b/src/libs/engine/Engine.hpp
index 26884f73..fce826db 100644
--- a/src/libs/engine/Engine.hpp
+++ b/src/libs/engine/Engine.hpp
@@ -47,6 +47,7 @@ class QueuedEngineInterface;
class Driver;
class ProcessSlave;
class ProcessContext;
+class MessageContext;
/** The main class for the Engine.
@@ -91,6 +92,7 @@ public:
PostProcessor* post_processor() const { return _post_processor; }
ClientBroadcaster* broadcaster() const { return _broadcaster; }
NodeFactory* node_factory() const { return _node_factory; }
+ MessageContext* message_context() const { return _message_context; }
SharedPtr<EngineStore> engine_store() const;
@@ -104,7 +106,7 @@ public:
inline ProcessSlaves& process_slaves() { return _process_slaves; }
private:
- ProcessSlaves _process_slaves;
+ ProcessSlaves _process_slaves;
Ingen::Shared::World* _world;
@@ -116,6 +118,7 @@ private:
PostProcessor* _post_processor;
ClientBroadcaster* _broadcaster;
NodeFactory* _node_factory;
+ MessageContext* _message_context;
bool _quit_flag;
bool _activated;
diff --git a/src/libs/engine/LV2Node.cpp b/src/libs/engine/LV2Node.cpp
index a3c20a95..a06cc55a 100644
--- a/src/libs/engine/LV2Node.cpp
+++ b/src/libs/engine/LV2Node.cpp
@@ -28,6 +28,7 @@
#include "EventBuffer.hpp"
#include "OutputPort.hpp"
#include "ProcessContext.hpp"
+#include "lv2_contexts.h"
using namespace std;
@@ -49,6 +50,7 @@ LV2Node::LV2Node(LV2Plugin* plugin,
, _lv2_plugin(plugin)
, _instances(NULL)
, _prepared_instances(NULL)
+ , _message_run(NULL)
{
assert(_lv2_plugin);
}
@@ -140,6 +142,17 @@ LV2Node::instantiate()
cerr << "Failed to instantiate plugin!" << endl;
return false;
}
+
+ const void* ctx_ext = slv2_instance_get_extension_data(
+ (*_instances)[i], LV2_CONTEXT_MESSAGE);
+
+ if (ctx_ext) {
+ cerr << "HAS CONTEXT EXTENSION" << endl;
+ if (_message_run == NULL)
+ _message_run = new MessageRunFuncs(_polyphony, NULL);
+ LV2MessageContext* mc = (LV2MessageContext*)ctx_ext;
+ (*_message_run)[i] = mc->message_run;
+ }
}
string port_name;
@@ -202,8 +215,17 @@ LV2Node::instantiate()
SLV2Value pred = slv2_value_new_uri(info->lv2_world(),
"http://lv2plug.in/ns/dev/contexts#context");
SLV2Values contexts = slv2_port_get_value(plug, id, pred);
- if (slv2_values_size(contexts) > 0) {
- cout << "PORT HAS CONTEXT!" << endl;
+ for (uint32_t i = 0; i < slv2_values_size(contexts); ++i) {
+ SLV2Value c = slv2_values_get_at(contexts, i);
+ const char* context = slv2_value_as_string(c);
+ if (!strcmp("http://lv2plug.in/ns/dev/contexts#MessageContext", context)) {
+ cout << "MESSAGE CONTEXT!" << endl;
+ port->set_context(Context::MESSAGE);
+ } else {
+ cout << "UNKNOWN CONTEXT: "
+ << slv2_value_as_string(slv2_values_get_at(contexts, i))
+ << endl;
+ }
}
_ports->at(j) = port;
@@ -250,7 +272,10 @@ LV2Node::deactivate()
void
LV2Node::message_process(MessageContext& context, uint32_t* output)
{
- *output = 0;
+ // FIXME: voice
+ if (_message_run)
+ (*_message_run)[0]((*_instances)[0], output);
+
/* MESSAGE PROCESS */
}
diff --git a/src/libs/engine/LV2Node.hpp b/src/libs/engine/LV2Node.hpp
index dbdb6511..3187005c 100644
--- a/src/libs/engine/LV2Node.hpp
+++ b/src/libs/engine/LV2Node.hpp
@@ -62,6 +62,10 @@ protected:
LV2Plugin* _lv2_plugin;
Raul::Array<SLV2Instance>* _instances;
Raul::Array<SLV2Instance>* _prepared_instances;
+
+ typedef bool (*MessageRunFunc)(LV2_Handle, uint32_t*);
+ typedef Raul::Array<MessageRunFunc> MessageRunFuncs;
+ MessageRunFuncs* _message_run;
};
diff --git a/src/libs/engine/LV2Plugin.hpp b/src/libs/engine/LV2Plugin.hpp
index c1f8671d..c9bc4ff9 100644
--- a/src/libs/engine/LV2Plugin.hpp
+++ b/src/libs/engine/LV2Plugin.hpp
@@ -61,7 +61,7 @@ public:
NodeImpl* instantiate(const string& name,
bool polyphonic,
Ingen::PatchImpl* parent,
- Engine& engine);
+ Engine& engine);
const string symbol() const;
const string name() const;
diff --git a/src/libs/engine/Makefile.am b/src/libs/engine/Makefile.am
index c7c433d3..3c464de3 100644
--- a/src/libs/engine/Makefile.am
+++ b/src/libs/engine/Makefile.am
@@ -178,6 +178,7 @@ libingen_engine_la_SOURCES = \
events/UnregisterClientEvent.cpp \
events/UnregisterClientEvent.hpp \
jack_compat.h \
+ lv2_contexts.h \
tuning.hpp \
types.hpp \
util.hpp
diff --git a/src/libs/engine/MessageContext.hpp b/src/libs/engine/MessageContext.hpp
index 3a53e73a..31531521 100644
--- a/src/libs/engine/MessageContext.hpp
+++ b/src/libs/engine/MessageContext.hpp
@@ -19,6 +19,7 @@
#define MESSAGECONTEXT_H
#include "EventSink.hpp"
+#include "Context.hpp"
namespace Ingen {
@@ -33,19 +34,14 @@ class NodeImpl;
*
* \ingroup engine
*/
-class MessageContext
+class MessageContext : public Context
{
public:
MessageContext(Engine& engine)
- : _engine(engine)
+ : Context(engine, MESSAGE)
{}
void run(NodeImpl* node);
-
- inline Engine& engine() const { return _engine; }
-
-private:
- Engine& _engine; ///< Engine we're running in
};
diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp
index 04352c2f..e4e2fec1 100644
--- a/src/libs/engine/OSCEngineReceiver.cpp
+++ b/src/libs/engine/OSCEngineReceiver.cpp
@@ -70,7 +70,7 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t
}
// For debugging, print all incoming OSC messages
- lo_server_add_method(_server, NULL, NULL, generic_cb, NULL);
+ //lo_server_add_method(_server, NULL, NULL, generic_cb, NULL);
// Set response address for this message.
// It's important this is first and returns nonzero.
diff --git a/src/libs/engine/PortImpl.cpp b/src/libs/engine/PortImpl.cpp
index 9b609323..3eac65ca 100644
--- a/src/libs/engine/PortImpl.cpp
+++ b/src/libs/engine/PortImpl.cpp
@@ -48,6 +48,7 @@ PortImpl::PortImpl(NodeImpl* const node,
, _broadcast(false)
, _set_by_user(false)
, _last_broadcasted_value(_value.type() == Atom::FLOAT ? _value.get_float() : 0.0f) // default?
+ , _context(Context::AUDIO)
, _buffers(new Raul::Array<Buffer*>(poly))
{
assert(node != NULL);
diff --git a/src/libs/engine/PortImpl.hpp b/src/libs/engine/PortImpl.hpp
index ca21bb4c..be96a910 100644
--- a/src/libs/engine/PortImpl.hpp
+++ b/src/libs/engine/PortImpl.hpp
@@ -26,6 +26,7 @@
#include "GraphObjectImpl.hpp"
#include "interface/DataType.hpp"
#include "Buffer.hpp"
+#include "Context.hpp"
namespace Raul { class Maid; class Atom; }
@@ -107,6 +108,9 @@ public:
void raise_set_by_user_flag() { _set_by_user = true; }
+ Context::ID context() const { return _context; }
+ void set_context(Context::ID c) { _context = c; }
+
protected:
PortImpl(NodeImpl* node,
const std::string& name,
@@ -130,6 +134,7 @@ protected:
bool _set_by_user;
Sample _last_broadcasted_value;
+ Context::ID _context;
Raul::Array<Buffer*>* _buffers;
// Dynamic polyphony
diff --git a/src/libs/engine/ProcessContext.hpp b/src/libs/engine/ProcessContext.hpp
index 0f090b3b..57677126 100644
--- a/src/libs/engine/ProcessContext.hpp
+++ b/src/libs/engine/ProcessContext.hpp
@@ -19,6 +19,7 @@
#define PROCESSCONTEXT_H
#include "EventSink.hpp"
+#include "Context.hpp"
namespace Ingen {
@@ -35,11 +36,11 @@ namespace Ingen {
*
* \ingroup engine
*/
-class ProcessContext
+class ProcessContext : public Context
{
public:
ProcessContext(Engine& engine)
- : _engine(engine)
+ : Context(engine, AUDIO)
, _event_sink(engine, 1024) // FIXME: size?
{}
@@ -49,7 +50,6 @@ public:
_end = end;
}
- inline Engine& engine() const { return _engine; }
inline SampleCount nframes() const { return _nframes; }
inline FrameTime start() const { return _start; }
inline FrameTime end() const { return _end; }
@@ -57,7 +57,6 @@ public:
inline EventSink& event_sink() { return _event_sink; }
private:
- Engine& _engine; ///< Engine we're running in
SampleCount _nframes; ///< Number of actual time (Jack) frames this cycle
FrameTime _start; ///< Start frame of this cycle, timeline relative
FrameTime _end; ///< End frame of this cycle, timeline relative
diff --git a/src/libs/engine/events/SetPortValueEvent.cpp b/src/libs/engine/events/SetPortValueEvent.cpp
index 90e66c1c..6d65082b 100644
--- a/src/libs/engine/events/SetPortValueEvent.cpp
+++ b/src/libs/engine/events/SetPortValueEvent.cpp
@@ -27,6 +27,7 @@
#include "AudioBuffer.hpp"
#include "EventBuffer.hpp"
#include "ProcessContext.hpp"
+#include "MessageContext.hpp"
using namespace std;
@@ -76,7 +77,7 @@ SetPortValueEvent::~SetPortValueEvent()
{
}
-
+
void
SetPortValueEvent::pre_process()
{
@@ -91,6 +92,12 @@ SetPortValueEvent::pre_process()
if (_port == NULL && _error == NO_ERROR)
_error = PORT_NOT_FOUND;
}
+
+ // Port is a message context port, set its value and
+ // call the plugin's message run function once
+ if (_port && _port->context() == Context::MESSAGE) {
+ _engine.message_context()->run(_port->parent_node());
+ }
QueuedEvent::pre_process();
}
@@ -101,6 +108,9 @@ SetPortValueEvent::execute(ProcessContext& context)
{
Event::execute(context);
assert(_time >= context.start() && _time <= context.end());
+
+ if (_port && _port->context() == Context::MESSAGE)
+ return;
if (_error == NO_ERROR && _port == NULL) {
if (Path::is_valid(_port_path))
diff --git a/src/libs/engine/lv2_contexts.h b/src/libs/engine/lv2_contexts.h
new file mode 120000
index 00000000..8556a582
--- /dev/null
+++ b/src/libs/engine/lv2_contexts.h
@@ -0,0 +1 @@
+../../../../lv2/lv2/contexts/lv2_contexts.h \ No newline at end of file