diff --git a/CLAUDE.md b/CLAUDE.md index 895be65..efd7afb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -159,7 +159,6 @@ Add a new genre called **"Classical"** with the following pieces. Each piece nee |-------|----------|-------| | Beethoven's 5th (Opening) | Beethoven | DA DA DA DUM — 3 same pad + 1 different | | Hall of the Mountain King | Grieg | Starts slow, accelerates — great difficulty curve | -| O Fortuna | Orff | Heavy rhythmic hits, powerful | | Ride of the Valkyries | Wagner | Galloping rhythm pattern | | Mars, Bringer of War | Holst | Heavy 5/4 march | | Toccata & Fugue in D Minor | Bach | Famous DUN DUN DUN opener | @@ -168,13 +167,14 @@ Add a new genre called **"Classical"** with the following pieces. Each piece nee | Also Sprach Zarathustra | Strauss | DA DAAAA DA DUM (2001 theme) | | Barber of Seville Overture | Rossini | Bugs Bunny classic | | The Blue Danube | Strauss Jr. | Waltz rhythm | -| Sabre Dance | Khachaturian | Very fast and fun | | Night on Bald Mountain | Mussorgsky | Fantasia — dark and dramatic | | Sorcerer's Apprentice | Dukas | Fantasia — Mickey Mouse | | Swan Lake (Theme) | Tchaikovsky | Elegant waltz | | Morning Mood | Grieg | Peer Gynt — gentle build | | In the Hall of the Mountain King | Grieg | (same as above, confirm not duplicate) | +> **Not actually public domain — do not re-add:** O Fortuna (Orff, 1936; composer d. 1982 — still under copyright until 2032 in the US / 2052 in the EU) and Sabre Dance (Khachaturian, 1942; composer d. 1978 — still under copyright until 2048 in the EU) were removed from the repo on this basis. The rest of this table is genuinely public domain (composers who died before ~1955, or works published before 1930). + #### How Classical Mode Should Work 1. Player selects a classical piece 2. Game starts with countdown diff --git a/README.md b/README.md index 2f1878e..08680a5 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Works with **keyboard**, **Wii Rock Band drums**, **Xbox/PS Rock Band drums**, * ## Features - **18 Genres** across two modes: synth orchestra songs + drum beat patterns -- **124 synth pieces** with full synthesized orchestra background +- **119 synth pieces** with full synthesized orchestra background - **120 drum patterns** across 8 genres - **Note density toggle** — switch between Full and Simple (fewer notes for beginners) - **Drums or Orchestra mode** — choose whether pad hits play drum sounds or the actual melody note @@ -82,7 +82,7 @@ Works with **keyboard**, **Wii Rock Band drums**, **Xbox/PS Rock Band drums**, * - Scarborough Fair (English Medieval) - My Bonnie Lies Over the Ocean (Scottish, 1881) -### Christmas (20 songs) +### Christmas (17 songs) - Jingle Bells (1857) - Silent Night (1818) - Deck the Halls (1862) @@ -98,9 +98,6 @@ Works with **keyboard**, **Wii Rock Band drums**, **Xbox/PS Rock Band drums**, * - What Child Is This (English, 1865) - Angels We Have Heard on High (French, 1862) - O Holy Night (A. Adam, 1847) -- Rudolph the Red-Nosed Reindeer (J. Marks, 1949) -- Frosty the Snowman (S. Nelson, 1950) -- Winter Wonderland (F. Bernard, 1934) - Good King Wenceslas (Finnish, 1582) - We Three Kings (J.H. Hopkins Jr., 1857) @@ -144,10 +141,9 @@ Works with **keyboard**, **Wii Rock Band drums**, **Xbox/PS Rock Band drums**, * - The Cascades (Scott Joplin, 1904) - Pineapple Rag (Scott Joplin, 1908) -### Classical (26 pieces) +### Classical (24 pieces) - Beethoven's 5th (Opening) - Hall of the Mountain King (Grieg) -- O Fortuna (Orff) - Ride of the Valkyries (Wagner) — Apocalypse Now - Mars, Bringer of War (Holst) - Toccata & Fugue in D Minor (Bach) @@ -156,7 +152,6 @@ Works with **keyboard**, **Wii Rock Band drums**, **Xbox/PS Rock Band drums**, * - Also Sprach Zarathustra (R. Strauss) — 2001: A Space Odyssey - Barber of Seville Overture (Rossini) — Bugs Bunny - The Blue Danube (J. Strauss II) — 2001: A Space Odyssey -- Sabre Dance (Khachaturian) - Night on Bald Mountain (Mussorgsky) — Fantasia - Sorcerer's Apprentice (Dukas) — Fantasia - Swan Lake Theme (Tchaikovsky) diff --git a/index.html b/index.html index 339e57e..9b31a7a 100644 --- a/index.html +++ b/index.html @@ -1065,322 +1065,6 @@ const CLASSICAL_PIECES=(function(){ return {n:"Hall of the Mountain King",composer:"Grieg",bpm:120,duration:Math.ceil(t+2.5),isClassical:true,bg:bg,melody:mel}; })(); - // ── O Fortuna (Carmina Burana) ── - // ~90 seconds, conductor style with continuous harmonic bed, SATB choir, tutti hits - // D minor, 3/4 time. Lead-sheet structure with tempo changes throughout. - var ofort=(function(){ - var bg=[],mel=[],t=0; - - // === HELPERS === - // Full orchestral hit (strings + brass + bass) - function tutti(time,freq,dur,v){ - bg.push({t:time,f:freq,d:dur,i:'strings',v:v}); - bg.push({t:time,f:freq,d:dur,i:'brass',v:v*0.6}); - bg.push({t:time,f:freq*0.75,d:dur,i:'strings',v:v*0.35}); - if(freq>200)bg.push({t:time,f:freq/2,d:dur,i:'bass',v:v*0.5}); - } - // SATB choir voicing (soprano + alto + tenor) - function choir4(time,sop,alt,ten,dur,v){ - bg.push({t:time,f:sop,d:dur,i:'choir',v:v}); - bg.push({t:time,f:alt,d:dur,i:'choir',v:v*0.85}); - bg.push({t:time,f:ten,d:dur,i:'choir',v:v*0.7}); - } - // Simple choir unison/octave - function choir1(time,freq,dur,v){ - bg.push({t:time,f:freq,d:dur,i:'choir',v:v}); - bg.push({t:time,f:freq/2,d:dur*0.9,i:'choir',v:v*0.5}); - } - // Timpani hit - function timp(time,v){bg.push({t:time,f:D3,d:0.5,i:'timpani',v:v||0.5});} - - // === CONTINUOUS HARMONIC BED (sustained string chords throughout) === - var harmony=[ - [0,6,[D4,F4,A4],0.18], // Dm - opening ff - [6,18,[D4,F4,A4],0.1], // Dm - pp soft verse - [18,30,[D4,F4,A4],0.1], // Dm - pp continued - [30,42,[G3,Bb3,D4],0.14], // Gm - building mp - [42,54,[D4,F4,A4],0.18], // Dm - dramatic - [54,64,[A3,D4,F4],0.2], // Dm inv - forte return - [64,76,[D4,F4,A4],0.25], // Dm - ff marcato - [76,88,[D4,F4,A4],0.3], // Dm - fff climax - [88,95,[D4,F4,A4],0.25] // Dm - finale - ]; - harmony.forEach(function(h){ - for(var ht=h[0];ht0.15)bg.push({t:ht,f:h[2][1],d:1.7,i:'woodwind',v:h[3]*0.4}); - } - }); - - // === SECTION 1 (0-6s): "O Fortuna" — ff, half=60, bold opening === - // 3/4 time, half note = 60 → quarter = 0.5s - var q1=0.5; - // "O For-tu-na, ve-lut Lu-na, sta-tu va-ri-a-bi-lis" - // Big unison D, then choral declamation - var s1notes=[D4,D4,D4,D4, A3,A3,Bb3,Bb3, A3,A3,G3,A3]; - var s1durs= [q1,q1,q1,q1*2, q1,q1*2,q1,q1*2, q1,q1,q1,q1*2]; - var s1lanes=[0,0,0,0, 1,1,2,2, 1,1,3,1]; - t=0; - s1notes.forEach(function(f,i){ - choir4(t,f,f>A3?D4:f,f>C4?A3:f*0.75,s1durs[i]*0.9,0.55); - tutti(t,f,s1durs[i]*0.85,0.5); - if(s1durs[i]>=q1*2)timp(t,0.55); - mel.push({t:t,l:s1lanes[i]}); - t+=s1durs[i]; - }); - - // === SECTION 2 (6-18s): "semper crescis aut decrescis" — pp, half=132, soft pairs === - // half=132 → quarter = ~0.227s - var q2=0.227; - t=6.5; - // Running strings background texture (not hittable) - for(var ri=0;ri<50;ri++){ - var rf=[D4,F4,A4,F4,D4,E4,F4,G4,A4,G4,F4,E4,D4,C4,Bb3,A3][ri%16]; - bg.push({t:t+ri*q2,f:rf,d:q2*0.8,i:'strings',v:0.12}); - } - // Soft choral pairs — only accents are hittable - // "sem-per cres-cis aut de-cres-cis" - var s2notes=[D4,E4, F4,E4, D4,C4, D4,D4]; - var s2durs= [q2*2,q2*2, q2*2,q2*2, q2*2,q2*2, q2*2,q2*4]; - var s2lanes=[0,1, 2,1, 0,3, 0,0]; - s2notes.forEach(function(f,i){ - choir1(t,f,s2durs[i]*0.9,0.3); - bg.push({t:t,f:f,d:s2durs[i]*0.85,i:'woodwind',v:0.18}); - mel.push({t:t,l:s2lanes[i]}); - t+=s2durs[i]; - }); - // "vi-ta de-tes-ta-bi-lis" - t+=q2; - var s2b=[A3,Bb3,A3,G3,A3,Bb3,C4,D4]; - var s2bd=[q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*4]; - var s2bl=[1,2,1,3,1,2,0,0]; - s2b.forEach(function(f,i){ - choir1(t,f,s2bd[i]*0.9,0.3); - bg.push({t:t,f:f,d:s2bd[i]*0.85,i:'woodwind',v:0.18}); - mel.push({t:t,l:s2bl[i]}); - t+=s2bd[i]; - }); - - // === SECTION 3 (18-30s): "nunc obdurat et tunc curat" — pp, same tempo === - t=18.5; - // Running string texture - for(var ri2=0;ri2<52;ri2++){ - var rf2=[A3,C4,D4,F4,E4,D4,C4,Bb3,A3,G3,A3,Bb3,C4,D4,E4,F4][ri2%16]; - bg.push({t:t+ri2*q2,f:rf2,d:q2*0.8,i:'strings',v:0.13}); - } - // "nunc ob-du-rat et tunc cu-rat" - var s3a=[D4,D4,E4,F4,E4,D4,C4,D4]; - var s3ad=[q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*4]; - var s3al=[0,0,1,2,1,0,3,0]; - s3a.forEach(function(f,i){ - choir1(t,f,s3ad[i]*0.9,0.32); - bg.push({t:t,f:f,d:s3ad[i]*0.85,i:'woodwind',v:0.2}); - mel.push({t:t,l:s3al[i]}); - t+=s3ad[i]; - }); - // "lu-do men-tis a-ci-em" - t+=q2; - var s3b=[A3,Bb3,C4,Bb3,A3,G3,A3]; - var s3bd=[q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*4]; - var s3bl=[1,2,0,2,1,3,1]; - s3b.forEach(function(f,i){ - choir1(t,f,s3bd[i]*0.9,0.32); - mel.push({t:t,l:s3bl[i]}); - t+=s3bd[i]; - }); - - // === SECTION 4 (30-42s): "egestatem potestatem" — building mp === - t=30.5; - // Strings now more active - for(var ri3=0;ri3<52;ri3++){ - var rf3=[D4,F4,A4,D5,A4,F4,D4,F4,G4,Bb4,G4,F4,E4,D4,C4,Bb3][ri3%16]; - bg.push({t:t+ri3*q2,f:rf3,d:q2*0.8,i:'strings',v:0.18}); - } - // "e-ges-ta-tem po-tes-ta-tem" - var s4a=[D4,E4,F4,G4,A4,G4,F4,E4]; - var s4ad=[q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*4]; - var s4al=[0,1,2,3,0,3,2,1]; - s4a.forEach(function(f,i){ - choir4(t,f,f>D4?D4:f,f>C4?A3:f*0.75,s4ad[i]*0.9,0.4); - bg.push({t:t,f:f,d:s4ad[i]*0.85,i:'brass',v:0.15}); - if(i%4===0)timp(t,0.35); - mel.push({t:t,l:s4al[i]}); - t+=s4ad[i]; - }); - // "dis-sol-vit ut gla-ci-em" - t+=q2; - var s4b=[F4,E4,D4,C4,D4,E4,D4]; - var s4bd=[q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*4]; - var s4bl=[2,1,0,3,0,1,0]; - s4b.forEach(function(f,i){ - choir4(t,f,D4,A3,s4bd[i]*0.9,0.42); - bg.push({t:t,f:f/2,d:s4bd[i]*0.85,i:'bass',v:0.25}); - if(s4bd[i]>=q2*4)timp(t,0.4); - mel.push({t:t,l:s4bl[i]}); - t+=s4bd[i]; - }); - - // === SECTION 5 (42-54s): "Sors immanis et inanis" — dramatic === - t=42.5; - // Running strings more intense - for(var ri4=0;ri4<52;ri4++){ - var rf4=[D4,A4,F4,D4,G4,Bb4,G4,D4,A4,D5,A4,F4,E4,D4,C4,D4][ri4%16]; - bg.push({t:t+ri4*q2,f:rf4,d:q2*0.8,i:'strings',v:0.22}); - } - // "Sors im-ma-nis et in-a-nis" - var s5a=[A4,A4,G4,F4,E4,F4,G4,A4]; - var s5ad=[q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*4]; - var s5al=[0,0,3,2,1,2,3,0]; - s5a.forEach(function(f,i){ - choir4(t,f,D4,A3,s5ad[i]*0.9,0.5); - tutti(t,f,s5ad[i]*0.85,0.3); - if(i%2===0)timp(t,0.45); - mel.push({t:t,l:s5al[i]}); - t+=s5ad[i]; - }); - // "ro-ta tu vo-lu-bi-lis" - t+=q2; - var s5b=[D5,C5,Bb4,A4,G4,F4,E4,D4]; - var s5bd=[q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*4]; - var s5bl=[4,0,2,1,3,2,1,0]; - s5b.forEach(function(f,i){ - choir4(t,f,F4,D4,s5bd[i]*0.9,0.52); - tutti(t,f,s5bd[i]*0.85,0.32); - if(i===0||i===4)timp(t,0.5); - mel.push({t:t,l:s5bl[i]}); - t+=s5bd[i]; - }); - - // === SECTION 6 (54-64s): More verses — "status malus" continuing pattern === - t=54.5; - for(var ri5=0;ri5<44;ri5++){ - var rf5=[D4,F4,A4,D5,C5,Bb4,A4,G4,F4,E4,D4,C4,Bb3,A3,C4,D4][ri5%16]; - bg.push({t:t+ri5*q2,f:rf5,d:q2*0.8,i:'strings',v:0.2}); - } - // Rising phrase "ve-rum est quod le-gi-tur" - var s6a=[D4,F4,A4,Bb4,A4,G4,F4,G4,A4,Bb4,C5,D5]; - var s6ad=[q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*2,q2*4]; - var s6al=[0,2,0,2,1,3,2,3,1,2,0,4]; - s6a.forEach(function(f,i){ - choir4(t,f,f>D4?D4:f,A3,s6ad[i]*0.9,0.48); - bg.push({t:t,f:f,d:s6ad[i]*0.85,i:'brass',v:0.22}); - bg.push({t:t,f:f/2,d:s6ad[i]*0.85,i:'bass',v:0.3}); - if(i%3===0)timp(t,0.42); - mel.push({t:t,l:s6al[i]}); - t+=s6ad[i]; - }); - - // === SECTION 7 (64-76s): "Sors salutis et virtutis" — f, half=144, marcato === - // half=144 → quarter = ~0.208s - var q3=0.208; - t=64.5; - // Driving string ostinato - for(var ri6=0;ri6<56;ri6++){ - var rf6=[D4,A4,D4,A4,F4,A4,F4,A4][ri6%8]; - bg.push({t:t+ri6*q3,f:rf6,d:q3*0.75,i:'strings',v:0.25}); - } - // Marcato choral accents - // "Sors sa-lu-tis et vir-tu-tis mi-chi nunc con-tra-ri-a" - var s7a=[D4,D4,E4,F4, E4,D4,C4,D4, A4,G4,F4,E4, D4,E4,F4,D4]; - var s7ad=[q3*2,q3*2,q3*2,q3*2, q3*2,q3*2,q3*2,q3*4, q3*2,q3*2,q3*2,q3*2, q3*2,q3*2,q3*2,q3*4]; - var s7al=[0,0,1,2, 1,0,3,0, 0,3,2,1, 0,1,2,4]; - s7a.forEach(function(f,i){ - choir4(t,f,f>D4?D4:f,f>C4?A3:D3,s7ad[i]*0.85,0.55); - tutti(t,f,s7ad[i]*0.8,0.45); - if(i%4===0)timp(t,0.5); - mel.push({t:t,l:s7al[i]}); - t+=s7ad[i]; - }); - // "est af-fec-tus et de-fec-tus" - t+=q3; - var s7b=[A4,Bb4,A4,G4,F4,G4,A4,D4]; - var s7bd=[q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*4]; - var s7bl=[0,2,1,3,2,3,1,4]; - s7b.forEach(function(f,i){ - choir4(t,f,D4,A3,s7bd[i]*0.85,0.58); - tutti(t,f,s7bd[i]*0.8,0.48); - if(i%2===0)timp(t,0.52); - mel.push({t:t,l:s7bl[i]}); - t+=s7bd[i]; - }); - - // === SECTION 8 (76-88s): "Hac in hora sine mora" — ff, climax === - // "corde pulsum tangite; quod per sortem sternit fortem mecum omnes plangite!" - t=76.5; - // Furious string tremolo - for(var ri7=0;ri7<60;ri7++){ - var rf7=[D4,F4,A4,D5,A4,F4,D4,F4,A4,D5,F5,D5,A4,F4,D4,A3][ri7%16]; - bg.push({t:t+ri7*q3,f:rf7,d:q3*0.7,i:'strings',v:0.3}); - if(ri7%4===0)bg.push({t:t+ri7*q3,f:rf7*0.5,d:q3*2,i:'bass',v:0.25}); - } - // "Hac in ho-ra si-ne mo-ra cor-de pul-sum tan-gi-te" - var s8a=[D5,D5,C5,Bb4,A4,G4,A4,Bb4,A4,G4,F4,E4,D4]; - var s8ad=[q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*4]; - var s8al=[4,4,0,2,1,3,1,2,1,3,2,1,0]; - s8a.forEach(function(f,i){ - choir4(t,f,f>D4?F4:f,f>C4?D4:A3,s8ad[i]*0.85,0.65); - tutti(t,f,s8ad[i]*0.8,0.55); - timp(t,0.55); - mel.push({t:t,l:s8al[i]}); - t+=s8ad[i]; - }); - // "quod per sor-tem ster-nit for-tem" - t+=q3; - var s8b=[A4,Bb4,C5,D5,C5,Bb4,A4,G4]; - var s8bd=[q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*2,q3*4]; - var s8bl=[1,2,0,4,0,2,1,3]; - s8b.forEach(function(f,i){ - choir4(t,f,D4,A3,s8bd[i]*0.85,0.68); - tutti(t,f,s8bd[i]*0.8,0.58); - timp(t,0.58); - mel.push({t:t,l:s8bl[i]}); - t+=s8bd[i]; - }); - // "me-cum om-nes plan-gi-te!" - t+=q3; - var s8c=[A4,A4,Bb4,A4,D5,D5,D4]; - var s8cd=[q3*2,q3*2,q3*2,q3*2,q3*3,q3*3,q3*6]; - var s8cl=[0,1,2,1,4,4,0]; - s8c.forEach(function(f,i){ - choir4(t,f,f>D4?F4:f,f>C4?D4:A3,s8cd[i]*0.85,0.72); - tutti(t,f,s8cd[i]*0.8,0.62); - timp(t,0.62); - mel.push({t:t,l:s8cl[i]}); - t+=s8cd[i]; - }); - - // === SECTION 9 (88-95s): Final sustained chords — fff, half=160 === - t=88.5; - // Massive repeated D minor chords - var finQ=0.4; - for(var fc=0;fc<8;fc++){ - var ft=t+fc*finQ; - [D4,F4,A4,D5].forEach(function(f){ - bg.push({t:ft,f:f,d:finQ*0.85,i:'choir',v:0.7}); - bg.push({t:ft,f:f,d:finQ*0.85,i:'brass',v:0.6}); - bg.push({t:ft,f:f,d:finQ*0.85,i:'strings',v:0.55}); - }); - bg.push({t:ft,f:D3,d:finQ*0.85,i:'bass',v:0.55}); - timp(ft,0.65); - mel.push({t:ft,l:4}); - } - // Final sustained Dm chord - t=t+8*finQ+0.3; - [D4,F4,A4,D5].forEach(function(f){ - bg.push({t:t,f:f,d:4.0,i:'choir',v:0.65}); - bg.push({t:t,f:f,d:4.0,i:'brass',v:0.55}); - bg.push({t:t,f:f,d:4.0,i:'strings',v:0.5}); - }); - bg.push({t:t,f:D3,d:3.5,i:'bass',v:0.55}); - bg.push({t:t,f:D3,d:3.0,i:'timpani',v:0.6}); - mel.push({t:t,l:4}); - - return {n:"O Fortuna",composer:"Orff",bpm:120,duration:Math.ceil(t+4.5),isClassical:true,bg:bg,melody:mel}; - })(); - // Theme-variation helper: repeats a theme across passes with growing intensity function tp(name,comp,bpm,th,ln,passes,br){ var bg=[],mel=[],t=0,root=th[0]; @@ -2011,110 +1695,6 @@ const CLASSICAL_PIECES=(function(){ return {n:"Barber of Seville Overture",composer:"Rossini",bpm:144,duration:Math.ceil(t+3),isClassical:true,bg:bg,melody:mel}; })(); - // ── Sabre Dance ── - // Khachaturian's frenetic Sabre Dance in D minor, ~75s - // Famous for its relentless, driving ostinato - var sabre=(function(){ - var bg=[],mel=[],t=0,q=60/168; - function str(t,f,d,v){bg.push({t:t,f:f,d:d,i:'strings',v:v||0.4});} - function brs(t,f,d,v){bg.push({t:t,f:f,d:d,i:'brass',v:v||0.4});} - function tutti(t,f,d,v){str(t,f,d,v);brs(t,f,d,(v||0.4)*0.6);bg.push({t:t,f:f/2,d:d,i:'bass',v:(v||0.4)*0.4});} - - // Harmonic bed - var harm=[ - [0,15,[D3,A3,D4],0.1],[15,30,[D3,A3,D4],0.15],[30,50,[D3,F3,A3],0.18], - [50,65,[D3,A3,D4],0.2],[65,80,[D3,A3,D4],0.25] - ]; - harm.forEach(function(h){ - for(var ht=h[0];ht=3)brs(t,n[0],n[1]*0.7,ov*0.5); - mel.push({t:t,l:n[2]});t+=n[1]; - }); - // Ascending burst: D-E-F-G-A - [D4,E4,F4,G4,A4].forEach(function(f,i){ - str(t,f,q*0.4,ov);mel.push({t:t,l:[0,2,3,0,1][i]});t+=q*0.5; - }); - bg.push({t:t,f:D3,d:0.2,i:'timpani',v:ov*0.6});mel.push({t:t,l:4});t+=q; - } - - // === SECTION 2 (15-30s): Contrasting lyrical middle section === - // Slower, sweeping melody in strings over sustained chords - var lyric=[[A4,q*2,1],[G4,q,0],[F4,q,3],[E4,q*2,2],[D4,q,0], - [F4,q*2,3],[E4,q,2],[D4,q,0],[A3,q*2,1],[D4,q*3,0]]; - for(var lr=0;lr<3;lr++){ - var lv=0.35+lr*0.08; - lyric.forEach(function(n){ - str(t,n[0],n[1]*0.9,lv); - if(lr>0)brs(t,n[0],n[1]*0.9,lv*0.5); - if(lr>1)bg.push({t:t,f:n[0]/2,d:n[1]*0.9,i:'bass',v:lv*0.4}); - mel.push({t:t,l:n[2]});t+=n[1]; - }); - if(lr>0){bg.push({t:t,f:D3,d:0.3,i:'timpani',v:lv*0.5});mel.push({t:t,l:4});t+=q;} - t+=q; - } - - // === SECTION 3 (30-50s): Ostinato returns — faster, louder === - var fastOst=[[D4,q*0.4,0],[D4,q*0.4,0],[D4,q*0.4,0],[Eb4,q*0.4,1],[D4,q*0.4,0], - [D4,q*0.4,0],[Eb4,q*0.4,1],[F4,q*0.4,3]]; - for(var fo=0;fo<6;fo++){ - var fv=0.45+fo*0.04; - fastOst.forEach(function(n){ - tutti(t,n[0],n[1]*0.7,fv); - mel.push({t:t,l:n[2]});t+=n[1]; - }); - // Ascending chromatic burst - [D4,Eb4,E4,F4,G4,Ab4,A4,Bb4].forEach(function(f,i){ - str(t,f,q*0.35,fv);brs(t,f,q*0.35,fv*0.5); - mel.push({t:t,l:[0,1,2,3,0,1,1,2][i]});t+=q*0.4; - }); - // Slam - [D4,A4,D5].forEach(function(f){brs(t,f,0.3,fv);}); - bg.push({t:t,f:D3,d:0.3,i:'timpani',v:fv*0.7});mel.push({t:t,l:4});t+=q; - } - - // === SECTION 4 (50-65s): Wild descending runs + ostinato === - var desc=[A4,G4,F4,E4,D4,E4,F4,G4,A4,Bb4,A4,G4,F4,E4,D4,A3]; - var dLn=[1,0,3,2,0,2,3,0,1,2,1,0,3,2,0,4]; - for(var dr=0;dr<3;dr++){ - var dv=0.55+dr*0.05; - var dq=q*(0.45-dr*0.04); - desc.forEach(function(f,i){ - tutti(t,f,dq*0.8,dv); - if(dr>0)bg.push({t:t,f:f,d:dq*0.8,i:'brass',v:dv*0.5}); - if(dr>1&&i%4===0)bg.push({t:t,f:D3,d:0.15,i:'timpani',v:dv*0.6}); - mel.push({t:t,l:dLn[i]});t+=dq; - }); - t+=q*0.5; - // Ostinato fragment - fastOst.forEach(function(n){ - tutti(t,n[0],n[1]*0.65,dv);mel.push({t:t,l:n[2]});t+=n[1]*0.85; - }); - t+=q*0.5; - } - - // === FINALE: Hammered D minor chords === - for(var c=0;c<8;c++){ - [D3,A3,D4,F4,A4].forEach(function(f){brs(t,f,0.3,0.65);str(t,f,0.3,0.55);}); - bg.push({t:t,f:D3/2,d:0.3,i:'timpani',v:0.65});mel.push({t:t,l:4});t+=0.38; - } - [D3,A3,D4,F4,A4,D5].forEach(function(f){brs(t,f,2.5,0.7);str(t,f,2.5,0.6);}); - bg.push({t:t,f:D3/2,d:2.0,i:'timpani',v:0.75});mel.push({t:t,l:4}); - - return {n:"Sabre Dance",composer:"Khachaturian",bpm:168,duration:Math.ceil(t+3),isClassical:true,bg:bg,melody:mel}; - })(); - // ── Sorcerer's Apprentice ── // Dukas's magical march in F minor, ~80s // Famous bassoon theme → march builds → magical chaos @@ -3548,7 +3128,7 @@ const CLASSICAL_PIECES=(function(){ return {n:"William Tell Overture (Storm)",composer:"Rossini",bpm:132,duration:Math.ceil(t+3),isClassical:true,bg:bg,melody:mel}; })(); - return [b5,hmk,ofort,valk,mars,toccata,tell,bolero,zarath,barber,danube,sabre,bald,sorcerer,swan,morning,bumblebee,sugarplum,overture1812,habanera,spring,furelise,canon,hungarian,odeToJoy,tellStorm]; + return [b5,hmk,valk,mars,toccata,tell,bolero,zarath,barber,danube,bald,sorcerer,swan,morning,bumblebee,sugarplum,overture1812,habanera,spring,furelise,canon,hungarian,odeToJoy,tellStorm]; })(); // ── VIDEO GAMES (public domain pieces associated with games) ── @@ -3893,7 +3473,9 @@ const CHRISTMAS_PIECES=(function(){ var jingle=carol("Jingle Bells","J. Pierpont (1857)",140, [E4,E4,E4,E4,E4,E4,E4,G4,C4,D4,E4,F4,F4,F4,F4,F4,E4,E4,E4,E4,D4,D4,E4,D4,G4,E4,E4,E4,E4,E4,E4,E4,G4,C4,D4,E4,F4,F4,F4,F4,F4,E4,E4,G4,G4,F4,D4,C4], [2,2,2,2,2,2,2,3,0,1,2,1,1,1,1,1,2,2,2,2,1,1,2,1,3,2,2,2,2,2,2,2,3,0,1,2,1,1,1,1,1,2,2,3,3,1,1,0], - [1,1,2,1,1,2,1,1,1,1,6,2,2,2,1,1,2,2,1,1,2,2,2,2,6,1,1,2,1,1,2,1,1,1,1,6,2,1,1,1,2,1,1,2,2,2,2,6], + // Standard quarter/half-note rhythm: "Jingle bells(q q h), jingle bells(q q h), jingle all the way(q q q q), (whole)" + // "Oh what fun it is(q q q q q), to ride in a(q q q e e), one horse open(q q q q), sleigh(whole)" — repeated, second ending resolves to tonic C + [2,2,4,2,2,4,2,2,2,2,8, 2,2,2,2,2,2,2,1,1,2,2,2,2,8, 2,2,4,2,2,4,2,2,2,2,8, 2,2,2,2,2,2,2,1,1,2,2,4], 3,C4); var silent=carol("Silent Night","F. Gruber (1818)",72, [G4,A4,G4,E4,G4,A4,G4,E4,D5,D5,B4,C5,C5,G4,A4,A4,C5,B4,A4,G4,A4,G4,E4,A4,A4,C5,B4,A4,G4,A4,G4,E4,D5,D5,F5,D5,B4,C5,E5,C5,G4,E4,G4,F4,D4,C4], @@ -3979,27 +3561,6 @@ const CHRISTMAS_PIECES=(function(){ [2,3,1,4,1,3,1,3,1,3,1, 2,3,1,4,1,3,1,3,1,4, 2,3,1,3,1,2,2,3,1,4], 3,F4); - // ── Rudolph the Red-Nosed Reindeer (in C major) ── - var rudolph=carol("Rudolph the Red-Nosed Reindeer","J. Marks (1949)",130, - [G4,A4,G4,E4,C5,A4,G4,G4,A4,G4,A4,G4,C5,B4,F4,A4,G4,F4,D4,E4,F4,D4,G4,A4,G4,E4,C5,A4,G4,G4,A4,G4,A4,G4,A4,D5,C5], - [3,0,3,2,0,0,3,3,0,3,0,3,0,3,1,0,3,1,1,2,1,1,3,0,3,2,0,0,3,3,0,3,0,3,0,1,0], - [2,2,2,2,4,2,4,2,2,2,2,2,4,6,2,2,2,2,2,2,2,6,2,2,2,2,4,2,4,2,2,2,2,2,2,2,8], - 3,C4); - - // ── Frosty the Snowman (in C major) ── - var frosty=carol("Frosty the Snowman","S. Nelson (1950)",125, - [G4,E4,F4,G4,C5,B4,A4,G4,A4,G4,F4,E4,F4,A4,G4,F4,E4,D4,C4,C4,G4,E4,F4,G4,C5,B4,A4,G4,A4,G4,F4,E4,D4,C4], - [3,2,1,3,0,3,0,3,0,3,1,2,1,0,3,1,2,1,0,0,3,2,1,3,0,3,0,3,0,3,1,2,1,0], - [2,2,2,4,2,2,2,2,2,2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,2,2,2,2,2,2,2,2,2,8], - 3,C4); - - // ── Winter Wonderland (in C major) ── - var winter=carol("Winter Wonderland","F. Bernard (1934)",120, - [E4,F4,G4,G4,A4,G4,F4,E4,D4,E4,F4,F4,G4,F4,E4,D4,C4,E4,F4,G4,G4,A4,G4,F4,E4,D4,E4,F4,F4,G4,F4,E4,D4,C4], - [2,1,3,3,0,3,1,2,1,2,1,1,3,1,2,1,0,2,1,3,3,0,3,1,2,1,2,1,1,3,1,2,1,0], - [2,2,4,2,2,2,2,2,2,2,4,2,2,2,2,2,6,2,2,4,2,2,2,2,2,2,2,4,2,2,2,2,2,8], - 3,C4); - // ── Good King Wenceslas (in F major) ── var wenceslas=carol("Good King Wenceslas","Finnish (1582)",110, [F4,F4,F4,G4,F4,F4,C4,D4,E4,F4,F4,G4,F4,F4,C4,C5,Bb4,A4,G4,A4,Bb4,A4,G4,F4,G4,A4,Bb4,C5,Bb4,A4,G4,F4], @@ -4014,7 +3575,7 @@ const CHRISTMAS_PIECES=(function(){ [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], 4,E4); - return [jingle,silent,deck,wish,ocometree,firstnoel,joy,away,twelve,hark,ocome,godrest,whatchild,angels,oholynight,rudolph,frosty,winter,wenceslas,threekings]; + return [jingle,silent,deck,wish,ocometree,firstnoel,joy,away,twelve,hark,ocome,godrest,whatchild,angels,oholynight,wenceslas,threekings]; })(); // ── SINGALONG (campfire, sea shanties, pub songs) ── @@ -4063,9 +3624,10 @@ const SINGALONG_PIECES=(function(){ // Add bass + chord backing if(pass>0){ var ct=t; - // Am chord backing per measure (8 measures per verse+chorus) - var chords=[[A3,C4,E4],[A3,C4,E4],[G3,B3,D4],[G3,B3,D4], + // Am chord backing per measure — verse (mm1-8) and chorus (mm9-16) share the same progression + var versechords=[[A3,C4,E4],[A3,C4,E4],[G3,B3,D4],[G3,B3,D4], [A3,C4,E4],[A3,C4,E4],[C4,E4,G4],[D4,F4,A4]]; + var chords=versechords.concat(versechords); chords.forEach(function(ch,ci){ ch.forEach(function(f){bg.push({t:ct+ci*q*4,f:f,d:q*3.5,i:'strings',v:v*0.3});}); bg.push({t:ct+ci*q*4,f:ch[0]/2,d:q*3.5,i:'bass',v:v*0.35}); @@ -4118,7 +3680,7 @@ const SINGALONG_PIECES=(function(){ note(G4,q,3,inst,v*1.2); note(E4,q,2,inst,v*1.2); note(D4,q*2,1,inst,v*1.2); note(D4,q*2,1,inst,v*1.2); - t+=q; // small gap between passes + t+=0.3; // small gap between passes — off the beat grid so it doesn't insert a stray beat into the 4/4 pulse } // Finale chord [A3,C4,E4,A4].forEach(function(f){bg.push({t:t,f:f,d:2.5,i:'brass',v:0.55});bg.push({t:t,f:f,d:2.5,i:'strings',v:0.4});}); @@ -4691,7 +4253,7 @@ function buildClassicalNotes(piece){ // Check for saved melody edits var saved=edLoadSaved(piece.n); var melody=saved?saved.melody:piece.melody; - return melody.filter(function(m){return activePads[m.l];}) + var raw=melody.filter(function(m){return activePads[m.l];}) .map(function(m){ var freq=261.63; for(var i=0;i