「Web Audio API」を使うと音声の「再生」だけでなく、音の「生成」や「加工」などもJavaScriptだけで手軽にプログラミングすることが出来るようになります。
ただ、ちょっとクセがあるので「扱いにくい…」と感じる人も少なくないでしょう。
そこで、誰でも簡単に「Web Audio API」を活用できるJavaScriptライブラリ「Tone.js」について、今回は簡単なサンプルと共にご紹介しようと思います!
ファイルを準備しよう!
まずは、「Tone.js」を使ったサンプルを作るのに必要な「index.html」と「app.js」を用意しましょう。
「Tone.js」自体は、GitHubからダウンロードするか、以下のURLから利用可能です。
https://tonejs.github.io/build/Tone.min.js
ひとまず、「index.html」はこんな感じでOKでしょう。
<!-- index.html --> <!doctype html> <html> <head> <meta charset="utf-8" /> <title>Tone.jsサンプル</title> </head> <body> <script src="Tone.min.js"></script> <script src="app.js"></script> </body> </html>
あとは、「app.js」ファイルを作成すれば準備完了です!
「音」を鳴らしてみよう!
それでは、早速「音」を生成して鳴らしてみたいと思います。
単純に「単音」を作って再生するだけであれば、以下のようにわずか2行のコードで実現できます!
// app.js //音源を生成 var synth = new Tone.Synth().toMaster(); //「C5」の音を「2分音符」で発音 synth.triggerAttackRelease('C5', '2n');
「Tone.js」には、さまざまな音源があらかじめ搭載されており、「Tone.Synth()」と書くだけで専用の音源に接続することができます。(この場合は「Synth」という音源に接続します…)
そして、その音源は「マスター」と呼ばれる場所「toMaster()」に接続することで発音する仕組みになっています。
これを変数「synth」に格納すると、あとは「synth.triggerAttackRelease()」で音を鳴らすことができます。
次のサンプルデモにある「再生」ボタンをクリックすると、実際に「音」を鳴らして確認することができます!
「triggerAttackRelease()」内の「2n」というのは、「Tone.js」が持つ独特の名称になっており、以下のような意味合いがあります。
「2n」:2分音符
「4n」:4分音符
「8n」:8分音符
「1m」:全音符(1小節)
これにより、どのくらいの「長さ」で音を発音するかを指定できるわけです。
「音階」を奏でよう!
「単音」だけ鳴ってもつまらないので、今度は「音階」を鳴らしてみたいと思います。
先ほどの「triggerAttackRelease()」を複数行書いても実現できますが、ちょっと面倒ですよね。そこで、「Tone.js」には「シーケンス制御」が可能なAPIが提供されています。
構文は以下のとおり!
var melody = new Tone.Sequence(【関数】, 【音階の配列】).start()
まず、【音階の配列】を以下のように作ります。
// 「ド・レ・ミ・ファ・ソ・ラ・シ・ド」を作る var melodyList = [ 'C3', 'D3', 'E3', 'F3', 'G3', 'A3', 'B3', 'C4' ];
1つの値が「一拍分」となるので、上記の配列だと2小節分の長さになります。
ちなみに、値を配列にすれば「一拍分」の中に、複数の音を配置することも出来ます。(1つの値を['C3','D3','E3','F3']にすれば、4つの音が一拍分に入ります…)
次に、【関数】の部分ですが、これは先ほどのコードを追加すればOKです。
function setPlay(time, note) { synth.triggerAttackRelease(note, '8n', time); }
引数として「time」と「note」が取得でき、「note」には音階の配列情報が入っており、「time」には全体の「時間軸」情報が入っています。
そして、このように指定すれば「シーケンス」は実現できます!
var melody = new Tone.Sequence(setPlay, melodyList).start();
ただし、このままでは「音階」は再生されません。
先ほど、変数「time」に全体の「時間軸」情報が入っていると書きましたが、この時間軸を動かすことで「シーケンス」で制御された「音階」が再生される仕組みになっています。
この時間軸を動かすには、以下のように書きます。
Tone.Transport.start();
これでOK!
次のサンプルデモにある「再生」ボタンをクリックすると、音階が実際に再生されます。
この「時間軸」を使って再生するメリットの1つとして、複数の音源を使った場合でもしっかり同期されるので「ズレ」も無くなり、全体が同じタイムライン上でキレイに再生されるわけです。
「コード(和音)」を奏でよう!
「音階」を鳴らすことに成功したので、今度は複数の「音」を同時に鳴らす「コード(和音)」に挑戦してみましょう!
これは「パート制御」ができる専用のAPIが用意されており、構文は次のとおり!
var melody = new Tone.Part(【関数】, 【コードの配列】).start();
基本的には、先ほどの「シーケンス制御」と同じです。
ただ、今回は「単音」ではなく「コード(和音)」になるので、あらかじめ複数の音を配置したコードの準備が必要になります。
つまり、こんな感じになります!
//「C」「D」「G」のコードを作る var C_chord = ['C4', 'E4', 'G4', 'B4']; var D_chord = ['D4', 'F4', 'A4', 'C5']; var G_chord = ['B3', 'D4', 'E4', 'A4'];
これで、配列の「C_chord」を指定すれば、「C」のコードが発音することになります。
あとは、このコードを使って、音階を再生するための配列をもう1つ作ればOK!
//コードを使った音階を作る var chordMelody = [ ['0:0:2', C_chord], ['0:1:0', C_chord], ['0:1:3', D_chord], ['0:2:2', C_chord], ['0:3:0', C_chord], ['0:3:2', G_chord] ];
ポイントは、左側に「発音タイミング」を記載している点です。
読み方は、次のとおり。
「1:0:0」:1小節目
「0:2:0」:2拍目
「0:0:2」:1拍の半分
この指定により、任意のタイミングでコードを鳴らすことが出来ます。
次のサンプルデモにある「再生」ボタンをクリックすると、実際にコード(和音)を再生することが出来ます!
「音源」について!
さて、これまで「音源」として利用していた「Synth」ですが、実は音色をさらに細かくカスタマイズすることが出来るようになっています。
これは、「option(オプション)」を指定することで対応可能です。
new Tone.Synth(option).toMaster(); var option = { // ここにオプションを書く }
オプションの中身については、各音源によって違いますが、「Synth」に関してはこんな感じになります。
var option = { oscillator: { type: "triangle" }, envelope: { attack: 0.005, decay: 0.1, sustain: 0.3, release: 1 } };
「oscillator」の箇所で、音色の元になる「波形」を指定します。
「envelope」の箇所は、基本的な音作りでよく使われる「ADSR」と呼ばれるパラメータに対応しています。
これらの「オプション値」をいじることで、手軽に音色を変えて楽しめるようになっているので便利です。
以下に、いくつかの音源によるサンプルデモがあるので、ぜひそれぞれの音源を聴き比べてみてください!
デモは、画面上に鍵盤が表示されるので、マウスでクリックしてみてください。(キーボードにも対応しています)
ちなみに、「Tone.js」は音源だけでなく、「エフェクト」も豊富に搭載されています。
「リバーブ」「フィルター」「コーラス」のように、一般的なDTMソフトに同梱されているモノはだいたい揃っている感じです。
利用方法も簡単で、例えば「リバーブ」を使うときはこんな感じに書きます。
var reverb = new Tone.Freeverb().toMaster();
今まで「音源」を指定していたような感覚で使えますね。
そして、生成した「リバーブ」を、音源(synth)に接続するには次のように書きます。
synth.connect(reverb);
これでOK!
再生すると、リバーブ効果が掛かった音色が鳴るのが分かると思います。
実際に、いくつかエフェクトを試せるサンプルデモがあるので、ぜひチェックしてみてください!
まとめ
今回は、「Tone.js」の基本的な部分のみに限定しましたが、これだけでも面白い音楽プログラミングが実現できるのが分かると思います。
他にも、自分で用意した「音声ファイル」を使って音源を作る「サンプラー」機能や、MIDIの読み込み、クオンタイズ…など、本格的なDTMソフトを開発できる機能が豊富に搭載されているのも魅力的です。
音楽アプリやサービスの開発にご興味ある方は、ぜひサンプルデモをチェックして豊富な機能を試してみてください!