paiza開発日誌

IT/Webエンジニア向け総合求人・学習サービス「paiza」(https://paiza.jp ギノ株式会社)の開発者が開発の事、プログラミングネタ、ITエンジニアの転職などについて書いています。

初心者でも音楽アプリが作れる!Web Audio APIを簡略化したJSライブラリ「Tone.js」でピアノ鍵盤を作ってみよう!

f:id:paiza:20170301143842j:plain
どうも、まさとらん(@0310lan)です。

今回は、Web Audio APIの実装で面倒な処理をすべて簡略化し、誰でも音楽プログラミングを楽しむことが可能なJavaScriptライブラリのご紹介です。

わずか数行のコードでゼロから「音」を作り出し、メロディを奏でたりエフェクトをかけたりシーケンスを組み立てたり…など、本格的なWebアプリも作れるポテンシャルを秘めていますよ!

Tone.js

f:id:paiza:20170301144103j:plain

(多彩なサンプル事例はコチラから確認できます)

■必要なファイルを準備しよう!

今回は、簡単なサンプルデモを実際に作りながら「Tone.js」の基本的な使い方をご紹介していこうと思います。

作るのは、簡易的な「ピアノの鍵盤」です!
f:id:paiza:20170301144129j:plain

Tone.js」を使うと、わずかなコードで「音」を生成して発音させることが出来るので、「鍵盤」のモチーフは初めての学習にちょうど良いと思います。


さて、このサンプルを作るのに必須なのが「Tone.js」の本体ファイルです。

これは、GitHubからダウンロードするか以下のURLから手軽に利用することが出来ます。

https://tonejs.github.io/build/Tone.min.js


そして、HTMLファイルで「Tone.js」を読み込むようにしておきましょう。

<body>


    <h1>Tone.jsサンプルデモ</h1>




    <script src="Tone.min.js"></script>
    <script src="main.js"></script>


</body>

一緒に読み込んでいる「main.js」は、これからプログラミングしていくファイルになります。

ひとまず、最初の準備はこれくらいで良いでしょう!

■基本的な「音」作りに挑戦!

それでは、いよいよ「音」を生成して鳴らしてみたいと思います!


Tone.js」には、さまざまな種類のシンセサイザーが用意されているのですが、まずは最もシンプルな「Tone.Synth()」を使ってみましょう。

わずか2行のコードで、簡単に音を「生成&再生」できることが分かります!

// 音源の「Tone.Synth()」を作り、マスター出力に接続
var synth = new Tone.Synth().toMaster();


// 中央の「ド(C4)」を4分音符で発音する
synth.triggerAttackRelease( 'C4', '4n' );

最初の1行で、「Tone.Synth()」のインスタンスを作成していますが、ポイントは「toMaster()」を付けている点です。これにより、「マスター出力」と接続されて発音する準備が整うわけです。


2行目は、実際に発音させる処理になりますが、1つ目の引数に「音名」を入れます。音名は、ド(C)、レ(D)、ミ(E)、ファ(F)、ソ(G)のような一般的な英文字で、音の高さを数値で表します。

2つ目の引数は「音の長さ」で、「4n(4分音符)」「8n(8分音符)」「16n(16分音符)」のように表記すればOK


以下のリンクから、実際に「音」を発音するサンプルを試せるので、ぜひ確認してみてください!

「音」の発音サンプルデモ

■「Tone.js」のシンセサイザーについて!

少し余談になりますが、先ほど「Tone.js」にはさまざまな音源となる「シンセサイザー」が用意されていると説明しました。

公式サイトにも掲載されていますが、アナログシンセサイザー、FMシンセサイザー、ポリフォニック・シンセサイザーサンプラーなども利用可能です。


その利用方法も簡単で、例えば先ほどはシンプルな「Tone.Synth()」を使いました。

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


これを、「FMシンセサイザー」に変更する方法は、単純に「Tone.FMSynth()」と書き換えるだけで利用可能になります!

var synth = new Tone.FMSynth().toMaster();

他にも、「Tone.AMSynth()」や「Tone.PolySynth()」などいくつかありますが、使い方はどれもほとんど同じなので簡単です!


また、すべてのシンセサイザーは各種パラメータも自由にいじれるようになっており、「Tone.Synth()」の場合は、こんな感じでオプションを設定できます。

synth = new Tone.Synth({
    oscillator:{


        // 波形の設定
        type:"triangle"


    },
    // エンベロープ(ADSR)の設定
    envelope:{


        attack:0.005,
        decay:0.1,
        sustain:0.3,
        release:1


    }
}).toMaster();

シンセサイザーによってパラメータの種類はいろいろありますが、設定方法はいずれも同じです。


今回の記事では、説明を簡単にするためにデフォルトの「Tone.Synth()」を使っていますが、多彩なシンセサイザーの音色もぜひ楽しんでみてください!

■「ピアノの鍵盤」を作ろう!

それでは、今回作るサンプルデモの「鍵盤」を作っていきましょう!

機能としては、マウスの「クリック操作」やPCの「キーボード操作」から音が鳴るようにしたいと思います。


「白鍵」「黒鍵」いずれも「div要素」で四角形を作り、CSSでレイアウトを整えていきます。

<div id="keyboard">


    <div data-key="65" class="whitekey"><span class="text">C5</span></div>


    <div data-key="87" class="blackkey"><span class="text">C#5</span></div>


    <div data-key="83" class="whitekey"><span class="text">D5</span></div>


    <div data-key="69" class="blackkey"><span class="text">D#5</span></div>
    ・
    ・
    ・


</div>

マウスの「クリック操作」からでも音が鳴るように「data属性」にKeyCodeを設定し、JavaScriptから識別するようにしています。(KeyCode一覧 | MDN


CSSで鍵盤っぽくなるようにサイズを調整し、「黒鍵」は「position: absolute」で配置したあとに「z-index」で一番上にレイアウトしましょう。

#keyboard {


    width: 100%;
    position: relative;


}


.whitekey {


    width: 10%;
    height: 240px;
    display: inline-block;
    border: 1px solid #000;


}


.blackkey {


    width: 9%;
    height: 140px;
    display: inline-block;
    margin-left: -5%;
    background-color: #000;


    position: absolute;
    top: 0;
    z-index: 1;


}


あとは、JavaScriptでプログラミングするだけなのですが、マウスやキーボードを押し続けると連続して「音」が発音されてしまうのを防ぐために、「押した時」「離した時」の状態をフラグで監視しながらイベント処理を組み立てていきます。

// Tone.Synth()の使用準備
var synth = new Tone.Synth().toMaster();


var state = true;  // 入力状態の監視用




// 「マウス」か「キーボード」を押した時のイベント処理
window.addEventListener('keydown', playSound);
window.addEventListener('mousedown', playSound);


// 「マウス」か「キーボード」を離した時のイベント処理
window.addEventListener('keyup', offSound);
window.addEventListener('mouseup', offSound);




function playSound( e ) {


}


function offSound( e ) {


}


マウスやキーボードを押した時に、どの「div要素」が押されたのかをチェックする仕組みとして、「キーボード」の場合は「keyCode」を取得してdiv要素を特定し、「マウス」の場合は「data属性の値」を取得してdiv要素を特定します。

function playSound(e) {
  
    // 「キーボード」はkeyCodeを、「マウス」はdata属性を取得する
    var key = e.keyCode || e.target.dataset.key;


    // 「key」を使って「div要素」を取得する
    div = document.querySelector('div[data-key="' + key + '"]');
  
}


「div要素」さえ特定できれば、「div.textContent」から「音名」を取得して発音させるだけです!

function playSound(e) {
    if(!state) return;  // falseなら処理を実行しない
  
    var key = e.keyCode || e.target.dataset.key;


    div = document.querySelector('div[data-key="'+ key +'"]');


    
    // 「div要素」が取得できたかチェック
    if(div) {


        // div要素のテキスト(音名)を代入する
        synth.triggerAttackRelease(div.textContent, '8n');


        // 状態をfalseにして、連続的な発音を防止する
        state = false;


    }


}

「state」フラグを使って、「押しっぱなし」状態でも1回しか発音しないようにしているのがポイントです。

また、「div要素」を取得できたかを「if文」で確認することで、関係ない「キー」を押してもエラーにならないようにしておきましょう。


そして、離した時の処理で「state」フラグをtrueに戻しておけばOK

function offSound(e) {
    state = true;  // 再度、発音できるようにtrueへ戻す
}


これで、基本的な「鍵盤」の完成です!

以下のリンクから、実際にサンプルデモを試してみてください!
「ピアノの鍵盤」サンプルデモ


上記サンプルデモは、スマホにも対応させているので「電源ON」と書かれたボタンをクリックすることで、発音できるようにしています。
スマホの場合、ユーザーが何らかのアクションをしないと発音できないため…)

