Renders one note by assembling the whole voice chain: sampler, pitch, filter, amplitude and pan.
More...
|
| | NoteRenderer (const RomImage &rom) |
| | Creates a note renderer over an open ROM image, which must outlive it.
|
| | NoteRenderer (NoteRenderer &&) noexcept |
| NoteRenderer & | operator= (NoteRenderer &&) noexcept |
| | NoteRenderer (const NoteRenderer &)=delete |
| NoteRenderer & | operator= (const NoteRenderer &)=delete |
| | ~NoteRenderer () |
| const RomImage & | rom () const noexcept |
| | The ROM this renderer was opened on.
|
| const TableSet & | tables () const noexcept |
| | The static tables this renderer loaded.
|
| EngineNoise & | noise () noexcept |
| | The engine's shared pseudo-random source.
|
| const PatchDirectory & | directory () const noexcept |
| | The patch directory.
|
| const DrumKitTable & | drums () const noexcept |
| | The drum kits.
|
| const Interpolator & | interpolator () const noexcept |
| | The 4-tap resampler.
|
| Sampler & | sampler () noexcept |
| | The wave decoder and player.
|
| const EnvelopeMachine & | envelopes () const noexcept |
| | The shared segment-rate machine, which also decodes the envelope hold clock.
|
| const TvaChain & | tva () const noexcept |
| | The amplitude chain.
|
| const TvfChain & | tvf () const noexcept |
| | The filter chain.
|
| const PitchChain & | pitch () const noexcept |
| | The pitch chain.
|
| const LfoEngine & | lfo () const noexcept |
| | The two LFO engines.
|
| const PanLaw & | pan () const noexcept |
| | The pan law.
|
| 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.
|
| 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.
|
| 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.
|
Renders one note by assembling the whole voice chain: sampler, pitch, filter, amplitude and pan.
Partials sum. Each is an independent voice dispatched into the same accumulation buffer, and there is no divide-by-count anywhere in the mix path — averaging would silently halve every two-partial patch relative to a one-partial one.
A note's timbre is latched at note-on, but volume and pitch keep tracking their controllers, because the engine re-reads those each block. That is why they arrive here as optional per-sample curves rather than scalars.
| double ts::NoteRenderer::drum_ring_scale |
( |
const DrumKey & | key | ) |
|
|
staticnodiscardnoexcept |
How much longer a hit needs than the nominal ring, given its coarse pitch.
The ring exists because a drum ignores note-off, so the renderer has to decide for itself how long to run. A fixed window is wrong once a key is pitched down: the sample plays proportionally slower, so the hit outlasts it and is cut off mid-decay. Measured on the real DLL, the splash at NRPN 18h = 24 takes 4.68 s to fall 40 dB against 1.15 s untouched — four times the nominal 1.8 s ring. The envelope, not this window, is what should end the note.
| int ts::NoteRenderer::envelope_rate_key |
( |
const DrumKey & | key, |
|
|
int | drum_pitch ) |
|
staticnodiscardnoexcept |
The key a drum hit's envelope rates are key-followed by.
Not 60, and not the MIDI note. The engine keeps this at voice+0x161, filled by voice_trigger_partials as the note plus a transpose, and on a drum part the sum works out to the kit's own coarse-pitch plane. Read back off the DLL for the 61 sounding keys of the SC-55 standard kit, the plane equals the engine's index for all 61.
The NRPN moves it a whole semitone per step, where the same step moves the pitch plane by two — so the offset is added here rather than reading the modified plane back.