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

The GS insertion EFX block: one stereo effect ahead of the send network. More...

#include <tabulasonora/insertion_effect.hpp>

Public Member Functions

 InsertionEffect (const RomImage &rom)
 ~InsertionEffect ()
 InsertionEffect (InsertionEffect &&) noexcept
InsertionEffectoperator= (InsertionEffect &&) noexcept
const std::vector< EfxRecord > & directory () const
 The directory, in file order: 65 named types plus the blank "no effect" record.
void select_type (int msb, int lsb)
 Selects a type by its GS key and loads its defaults, exactly as 40 03 00/01 does.
void set_parameter (int address, int value)
 Writes one byte of the 40 03 block, addresses 0x030x1E.
const EfxRecordcurrent () const
 The record currently selected, or the "no effect" record before any selection.
bool implemented () const
 Whether the selected type's processor has been transcribed.
double reverb_send () const noexcept
 The block's common send levels, 40 03 1719, as linear gains on the block's output.
double chorus_send () const noexcept
double delay_send () const noexcept
void process (std::span< const float > in_left, std::span< const float > in_right, std::span< float > out_left, std::span< float > out_right)
 Processes one block in place: EFX-part dry in, effect out.
void reset ()
 Clears delay lines and scratch, keeping type and parameters.

Static Public Attributes

static constexpr int register_count = 0x180
 Registers in the file: engine numbers 0x800x1FF, stored zero-based.
static constexpr int parameter_bytes = 0x20
 Bytes in the live parameter block, addressed by 40 03 031E plus internal state.

Detailed Description

The GS insertion EFX block: one stereo effect ahead of the send network.

This is the subsystem the spec's scope note leaves to the downstream engine. The block-level machinery is transcribed from the engine and is the same for all 65 types: a register file of byte parameters converted to float coefficients (fx_reg_write @ 0x1800898d0, with the per-register width map and the bit-15 scale select), a per-type packed preset that fills registers 0x8A0x1EF on selection (fx_set_algo_index @ 0x180062410), and two delay lines whose base decrements one sample per sample, so an algorithm is a program of taps at fixed offsets (fx_delayline_wrap @ 0x180089830).

The per-algorithm processors are transcribed individually, and only a first tranche exists: Thru, Overdrive and Distortion (one dataflow — the decompiled functions differ only in presets). A type whose processor has not been transcribed yet passes the signal through unchanged and reports itself via implemented(), so a host can say which effect it is not rendering rather than rendering it wrong.

Roland-derived data — the directory, the presets, the parameter curves — is decoded from the user's own DLL at runtime, like every other table in this engine. Offsets are pinned to SOUND Canvas VA 1.1.6.

Constructor & Destructor Documentation

◆ InsertionEffect() [1/2]

ts::InsertionEffect::InsertionEffect ( const RomImage & rom)
explicit

◆ ~InsertionEffect()

ts::InsertionEffect::~InsertionEffect ( )

◆ InsertionEffect() [2/2]

ts::InsertionEffect::InsertionEffect ( InsertionEffect && )
noexcept

Member Function Documentation

◆ operator=()

InsertionEffect & ts::InsertionEffect::operator= ( InsertionEffect && )
noexcept

◆ directory()

const std::vector< EfxRecord > & ts::InsertionEffect::directory ( ) const
nodiscard

The directory, in file order: 65 named types plus the blank "no effect" record.

◆ select_type()

void ts::InsertionEffect::select_type ( int msb,
int lsb )

Selects a type by its GS key and loads its defaults, exactly as 40 03 00/01 does.

A key that matches no record leaves the block on algorithm 0 (Thru), which is the engine's own behaviour — the algorithm index is only ever written from a successful map scan.

◆ set_parameter()

void ts::InsertionEffect::set_parameter ( int address,
int value )

Writes one byte of the 40 03 block, addresses 0x030x1E.

◆ current()

const EfxRecord & ts::InsertionEffect::current ( ) const
nodiscard

The record currently selected, or the "no effect" record before any selection.

◆ implemented()

bool ts::InsertionEffect::implemented ( ) const
nodiscard

Whether the selected type's processor has been transcribed.

False means the block is passing the signal through unchanged: routing, sends and defaults are all live, but the DSP itself is not this effect's.

◆ reverb_send()

double ts::InsertionEffect::reverb_send ( ) const
nodiscardnoexcept

The block's common send levels, 40 03 1719, as linear gains on the block's output.

EFX parts have their own sends forced off; these are what replaces them.

◆ chorus_send()

double ts::InsertionEffect::chorus_send ( ) const
nodiscardnoexcept

◆ delay_send()

double ts::InsertionEffect::delay_send ( ) const
nodiscardnoexcept

◆ process()

void ts::InsertionEffect::process ( std::span< const float > in_left,
std::span< const float > in_right,
std::span< float > out_left,
std::span< float > out_right )

Processes one block in place: EFX-part dry in, effect out.

The engine doubles the input and halves the output around each algorithm (fx_process_block), and that pairing is preserved here.

◆ reset()

void ts::InsertionEffect::reset ( )

Clears delay lines and scratch, keeping type and parameters.

Member Data Documentation

◆ register_count

int ts::InsertionEffect::register_count = 0x180
staticconstexpr

Registers in the file: engine numbers 0x800x1FF, stored zero-based.

◆ parameter_bytes

int ts::InsertionEffect::parameter_bytes = 0x20
staticconstexpr

Bytes in the live parameter block, addressed by 40 03 031E plus internal state.


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