summaryrefslogtreecommitdiffstats
path: root/src/server/internals
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/internals')
-rw-r--r--src/server/internals/BlockDelay.cpp89
-rw-r--r--src/server/internals/BlockDelay.hpp62
-rw-r--r--src/server/internals/Controller.cpp174
-rw-r--r--src/server/internals/Controller.hpp71
-rw-r--r--src/server/internals/Note.cpp420
-rw-r--r--src/server/internals/Note.hpp109
-rw-r--r--src/server/internals/Time.cpp78
-rw-r--r--src/server/internals/Time.hpp59
-rw-r--r--src/server/internals/Trigger.cpp187
-rw-r--r--src/server/internals/Trigger.hpp75
10 files changed, 0 insertions, 1324 deletions
diff --git a/src/server/internals/BlockDelay.cpp b/src/server/internals/BlockDelay.cpp
deleted file mode 100644
index 6b27ed83..00000000
--- a/src/server/internals/BlockDelay.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <climits>
-
-#include <cmath>
-
-#include "ingen/URIs.hpp"
-#include "raul/Array.hpp"
-#include "raul/Maid.hpp"
-
-#include "Buffer.hpp"
-#include "InputPort.hpp"
-#include "InternalPlugin.hpp"
-#include "OutputPort.hpp"
-#include "RunContext.hpp"
-#include "internals/BlockDelay.hpp"
-
-namespace Ingen {
-namespace Server {
-namespace Internals {
-
-InternalPlugin* BlockDelayNode::internal_plugin(URIs& uris) {
- return new InternalPlugin(
- uris, URI(NS_INTERNALS "BlockDelay"), Raul::Symbol("blockDelay"));
-}
-
-BlockDelayNode::BlockDelayNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate)
- : InternalBlock(plugin, symbol, polyphonic, parent, srate)
-{
- const Ingen::URIs& uris = bufs.uris();
- _ports = bufs.maid().make_managed<Ports>(2);
-
- _in_port = new InputPort(bufs, this, Raul::Symbol("in"), 0, 1,
- PortType::AUDIO, 0, bufs.forge().make(0.0f));
- _in_port->set_property(uris.lv2_name, bufs.forge().alloc("In"));
- _ports->at(0) = _in_port;
-
- _out_port = new OutputPort(bufs, this, Raul::Symbol("out"), 0, 1,
- PortType::AUDIO, 0, bufs.forge().make(0.0f));
- _out_port->set_property(uris.lv2_name, bufs.forge().alloc("Out"));
- _ports->at(1) = _out_port;
-}
-
-BlockDelayNode::~BlockDelayNode()
-{
- _buffer.reset();
-}
-
-void
-BlockDelayNode::activate(BufferFactory& bufs)
-{
- _buffer = bufs.create(
- bufs.uris().atom_Sound, 0, bufs.audio_buffer_size());
-
- BlockImpl::activate(bufs);
-}
-
-void
-BlockDelayNode::run(RunContext& context)
-{
- // Copy buffer from last cycle to output
- _out_port->buffer(0)->copy(context, _buffer.get());
-
- // Copy input from this cycle to buffer
- _buffer->copy(context, _in_port->buffer(0).get());
-}
-
-} // namespace Internals
-} // namespace Server
-} // namespace Ingen
diff --git a/src/server/internals/BlockDelay.hpp b/src/server/internals/BlockDelay.hpp
deleted file mode 100644
index e1ef5311..00000000
--- a/src/server/internals/BlockDelay.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef INGEN_INTERNALS_BLOCKDELAY_HPP
-#define INGEN_INTERNALS_BLOCKDELAY_HPP
-
-#include "BufferRef.hpp"
-#include "InternalBlock.hpp"
-#include "types.hpp"
-
-namespace Ingen {
-namespace Server {
-
-class InputPort;
-class OutputPort;
-class InternalPlugin;
-class BufferFactory;
-
-namespace Internals {
-
-class BlockDelayNode : public InternalBlock
-{
-public:
- BlockDelayNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate);
-
- ~BlockDelayNode();
-
- void activate(BufferFactory& bufs);
-
- void run(RunContext& context);
-
- static InternalPlugin* internal_plugin(URIs& uris);
-
-private:
- InputPort* _in_port;
- OutputPort* _out_port;
- BufferRef _buffer;
-};
-
-} // namespace Server
-} // namespace Ingen
-} // namespace Internals
-
-#endif // INGEN_INTERNALS_BLOCKDELAY_HPP
diff --git a/src/server/internals/Controller.cpp b/src/server/internals/Controller.cpp
deleted file mode 100644
index 4c1cf45a..00000000
--- a/src/server/internals/Controller.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2016 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <cmath>
-
-#include "ingen/URIs.hpp"
-#include "internals/Controller.hpp"
-#include "lv2/lv2plug.in/ns/ext/atom/util.h"
-#include "lv2/lv2plug.in/ns/ext/midi/midi.h"
-
-#include "Buffer.hpp"
-#include "Engine.hpp"
-#include "InputPort.hpp"
-#include "InternalPlugin.hpp"
-#include "OutputPort.hpp"
-#include "PostProcessor.hpp"
-#include "RunContext.hpp"
-#include "util.hpp"
-
-namespace Ingen {
-namespace Server {
-namespace Internals {
-
-InternalPlugin* ControllerNode::internal_plugin(URIs& uris) {
- return new InternalPlugin(
- uris, URI(NS_INTERNALS "Controller"), Raul::Symbol("controller"));
-}
-
-ControllerNode::ControllerNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate)
- : InternalBlock(plugin, symbol, false, parent, srate)
- , _learning(false)
-{
- const Ingen::URIs& uris = bufs.uris();
- _ports = bufs.maid().make_managed<Ports>(7);
-
- const Atom zero = bufs.forge().make(0.0f);
- const Atom one = bufs.forge().make(1.0f);
- const Atom atom_Float = bufs.forge().make_urid(URI(LV2_ATOM__Float));
-
- _midi_in_port = new InputPort(bufs, this, Raul::Symbol("input"), 0, 1,
- PortType::ATOM, uris.atom_Sequence, Atom());
- _midi_in_port->set_property(uris.lv2_name, bufs.forge().alloc("Input"));
- _midi_in_port->set_property(uris.atom_supports,
- bufs.forge().make_urid(uris.midi_MidiEvent));
- _ports->at(0) = _midi_in_port;
-
- _midi_out_port = new OutputPort(bufs, this, Raul::Symbol("event"), 1, 1,
- PortType::ATOM, uris.atom_Sequence, Atom());
- _midi_out_port->set_property(uris.lv2_name, bufs.forge().alloc("Event"));
- _midi_out_port->set_property(uris.atom_supports,
- bufs.forge().make_urid(uris.midi_MidiEvent));
- _ports->at(1) = _midi_out_port;
-
- _param_port = new InputPort(bufs, this, Raul::Symbol("controller"), 2, 1,
- PortType::ATOM, uris.atom_Sequence, zero);
- _param_port->set_property(uris.atom_supports, atom_Float);
- _param_port->set_property(uris.lv2_minimum, zero);
- _param_port->set_property(uris.lv2_maximum, bufs.forge().make(127.0f));
- _param_port->set_property(uris.lv2_portProperty, uris.lv2_integer);
- _param_port->set_property(uris.lv2_name, bufs.forge().alloc("Controller"));
- _ports->at(2) = _param_port;
-
- _log_port = new InputPort(bufs, this, Raul::Symbol("logarithmic"), 3, 1,
- PortType::ATOM, uris.atom_Sequence, zero);
- _log_port->set_property(uris.atom_supports, atom_Float);
- _log_port->set_property(uris.lv2_portProperty, uris.lv2_toggled);
- _log_port->set_property(uris.lv2_name, bufs.forge().alloc("Logarithmic"));
- _ports->at(3) = _log_port;
-
- _min_port = new InputPort(bufs, this, Raul::Symbol("minimum"), 4, 1,
- PortType::ATOM, uris.atom_Sequence, zero);
- _min_port->set_property(uris.atom_supports, atom_Float);
- _min_port->set_property(uris.lv2_name, bufs.forge().alloc("Minimum"));
- _ports->at(4) = _min_port;
-
- _max_port = new InputPort(bufs, this, Raul::Symbol("maximum"), 5, 1,
- PortType::ATOM, uris.atom_Sequence, one);
- _max_port->set_property(uris.atom_supports, atom_Float);
- _max_port->set_property(uris.lv2_name, bufs.forge().alloc("Maximum"));
- _ports->at(5) = _max_port;
-
- _audio_port = new OutputPort(bufs, this, Raul::Symbol("output"), 6, 1,
- PortType::ATOM, uris.atom_Sequence, zero);
- _audio_port->set_property(uris.atom_supports, atom_Float);
- _audio_port->set_property(uris.lv2_name, bufs.forge().alloc("Output"));
- _ports->at(6) = _audio_port;
-}
-
-void
-ControllerNode::run(RunContext& context)
-{
- const BufferRef midi_in = _midi_in_port->buffer(0);
- LV2_Atom_Sequence* seq = midi_in->get<LV2_Atom_Sequence>();
- const BufferRef midi_out = _midi_out_port->buffer(0);
- LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
- const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY(&ev->body);
- if (ev->body.type == _midi_in_port->bufs().uris().midi_MidiEvent &&
- ev->body.size >= 3 &&
- lv2_midi_message_type(buf) == LV2_MIDI_MSG_CONTROLLER) {
- if (control(context, buf[1], buf[2], ev->time.frames + context.start())) {
- midi_out->append_event(ev->time.frames, &ev->body);
- }
- }
- }
-}
-
-bool
-ControllerNode::control(RunContext& context, uint8_t control_num, uint8_t val, FrameTime time)
-{
- assert(time >= context.start() && time <= context.end());
- const uint32_t offset = time - context.start();
-
- const Sample nval = (val / 127.0f); // normalized [0, 1]
-
- if (_learning) {
- _param_port->set_control_value(context, time, control_num);
- _param_port->force_monitor_update();
- _learning = false;
- } else {
- _param_port->update_values(offset, 0);
- }
-
- if (control_num != _param_port->buffer(0)->value_at(offset)) {
- return false;
- }
-
- for (const auto& port : { _min_port, _max_port, _log_port }) {
- port->update_values(offset, 0);
- }
-
- const Sample min_port_val = _min_port->buffer(0)->value_at(offset);
- const Sample max_port_val = _max_port->buffer(0)->value_at(offset);
- const Sample log_port_val = _log_port->buffer(0)->value_at(offset);
-
- Sample scaled_value;
- if (log_port_val > 0.0f) {
- // haaaaack, stupid negatives and logarithms
- Sample log_offset = 0;
- if (min_port_val < 0) {
- log_offset = fabs(min_port_val);
- }
- const Sample min = log(min_port_val + 1 + log_offset);
- const Sample max = log(max_port_val + 1 + log_offset);
- scaled_value = expf(nval * (max - min) + min) - 1 - log_offset;
- } else {
- scaled_value = ((nval) * (max_port_val - min_port_val)) + min_port_val;
- }
-
- _audio_port->set_control_value(context, time, scaled_value);
-
- return true;
-}
-
-} // namespace Internals
-} // namespace Server
-} // namespace Ingen
diff --git a/src/server/internals/Controller.hpp b/src/server/internals/Controller.hpp
deleted file mode 100644
index 720f78c0..00000000
--- a/src/server/internals/Controller.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2016 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef INGEN_INTERNALS_CONTROLLER_HPP
-#define INGEN_INTERNALS_CONTROLLER_HPP
-
-#include "InternalBlock.hpp"
-
-namespace Ingen {
-namespace Server {
-
-class InputPort;
-class OutputPort;
-class InternalPlugin;
-
-namespace Internals {
-
-/** MIDI control input block.
- *
- * Creating one of these nodes is how a user makes "MIDI Bindings". Note that
- * this node will always be monophonic, the poly parameter is ignored.
- *
- * \ingroup engine
- */
-class ControllerNode : public InternalBlock
-{
-public:
- ControllerNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate);
-
- void run(RunContext& context);
-
- bool control(RunContext& context, uint8_t control_num, uint8_t val, FrameTime time);
-
- void learn() { _learning = true; }
-
- static InternalPlugin* internal_plugin(URIs& uris);
-
-private:
- InputPort* _midi_in_port;
- OutputPort* _midi_out_port;
- InputPort* _param_port;
- InputPort* _log_port;
- InputPort* _min_port;
- InputPort* _max_port;
- OutputPort* _audio_port;
- bool _learning;
-};
-
-} // namespace Server
-} // namespace Ingen
-} // namespace Internals
-
-#endif // INGEN_INTERNALS_CONTROLLER_HPP
diff --git a/src/server/internals/Note.cpp b/src/server/internals/Note.cpp
deleted file mode 100644
index b39dd1d4..00000000
--- a/src/server/internals/Note.cpp
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <cmath>
-
-#include "ingen/URIs.hpp"
-#include "lv2/lv2plug.in/ns/ext/atom/util.h"
-#include "lv2/lv2plug.in/ns/ext/midi/midi.h"
-#include "raul/Array.hpp"
-#include "raul/Maid.hpp"
-
-#include "Buffer.hpp"
-#include "GraphImpl.hpp"
-#include "InputPort.hpp"
-#include "InternalPlugin.hpp"
-#include "OutputPort.hpp"
-#include "RunContext.hpp"
-#include "ingen_config.h"
-#include "internals/Note.hpp"
-#include "util.hpp"
-
-// #define NOTE_DEBUG 1
-
-namespace Ingen {
-namespace Server {
-namespace Internals {
-
-InternalPlugin* NoteNode::internal_plugin(URIs& uris) {
- return new InternalPlugin(
- uris, URI(NS_INTERNALS "Note"), Raul::Symbol("note"));
-}
-
-NoteNode::NoteNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate)
- : InternalBlock(plugin, symbol, polyphonic, parent, srate)
- , _voices(bufs.maid().make_managed<Voices>(_polyphony))
- , _sustain(false)
-{
- const Ingen::URIs& uris = bufs.uris();
- _ports = bufs.maid().make_managed<Ports>(8);
-
- const Atom zero = bufs.forge().make(0.0f);
- const Atom one = bufs.forge().make(1.0f);
-
- _midi_in_port = new InputPort(bufs, this, Raul::Symbol("input"), 0, 1,
- PortType::ATOM, uris.atom_Sequence, Atom());
- _midi_in_port->set_property(uris.lv2_name, bufs.forge().alloc("Input"));
- _midi_in_port->set_property(uris.atom_supports,
- bufs.forge().make_urid(uris.midi_MidiEvent));
- _ports->at(0) = _midi_in_port;
-
- _freq_port = new OutputPort(bufs, this, Raul::Symbol("frequency"), 1, _polyphony,
- PortType::ATOM, uris.atom_Sequence,
- bufs.forge().make(440.0f));
- _freq_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _freq_port->set_property(uris.lv2_name, bufs.forge().alloc("Frequency"));
- _freq_port->set_property(uris.lv2_minimum, bufs.forge().make(16.0f));
- _freq_port->set_property(uris.lv2_maximum, bufs.forge().make(25088.0f));
- _ports->at(1) = _freq_port;
-
- _num_port = new OutputPort(bufs, this, Raul::Symbol("number"), 1, _polyphony,
- PortType::ATOM, uris.atom_Sequence, zero);
- _num_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _num_port->set_property(uris.lv2_minimum, zero);
- _num_port->set_property(uris.lv2_maximum, bufs.forge().make(127.0f));
- _num_port->set_property(uris.lv2_portProperty, uris.lv2_integer);
- _num_port->set_property(uris.lv2_name, bufs.forge().alloc("Number"));
- _ports->at(2) = _num_port;
-
- _vel_port = new OutputPort(bufs, this, Raul::Symbol("velocity"), 2, _polyphony,
- PortType::ATOM, uris.atom_Sequence, zero);
- _vel_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _vel_port->set_property(uris.lv2_minimum, zero);
- _vel_port->set_property(uris.lv2_maximum, one);
- _vel_port->set_property(uris.lv2_name, bufs.forge().alloc("Velocity"));
- _ports->at(3) = _vel_port;
-
- _gate_port = new OutputPort(bufs, this, Raul::Symbol("gate"), 3, _polyphony,
- PortType::ATOM, uris.atom_Sequence, zero);
- _gate_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _gate_port->set_property(uris.lv2_portProperty, uris.lv2_toggled);
- _gate_port->set_property(uris.lv2_name, bufs.forge().alloc("Gate"));
- _ports->at(4) = _gate_port;
-
- _trig_port = new OutputPort(bufs, this, Raul::Symbol("trigger"), 4, _polyphony,
- PortType::ATOM, uris.atom_Sequence, zero);
- _trig_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _trig_port->set_property(uris.lv2_portProperty, uris.lv2_toggled);
- _trig_port->set_property(uris.lv2_name, bufs.forge().alloc("Trigger"));
- _ports->at(5) = _trig_port;
-
- _bend_port = new OutputPort(bufs, this, Raul::Symbol("bend"), 5, _polyphony,
- PortType::ATOM, uris.atom_Sequence, zero);
- _bend_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _bend_port->set_property(uris.lv2_name, bufs.forge().alloc("Bender"));
- _bend_port->set_property(uris.lv2_default, zero);
- _bend_port->set_property(uris.lv2_minimum, bufs.forge().make(-1.0f));
- _bend_port->set_property(uris.lv2_maximum, one);
- _ports->at(6) = _bend_port;
-
- _pressure_port = new OutputPort(bufs, this, Raul::Symbol("pressure"), 6, _polyphony,
- PortType::ATOM, uris.atom_Sequence, zero);
- _pressure_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _pressure_port->set_property(uris.lv2_name, bufs.forge().alloc("Pressure"));
- _pressure_port->set_property(uris.lv2_default, zero);
- _pressure_port->set_property(uris.lv2_minimum, zero);
- _pressure_port->set_property(uris.lv2_maximum, one);
- _ports->at(7) = _pressure_port;
-}
-
-bool
-NoteNode::prepare_poly(BufferFactory& bufs, uint32_t poly)
-{
- if (!_polyphonic) {
- return true;
- }
-
- BlockImpl::prepare_poly(bufs, poly);
-
- if (_prepared_voices && poly <= _prepared_voices->size()) {
- return true;
- }
-
- _prepared_voices = bufs.maid().make_managed<Voices>(
- poly, *_voices, Voice());
-
- return true;
-}
-
-bool
-NoteNode::apply_poly(RunContext& context, uint32_t poly)
-{
- if (!BlockImpl::apply_poly(context, poly)) {
- return false;
- }
-
- if (_prepared_voices) {
- assert(_polyphony <= _prepared_voices->size());
- _voices = std::move(_prepared_voices);
- }
- assert(_polyphony <= _voices->size());
-
- return true;
-}
-
-void
-NoteNode::run(RunContext& context)
-{
- Buffer* const midi_in = _midi_in_port->buffer(0).get();
- LV2_Atom_Sequence* seq = midi_in->get<LV2_Atom_Sequence>();
- LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
- const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY_CONST(&ev->body);
- const FrameTime time = context.start() + (FrameTime)ev->time.frames;
- if (ev->body.type == _midi_in_port->bufs().uris().midi_MidiEvent &&
- ev->body.size >= 3) {
- switch (lv2_midi_message_type(buf)) {
- case LV2_MIDI_MSG_NOTE_ON:
- if (buf[2] == 0) {
- note_off(context, buf[1], time);
- } else {
- note_on(context, buf[1], buf[2], time);
- }
- break;
- case LV2_MIDI_MSG_NOTE_OFF:
- note_off(context, buf[1], time);
- break;
- case LV2_MIDI_MSG_CONTROLLER:
- switch (buf[1]) {
- case LV2_MIDI_CTL_ALL_NOTES_OFF:
- case LV2_MIDI_CTL_ALL_SOUNDS_OFF:
- all_notes_off(context, time);
- break;
- case LV2_MIDI_CTL_SUSTAIN:
- if (buf[2] > 63) {
- sustain_on(context, time);
- } else {
- sustain_off(context, time);
- }
- break;
- }
- break;
- case LV2_MIDI_MSG_BENDER:
- bend(context, time, (((((uint16_t)buf[2] << 7) | buf[1]) - 8192.0f)
- / 8192.0f));
- break;
- case LV2_MIDI_MSG_CHANNEL_PRESSURE:
- channel_pressure(context, time, buf[1] / 127.0f);
- break;
- case LV2_MIDI_MSG_NOTE_PRESSURE:
- note_pressure(context, time, buf[1], buf[2] / 127.0f);
- break;
- default:
- break;
- }
- }
- }
-}
-
-static inline float
-note_to_freq(uint8_t num)
-{
- static const float A4 = 440.0f;
- return A4 * powf(2.0f, (float)(num - 57.0f) / 12.0f);
-}
-
-void
-NoteNode::note_on(RunContext& context, uint8_t note_num, uint8_t velocity, FrameTime time)
-{
- assert(time >= context.start() && time <= context.end());
- assert(note_num <= 127);
-
- Key* key = &_keys[note_num];
- Voice* voice = nullptr;
- uint32_t voice_num = 0;
-
- if (key->state != Key::State::OFF) {
- return;
- }
-
- // Look for free voices
- for (uint32_t i=0; i < _polyphony; ++i) {
- if ((*_voices)[i].state == Voice::State::FREE) {
- voice = &(*_voices)[i];
- voice_num = i;
- break;
- }
- }
-
- // If we didn't find a free one, steal the oldest
- if (voice == nullptr) {
- voice_num = 0;
- voice = &(*_voices)[0];
- FrameTime oldest_time = (*_voices)[0].time;
- for (uint32_t i=1; i < _polyphony; ++i) {
- if ((*_voices)[i].time < oldest_time) {
- voice = &(*_voices)[i];
- voice_num = i;
- oldest_time = voice->time;
- }
- }
- }
- assert(voice != nullptr);
- assert(voice == &(*_voices)[voice_num]);
-
- // Update stolen key, if applicable
- if (voice->state == Voice::State::ACTIVE) {
- assert(_keys[voice->note].state == Key::State::ON_ASSIGNED);
- assert(_keys[voice->note].voice == voice_num);
- _keys[voice->note].state = Key::State::ON_UNASSIGNED;
- }
-
- // Store key information for later reallocation on note off
- key->state = Key::State::ON_ASSIGNED;
- key->voice = voice_num;
- key->time = time;
-
- // Check if we just triggered this voice at the same time
- // (Double note-on at the same sample on the same voice)
- const bool double_trigger = (voice->state == Voice::State::ACTIVE &&
- voice->time == time);
-
- // Trigger voice
- voice->state = Voice::State::ACTIVE;
- voice->note = note_num;
- voice->time = time;
-
- assert(_keys[voice->note].state == Key::State::ON_ASSIGNED);
- assert(_keys[voice->note].voice == voice_num);
-
- _freq_port->set_voice_value(context, voice_num, time, note_to_freq(note_num));
- _num_port->set_voice_value(context, voice_num, time, (float)note_num);
- _vel_port->set_voice_value(context, voice_num, time, velocity / 127.0f);
- _gate_port->set_voice_value(context, voice_num, time, 1.0f);
- if (!double_trigger) {
- _trig_port->set_voice_value(context, voice_num, time, 1.0f);
- _trig_port->set_voice_value(context, voice_num, time + 1, 0.0f);
- }
-
- assert(key->state == Key::State::ON_ASSIGNED);
- assert(voice->state == Voice::State::ACTIVE);
- assert(key->voice == voice_num);
- assert((*_voices)[key->voice].note == note_num);
-}
-
-void
-NoteNode::note_off(RunContext& context, uint8_t note_num, FrameTime time)
-{
- assert(time >= context.start() && time <= context.end());
-
- Key* key = &_keys[note_num];
-
- if (key->state == Key::State::ON_ASSIGNED) {
- // Assigned key, turn off voice and key
- if ((*_voices)[key->voice].state == Voice::State::ACTIVE) {
- assert((*_voices)[key->voice].note == note_num);
- if ( ! _sustain) {
- free_voice(context, key->voice, time);
- } else {
- (*_voices)[key->voice].state = Voice::State::HOLDING;
- }
- }
- }
-
- key->state = Key::State::OFF;
-}
-
-void
-NoteNode::free_voice(RunContext& context, uint32_t voice, FrameTime time)
-{
- assert(time >= context.start() && time <= context.end());
-
- // Find a key to reassign to the freed voice (the newest, if there is one)
- Key* replace_key = nullptr;
- uint8_t replace_key_num = 0;
-
- for (uint8_t i = 0; i <= 127; ++i) {
- if (_keys[i].state == Key::State::ON_UNASSIGNED) {
- if (replace_key == nullptr || _keys[i].time > replace_key->time) {
- replace_key = &_keys[i];
- replace_key_num = i;
- }
- }
- }
-
- if (replace_key != nullptr) { // Found a key to assign to freed voice
- assert(&_keys[replace_key_num] == replace_key);
- assert(replace_key->state == Key::State::ON_UNASSIGNED);
-
- // Change the freq but leave the gate high and don't retrigger
- _freq_port->set_voice_value(context, voice, time, note_to_freq(replace_key_num));
- _num_port->set_voice_value(context, voice, time, replace_key_num);
-
- replace_key->state = Key::State::ON_ASSIGNED;
- replace_key->voice = voice;
- _keys[(*_voices)[voice].note].state = Key::State::ON_UNASSIGNED;
- (*_voices)[voice].note = replace_key_num;
- (*_voices)[voice].state = Voice::State::ACTIVE;
- } else {
- // No new note for voice, deactivate (set gate low)
- _gate_port->set_voice_value(context, voice, time, 0.0f);
- (*_voices)[voice].state = Voice::State::FREE;
- }
-}
-
-void
-NoteNode::all_notes_off(RunContext& context, FrameTime time)
-{
- assert(time >= context.start() && time <= context.end());
-
- // FIXME: set all keys to Key::OFF?
-
- for (uint32_t i = 0; i < _polyphony; ++i) {
- _gate_port->set_voice_value(context, i, time, 0.0f);
- (*_voices)[i].state = Voice::State::FREE;
- }
-}
-
-void
-NoteNode::sustain_on(RunContext& context, FrameTime time)
-{
- _sustain = true;
-}
-
-void
-NoteNode::sustain_off(RunContext& context, FrameTime time)
-{
- assert(time >= context.start() && time <= context.end());
-
- _sustain = false;
-
- for (uint32_t i=0; i < _polyphony; ++i) {
- if ((*_voices)[i].state == Voice::State::HOLDING) {
- free_voice(context, i, time);
- }
- }
-}
-
-void
-NoteNode::bend(RunContext& context, FrameTime time, float amount)
-{
- _bend_port->set_control_value(context, time, amount);
-}
-
-void
-NoteNode::note_pressure(RunContext& context, FrameTime time, uint8_t note_num, float amount)
-{
- for (uint32_t i=0; i < _polyphony; ++i) {
- if ((*_voices)[i].state != Voice::State::FREE && (*_voices)[i].note == note_num) {
- _pressure_port->set_voice_value(context, i, time, amount);
- return;
- }
- }
-}
-
-void
-NoteNode::channel_pressure(RunContext& context, FrameTime time, float amount)
-{
- _pressure_port->set_control_value(context, time, amount);
-}
-
-} // namespace Internals
-} // namespace Server
-} // namespace Ingen
diff --git a/src/server/internals/Note.hpp b/src/server/internals/Note.hpp
deleted file mode 100644
index 1e60c130..00000000
--- a/src/server/internals/Note.hpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef INGEN_INTERNALS_NOTE_HPP
-#define INGEN_INTERNALS_NOTE_HPP
-
-#include "InternalBlock.hpp"
-#include "types.hpp"
-
-namespace Ingen {
-namespace Server {
-
-class InputPort;
-class OutputPort;
-class InternalPlugin;
-
-namespace Internals {
-
-/** MIDI note input block.
- *
- * For pitched instruments like keyboard, etc.
- *
- * \ingroup engine
- */
-class NoteNode : public InternalBlock
-{
-public:
- NoteNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate);
-
- bool prepare_poly(BufferFactory& bufs, uint32_t poly);
- bool apply_poly(RunContext& context, uint32_t poly);
-
- void run(RunContext& context);
-
- void note_on(RunContext& context, uint8_t note_num, uint8_t velocity, FrameTime time);
- void note_off(RunContext& context, uint8_t note_num, FrameTime time);
- void all_notes_off(RunContext& context, FrameTime time);
-
- void sustain_on(RunContext& context, FrameTime time);
- void sustain_off(RunContext& context, FrameTime time);
-
- void bend(RunContext& context, FrameTime time, float amount);
- void note_pressure(RunContext& context, FrameTime time, uint8_t note_num, float amount);
- void channel_pressure(RunContext& context, FrameTime time, float amount);
-
- static InternalPlugin* internal_plugin(URIs& uris);
-
-private:
- /** Key, one for each key on the keyboard */
- struct Key {
- enum class State { OFF, ON_ASSIGNED, ON_UNASSIGNED };
- Key() : state(State::OFF), voice(0), time(0) {}
- State state;
- uint32_t voice;
- SampleCount time;
- };
-
- /** Voice, one of these always exists for each voice */
- struct Voice {
- enum class State { FREE, ACTIVE, HOLDING };
- Voice() : state(State::FREE), note(0), time(0) {}
- State state;
- uint8_t note;
- SampleCount time;
- };
-
- typedef Raul::Array<Voice> Voices;
-
- void free_voice(RunContext& context, uint32_t voice, FrameTime time);
-
- MPtr<Voices> _voices;
- MPtr<Voices> _prepared_voices;
-
- Key _keys[128];
- bool _sustain; ///< Whether or not hold pedal is depressed
-
- InputPort* _midi_in_port;
- OutputPort* _freq_port;
- OutputPort* _num_port;
- OutputPort* _vel_port;
- OutputPort* _gate_port;
- OutputPort* _trig_port;
- OutputPort* _bend_port;
- OutputPort* _pressure_port;
-};
-
-} // namespace Server
-} // namespace Ingen
-} // namespace Internals
-
-#endif // INGEN_INTERNALS_NOTE_HPP
diff --git a/src/server/internals/Time.cpp b/src/server/internals/Time.cpp
deleted file mode 100644
index 5474bf21..00000000
--- a/src/server/internals/Time.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "ingen/URIs.hpp"
-#include "lv2/lv2plug.in/ns/ext/atom/util.h"
-#include "lv2/lv2plug.in/ns/ext/midi/midi.h"
-
-#include "Buffer.hpp"
-#include "Driver.hpp"
-#include "Engine.hpp"
-#include "InternalPlugin.hpp"
-#include "OutputPort.hpp"
-#include "RunContext.hpp"
-#include "internals/Time.hpp"
-#include "util.hpp"
-
-namespace Ingen {
-namespace Server {
-namespace Internals {
-
-InternalPlugin* TimeNode::internal_plugin(URIs& uris) {
- return new InternalPlugin(
- uris, URI(NS_INTERNALS "Time"), Raul::Symbol("time"));
-}
-
-TimeNode::TimeNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate)
- : InternalBlock(plugin, symbol, false, parent, srate)
-{
- const Ingen::URIs& uris = bufs.uris();
- _ports = bufs.maid().make_managed<Ports>(1);
-
- _notify_port = new OutputPort(
- bufs, this, Raul::Symbol("notify"), 0, 1,
- PortType::ATOM, uris.atom_Sequence, Atom(), 1024);
- _notify_port->set_property(uris.lv2_name, bufs.forge().alloc("Notify"));
- _notify_port->set_property(uris.atom_supports,
- bufs.forge().make_urid(uris.time_Position));
- _ports->at(0) = _notify_port;
-}
-
-void
-TimeNode::run(RunContext& context)
-{
- BufferRef buf = _notify_port->buffer(0);
- LV2_Atom_Sequence* seq = buf->get<LV2_Atom_Sequence>();
-
- // Initialise output to the empty sequence
- seq->atom.type = _notify_port->bufs().uris().atom_Sequence;
- seq->atom.size = sizeof(LV2_Atom_Sequence_Body);
- seq->body.unit = 0;
- seq->body.pad = 0;
-
- // Ask the driver to append any time events for this cycle
- context.engine().driver()->append_time_events(
- context, *_notify_port->buffer(0));
-}
-
-} // namespace Internals
-} // namespace Server
-} // namespace Ingen
diff --git a/src/server/internals/Time.hpp b/src/server/internals/Time.hpp
deleted file mode 100644
index 1a063f8d..00000000
--- a/src/server/internals/Time.hpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2015 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef INGEN_INTERNALS_TIME_HPP
-#define INGEN_INTERNALS_TIME_HPP
-
-#include "InternalBlock.hpp"
-
-namespace Ingen {
-namespace Server {
-
-class InputPort;
-class OutputPort;
-class InternalPlugin;
-
-namespace Internals {
-
-/** Time information block.
- *
- * This sends messages whenever the transport speed or tempo changes.
- *
- * \ingroup engine
- */
-class TimeNode : public InternalBlock
-{
-public:
- TimeNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate);
-
- void run(RunContext& context);
-
- static InternalPlugin* internal_plugin(URIs& uris);
-
-private:
- OutputPort* _notify_port;
-};
-
-} // namespace Server
-} // namespace Ingen
-} // namespace Internals
-
-#endif // INGEN_INTERNALS_TIME_HPP
diff --git a/src/server/internals/Trigger.cpp b/src/server/internals/Trigger.cpp
deleted file mode 100644
index 69967877..00000000
--- a/src/server/internals/Trigger.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2016 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <cmath>
-
-#include "ingen/URIs.hpp"
-#include "lv2/lv2plug.in/ns/ext/atom/util.h"
-#include "lv2/lv2plug.in/ns/ext/midi/midi.h"
-
-#include "Buffer.hpp"
-#include "Engine.hpp"
-#include "InputPort.hpp"
-#include "InternalPlugin.hpp"
-#include "OutputPort.hpp"
-#include "RunContext.hpp"
-#include "ingen_config.h"
-#include "internals/Trigger.hpp"
-#include "util.hpp"
-
-namespace Ingen {
-namespace Server {
-namespace Internals {
-
-InternalPlugin* TriggerNode::internal_plugin(URIs& uris) {
- return new InternalPlugin(
- uris, URI(NS_INTERNALS "Trigger"), Raul::Symbol("trigger"));
-}
-
-TriggerNode::TriggerNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate)
- : InternalBlock(plugin, symbol, false, parent, srate)
- , _learning(false)
-{
- const Ingen::URIs& uris = bufs.uris();
- _ports = bufs.maid().make_managed<Ports>(6);
-
- const Atom zero = bufs.forge().make(0.0f);
-
- _midi_in_port = new InputPort(bufs, this, Raul::Symbol("input"), 0, 1,
- PortType::ATOM, uris.atom_Sequence, Atom());
- _midi_in_port->set_property(uris.lv2_name, bufs.forge().alloc("Input"));
- _midi_in_port->set_property(uris.atom_supports,
- bufs.forge().make_urid(uris.midi_MidiEvent));
- _ports->at(0) = _midi_in_port;
-
- _midi_out_port = new OutputPort(bufs, this, Raul::Symbol("event"), 1, 1,
- PortType::ATOM, uris.atom_Sequence, Atom());
- _midi_out_port->set_property(uris.lv2_name, bufs.forge().alloc("Event"));
- _midi_out_port->set_property(uris.atom_supports,
- bufs.forge().make_urid(uris.midi_MidiEvent));
- _ports->at(1) = _midi_out_port;
-
- _note_port = new InputPort(bufs, this, Raul::Symbol("note"), 2, 1,
- PortType::ATOM, uris.atom_Sequence,
- bufs.forge().make(60.0f));
- _note_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _note_port->set_property(uris.lv2_minimum, zero);
- _note_port->set_property(uris.lv2_maximum, bufs.forge().make(127.0f));
- _note_port->set_property(uris.lv2_portProperty, uris.lv2_integer);
- _note_port->set_property(uris.lv2_name, bufs.forge().alloc("Note"));
- _ports->at(2) = _note_port;
-
- _gate_port = new OutputPort(bufs, this, Raul::Symbol("gate"), 3, 1,
- PortType::ATOM, uris.atom_Sequence, zero);
- _gate_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _gate_port->set_property(uris.lv2_portProperty, uris.lv2_toggled);
- _gate_port->set_property(uris.lv2_name, bufs.forge().alloc("Gate"));
- _ports->at(3) = _gate_port;
-
- _trig_port = new OutputPort(bufs, this, Raul::Symbol("trigger"), 4, 1,
- PortType::ATOM, uris.atom_Sequence, zero);
- _trig_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _trig_port->set_property(uris.lv2_portProperty, uris.lv2_toggled);
- _trig_port->set_property(uris.lv2_name, bufs.forge().alloc("Trigger"));
- _ports->at(4) = _trig_port;
-
- _vel_port = new OutputPort(bufs, this, Raul::Symbol("velocity"), 5, 1,
- PortType::ATOM, uris.atom_Sequence, zero);
- _vel_port->set_property(uris.atom_supports, bufs.uris().atom_Float);
- _vel_port->set_property(uris.lv2_minimum, zero);
- _vel_port->set_property(uris.lv2_maximum, bufs.forge().make(1.0f));
- _vel_port->set_property(uris.lv2_name, bufs.forge().alloc("Velocity"));
- _ports->at(5) = _vel_port;
-}
-
-void
-TriggerNode::run(RunContext& context)
-{
- const BufferRef midi_in = _midi_in_port->buffer(0);
- LV2_Atom_Sequence* const seq = midi_in->get<LV2_Atom_Sequence>();
- const BufferRef midi_out = _midi_out_port->buffer(0);
-
- // Initialise output to the empty sequence
- midi_out->prepare_write(context);
-
- LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
- const int64_t t = ev->time.frames;
- const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY(&ev->body);
- bool emit = false;
- if (ev->body.type == _midi_in_port->bufs().uris().midi_MidiEvent &&
- ev->body.size >= 3) {
- const FrameTime time = context.start() + t;
- switch (lv2_midi_message_type(buf)) {
- case LV2_MIDI_MSG_NOTE_ON:
- if (buf[2] == 0) {
- emit = note_off(context, buf[1], time);
- } else {
- emit = note_on(context, buf[1], buf[2], time);
- }
- break;
- case LV2_MIDI_MSG_NOTE_OFF:
- emit = note_off(context, buf[1], time);
- break;
- case LV2_MIDI_MSG_CONTROLLER:
- switch (buf[1]) {
- case LV2_MIDI_CTL_ALL_NOTES_OFF:
- case LV2_MIDI_CTL_ALL_SOUNDS_OFF:
- _gate_port->set_control_value(context, time, 0.0f);
- emit = true;
- }
- default:
- break;
- }
- }
-
- if (emit) {
- midi_out->append_event(t, &ev->body);
- }
- }
-}
-
-bool
-TriggerNode::note_on(RunContext& context, uint8_t note_num, uint8_t velocity, FrameTime time)
-{
- assert(time >= context.start() && time <= context.end());
- const uint32_t offset = time - context.start();
-
- if (_learning) {
- _note_port->set_control_value(context, time, (float)note_num);
- _note_port->force_monitor_update();
- _learning = false;
- }
-
- if (note_num == lrintf(_note_port->buffer(0)->value_at(offset))) {
- _gate_port->set_control_value(context, time, 1.0f);
- _trig_port->set_control_value(context, time, 1.0f);
- _trig_port->set_control_value(context, time + 1, 0.0f);
- _vel_port->set_control_value(context, time, velocity / 127.0f);
- return true;
- }
- return false;
-}
-
-bool
-TriggerNode::note_off(RunContext& context, uint8_t note_num, FrameTime time)
-{
- assert(time >= context.start() && time <= context.end());
- const uint32_t offset = time - context.start();
-
- if (note_num == lrintf(_note_port->buffer(0)->value_at(offset))) {
- _gate_port->set_control_value(context, time, 0.0f);
- return true;
- }
-
- return false;
-}
-
-} // namespace Internals
-} // namespace Server
-} // namespace Ingen
diff --git a/src/server/internals/Trigger.hpp b/src/server/internals/Trigger.hpp
deleted file mode 100644
index 4d67395a..00000000
--- a/src/server/internals/Trigger.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- This file is part of Ingen.
- Copyright 2007-2016 David Robillard <http://drobilla.net/>
-
- Ingen is free software: you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free
- Software Foundation, either version 3 of the License, or any later version.
-
- Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for details.
-
- You should have received a copy of the GNU Affero General Public License
- along with Ingen. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef INGEN_INTERNALS_TRIGGER_HPP
-#define INGEN_INTERNALS_TRIGGER_HPP
-
-#include "InternalBlock.hpp"
-
-namespace Ingen {
-namespace Server {
-
-class InputPort;
-class OutputPort;
-class InternalPlugin;
-
-namespace Internals {
-
-/** MIDI trigger input block.
- *
- * Just has a gate, for drums etc. A control port is used to select
- * which note number is responded to.
- *
- * Note that this block is always monophonic, the poly parameter is ignored.
- * (Should that change?)
- *
- * \ingroup engine
- */
-class TriggerNode : public InternalBlock
-{
-public:
- TriggerNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate);
-
- void run(RunContext& context);
-
- bool note_on(RunContext& context, uint8_t note_num, uint8_t velocity, FrameTime time);
- bool note_off(RunContext& context, uint8_t note_num, FrameTime time);
-
- void learn() { _learning = true; }
-
- static InternalPlugin* internal_plugin(URIs& uris);
-
-private:
- bool _learning;
-
- InputPort* _midi_in_port;
- OutputPort* _midi_out_port;
- InputPort* _note_port;
- OutputPort* _gate_port;
- OutputPort* _trig_port;
- OutputPort* _vel_port;
-};
-
-} // namespace Server
-} // namespace Ingen
-} // namespace Internals
-
-#endif // INGEN_INTERNALS_TRIGGER_HPP