4

処理のために生のオーディオを録音するためにAudioRecordを使用しています。オーディオは完全にノイズなしで録音されますが、生成された生のPCMデータが再生されると、大幅に高速化されたかのように再生されます(最大約2倍)。AudacityでPCMデータを表示および再生しています。テストには実際の電話(Samsung Galaxy S5670)を使用しています。録音は44100Hz、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();
            }
        }

次のように、1回の書き込みで:

       bos.write(buffer, 0, iBufferReadResult);

私は、より低いサンプルレートとバッファ更新のために機能した本のコードを使用していたと思います。

于 2012-06-23T11:22:28.193 に答える