Tabula Sonora 0.1.0
A native C++20 implementation of the Roland Sound Canvas VA synth voice
Loading...
Searching...
No Matches
ts::PartialParameters Class Reference

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.

Detailed Description

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.

Constructor & Destructor Documentation

◆ PartialParameters() [1/2]

ts::PartialParameters::PartialParameters ( )
default

An absent partial.

◆ PartialParameters() [2/2]

ts::PartialParameters::PartialParameters ( const std::uint8_t * block)
inlineexplicitnoexcept

Creates a view over a partial block's first byte.

Member Function Documentation

◆ raw()

std::span< const std::uint8_t > ts::PartialParameters::raw ( ) const
inlinenodiscardnoexcept

The block's raw bytes.

◆ is_present()

bool ts::PartialParameters::is_present ( ) const
inlinenodiscardnoexcept

True when this slot holds a real partial.

◆ multisample()

int ts::PartialParameters::multisample ( ) const
inlinenodiscardnoexcept

Multisample index, or no_multisample when the slot is empty. Block +0x02.

◆ key_center()

int ts::PartialParameters::key_center ( ) const
inlinenodiscardnoexcept

Key centre — the origin the multisample's key zones are measured from. Block +0x04.

◆ pan()

int ts::PartialParameters::pan ( ) const
inlinenodiscardnoexcept

Per-partial pan, 0x40 centre. Block +0x0f.

◆ key_transpose()

int ts::PartialParameters::key_transpose ( ) const
inlinenodiscardnoexcept

Key transpose in whole semitones, 0x40 neutral. Block +0x10.

◆ coarse_tune_raw()

int ts::PartialParameters::coarse_tune_raw ( ) const
inlinenodiscardnoexcept

Raw coarse-tune byte, 0x40 neutral. Block +0x11.

◆ coarse_tune_milli_semitones()

int ts::PartialParameters::coarse_tune_milli_semitones ( ) const
inlinenodiscardnoexcept

Coarse tune in milli-semitones: (raw - 0x40) * 10. Block +0x11.

◆ pitch_key_follow()

int ts::PartialParameters::pitch_key_follow ( ) const
inlinenodiscardnoexcept

Pitch key-follow amount: 0x40 is 0%, 0x4a is 100%. Block +0x13.

◆ cutoff_base()

int ts::PartialParameters::cutoff_base ( ) const
inlinenodiscardnoexcept

TVF cutoff base, scaled by 0x100 into the runtime domain. Block +0x2f.

◆ resonance()

int ts::PartialParameters::resonance ( ) const
inlinenodiscardnoexcept

TVF resonance, 0x40 neutral. Block +0x30.

◆ filter_type()

int ts::PartialParameters::filter_type ( ) const
inlinenodiscardnoexcept

TVF filter type selector. Block +0x31.

◆ velocity_curve()

int ts::PartialParameters::velocity_curve ( ) const
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.

◆ velocity_crossfade_curve()

int ts::PartialParameters::velocity_crossfade_curve ( ) const
inlinenodiscardnoexcept

Velocity-crossfade curve selector; only the low nibble is used. Block +0x4e.

◆ velocity_low()

int ts::PartialParameters::velocity_low ( ) const
inlinenodiscardnoexcept

One edge of the velocity window. Block +0x4f.

◆ velocity_high()

int ts::PartialParameters::velocity_high ( ) const
inlinenodiscardnoexcept

The other edge of the velocity window. Block +0x51.

◆ level_at_low()

int ts::PartialParameters::level_at_low ( ) const
inlinenodiscardnoexcept

Partial level at the velocity_low edge. Block +0x50.

◆ level_at_high()

int ts::PartialParameters::level_at_high ( ) const
inlinenodiscardnoexcept

Partial level at the velocity_high edge. Block +0x52.

◆ tva_base_level()

int ts::PartialParameters::tva_base_level ( ) const
inlinenodiscardnoexcept

TVA base level. Block +0x53.

◆ velocity_window()

std::pair< int, int > ts::PartialParameters::velocity_window ( ) const
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.

◆ accepts_velocity()

bool ts::PartialParameters::accepts_velocity ( int velocity) const
inlinenodiscardnoexcept

True when a velocity falls inside this partial's window.

◆ transposed_key()

int ts::PartialParameters::transposed_key ( int note) const
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.

◆ operator==

bool operator== ( const PartialParameters & left,
const PartialParameters & right )
friend

Whether two views refer to the same block.

Member Data Documentation

◆ stride

int ts::PartialParameters::stride = 0x6E
staticconstexpr

Bytes per partial block.

◆ no_multisample

int ts::PartialParameters::no_multisample = 0xFFFF
staticconstexpr

Value of multisample meaning the partial is absent.


The documentation for this class was generated from the following file: