Tabula Sonora 0.1.0
A native C++20 implementation of the Roland Sound Canvas VA synth voice
Loading...
Searching...
No Matches
note_renderer.hpp
Go to the documentation of this file.
1#pragma once
2
14
15#include <memory>
16#include <optional>
17#include <span>
18#include <string>
19#include <vector>
20
21namespace ts {
22
25 std::vector<float> left;
26 std::vector<float> right;
28 std::vector<float> mono;
30 std::string name;
31};
32
43public:
45 static constexpr int control_block = 320;
46
48 static constexpr int sample_rate = 32000;
49
51 static constexpr double max_drum_ring_scale = 16.0;
52
57 explicit NoteRenderer(const RomImage& rom);
58
60 NoteRenderer& operator=(NoteRenderer&&) noexcept;
61 NoteRenderer(const NoteRenderer&) = delete;
62 NoteRenderer& operator=(const NoteRenderer&) = delete;
64
68 struct Controllers {
70 std::span<const double> volume;
72 std::span<const double> pitch_add;
75 std::span<const double> mod_wheel_per_tick;
76 };
77
83 [[nodiscard]] const RomImage& rom() const noexcept;
84
86 [[nodiscard]] const TableSet& tables() const noexcept;
87
92 [[nodiscard]] EngineNoise& noise() noexcept;
93
95 [[nodiscard]] const PatchDirectory& directory() const noexcept;
96
98 [[nodiscard]] const DrumKitTable& drums() const noexcept;
99
105 [[nodiscard]] const Interpolator& interpolator() const noexcept;
106
108 [[nodiscard]] Sampler& sampler() noexcept;
109
111 [[nodiscard]] const EnvelopeMachine& envelopes() const noexcept;
112
114 [[nodiscard]] const TvaChain& tva() const noexcept;
115
117 [[nodiscard]] const TvfChain& tvf() const noexcept;
118
120 [[nodiscard]] const PitchChain& pitch() const noexcept;
121
123 [[nodiscard]] const LfoEngine& lfo() const noexcept;
124
126 [[nodiscard]] const PanLaw& pan() const noexcept;
127
129 [[nodiscard]] RenderedNote render_note(int program,
130 int note,
131 int velocity,
132 double hold_seconds,
133 double tail_seconds,
134 ToneMap map = ToneMap::sc8820,
135 int bank = 0,
136 int part_pan = 0x40,
137 const Controllers& controllers = {});
138
146 [[nodiscard]] static double drum_ring_scale(const DrumKey& key) noexcept;
147
151 [[nodiscard]] double drum_ring_scale(int note, int kit, int drum_pitch) const;
152
158 [[nodiscard]] RenderedNote render_drum_note(int note,
159 int velocity,
160 double ring_seconds,
161 double tail_seconds = 0.4,
162 int kit = 0,
163 std::span<const double> volume = {},
164 int drum_pitch = 0,
165 std::optional<int> drum_pan = std::nullopt);
166
176 [[nodiscard]] static int envelope_rate_key(const DrumKey& key, int drum_pitch) noexcept;
177
179 [[nodiscard]] static std::vector<double> expand(std::span<const double> ticks,
180 std::size_t sample_count);
181
182private:
183 struct Impl;
184 std::unique_ptr<Impl> impl_;
185};
186
187} // namespace ts
The drum kit records: for each of 128 keys, which tone sounds and how it is levelled,...
Definition drum_kit_table.hpp:57
The engine's shared pseudo-random generator.
Definition engine_noise.hpp:18
The segment-rate and segment-shape machine shared by the TVA, TVF and pitch envelopes.
Definition envelope_machine.hpp:22
The sampler's 4-tap FIR resampler — the single most timbre-defining element of the engine.
Definition interpolator.hpp:25
The two LFO engines that modulate every partial.
Definition lfo_engine.hpp:76
static std::vector< double > expand(std::span< const double > ticks, std::size_t sample_count)
Holds control-rate values across their block, as the engine does.
RenderedNote render_drum_note(int note, int velocity, double ring_seconds, double tail_seconds=0.4, int kit=0, std::span< const double > volume={}, int drum_pitch=0, std::optional< int > drum_pan=std::nullopt)
Renders one drum hit.
static int envelope_rate_key(const DrumKey &key, int drum_pitch) noexcept
The key a drum hit's envelope rates are key-followed by.
const PanLaw & pan() const noexcept
The pan law.
const EnvelopeMachine & envelopes() const noexcept
The shared segment-rate machine, which also decodes the envelope hold clock.
const Interpolator & interpolator() const noexcept
The 4-tap resampler.
static constexpr double max_drum_ring_scale
Largest drum ring scale, so a caller can bound its buffers.
Definition note_renderer.hpp:51
NoteRenderer(const RomImage &rom)
Creates a note renderer over an open ROM image, which must outlive it.
const TvaChain & tva() const noexcept
The amplitude chain.
const DrumKitTable & drums() const noexcept
The drum kits.
const TableSet & tables() const noexcept
The static tables this renderer loaded.
Sampler & sampler() noexcept
The wave decoder and player.
const TvfChain & tvf() const noexcept
The filter chain.
const RomImage & rom() const noexcept
The ROM this renderer was opened on.
RenderedNote render_note(int program, int note, int velocity, double hold_seconds, double tail_seconds, ToneMap map=ToneMap::sc8820, int bank=0, int part_pan=0x40, const Controllers &controllers={})
Renders one melodic note.
const PatchDirectory & directory() const noexcept
The patch directory.
static double drum_ring_scale(const DrumKey &key) noexcept
How much longer a hit needs than the nominal ring, given its coarse pitch.
const PitchChain & pitch() const noexcept
The pitch chain.
const LfoEngine & lfo() const noexcept
The two LFO engines.
NoteRenderer(NoteRenderer &&) noexcept
static constexpr int control_block
Samples per control tick.
Definition note_renderer.hpp:45
double drum_ring_scale(int note, int kit, int drum_pitch) const
How much longer a hit needs than the nominal ring, before it is rendered.
static constexpr int sample_rate
Internal sample rate.
Definition note_renderer.hpp:48
EngineNoise & noise() noexcept
The engine's shared pseudo-random source.
The engine's pan law: an exact 128-entry table, not a computed curve.
Definition interpolator.hpp:66
The static patch directory: resolves a program change and a played note to the waves that sound,...
Definition patch_directory.hpp:76
The pitch side of a voice: key-follow, transposition, the pitch envelope, and bend.
Definition pitch_chain.hpp:90
Read-only access to SCCore.dll as a data file.
Definition rom_image.hpp:39
Wave playback: decode, then resample at a moving rate while honouring the loop.
Definition sampler.hpp:86
The static tables the engine needs, loaded from SCCore.dll or from a directory of extracted ....
Definition table_set.hpp:30
The amplitude side of a voice: the level chain that turns static bytes into a gain,...
Definition tva_chain.hpp:25
The filter side of a voice: the cutoff chain that turns static bytes into the two coefficients the st...
Definition tvf_chain.hpp:28
Definition control_decode.hpp:7
ToneMap
Which vintage's tone map a program change resolves against.
Definition patch_directory.hpp:22
@ sc8820
Definition patch_directory.hpp:26
@ volume
Definition control_decode.hpp:18
@ bank
Definition control_decode.hpp:26
One drum key's settings within a kit.
Definition drum_kit_table.hpp:15
Optional per-note controller curves.
Definition note_renderer.hpp:68
std::span< const double > mod_wheel_per_tick
Mod-wheel depth per control tick in milli-semitones; empty when the wheel is untouched.
Definition note_renderer.hpp:75
std::span< const double > pitch_add
Per-sample bend and tune in milli-semitones; empty for none.
Definition note_renderer.hpp:72
std::span< const double > volume
Per-sample part volume; empty for unity.
Definition note_renderer.hpp:70
One rendered note: stereo output plus the pre-pan mono the send buses are fed from.
Definition note_renderer.hpp:24
std::vector< float > mono
Pre-pan sum of the partials — the pan-independent send source.
Definition note_renderer.hpp:28
std::vector< float > left
Definition note_renderer.hpp:25
std::string name
The tone's name.
Definition note_renderer.hpp:30
std::vector< float > right
Definition note_renderer.hpp:26