これはTSG Advent Calendar 2016 - Adventarの18日目の記事として書かれるはずのものでした。

デモページ
とりあえず説明です。

概要
 JavaScriptとHTML5 Canvas+pixi.jsを用いた音楽アナライザー
特徴
 サーバーに頼らずクライアント内で処理をしている
 最新ブラウザならパソコンだけではなくスマホでも利用可能
説明
・ファイルを選択で手持ちの音楽ファイル(.mp3,.wav,.m4aで動作確認済み.動画ファイルだが.mp4でも可能)
・一番下がC3,上がB8までの72音階に分けてその音階がどれだけ出ていたのかを表しています。上のほうが周波数としては高く、下は低くなっています。音と周波数の関係はこちらのページを参考にしてください。
・緑色で表示されている部分はその時間帯で最も音が強い音階です。
・黄色で表示されている部分は緑色と同じくらい音が強いです。
・赤色で表示されている部分は赤色に近ければ近いほど音が強いことを表しています。緑色黄色には及びません。
・同時にBPMの検出も行っています。右上に表示されています。その横にある赤い丸はBPMに応じて点滅しています。
・BPMの検出に応じて赤い線と赤い線の間が4分音符1つ分になるように調整しています。
・曲を変える時は一度更新ボタンを押さないと正しく動作しません。

どのように解析しているのかを軽く説明します。

(1)ユーザーの手元にあるファイルを解析する段階まで
ファイルの読み込みは、HTMLのinput要素を使います。"ファイルを選択する"というボタンのことです。こちらから音楽ファイルを読み込みaudio要素のsrc属性で指定すれば音楽の再生は可能です。しかし、これだけでは解析することが不可能です。そこでWebAudioAPIを利用します。具体的にはAudioContext インターフェースのdecodeAudioDataメソッドによって、音楽データをデコードします。そうすると音量のデータが配列として扱えるので便利になります。また音楽解析用にJavaScriptでクラスを定義しておき、各種メソッドを行うことで解析できるようにします。

(2)どのように解析するか
音楽解析用クラスのプロパティに音楽ファイルのデータを設定した後、各種解析を行います。
まず最初にBPMの検出を行います。こちらはいろんな手法が考えられていますが、
C/C++言語で音声ファイルのテンポ解析を行うサンプルプログラム(http://hp.vector.co.jp/authors/VA046927/tempo/tempo.html)
を参考に実装してみました。

他には1秒間に数十回くらいWebAudioAPIで定義されているFFT(フーリエ高速変換)を行います。そうするとある特定の周波数ごとの強弱が数値として表れます。ただ、特定の周波数が12音階の周波数と一致するわけではないので多少計算で処理を行う必要があります。

(3)どのように表示するのか
HTML5 Canvas+pixi.jsを使って表示しています。
pixi.jsだとWebGLを利用するので描画が高速になると思い利用しました。実際どれくらい速くなっているかは分かりません。


本当は自動採譜などを入れたかったんですが難しいですね。