fixed-point: converted normalise_bands (had to split implementation)
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Fri, 7 Mar 2008 04:33:32 +0000 (15:33 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Fri, 7 Mar 2008 04:33:32 +0000 (15:33 +1100)
libcelt/bands.c

index b6d702e..05cab6e 100644 (file)
@@ -93,6 +93,9 @@ void compute_band_energies(const CELTMode *m, const celt_sig_t *X, celt_ener_t *
    /*printf ("\n");*/
 }
 
+const celt_word16_t sqrtC_1[2] = {QCONST16(1.f, 14), QCONST16(1.414214f, 14)};
+
+#ifdef FIXED_POINT
 /* Normalise each band such that the energy is one. */
 void normalise_bands(const CELTMode *m, const celt_sig_t *freq, celt_norm_t *X, const celt_ener_t *bank)
 {
@@ -104,17 +107,23 @@ void normalise_bands(const CELTMode *m, const celt_sig_t *freq, celt_norm_t *X,
    {
       for (i=0;i<m->nbEBands;i++)
       {
-         int j;
-         float g = 1.f/(1e-10+ENER_SCALING_1*bank[i*C+c]*sqrt(C));
+         celt_word16_t g;
+         int j,shift;
+         celt_word16_t E;
+         shift = celt_ilog2(bank[i*C+c])-13;
+         E = VSHR32(bank[i*C+c], shift);
+         if (E>0)
+            g = DIV32_16(SHL32(Q15ONE,13),MULT16_16_Q14(E,sqrtC_1[C-1]));
+         else
+            g = 0;
          for (j=B*eBands[i];j<B*eBands[i+1];j++)
-            X[j*C+c] = NORM_SCALING*SIG_SCALING_1*freq[j*C+c]*g;
+            X[j*C+c] = MULT16_16_Q14(VSHR32(freq[j*C+c],shift),g);
       }
    }
    for (i=B*C*eBands[m->nbEBands];i<B*C*eBands[m->nbEBands+1];i++)
       X[i] = 0;
 }
 
-#ifdef FIXED_POINT
 void renormalise_bands(const CELTMode *m, celt_norm_t *X)
 {
    int i;
@@ -130,6 +139,27 @@ void renormalise_bands(const CELTMode *m, celt_norm_t *X)
    RESTORE_STACK;
 }
 #else
+/* Normalise each band such that the energy is one. */
+void normalise_bands(const CELTMode *m, const celt_sig_t *freq, celt_norm_t *X, const celt_ener_t *bank)
+{
+   int i, c, B, C;
+   const int *eBands = m->eBands;
+   B = m->nbMdctBlocks;
+   C = m->nbChannels;
+   for (c=0;c<C;c++)
+   {
+      for (i=0;i<m->nbEBands;i++)
+      {
+         int j;
+         float g = 1.f/(1e-10+ENER_SCALING_1*bank[i*C+c]*sqrt(C));
+         for (j=B*eBands[i];j<B*eBands[i+1];j++)
+            X[j*C+c] = NORM_SCALING*SIG_SCALING_1*freq[j*C+c]*g;
+      }
+   }
+   for (i=B*C*eBands[m->nbEBands];i<B*C*eBands[m->nbEBands+1];i++)
+      X[i] = 0;
+}
+
 void renormalise_bands(const CELTMode *m, celt_norm_t *X)
 {
    VARDECL(celt_ener_t *tmpE);
@@ -145,7 +175,6 @@ void renormalise_bands(const CELTMode *m, celt_norm_t *X)
 void denormalise_bands(const CELTMode *m, const celt_norm_t *X, celt_sig_t *freq, const celt_ener_t *bank)
 {
    int i, c, B, C;
-   const celt_word16_t sqrtC_1[2] = {QCONST16(1.f, 14), QCONST16(1.414214f, 14)};
    const int *eBands = m->eBands;
    B = m->nbMdctBlocks;
    C = m->nbChannels;