Fix collapse mask tracking for recombine steps.
authorTimothy B. Terriberry <tterribe@xiph.org>
Thu, 3 Feb 2011 09:57:57 +0000 (01:57 -0800)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 3 Feb 2011 11:31:51 +0000 (06:31 -0500)
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.

libcelt/bands.c

index 68ba697..20b93b9 100644 (file)
@@ -705,11 +705,14 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
 
       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 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
 
          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;