The pitch side of a voice: key-follow, transposition, the pitch envelope, and bend.
More...
|
| | PitchChain (const TableSet &tables, const EnvelopeMachine &envelope, EngineNoise *noise=nullptr) |
| | Creates the chain over a loaded table set and machine, both of which must outlive it.
|
| int | base_pitch_milli_semitones (const PartialParameters &partial, int note, int key_center=0x3C) const noexcept |
| | The note's absolute base pitch in milli-semitones.
|
| int | portamento_step (int time) const noexcept |
| | The portamento glide step for a CC#5 time byte, in milli-semitones per control tick.
|
| std::optional< PitchEnvelope > | envelope_offsets (const PartialParameters &partial, int key, int velocity) const noexcept |
| | Decodes the pitch envelope's targets and timings, or nothing when it is disabled.
|
| std::optional< std::vector< double > > | envelope_ticks (const PartialParameters &partial, int key, int velocity, double hold_seconds, int tick_count) const |
| | The pitch envelope's offset at each control tick, or nothing when it is inactive.
|
| std::optional< PitchEnvelopeRunner > | create_envelope_runner (const PartialParameters &partial, int key, int velocity) const |
| | Creates a runner for a partial's pitch envelope, or nothing when it does nothing.
|
|
| static KeyFollow | key_follow_key (const PartialParameters &partial, int note, int key_center=0x3C) noexcept |
| | The effective pitch key and its fractional crossfade weight.
|
| static int | drum_pitch_milli_semitones (const PartialParameters &partial, int coarse_pitch) noexcept |
| | A drum key's absolute pitch in milli-semitones, from its coarse-pitch plane value.
|
| static int | portamento_offset (int from_key, int target_pitch) noexcept |
| | The glide offset a note starts with, in milli-semitones, decaying to zero as it completes.
|
| static double | bend_offset_milli_semitones (int bend=8192, double semitone_range=2.0) noexcept |
| | Pitch-bend offset in milli-semitones, from a 14-bit bend with 8192 centre.
|
| static int | segment_rate_word (double milliseconds) noexcept |
| | The segment machine's rate word for a duration.
|
| static int | start_jitter_milli_semitones (int depth, std::uint16_t draw) noexcept |
| | The random start-pitch jitter for one note-on, in milli-semitones.
|
| static double | ratio (const PartialParameters &partial, const WaveDescriptor &descriptor, double pitch_milli_semitones) noexcept |
| | The playback ratio for a partial, from its absolute pitch against the sample's own root.
|
| static double | clamp (double milli_semitones) noexcept |
| | Clamps an absolute pitch the way the engine's accumulator does.
|
The pitch side of a voice: key-follow, transposition, the pitch envelope, and bend.
Pitch is absolute, in milli-semitones, and the engine clamps the accumulator to [0, 0x1f018] — 127 semitones x 1000, which is what fixes the unit. Working in offsets from a base cannot express that clamp, and at least one patch sits exactly on it: Jetplane's first partial has a base of 24000 with an envelope starting at -24000, landing on zero.
| int ts::PitchChain::drum_pitch_milli_semitones |
( |
const PartialParameters & | partial, |
|
|
int | coarse_pitch ) |
|
staticnodiscardnoexcept |
A drum key's absolute pitch in milli-semitones, from its coarse-pitch plane value.
A drum note does not transpose its sample; the coarse-pitch plane supplies the key instead, pivoting on drum_key_centre. What a step of that plane is worth is then the tone's own business: it runs through the same block[0x13] key-follow ladder as a melodic note, so a 100%-follow tone moves a whole semitone per unit and a 50%-follow tone half of one.
Unlike the melodic chain this omits the g_kf_pitch key-follow curve: the engine gates that term off for drums, and the measured pitches are exact multiples of 1000 where the curve would have contributed -11 or +3.
| int ts::PitchChain::start_jitter_milli_semitones |
( |
int | depth, |
|
|
std::uint16_t | draw ) |
|
staticnodiscardnoexcept |
The random start-pitch jitter for one note-on, in milli-semitones.
Bit 14 of the draw picks the sign. The magnitude slice is asymmetric — 7 bits on the positive side, 8 on the negative — so the range is about [-10*d, +5*d], and that asymmetry is the hardware's, not an artefact.
Creates a runner for a partial's pitch envelope, or nothing when it does nothing.
An envelope whose start, four targets and release are all zero is not merely flat — it is absent, and skipping it saves the pitch chain a per-tick update on most patches.
A non-zero block byte 0x1a draws start jitter here, one draw per partial voice, matching the engine (which skips the draw entirely when the byte is zero, so unaffected patches consume nothing from the generator).