Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Rice Parameter 0 (Read 4571 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Rice Parameter 0

I'm decoding FLAC and I'm having some trouble understanding residual encoding for when the rice parameter is 0.  I've been referring to the format specifications and this guy's documentation.  I've included a block header, and some of the lines from a block partition. 

Header: FF F8 C9 18 04 DE 12 00 00 04 3F

Block Header:

[Sync]
FF F8
[Block Size (4096 samples?)]
C                       
[Sample Rate]
9                   
[Ch. Assign]
1                 
[Sample Size]
8         
[Frame #]
04         
[CRC8]
DE

[type]
  12    (SUBFRAME_FIXED  order = 1)

[warm-up sample]
  00 00             
[residual]
  b’00           
[partition order]
b’0001           
[Rice Parameter]
b’0000         

4096 16-bit Samples
Coded in 2 Rice Partitions
Residual Order  = 1
Rice Parameter  = 0
Sample Rate = 44.1 KHz

How would a value of 0xFF in the residual stream be interpreted in this case?  My first guess would be as 8 0's...  But then when I encounter 0x87 I would interpret that as (0,4,0,0).  When I looked at an uncompressed .wav file converted from this same .flac, I noticed all of the samples in this block of data only varied from the previous sample by +-1.  So I feel like I'm missing something big since I don't see how a negative residual would be represented with rice parameter = 0.  Also, the uncompressed .wav samples and decoded .flac don't line up in this block. 

0xFF words of FF + 6 -- (2046?) residuals of 0
3F FFFFFFFFFFFFFFFFFFFFFFFF..

Next byte:
Residuals:[0, 4,0,0]?
10000111 (0x87)

0x4C words of FF --  (608?) residuals of 0
FFFFFFFFFFFFFFFFFFFFFFFF..

Next byte:
Residuals: [0,0, 2,1]?
11001011 (0xCB)

Rice Parameter 0

Reply #1
The actual C code for residual decoding looks something like:
Code: [Select]
msb = read_unary(bitstream, 1);                 /*count 0 bits until the next 1 bit*/
lsb = read(bitstream, rice_parameter);          /*read "Rice parameter" number of additional bits, or 0 if "parameter" is 0*/
value = (msb << rice_parameter) | lsb;          /*combine the high and low bits - note that value = msb if "parameter" is 0*/
if (value & 1) {                                /*chop off the bottom bit as a sign value*/
  residuals_data[sample++] = -(value >> 1) - 1; /*negative residual if 1*/
} else {
  residuals_data[sample++] = value >> 1;        /*positive residual if 0*/
}

So if the Rice parameter is 0, the sign bit gets pulled out of the unary value.  But when in doubt, it's often easier to check your results against the output of
Code: [Select]
flac -a --residual-text file.flac

which is a good way to separate problems parsing the input stream from problems doing the decoding calculations.

Anyway, I'll try to make my document more clear in the next version. 

Rice Parameter 0

Reply #2
Thanks for the explanation.  There's actually another issue I'm running into.

What I'm seeing is a 10000111 (0x87) after the first 2046 residuals.

___________________________________________________________
6 residuals of 0 (first byte)
3F

0xFF words of FF
FFFFFFFFFFFFFFFFFFFFFFFF..

(total at this point 0xFF*8+ 6 = 2046 residuals of 0)

Next byte:
10000111 (0x87)
___________________________________________________________


This would normally correspond with four residuals {0,+2,0,0} according to the algorithm you've provided me (rice parameter = 0):

+2 should correspond with residual[2048-1].  From the residual output text file I have residual[2047]=0 though.  Actually, all residuals in the text file are 0 until residual[2660].

next I have:

___________________________________________________________
0x4C words of FF -- 608 residuals of 0
FFFFFFFFFFFFFFFFFFFFFFFF..


(total at this point: 2050+608 = 2658 residuals --*including the +2)

Next byte:
Residuals: {0,0, +1,-1,0}
11001011 (0xCB)
___________________________________________________________

These correspond with my residual output text file:

residual[2661-1] = residual[2660]=1
residual[2662-1 ]= residual[2661]=-1


So there are 3 unaccounted for 0's after the first 2048 samples in my fixed subframe (2047 residuals + warm-up sample).  If I ignore the 0's, the residuals I calculate match those in the residual text file.  The subframe length is 4096 samples.  Could you shed some light on this please?

Thanks,
Tyler

 

Rice Parameter 0

Reply #3
From where the residuals cut off, it looks like your 0 bits mark the Rice parameter header for the second partition.  Given a block size of 4096 (from the frame header), a FIXED subframe order of 1 (from the subframe header) and a partition order of 1 (from the residuals block header), there will be (4096 / (2 ^ 1)) - 1 = 2047 residuals in the first partition and then 2048 residuals in the second.  But the second partition will start with a fresh, 4-bit Rice parameter value which you'll need to read and account for.