とりあえず難しいこと置いといて、Web Audio APIから波形データだけ抽出して遊んでみたい人向け

色々できるWeb Audio API

音自体をWeb Audio API経由で生成したり、AudioNodeに対してイコライザーみたいなフィルターを掛けれたりと、何やら凄そうな Web Audio API さん

ただ、自分的にはとりあえず難しいことは一旦置いといて可視化して遊びたいだけだったりする。

遊びたいだけなんだけど :(

肝心のお遊びコードを書くまでに、色々前準備が必要なので ;(
そこら辺をすっ飛ばす用のコードを書いてみた。

※ といっても準備自体はそんなに大変じゃないですが


こんな感じで遊べます

下部四角い領域をクリックしてみてください。

※ 注意:音が流れます

お借りした音源
http://maoudamashii.jokersounds.com/archives/song_mio_noapusa.html


AudioManager

ソースコードはGithubにあげておきました。

tnker/AudioManager.js
https://github.com/tnker/AudioManager.js

上記GithubページからソースコードZIPとかでダンロードしてもらって、binの中身を読み込ませてもらえれば使えます。

簡単な使い方

細かい使い方は後ほど記載するので、とりあえずマイク入力を使って波形の数値を取得してみる

scriptタグでダウンロードしたJSファイル定義後、下記JSコードをscriptタグ上に実装してもらって、htmlファイルをブラウザで開いてみてください。

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <script src="./bin/audioManager.min.js"></script>
    <script>
        var manager;
        window.onload = function() {
            manager = (new AudioManager({
                useMicrophone   : true,
                onEnterFrame    : function() {
                    console.log(Utils.sum(this.analyser.mic.getByteFrequencyData()));
                }
            })).init();
        };
    </script>
</body>
</html>

htmlをブラウザで開くと、下記のようなマイクアクセスの許可を催促するようなバルーンが表示されると思います。

下記画像はGoogle Chromeの場合ですが、大体ブラウザ上部に何か出てきます

バルーンが表示されたら、許可を選択してあげてください。

稀にバルーンが表示されずにリジェクトされる場合があるので、consoleに「reject」みたいなログが出てたら一回リロードしてみてください

許可を終えると、マイク入力が有効になって一番最初に記述してもらったコード内の onEnterFrame が走り始めます。

この onEnterFrame が毎フレーム実行されます。
上記コード内で行っている処理は次のコードの結果をconsoleに出力してるだけです

Utils.sum(this.analyser.mic.getByteFrequencyData())

this.analyser.mic.getByteFrequencyData()

マイク入力を有効にするとAudioManagerのプロパティ analyser.mic 配下に、波形データを取り扱うAnalyserをラップしたインスタンスが生成され、そのインスタンスが持っている getByteFrequencyData() メソッドを実行すると波形データが格納された配列が取得できます。

ここで記載している getByteFrequencyData メソッドは、実際にanalyserのインスタンスが持っているメソッドではなく、私が勝手に同名で生やしたメソッドです
マイク入力を管理している実際のanalyserのインスタンスは this.analyser.mic.a でアクセスできます

Utils.sum

こやつは単純に配列内の数値をすべて足した結果を返してくれるだけの関数です(1ファイルで完結させたかったので自分で書いちゃってます)

実際に実行してみると、consoleに大量の数値が出力されるので、マイクに向かって音を立ててみると数値が大きくなったり小さくなったりします。

あとは、この数値使って遊ぶだけですね!:)
ということで、マイク入力はこんな感じ。


音源データ再生周り

細かい使い方は Github のREADMEに殴り書きしたので、ここではこんな感じで書けば使える!程度の説明になります。

長くなるので ;(

あと、ここからは window.onload 内の処理を抜粋した形でコードを載せていきます。

音源データの読み込み

htmlと同階層に適当なmp3ファイルとかを用意してもらって、次のような形でAudioManagerのloadメソッドを実行すると読み込みが開始します。

manager = (new AudioManager({
    onEnterFrame    : function() {
    }
})).init();
// 読み込み処理開始
manager.load({
    bgm: './bgm.mp3'
});

音源データ読み込み後処理

音源データの読み込み後に処理を実行したい場合は、AudioManagerのコンストラクタの設定に onLoaded メソッドをバインドしてあげます。

manager = (new AudioManager({
    onLoaded: function() {
        // 音源データ読み込み完了後に実行される
    },
    onEnterFrame    : function() {
    }
})).init();
// 読み込み処理開始
manager.load({
    bgm: './bgm.mp3'
});

音源データの再生/停止/状態取得

再生 - play('文字列')

例えば先ほどの音源データ読み込み完了時に合わせて再生を開始したい場合は

manager = (new AudioManager({
    onLoaded: function() {
        // 再生開始
        this.play('bgm');
    },
    onEnterFrame    : function() {
    }
})).init();
// 読み込み処理開始
manager.load({
    bgm: './bgm.mp3'
});

playメソッドの引数に与える文字列は、音源データ読み込みの loadメソッドにの引数に設定したオブジェクトの各キーになります。

停止 - stop('文字列')

manager = (new AudioManager({
    onLoaded: function() {
        // 再生開始
        this.play('bgm');
    },
    onEnterFrame    : function() {
    }
})).init();
// 読み込み処理開始
manager.load({
    bgm: './bgm.mp3'
});
// ...なんか色々処理があって
manager.stop('bgm');

stopメソッドもplayメソッド同様に、操作を行いたい音源データのキー文字列を指定します。

再生状態 - isPlaying('文字列')

manager = (new AudioManager({
    onLoaded: function() {
        // 再生開始
        this.play('bgm');
    },
    onEnterFrame    : function() {
        if (this.isPlaying('bgm')) {
            // 再生中であれば何か処理
        }
    }
})).init();
// 読み込み処理開始
manager.load({
    bgm: './bgm.mp3'
});

指定した音源が再生中であれば true 、そうでなければ false を返します。


毎フレーム処理周りのオプション

fps値設定できます。

manager = (new AudioManager({
    fps             : 60,
    onEnterFrame    : function() {
        // 毎フレーム処理
    }
})).init();

波形データ周りの使い方

波形データの取得について

基本的にはマイク入力もしくは、読み込んだ音源データの波形データを onEnterFrame内で更新しつつ、波形データの値を使って「なんかする」ことを想定して作ってます。

エントリの最初の方で、マイク入力の波形データを更新しつつ取得する方法で

this.analyser.mic.getByteFrequencyData();

を実行すれば良いよ!と記載しましたが、音源データを読み込んだ場合は上記コードの mic 部分が、音源データ読み込み時の loadメソッドに渡したオブジェクトのキーになります。

実際のサンプル

manager = (new AudioManager({
    onLoaded: function() {
        // 再生開始
        this.play('bgm');
    },
    onEnterFrame: function() {
        // ここで読み込んだbgm.mp3の波形データにアクセスしたい場合
        console.log(this.analyser.bgm.getByteFrequencyData());
    }
})).init();
// 読み込み処理開始
manager.load({
    bgm: './bgm.mp3'
});

loadメソッドにbgmというキーで音源を読み込ませた場合は、その音源の波形データを取得する際のプロパティがbgmになります。

波形データ取得時のレンジ(ffSize)について

AudioManagerのコンストラクタのオプションにffSizeというプロパティを指定できます。

ここで詳しくは説明しませんが、このffSizeは波形データの領域になっており上記で記載した getByteFrequencyDataメソッドで取得できる配列のlengthは、このffSizeを半分にした値になります。

デフォルトでffSizeは 2048 なので、getByteFrequencyData で返却される配列のlengthは、1024になります。

なので、波形データを取得してごにょごにょしたい際に少し波形データを小さくしたい場合はffSizeの値を絞ればOKです

manager = (new AudioManager({
    ....
    ffSize: 256,
    onEnterFrame: function() {
        var d = this.analyser.bgm.getByteFrequencyData();
        console.log(d.length); // output: 128
    }
})).init();

ということで

とりあえず音鳴らしてなんかやってみたい人向けには大分手間省けていいんじゃないかなー。そんなことないかなー。

とりあえず、Audio API他にも色々できるので行けるとこまでやってみる :)