35
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ベーシックAdvent Calendar 2017

Day 9

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

Last updated at Posted at 2017-12-08

ブラウザで音声を鳴らすことができる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など他のライブラリと連携させると面白いことができそうな気がしました。
また今度、遊んでみたいと思います。

35
21
0

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
35
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?