Tabula Sonora 0.1.0
A native C++20 implementation of the Roland Sound Canvas VA synth voice
Loading...
Searching...
No Matches
sampler.hpp
Go to the documentation of this file.
1#pragma once
2
6
7#include <cstdint>
8#include <memory>
9#include <span>
10#include <unordered_map>
11#include <vector>
12
13namespace ts {
14
24
28 std::vector<float> samples;
30 std::vector<std::int32_t> steps;
38 std::int32_t seed = 0;
40 int loop_start = 0;
42 int data_end = 0;
45
52 std::vector<float> loop_buffer;
53
60 bool reversed = false;
61
67 [[nodiscard]] int loop_period() const noexcept { return data_end - loop_start + 1; }
68
70 [[nodiscard]] bool is_looping() const noexcept
71 {
72 return mode == SamplerMode::loop && data_end > loop_start + 1 && !loop_buffer.empty();
73 }
74};
75
86class Sampler {
87public:
89 Sampler(const WaveRom& rom, const Interpolator& interpolator)
90 : rom_(&rom), interpolator_(&interpolator)
91 {
92 }
93
98 [[nodiscard]] const DecodedWave* decode(const WaveDescriptor& descriptor);
99
101 [[nodiscard]] std::vector<float>
102 play(const DecodedWave& wave, int sample_count, double ratio) const;
103
108 [[nodiscard]] std::vector<float>
109 play_variable(const DecodedWave& wave, int sample_count, std::span<const double> ratios) const;
110
111private:
112 [[nodiscard]] std::unique_ptr<DecodedWave> decode_core(const WaveDescriptor& descriptor) const;
113 [[nodiscard]] std::vector<float> play_at(const DecodedWave& wave,
114 std::span<const double> positions) const;
115
117 [[nodiscard]] static std::vector<float> build_loop_buffer(const DecodedWave& wave);
118
120 [[nodiscard]] static std::vector<float> build_ping_pong_buffer(const DecodedWave& wave,
121 int required);
122
123 const WaveRom* rom_;
124 const Interpolator* interpolator_;
125
128 std::unordered_map<std::uint64_t, std::unique_ptr<DecodedWave>> cache_;
129};
130
131} // namespace ts
The sampler's 4-tap FIR resampler — the single most timbre-defining element of the engine.
Definition interpolator.hpp:25
std::vector< float > play_variable(const DecodedWave &wave, int sample_count, std::span< const double > ratios) const
Plays a wave at a rate that changes per sample; a shorter input holds its last value.
std::vector< float > play(const DecodedWave &wave, int sample_count, double ratio) const
Plays a wave at a constant rate.
const DecodedWave * decode(const WaveDescriptor &descriptor)
Decodes a wave, caching the result.
Sampler(const WaveRom &rom, const Interpolator &interpolator)
Creates the sampler over a ROM and resampler, both of which must outlive it.
Definition sampler.hpp:89
The 24 MB wave ROM embedded in SCCore.dll — the literal Sound Canvas hardware mask ROM,...
Definition wave_rom.hpp:49
Definition control_decode.hpp:7
SamplerMode
Which sampler variant plays a wave.
Definition sampler.hpp:16
@ one_shot
Plays once and stops. The predictor is zeroed at the end.
Definition sampler.hpp:18
@ loop
Forward loop. Rewinds the delta index and keeps the predictor.
Definition sampler.hpp:20
@ ping_pong
Bidirectional. Walks up to the end, turns around, and walks back to the loop point.
Definition sampler.hpp:22
A wave decoded from the ROM, with everything playback needs.
Definition sampler.hpp:26
std::vector< float > samples
The decoded samples.
Definition sampler.hpp:28
bool is_looping() const noexcept
Whether a forward loop is actually in effect.
Definition sampler.hpp:70
std::vector< float > loop_buffer
The buffer a forward loop reads from; empty for the other modes.
Definition sampler.hpp:52
SamplerMode mode
Which sampler variant applies.
Definition sampler.hpp:44
int loop_start
Index of the loop point.
Definition sampler.hpp:40
bool reversed
Whether samples has been turned round because the wave plays backwards.
Definition sampler.hpp:60
std::int32_t seed
The predictor's value entering the data start — the integral of the preamble deltas from the 32-sampl...
Definition sampler.hpp:38
std::vector< std::int32_t > steps
The shifted per-sample deltas, needed to rebuild a ping-pong traversal.
Definition sampler.hpp:30
int data_end
Number of decodable samples.
Definition sampler.hpp:42
int loop_period() const noexcept
The forward loop's period in samples.
Definition sampler.hpp:67
One entry of the wave-descriptor table: where a sample lives in the wave ROM, how it is tuned,...
Definition wave_descriptor.hpp:14