You hear a friend sing a familiar tune in a different register. Their starting note is different from the recording, yet you recognize the song almost immediately. What stayed the same?
A melody has relationships between its notes, as well as individual pitches. This lesson separates moving an entire phrase from editing one note inside it. You will not need to identify notes by ear. Use the sound, the diagram, and the printed note names together.
Allow about ten minutes, including repeated listening. First recall lesson 1: the timing of a note and its pitch are separate choices. Here we keep the timing fixed.
Listen to the shape, then inspect the distances
Play Original, then All notes +5. Hum along if comfortable, or simply follow the rise and fall with a hand. Does the second version sound like a different register of the same idea? Now compare One note +1 with the original. Listen around the highest point.
Preparing the visual
Move the whole melody
All three versions have eight equally spaced notes at 100 BPM. The second raises every note by five semitones; the third raises only the fourth note by one semitone.
{"id":"music-pitch-shift","title":"Move the whole melody","summary":"All three versions have eight equally spaced notes at 100 BPM. The second raises every note by five semitones; the third raises only the fourth note by one semitone.","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\":60,\"max\":74,\"blind\":false,\"variants\":[{\"score\":{\"bpm\":100,\"beats\":8,\"events\":[{\"midi\":60,\"hz\":261.625565,\"beat\":0,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":62,\"hz\":293.664768,\"beat\":1,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":64,\"hz\":329.627557,\"beat\":2,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":3,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":64,\"hz\":329.627557,\"beat\":4,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":62,\"hz\":293.664768,\"beat\":5,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":60,\"hz\":261.625565,\"beat\":6,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":60,\"hz\":261.625565,\"beat\":7,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"}]},\"notation\":\"C4 · D4 · E4 · G4 · E4 · D4 · C4 · C4\",\"groups\":[]},{\"score\":{\"bpm\":100,\"beats\":8,\"events\":[{\"midi\":65,\"hz\":349.228231,\"beat\":0,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":1,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":69,\"hz\":440.0,\"beat\":2,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":72,\"hz\":523.251131,\"beat\":3,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":69,\"hz\":440.0,\"beat\":4,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":5,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":65,\"hz\":349.228231,\"beat\":6,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":65,\"hz\":349.228231,\"beat\":7,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"}]},\"notation\":\"F4 · G4 · A4 · C5 · A4 · G4 · F4 · F4\",\"groups\":[]},{\"score\":{\"bpm\":100,\"beats\":8,\"events\":[{\"midi\":60,\"hz\":261.625565,\"beat\":0,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":62,\"hz\":293.664768,\"beat\":1,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":64,\"hz\":329.627557,\"beat\":2,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":68,\"hz\":415.304698,\"beat\":3,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":64,\"hz\":329.627557,\"beat\":4,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":62,\"hz\":293.664768,\"beat\":5,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":60,\"hz\":261.625565,\"beat\":6,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":60,\"hz\":261.625565,\"beat\":7,\"duration\":0.48,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"}]},\"notation\":\"C4 · D4 · E4 · G♯4 · E4 · D4 · C4 · C4\",\"groups\":[]}]};\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":"Time → · higher marks = higher pitch","choose":"Choose a version","clip":"Clip:","envelope":"Amplitude over time → (1.4 seconds). The curve rises to a peak, then decays. Compare how much time the attack occupies.","error":"Audio could not start. Try again, or use the diagram and written explanation.","fact0":"C4 D4 E4 G4 E4 D4 C4 C4. Notice the climb and the return.","fact1":"F4 G4 A4 C5 A4 G4 F4 F4. Every interval and onset is preserved.","fact2":"Only G4 becomes G♯4. The broad up/down contour remains, but two neighboring intervals change.","heading":"Move the whole melody","idle":"Choose a version, then play. Editing stops playback; each clip ends automatically.","intro":"Compare the original, a uniform shift, and a one-note edit. Keep tapping at the same pace.","key":"Read left to right. A bar shows a note’s onset and scheduled length. Simultaneous marks are stacked; use the note names and explanation as a text alternative.","option0":"Original","option1":"All notes +5","option2":"One note +1","play":"Play this version","playing":"Playing. You can stop at any time.","seconds":"seconds","starting":"Preparing audio…","stop":"Stop","volume":"Volume"}}
The diagram reads left to right in time; higher marks represent higher pitches. Its vertical scale stays fixed across the three choices. A mark’s width shows the scheduled sound length, not its loudness. The note names provide a text alternative to the picture.
The original begins C–D–E. Those movements are two semitones up and another two semitones up. The shifted version begins F–G–A, with exactly the same distances. The whole phrase moves five semitones higher: this is transposition. The starting pitch changes, but the intervals and rhythm remain intact.
In the one-note edit, G becomes G♯. E to G was three semitones; E to G♯ is four. The return from that note to E also changes. Both melodies still climb and fall in the same general direction. Contour is useful, but it is less specific than an exact interval pattern.
A small vocabulary for pitch
Term
Meaning in these experiments
Example
Pitch
The high or low quality we hear
C5 is higher than C4
Semitone, or half step
One step between adjacent piano keys, including black keys
E to F; C to C♯
Interval
The distance between two pitches
C to E is four semitones
Octave
A span of twelve semitones here
C4 to C5
Transposition
Moving every pitch by the same interval
Every note up five semitones
The letter names run A through G and then repeat. A sharp, ♯, raises a written note by a semitone; a flat, ♭, lowers it. The number identifies the octave: C4 is middle C in the convention used here. E–F and B–C are already semitone neighbors; there is no missing black key you must count. Half steps and whole steps
Our sounds use twelve-tone equal temperament: twelve equal semitone steps make an octave, and an octave doubles the frequency. You do not need that calculation to do the exercise. Other musical traditions and tuning systems organize pitch differently; this is a practical starting vocabulary for much Western tonal music.
Transfer the idea to an unfamiliar phrase
Before playing the next model, predict what a correct transposition must preserve. Is keeping the first and last notes enough? Is keeping only the direction of each move enough?
Compare the reference with P, then with Q. Choose an answer first; the revealed diagram then lets you check the pitches and distances. Checking a relationship is the goal; instant recognition is not.
Preparing the visual
A new phrase: which version is transposed?
Compare the reference with P and Q, choose which is a transposition, then reveal the diagram and explanation.
{"id":"music-pitch-check","title":"A new phrase: which version is transposed?","summary":"Compare the reference with P and Q, choose which is a transposition, then reveal the diagram and explanation.","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\":65,\"max\":74,\"blind\":true,\"variants\":[{\"score\":{\"bpm\":90,\"beats\":4,\"events\":[{\"midi\":65,\"hz\":349.228231,\"beat\":0,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":69,\"hz\":440.0,\"beat\":1,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":67,\"hz\":391.995436,\"beat\":2,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":72,\"hz\":523.251131,\"beat\":3,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"}]},\"notation\":\"F4 · A4 · G4 · C5\",\"groups\":[]},{\"score\":{\"bpm\":90,\"beats\":4,\"events\":[{\"midi\":67,\"hz\":391.995436,\"beat\":0,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":71,\"hz\":493.883301,\"beat\":1,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":69,\"hz\":440.0,\"beat\":2,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":74,\"hz\":587.329536,\"beat\":3,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"}]},\"notation\":\"G4 · B4 · A4 · D5\",\"groups\":[]},{\"score\":{\"bpm\":90,\"beats\":4,\"events\":[{\"midi\":67,\"hz\":391.995436,\"beat\":0,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":70,\"hz\":466.163762,\"beat\":1,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":69,\"hz\":440.0,\"beat\":2,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"},{\"midi\":74,\"hz\":587.329536,\"beat\":3,\"duration\":0.5,\"gain\":0.8,\"wave\":\"triangle\",\"layer\":\"melody\"}]},\"notation\":\"G4 · B♭4 · A4 · D5\",\"groups\":[]}]};\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":"Time → · higher marks = higher pitch","before":"Make your choice, then check the explanation.","choose":"Choose a version","choose_p":"P is transposed","choose_q":"Q is transposed","clip":"Clip:","compare_title":"Commit to an answer before revealing the diagram","comparison_correct":"P keeps every interval; Q changes one internal pitch. Compare the revealed distances.","correct":"Correct.","envelope":"Amplitude over time → (1.4 seconds). The curve rises to a peak, then decays. Compare how much time the attack occupies.","error":"Audio could not start. Try again, or use the diagram and written explanation.","fact0":"Compare the distances: +4, −2, +5 semitones.","fact1":"G4 B4 A4 D5. All notes move the same distance.","fact2":"G4 B♭4 A4 D5. The second note moves a smaller distance.","heading":"A new phrase: which version is transposed?","idle":"Choose a version, then play. Editing stops playback; each clip ends automatically.","intro":"Listen to the reference, P, and Q before reading the answer below the experiment.","key":"Read left to right. A bar shows a note’s onset and scheduled length. Simultaneous marks are stacked; use the note names and explanation as a text alternative.","option0":"Reference","option1":"Version P","option2":"Version Q","play":"Play this version","playing":"Playing. You can stop at any time.","reveal":"Reveal explanation","seconds":"seconds","starting":"Preparing audio…","stop":"Stop","volume":"Volume","wrong":"Not yet. Compare your choice with the explanation."}}Check the answer and the interval calculation
P is the exact transposition. The reference F–A–G–C moves +4, −2, +5 semitones. P, G–B–A–D, uses the same sequence. Each note is two semitones above its counterpart.
Q, G–B♭–A–D, moves +3, −1, +5. It has the same up–down–up contour, and its first and last pitches match P, but its inner distances differ. This is why comparing only the endpoints can miss an edit.
For a paper-only check, number the reference pitches 65, 69, 67, 72 and P’s pitches 67, 71, 69, 74. Subtract corresponding entries: four identical answers, +2. These numbers are just a convenient counting scale, not extra notation to memorize.
What recognition does—and does not—prove
Does transposition always leave the musical effect unchanged?
No. A higher version can feel more exposed, brighter, or harder to sing. Instruments have different colors across their ranges, and a singer has physical limits. Even with our fixed synthesized tone, changing register changes the sound you hear. We preserve the phrase’s interval structure, not every possible expressive effect.
Recognition also uses rhythm, repetition, words, and memory. An edited tune may remain recognizable. “I know this song” is therefore not a precise test of whether every interval stayed the same.
Try singing the first few notes of a familiar tune from two comfortable starting pitches. Notice which leaps you keep, and where you accidentally flatten a leap to fit your voice. Describe the change as “the whole phrase moved” or “this particular interval changed.”
Next, we learn to write and read these pitch relationships on a five-line staff.