AudioTrack没有播放完整的缓冲区

时间:2012-08-13 04:13:42

标签: java android audio audiotrack

我试图在600hz播放10s的声音但是我得到600hz不超过3秒。有人可以指出我做错了吗?

    int minBuffersize = AudioTrack.getMinBufferSize(samplerate, 
           AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT);

    int size= (int) ((10f*samplerate)
            /minBuffersize +1);

            size*=minBuffersize;//round to the nearest minBuffersize multiple so I don't get an error

    short[] play= new short[size];

    for(int i =0;i<play.length;i++){
        float time=(float)i/(float)samplerate;

        play[i]=(short) (((float)Short.MAX_VALUE/10f)*Math.sin(
                600f
                *time
                *(2f*Math.PI)));
    }

    AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC,
            samplerate,
            AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT,
            play.length,
            AudioTrack.MODE_STATIC);


    int result=at.write(play,0,play.length);

    Log.d("!!!", "result: "+result);

    at.play();

调试行返回

result: 221184

一致。

请注意,play.length = 442368。

经过一些实验后,缓冲区总是play.length的一半,但声音本身只持续3-5秒,无论缓冲区有多大。

3 个答案:

答案 0 :(得分:1)

AudioTrack需要缓冲区大小(以字节为单位)。由于Short使用2个字节,因此应使用size * 2作为缓冲区大小。

答案 1 :(得分:1)

在AudioTrack中你正在使用AudioTrack.MODE_STATIC(对于具有低延迟要求的短声音)而你应该使用AudioTrack.MODE_STREAM,因为它对于长缓冲区来说是正确的(不知道确切但是是可能与3秒钟相关。)

看看here : AudioTrack

只需将您的代码更改为:

AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC,
        samplerate,
        AudioFormat.CHANNEL_OUT_MONO,
        AudioFormat.ENCODING_PCM_16BIT,
        play.length,
        AudioTrack.MODE_STREAM);

它应该有用。

答案 2 :(得分:0)

我建议将播放长度与AudioTrack缓冲区大小分离。根据我的经验,只使用最小缓冲区大小然后让大写块直到它完成为止。

我注意到的其他可能影响这一点的是,在填充缓冲区的一半之前音频不会播放。 AudioTrack中的缓冲区可能很大,它只占用了一半,并尝试通过它。