shithub: opus

Download patch

ref: 57854e816a261415b07fa032af81bc6673401b04
parent: cf5d3a8cf28d18145424f555b0060e4e9465b1da
author: Timothy B. Terriberry <[email protected]>
date: Wed Feb 2 20:57:57 EST 2011

Fix collapse mask tracking for recombine steps.

The recombine loop for cm was correct if one started at 1 block,
 but was wrong otherwise (for a test case, convert 2 recombined
 blocks back to 4 with an initial cm of 0x3; the result should be
 0xF, but instead you get 0x7).
The recombine loop for fill was always wrong (for a test case,
 combine 8 blocks down to 1 with an initial fill=0xFE; the low bit
 remains unset).
This now properly interleaves and deinterleaves bits for these
 steps, which avoids declaring collapses (and skipping folding)
 where none, in fact, occurred.

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -705,11 +705,14 @@
 
       for (k=0;k<recombine;k++)
       {
+         static const unsigned char bit_interleave_table[16]={
+           0,1,1,1,2,3,3,3,2,3,3,3,2,3,3,3
+         };
          if (encode)
             haar1(X, N>>k, 1<<k);
          if (lowband)
             haar1(lowband, N>>k, 1<<k);
-         fill |= fill<<(1<<k);
+         fill = bit_interleave_table[fill&0xF]|bit_interleave_table[fill>>4]<<2;
       }
       B>>=recombine;
       N_B<<=recombine;
@@ -1126,7 +1129,11 @@
 
          for (k=0;k<recombine;k++)
          {
-            cm |= cm<<(1<<k);
+            static const unsigned char bit_deinterleave_table[16]={
+              0x00,0x03,0x0C,0x0F,0x30,0x33,0x3C,0x3F,
+              0xC0,0xC3,0xCC,0xCF,0xF0,0xF3,0xFC,0xFF
+            };
+            cm = bit_deinterleave_table[cm];
             haar1(X, N0>>k, 1<<k);
          }
          B<<=recombine;