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:
2026-08-01 09:47:07 -04:00
parent 7f74b11dce
commit ca464397b2
17 changed files with 310 additions and 138 deletions
+15 -19
View File
@@ -27,6 +27,10 @@ using ui::compressAmplitudeForDisplay;
using ui::roleColor;
using ui::roleColorState;
using ui::spectralColor;
using ui::WaveformBand;
using ui::waveformBand;
using ui::WaveformColumnSpan;
using ui::waveformColumnSpan;
// The one place a pure KitColor becomes a LICE_pixel (LICE_RGBA(r,g,b,a), verified against
// lice.h). The theme owns the color; the shell owns the packing.
@@ -289,11 +293,9 @@ void drawWaveform(LICE_IBitmap* bmp, const KitBox& box, const Envelope& env) {
for (int ch = 0; ch < channels; ++ch) {
const ChannelEnvelope& bins = env[static_cast<std::size_t>(ch)];
const int bandTop = box.y + ch * bandH;
const int midY = bandTop + bandH / 2;
const double halfSpan = (bandH / 2) - 2;
const WaveformBand band = waveformBand(box.y + ch * bandH, bandH);
LICE_Line(bmp, box.x + 2, midY, box.x + box.width - 2, midY,
LICE_Line(bmp, box.x + 2, band.midY, box.x + box.width - 2, band.midY,
midCol, 1.0f, 0, false);
if (bins.empty() || innerW <= 0) continue;
@@ -303,28 +305,22 @@ void drawWaveform(LICE_IBitmap* bmp, const KitBox& box, const Envelope& env) {
// alone leaves the outline stepped — a vertical span has no aa to apply — and where two
// adjacent columns differ sharply it reads as a comb rather than one envelope. The
// stroke is the SAME ink as the fill it edges, so it can only soften the boundary.
double prevTop = 0.0;
double prevBottom = 0.0;
WaveformColumnSpan prev;
for (int col = 0; col < innerW; ++col) {
const MinMax mm = columnMinMax(bins, innerW, col);
const int x = box.x + 2 + col;
const double topF = midY - compressAmplitudeForDisplay(mm.max) * halfSpan;
const double bottomF = midY - compressAmplitudeForDisplay(mm.min) * halfSpan;
int yMax = static_cast<int>(topF);
int yMin = static_cast<int>(bottomF);
if (yMax < bandTop) yMax = bandTop;
if (yMin > bandTop + bandH - 1) yMin = bandTop + bandH - 1;
LICE_Line(bmp, x, yMin, x, yMax, waveCol, 1.0f, 0, false);
const WaveformColumnSpan s = waveformColumnSpan(
band, compressAmplitudeForDisplay(mm.max), compressAmplitudeForDisplay(mm.min));
LICE_Line(bmp, x, s.bottom, x, s.top, waveCol, 1.0f, 0, false);
if (col > 0) {
const float xPrev = static_cast<float>(x - 1);
const float xF = static_cast<float>(x);
LICE_FLine(bmp, xPrev, static_cast<float>(prevTop), xF,
static_cast<float>(topF), waveCol, 1.0f, 0, true);
LICE_FLine(bmp, xPrev, static_cast<float>(prevBottom), xF,
static_cast<float>(bottomF), waveCol, 1.0f, 0, true);
LICE_FLine(bmp, xPrev, static_cast<float>(prev.topF), xF,
static_cast<float>(s.topF), waveCol, 1.0f, 0, true);
LICE_FLine(bmp, xPrev, static_cast<float>(prev.bottomF), xF,
static_cast<float>(s.bottomF), waveCol, 1.0f, 0, true);
}
prevTop = topF;
prevBottom = bottomF;
prev = s;
}
}
}