Stack L/R waveform lanes in stereo mode, with overlays drawn once at full band height

This commit is contained in:
2026-07-30 09:04:57 -04:00
parent 81f5861ba4
commit 2a0d10fab5
9 changed files with 341 additions and 77 deletions
+27
View File
@@ -262,6 +262,28 @@ private:
// thread only (file I/O); cleared with the thumbnail cache on refresh.
const std::vector<AudioSample>& monoPcmFor(const std::string& sampleId);
// The interleaved source PCM behind the stereo waveform lanes.
struct ChannelPcm {
std::vector<AudioSample> interleaved; // frame-interleaved source frames
int channelCount = 0; // 0 = nothing decoded
std::int64_t frameCount() const {
return channelCount > 0
? static_cast<std::int64_t>(interleaved.size()) / channelCount
: 0;
}
};
// The interleaved PCM + channel count for a bank sample id. SINGLE-SLOT by design: the
// waveform band draws one capture at a time, while monoPcmFor's cache spans every
// browsed card — holding interleaved PCM there would pin a whole bank at multi-channel
// size. A miss re-decodes (only on selection change or a bank refresh; an edit commit
// does not clear it). UI thread only (file I/O).
const ChannelPcm& channelPcmFor(const std::string& sampleId);
// The project-relative WAV path for a bank sample id: the live bank blob first, the
// instance's own SampleRefs as the self-contained fallback. "" when unresolvable.
std::string samplePathFor(const std::string& sampleId) const;
// The effective loop + start markers for the loaded capture: the parameter set's
// override when one is set, else the bank's loop intrinsic / frame 0. Absent loop ->
// loopStart==loopEnd==0. `frames` defaults loopEnd when the bank left the loop empty.
@@ -434,6 +456,11 @@ private:
// Decoded mono-PCM cache, keyed by id (width-independent). Feeds the waveform envelope
// binning + zero-crossing snap. Cleared alongside thumbCache_ on refresh.
std::unordered_map<std::string, std::vector<AudioSample>> pcmCache_;
// The single-slot interleaved-PCM cache behind channelPcmFor (see its note on why this
// is not keyed into pcmCache_). Cleared alongside pcmCache_ on refresh.
std::string channelPcmId_;
ChannelPcm channelPcm_;
};
} // namespace reasampler::vst