Android AudioTrack流提前删除

时间:2014-02-27 03:14:44

标签: android audio

我正试图在Android中播放一些循环声音,而且我对我来说非常好。但是,所有美好的事物必须结束,我希望包含我的音频循环。但是,如果我在这个循环之后调用AudioTrack.release(),就像我应该的那样,音频流的结尾会被切断 - 我知道我应该听到额外的数据,但是没有。

我通过在发布之前放入一个Thread.sleep(2000)来验证这一点 - 声音在那里正确播放。我的代码看起来像这样:

// Initialize Audiotrack
int minBufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 2 * minBufferSize, AudioTrack.MODE_STREAM);

mAudioTrack.play();

// Play looping sound
while (stuff) {
    mAudioTrack.write(stuff);
}

// Play one last bit of sound before returning
mAudioTrack.write(lastSound);

// Block until the AudioTrack has played everything we've given it
Thread.sleep(2000); 

// Get rid of the Audiotrack
mAudioTrack.release();

我想我可以将Thread.sleep(2000)留在那里并称之为一天,但这对我来说听起来很混乱和不负责任。我希望在最合适的时间内使用while()循环块,或者使用AudioTrack.setPlaybackPositionUpdateListener()并将release()放在那里。

如果我走第一条路线,我需要一些东西可以挂起,而AudioTrack.getPlayState()似乎总是报道该曲目正在播放。所以我被困在那里。

如果我走第二条路线,我需要一种方法来获取最后写入的AudioTrack缓冲区中的位置,所以我可以告诉AudioTrack我正在等待它播放的位置。但是,我对如何获取这些信息没有任何想法。

我想我并不关心我这样做的方式,所以对于以某种方式解决问题的任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:1)

问题与AudioTrack中的缓冲区大小有关。

想象一下,minBufferSize是8k。这意味着当缓冲区已满时,AudioTrack将播放声音。

mAudioTrack.write(stuff);

如果stuff仅为4K,则AudioTrack将等到下一次调用write,直到有足够的数据播放。

结论:您需要跟踪已写入的数据量,并在播放结束时向AudioTrack提供一些虚拟字节以完成minBufferSize。为了让事情变得更容易,你可以提供整整minBufferSize个静音字节。

顺便说一下,要输入虚拟或静音,只需用填充数据。