簡體   English   中英

從Android 2.2中的麥克風錄制時出現奇怪的失真

[英]Strange distortion while recording from microphone in Android 2.2

我有一個應用程序,該應用程序記錄來自麥克風的音頻,然后實時對音頻進行一些后處理,因此我必須使用AudioRecord類而不是標准MediaRecorder 我的錄制代碼是這樣的:

DataOutputStream dataOutputStreamInstance = new DataOutputStream(bufferedStreamInstance);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

int bufferSize = AudioRecord.getMinBufferSize((int)sampleRate, channelConfiguration, DEFAULT_AUDIO_ENCODING) * 2;
short[] microphoneBuffer = new short[bufferSize];
float[] processingBuffer = new float[bufferSize];
short[] outputBuffer = new short[bufferSize];

AudioRecord microphoneRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);

microphoneRecorder.startRecording();
while(isRecording) {
  synchronized(mutex) { ... check for pause condition, wait, etc. ... }
  int numSamplesRead = microphoneRecorder.read(microphoneBuffer, 0, bufferSize);

  // Convert 16-bit short data to floating point
  getFloatingPointBufferFromPcmData(microphoneBuffer, processingBuffer, bufferSize);

  doProcessingStuff(processingBuffer, bufferSize);

  if(numSamplesRead == AudioRecord.ERROR_INVALID_OPERATION) {
    throw new IllegalStateException("read() returned AudioRecord.ERROR_INVALID_OPERATION");
  }
  else if(numSamplesRead == AudioRecord.ERROR_BAD_VALUE) {
    throw new IllegalStateException("read() returned AudioRecord.ERROR_BAD_VALUE");
  }

  try {
    // Dump the output to the target file in 16-bit short format
    getShortPcmBufferFromFloatingPointData(processingBuffer, outputBuffer, bufferSize);
    for(int bufferIndex = 0; bufferIndex < numSamplesRead; bufferIndex++) {
      dataOutputStreamInstance.writeShort(outputBuffer[bufferIndex]);
    }
  }
  catch(Exception e) {
    Log.e("MyApp", "Error while writing audio data to file: " + e.getMessage());
    e.getStackTrace();
  }
}

microphoneRecorder.stop();

上面的代碼工作正常,我實際上可以錄制設備中的音頻,並且聽到聲音等。 問題是幾秒鍾后,一個非常奇怪的失真模式開始出現,直到整個信號被淹沒為止。 這是靜音錄音的屏幕截圖,我是通過將一些錄音帶放在麥克風上並讓該應用錄制一分鍾左右來制作的:

波形文件中的變形的屏幕截圖

原始wave文件可在此處下載

問題絕對不是我的效果處理代碼造成的,因為我嘗試將其注釋掉,並且在兩種情況下都得到相同的結果。 我在網上搜尋了其他代碼或可能遇到類似問題但未發現任何問題的人員。

我一點也不了解Android SDK,盡管命名約定很可愛,但getFloatingPointBufferFromPcmDatagetShortPcmBufferFromFloatingPointData看起來並不像標准API函數。 :)

你自己寫這些嗎? 也許他們使用共享狀態並在循環迭代中累積結果? 如果這些是您的實現,請共享這些代碼,以便我們可以幫助您確定實際問題。

還有可能是您以錯誤的格式(位數,字節序)寫出了PCM數據,並且音頻編輯器根據另一種格式解釋了該數據,從而導致音頻數據解碼不正確,從而似乎在欺騙性地出現有一些積累效應正在發生。

如果這些查詢都不能幫助您解決問題,那么我的下一個建議是為每個循環迭代創建一個新的MikeBuffer實例,而不是在while循環中使用單個實例。

再說一次,我不是Android SDK專家,所以這些只是一般性的建議,這些建議來自多年處理幾乎所有類型的API及其實現細節的經驗。

希望能幫助您診斷問題!

保持沉默的情況下,可能會有一個自動增益控制,使輸入增益超出了合理范圍,試圖尋找“東西”供您記錄(當然也找到了本底噪聲)

如果您將PC揚聲器設置為播放良好的音頻正弦波,會發生什么?噪聲是否仍會出現?還是繼續記錄正弦波?

Bah,實際上問題不是Android的錯-這是由我用來將原始PCM數據轉換為WAV格式的軟件引起的。 字節序轉換中顯然存在一些錯誤,因為ARM芯片是大字節序,而WAV是小字節序。 當我們嘗試在Audacity中打開原始PCM文件時,它們看起來不錯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM