音楽を聴くと、うなずいたり手で拍を刻んだりすることがあります。規則的なパターンもあれば、前へ押すように聞こえるものや、意外な空白のあるものもあります。
この違いを、すべて「速い」「遅い」で説明できるでしょうか。
拍が進む速さと、音が鳴る位置は、別々に変えられます。 この回では、まず耳でその違いを比べます。
「音楽の基礎」の第 1 回です。楽器も読譜の経験も必要ありません。短い二つのリズムを比べ、変わったのがテンポか発音位置かを説明することが目標です。
まず聴く:変化を感じるのはどちら?
機器の音量を快適な範囲にし、A と B を別々に聴きます。どちらも短く、最後まで行くと自動で止まります。規則的なのはどちらか、跳ねるように感じるのはどちらか、最初の印象を覚えておきましょう。差が小さく感じられても進めて構いません。
図を準備しています
二つの版を聴いて、音の位置を見るA と B はともに 100 BPM の二小節で、一小節に四回発音します。A は 1、2、3、4 拍目、B は 1 拍目、2 拍目の後半、3 拍目、4 拍目の後半です。音色、音量、全長は同じで、位置が異なります。
{"id":"music-rhythm-compare","title":"二つの版を聴いて、音の位置を見る","summary":"A と B はともに 100 BPM の二小節で、一小節に四回発音します。A は 1、2、3、4 拍目、B は 1 拍目、2 拍目の後半、3 拍目、4 拍目の後半です。音色、音量、全長は同じで、位置が異なります。","height":440,"html":"<p class=\"eyebrow\" data-i18n=\"eyebrow\"></p><h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p>\n<div class=\"actions\"><button class=\"audio-play\" data-listen=\"a\" aria-pressed=\"false\" data-i18n=\"a\"></button><button class=\"audio-play\" data-listen=\"b\" aria-pressed=\"false\" data-i18n=\"b\"></button><button id=\"stop\" disabled data-i18n=\"stop\"></button></div>\n<div class=\"options\"><label><input id=\"reference\" type=\"checkbox\"><span data-i18n=\"reference\"></span></label><button id=\"reveal\" aria-expanded=\"false\" data-i18n=\"reveal\"></button></div>\n<div id=\"comparison\" hidden><div class=\"readout\"><strong>100 <span>BPM</span></strong><span data-i18n=\"fixed\"></span></div><p class=\"row-title\">A <span data-i18n=\"a_hint\"></span></p><div class=\"grid\" id=\"grid-a\" data-track=\"a\"></div><p class=\"row-title\">B <span data-i18n=\"b_hint\"></span></p><div class=\"grid\" id=\"grid-b\" data-track=\"b\"></div><p class=\"hint\" data-i18n=\"legend\"></p></div><p id=\"status\" class=\"status\" role=\"status\" aria-live=\"polite\" data-i18n=\"idle\"></p><div class=\"volume\"><label for=\"volume\" data-i18n=\"volume\"></label><input id=\"volume\" type=\"range\" min=\"0\" max=\"100\" value=\"65\" data-i18n-label=\"volume\"></div>","css":"\nbody {padding:24px;} h2 {font-size:21px;} .intro {color:var(--muted);margin:8px 0 18px;}\nbutton,label,.hint {font-size:16px;} button {min-height:46px;} .actions {display:flex;gap:8px;flex-wrap:wrap;margin:16px 0;}\n.actions button {flex:1 1 90px;} .audio-play::before {content:'';display:inline-block;width:10px;height:11px;background:currentColor;clip-path:polygon(0 0,100% 50%,0 100%);margin-right:5px;} .audio-play[aria-pressed=true]::before {clip-path:none;}\n.readout {display:flex;gap:12px;justify-content:space-between;align-items:baseline;padding:12px 14px;border-bottom:1px solid var(--rule);}\n.readout strong {font-size:28px;font-weight:500;} .readout span {color:var(--muted);font-size:14px;}\n.grid {display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:6px;margin:14px 0;}\n.cell {min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:7px 2px;border:1px solid var(--rule);border-radius:7px;min-height:66px;font-size:14px;}\n.cell b {font-size:21px;line-height:1;} .cell small {font-size:13px;color:var(--muted);} .cell.on {background:var(--accent-soft);border-color:var(--accent);color:var(--accent);}\n.cell.current {outline:2px solid var(--ink);outline-offset:1px;} .grid button.cell {font-size:14px;}\n.row-title {margin-top:18px;font-size:16px;font-weight:600;display:flex;justify-content:space-between;}\n.row-title span {font-size:14px;font-weight:400;color:var(--muted);} .status {min-height:3.4em;margin:14px 0 0;font-size:15px;line-height:1.7;color:var(--muted);}\n.options {display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin:14px 0;} .options label {display:flex;align-items:center;gap:8px;min-height:44px;}\ninput[type=checkbox] {width:19px;height:19px;accent-color:var(--accent);} .volume {display:flex;align-items:center;gap:12px;border-top:1px solid var(--rule);padding-top:10px;margin-top:14px;}\n.volume label {font-size:14px;color:var(--muted);white-space:nowrap;} .volume input {max-width:140px;} .tempo {margin:14px 0;} .tempo label {display:flex;justify-content:space-between;}\n.feedback {padding:14px;background:var(--surface);border-radius:8px;margin-top:12px;line-height:1.7;font-size:16px;} .choices {display:flex;gap:7px;flex-wrap:wrap;} .choices button {flex:1 1 90px;}\n@media(max-width:420px) {body {padding:20px 14px;} .grid {grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;} .cell {min-height:58px;} h2 {font-size:20px;} .readout strong {font-size:25px;}}\n","js":"\nconst $=s=>document.querySelector(s), $$=s=>[...document.querySelectorAll(s)];\nconst patterns={a:[0,2,4,6],b:[0,3,4,7]};\nlet playingKey='', bpm=100;\nconst beatLabels=['1','&','2','&','3','&','4','&'];\nfunction grid(el, pattern, editable=false) {\n el.replaceChildren();\n for(let i=0;i<8;i++) {\n const cell=document.createElement(editable?'button':'div'); cell.className='cell'+(pattern.includes(i)?' on':''); cell.dataset.slot=i;\n if(editable) {cell.type='button';cell.setAttribute('aria-pressed',String(pattern.includes(i)));}\n cell.setAttribute('aria-label',viz.t('beat')+' '+(Math.floor(i/2)+1)+(i%2?viz.t('half'):'')+' · '+viz.t(pattern.includes(i)?'hit':'rest'));\n const label=document.createElement('small');label.textContent=beatLabels[i];\n const mark=document.createElement('b');mark.textContent=pattern.includes(i)?'●':'—';mark.setAttribute('aria-hidden','true');cell.append(label,mark);el.append(cell);\n }\n}\nfunction makeScore(pattern, tempo, reference=false) {\n const events=[];\n for(let bar=0;bar<2;bar++) {\n for(const step of pattern) events.push({beat:bar*4+step/2,hz:740,duration:.075,gain:1,wave:'triangle'});\n if(reference) for(let beat=0;beat<4;beat++) events.push({beat:bar*4+beat,hz:1500,duration:.035,gain:.45});\n }\n return {bpm:tempo,beats:8,events};\n}\nconst player=viz.audio({\n onState(state) {\n document.body.dataset.audioState=state;\n $$('[data-listen]').forEach(b=>b.setAttribute('aria-pressed',String(state!=='idle'&&b.dataset.listen===playingKey)));\n $('#stop').disabled=state==='idle';\n $('#status').textContent=viz.t(state==='playing'?'playing':state==='starting'?'starting':'idle');\n },\n onTick(beat) {\n const step=beat<0?-1:Math.floor(beat*2)%8;\n $$('.cell').forEach(c=>c.classList.toggle('current',beat>=0&&Number(c.dataset.slot)===step&&(!c.closest('[data-track]')||c.closest('[data-track]').dataset.track===playingKey)));\n },\n onError() {$('#status').textContent=viz.t('error');}\n});\n$('#stop').onclick=()=>player.stop();\n$('#volume').oninput=e=>player.setVolume(Number(e.target.value)/100);\nfunction listen(key,pattern,tempo,reference=false) {playingKey=key;return player.play(makeScore(pattern,tempo,reference));}\n\nfor(const key of ['a','b']) {grid($('#grid-'+key),patterns[key]);$('[data-listen='+key+']').onclick=()=>listen(key,patterns[key],100,$('#reference').checked);}\n$('#reference').onchange=()=>player.stop();\n$('#reveal').onclick=()=>{const expanded=$('#comparison').hidden;$('#comparison').hidden=!expanded;$('#reveal').setAttribute('aria-expanded',String(expanded));$('#reveal').textContent=viz.t(expanded?'hide':'reveal');};\n","audio":true,"strings":{"a":"A を聴く","a_hint":"毎拍に発音","b":"B を聴く","b_hint":"二つの音が拍の間に入る","beat":"拍","error":"音声を開始できませんでした。機器のミュートを確認し、もう一度お試しください。図でも確認できます。","eyebrow":"01 / 聴く","fixed":"テンポは両方とも同じ","half":"、次の拍までの中間","heading":"A と B は同じ速さ?","hide":"図を隠す","hit":"発音","idle":"各クリップは二小節です。いつでも停止・再生できます。","intro":"A と B を別々に聴き、うなずいたり手を叩いたりしたくなる感じを比べましょう。まずは自分の印象から。","legend":"● は発音、— は発音なし。& は拍の中間です。","playing":"二小節を再生中。最後まで行くと止まります。","reference":"一定のパルスを加える","rest":"発音なし","reveal":"タイミングを表示","starting":"音声を準備中…","stop":"停止","volume":"音量"}}
「タイミングを表示」を選んで、もう一度聴きます。両方とも 100 BPM、一小節に四回の発音で、音色と音量も同じです。B では二つの音が半拍後ろへ移っています。
「一定のパルスを加える」を選ぶと、控えめで高い音が等間隔に鳴ります。それに合わせて「1、2、3、4」と数えましょう。低い音はパルスと重なることも、その間に入ることもあります。
一つのマスは半拍です。● は発音、— は発音なし、& は拍の中間を示します。英語の and のように読み、one and two and three and four and と数えられます。パターンを一度繰り返すので、全体は二小節です。
B が「速い」と感じられる必要はありません。印象は人によって異なります。確かめられるのは、基準パルスは速くなっていないのに、一部の音の位置が変わったという関係です。
拍、テンポ、リズム型を分ける
一定の速さで歩く場面を想像してください。足取りを拍、その進む速さをテンポと考えます。特定の足取りや、その間で手を叩くと、さまざまなリズム型ができます。
| 概念 | ここでの意味 | 確かめ方 |
| 拍 | 音楽を通して追える規則的なパルス | 基準パルスに合わせて数える |
| テンポ | パルスが進む速さ | 拍同士の時間間隔を比べる |
| リズム型 | 音と空白の時間的な配置 | 拍上か、拍の間かを確認する |
BPM は一分あたりの拍数です。 ここで選んだ拍の単位なら、60 BPM は一秒に一拍、120 BPM は 0.5 秒に一拍、100 BPM は 0.6 秒に一拍です。BPM は聞こえた音の総数を数えるものではありません。一拍に二音が入ることも、一音も鳴らないこともあります。拍、テンポ、拍子
今回は比べやすいよう、四拍を一つの小節にまとめます。音楽が常に四拍ずつとは限りません。拍とアクセントのまとまりは後の回で扱います。
実際のリズムには音の長さ、アクセント、演奏の細かな揺れも関わります。ここでは短い打音と音色を固定し、いつ音が始まるかに集中します。
一音を動かしてから、テンポを変える
まず 100 BPM のまま、A の二番目の発音を「2」から直後の「&」へ移してください。同じ速さで数え続けられますか。
次に A を復元し、マスを変えず 80、100、120 BPM を比較します。今度は基準パルスも速くなり、全体が短い時間で終わります。
図を準備しています
一つを固定し、別の一つを変える四拍の各拍を二マスに分け、配置を二回繰り返します。A または B を復元して 100 BPM のまま位置を編集するか、配置を固定して 80、100、120 BPM を比べます。編集すると停止し、次は最初から再生します。
{"id":"music-rhythm-workbench","title":"一つを固定し、別の一つを変える","summary":"四拍の各拍を二マスに分け、配置を二回繰り返します。A または B を復元して 100 BPM のまま位置を編集するか、配置を固定して 80、100、120 BPM を比べます。編集すると停止し、次は最初から再生します。","height":650,"html":"<p class=\"eyebrow\" data-i18n=\"eyebrow\"></p><h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p>\n<div class=\"grid\" id=\"edit-grid\"></div><p class=\"hint\" data-i18n=\"legend\"></p>\n<div class=\"actions\"><button data-pattern=\"a\" data-i18n=\"restore_a\"></button><button data-pattern=\"b\" data-i18n=\"restore_b\"></button></div>\n<div class=\"tempo\"><label for=\"tempo\"><span data-i18n=\"tempo\"></span><output id=\"tempo-value\">100 BPM</output></label><input id=\"tempo\" type=\"range\" min=\"60\" max=\"140\" step=\"1\" value=\"100\" data-i18n-label=\"tempo\"></div>\n<div class=\"choices\"><button data-tempo=\"80\">80 BPM</button><button data-tempo=\"100\">100 BPM</button><button data-tempo=\"120\">120 BPM</button></div>\n<div class=\"options\"><label><input id=\"reference\" type=\"checkbox\" checked><span data-i18n=\"reference\"></span></label></div>\n<div class=\"actions\"><button class=\"audio-play primary\" data-listen=\"edit\" aria-pressed=\"false\" data-i18n=\"listen\"></button><button id=\"stop\" disabled data-i18n=\"stop\"></button></div><p class=\"hint\" id=\"configuration\"></p><p id=\"status\" class=\"status\" role=\"status\" aria-live=\"polite\" data-i18n=\"idle\"></p><div class=\"volume\"><label for=\"volume\" data-i18n=\"volume\"></label><input id=\"volume\" type=\"range\" min=\"0\" max=\"100\" value=\"65\" data-i18n-label=\"volume\"></div>","css":"\nbody {padding:24px;} h2 {font-size:21px;} .intro {color:var(--muted);margin:8px 0 18px;}\nbutton,label,.hint {font-size:16px;} button {min-height:46px;} .actions {display:flex;gap:8px;flex-wrap:wrap;margin:16px 0;}\n.actions button {flex:1 1 90px;} .audio-play::before {content:'';display:inline-block;width:10px;height:11px;background:currentColor;clip-path:polygon(0 0,100% 50%,0 100%);margin-right:5px;} .audio-play[aria-pressed=true]::before {clip-path:none;}\n.readout {display:flex;gap:12px;justify-content:space-between;align-items:baseline;padding:12px 14px;border-bottom:1px solid var(--rule);}\n.readout strong {font-size:28px;font-weight:500;} .readout span {color:var(--muted);font-size:14px;}\n.grid {display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:6px;margin:14px 0;}\n.cell {min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:7px 2px;border:1px solid var(--rule);border-radius:7px;min-height:66px;font-size:14px;}\n.cell b {font-size:21px;line-height:1;} .cell small {font-size:13px;color:var(--muted);} .cell.on {background:var(--accent-soft);border-color:var(--accent);color:var(--accent);}\n.cell.current {outline:2px solid var(--ink);outline-offset:1px;} .grid button.cell {font-size:14px;}\n.row-title {margin-top:18px;font-size:16px;font-weight:600;display:flex;justify-content:space-between;}\n.row-title span {font-size:14px;font-weight:400;color:var(--muted);} .status {min-height:3.4em;margin:14px 0 0;font-size:15px;line-height:1.7;color:var(--muted);}\n.options {display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin:14px 0;} .options label {display:flex;align-items:center;gap:8px;min-height:44px;}\ninput[type=checkbox] {width:19px;height:19px;accent-color:var(--accent);} .volume {display:flex;align-items:center;gap:12px;border-top:1px solid var(--rule);padding-top:10px;margin-top:14px;}\n.volume label {font-size:14px;color:var(--muted);white-space:nowrap;} .volume input {max-width:140px;} .tempo {margin:14px 0;} .tempo label {display:flex;justify-content:space-between;}\n.feedback {padding:14px;background:var(--surface);border-radius:8px;margin-top:12px;line-height:1.7;font-size:16px;} .choices {display:flex;gap:7px;flex-wrap:wrap;} .choices button {flex:1 1 90px;}\n@media(max-width:420px) {body {padding:20px 14px;} .grid {grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;} .cell {min-height:58px;} h2 {font-size:20px;} .readout strong {font-size:25px;}}\n","js":"\nconst $=s=>document.querySelector(s), $$=s=>[...document.querySelectorAll(s)];\nconst patterns={a:[0,2,4,6],b:[0,3,4,7]};\nlet playingKey='', bpm=100;\nconst beatLabels=['1','&','2','&','3','&','4','&'];\nfunction grid(el, pattern, editable=false) {\n el.replaceChildren();\n for(let i=0;i<8;i++) {\n const cell=document.createElement(editable?'button':'div'); cell.className='cell'+(pattern.includes(i)?' on':''); cell.dataset.slot=i;\n if(editable) {cell.type='button';cell.setAttribute('aria-pressed',String(pattern.includes(i)));}\n cell.setAttribute('aria-label',viz.t('beat')+' '+(Math.floor(i/2)+1)+(i%2?viz.t('half'):'')+' · '+viz.t(pattern.includes(i)?'hit':'rest'));\n const label=document.createElement('small');label.textContent=beatLabels[i];\n const mark=document.createElement('b');mark.textContent=pattern.includes(i)?'●':'—';mark.setAttribute('aria-hidden','true');cell.append(label,mark);el.append(cell);\n }\n}\nfunction makeScore(pattern, tempo, reference=false) {\n const events=[];\n for(let bar=0;bar<2;bar++) {\n for(const step of pattern) events.push({beat:bar*4+step/2,hz:740,duration:.075,gain:1,wave:'triangle'});\n if(reference) for(let beat=0;beat<4;beat++) events.push({beat:bar*4+beat,hz:1500,duration:.035,gain:.45});\n }\n return {bpm:tempo,beats:8,events};\n}\nconst player=viz.audio({\n onState(state) {\n document.body.dataset.audioState=state;\n $$('[data-listen]').forEach(b=>b.setAttribute('aria-pressed',String(state!=='idle'&&b.dataset.listen===playingKey)));\n $('#stop').disabled=state==='idle';\n $('#status').textContent=viz.t(state==='playing'?'playing':state==='starting'?'starting':'idle');\n },\n onTick(beat) {\n const step=beat<0?-1:Math.floor(beat*2)%8;\n $$('.cell').forEach(c=>c.classList.toggle('current',beat>=0&&Number(c.dataset.slot)===step&&(!c.closest('[data-track]')||c.closest('[data-track]').dataset.track===playingKey)));\n },\n onError() {$('#status').textContent=viz.t('error');}\n});\n$('#stop').onclick=()=>player.stop();\n$('#volume').oninput=e=>player.setVolume(Number(e.target.value)/100);\nfunction listen(key,pattern,tempo,reference=false) {playingKey=key;return player.play(makeScore(pattern,tempo,reference));}\n\nlet pattern=[...patterns.a];\nfunction render() {\n grid($('#edit-grid'),pattern,true);$('#tempo-value').textContent=bpm+' BPM';\n $('#configuration').textContent=viz.t('current')+bpm+' BPM · '+pattern.length+viz.t('hits');\n $$('#edit-grid button').forEach(cell=>cell.onclick=()=>{player.stop();const step=Number(cell.dataset.slot);pattern=pattern.includes(step)?pattern.filter(x=>x!==step):[...pattern,step].sort((a,b)=>a-b);render();$('#edit-grid').children[step].focus();});\n $$('[data-tempo]').forEach(b=>b.setAttribute('aria-pressed',String(Number(b.dataset.tempo)===bpm)));\n}\nfunction tempo(value) {player.stop();bpm=Number(value);$('#tempo').value=bpm;render();}\n$('#tempo').oninput=e=>tempo(e.target.value);\n$$('[data-tempo]').forEach(b=>b.onclick=()=>tempo(b.dataset.tempo));\n$$('[data-pattern]').forEach(b=>b.onclick=()=>{player.stop();pattern=[...patterns[b.dataset.pattern]];render();});\n$('[data-listen]').onclick=()=>listen('edit',pattern,bpm,$('#reference').checked);\n$('#reference').onchange=()=>player.stop();render();\n","audio":true,"strings":{"beat":"拍","current":"現在:","error":"音声を開始できませんでした。機器のミュートを確認し、もう一度お試しください。図でも確認できます。","eyebrow":"02 / 試す","half":"、次の拍までの中間","heading":"音の位置、またはテンポを変える","hit":"発音","hits":" 回の発音/小節","idle":"各クリップは二小節です。いつでも停止・再生できます。","intro":"100 BPM のままマスを押し、発音を追加・削除します。その後は配置を固定してテンポだけを変え、編集のたびに聴き直しましょう。","legend":"● は発音、— は発音なし。& は拍の中間です。","listen":"自分のパターンを聴く","playing":"二小節を再生中。最後まで行くと止まります。","reference":"一定のパルスを加える","rest":"発音なし","restore_a":"A を復元","restore_b":"B を復元","starting":"音声を準備中…","stop":"停止","tempo":"テンポ","volume":"音量"}}
発音を動かす編集は、拍に対する位置を変えます。テンポを上げる編集は、同じ配置全体を速く進めます。
基準パルスを残し、拍上の一音を消して空白も試しましょう。その瞬間も数え続けられます。何も鳴らないからといって、拍がなくなるわけではありません。 基準パルスを切って心の中で数え、必要なら戻して構いません。
打音につられて、一定の拍を見失ったら?
A を復元し、高い基準パルスに注意して「1、2、3、4」と数えます。その間隔を保って B に切り替えましょう。80 BPM に遅くするか、図で位置を確認しても構いません。反応速度ではなく、どの層を追うかを選ぶ練習です。
音楽によっては、拍の取り方が複数成り立ちます。人によって半分や二倍の速さで拍を感じることもあります。この実験は同じ時間の枠で比較できるよう、基準パルスを指定しています。
新しい例では、何が変わった?
次は別のパターンです。各組の C と D で、基準パルスが速くなったのか、低い打音の位置が動いたのかを比べます。何度聴いても構いません。まずパルス、次に打音へ注意を移しましょう。
図を準備しています
新しい例で変化を聴き分ける第一の組は C と D がともに 100 BPM、一小節四音で、発音位置が違います。第二の組は配置が同じで、C は 90 BPM、D は 120 BPM。高い基準パルスを手がかりにし、答えを選んで理由を確認できます。
{"id":"music-rhythm-check","title":"新しい例で変化を聴き分ける","summary":"第一の組は C と D がともに 100 BPM、一小節四音で、発音位置が違います。第二の組は配置が同じで、C は 90 BPM、D は 120 BPM。高い基準パルスを手がかりにし、答えを選んで理由を確認できます。","height":520,"html":"<p class=\"eyebrow\" data-i18n=\"eyebrow\"></p><h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p>\n<div class=\"choices\"><button data-question=\"0\" aria-pressed=\"true\" data-i18n=\"q1\"></button><button data-question=\"1\" aria-pressed=\"false\" data-i18n=\"q2\"></button></div>\n<div class=\"actions\"><button class=\"audio-play\" data-listen=\"c\" aria-pressed=\"false\" data-i18n=\"c\"></button><button class=\"audio-play\" data-listen=\"d\" aria-pressed=\"false\" data-i18n=\"d\"></button><button id=\"stop\" disabled data-i18n=\"stop\"></button></div>\n<p class=\"intro\" data-i18n=\"prompt\"></p><div class=\"choices\"><button data-answer=\"rhythm\" data-i18n=\"rhythm\"></button><button data-answer=\"tempo\" data-i18n=\"tempo_answer\"></button><button data-answer=\"unsure\" data-i18n=\"unsure\"></button></div>\n<p id=\"feedback\" class=\"feedback\" role=\"status\" aria-live=\"polite\" data-i18n=\"initial\"></p><p id=\"status\" class=\"status\" role=\"status\" aria-live=\"polite\" data-i18n=\"idle\"></p><div class=\"volume\"><label for=\"volume\" data-i18n=\"volume\"></label><input id=\"volume\" type=\"range\" min=\"0\" max=\"100\" value=\"65\" data-i18n-label=\"volume\"></div>","css":"\nbody {padding:24px;} h2 {font-size:21px;} .intro {color:var(--muted);margin:8px 0 18px;}\nbutton,label,.hint {font-size:16px;} button {min-height:46px;} .actions {display:flex;gap:8px;flex-wrap:wrap;margin:16px 0;}\n.actions button {flex:1 1 90px;} .audio-play::before {content:'';display:inline-block;width:10px;height:11px;background:currentColor;clip-path:polygon(0 0,100% 50%,0 100%);margin-right:5px;} .audio-play[aria-pressed=true]::before {clip-path:none;}\n.readout {display:flex;gap:12px;justify-content:space-between;align-items:baseline;padding:12px 14px;border-bottom:1px solid var(--rule);}\n.readout strong {font-size:28px;font-weight:500;} .readout span {color:var(--muted);font-size:14px;}\n.grid {display:grid;grid-template-columns:repeat(8,minmax(0,1fr));gap:6px;margin:14px 0;}\n.cell {min-width:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;padding:7px 2px;border:1px solid var(--rule);border-radius:7px;min-height:66px;font-size:14px;}\n.cell b {font-size:21px;line-height:1;} .cell small {font-size:13px;color:var(--muted);} .cell.on {background:var(--accent-soft);border-color:var(--accent);color:var(--accent);}\n.cell.current {outline:2px solid var(--ink);outline-offset:1px;} .grid button.cell {font-size:14px;}\n.row-title {margin-top:18px;font-size:16px;font-weight:600;display:flex;justify-content:space-between;}\n.row-title span {font-size:14px;font-weight:400;color:var(--muted);} .status {min-height:3.4em;margin:14px 0 0;font-size:15px;line-height:1.7;color:var(--muted);}\n.options {display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin:14px 0;} .options label {display:flex;align-items:center;gap:8px;min-height:44px;}\ninput[type=checkbox] {width:19px;height:19px;accent-color:var(--accent);} .volume {display:flex;align-items:center;gap:12px;border-top:1px solid var(--rule);padding-top:10px;margin-top:14px;}\n.volume label {font-size:14px;color:var(--muted);white-space:nowrap;} .volume input {max-width:140px;} .tempo {margin:14px 0;} .tempo label {display:flex;justify-content:space-between;}\n.feedback {padding:14px;background:var(--surface);border-radius:8px;margin-top:12px;line-height:1.7;font-size:16px;} .choices {display:flex;gap:7px;flex-wrap:wrap;} .choices button {flex:1 1 90px;}\n@media(max-width:420px) {body {padding:20px 14px;} .grid {grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;} .cell {min-height:58px;} h2 {font-size:20px;} .readout strong {font-size:25px;}}\n","js":"\nconst $=s=>document.querySelector(s), $$=s=>[...document.querySelectorAll(s)];\nconst patterns={a:[0,2,4,6],b:[0,3,4,7]};\nlet playingKey='', bpm=100;\nconst beatLabels=['1','&','2','&','3','&','4','&'];\nfunction grid(el, pattern, editable=false) {\n el.replaceChildren();\n for(let i=0;i<8;i++) {\n const cell=document.createElement(editable?'button':'div'); cell.className='cell'+(pattern.includes(i)?' on':''); cell.dataset.slot=i;\n if(editable) {cell.type='button';cell.setAttribute('aria-pressed',String(pattern.includes(i)));}\n cell.setAttribute('aria-label',viz.t('beat')+' '+(Math.floor(i/2)+1)+(i%2?viz.t('half'):'')+' · '+viz.t(pattern.includes(i)?'hit':'rest'));\n const label=document.createElement('small');label.textContent=beatLabels[i];\n const mark=document.createElement('b');mark.textContent=pattern.includes(i)?'●':'—';mark.setAttribute('aria-hidden','true');cell.append(label,mark);el.append(cell);\n }\n}\nfunction makeScore(pattern, tempo, reference=false) {\n const events=[];\n for(let bar=0;bar<2;bar++) {\n for(const step of pattern) events.push({beat:bar*4+step/2,hz:740,duration:.075,gain:1,wave:'triangle'});\n if(reference) for(let beat=0;beat<4;beat++) events.push({beat:bar*4+beat,hz:1500,duration:.035,gain:.45});\n }\n return {bpm:tempo,beats:8,events};\n}\nconst player=viz.audio({\n onState(state) {\n document.body.dataset.audioState=state;\n $$('[data-listen]').forEach(b=>b.setAttribute('aria-pressed',String(state!=='idle'&&b.dataset.listen===playingKey)));\n $('#stop').disabled=state==='idle';\n $('#status').textContent=viz.t(state==='playing'?'playing':state==='starting'?'starting':'idle');\n },\n onTick(beat) {\n const step=beat<0?-1:Math.floor(beat*2)%8;\n $$('.cell').forEach(c=>c.classList.toggle('current',beat>=0&&Number(c.dataset.slot)===step&&(!c.closest('[data-track]')||c.closest('[data-track]').dataset.track===playingKey)));\n },\n onError() {$('#status').textContent=viz.t('error');}\n});\n$('#stop').onclick=()=>player.stop();\n$('#volume').oninput=e=>player.setVolume(Number(e.target.value)/100);\nfunction listen(key,pattern,tempo,reference=false) {playingKey=key;return player.play(makeScore(pattern,tempo,reference));}\n\nconst questions=[{c:[0,1,4,6],d:[0,2,5,6],tempos:[100,100],answer:'rhythm'},{c:[0,2,3,6],d:[0,2,3,6],tempos:[90,120],answer:'tempo'}];\nlet question=0;\n$$('[data-question]').forEach(b=>b.onclick=()=>{player.stop();question=Number(b.dataset.question);$$('[data-question]').forEach(x=>x.setAttribute('aria-pressed',String(x===b)));$('#feedback').textContent=viz.t('initial');});\n$$('[data-listen]').forEach(b=>b.onclick=()=>{const q=questions[question],key=b.dataset.listen;listen(key,q[key],q.tempos[key==='c'?0:1],true);});\n$$('[data-answer]').forEach(b=>b.onclick=()=>{const prefix=b.dataset.answer==='unsure'?'unsure_feedback':b.dataset.answer===questions[question].answer?'correct':'retry';$('#feedback').textContent=viz.t(prefix)+' '+viz.t('explain_'+question);});\n","audio":true,"strings":{"beat":"拍","c":"C を聴く","correct":"この例の変化と一致しています。","d":"D を聴く","error":"音声を開始できませんでした。機器のミュートを確認し、もう一度お試しください。図でも確認できます。","explain_0":"第一の組は両方とも 100 BPM、一小節に四回の発音ですが、二つの発音位置が動いています。","explain_1":"第二の組は同じ配置で、C が 90 BPM、D が 120 BPM。パルスも打音も一緒に速くなります。","eyebrow":"03 / 確認","half":"、次の拍までの中間","heading":"今度は何が変わった?","hit":"発音","idle":"各クリップは二小節です。いつでも停止・再生できます。","initial":"何度比較しても構いません。答えを選ぶと解説が表示されます。","intro":"両方の組に、控えめで高い基準パルスがあります。まずその速さ、次に低い打音を追いましょう。","legend":"● は発音、— は発音なし。& は拍の中間です。","playing":"二小節を再生中。最後まで行くと止まります。","prompt":"C から D へ、何が変わった?","q1":"第一の組","q2":"第二の組","reference":"一定のパルスを加える","rest":"発音なし","retry":"基準パルスをもう一度聴いてみましょう。","rhythm":"発音位置","starting":"音声を準備中…","stop":"停止","tempo_answer":"テンポ","unsure":"まだ分からない","unsure_feedback":"解説を読んでから、もう一度聴きましょう。","volume":"音量"}}
二組の答えと理由を見る
第一の組: C と D はともに 100 BPM、一小節に四回の発音です。C は「1、1 の後の and、3、4」、D は「1、2、3 の後の and、4」で鳴ります。テンポと数は同じで、位置が違います。
第二の組: 両方とも「1、2、2 の後の and、4」で鳴ります。C は 90 BPM、D は 120 BPM。配置は同じでも D のパルスと打音が速く進むので、二小節が早く終わります。
今は音を出せない場合、紙に八マスを描いて位置を印してください。位置と BPM のどちらが変わるかを確認し、音を聴けるときに戻りましょう。
次に聴く曲へ、一つの観察を持ち込む
拍が分かりやすい好きな曲を選び、静かに数えながらドラムや声を追います。すべての音が拍上から始まるでしょうか。空白はどこにあり、拍の間で始まる音はどこでしょう。まだ正確な BPM を計算する必要はありません。
「勢いが増した」と感じたら、「拍は同じで、発音位置が変わった」「同じ型が速くなった」と一文加えてみましょう。大まかな印象を、比較して話せる音楽的な関係にできます。
次回は「いつ鳴るか」から「どの音か」へ進みます。全部の音が高くなっても、なぜ旋律が分かるのでしょうか。
さらに聴く・読む
本回のパターンは練習用の自作です。打音と基準パルスは合成したデモ音を使っています。