Playing output from self made MP3 Decoder

Jan 14, 2013 at 10:34 PM
Edited Jan 15, 2013 at 10:05 AM

Hello,

 

The last 3 months i have been working on a MP3 decoder as a hobby project. For each channel i now have a array of floats that range from -1 to 1. When i plot these points the resulting graph matches that of Audacity.

My attempts to play the samples have resulted in sound with the correct rhythm but it sounds weird. I dont know of its my decoders fault or i dont play it in the correct way.

So my question is: Assuming my decoder works, how should i continue with these float values?

After 3 months of work i really want to know if it works haha

 

Thanks!

Coordinator
Jan 15, 2013 at 3:24 PM

I'd recommend saving your audio into a WAV file. Use the WaveFileWriter and WaveFormat.CreateIEEEFormat to make the WaveFormat. Then you can play your audio with Windows Media Player and look at it in Audacity to see what the problem is.

Jan 15, 2013 at 8:38 PM
Edited Jan 15, 2013 at 8:41 PM

Thanks for your reply!

 

I used the following code,
It sounds exactly the same as described above, same rhythm but really distorted.

WaveFormat wFormat = WaveFormat.CreateIeeeFloatWaveFormat(44100, 1);
WaveFileWriter waveWriter = new WaveFileWriter(path, wFormat);

for (int i = 0; i < decodedSamples.Count; i++)
{
    waveWriter.WriteSample(decodedSamples[i]);
}

waveWriter.Close();

 

I made some screenshots of Audacity.
(bottom wave is 1st channel of my decoders output)

The following pic shows that the global shape matches:
http://reinverberne.nl/tmp/1.png

But when zoomed in, its not a "nice" wave:
http://reinverberne.nl/tmp/2.png

If my decoder is bad (verry probably) it could be 1001 places in my code :/
How did you debug your decoder (Nlayer) when writing it?

Regards

Coordinator
Jan 15, 2013 at 8:52 PM

shouldn't you be making a stereo file?

Jan 15, 2013 at 9:08 PM

I tried it but did not matter:

http://reinverberne.nl/tmp/3.png

I think i need a way to compare the outputs of the various decoder blocks with a working decoder
all the way from the huffman decoding block, then the requantize block, then reordering, etc.
To see where the problem lies.

Regards

Jan 16, 2013 at 2:46 PM

I just finished a flac decoder. Of course it is not a mp3 decoder but its always the same. I also got bad results. If nearly the whole wave contains mistakes you would not be able to find the bug quite easy. I thought about different things how to solve my problem but I ended up in reading line for line again and search for mistakes I made. If there is an opensource deocer(in my case there was no flac decoder) you could debug that decoder and compare results with your decoder. 

A very big problem is also if you just have very small  mistakes in your wave. So you can use Audacity, zoom in and get the sample the mistake is. Now you can calculate the frame index where the error happens. Now you can debug start debugging there. 

But all in all. Debugging decoders is always very very hard because there is just such a huge amount of data and you have nothing more than numbers and bytes :(

I really can feel with you... (by the way... I spent over 2 month debugging until everything worked fine :P)

Coordinator
Jan 16, 2013 at 3:52 PM

yes, debugging decoders is really hard. Check in often and regularly so you can rewind mistakes, have a good set of test files that you can check regularly. Still you'll probably need to painstakingly code review each line of your source to spot the problems.

Jan 16, 2013 at 4:01 PM

MrGroovy,

You're on the right track with logging the output (though I'd also log side decode, bit reservoir calc, & scalefactor read).  Just make sure you don't overdo it and force yourself to wade through too much data at once (i.e., only do one frame at a time).

From 2.png and 3.png, it looks like everything through stereo decode is fine, but everything after it is questionable...

One other thought:  Make sure SubBandSynthesis' outer loop reads out polyphase information correctly (looping ss, read element ss from each subband in order, then inverse polyphase decode into your pcm buffer, repeat until all 18 elements have been decoded in all subbands).

Layer III is a bear to get right, so good luck!

Jan 16, 2013 at 10:41 PM

Thanks for all the respones,
i really like that.

So its bug killing time, i think i will use NLayer to see where it goes wrong. I dont know how yet, existing decoders are really well optimised making it harder to follow what is going on where. But i will not give up.

Thanks again :)

 

Jan 22, 2013 at 10:42 PM
Edited Jan 22, 2013 at 10:42 PM

Hi again,

I wanted to share updates and ask some questions :)

Bugs fixed until now:

  1. Small bug in sideinfo decoding
  2. Alias reduction block was not working
  3. IMDCT: i misunderstood how the overlapping worked

Screenshots:

As one can see from imdct and onwards small differences are beginning to crop up. I dont know if these are errors or just the result of different implementations (uber optimised vs unoptimised). Would these differences be audible?

I am now stuck at the synthesis filterbank, dont know what is wrong yet :/

Debugging of reordering and MS stereo processing is not done yet because the file i am trying to decode has no short blocks and is stereo, not joint stereo. "RV" in the screenshots are my initials btw :)

Coordinator
Jan 23, 2013 at 11:17 AM

wow, wish I knew enough about the inner workings of MP3 to be able to offer help with this. Good luck and let us know how you get on

Mark

Jan 24, 2013 at 5:50 PM

@MrGroovy:

The Hybrid (IMDCT) step is really close, so you may just be using too large of a datatype (NLayer and MPEG dist10 use 32-bit floats, libMAD uses 24-bit fixed point [which has about the same precision]).  If that's not it, double-check that you are handling the overlap correctly, then make sure your IMDCT implementation is "correct".  I think it's a "standard" 32-point IMDCT...

I *think* your frequency inversion is fine.  There aren't enough data points visible in the screenshot to say for sure.  It's a pretty simple algorithm, so I don't doubt yours is correct.

The synthesis filterbank is a beast.  See http://doru.info/projects/programming/mpeg1l1l2/ for some pretty high-level math describing how to do it.  You can also search for the MPEG dist10 source code and use theirs (it's probably the slowest algorithm, but still plenty fast enough for real-time decoding).

There are official test files for MP3 out there.  Finding them might be a trick, though...

Jan 24, 2013 at 9:14 PM
Edited Jan 24, 2013 at 9:30 PM

Whoohoo!!

It works :D:D

 

So what was the bug? I had found a usefull PDF that contained a formula but it has a flaw in it!
see: http://www.reinverberne.nl/tmp/9_error.png

so small, so deadly

Coordinator
Jan 24, 2013 at 9:35 PM

congratulations, a great achievement. what are your plans for this decoder?

Jan 24, 2013 at 9:44 PM

Thanks :)

I dont really have plans for it, it is the slowest possible decoder, no optimisations so it cant decode in real time. Maybe i will try to optimise it. Once i cleaned up the source i will share the code somewhere. Maybe blog about it on my site. Right now i am just happy it finally works :))