bool PortImpl::apply_poly(ProcessContext& context, Raul::Maid& maid, uint32_t poly) { if (_parent->path().is_root() || (_type == PortType::ATOM && !_value.is_valid())) { return false; } if (!_prepared_voices) { return true; } assert(poly == _prepared_voices->size()); _poly = poly; // 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(_voices->size() >= poly); assert(this->poly() == poly); assert(!_prepared_voices); return true; }
void SetPortValue::execute(ProcessContext& context) { Event::execute(context); assert(_time >= context.start() && _time <= context.end()); if (_port && _port->context() == Context::MESSAGE) return; apply(context); _engine.control_bindings()->port_value_changed(context, _port); }
unsigned PreProcessor::process(ProcessContext& context, PostProcessor& dest, size_t limit) { Event* const head = _head.load(); if (!head) { return 0; } size_t n_processed = 0; Event* ev = head; Event* last = ev; while (ev && ev->is_prepared() && ev->time() < context.end()) { if (ev->time() < context.start()) { // Didn't get around to executing in time, oh well... ev->set_time(context.start()); } ev->execute(context); last = ev; ev = ev->next(); ++n_processed; if (limit && n_processed >= limit) { break; } } if (n_processed > 0) { Event* next = (Event*)last->next(); last->next(NULL); dest.append(context, head, last); // Since _head was not NULL, we know it hasn't been changed since _head = next; /* If next is NULL, then _tail may now be invalid. However, it would cause a race to reset _tail here. Instead, append() checks only _head for emptiness, and resets the tail appropriately. */ } return n_processed; }