summaryrefslogtreecommitdiffstats
path: root/src/server/PortImpl.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-07-31 04:34:18 +0000
committerDavid Robillard <d@drobilla.net>2012-07-31 04:34:18 +0000
commitd184de93fce861f4b632f410bde8d527ce1bf34f (patch)
tree9efa412f62028113381f66f8fe256d09fdeb6749 /src/server/PortImpl.cpp
parent66ac730782803a47ae4977d2db2407126005f4bd (diff)
downloadingen-d184de93fce861f4b632f410bde8d527ce1bf34f.tar.gz
ingen-d184de93fce861f4b632f410bde8d527ce1bf34f.tar.bz2
ingen-d184de93fce861f4b632f410bde8d527ce1bf34f.zip
Move continuous value setting stuff from AudioBuffer to PortImpl.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@4582 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/server/PortImpl.cpp')
-rw-r--r--src/server/PortImpl.cpp101
1 files changed, 94 insertions, 7 deletions
diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp
index 8c044d7b..5a4ca349 100644
--- a/src/server/PortImpl.cpp
+++ b/src/server/PortImpl.cpp
@@ -52,6 +52,8 @@ PortImpl::PortImpl(BufferFactory& bufs,
, _min(bufs.forge().make(0.0f))
, _max(bufs.forge().make(1.0f))
, _last_broadcasted_value(value)
+ , _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)
, _broadcast(false)
@@ -132,6 +134,62 @@ PortImpl::cache_properties()
_bufs.uris().lv2_toggled);
}
+void
+PortImpl::set_control_value(Context& context, FrameTime time, Sample value)
+{
+ for (uint32_t v = 0; v < poly(); ++v) {
+ set_voice_value(context, v, time, value);
+ }
+}
+
+void
+PortImpl::set_voice_value(Context& context, uint32_t voice, FrameTime time, Sample value)
+{
+ // Time may be at end so internal nodes can set single sample triggers
+ assert(time >= context.start());
+ assert(time <= context.start() + context.nframes());
+
+ if (_type == PortType::CONTROL) {
+ time = context.start();
+ }
+
+ FrameTime offset = time - context.start();
+ FrameTime last = (_type == PortType::CONTROL) ? 0 : context.nframes() - 1;
+ if (offset < context.nframes()) {
+ AudioBuffer* const abuf = dynamic_cast<AudioBuffer*>(buffer(voice).get());
+ abuf->set_block(value, offset, last);
+ } // else trigger at very end of block, and set to 0 at start of next block
+
+ SetState& state = _set_states->at(voice);
+ state.state = (offset == 0) ? SetState::SET : SetState::HALF_SET_CYCLE_1;
+ state.time = time;
+ state.value = value;
+}
+
+void
+PortImpl::update_set_state(Context& context, uint32_t voice)
+{
+ SetState& state = _set_states->at(voice);
+ switch (state.state) {
+ case SetState::HALF_SET_CYCLE_1:
+ if (context.start() > state.time) {
+ state.state = SetState::HALF_SET_CYCLE_2;
+ }
+ break;
+ case SetState::HALF_SET_CYCLE_2: {
+ AudioBuffer* const abuf = dynamic_cast<AudioBuffer*>(buffer(voice).get());
+ abuf->set_block(state.value, 0, context.nframes() - 1);
+ for (unsigned i = 0; i < context.nframes(); ++i) {
+ assert(abuf->data()[i] == state.value);
+ }
+ state.state = SetState::SET;
+ break;
+ }
+ default:
+ break;
+ }
+}
+
bool
PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly)
{
@@ -150,10 +208,18 @@ PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly)
delete _prepared_buffers;
_prepared_buffers = 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());
+
get_buffers(bufs.engine().message_context(),
bufs,
_prepared_buffers,
@@ -176,6 +242,7 @@ PortImpl::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly)
}
assert(poly == _prepared_buffers->size());
+ assert(poly == _prepared_set_states->size());
_poly = poly;
@@ -184,15 +251,19 @@ PortImpl::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly)
assert(_buffers == _prepared_buffers);
_prepared_buffers = NULL;
- if (is_a(PortType::CONTROL) || is_a(PortType::CV))
- for (uint32_t v = 0; v < _poly; ++v)
- if (_buffers->at(v))
- boost::static_pointer_cast<AudioBuffer>(
- _buffers->at(v))->set_value(_value.get_float(), 0, 0);
+ maid.push(_set_states);
+ _set_states = _prepared_set_states;
+ _prepared_set_states = 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(this->poly() == poly);
assert(!_prepared_buffers);
+ assert(!_prepared_set_states);
return true;
}
@@ -225,8 +296,24 @@ PortImpl::recycle_buffers()
void
PortImpl::clear_buffers()
{
- for (uint32_t v = 0; v < _poly; ++v)
- buffer(v)->clear();
+ switch (_type.symbol()) {
+ case PortType::AUDIO:
+ case PortType::CONTROL:
+ case PortType::CV:
+ for (uint32_t v = 0; v < _poly; ++v) {
+ AudioBuffer* abuf = (AudioBuffer*)buffer(0).get();
+ abuf->set_block(_value.get_float(), 0, abuf->nframes() - 1);
+ SetState& state = _set_states->at(v);
+ state.state = SetState::SET;
+ state.value = _value.get_float();
+ state.time = 0;
+ }
+ break;
+ default:
+ for (uint32_t v = 0; v < _poly; ++v) {
+ buffer(v)->clear();
+ }
+ }
}
void