0

I am simply trying to take any or first frame from an mp3 file and then decompress it.

internal void Read3(string location) //take in file location
    {
        Mp3FileReader mp3 = new Mp3FileReader(location); //make a Mp3FileReader

        SECTIONA: //to jump back here when needed.

        byte[] _passedBuffer = Decompress(mp3.ReadNextFrame()); //passed the decompressed byte array here.
        int jump_size = mp3.WaveFormat.Channels *2; //just to get how many bytes to skip
        for (int i = 0; i < _passedBuffer.Length; i += jump_size)
        {
            short FinalSample = BitConverter.ToInt16(_passedBuffer, i);

            if (jump_size == 4) //converting the bytes to Int16,nothing special here.
            { 
               FinalSample = (short)(((BitConverter.ToInt16(_passedBuffer, i + 2)) + FinalSample) / 2); 
            }
            Console.Write(FinalSample+"|"); //and writing it down to Console.
        }
        Console.WriteLine("Frames are Written,continue to next frame?");
        if (Convert.ToChar(Console.Read()) == 'y') //asking to go on or not.
        { goto SECTIONA; }
    }


 private byte[] Decompress(Mp3Frame fm)
    {
        var buffer = new byte[16384 * 4]; //big enough buffer size
        WaveFormat wf = new Mp3WaveFormat(fm.SampleRate, fm.ChannelMode == ChannelMode.Mono ? 1 : 2, fm.FrameLength, fm.BitRate); //creating a new WaveFormat

        IMp3FrameDecompressor decompressor = new AcmMp3FrameDecompressor(wf); //passing in to AcmMp3FrameDecompressor.
        decompressor.DecompressFrame(fm, buffer, 0); //running the DecompressFrame method and then passing back the buffer.
        return buffer;

    }

Now the Mp3FileReader is reading the Frame correctly as I checked the Frame's RawData. Now I am trying to decompress that Frame and then convert its PCM data into Int16 in that only For Loop but every Int16 FinalSample value is returning 0. I know that just using Mp3FileReader.Read(Buffer,Offset,Length) will get the job done but for all the frames so:

  • how do I do it for just one frame?
  • what is wrong with my code because of which I am getting all zeros?
  • I know that RawData is ok, so something must be wrong with Decompress method, How do I setup a decompressor for mp3 file?

1 Answers1

0

You can use the AcmMp3FrameDecompressor or DmoMp3FrameDecompressor to decompress individual MP3 frames.

You need to check the return value of Decompress to see how much data was returned. It's possible for the first frame not to return anything.

You should also create a single frame decompressor and use it for all frames in the MP3 file, as it retains state between calls.

Mark Heath
  • 48,273
  • 29
  • 137
  • 194
  • I made some changes to the code, I replaced `AcmMp3FrameDecompressor` with `DmoMp3FrameDecompressor` but an exception arrived saying "Unsupported input format". –  Feb 20 '18 at 08:34
  • welcome to the fun world of debugging codecs! It's always a pain setting up exactly the right WaveFormat that a codec will accept. The way I would approach this is to set up an Mp3FileReader using DmoMp3FrameDecompressor and then put a breakpoint in to examine the WaveFormat it receives and make sure yours exactly matches (including any additional bytes). – Mark Heath Feb 20 '18 at 09:39