summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/LADSPANode.cpp16
-rw-r--r--src/engine/LADSPANode.hpp4
-rw-r--r--src/engine/LV2Node.cpp16
-rw-r--r--src/engine/LV2Node.hpp4
-rw-r--r--src/engine/MessageContext.cpp1
-rw-r--r--src/engine/NodeBase.cpp280
-rw-r--r--src/engine/NodeBase.hpp151
-rw-r--r--src/engine/NodeImpl.hpp145
-rw-r--r--src/engine/PatchImpl.cpp14
-rw-r--r--src/engine/PatchImpl.hpp4
-rw-r--r--src/engine/events/CreatePort.cpp2
-rw-r--r--src/engine/events/Delete.cpp2
-rw-r--r--src/engine/events/SetMetadata.cpp4
-rw-r--r--src/engine/internals/Controller.cpp6
-rw-r--r--src/engine/internals/Controller.hpp4
-rw-r--r--src/engine/internals/Delay.cpp8
-rw-r--r--src/engine/internals/Delay.hpp4
-rw-r--r--src/engine/internals/Note.cpp10
-rw-r--r--src/engine/internals/Note.hpp4
-rw-r--r--src/engine/internals/Trigger.cpp6
-rw-r--r--src/engine/internals/Trigger.hpp4
-rw-r--r--src/engine/wscript2
22 files changed, 158 insertions, 533 deletions
diff --git a/src/engine/LADSPANode.cpp b/src/engine/LADSPANode.cpp
index 66472f6a..ec793915 100644
--- a/src/engine/LADSPANode.cpp
+++ b/src/engine/LADSPANode.cpp
@@ -49,7 +49,7 @@ LADSPANode::LADSPANode(PluginImpl* plugin,
PatchImpl* parent,
const LADSPA_Descriptor* descriptor,
SampleRate srate)
- : NodeBase(plugin, path, polyphonic, parent, srate)
+ : NodeImpl(plugin, path, polyphonic, parent, srate)
, _descriptor(descriptor)
, _instances(NULL)
, _prepared_instances(NULL)
@@ -70,7 +70,7 @@ LADSPANode::prepare_poly(BufferFactory& bufs, uint32_t poly)
if (!_polyphonic)
poly = 1;
- NodeBase::prepare_poly(bufs, poly);
+ NodeImpl::prepare_poly(bufs, poly);
if (_polyphony == poly)
return true;
@@ -118,7 +118,7 @@ LADSPANode::apply_poly(Raul::Maid& maid, uint32_t poly)
}
assert(poly <= _instances->size());
- return NodeBase::apply_poly(maid, poly);
+ return NodeImpl::apply_poly(maid, poly);
}
@@ -243,7 +243,7 @@ LADSPANode::instantiate(BufferFactory& bufs)
void
LADSPANode::activate(BufferFactory& bufs)
{
- NodeBase::activate(bufs);
+ NodeImpl::activate(bufs);
if (_descriptor->activate != NULL)
for (uint32_t i = 0; i < _polyphony; ++i)
@@ -254,7 +254,7 @@ LADSPANode::activate(BufferFactory& bufs)
void
LADSPANode::deactivate()
{
- NodeBase::deactivate();
+ NodeImpl::deactivate();
for (uint32_t i = 0; i < _polyphony; ++i)
if (_descriptor->deactivate != NULL)
@@ -265,12 +265,12 @@ LADSPANode::deactivate()
void
LADSPANode::process(ProcessContext& context)
{
- NodeBase::pre_process(context);
+ NodeImpl::pre_process(context);
for (uint32_t i = 0; i < _polyphony; ++i)
_descriptor->run(instance(i), context.nframes());
- NodeBase::post_process(context);
+ NodeImpl::post_process(context);
}
@@ -278,7 +278,7 @@ void
LADSPANode::set_port_buffer(uint32_t voice, uint32_t port_num,
IntrusivePtr<Buffer> buf, SampleCount offset)
{
- NodeBase::set_port_buffer(voice, port_num, buf, offset);
+ NodeImpl::set_port_buffer(voice, port_num, buf, offset);
_descriptor->connect_port(instance(voice), port_num,
buf ? (LADSPA_Data*)buf->port_data(_ports->at(port_num)->type(), offset) : NULL);
diff --git a/src/engine/LADSPANode.hpp b/src/engine/LADSPANode.hpp
index ad2073c6..a246e2dc 100644
--- a/src/engine/LADSPANode.hpp
+++ b/src/engine/LADSPANode.hpp
@@ -23,7 +23,7 @@
#include <boost/optional.hpp>
#include "raul/IntrusivePtr.hpp"
#include "types.hpp"
-#include "NodeBase.hpp"
+#include "NodeImpl.hpp"
#include "PluginImpl.hpp"
namespace Ingen {
@@ -33,7 +33,7 @@ namespace Ingen {
*
* \ingroup engine
*/
-class LADSPANode : public NodeBase
+class LADSPANode : public NodeImpl
{
public:
LADSPANode(PluginImpl* plugin,
diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp
index a8892925..60bb2bbb 100644
--- a/src/engine/LV2Node.cpp
+++ b/src/engine/LV2Node.cpp
@@ -49,7 +49,7 @@ LV2Node::LV2Node(LV2Plugin* plugin,
bool polyphonic,
PatchImpl* parent,
SampleRate srate)
- : NodeBase(plugin, name, polyphonic, parent, srate)
+ : NodeImpl(plugin, name, polyphonic, parent, srate)
, _lv2_plugin(plugin)
, _instances(NULL)
, _prepared_instances(NULL)
@@ -71,7 +71,7 @@ LV2Node::prepare_poly(BufferFactory& bufs, uint32_t poly)
if (!_polyphonic)
poly = 1;
- NodeBase::prepare_poly(bufs, poly);
+ NodeImpl::prepare_poly(bufs, poly);
if (_polyphony == poly)
return true;
@@ -123,7 +123,7 @@ LV2Node::apply_poly(Raul::Maid& maid, uint32_t poly)
}
assert(poly <= _instances->size());
- return NodeBase::apply_poly(maid, poly);
+ return NodeImpl::apply_poly(maid, poly);
}
@@ -345,7 +345,7 @@ LV2Node::instantiate(BufferFactory& bufs)
void
LV2Node::activate(BufferFactory& bufs)
{
- NodeBase::activate(bufs);
+ NodeImpl::activate(bufs);
for (uint32_t i = 0; i < _polyphony; ++i)
slv2_instance_activate(instance(i));
@@ -355,7 +355,7 @@ LV2Node::activate(BufferFactory& bufs)
void
LV2Node::deactivate()
{
- NodeBase::deactivate();
+ NodeImpl::deactivate();
for (uint32_t i = 0; i < _polyphony; ++i)
slv2_instance_deactivate(instance(i));
@@ -382,12 +382,12 @@ LV2Node::message_run(MessageContext& context)
void
LV2Node::process(ProcessContext& context)
{
- NodeBase::pre_process(context);
+ NodeImpl::pre_process(context);
for (uint32_t i = 0; i < _polyphony; ++i)
slv2_instance_run(instance(i), context.nframes());
- NodeBase::post_process(context);
+ NodeImpl::post_process(context);
}
@@ -395,7 +395,7 @@ void
LV2Node::set_port_buffer(uint32_t voice, uint32_t port_num,
IntrusivePtr<Buffer> buf, SampleCount offset)
{
- NodeBase::set_port_buffer(voice, port_num, buf, offset);
+ NodeImpl::set_port_buffer(voice, port_num, buf, offset);
slv2_instance_connect_port(instance(voice), port_num,
buf ? buf->port_data(_ports->at(port_num)->type(), offset) : NULL);
}
diff --git a/src/engine/LV2Node.hpp b/src/engine/LV2Node.hpp
index 8b7a7bc3..dd3ce1b3 100644
--- a/src/engine/LV2Node.hpp
+++ b/src/engine/LV2Node.hpp
@@ -23,7 +23,7 @@
#include "raul/IntrusivePtr.hpp"
#include "contexts.lv2/contexts.h"
#include "types.hpp"
-#include "NodeBase.hpp"
+#include "NodeImpl.hpp"
#include "LV2Features.hpp"
namespace Ingen {
@@ -35,7 +35,7 @@ class LV2Plugin;
*
* \ingroup engine
*/
-class LV2Node : public NodeBase
+class LV2Node : public NodeImpl
{
public:
LV2Node(LV2Plugin* plugin,
diff --git a/src/engine/MessageContext.cpp b/src/engine/MessageContext.cpp
index 71700bbf..eec5acaa 100644
--- a/src/engine/MessageContext.cpp
+++ b/src/engine/MessageContext.cpp
@@ -15,6 +15,7 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "contexts.lv2/contexts.h"
#include "raul/log.hpp"
#include "raul/Atom.hpp"
#include "ConnectionImpl.hpp"
diff --git a/src/engine/NodeBase.cpp b/src/engine/NodeBase.cpp
deleted file mode 100644
index 967f7d3c..00000000
--- a/src/engine/NodeBase.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-/* This file is part of Ingen.
- * Copyright (C) 2007-2009 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
- */
-
-#include "NodeBase.hpp"
-#include <cassert>
-#include <stdint.h>
-#include "raul/List.hpp"
-#include "raul/Array.hpp"
-#include "util.hpp"
-#include "AudioBuffer.hpp"
-#include "ClientBroadcaster.hpp"
-#include "EngineStore.hpp"
-#include "PatchImpl.hpp"
-#include "PluginImpl.hpp"
-#include "PortImpl.hpp"
-#include "ThreadManager.hpp"
-
-using namespace std;
-
-namespace Ingen {
-
-
-NodeBase::NodeBase(PluginImpl* plugin, const Raul::Symbol& symbol, bool polyphonic, PatchImpl* parent, SampleRate srate)
- : NodeImpl(parent, symbol)
- , _plugin(plugin)
- , _polyphonic(polyphonic)
- , _polyphony((polyphonic && parent) ? parent->internal_poly() : 1)
- , _srate(srate)
- , _valid_ports(NULL)
- , _input_ready(1)
- , _process_lock(0)
- , _n_inputs_ready(0)
- , _ports(NULL)
- , _providers(new Raul::List<NodeImpl*>())
- , _dependants(new Raul::List<NodeImpl*>())
- , _activated(false)
- , _traversed(false)
-{
- assert(_plugin);
- assert(_polyphony > 0);
- assert(_parent == NULL || (_polyphony == parent->internal_poly() || _polyphony == 1));
-}
-
-
-NodeBase::~NodeBase()
-{
- if (_activated)
- deactivate();
-
- delete _providers;
- delete _dependants;
- delete _ports;
-
- free(_valid_ports);
-}
-
-
-Shared::Port*
-NodeBase::port(uint32_t index) const
-{
- return (*_ports)[index];
-}
-
-
-const Shared::Plugin*
-NodeBase::plugin() const
-{
- return _plugin;
-}
-
-
-void
-NodeBase::activate(BufferFactory& bufs)
-{
- ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- assert(!_activated);
- _activated = true;
-
- for (unsigned long p = 0; p < num_ports(); ++p) {
- PortImpl* const port = _ports->at(p);
- port->setup_buffers(bufs, port->poly());
- port->connect_buffers();
- for (uint32_t v = 0; v < _polyphony; ++v) {
- if (!port->buffer(v))
- continue;
- if (port->type() == PortType::CONTROL)
- ((AudioBuffer*)port->buffer(v).get())->set_value(port->value().get_float(), 0, 0);
- else
- port->buffer(v)->clear();
- }
- }
-}
-
-
-void
-NodeBase::deactivate()
-{
- assert(_activated);
- _activated = false;
- for (uint32_t i = 0; i < _polyphony; ++i) {
- for (unsigned long j = 0; j < num_ports(); ++j) {
- PortImpl* const port = _ports->at(j);
- if (port->is_output() && port->buffer(i))
- port->buffer(i)->clear();
- }
- }
-}
-
-
-bool
-NodeBase::prepare_poly(BufferFactory& bufs, uint32_t poly)
-{
- ThreadManager::assert_thread(THREAD_PRE_PROCESS);
-
- if (!_polyphonic)
- poly = 1;
-
- for (size_t i = 0; i < _ports->size(); ++i)
- _ports->at(i)->prepare_poly(bufs, poly);
-
- return true;
-}
-
-
-bool
-NodeBase::apply_poly(Raul::Maid& maid, uint32_t poly)
-{
- ThreadManager::assert_thread(THREAD_PROCESS);
-
- if (!_polyphonic)
- poly = 1;
-
- _polyphony = poly;
-
- for (size_t i = 0; i < num_ports(); ++i)
- _ports->at(i)->apply_poly(maid, poly);
-
- return true;
-}
-
-
-void
-NodeBase::set_buffer_size(Context& context, BufferFactory& bufs, PortType type, size_t size)
-{
- if (_ports)
- for (size_t i = 0; i < _ports->size(); ++i)
- if (_ports->at(i)->type() == type && _ports->at(i)->context() == context.id())
- _ports->at(i)->set_buffer_size(context, bufs, size);
-}
-
-
-void
-NodeBase::reset_input_ready()
-{
- _n_inputs_ready = 0;
- _process_lock = 0;
- _input_ready.reset(0);
-}
-
-
-bool
-NodeBase::process_lock()
-{
- return _process_lock.compare_and_exchange(0, 1);
-}
-
-
-void
-NodeBase::process_unlock()
-{
- _process_lock = 0;
-}
-
-
-void
-NodeBase::wait_for_input(size_t num_providers)
-{
- ThreadManager::assert_thread(THREAD_PROCESS);
- assert(_process_lock.get() == 1);
-
- while ((unsigned)_n_inputs_ready.get() < num_providers)
- _input_ready.wait();
-}
-
-
-void
-NodeBase::signal_input_ready()
-{
- ThreadManager::assert_thread(THREAD_PROCESS);
- ++_n_inputs_ready;
- _input_ready.post();
-}
-
-
-/** Prepare to run a cycle (in the audio thread)
- */
-void
-NodeBase::pre_process(Context& context)
-{
- ThreadManager::assert_thread(THREAD_PROCESS);
-
- // Mix down input ports
- for (uint32_t i = 0; i < num_ports(); ++i) {
- PortImpl* const port = _ports->at(i);
- if (port->context() == Context::AUDIO) {
- port->pre_process(context);
- port->connect_buffers(context.offset());
- }
- }
-}
-
-
-/** Prepare to run a cycle (in the audio thread)
- */
-void
-NodeBase::post_process(Context& context)
-{
- ThreadManager::assert_thread(THREAD_PROCESS);
-
- // Write output ports
- for (size_t i = 0; _ports && i < _ports->size(); ++i) {
- PortImpl* const port = _ports->at(i);
- if (port->context() == Context::AUDIO)
- _ports->at(i)->post_process(context);
- }
-}
-
-
-/** Flag a port as set (for message context)
- */
-void
-NodeBase::set_port_valid(uint32_t port_index)
-{
- // Allocate enough space for one bit per port
- if (!_valid_ports)
- _valid_ports = calloc(num_ports() / 8, 1);
- lv2_contexts_set_port_valid(_valid_ports, port_index);
-}
-
-
-void*
-NodeBase::valid_ports()
-{
- return _valid_ports;
-}
-
-
-void
-NodeBase::reset_valid_ports()
-{
- if (_valid_ports)
- memset(_valid_ports, '\0', num_ports() / 8);
-}
-
-
-void
-NodeBase::set_port_buffer(uint32_t voice, uint32_t port_num,
- BufferFactory::Ref buf, SampleCount offset)
-{
- /*std::cout << path() << " set port " << port_num << " voice " << voice
- << " buffer " << buf << " offset " << offset << std::endl;*/
-}
-
-
-} // namespace Ingen
-
diff --git a/src/engine/NodeBase.hpp b/src/engine/NodeBase.hpp
deleted file mode 100644
index baab7f50..00000000
--- a/src/engine/NodeBase.hpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/* This file is part of Ingen.
- * Copyright (C) 2007-2009 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 INGEN_ENGINE_NODEBASE_HPP
-#define INGEN_ENGINE_NODEBASE_HPP
-
-#include "types.hpp"
-#include <string>
-#include <cstdlib>
-#include "raul/Array.hpp"
-#include "raul/Atom.hpp"
-#include "raul/AtomicInt.hpp"
-#include "raul/IntrusivePtr.hpp"
-#include "raul/Semaphore.hpp"
-#include "contexts.lv2/contexts.h"
-#include "interface/Port.hpp"
-#include "interface/PortType.hpp"
-#include "NodeImpl.hpp"
-
-namespace Ingen {
-
-class Context;
-class EngineStore;
-class PatchImpl;
-class PluginImpl;
-class BufferFactory;
-
-namespace Shared { class ClientInterface; }
-
-
-/** Common implementation stuff for Node.
- *
- * \ingroup engine
- */
-class NodeBase : public NodeImpl
-{
-public:
- NodeBase(PluginImpl* plugin,
- const Raul::Symbol& symbol,
- bool poly,
- PatchImpl* parent,
- SampleRate rate);
-
- virtual ~NodeBase();
-
- virtual void activate(BufferFactory& bufs);
- virtual void deactivate();
- bool activated() { return _activated; }
-
- /** Flag node as polyphonic.
- *
- * Note this will not actually allocate voices etc., prepare_poly
- * and apply_poly must be called after this function to truly make
- * a node polyphonic.
- */
- virtual void set_polyphonic(bool p) { _polyphonic = p; }
-
- virtual bool prepare_poly(BufferFactory& bufs, uint32_t poly);
- virtual bool apply_poly(Raul::Maid& maid, uint32_t poly);
-
- virtual void reset_input_ready();
- virtual bool process_lock();
- virtual void process_unlock();
- virtual void wait_for_input(size_t num_providers);
- virtual unsigned n_inputs_ready() const { return _n_inputs_ready.get(); }
-
- virtual void learn() {}
-
- virtual void message_run(MessageContext& context) {}
-
- virtual void set_port_valid(uint32_t port_index);
-
- virtual void* valid_ports();
- virtual void reset_valid_ports();
-
- virtual void pre_process(Context& context);
- virtual void process(ProcessContext& context) = 0;
- virtual void post_process(Context& context);
-
- virtual void set_port_buffer(uint32_t voice, uint32_t port_num,
- IntrusivePtr<Buffer> buf, SampleCount offset);
-
- virtual void set_buffer_size(Context& context, BufferFactory& bufs,
- Shared::PortType type, size_t size);
-
- SampleRate sample_rate() const { return _srate; }
- uint32_t num_ports() const { return _ports ? _ports->size() : 0; }
- uint32_t polyphony() const { return _polyphony; }
- bool traversed() const { return _traversed; }
- void traversed(bool b) { _traversed = b; }
-
- virtual Shared::Port* port(uint32_t index) const;
- virtual PortImpl* port_impl(uint32_t index) const { return (*_ports)[index]; }
-
- /* These are NOT to be used in the audio thread!
- * The providers and dependants in CompiledNode are for that
- */
-
- Raul::List<NodeImpl*>* providers() { return _providers; }
- void providers(Raul::List<NodeImpl*>* l) { _providers = l; }
-
- Raul::List<NodeImpl*>* dependants() { return _dependants; }
- void dependants(Raul::List<NodeImpl*>* l) { _dependants = l; }
-
- virtual const Shared::Plugin* plugin() const;
- virtual PluginImpl* plugin_impl() const { return _plugin; }
- virtual void plugin(PluginImpl* pi) { _plugin = pi; }
-
- /** A node's parent is always a patch, so static cast should be safe */
- inline PatchImpl* parent_patch() const { return (PatchImpl*)_parent; }
-
-protected:
- virtual void signal_input_ready();
-
- PluginImpl* _plugin;
-
- bool _polyphonic;
- uint32_t _polyphony;
- SampleRate _srate;
-
- void* _valid_ports; ///< Valid port flags for message context
-
- Raul::Semaphore _input_ready; ///< Parallelism: input ready signal
- Raul::AtomicInt _process_lock; ///< Parallelism: Waiting on inputs 'lock'
- Raul::AtomicInt _n_inputs_ready; ///< Parallelism: # input ready signals this cycle
- Raul::Array<PortImpl*>* _ports; ///< Access in audio thread only
- Raul::List<NodeImpl*>* _providers; ///< Nodes connected to this one's input ports
- Raul::List<NodeImpl*>* _dependants; ///< Nodes this one's output ports are connected to
-
- bool _activated;
- bool _traversed; ///< Flag for process order algorithm
-};
-
-
-} // namespace Ingen
-
-#endif // INGEN_ENGINE_NODEBASE_HPP
diff --git a/src/engine/NodeImpl.hpp b/src/engine/NodeImpl.hpp
index 97724bfb..53e8b285 100644
--- a/src/engine/NodeImpl.hpp
+++ b/src/engine/NodeImpl.hpp
@@ -19,7 +19,10 @@
#define INGEN_ENGINE_NODEIMPL_HPP
#include <string>
+#include "raul/Array.hpp"
+#include "raul/AtomicInt.hpp"
#include "raul/IntrusivePtr.hpp"
+#include "raul/Semaphore.hpp"
#include "interface/Node.hpp"
#include "GraphObjectImpl.hpp"
#include "types.hpp"
@@ -28,7 +31,7 @@ namespace Raul { template <typename T> class List; class Maid; }
namespace Ingen {
-namespace Shared { class Plugin; class Node; class Port; }
+namespace Shared { class Plugin; class Port; }
class Buffer;
class BufferFactory;
@@ -45,72 +48,83 @@ class ProcessContext;
* A Node is a unit with input/output ports, a process() method, and some other
* things.
*
- * This is a pure abstract base class for any Node, it contains no
- * implementation details/data whatsoever. This is the interface you need to
- * implement to add a new Node type.
- *
* \ingroup engine
*/
class NodeImpl : public GraphObjectImpl, virtual public Ingen::Shared::Node
{
public:
- NodeImpl(GraphObjectImpl* parent, const Raul::Symbol& symbol)
- : GraphObjectImpl(parent, symbol)
- {}
+ NodeImpl(PluginImpl* plugin,
+ const Raul::Symbol& symbol,
+ bool poly,
+ PatchImpl* parent,
+ SampleRate rate);
+
+ virtual ~NodeImpl();
/** Activate this Node.
*
- * This function will be called in a non-realtime thread before it is
+ * This function must be called in a non-realtime thread before it is
* inserted in to a patch. Any non-realtime actions that need to be
* done before the Node is ready for use should be done here.
*/
- virtual void activate(BufferFactory& bufs) = 0;
- virtual void deactivate() = 0;
- virtual bool activated() = 0;
+ virtual void activate(BufferFactory& bufs);
- /** Parallelism: Reset flags for start of a new cycle.
+ /** Deactivate this Node.
+ *
+ * This function must be called in a non-realtime thread after the
+ * node has been removed from its patch (i.e. processing is finished).
*/
- virtual void reset_input_ready() = 0;
+ virtual void deactivate();
+
+ /** Return true iff this node is activated */
+ bool activated() { return _activated; }
+
+ /** Parallelism: Reset flags for start of a new cycle. */
+ virtual void reset_input_ready();
/** Parallelism: Claim this node (to wait on its input).
* Only one thread will ever take this lock on a particular Node.
* \return true if lock was aquired, false otherwise
*/
- virtual bool process_lock() = 0;
+ virtual bool process_lock();
/** Parallelism: Unclaim this node (let someone else wait on its input).
* Only a thread which successfully called process_lock may call this.
*/
- virtual void process_unlock() = 0;
+ virtual void process_unlock();
/** Parallelism: Wait for signal that input is ready.
* Only a thread which successfully called process_lock may call this.
*/
- virtual void wait_for_input(size_t num_providers) = 0;
+ virtual void wait_for_input(size_t num_providers);
/** Parallelism: Signal that input is ready. Realtime safe.
* Calling this will wake up the thread which blocked on wait_for_input
* if there is one, and otherwise cause it to return true the next call.
* \return true if lock was aquired and input is ready, false otherwise
*/
- virtual void signal_input_ready() = 0;
+ virtual void signal_input_ready();
- /** Parallelism: Return the number of providers that have signalled.
- */
- virtual unsigned n_inputs_ready() const = 0;
+ /** Parallelism: Return the number of providers that have signalled. */
+ virtual unsigned n_inputs_ready() const { return _n_inputs_ready.get(); }
- /** Run the node for one instant in the message thread.
- */
- virtual void message_run(MessageContext& context) = 0;
+ /** Learn the next incoming MIDI event (for internals) */
+ virtual void learn() {}
+
+ /** Run the node for one instant in the message thread. */
+ virtual void message_run(MessageContext& context) {}
/** Flag a port as valid (for message context) */
- virtual void set_port_valid(uint32_t index) = 0;
+ virtual void set_port_valid(uint32_t index);
/** Return a bit vector of which ports are valid */
- virtual void* valid_ports() = 0;
+ virtual void* valid_ports();
/** Clear all bits in valid_ports() */
- virtual void reset_valid_ports() = 0;
+ virtual void reset_valid_ports();
+
+ /** Do whatever needs doing in the process thread before process() is called */
+ virtual void pre_process(Context& context);
/** Run the node for @a nframes input/output.
*
@@ -119,45 +133,86 @@ public:
*/
virtual void process(ProcessContext& context) = 0;
- virtual void set_port_buffer(uint32_t voice, uint32_t port_num,
- IntrusivePtr<Buffer> buf, SampleCount offset) = 0;
-
- virtual uint32_t num_ports() const = 0;
+ /** Do whatever needs doing in the process thread after process() is called */
+ virtual void post_process(Context& context);
- virtual Shared::Port* port(uint32_t index) const = 0;
- virtual PortImpl* port_impl(uint32_t index) const = 0;
+ /** Set the buffer of a port to a given buffer (e.g. connect plugin to buffer) */
+ virtual void set_port_buffer(
+ uint32_t voice,
+ uint32_t port_num,
+ IntrusivePtr<Buffer> buf,
+ SampleCount offset);
- /** Used by the process order finding algorithm (ie during connections) */
- virtual bool traversed() const = 0;
- virtual void traversed(bool b) = 0;
+ virtual Shared::Port* port(uint32_t index) const;
+ virtual PortImpl* port_impl(uint32_t index) const { return (*_ports)[index]; }
/** Nodes that are connected to this Node's inputs.
* (This Node depends on them)
*/
- virtual Raul::List<NodeImpl*>* providers() = 0;
- virtual void providers(Raul::List<NodeImpl*>* l) = 0;
+ Raul::List<NodeImpl*>* providers() { return _providers; }
+ void providers(Raul::List<NodeImpl*>* l) { _providers = l; }
/** Nodes are are connected to this Node's outputs.
* (They depend on this Node)
*/
- virtual Raul::List<NodeImpl*>* dependants() = 0;
- virtual void dependants(Raul::List<NodeImpl*>* l) = 0;
+ Raul::List<NodeImpl*>* dependants() { return _dependants; }
+ void dependants(Raul::List<NodeImpl*>* l) { _dependants = l; }
- /** The Patch this Node belongs to. */
- virtual PatchImpl* parent_patch() const = 0;
+ /** Flag node as polyphonic.
+ *
+ * Note this will not actually allocate voices etc., prepare_poly
+ * and apply_poly must be called after this function to truly make
+ * a node polyphonic.
+ */
+ virtual void set_polyphonic(bool p) { _polyphonic = p; }
+
+ virtual bool prepare_poly(BufferFactory& bufs, uint32_t poly);
+ virtual bool apply_poly(Raul::Maid& maid, uint32_t poly);
/** Information about the Plugin this Node is an instance of.
* Not the best name - not all nodes come from plugins (ie Patch)
*/
- virtual PluginImpl* plugin_impl() const = 0;
+ virtual PluginImpl* plugin_impl() const { return _plugin; }
/** Information about the Plugin this Node is an instance of.
* Not the best name - not all nodes come from plugins (ie Patch)
*/
- virtual const Shared::Plugin* plugin() const = 0;
+ virtual const Shared::Plugin* plugin() const;
+
+ virtual void plugin(PluginImpl* pi) { _plugin = pi; }
virtual void set_buffer_size(Context& context, BufferFactory& bufs,
- Shared::PortType type, size_t size) = 0;
+ Shared::PortType type, size_t size);
+
+ /** The Patch this Node belongs to. */
+ inline PatchImpl* parent_patch() const { return (PatchImpl*)_parent; }
+
+ SampleRate sample_rate() const { return _srate; }
+ virtual uint32_t num_ports() const { return _ports ? _ports->size() : 0; }
+ virtual uint32_t polyphony() const { return _polyphony; }
+
+ /** Used by the process order finding algorithm (ie during connections) */
+ bool traversed() const { return _traversed; }
+ void traversed(bool b) { _traversed = b; }
+
+protected:
+ PluginImpl* _plugin;
+
+ bool _polyphonic;
+ uint32_t _polyphony;
+ SampleRate _srate;
+
+ void* _valid_ports; ///< Valid port flags for message context
+
+ Raul::Semaphore _input_ready; ///< Parallelism: input ready signal
+ Raul::AtomicInt _process_lock; ///< Parallelism: Waiting on inputs 'lock'
+ Raul::AtomicInt _n_inputs_ready; ///< Parallelism: # input ready signals this cycle
+ Raul::Array<PortImpl*>* _ports; ///< Access in audio thread only
+ Raul::List<NodeImpl*>* _providers; ///< Nodes connected to this one's input ports
+ Raul::List<NodeImpl*>* _dependants; ///< Nodes this one's output ports are connected to
+
+ bool _activated;
+ bool _traversed; ///< Flag for process order algorithm
};
diff --git a/src/engine/PatchImpl.cpp b/src/engine/PatchImpl.cpp
index a7b9c699..6b31532a 100644
--- a/src/engine/PatchImpl.cpp
+++ b/src/engine/PatchImpl.cpp
@@ -39,7 +39,7 @@ using namespace Shared;
PatchImpl::PatchImpl(Engine& engine, const Raul::Symbol& symbol, uint32_t poly, PatchImpl* parent, SampleRate srate, uint32_t internal_poly)
- : NodeBase(new PatchPlugin("http://example.org/FIXME", "patch", "Ingen Patch"),
+ : NodeImpl(new PatchPlugin("http://example.org/FIXME", "patch", "Ingen Patch"),
symbol, poly, parent, srate)
, _engine(engine)
, _internal_poly(internal_poly)
@@ -62,7 +62,7 @@ PatchImpl::~PatchImpl()
void
PatchImpl::activate(BufferFactory& bufs)
{
- NodeBase::activate(bufs);
+ NodeImpl::activate(bufs);
for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i)
(*i)->activate(bufs);
@@ -76,7 +76,7 @@ PatchImpl::deactivate()
{
if (_activated) {
- NodeBase::deactivate();
+ NodeImpl::deactivate();
for (List<NodeImpl*>::iterator i = _nodes.begin(); i != _nodes.end(); ++i) {
if ((*i)->activated())
@@ -160,7 +160,7 @@ PatchImpl::process(ProcessContext& context)
if (!_process)
return;
- NodeBase::pre_process(context);
+ NodeImpl::pre_process(context);
// Run all nodes
if (_compiled_patch && _compiled_patch->size() > 0) {
@@ -180,7 +180,7 @@ PatchImpl::process(ProcessContext& context)
}
}
- NodeBase::post_process(context);
+ NodeImpl::post_process(context);
}
@@ -263,7 +263,7 @@ PatchImpl::process_single(ProcessContext& context)
void
PatchImpl::set_buffer_size(Context& context, BufferFactory& bufs, PortType type, size_t size)
{
- NodeBase::set_buffer_size(context, bufs, type, size);
+ NodeImpl::set_buffer_size(context, bufs, type, size);
for (size_t i = 0; i < _compiled_patch->size(); ++i)
(*_compiled_patch)[i].node()->set_buffer_size(context, bufs, type, size);
@@ -349,7 +349,7 @@ PatchImpl::num_ports() const
ThreadID context = ThreadManager::current_thread_id();
if (context == THREAD_PROCESS)
- return NodeBase::num_ports();
+ return NodeImpl::num_ports();
else
return _input_ports.size() + _output_ports.size();
}
diff --git a/src/engine/PatchImpl.hpp b/src/engine/PatchImpl.hpp
index a8392aca..ff2f0631 100644
--- a/src/engine/PatchImpl.hpp
+++ b/src/engine/PatchImpl.hpp
@@ -23,7 +23,7 @@
#include "raul/List.hpp"
#include "interface/PortType.hpp"
#include "interface/Patch.hpp"
-#include "NodeBase.hpp"
+#include "NodeImpl.hpp"
#include "PluginImpl.hpp"
#include "CompiledPatch.hpp"
@@ -46,7 +46,7 @@ class ProcessContext;
*
* \ingroup engine
*/
-class PatchImpl : public NodeBase, public Ingen::Shared::Patch
+class PatchImpl : public NodeImpl, public Ingen::Shared::Patch
{
public:
PatchImpl(Engine& engine,
diff --git a/src/engine/events/CreatePort.cpp b/src/engine/events/CreatePort.cpp
index 7d8f9d16..4aebc0b2 100644
--- a/src/engine/events/CreatePort.cpp
+++ b/src/engine/events/CreatePort.cpp
@@ -62,7 +62,7 @@ CreatePort::CreatePort(
, _properties(properties)
{
/* This is blocking because of the two different sets of Patch ports, the array used in the
- * audio thread (inherited from NodeBase), and the arrays used in the pre processor thread.
+ * audio thread (inherited from NodeImpl), and the arrays used in the pre processor thread.
* If two add port events arrive in the same cycle and the second pre processes before the
* first executes, bad things happen (ports are lost).
*
diff --git a/src/engine/events/Delete.cpp b/src/engine/events/Delete.cpp
index 31e249f5..9e4548ac 100644
--- a/src/engine/events/Delete.cpp
+++ b/src/engine/events/Delete.cpp
@@ -24,7 +24,7 @@
#include "Driver.hpp"
#include "Engine.hpp"
#include "EngineStore.hpp"
-#include "NodeBase.hpp"
+#include "NodeImpl.hpp"
#include "PatchImpl.hpp"
#include "PluginImpl.hpp"
#include "PortImpl.hpp"
diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp
index 4de74eac..c1cc97f0 100644
--- a/src/engine/events/SetMetadata.cpp
+++ b/src/engine/events/SetMetadata.cpp
@@ -231,7 +231,7 @@ SetMetadata::pre_process()
op = POLYPHONIC;
_blocking = true;
obj->set_property(key, value.get_bool());
- NodeBase* node = dynamic_cast<NodeBase*>(obj);
+ NodeImpl* node = dynamic_cast<NodeImpl*>(obj);
if (node)
node->set_polyphonic(value.get_bool());
if (value.get_bool()) {
@@ -280,7 +280,7 @@ SetMetadata::execute(ProcessContext& context)
(*i)->execute(context);
GraphObjectImpl* const object = dynamic_cast<GraphObjectImpl*>(_object);
- NodeBase* const node = dynamic_cast<NodeBase*>(_object);
+ NodeImpl* const node = dynamic_cast<NodeImpl*>(_object);
PortImpl* const port = dynamic_cast<PortImpl*>(_object);
std::vector<SpecialType>::const_iterator t = _types.begin();
diff --git a/src/engine/internals/Controller.cpp b/src/engine/internals/Controller.cpp
index 870dfc8e..aeeb1cd1 100644
--- a/src/engine/internals/Controller.cpp
+++ b/src/engine/internals/Controller.cpp
@@ -45,7 +45,7 @@ ControllerNode::ControllerNode(BufferFactory& bufs,
bool polyphonic,
PatchImpl* parent,
SampleRate srate)
- : NodeBase(&controller_plugin, path, false, parent, srate)
+ : NodeImpl(&controller_plugin, path, false, parent, srate)
, _learning(false)
{
const LV2URIMap& uris = Shared::LV2URIMap::instance();
@@ -84,7 +84,7 @@ ControllerNode::ControllerNode(BufferFactory& bufs,
void
ControllerNode::process(ProcessContext& context)
{
- NodeBase::pre_process(context);
+ NodeImpl::pre_process(context);
uint32_t frames = 0;
uint32_t subframes = 0;
@@ -104,7 +104,7 @@ ControllerNode::process(ProcessContext& context)
midi_in->increment();
}
- NodeBase::post_process(context);
+ NodeImpl::post_process(context);
}
diff --git a/src/engine/internals/Controller.hpp b/src/engine/internals/Controller.hpp
index b6d7302f..b3363665 100644
--- a/src/engine/internals/Controller.hpp
+++ b/src/engine/internals/Controller.hpp
@@ -19,7 +19,7 @@
#define INGEN_INTERNALS_CONTROLLER_HPP
#include <string>
-#include "NodeBase.hpp"
+#include "NodeImpl.hpp"
namespace Ingen {
@@ -37,7 +37,7 @@ namespace Internals {
*
* \ingroup engine
*/
-class ControllerNode : public NodeBase
+class ControllerNode : public NodeImpl
{
public:
ControllerNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate);
diff --git a/src/engine/internals/Delay.cpp b/src/engine/internals/Delay.cpp
index 202ba616..7910713f 100644
--- a/src/engine/internals/Delay.cpp
+++ b/src/engine/internals/Delay.cpp
@@ -54,7 +54,7 @@ static InternalPlugin note_plugin(NS_INTERNALS "Delay", "delay");
InternalPlugin& DelayNode::internal_plugin() { return note_plugin; }
DelayNode::DelayNode(BufferFactory& bufs, const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate)
- : NodeBase(&note_plugin, path, polyphonic, parent, srate)
+ : NodeImpl(&note_plugin, path, polyphonic, parent, srate)
, _buffer(0)
, _buffer_length(0)
, _buffer_mask(0)
@@ -97,7 +97,7 @@ DelayNode::~DelayNode()
void
DelayNode::activate(BufferFactory& bufs)
{
- NodeBase::activate(bufs);
+ NodeImpl::activate(bufs);
const SampleCount min_size = MAX_DELAY_SECONDS * _srate;
// Smallest power of two larger than min_size
@@ -142,7 +142,7 @@ DelayNode::process(ProcessContext& context)
AudioBuffer* const in_buf = (AudioBuffer*)_in_port->buffer(0).get();
AudioBuffer* const out_buf = (AudioBuffer*)_out_port->buffer(0).get();
- NodeBase::pre_process(context);
+ NodeImpl::pre_process(context);
DelayNode* plugin_data = this;
@@ -199,7 +199,7 @@ DelayNode::process(ProcessContext& context)
_write_phase = write_phase;
- NodeBase::post_process(context);
+ NodeImpl::post_process(context);
}
diff --git a/src/engine/internals/Delay.hpp b/src/engine/internals/Delay.hpp
index 077c65f9..758d32e7 100644
--- a/src/engine/internals/Delay.hpp
+++ b/src/engine/internals/Delay.hpp
@@ -23,7 +23,7 @@
#include "types.hpp"
//#include "Buffer.hpp"
//#include "BufferFactory.hpp"
-#include "NodeBase.hpp"
+#include "NodeImpl.hpp"
namespace Ingen {
@@ -41,7 +41,7 @@ namespace Internals {
*
* \ingroup engine
*/
-class DelayNode : public NodeBase
+class DelayNode : public NodeImpl
{
public:
DelayNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate);
diff --git a/src/engine/internals/Note.cpp b/src/engine/internals/Note.cpp
index fd2dee71..298af84a 100644
--- a/src/engine/internals/Note.cpp
+++ b/src/engine/internals/Note.cpp
@@ -48,7 +48,7 @@ static InternalPlugin note_plugin(NS_INTERNALS "Note", "note");
InternalPlugin& NoteNode::internal_plugin() { return note_plugin; }
NoteNode::NoteNode(BufferFactory& bufs, const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate)
- : NodeBase(&note_plugin, path, polyphonic, parent, srate)
+ : NodeImpl(&note_plugin, path, polyphonic, parent, srate)
, _voices(new Raul::Array<Voice>(_polyphony))
, _prepared_voices(NULL)
, _sustain(false)
@@ -94,7 +94,7 @@ NoteNode::prepare_poly(BufferFactory& bufs, uint32_t poly)
if (!_polyphonic)
return true;
- NodeBase::prepare_poly(bufs, poly);
+ NodeImpl::prepare_poly(bufs, poly);
if (_prepared_voices && poly <= _prepared_voices->size())
return true;
@@ -108,7 +108,7 @@ NoteNode::prepare_poly(BufferFactory& bufs, uint32_t poly)
bool
NoteNode::apply_poly(Raul::Maid& maid, uint32_t poly)
{
- if (!NodeBase::apply_poly(maid, poly))
+ if (!NodeImpl::apply_poly(maid, poly))
return false;
if (_prepared_voices) {
@@ -127,7 +127,7 @@ void
NoteNode::process(ProcessContext& context)
{
EventBuffer* const midi_in = (EventBuffer*)_midi_in_port->buffer(0).get();
- NodeBase::pre_process(context);
+ NodeImpl::pre_process(context);
uint32_t frames = 0;
uint32_t subframes = 0;
@@ -195,7 +195,7 @@ NoteNode::process(ProcessContext& context)
}
}
- NodeBase::post_process(context);
+ NodeImpl::post_process(context);
}
diff --git a/src/engine/internals/Note.hpp b/src/engine/internals/Note.hpp
index 8ad7f452..2866fb01 100644
--- a/src/engine/internals/Note.hpp
+++ b/src/engine/internals/Note.hpp
@@ -20,7 +20,7 @@
#include <string>
#include "types.hpp"
-#include "NodeBase.hpp"
+#include "NodeImpl.hpp"
namespace Ingen {
@@ -37,7 +37,7 @@ namespace Internals {
*
* \ingroup engine
*/
-class NoteNode : public NodeBase
+class NoteNode : public NodeImpl
{
public:
NoteNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate);
diff --git a/src/engine/internals/Trigger.cpp b/src/engine/internals/Trigger.cpp
index c8d6b77e..ed3b2d90 100644
--- a/src/engine/internals/Trigger.cpp
+++ b/src/engine/internals/Trigger.cpp
@@ -44,7 +44,7 @@ static InternalPlugin trigger_plugin(NS_INTERNALS "Trigger", "trigger");
InternalPlugin& TriggerNode::internal_plugin() { return trigger_plugin; }
TriggerNode::TriggerNode(BufferFactory& bufs, const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate)
- : NodeBase(&trigger_plugin, path, false, parent, srate)
+ : NodeImpl(&trigger_plugin, path, false, parent, srate)
, _learning(false)
{
const LV2URIMap& uris = LV2URIMap::instance();
@@ -82,7 +82,7 @@ TriggerNode::TriggerNode(BufferFactory& bufs, const string& path, bool polyphoni
void
TriggerNode::process(ProcessContext& context)
{
- NodeBase::pre_process(context);
+ NodeImpl::pre_process(context);
uint32_t frames = 0;
uint32_t subframes = 0;
@@ -120,7 +120,7 @@ TriggerNode::process(ProcessContext& context)
midi_in->increment();
}
- NodeBase::post_process(context);
+ NodeImpl::post_process(context);
}
diff --git a/src/engine/internals/Trigger.hpp b/src/engine/internals/Trigger.hpp
index 53aba06f..5513f6d8 100644
--- a/src/engine/internals/Trigger.hpp
+++ b/src/engine/internals/Trigger.hpp
@@ -19,7 +19,7 @@
#define INGEN_INTERNALS_TRIGGER_HPP
#include <string>
-#include "NodeBase.hpp"
+#include "NodeImpl.hpp"
namespace Ingen {
@@ -40,7 +40,7 @@ namespace Internals {
*
* \ingroup engine
*/
-class TriggerNode : public NodeBase
+class TriggerNode : public NodeImpl
{
public:
TriggerNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate);
diff --git a/src/engine/wscript b/src/engine/wscript
index b551a5bc..39ac47d5 100644
--- a/src/engine/wscript
+++ b/src/engine/wscript
@@ -22,8 +22,8 @@ def build(bld):
InputPort.cpp
InternalPlugin.cpp
MessageContext.cpp
- NodeBase.cpp
NodeFactory.cpp
+ NodeImpl.cpp
ObjectBuffer.cpp
ObjectSender.cpp
OutputPort.cpp