Sep 13 2012, 22:44
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;
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
Sep 13 2012, 23:16
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.
|Lo-Fi Version||Time is now: 1st March 2015 - 23:08|