Changed the rules for using the pulse spreading. It should be used less often
[opus.git] / libcelt / bands.c
index 49c708a..7efa58d 100644 (file)
@@ -96,7 +96,7 @@ void compute_band_energies(const CELTMode *m, const celt_sig_t *X, celt_ener_t *
          {
             int shift = celt_ilog2(maxval)-10;
             for (j=B*eBands[i];j<B*eBands[i+1];j++)
-               sum += VSHR32(X[j*C+c],shift)*VSHR32(X[j*C+c],shift);
+               sum += MULT16_16(EXTRACT16(VSHR32(X[j*C+c],shift)),EXTRACT16(VSHR32(X[j*C+c],shift)));
             /* We're adding one here to make damn sure we never end up with a pitch vector that's
                larger than unity norm */
             bank[i*C+c] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift);
@@ -324,18 +324,22 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce
       {
          q -= 1;
          if (q<0)
-            intra_fold(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), norm, P+B*eBands[i], B, eBands[i], eBands[m->nbEBands+1]);
+            intra_fold(X+B*eBands[i], eBands[i+1]-eBands[i], norm, P+B*eBands[i], B, eBands[i], eBands[m->nbEBands+1]);
          else
-            intra_prediction(X+B*eBands[i], W+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i], enc);
+            intra_prediction(X+B*eBands[i], W+B*eBands[i], eBands[i+1]-eBands[i], q, norm, P+B*eBands[i], B, eBands[i], enc);
       }
       
       if (q > 0)
       {
-         int nb_rotations = (B*(eBands[i+1]-eBands[i])+4*q)/(8*q);
-         exp_rotation(P+B*eBands[i], B*(eBands[i+1]-eBands[i]), -1, B, nb_rotations);
-         exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), -1, B, nb_rotations);
+         int nb_rotations = q <= 2*B ? 2*B/q : 0;
+         if (nb_rotations != 0)
+         {
+            exp_rotation(P+B*eBands[i], B*(eBands[i+1]-eBands[i]), -1, B, nb_rotations);
+            exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), -1, B, nb_rotations);
+         }
          alg_quant(X+B*eBands[i], W+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, P+B*eBands[i], enc);
-         exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), 1, B, nb_rotations);
+         if (nb_rotations != 0)
+            exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), 1, B, nb_rotations);
       }
       for (j=B*eBands[i];j<B*eBands[i+1];j++)
          norm[j] = MULT16_16_Q15(n,X[j]);
@@ -381,17 +385,19 @@ void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P,
       {
          q -= 1;
          if (q<0)
-            intra_fold(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), norm, P+B*eBands[i], B, eBands[i], eBands[m->nbEBands+1]);
+            intra_fold(X+B*eBands[i], eBands[i+1]-eBands[i], norm, P+B*eBands[i], B, eBands[i], eBands[m->nbEBands+1]);
          else
-            intra_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i], dec);
+            intra_unquant(X+B*eBands[i], eBands[i+1]-eBands[i], q, norm, P+B*eBands[i], B, eBands[i], dec);
       }
       
       if (q > 0)
       {
-         int nb_rotations = (B*(eBands[i+1]-eBands[i])+4*q)/(8*q);
-         exp_rotation(P+B*eBands[i], B*(eBands[i+1]-eBands[i]), -1, B, nb_rotations);
+         int nb_rotations = q <= 2*B ? 2*B/q : 0;
+         if (nb_rotations != 0)
+            exp_rotation(P+B*eBands[i], B*(eBands[i+1]-eBands[i]), -1, B, nb_rotations);
          alg_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, P+B*eBands[i], dec);
-         exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), 1, B, nb_rotations);
+         if (nb_rotations != 0)
+            exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), 1, B, nb_rotations);
       }
       for (j=B*eBands[i];j<B*eBands[i+1];j++)
          norm[j] = MULT16_16_Q15(n,X[j]);