Retire the zone system: one capture = one parameter set, and re-seam the engine and Sample face into bands
This commit is contained in:
+30
-59
@@ -1,12 +1,11 @@
|
||||
// Standalone tests for reasampler::instrument::ui::embed_strip — no VST3, no REAPER, no framework.
|
||||
// Same fast assert loop as the sibling pure tests (editor_geometry et al.): assert the
|
||||
// embedded TCP/MCP strip's layout math + zone hit-testing + level fill directly.
|
||||
// Same fast assert loop as the sibling pure tests: assert the embedded TCP/MCP strip's
|
||||
// layout math + key-span mapping + level fill directly.
|
||||
//
|
||||
// Covers: layoutEmbed splitting a normal area into keymap + level band, a tiny area
|
||||
// (band yields to the keymap minimum, no inversion), and a zero area (all empty);
|
||||
// zoneSegmentRect mapping the 128-key span linearly, tiling adjacent zones seamlessly,
|
||||
// clamping out-of-range/inverted notes; zoneAtPoint hitting the covering zone, first-match
|
||||
// on overlap, missing on uncovered keys and off-band, and rejecting a null/empty list;
|
||||
// keySpanRect mapping the 128-key span linearly, tiling adjacent spans seamlessly,
|
||||
// resolving a single-key span (the root marker), and clamping out-of-range/inverted notes;
|
||||
// levelFillRect clamping 0..1 and its endpoints.
|
||||
|
||||
#include "../src/core/instrument/ui/embed_strip.h"
|
||||
@@ -55,74 +54,48 @@ static void testLayoutZeroArea() {
|
||||
CHECK(N.keymap.right() >= N.keymap.x && N.keymap.bottom() >= N.keymap.y);
|
||||
}
|
||||
|
||||
// --- zoneSegmentRect ----------------------------------------------------------
|
||||
// --- keySpanRect --------------------------------------------------------------
|
||||
|
||||
static void testZoneSegmentFullSpan() {
|
||||
// A zone covering the whole keyboard spans the entire keymap band width.
|
||||
static void testKeySpanFullKeyboard() {
|
||||
// The loaded capture responds across the whole keyboard, so its span is the whole band.
|
||||
const EmbedLayout L = layoutEmbed(256, 40);
|
||||
const Rect r = zoneSegmentRect(L, 0, 127);
|
||||
const Rect r = keySpanRect(L, 0, 127);
|
||||
CHECK(r.x == L.keymap.x);
|
||||
CHECK(r.right() == L.keymap.right());
|
||||
CHECK(r.y == L.keymap.y && r.bottom() == L.keymap.bottom());
|
||||
}
|
||||
|
||||
static void testAdjacentZonesTileSeamlessly() {
|
||||
// 256px band, 128 keys -> 2px/key. Zones 0..59 and 60..127 must abut with no gap or
|
||||
// overlap: the low zone's right == the high zone's left.
|
||||
static void testAdjacentSpansTileSeamlessly() {
|
||||
// 256px band, 128 keys -> 2px/key. Spans 0..59 and 60..127 must abut with no gap or
|
||||
// overlap: the low span's right == the high span's left.
|
||||
const EmbedLayout L = layoutEmbed(256, 40);
|
||||
const Rect lo = zoneSegmentRect(L, 0, 59);
|
||||
const Rect hi = zoneSegmentRect(L, 60, 127);
|
||||
const Rect lo = keySpanRect(L, 0, 59);
|
||||
const Rect hi = keySpanRect(L, 60, 127);
|
||||
CHECK(lo.x == L.keymap.x);
|
||||
CHECK(hi.right() == L.keymap.right());
|
||||
CHECK(lo.right() == hi.x); // seamless tile — the load-bearing assertion
|
||||
CHECK(lo.right() == L.keymap.x + 60 * 2); // 60 keys * 2px
|
||||
}
|
||||
|
||||
static void testZoneSegmentClampsBadNotes() {
|
||||
static void testSingleKeySpanIsTheRootMarker() {
|
||||
// low == high is the root marker: exactly one key wide, inside the band.
|
||||
const EmbedLayout L = layoutEmbed(256, 40);
|
||||
// Out-of-range notes clamp into the band; an inverted zone (low > high) collapses to a
|
||||
const Rect root = keySpanRect(L, 60, 60);
|
||||
CHECK(root.x == L.keymap.x + 60 * 2);
|
||||
CHECK(root.width == 2);
|
||||
CHECK(root.y == L.keymap.y && root.bottom() == L.keymap.bottom());
|
||||
}
|
||||
|
||||
static void testKeySpanClampsBadNotes() {
|
||||
const EmbedLayout L = layoutEmbed(256, 40);
|
||||
// Out-of-range notes clamp into the band; an inverted span (low > high) collapses to a
|
||||
// zero-or-positive-width rect, never inverts.
|
||||
const Rect over = zoneSegmentRect(L, -10, 200);
|
||||
const Rect over = keySpanRect(L, -10, 200);
|
||||
CHECK(over.x == L.keymap.x && over.right() == L.keymap.right());
|
||||
const Rect inv = zoneSegmentRect(L, 100, 20);
|
||||
const Rect inv = keySpanRect(L, 100, 20);
|
||||
CHECK(inv.right() >= inv.x);
|
||||
}
|
||||
|
||||
// --- zoneAtPoint --------------------------------------------------------------
|
||||
|
||||
static void testZoneAtPointHits() {
|
||||
const EmbedLayout L = layoutEmbed(256, 40);
|
||||
const EmbedZone zones[2] = {{0, 59}, {60, 127}};
|
||||
// A point inside the low zone's segment resolves to zone 0; inside the high zone, 1.
|
||||
const Rect lo = zoneSegmentRect(L, 0, 59);
|
||||
const Rect hi = zoneSegmentRect(L, 60, 127);
|
||||
const int yMid = (L.keymap.y + L.keymap.bottom()) / 2;
|
||||
CHECK(zoneAtPoint(L, zones, 2, lo.x + 1, yMid) == 0);
|
||||
CHECK(zoneAtPoint(L, zones, 2, hi.right() - 1, yMid) == 1);
|
||||
}
|
||||
|
||||
static void testZoneAtPointFirstMatchOnOverlap() {
|
||||
const EmbedLayout L = layoutEmbed(256, 40);
|
||||
// Two overlapping zones; the FIRST in order must win the contested keys.
|
||||
const EmbedZone zones[2] = {{0, 127}, {40, 80}};
|
||||
const int yMid = (L.keymap.y + L.keymap.bottom()) / 2;
|
||||
const Rect contested = zoneSegmentRect(L, 40, 80);
|
||||
CHECK(zoneAtPoint(L, zones, 2, contested.x + 1, yMid) == 0); // zone 0 wins
|
||||
}
|
||||
|
||||
static void testZoneAtPointMisses() {
|
||||
const EmbedLayout L = layoutEmbed(256, 40);
|
||||
const EmbedZone zones[1] = {{60, 72}}; // a narrow zone; most keys uncovered
|
||||
const int yMid = (L.keymap.y + L.keymap.bottom()) / 2;
|
||||
// A key left of the zone is uncovered -> -1.
|
||||
CHECK(zoneAtPoint(L, zones, 1, L.keymap.x + 1, yMid) == -1);
|
||||
// A point in the level band (below the keymap) is off the keymap -> -1.
|
||||
CHECK(zoneAtPoint(L, zones, 1, L.levelBand.x + 4, L.levelBand.y) == -1);
|
||||
// Empty / null list -> -1.
|
||||
CHECK(zoneAtPoint(L, zones, 0, L.keymap.x + 1, yMid) == -1);
|
||||
CHECK(zoneAtPoint(L, nullptr, 3, L.keymap.x + 1, yMid) == -1);
|
||||
}
|
||||
|
||||
// --- levelFillRect ------------------------------------------------------------
|
||||
|
||||
static void testLevelFillClamps() {
|
||||
@@ -144,12 +117,10 @@ int main() {
|
||||
testLayoutNormalArea();
|
||||
testLayoutTinyAreaKeepsKeymap();
|
||||
testLayoutZeroArea();
|
||||
testZoneSegmentFullSpan();
|
||||
testAdjacentZonesTileSeamlessly();
|
||||
testZoneSegmentClampsBadNotes();
|
||||
testZoneAtPointHits();
|
||||
testZoneAtPointFirstMatchOnOverlap();
|
||||
testZoneAtPointMisses();
|
||||
testKeySpanFullKeyboard();
|
||||
testAdjacentSpansTileSeamlessly();
|
||||
testSingleKeySpanIsTheRootMarker();
|
||||
testKeySpanClampsBadNotes();
|
||||
testLevelFillClamps();
|
||||
|
||||
if (g_fail == 0) std::printf("embed_strip: all tests passed\n");
|
||||
|
||||
Reference in New Issue
Block a user