JLayer Mono Mp3转PCM解码

时间:2012-12-19 19:21:29

标签: mp3 decode pcm

我目前正在使用javalayer 1.1进行mp3解码。

所以我想从44100 Hz,16bit,Mp3s接收原始PCM数据。 它与立体声mp3完美配合,但我对单声道mp3有奇怪的问题。

这里有一些代码。

InputStream data = c.getResources().openRawResource(resId);
Bitstream bitstream = new Bitstream(data);
Decoder decoder = new Decoder();
while(thereIsData) {
  Head frameHeader = bitstream.readFrame();
  SampleBuffer buffer = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
  short[] pcmBuffer = buffer.getBuffer();

  // Do some stuff with pcm (For example creating a wav file )

  bitstream.closeFrame();
}

buffer.getChannelCount()== 1, buffer.getFrequency()== 41000

所以......问题是。如果我创建一个44100 Hz,单声道,16位WaveFile并将其放入Audacity中以查看波形。声音周期性为0,如:(200ms声音)...(200ms NoSound)......(200ms声音)......(200ms NoSound)

这也适用于写入.wav之前的pcm数据...(Yeahi syso所有的东西)

所以有人可能会认为,必须有零帧或者......在那里...所以我切断了所有帧只有0值。这导致wav文件中的零中断略微缩短。对我来说,必须有部分零帧。 所以我从pcm数据中删除了所有零值...而且看起来很奇怪,这很有效。该文件听起来不错。

但这不能解决问题。我仍然不知道为什么有这些假零值。我也需要在我的mp3中保持沉默。

我很欣赏每一个解释提示。感谢

2 个答案:

答案 0 :(得分:3)

我使用此代码完成了工作,转换为byte []:

  
ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
int divider = 1;
if (SAMPLE_RATE < 44100) divider *= 2;
if (CHANNELS == 1) divider *= 2;

[...]

short[] pcmBuffer = buffer.getBuffer();    
for (int i=0; i<pcm.length/divider; i++) {
    outStream.write(pcm[i] & 0xff);
    outStream.write((pcm[i] >> 8 ) & 0xff);
}
  

关键是divider参数,即立体声44中的1,单声道44中的2和单声道22中的4。没有尝试过其他组合。

答案 1 :(得分:1)

嗯......我的回答有点迟了......很抱歉。

我完全解决了这个问题。

JLayer做了一些奇怪的事情。 如果输入mp3是立体声,则pcmbuffer中的值编码如下: leftchannel,rightchannel,leftchannel,... 这应该是这样的。 但如果输入mp3是Mono,我在pcmbuffer中得到相同数量的样本。 但它不像: 单通道,0,单通道,0 整个数据位于pcmbuffer的前半部分,后半部分全部为0.所以你只需要切断下半部分。