Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
convolver_non_uniform.hpp File Reference

Two-stage Gardner-style non-uniform partitioned convolution. More...

#include <pulp/signal/convolver.hpp>
#include <pulp/signal/convolver_messages.hpp>
#include <algorithm>
#include <array>
#include <cassert>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <string_view>
#include <type_traits>
#include <vector>
#include <TargetConditionals.h>
#include <sys/sysctl.h>

Go to the source code of this file.

Classes

class  pulp::signal::NonUniformPartitionedConvolverT< SampleType >
 Two-stage non-uniform partitioned convolver. More...

Namespaces

namespace  pulp
namespace  pulp::signal

Macros

#define PULP_NON_UNIFORM_MEASURED_TABLE   0

Typedefs

using pulp::signal::NonUniformPartitionedConvolver = NonUniformPartitionedConvolverT<float>
using pulp::signal::NonUniformPartitionedConvolver64 = NonUniformPartitionedConvolverT<double>

Detailed Description

Two-stage Gardner-style non-uniform partitioned convolution.

NonUniformPartitionedConvolver splits an impulse response into: • a small-block "head" stage processing the first head_samples of the IR at the user-provided audio block size B (zero-latency overlap-save partitioned convolution), and • a large-block "tail" stage processing IR samples [head_samples, ir_length) at a larger block size K · B (K ≥ 2), which fires only every K audio blocks, amortizing the larger FFT cost across many small blocks.

Why: a single uniform partitioned convolver at block size B pays the per-block FFT cost on every block. A long IR (1 s @ 48 kHz = 48 000 samples) needs num_partitions = ceil(ir_len / B) complex multiplies per block in the frequency-domain accumulate; the FFTs themselves stay O(B log B) per block. Switching the tail to a larger block size collapses those tail-partition spectra into fewer (and larger) FFT bins and runs the convolution loop on a schedule of one out of every K blocks.

Latency: zero — head stage produces the current block immediately via overlap-save. The tail stage's contribution to a given input sample arrives at the output head_samples samples later, which is exactly where tail IR taps would have contributed in a direct convolution.

Acceptance pinned in test/test_convolver_non_uniform.cpp: • impulse round-trip matches the IR within float epsilon, • non-uniform output matches uniform PartitionedConvolver output to within float epsilon over a sine sweep, • short noise burst through a 4 096-tap IR matches the direct-convolution reference within float epsilon.

IR loading: unlike the uniform convolver, this class does not provide a background swapper. load_ir() rebuilds both stages inline and must be called off the audio thread.

Macro Definition Documentation

◆ PULP_NON_UNIFORM_MEASURED_TABLE

#define PULP_NON_UNIFORM_MEASURED_TABLE   0