我正在尝试将从Java SE播放chiptunes(NSF,SPC等)音乐文件的应用程序移植到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 );
我已经将那些常量和变量替换为尽可能简洁有意义,但我的基本问题是,当我从一种格式转到另一种格式时所做的假设中是否存在任何明显的问题。
答案 0 :(得分: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,但似乎没有翻转单个样本中的字节。
我会在未来找到更好的东西,但这里的基本问题已经解决了。希望别人觉得这很有用!