From 46e5de590817756b21a7a5d99bd4963df343f455 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 20 Feb 2010 21:52:36 +0000 Subject: Heavy overhaul of buffer management and polyphony. * Working polyphony when nodes are instantiated at desired polyphony level (dynamic still doesn't work) * Use shared silent buffer for disconnected audio inputs (save memory) * Eliminate redundant patch compiling on delete and disconnect-all events that have child events * Fix a ton of crash bugs and other issues I've since forgotten git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2468 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/internals/Controller.cpp | 19 ++++++++----------- src/engine/internals/Controller.hpp | 2 +- src/engine/internals/Note.cpp | 33 ++++++++++++--------------------- src/engine/internals/Note.hpp | 4 ++-- src/engine/internals/Trigger.cpp | 16 +++++++--------- src/engine/internals/Trigger.hpp | 2 +- 6 files changed, 31 insertions(+), 45 deletions(-) (limited to 'src/engine/internals') diff --git a/src/engine/internals/Controller.cpp b/src/engine/internals/Controller.cpp index 3d856fe0..870dfc8e 100644 --- a/src/engine/internals/Controller.cpp +++ b/src/engine/internals/Controller.cpp @@ -44,39 +44,38 @@ ControllerNode::ControllerNode(BufferFactory& bufs, const string& path, bool polyphonic, PatchImpl* parent, - SampleRate srate, - size_t buffer_size) - : NodeBase(&controller_plugin, path, false, parent, srate, buffer_size) + SampleRate srate) + : NodeBase(&controller_plugin, path, false, parent, srate) , _learning(false) { const LV2URIMap& uris = Shared::LV2URIMap::instance(); _ports = new Raul::Array(6); - _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom(), _buffer_size); + _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom()); _midi_in_port->set_property(uris.lv2_name, "Input"); _ports->at(0) = _midi_in_port; - _param_port = new InputPort(bufs, this, "controller", 1, 1, PortType::CONTROL, 0.0f, sizeof(Sample)); + _param_port = new InputPort(bufs, this, "controller", 1, 1, PortType::CONTROL, 0.0f); _param_port->set_property(uris.lv2_minimum, 0.0f); _param_port->set_property(uris.lv2_maximum, 127.0f); _param_port->set_property(uris.lv2_integer, true); _param_port->set_property(uris.lv2_name, "Controller"); _ports->at(1) = _param_port; - _log_port = new InputPort(bufs, this, "logarithmic", 2, 1, PortType::CONTROL, 0.0f, sizeof(Sample)); + _log_port = new InputPort(bufs, this, "logarithmic", 2, 1, PortType::CONTROL, 0.0f); _log_port->set_property(uris.lv2_portProperty, uris.lv2_toggled); _log_port->set_property(uris.lv2_name, "Logarithmic"); _ports->at(2) = _log_port; - _min_port = new InputPort(bufs, this, "minimum", 3, 1, PortType::CONTROL, 0.0f, sizeof(Sample)); + _min_port = new InputPort(bufs, this, "minimum", 3, 1, PortType::CONTROL, 0.0f); _min_port->set_property(uris.lv2_name, "Minimum"); _ports->at(3) = _min_port; - _max_port = new InputPort(bufs, this, "maximum", 4, 1, PortType::CONTROL, 1.0f, sizeof(Sample)); + _max_port = new InputPort(bufs, this, "maximum", 4, 1, PortType::CONTROL, 1.0f); _max_port->set_property(uris.lv2_name, "Maximum"); _ports->at(4) = _max_port; - _audio_port = new OutputPort(bufs, this, "ar_output", 5, 1, PortType::AUDIO, 0.0f, _buffer_size); + _audio_port = new OutputPort(bufs, this, "ar_output", 5, 1, PortType::AUDIO, 0.0f); _audio_port->set_property(uris.lv2_name, "Output"); _ports->at(5) = _audio_port; } @@ -112,8 +111,6 @@ ControllerNode::process(ProcessContext& context) void ControllerNode::control(ProcessContext& context, uint8_t control_num, uint8_t val, FrameTime time) { - assert(time - context.start() < _buffer_size); - Sample scaled_value; const Sample nval = (val / 127.0f); // normalized [0, 1] diff --git a/src/engine/internals/Controller.hpp b/src/engine/internals/Controller.hpp index 9482916e..b6d7302f 100644 --- a/src/engine/internals/Controller.hpp +++ b/src/engine/internals/Controller.hpp @@ -40,7 +40,7 @@ namespace Internals { class ControllerNode : public NodeBase { public: - ControllerNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); + ControllerNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate); void process(ProcessContext& context); diff --git a/src/engine/internals/Note.cpp b/src/engine/internals/Note.cpp index a400e3c4..2798a948 100644 --- a/src/engine/internals/Note.cpp +++ b/src/engine/internals/Note.cpp @@ -47,8 +47,8 @@ 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, size_t buffer_size) - : NodeBase(¬e_plugin, path, polyphonic, parent, srate, buffer_size) +NoteNode::NoteNode(BufferFactory& bufs, const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate) + : NodeBase(¬e_plugin, path, polyphonic, parent, srate) , _voices(new Raul::Array(_polyphony)) , _prepared_voices(NULL) , _sustain(false) @@ -56,26 +56,26 @@ NoteNode::NoteNode(BufferFactory& bufs, const string& path, bool polyphonic, Pat const LV2URIMap& uris = Shared::LV2URIMap::instance(); _ports = new Raul::Array(5); - _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom(), _buffer_size); + _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom()); _midi_in_port->set_property(uris.lv2_name, "Input"); _ports->at(0) = _midi_in_port; - _freq_port = new OutputPort(bufs, this, "frequency", 1, _polyphony, PortType::AUDIO, 440.0f, _buffer_size); + _freq_port = new OutputPort(bufs, this, "frequency", 1, _polyphony, PortType::AUDIO, 440.0f); _freq_port->set_property(uris.lv2_name, "Frequency"); _ports->at(1) = _freq_port; - _vel_port = new OutputPort(bufs, this, "velocity", 2, _polyphony, PortType::AUDIO, 0.0f, _buffer_size); + _vel_port = new OutputPort(bufs, this, "velocity", 2, _polyphony, PortType::AUDIO, 0.0f); _vel_port->set_property(uris.lv2_minimum, 0.0f); _vel_port->set_property(uris.lv2_maximum, 1.0f); _vel_port->set_property(uris.lv2_name, "Velocity"); _ports->at(2) = _vel_port; - _gate_port = new OutputPort(bufs, this, "gate", 3, _polyphony, PortType::AUDIO, 0.0f, _buffer_size); + _gate_port = new OutputPort(bufs, this, "gate", 3, _polyphony, PortType::AUDIO, 0.0f); _gate_port->set_property(uris.lv2_portProperty, uris.lv2_toggled); _gate_port->set_property(uris.lv2_name, "Gate"); _ports->at(3) = _gate_port; - _trig_port = new OutputPort(bufs, this, "trigger", 4, _polyphony, PortType::AUDIO, 0.0f, _buffer_size); + _trig_port = new OutputPort(bufs, this, "trigger", 4, _polyphony, PortType::AUDIO, 0.0f); _trig_port->set_property(uris.lv2_portProperty, uris.lv2_toggled); _trig_port->set_property(uris.lv2_name, "Trigger"); _ports->at(4) = _trig_port; @@ -99,7 +99,7 @@ NoteNode::prepare_poly(BufferFactory& bufs, uint32_t poly) if (_prepared_voices && poly <= _prepared_voices->size()) return true; - _prepared_voices = new Raul::Array(poly, *_voices); + _prepared_voices = new Raul::Array(poly, *_voices, Voice()); return true; } @@ -108,20 +108,16 @@ NoteNode::prepare_poly(BufferFactory& bufs, uint32_t poly) bool NoteNode::apply_poly(Raul::Maid& maid, uint32_t poly) { - if (!_polyphonic) - return true; - - NodeBase::apply_poly(maid, poly); + if (!NodeBase::apply_poly(maid, poly)) + return false; if (_prepared_voices) { - assert(poly <= _prepared_voices->size()); + assert(_polyphony <= _prepared_voices->size()); maid.push(_voices); _voices = _prepared_voices; _prepared_voices = NULL; } - - _polyphony = poly; - assert(_voices->size() >= _polyphony); + assert(_polyphony <= _voices->size()); return true; } @@ -202,7 +198,6 @@ void NoteNode::note_on(ProcessContext& context, uint8_t note_num, uint8_t velocity, FrameTime time) { assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); assert(note_num <= 127); Key* key = &_keys[note_num]; @@ -293,7 +288,6 @@ void NoteNode::note_off(ProcessContext& context, uint8_t note_num, FrameTime time) { assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); Key* key = &_keys[note_num]; @@ -333,7 +327,6 @@ void NoteNode::free_voice(ProcessContext& context, uint32_t voice, FrameTime time) { assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); // Find a key to reassign to the freed voice (the newest, if there is one) Key* replace_key = NULL; @@ -375,7 +368,6 @@ void NoteNode::all_notes_off(ProcessContext& context, FrameTime time) { assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); #ifdef LOG_DEBUG LOG(debug) << "All notes off @ " << time << endl; @@ -411,7 +403,6 @@ void NoteNode::sustain_off(ProcessContext& context, FrameTime time) { assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); _sustain = false; diff --git a/src/engine/internals/Note.hpp b/src/engine/internals/Note.hpp index 11fc1344..8ad7f452 100644 --- a/src/engine/internals/Note.hpp +++ b/src/engine/internals/Note.hpp @@ -40,7 +40,7 @@ namespace Internals { class NoteNode : public NodeBase { public: - NoteNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); + NoteNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate); ~NoteNode(); bool prepare_poly(BufferFactory& bufs, uint32_t poly); @@ -68,7 +68,7 @@ private: /** Voice, one of these always exists for each voice */ struct Voice { enum State { FREE, ACTIVE, HOLDING }; - Voice() : state(FREE), note(0) {} + Voice() : state(FREE), note(0), time(0) {} State state; uint8_t note; SampleCount time; }; diff --git a/src/engine/internals/Trigger.cpp b/src/engine/internals/Trigger.cpp index eded1ac7..c8d6b77e 100644 --- a/src/engine/internals/Trigger.cpp +++ b/src/engine/internals/Trigger.cpp @@ -43,35 +43,35 @@ 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, size_t buffer_size) - : NodeBase(&trigger_plugin, path, false, parent, srate, buffer_size) +TriggerNode::TriggerNode(BufferFactory& bufs, const string& path, bool polyphonic, PatchImpl* parent, SampleRate srate) + : NodeBase(&trigger_plugin, path, false, parent, srate) , _learning(false) { const LV2URIMap& uris = LV2URIMap::instance(); _ports = new Raul::Array(5); - _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom(), _buffer_size); + _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom()); _midi_in_port->set_property(uris.lv2_name, "Input"); _ports->at(0) = _midi_in_port; - _note_port = new InputPort(bufs, this, "note", 1, 1, PortType::CONTROL, 60.0f, sizeof(Sample)); + _note_port = new InputPort(bufs, this, "note", 1, 1, PortType::CONTROL, 60.0f); _note_port->set_property(uris.lv2_minimum, 0.0f); _note_port->set_property(uris.lv2_maximum, 127.0f); _note_port->set_property(uris.lv2_integer, true); _note_port->set_property(uris.lv2_name, "Note"); _ports->at(1) = _note_port; - _gate_port = new OutputPort(bufs, this, "gate", 2, 1, PortType::AUDIO, 0.0f, _buffer_size); + _gate_port = new OutputPort(bufs, this, "gate", 2, 1, PortType::AUDIO, 0.0f); _gate_port->set_property(uris.lv2_portProperty, uris.lv2_toggled); _gate_port->set_property(uris.lv2_name, "Gate"); _ports->at(2) = _gate_port; - _trig_port = new OutputPort(bufs, this, "trigger", 3, 1, PortType::AUDIO, 0.0f, _buffer_size); + _trig_port = new OutputPort(bufs, this, "trigger", 3, 1, PortType::AUDIO, 0.0f); _trig_port->set_property(uris.lv2_portProperty, uris.lv2_toggled); _trig_port->set_property(uris.lv2_name, "Trigger"); _ports->at(3) = _trig_port; - _vel_port = new OutputPort(bufs, this, "velocity", 4, 1, PortType::AUDIO, 0.0f, _buffer_size); + _vel_port = new OutputPort(bufs, this, "velocity", 4, 1, PortType::AUDIO, 0.0f); _vel_port->set_property(uris.lv2_minimum, 0.0f); _vel_port->set_property(uris.lv2_maximum, 1.0f); _vel_port->set_property(uris.lv2_name, "Velocity"); @@ -128,7 +128,6 @@ void TriggerNode::note_on(ProcessContext& context, uint8_t note_num, uint8_t velocity, FrameTime time) { assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); if (_learning) { _note_port->set_value(note_num); @@ -157,7 +156,6 @@ void TriggerNode::note_off(ProcessContext& context, uint8_t note_num, FrameTime time) { assert(time >= context.start() && time <= context.end()); - assert(time - context.start() < _buffer_size); if (note_num == lrintf(((AudioBuffer*)_note_port->buffer(0).get())->value_at(0))) ((AudioBuffer*)_gate_port->buffer(0).get())->set_value(0.0f, context.start(), time); diff --git a/src/engine/internals/Trigger.hpp b/src/engine/internals/Trigger.hpp index 12e5c140..53aba06f 100644 --- a/src/engine/internals/Trigger.hpp +++ b/src/engine/internals/Trigger.hpp @@ -43,7 +43,7 @@ namespace Internals { class TriggerNode : public NodeBase { public: - TriggerNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate, size_t buffer_size); + TriggerNode(BufferFactory& bufs, const std::string& path, bool polyphonic, PatchImpl* parent, SampleRate srate); void process(ProcessContext& context); -- cgit v1.2.1