2012-06-22 83 views
4

我正在使用AudioRecord來錄製原始音頻進行處理。 完全沒有任何噪音的音頻記錄,但是當回放生成的原始PCM數據時,它會播放,好像它已經加速了很多(最多約兩倍)。 我正在查看和播放Audacity中的PCM數據。我正在使用實際的手機(三星Galaxy S5670)進行測試。 記錄在44100Hz,16位完成。任何想法可能會導致這種情況?在Android上使用AudioRecord進行錄音可加速音頻?

以下是記錄代碼:

public class TestApp extends Activity 
{ 
File file; 
OutputStream os; 
BufferedOutputStream bos;  
AudioRecord recorder; 
int iAudioBufferSize; 
boolean bRecording; 
int iBytesRead; 

Thread recordThread = new Thread(){ 
    @Override 
    public void run() 
    { 
     byte[] buffer = new byte[iAudioBufferSize]; 
     int iBufferReadResult; 
     iBytesRead = 0; 
     while(!interrupted()) 
     { 
      iBufferReadResult = recorder.read(buffer, 0, iAudioBufferSize); 
      // Android is reading less number of bytes than requested. 
      if(iAudioBufferSize > iBufferReadResult) 
      { 
       iBufferReadResult = iBufferReadResult + 
         recorder.read(buffer, iBufferReadResult - 1, iAudioBufferSize - iBufferReadResult); 
      }    
      iBytesRead = iBytesRead + iBufferReadResult; 
      for (int i = 0; i < iBufferReadResult; i++) 
      { 
       try 
       { 
        bos.write(buffer[i]); 
       } catch (IOException e) 
       {            
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
}; 

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    // File Creation and UI init stuff etc. 

    bRecording = false; 
    bPlaying = false; 

    int iSampleRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_SYSTEM); 
    iAudioBufferSize = AudioRecord.getMinBufferSize(iSampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); 
    recorder = new AudioRecord(AudioSource.MIC, iSampleRate, AudioFormat.CHANNEL_IN_MONO, 
     AudioFormat.ENCODING_PCM_16BIT, iAudioBufferSize); 

    bt_Record.setOnClickListener(new OnClickListener() 
    { 
     @Override 
     public void onClick(View v) 
     { 
      if (!bRecording) 
      { 
       try 
       {      
        recorder.startRecording(); 
        bRecording = true; 
        recordThread.start();      
       } 
       catch(Exception e) 
       { 
        tv_Error.setText(e.getLocalizedMessage()); 
       } 
      } 
      else 
      { 
       recorder.stop(); 
       bRecording = false; 
       recordThread.interrupt(); 
       try 
       { 
        bos.close(); 
       } 
       catch(IOException e) 
       { 

       } 
       tv_Hello.setText("Recorded Sucessfully. Total " + iBytesRead + " bytes."); 
      } 
     } 

    }); 
} 
} 

解決:我張貼這與它掙扎了1-2天。但具有諷刺意味的是,我發佈後不久就找到了解決方案。緩衝輸出流寫入在for循環中花費了太多時間,所以流正在跳過樣本。將其更改爲阻止寫入,刪除for循環。完美的作品。

+1

如果您找到解決方案,只需回答自己的問題並將其標記爲答案。 – Flow

回答

5

音頻跳過是由於寫入緩衝區的延遲造成的。 的解決方法就是更換for循環:採用單一記錄

 for (int i = 0; i < iBufferReadResult; i++) 
     { 
      try 
      { 
       bos.write(buffer[i]); 
      } catch (IOException e) 
      {            
       e.printStackTrace(); 
      } 
     } 

,就像這樣:

 bos.write(buffer, 0, iBufferReadResult); 

我從一本書,工作中使用的代碼,我想,對於較低的採樣費率和緩衝區更新。

相關問題