Program Listing for File block_convolver.hpp¶
↰ Return to documentation for file (ear/dsp/block_convolver.hpp
)
#pragma once
#include <complex>
#include <cstddef>
#include <memory>
#include <utility>
#include <vector>
#include "../export.hpp"
#include "../fft.hpp"
namespace ear {
namespace dsp {
namespace block_convolver_impl {
class Context;
class Filter;
class BlockConvolver;
} // namespace block_convolver_impl
namespace block_convolver {
/// Type for real data (float).
using real_t = float;
/// Type for complex data.
using complex_t = std::complex<real_t>;
/** Static data required to perform convolution of a particular block
* size; may be shared between any number of BlockConvolver and Filter
* instances. */
class EAR_EXPORT Context {
public:
/** Create a Context with a given block size.
* @param block_size Block size in samples.
* @param fft_impl FFT implementation to use.
*/
Context(size_t block_size, FFTImpl<real_t> &fft_impl);
private:
std::shared_ptr<block_convolver_impl::Context> impl;
friend class Filter;
friend class BlockConvolver;
};
/** A filter response which may be shared between many BlockConvolver
* instances.
*
* This stores the pre-transformed filter blocks. */
class EAR_EXPORT Filter {
public:
Filter(const Context &ctx, size_t n, const real_t *filter);
/** The number of blocks in the filter. */
size_t num_blocks() const;
private:
std::shared_ptr<block_convolver_impl::Filter> impl;
friend class BlockConvolver;
};
/** BlockConvolver implements partitioned overlap-add convolution with a
* fixed block size, with efficient fading between filters.
*/
class EAR_EXPORT BlockConvolver {
public:
/** Create a BlockConvolver given the block size and number of blocks.
* @param ctx Context required for transformations.
* @param num_blocks Maximum number of blocks of any filter used.
*/
BlockConvolver(const Context &ctx, size_t num_blocks);
/** Create a BlockConvolver given the block size and number of blocks.
* If filter == nullptr, num_blocks must be specified.
* @param ctx Context required for transformations.
* @param filter Initial filter to be used, or nullptr for no filter.
* @param num_blocks Maximum number of blocks of any filter used; using
* 0 will take the number of blocks from the passed filter.
*/
BlockConvolver(const Context &ctx, const Filter &filter,
size_t num_blocks = 0);
~BlockConvolver();
/** Pass a block of audio through the filter.
* @param in Input samples of length block_size
* @param out Output samples of length block_size
*/
void process(const float *in, float *out);
/** Crossfade to a new filter during the next block.
*
* This is equivalent to:
* - Creating a new convolver.
* - Passing the next block of samples through the old and new
* convolvers, with the input to the old faded down across the block,
* and the input to the new faded up across the block. All subsequent
* blocks are passed through the new filter.
* - Mixing the output of the old and new filters for the next
* num_blocks blocks.
*/
void crossfade_filter(const Filter &filter);
/** Crossfade to a zero-valued filter */
void fade_down();
/** Switch to a different filter at the start of the next block.
*/
void set_filter(const Filter &filter);
/** Switch to a zero-valued filter at the start of the next block. */
void unset_filter();
private:
std::unique_ptr<block_convolver_impl::BlockConvolver> impl;
};
} // namespace block_convolver
} // namespace dsp
} // namespace ear