4

我正在使用 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 循环。完美运行。

4

1 回答 1

5

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

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

通过一次写入,如下所示:

       bos.write(buffer, 0, iBufferReadResult);

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

于 2012-06-23T11:22:28.193 回答