2010-04-25 48 views
8

我試圖將從Java SE播放chiptunes(NSF,SPC等)音樂文件的應用程序移植到Android。 Android API似乎缺少此應用程序用於輸出原始PCM音頻的javax多媒體類。我在API中找到的最接近的模擬器是AudioTrack,所以我一直在與之搏鬥。難以將原始PCM輸出代碼從Java移植到Android AudioTrack API

但是,當我嘗試通過正在運行的端口運行我的一個示例音樂文件時,我所得到的所有內容都是靜態的。我的懷疑是,這是我設置的AudioTrack,這是錯誤的。我嘗試了各種不同的構造函數,但最終都輸出了靜態。

中的DataLine設置在原來的代碼是一樣的東西:

AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
       44100, 16, 2, 4, 44100, true); 
DataLine.Info lineInfo = new DataLine.Info(SourceDataLine.class, audioFormat); 
DataLine line = (SourceDataLine)AudioSystem.getLine(lineInfo); 

我現在使用的構造是:

AudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
     44100, 
     AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
     AudioFormat.ENCODING_PCM_16BIT, 
     AudioTrack.getMinBufferSize(44100, 
       AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
       AudioFormat.ENCODING_PCM_16BIT), 
     AudioTrack.MODE_STREAM); 

我已經取代了那些常量和變量,使他們儘可能簡明扼要,但是我的基本問題是,當我從一種格式轉到另一種格式時,是否存在明顯的問題。

+0

即使您變得靜止,您是否檢查過軌道長度是否正確? – nvuono 2010-04-25 05:53:18

+0

有問題的音樂文件沒有真正的音軌長度。也就是說,它們是以DSP的代碼形式出現的,直到它們被告知停止時才繼續循環播放。 – alexanderfb 2010-04-25 17:55:17

回答

7

所以我今天有一點時間去看這個,我想我已經明白了。上面第一個代碼示例中的AudioFormat聲明將big endian參數設置爲「true」,但Android AudioTrack期望PCM數據採用小尾數格式。

所以我寫了一個小巧的循環來測試我的預感,像這樣:

for(int i = 0; i + LEN_PCM_SAMPLE_BYTES < LEN_PCM_BUFFER; i += LEN_PCM_SAMPLE_BYTES) { 
    // Really rude endian conversion. 
    byte bytTemp = a_bytBuffer[i]; 
    a_bytBuffer[i] = a_bytBuffer[i + 1]; 
    a_bytBuffer[i + 1] = bytTemp; 
} 

基本上,這個循環翻轉的緩衝區每(16位),樣本中的字節。這樣做效果很好,除了它有點不連貫之外,因爲效率非常低。我嘗試使用ByteBuffer,但似乎並沒有翻轉單個樣本中的字節。

我會更好地向前看,但這裏的基本問題已經解決了。希望別人認爲這有用!

+0

你是否能夠想出一些簡單的東西? – StackOverflowed 2013-03-04 15:31:36