JavaScript
Tone.js

Tone.jsを使ってテキストからメロディを鳴らしてみた

More than 1 year has passed since last update.

ブラウザで音声を鳴らすことができるJavaScriptライブラリ「Tone.js」を使って、試しにテキストを音楽に変換するコードを書いてみました。


Hello Tone

まずは何か音を出してみます。

Tone.jsを読み込んで2行書くだけです。


HTML

<script src="https://tonejs.github.io/build/Tone.min.js"></script>



JavaScript

// 使用する音源を用意する

var synth = new Tone.Synth().toMaster();
// C5(音程)を4分音符で鳴らす
synth.triggerAttackRelease('C5', '4n');

これでポーンという単音が鳴りました。

簡単ですね。

コード&サンプル

http://jsbin.com/torufil/edit?html,js,output


メロディを鳴らす

次に複数の音を連続して鳴らします。

いきなり複雑になりますが、以下のようにします。


JavaScript

// メロディを鳴らす音源

var synth = new Tone.Synth().toMaster();
// メロディの音階データ
var melody_data = [
'E5', 'C5', 'G4', 'C5', 'D5', 'G5', null, 'G4',
'D5', 'E5', 'D5', 'G4', 'C5', null, null, null // nullは休符
];
function addMelody(time, note) {
synth.triggerAttackRelease(note, '8n', time);
}
var melody = new Tone.Sequence(addMelody, melody_data).start();
// テンポを指定
Tone.Transport.bpm.value = 140

function play_music() {
Tone.Transport.start();
}


コード&サンプル

http://jsbin.com/qaxobun/edit?html,js,output

どこかで聞いたことのあるメロディではないでしょうか?


マルチトラック再生

今度は複数のメロディを同時に鳴らしてみます。

先ほど作ったメロディにベースラインのようなものを追加しました。


JavaScript

var melody_synth = new Tone.Synth().toMaster();

var bass_synth = new Tone.Synth().toMaster();
var melody_data = [
'E5', 'C5', 'G4', 'C5', 'D5', 'G5', null, 'G4',
'D5', 'E5', 'D5', 'G4', 'C5', null, null, null
];
var bass_data = [
'C3', null, null, 'C3', 'G2', 'G2', null, null,
'G2', 'G2', null, 'G2', 'C3', null, null, null
];
function addMelody(time, note) {
melody_synth.triggerAttackRelease(note, '8n', time);
}
function addBass(time, note) {
bass_synth.triggerAttackRelease(note, '8n', time);
}

var melody = new Tone.Sequence(addMelody, melody_data).start();
var bass = new Tone.Sequence(addBass, bass_data).start();
Tone.Transport.bpm.value = 140

function play_music() {
 // 複数のSequenceを同期再生させる
Tone.Transport.start();
}


コード&サンプル

http://jsbin.com/dutotix/edit?html,js,output


ドレミのテキストからメロディを鳴らす

最後にテキストをメロディに変換してみます。

入力は以下のようなテキストで、これを適当にパースしてTone.jsにメロディデータとして渡してやります。

ドレミファミレドー

ミファソラソファミー
ドードードードー
ドレミファミレドー


JavaScript

var melody_synth = new Tone.Synth().toMaster();

var tone_texts = {
"ド": "C5",
"レ": "D5",
"ミ": "E5",
"ファ": "F5",
"ソ": "G5",
"ラ": "A5",
"シ": "B5",
"ー": null
}
function addMelody(time, note) {
melody_synth.triggerAttackRelease(note, '8n', time);
}

Tone.Transport.bpm.value = 140

function play_music() {
var melody_data = [];
var score = document.getElementById('score');
var score_source = score.value
while (score_source.length > 0) {
for(text in tone_texts){
if (score_source.indexOf(text) == 0) {
melody_data.push(tone_texts[text]);
break;
}
}
score_source = score_source.slice(1);
}
var melody = new Tone.Sequence(addMelody, melody_data).start();
Tone.Transport.start();
}


コード&サンプル

http://jsbin.com/levuwah/edit?html,js,output

無事に曲が流れました。めでたしめでたし♪


まとめ

今回はTone.jsを使ってテキストを入力として単純な曲を再生するところまでやってみました。

Tone.jsは他にも楽器を選択したり、音そのものを加工したり、音を可視化したりできるようです。JavaScriptで扱えるので、Three.jsなど他のライブラリと連携させると面白いことができそうな気がしました。

また今度、遊んでみたいと思います。