在Android上使用AudioRecord录音可加快音频速度吗?

时间:2012-06-22 06:50:21

标签: android audiorecord

我正在使用AudioRecord录制原始音频进行处理。 音频记录完全没有任何噪音,但是当播放生成的原始PCM数据时,它的播放就好像它已经加速了很多(高达两倍左右)。 我在Audacity中查看和播放PCM数据。我正在使用实际手机(三星Galaxy S5670)进行测试。 录音以44100 Hz,16位完成。知道可能导致这种情况的原因吗?

以下是录制代码:

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 个答案:

答案 0 :(得分:5)

音频跳过是由写入缓冲区的延迟引起的。 解决方案就是替换这个FOR循环:

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

通过单一写入,如下:

       bos.write(buffer, 0, iBufferReadResult);

我曾使用过一本书中的代码,我认为这样可以降低采样率和缓冲区更新。