2 * Copyright (C) 2016 Robin Gareus <robin@gareus.org>
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "ardour/audio_buffer.h"
20 #include "ardour/buffer_set.h"
21 #include "ardour/fixed_delay.h"
22 #include "ardour/midi_buffer.h"
24 using namespace ARDOUR;
26 FixedDelay::FixedDelay ()
31 for (size_t i = 0; i < DataType::num_types; ++i) {
32 _buffers.push_back (BufferVec ());
37 FixedDelay::~FixedDelay ()
43 FixedDelay::ensure_buffers (DataType type, size_t num_buffers, size_t buffer_capacity)
45 assert (type != DataType::NIL);
46 assert (type < _buffers.size ());
47 if (num_buffers == 0) {
50 BufferVec& bufs = _buffers[type];
51 if (bufs.size () < num_buffers || (bufs.size () > 0 && bufs[0]->buf->capacity () < buffer_capacity)) {
52 for (BufferVec::iterator i = bufs.begin (); i != bufs.end (); ++i) {
56 for (size_t i = 0; i < num_buffers; ++i) {
57 bufs.push_back (new DelayBuffer (type, buffer_capacity));
59 _count.set (type, num_buffers);
66 for (std::vector<BufferVec>::iterator i = _buffers.begin (); i != _buffers.end (); ++i) {
67 for (BufferVec::iterator j = (*i).begin (); j != (*i).end (); ++j) {
79 for (std::vector<BufferVec>::iterator i = _buffers.begin (); i != _buffers.end (); ++i) {
80 for (BufferVec::iterator j = (*i).begin (); j != (*i).end (); ++j) {
81 (*j)->buf->silence (_buf_size);
87 FixedDelay::configure (const ChanCount& count, framecnt_t max_delay, bool shrink)
90 if (max_delay == _max_delay && count == _count) {
93 _max_delay = max_delay;
94 } else if (max_delay <= _max_delay || count <= _count) {
96 _max_delay = std::max (_max_delay, max_delay);
99 // max possible (with all engines and during export)
100 static const framecnt_t max_block_length = 8192;
101 _buf_size = _max_delay + max_block_length;
102 for (DataType::iterator i = DataType::begin (); i != DataType::end (); ++i) {
103 ensure_buffers (*i, count.get (*i), _buf_size);
108 FixedDelay::set (const ChanCount& count, framecnt_t delay)
110 configure (count, delay, false);
111 if (_delay != delay) {
119 ARDOUR::DataType dt, uint32_t id,
120 Buffer& out, const Buffer& in,
122 framecnt_t dst_offset, framecnt_t src_offset)
125 out.read_from (in, n_frames, dst_offset, src_offset);
129 assert (dt < _buffers.size ());
130 assert (id < _buffers[dt].size ());
131 DelayBuffer *db = _buffers[dt][id];
133 if (db->pos + n_frames > _buf_size) {
134 uint32_t w0 = _buf_size - db->pos;
135 uint32_t w1 = db->pos + n_frames - _buf_size;
136 db->buf->read_from (in, w0, db->pos, src_offset);
137 db->buf->read_from (in, w1, 0, src_offset + w0);
139 db->buf->read_from (in, n_frames, db->pos, src_offset);
142 uint32_t rp = (db->pos + _buf_size - _delay) % _buf_size;
144 if (rp + n_frames > _buf_size) {
145 uint32_t r0 = _buf_size - rp;
146 uint32_t r1 = rp + n_frames - _buf_size;
147 out.read_from (*db->buf, r0, dst_offset, rp);
148 out.read_from (*db->buf, r1, dst_offset + r0, 0);
150 out.read_from (*db->buf, n_frames, dst_offset, rp);
153 db->pos = (db->pos + n_frames) % _buf_size;