Cut core/instrument/map comment bloat ~30% (comments only, zero code change)

This commit is contained in:
2026-07-29 20:48:35 -04:00
parent 1f24c4b095
commit 354192ae27
12 changed files with 546 additions and 814 deletions
+27 -46
View File
@@ -1,6 +1,5 @@
// sample_map — pure implementation (the RESOLUTION half; the ComponentState codec
// lives in component_state_io.cpp since Q-W2v). See sample_map.h. NO VST3 / REAPER /
// SWELL / vendor includes; standard library + the pure bank_book / wav_codec / sampler_core.
// sample_map — pure implementation (the resolution half; the ComponentState codec lives
// in component_state_io.cpp). See sample_map.h.
#include "core/instrument/map/sample_map.h"
@@ -12,9 +11,8 @@ namespace reasampler::instrument::map {
namespace {
// Translate a bank_model Sample's S2 intrinsics into the core's SampleLoop. The bank
// stores loop points as an optional LoopPoints (both-or-neither); the core wants a
// SampleLoop with an explicit hasLoop. Absent -> no loop.
// The bank stores loop points as an optional LoopPoints (both-or-neither); the core wants
// a SampleLoop with an explicit hasLoop. Absent -> no loop.
SampleLoop loopFromSample(const Sample& s) {
SampleLoop out;
if (s.loop) {
@@ -25,41 +23,33 @@ SampleLoop loopFromSample(const Sample& s) {
return out;
}
// A distilled SelectedSample from a bank_model Sample. rootNote defaults to middle C
// (60) when the bank left the intrinsic empty — Tier 0 still plays, just centered on
// C rather than a captured pitch (surfaced: an un-rooted sample plays unity at C4).
// rootNote defaults to middle C (60) when the bank left the intrinsic empty — an
// un-rooted sample plays unity at C4 rather than failing to play.
SelectedSample distill(const Sample& s) {
SelectedSample out;
out.relativePath = s.relativePath;
out.rootNote = s.rootNote ? *s.rootNote : 60;
out.loop = loopFromSample(s);
out.channelCount = s.channelCount; // capture intrinsic; 0 = unknown (older entry)
out.channelCount = s.channelCount; // 0 = unknown (older entry)
return out;
}
// The ONE override-beats-intrinsic fold shared by the bank-side resolvePerformance and the
// refs-side resolvePerformanceFromRefs (pS): a zone's authored fields + the sample's
// intrinsics (already distilled — rootNote carries the middle-C default) -> ResolvedZone.
// Shared so the two resolution paths cannot drift.
// The ONE override-beats-intrinsic fold shared by resolvePerformance and
// resolvePerformanceFromRefs, so the two resolution paths cannot drift.
ResolvedZone foldZone(const PerformanceZone& z, const SelectedSample& ref) {
ResolvedZone rz;
rz.relativePath = ref.relativePath;
rz.lowNote = z.lowNote;
rz.highNote = z.highNote;
// Effective root: override beats intrinsic (distill already defaulted an empty
// intrinsic to middle C).
rz.rootNote = z.rootOverride ? *z.rootOverride : ref.rootNote;
// S-VIEW-6/S-VIEW-9: key tracking + the velocity->amp curve are instrument state —
// carried straight through and applied at play time.
// Key tracking + velocity curve are instrument state — carried straight through.
rz.keyTrack = z.keyTrack;
rz.velocityCurve = z.velocityCurve;
// Effective loop / start (S11): the per-zone override wins over the intrinsic; absent
// -> the intrinsic (loop) / frame 0 (start). The bank is never mutated (D-B).
// Per-zone override wins over the intrinsic; absent -> intrinsic (loop) / frame 0
// (start). The bank is never mutated.
rz.loop = z.loopOverride ? *z.loopOverride : ref.loop;
rz.startFrame = z.startPoint ? *z.startPoint : 0;
// S15/S16 per-zone play params (SECONDS) carry through unchanged; buildZonedKeymap
// resolves them to frames.
rz.play = z.play;
rz.play = z.play; // SECONDS; buildZonedKeymap resolves to frames
return rz;
}
@@ -67,22 +57,20 @@ ResolvedZone foldZone(const PerformanceZone& z, const SelectedSample& ref) {
std::optional<SelectedSample> selectSample(const std::string& banksJson,
const std::string& sampleId) {
// POLICY REVERSAL (S10): an empty selection is SILENCE, not the first sample. Short-
// circuit before parsing — no stored id resolves to nothing to play by design.
// An empty selection is SILENCE, not the first sample — by design.
if (sampleId.empty()) return std::nullopt;
if (banksJson.empty()) return std::nullopt;
std::optional<BankBook> book = BankBook::deserialize(banksJson);
if (!book) return std::nullopt; // malformed -> nothing to play (never throw)
// Search every bank (pool first, then named — banks() is ordinal order) for the
// stored id. A sample lives in exactly one bank, so first hit wins.
// Search every bank (ordinal order) for the stored id; a sample lives in exactly
// one bank, so first hit wins.
for (const Bank& b : book->banks()) {
if (const Sample* s = b.index.query(sampleId)) {
return distill(*s);
}
}
// A stale stored id (no longer resolves) is SILENCE, not a substituted first sample:
// the editor reflects the missing pick with its empty state rather than masking it.
// A stale stored id is SILENCE too — the editor's empty state, not a substitution.
return std::nullopt;
}
@@ -92,7 +80,7 @@ ChannelMode channelModeFor(int channelCount, ChannelMode current, bool isExplici
return channelCount >= 2 ? ChannelMode::Stereo : ChannelMode::Mono;
}
// --- Instance-owned sample references (pS self-contained playback) -------------
// --- Instance-owned sample references (self-contained playback) -------------
const SelectedSample* findRef(const SampleRefs& refs, const std::string& sampleId) {
if (sampleId.empty()) return nullptr;
@@ -133,7 +121,7 @@ void refreshRefsFromBank(SampleRefs& refs, const std::string& banksJson,
for (SampleRefEntry& e : refs) {
if (e.sampleId == id) {
e.ref = distilled;
e.displayName = found->displayName; // rename sync rides the same refresh
e.displayName = found->displayName; // rename sync
updated = true;
break;
}
@@ -233,22 +221,18 @@ DecodedZonePcm decodeChannels(const std::vector<AudioSample>& interleaved,
if (sampleRate <= 0) return out; // safe early-return; caller supplied an invalid rate
out.sampleRate = sampleRate;
if (mode == ChannelMode::Mono) {
// MONO mode: the existing downmix policy (average all source channels), one channel out.
out.monoFrames = downmixToMono(interleaved, sourceChannels);
return out; // framesR stays empty
}
// STEREO mode: channel 0 = source channel 0; channel 1 = source channel 1, or channel 0
// duplicated when the source is mono (dual-mono, centered). extractChannel clamps the
// out-of-range channel request to the last channel, so a mono source yields L == R.
// extractChannel clamps out-of-range, so a mono source yields L == R (dual-mono).
out.monoFrames = extractChannel(interleaved, sourceChannels, 0);
out.framesR = extractChannel(interleaved, sourceChannels, 1);
return out;
}
ZonePlayParams resolvePlay(const ZonePlaySeconds& stored, int sampleRate) {
// seconds -> frames at the LIVE rate (round-to-nearest). Wall-clock quantities (AHDSR A/H/D/R,
// pitch env A/D) resolve here; source-timeline quantities (trigger %-length + fades) carry
// through untouched — they are already source frames / fractions. Non-time fields pass as-is.
// seconds -> frames at the LIVE rate; source-timeline quantities (trigger %-length +
// fades) carry through untouched, already frames/fractions.
assert(sampleRate > 0 && "resolvePlay: sampleRate must be > 0 (programming error)");
const double sr = sampleRate > 0 ? static_cast<double>(sampleRate) : 1.0; // 1.0 avoids div-by-zero; assert fires first
const auto secToFrames = [sr](double sec) {
@@ -304,8 +288,7 @@ ResolvedPerformance resolvePerformance(const std::string& banksJson,
if (!book) return out; // malformed -> nothing (never throw)
for (const PerformanceZone& z : map.zones) {
// Look the id up across every bank (pool + named) — a sample lives in exactly
// one bank, so first hit wins.
// A sample lives in exactly one bank, so first hit wins.
const Sample* found = nullptr;
for (const Bank& b : book->banks()) {
if (const Sample* s = b.index.query(z.sampleId)) {
@@ -314,12 +297,11 @@ ResolvedPerformance resolvePerformance(const std::string& banksJson,
}
}
if (!found) {
// STALE-ID POLICY: drop the zone cleanly, report the id (editor can prune).
out.droppedSampleIds.push_back(z.sampleId);
out.droppedSampleIds.push_back(z.sampleId); // stale: drop, report
continue;
}
// Distill the bank Sample to the same intrinsics shape the refs table carries, then
// run the SHARED fold — so the bank path and the refs path resolve identically.
// Distill to the same intrinsics shape the refs table carries, then run the SHARED
// fold — so the bank path and refs path resolve identically.
out.zones.push_back(foldZone(z, distill(*found)));
}
return out;
@@ -332,8 +314,7 @@ ResolvedPerformance resolvePerformanceFromRefs(const SampleRefs& refs,
if (const SelectedSample* r = findRef(refs, z.sampleId)) {
out.zones.push_back(foldZone(z, *r));
} else {
// No ref for this id (never copied, or a pre-v10 blob not yet lifted): drop the
// zone cleanly + report — the same shape as the bank path's stale-id policy.
// No ref for this id: drop + report, same shape as the bank path's stale-id policy.
out.droppedSampleIds.push_back(z.sampleId);
}
}