概要
私の2023年のラストの記事で、🐸PowerShellのビープ音で「カエルの歌」を奏でる🐸という記事を書きました。その記事のセルフオマージュとなります。
今回はPowerShellではなく、JavaScriptのWeb Audio APIで同等の機能を実装してみます。
ぜひ、記事のコードを見比べながら読んでいただければと思います。
完成したもの
先に完成物です。ボタンを押すとファミマの入店音が流れます。
(音が出ますご注意ください)
See the Pen ファミマ入店 by ishi720 (@ishi720) on CodePen.
プログラム
音の再生する関数
/**
* 指定した周波数と長さの音を再生する
*
* @param {number} frequency - 再生する音の周波数(Hz)
* @param {number} duration - 再生する音の長さ(ミリ秒)
* @returns {Promise<void>} 音の再生が終了した後に解決されるPromise
*/
function playTone(frequency, duration) {
// Web Audio API コンテキストを作成する
const context = new (window.AudioContext || window.webkitAudioContext)();
// 音を生成するためのオシレーターノードを作成
const oscillator = context.createOscillator();
// 音量を制御するためのゲインノードを作成
const gainNode = context.createGain();
// オシレーターの周波数を引数で渡された値に設定
oscillator.frequency.value = frequency;
oscillator.type = "sine";
// オシレーターノードをゲインノードに接続し、ゲインノードを出力に接続
oscillator.connect(gainNode);
gainNode.connect(context.destination);
// 音の再生を開始
oscillator.start();
// 音量を徐々に下げていく
gainNode.gain.setValueAtTime(1, context.currentTime);
gainNode.gain.exponentialRampToValueAtTime(0.001, context.currentTime + duration / 1000);
// 音の再生の終了
oscillator.stop(context.currentTime + duration / 1000);
return new Promise(resolve => setTimeout(resolve, duration));
}
公式ドキュメントを参考にして作成しています。
oscillator.type
を変えるとトライアングルような音やギターのような音を表現することができます。
パラメータは、いろいろ用意されているので、試してみてください!
- sine
- square
- sawtooth
- triangle
- custom
こちらの公式ドキュメントを参照いただければと思います。
https://developer.mozilla.org/ja/docs/Web/API/OscillatorNode/type
ファミマのメロディを設定
/**
* (非同期関数)ファミリーマートの入店音メロディを再生
*/
async function playMelody() {
const Rhythm = 1000;
// ファミマのメロディを再現
await playTone(493.88, Rhythm / 4); // シ (B4)
await playTone(392, Rhythm / 4); // ソ (G4)
await playTone(294, Rhythm / 4); // レ (D4)
await playTone(392, Rhythm / 4); // ソ (G4)
await playTone(440, Rhythm / 4); // ラ (A4)
await playTone(587.33, Rhythm / 4); // レ (D5)
await new Promise(resolve => setTimeout(resolve, Rhythm / 4));
await playTone(587.33, Rhythm / 4); // レ (D5)
await playTone(440, Rhythm / 4); // ラ (A4)
await playTone(493.88, Rhythm / 4); // シ (B4)
await playTone(440, Rhythm / 4); // ラ (A4)
await playTone(294, Rhythm / 4); // レ (D4)
await playTone(392, Rhythm / 4); // ソ (G4)
}
基本的に、PowerShellで作成したときと同じ内容ですが、音符と休符を連続的に設定しているだけです。
//四分音符
await playTone(493.88, Rhythm / 4);
//四分休符
await new Promise(resolve => setTimeout(resolve, Rhythm / 4));
おわりに
powershellのBeep音で作成したときは、音がガビガビしていたのですが、JavaScriptのWeb Audio APIだと音がきれいですね。
また、WEB画面で動作するので、かなり可能性が広がりそうです。
ここまで読んでいただきありがとうございました。
2025年も頑張りましょう!