fix: restore waveform symmetry about the midline, cut deck_values' link to the bank model, and unit-test the column arithmetic
The waveform column's vertical extents move to pure component_geometry so the shared primitive stops being untested; PlaySeconds hoists into a header-only play_seconds target.
This commit is contained in:
@@ -97,4 +97,31 @@ int waveformColumnCount(const KitBox& box) {
|
||||
return w > 0 ? w : 0;
|
||||
}
|
||||
|
||||
WaveformBand waveformBand(int bandTop, int bandHeight) {
|
||||
WaveformBand b;
|
||||
b.top = bandTop;
|
||||
b.height = bandHeight;
|
||||
b.midY = bandTop + bandHeight / 2;
|
||||
b.halfSpan = (bandHeight / 2) - 2; // matches drawWaveform's 2px vertical breathing room
|
||||
return b;
|
||||
}
|
||||
|
||||
WaveformColumnSpan waveformColumnSpan(const WaveformBand& band,
|
||||
double compressedMax, double compressedMin) {
|
||||
const int lo = band.top;
|
||||
const int hi = band.top + band.height - 1;
|
||||
|
||||
WaveformColumnSpan s;
|
||||
s.top = band.midY - static_cast<int>(compressedMax * band.halfSpan);
|
||||
s.bottom = band.midY - static_cast<int>(compressedMin * band.halfSpan);
|
||||
s.topF = band.midY - compressedMax * band.halfSpan;
|
||||
s.bottomF = band.midY - compressedMin * band.halfSpan;
|
||||
|
||||
if (s.top < lo) s.top = lo;
|
||||
if (s.bottom > hi) s.bottom = hi;
|
||||
if (s.topF < lo) s.topF = lo;
|
||||
if (s.bottomF > hi) s.bottomF = hi;
|
||||
return s;
|
||||
}
|
||||
|
||||
} // namespace reasampler::ui
|
||||
|
||||
@@ -75,11 +75,38 @@ ListRowBox computeListRow(const KitBox& list, int index, int rowHeight);
|
||||
// `rowCount` rows). rowCount bounds the hit so blank space past the last row is a clean miss.
|
||||
int hitTestListRow(int px, int py, const KitBox& list, int rowHeight, int rowCount);
|
||||
|
||||
// --- Waveform column count ---------------------------------------------------
|
||||
// --- Waveform columns --------------------------------------------------------
|
||||
|
||||
// Pixel columns drawWaveform renders inside `box` (its fixed 2px side insets), never negative.
|
||||
// Pass directly as peaks::computeEnvelope's binCount — one bin per column is correct resolution;
|
||||
// overbinning doesn't improve render quality and wastes memory/CPU.
|
||||
int waveformColumnCount(const KitBox& box);
|
||||
|
||||
// One channel band's shared vertical metrics: the zero line every column mirrors about, and the
|
||||
// pixel height a full-scale amplitude reaches (inset so a peak keeps the band's breathing room).
|
||||
struct WaveformBand {
|
||||
int top = 0;
|
||||
int height = 0;
|
||||
int midY = 0;
|
||||
double halfSpan = 0.0;
|
||||
};
|
||||
WaveformBand waveformBand(int bandTop, int bandHeight);
|
||||
|
||||
// The vertical extents of one column: the integer edges of the filled span, and the same edges
|
||||
// at sub-pixel precision for the antialiased outline stroke that joins a column's extremes to
|
||||
// its neighbour's. Both take the band clamp, so the stroke cannot leave the band the fill is
|
||||
// confined to. Amplitudes arrive already through the display curve.
|
||||
struct WaveformColumnSpan {
|
||||
int top = 0;
|
||||
int bottom = 0;
|
||||
double topF = 0.0;
|
||||
double bottomF = 0.0;
|
||||
};
|
||||
|
||||
// Truncation is applied to the SCALED AMPLITUDE and then mirrored about midY — never to the
|
||||
// resulting y, which would round the two edges in opposite directions and leave a column with
|
||||
// |max| == |min| a pixel taller above the zero line than below.
|
||||
WaveformColumnSpan waveformColumnSpan(const WaveformBand& band,
|
||||
double compressedMax, double compressedMin);
|
||||
|
||||
} // namespace reasampler::ui
|
||||
|
||||
Reference in New Issue
Block a user