0

私は、Android プラットフォームにある種のサウンドメーターを構築しようとしています。(私はHTCワイルドファイアを使用しています)AudioRecordその目標のためにクラスを使用していますが、その「読み取り」から返される値は妥当ではないようです。

これは私が AudioRecord オブジェクトを作成した方法です:

int minBufferSize = 
         AudioRecord.getMinBufferSize(sampleRateInHz,
                                      android.media.AudioFormat.CHANNEL_IN_MONO,
                                      android.media.AudioFormat.ENCODING_PCM_16BIT);

audioRecored = new AudioRecord( MediaRecorder.AudioSource.MIC,          
                                44100, 
                                android.media.AudioFormat.CHANNEL_IN_MONO,
                                android.media.AudioFormat.ENCODING_PCM_16BIT,
                                minBufferSize );

これは私がそれからデータを読み取ろうとする方法です:

    short[] audioData = new short[bufferSize];
    int offset =0;
    int shortRead = 0;
    int sampleToReadPerGet = 1000;//some value in order to avoid momentaraly nosies.

    //start tapping into the microphone
    audioRecored.startRecording();

   //start reading from the microphone to an internal buffer - chuck by chunk
   while (offset < sampleToReadPerGet)
   {
            shortRead = audioRecored.read(audioData, offset ,sampleToReadPerGet - offset);
            offset += shortRead;
   }

   //stop tapping into the microphone
   audioRecored.stop();

    //average the buffer
    int averageSoundLevel = 0;
    for (int i = 0 ; i < sampleToReadPerGet ; i++)
    {
        averageSoundLevel += audioData[i];          
    }
    averageSoundLevel /= sampleToReadPerGet;      

それらの値は何ですか?彼らはデシベルですか?

編集: 値は -200 から 3000 になります。shortRead の値は sampleToReadPerGet (1000) です。

4

2 に答える 2

1

あなたが参照している「それらの値」、生の出力または平均値はわかりませんが、生の出力は瞬間的な振幅レベルです。このような値は、特定の何かを参照しているわけではないことを理解することが重要です。つまり、あなたが 20 を読んでいるからといって、20 が何であるかを教えてくれるわけではありません。

これらの値の平均を取ることは意味がありません。なぜなら、これらの値は 0 の上下に変動するからです。十分に長くやれば、ゼロになります。

2 乗の平均をとり、平均の平方根を求めることは理にかなっているかもしれません。これを RMS と呼びます。ただし、平均化するための固定バッファ サイズがない場合、これはよくても危険です。

dB を測定するには、式 dB = 20 log_10 (|A|/A_r) を使用する必要があります。ここで、A は振幅、A_r は基準振幅です。明らかに、何を参照しているかを決定する必要があります (HTC を校正できます)。 、または最大レベルまたはそのようなものに対して測定します)。

于 2012-06-17T17:27:10.323 に答える
0

負の値を取得しないでください。値は 16 ビットまたは 8 ビットに及ぶため、最大値は約 32000 程度です。値に単位はありません。

また、ボリュームを決定するための平均ではなく、二乗平均平方根をお勧めします。より安定しています。

あなたが試すべきこと:

  • バッファ サイズを 3 増やします。アプリの読み取り速度が十分でない可能性があるため、スペースが必要です。そうしないと、バッファ オーバーフロー エラーが発生する可能性があります (コードでチェックしていません)。

  • gast -libのコードを試してください: 定期的にオーディオを録音するのに役立ち、AsyncTask も提供します。

  • 二乗平均平方根:

public static double rootMeanSquared(short[] nums)
{
    double ms = 0;
    for (int i = 0; i < nums.length; i++)
    {
        ms += nums[i] * nums[i];
    }
    ms /= nums.length;
    return Math.sqrt(ms);
}
于 2012-06-18T08:41:29.787 に答える