The jonki

呼ばれて飛び出てじょじょじょじょーんき

Unityでマイクのボリュームをリアルタイムに取得する

2013/11/10 追記 やっぱりちゃんと動いていなさそうです。。



Unityでマイクから毎フレームのボリュームを取得しようとしたところ、こんな関数を発見してUpdateの度に呼んでみるがlengthSec毎にしかボリュームが更新されていなかった。基本録音用に使われるのでfloatではなくintで秒単位にしか取得できない。つまり1秒の粒度でしか音量が更新されない。

static function Start (deviceName : String, loop : boolean, lengthSec : int, frequency : int) : AudioClip


そこでさらに調べてみるとちゃんと音量が毎フレーム取得する方法が見つかったので日本語でも書いておく。

Using microphone input in Unity3D

簡単に言うとMicrophoneで録音している音源をAudioSourceに流し、AudioSource経由で毎フレーム音量を見ればよい。ちょっと変わった方法、というか公式に便利なものがない。

1. GameObjectを作る

適当なGameObject(Emptyで良い)を作って適当なスクリプト(今回はC#)をアタッチする

2. AudioSourceを作る

このGameObjectを選択した状態で、ComponentメニューからAudioSourceを選択するとAudioSourceが使えるようになる

3. Microphoneからの入力をこのAudioSourceに割り当てる

audioというのは先ほど作成したAudioSourceのことでコード内で定義しなくても使える

void Start()
{
    audio.clip = Microphone.Start(null, true, 999, 44100);  // マイクからのAudio-InをAudioSourceに流す
    audio.loop = true;                                      // ループ再生にしておく
    audio.mute = true;                                      // マイクからの入力音なので音を流す必要がない
    while (!(Microphone.GetPosition("") > 0)){}             // マイクが取れるまで待つ。空文字でデフォルトのマイクを探してくれる
    audio.Play();                                           // 再生する
}
4. 毎フレームボリュームを取得する
void Update()
{
    float vol = GetAveragedVolume();
    print(vol);    
}

float GetAveragedVolume()
{ 
    float[] data = new float[256];
    float a = 0;
    audio.GetOutputData(data,0);
    foreach(float s in data)
    {
        a += Mathf.Abs(s);
    }
    return a/256.0f;
}


rawデータが取れるので色々料理できますね。