summaryrefslogtreecommitdiffstats
path: root/src/server/internals
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2015-11-14 18:47:19 -0500
committerDavid Robillard <d@drobilla.net>2016-10-02 12:24:56 -0400
commita077166ec6c31ad4aaab738b9dffc139bf3a4d50 (patch)
tree8e32e8003bebe0d879b1f9879f3e88c90b9d1b26 /src/server/internals
parentc73c877f8bd09e0d5a6663ea5ba32a54465f5376 (diff)
downloadingen-a077166ec6c31ad4aaab738b9dffc139bf3a4d50.tar.gz
ingen-a077166ec6c31ad4aaab738b9dffc139bf3a4d50.tar.bz2
ingen-a077166ec6c31ad4aaab738b9dffc139bf3a4d50.zip
Replace Delay internal with simpler BlockDelay
Diffstat (limited to 'src/server/internals')
-rw-r--r--src/server/internals/BlockDelay.cpp89
-rw-r--r--src/server/internals/BlockDelay.hpp (renamed from src/server/internals/Delay.hpp)37
-rw-r--r--src/server/internals/Delay.cpp205
3 files changed, 102 insertions, 229 deletions
diff --git a/src/server/internals/BlockDelay.cpp b/src/server/internals/BlockDelay.cpp
new file mode 100644
index 00000000..39bd09b9
--- /dev/null
+++ b/src/server/internals/BlockDelay.cpp
@@ -0,0 +1,89 @@
+/*
+ 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 <limits.h>
+
+#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 "ProcessContext.hpp"
+#include "internals/BlockDelay.hpp"
+
+namespace Ingen {
+namespace Server {
+namespace Internals {
+
+InternalPlugin* BlockDelayNode::internal_plugin(URIs& uris) {
+ return new InternalPlugin(
+ uris, Raul::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 = new Raul::Array<PortImpl*>(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.get_buffer(
+ bufs.uris().atom_Sound, 0, bufs.audio_buffer_size(), false, true);
+
+ BlockImpl::activate(bufs);
+}
+
+void
+BlockDelayNode::run(ProcessContext& 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/Delay.hpp b/src/server/internals/BlockDelay.hpp
index 0dc5da30..e1ef5311 100644
--- a/src/server/internals/Delay.hpp
+++ b/src/server/internals/BlockDelay.hpp
@@ -14,11 +14,10 @@
along with Ingen. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef INGEN_INTERNALS_DELAY_HPP
-#define INGEN_INTERNALS_DELAY_HPP
-
-#include <math.h>
+#ifndef INGEN_INTERNALS_BLOCKDELAY_HPP
+#define INGEN_INTERNALS_BLOCKDELAY_HPP
+#include "BufferRef.hpp"
#include "InternalBlock.hpp"
#include "types.hpp"
@@ -32,17 +31,17 @@ class BufferFactory;
namespace Internals {
-class DelayNode : public InternalBlock
+class BlockDelayNode : public InternalBlock
{
public:
- DelayNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate);
+ BlockDelayNode(InternalPlugin* plugin,
+ BufferFactory& bufs,
+ const Raul::Symbol& symbol,
+ bool polyphonic,
+ GraphImpl* parent,
+ SampleRate srate);
- ~DelayNode();
+ ~BlockDelayNode();
void activate(BufferFactory& bufs);
@@ -50,24 +49,14 @@ public:
static InternalPlugin* internal_plugin(URIs& uris);
- float delay_samples() const { return _delay_samples; }
-
private:
- inline float& buffer_at(int64_t phase) const { return _buffer[phase & _buffer_mask]; }
-
- InputPort* _delay_port;
InputPort* _in_port;
OutputPort* _out_port;
- float* _buffer;
- uint32_t _buffer_length;
- uint32_t _buffer_mask;
- uint64_t _write_phase;
- float _last_delay_time;
- float _delay_samples;
+ BufferRef _buffer;
};
} // namespace Server
} // namespace Ingen
} // namespace Internals
-#endif // INGEN_INTERNALS_DELAY_HPP
+#endif // INGEN_INTERNALS_BLOCKDELAY_HPP
diff --git a/src/server/internals/Delay.cpp b/src/server/internals/Delay.cpp
deleted file mode 100644
index 6ac97008..00000000
--- a/src/server/internals/Delay.cpp
+++ /dev/null
@@ -1,205 +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 <limits.h>
-
-#include <cmath>
-
-#include "ingen/URIs.hpp"
-#include "raul/Array.hpp"
-#include "raul/Maid.hpp"
-
-#include "Buffer.hpp"
-#include "Driver.hpp"
-#include "Engine.hpp"
-#include "GraphImpl.hpp"
-#include "InputPort.hpp"
-#include "InternalPlugin.hpp"
-#include "OutputPort.hpp"
-#include "RunContext.hpp"
-#include "internals/Delay.hpp"
-#include "util.hpp"
-
-#define CALC_DELAY(delaytime) \
- (f_clamp (delaytime * (float)sample_rate, 1.0f, (float)(buffer_mask + 1)))
-
-using namespace std;
-
-namespace Ingen {
-namespace Server {
-namespace Internals {
-
-static const float MAX_DELAY_SECONDS = 8.0f;
-
-InternalPlugin* DelayNode::internal_plugin(URIs& uris) {
- return new InternalPlugin(
- uris, Raul::URI(NS_INTERNALS "Delay"), Raul::Symbol("delay"));
-}
-
-DelayNode::DelayNode(InternalPlugin* plugin,
- BufferFactory& bufs,
- const Raul::Symbol& symbol,
- bool polyphonic,
- GraphImpl* parent,
- SampleRate srate)
- : InternalBlock(plugin, symbol, polyphonic, parent, srate)
- , _buffer(0)
- , _buffer_length(0)
- , _buffer_mask(0)
- , _write_phase(0)
-{
- const Ingen::URIs& uris = bufs.uris();
- _ports = new Raul::Array<PortImpl*>(3);
-
- const float default_delay = 1.0f;
- _last_delay_time = default_delay;
- _delay_samples = default_delay;
-
- _delay_port = new InputPort(bufs, this, Raul::Symbol("delay"), 1, _polyphony,
- PortType::CONTROL, 0, bufs.forge().make(default_delay));
- _delay_port->set_property(uris.lv2_name, bufs.forge().alloc("Delay"));
- _delay_port->set_property(uris.lv2_default, bufs.forge().make(default_delay));
- _delay_port->set_property(uris.lv2_minimum, bufs.forge().make((float)(1.0/(double)srate)));
- _delay_port->set_property(uris.lv2_maximum, bufs.forge().make(MAX_DELAY_SECONDS));
- _ports->at(0) = _delay_port;
-
- _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("Input"));
- _ports->at(1) = _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("Output"));
- _ports->at(2) = _out_port;
-
- //_buffer = bufs.get(PortType::AUDIO, bufs.audio_buffer_size(buffer_length_frames), true);
-
-}
-
-DelayNode::~DelayNode()
-{
- //_buffer.reset();
- free(_buffer);
-}
-
-void
-DelayNode::activate(BufferFactory& bufs)
-{
- BlockImpl::activate(bufs);
- const SampleRate rate = bufs.engine().driver()->sample_rate();
- const SampleCount min_size = MAX_DELAY_SECONDS * rate;
-
- // Smallest power of two larger than min_size
- SampleCount size = 1;
- while (size < min_size)
- size <<= 1;
-
- _buffer = (float*)calloc(size, sizeof(float));
- _buffer_mask = size - 1;
- _buffer_length = size;
- //_buffer->clear();
- _write_phase = 0;
-}
-
-static inline float f_clamp(float x, float a, float b)
-{
- const float x1 = fabs(x - a);
- const float x2 = fabs(x - b);
-
- x = x1 + a + b;
- x -= x2;
- x *= 0.5;
-
- return x;
-}
-
-static inline float cube_interp(const float fr, const float inm1, const float
- in, const float inp1, const float inp2)
-{
- return in + 0.5f * fr * (
- inp1 - inm1 + fr * (
- 4.0f * inp1 + 2.0f * inm1 - 5.0f * in - inp2 + fr * (
- 3.0f * (in - inp1) - inm1 + inp2)));
-}
-
-void
-DelayNode::run(RunContext& context)
-{
- Buffer* const delay_buf = _delay_port->buffer(0).get();
- Buffer* const in_buf = _in_port->buffer(0).get();
- Buffer* const out_buf = _out_port->buffer(0).get();
-
- DelayNode* plugin_data = this;
-
- const float* const in = in_buf->samples();
- float* const out = out_buf->samples();
- const float delay_time = delay_buf->samples()[0];
- const uint32_t buffer_mask = plugin_data->_buffer_mask;
- const SampleRate sample_rate = context.engine().driver()->sample_rate();
- float delay_samples = plugin_data->_delay_samples;
- int64_t write_phase = plugin_data->_write_phase;
- const uint32_t sample_count = context.nframes();
-
- if (write_phase == 0) {
- _last_delay_time = delay_time;
- _delay_samples = delay_samples = CALC_DELAY(delay_time);
- }
-
- if (delay_time == _last_delay_time) {
- const int64_t idelay_samples = (int64_t)delay_samples;
- const float frac = delay_samples - idelay_samples;
-
- for (uint32_t i = 0; i < sample_count; i++) {
- int64_t read_phase = write_phase - (int64_t)delay_samples;
- const float read = cube_interp(frac,
- buffer_at(read_phase - 1),
- buffer_at(read_phase),
- buffer_at(read_phase + 1),
- buffer_at(read_phase + 2));
- buffer_at(write_phase++) = in[i];
- out[i] = read;
- }
- } else {
- const float next_delay_samples = CALC_DELAY(delay_time);
- const float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count;
-
- for (uint32_t i = 0; i < sample_count; i++) {
- delay_samples += delay_samples_slope;
- write_phase++;
- const int64_t read_phase = write_phase - (int64_t)delay_samples;
- const int64_t idelay_samples = (int64_t)delay_samples;
- const float frac = delay_samples - idelay_samples;
- const float read = cube_interp(frac,
- buffer_at(read_phase - 1),
- buffer_at(read_phase),
- buffer_at(read_phase + 1),
- buffer_at(read_phase + 2));
- buffer_at(write_phase) = in[i];
- out[i] = read;
- }
-
- _last_delay_time = delay_time;
- _delay_samples = delay_samples;
- }
-
- _write_phase = write_phase;
-}
-
-} // namespace Internals
-} // namespace Server
-} // namespace Ingen