|
Tabula Sonora 0.1.0
A native C++20 implementation of the Roland Sound Canvas VA synth voice
|
The sampler's 4-tap FIR resampler — the single most timbre-defining element of the engine. More...
#include <tabulasonora/interpolator.hpp>
Public Member Functions | |
| Interpolator (const TableSet &tables) | |
| Creates the resampler over a loaded table set, which must outlive it. | |
| float | sample (std::span< const float > buffer, double position) const noexcept |
| Reads one sample at a fractional position. | |
| float | sample_ring (std::span< const float > ring, std::int64_t index, double fraction) const noexcept |
| Reads one sample from a power-of-two ring buffer at an absolute index. | |
| void | resample (std::span< const float > buffer, std::span< const double > positions, std::span< float > destination) const noexcept |
| Resamples a buffer at a series of fractional positions. | |
Static Public Attributes | |
| static constexpr int | phase_count = 128 |
| Number of phase rows in the kernel. | |
| static constexpr int | tap_count = 4 |
| Taps per phase row. | |
The sampler's 4-tap FIR resampler — the single most timbre-defining element of the engine.
128 phase rows of four coefficients, indexed by the top seven bits of the fractional phase, with no interpolation between rows. Every row sums to 1.0 — to within 1e-5, measured: the sums span 0.999999999970896 to 1.000009999999747, so a flat input comes back flat to about five decimal places and not to float epsilon.
The row at zero fractional phase is [0.174, 0.653, 0.173, 1e-5] — not a passthrough. That mild lowpass is applied at every sample regardless of pitch, and it is why linear interpolation sounds measurably brighter: at a quarter of the sample rate this kernel passes 0.638 where linear passes 0.707.
Deliberately scalar. Vectorising the tap sum would reassociate float addition, and float addition is not associative — the result would be close, and not the same.
|
inlineexplicit |
Creates the resampler over a loaded table set, which must outlive it.
|
nodiscardnoexcept |
Reads one sample at a fractional position.
The window reaches from i-1 to i+2, so the index is clamped to leave room for all four taps. Near a loop boundary the caller must supply the samples the loop wraps to, not whatever follows it in the buffer.
|
nodiscardnoexcept |
Reads one sample from a power-of-two ring buffer at an absolute index.
For a stream generated as it is read rather than held whole — a ping-pong traversal, whose predictor keeps accumulating in both directions and so never repeats. The window still reaches from i-1 to i+2, so the caller must have generated two samples ahead.
|
noexcept |
Resamples a buffer at a series of fractional positions.
|
staticconstexpr |
Number of phase rows in the kernel.
|
staticconstexpr |
Taps per phase row.