summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/DuplexPort.cpp14
-rw-r--r--src/server/DuplexPort.hpp8
-rw-r--r--src/server/InputPort.cpp24
-rw-r--r--src/server/InputPort.hpp8
-rw-r--r--src/server/OutputPort.cpp12
-rw-r--r--src/server/OutputPort.hpp8
-rw-r--r--src/server/PortImpl.cpp82
-rw-r--r--src/server/PortImpl.hpp92
-rw-r--r--src/server/events/Connect.cpp8
-rw-r--r--src/server/events/Connect.hpp24
-rw-r--r--src/server/events/Disconnect.cpp16
-rw-r--r--src/server/events/Disconnect.hpp10
12 files changed, 147 insertions, 159 deletions
diff --git a/src/server/DuplexPort.cpp b/src/server/DuplexPort.cpp
index 0e19e939..439d40ef 100644
--- a/src/server/DuplexPort.cpp
+++ b/src/server/DuplexPort.cpp
@@ -88,15 +88,15 @@ DuplexPort::inherit_neighbour(const PortImpl* port,
}
bool
-DuplexPort::get_buffers(BufferFactory& bufs,
- Raul::Array<BufferRef>* buffers,
- uint32_t poly,
- bool real_time) const
+DuplexPort::get_buffers(BufferFactory& bufs,
+ Raul::Array<Voice>* voices,
+ uint32_t poly,
+ bool real_time) const
{
if (_is_output) {
- return InputPort::get_buffers(bufs, buffers, poly, real_time);
+ return InputPort::get_buffers(bufs, voices, poly, real_time);
} else {
- return OutputPort::get_buffers(bufs, buffers, poly, real_time);
+ return OutputPort::get_buffers(bufs, voices, poly, real_time);
}
}
@@ -115,7 +115,7 @@ DuplexPort::pre_process(Context& context)
perspective. Prepare buffers for write so plugins can deliver to
them */
for (uint32_t v = 0; v < _poly; ++v) {
- _buffers->at(v)->prepare_write(context);
+ _voices->at(v).buffer->prepare_write(context);
}
} else {
/* This is a a graph input, which is an output from the internal
diff --git a/src/server/DuplexPort.hpp b/src/server/DuplexPort.hpp
index 725c09c7..46ab18bf 100644
--- a/src/server/DuplexPort.hpp
+++ b/src/server/DuplexPort.hpp
@@ -62,10 +62,10 @@ public:
uint32_t max_tail_poly(Context& context) const;
- bool get_buffers(BufferFactory& bufs,
- Raul::Array<BufferRef>* buffers,
- uint32_t poly,
- bool real_time) const;
+ bool get_buffers(BufferFactory& bufs,
+ Raul::Array<Voice>* voices,
+ uint32_t poly,
+ bool real_time) const;
void pre_process(Context& context);
void post_process(Context& context);
diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp
index 34c71116..f1be3b8f 100644
--- a/src/server/InputPort.cpp
+++ b/src/server/InputPort.cpp
@@ -68,26 +68,26 @@ InputPort::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly)
if (!ret)
poly = 1;
- assert(_buffers->size() >= poly);
+ assert(_voices->size() >= poly);
return true;
}
-/** Set @a buffers to the buffers to be used for this port.
+/** Set the buffers of @p voices to the buffers to be used for this port.
* @return true iff buffers are locally owned by the port
*/
bool
-InputPort::get_buffers(BufferFactory& bufs,
- Raul::Array<BufferRef>* buffers,
- uint32_t poly,
- bool real_time) const
+InputPort::get_buffers(BufferFactory& bufs,
+ Raul::Array<Voice>* voices,
+ uint32_t poly,
+ bool real_time) const
{
const size_t num_arcs = real_time ? _arcs.size() : _num_arcs;
if (is_a(PortType::AUDIO) && num_arcs == 0) {
// Audio input with no arcs, use shared zero buffer
for (uint32_t v = 0; v < poly; ++v) {
- buffers->at(v) = bufs.silent_buffer();
+ voices->at(v).buffer = bufs.silent_buffer();
}
return false;
@@ -96,7 +96,7 @@ InputPort::get_buffers(BufferFactory& bufs,
if (!_arcs.front().must_mix()) {
// Single non-mixing connection, use buffers directly
for (uint32_t v = 0; v < poly; ++v) {
- buffers->at(v) = _arcs.front().buffer(v);
+ voices->at(v).buffer = _arcs.front().buffer(v);
}
return false;
}
@@ -105,9 +105,9 @@ InputPort::get_buffers(BufferFactory& bufs,
// Otherwise, allocate local buffers
for (uint32_t v = 0; v < poly; ++v) {
- buffers->at(v).reset();
- buffers->at(v) = bufs.get_buffer(buffer_type(), _buffer_size, real_time);
- buffers->at(v)->clear();
+ voices->at(v).buffer.reset();
+ voices->at(v).buffer = bufs.get_buffer(buffer_type(), _buffer_size, real_time);
+ voices->at(v).buffer->clear();
}
return true;
}
@@ -194,7 +194,7 @@ InputPort::pre_process(Context& context)
}
} else if (direct_connect()) {
for (uint32_t v = 0; v < _poly; ++v) {
- _buffers->at(v) = _arcs.front().buffer(v);
+ _voices->at(v).buffer = _arcs.front().buffer(v);
}
} else {
const uint32_t src_poly = max_tail_poly(context);
diff --git a/src/server/InputPort.hpp b/src/server/InputPort.hpp
index 43a182e4..da0d9327 100644
--- a/src/server/InputPort.hpp
+++ b/src/server/InputPort.hpp
@@ -75,10 +75,10 @@ public:
bool apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly);
- bool get_buffers(BufferFactory& bufs,
- Raul::Array<BufferRef>* buffers,
- uint32_t poly,
- bool real_time) const;
+ bool get_buffers(BufferFactory& bufs,
+ Raul::Array<Voice>* voices,
+ uint32_t poly,
+ bool real_time) const;
void pre_process(Context& context);
void post_process(Context& context);
diff --git a/src/server/OutputPort.cpp b/src/server/OutputPort.cpp
index 881c6782..9f97930e 100644
--- a/src/server/OutputPort.cpp
+++ b/src/server/OutputPort.cpp
@@ -46,13 +46,13 @@ OutputPort::OutputPort(BufferFactory& bufs,
}
bool
-OutputPort::get_buffers(BufferFactory& bufs,
- Raul::Array<BufferRef>* buffers,
- uint32_t poly,
- bool real_time) const
+OutputPort::get_buffers(BufferFactory& bufs,
+ Raul::Array<Voice>* voices,
+ uint32_t poly,
+ bool real_time) const
{
for (uint32_t v = 0; v < poly; ++v)
- buffers->at(v) = bufs.get_buffer(buffer_type(), _buffer_size, real_time);
+ voices->at(v).buffer = bufs.get_buffer(buffer_type(), _buffer_size, real_time);
return true;
}
@@ -61,7 +61,7 @@ void
OutputPort::pre_process(Context& context)
{
for (uint32_t v = 0; v < _poly; ++v)
- _buffers->at(v)->prepare_output_write(context);
+ _voices->at(v).buffer->prepare_output_write(context);
}
void
diff --git a/src/server/OutputPort.hpp b/src/server/OutputPort.hpp
index 1fe8c957..92ed8428 100644
--- a/src/server/OutputPort.hpp
+++ b/src/server/OutputPort.hpp
@@ -50,10 +50,10 @@ public:
virtual ~OutputPort() {}
- bool get_buffers(BufferFactory& bufs,
- Raul::Array<BufferRef>* buffers,
- uint32_t poly,
- bool real_time) const;
+ bool get_buffers(BufferFactory& bufs,
+ Raul::Array<Voice>* voices,
+ uint32_t poly,
+ bool real_time) const;
void pre_process(Context& context);
void post_process(Context& context);
diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp
index e05aa1ce..e4b3ad4d 100644
--- a/src/server/PortImpl.cpp
+++ b/src/server/PortImpl.cpp
@@ -65,10 +65,8 @@ PortImpl::PortImpl(BufferFactory& bufs,
, _value(value)
, _min(bufs.forge().make(0.0f))
, _max(bufs.forge().make(1.0f))
- , _set_states(new Raul::Array<SetState>(static_cast<size_t>(poly)))
- , _prepared_set_states(NULL)
- , _buffers(new Raul::Array<BufferRef>(static_cast<size_t>(poly)))
- , _prepared_buffers(NULL)
+ , _voices(new Raul::Array<Voice>(static_cast<size_t>(poly)))
+ , _prepared_voices(NULL)
, _monitored(false)
, _set_by_user(false)
, _is_morph(false)
@@ -97,8 +95,7 @@ PortImpl::PortImpl(BufferFactory& bufs,
PortImpl::~PortImpl()
{
- delete _set_states;
- delete _buffers;
+ delete _voices;
}
void
@@ -164,8 +161,8 @@ PortImpl::deactivate()
{
if (is_output()) {
for (uint32_t v = 0; v < _poly; ++v) {
- if (_buffers->at(v)) {
- _buffers->at(v)->clear();
+ if (_voices->at(v).buffer) {
+ _voices->at(v).buffer->clear();
}
}
}
@@ -173,13 +170,13 @@ PortImpl::deactivate()
_peak = 0.0f;
}
-Raul::Array<BufferRef>*
-PortImpl::set_buffers(ProcessContext& context, Raul::Array<BufferRef>* buffers)
+Raul::Array<PortImpl::Voice>*
+PortImpl::set_voices(ProcessContext& context, Raul::Array<Voice>* voices)
{
- Raul::Array<BufferRef>* ret = NULL;
- if (buffers != _buffers) {
- ret = _buffers;
- _buffers = buffers;
+ Raul::Array<Voice>* ret = NULL;
+ if (voices != _voices) {
+ ret = _voices;
+ _voices = voices;
}
connect_buffers();
@@ -217,7 +214,7 @@ PortImpl::set_voice_value(const Context& context,
switch (_type.id()) {
case PortType::CONTROL:
buffer(voice)->samples()[0] = value;
- _set_states->at(voice).state = SetState::State::SET;
+ _voices->at(voice).set_state.state = SetState::State::SET;
break;
case PortType::AUDIO:
case PortType::CV: {
@@ -233,7 +230,7 @@ PortImpl::set_voice_value(const Context& context,
value for the next block, particularly for triggers on the last
frame of a block (set nframes-1 to 1, then nframes to 0). */
- SetState& state = _set_states->at(voice);
+ SetState& state = _voices->at(voice).set_state;
state.state = (offset == 0)
? SetState::State::SET
: SetState::State::HALF_SET_CYCLE_1;
@@ -248,7 +245,7 @@ PortImpl::set_voice_value(const Context& context,
void
PortImpl::update_set_state(Context& context, uint32_t voice)
{
- SetState& state = _set_states->at(voice);
+ SetState& state = _voices->at(voice).set_state;
switch (state.state) {
case SetState::State::SET:
break;
@@ -276,25 +273,17 @@ PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly)
return true;
}
- if (_prepared_buffers && _prepared_buffers->size() != poly) {
- delete _prepared_buffers;
- _prepared_buffers = NULL;
+ if (_prepared_voices && _prepared_voices->size() != poly) {
+ delete _prepared_voices;
+ _prepared_voices = NULL;
}
- if (_prepared_set_states && _prepared_set_states->size() != poly) {
- delete _prepared_set_states;
- _prepared_set_states = NULL;
- }
-
- if (!_prepared_buffers)
- _prepared_buffers = new Raul::Array<BufferRef>(poly, *_buffers, NULL);
-
- if (!_prepared_set_states)
- _prepared_set_states = new Raul::Array<SetState>(poly, *_set_states, SetState());
+ if (!_prepared_voices)
+ _prepared_voices = new Raul::Array<Voice>(poly, *_voices, Voice());
get_buffers(bufs,
- _prepared_buffers,
- _prepared_buffers->size(),
+ _prepared_voices,
+ _prepared_voices->size(),
false);
return true;
@@ -309,33 +298,26 @@ PortImpl::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly)
return false;
}
- if (!_prepared_buffers) {
+ if (!_prepared_voices) {
return true;
}
- assert(poly == _prepared_buffers->size());
- assert(poly == _prepared_set_states->size());
+ assert(poly == _prepared_voices->size());
_poly = poly;
- // Apply a new set of buffers from a preceding call to prepare_poly
- maid.dispose(set_buffers(context, _prepared_buffers));
- assert(_buffers == _prepared_buffers);
- _prepared_buffers = NULL;
-
- maid.dispose(_set_states);
- _set_states = _prepared_set_states;
- _prepared_set_states = NULL;
+ // Apply a new set of voices from a preceding call to prepare_poly
+ maid.dispose(set_voices(context, _prepared_voices));
+ assert(_voices == _prepared_voices);
+ _prepared_voices = NULL;
if (is_a(PortType::CONTROL) || is_a(PortType::CV)) {
set_control_value(context, context.start(), _value.get<float>());
}
- assert(_buffers->size() >= poly);
- assert(_set_states->size() >= poly);
+ assert(_voices->size() >= poly);
assert(this->poly() == poly);
- assert(!_prepared_buffers);
- assert(!_prepared_set_states);
+ assert(!_prepared_voices);
return true;
}
@@ -346,7 +328,7 @@ PortImpl::set_buffer_size(Context& context, BufferFactory& bufs, size_t size)
_buffer_size = size;
for (uint32_t v = 0; v < _poly; ++v)
- _buffers->at(v)->resize(size);
+ _voices->at(v).buffer->resize(size);
connect_buffers();
}
@@ -362,7 +344,7 @@ void
PortImpl::recycle_buffers()
{
for (uint32_t v = 0; v < _poly; ++v)
- _buffers->at(v) = NULL;
+ _voices->at(v).buffer = NULL;
}
void
@@ -375,7 +357,7 @@ PortImpl::clear_buffers()
for (uint32_t v = 0; v < _poly; ++v) {
Buffer* buf = buffer(v).get();
buf->set_block(_value.get<float>(), 0, buf->nframes());
- SetState& state = _set_states->at(v);
+ SetState& state = _voices->at(v).set_state;
state.state = SetState::State::SET;
state.value = _value.get<float>();
state.time = 0;
diff --git a/src/server/PortImpl.hpp b/src/server/PortImpl.hpp
index 8e6c8e77..4dd1afb3 100644
--- a/src/server/PortImpl.hpp
+++ b/src/server/PortImpl.hpp
@@ -43,6 +43,23 @@ class BufferFactory;
class PortImpl : public NodeImpl
{
public:
+ struct SetState {
+ enum class State { SET, HALF_SET_CYCLE_1, HALF_SET_CYCLE_2 };
+
+ SetState() : state(State::SET), value(0), time(0) {}
+
+ State state; ///< State of buffer for setting control value
+ Sample value; ///< Value currently being set
+ FrameTime time; ///< Time value was set
+ };
+
+ struct Voice {
+ Voice() : buffer(NULL) {}
+
+ SetState set_state;
+ BufferRef buffer;
+ };
+
~PortImpl();
virtual GraphType graph_type() const { return GraphType::PORT; }
@@ -55,8 +72,8 @@ public:
* Audio thread. Returned value must be freed by caller.
* \a buffers must be poly() long
*/
- Raul::Array<BufferRef>* set_buffers(ProcessContext& context,
- Raul::Array<BufferRef>* buffers);
+ Raul::Array<Voice>* set_voices(ProcessContext& context,
+ Raul::Array<Voice>* voices);
/** Prepare for a new (external) polyphony value.
*
@@ -86,10 +103,10 @@ public:
void set_maximum(const Atom& max) { _max = max; }
inline BufferRef buffer(uint32_t voice) const {
- return _buffers->at((_poly == 1) ? 0 : voice);
+ return _voices->at((_poly == 1) ? 0 : voice).buffer;
}
inline BufferRef prepared_buffer(uint32_t voice) const {
- return _prepared_buffers->at(voice);
+ return _prepared_voices->at(voice).buffer;
}
void update_set_state(Context& context, uint32_t voice);
@@ -110,13 +127,14 @@ public:
/** Empty buffer contents completely (ie silence) */
virtual void clear_buffers();
- virtual bool get_buffers(BufferFactory& bufs,
- Raul::Array<BufferRef>* buffers,
- uint32_t poly,
- bool real_time) const = 0;
+public:
+ virtual bool get_buffers(BufferFactory& bufs,
+ Raul::Array<Voice>* voices,
+ uint32_t poly,
+ bool real_time) const = 0;
void setup_buffers(BufferFactory& bufs, uint32_t poly, bool real_time) {
- get_buffers(bufs, _buffers, poly, real_time);
+ get_buffers(bufs, _voices, poly, real_time);
}
void activate(BufferFactory& bufs);
@@ -153,7 +171,7 @@ public:
return _poly;
}
uint32_t prepared_poly() const {
- return (_prepared_buffers) ? _prepared_buffers->size() : 1;
+ return (_prepared_voices) ? _prepared_voices->size() : 1;
}
void set_buffer_size(Context& context, BufferFactory& bufs, size_t size);
@@ -202,39 +220,27 @@ protected:
const Atom& value,
size_t buffer_size);
- struct SetState {
- enum class State { SET, HALF_SET_CYCLE_1, HALF_SET_CYCLE_2 };
-
- SetState() : state(State::SET), value(0), time(0) {}
-
- State state; ///< State of buffer for setting control value
- Sample value; ///< Value currently being set
- FrameTime time; ///< Time value was set
- };
-
- BufferFactory& _bufs;
- uint32_t _index;
- uint32_t _poly;
- uint32_t _buffer_size;
- uint32_t _frames_since_monitor;
- float _monitor_value;
- float _peak;
- PortType _type;
- LV2_URID _buffer_type;
- Atom _value;
- Atom _min;
- Atom _max;
- Raul::Array<SetState>* _set_states;
- Raul::Array<SetState>* _prepared_set_states;
- Raul::Array<BufferRef>* _buffers;
- Raul::Array<BufferRef>* _prepared_buffers;
- bool _monitored;
- bool _set_by_user;
- bool _is_morph;
- bool _is_auto_morph;
- bool _is_logarithmic;
- bool _is_sample_rate;
- bool _is_toggled;
+ BufferFactory& _bufs;
+ uint32_t _index;
+ uint32_t _poly;
+ uint32_t _buffer_size;
+ uint32_t _frames_since_monitor;
+ float _monitor_value;
+ float _peak;
+ PortType _type;
+ LV2_URID _buffer_type;
+ Atom _value;
+ Atom _min;
+ Atom _max;
+ Raul::Array<Voice>* _voices;
+ Raul::Array<Voice>* _prepared_voices;
+ bool _monitored;
+ bool _set_by_user;
+ bool _is_morph;
+ bool _is_auto_morph;
+ bool _is_logarithmic;
+ bool _is_sample_rate;
+ bool _is_toggled;
};
} // namespace Server
diff --git a/src/server/events/Connect.cpp b/src/server/events/Connect.cpp
index 75659452..13faabd4 100644
--- a/src/server/events/Connect.cpp
+++ b/src/server/events/Connect.cpp
@@ -46,7 +46,7 @@ Connect::Connect(Engine& engine,
, _graph(NULL)
, _head(NULL)
, _compiled_graph(NULL)
- , _buffers(NULL)
+ , _voices(NULL)
{}
bool
@@ -129,9 +129,9 @@ Connect::pre_process()
_head->inherit_neighbour(tail_output, _head_remove, _head_add);
}
- _buffers = new Raul::Array<BufferRef>(_head->poly());
+ _voices = new Raul::Array<PortImpl::Voice>(_head->poly());
_head->get_buffers(*_engine.buffer_factory(),
- _buffers,
+ _voices,
_head->poly(),
false);
@@ -147,7 +147,7 @@ Connect::execute(ProcessContext& context)
{
if (_status == Status::SUCCESS) {
_head->add_arc(context, _arc.get());
- _engine.maid()->dispose(_head->set_buffers(context, _buffers));
+ _engine.maid()->dispose(_head->set_voices(context, _voices));
_head->connect_buffers();
_graph->set_compiled_graph(_compiled_graph);
}
diff --git a/src/server/events/Connect.hpp b/src/server/events/Connect.hpp
index d5e58a99..0750fbdc 100644
--- a/src/server/events/Connect.hpp
+++ b/src/server/events/Connect.hpp
@@ -20,8 +20,8 @@
#include "raul/Path.hpp"
#include "Event.hpp"
+#include "PortImpl.hpp"
#include "types.hpp"
-#include "BufferRef.hpp"
namespace Raul {
template <typename T> class Array;
@@ -57,17 +57,17 @@ public:
void post_process();
private:
- const Raul::Path _tail_path;
- const Raul::Path _head_path;
- GraphImpl* _graph;
- InputPort* _head;
- CompiledGraph* _compiled_graph;
- SPtr<ArcImpl> _arc;
- Raul::Array<BufferRef>* _buffers;
- Resource::Properties _tail_remove;
- Resource::Properties _tail_add;
- Resource::Properties _head_remove;
- Resource::Properties _head_add;
+ const Raul::Path _tail_path;
+ const Raul::Path _head_path;
+ GraphImpl* _graph;
+ InputPort* _head;
+ CompiledGraph* _compiled_graph;
+ SPtr<ArcImpl> _arc;
+ Raul::Array<PortImpl::Voice>* _voices;
+ Resource::Properties _tail_remove;
+ Resource::Properties _tail_add;
+ Resource::Properties _head_remove;
+ Resource::Properties _head_add;
};
} // namespace Events
diff --git a/src/server/events/Disconnect.cpp b/src/server/events/Disconnect.cpp
index a9b30a60..3ea94796 100644
--- a/src/server/events/Disconnect.cpp
+++ b/src/server/events/Disconnect.cpp
@@ -62,7 +62,7 @@ Disconnect::Impl::Impl(Engine& e,
, _src_output_port(s)
, _dst_input_port(d)
, _arc(graph->remove_arc(_src_output_port, _dst_input_port))
- , _buffers(NULL)
+ , _voices(NULL)
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
@@ -88,21 +88,21 @@ Disconnect::Impl::Impl(Engine& e,
_dst_input_port->decrement_num_arcs();
if (_dst_input_port->num_arcs() == 0) {
- _buffers = new Raul::Array<BufferRef>(_dst_input_port->poly());
+ _voices = new Raul::Array<PortImpl::Voice>(_dst_input_port->poly());
_dst_input_port->get_buffers(*_engine.buffer_factory(),
- _buffers,
+ _voices,
_dst_input_port->poly(),
false);
const bool is_control = _dst_input_port->is_a(PortType::CONTROL) ||
_dst_input_port->is_a(PortType::CV);
const float value = is_control ? _dst_input_port->value().get<float>() : 0;
- for (uint32_t i = 0; i < _buffers->size(); ++i) {
+ for (uint32_t i = 0; i < _voices->size(); ++i) {
if (is_control) {
- Buffer* buf = _buffers->at(i).get();
+ Buffer* buf = _voices->at(i).buffer.get();
buf->set_block(value, 0, buf->nframes());
} else {
- _buffers->at(i)->clear();
+ _voices->at(i).buffer->clear();
}
}
}
@@ -179,8 +179,8 @@ Disconnect::Impl::execute(ProcessContext& context, bool set_dst_buffers)
}
if (set_dst_buffers) {
- if (_buffers) {
- _engine.maid()->dispose(_dst_input_port->set_buffers(context, _buffers));
+ if (_voices) {
+ _engine.maid()->dispose(_dst_input_port->set_voices(context, _voices));
} else {
_dst_input_port->setup_buffers(*_engine.buffer_factory(),
_dst_input_port->poly(),
diff --git a/src/server/events/Disconnect.hpp b/src/server/events/Disconnect.hpp
index de176d34..058104f6 100644
--- a/src/server/events/Disconnect.hpp
+++ b/src/server/events/Disconnect.hpp
@@ -68,11 +68,11 @@ public:
inline InputPort* head() { return _dst_input_port; }
private:
- Engine& _engine;
- OutputPort* _src_output_port;
- InputPort* _dst_input_port;
- SPtr<ArcImpl> _arc;
- Raul::Array<BufferRef>* _buffers;
+ Engine& _engine;
+ OutputPort* _src_output_port;
+ InputPort* _dst_input_port;
+ SPtr<ArcImpl> _arc;
+ Raul::Array<PortImpl::Voice>* _voices;
};
private: