summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/server/ArcImpl.cpp16
-rw-r--r--src/server/BlockImpl.cpp11
-rw-r--r--src/server/Buffer.cpp7
-rw-r--r--src/server/Buffer.hpp8
-rw-r--r--src/server/InputPort.cpp4
-rw-r--r--src/server/LV2Block.cpp5
-rw-r--r--src/server/PortImpl.cpp24
-rw-r--r--src/server/events/SetPortValue.cpp4
8 files changed, 43 insertions, 36 deletions
diff --git a/src/server/ArcImpl.cpp b/src/server/ArcImpl.cpp
index 406d2010..5b96ca03 100644
--- a/src/server/ArcImpl.cpp
+++ b/src/server/ArcImpl.cpp
@@ -67,21 +67,7 @@ ArcImpl::head_path() const
BufferRef
ArcImpl::buffer(uint32_t voice, SampleCount offset) const
{
- assert(_tail->poly() == 1 || _tail->poly() > voice);
- if (_tail->poly() == 1) {
- voice = 0;
- }
-
- if (_tail->buffer(0)->is_sequence()) {
- if (_head->type() == PortType::CONTROL) {
- _tail->update_values(offset, voice); // Update value buffer
- return _tail->value_buffer(voice); // Return value buffer
- } else if (_head->type() == PortType::CV) {
- // Return full tail buffer below
- }
- }
-
- return _tail->buffer(voice);
+ return _tail->buffer(std::min(voice, _tail->poly() - 1));
}
bool
diff --git a/src/server/BlockImpl.cpp b/src/server/BlockImpl.cpp
index 3b051fd4..d0f0d646 100644
--- a/src/server/BlockImpl.cpp
+++ b/src/server/BlockImpl.cpp
@@ -258,6 +258,17 @@ BlockImpl::process(RunContext& context)
// Run the chunk
run(subcontext);
+ // Emit control port outputs as events
+ for (uint32_t i = 0; _ports && i < _ports->size(); ++i) {
+ PortImpl* const port = _ports->at(i);
+ if (port->type() == PortType::CONTROL && port->is_output()) {
+ // TODO: Only emit events when value has actually changed?
+ for (uint32_t v = 0; v < _polyphony; ++v) {
+ port->buffer(v)->append_event(offset, port->buffer(v)->value());
+ }
+ }
+ }
+
offset = chunk_end;
subcontext.slice(offset, chunk_end - offset);
}
diff --git a/src/server/Buffer.cpp b/src/server/Buffer.cpp
index fb7efa85..2353ab5d 100644
--- a/src/server/Buffer.cpp
+++ b/src/server/Buffer.cpp
@@ -166,12 +166,6 @@ Buffer::copy(const RunContext& context, const Buffer* src)
} else {
clear();
}
-
- if (_value_buffer && src->_value_buffer) {
- memcpy(_value_buffer->get<LV2_Atom>(),
- src->value(),
- lv2_atom_total_size(src->value()));
- }
} else if (src->is_audio() && is_control()) {
samples()[0] = src->samples()[0];
} else if (src->is_control() && is_audio()) {
@@ -201,6 +195,7 @@ Buffer::port_data(PortType port_type, SampleCount offset)
{
switch (port_type.id()) {
case PortType::ID::CONTROL:
+ return &_value_buffer->get<LV2_Atom_Float>()->body;
case PortType::ID::CV:
case PortType::ID::AUDIO:
if (_type == _factory.uris().atom_Float) {
diff --git a/src/server/Buffer.hpp b/src/server/Buffer.hpp
index 939f1f87..bc8ff1aa 100644
--- a/src/server/Buffer.hpp
+++ b/src/server/Buffer.hpp
@@ -115,6 +115,14 @@ public:
const SampleCount start,
const SampleCount end)
{
+ if (is_sequence()) {
+ append_event(start, sizeof(val), _factory.uris().atom_Float,
+ reinterpret_cast<const uint8_t*>(
+ static_cast<const float*>(&val)));
+ _value_buffer->get<LV2_Atom_Float>()->body = val;
+ return;
+ }
+
assert(is_audio() || is_control());
assert(end <= _capacity / sizeof(Sample));
// Note: Do not change this without ensuring GCC can still vectorize it
diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp
index fe613f31..cfc43526 100644
--- a/src/server/InputPort.cpp
+++ b/src/server/InputPort.cpp
@@ -210,6 +210,10 @@ InputPort::pre_run(RunContext& context)
mix(context, buffer(v).get(), srcs, n_srcs);
update_values(context.offset(), v);
}
+ } else if (is_a(PortType::CONTROL)) {
+ for (uint32_t v = 0; v < _poly; ++v) {
+ update_values(context.offset(), v);
+ }
}
}
diff --git a/src/server/LV2Block.cpp b/src/server/LV2Block.cpp
index 77835b67..e023e3d7 100644
--- a/src/server/LV2Block.cpp
+++ b/src/server/LV2Block.cpp
@@ -117,7 +117,7 @@ LV2Block::make_instance(URIs& uris,
if (buffer) {
if (port->is_a(PortType::CONTROL)) {
- buffer->samples()[0] = port->value().get<float>();
+ buffer->set_value(port->value());
} else if (port->is_a(PortType::CV)) {
buffer->set_block(port->value().get<float>(), 0, engine.block_length());
} else {
@@ -267,7 +267,8 @@ LV2Block::instantiate(BufferFactory& bufs, const LilvState* state)
}
if (port_type == PortType::UNKNOWN) {
port_type = PortType::CONTROL;
- buffer_type = uris.atom_Float;
+ buffer_type = uris.atom_Sequence;
+ val = forge.make(def_values[j]);
}
} else if (lilv_port_is_a(plug, id, uris.lv2_CVPort)) {
port_type = PortType::CV;
diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp
index 45a5a082..a9c1aefe 100644
--- a/src/server/PortImpl.cpp
+++ b/src/server/PortImpl.cpp
@@ -243,7 +243,7 @@ PortImpl::set_voice_value(const RunContext& context,
{
switch (_type.id()) {
case PortType::CONTROL:
- buffer(voice)->samples()[0] = value;
+ ((LV2_Atom_Float*)buffer(voice)->value())->body = value;
_voices->at(voice).set_state.set(context, context.start(), value);
break;
case PortType::AUDIO:
@@ -411,22 +411,24 @@ void
PortImpl::clear_buffers(const RunContext& ctx)
{
switch (_type.id()) {
- case PortType::CONTROL:
- case PortType::CV:
+ case PortType::AUDIO:
+ default:
for (uint32_t v = 0; v < _poly; ++v) {
- Buffer* buf = buffer(v).get();
- buf->set_block(_value.get<float>(), 0, ctx.nframes());
- SetState& state = _voices->at(v).set_state;
- state.state = SetState::State::SET;
- state.value = _value.get<float>();
- state.time = 0;
+ buffer(v)->clear();
}
break;
- case PortType::AUDIO:
- default:
+ case PortType::CONTROL:
for (uint32_t v = 0; v < _poly; ++v) {
buffer(v)->clear();
+ _voices->at(v).set_state.set(ctx, ctx.start(), _value.get<float>());
+ }
+ break;
+ case PortType::CV:
+ for (uint32_t v = 0; v < _poly; ++v) {
+ buffer(v)->set_block(_value.get<float>(), 0, ctx.nframes());
+ _voices->at(v).set_state.set(ctx, ctx.start(), _value.get<float>());
}
+ break;
}
}
diff --git a/src/server/events/SetPortValue.cpp b/src/server/events/SetPortValue.cpp
index b8c23605..89c92580 100644
--- a/src/server/events/SetPortValue.cpp
+++ b/src/server/events/SetPortValue.cpp
@@ -56,7 +56,7 @@ SetPortValue::~SetPortValue()
bool
SetPortValue::pre_process(PreProcessContext& ctx)
{
- Ingen::URIs& uris = _engine.world()->uris();
+ Ingen::URIs& uris = _engine.world()->uris();
if (_port->is_output()) {
return Event::pre_process_done(Status::DIRECTION_MISMATCH, _port->path());
}
@@ -72,7 +72,7 @@ SetPortValue::pre_process(PreProcessContext& ctx)
if (_port->buffer_type() == uris.atom_Sequence) {
_buffer = _engine.buffer_factory()->get_buffer(
_port->buffer_type(),
- 0,
+ _value.type() == uris.atom_Float ? _value.type() : 0,
_engine.buffer_factory()->default_size(_port->buffer_type()));
}