|
Tabula Sonora 0.1.0
A native C++20 implementation of the Roland Sound Canvas VA synth voice
|
A wave decoded from the ROM, with everything playback needs. More...
#include <tabulasonora/sampler.hpp>
Public Member Functions | |
| int | loop_period () const noexcept |
| The forward loop's period in samples. | |
| bool | is_looping () const noexcept |
| Whether a forward loop is actually in effect. | |
Public Attributes | |
| std::vector< float > | samples |
| The decoded samples. | |
| std::vector< std::int32_t > | steps |
| The shifted per-sample deltas, needed to rebuild a ping-pong traversal. | |
| std::int32_t | seed = 0 |
| The predictor's value entering the data start — the integral of the preamble deltas from the 32-sample exponent-block boundary below it, where the engine's decoder zeroes. | |
| int | loop_start = 0 |
| Index of the loop point. | |
| int | data_end = 0 |
| Number of decodable samples. | |
| SamplerMode | mode = SamplerMode::one_shot |
| Which sampler variant applies. | |
| std::vector< float > | loop_buffer |
| The buffer a forward loop reads from; empty for the other modes. | |
| bool | reversed = false |
| Whether samples has been turned round because the wave plays backwards. | |
A wave decoded from the ROM, with everything playback needs.
|
inlinenodiscardnoexcept |
The forward loop's period in samples.
Inclusive of the data end: one pass plays loop_start..data_end. Dropping that last sample is inaudible on a long loop but detunes a short single-cycle one outright — a 63 against 64 sample period is 27 cents sharp.
|
inlinenodiscardnoexcept |
Whether a forward loop is actually in effect.
| std::vector<float> ts::DecodedWave::samples |
The decoded samples.
| std::vector<std::int32_t> ts::DecodedWave::steps |
The shifted per-sample deltas, needed to rebuild a ping-pong traversal.
| std::int32_t ts::DecodedWave::seed = 0 |
The predictor's value entering the data start — the integral of the preamble deltas from the 32-sample exponent-block boundary below it, where the engine's decoder zeroes.
Every decoded sample already includes it; it is kept so the ping-pong rebuild can integrate from the same origin. An unaligned wave rides this as a constant DC — the verification article's "module has DC", measured live at exactly −0.041015625 on Crash Cym.1 and −0.139 on the sine-kick zone.
| int ts::DecodedWave::loop_start = 0 |
Index of the loop point.
| int ts::DecodedWave::data_end = 0 |
Number of decodable samples.
| SamplerMode ts::DecodedWave::mode = SamplerMode::one_shot |
Which sampler variant applies.
| std::vector<float> ts::DecodedWave::loop_buffer |
The buffer a forward loop reads from; empty for the other modes.
The 4-tap window reaches two samples past the read index, so the buffer must carry the samples the loop wraps to rather than whatever follows it. It is the wave plus a few wrapped samples — a fixed size, independent of how long a note holds — so it is built once with the wave and shared by every voice that plays it.
| bool ts::DecodedWave::reversed = false |
Whether samples has been turned round because the wave plays backwards.
Playback does not consult this: the samples are already in the order they are read, so a reverse wave is an ordinary one-shot from here on. It is recorded because a buffer that no longer matches the order steps is in would otherwise be silently confusing — the steps stay forward, and nothing that reads them applies to a reverse wave.