フレーズが戻り、聞き覚えがあると気づきます。対照的な部分が入れば、その回帰を少し長く待ちます。後には、冒頭が楽器を増やして戻るかもしれません。一音程や一拍より大きな時間の関係です。
形式は、反復、変奏、対照を通して部分がどう組織されるかに関わります。 最終回では少数の素材を並べ替え、旋律の変化とテクスチュアの変化を区別します。十〜十五分ほど進めたら、シリーズ全体の方法を知っている録音に使ってみましょう。
四小節を並べて、違いを説明する
A は E–G–A–G、B は C–B–G–D、A′ は A の最後の G だけを高い C に変えたものです。各小節は 4/4、四分音符四つ、100 BPM。最初の配置は A–A–B–A です。
小節を選んで素材を変えます。順序だけなら A 三つと B 一つを保ち、A–B–A–A にしましょう。次は A′ を自由に加えます。回帰がいつ聞こえるかを予想して全体を聴き、一小節ずつ読んで試聴することもできます。
図を準備しています
自分で素材を並べるA は E–G–A–G、A′ は末尾 G を C に変更、B は C–B–G–D。各小節は四分音符四つで、素材の変更・一小節・全体の試聴ができます。
{"id":"music-form-workshop","title":"自分で素材を並べる","summary":"A は E–G–A–G、A′ は末尾 G を C に変更、B は C–B–G–D。各小節は四分音符四つで、素材の変更・一小節・全体の試聴ができます。","height":800,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"mf-intro\" data-i18n=\"intro\"></p>\n<div id=\"controls\" class=\"mf-controls\"></div><div id=\"sheet\"></div><p id=\"meta\" class=\"mf-meta\"></p>\n<div id=\"answers\" class=\"mf-answers\" role=\"group\" data-i18n-label=\"question\"></div><div id=\"quiz-actions\" class=\"mf-actions\"></div>\n<p id=\"feedback\" class=\"mf-feedback\" role=\"status\" aria-live=\"polite\"></p>\n<div class=\"mf-actions\"><button id=\"play\" data-i18n=\"play\"></button><button id=\"stop\" data-i18n=\"stop\" disabled></button></div><p id=\"status\" class=\"mf-meta\" role=\"status\" data-i18n=\"idle\"></p>\n<label class=\"mf-volume\"><span data-i18n=\"volume\"></span><input id=\"volume\" type=\"range\" min=\"0\" max=\"100\" value=\"65\"></label>\n","css":"body{padding:24px}h2{font-size:22px;line-height:1.4}p{line-height:1.75}.mf-intro{color:var(--muted);margin:10px 0 18px}.mf-staff{display:block;width:100%;height:auto;max-height:270px;color:var(--ink);background:var(--surface);border:1px solid var(--rule);border-radius:8px;margin:16px 0}.mf-controls,.mf-actions,.mf-answers{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0}button,select{min-height:46px;font-size:16px}button{white-space:normal;line-height:1.5}.mf-controls button,.mf-answers button{flex:1 1 64px}.mf-actions button{flex:1 1 110px}label{display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:16px;margin:12px 0}select{max-width:100%;background:var(--paper);color:var(--ink);border:1px solid var(--rule);padding:8px;border-radius:6px}.mf-feedback{border-left:3px solid var(--accent);padding:12px;background:var(--surface);min-height:3.5em;margin:14px 0;font-size:16px}.mf-meta{font-size:14px;color:var(--muted);margin:10px 0}.mf-staff [data-current=true]{color:var(--accent);filter:drop-shadow(0 0 1px currentColor)}.mf-staff [data-current=true] path{fill:currentColor}.mf-queue{display:flex;flex-wrap:wrap;gap:8px}.mf-queue button{min-width:50px}.mf-queue button[aria-pressed=true]{border-color:var(--accent);background:var(--accent-soft)}.mf-score{font-variant-numeric:tabular-nums}.mf-volume{display:flex;gap:12px;align-items:center;font-size:14px;border-top:1px solid var(--rule);padding-top:12px}.mf-volume input{min-width:80px;max-width:180px}.mf-answer-note{color:var(--muted);font-size:14px}button[aria-pressed=true]{background:var(--accent-soft);border-color:var(--accent)}[hidden]{display:none!important}@media(max-width:420px){body{padding:20px 14px}h2{font-size:20px}.mf-controls button{flex-basis:75px}}\n\n.mf-answers button{border:1px solid var(--rule);background:var(--surface);border-radius:8px;min-height:52px;padding:10px 14px;cursor:pointer}.mf-answers button:not(:disabled):hover{border-color:var(--accent);background:var(--accent-soft)}.mf-answers button:focus-visible{outline:2px solid var(--accent);outline-offset:3px}.mf-answers button[aria-pressed=true]{border:2px solid var(--accent);background:var(--accent-soft);font-weight:600}.mf-answers button:disabled{cursor:default}\n","js":"const GLYPHS = {\"treble\":\"M376 415C374 427 376 428 382 434C398 449 419 470 438 491C522 583 572 702 572 815C572 902 548 988 507 1048C492 1070 466 1098 455 1098C441 1098 410 1072 390 1050C316 968 292 843 292 739C292 681 299 616 306 575C308 563 309 561 297 551C233 498 164 437 112 373C43 287 0 194 0 87C0 -87 119 -252 364 -252C387 -252 413 -250 433 -246C444 -244 446 -243 448 -255C460 -322 475 -409 475 -456C475 -604 375 -622 316 -622C262 -622 236 -606 236 -593C236 -586 245 -583 268 -576C299 -567 335 -540 335 -482C335 -427 300 -380 239 -380C172 -380 132 -433 132 -495C132 -560 171 -658 322 -658C389 -658 519 -628 519 -458C519 -401 501 -306 490 -244C488 -232 489 -233 503 -227C604 -187 671 -102 671 11C671 139 577 252 430 252C404 252 404 252 401 270ZM470 943C503 943 530 916 530 861C530 792 497 728 419 650C403 634 379 611 356 591C349 585 345 586 343 599C339 625 337 659 337 691C337 847 409 943 470 943ZM361 262C364 243 364 244 346 238C258 208 201 129 201 44C201 -46 248 -110 316 -133C324 -136 336 -139 343 -139C351 -139 355 -134 355 -128C355 -121 347 -118 340 -115C298 -97 268 -54 268 -8C268 49 307 92 368 109C384 113 386 112 388 101L438 -197C440 -208 439 -208 424 -211C408 -214 388 -216 368 -216C193 -216 80 -119 80 20C80 79 90 158 173 252C233 319 279 356 326 394C336 402 338 401 340 390ZM430 103C428 115 429 118 441 117C522 110 589 42 589 -46C589 -109 551 -160 495 -188C483 -194 481 -194 479 -182Z\",\"bass\":\"M252 262C78 262 0 135 0 39C0 -41 42 -110 123 -110C186 -110 229 -66 229 -4C229 60 182 100 133 100C106 100 96 93 83 93C70 93 67 101 67 111C67 151 127 224 229 224C335 224 381 120 381 -37C381 -140 359 -260 297 -356C237 -449 134 -534 10 -605C1 -610 -5 -615 -5 -623C-5 -629 -1 -635 8 -635C13 -635 19 -633 25 -630C158 -565 286 -489 392 -375C479 -281 531 -159 531 -28C531 146 425 262 252 262ZM629 180C598 180 574 156 574 125C574 94 598 70 629 70C660 70 684 94 684 125C684 156 660 180 629 180ZM630 -71C599 -71 576 -94 576 -125C576 -156 599 -179 630 -179C661 -179 684 -156 684 -125C684 -94 661 -71 630 -71Z\",\"black\":\"M97 -125C186 -125 295 -43 295 42C295 93 255 125 198 125C88 125 0 44 0 -42C0 -94 43 -125 97 -125Z\",\"half\":\"M97 -125C262 -125 295 9 295 42C295 93 254 125 196 125C47 125 0 10 0 -42C0 -95 42 -125 97 -125ZM173 -46C128 -76 97 -87 75 -87C54 -87 42 -76 35 -64C32 -58 29 -51 29 -44C29 -22 51 5 120 45C170 74 201 84 221 84C240 84 251 75 258 63C261 57 264 51 264 44C264 24 243 0 173 -46Z\",\"whole\":\"M216 125C83 125 0 70 0 2C0 -65 57 -125 206 -125C370 -125 422 -68 422 2C422 73 309 125 216 125ZM111 63C122 98 159 103 190 103C259 103 314 29 314 -31C314 -38 313 -44 312 -50C307 -75 293 -92 268 -98C258 -101 247 -102 237 -102C228 -102 220 -101 211 -98C194 -93 178 -84 164 -72C156 -65 149 -58 143 -50C123 -27 108 7 108 39C108 47 109 55 111 63Z\",\"flag\":\"M238 -790C238 -790 264 -695 264 -617C264 -492 212 -374 149 -274C98 -195 56 -109 40 -13C37 3 29 9 19 9C8 9 0 6 0 -6V-245C66 -257 161 -393 197 -478C212 -512 221 -569 221 -628C221 -673 214 -720 197 -765C195 -771 194 -776 194 -780C194 -796 204 -805 210 -809C211 -810 213 -810 215 -810C222 -810 234 -804 238 -790Z\",\"quarterRest\":\"M78 -38C94 -58 108 -77 121 -98C123 -102 127 -110 127 -112C127 -113 127 -115 126 -116C124 -120 120 -121 115 -121C111 -121 103 -119 99 -118C94 -118 88 -115 83 -115C40 -115 1 -158 1 -211C1 -261 44 -310 117 -366C125 -372 135 -375 143 -375C150 -375 157 -373 158 -369C159 -366 160 -364 160 -362C160 -353 152 -345 144 -338C131 -338 120 -311 118 -302C115 -294 114 -285 114 -276C114 -245 129 -210 161 -204C166 -203 171 -203 177 -203C206 -203 239 -214 255 -220C256 -220 257 -221 258 -221C261 -222 263 -222 265 -222C268 -222 270 -221 270 -218C270 -206 244 -173 233 -161C195 -115 164 -78 164 -22C164 -18 165 -13 165 -9C169 49 205 97 231 138C234 143 235 148 235 153C235 163 231 172 231 172C231 172 83 348 66 365C61 370 54 373 48 373C38 373 28 366 28 352C28 347 29 342 32 336C36 325 93 274 93 202C93 165 78 122 33 75C23 65 19 54 19 46C19 32 29 22 29 22Z\",\"eighthRest\":\"M134 107C134 144 104 174 67 174C30 174 0 144 0 107C0 86 12 68 27 56C36 50 45 45 55 43C63 41 72 39 81 39C95 39 109 42 120 46C134 50 143 54 156 61C158 62 160 62 161 62C165 62 166 58 166 53C166 50 166 46 165 42C162 27 90 -172 72 -238C72 -250 95 -251 101 -251C112 -251 126 -249 136 -241C139 -239 237 112 237 112C241 130 246 146 247 151C247 161 237 166 235 167C233 167 230 167 224 163C217 157 167 97 134 97Z\",\"halfRest\":\"M282 24V116C282 131 270 142 256 142H26C11 142 0 131 0 116V24C0 10 11 -2 26 -2H256C270 -2 282 10 282 24Z\",\"wholeRest\":\"M282 -109V-17C282 -2 270 9 256 9H26C11 9 0 -2 0 -17V-109C0 -123 11 -135 26 -135H256C270 -135 282 -123 282 -109Z\",\"sharp\":\"M237 118C244 121 249 129 249 135V206C249 211 246 214 242 214C240 214 239 214 237 213C237 213 217 205 212 204C205 204 198 209 198 217V339C198 345 192 350 184 350C174 350 168 345 168 339V209C167 199 164 186 155 180C143 173 109 159 92 155C83 155 80 167 80 175V295C80 301 73 306 66 306C56 306 50 301 50 295V160C50 146 44 136 38 133C32 130 12 122 12 122C5 120 0 112 0 106V35C0 29 3 26 8 26C9 26 11 27 12 27C12 27 27 33 34 37C35 37 36 38 37 38C44 38 50 28 50 20V-79C50 -90 45 -99 39 -102C33 -104 12 -113 12 -113C5 -115 0 -123 0 -129V-200C0 -206 3 -209 8 -209C9 -209 11 -208 12 -208C12 -208 26 -202 35 -199C36 -198 37 -198 38 -198C45 -198 50 -209 50 -214V-337C50 -343 56 -348 63 -348C73 -348 80 -343 80 -337V-198C80 -185 85 -178 90 -176L151 -151C152 -151 154 -150 155 -150C163 -150 168 -162 168 -168V-293C168 -299 174 -304 181 -304C192 -304 198 -299 198 -293V-151C198 -143 202 -131 209 -128C216 -125 237 -117 237 -117C244 -114 249 -106 249 -100V-29C249 -24 246 -21 242 -21C240 -21 239 -21 237 -22L211 -32C205 -32 198 -26 198 -14V79C198 86 203 105 211 108ZM168 -45C162 -65 115 -85 92 -85C86 -85 81 -83 80 -80C78 -76 77 -54 77 -30C77 1 78 36 80 44C82 61 128 82 153 82C160 82 166 80 168 76C170 71 172 46 172 19C172 -8 170 -36 168 -45Z\",\"flat\":\"M12 -170C15 -174 18 -175 21 -175C24 -175 27 -173 27 -173C57 -156 81 -129 106 -112C195 -50 226 11 226 57C226 114 182 150 136 153C129 153 122 152 115 150C104 147 92 143 81 136C75 131 64 122 59 122C57 122 56 122 54 123C47 126 43 133 43 140C44 162 50 402 50 422C50 433 41 439 31 439C17 439 1 429 0 411C0 411 4 -160 12 -170ZM47 -81C47 -81 44 -21 44 19C44 35 45 47 46 51C50 63 76 85 90 93C99 98 108 100 116 100C126 100 135 96 141 89C151 78 157 61 157 42C157 24 152 3 140 -18C127 -42 98 -74 68 -93C64 -95 61 -96 58 -96C49 -96 47 -86 47 -81Z\",\"natural\":\"M141 181C139 181 138 180 137 180C137 180 73 157 47 157C41 157 37 158 37 162V329C37 336 31 341 25 341H12C5 341 0 336 0 329V-186C0 -192 3 -195 8 -195C9 -195 11 -194 12 -194C12 -194 14 -194 15 -193C29 -187 85 -163 114 -163C124 -163 131 -166 131 -174V-323C131 -330 136 -335 143 -335H156C162 -335 168 -330 168 -323V179C168 184 164 187 160 187C159 187 157 187 156 186ZM37 39C37 53 98 79 122 79C128 79 131 78 131 74V-29C131 -47 74 -70 49 -70C42 -70 37 -68 37 -64Z\",\"flagDown\":\"M240 760C254 718 261 668 261 623C261 564 236 480 221 446C184 362 134 281 0 236V1C0 -9 8 -14 16 -14C25 -14 38 -8 40 8C57 103 131 190 182 269C245 368 306 487 306 612C306 690 286 761 278 793C275 804 269 808 262 808C250 808 237 796 237 777C237 772 238 766 240 760Z\"};\n// Small SVG engraver for the deliberately limited notation taught in this course.\n// Bravura outlines: Steinberg, SIL OFL 1.1; see engraving/OFL.txt.\nconst MusicStaff=(()=>{\n const ns='http://www.w3.org/2000/svg',letters=['C','D','E','F','G','A','B'],pcs=[0,2,4,5,7,9,11];\n const el=(tag,attrs={})=>{const n=document.createElementNS(ns,tag);for(const [k,v] of Object.entries(attrs))n.setAttribute(k,v);return n;};\n const parse=p=>{const m=p.match(/^([A-G])([♯♭♮]?)([0-8])$/);if(!m)throw Error('invalid written pitch');const letter=letters.indexOf(m[1]),oct=+m[3],alter=m[2]==='♯'?1:m[2]==='♭'?-1:0;return {step:oct*7+letter,midi:(oct+1)*12+pcs[letter]+alter,alter,sign:m[2],name:p};};\n const fromStep=(step,alter=0)=>letters[((step%7)+7)%7]+(alter>0?'♯':alter<0?'♭':'')+Math.floor(step/7);\n const fromMidi=(m,flat=false)=>{const names=flat?['C','D♭','D','E♭','E','F','G♭','G','A♭','A','B♭','B']:['C','C♯','D','D♯','E','F','F♯','G','G♯','A','A♯','B'];return names[m%12]+(Math.floor(m/12)-1);};\n function glyph(parent,name,x,y,gap){parent.append(el('path',{d:GLYPHS[name],transform:`translate(${x} ${y}) scale(${gap/250} ${-gap/250})`,fill:'currentColor'}));}\n function render({clef='treble',notes=[],meter=null,key=null,labels=false,small=false,answerLabel='',barEnds=[]}={}){\n const gap=small?12:16,bottom=small?92:114,width=Math.max(300,Math.min(660,110+notes.length*66)),height=small?158:196;\n const svg=el('svg',{viewBox:`0 0 ${width} ${height}`,class:'mf-staff',role:'img','aria-label':answerLabel||viz.t('staff_description')});\n const line=(x1,y1,x2,y2,w=1)=>svg.append(el('line',{x1,y1,x2,y2,stroke:'currentColor','stroke-width':w,opacity:.7}));\n for(let i=0;i<5;i++)line(12,bottom-i*gap,width-12,bottom-i*gap);\n glyph(svg,clef,24,clef==='treble'?bottom-gap:bottom-3*gap,gap);\n let left=80;\n if(key==='G'){glyph(svg,'sharp',left,bottom-4*gap,gap);left+=32;}\n if(meter){const [n,d]=meter.split('/');for(const [v,y] of [[n,bottom-2.65*gap],[d,bottom-.7*gap]]){const t=el('text',{x:left,y,'font-size':gap*1.9,'font-weight':700,'text-anchor':'middle',fill:'currentColor'});t.textContent=v;svg.append(t);}left+=30;}\n const base=clef==='treble'?30:18,positions=[];\n notes.forEach((n,i)=>{\n const x=left+(i+.5)*(width-24-left)/Math.max(1,notes.length),group=el('g',{'data-note-index':i});svg.append(group);positions.push(x);\n if(n.blank){group.append(el('rect',{x:x-11,y:bottom-2*gap-13,width:22,height:26,fill:'var(--paper)',stroke:'currentColor','stroke-dasharray':'3 2'}));}\n else if(n.rest){glyph(group,({4:'wholeRest',2:'halfRest',1:'quarterRest','0.5':'eighthRest'})[n.value]||'quarterRest',x-6,bottom-(n.value===4?3:2)*gap,gap);}\n else{\n const pitches=n.chord||[n.pitch];\n for(const pitch of pitches){const p=parse(pitch),pos=p.step-base,y=bottom-pos*gap/2;\n for(let k=-2;k>=pos;k-=2)line(x-14,bottom-k*gap/2,x+14,bottom-k*gap/2,1.4);\n for(let k=10;k<=pos;k+=2)line(x-14,bottom-k*gap/2,x+14,bottom-k*gap/2,1.4);\n glyph(group,n.value===4?'whole':n.value===2?'half':'black',x-gap*.59,y,gap);\n if(p.sign)glyph(group,p.sign==='♯'?'sharp':p.sign==='♭'?'flat':'natural',x-gap*1.7,y,gap);\n if(n.dot)group.append(el('circle',{cx:x+gap*.95,cy:y-(pos%2===0?gap/2:0),r:gap*.13,fill:'currentColor'}));\n }\n const ps=pitches.map(parse).map(p=>p.step-base),highest=Math.max(...ps),lowest=Math.min(...ps),down=(highest+lowest)/2>=4;\n if(n.value!==4){const stemx=x+(down?-gap*.55:gap*.55),from=bottom-(down?highest:lowest)*gap/2,to=bottom-(down?lowest:highest)*gap/2+(down?gap*3.5:-gap*3.5);group.append(el('line',{x1:stemx,x2:stemx,y1:from,y2:to,stroke:'currentColor','stroke-width':1.5}));\n if(n.value===.5){glyph(group,down?'flagDown':'flag',stemx,to,gap);}\n }\n }\n if(labels){const text=el('text',{x,y:height-15,'font-size':14,'text-anchor':'middle',fill:'currentColor'});text.textContent=n.rest?viz.t('rest'):(n.chord||[n.pitch]).join(' ');svg.append(text);}\n if(n.barAfter||barEnds.includes(i))line(x+(width-24-left)/notes.length*.48,bottom,x+(width-24-left)/notes.length*.48,bottom-4*gap,1.5);\n });\n for(let i=0;i<notes.length-1;i++)if(notes[i].tie){const x=positions[i],x2=positions[i+1],pos=parse(notes[i].pitch).step-base,direction=pos>=4?-1:1,y=bottom-pos*gap/2+direction*gap;svg.append(el('path',{d:`M ${x} ${y} Q ${(x+x2)/2} ${y+direction*gap} ${x2} ${y}`,fill:'none',stroke:'currentColor','stroke-width':1.5}));}\n line(width-12,bottom,width-12,bottom-4*gap,1.5);return svg;\n }\n function score(notes,bpm=90){let beat=0;const events=[];notes.forEach(n=>{const length=n.value*(n.dot?1.5:1);if(!n.rest){if(n.continueTie){const last=events[events.length-1];last.duration+=length*60/bpm;}else for(const p of n.chord||[n.pitch])events.push({beat,hz:440*2**((parse(p).midi-69)/12),duration:length*60/bpm*.94,gain:.8,wave:'triangle',hold:true});}beat+=length;});return {bpm,beats:beat,events};}\n return {render,parse,fromStep,fromMidi,score};\n})();\n\nconst PRACTICE = {\"kind\": \"form\", \"bars\": 4};\nconst $=s=>document.querySelector(s),t=viz.t;\nfunction make(tag,attrs={},text=''){const e=document.createElement(tag);for(const [k,v]of Object.entries(attrs))e.setAttribute(k,v);e.textContent=text;return e;}\nfunction button(parent,key,fn,attrs={}){const b=make('button',{type:'button',...attrs},t(key));b.onclick=fn;parent.append(b);return b;}\nfunction select(parent,key,items,fn,id){const label=make('label',{},t(key)),s=make('select',{id});for(const [value,k]of items)s.append(make('option',{value},t(k)));s.onchange=()=>{player.stop();fn(s.value);};label.append(s);parent.append(label);return s;}\nlet tickAction=()=>{},currentScore=null;\nconst player=viz.audio({onState(s){document.body.dataset.audioState=s;$('#status').textContent=t(s==='idle'?'idle':s==='starting'?'starting':'playing');$('#stop').disabled=s==='idle';},onTick:b=>tickAction(b),onError:()=>$('#status').textContent=t('error')});\n$('#stop').onclick=()=>player.stop();$('#volume').oninput=e=>player.setVolume(+e.target.value/100);\n$('#play').onclick=()=>{if(currentScore)player.play(currentScore);};document.body.dataset.audioState='idle';\nconst controls=$('#controls'),answers=$('#answers'),feedback=$('#feedback'),sheet=$('#sheet'),meta=$('#meta');\nconst staff=(notes,extra={})=>{sheet.replaceChildren(MusicStaff.render({notes,...extra}));};\nconst note=pitch=>({pitch,value:1});\nfunction highlight(beat,notes){let at=0;for(const [i,n]of notes.entries()){const end=at+n.value*(n.dot?1.5:1);const g=sheet.querySelector(`[data-note-index=\"${i}\"]`);g?.setAttribute('data-current',String(beat>=at&&beat<end));at=end;}}\nconst shuffle=a=>{a=[...a];for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]];}return a;};\nif(PRACTICE.kind==='map'){\n let clef='treble',step=32,alter=0;\n select(controls,'clef',[['treble','treble'],['bass','bass']],v=>{clef=v;step=v==='treble'?32:24;draw();},'clef');\n const row=make('div',{class:'mf-controls'});controls.append(row);\n button(row,'down',()=>{player.stop();step=Math.max(clef==='treble'?28:16,step-1);draw();},{id:'pitch-down'});\n button(row,'up',()=>{player.stop();step=Math.min(clef==='treble'?39:28,step+1);draw();},{id:'pitch-up'});\n select(controls,'accidental',[['0','natural'],['1','sharp'],['-1','flat']],v=>{alter=+v;draw();},'accidental');\n function draw(){const pitch=MusicStaff.fromStep(step,alter),notes=[note(pitch)];staff(notes,{clef,labels:true});feedback.textContent=pitch+' · '+t('position')+' '+(step-(clef==='treble'?30:18));meta.textContent=t('anchor_'+clef)+(step<(clef==='treble'?30:18)||step>(clef==='treble'?38:26)?' '+t('ledger'):'');currentScore=MusicStaff.score(notes);tickAction=b=>highlight(b,notes);}\n draw();\n}else if(['pitchQuiz','rhythmQuiz','keyQuiz'].includes(PRACTICE.kind)){\n let clefMode='treble',altered=false,deck=[],index=0,choice=null,answered=false,usedHint=false,assisted=0,correct=0;\n const stats=make('p',{class:'mf-meta mf-score',id:'round-score'});controls.append(stats);\n if(PRACTICE.kind==='pitchQuiz'){\n select(controls,'clef',[['treble','treble'],['bass','bass'],['mixed','mixed']],v=>{clefMode=v;start();},'clef');\n select(controls,'difficulty',[['plain','plain'],['altered','altered']],v=>{altered=v==='altered';start();},'difficulty');\n }\n const action=make('div',{class:'mf-actions'});$('#quiz-actions').append(action);\n const check=button(action,'check',()=>finish(false),{id:'check',disabled:''});\n const hint=button(action,'hint',()=>{if(!answered)usedHint=true;meta.textContent=hintText();},{id:'hint'});\n const reveal=button(action,'reveal',()=>finish(true),{id:'reveal'});\n const next=button(action,'next',()=>{if(index<deck.length-1){index++;draw();}else{feedback.textContent=t('finished');next.disabled=true;}},{id:'next',disabled:''});\n button(action,'restart',start,{id:'restart'});\n function bank(){\n if(PRACTICE.kind==='pitchQuiz'){\n const clefs=clefMode==='mixed'?['treble','bass']:[clefMode],qs=[];\n for(const clef of clefs)for(let step=clef==='treble'?28:16;step<=(clef==='treble'?39:28);step++){const alter=altered?[0,1,-1][Math.floor(Math.random()*3)]:0,pitch=MusicStaff.fromStep(step,alter);qs.push({clef,step,pitch,answer:pitch,notes:[note(pitch)]});}\n return shuffle(qs).slice(0,12);\n }\n if(PRACTICE.kind==='rhythmQuiz')return shuffle([\n ['4/4',[note('C5'),{rest:true,value:1},{pitch:'C5',value:.5},{pitch:'C5',value:.5}],1],\n ['3/4',[note('C5'),note('C5')],1],['4/4',[{pitch:'C5',value:2},note('C5')],1],\n ['3/4',[{pitch:'C5',value:1,dot:true},{pitch:'C5',value:.5}],1],\n ['4/4',[{rest:true,value:2}],2],['6/8',[{pitch:'C5',value:1,dot:true},note('C5')],.5],\n ['6/8',[{pitch:'C5',value:.5},{rest:true,value:.5},note('C5')],1],\n ['4/4',[{pitch:'C5',value:1,dot:true},note('C5')],1.5],['3/4',[note('C5')],2],\n ['4/4',[{rest:true,value:1}],3],['3/4',[{rest:true,value:.5},note('C5')],1.5],['6/8',[{pitch:'C5',value:.5},{pitch:'C5',value:.5}],2]\n ].map(([meter,notes,missing])=>({meter,notes,missing,answer:String(missing),clef:'treble'})));\n return shuffle([\n {notes:[{pitch:'F4',value:4}],target:0,answer:'F♯4',sounds:['F♯4']},\n {notes:[note('F♮4'),note('F4'),note('G4'),note('A4')],target:1,answer:'F4',sounds:['F4','F4','G4','A4']},\n {notes:[{pitch:'F♮4',value:4,barAfter:true},{pitch:'F4',value:4}],target:1,answer:'F♯4',sounds:['F4','F♯4']},\n {notes:[{pitch:'F5',value:4}],target:0,answer:'F♯5',sounds:['F♯5']}\n ].map(q=>({...q,clef:'treble',key:'G',meter:'4/4'})));\n }\n function start(){player.stop();deck=bank();index=0;correct=0;assisted=0;draw();}\n function hintText(){const q=deck[index];if(PRACTICE.kind==='pitchQuiz')return t('anchor_'+q.clef)+' '+t('position')+' '+(q.step-(q.clef==='treble'?30:18));return t(PRACTICE.kind==='keyQuiz'?'key_hint':'bar_hint');}\n function draw(){player.stop();choice=null;answered=false;usedHint=false;check.disabled=true;next.disabled=true;reveal.disabled=false;hint.disabled=false;$('#play').disabled=PRACTICE.kind!=='pitchQuiz';feedback.textContent=t(PRACTICE.kind==='pitchQuiz'?'before':'before_check');meta.textContent=t(PRACTICE.kind==='pitchQuiz'?'question':PRACTICE.kind==='keyQuiz'?'key_prompt':'bar_prompt');answers.replaceChildren();\n const q=deck[index];let choices;\n if(PRACTICE.kind==='pitchQuiz'){const offsets=shuffle([-2,-1,1,2]).slice(0,2),accOther=MusicStaff.parse(q.pitch).alter===0?1:0;choices=shuffle([q.answer,...offsets.map(d=>MusicStaff.fromStep(q.step+d,MusicStaff.parse(q.pitch).alter)),MusicStaff.fromStep(q.step,accOther)]);staff(q.notes,{clef:q.clef});currentScore=MusicStaff.score(q.notes);}\n else if(PRACTICE.kind==='rhythmQuiz'){staff([...q.notes,{blank:true,value:q.missing}],{meter:q.meter});choices=['0.5','1','1.5','2','3','4'];currentScore=null;}\n else{staff(q.notes,{meter:q.meter,key:'G'});sheet.querySelector(`[data-note-index=\"${q.target}\"]`)?.setAttribute('data-current','true');meta.textContent+=' '+t('target_note')+' '+(q.target+1);choices=['F4','F♯4','F5','F♯5'];currentScore=MusicStaff.score(q.notes.map((n,i)=>({...n,pitch:q.sounds[i]})));}\n for(const c of choices){const b=make('button',{type:'button','data-answer':c,'aria-pressed':'false'},c==='0.5'?'½':c==='1.5'?'1½':c);b.onclick=()=>{if(answered)return;choice=c;check.disabled=false;[...answers.children].forEach(x=>x.setAttribute('aria-pressed',String(x===b)));};answers.append(b);}\n updateStats();tickAction=b=>highlight(b,q.notes);\n }\n function updateStats(){stats.textContent=t('round')+' '+(index+1)+' / '+deck.length+' · '+t('first_try')+' '+correct+' · '+t('assisted')+' '+assisted;}\n function finish(explicit){if(answered||(!explicit&&choice===null))return;player.stop();answered=true;if(explicit)usedHint=true;if(usedHint)assisted++;if(!usedHint&&choice===deck[index].answer)correct++;const q=deck[index];feedback.textContent=(explicit?'':t(choice===q.answer?'correct':'wrong')+' ')+t('answer')+' '+q.answer+'. '+hintText();\n if(PRACTICE.kind==='rhythmQuiz'){const missing=q.missing===3?{pitch:'C5',value:2,dot:true}:q.missing===1.5?{pitch:'C5',value:1,dot:true}:{pitch:'C5',value:q.missing};const ns=[...q.notes,missing];staff(ns,{meter:q.meter});currentScore=MusicStaff.score(ns);const sum=q.notes.reduce((a,n)=>a+n.value*(n.dot?1.5:1),0);feedback.textContent+=' '+t('bar_total')+' '+(sum+q.missing)+' − '+t('written')+' '+sum+' = '+q.missing;tickAction=b=>highlight(b,ns);}\n else if(PRACTICE.kind==='pitchQuiz')staff(q.notes,{clef:q.clef,labels:true});\n $('#play').disabled=false;check.disabled=true;reveal.disabled=true;hint.disabled=true;next.disabled=false;[...answers.children].forEach(b=>b.disabled=true);updateStats();}\n start();\n}else if(PRACTICE.kind==='symbols'){\n const kinds=[['whole',4,false,false],['half',2,false,false],['quarter',1,false,false],['eighth',.5,false,false],['dotted',1,false,true],['whole_rest',4,true,false],['half_rest',2,true,false],['quarter_rest',1,true,false],['eighth_rest',.5,true,false]];\n for(const [label,value,rest,dot] of kinds)button(controls,label,()=>draw(label,{pitch:'C5',value,rest,dot}));\n for(const tied of [true,false])button(controls,tied?'tied':'untied',()=>draw(tied?'tied':'untied',[{pitch:'C5',value:1,tie:tied},{pitch:'C5',value:1,continueTie:tied}]));\n function draw(label,n){player.stop();const notes=Array.isArray(n)?n:[n];staff(notes);feedback.textContent=t(label);meta.textContent=t('unit');const score=MusicStaff.score(notes);score.beats=4;for(let i=0;i<4;i++)score.events.push({beat:i,hz:1500,duration:.035,gain:.25});currentScore=score;tickAction=b=>highlight(b,notes);}\n draw('quarter',{pitch:'C5',value:1});\n}else if(PRACTICE.kind==='chord'){\n let root='C4',quality='major',inv=0;\n select(controls,'root',[['C4','C'],['D4','D'],['F4','F']],v=>{root=v;draw();},'root');\n select(controls,'quality',[['major','major'],['minor','minor']],v=>{quality=v;draw();},'quality');\n select(controls,'inversion',[['0','root_position'],['1','first_inversion'],['2','second_inversion']],v=>{inv=+v;draw();},'inversion');\n function draw(){const p=MusicStaff.parse(root),intervals=[0,quality==='major'?4:3,7],pitches=intervals.map((v,i)=>{const step=p.step+i*2,plain=MusicStaff.parse(MusicStaff.fromStep(step));return MusicStaff.fromStep(step,p.midi+v-plain.midi);});for(let i=0;i<inv;i++){const p=MusicStaff.parse(pitches.shift());pitches.push(MusicStaff.fromStep(p.step+7,p.alter));}const ns=[{chord:pitches,value:2}];staff(ns,{labels:false});feedback.textContent=t('root')+': '+root+' · '+t('quality')+': '+t(quality)+' · '+pitches.join(' – ');meta.textContent=t('chord_tip');currentScore=MusicStaff.score(ns);tickAction=b=>highlight(b,ns);}\n draw();\n}else if(PRACTICE.kind==='form'){\n const initial=PRACTICE.bars===8?['A','A','B','A','A','A′','B','A']:['A','A','B','A'];let order=[...initial],selected=0,melodyOnly=false;\n const material={A:['E4','G4','A4','G4'],'A′':['E4','G4','A4','C5'],B:['C5','B4','G4','D4']};\n const queue=make('div',{class:'mf-queue',id:'bar-queue'});controls.append(queue);\n const sel=select(controls,'material',[['A','A'],['A′','A′'],['B','B']],v=>{order[selected]=v;draw();},'material');\n const label=make('label'),box=make('input',{type:'checkbox',id:'melody-only'});label.append(box,make('span',{},t('melody_only')));controls.append(label);box.onchange=()=>{player.stop();melodyOnly=box.checked;draw();};\n button(controls,'reset',()=>{player.stop();order=[...initial];selected=0;draw();},{id:'reset'});\n button($('#quiz-actions'),'one_bar',()=>play(false),{id:'play-bar'});$('#play').textContent=t('full');$('#play').onclick=()=>play(true);\n function getScore(sequence){const s={bpm:100,beats:sequence.length*4,events:[]};sequence.forEach((name,bar)=>{const ns=material[name].map(note),m=MusicStaff.score(ns,100);s.events.push(...m.events.map(e=>({...e,beat:e.beat+bar*4})));if(!melodyOnly)for(const beat of [0,2])for(const midi of [36,48,52,55])s.events.push({beat:bar*4+beat,hz:440*2**((midi-69)/12),duration:.95,gain:midi===36?.65:.35,wave:'triangle'});});return s;}\n function draw(){queue.replaceChildren();order.forEach((m,i)=>{const b=make('button',{type:'button','data-bar':i,'aria-pressed':String(i===selected)},(i+1)+' · '+m);b.onclick=()=>{player.stop();selected=i;draw();};queue.append(b);});sel.value=order[selected];staff(material[order[selected]].map(note),{meter:'4/4'});feedback.textContent=order.join(' · ');meta.textContent=t('arrange_tip');}\n function play(all){const start=selected,sequence=all?order:[order[selected]];tickAction=beat=>{if(beat<0){highlight(-1,material[order[selected]].map(note));return;}const b=all?Math.min(order.length-1,Math.floor(beat/4)):start;if(b!==selected){selected=b;draw();}highlight(beat%4,material[order[selected]].map(note));};player.play(getScore(sequence));}\n draw();\n}\n","audio":true,"strings":{"accidental":"臨時記号","altered":"臨時記号を含む","anchor_bass":"基準:下から四番目、二つの点に挟まれた線が F3 です。","anchor_treble":"基準:下から二番目の線が G4。隣の線・間へ移るたび、音名を一つ進めます。","answer":"答え:","arrange_tip":"小節を選んで素材を替え、聴きます。譜面は選択した小節を表示し、全体再生中は現在の小節を追います。","assisted":"ヒント使用","bar":"小節","bar_hint":"拍子記号を四分音符の単位に換算し、書かれた音価の合計を小節全体から引きます。","bar_prompt":"この小節を完成させます。空欄に必要な長さを、四分音符の拍数で選んでください。","bar_total":"小節の合計","bass":"ヘ音記号","before":"答えを選び、解説で確かめましょう。","before_check":"答えを選んで確認するか、解説を表示します。","check":"答えを確認","choose_p":"移調は P","choose_q":"移調は Q","chord_tip":"下から上へ和音を読みます。転回形を変えても根音の名前は同じです。","clef":"音部記号","compare_title":"答えを選んでから図を見る","comparison_correct":"P は全音程を保ち、Q は内部の一音を変えています。表示された間隔を確かめましょう。","correct":"正解です。","difficulty":"出題範囲","dotted":"付点四分音符・1½","down":"一つ下の線・間へ","eighth":"八分音符・½","eighth_rest":"八分休符・½","error":"再生できませんでした。再試行するか文章で確認してください。","finished":"終了です。最後の解説を復習するか、新しいラウンドへ進みましょう。","first_inversion":"第一転回形","first_try":"初回で正解","flat":"フラット ♭","full":"全体を再生","half":"二分音符・2","half_rest":"二分休符・2","heading":"自分で素材を並べる","hint":"位置のヒント","idle":"再生を押すと音が鳴ります。編集すると停止します。","intro":"四小節の好きな位置を選び、A・A′・B に置き換え、最初の A–A–B–A と比べます。","inversion":"最低音の位置","key_hint":"調号のシャープ一つは、臨時記号で変更されない限り全オクターブの F に効きます。小節線で臨時記号はリセットされますが、調号は残ります。","key_prompt":"調号と臨時記号を使って、示された音を読みます。","ledger":"短い加線で五線を延長します。数え方は五線内と同じです。","major":"長三和音","material":"選んだ小節の素材","melody_only":"旋律だけ","minor":"短三和音","missing":"不足分","mixed":"両方の音部記号","natural":"ナチュラル ♮","next":"次の問題","one_bar":"選んだ小節を再生","plain":"幹音","play":"再生","playing":"再生中…","position":"最下線からの段数(隣の線・間へ一つで 1):","pulse":"基準パルス","quality":"種類","quarter":"四分音符・1","quarter_rest":"四分休符・1","question":"オクターブと臨時記号も含めて読み、確認する前に答えを選びます。","reset":"最初の配置に戻す","rest":"休符","restart":"新しいラウンド","reveal":"解説を見る","root":"根音","root_position":"基本形","round":"進行","second_inversion":"第二転回形","sharp":"シャープ ♯","staff_description":"五線譜。譜面を見られない場合は位置の説明を使えます。","starting":"音声を準備中…","stop":"停止","symbols":"音符と休符の音価","target_note":"読む音の番号:","tied":"タイで結ぶ四分音符二つ・2","treble":"ト音記号","unit":"完全な小節ではなく記号の抜粋です。音価は四分音符の単位。試聴は四拍で、休符でも控えめなパルスが続きます。","untied":"別々の四分音符二つ・1 + 1","up":"一つ上の線・間へ","volume":"音量","whole":"全音符・4","whole_rest":"全休符・ここでは 4","written":"記載済み","wrong":"まだ違います。選んだ答えと解説を比べましょう。"}}
A–A–B–A は A を二度示してから対照と回帰を作り、A–B–A–A は対照を早めます。A を A′ に替えると素材も変わるので、順序の変更とは分けて説明します。この比較では、B を冒頭へ移しても文字の名前を保ちます。
学習用の一小節単位は、実際の曲の完全な部分とは限りません。この小型 AABA は、32 小節 AABA 歌曲形式のフレーズ長や和声の慣習すべてを示しません。フレーズと部分
同じものを保ちながら、別のものを変えられる
旋律は楽器を変えて戻ることも、一音だけを変えて戻ることもあります。新しい文字を付ける前に、どの水準の共通性を追っているかを決めましょう。
| 関係 | 認識できる共通部分 | 今回変わるもの |
| 反復 | A の旋律全体 | 旋律は変わらない |
| 変奏 A′ | A の出だしとリズム | 最後の音高 |
| 対照 B | 共通のパルスと伴奏 | 音高の並びの多く |
| テクスチュアの変化 | A の旋律全体 | 伴奏の層が入る |
A′ のプライム記号は「A に関連する版」を示します。何音変えたら変奏になるという固定の計算法ではありません。文脈によっては小さな変更が構造上重要になり、逆に大きな表面の変化でも主題が保たれることがあります。
三種類の境目を比べる
各版は四拍の単位二つからなります。最初は A を繰り返しながら伴奏を追加。次は A の最後の G を高い C に変更。最後は伴奏を固定し、A を B に置き換えます。
図を準備しています
境目で何が変わった?最初の組は A を繰り返しながら伴奏を追加。次は伴奏を固定し、A の末尾 G だけを C にして A′ に。最後は伴奏を固定し、A を B に置き換えます。
{"id":"music-form-change","title":"境目で何が変わった?","summary":"最初の組は A を繰り返しながら伴奏を追加。次は伴奏を固定し、A の末尾 G だけを C にして A′ に。最後は伴奏を固定し、A を B に置き換えます。","height":760,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"mf-intro\" data-i18n=\"intro\"></p>\n<div id=\"variants\" class=\"mf-options\" role=\"group\" data-i18n-label=\"choose\"></div>\n<p id=\"facts\" class=\"mf-facts\" aria-live=\"polite\"></p>\n<svg id=\"plot\" class=\"mf-plot\" viewBox=\"0 0 540 200\" aria-hidden=\"true\"></svg>\n<div class=\"mf-axis\"><span data-i18n=\"axis\"></span><span id=\"duration\"></span></div>\n<div id=\"groups\" class=\"mf-groups\"></div><p id=\"notation\" class=\"mf-notation\"></p><p class=\"mf-key\" data-i18n=\"key\"></p>\n<div id=\"envelope-panel\" hidden><svg id=\"envelope-plot\" class=\"mf-plot\" viewBox=\"0 0 540 120\" aria-hidden=\"true\"></svg><p class=\"mf-key\" data-i18n=\"envelope\"></p></div>\n<div class=\"mf-actions\"><button id=\"play\" data-i18n=\"play\"></button><button id=\"stop\" data-i18n=\"stop\" disabled></button></div>\n<div class=\"mf-progress\" aria-hidden=\"true\"><span id=\"progress\"></span></div><p id=\"status\" class=\"mf-status\" role=\"status\" data-i18n=\"idle\"></p>\n<div class=\"mf-volume\"><label for=\"volume\" data-i18n=\"volume\"></label><input id=\"volume\" type=\"range\" min=\"0\" max=\"100\" value=\"65\"></div>\n","css":"body{padding:24px}h2{font-size:22px;line-height:1.4}.mf-intro{color:var(--muted);margin:10px 0 18px;line-height:1.7}.mf-options{display:flex;gap:8px;flex-wrap:wrap}.mf-options button{flex:1 1 125px;min-height:46px;font-size:16px;white-space:normal;line-height:1.45;text-align:left;padding:10px 12px}.mf-options button[aria-pressed=true]{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}.mf-facts{margin:16px 0;padding:14px;border-left:3px solid var(--accent);background:var(--surface);font-size:16px;line-height:1.75;min-height:4em}.mf-plot{width:100%;height:auto;display:block;margin:12px 0 0;background:var(--surface);border:1px solid var(--rule);border-radius:8px}.mf-axis{display:flex;justify-content:space-between;font-size:13px;color:var(--muted);gap:16px;margin:6px 0}.mf-notation{font-size:15px;line-height:1.8;overflow-wrap:anywhere;margin:10px 0;color:var(--ink)}.mf-groups{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0}.mf-groups span{padding:6px 10px;border:1px solid var(--rule);border-radius:5px;font-size:15px;white-space:pre}.mf-actions{display:flex;gap:8px;margin:18px 0 12px}.mf-actions button{min-height:46px;font-size:16px;flex:1}.mf-progress{height:3px;background:var(--rule);overflow:hidden}.mf-progress span{display:block;height:100%;background:var(--accent);width:0}.mf-status{font-size:14px;line-height:1.7;margin:10px 0;min-height:3.4em;color:var(--muted)}.mf-volume{display:flex;gap:12px;align-items:center;margin-top:12px;border-top:1px solid var(--rule);padding-top:12px;font-size:14px}.mf-volume input{min-width:60px;max-width:180px}.mf-volume label{white-space:nowrap}.mf-key{color:var(--muted);font-size:14px;line-height:1.6;margin:12px 0}@media(max-width:420px){body{padding:20px 14px}h2{font-size:20px}.mf-options button{flex-basis:105px}.mf-facts{padding:12px}}\n\n.mf-groups span.is-current{border-color:var(--accent);background:var(--accent-soft);box-shadow:inset 0 -2px 0 var(--accent)}\n\n[hidden]{display:none!important}\n#blind-answers{flex-wrap:wrap}#blind-answers button{flex:1 1 100px;white-space:normal;line-height:1.5;min-width:0;padding:10px}\n","js":"const MODEL = {\"mode\":\"notes\",\"min\":36,\"max\":86,\"blind\":false,\"variants\":[{\"score\":{\"bpm\":100,\"beats\":8,\"events\":[{\"midi\":64,\"hz\":329.627557,\"beat\":0,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":1,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":69,\"hz\":440.0,\"beat\":2,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":3,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":64,\"hz\":329.627557,\"beat\":4,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":5,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":69,\"hz\":440.0,\"beat\":6,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":7,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":36,\"hz\":65.406391,\"beat\":4,\"duration\":0.7,\"gain\":0.75,\"wave\":\"triangle\",\"layer\":\"bass\"},{\"midi\":36,\"hz\":65.406391,\"beat\":6,\"duration\":0.7,\"gain\":0.75,\"wave\":\"triangle\",\"layer\":\"bass\"},{\"midi\":48,\"hz\":130.812783,\"beat\":4,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":52,\"hz\":164.813778,\"beat\":4,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":55,\"hz\":195.997718,\"beat\":4,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":48,\"hz\":130.812783,\"beat\":6,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":52,\"hz\":164.813778,\"beat\":6,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":55,\"hz\":195.997718,\"beat\":6,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":4,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":5,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":6,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":7,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"}]},\"notation\":\"E G A G | E G A G\",\"groups\":[\"A\",\"A\"]},{\"score\":{\"bpm\":100,\"beats\":8,\"events\":[{\"midi\":64,\"hz\":329.627557,\"beat\":0,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":1,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":69,\"hz\":440.0,\"beat\":2,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":3,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":36,\"hz\":65.406391,\"beat\":0,\"duration\":0.7,\"gain\":0.75,\"wave\":\"triangle\",\"layer\":\"bass\"},{\"midi\":36,\"hz\":65.406391,\"beat\":2,\"duration\":0.7,\"gain\":0.75,\"wave\":\"triangle\",\"layer\":\"bass\"},{\"midi\":48,\"hz\":130.812783,\"beat\":0,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":52,\"hz\":164.813778,\"beat\":0,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":55,\"hz\":195.997718,\"beat\":0,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":48,\"hz\":130.812783,\"beat\":2,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":52,\"hz\":164.813778,\"beat\":2,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":55,\"hz\":195.997718,\"beat\":2,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":0,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":1,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":2,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":3,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":64,\"hz\":329.627557,\"beat\":4,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":5,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":69,\"hz\":440.0,\"beat\":6,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":72,\"hz\":523.251131,\"beat\":7,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":36,\"hz\":65.406391,\"beat\":4,\"duration\":0.7,\"gain\":0.75,\"wave\":\"triangle\",\"layer\":\"bass\"},{\"midi\":36,\"hz\":65.406391,\"beat\":6,\"duration\":0.7,\"gain\":0.75,\"wave\":\"triangle\",\"layer\":\"bass\"},{\"midi\":48,\"hz\":130.812783,\"beat\":4,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":52,\"hz\":164.813778,\"beat\":4,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":55,\"hz\":195.997718,\"beat\":4,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":48,\"hz\":130.812783,\"beat\":6,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":52,\"hz\":164.813778,\"beat\":6,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":55,\"hz\":195.997718,\"beat\":6,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":4,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":5,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":6,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":7,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"}]},\"notation\":\"E G A G | E G A C\",\"groups\":[\"A\",\"A′\"]},{\"score\":{\"bpm\":100,\"beats\":8,\"events\":[{\"midi\":64,\"hz\":329.627557,\"beat\":0,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":1,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":69,\"hz\":440.0,\"beat\":2,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":3,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":36,\"hz\":65.406391,\"beat\":0,\"duration\":0.7,\"gain\":0.75,\"wave\":\"triangle\",\"layer\":\"bass\"},{\"midi\":36,\"hz\":65.406391,\"beat\":2,\"duration\":0.7,\"gain\":0.75,\"wave\":\"triangle\",\"layer\":\"bass\"},{\"midi\":48,\"hz\":130.812783,\"beat\":0,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":52,\"hz\":164.813778,\"beat\":0,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":55,\"hz\":195.997718,\"beat\":0,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":48,\"hz\":130.812783,\"beat\":2,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":52,\"hz\":164.813778,\"beat\":2,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":55,\"hz\":195.997718,\"beat\":2,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":0,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":1,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":2,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":3,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":72,\"hz\":523.251131,\"beat\":4,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":71,\"hz\":493.883301,\"beat\":5,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":6,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":62,\"hz\":293.664768,\"beat\":7,\"duration\":0.45,\"gain\":0.85,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":36,\"hz\":65.406391,\"beat\":4,\"duration\":0.7,\"gain\":0.75,\"wave\":\"triangle\",\"layer\":\"bass\"},{\"midi\":36,\"hz\":65.406391,\"beat\":6,\"duration\":0.7,\"gain\":0.75,\"wave\":\"triangle\",\"layer\":\"bass\"},{\"midi\":48,\"hz\":130.812783,\"beat\":4,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":52,\"hz\":164.813778,\"beat\":4,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":55,\"hz\":195.997718,\"beat\":4,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":48,\"hz\":130.812783,\"beat\":6,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":52,\"hz\":164.813778,\"beat\":6,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":55,\"hz\":195.997718,\"beat\":6,\"duration\":1.1,\"gain\":0.35,\"wave\":\"triangle\",\"layer\":\"chord\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":4,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":5,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":6,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"},{\"midi\":86,\"hz\":1174.659072,\"beat\":7,\"duration\":0.035,\"gain\":0.3,\"wave\":\"sine\",\"layer\":\"pulse\"}]},\"notation\":\"E G A G | C B G D\",\"groups\":[\"A\",\"B\"]}]};\nconst $ = s => document.querySelector(s);\nconst variants = MODEL.variants;\nlet selected = 0;\nlet quizRevealed = !MODEL.blind;\nfunction visibility(){for(const q of ['#facts','#plot','.mf-axis','#groups','#notation','.mf-key'])$(q).toggleAttribute('hidden',!quizRevealed);document.body.dataset.quizRevealed=String(quizRevealed);}\nconst svgNS = 'http://www.w3.org/2000/svg';\nfunction node(tag, attrs = {}) { const el = document.createElementNS(svgNS, tag); for (const [k,v] of Object.entries(attrs)) el.setAttribute(k,v); return el; }\nfunction draw() {\n const v = variants[selected], plot = $('#plot'); plot.replaceChildren();\n $('#facts').textContent = viz.t('fact'+selected);\n $('#duration').textContent = viz.t('clip') + ' ' + (v.score.beats * 60 / v.score.bpm).toFixed(1) + ' ' + viz.t('seconds');\n $('#notation').textContent = v.notation;\n if (MODEL.mode === 'partials') {\n const e=v.score.events[0], p=e.partials;\n $('#envelope-panel').hidden=false;\n const envelope=$('#envelope-plot');envelope.replaceChildren();\n const attack=Math.min(e.attack,e.duration/2),points=[[12,108],[12+516*attack/e.duration,12]];\n for(let i=1;i<=60;i++){const t=attack+(e.duration-attack)*i/60,amplitude=Math.pow(.0001/(.05*e.gain),(t-attack)/(e.duration-attack));points.push([12+516*t/e.duration,108-amplitude*96]);}\n points.push([528,108]);envelope.append(node('polyline',{points:points.map(p=>p.join(',')).join(' '),fill:'none',stroke:'var(--accent)','stroke-width':3}));\n for(let i=0;i<4;i++) {\n plot.append(node('rect',{x:40+i*125,y:160-(p[i]||0)*125,width:58,height:(p[i]||0)*125,fill:'var(--accent)'}));\n const t=node('text',{x:69+i*125,y:185,'text-anchor':'middle',fill:'var(--ink)','font-size':18}); t.textContent=(i+1)+'×';plot.append(t);\n }\n } else {\n const events=v.score.events, min=MODEL.min??Math.min(...events.map(e=>e.midi)), max=MODEL.max??Math.max(...events.map(e=>e.midi));\n for(let i=0;i<=v.score.beats;i++) plot.append(node('line',{x1:12+i/v.score.beats*516,x2:12+i/v.score.beats*516,y1:16,y2:170,stroke:'var(--rule)'}));\n for(const e of events){\n const x=12+e.beat/v.score.beats*516;\n if(MODEL.mode==='pulse') plot.append(node('rect',{x,y:166-e.gain*140,width:Math.max(4,516/v.score.beats*.38),height:e.gain*140,rx:3,fill:'var(--accent)'}));\n else { const y=160-(e.midi-min)/Math.max(1,max-min)*130; plot.append(node('rect',{x,y:y-4,width:Math.max(4,Math.min(528-x,e.duration*v.score.bpm/60/v.score.beats*516)),height:8,rx:3,fill:e.layer==='bass'?'var(--ink)':'var(--accent)',opacity:e.layer==='chord'?'.45':'1'})); }\n }\n }\n if(MODEL.mode!=='partials') plot.append(node('line',{id:'cursor',x1:12,x2:12,y1:10,y2:177,stroke:'var(--ink)','stroke-width':2,visibility:'hidden'}));\n const groups=$('#groups'); groups.replaceChildren();\n for (const label of v.groups || []) {const chip=document.createElement('span');chip.textContent=label;groups.append(chip);}\n if(MODEL.blind)visibility();\n [...$('#variants').children].forEach((b,i)=>b.setAttribute('aria-pressed',String(i===selected)));\n}\nconst player=viz.audio({onState(state){document.body.dataset.audioState=state;$('#play').disabled=state!=='idle';$('#stop').disabled=state==='idle';$('#status').textContent=viz.t(state==='idle'?'idle':state==='starting'?'starting':'playing');},onTick(beat){const fraction=beat<0?0:Math.min(1,beat/variants[selected].score.beats);$('#progress').style.width=(fraction*100)+'%';const cursor=$('#cursor');if(cursor){cursor.setAttribute('x1',12+fraction*516);cursor.setAttribute('x2',12+fraction*516);cursor.setAttribute('visibility',beat<0?'hidden':'visible');}const chips=[...$('#groups').children];chips.forEach((el,i)=>el.classList.toggle('is-current',beat>=0&&i===Math.min(chips.length-1,Math.floor(fraction*chips.length))));},onError(){$('#status').textContent=viz.t('error');}});\nvariants.forEach((v,i)=>{const b=document.createElement('button');b.type='button';b.dataset.variant=i;b.textContent=viz.t('option'+i);b.onclick=()=>{player.stop();selected=i;draw();};$('#variants').append(b);});\n$('#play').onclick=()=>player.play(variants[selected].score);\n$('#stop').onclick=()=>player.stop();\n$('#volume').oninput=e=>player.setVolume(Number(e.target.value)/100);\ndocument.body.dataset.audioState='idle';draw();\n\nif(MODEL.blind){\n const panel=document.createElement('div');panel.className='mf-actions';panel.id='blind-answers';\n const result=document.createElement('p');result.className='mf-facts';result.id='blind-feedback';result.setAttribute('role','status');result.textContent=viz.t('before');\n for(const [key,correct]of [['choose_p',true],['choose_q',false],['reveal',null]]){const b=document.createElement('button');b.type='button';b.textContent=viz.t(key);b.dataset.blindAnswer=key;b.onclick=()=>{player.stop();quizRevealed=true;visibility();result.textContent=(correct===null?'':viz.t(correct?'correct':'wrong')+' ')+viz.t('comparison_correct');};panel.append(b);}\n $('#variants').after(panel,result);\n}\n","audio":true,"strings":{"axis":"時間 →・上ほど高い音","choose":"版を選ぶ","clip":"全長:","envelope":"時間に対する振幅 →(1.4 秒)。ピークまで上がり、その後減衰します。立ち上がりに使う時間を比べましょう。","error":"音声を開始できませんでした。再試行するか、図と文章で確認してください。","fact0":"A は E G A G のまま。後半に低音、和音、パルスを加えます。厚みが増すだけで新しい旋律になるわけではありません。","fact1":"E G A G が E G A C に。同じ出だしとリズムが、変奏として聴く手がかりになります。","fact2":"E G A G が C B G D に。リズムと伴奏は同じまま、より多くの音高関係が変わります。","heading":"境目で何が変わった?","idle":"版を選んで再生します。変更すると停止し、各クリップは最後で自動停止します。","intro":"四拍ずつの二単位を比較。パートの追加、旋律の局所的な変化、対照的なフレーズを区別します。","key":"左から右へ読みます。棒は発音の開始と設定した長さ、上下の重なりは同時発音です。音名と説明でも確認できます。","option0":"同じ旋律・層を追加","option1":"A → A′・一音変更","option2":"A → B・対照","play":"この版を再生","playing":"再生中。いつでも停止できます。","seconds":"秒","starting":"音声を準備中…","stop":"停止","volume":"音量"}}
まず上の旋律、次に全体を聴きます。最初の組は後半が厚くなりますが、旋律は正確な反復です。A′ の組は E–G–A の出だしが共通なので、末尾の変更を探しやすいでしょう。A–B の C–B–G–D は、この小さな例ではより大きな旋律上の対照を作ります。
音量や密度が増した箇所をすべて「サビ」と呼ぶと、この違いを見失います。コーラスやサビは曲全体の中での役割であり、音楽や歌詞の反復などに関わります。音量だけでは判断できず、そもそもヴァースとコーラスの構成を使わない曲もあります。
新しい並びに見取り図を付ける
四音のアイデア X、最後の音だけが違う X、対照的な Y、元の X が順に現れます。最初の二つの関係を残すには、どう文字で表せますか。最後の X に打楽器が加わったら、旋律にも必ず新しい文字が必要でしょうか。
根拠のある分析例を見る
A–A′–B–A が一つの有用な表し方です。A′ が関連する変奏、B が対照、最後の A が回帰を記録します。最後は「打楽器追加」と注記し、旋律のラベルは A のままで構いません。パートの追加だけでは旋律の同一性は変わらないからです。
これは追う水準を明示した答えです。別にテクスチュアの図を作れば、最後の入口を変化として示せます。すべての差を一列の文字に押し込まず、複数の層を記述してよいのです。
総合課題:八小節を読み、聴き、編集する
次のフレーズは八小節です。再生せず第一小節を読みましょう。ト音記号、4/4、四分音符四つ E4–G4–A4–G4 です。四拍数えてから聴き、第六小節を選んで一音の変奏を譜面で探します。
図を準備しています
総合練習:八小節の小品初期配置は A A B A A A′ B A、四分音符 = 100。C の長三和音の伴奏を固定し、旋律だけでも聴けます。各小節をト音記号の譜表で読めます。
{"id":"music-final-piece","title":"総合練習:八小節の小品","summary":"初期配置は A A B A A A′ B A、四分音符 = 100。C の長三和音の伴奏を固定し、旋律だけでも聴けます。各小節をト音記号の譜表で読めます。","height":800,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"mf-intro\" data-i18n=\"intro\"></p>\n<div id=\"controls\" class=\"mf-controls\"></div><div id=\"sheet\"></div><p id=\"meta\" class=\"mf-meta\"></p>\n<div id=\"answers\" class=\"mf-answers\" role=\"group\" data-i18n-label=\"question\"></div><div id=\"quiz-actions\" class=\"mf-actions\"></div>\n<p id=\"feedback\" class=\"mf-feedback\" role=\"status\" aria-live=\"polite\"></p>\n<div class=\"mf-actions\"><button id=\"play\" data-i18n=\"play\"></button><button id=\"stop\" data-i18n=\"stop\" disabled></button></div><p id=\"status\" class=\"mf-meta\" role=\"status\" data-i18n=\"idle\"></p>\n<label class=\"mf-volume\"><span data-i18n=\"volume\"></span><input id=\"volume\" type=\"range\" min=\"0\" max=\"100\" value=\"65\"></label>\n","css":"body{padding:24px}h2{font-size:22px;line-height:1.4}p{line-height:1.75}.mf-intro{color:var(--muted);margin:10px 0 18px}.mf-staff{display:block;width:100%;height:auto;max-height:270px;color:var(--ink);background:var(--surface);border:1px solid var(--rule);border-radius:8px;margin:16px 0}.mf-controls,.mf-actions,.mf-answers{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0}button,select{min-height:46px;font-size:16px}button{white-space:normal;line-height:1.5}.mf-controls button,.mf-answers button{flex:1 1 64px}.mf-actions button{flex:1 1 110px}label{display:flex;gap:8px;align-items:center;flex-wrap:wrap;font-size:16px;margin:12px 0}select{max-width:100%;background:var(--paper);color:var(--ink);border:1px solid var(--rule);padding:8px;border-radius:6px}.mf-feedback{border-left:3px solid var(--accent);padding:12px;background:var(--surface);min-height:3.5em;margin:14px 0;font-size:16px}.mf-meta{font-size:14px;color:var(--muted);margin:10px 0}.mf-staff [data-current=true]{color:var(--accent);filter:drop-shadow(0 0 1px currentColor)}.mf-staff [data-current=true] path{fill:currentColor}.mf-queue{display:flex;flex-wrap:wrap;gap:8px}.mf-queue button{min-width:50px}.mf-queue button[aria-pressed=true]{border-color:var(--accent);background:var(--accent-soft)}.mf-score{font-variant-numeric:tabular-nums}.mf-volume{display:flex;gap:12px;align-items:center;font-size:14px;border-top:1px solid var(--rule);padding-top:12px}.mf-volume input{min-width:80px;max-width:180px}.mf-answer-note{color:var(--muted);font-size:14px}button[aria-pressed=true]{background:var(--accent-soft);border-color:var(--accent)}[hidden]{display:none!important}@media(max-width:420px){body{padding:20px 14px}h2{font-size:20px}.mf-controls button{flex-basis:75px}}\n\n.mf-answers button{border:1px solid var(--rule);background:var(--surface);border-radius:8px;min-height:52px;padding:10px 14px;cursor:pointer}.mf-answers button:not(:disabled):hover{border-color:var(--accent);background:var(--accent-soft)}.mf-answers button:focus-visible{outline:2px solid var(--accent);outline-offset:3px}.mf-answers button[aria-pressed=true]{border:2px solid var(--accent);background:var(--accent-soft);font-weight:600}.mf-answers button:disabled{cursor:default}\n","js":"const GLYPHS = {\"treble\":\"M376 415C374 427 376 428 382 434C398 449 419 470 438 491C522 583 572 702 572 815C572 902 548 988 507 1048C492 1070 466 1098 455 1098C441 1098 410 1072 390 1050C316 968 292 843 292 739C292 681 299 616 306 575C308 563 309 561 297 551C233 498 164 437 112 373C43 287 0 194 0 87C0 -87 119 -252 364 -252C387 -252 413 -250 433 -246C444 -244 446 -243 448 -255C460 -322 475 -409 475 -456C475 -604 375 -622 316 -622C262 -622 236 -606 236 -593C236 -586 245 -583 268 -576C299 -567 335 -540 335 -482C335 -427 300 -380 239 -380C172 -380 132 -433 132 -495C132 -560 171 -658 322 -658C389 -658 519 -628 519 -458C519 -401 501 -306 490 -244C488 -232 489 -233 503 -227C604 -187 671 -102 671 11C671 139 577 252 430 252C404 252 404 252 401 270ZM470 943C503 943 530 916 530 861C530 792 497 728 419 650C403 634 379 611 356 591C349 585 345 586 343 599C339 625 337 659 337 691C337 847 409 943 470 943ZM361 262C364 243 364 244 346 238C258 208 201 129 201 44C201 -46 248 -110 316 -133C324 -136 336 -139 343 -139C351 -139 355 -134 355 -128C355 -121 347 -118 340 -115C298 -97 268 -54 268 -8C268 49 307 92 368 109C384 113 386 112 388 101L438 -197C440 -208 439 -208 424 -211C408 -214 388 -216 368 -216C193 -216 80 -119 80 20C80 79 90 158 173 252C233 319 279 356 326 394C336 402 338 401 340 390ZM430 103C428 115 429 118 441 117C522 110 589 42 589 -46C589 -109 551 -160 495 -188C483 -194 481 -194 479 -182Z\",\"bass\":\"M252 262C78 262 0 135 0 39C0 -41 42 -110 123 -110C186 -110 229 -66 229 -4C229 60 182 100 133 100C106 100 96 93 83 93C70 93 67 101 67 111C67 151 127 224 229 224C335 224 381 120 381 -37C381 -140 359 -260 297 -356C237 -449 134 -534 10 -605C1 -610 -5 -615 -5 -623C-5 -629 -1 -635 8 -635C13 -635 19 -633 25 -630C158 -565 286 -489 392 -375C479 -281 531 -159 531 -28C531 146 425 262 252 262ZM629 180C598 180 574 156 574 125C574 94 598 70 629 70C660 70 684 94 684 125C684 156 660 180 629 180ZM630 -71C599 -71 576 -94 576 -125C576 -156 599 -179 630 -179C661 -179 684 -156 684 -125C684 -94 661 -71 630 -71Z\",\"black\":\"M97 -125C186 -125 295 -43 295 42C295 93 255 125 198 125C88 125 0 44 0 -42C0 -94 43 -125 97 -125Z\",\"half\":\"M97 -125C262 -125 295 9 295 42C295 93 254 125 196 125C47 125 0 10 0 -42C0 -95 42 -125 97 -125ZM173 -46C128 -76 97 -87 75 -87C54 -87 42 -76 35 -64C32 -58 29 -51 29 -44C29 -22 51 5 120 45C170 74 201 84 221 84C240 84 251 75 258 63C261 57 264 51 264 44C264 24 243 0 173 -46Z\",\"whole\":\"M216 125C83 125 0 70 0 2C0 -65 57 -125 206 -125C370 -125 422 -68 422 2C422 73 309 125 216 125ZM111 63C122 98 159 103 190 103C259 103 314 29 314 -31C314 -38 313 -44 312 -50C307 -75 293 -92 268 -98C258 -101 247 -102 237 -102C228 -102 220 -101 211 -98C194 -93 178 -84 164 -72C156 -65 149 -58 143 -50C123 -27 108 7 108 39C108 47 109 55 111 63Z\",\"flag\":\"M238 -790C238 -790 264 -695 264 -617C264 -492 212 -374 149 -274C98 -195 56 -109 40 -13C37 3 29 9 19 9C8 9 0 6 0 -6V-245C66 -257 161 -393 197 -478C212 -512 221 -569 221 -628C221 -673 214 -720 197 -765C195 -771 194 -776 194 -780C194 -796 204 -805 210 -809C211 -810 213 -810 215 -810C222 -810 234 -804 238 -790Z\",\"quarterRest\":\"M78 -38C94 -58 108 -77 121 -98C123 -102 127 -110 127 -112C127 -113 127 -115 126 -116C124 -120 120 -121 115 -121C111 -121 103 -119 99 -118C94 -118 88 -115 83 -115C40 -115 1 -158 1 -211C1 -261 44 -310 117 -366C125 -372 135 -375 143 -375C150 -375 157 -373 158 -369C159 -366 160 -364 160 -362C160 -353 152 -345 144 -338C131 -338 120 -311 118 -302C115 -294 114 -285 114 -276C114 -245 129 -210 161 -204C166 -203 171 -203 177 -203C206 -203 239 -214 255 -220C256 -220 257 -221 258 -221C261 -222 263 -222 265 -222C268 -222 270 -221 270 -218C270 -206 244 -173 233 -161C195 -115 164 -78 164 -22C164 -18 165 -13 165 -9C169 49 205 97 231 138C234 143 235 148 235 153C235 163 231 172 231 172C231 172 83 348 66 365C61 370 54 373 48 373C38 373 28 366 28 352C28 347 29 342 32 336C36 325 93 274 93 202C93 165 78 122 33 75C23 65 19 54 19 46C19 32 29 22 29 22Z\",\"eighthRest\":\"M134 107C134 144 104 174 67 174C30 174 0 144 0 107C0 86 12 68 27 56C36 50 45 45 55 43C63 41 72 39 81 39C95 39 109 42 120 46C134 50 143 54 156 61C158 62 160 62 161 62C165 62 166 58 166 53C166 50 166 46 165 42C162 27 90 -172 72 -238C72 -250 95 -251 101 -251C112 -251 126 -249 136 -241C139 -239 237 112 237 112C241 130 246 146 247 151C247 161 237 166 235 167C233 167 230 167 224 163C217 157 167 97 134 97Z\",\"halfRest\":\"M282 24V116C282 131 270 142 256 142H26C11 142 0 131 0 116V24C0 10 11 -2 26 -2H256C270 -2 282 10 282 24Z\",\"wholeRest\":\"M282 -109V-17C282 -2 270 9 256 9H26C11 9 0 -2 0 -17V-109C0 -123 11 -135 26 -135H256C270 -135 282 -123 282 -109Z\",\"sharp\":\"M237 118C244 121 249 129 249 135V206C249 211 246 214 242 214C240 214 239 214 237 213C237 213 217 205 212 204C205 204 198 209 198 217V339C198 345 192 350 184 350C174 350 168 345 168 339V209C167 199 164 186 155 180C143 173 109 159 92 155C83 155 80 167 80 175V295C80 301 73 306 66 306C56 306 50 301 50 295V160C50 146 44 136 38 133C32 130 12 122 12 122C5 120 0 112 0 106V35C0 29 3 26 8 26C9 26 11 27 12 27C12 27 27 33 34 37C35 37 36 38 37 38C44 38 50 28 50 20V-79C50 -90 45 -99 39 -102C33 -104 12 -113 12 -113C5 -115 0 -123 0 -129V-200C0 -206 3 -209 8 -209C9 -209 11 -208 12 -208C12 -208 26 -202 35 -199C36 -198 37 -198 38 -198C45 -198 50 -209 50 -214V-337C50 -343 56 -348 63 -348C73 -348 80 -343 80 -337V-198C80 -185 85 -178 90 -176L151 -151C152 -151 154 -150 155 -150C163 -150 168 -162 168 -168V-293C168 -299 174 -304 181 -304C192 -304 198 -299 198 -293V-151C198 -143 202 -131 209 -128C216 -125 237 -117 237 -117C244 -114 249 -106 249 -100V-29C249 -24 246 -21 242 -21C240 -21 239 -21 237 -22L211 -32C205 -32 198 -26 198 -14V79C198 86 203 105 211 108ZM168 -45C162 -65 115 -85 92 -85C86 -85 81 -83 80 -80C78 -76 77 -54 77 -30C77 1 78 36 80 44C82 61 128 82 153 82C160 82 166 80 168 76C170 71 172 46 172 19C172 -8 170 -36 168 -45Z\",\"flat\":\"M12 -170C15 -174 18 -175 21 -175C24 -175 27 -173 27 -173C57 -156 81 -129 106 -112C195 -50 226 11 226 57C226 114 182 150 136 153C129 153 122 152 115 150C104 147 92 143 81 136C75 131 64 122 59 122C57 122 56 122 54 123C47 126 43 133 43 140C44 162 50 402 50 422C50 433 41 439 31 439C17 439 1 429 0 411C0 411 4 -160 12 -170ZM47 -81C47 -81 44 -21 44 19C44 35 45 47 46 51C50 63 76 85 90 93C99 98 108 100 116 100C126 100 135 96 141 89C151 78 157 61 157 42C157 24 152 3 140 -18C127 -42 98 -74 68 -93C64 -95 61 -96 58 -96C49 -96 47 -86 47 -81Z\",\"natural\":\"M141 181C139 181 138 180 137 180C137 180 73 157 47 157C41 157 37 158 37 162V329C37 336 31 341 25 341H12C5 341 0 336 0 329V-186C0 -192 3 -195 8 -195C9 -195 11 -194 12 -194C12 -194 14 -194 15 -193C29 -187 85 -163 114 -163C124 -163 131 -166 131 -174V-323C131 -330 136 -335 143 -335H156C162 -335 168 -330 168 -323V179C168 184 164 187 160 187C159 187 157 187 156 186ZM37 39C37 53 98 79 122 79C128 79 131 78 131 74V-29C131 -47 74 -70 49 -70C42 -70 37 -68 37 -64Z\",\"flagDown\":\"M240 760C254 718 261 668 261 623C261 564 236 480 221 446C184 362 134 281 0 236V1C0 -9 8 -14 16 -14C25 -14 38 -8 40 8C57 103 131 190 182 269C245 368 306 487 306 612C306 690 286 761 278 793C275 804 269 808 262 808C250 808 237 796 237 777C237 772 238 766 240 760Z\"};\n// Small SVG engraver for the deliberately limited notation taught in this course.\n// Bravura outlines: Steinberg, SIL OFL 1.1; see engraving/OFL.txt.\nconst MusicStaff=(()=>{\n const ns='http://www.w3.org/2000/svg',letters=['C','D','E','F','G','A','B'],pcs=[0,2,4,5,7,9,11];\n const el=(tag,attrs={})=>{const n=document.createElementNS(ns,tag);for(const [k,v] of Object.entries(attrs))n.setAttribute(k,v);return n;};\n const parse=p=>{const m=p.match(/^([A-G])([♯♭♮]?)([0-8])$/);if(!m)throw Error('invalid written pitch');const letter=letters.indexOf(m[1]),oct=+m[3],alter=m[2]==='♯'?1:m[2]==='♭'?-1:0;return {step:oct*7+letter,midi:(oct+1)*12+pcs[letter]+alter,alter,sign:m[2],name:p};};\n const fromStep=(step,alter=0)=>letters[((step%7)+7)%7]+(alter>0?'♯':alter<0?'♭':'')+Math.floor(step/7);\n const fromMidi=(m,flat=false)=>{const names=flat?['C','D♭','D','E♭','E','F','G♭','G','A♭','A','B♭','B']:['C','C♯','D','D♯','E','F','F♯','G','G♯','A','A♯','B'];return names[m%12]+(Math.floor(m/12)-1);};\n function glyph(parent,name,x,y,gap){parent.append(el('path',{d:GLYPHS[name],transform:`translate(${x} ${y}) scale(${gap/250} ${-gap/250})`,fill:'currentColor'}));}\n function render({clef='treble',notes=[],meter=null,key=null,labels=false,small=false,answerLabel='',barEnds=[]}={}){\n const gap=small?12:16,bottom=small?92:114,width=Math.max(300,Math.min(660,110+notes.length*66)),height=small?158:196;\n const svg=el('svg',{viewBox:`0 0 ${width} ${height}`,class:'mf-staff',role:'img','aria-label':answerLabel||viz.t('staff_description')});\n const line=(x1,y1,x2,y2,w=1)=>svg.append(el('line',{x1,y1,x2,y2,stroke:'currentColor','stroke-width':w,opacity:.7}));\n for(let i=0;i<5;i++)line(12,bottom-i*gap,width-12,bottom-i*gap);\n glyph(svg,clef,24,clef==='treble'?bottom-gap:bottom-3*gap,gap);\n let left=80;\n if(key==='G'){glyph(svg,'sharp',left,bottom-4*gap,gap);left+=32;}\n if(meter){const [n,d]=meter.split('/');for(const [v,y] of [[n,bottom-2.65*gap],[d,bottom-.7*gap]]){const t=el('text',{x:left,y,'font-size':gap*1.9,'font-weight':700,'text-anchor':'middle',fill:'currentColor'});t.textContent=v;svg.append(t);}left+=30;}\n const base=clef==='treble'?30:18,positions=[];\n notes.forEach((n,i)=>{\n const x=left+(i+.5)*(width-24-left)/Math.max(1,notes.length),group=el('g',{'data-note-index':i});svg.append(group);positions.push(x);\n if(n.blank){group.append(el('rect',{x:x-11,y:bottom-2*gap-13,width:22,height:26,fill:'var(--paper)',stroke:'currentColor','stroke-dasharray':'3 2'}));}\n else if(n.rest){glyph(group,({4:'wholeRest',2:'halfRest',1:'quarterRest','0.5':'eighthRest'})[n.value]||'quarterRest',x-6,bottom-(n.value===4?3:2)*gap,gap);}\n else{\n const pitches=n.chord||[n.pitch];\n for(const pitch of pitches){const p=parse(pitch),pos=p.step-base,y=bottom-pos*gap/2;\n for(let k=-2;k>=pos;k-=2)line(x-14,bottom-k*gap/2,x+14,bottom-k*gap/2,1.4);\n for(let k=10;k<=pos;k+=2)line(x-14,bottom-k*gap/2,x+14,bottom-k*gap/2,1.4);\n glyph(group,n.value===4?'whole':n.value===2?'half':'black',x-gap*.59,y,gap);\n if(p.sign)glyph(group,p.sign==='♯'?'sharp':p.sign==='♭'?'flat':'natural',x-gap*1.7,y,gap);\n if(n.dot)group.append(el('circle',{cx:x+gap*.95,cy:y-(pos%2===0?gap/2:0),r:gap*.13,fill:'currentColor'}));\n }\n const ps=pitches.map(parse).map(p=>p.step-base),highest=Math.max(...ps),lowest=Math.min(...ps),down=(highest+lowest)/2>=4;\n if(n.value!==4){const stemx=x+(down?-gap*.55:gap*.55),from=bottom-(down?highest:lowest)*gap/2,to=bottom-(down?lowest:highest)*gap/2+(down?gap*3.5:-gap*3.5);group.append(el('line',{x1:stemx,x2:stemx,y1:from,y2:to,stroke:'currentColor','stroke-width':1.5}));\n if(n.value===.5){glyph(group,down?'flagDown':'flag',stemx,to,gap);}\n }\n }\n if(labels){const text=el('text',{x,y:height-15,'font-size':14,'text-anchor':'middle',fill:'currentColor'});text.textContent=n.rest?viz.t('rest'):(n.chord||[n.pitch]).join(' ');svg.append(text);}\n if(n.barAfter||barEnds.includes(i))line(x+(width-24-left)/notes.length*.48,bottom,x+(width-24-left)/notes.length*.48,bottom-4*gap,1.5);\n });\n for(let i=0;i<notes.length-1;i++)if(notes[i].tie){const x=positions[i],x2=positions[i+1],pos=parse(notes[i].pitch).step-base,direction=pos>=4?-1:1,y=bottom-pos*gap/2+direction*gap;svg.append(el('path',{d:`M ${x} ${y} Q ${(x+x2)/2} ${y+direction*gap} ${x2} ${y}`,fill:'none',stroke:'currentColor','stroke-width':1.5}));}\n line(width-12,bottom,width-12,bottom-4*gap,1.5);return svg;\n }\n function score(notes,bpm=90){let beat=0;const events=[];notes.forEach(n=>{const length=n.value*(n.dot?1.5:1);if(!n.rest){if(n.continueTie){const last=events[events.length-1];last.duration+=length*60/bpm;}else for(const p of n.chord||[n.pitch])events.push({beat,hz:440*2**((parse(p).midi-69)/12),duration:length*60/bpm*.94,gain:.8,wave:'triangle',hold:true});}beat+=length;});return {bpm,beats:beat,events};}\n return {render,parse,fromStep,fromMidi,score};\n})();\n\nconst PRACTICE = {\"kind\": \"form\", \"bars\": 8};\nconst $=s=>document.querySelector(s),t=viz.t;\nfunction make(tag,attrs={},text=''){const e=document.createElement(tag);for(const [k,v]of Object.entries(attrs))e.setAttribute(k,v);e.textContent=text;return e;}\nfunction button(parent,key,fn,attrs={}){const b=make('button',{type:'button',...attrs},t(key));b.onclick=fn;parent.append(b);return b;}\nfunction select(parent,key,items,fn,id){const label=make('label',{},t(key)),s=make('select',{id});for(const [value,k]of items)s.append(make('option',{value},t(k)));s.onchange=()=>{player.stop();fn(s.value);};label.append(s);parent.append(label);return s;}\nlet tickAction=()=>{},currentScore=null;\nconst player=viz.audio({onState(s){document.body.dataset.audioState=s;$('#status').textContent=t(s==='idle'?'idle':s==='starting'?'starting':'playing');$('#stop').disabled=s==='idle';},onTick:b=>tickAction(b),onError:()=>$('#status').textContent=t('error')});\n$('#stop').onclick=()=>player.stop();$('#volume').oninput=e=>player.setVolume(+e.target.value/100);\n$('#play').onclick=()=>{if(currentScore)player.play(currentScore);};document.body.dataset.audioState='idle';\nconst controls=$('#controls'),answers=$('#answers'),feedback=$('#feedback'),sheet=$('#sheet'),meta=$('#meta');\nconst staff=(notes,extra={})=>{sheet.replaceChildren(MusicStaff.render({notes,...extra}));};\nconst note=pitch=>({pitch,value:1});\nfunction highlight(beat,notes){let at=0;for(const [i,n]of notes.entries()){const end=at+n.value*(n.dot?1.5:1);const g=sheet.querySelector(`[data-note-index=\"${i}\"]`);g?.setAttribute('data-current',String(beat>=at&&beat<end));at=end;}}\nconst shuffle=a=>{a=[...a];for(let i=a.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[a[i],a[j]]=[a[j],a[i]];}return a;};\nif(PRACTICE.kind==='map'){\n let clef='treble',step=32,alter=0;\n select(controls,'clef',[['treble','treble'],['bass','bass']],v=>{clef=v;step=v==='treble'?32:24;draw();},'clef');\n const row=make('div',{class:'mf-controls'});controls.append(row);\n button(row,'down',()=>{player.stop();step=Math.max(clef==='treble'?28:16,step-1);draw();},{id:'pitch-down'});\n button(row,'up',()=>{player.stop();step=Math.min(clef==='treble'?39:28,step+1);draw();},{id:'pitch-up'});\n select(controls,'accidental',[['0','natural'],['1','sharp'],['-1','flat']],v=>{alter=+v;draw();},'accidental');\n function draw(){const pitch=MusicStaff.fromStep(step,alter),notes=[note(pitch)];staff(notes,{clef,labels:true});feedback.textContent=pitch+' · '+t('position')+' '+(step-(clef==='treble'?30:18));meta.textContent=t('anchor_'+clef)+(step<(clef==='treble'?30:18)||step>(clef==='treble'?38:26)?' '+t('ledger'):'');currentScore=MusicStaff.score(notes);tickAction=b=>highlight(b,notes);}\n draw();\n}else if(['pitchQuiz','rhythmQuiz','keyQuiz'].includes(PRACTICE.kind)){\n let clefMode='treble',altered=false,deck=[],index=0,choice=null,answered=false,usedHint=false,assisted=0,correct=0;\n const stats=make('p',{class:'mf-meta mf-score',id:'round-score'});controls.append(stats);\n if(PRACTICE.kind==='pitchQuiz'){\n select(controls,'clef',[['treble','treble'],['bass','bass'],['mixed','mixed']],v=>{clefMode=v;start();},'clef');\n select(controls,'difficulty',[['plain','plain'],['altered','altered']],v=>{altered=v==='altered';start();},'difficulty');\n }\n const action=make('div',{class:'mf-actions'});$('#quiz-actions').append(action);\n const check=button(action,'check',()=>finish(false),{id:'check',disabled:''});\n const hint=button(action,'hint',()=>{if(!answered)usedHint=true;meta.textContent=hintText();},{id:'hint'});\n const reveal=button(action,'reveal',()=>finish(true),{id:'reveal'});\n const next=button(action,'next',()=>{if(index<deck.length-1){index++;draw();}else{feedback.textContent=t('finished');next.disabled=true;}},{id:'next',disabled:''});\n button(action,'restart',start,{id:'restart'});\n function bank(){\n if(PRACTICE.kind==='pitchQuiz'){\n const clefs=clefMode==='mixed'?['treble','bass']:[clefMode],qs=[];\n for(const clef of clefs)for(let step=clef==='treble'?28:16;step<=(clef==='treble'?39:28);step++){const alter=altered?[0,1,-1][Math.floor(Math.random()*3)]:0,pitch=MusicStaff.fromStep(step,alter);qs.push({clef,step,pitch,answer:pitch,notes:[note(pitch)]});}\n return shuffle(qs).slice(0,12);\n }\n if(PRACTICE.kind==='rhythmQuiz')return shuffle([\n ['4/4',[note('C5'),{rest:true,value:1},{pitch:'C5',value:.5},{pitch:'C5',value:.5}],1],\n ['3/4',[note('C5'),note('C5')],1],['4/4',[{pitch:'C5',value:2},note('C5')],1],\n ['3/4',[{pitch:'C5',value:1,dot:true},{pitch:'C5',value:.5}],1],\n ['4/4',[{rest:true,value:2}],2],['6/8',[{pitch:'C5',value:1,dot:true},note('C5')],.5],\n ['6/8',[{pitch:'C5',value:.5},{rest:true,value:.5},note('C5')],1],\n ['4/4',[{pitch:'C5',value:1,dot:true},note('C5')],1.5],['3/4',[note('C5')],2],\n ['4/4',[{rest:true,value:1}],3],['3/4',[{rest:true,value:.5},note('C5')],1.5],['6/8',[{pitch:'C5',value:.5},{pitch:'C5',value:.5}],2]\n ].map(([meter,notes,missing])=>({meter,notes,missing,answer:String(missing),clef:'treble'})));\n return shuffle([\n {notes:[{pitch:'F4',value:4}],target:0,answer:'F♯4',sounds:['F♯4']},\n {notes:[note('F♮4'),note('F4'),note('G4'),note('A4')],target:1,answer:'F4',sounds:['F4','F4','G4','A4']},\n {notes:[{pitch:'F♮4',value:4,barAfter:true},{pitch:'F4',value:4}],target:1,answer:'F♯4',sounds:['F4','F♯4']},\n {notes:[{pitch:'F5',value:4}],target:0,answer:'F♯5',sounds:['F♯5']}\n ].map(q=>({...q,clef:'treble',key:'G',meter:'4/4'})));\n }\n function start(){player.stop();deck=bank();index=0;correct=0;assisted=0;draw();}\n function hintText(){const q=deck[index];if(PRACTICE.kind==='pitchQuiz')return t('anchor_'+q.clef)+' '+t('position')+' '+(q.step-(q.clef==='treble'?30:18));return t(PRACTICE.kind==='keyQuiz'?'key_hint':'bar_hint');}\n function draw(){player.stop();choice=null;answered=false;usedHint=false;check.disabled=true;next.disabled=true;reveal.disabled=false;hint.disabled=false;$('#play').disabled=PRACTICE.kind!=='pitchQuiz';feedback.textContent=t(PRACTICE.kind==='pitchQuiz'?'before':'before_check');meta.textContent=t(PRACTICE.kind==='pitchQuiz'?'question':PRACTICE.kind==='keyQuiz'?'key_prompt':'bar_prompt');answers.replaceChildren();\n const q=deck[index];let choices;\n if(PRACTICE.kind==='pitchQuiz'){const offsets=shuffle([-2,-1,1,2]).slice(0,2),accOther=MusicStaff.parse(q.pitch).alter===0?1:0;choices=shuffle([q.answer,...offsets.map(d=>MusicStaff.fromStep(q.step+d,MusicStaff.parse(q.pitch).alter)),MusicStaff.fromStep(q.step,accOther)]);staff(q.notes,{clef:q.clef});currentScore=MusicStaff.score(q.notes);}\n else if(PRACTICE.kind==='rhythmQuiz'){staff([...q.notes,{blank:true,value:q.missing}],{meter:q.meter});choices=['0.5','1','1.5','2','3','4'];currentScore=null;}\n else{staff(q.notes,{meter:q.meter,key:'G'});sheet.querySelector(`[data-note-index=\"${q.target}\"]`)?.setAttribute('data-current','true');meta.textContent+=' '+t('target_note')+' '+(q.target+1);choices=['F4','F♯4','F5','F♯5'];currentScore=MusicStaff.score(q.notes.map((n,i)=>({...n,pitch:q.sounds[i]})));}\n for(const c of choices){const b=make('button',{type:'button','data-answer':c,'aria-pressed':'false'},c==='0.5'?'½':c==='1.5'?'1½':c);b.onclick=()=>{if(answered)return;choice=c;check.disabled=false;[...answers.children].forEach(x=>x.setAttribute('aria-pressed',String(x===b)));};answers.append(b);}\n updateStats();tickAction=b=>highlight(b,q.notes);\n }\n function updateStats(){stats.textContent=t('round')+' '+(index+1)+' / '+deck.length+' · '+t('first_try')+' '+correct+' · '+t('assisted')+' '+assisted;}\n function finish(explicit){if(answered||(!explicit&&choice===null))return;player.stop();answered=true;if(explicit)usedHint=true;if(usedHint)assisted++;if(!usedHint&&choice===deck[index].answer)correct++;const q=deck[index];feedback.textContent=(explicit?'':t(choice===q.answer?'correct':'wrong')+' ')+t('answer')+' '+q.answer+'. '+hintText();\n if(PRACTICE.kind==='rhythmQuiz'){const missing=q.missing===3?{pitch:'C5',value:2,dot:true}:q.missing===1.5?{pitch:'C5',value:1,dot:true}:{pitch:'C5',value:q.missing};const ns=[...q.notes,missing];staff(ns,{meter:q.meter});currentScore=MusicStaff.score(ns);const sum=q.notes.reduce((a,n)=>a+n.value*(n.dot?1.5:1),0);feedback.textContent+=' '+t('bar_total')+' '+(sum+q.missing)+' − '+t('written')+' '+sum+' = '+q.missing;tickAction=b=>highlight(b,ns);}\n else if(PRACTICE.kind==='pitchQuiz')staff(q.notes,{clef:q.clef,labels:true});\n $('#play').disabled=false;check.disabled=true;reveal.disabled=true;hint.disabled=true;next.disabled=false;[...answers.children].forEach(b=>b.disabled=true);updateStats();}\n start();\n}else if(PRACTICE.kind==='symbols'){\n const kinds=[['whole',4,false,false],['half',2,false,false],['quarter',1,false,false],['eighth',.5,false,false],['dotted',1,false,true],['whole_rest',4,true,false],['half_rest',2,true,false],['quarter_rest',1,true,false],['eighth_rest',.5,true,false]];\n for(const [label,value,rest,dot] of kinds)button(controls,label,()=>draw(label,{pitch:'C5',value,rest,dot}));\n for(const tied of [true,false])button(controls,tied?'tied':'untied',()=>draw(tied?'tied':'untied',[{pitch:'C5',value:1,tie:tied},{pitch:'C5',value:1,continueTie:tied}]));\n function draw(label,n){player.stop();const notes=Array.isArray(n)?n:[n];staff(notes);feedback.textContent=t(label);meta.textContent=t('unit');const score=MusicStaff.score(notes);score.beats=4;for(let i=0;i<4;i++)score.events.push({beat:i,hz:1500,duration:.035,gain:.25});currentScore=score;tickAction=b=>highlight(b,notes);}\n draw('quarter',{pitch:'C5',value:1});\n}else if(PRACTICE.kind==='chord'){\n let root='C4',quality='major',inv=0;\n select(controls,'root',[['C4','C'],['D4','D'],['F4','F']],v=>{root=v;draw();},'root');\n select(controls,'quality',[['major','major'],['minor','minor']],v=>{quality=v;draw();},'quality');\n select(controls,'inversion',[['0','root_position'],['1','first_inversion'],['2','second_inversion']],v=>{inv=+v;draw();},'inversion');\n function draw(){const p=MusicStaff.parse(root),intervals=[0,quality==='major'?4:3,7],pitches=intervals.map((v,i)=>{const step=p.step+i*2,plain=MusicStaff.parse(MusicStaff.fromStep(step));return MusicStaff.fromStep(step,p.midi+v-plain.midi);});for(let i=0;i<inv;i++){const p=MusicStaff.parse(pitches.shift());pitches.push(MusicStaff.fromStep(p.step+7,p.alter));}const ns=[{chord:pitches,value:2}];staff(ns,{labels:false});feedback.textContent=t('root')+': '+root+' · '+t('quality')+': '+t(quality)+' · '+pitches.join(' – ');meta.textContent=t('chord_tip');currentScore=MusicStaff.score(ns);tickAction=b=>highlight(b,ns);}\n draw();\n}else if(PRACTICE.kind==='form'){\n const initial=PRACTICE.bars===8?['A','A','B','A','A','A′','B','A']:['A','A','B','A'];let order=[...initial],selected=0,melodyOnly=false;\n const material={A:['E4','G4','A4','G4'],'A′':['E4','G4','A4','C5'],B:['C5','B4','G4','D4']};\n const queue=make('div',{class:'mf-queue',id:'bar-queue'});controls.append(queue);\n const sel=select(controls,'material',[['A','A'],['A′','A′'],['B','B']],v=>{order[selected]=v;draw();},'material');\n const label=make('label'),box=make('input',{type:'checkbox',id:'melody-only'});label.append(box,make('span',{},t('melody_only')));controls.append(label);box.onchange=()=>{player.stop();melodyOnly=box.checked;draw();};\n button(controls,'reset',()=>{player.stop();order=[...initial];selected=0;draw();},{id:'reset'});\n button($('#quiz-actions'),'one_bar',()=>play(false),{id:'play-bar'});$('#play').textContent=t('full');$('#play').onclick=()=>play(true);\n function getScore(sequence){const s={bpm:100,beats:sequence.length*4,events:[]};sequence.forEach((name,bar)=>{const ns=material[name].map(note),m=MusicStaff.score(ns,100);s.events.push(...m.events.map(e=>({...e,beat:e.beat+bar*4})));if(!melodyOnly)for(const beat of [0,2])for(const midi of [36,48,52,55])s.events.push({beat:bar*4+beat,hz:440*2**((midi-69)/12),duration:.95,gain:midi===36?.65:.35,wave:'triangle'});});return s;}\n function draw(){queue.replaceChildren();order.forEach((m,i)=>{const b=make('button',{type:'button','data-bar':i,'aria-pressed':String(i===selected)},(i+1)+' · '+m);b.onclick=()=>{player.stop();selected=i;draw();};queue.append(b);});sel.value=order[selected];staff(material[order[selected]].map(note),{meter:'4/4'});feedback.textContent=order.join(' · ');meta.textContent=t('arrange_tip');}\n function play(all){const start=selected,sequence=all?order:[order[selected]];tickAction=beat=>{if(beat<0){highlight(-1,material[order[selected]].map(note));return;}const b=all?Math.min(order.length-1,Math.floor(beat/4)):start;if(b!==selected){selected=b;draw();}highlight(beat%4,material[order[selected]].map(note));};player.play(getScore(sequence));}\n draw();\n}\n","audio":true,"strings":{"accidental":"臨時記号","altered":"臨時記号を含む","anchor_bass":"基準:下から四番目、二つの点に挟まれた線が F3 です。","anchor_treble":"基準:下から二番目の線が G4。隣の線・間へ移るたび、音名を一つ進めます。","answer":"答え:","arrange_tip":"小節を選んで素材を替え、聴きます。譜面は選択した小節を表示し、全体再生中は現在の小節を追います。","assisted":"ヒント使用","bar":"小節","bar_hint":"拍子記号を四分音符の単位に換算し、書かれた音価の合計を小節全体から引きます。","bar_prompt":"この小節を完成させます。空欄に必要な長さを、四分音符の拍数で選んでください。","bar_total":"小節の合計","bass":"ヘ音記号","before":"答えを選び、解説で確かめましょう。","before_check":"答えを選んで確認するか、解説を表示します。","check":"答えを確認","choose_p":"移調は P","choose_q":"移調は Q","chord_tip":"下から上へ和音を読みます。転回形を変えても根音の名前は同じです。","clef":"音部記号","compare_title":"答えを選んでから図を見る","comparison_correct":"P は全音程を保ち、Q は内部の一音を変えています。表示された間隔を確かめましょう。","correct":"正解です。","difficulty":"出題範囲","dotted":"付点四分音符・1½","down":"一つ下の線・間へ","eighth":"八分音符・½","eighth_rest":"八分休符・½","error":"再生できませんでした。再試行するか文章で確認してください。","finished":"終了です。最後の解説を復習するか、新しいラウンドへ進みましょう。","first_inversion":"第一転回形","first_try":"初回で正解","flat":"フラット ♭","full":"全体を再生","half":"二分音符・2","half_rest":"二分休符・2","heading":"総合練習:八小節の小品","hint":"位置のヒント","idle":"再生を押すと音が鳴ります。編集すると停止します。","intro":"自作八小節を読み、旋律・低音・和音・回帰を追います。その後、意図して一か所編集し説明しましょう。","inversion":"最低音の位置","key_hint":"調号のシャープ一つは、臨時記号で変更されない限り全オクターブの F に効きます。小節線で臨時記号はリセットされますが、調号は残ります。","key_prompt":"調号と臨時記号を使って、示された音を読みます。","ledger":"短い加線で五線を延長します。数え方は五線内と同じです。","major":"長三和音","material":"選んだ小節の素材","melody_only":"旋律だけ","minor":"短三和音","missing":"不足分","mixed":"両方の音部記号","natural":"ナチュラル ♮","next":"次の問題","one_bar":"選んだ小節を再生","plain":"幹音","play":"再生","playing":"再生中…","position":"最下線からの段数(隣の線・間へ一つで 1):","pulse":"基準パルス","quality":"種類","quarter":"四分音符・1","quarter_rest":"四分休符・1","question":"オクターブと臨時記号も含めて読み、確認する前に答えを選びます。","reset":"最初の配置に戻す","rest":"休符","restart":"新しいラウンド","reveal":"解説を見る","root":"根音","root_position":"基本形","round":"進行","second_inversion":"第二転回形","sharp":"シャープ ♯","staff_description":"五線譜。譜面を見られない場合は位置の説明を使えます。","starting":"音声を準備中…","stop":"停止","symbols":"音符と休符の音価","target_note":"読む音の番号:","tied":"タイで結ぶ四分音符二つ・2","treble":"ト音記号","unit":"完全な小節ではなく記号の抜粋です。音価は四分音符の単位。試聴は四拍で、休符でも控えめなパルスが続きます。","untied":"別々の四分音符二つ・1 + 1","up":"一つ上の線・間へ","volume":"音量","whole":"全音符・4","whole_rest":"全休符・ここでは 4","written":"記載済み","wrong":"まだ違います。選んだ答えと解説を比べましょう。"}}
全体を聴き、次に旋律だけにします。低音と反復する C の長三和音を見つけ、B の後の A の回帰を追います。初期配置は A A B A A A′ B A。次に一小節を替え、元の配置をメモし、予想してから復元・再編集で比べましょう。
読譜を確認し、一つの編集を説明する
第六小節は A′:E4–G4–A4–C5。末尾が A の G4 と異なり、音価はすべて四分音符のままです。A の A4 は土台の C–E–G には含まれませんが、それだけで誤音にはなりません。旋律が変わっても低音は C です。
第八小節を A から B に替えると、最後の A の回帰がなくなります。終わりの素材は変わり、拍子とテンポは同じです。伴奏だけを消すなら、旋律の配置を保ってテクスチュアが変わります。どちらを編集したかを述べ、具体的な音やパートを根拠にしてください。
シリーズ全体を一つの録音に使う
好きな短い部分を選び、最初は分析せずに聴きます。二回目は時刻や紙の線で大まかな境目を記録し、具体的な観察をいくつか加えましょう。
- 時間:パルスは一定か。テンポが似たまま、アクセントや発音位置が変わるか。
- 音高:フレーズは反復、移調、それとも内部の音程の変更か。
- 和声:同じ旋律に別の低音や和音が付くか。どこが到着点に聞こえるか。
- 音と形式:どのパートが出入りするか。回帰は正確か、変奏か、主にテクスチュアが違うのか。
すべてに断定的な答えを出す必要はありません。聴こえたこと、確かめられること、まだ不確かなことを分けます。「0:40 ごろに旋律が戻り、低音が加わる」は、根拠のない形式名より有益です。
このシリーズの目標は、違いに気づき、音楽的な関係を指摘し、音に戻って確かめ、根拠を説明する習慣です。新しい問いを持って第 1 回を聴き直しても、読譜、聴音、自分の短い編曲へ進んでもよいでしょう。