Reducing the size of the pulses->bits cache by restricting the number of pulses
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Wed, 22 Jul 2009 11:48:35 +0000 (07:48 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 23 Jul 2009 11:24:03 +0000 (07:24 -0400)
possible

libcelt/rate.c
libcelt/rate.h
libcelt/vq.c

index 9248396..b388701 100644 (file)
@@ -64,9 +64,13 @@ celt_int16_t **compute_alloc_cache(CELTMode *m, int C)
       {
          bits[i] = bits[i-1];
       } else {
-         bits[i] = celt_alloc(MAX_PULSES*sizeof(celt_int16_t));
+         bits[i] = celt_alloc(MAX_PSEUDO*sizeof(celt_int16_t));
          if (bits[i]!=NULL) {
-           get_required_bits(bits[i], N, MAX_PULSES, BITRES);
+            int j;
+            celt_int16_t tmp[MAX_PULSES];
+            get_required_bits(tmp, N, MAX_PULSES, BITRES);
+            for (j=0;j<MAX_PSEUDO;j++)
+               bits[i][j] = tmp[get_pulses(j)];
          } else {
             error=1;
          }
index bc69037..c5c4884 100644 (file)
@@ -32,6 +32,9 @@
 #ifndef RATE_H
 #define RATE_H
 
+#define MAX_PSEUDO 40
+#define LOG_MAX_PSEUDO 6
+
 #define MAX_PULSES 128
 #define LOG_MAX_PULSES 7
 
 
 #include "cwrs.h"
 
+static inline int get_pulses(int i)
+{
+   return i<8 ? i : (8 + (i&7)) << ((i>>3)-1);
+}
+
 static inline int bits2pulses(const CELTMode *m, const celt_int16_t *cache, int N, int bits)
 {
    int i;
    int lo, hi;
+   
+   lo = 0;
+   hi = MAX_PSEUDO-1;
+   for (i=0;i<LOG_MAX_PSEUDO;i++)
+   {
+      int mid = (lo+hi)>>1;
+      /* OPT: Make sure this is implemented with a conditional move */
+      if (cache[mid] >= bits)
+         hi = mid;
+      else
+         lo = mid;
+   }
+   if (bits-cache[lo] <= cache[hi]-bits)
+      return lo;
+   else
+      return hi;
+   
    lo = 0;
    hi = MAX_PULSES-1;
    
index d5c0206..009fcb7 100644 (file)
@@ -38,6 +38,7 @@
 #include "vq.h"
 #include "arch.h"
 #include "os_support.h"
+#include "rate.h"
 
 /** Takes the pitch vector and the decoded residual vector, computes the gain
     that will give ||p+g*y||=1 and mixes the residual with the pitch. */
@@ -106,6 +107,7 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, ec_
 #endif
    SAVE_STACK;
 
+   K = get_pulses(K);
 #ifdef FIXED_POINT
    yshift = 13-celt_ilog2(K);
 #endif
@@ -309,6 +311,7 @@ void alg_unquant(celt_norm_t *X, int N, int K, celt_norm_t *P, ec_dec *dec)
 {
    VARDECL(int, iy);
    SAVE_STACK;
+   K = get_pulses(K);
    ALLOC(iy, N, int);
    decode_pulses(iy, N, K, dec);
    mix_pitch_and_residual(iy, X, N, K, P);
@@ -379,7 +382,7 @@ void intra_fold(const CELTMode *m, celt_norm_t * restrict x, int N, int *pulses,
    fold(m, N, Y, P, N0, B);
    c=0;
    do {
-      int K = pulses[c];
+      int K = get_pulses(pulses[c]);
       if (K==0)
          pred_gain = Q15ONE;
       else