【java】無法將Java的原始PCM輸出程式碼從Java移植到Android AudioTrack API
阿新 • • 發佈:2020-11-11
我正在嘗試將播放晶片音樂(NSF,SPC等)音樂檔案的應用程式從Java SE移植到Android。 Android API似乎缺少此應用程式用於輸出原始PCM音訊的javax多媒體類。我在API中找到的最接近的模擬是AudioTrack,因此我一直在努力。
但是,當我嘗試通過進行中的埠執行示例音樂檔案之一時,我得到的都是靜態的。我懷疑是我設定的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 );
我已經在其中替換了常量和變數,以便它們儘可能簡潔明瞭,但是我的基本問題是,當我從一種格式轉換為另一種格式時,所做的假設是否存在任何明顯的問題。
解決辦法
因此,我今天有一點時間來進一步研究這個問題,我想我已經確定了這一點。上面的第一個程式碼示例中的AudioFormat宣告將big endian引數設定為“true”,但是Android AudioTrack期望PCM資料採用little endian格式。
所以我寫了一個快速的小迴圈來測試我的直覺,如下所示:
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,但這似乎並沒有翻轉單個樣本中的位元組。
我會想出一些更好的方法,但是這裡的基本問題已經解決。希望其他人覺得這有用!
