shithub: opus

Download patch

ref: df38f2bf013670903fa273153c1beabb5d27a6f9
parent: 2c733067501cf257cb3b428077a728074ab156d0
author: Jean-Marc Valin <[email protected]>
date: Sun Jul 20 16:36:54 EDT 2008

Re-enabling folding/intra for transients

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -377,7 +377,7 @@
 
 
 /* Quantisation of the residual */
-void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int total_bits, int time_domain, ec_enc *enc)
+void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int total_bits, int shortBlocks, ec_enc *enc)
 {
    int i, j, bits;
    const celt_int16_t * restrict eBands = m->eBands;
@@ -386,8 +386,10 @@
    VARDECL(int, pulses);
    VARDECL(int, offsets);
    const int C = CHANNELS(m);
+   int B;
    SAVE_STACK;
 
+   B = shortBlocks ? m->nbShortMdcts : 1;
    ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
    ALLOC(pulses, m->nbEBands, int);
    ALLOC(offsets, m->nbEBands, int);
@@ -415,13 +417,10 @@
       if (eBands[i] >= m->pitchEnd || q<=0)
       {
          q -= 1;
-         if (!time_domain)
-         {
-            if (q<0)
-               intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], norm, P+C*eBands[i], eBands[i], eBands[m->nbEBands+1]);
-            else
-               intra_prediction(m, X+C*eBands[i], W+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], eBands[m->nbEBands+1], enc);
-         }
+         if (q<0)
+            intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], norm, P+C*eBands[i], eBands[i], B);
+         else
+            intra_prediction(m, X+C*eBands[i], W+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], B, enc);
       }
       
       if (q > 0)
@@ -448,7 +447,7 @@
 }
 
 /* Decoding of the residual */
-void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int total_bits, int time_domain, ec_dec *dec)
+void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int total_bits, int shortBlocks, ec_dec *dec)
 {
    int i, j, bits;
    const celt_int16_t * restrict eBands = m->eBands;
@@ -457,8 +456,10 @@
    VARDECL(int, pulses);
    VARDECL(int, offsets);
    const int C = CHANNELS(m);
+   int B;
    SAVE_STACK;
 
+   B = shortBlocks ? m->nbShortMdcts : 1;
    ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
    ALLOC(pulses, m->nbEBands, int);
    ALLOC(offsets, m->nbEBands, int);
@@ -481,13 +482,10 @@
       if (eBands[i] >= m->pitchEnd || q<=0)
       {
          q -= 1;
-         if (!time_domain)
-         {
-            if (q<0)
-               intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], norm, P+C*eBands[i], eBands[i], eBands[m->nbEBands+1]);
-            else
-               intra_unquant(m, X+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], eBands[m->nbEBands+1], dec);
-         }
+         if (q<0)
+            intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], norm, P+C*eBands[i], eBands[i], B);
+         else
+            intra_unquant(m, X+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], B, dec);
       }
       
       if (q > 0)
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -259,29 +259,19 @@
    RESTORE_STACK;
 }
 
-static celt_word32_t fold(const CELTMode *m, int N, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int Nmax)
+static celt_word32_t fold(const CELTMode *m, int N, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B)
 {
-   int i, j;
+   int j;
    celt_word32_t E;
    const int C = CHANNELS(m);
-
+   int id = N0 % (C*B);
+   /* Here, we assume that id will never be greater than N0, i.e. that 
+      no band is wider than N0. */
    E = EPSILON;
-   if (N0 >= (Nmax>>1))
+   for (j=0;j<C*N;j++)
    {
-      for (i=0;i<C;i++)
-      {
-         for (j=0;j<N;j++)
-         {
-            P[j*C+i] = Y[(Nmax-N0-j-1)*C+i];
-            E += P[j*C+i]*P[j*C+i];
-         }
-      }
-   } else {
-      for (j=0;j<C*N;j++)
-      {
-         P[j] = Y[j];
-         E = MAC16_16(E, P[j],P[j]);
-      }
+      P[j] = Y[id++];
+      E = MAC16_16(E, P[j],P[j]);
    }
    return E;
 }
@@ -288,7 +278,7 @@
 
 #define KGAIN 6
 
-void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *W, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int Nmax, ec_enc *enc)
+void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *W, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B, ec_enc *enc)
 {
    int j;
    celt_word16_t s = 1;
@@ -300,7 +290,7 @@
    
    pred_gain = celt_div((celt_word32_t)MULT16_16(Q15_ONE,N),(celt_word32_t)(N+KGAIN*K));
    
-   E = fold(m, N, Y, P, N0, Nmax);
+   E = fold(m, N, Y, P, N0, B);
    
    for (j=0;j<C*N;j++)
       xy = MAC16_16(xy, P[j], x[j]);
@@ -320,7 +310,7 @@
       P[j] = PSHR32(MULT16_16(pred_gain, P[j]),8);
 }
 
-void intra_unquant(const CELTMode *m, celt_norm_t *x, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int Nmax, ec_dec *dec)
+void intra_unquant(const CELTMode *m, celt_norm_t *x, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B, ec_dec *dec)
 {
    int j;
    celt_word16_t s;
@@ -335,7 +325,7 @@
    
    pred_gain = celt_div((celt_word32_t)MULT16_16(Q15_ONE,N),(celt_word32_t)(N+KGAIN*K));
    
-   E = fold(m, N, Y, P, N0, Nmax);
+   E = fold(m, N, Y, P, N0, B);
    
    /*pred_gain = pred_gain/sqrt(E);*/
    pred_gain = s*MULT16_16_Q15(pred_gain,celt_rcp(SHL32(celt_sqrt(E),9)));
@@ -343,7 +333,7 @@
       P[j] = PSHR32(MULT16_16(pred_gain, P[j]),8);
 }
 
-void intra_fold(const CELTMode *m, celt_norm_t *x, int N, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int Nmax)
+void intra_fold(const CELTMode *m, celt_norm_t *x, int N, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B)
 {
    int j;
    celt_word32_t E;
@@ -350,7 +340,7 @@
    celt_word16_t g;
    const int C = CHANNELS(m);
 
-   E = fold(m, N, Y, P, N0, Nmax);
+   E = fold(m, N, Y, P, N0, B);
    
    g = celt_rcp(SHL32(celt_sqrt(E),9));
    for (j=0;j<C*N;j++)
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -73,11 +73,11 @@
  * @param N0 Number of valid offsets
  * @param enc Entropy encoder state
  */
-void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *W, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int Nmax, ec_enc *enc);
+void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *W, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B, ec_enc *enc);
 
-void intra_unquant(const CELTMode *m, celt_norm_t *x, int N, int K, celt_norm_t *Y, celt_norm_t *P, int N0, int Nmax, ec_dec *dec);
+void intra_unquant(const CELTMode *m, celt_norm_t *x, int N, int K, celt_norm_t *Y, celt_norm_t *P, int N0, int B, ec_dec *dec);
 
 /** Encode the entire band as a "fold" from other parts of the spectrum. No bits required (only use is case of an emergency!) */
-void intra_fold(const CELTMode *m, celt_norm_t *x, int N, celt_norm_t *Y, celt_norm_t *P, int N0, int Nmax);
+void intra_fold(const CELTMode *m, celt_norm_t *x, int N, celt_norm_t *Y, celt_norm_t *P, int N0, int B);
 
 #endif /* VQ_H */