f:id:paiza:20170301144827j:plain

今回のサンプルデモの全ソースコードは、以下のリンクから閲覧可能です!

サンプルデモの全ソースコード|GitHub

■まだまだある「Tone.js」のこんな機能!

Tone.js」には、紹介しきれないくらい優れた機能があるのですが、ユニークな機能を3つほどピックアップしてご紹介しようと思います。


1つ目は、「メロディ演奏」について!

サンプルデモは「単音」で発音するだけでしたが、「Tone.Sequence()」を使うと複雑なメロディを一定のタイミングで制御することができます。

また、「Tone.Transport」と組み合わせることで、メインのタイムラインに沿った同期演奏が可能になり、複数の音源をミックスさせてもズレのない再生を簡単に実現できます。


以下は、メロディ演奏の簡単なサンプル事例です。

// メロディの音符を配列で保持
var melodyList = [
  'C4', 'D4', 'E4', 'F4',
  'G4', ['A4', 'B4'], 'C5'
];
var synth = new Tone.Synth().toMaster();


// メロディをシーケンス制御する
var melody = new Tone.Sequence(setPlay, melodyList).start();


  
melody.loop = 1;  // ループを1回に設定
Tone.Transport.bpm.value = 90;  // BPMを90に設定
Tone.Transport.start('1m');  // 1小節分の時間をおいてから発音




