ref: a847b775c948a80da60c6193ce8e99275d6e9c2a
parent: 1ca07225343929f7270432f5ab9391273acb961b
author: Jean-Marc Valin <[email protected]>
date: Wed Feb 27 12:46:49 EST 2008
fixed-point: done with mix_pitch_and_residual() though a bit of cleaning up wouldn't hurt
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -59,6 +59,29 @@
#define approx_inv(x) (1.f/(x))
#endif
+#ifdef FIXED_POINT
+#define C0 3634
+#define C1 21173
+#define C2 -12627
+#define C3 4204
+
+static inline celt_word32_t celt_sqrt(celt_word32_t x)
+{
+ int k;
+ //printf ("%d ", x);
+ celt_word32_t rt;
+ /* ((EC_ILOG(x)-1)>>1) is just the int log4(x) (EC_ILOG returns log2 + 1) */
+ k = ((EC_ILOG(x)-1)>>1)-6;
+ x = VSHR32(x, (k<<1));
+ rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
+ rt = VSHR32(rt,7-k);
+ //printf ("%d\n", rt);
+ return rt;
+}
+#else
+#define celt_sqrt sqrt
+#endif
+
/** Takes the pitch vector and the decoded residual vector (non-compressed),
applies the compression in the pitch direction, computes the gain that will
give ||p+g*y||=1 and mixes the residual with the pitch. */
@@ -66,7 +89,7 @@
{
int i;
celt_word32_t Ryp, Ryy, Rpp;
- float g;
+ celt_word32_t g;
VARDECL(celt_norm_t *y);
#ifdef FIXED_POINT
int yshift = 14-EC_ILOG(K);
@@ -99,10 +122,10 @@
Ryy = MAC16_16(Ryy, y[i],y[i]);
/* g = (sqrt(Ryp^2 + Ryy - Rpp*Ryy)-Ryp)/Ryy */
- g = (sqrt(MULT16_16(PSHR32(Ryp,14),PSHR32(Ryp,14)) + Ryy - MULT16_16(PSHR32(Ryy,14),PSHR32(Rpp,14))) - PSHR32(Ryp,14))/Ryy;
+ g = DIV32(SHL32(celt_sqrt(MULT16_16(PSHR32(Ryp,14),PSHR32(Ryp,14)) + Ryy - MULT16_16(PSHR32(Ryy,14),PSHR32(Rpp,14))) - PSHR32(Ryp,14),14),PSHR32(Ryy,14));
for (i=0;i<N;i++)
- X[i] = P[i] + NORM_SCALING*g*y[i];
+ X[i] = P[i] + MULT16_32_Q14(y[i], g);
}
/** All the info necessary to keep track of a hypothesis during the search */