fix(waveform): 4x-oversampled min/max envelope, columnMinMax homed in peaks, panel routed through shared drawWaveform — one gap-free algorithm on all surfaces
This commit is contained in:
@@ -121,10 +121,12 @@ std::string sampleLabel(const std::vector<SampleChoice>& samples, const std::str
|
||||
return "?";
|
||||
}
|
||||
|
||||
// The bin count a card's thumbnail is computed at: the card thumbnail width, so one bin
|
||||
// per horizontal pixel.
|
||||
// The bin count a card's thumbnail is computed at: kWaveformOversample bins per drawn
|
||||
// thumbnail pixel column (FA3 anti-alias) — drawWaveform collapses them per column via
|
||||
// peaks::columnMinMax. thumbnailFor clamps the request to the decoded frame count.
|
||||
int thumbBins(const BrowserLayout& layout) {
|
||||
return (std::max)(1, cardThumbnailRect(layout, 0).width());
|
||||
return (std::max)(1, kWaveformOversample *
|
||||
waveformColumnCount(toKitBox(cardThumbnailRect(layout, 0))));
|
||||
}
|
||||
#endif
|
||||
} // namespace
|
||||
@@ -570,8 +572,12 @@ const Envelope& ReaSamplerEditor::thumbnailFor(const std::string& sampleId, int
|
||||
const std::vector<AudioSample>& mono = monoPcmFor(sampleId);
|
||||
Envelope env;
|
||||
if (!mono.empty()) {
|
||||
env = computeEnvelope(mono, 1, mono.size(),
|
||||
static_cast<std::size_t>((std::max)(1, binCount)));
|
||||
// Clamp bins to the frame count: computeEnvelope pads binCount > frameCount with
|
||||
// trailing empty {0,0} bins, which would render a very short sample as a comb of
|
||||
// spikes over flat gaps.
|
||||
const std::size_t bins =
|
||||
(std::min)(static_cast<std::size_t>((std::max)(1, binCount)), mono.size());
|
||||
env = computeEnvelope(mono, 1, mono.size(), bins);
|
||||
}
|
||||
auto ins = thumbCache_.emplace(key, std::move(env));
|
||||
return ins.first->second;
|
||||
@@ -1005,8 +1011,15 @@ void ReaSamplerEditor::paintSample(LICE_IBitmap* bmp, int w, int h) {
|
||||
const Rect waveArea = bands.hero;
|
||||
fillSurface(bmp, toKitBox(waveArea), Role::BgBase, InteractionState::Rest);
|
||||
if (frames > 0 && waveArea.width() > 0) {
|
||||
const int bins = (std::max)(1, waveArea.width());
|
||||
const Envelope env = computeEnvelope(pcm, 1, pcm.size(), static_cast<std::size_t>(bins));
|
||||
// FA3 anti-alias: request kWaveformOversample bins per drawn pixel column (clamped
|
||||
// to the frame count) — drawWaveform collapses them per column via
|
||||
// peaks::columnMinMax into a gap-free true min/max envelope.
|
||||
const std::int64_t wantBins =
|
||||
static_cast<std::int64_t>((std::max)(1, waveformColumnCount(toKitBox(waveArea)))) *
|
||||
kWaveformOversample;
|
||||
const std::size_t bins =
|
||||
static_cast<std::size_t>(wantBins < frames ? wantBins : frames);
|
||||
const Envelope env = computeEnvelope(pcm, 1, pcm.size(), bins);
|
||||
drawEnvelope(bmp, waveArea, env);
|
||||
|
||||
const SetupMarkers m = pickedMarkers(frames);
|
||||
|
||||
Reference in New Issue
Block a user