First step in quant_band() cleanup: N=1 case.
[opus.git] / celt / bands.c
index d3630b6..412e37f 100644 (file)
@@ -187,7 +187,8 @@ void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, cel
 #endif /* FIXED_POINT */
 
 /* De-normalise the energy to produce the synthesis from the unit-energy bands */
-void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, celt_sig * OPUS_RESTRICT freq, const celt_ener *bandE, int end, int C, int M)
+void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
+      celt_sig * OPUS_RESTRICT freq, const celt_ener *bandE, int start, int end, int C, int M)
 {
    int i, c, N;
    const opus_int16 *eBands = m->eBands;
@@ -197,8 +198,10 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, cel
       celt_sig * OPUS_RESTRICT f;
       const celt_norm * OPUS_RESTRICT x;
       f = freq+c*N;
-      x = X+c*N;
-      for (i=0;i<end;i++)
+      x = X+c*N+M*eBands[start];
+      for (i=0;i<M*eBands[start];i++)
+         *f++ = 0;
+      for (i=start;i<end;i++)
       {
          int j, band_end;
          opus_val32 g = SHR32(bandE[i+c*m->nbEBands],1);
@@ -209,6 +212,7 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, cel
             x++;
          } while (++j<band_end);
       }
+      celt_assert(start <= end);
       for (i=M*eBands[end];i<N;i++)
          *f++ = 0;
    } while (++c<C);
@@ -644,6 +648,41 @@ static int compute_qn(int N, int b, int offset, int pulse_cap, int stereo)
    return qn;
 }
 
+static unsigned quant_band_n1(int encode, celt_norm *X, celt_norm *Y, int b,
+      opus_int32 *remaining_bits, ec_ctx *ec, celt_norm *lowband_out)
+{
+#ifdef RESYNTH
+   int resynth = 1;
+#else
+   int resynth = !encode;
+#endif
+   int c;
+   int stereo;
+   celt_norm *x = X;
+   stereo = Y != NULL;
+   c=0; do {
+      int sign=0;
+      if (*remaining_bits>=1<<BITRES)
+      {
+         if (encode)
+         {
+            sign = x[0]<0;
+            ec_enc_bits(ec, sign, 1);
+         } else {
+            sign = ec_dec_bits(ec, 1);
+         }
+         *remaining_bits -= 1<<BITRES;
+         b-=1<<BITRES;
+      }
+      if (resynth)
+         x[0] = sign ? -NORM_SCALING : NORM_SCALING;
+      x = Y;
+   } while (++c<1+stereo);
+   if (lowband_out)
+      lowband_out[0] = SHR16(X[0],4);
+   return 1;
+}
+
 /* This function is responsible for encoding and decoding a band for both
    the mono and stereo case. Even in the mono case, it can split the band
    in two and transmit the energy difference with the two half-bands. It
@@ -684,29 +723,7 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
    /* Special case for one sample */
    if (N==1)
    {
-      int c;
-      celt_norm *x = X;
-      c=0; do {
-         int sign=0;
-         if (*remaining_bits>=1<<BITRES)
-         {
-            if (encode)
-            {
-               sign = x[0]<0;
-               ec_enc_bits(ec, sign, 1);
-            } else {
-               sign = ec_dec_bits(ec, 1);
-            }
-            *remaining_bits -= 1<<BITRES;
-            b-=1<<BITRES;
-         }
-         if (resynth)
-            x[0] = sign ? -NORM_SCALING : NORM_SCALING;
-         x = Y;
-      } while (++c<1+stereo);
-      if (lowband_out)
-         lowband_out[0] = SHR16(X[0],4);
-      return 1;
+      return quant_band_n1(encode, X, Y, b, remaining_bits, ec, lowband_out);
    }
 
    if (!stereo && level == 0)
@@ -920,8 +937,8 @@ static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, c
          fill &= ((1<<B)-1)<<B;
          delta = 16384;
       } else {
-         imid = bitexact_cos(itheta);
-         iside = bitexact_cos(16384-itheta);
+         imid = bitexact_cos((opus_int16)itheta);
+         iside = bitexact_cos((opus_int16)(16384-itheta));
          /* This is the mid vs side allocation that minimizes squared error
             in that band. */
          delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid));
