mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-07-26 06:42:32 +00:00
Default lookahead 8s -> 4s: don't hang unsung lines through gaps
Field report ("Marks Of The Evil One", authored syllable-timed lyrics
with short lines around ~6s instrumental gaps): with an 8s lookahead the
banner no longer hid during those gaps — it sat there showing the next
dim lines while nothing was being sung, which reads as "the lyrics are
out of sync". The highlight clock was never wrong (invariant-tested);
the preview policy was.
4s keeps the full upcoming-context win during dense singing (next lines
start within a couple of seconds) while instrumental gaps go blank like
they used to. Still live-tunable via highway.setLyricsDisplay(). New
regression test pins the mid-gap hide + within-lookahead return.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: topkoa <topkoa@gmail.com>
This commit is contained in:
parent
5a35d1c0b4
commit
dd6e971390
@ -6965,7 +6965,7 @@
|
||||
// because this plugin deliberately does not import the shared
|
||||
// module. Both read localStorage['lyricsDisplay'], so
|
||||
// highway.setLyricsDisplay() tunes both at once.
|
||||
const LYRICS_DISPLAY_DEFAULTS = { upcomingLines: 2, lookaheadSec: 8 };
|
||||
const LYRICS_DISPLAY_DEFAULTS = { upcomingLines: 2, lookaheadSec: 4 };
|
||||
let _lyrCfgRaw, _lyrCfg = LYRICS_DISPLAY_DEFAULTS;
|
||||
function getLyricsDisplayCfg() {
|
||||
let raw = null;
|
||||
|
||||
@ -929,7 +929,11 @@ export function drawChords(hwState, W, H) {
|
||||
// without a reload.
|
||||
// upcomingLines — how many lines beyond the current one may be shown (0-4)
|
||||
// lookaheadSec — how far ahead a line may start and still be previewed (1-30)
|
||||
const LYRICS_DISPLAY_DEFAULTS = { upcomingLines: 2, lookaheadSec: 8 };
|
||||
// lookahead default is deliberately modest (4s): dense singing still gets
|
||||
// full upcoming context (next lines start within a couple of seconds), but
|
||||
// the banner goes away during instrumental gaps instead of hanging there
|
||||
// with unsung lines — which reads as "the lyrics are out of sync".
|
||||
const LYRICS_DISPLAY_DEFAULTS = { upcomingLines: 2, lookaheadSec: 4 };
|
||||
let _lyricsCfgRaw;
|
||||
let _lyricsCfg = LYRICS_DISPLAY_DEFAULTS;
|
||||
export function getLyricsDisplayCfg() {
|
||||
|
||||
@ -47,16 +47,16 @@ function makeStorage(initial) {
|
||||
test('cfg reader: defaults, clamping, corrupt JSON, live re-read', () => {
|
||||
const storage = makeStorage();
|
||||
const read = loadCfgReader(storage);
|
||||
assert.deepEqual(read(), { upcomingLines: 2, lookaheadSec: 8 });
|
||||
assert.deepEqual(read(), { upcomingLines: 2, lookaheadSec: 4 });
|
||||
|
||||
storage.setItem('lyricsDisplay', JSON.stringify({ upcomingLines: 99, lookaheadSec: 0 }));
|
||||
assert.deepEqual(read(), { upcomingLines: 4, lookaheadSec: 1 }); // clamped
|
||||
|
||||
storage.setItem('lyricsDisplay', '{not json');
|
||||
assert.deepEqual(read(), { upcomingLines: 2, lookaheadSec: 8 }); // corrupt -> defaults
|
||||
assert.deepEqual(read(), { upcomingLines: 2, lookaheadSec: 4 }); // corrupt -> defaults
|
||||
|
||||
storage.setItem('lyricsDisplay', JSON.stringify({ upcomingLines: 1 }));
|
||||
assert.deepEqual(read(), { upcomingLines: 1, lookaheadSec: 8 }); // partial merges over defaults
|
||||
assert.deepEqual(read(), { upcomingLines: 1, lookaheadSec: 4 }); // partial merges over defaults
|
||||
});
|
||||
|
||||
// ── drawLyrics harness ───────────────────────────────────────────────────
|
||||
@ -153,6 +153,22 @@ test('pre-song preview appears within lookahead, not before', () => {
|
||||
assert.deepEqual(near.calls.map(c => c.text), ['one']);
|
||||
});
|
||||
|
||||
test('banner hides during an instrumental gap, returns within lookahead', () => {
|
||||
// The "Marks Of The Evil One" report: short authored lines around a ~6s
|
||||
// instrumental gap. Mid-gap the banner must hide (nothing is being
|
||||
// sung), then return once the next line is inside the lookahead.
|
||||
const lyrics = [syl(10, 'sung', true), syl(17, 'next', true)];
|
||||
const draw = loadDrawLyrics({ upcomingLines: 2, lookaheadSec: 4 });
|
||||
|
||||
const midGap = makeCtx();
|
||||
draw({ lyrics, ctx: midGap, currentTime: 12 }, 2000, H); // next is 5s out
|
||||
assert.equal(midGap.calls.length, 0, 'mid-gap: no unsung lyrics on screen');
|
||||
|
||||
const nearNext = makeCtx();
|
||||
draw({ lyrics, ctx: nearNext, currentTime: 13.5 }, 2000, H); // 3.5s out
|
||||
assert.deepEqual(nearNext.calls.map(c => c.text), ['sung', 'next']);
|
||||
});
|
||||
|
||||
test('banner hides after the last line ends with nothing upcoming', () => {
|
||||
const lyrics = [syl(10, 'one', true)];
|
||||
const draw = loadDrawLyrics({ upcomingLines: 2, lookaheadSec: 8 });
|
||||
|
||||
Loading…
Reference in New Issue
Block a user