Android 音频播放难题

Android 音频播放难题,android,media-player,recording,playback,audiorecord,Android,Media Player,Recording,Playback,Audiorecord,我希望有人能给我指出正确的方向。我已经能够让录音工作良好,以及水平仪。我开始播放音频,这让我有些头疼。我读过很多关于MediaPlayer和AudioTrack的文章,以及这两门课程之间的一些差异。我读到的一件事是,这两个类都支持PCM,这是我录制的音频的格式 在音频录制中,我使用AudioRecord类捕获16位PCM单声道数据。我正在捕获数据,然后将数据写入保存到SD卡的文件中。以下是要写入文件的代码的核心: totalAudioLen = in.getChannel().s

我希望有人能给我指出正确的方向。我已经能够让录音工作良好,以及水平仪。我开始播放音频,这让我有些头疼。我读过很多关于MediaPlayer和AudioTrack的文章,以及这两门课程之间的一些差异。我读到的一件事是,这两个类都支持PCM,这是我录制的音频的格式

在音频录制中,我使用AudioRecord类捕获16位PCM单声道数据。我正在捕获数据,然后将数据写入保存到SD卡的文件中。以下是要写入文件的代码的核心:

        totalAudioLen = in.getChannel().size();
        totalDataLen = totalAudioLen + 36;

        WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
                longSampleRate, channels, byteRate);

        while (dis.available() > 0 )
        {
            dos.writeShort(dis.readShort());
        }
下面是编写WAVE头的代码:

    byte[] header = new byte[44];

    header[0] = 'R';  // RIFF/WAVE header
    header[1] = 'I';
    header[2] = 'F';
    header[3] = 'F';
    header[4] = (byte) (totalDataLen & 0xff);
    header[5] = (byte) ((totalDataLen >> 8) & 0xff);
    header[6] = (byte) ((totalDataLen >> 16) & 0xff);
    header[7] = (byte) ((totalDataLen >> 24) & 0xff);
    header[8] = 'W';
    header[9] = 'A';
    header[10] = 'V';
    header[11] = 'E';
    header[12] = 'f';  // 'fmt ' chunk
    header[13] = 'm';
    header[14] = 't';
    header[15] = ' ';
    header[16] = 16;  // 4 bytes: size of 'fmt ' chunk
    header[17] = 0;
    header[18] = 0;
    header[19] = 0;
    header[20] = 1;  // format = 1
    header[21] = 0;
    header[22] = (byte) channels;
    header[23] = 0;
    header[24] = (byte) (longSampleRate & 0xff);
    header[25] = (byte) ((longSampleRate >> 8) & 0xff);
    header[26] = (byte) ((longSampleRate >> 16) & 0xff);
    header[27] = (byte) ((longSampleRate >> 24) & 0xff);
    header[28] = (byte) (byteRate & 0xff);
    header[29] = (byte) ((byteRate >> 8) & 0xff);
    header[30] = (byte) ((byteRate >> 16) & 0xff);
    header[31] = (byte) ((byteRate >> 24) & 0xff);
    header[32] = (byte) (2 * 16 / 8);  // block align
    header[33] = 0;
    header[34] = RECORDER_BPP;  // bits per sample
    header[35] = 0;
    header[36] = 'd';
    header[37] = 'a';
    header[38] = 't';
    header[39] = 'a';
    header[40] = (byte) (totalAudioLen & 0xff);
    header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
    header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
    header[43] = (byte) ((totalAudioLen >> 24) & 0xff);

    out.write(header, 0, 44);
问题在于音频文件的播放。MediaPlayer在播放时速度非常快,但结果是噪音很大。我正在使用上面的代码创建文件,并试图通过MediaPlayer播放它。据我所知,MediaPlayer支持16位PCM音频,我相信这是我在上面创建的

    mPlayer = new MediaPlayer();
    mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    File file = new File(mFileName);
    FileInputStream fis = new FileInputStream(file);
    mPlayer.setDataSource(mFileName);
    mPlayer.prepare();
    mPlayer.start();
当我使用AudioTrack时,音频播放是正常的,这意味着音频与录制时一样。使用这个类的最大问题是我在尝试开始播放时遇到的延迟。我使用的是流模式,音频开始播放需要5-15秒,这是完全不可接受的

下面是我调用AudioTrack类的代码:

    int intSize = android.media.AudioTrack.getMinBufferSize(RECORDER_SAMPLERATE, 
           AudioFormat.CHANNEL_CONFIGURATION_MONO,
           AudioFormat.ENCODING_PCM_16BIT);

    audioPlayer = new AudioTrack(AudioManager.STREAM_MUSIC,RECORDER_SAMPLERATE, 
                      AudioFormat.CHANNEL_CONFIGURATION_MONO,
                       AudioFormat.ENCODING_PCM_16BIT, 
                       intSize, 
                       AudioTrack.MODE_STREAM);

    short[] byteData = null;
    File file = null;
    file = new File(mFileName);

    InputStream is  = null;
    BufferedInputStream bis = null;
DataInputStream dis = null;

    try 
    {
        is = new FileInputStream( file );
        bis = new BufferedInputStream(is);
        dis = new DataInputStream(bis);
    } 
    catch (FileNotFoundException e) 
    {
        e.printStackTrace();
    }

    try
    {
        int bytesread = 0, ret = 0;
        int size = (int) file.length();
        audioPlayer.play();

        byteData = new short[size/2];

    while (dis.available() > 0 )
    {
        byteData[ret] = dis.readShort();
        ret++;
    }
    if (byteData != null ) 
    { 
        //  Write the byte array to the track 
        audioPlayer.write(byteData,0, ret); 
        bytesread += ret; 
    } 

    dis.close();

    is.close(); 
    audioPlayer.stop(); 
    audioPlayer.release();
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }

关于使用MediaPlayer时可能导致静电的原因有什么想法?或者在使用AudioTrack时如何提高性能

你不使用它有什么原因吗?当我第一次开发应用程序时,在用麦克风初始化类时,我在MediaRecorder中遇到了崩溃。我读得越多,似乎录音是最好的课堂。在实现时,我不再遇到任何崩溃。如果你计划快速播放音频,而且文件不太大,考虑使用SooPooSo.我看了SooCub类,但是我发现一篇文章不推荐音频文件>1 MB的大小。由于我使用的是PCM文件,我肯定会超出此限制。您不使用的原因是什么?当我第一次开发应用程序时,在使用麦克风初始化类时,我在MediaRecorder中遇到了崩溃。我读得越多,似乎录音是最好的课堂。在实现时,我不再遇到任何崩溃。如果你计划快速播放音频,而且文件不太大,考虑使用SooPooSo.我看了SooCub类,但是我发现一篇文章不推荐音频文件>1 MB的大小。由于我正在处理PCM文件,我肯定会超过这个限制。