Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

17
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🏪JavaScriptのWeb Audio APIで「ファミマの入店音」を奏でる🏪

Last updated at Posted at 2024-12-28

概要

私の2023年のラストの記事で、🐸PowerShellのビープ音で「カエルの歌」を奏でる🐸という記事を書きました。その記事のセルフオマージュとなります。

今回はPowerShellではなく、JavaScriptのWeb Audio APIで同等の機能を実装してみます。

ぜひ、記事のコードを見比べながら読んでいただければと思います。

完成したもの

先に完成物です。ボタンを押すとファミマの入店音が流れます。
(音が出ますご注意ください)

プログラム

音の再生する関数

/**
 * 指定した周波数と長さの音を再生する
 *
 * @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年も頑張りましょう!

17
12
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

@ishi720's pickup articles

ishi720

@ishi720

休日は、無駄なものを開発しているオカメインコです。革新的なアイデアや文化は、無駄から生まれると思ってます。
Linked from these articles

Comments

ffgogfb454
@ffgogfb454

oscillator.typeを変えるとトライアングルみたいにしたりすることができます。

oscillator.typeのtriangleというのは三角波のことで波形の形を表しているもので、楽器のトライアングルのような音ということではありません。

2
ishi720
@ishi720

@ffgogfb454
ありがとうございます。
確かに紛らわしい表現になってましたので、記事の内容を修正しました。

2

Let's comment your feelings that are more than good

Qiita Advent Calendar is held!

Qiita Advent Calendar is an article posting event where you post articles by filling a calendar 🎅

Some calendars come with gifts and some gifts are drawn from all calendars 👀

Please tie the article to your calendar and let's enjoy Christmas together!

Being held Article posting campaign

17
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Login to continue?

Login or Sign up with social account

Login or Sign up with your email address