2017-01-23 6 views
1

私が作成したAudioRecord機能があり、記録された分の平均音量をデシベル単位で取得したいのですが、私はこれを行う方法を理解することはできません。私は、AudioRecordオブジェクトがバッファ配列内に記録されたデータの完全な分を与えているかどうかは分かりません。Android AudioRecord - 1分間平均音量を取得する方法

これまでのコードはありますが、誰かがそれを適応させることができますか?私はそれをオンラインで行う方法を見つけようとしましたが、まだ何も見つかりませんでした。

Runnable mrHandlerRunnable = new Runnable() { 
      @Override 
      public void run() { 
       ar.stop(); 
       short[] buffer = new short[minSize]; 
       Log.d("LEN: " , ""+buffer.length); 
       ar.read(buffer, 0, minSize); 
       int max = Integer.MIN_VALUE; 
       int min = Integer.MAX_VALUE; 
       Double avg = 0.0; 
       for (short s : buffer) 
       { 
        if (Math.abs(s) > max) 
        { 
         max = Math.abs(s); 
        } 
        if (Math.abs(s) < min) 
        { 
         min = Math.abs(s); 
        } 
        avg = avg+Math.abs(s); 
       } 
       avg = avg/buffer.length; 

       ar.startRecording(); 

      } 
     }; 
     mrHandler.postDelayed(mrHandlerRunnable, 60000); 

答えて

1

これを試してください:

public class NoiseRecorder 
{ 

private final String TAG = SoundOfTheCityConstants.TAG; 
public static double REFERENCE = 0.00002; 

public double getNoiseLevel() throws NoValidNoiseLevelException 
{ 
    Logging.e(TAG, "start new recording process"); 
    int bufferSize = AudioRecord.getMinBufferSize(44100,AudioFormat.CHANNEL_IN_DEFAULT,AudioFormat.ENCODING_PCM_16BIT); 
    //making the buffer bigger.... 
    bufferSize=bufferSize*4; 
    AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
      44100, AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_PCM_16BIT, bufferSize); 

    short data [] = new short[bufferSize]; 
    double average = 0.0; 
    recorder.startRecording(); 
    //recording data; 
    recorder.read(data, 0, bufferSize); 

    recorder.stop(); 
    Logging.e(TAG, "stop"); 
    for (short s : data) 
    { 
     if(s>0) 
     { 
      average += Math.abs(s); 
     } 
     else 
     { 
      bufferSize--; 
     } 
    } 
    //x=max; 
    double x = average/bufferSize; 
    Logging.e(TAG, ""+x); 
    recorder.release(); 
    Logging.d(TAG, "getNoiseLevel() "); 
    double db=0; 
    if (x==0){ 
     NoValidNoiseLevelException e = new NoValidNoiseLevelException(x); 
     throw e; 
    } 
    // calculating the pascal pressure based on the idea that the max amplitude (between 0 and 32767) is 
    // relative to the pressure 
    double pressure = x/51805.5336; //the value 51805.5336 can be derived from asuming that x=32767=0.6325 Pa and x=1 = 0.00002 Pa (the reference value) 
    Logging.d(TAG, "x="+pressure +" Pa"); 
    db = (20 * Math.log10(pressure/REFERENCE)); 
    Logging.d(TAG, "db="+db); 
    if(db>0) 
    { 
     return db; 
    } 
    NoValidNoiseLevelException e = new NoValidNoiseLevelException(x); 
    throw e; 
} 
} 

これは4秒、試料中のオーディオの平均振幅を算出します。平均振幅が得られたら、dbに変換されます。それが役に立てば幸い。

+0

ありがとうございます!素晴らしい答え。私は推測しているbufferSize = bufferSize * 4;この場合、4秒を要するからでしょうか?私はまた、すべての例がMath.abs(amp)を取る理由を知っていますか? – mino

+0

私が理解したところでは、振幅値は-32768〜32767の間にあるので、 'abs()'はこの目的のために絶対値をとります。デフォルトのアンドロイドの '.getMaxAmplitude()'もこれを行い、絶対値を返します – OBX

+0

答えとアドバイスありがとう! – mino

関連する問題