ブラウザでドレミを鳴らす!「Web Audio API」を簡単に活用できるJSライブラリ Tone.js
ブラウザで和音を鳴らすことができるTone.jsの紹介です。
Tone.jsは、Web Audio APIを使うとJSで音を操ることができますが、さらにそれを活用できるJavaScriptライブラリです。
WEBサイトで音を鳴らすというのは勇気がいる行為です。ほとんどのユーザーには歓迎されないので、WEB制作において、Web Audio APIを使うことはほとんどありません。
でもアプリケーションなら需要があります。今回Tone.jsを使ってみると、本当に簡単に和音が鳴らせたので、感動しました。
音源やエフェクトをこちらで確認できます。
デモ
この記事とは関係ないですが、DTMやっています。OpenSeaに作曲したものを公開していく予定ですので、よければみてください。
Web Audio APIとは
Web Audio APIを使うと、jsで音楽や音声をコントロールすることができます。つまり、ブラウザ上にピアノのようなものを作ったり、インタラクティブに音を操作できます。
エフェクトを加えたり、ビジュアライゼーションを加えたり、パンニングなどの特殊効果を適用したり、ウェブ上で音声を扱うための強力で多機能なシステムです。
Web Audioの使い方を大まかにいうと、
1、オーディオコンテキストを作成
2、コンテキストの中で、audio、オシレーター、ストリームなどの音源を作成
3、リバーブ・フィルター・パンナー・コンプレッサーなどのエフェクトノードを作成
4、最終的な音声の到達先を選ぶ(例えばスピーカー)
5、音源をエフェクトに繋げ、エフェクトを到達先(destination)に繋げる
・・もうやってることはシンセサイザーです。昔のシンセみたいなことができるJavaScriptです。すごい。
しかも同時発音数の制限がないらしいです。32音やら64音やらの上限はなし。1000以上の音を詰まることなく再生できます。(そんなに同時に出さないけど)
Web Audio API は、img要素でいうcanvasみたいなもので、audio要素を置き換えるものではありません。audioを補完するものです。
音声の再生だけではなく、複雑な音声処理が必要な時に、「Web Audio API」で制御することができます。
Tone.jsのインストールと基本的な使い方
前置きが長くなりましたが、このWeb Audio APIのコンテキストをあれこれと簡単に使えるようにしてくれるのがTone.jsの紹介です。
インストール
npm i tone
インポート
import * as Tone from 'tone'
基本的な使い方
//音を作ってスピーカーに接続
const synth = new Tone.Synth().toDestination();
//音程は真ん中のド(C4)、再生時間は八分音符の長さを指定
synth.triggerAttackRelease("C4", "8n");
triggerAttackRelease()
triggerAttackReleaseにはパラメータが4つあります。
- notes — 音符データ
- duration — 音符の長さ
- time — アタック開始(再生開始)のタイミング
- velocity — ベロシティ(音の強さ)
上記ではnotesとdurationのみ指定しています。これだけでこの音が鳴ります。簡単すぎる。
八分音符の長さというとBPMによって変わってしまいますが、デフォルトBPMは120です(多分。コード内さらっと見ただけなので違うかも)。
durationは、秒で指定することも可能です。1にすると1秒間鳴ります。
timeを指定すると分散和音も鳴らせます。
toDestination()
アウトプットできるもの(スピーカーなどのオーディオレンダリングデバイス)に接続します。
これがあるから、PCから音が鳴ります。
音源と、モノフォニック/ポリフォニックについて
上記ではTone.Synth()で、シンプルなSynthの音源を指定しています。
「ぽーっ」という、THE.デフォルト!という感じの音です。ファミコンです。
音源はTone.FMSynth、Tone.AMSynth、Tone.NoiseSynthなど、数多くのシンセサイザーが用意されています。
これらの楽器はすべてモノフォニック(単一音声)で、一度に一つの音しか演奏できません。
モノフォニックの音源を使うと、
synth.triggerAttack("F4", 0.5);
のようなコードを何行も書いて和音にしないといけなくなります。
反対に、楽器やシンセサイザーなどで、同時に複数の音が出る(和音が出せる)事をポリフォニックと言います。
ポリフォニックなシンセサイザーを作るには、Tone.PolySynthを使います。
Tone.PolySynthは、triggerReleaseにノートの配列を指定して、和音にすることができます。
PolySynthは、モノフォニックなシンセサイザーを最初のパラメータとして受け取り、ノートの割り当てを自動的に処理するので、複数のノートを渡すことができます。
デフォルトの音源はTone.Synthですが、いくつか他の音源を試してみました。
AMSynth (モノフォニック)
AMはAmplitude Modulationの略で、振幅変調のこと。
Tone.Synthの出力を使って、別のTone.Synth の振幅を変調します。
やってみると、ふぉんっていう音が鳴りました。
FMSynth (モノフォニック)
FM(Frequency Modulation)は周波数変調。あるピッチの周波数を別の音で動かす技術のこと。
ピッチ、音色、音量の3要素を一括してコントロールできるのがおおきなメリットでした。(歴史的に)
AMSynthと似た音色でちょっと大きめのしっかりした音がなりました。
DuoSynth (モノフォニック x 2)
DuoSynthは、2台のMonoSynthを並列に動作させたモノフォニック・シンセサイザーで、2つのボイスの周波数比やビブラート効果をコントロールできます。
…ということですが、やってみたら、なんか濁った音になった…
PolySynth (ポリフォニック)
PolySynthはそれ自体はシンセサイザーではなく、他のタイプのシンセサイザーのボイスを管理するだけで、モノフォニックシンセサイザーをポリフォニックにすることができます。
つまり、パラメータに他の音源を指定し、それを和音で鳴らすことができます。
const synth = new Tone.PolySynth(Tone.FMSynth, { detune: 5 }).toDestination();
synth.triggerAttackRelease(["C4", "E4", "A4"], 1);
PolySynthのパラメータは、voiceとoptionです。(今の所ドキュメントが古いのか、ドキュメントでは第一引数はポリフォニーのナンバー、第二引数はvoiceになってました。惑わされた)
オプションで例に指定しているdetuneというのは、チューニングを微妙にずらすプロパティです。公式に例が載ってたので載せましたが、こういう使い方はあまりしないかもしれません。和音の全体のチューニングをずらしたところであまり意味がない(コーラス効果も得られない)ので。
やりすぎるとキーがかわります。
オプションは上のようにsynth.setを使ってセットすることもできます。
synth.set({ detune: 5 });
Sampler (ポリフォニック)
今回はこれを使います。なんとサンプラーがあるとは驚きました。
ノートのピッチやMIDI値をURLにマッピングしたオブジェクトを渡すことで音を鳴らすことができます。
つまり、波形を作るのではなく、サンプリング(録音)した音を使います。
これは強力な機能です。
使う音程全てを録音しないといけないのかというとそうではなく、音声ファイルを自動的にリピッチすることで、明示的に含まれていない音程を補完してくれます。結果、ロード時間を短縮することができます。
urlsプロパティで下記のようにオブジェクト{音程: ファイル名}で指定します。
const sampler = new Tone.Sampler({
urls: {
"C4": "C4.mp3",
"D#4": "Ds4.mp3",
"F#4": "Fs4.mp3",
"A4": "A4.mp3",
},
baseUrl: "https://tonejs.github.io/audio/salamander/",
}).toDestination();
Tone.loaded().then(() => {
sampler.triggerAttackRelease(["Eb4", "G4", "Bb4"], 1.5);
})
上記はTone.jsの公式に載っているサンプルコードです。これでピアノの音がなります。
自分で音源を用意しなくても、tone.jsがサンプリング音源をbaseUrlのところに置いてくれています。
なので、
https://tonejs.github.io/audio/casio/A2.mp3
にアクセスしたら、ラの音(A2)がなります。
このgithubのページにホストされているオーディオファイルの、わかりやすいリストは見つけられませんでした・・。が、Githubでディレクトリを見ることはできました。
各ファイルのリンクとライセンスは、各コレクションのフォルダにあります。
例にあるピアノのsalamanderは、READMEを読むと
ヤマハのグランドピアノ C5 をサンプリングしたものみたいです。さすがいい音。
midiも扱える
今回まだ試していませんが、midi音源も扱えるようです。
こちらのMidiというプラグインで、midiファイルを読み込んで解析し、JSON形式に変換して演奏させるようです。
https://github.com/Tonejs/Midi
midiが扱えるとは…もう無敵やないの…と思いました。が、
Tone.jsが用意してくれている、midiをJSON形式するジェネレータを使って
試しにGM規格の音源を使って作ったmidiファイルをドロップしてみましたが、音がおそらくSynthの音なので、ファミコンのようでした。
さすがにこれは再現できなかったです。頑張ればできるんでしょうか…
とはいえ、JSONデータをみると、bpmやキーなど、いろんなものが変更可能そうな感じでした。
また試してみたいです。
まとめ(というか語る。)
なぜこんなライブラリを調べていたのかというと、とあるアプリを作ろうと今頑張っているからです。
趣味でやってるバンドが、コロナにより休止してからもう1年をすぎました…。
スタジオに入らない→練習しない。という悪習慣を断つために、練習用のアプリを開発しようとしているのです。(何か方向が間違っている気がしなくもない)
WEB制作の仕事と音楽は、自分の2大趣味でありながら今までまったく噛み合わず、相乗効果も全然ないです。
WEB制作の知識、バンドに役立たない。バンドの知識、WEB制作に役立たない。
今回初めてキーボーディストとしてWEB制作側に貢献することができそうです。(完全に自分の中で完結してますが)
midiファイルを適当に探そうと思って、昔(もう15年前)作った曲を漁ってると、
意外といろいろ作ってました。懐かしい・・・と思ったのもつかの間、まともに再生できるものがほとんどない(泣)
というのも、当時、Windows XPで「Singer song writer4」というソフトで作っていたので、
拡張子がss4!!!!⬅️singer song writer 4 の独自ファイル形式!!!!!
Singer song writer4のソフト自体は捨てられずに物置にありますが、Windows XPじゃないと動かない。(もうそんなPC、とうにナイ)
しかも、偶然にもmid拡張子で残してたものも、聞いてみるとなんか音が変だったり抜けてたり…
記憶もおぼろげですが、デフォルトのmidi音源では音色が足りなかったので、外付け音源買ってた気がする
そしてその音源、なんと5年かそれくらい前にヤフオクに売ってしまいました。
もう再現不可能かもしれません。MU1000というヤマハの音源でしたが、15000円で売れたなあ(遠い目)
なんでmp3とかにしとかなかったんでしょう。めちゃくちゃ悔やまれます。
そんな悔いを昇天させるため、2023年からまた音楽制作(ソフトはStudio One)を始めました。
OpenSeaに公開していこうと思いますので、よろしくおねがいします!
conversationは2023年の曲、omoide-to-miraiは2003年ごろの曲です。
どうでもいいですが、昔のmidi音源を再生しようとしたら、macのデフォルトアプリである「GarageBand」というのが立ち上がってびっくりしました。
なんかすごいの入ってるな…Mac!!