はじめに
今回は、前回同様、簡単なミニアプリ作成において使用したAPIについて。
「Web Audio API」というものを使用しました。
参考サイトから、こんな便利な機能があるとは。驚きです。
参考サイト
こちらのサイトで動作確認できます
以下に示すコードを自分の手元で試してみたい方はこちらのサイトを利用されてみる事をお勧めします。(私も今回初めて知りました。)
こんな感じのコード
以下コードはあくまで参考。
ボタンを押したら音が再生するというものになります。
👇まずはhtmlファイルにボタンを配置
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebAudio API テスト</title>
</head>
<body>
<h1>ボタンを押すと音が鳴る</h1>
<button id="myButton">ボタン</button>
<script src="smilescript.js"></script>
</body>
</html>
👇次にボタンを押したら音が鳴る仕組みを作る
// 音を鳴らす関数(周波数と長さを指定)
function playTone(frequency, duration) {
return new Promise(resolve => {
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();
oscillator.type = "sine"; // 正弦波
oscillator.frequency.value = frequency; // 周波数を設定
gainNode.gain.setValueAtTime(0.5, audioCtx.currentTime); // 音量調整
oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);
oscillator.start();
setTimeout(() => {
oscillator.stop();
resolve();
}, duration);
});
}
// 休符(無音時間を作る)
function rest(duration) {
return new Promise(resolve => setTimeout(resolve, duration));
}
// 休符 → ド(C4)の音を鳴らす
async function playRestThenDo() {
await rest(1000); // 休符(1秒)
await playTone(261.63, 1000); // ドの音(1秒)
}
// ボタンがクリックされたときの処理
document.getElementById("myButton").addEventListener("click", () => {
playRestThenDo();
});
コードの解説(Javascript)
「〇〇でもわかる!」を目指してコードをかみ砕いてみます
ボタンを押したら音を鳴らす
document.getElementById("myButton").addEventListener("click", () => {
playRestThenDo();
});
上からコードを見ていくと順番が「?」に感じることがあるのですが、まずは「ボタン」の処理からスタートします
ここで、ボタンがクリックされたときに playRestThenDo()
を実行します。
音を鳴らす
// 休符 → ド(C4)の音を鳴らす
async function playRestThenDo() {
await rest(1000); // 休符(1秒)
await playTone(261.63, 1000); // ドの音(1秒)
}
async function 宣言は、AsyncFunction オブジェクトを作成します。非同期関数が呼び出されるたびに、新しいプロミス (Promise) が返され、非同期関数によって返された値で解決されます。または、非同期関数内で捕捉されなかった例外で拒否されます。
「エイシンク ファンクション」によって、await
を使って処理の順番をコントロールしています。
rest(1000)
は 1秒後に完了する Promise
を返す → 「1秒待つ」
playTone(261.63, 1000)
も Promise
を返す → 「ドの音を1秒鳴らす」
await
を使うことで、「1秒待ってから、ドの音を1秒鳴らす」
という動きが可能に。
実際に音を鳴らす関数での処理
// 音を鳴らす関数(周波数と長さを指定)
function playTone(frequency, duration) {
return new Promise(resolve => {
// audioCtx = 音の作業場。
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const oscillator = audioCtx.createOscillator();
const gainNode = audioCtx.createGain();
oscillator.type = "sine"; // 正弦波
oscillator.frequency.value = frequency; // 周波数を設定
gainNode.gain.setValueAtTime(0.5, audioCtx.currentTime); // 音量調整
oscillator.connect(gainNode); // 発振器と音量調整を接続する
gainNode.connect(audioCtx.destination); // 音をスピーカーに送る
oscillator.start(); // 音を鳴らす
setTimeout(() => {
oscillator.stop(); // 一定時間経ったら音を止める
resolve(); // 終わったら次に進む
}, duration);
});
}
// 休符(無音時間を作る)
function rest(duration) {
return new Promise(resolve => setTimeout(resolve, duration));
}
やたらplayTone
に関する部分が多いので、「???」が多くなりますが、少しずつ見ていくと意外と単純。公式の説明を見たうえで、ここではコメント形式で意味を記載します。
また、swetTimeout
については以下を参考にすると次のような意味になります。
rest(1000)
を実行
new Promise(resolve => setTimeout(resolve, 1000))
が作られる
setTimeout()
が 1秒後に resolve()
を実行
await
があるので 「1秒経つまで次の処理を止める」
1秒後に Promise
が完了し、次の処理へ進む
さいごに
今回実装にあたり、定数の名前で「?」が生じました。一般的に使用されているものですが、いままでなじみがなかったので知る事、発見が多いです。
今回の記事が何か参考になれば幸いです。