Welcome Guest ( Log In | Register )

Reply to this topicStart new topic
ResidualDecoding Help
post Sep 13 2012, 22:44
Post #1

Group: Members
Posts: 15
Joined: 7-April 12
Member No.: 98516

I read the documention of here http://flac.sourceforge.net/format.html#residual about the residual. And I think I ve got a quite good overview but I still wasn t able to write a full decoder.
So I searched after that on the internet and I found two different codes. The first one is the official libflac libary.
That code is very very big if you take a look at the FLAC__bitreader_read_rice_signed_block function in bitreader.c.

The other libary was the flake libary of cuetools (also posted in this forum):
That libary does all that very very easy and in much less code. But I dont understand the code.
So may anyone of you explain me what that code does and how is it possible that the code is so small.
So I thought about that it may does not support highest compression level. And I got it right. It does not support all flac files export from audacity.
If I use compression level 8 it will fail.

So may someone of you tell me a bit about it and how the residual is stored ...

here is the code of cuetools:
        unsafe void decode_residual(BitReader bitreader, FlacFrame frame, int ch)
            // rice-encoded block
            // coding method
            frame.subframes[ch].best.rc.coding_method = (int)bitreader.readbits(2); // ????? == 0
            if (frame.subframes[ch].best.rc.coding_method != 0 && frame.subframes[ch].best.rc.coding_method != 1)
                throw new Exception("unsupported residual coding");
            // partition order
            frame.subframes[ch].best.rc.porder = (int)bitreader.readbits(4);
            if (frame.subframes[ch].best.rc.porder > 8)
                throw new Exception("invalid partition order");
            int porder = frame.blocksize >> frame.subframes[ch].best.rc.porder;
            int res_cnt = porder - frame.subframes[ch].best.order;

            int plen = 4 + frame.subframes[ch].best.rc.coding_method;
            // residual
            int order = frame.subframes[ch].best.order;
            int* r = frame.subframes[ch].best.residual + order;
            int partitions = 1 << frame.subframes[ch].best.rc.porder;
            for (int p = 0; p < partitions; p++)
                if (p == 1) res_cnt = porder;
                int n = Math.Min(res_cnt, frame.blocksize - order);

                int k = frame.subframes[ch].best.rc.rparams[p] = (int)bitreader.readbits(plen);
                if (k == (1 << plen) - 1)
                    k = frame.subframes[ch].best.rc.esc_bps[p] = (int)bitreader.readbits(5);
                    for (int i = n; i > 0; i--)
                        *(r++) = bitreader.readbits_signed((int)k);
                    bitreader.read_rice_block(n, (int)k, r);
                    r += n;
                order += n;

Please help me sad.gif
Go to the top of the page
+Quote Post
post Sep 13 2012, 23:16
Post #2

Winamp Developer

Group: Developer
Posts: 670
Joined: 17-July 05
From: Brooklyn, NY
Member No.: 23375

it's smaller because the complexity is hidden in bitreader.read_rice_block and bitreader.readbits_signed, etc.

The residuals are the "differences" that get you from the predicted audio back to the original audio. Rice codes are one method of storing Variable Length Codes. It has two important aspects. First, it allows for a variable number of bits in storage, so you don't waste overhead mandating, e.g. 16bits per residual. It allows smaller numbers to be stored with fewer bits. Ideally, the predictor is very good and most of the residuals should be zero or close to it. And those small values can be stored in less than 16bits, there-by saving space.
FLAC uses either 4-bit or 5-bit rice parameters. The special value of all 1's , i.e. (1 << plen) - 1, indicates that a literal value is stored after the rice parameter.
Go to the top of the page
+Quote Post
post Sep 14 2012, 00:02
Post #3

Group: Members
Posts: 131
Joined: 20-August 07
Member No.: 46367

This psuedocode-heavy explanation of FLAC decoding with residuals starting on page 28, which might help clarify how it operates from a programmer's perspective.

This post has been edited by tuffy: Sep 14 2012, 00:02
Go to the top of the page
+Quote Post
post Sep 14 2012, 20:39
Post #4

Group: Members
Posts: 15
Joined: 7-April 12
Member No.: 98516

I know that the complexity is hidden in the bitreader. BUT the the method read_rice_block is muuuuuch smaller than the method used in libflac.
If you take a look at this: http://sourceforge.net/projects/jflac/files/jflac/jflac-1.3/
As example take a look at the FixedSubframe. The decoding is much much more code.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:


RSS Lo-Fi Version Time is now: 25th November 2015 - 04:43