Search code examples
mp3decodepcm

JLayer Mono Mp3 to PCM decoding


I am currently working on mp3 decoding with javalayer 1.1.

So I want to receive the raw PCM data from my 44100 Hz, 16bit, Mp3s. It is perfectly working fine with stereo mp3s, but i have strange issues with mono mp3s.

Here some code.

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

So... The Problem is. If I create a 44100 Hz, mono Channel, 16-bit WaveFile and put it in Audacity to see the waves. The sound is periodically 0,like: (200ms Sound)...(200ms NoSound)...(200ms Sound)...(200ms NoSound)

This goes also for the pcm data before writing to .wav... (Yeahi syso all the stuff)

So one may think, well there got to be zero-frames or sth. in there... So I cut off all frames with only 0 values in it. This results in slighty shorter zero breaks in the wav file. Means to me, there must be partial zero frames. So I cut ALL zero values from the pcm data... And as weird as it seems, this worked. The file sounds OK.

But this cant be the solution. I still dont know why there are these false zero values. And I need silence in my mp3's as well.

I'd appreciate every explanation hint. Thanks


Solution

  • I got it working, converting to byte[], using this code:

    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);
    }
    

    The key was the divider parameter, that is 1 in stereo-44, 2 in mono-44 and 4 in mono-22. Didn't try yet other combinations.