From ff5bdd964c4917b079b5a730d4f1d0a5598e5fea Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 11:55:17 +0000 Subject: [PATCH 1/4] Fix missing choruses/refrains in Singalong and World songs; dedupe Nursery Rhymes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same class of bug as the Folk/Christmas fixes: the pub()/world() helpers loop a single melody, which drops any distinct chorus or refrain. - Molly Malone: added the "Alive, alive-o!" hook, previously missing - Whiskey in the Jar: added the "Musha ring dum-a-doo-dum-a-da / Whack for the daddy-o" chorus, previously missing - Cielito Lindo: added the iconic "Ay, ay, ay, ay, canta y no llores" refrain (arguably the most recognizable part of the song), previously missing Also removed a dead duplicate block in NURSERY_PIECES where twinkle, mary, birthday, chopsticks, lavender, and shortnin were each declared twice with byte-identical content — harmless (the second assignment always won) but pure waste. Verified other Singalong/Spirituals/World songs and left them as-is: their chorus/refrain reuses the same melody as the verse in the real song, so the single-loop structure is already correct. Ragtime pieces are honestly labeled "A section" only in their comments — a known, intentional simplification rather than a bug, since accurately transcribing the additional strains of Joplin's multi-strain piano rags is a materially different and much higher-risk undertaking than a folk-song verse/chorus fix. --- index.html | 138 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 46 deletions(-) diff --git a/index.html b/index.html index 06424c5..e02794a 100644 --- a/index.html +++ b/index.html @@ -3935,16 +3935,67 @@ const SINGALONG_PIECES=(function(){ bg.push({t:t,f:A3/2,d:2.0,i:'timpani',v:0.6});mel.push({t:t,l:4}); return {n:"Drunken Sailor",composer:"Sea Shanty (Trad.)",bpm:140,duration:Math.ceil(t+3),isClassical:true,isSingalong:true,timeSig:[4,4],bg:bg,melody:mel}; })(); - var molly=pub("Molly Malone","Irish (1880s)",100, - [C4,E4,E4,E4,F4,G4,G4,G4,A4,G4,F4,E4,D4,E4,F4,G4,A4,C5,C5,B4,A4,G4,F4,E4,D4,C4,E4,G4,C5,C5,B4,A4,G4,F4,E4,D4,C4], - [0,2,2,2,1,3,3,3,0,3,1,2,1,2,1,3,0,0,0,3,0,3,1,2,1,0,2,3,0,0,3,0,3,1,2,1,0], - [2,2,2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,4,2,2,2,2,2,2,2,4,2,2,4,2,2,2,2,2,2,2,6], - 4,C4); - var whiskey=pub("Whiskey in the Jar","Irish (Trad.)",125, - [G4,G4,A4,B4,B4,A4,G4,E4,D4,E4,G4,G4,A4,B4,D5,B4,A4,G4,E4,D4,E4,G4,A4,B4,A4,G4,E4,D4,E4,G4], - [3,3,0,3,3,0,3,2,1,2,3,3,0,3,1,3,0,3,2,1,2,3,0,3,0,3,2,1,2,3], - [2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,2,2,2,2,6], - 5,G4); + // Verse + the DISTINCT repeated "Alive, alive-o!" hook, which was previously missing. + var molly=(function(){ + var bg=[],mel=[],t=0,u=30/100; // u = one eighth-note unit + function seq(theme,lanes,durs,inst,v,rep){ + theme.forEach(function(f,i){ + var d=durs[i]*u; + bg.push({t:t,f:f,d:d*0.85,i:inst,v:v}); + if(rep>1)bg.push({t:t,f:f/2,d:d*0.85,i:'bass',v:v*0.35}); + mel.push({t:t,l:lanes[i],d:d,f:f}); + t+=d; + }); + } + var verseTheme=[C4,E4,E4,E4,F4,G4,G4,G4,A4,G4,F4,E4,D4,E4,F4,G4,A4,C5,C5,B4,A4,G4,F4,E4,D4,C4,E4,G4,C5,C5,B4,A4,G4,F4,E4,D4,C4]; + var verseLanes=[0,2,2,2,1,3,3,3,0,3,1,2,1,2,1,3,0,0,0,3,0,3,1,2,1,0,2,3,0,0,3,0,3,1,2,1,0]; + var verseDurs=[2,2,2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,4,2,2,2,2,2,2,2,4,2,2,4,2,2,2,2,2,2,2,6]; + // "Alive, alive-o! Alive, alive-o! Crying cockles and mussels, alive, alive-o!" + var hookTheme=[C5,C5,B4,A4,G4, C5,C5,B4,A4,G4, F4,E4,D4,E4,F4,G4,A4, G4,F4,E4,D4,C4]; + var hookLanes=[0,0,3,0,3, 0,0,3,0,3, 1,2,1,2,1,3,0, 3,1,2,1,0]; + var hookDurs=[1,1,1,1,4, 1,1,1,1,4, 2,2,2,2,2,2,4, 2,2,2,2,8]; + for(var rep=0;rep<4;rep++){ + var v=0.2+rep*0.08; + var inst=rep===0?'woodwind':rep===1?'strings':'brass'; + seq(verseTheme,verseLanes,verseDurs,inst,v,rep); + seq(hookTheme,hookLanes,hookDurs,inst,v*1.1,rep); + t+=0.4; + } + [C4,C4*5/4,C4*3/2,C4*2].forEach(function(f){bg.push({t:t,f:f,d:2.0,i:'strings',v:0.5});bg.push({t:t,f:f,d:2.0,i:'brass',v:0.4});}); + bg.push({t:t,f:C4/2,d:1.5,i:'timpani',v:0.55});mel.push({t:t,l:4}); + return {n:"Molly Malone",composer:"Irish (1880s)",bpm:100,duration:Math.ceil(t+2.5),isClassical:true,isSingalong:true,timeSig:[4,4],bg:bg,melody:mel}; + })(); + // Verse + the DISTINCT "Musha ring dum-a-doo-dum-a-da / Whack for the daddy-o" + // chorus, which was previously missing entirely. + var whiskey=(function(){ + var bg=[],mel=[],t=0,u=30/125; // u = one eighth-note unit + function seq(theme,lanes,durs,inst,v,rep){ + theme.forEach(function(f,i){ + var d=durs[i]*u; + bg.push({t:t,f:f,d:d*0.85,i:inst,v:v}); + if(rep>1)bg.push({t:t,f:f/2,d:d*0.85,i:'bass',v:v*0.35}); + mel.push({t:t,l:lanes[i],d:d,f:f}); + t+=d; + }); + } + var verseTheme=[G4,G4,A4,B4,B4,A4,G4,E4,D4,E4,G4,G4,A4,B4,D5,B4,A4,G4,E4,D4,E4,G4,A4,B4,A4,G4,E4,D4,E4,G4]; + var verseLanes=[3,3,0,3,3,0,3,2,1,2,3,3,0,3,1,3,0,3,2,1,2,3,0,3,0,3,2,1,2,3]; + var verseDurs=[2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,2,2,2,2,6]; + // "Musha ring dum-a-doo-dum-a-da, / Whack for the daddy-o, / Whack for the daddy-o, / There's whiskey in the jar." + var chorusTheme=[G4,G4,A4,B4,B4,A4,G4,E4,D4, D4,E4,G4,A4,B4, D4,E4,G4,A4,B4, D5,B4,A4,G4,E4,D4]; + var chorusLanes=[3,3,0,3,3,0,3,2,1, 1,2,3,0,3, 1,2,3,0,3, 1,3,0,3,2,1]; + var chorusDurs=[1,1,1,1,1,1,1,1,2, 2,1,1,1,4, 2,1,1,1,4, 1,1,1,1,1,8]; + for(var rep=0;rep<5;rep++){ + var v=0.22+rep*0.06; + var inst=rep<2?'woodwind':rep<4?'strings':'brass'; + seq(verseTheme,verseLanes,verseDurs,inst,v,rep); + seq(chorusTheme,chorusLanes,chorusDurs,inst,v*1.1,rep); + t+=0.4; + } + [G4,G4*5/4,G4*3/2,G4*2].forEach(function(f){bg.push({t:t,f:f,d:2.0,i:'strings',v:0.5});bg.push({t:t,f:f,d:2.0,i:'brass',v:0.4});}); + bg.push({t:t,f:G4/2,d:1.5,i:'timpani',v:0.55});mel.push({t:t,l:4}); + return {n:"Whiskey in the Jar",composer:"Irish (Trad.)",bpm:125,duration:Math.ceil(t+2.5),isClassical:true,isSingalong:true,timeSig:[4,4],bg:bg,melody:mel}; + })(); var parting=pub("The Parting Glass","Irish/Scots (Trad.)",80, [E4,G4,A4,B4,A4,G4,E4,D4,E4,G4,A4,B4,D5,B4,A4,G4,E4,G4,A4,B4,A4,G4,E4,D4,E4,G4,A4,B4,D5,B4,A4,G4], [2,3,0,3,0,3,2,1,2,3,0,3,1,3,0,3,2,3,0,3,0,3,2,1,2,3,0,3,1,3,0,3], @@ -4216,11 +4267,37 @@ const WORLD_PIECES=(function(){ [0,1,2,0,0,1,2,0,2,1,3,2,1,3,3,0,3,1,2,0,3,0,3,1,2,0,0,3,0,0,3,0], [2,2,2,2,2,2,2,2,2,2,4,2,2,4,2,2,2,2,2,4,2,2,2,2,2,4,2,2,4,2,2,8], 4,C4); - var cielito=world("Cielito Lindo","Mexican (1882)",120, - [E4,E4,F4,G4,A4,G4,F4,E4,D4,E4,F4,E4,D4,C4,E4,G4,C5,C5,B4,A4,G4,F4,E4,D4,C4,E4,G4,C5], - [2,2,1,3,0,3,1,2,1,2,1,2,1,0,2,3,0,0,3,0,3,1,2,1,0,2,3,0], - [2,2,2,2,4,2,2,2,2,2,2,2,2,6,2,2,4,2,2,2,2,2,2,2,4,2,2,8], - 4,C4); + // Verse + the iconic "Ay, ay, ay, ay, canta y no llores..." refrain, which was + // previously missing entirely (this refrain is the most recognizable part of the song). + var cielito=(function(){ + var bg=[],mel=[],t=0,u=30/120; // u = one eighth-note unit + function seq(theme,lanes,durs,inst,v,rep){ + theme.forEach(function(f,i){ + var d=durs[i]*u; + bg.push({t:t,f:f,d:d*0.85,i:inst,v:v}); + if(rep>1)bg.push({t:t,f:f/2,d:d*0.85,i:'bass',v:v*0.35}); + mel.push({t:t,l:lanes[i],d:d,f:f}); + t+=d; + }); + } + var verseTheme=[E4,E4,F4,G4,A4,G4,F4,E4,D4,E4,F4,E4,D4,C4,E4,G4,C5,C5,B4,A4,G4,F4,E4,D4,C4,E4,G4,C5]; + var verseLanes=[2,2,1,3,0,3,1,2,1,2,1,2,1,0,2,3,0,0,3,0,3,1,2,1,0,2,3,0]; + var verseDurs=[2,2,2,2,4,2,2,2,2,2,2,2,2,6,2,2,4,2,2,2,2,2,2,2,4,2,2,8]; + // "Ay, ay, ay, ay, / canta y no llores, / porque cantando se alegran, / cielito lindo, los corazones." + var refTheme=[G4,F4,E4,D4, C4,D4,E4,F4,G4,F4, F4,G4,F4,E4,D4,C4,D4,E4,F4, F4,G4,F4,E4,D4,C4,D4,C4]; + var refLanes=[3,1,2,1, 0,1,2,1,3,1, 1,3,1,2,1,0,1,2,1, 1,3,1,2,1,0,1,0]; + var refDurs=[2,2,2,4, 1,1,1,1,2,4, 1,1,1,1,1,1,1,1,4, 1,1,1,1,1,1,1,8]; + for(var rep=0;rep<4;rep++){ + var v=0.2+rep*0.08; + var inst=rep<1?'woodwind':rep<3?'strings':'brass'; + seq(verseTheme,verseLanes,verseDurs,inst,v,rep); + seq(refTheme,refLanes,refDurs,inst,v*1.15,rep); + t+=0.4; + } + [C4,C4*5/4,C4*3/2,C4*2].forEach(function(f){bg.push({t:t,f:f,d:2.0,i:'brass',v:0.5});bg.push({t:t,f:f,d:2.0,i:'strings',v:0.4});}); + bg.push({t:t,f:C4/2,d:1.5,i:'timpani',v:0.55});mel.push({t:t,l:4}); + return {n:"Cielito Lindo",composer:"Mexican (1882)",bpm:120,duration:Math.ceil(t+2.5),isClassical:true,bg:bg,melody:mel}; + })(); var waltzing=world("Waltzing Matilda","Australian (1895)",110, [G4,G4,A4,B4,D5,B4,A4,G4,E4,G4,A4,B4,A4,G4,E4,D4,G4,G4,A4,B4,D5,B4,A4,G4,E4,D4,G4], [3,3,0,3,1,3,0,3,2,3,0,3,0,3,2,1,3,3,0,3,1,3,0,3,2,1,3], @@ -4362,37 +4439,6 @@ const NURSERY_PIECES=(function(){ [0,0,3,3,0,0,0,3,1,1,2,2,1,1,0,3,3,3,1,1,1,2,2,2,1,1,1,0], [2,2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,2,2,2,2,2,2,6], 3,C4); - // ── Classics (from Prime, simple versions) ── - var twinkle=rhyme("Twinkle Twinkle Little Star","Traditional (1760s)",75, - [C4,C4,G4,G4,A4,A4,G4,F4,F4,E4,E4,D4,D4,C4,G4,G4,F4,F4,E4,E4,D4,C4,C4,G4,G4,A4,A4,G4,F4,F4,E4,E4,D4,D4,C4], - [0,0,3,3,0,0,3,1,1,2,2,1,1,0,3,3,1,1,2,2,1,0,0,3,3,0,0,3,1,1,2,2,1,1,0], - [2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,6], - 3,C4); - var mary=rhyme("Mary Had a Little Lamb","S.J. Hale (1830)",80, - [E4,D4,C4,D4,E4,E4,E4,D4,D4,D4,E4,G4,G4,E4,D4,C4,D4,E4,E4,E4,D4,D4,E4,D4,C4], - [2,1,0,1,2,2,2,1,1,1,2,3,3,2,1,0,1,2,2,2,1,1,2,1,0], - [2,2,2,2,2,2,4,2,2,4,2,2,4,2,2,2,2,2,2,2,2,2,2,2,6], - 3,C4); - var birthday=rhyme("Happy Birthday","P.S. Hill (1893)",75, - [C4,C4,D4,C4,F4,E4,C4,C4,D4,C4,G4,F4,C4,C4,C5,A4,F4,E4,D4,Bb4,Bb4,A4,F4,G4,F4], - [0,0,1,0,1,2,0,0,1,0,3,1,0,0,0,0,1,2,1,2,2,0,1,3,1], - [1,1,2,2,2,4,1,1,2,2,2,4,1,1,2,2,2,2,4,1,1,2,2,2,6], - 3,C4); - var chopsticks=rhyme("Chopsticks","Euphemia Allen (1877)",95, - [F4,G4,F4,G4,F4,G4,E4,G4,E4,G4,E4,G4,D4,F4,D4,F4,C4,E4,C4,E4,F4,G4,F4,G4,E4,G4,E4,G4,D4,F4,D4,F4,C4,E4,C4,E4], - [1,3,1,3,1,3,2,3,2,3,2,3,1,1,1,1,0,2,0,2,1,3,1,3,2,3,2,3,1,1,1,1,0,2,0,2], - [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8], - 3,C4); - var lavender=rhyme("Lavender's Blue","English Traditional (1670s)",80, - [E4,E4,D4,E4,F4,G4,G4,A4,G4,F4,F4,E4,D4,E4,E4,E4,D4,E4,F4,G4,G4,A4,G4,F4,E4], - [2,2,1,2,1,3,3,0,3,1,1,2,1,2,2,2,1,2,1,3,3,0,3,1,2], - [2,2,2,2,2,2,2,2,2,4,2,2,2,4,2,2,2,2,2,2,2,2,2,2,6], - 3,C4); - var shortnin=rhyme("Shortnin' Bread","Traditional (1900s)",95, - [E5,E5,D5,C5,D5,C5,A4,G4,A4,G4,A4,G4,E5,E5,D5,C5,D5,C5,A4,G4,A4,G4,C5], - [2,2,1,0,1,0,0,3,0,3,0,3,2,2,1,0,1,0,0,3,0,3,0], - [2,2,2,2,2,2,4,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,8], - 3,C4); return [baa,london,macdonald,row,mice,spider,weasel,hotcross,jack,humpty,twinkle,mary,birthday,chopsticks,lavender,shortnin]; })(); From 5161d062e44a7bc922e2031af0afed75edab14d9 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 12:24:22 +0000 Subject: [PATCH 2/4] Re-verify session's rhythm fixes against fetched public-domain scores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Went back through the pieces modified this session and checked each against an actual fetched source (mobilehymns.org, gmajormusictheory.org public-domain hymnal/beginner scores, rendered and read directly) instead of relying on memory alone. Corrected what didn't match: - Oh! Susanna: chorus was too fast/rhythmically flat; the real setting opens "Oh! Su-" on sustained half notes, much slower than the verse - Camptown Races: "Doo-dah! Doo-dah!" was an even stepwise run; the real song is quick "Doo-" + long held "dah!" (quarter + dotted-half) - We Three Kings: refrain confirmed to be in a lilting compound meter, not straight 4/4 as this had it; opening "O" adjusted toward that feel - Angels We Have Heard on High: the Gloria melisma is a 16-note rise- and-fall that dramatically descends a full octave; previous version was 15 notes spanning only a 6th - Hark the Herald Angels Sing: confirmed this hymn is truly strophic — "Joyful, all ye nations rise" is sung to the exact same tune as "Hark! the herald angels sing," not a different melody. Rebuilt from an invented chorus+verse alternation into one repeated 8-line stanza tune with a closing reprise of just the opening couplet, matching the score - O Come All Ye Faithful: "O come, let us adore Him" is a descending sequence — the same phrase shape repeated a step lower each time — not one phrase repeated verbatim three times - What Child Is This: the hymn is published in E minor with its own confirmed melodic shape, distinct in some details from the Greensleeves transcription elsewhere in this file; corrected to the hymn's own source rather than assuming the two are pitch-for-pitch identical Also fetched and read an actual public-domain score for 12 Days of Christmas and We Wish You a Merry Christmas: both confirmed the existing content (cumulative day-by-day structure, and the earlier New Year's ending fix, respectively) without needing further changes. Molly Malone, Whiskey in the Jar, and Cielito Lindo: attempted the same verification, but couldn't reach a fetchable note-level source for these (several sites blocked automated fetches); their content is unchanged from the prior pass and remains a best-effort construction rather than source-verified. --- index.html | 102 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/index.html b/index.html index e02794a..4d65943 100644 --- a/index.html +++ b/index.html @@ -3400,10 +3400,14 @@ const FOLK_PIECES=(function(){ var inst=rep===0?'woodwind':rep===1?'strings':'brass'; verseLine(inst,v,rep); // "I come from Alabama with my banjo on my knee" verseLine(inst,v,rep); // "I'm going to Louisiana my true love for to see" - // CHORUS: "Oh! Su-san-na, oh don't you cry for me," - note(G4,q,3,inst,v*1.15,rep);note(C5,e,2,inst,v*1.15,rep);note(C5,e,2,inst,v*1.15,rep);note(C5,q,2,inst,v*1.15,rep); - note(A4,e,0,inst,v*1.15,rep);note(G4,e,3,inst,v*1.15,rep);note(E4,q,2,inst,v*1.15,rep);note(D4,q,1,inst,v*1.15,rep); - note(E4,q,2,inst,v*1.15,rep);note(E4,q*2,2,inst,v*1.15,rep); + // CHORUS: "Oh! Su-san-na, oh don't you cry for me," — verified against a + // period arrangement (gmajormusictheory.org): the chorus opens with sustained + // half notes (much slower than the verse's steady eighth/quarter pattern), + // rising 3rd-to-5th-degree on "Oh! Su-" before the stepwise cadence. + note(E4,q*2,2,inst,v*1.15,rep);note(G4,q*2,3,inst,v*1.15,rep); + note(G4,q,3,inst,v*1.15,rep);note(A4,q*2,0,inst,v*1.15,rep);note(G4,q,3,inst,v*1.15,rep); + note(F4,q,1,inst,v*1.15,rep);note(G4,q,3,inst,v*1.15,rep);note(E4,q,2,inst,v*1.15,rep);note(C4,q,0,inst,v*1.15,rep); + note(D4,q*4,1,inst,v*1.15,rep); verseLine(inst,v*1.15,rep); // "for I come from Alabama, with my banjo on my knee" t+=0.4; } @@ -3434,9 +3438,12 @@ const FOLK_PIECES=(function(){ t+=d; }); } - var verseTheme=[G4,G4,E4,G4,A4,G4,E4,C4,D4,D4,E4,E4,F4,E4,D4,C4,C4,E4,G4,G4,G4,E4,G4,A4,G4,E4,C4,G4,A4,B4,A4,G4,E4,D4,D4,C4]; - var verseLanes=[3,3,2,3,0,3,2,0,1,1,2,2,1,2,1,0,0,2,3,3,3,2,3,0,3,2,0,3,0,3,0,3,2,1,1,0]; - var verseDurs=[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8]; + // "Doo-dah! Doo-dah!" verified against a period arrangement (gmajormusictheory.org): + // it's "Doo-" quick, "dah!" held (quarter + dotted-half per repetition), not a stepwise + // run of even quarters as this previously had it. + var verseTheme=[G4,G4,E4,G4,A4,G4,E4,C4,D4,F4,D4,C4,C4,E4,G4,G4,G4,E4,G4,A4,G4,E4,C4,G4,A4,B4,A4,G4,E4,D4,D4,C4]; + var verseLanes=[3,3,2,3,0,3,2,0,1,1,1,0,0,2,3,3,3,2,3,0,3,2,0,3,0,3,0,3,2,1,1,0]; + var verseDurs=[2,2,2,2,2,2,2,2,2,6,2,6,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8]; // "Gwine to run all night, gwine to run all day," / "I'll bet my money on de bob-tail nag," / "somebody bet on de bay." var refrainTheme=[G4,G4,G4,A4,G4,E4,E4,E4,F4,G4, C5,C5,B4,A4,G4,G4,G4,A4,G4,E4, D4,E4,F4,G4,E4,D4,C4]; var refrainLanes=[3,3,3,0,3,2,2,2,1,3, 0,0,3,0,3,3,3,0,3,2, 1,2,1,3,2,1,0]; @@ -3647,9 +3654,12 @@ const CHRISTMAS_PIECES=(function(){ bg.push({t:t,f:F4/2,d:1.5,i:'timpani',v:0.55});mel.push({t:t,l:4}); return {n:"12 Days of Christmas",composer:"English (1780)",bpm:110,duration:Math.ceil(t+2.5),isClassical:true,bg:bg,melody:mel}; })(); - // Sung as Refrain, Verse, Refrain, Verse, Refrain — the existing melody below is the - // famous "Hark! The herald angels sing" REFRAIN; the "Joyful, all ye nations rise" - // VERSE (a different tune) was previously missing, so the refrain just looped forever. + // Genuinely strophic: a verified public-domain score (mobilehymns.org) confirms + // "Joyful, all ye nations rise" is sung to the SAME tune as "Hark! The herald + // angels sing" (not a different melody) — every stanza reuses this one 8-line tune. + // Previously this was built as alternating chorus+verse with two different melodies, + // which invented a melody for "Joyful" that doesn't match the real hymn. The one + // genuine repeat in performance is a closing reprise of just the opening couplet. var hark=(function(){ var bg=[],mel=[],t=0,u=30/115; // u = one eighth-note unit function seq(theme,lanes,durs,inst,v,rep){ @@ -3661,21 +3671,20 @@ const CHRISTMAS_PIECES=(function(){ t+=d; }); } - var refTheme=[C4,F4,F4,E4,F4,A4,A4,G4,C5,A4,A4,G4,C5,A4,A4,G4,A4,Bb4,G4,A4,Bb4,C5,A4,F4,G4,Bb4,A4,G4,F4]; - var refLanes=[0,1,1,2,1,0,0,3,0,0,0,3,0,0,0,3,0,2,3,0,2,0,0,1,3,2,0,3,1]; - var refDurs=[2,4,2,2,4,2,2,4,2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,2,2,2,2,2,8]; - // "Joyful, all ye nations rise, / join the triumph of the skies, / with angelic host proclaim, / Christ is born in Bethlehem." - var verseTheme=[F4,G4,A4,Bb4,C5,Bb4,A4, F4,G4,A4,Bb4,C5,D5,C5, F4,G4,A4,Bb4,C5,Bb4,A4, F4,G4,A4,F4,G4,A4,F4]; - var verseLanes=[1,3,0,2,0,2,0, 1,3,0,2,0,3,0, 1,3,0,2,0,2,0, 1,3,0,1,3,0,1]; - var verseDurs=[2,1,1,2,2,1,4, 2,1,1,2,2,1,4, 2,1,1,2,2,1,4, 2,1,1,2,1,1,8]; - seq(refTheme,refLanes,refDurs,'woodwind',0.22,0); - for(var rep=0;rep<2;rep++){ - var v=0.28+rep*0.12; - var inst=rep===0?'strings':'brass'; - seq(verseTheme,verseLanes,verseDurs,inst,v,rep+1); - seq(refTheme,refLanes,refDurs,inst,v,rep+1); + var stanzaTheme=[C4,F4,F4,E4,F4,A4,A4,G4,C5,A4,A4,G4,C5,A4,A4,G4,A4,Bb4,G4,A4,Bb4,C5,A4,F4,G4,Bb4,A4,G4,F4]; + var stanzaLanes=[0,1,1,2,1,0,0,3,0,0,0,3,0,0,0,3,0,2,3,0,2,0,0,1,3,2,0,3,1]; + var stanzaDurs=[2,4,2,2,4,2,2,4,2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,2,2,2,2,2,8]; + // Closing reprise tag: just "Hark! The herald angels sing, Glory to the newborn King!" + var tagTheme=[C4,F4,F4,E4,F4,A4,A4,G4,C5,A4,A4,G4,C5,A4,A4,G4]; + var tagLanes=[0,1,1,2,1,0,0,3,0,0,0,3,0,0,0,3]; + var tagDurs=[2,4,2,2,4,2,2,4,2,2,2,4,2,2,2,8]; + for(var rep=0;rep<3;rep++){ + var v=0.2+rep*0.1; + var inst=rep===0?'woodwind':rep===1?'strings':'brass'; + seq(stanzaTheme,stanzaLanes,stanzaDurs,inst,v,rep); t+=0.4; } + seq(tagTheme,tagLanes,tagDurs,'brass',0.5,3); [F4,F4*5/4,F4*3/2,F4*2].forEach(function(f){bg.push({t:t,f:f,d:2.5,i:'choir',v:0.45});bg.push({t:t,f:f,d:2.5,i:'strings',v:0.4});}); bg.push({t:t,f:F4/2,d:2.0,i:'timpani',v:0.5});mel.push({t:t,l:4}); return {n:"Hark the Herald Angels Sing",composer:"Mendelssohn (1840)",bpm:115,duration:Math.ceil(t+3),isClassical:true,bg:bg,melody:mel}; @@ -3697,20 +3706,22 @@ const CHRISTMAS_PIECES=(function(){ var verseTheme=[C4,C4,G4,C4,D4,G4,E4,D4,E4,F4,E4,D4,C4,B4,A4,B4,C5,B4,A4,G4,A4,E4,F4,E4,D4,E4,F4,D4,C4,D4,C4,Bb4,A4,G4,F4,E4,F4,E4,D4,C4]; var verseLanes=[0,0,3,0,1,3,2,1,2,1,2,1,0,3,0,3,0,3,0,3,0,2,1,2,1,2,1,1,0,1,0,2,0,3,1,2,1,2,1,0]; var verseDurs=[4,2,4,2,4,6,2,2,2,2,2,2,4,2,2,2,4,2,2,4,2,2,2,2,2,2,2,4,2,2,2,2,2,4,2,2,2,2,2,6]; - // "O come, let us adore Him," (x3) "Christ the Lord." - var adoreTheme=[G4,A4,G4,F4,E4,D4,C4]; - var adoreLanes=[3,0,3,1,2,1,0]; - var adoreDurs=[2,2,2,2,2,2,4]; - var lordTheme=[F4,E4,D4,C4]; - var lordLanes=[1,2,1,0]; + // "O come, let us adore Him," (x3) "Christ the Lord." — verified against a public- + // domain score (mobilehymns.org): each repetition is the SAME phrase shape sung a + // step lower than the one before (a descending sequence), not one repeated phrase. + var adore1Theme=[G4,G4,F4,E4,F4,G4,G4],adore1Lanes=[3,3,1,2,1,3,3],adore1Durs=[2,2,1,1,2,2,4]; + var adore2Theme=[F4,F4,E4,D4,E4,F4,F4],adore2Lanes=[1,1,2,1,2,1,1],adore2Durs=[2,2,1,1,2,2,4]; + var adore3Theme=[E4,E4,D4,C4,D4,E4,F4],adore3Lanes=[2,2,1,0,1,2,1],adore3Durs=[2,2,1,1,2,2,2]; + var lordTheme=[G4,F4,E4,C4]; + var lordLanes=[3,1,2,0]; var lordDurs=[2,2,2,8]; for(var rep=0;rep<3;rep++){ var v=0.2+rep*0.09; var inst=rep===0?'woodwind':rep===1?'strings':'brass'; seq(verseTheme,verseLanes,verseDurs,inst,v,rep); - seq(adoreTheme,adoreLanes,adoreDurs,inst,v*1.1,rep); - seq(adoreTheme,adoreLanes,adoreDurs,inst,v*1.1,rep); - seq(adoreTheme,adoreLanes,adoreDurs,inst,v*1.2,rep); + seq(adore1Theme,adore1Lanes,adore1Durs,inst,v*1.1,rep); + seq(adore2Theme,adore2Lanes,adore2Durs,inst,v*1.1,rep); + seq(adore3Theme,adore3Lanes,adore3Durs,inst,v*1.2,rep); seq(lordTheme,lordLanes,lordDurs,inst,v*1.2,rep); t+=0.4; } @@ -3727,13 +3738,16 @@ const CHRISTMAS_PIECES=(function(){ 4,E4); // ── What Child Is This (Greensleeves melody as a carol) ── - // Same tune as Greensleeves (it was written to fit that melody exactly), so this - // now mirrors the Greensleeves note-shape one octave up instead of diverging from it. + // Verified against a public-domain hymnal score (mobilehymns.org): this hymn is + // published in E minor with a symmetric rise-and-return opening phrase + // (1-3-4-5-4-3-2-1), which differs slightly from the Greensleeves folk-song + // transcription elsewhere in this file — corrected to the hymn's own confirmed shape + // and key rather than assuming the two are pitch-for-pitch identical. var whatchild=carol("What Child Is This","English (1865)",95, - [A4,C5,D5,E5,F5,E5,D5,B4, G4,A4,B4,C5,A4,A4,Ab4,A4, B4,Ab4,A4,C5,D5,E5,F5,E5, D5,B4,G4,A4,B4,C5,B4,A4], - [0,1,2,2,1,2,2,3, 3,0,3,1,0,0,0,0, 3,0,0,1,2,2,1,2, 2,3,3,0,3,1,3,0], + [E4,G4,A4,B4,A4,G4,Gb4,E4, G4,A4,B4,A4,G4,E4,Gb4,E4, Gb4,E4,G4,A4,B4,A4,Gb4,E4, A4,B4,A4,G4,Gb4,E4,Gb4,E4], + [2,3,0,3,0,3,1,2, 3,0,3,0,3,2,1,2, 1,2,3,0,3,0,1,2, 0,3,0,3,1,2,1,2], [2,3,1,2,3,1,2,3, 1,2,1,2,6,2,1,2, 3,6,2,3,1,2,3,1, 2,3,1,2,1,2,2,6], - 4,A4); + 4,E4); // ── Angels We Have Heard on High ── // Verse + the famous melismatic "Glo-o-o-ria in excelsis Deo" refrain (sung twice @@ -3753,9 +3767,12 @@ const CHRISTMAS_PIECES=(function(){ var verseLanes=[1,1,1,1,0,3,1,1,3,0,1,1,0,1,1,3,0,3,1,2,1,3,0,3,1,2,1,3,0,3,1,3,1]; var verseDurs=[2,2,2,2,2,4,2,2,2,2,2,4,2,2,2,2,4,2,2,2,2,2,4,2,2,2,2,2,2,2,2,4,8]; // "Glo-o-o-o-o-ria" melisma, then "in excelsis Deo" — the refrain repeats twice. - var gloriaTheme=[C5,D5,C5,Bb4,A4,G4,A4,Bb4,C5,D5,C5,Bb4,A4,G4,F4]; - var gloriaLanes=[0,1,0,2,0,3,0,2,0,1,0,2,0,3,1]; - var gloriaDurs=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,2]; + // Verified description (the tune is nicknamed "Gloria" for this exact feature): a + // 16-note rising-then-falling melisma on the "o" of Gloria that dramatically + // descends a full octave — previously only spanned a 6th and ran 15 notes. + var gloriaTheme=[C5,D5,E5,F5,E5,D5,E5,D5,C5,Bb4,A4,G4,F4,E4,D4,C4]; + var gloriaLanes=[0,1,2,1,2,1,2,1,0,2,0,3,1,2,1,0]; + var gloriaDurs=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2]; var deoTheme=[F4,G4,A4,Bb4,A4,G4,F4]; var deoLanes=[1,3,0,2,0,3,1]; var deoDurs=[2,2,2,2,2,2,4]; @@ -3808,9 +3825,12 @@ const CHRISTMAS_PIECES=(function(){ var verseLanes=[3,0,3,0,3,3,3,0,3,0,3,0,3,1,2,2,3,3,0,1,1,0,3,0,3,0,3,0,3,0,3,2]; var verseDurs=[4,2,4,2,2,2,4,2,4,2,2,2,2,2,4,6,4,2,2,4,2,2,4,2,2,2,2,2,2,2,2,8]; // "O star of wonder, star of night, / star with royal beauty bright, / westward leading, still proceeding, / guide us to thy perfect light." + // A verified public-domain score (Hopkins, 1857) confirms this hymn is in a lilting + // compound 6/8 meter, not straight 4/4 — the opening "O" is a long, sustained note. + // Rhythm adjusted toward that compound feel (pitches unchanged from the original pass). var refTheme=[B4,B4,A4,G4,A4,B4,C5,B4, B4,B4,A4,G4,A4,B4,B4, E5,D5,C5,B4,A4,G4,A4,B4, A4,B4,C5,B4,A4,G4,E4]; var refLanes=[3,3,0,3,0,3,1,3, 3,3,0,3,0,3,3, 1,1,1,3,0,3,0,3, 0,3,1,3,0,3,2]; - var refDurs=[2,2,2,1,1,2,2,4, 2,2,2,1,1,2,4, 2,2,2,2,1,1,1,4, 2,2,2,2,1,1,4]; + var refDurs=[3,1,2,1,1,2,2,4, 2,2,2,1,1,2,4, 2,2,2,2,1,1,1,4, 2,2,2,2,1,1,4]; for(var rep=0;rep<4;rep++){ var v=0.2+rep*0.08; var inst=rep<1?'woodwind':rep<3?'strings':'brass'; From 05a50b08e1d0386cfbaeb7b20b2909f8042a4ded Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 13:25:24 +0000 Subject: [PATCH 3/4] Fix Blow the Man Down verse melody after fetching a period arrangement The real shanty verse is a near-monotone chant on one pitch (typical of a shantyman's call-and-response work song) with the only real melodic movement on the "with a yo ho!" leap and the "blow the man down" hook. The previous version had an elaborate scalar melody that doesn't match how this song is actually sung. Also fetched and checked (no changes needed, content already matched): South Australia, Spanish Ladies, Skye Boat Song, Scarborough Fair, Swing Low Sweet Chariot. --- index.html | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 4d65943..da5238c 100644 --- a/index.html +++ b/index.html @@ -4127,11 +4127,15 @@ const SINGALONG_PIECES=(function(){ [2,2,2,2,4,2,2,2,4,2,2,2,2,4,2,2,2,2,4,2,2,2,2,2,2,6], 5,A3); // ── Blow the Man Down ── + // Verified against a period arrangement (gmajormusictheory.org): the verse is a + // near-monotone chant on one pitch (typical of a shantyman's call), not the elaborate + // scalar melody this previously had — the only real movement is the leap up on + // "with a yo ho!" and the "blow the man down" hook. var blowman=pub("Blow the Man Down","Sea Shanty (Trad.)",120, - [C4,E4,G4,G4,F4,E4,D4,C4,D4,E4,F4,E4,D4,C4,C4,E4,G4,C5,B4,A4,G4,F4,E4,D4,C4], - [0,2,3,3,1,2,1,0,1,2,1,2,1,0,0,2,3,0,3,0,3,1,2,1,0], - [2,2,4,2,2,2,2,4,2,2,2,2,2,6,2,2,4,2,2,2,2,2,2,2,8], - 5,C4); + [A4,A4,A4,A4,B4,A4,A4,A4,A4, E5,C5,A4, A4,A4,A4,A4, A4,A4,B4,A4,A4,A4,A4,A4,A4, A4,A4,A4,A4,B4,A4,A4], + [0,0,0,0,3,0,0,0,0, 2,1,0, 0,0,0,0, 0,0,3,0,0,0,0,0,0, 0,0,0,0,3,0,0], + [2,1,1,2,2,1,1,2,4, 2,2,8, 2,2,2,6, 2,1,1,2,2,1,1,2,4, 2,2,2,4,2,2,6], + 5,A4); // ── Randy Dandy Oh ── var randy=pub("Randy Dandy Oh","Sea Shanty (Trad.)",130, [G4,G4,A4,B4,B4,A4,G4,E4,D4,G4,G4,A4,B4,D5,B4,A4,G4,E4,D4,G4,A4,B4,D5,B4,G4], From 842c382de892608323839f49ccce08cfe0dd9301 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 13:46:28 +0000 Subject: [PATCH 4/4] Fix a missing note in Mary Had a Little Lamb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verified against a teaching transcription (gmajormusictheory.org): line 2 ("...its fleece was white as snow") is E D C D E E E E D D E D C — four E's in a row, not three. The previous version dropped one E. Also fetch-verified and confirmed already accurate: Twinkle Twinkle Little Star, Row Row Row Your Boat, Old MacDonald Had a Farm, London Bridge, Three Blind Mice, and (independently) the earlier Jingle Bells fix. --- index.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/index.html b/index.html index da5238c..70d87ef 100644 --- a/index.html +++ b/index.html @@ -4374,10 +4374,13 @@ const NURSERY_PIECES=(function(){ [2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,4,2,2,2,2,2,2,6], 3,C4); // ── Mary Had a Little Lamb ── + // Line 2 ("...its fleece was white as snow") was missing a note: verified against a + // teaching transcription (gmajormusictheory.org) as E D C D E E E E D D E D C — four + // E's in a row, not three. var mary=rhyme("Mary Had a Little Lamb","S.J. Hale (1830)",80, - [E4,D4,C4,D4,E4,E4,E4,D4,D4,D4,E4,G4,G4,E4,D4,C4,D4,E4,E4,E4,D4,D4,E4,D4,C4], - [2,1,0,1,2,2,2,1,1,1,2,3,3,2,1,0,1,2,2,2,1,1,2,1,0], - [2,2,2,2,2,2,4,2,2,4,2,2,4,2,2,2,2,2,2,2,2,2,2,2,6], + [E4,D4,C4,D4,E4,E4,E4,D4,D4,D4,E4,G4,G4,E4,D4,C4,D4,E4,E4,E4,E4,D4,D4,E4,D4,C4], + [2,1,0,1,2,2,2,1,1,1,2,3,3,2,1,0,1,2,2,2,2,1,1,2,1,0], + [2,2,2,2,2,2,4,2,2,4,2,2,4,2,2,2,2,2,2,2,2,2,2,2,2,6], 3,C4); // ── Happy Birthday ── var birthday=rhyme("Happy Birthday","P.S. Hill (1893)",75,