author Jean-Marc Valin Sat, 19 Jun 2010 14:27:28 +0000 (10:27 -0400) committer Jean-Marc Valin Sat, 19 Jun 2010 14:27:28 +0000 (10:27 -0400)
 libcelt/bands.c patch | blob | history libcelt/mathops.h patch | blob | history

index 8b35921..4334e7d 100644 (file)
@@ -553,6 +553,8 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
N_B0 = N_B;
}
+
+   /* Reorganize the samples in time order instead of frequency order */
if (!stereo && spread0>1 && level==0)
{
if (encode)
@@ -583,6 +585,8 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
celt_word16 mid, side;
int offset, N2;
offset = m->logN[i]+(LM<<BITRES)-QTHETA_OFFSET;
+
+      /* Decide on the resolution to give to the split parameter theta */
N2 = 2*N-1;
if (stereo && N>2)
N2--;
@@ -609,8 +613,12 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
mid = renormalise_vector(X, Q15ONE, N, 1);
side = renormalise_vector(Y, Q15ONE, N, 1);

-            /* 0.63662 = 2/pi */
+            /* theta is the atan() of the ration between the (normalized)
+               side and mid. With just that parameter, we can re-scale both
+               mid and side because we know that 1) they have unit norm and
+               2) they are orthogonal. */
#ifdef FIXED_POINT
+            /* 0.63662 = 2/pi */
itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid));
#else
itheta = floor(.5f+16384*0.63662f*atan2(side,mid));
@@ -685,6 +693,8 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
} else {
imid = bitexact_cos(itheta);
iside = bitexact_cos(16384-itheta);
+         /* This is the mid vs side allocation that minimizes squared error
+            in that band. */
delta = (N-1)*(log2_frac(iside,BITRES+2)-log2_frac(imid,BITRES+2))>>2;
}

@@ -806,6 +816,7 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
alg_unquant(X, N, q, spread, lowband, (ec_dec*)ec);
}

+   /* This code is used by the decoder and by the resynthesis-enabled encoder */
if (resynth)
{
int k;
@@ -834,6 +845,7 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_
}

+      /* Undo time-freq changes that we did earlier */
N_B = N_B0;
for (k=0;k<time_divide;k++)
@@ -931,12 +943,6 @@ void quant_all_bands(int encode, const CELTMode *m, int start, celt_norm *_X, ce
} else
lowband = NULL;

-      /*if (shortBlocks)
-      {
-         tf_change = tf_res[i] ? -1 : 2;
-      } else {
-         tf_change = tf_res[i] ? -2 : 0;
-      }*/
tf_change = tf_res[i];
quant_band(encode, m, i, X, Y, N, b, spread, tf_change, lowband, resynth, ec, &remaining_bits, LM, norm+M*eBands[i], bandE, 0);

index 29ed4ea..412f7fa 100644 (file)
@@ -76,7 +76,11 @@ static inline int find_max32(celt_word32 *x, int len)
}
#endif

+/* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */
#define FRAC_MUL16(a,b) ((16384+((celt_int32)(celt_int16)(a)*(celt_int16)(b)))>>15)
+
+/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness
+   with this approximation is important because it has an impact on the bit allocation */
static inline celt_int16 bitexact_cos(celt_int16 x)
{
celt_int32 tmp;
@@ -231,7 +235,7 @@ static inline celt_word32 celt_sqrt(celt_word32 x)
int k;
celt_word16 n;
celt_word32 rt;
-   const celt_word16 C = {23175, 11561, -3011, 1699, -664};
+   static const celt_word16 C = {23175, 11561, -3011, 1699, -664};
if (x==0)
return 0;
k = (celt_ilog2(x)>>1)-7;
@@ -250,7 +254,7 @@ static inline celt_word32 celt_psqrt(celt_word32 x)
int k;
celt_word16 n;
celt_word32 rt;
-   const celt_word16 C = {23175, 11561, -3011, 1699, -664};
+   static const celt_word16 C = {23175, 11561, -3011, 1699, -664};
k = (celt_ilog2(x)>>1)-7;
x = VSHR32(x, (k<<1));
n = x-32768;
@@ -308,7 +312,7 @@ static inline celt_word16 celt_log2(celt_word32 x)
celt_word16 n, frac;
/* -0.41509302963303146, 0.9609890551383969, -0.31836011537636605,
0.15530808010959576, -0.08556153059057618 */
-   const celt_word16 C = {-6801+(1<<13-DB_SHIFT), 15746, -5217, 2545, -1401};
+   static const celt_word16 C = {-6801+(1<<13-DB_SHIFT), 15746, -5217, 2545, -1401};
if (x==0)
return -32767;
i = celt_ilog2(x);
@@ -379,6 +383,8 @@ static inline celt_word32 celt_rcp(celt_word32 x)
#define M3 -11943
#define M4 4936

+/* Atan approximation using a 4th order polynomial. Input is in Q15 format
+   and normalized by pi/4. Output is in Q15 format */
static inline celt_word16 celt_atan01(celt_word16 x)
{