ref: 2c733067501cf257cb3b428077a728074ab156d0
parent: 7028d62f85001c8606938b6d5e421a1e3a9c3366
author: Jean-Marc Valin <[email protected]>
date: Thu Jul 17 12:22:23 EDT 2008
isolated the folding part of the code that's common in vq.c
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -259,21 +259,12 @@
RESTORE_STACK;
}
-
-#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)
+static celt_word32_t fold(const CELTMode *m, int N, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int Nmax)
{
- int i,j;
- celt_word16_t s = 1;
- int sign;
+ int i, j;
celt_word32_t E;
- celt_word16_t pred_gain;
- celt_word32_t xy=0;
const int C = CHANNELS(m);
-
- pred_gain = celt_div((celt_word32_t)MULT16_16(Q15_ONE,N),(celt_word32_t)(N+KGAIN*K));
-
+
E = EPSILON;
if (N0 >= (Nmax>>1))
{
@@ -292,6 +283,25 @@
E = MAC16_16(E, P[j],P[j]);
}
}
+ return E;
+}
+
+#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)
+{
+ int j;
+ celt_word16_t s = 1;
+ int sign;
+ celt_word32_t E;
+ celt_word16_t pred_gain;
+ celt_word32_t xy=0;
+ const int C = CHANNELS(m);
+
+ 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);
+
for (j=0;j<C*N;j++)
xy = MAC16_16(xy, P[j], x[j]);
if (xy<0)
@@ -312,7 +322,7 @@
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)
{
- int i, j;
+ int j;
celt_word16_t s;
celt_word32_t E;
celt_word16_t pred_gain;
@@ -324,24 +334,9 @@
s = -1;
pred_gain = celt_div((celt_word32_t)MULT16_16(Q15_ONE,N),(celt_word32_t)(N+KGAIN*K));
- E = EPSILON;
- if (N0 >= (Nmax>>1))
- {
- 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]);
- }
- }
+
+ E = fold(m, N, Y, P, N0, Nmax);
+
/*pred_gain = pred_gain/sqrt(E);*/
pred_gain = s*MULT16_16_Q15(pred_gain,celt_rcp(SHL32(celt_sqrt(E),9)));
for (j=0;j<C*N;j++)
@@ -350,29 +345,13 @@
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)
{
- int i, j;
+ int j;
celt_word32_t E;
celt_word16_t g;
const int C = CHANNELS(m);
- E = EPSILON;
- if (N0 >= (Nmax>>1))
- {
- 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]);
- }
- }
+ E = fold(m, N, Y, P, N0, Nmax);
+
g = celt_rcp(SHL32(celt_sqrt(E),9));
for (j=0;j<C*N;j++)
P[j] = PSHR32(MULT16_16(g, P[j]),8);