feat(keyboard_strip): add isNaturalKey predicate for piano-pattern overlay (S-VIEW-7)

This commit is contained in:
2026-07-27 13:26:08 -04:00
parent 3b9b78b82c
commit 858f736466
3 changed files with 70 additions and 1 deletions
+37 -1
View File
@@ -11,7 +11,8 @@
// classifying low-edge / high-edge / body and the narrow-bar midpoint split (low wins the
// tie); zoneBarAtPoint first-match on overlap + null-list rejection; resolveDragNote rounding
// to the nearest key at the key centre, clamping to [0,127], and the zero-delta / zero-width
// no-ops.
// no-ops; isNaturalKey across a full octave (C4..B4), at boundary notes 0 and 127, and with
// out-of-range inputs that clamp to [0,127].
#include "../src/vst/keyboard_strip.h"
@@ -179,6 +180,38 @@ static void testResolveDragClampsAndNoOps() {
CHECK(resolveDragNote(Z, 60, 500) == 60);
}
// --- isNaturalKey -------------------------------------------------------------
static void testIsNaturalKeyFullOctave() {
// Semitone positions 0..11 starting at C4 (MIDI 60):
// C=60(nat) C#=61(acc) D=62(nat) D#=63(acc) E=64(nat) F=65(nat)
// F#=66(acc) G=67(nat) G#=68(acc) A=69(nat) A#=70(acc) B=71(nat)
const bool expected[12] = {
true, false, true, false, true, true,
false, true, false, true, false, true,
};
for (int i = 0; i < 12; ++i) {
CHECK(isNaturalKey(60 + i) == expected[i]);
}
}
static void testIsNaturalKeyBoundaryNotes() {
// Note 0 is C (natural); note 127 is G (natural); note 1 is C# (accidental).
CHECK(isNaturalKey(0) == true); // C0 — natural
CHECK(isNaturalKey(1) == false); // C#0 — accidental
CHECK(isNaturalKey(127) == true); // G9 — natural (127 % 12 == 7)
CHECK(isNaturalKey(126) == false); // F#9 — accidental (126 % 12 == 6)
}
static void testIsNaturalKeyOutOfRangeClamped() {
// Values outside [0,127] clamp to [0,127]; must not crash/UB.
// note -1 clamps to 0 (C, natural); note 128 clamps to 127 (G, natural).
CHECK(isNaturalKey(-1) == true);
CHECK(isNaturalKey(128) == true);
CHECK(isNaturalKey(-100) == true);
CHECK(isNaturalKey(200) == true);
}
static void testResolveDragProportionalNonDivisibleWidth() {
// THE REVIEW FINDING: 544px / 128 = 4.25 (non-integer). Old uniform-keyW math used
// keyW = 4 (floor), accumulating ~7 keys of drift at the far end. The proportional fix
@@ -221,6 +254,9 @@ int main() {
testResolveDragRoundsToNearestKey();
testResolveDragClampsAndNoOps();
testResolveDragProportionalNonDivisibleWidth();
testIsNaturalKeyFullOctave();
testIsNaturalKeyBoundaryNotes();
testIsNaturalKeyOutOfRangeClamped();
if (g_fail == 0) std::printf("keyboard_strip: all tests passed\n");
return g_fail != 0;