Tabula Sonora 0.1.0
A native C++20 implementation of the Roland Sound Canvas VA synth voice
Loading...
Searching...
No Matches
tone_generator.hpp
Go to the documentation of this file.
1#pragma once
2
8
9#include <cstdint>
10#include <memory>
11#include <optional>
12#include <span>
13
14namespace ts {
15
19 static constexpr int unlimited_polyphony = 0;
20
34 int polyphony = 64;
35
42 int ports = 2;
43
59
61 int drum_channel = 9;
62
63 bool reverb = true;
64 bool chorus = true;
65 bool delay = true;
66
71 bool efx = true;
72
74 std::optional<int> reverb_type;
75 std::optional<int> chorus_type;
76 std::optional<int> delay_type;
77
79 double output_gain = 1.0;
80
82 const ChannelMask* channels = nullptr;
83};
84
101public:
104
106 static constexpr int block_size = smf::block_grid;
107
110
119 static constexpr int port_count = 2;
120
123
137 static constexpr int max_port_count = 4;
138
141
143 explicit ToneGenerator(NoteRenderer& notes, const ToneGeneratorOptions& options = {});
144
146 ToneGenerator& operator=(ToneGenerator&&) noexcept;
147 ToneGenerator(const ToneGenerator&) = delete;
148 ToneGenerator& operator=(const ToneGenerator&) = delete;
150
155 [[nodiscard]] double output_gain() const noexcept;
156 void set_output_gain(double gain) noexcept;
157
159 [[nodiscard]] int ports() const noexcept;
160
162 [[nodiscard]] int parts() const noexcept;
163
165 [[nodiscard]] std::int64_t position() const noexcept;
166
171 [[nodiscard]] int note_count() const noexcept;
172
174 [[nodiscard]] int active_voices() const noexcept;
175
182 [[nodiscard]] bool polyphony_limit_reached() const noexcept;
183
185 [[nodiscard]] int stolen_voices() const noexcept;
186
192 [[nodiscard]] int voice_slots() const noexcept;
193
202 [[nodiscard]] const Part& part(int index) const noexcept;
203
205 [[nodiscard]] const VoicePool& voices() const noexcept;
206
212 [[nodiscard]] int drum_kit() const noexcept;
213
219 [[nodiscard]] int drum_kit_for(int port) const noexcept;
220
229 [[nodiscard]] std::optional<int> drum_map_row() const noexcept;
230 void set_drum_map_row(std::optional<int> row) noexcept;
231
233 [[nodiscard]] int effective_drum_map_row() const noexcept;
234
236 [[nodiscard]] bool xg_mode() const noexcept;
237
243 [[nodiscard]] ToneMap part_tone_map(int index) const noexcept;
244
249 [[nodiscard]] int part_lookup_bank(int index) const noexcept;
250
256 [[nodiscard]] bool part_is_drum(int index) const noexcept;
257
259 [[nodiscard]] int part_drum_kit(int index) const noexcept;
260
262 void reset();
263
265 void send(const MidiEvent& message);
266
268 void send(int port, const MidiEvent& message);
269
274 void send_channel(int status, int data1, int data2);
275
282 void send_channel(int port, int status, int data1, int data2);
283
285 void send_sysex(std::span<const std::uint8_t> bytes);
286
293 void send_sysex(int port, std::span<const std::uint8_t> bytes);
294
306 void send_packet(std::uint32_t packet);
307
315 void render(std::span<float> left, std::span<float> right);
316
317private:
318 struct Impl;
319 std::unique_ptr<Impl> impl_;
320};
321
322} // namespace ts
Per-channel mute and solo.
Definition render_options.hpp:28
Renders one note by assembling the whole voice chain: sampler, pitch, filter, amplitude and pan.
Definition note_renderer.hpp:42
static constexpr int control_block
Samples per control tick.
Definition note_renderer.hpp:45
static constexpr int sample_rate
Internal sample rate.
Definition note_renderer.hpp:48
One of the sixteen parts: the channel state a running engine keeps between events.
Definition part.hpp:58
double output_gain() const noexcept
Linear gain applied to the audio handed to the host.
ToneGenerator(NoteRenderer &notes, const ToneGeneratorOptions &options={})
Creates an engine over a note renderer's loaded tables, which must outlive it.
static constexpr int sample_rate
Internal sample rate.
Definition tone_generator.hpp:103
static constexpr int block_size
Samples per render block — the grid events are applied on.
Definition tone_generator.hpp:106
void reset()
Silences everything and returns every part to its power-on state.
const VoicePool & voices() const noexcept
The voice allocator.
bool part_is_drum(int index) const noexcept
Whether a part is currently sounding drums.
void send_channel(int status, int data1, int data2)
Applies one channel voice message on port A.
int drum_kit_for(int port) const noexcept
The drum kit in force on one port.
int part_lookup_bank(int index) const noexcept
The bank a part's melodic lookup is given.
int ports() const noexcept
How many ports this engine was created with; parts are ports() * 16.
void set_drum_map_row(std::optional< int > row) noexcept
void render(std::span< float > left, std::span< float > right)
Renders audio into two equal-length channels.
void send_packet(std::uint32_t packet)
Applies one USB-MIDI Event Packet: (port << 4) | class in the low byte, then the MIDI message in the ...
static constexpr int max_part_count
Parts at max_port_count.
Definition tone_generator.hpp:140
std::optional< int > drum_map_row() const noexcept
Which drum map row a program change on the drum part resolves against.
void set_output_gain(double gain) noexcept
ToneGenerator(ToneGenerator &&) noexcept
int note_count() const noexcept
How many notes have sounded since the last reset.
int stolen_voices() const noexcept
How many sounding voices were taken to make room.
int effective_drum_map_row() const noexcept
The drum map row this engine actually resolves against.
int drum_kit() const noexcept
The drum kit in force, as the last program change on the drum part resolved it.
bool xg_mode() const noexcept
Whether the engine is in XG mode, having seen XG System On and no Roland or GM reset since.
int voice_slots() const noexcept
The number of voice slots that exist, after any growth.
static constexpr int control_block
Samples per control tick, at 100 Hz.
Definition tone_generator.hpp:109
bool polyphony_limit_reached() const noexcept
Whether this render ever ran out of voices.
ToneMap part_tone_map(int index) const noexcept
Which tone map a part's program change currently resolves against.
void send(const MidiEvent &message)
Applies one MIDI event on port A; its position is ignored, since it applies now.
static constexpr int max_port_count
The widest this engine can be asked to run, past what the module can do.
Definition tone_generator.hpp:137
static constexpr int part_count
How many parts the hardware has: sixteen per port.
Definition tone_generator.hpp:122
const Part & part(int index) const noexcept
The parts, indexed by port * 16 + channel; parts() of them.
int part_drum_kit(int index) const noexcept
The drum kit a part would sound, or -1 if it is not a drum part.
int active_voices() const noexcept
How many voices are currently sounding, including those fading after being stolen.
int parts() const noexcept
How many parts this engine was created with.
static constexpr int port_count
How many MIDI ports the hardware accepts input on.
Definition tone_generator.hpp:119
std::int64_t position() const noexcept
How many samples have been rendered since the last reset.
void send_sysex(std::span< const std::uint8_t > bytes)
Applies one system-exclusive message on port A, including the leading F0.
The voice allocator.
Definition voice_pool.hpp:55
constexpr int block_grid
Samples per render block — the grid events are applied on.
Definition smf_reader.hpp:72
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
One scheduled MIDI message.
Definition smf_reader.hpp:21
static constexpr int channel_count
MIDI channels.
Definition sequence.hpp:239
How a running engine should behave.
Definition tone_generator.hpp:17
std::optional< int > reverb_type
Force an effect type instead of taking it from the stream.
Definition tone_generator.hpp:74
std::optional< int > chorus_type
Definition tone_generator.hpp:75
bool delay
Definition tone_generator.hpp:65
bool efx
The insertion EFX block, 40 03 and the per-part 40 4x 22 switch.
Definition tone_generator.hpp:71
int polyphony
Maximum simultaneous voices, or unlimited_polyphony.
Definition tone_generator.hpp:34
std::optional< int > delay_type
Definition tone_generator.hpp:76
const ChannelMask * channels
Per-channel mute and solo, read live so a mixer can change it while sound is running.
Definition tone_generator.hpp:82
int ports
MIDI ports to accept input on: 1, 2 or 4, giving 16, 32 or 64 parts.
Definition tone_generator.hpp:42
int drum_channel
MIDI channel routed to the drum path.
Definition tone_generator.hpp:61
ToneMap map
Which tone map program changes resolve against.
Definition tone_generator.hpp:58
double output_gain
Linear gain applied to the audio handed to the host.
Definition tone_generator.hpp:79
static constexpr int unlimited_polyphony
Asks for polyphony that grows on demand instead of stealing.
Definition tone_generator.hpp:19
bool reverb
Definition tone_generator.hpp:63
bool chorus
Definition tone_generator.hpp:64