Recording with AudioRecord on Android speeds up audio?

I use AudioRecord to record raw sound for processing. Sound recordings are completely without any interference, but when raw PCM data is played, it plays as if it were significantly accelerated (about twice as much). I view and play PCM data in Audacity. I am using the actual phone (Samsung Galaxy S5670) for testing. Recording is performed at a frequency of 44100 Hz, 16 bits. Any idea what might trigger this?

The following is the recording code:

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."); } } }); } } 

RESOLVED: I published this after fighting it for 1-2 days. But, ironically, I found a solution shortly after publication. Writing a buffered output stream took too much time in a for loop, so the stream skipped samples. changed it to write lock by deleting the for loop. It works great.

+4
source share
1 answer

Sound skipping was caused by a delay in writing to the buffer. the solution is to simply replace this FOR loop:

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

using a single entry, for example:

  bos.write(buffer, 0, iBufferReadResult); 

I used the code from a book that worked, I think, for lower sample rates and buffer updates.

+5
source

All Articles