Files
reasampler/src/core/instrument/ui/deck_groups.h
T
daniel 39389c1183 fix: guard filter tail NaNs, skip static-filter envelope work, pin stereo filter path, correct stale comments
Codec fallback for non-finite filter fields, a modAmount==0 early-out in tickFilterCutoff,
new stereo render tests for the dual-mono mirror, and comment/test accuracy fixes flagged
in review (stale deck-width claims, restated invariants, drifted CMake link comments).
2026-07-30 17:35:45 -04:00

82 lines
3.6 KiB
C++

// deck_groups.h — WHICH groups the Sample face's knob deck carries and in what order, plus
// the control-id space they are built from. Pure data: knob_deck lays out whatever descriptors
// it is handed, and this module decides what those descriptors are, so the deck's signal-flow
// ordering is provable without a host.
#pragma once
#include <vector>
#include "core/instrument/engine/play_params.h" // PlayMode (the AMP group's Gate/Trigger face)
#include "core/instrument/ui/knob_deck.h" // DeckGroupDesc
namespace reasampler::instrument::ui {
// Deck control ids. Opaque to knob_deck, resolved by the shell's hit-test and value binding.
// Runtime-only — nothing persists them, so the ordering here is free to change.
enum class DeckParam {
kPlayMode = 0, // Gate | Trigger toggle
kPitchEngine, // Varispeed | Preserve toggle
kAttack, // AHDSR attack (Gate) / —
kHold, // AHDSR hold (Gate)
kDecay, // AHDSR decay (Gate)
kSustain, // AHDSR sustain (Gate)
kRelease, // AHDSR release (Gate)
kTrigLength, // Trigger %-length
kTrigFadeIn, // Trigger fade-in
kTrigFadeOut, // Trigger fade-out
kPitchEnvEnable, // AD pitch envelope on|off
kPitchEnvAttack, // AD pitch attack
kPitchEnvDecay, // AD pitch decay
kPitchEnvDepth, // AD pitch depth in +/- semitones
kKeyTrack, // key-tracking 0..200% (lives on InstrumentParams, not PlaySeconds)
// Filter. The four control positions map through filter_params' own laws; the three
// depths are bipolar and centred at zero.
kFilterEnable, // filter on|off caption toggle
kFilterMorph, // morph position: high-pass .. low-pass
kFilterCutoff, // cutoff, log across the audio band
kFilterQ, // resonance
kFilterDrive, // in-loop drive depth
kFilterModAmt, // filter envelope -> cutoff, +/-100%
kFilterVel, // velocity -> cutoff, +/-100%
kFilterKeyTrack, // note -> cutoff, 0..200%
kFilterLaw, // morph law row toggle: HP-BP-LP | HP-notch-LP
kFilterEnvAttack,
kFilterEnvHold,
kFilterEnvDecay,
kFilterEnvSustain,
kFilterEnvRelease,
// Deck-only controls: processor-side per-instance params — routed to the processor
// setters, never through the parameter set.
kVoiceCount, // polyphony bound (1..32) — a stepped knob in the VOICE group
kVoiceMode, // Poly | Mono caption toggle (VOICE group)
kMonoTrigger, // Retrig | Legato row toggle (VOICE group; live only in Mono)
kMasterGain, // post-mixer master gain knob (-inf..+24 dB taper, MASTER group)
kCount
};
// Deck group ids. Unscoped so the shell's caption switch reads against the plain `id` int
// knob_deck carries.
enum DeckGroupId {
kGroupPitch = 0,
kGroupPitchEnv,
kGroupFilter,
kGroupFilterEnv,
kGroupAmpEnv,
kGroupVoice,
kGroupMaster,
};
// The deck's groups, left to right, in SIGNAL-FLOW order: pitch -> filter -> amp, then the
// two instance-wide groups. `playMode` picks the AMP group's face, via knob_deck's blank-cell
// reservation (knob_deck.h) so a mode flip never reflows the neighbouring groups.
std::vector<DeckGroupDesc> sampleDeckGroups(PlayMode playMode);
// The deck's BIPOLAR knob law: 0.5 of the knob's travel is zero depth, the ends are -1 and
// +1. Exact inverses, and exact at the centre detent (0.5 -> 0 -> 0.5), so a knob parked at
// centre can never persist a hair of modulation. Out-of-range norm clamps to the endpoints.
double deckBipolarFromNorm(double norm);
double deckNormFromBipolar(double value);
} // namespace reasampler::instrument::ui