30#ifndef APF_BLOCKDELAYLINE_H
31#define APF_BLOCKDELAYLINE_H
46template<
typename T,
typename Container = std::vector<T>>
50 using size_type =
typename Container::size_type;
51 using difference_type =
typename Container::difference_type;
52 using pointer =
typename Container::pointer;
64 bool valid = (delay <= _max_delay);
65 corrected = valid ? delay : _max_delay;
80 _data_circulator +=
static_cast<difference_type
>(
_block_size);
83 template<
typename Iterator>
86 template<
typename Iterator>
87 bool read_block(Iterator destination, size_type delay)
const;
89 template<
typename Iterator>
90 bool read_block(Iterator destination, size_type delay, T weight)
const;
103 const size_type _max_delay;
105 const size_type _number_of_blocks;
120template<
typename T,
typename Container>
122 , size_type max_delay)
123 : _block_size(block_size)
124 , _max_delay(max_delay)
130 std::max(size_type(2), (_max_delay + 2 * _block_size - 1) / _block_size))
131 , _data(_number_of_blocks * _block_size)
132 , _data_circulator(_data.begin(), _data.end())
134 _data_circulator, static_cast<difference_type>(_block_size))
149template<
typename T,
typename Container>
150template<
typename Iterator>
156 std::copy(source, source + _block_size, this->get_write_pointer());
164template<
typename T,
typename Container>
165template<
typename Iterator>
172 if (!this->delay_is_valid(delay))
return false;
173 circulator source = this->get_read_circulator(delay);
174 std::copy(source, source +
static_cast<difference_type
>(_block_size)
180template<
typename T,
typename Container>
181template<
typename Iterator>
184 , size_type delay, T weight)
const
186 if (!this->delay_is_valid(delay))
return false;
187 circulator source = this->get_read_circulator(delay);
188 std::transform(source, source +
static_cast<difference_type
>(_block_size)
189 , destination, [weight] (T in) {
return in * weight; });
199template<
typename T,
typename Container>
200typename BlockDelayLine<T, Container>::pointer
203 return &*_block_circulator.base().base();
211template<
typename T,
typename Container>
215 return _get_data_circulator() -
static_cast<difference_type
>(delay);
223template<
typename T,
typename Container = std::vector<T>>
230 using typename _base::size_type;
232 using difference_type =
typename _base::circulator::difference_type;
240 , size_type initial_delay)
241 :
_base(block_size, max_delay + initial_delay)
242 , _initial_delay(static_cast<difference_type>(initial_delay))
245#ifdef APF_DOXYGEN_HACK
268 if (delay < -_initial_delay)
270 corrected = -_initial_delay;
275 static_cast<size_type
>(delay + _initial_delay), tmp);
276 corrected =
static_cast<difference_type
>(tmp) - _initial_delay;
283 difference_type dummy;
288 template<
typename Iterator>
289 bool read_block(Iterator destination, difference_type delay)
const
291 if (delay < -_initial_delay)
return false;
293 ,
static_cast<size_type
>(delay + _initial_delay));
297 template<
typename Iterator>
298 bool read_block(Iterator destination, difference_type delay, T weight)
const
300 if (delay < -_initial_delay)
return false;
302 ,
static_cast<size_type
>(delay + _initial_delay), weight);
312 const difference_type _initial_delay;
pointer get_write_pointer() const
Get the write pointer.
void advance()
Advance the internal iterators/pointers to the next block.
const size_type _block_size
Size of read/write blocks.
bool delay_is_valid(size_type delay, size_type &corrected) const
Check if a given delay is valid.
BlockDelayLine(size_type block_size, size_type max_delay)
Constructor.
bool delay_is_valid(size_type delay) const
Return true if delay is valid.
circulator get_read_circulator(size_type delay=0) const
Get the read circulator.
bool read_block(Iterator destination, size_type delay) const
Read a block of data from the delay line.
void write_block(Iterator source)
Write a block of data to the delay line.
circulator _get_data_circulator() const
Get a circular iterator to the sample with time 0.
bool read_block(Iterator destination, size_type delay, T weight) const
Read from the delay line and multiply each element by a given factor.
A block-based delay line where negative delay is possible.
void write_block(Iterator source)
NonCausalBlockDelayLine(size_type block_size, size_type max_delay, size_type initial_delay)
Constructor.
circulator get_read_circulator(difference_type delay=0) const
bool read_block(Iterator destination, difference_type delay) const
bool read_block(Iterator destination, difference_type delay, T weight) const
bool delay_is_valid(difference_type delay, difference_type &corrected) const
Check if a given delay is valid.
bool delay_is_valid(difference_type delay) const
Return true if delay is valid.
pointer get_write_pointer() const
Several more or less useful iterators and some macros.
Audio Processing Framework.