Skip to content

Instantly share code, notes, and snippets.

@kawaz
Last active September 5, 2023 02:44
Show Gist options
  • Save kawaz/4c0817d55a49cf0d3eea11333dc234b4 to your computer and use it in GitHub Desktop.
Save kawaz/4c0817d55a49cf0d3eea11333dc234b4 to your computer and use it in GitHub Desktop.
Web Audio API を使って beep 音を鳴らすサンプル。
const beep = (duration=200, frequency=440, gain=1.0) => new Promise((resolve, reject) => {
try {
const audioCtx = new AudioContext()
const oscNode = new OscillatorNode(audioCtx, {frequency, type:"square"})
const gainNode = new GainNode(audioCtx, {gain})
oscNode.onended = resolve
oscNode.connect(gainNode).connect(audioCtx.destination)
oscNode.start(audioCtx.currentTime)
oscNode.stop(audioCtx.currentTime + duration / 1000)
} catch(err){
reject(err)
}
})
// 再生テスト
//await beep()
// 88音階の周波数を生成する
const onkai = Array.from({length:88}, (_,k) => {
const kn = k+1;
const frequency = 440 * Math.pow(2,(k-48)/12)
const octave = Math.floor((k+9)/12)
const names = [`${`AA#BCC#DD#EFF#GG#`.split(/(?=[A-Z])/)[k%12]}${octave}`]
if(names[0].includes("#")) {
names.push(`${String.fromCharCode((names[0].charCodeAt(0)-64)%7+65)}♭${octave}`)
}
names.push(...names.map(n=>n.replace(/[A-Z]/, a=>`ラシドレミファソ`.split(/(?=[^ァ])/)[a.charCodeAt(0)-65])))
return {kn, frequency, octave, code:names[0], names}
})
@kawaz
Copy link
Author

kawaz commented May 9, 2023

上の2つを合わせたテスト

// きらきら星(ハ長調)
for(const code of `ドドソソララソ ファファミミレレド ソソファファミミレ ソソファファミミレ ドドソソララソ ファファミミレレド`.split(/(?=[^ァ])/)) {
    const bpm = 120
    const duration = 60000 / bpm
    const oto = onkai.filter(v=>v.names.includes(`${code}4`))[0]
    if(oto) {
        await beep(duration, oto.frequency)
    } else {
        await new Promise(done=>setTimeout(done, duration))
    }
}


// きらきら星 (ト長調=楽譜はハ長調のままだが周波数を1.5倍すれば ソソレレミミレ で始まるト長調になる)
for(const code of `ドドソソララソ ファファミミレレド ソソファファミミレ ソソファファミミレ ドドソソララソ ファファミミレレド`.split(/(?=[^ァ])/)) {
    const bpm = 120
    const duration = 60000 / bpm
    const oto = onkai.filter(v=>v.names.includes(`${code}4`))[0]
    if(oto) {
        await beep(duration, oto.frequency * 1.5)
    } else {
        await new Promise(done=>setTimeout(done, duration))
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment