2014-02-27 60 views
0

我正在嘗試在Android中播放一些循環聲音,並且我對此非常滿意。儘管如此,所有好的事情都必須結束,我希望包括我的音頻循環。但是,如果我在此循環後呼叫AudioTrack.release(),就像我應該那樣,我的音頻流的末尾被切斷 - 我知道我應該聽到額外的數據,但是不要。Android AudioTrack流盡早切出

我已經通過在發佈之前放入一個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

該問題與AudioTrack中的緩衝區大小有關。想象一下minBufferSize是8k。這意味着當緩衝區已滿時,AudioTrack將播放聲音。

mAudioTrack.write(stuff); 

如果stuff只有4K,該AudioTrack會等到到write下一個呼叫,直到它有足夠的數據來播放。

結論:你需要跟蹤你有多少數據寫入,並且在您的播放結束喂AudioTrack一些僞字節來完成minBufferSize。爲了讓事情變得更簡單,您可以提供整個minBufferSize數量的靜音字節。

順便說一下,要填充虛擬或沉默只是填充數據與

+0

寫一個零的'minBufferSize'看起來就像是訣竅。我不知道AudioTrack只能播放完整的緩衝區;我認爲它會不斷地在緩衝區中提前播放位置,直到它到達緩衝區中的最後寫入位置。謝謝。 – sigmabeta