|
Tabula Sonora 0.1.0
A native C++20 implementation of the Roland Sound Canvas VA synth voice
|
A zero-copy typed view over one 0x6e-byte partial parameter block inside a tone record. More...
#include <tabulasonora/partial_parameters.hpp>
Public Member Functions | |
| PartialParameters ()=default | |
| An absent partial. | |
| PartialParameters (const std::uint8_t *block) noexcept | |
| Creates a view over a partial block's first byte. | |
| std::span< const std::uint8_t > | raw () const noexcept |
| The block's raw bytes. | |
| bool | is_present () const noexcept |
| True when this slot holds a real partial. | |
| int | multisample () const noexcept |
| Multisample index, or no_multisample when the slot is empty. Block +0x02. | |
| int | key_center () const noexcept |
| Key centre — the origin the multisample's key zones are measured from. Block +0x04. | |
| int | pan () const noexcept |
| Per-partial pan, 0x40 centre. Block +0x0f. | |
| int | key_transpose () const noexcept |
| Key transpose in whole semitones, 0x40 neutral. Block +0x10. | |
| int | coarse_tune_raw () const noexcept |
| Raw coarse-tune byte, 0x40 neutral. Block +0x11. | |
| int | coarse_tune_milli_semitones () const noexcept |
| Coarse tune in milli-semitones: (raw - 0x40) * 10. Block +0x11. | |
| int | pitch_key_follow () const noexcept |
| Pitch key-follow amount: 0x40 is 0%, 0x4a is 100%. Block +0x13. | |
| int | cutoff_base () const noexcept |
| TVF cutoff base, scaled by 0x100 into the runtime domain. Block +0x2f. | |
| int | resonance () const noexcept |
| TVF resonance, 0x40 neutral. Block +0x30. | |
| int | filter_type () const noexcept |
| TVF filter type selector. Block +0x31. | |
| int | velocity_curve () const noexcept |
| Velocity response curve selector for the filter envelope's depth; low nibble only. | |
| int | velocity_crossfade_curve () const noexcept |
| Velocity-crossfade curve selector; only the low nibble is used. Block +0x4e. | |
| int | velocity_low () const noexcept |
| One edge of the velocity window. Block +0x4f. | |
| int | velocity_high () const noexcept |
| The other edge of the velocity window. Block +0x51. | |
| int | level_at_low () const noexcept |
| Partial level at the velocity_low edge. Block +0x50. | |
| int | level_at_high () const noexcept |
| Partial level at the velocity_high edge. Block +0x52. | |
| int | tva_base_level () const noexcept |
| TVA base level. Block +0x53. | |
| std::pair< int, int > | velocity_window () const noexcept |
| The velocity window as an ordered range. | |
| bool | accepts_velocity (int velocity) const noexcept |
| True when a velocity falls inside this partial's window. | |
| int | transposed_key (int note) const noexcept |
| The key handed to the multisample zone lookup, clamped to 0–127. | |
Static Public Attributes | |
| static constexpr int | stride = 0x6E |
| Bytes per partial block. | |
| static constexpr int | no_multisample = 0xFFFF |
| Value of multisample meaning the partial is absent. | |
Friends | |
| bool | operator== (const PartialParameters &left, const PartialParameters &right) noexcept |
| Whether two views refer to the same block. | |
A zero-copy typed view over one 0x6e-byte partial parameter block inside a tone record.
A melodic tone holds two of these at tone_base + 0x24. The block carries everything the synthesis chain needs: the multisample and key mapping, the pitch/TVF/TVA envelopes and their key-follow rows, the two LFO depth sets, and the velocity window. Offsets are block-relative and match the reverse-engineering notes directly.
This is a non-owning view and it does not keep the tone table alive. It is copied by value all over the DSP, so the table it points into — normally the one owned by TableSet — has to outlive every partial taken from it. A default-constructed view is "absent" rather than dangling, which is what is_present reports.
|
default |
An absent partial.
|
inlineexplicitnoexcept |
Creates a view over a partial block's first byte.
|
inlinenodiscardnoexcept |
The block's raw bytes.
|
inlinenodiscardnoexcept |
True when this slot holds a real partial.
|
inlinenodiscardnoexcept |
Multisample index, or no_multisample when the slot is empty. Block +0x02.
|
inlinenodiscardnoexcept |
Key centre — the origin the multisample's key zones are measured from. Block +0x04.
|
inlinenodiscardnoexcept |
Per-partial pan, 0x40 centre. Block +0x0f.
|
inlinenodiscardnoexcept |
Key transpose in whole semitones, 0x40 neutral. Block +0x10.
|
inlinenodiscardnoexcept |
Raw coarse-tune byte, 0x40 neutral. Block +0x11.
|
inlinenodiscardnoexcept |
Coarse tune in milli-semitones: (raw - 0x40) * 10. Block +0x11.
|
inlinenodiscardnoexcept |
Pitch key-follow amount: 0x40 is 0%, 0x4a is 100%. Block +0x13.
|
inlinenodiscardnoexcept |
TVF cutoff base, scaled by 0x100 into the runtime domain. Block +0x2f.
|
inlinenodiscardnoexcept |
TVF resonance, 0x40 neutral. Block +0x30.
|
inlinenodiscardnoexcept |
TVF filter type selector. Block +0x31.
|
inlinenodiscardnoexcept |
Velocity response curve selector for the filter envelope's depth; low nibble only.
Block +0x2e.
Row 0 is the identity, so a patch that leaves this at zero sees raw MIDI velocity. Roughly a quarter of the library does not: Brass 1 selects row 1, which maps velocity 100 to 71.
|
inlinenodiscardnoexcept |
Velocity-crossfade curve selector; only the low nibble is used. Block +0x4e.
|
inlinenodiscardnoexcept |
One edge of the velocity window. Block +0x4f.
|
inlinenodiscardnoexcept |
The other edge of the velocity window. Block +0x51.
|
inlinenodiscardnoexcept |
Partial level at the velocity_low edge. Block +0x50.
|
inlinenodiscardnoexcept |
Partial level at the velocity_high edge. Block +0x52.
|
inlinenodiscardnoexcept |
TVA base level. Block +0x53.
|
inlinenodiscardnoexcept |
The velocity window as an ordered range.
The stored edges may be the other way round, which is how a partial fades in from the top of the window rather than the bottom.
|
inlinenodiscardnoexcept |
True when a velocity falls inside this partial's window.
|
nodiscardnoexcept |
The key handed to the multisample zone lookup, clamped to 0–127.
The engine shifts the voice's key by the partial transpose before the multisample sees it, and the multisample then adds 0x40 - key_center itself. Skipping the transpose selects a wave from the wrong zone, which the pitch chain then stretches to compensate — audible aliasing.
|
friend |
Whether two views refer to the same block.
|
staticconstexpr |
Bytes per partial block.
|
staticconstexpr |
Value of multisample meaning the partial is absent.