当我尝试通过音轨播放 pcm 数据时,我使用 jLayer lib 解码了 mp3,这会产生很多音频失真。
我的解码器代码:
public static void decode(String path, int startMs, int maxMs)
throws IOException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
float totalMs = 0;
boolean seeking = true;
File file = new File(path);
System.out.println("the data "+path);
InputStream inputStream = new BufferedInputStream(new FileInputStream(file), 8 * 1024);
try {
Bitstream bitstream = new Bitstream(inputStream);
Decoder decoder = new Decoder();
boolean done = false;
while (! done) {
javazoom.jl.decoder.Header frameHeader = bitstream.readFrame();
if (frameHeader == null) {
done = true;
} else {
totalMs += frameHeader.ms_per_frame();
if (totalMs >= startMs) {
seeking = false;
}
if (! seeking) {
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
if (output.getSampleFrequency() != 44100
|| output.getChannelCount() != 2) {
// throw new com.mindtherobot.libs.mpg.DecoderException("mono or non-44100 MP3 not supported");
}
short[] pcm = output.getBuffer();
byte[] bs;
int index=0;
ByteBuffer buffer;
buffer = ByteBuffer.allocate(2*pcm.length);
for (short s : pcm) {
// outStream.write(s & 0xff);
// outStream.write((s >> 8 ) & 0xff);
buffer.putShort(s);
}
byte[] dataaudio = buffer.array();
//return buffer.array();
track.write(dataaudio, 0, dataaudio.length);
}
if (totalMs >= (startMs + maxMs)) {
done = true;
}
}
bitstream.closeFrame();
}
//return outStream.toByteArray();
} catch (BitstreamException e) {
throw new IOException("Bitstream error: " + e);
} catch (DecoderException e) {
Log.w("data", "Decoder error", e);
;
} finally {
// IOUtils.safeClose(inputStream);
}
}
我建议你不要将你的short[]转换为byte[],而是将你的short[]写入AudioTrack,即调用track.write(pcm,0,pcm.length)而不是track.write(dataaudio,0,dataaudio.length)。
我一直在为Android编写一个音频处理器,它使用JLayer读取MP3文件,处理数据,然后输出到AudioTrack。如果我不做任何数据处理,而只是将数据从JLayer发送到AudioTrack,它在我的Nexus7上播放得非常好。但是,当我进行处理(音调偏移和/或时间压缩)时,我会发出烦人的噼啪声。
奇怪的是,当我从 JLayer 读取一帧并将其发送到 AudioTrack (无处理)时,听起来不错,但是当我从 JLayer 读取两帧并将它们发送到 AudioTrack (无处理)时,我得到了噼啪声!
我已经开始在Android之外进行一些调查(基本上运行相同的代码,但使用我自己的AudioTrack实现假人,它可以在我的笔记本电脑上播放声音或转换为WAV文件),到目前为止的结果非常奇怪。
所以,如果你有进一步的进步,我很想知道你过得怎么样。