录制pcm文件并通过Audiotrack崩溃播放

时间:2014-05-22 06:33:52

标签: java android eclipse

我正在通过AudioRecorder录制一个pcm文件并在sdcard中创建一个文件。录制完成后我用Audiotrack播放同一个文件,但它崩溃了。在logcat中它说"音频缓冲区大小无效"。我在SD卡上的文件大小也是0.0kb,我不明白为什么。这是代码。 `

public void startRecord() {

        File file = new File(Environment.getExternalStorageDirectory(),
                "test.pcm");

        int sampleFreq = 11025;

        try {
            file.createNewFile();

            OutputStream outputStream = new FileOutputStream(file);
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
                    outputStream);
            DataOutputStream dataOutputStream = new DataOutputStream(
                    bufferedOutputStream);

            int minBufferSize = AudioRecord.getMinBufferSize(sampleFreq,
                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT);

            short[] audioData = new short[minBufferSize];

            AudioRecord audioRecord = new AudioRecord(
                    MediaRecorder.AudioSource.MIC, sampleFreq,
                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, minBufferSize);

            audioRecord.startRecording();

            while (recording) {
                int numberOfShort = audioRecord.read(audioData, 0,
                        minBufferSize);
                for (int i = 0; i < numberOfShort; i++) {
                    dataOutputStream.writeShort(audioData[i]);
                }
            }

            audioRecord.stop();
            dataOutputStream.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void PLaying(int explosion) {

        File file = new File(Environment.getExternalStorageDirectory(),
                "test.pcm");

        int shortSizeInBytes = Short.SIZE / Byte.SIZE;

        int bufferSizeInBytes = (int) (file.length() / shortSizeInBytes);
        short[] audioData = new short[bufferSizeInBytes];

        try {
            InputStream inputStream = new FileInputStream(file);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(
                    inputStream);
            DataInputStream dataInputStream = new DataInputStream(
                    bufferedInputStream);

            int i = 0;
            while (dataInputStream.available() > 0) {
                audioData[i] = dataInputStream.readShort();
                i++;
            }

            dataInputStream.close();

            int sampleFreq = explosion;

            AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                    sampleFreq, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes,
                    AudioTrack.MODE_STREAM);

            audioTrack.play();
            audioTrack.write(audioData, 0, bufferSizeInBytes);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

`

3 个答案:

答案 0 :(得分:0)

这段代码看起来很狡猾

while (recording) {
      int numberOfShort = audioRecord.read(audioData, 0,
                    minBufferSize);
      for (int i = 0; i < numberOfShort; i++) {
                dataOutputStream.writeShort(audioData[i]);
      }
}

recording的价值是多少?价值在哪里变化。如果它没有改变,它将是一个无限循环(除非抛出异常)。

答案 1 :(得分:0)

您是否已整合了停止方法?请给我们一些代码。问题是,如果你没有实现一个正确的停止mehtod,它将永远循环..你做过这样的事情:

   yourStopButton.setOnClickListener(new OnClickListener(){

         @Override
         public void onClick(View view){

             recording=false;
      }

   });

然后,不要忘记在onStart中执行相同的操作并将记录设置为true。

答案 2 :(得分:0)

构造AudioRecord实例时,将最小缓冲区大小除以2