Tabula Sonora 0.1.0
A native C++20 implementation of the Roland Sound Canvas VA synth voice
Loading...
Searching...
No Matches
envelope_machine.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <array>
7#include <cstdint>
8#include <limits>
9
10namespace ts {
11
23public:
25 static constexpr int unity_multiplier = 0x100;
26
28 static constexpr int minimum_segment_ticks = 9;
29
31 static constexpr std::int64_t hold_forever = std::numeric_limits<std::int64_t>::max();
32
34 explicit EnvelopeMachine(const TableSet& tables);
35
40 [[nodiscard]] static constexpr bool is_linear_segment(int rate_byte) noexcept
41 {
42 return (rate_byte & 0x80) != 0;
43 }
44
46 [[nodiscard]] int rate_scale(int base_rate, int modifier) const noexcept;
47
49 [[nodiscard]] int level_scale(int level, int modifier) const noexcept;
50
55 [[nodiscard]] double segment_milliseconds(int rate_byte,
56 int rate_multiplier,
57 int velocity_multiplier = unity_multiplier,
58 int bias = 0) const noexcept;
59
66 [[nodiscard]] double
67 segment_curve(double position, double start, double target, bool linear) const noexcept;
68
80 [[nodiscard]] std::int64_t hold_samples(const PartialParameters& partial,
81 int velocity) const noexcept;
82
83private:
84 std::span<const std::uint16_t> rate_curve_;
85 std::span<const std::uint16_t> rate_out_;
86 std::span<const std::uint8_t> scale_curve_;
87
90 std::array<double, 257> shape_{};
91};
92
93} // namespace ts
double segment_curve(double position, double start, double target, bool linear) const noexcept
Interpolates one segment's value at a normalised position, 0 to 1.
int rate_scale(int base_rate, int modifier) const noexcept
Converts a base rate byte and a 0x40-neutral modifier into an 8.8 rate multiplier.
static constexpr bool is_linear_segment(int rate_byte) noexcept
True when a segment interpolates linearly rather than through the fast-approach curve.
Definition envelope_machine.hpp:40
std::int64_t hold_samples(const PartialParameters &partial, int velocity) const noexcept
How long a partial's envelope machine stays held at its note-on state, in samples.
static constexpr int unity_multiplier
Neutral value of an 8.8 multiplier, meaning 1.0.
Definition envelope_machine.hpp:25
double segment_milliseconds(int rate_byte, int rate_multiplier, int velocity_multiplier=unity_multiplier, int bias=0) const noexcept
The duration of one envelope segment in milliseconds, or zero for an instant segment.
int level_scale(int level, int modifier) const noexcept
Converts a level byte and a 0x40-neutral modifier into an 8.8 multiplier.
static constexpr std::int64_t hold_forever
A hold that never expires: the envelope machine stays at its note-on state.
Definition envelope_machine.hpp:31
EnvelopeMachine(const TableSet &tables)
Creates the machine over a loaded table set, which must outlive it.
static constexpr int minimum_segment_ticks
A rate-curve entry below this yields a zero-length segment.
Definition envelope_machine.hpp:28
A zero-copy typed view over one 0x6e-byte partial parameter block inside a tone record.
Definition partial_parameters.hpp:20
The static tables the engine needs, loaded from SCCore.dll or from a directory of extracted ....
Definition table_set.hpp:30
Definition control_decode.hpp:7