@@ -1199,6 +1216,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
    int lowband_offset;
    int update_lowband = 1;
    int C = Y_ != NULL ? 2 : 1;
+   int norm_offset;
 #ifdef RESYNTH
    int resynth = 1;
 #else
@@ -1208,11 +1226,12 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
 
    M = 1<<LM;
    B = shortBlocks ? M : 1;
+   norm_offset = M*eBands[start];
    /* No need to allocate norm for the last band because we don't need an
       output in that band */
-   ALLOC(_norm, C*M*eBands[m->nbEBands-1], celt_norm);
+   ALLOC(_norm, C*(M*eBands[m->nbEBands-1]-norm_offset), celt_norm);
    norm = _norm;
-   norm2 = norm + M*eBands[m->nbEBands-1];
+   norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset;
    /* We can use the last band as scratch space because we don't need that
       scratch space for the last band */
    lowband_scratch = X_+M*eBands[m->nbEBands-1];
@@ -1275,11 +1294,11 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
          int fold_end;
          int fold_i;
          /* This ensures we never repeat spectral content within one band */
-         effective_lowband = IMAX(M*eBands[start], M*eBands[lowband_offset]-N);
+         effective_lowband = IMAX(0, M*eBands[lowband_offset]-norm_offset-N);
          fold_start = lowband_offset;
-         while(M*eBands[--fold_start] > effective_lowband);
+         while(M*eBands[--fold_start] > effective_lowband+norm_offset);
          fold_end = lowband_offset-1;
-         while(M*eBands[++fold_end] < effective_lowband+N);
+         while(M*eBands[++fold_end] < effective_lowband+norm_offset+N);
          x_cm = y_cm = 0;
          fold_i = fold_start; do {
            x_cm |= collapse_masks[fold_i*C+0];
@@ -1298,21 +1317,21 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
          /* Switch off dual stereo to do intensity */
          dual_stereo = 0;
          if (resynth)
-            for (j=M*eBands[start];j<M*eBands[i];j++)
+            for (j=0;j<M*eBands[i]-norm_offset;j++)
                norm[j] = HALF32(norm[j]+norm2[j]);
       }
       if (dual_stereo)
       {
          x_cm = quant_band(encode, m, i, X, NULL, N, b/2, spread, B, intensity, tf_change,
                effective_lowband != -1 ? norm+effective_lowband : NULL, ec, &remaining_bits, LM,
-               last?NULL:norm+M*eBands[i], bandE, 0, seed, Q15ONE, lowband_scratch, x_cm);
+               last?NULL:norm+M*eBands[i]-norm_offset, bandE, 0, seed, Q15ONE, lowband_scratch, x_cm);
          y_cm = quant_band(encode, m, i, Y, NULL, N, b/2, spread, B, intensity, tf_change,
                effective_lowband != -1 ? norm2+effective_lowband : NULL, ec, &remaining_bits, LM,
-               last?NULL:norm2+M*eBands[i], bandE, 0, seed, Q15ONE, lowband_scratch, y_cm);
+               last?NULL:norm2+M*eBands[i]-norm_offset, bandE, 0, seed, Q15ONE, lowband_scratch, y_cm);
       } else {
          x_cm = quant_band(encode, m, i, X, Y, N, b, spread, B, intensity, tf_change,
                effective_lowband != -1 ? norm+effective_lowband : NULL, ec, &remaining_bits, LM,
-               last?NULL:norm+M*eBands[i], bandE, 0, seed, Q15ONE, lowband_scratch, x_cm|y_cm);
+               last?NULL:norm+M*eBands[i]-norm_offset, bandE, 0, seed, Q15ONE, lowband_scratch, x_cm|y_cm);
          y_cm = x_cm;
       }
       collapse_masks[i*C+0] = (unsigned char)x_cm;