Help us understand the problem. What is going on with this article?

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

basicinc
マーケティングとテクノロジーで社会のあらゆる問題を解決する集団
https://tech.basicinc.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした