Skip to content

Commit 8e7de39

Browse files
RuitingMaclaude
andcommitted
Score: mid-piece key/clef changes, e-piano voice, responsive layout
- Frozen overlay crossfades between pre-rendered shells when a clef or key signature changes mid-piece; shells are deduped by (clef, keysig) fingerprint and fade is re-timed to when the inline glyph crosses the playhead, not the first note of the new measure - Axis stays at a stable stage position across scores, scaled with stage height so narrow viewports shrink the reserved zone in step - Overlay + mask hug each score's widest shell so narrow-keysig scores reclaim the empty space past the header as a longer note-fade zone - Glow animation on active notes/harms: attack → sustain → fade-out via keyframe-driven color + four-layer drop-shadow - Synth rewritten to an electric-piano voice (sine + decaying bell octave through a lowpass) with shared convolution reverb - Only one Score sounds audio at a time per page — play() pauses any other active player - Loop wrap now defers until iter > 0 so the first iteration doesn't flash a duplicate tail under the playhead at start - Suspend backdrop-filter during playback (matching drag) to kill the per-frame re-sample stutter - Fix harm onset extraction: compute from MEI bpm + meter + tstamp (Verovio's getTimesForElement returns {} for harm elements) - Fix abnormal measure widths in MEI by grouping above/below harms with @n so Verovio stops padding around asymmetric labels Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent eb3a4b7 commit 8e7de39

8 files changed

Lines changed: 785 additions & 200 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0">
3+
<meiHead>
4+
<fileDesc>
5+
<titleStmt><title>Clef-change test — treble ↔ bass, with key modulation</title></titleStmt>
6+
<pubStmt/>
7+
</fileDesc>
8+
</meiHead>
9+
<music>
10+
<body>
11+
<mdiv>
12+
<score>
13+
<scoreDef meter.count="4" meter.unit="4" key.sig="0" midi.bpm="96">
14+
<staffGrp>
15+
<staffDef n="1" lines="5" clef.shape="G" clef.line="2"/>
16+
</staffGrp>
17+
</scoreDef>
18+
<section>
19+
<!-- Bar 1 — treble, C major -->
20+
<measure n="1">
21+
<staff n="1"><layer n="1">
22+
<note pname="c" oct="5" dur="4"/>
23+
<note pname="e" oct="5" dur="4"/>
24+
<note pname="g" oct="5" dur="4"/>
25+
<note pname="e" oct="5" dur="4"/>
26+
</layer></staff>
27+
<harm place="above" staff="1" tstamp="1" n="1">treble · C</harm>
28+
</measure>
29+
30+
<!-- Bar 2 — switch to bass clef, G major (1 sharp), low voicing -->
31+
<scoreDef key.sig="1s">
32+
<staffGrp>
33+
<staffDef n="1" lines="5" clef.shape="F" clef.line="4"/>
34+
</staffGrp>
35+
</scoreDef>
36+
<measure n="2">
37+
<staff n="1"><layer n="1">
38+
<note pname="g" oct="2" dur="4"/>
39+
<note pname="d" oct="3" dur="4"/>
40+
<note pname="b" oct="2" dur="4"/>
41+
<note pname="d" oct="3" dur="4"/>
42+
</layer></staff>
43+
<harm place="above" staff="1" tstamp="1" n="1">bass · G</harm>
44+
</measure>
45+
46+
<!-- Bar 3 — back to treble, E♭ major (3 flats) -->
47+
<scoreDef key.sig="3f">
48+
<staffGrp>
49+
<staffDef n="1" lines="5" clef.shape="G" clef.line="2"/>
50+
</staffGrp>
51+
</scoreDef>
52+
<measure n="3">
53+
<staff n="1"><layer n="1">
54+
<note pname="e" oct="4" accid.ges="f" dur="4"/>
55+
<note pname="g" oct="4" dur="4"/>
56+
<note pname="b" oct="4" accid.ges="f" dur="4"/>
57+
<note pname="e" oct="5" accid.ges="f" dur="4"/>
58+
</layer></staff>
59+
<harm place="above" staff="1" tstamp="1" n="1">treble · E♭</harm>
60+
</measure>
61+
62+
<!-- Bar 4 — back to treble C major so the loop closes -->
63+
<scoreDef key.sig="0"/>
64+
<measure n="4">
65+
<staff n="1"><layer n="1">
66+
<note pname="c" oct="5" dur="4"/>
67+
<note pname="g" oct="4" dur="4"/>
68+
<note pname="e" oct="4" dur="4"/>
69+
<note pname="c" oct="4" dur="4"/>
70+
</layer></staff>
71+
<harm place="above" staff="1" tstamp="1" n="1">treble · C</harm>
72+
</measure>
73+
</section>
74+
</score>
75+
</mdiv>
76+
</body>
77+
</music>
78+
</mei>

public/scores/ii-V-I/score.mei

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@
2424
<note pname="b" oct="3" dur="4"/>
2525
<note pname="d" oct="4" dur="4"/>
2626
</layer></staff>
27-
<harm place="above" staff="1" tstamp="1">Dm7</harm>
28-
<harm place="above" staff="1" tstamp="3">G7</harm>
29-
<harm place="below" staff="1" tstamp="1">ii</harm>
30-
<harm place="below" staff="1" tstamp="3">V7</harm>
27+
<harm place="above" staff="1" tstamp="1" n="1">Dm7</harm>
28+
<harm place="above" staff="1" tstamp="3" n="1">G7</harm>
29+
<harm place="below" staff="1" tstamp="1" n="2">ii</harm>
30+
<harm place="below" staff="1" tstamp="3" n="2">V7</harm>
3131
</measure>
3232

3333
<!-- Bar 2: Cmaj7, whole note on the 3rd, suspended into air -->
3434
<measure n="2">
3535
<staff n="1"><layer n="1">
3636
<note pname="e" oct="4" dur="1"/>
3737
</layer></staff>
38-
<harm place="above" staff="1" tstamp="1">Cmaj7</harm>
39-
<harm place="below" staff="1" tstamp="1">I</harm>
38+
<harm place="above" staff="1" tstamp="1" n="1">Cmaj7</harm>
39+
<harm place="below" staff="1" tstamp="1" n="2">I</harm>
4040
</measure>
4141
</section>
4242
</score>

public/scores/modulating/score.mei

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0">
3+
<meiHead>
4+
<fileDesc>
5+
<titleStmt><title>Modulation test — C → D → B♭ → loop</title></titleStmt>
6+
<pubStmt/>
7+
</fileDesc>
8+
</meiHead>
9+
<music>
10+
<body>
11+
<mdiv>
12+
<score>
13+
<scoreDef meter.count="4" meter.unit="4" key.sig="0" midi.bpm="96">
14+
<staffGrp>
15+
<staffDef n="1" lines="5" clef.shape="G" clef.line="2"/>
16+
</staffGrp>
17+
</scoreDef>
18+
<section>
19+
<!-- Bar 1 — C major, arpeggiation -->
20+
<measure n="1">
21+
<staff n="1"><layer n="1">
22+
<note pname="c" oct="4" dur="4"/>
23+
<note pname="e" oct="4" dur="4"/>
24+
<note pname="g" oct="4" dur="4"/>
25+
<note pname="c" oct="5" dur="4"/>
26+
</layer></staff>
27+
<harm place="above" staff="1" tstamp="1" n="1">C</harm>
28+
</measure>
29+
30+
<!-- Bar 2 — modulate to D major (2 sharps) -->
31+
<scoreDef key.sig="2s"/>
32+
<measure n="2">
33+
<staff n="1"><layer n="1">
34+
<note pname="d" oct="4" dur="4"/>
35+
<note pname="f" oct="4" accid.ges="s" dur="4"/>
36+
<note pname="a" oct="4" dur="4"/>
37+
<note pname="d" oct="5" dur="4"/>
38+
</layer></staff>
39+
<harm place="above" staff="1" tstamp="1" n="1">D</harm>
40+
</measure>
41+
42+
<!-- Bar 3 — modulate to B♭ major (2 flats) -->
43+
<scoreDef key.sig="2f"/>
44+
<measure n="3">
45+
<staff n="1"><layer n="1">
46+
<note pname="b" oct="3" accid.ges="f" dur="4"/>
47+
<note pname="d" oct="4" dur="4"/>
48+
<note pname="f" oct="4" dur="4"/>
49+
<note pname="b" oct="4" accid.ges="f" dur="4"/>
50+
</layer></staff>
51+
<harm place="above" staff="1" tstamp="1" n="1">B♭</harm>
52+
</measure>
53+
54+
<!-- Bar 4 — back to C major so the loop closes cleanly -->
55+
<scoreDef key.sig="0"/>
56+
<measure n="4">
57+
<staff n="1"><layer n="1">
58+
<note pname="c" oct="5" dur="4"/>
59+
<note pname="g" oct="4" dur="4"/>
60+
<note pname="e" oct="4" dur="4"/>
61+
<note pname="c" oct="4" dur="4"/>
62+
</layer></staff>
63+
<harm place="above" staff="1" tstamp="1" n="1">C</harm>
64+
</measure>
65+
</section>
66+
</score>
67+
</mdiv>
68+
</body>
69+
</music>
70+
</mei>

public/scores/twinkle/score.mei

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
<note pname="g" oct="4" dur="4"/>
2525
<note pname="g" oct="4" dur="4"/>
2626
</layer></staff>
27-
<harm place="above" staff="1" tstamp="1">Cmaj7</harm>
28-
<harm place="below" staff="1" tstamp="1">I</harm>
27+
<harm place="above" staff="1" tstamp="1" n="1">Cmaj7</harm>
28+
<harm place="below" staff="1" tstamp="1" n="2">I</harm>
2929
</measure>
3030

3131
<!-- Bar 2 — little star, Am7, vi -->
@@ -35,8 +35,8 @@
3535
<note pname="a" oct="4" dur="4"/>
3636
<note pname="g" oct="4" dur="2"/>
3737
</layer></staff>
38-
<harm place="above" staff="1" tstamp="1">Am7</harm>
39-
<harm place="below" staff="1" tstamp="1">vi</harm>
38+
<harm place="above" staff="1" tstamp="1" n="1">Am7</harm>
39+
<harm place="below" staff="1" tstamp="1" n="2">vi</harm>
4040
</measure>
4141

4242
<!-- Bar 3 — How I wonder, Fmaj7, IV -->
@@ -47,8 +47,8 @@
4747
<note pname="e" oct="4" dur="4"/>
4848
<note pname="e" oct="4" dur="4"/>
4949
</layer></staff>
50-
<harm place="above" staff="1" tstamp="1">Fmaj7</harm>
51-
<harm place="below" staff="1" tstamp="1">IV</harm>
50+
<harm place="above" staff="1" tstamp="1" n="1">Fmaj7</harm>
51+
<harm place="below" staff="1" tstamp="1" n="2">IV</harm>
5252
</measure>
5353

5454
<!-- Bar 4 — what you are, Dm7 → G7 (ii-V), resolving to I next bar -->
@@ -58,10 +58,10 @@
5858
<note pname="d" oct="4" dur="4"/>
5959
<note pname="c" oct="4" dur="2"/>
6060
</layer></staff>
61-
<harm place="above" staff="1" tstamp="1">Dm7</harm>
62-
<harm place="above" staff="1" tstamp="3">G7</harm>
63-
<harm place="below" staff="1" tstamp="1">ii</harm>
64-
<harm place="below" staff="1" tstamp="3">V7</harm>
61+
<harm place="above" staff="1" tstamp="1" n="1">Dm7</harm>
62+
<harm place="above" staff="1" tstamp="3" n="1">G7</harm>
63+
<harm place="below" staff="1" tstamp="1" n="2">ii</harm>
64+
<harm place="below" staff="1" tstamp="3" n="2">V7</harm>
6565
</measure>
6666

6767
<!-- Bar 5 — Up above, Cmaj7, I -->
@@ -72,8 +72,8 @@
7272
<note pname="f" oct="4" dur="4"/>
7373
<note pname="f" oct="4" dur="4"/>
7474
</layer></staff>
75-
<harm place="above" staff="1" tstamp="1">Cmaj7</harm>
76-
<harm place="below" staff="1" tstamp="1">I</harm>
75+
<harm place="above" staff="1" tstamp="1" n="1">Cmaj7</harm>
76+
<harm place="below" staff="1" tstamp="1" n="2">I</harm>
7777
</measure>
7878

7979
<!-- Bar 6 — the world so high, G7, V7 -->
@@ -83,8 +83,8 @@
8383
<note pname="e" oct="4" dur="4"/>
8484
<note pname="d" oct="4" dur="2"/>
8585
</layer></staff>
86-
<harm place="above" staff="1" tstamp="1">G7</harm>
87-
<harm place="below" staff="1" tstamp="1">V7</harm>
86+
<harm place="above" staff="1" tstamp="1" n="1">G7</harm>
87+
<harm place="below" staff="1" tstamp="1" n="2">V7</harm>
8888
</measure>
8989

9090
<!-- Bar 7 — Like a diamond, C/E, I⁶ -->
@@ -95,8 +95,8 @@
9595
<note pname="f" oct="4" dur="4"/>
9696
<note pname="f" oct="4" dur="4"/>
9797
</layer></staff>
98-
<harm place="above" staff="1" tstamp="1">C/E</harm>
99-
<harm place="below" staff="1" tstamp="1">I⁶</harm>
98+
<harm place="above" staff="1" tstamp="1" n="1">C/E</harm>
99+
<harm place="below" staff="1" tstamp="1" n="2">I⁶</harm>
100100
</measure>
101101

102102
<!-- Bar 8 — in the sky, ii-V-I cadence -->
@@ -107,10 +107,10 @@
107107
<note pname="d" oct="4" dur="4"/>
108108
<note pname="c" oct="4" dur="4"/>
109109
</layer></staff>
110-
<harm place="above" staff="1" tstamp="1">Dm7</harm>
111-
<harm place="above" staff="1" tstamp="3">G7</harm>
112-
<harm place="below" staff="1" tstamp="1">ii</harm>
113-
<harm place="below" staff="1" tstamp="3">V7</harm>
110+
<harm place="above" staff="1" tstamp="1" n="1">Dm7</harm>
111+
<harm place="above" staff="1" tstamp="3" n="1">G7</harm>
112+
<harm place="below" staff="1" tstamp="1" n="2">ii</harm>
113+
<harm place="below" staff="1" tstamp="3" n="2">V7</harm>
114114
</measure>
115115
</section>
116116
</score>

0 commit comments

Comments
 (0)