function setPlay(time, note) {
    // 8分音符でメロディを発音
    synth.triggerAttackRelease(note, '8n', time);
}


2つ目は、「エフェクト」について!

Tone.js」では、多種多様なエフェクトも簡単に扱えるように設計されており、基本的な使い方はこんな感じです!

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


// 「リバーブ」エフェクトを使用する
var reverb = new Tone.Freeverb().toMaster();


// シンセとエフェクトを接続
synth.connect(reverb);


// エフェクト付きで発音
synth.triggerAttackRelease('C4', '2n');

音源の「Tone.Synth()」とほぼ同じような使い方になっており、「connect()」メソッドを使ってシンセと接続するだけで利用できるわけです。
(もちろん、複数のエフェクトを繋ぐことも可能です)

「エフェクト」公式ドキュメント


3つ目は、「MIDI」の扱いについて!

Tone.js」には、「MidiConvert.js」というプラグインが用意されており、これを読み込むことでMIDIファイルをJSON形式に変換して演奏させることが可能になっています。


以下は、任意のMIDIファイルを読み込んで演奏させる簡単なサンプル事例です。

var synth = new Tone.PolySynth(16).toMaster();


MidiConvert.load("【.midファイルを指定】", function(midi) {


    // .midファイルと同じBPMに設定
    Tone.Transport.bpm.value = midi.header.bpm;


    // 必要なパート分をループ
    for(var i=0; i<midi.tracks.length; i++) {
        new Tone.Part(function(time, note) {


            // .midファイルの通りに発音させる
            synth.triggerAttackRelease(note.name, note.duration, time, note.velocity);


        }, midi.tracks[i].notes).start();
    }
  
    // 全体のパートを同期させて演奏
    Tone.Transport.start();
});

公式サイトでは、ドラッグ&ドロップで「MIDIファイル」をJSON形式に変換できるデモサイトも用意されています。

これらの機能を活用することで、今回作った「ピアノの鍵盤」をさらに改造してバージョンアップさせてみるのも楽しいと思いますよ!

ポートフォリオ制作編やJavaScript・HTML/CSS講座も公開中「paizaラーニング


paizaラーニング」では、未経験者でもブラウザさえあれば、今すぐプログラミングの基礎が動画で学べるレッスンを多数用意しております。

先日、就職・転職活動に使える「ポートフォリオ制作編も公開されました!

今回ご紹介したようなアプリを自分で作って、「応募企業へのアピールに使いたいけどどうしたらいいの?」という場合も、ポートフォリオがあればスムーズです。詳しくはポートフォリオ制作編をぜひごらんください!

また、今回の記事で登場したJavaScriptやHTMLなど、言語ごとに基礎を学べる入門講座も好評公開中です!

↓詳しくはこちら
paiza.jp

■まとめ

今回ご紹介した「Tone.js」を使いこなせば、音楽編集ができる本格的なWebアプリを開発することも可能なポテンシャルを秘めています。

公式の「ドキュメント」と「サンプル」が非常に充実しているのも特徴で、順番に見ていくだけでどんな機能があって、どのように動くのか理解できるようになっているので、独学でも無理なく学習ができるでしょう。

ぜひ、みなさんもオリジナルの音楽Webアプリを作って、公開してみてはいかがでしょうか!

<参考>




paizaは、技術を追い続けることが仕事につながり、スキルのある人がきちんと評価される場を作ることで、日本のITエンジニアの地位向上を目指したいと考えています。

自分のスキルを磨いていきたいという方におすすめなのが「paizaラーニング」。オンラインでプログラミングしながらスキルアップできる入門学習コンテンツです。初心者でも楽しくプログラミングの基本を学ぶことができます。
paiza.jp
そして、paizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。
paiza.jp
スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。

ITプログラマ・エンジニア向け転職・就活・学習サービスのpaiza


プログラミング入門講座|paizaラーニング

PHP入門編Ruby入門編Python入門編Java入門編JavaScript入門編C言語入門編C#入門編アルゴリズム入門編