2012-06-16 72 views
0

我正在嘗試在Android平臺上構建某種聲音計。 (我正在使用HTC Wildfire)爲此目標使用AudioRecord類,但是從「讀取」返回的 值似乎不合理。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)。

+1

你得到什麼樣的價值觀?當然你只是回來了16位PCM樣本。 – Brad

+1

調用讀取後'shortRead'的值是多少? –

+0

爲問題添加了值。 – talel

回答

1

不確定你所指的是什麼「那些值」,原始輸出或平均值,但原始輸出是瞬時幅度水平。認識到這些值並沒有被特別引用是很重要的。就是因爲你正在閱讀20,並沒有告訴你20。

考慮到這些值的平均值沒有任何意義,因爲這些值在零以上和以下襬動。做足夠長的時間,你會得到零。

這可能是有意義的取平方的平方,然後找到平均的平方根。這被稱爲RMS。但是,如果沒有固定的緩衝區大小來平均,這是最好的危險。要測量dB,必須使用公式dB = 20 log_10(| A |/A_r)其中A是振幅,A_r是參考振幅 - 顯然,您必須決定您所參考的參數(您可以校準HTC,或者根據最高等級進行測量)。

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); 
} 
+0

來自gast-lib的代碼不會生成 – Mirko

+0

實際上它在調整幾小時之後會執行;) – Mirko