2011-05-18 121 views
6

我有一個AudioTrack的問題,這個Android API正在殺死我。我來自以前沒有任何Android或Java經驗,但我是一個非常有經驗的編碼員(在很多平臺上是asm,C++等),我從來沒有想過我特別笨,就像Android現在讓我感覺一樣。Android的AudioTrack MODE_STATIC重播問題

我在做什麼錯?顯然沒什麼:

audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minbufsizbytes*64, AudioTrack.MODE_STATIC); 
audioTrack.write(Buffer, 0, numSamples); 
audioTrack.play(); 

其實採樣率= 8000和minbufsizbytes = 742(742 * 64 = 47488)是相當大於緩衝區我寫(16000個16bit的採樣)。

音頻播放第一次就很好。但是......我怎麼不止一次地演奏它? (例如響應於事件,例如按下的鋼琴鍵)。如果我再次調用play(),則不會產生新的聲音。所以無奈天之後,這裏就是我想出了:

for (i=0;;i++) { 
    SystemClock.sleep(3000L); // so the problem is NOT "fast, repeated attempts to replay sound", but looks like internal buffer overrun related (please see the Log'ed error below) 
    audioTrack.stop(); 
    audioTrack.reloadStaticData(); 
    audioTrack.setPlaybackHeadPosition(0); 
    audioTrack.play(); 
} 

所以播放聲音第二次或第三次..然後無音訊!(!)和日誌獲取此錯誤信息充斥:

05-18 13:03:16.785: ERROR/AudioFlinger(345): TrackBase::getBuffer buffer out of range: 
05-18 13:03:16.785: ERROR/AudioFlinger(345):  start: 0x404fb680, end 0x404fb7f2 , mBuffer 0x40507000 mBufferEnd 0x40512980 
05-18 13:03:16.785: ERROR/AudioFlinger(345):      server 0, serverBase 23744, user 47488, userBase 47488, channels 1 

我則必須重啓手機(模擬或實際)否則日誌洪水不會停止..

(MIS)的行爲在我的銀河2.2 .1,在我的IDEOS 2.1和仿真器上(各種版本)..所以這不是一個電話錯誤問題。

如果我讓內部緩衝區更大(在AudioTrack第五個參數),它會播放多次,停止發出聲音之前,開始淹沒日誌,所以我覺得這就像如果內部緩衝區是侵佔

PS :你知道getMinBufferSize是否返回採樣或字節(即使是PCM_16BIT),正如一些報道的那樣?

回答

4

下面是已經運行多次的代碼示例! '超' 是AudioTrack

公共無效播放(){

switch (super.getPlayState()) { 
    case AudioTrack.PLAYSTATE_PAUSED: 
    super.stop(); 
     super.reloadStaticData(); 
     super.play(); 
     break; 
    case AudioTrack.PLAYSTATE_PLAYING: 
    super.stop(); 
     super.reloadStaticData(); 
     super.play(); 
     break; 
    case AudioTrack.PLAYSTATE_STOPPED: 
     super.reloadStaticData(); 
     super.play(); 
     break; 
    } 

}