ref: 9375aa4faa9ea7a32b1ae5ba7fd8aebd92949c3a
parent: 16ca18b9b087fffb7fec386115e759e334a629ad
author: Jean-Marc Valin <[email protected]>
date: Fri Jun 27 03:57:35 EDT 2008
Cleaned up the pre-echo avoidance code so it works when compiled as fixed-point (still requires float ops though). Also, removed the per-band IDCT.
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -42,24 +42,6 @@
#include "os_support.h"
#include "mathops.h"
-static void dctIV(float *X, int len, int dim)
-{
- return;
- int d, n, k;
- for (d=0;d<dim;d++)
- {
- float x[len];
- for (n=0;n<len;n++)
- x[n] = X[dim*n+d];
- for (k=0;k<len;k++)
- {
- float sum = 0;
- for (n=0;n<len;n++)
- sum += x[n]*cos(M_PI/len*(n+.5)*(k+.5));
- X[dim*k+d] = sqrt(2.f/len)*sum;
- }
- }
-}
#if 0
void exp_rotation(celt_norm_t *X, int len, int dir, int stride, int iter)
{
@@ -429,8 +411,6 @@
q = pulses[i];
n = SHL16(celt_sqrt(C*(eBands[i+1]-eBands[i])),11);
- if (time_domain)
- dctIV(X+C*eBands[i], eBands[i+1]-eBands[i], C);
/* If pitch isn't available, use intra-frame prediction */
if (eBands[i] >= m->pitchEnd || q<=0)
{
@@ -461,8 +441,6 @@
for (j=C*eBands[i];j<C*eBands[i+1];j++)
X[j] = P[j];
}
- if (time_domain)
- dctIV(X+C*eBands[i], eBands[i+1]-eBands[i], C);
for (j=C*eBands[i];j<C*eBands[i+1];j++)
norm[j] = MULT16_16_Q15(n,X[j]);
}
@@ -526,8 +504,6 @@
for (j=C*eBands[i];j<C*eBands[i+1];j++)
X[j] = P[j];
}
- if (time_domain)
- dctIV(X+C*eBands[i], eBands[i+1]-eBands[i], C);
for (j=C*eBands[i];j<C*eBands[i+1];j++)
norm[j] = MULT16_16_Q15(n,X[j]);
}
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -158,6 +158,51 @@
#endif
}
+static int transient_analysis(celt_word32_t *in, int len, int C, float *r)
+{
+ int c, i, n;
+ float ratio, maxN, maxD;
+ float x[len];
+ float begin[len], end[len];
+
+ for (i=0;i<len;i++)
+ x[i] = in[C*i];
+ for (c=1;c<C;c++)
+ {
+ for (i=0;i<len;i++)
+ x[i] = x[i] + in[C*i+c];
+ }
+ begin[0] = x[0]*x[0];
+ for (i=1;i<len;i++)
+ begin[i] = begin[i-1]+x[i]*x[i];
+ end[len-1] = x[len-1]*x[len-1];
+ for (i=len-2;i>=0;i--)
+ end[i] = end[i+1] + x[i]*x[i];
+ maxD = VERY_LARGE32;
+ maxN = 0;
+ n = -1;
+ for (i=8;i<len-8;i++)
+ {
+ float num, den;
+ num = end[i]*i;
+ den = (1000+begin[i])*(len-i)+.01*end[i]*len;
+ if (num*maxD > den*maxN && end[i] > .05*begin[i])
+ {
+ maxN = num;
+ maxD = den;
+ n = i;
+ }
+ }
+ ratio = (end[n]*n)/((100+begin[n])*(len-n));
+ if (n<32)
+ {
+ n = -1;
+ ratio = 0;
+ }
+ *r = ratio;
+ return n;
+}
+
/** Apply window and compute the MDCT for all sub-frames and all channels in a frame */
static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig_t * restrict in, celt_sig_t * restrict out)
{
@@ -317,6 +362,7 @@
int shortBlocks=0;
int transient_time;
float transient_gain;
+ float maxR;
const int C = CHANNELS(st->mode);
SAVE_STACK;
@@ -343,73 +389,44 @@
}
}
CELT_COPY(st->in_mem, in+C*(2*N-2*N4-st->overlap), C*st->overlap);
- if (1) {
- int len = N+st->overlap;
- float maxR, maxD;
- float begin[C*len], end[C*len];
- begin[0] = in[0]*in[0];
- for (i=1;i<len*C;i++)
- begin[i] = begin[i-1]+in[i]*in[i];
- end[len-1] = in[len-1]*in[len-1];
- for (i=C*len-2;i>=0;i--)
- end[i] = end[i+1] + in[i]*in[i];
- maxD = 0;
- maxR = 1;
- transient_time = -1;
- for (i=8*C;i<C*(len-8);i++)
+
+ transient_time = transient_analysis(in, N+st->overlap, C, &maxR);
+ if (maxR > 30)
+ {
+ float gain_1;
+ ec_enc_bits(&st->enc, 1, 1);
+ if (maxR < 30)
{
- float diff = sqrt(sqrt(end[i]/(C*len-i)))-sqrt(sqrt(begin[i]/(i)));
- float ratio = ((1000+end[i])*i)/((1000+begin[i])*(C*len-i));
- if (diff > maxD && end[i] > .5*begin[i])
- {
- maxD = diff;
- maxR = ratio;
- transient_time = i;
- }
- }
- transient_time /= C;
- if (transient_time<32)
+ transient_time = 16;
+ transient_gain = 1;
+ ec_enc_bits(&st->enc, 0, 2);
+ } else if (maxR < 100)
{
- transient_time = -1;
- maxR = 0;
- }
- if (maxR > 30)
+ transient_gain = 2;
+ ec_enc_bits(&st->enc, 1, 2);
+ } else if (maxR < 500)
{
- float gain_1;
- ec_enc_bits(&st->enc, 1, 1);
- if (maxR < 30)
- {
- transient_time = 16;
- transient_gain = 1;
- ec_enc_bits(&st->enc, 0, 2);
- } else if (maxR < 100)
- {
- transient_gain = 2;
- ec_enc_bits(&st->enc, 1, 2);
- } else if (maxR < 500)
- {
- transient_gain = 4;
- ec_enc_bits(&st->enc, 2, 2);
- } else
- {
- transient_gain = 8;
- ec_enc_bits(&st->enc, 3, 2);
- }
- ec_enc_uint(&st->enc, transient_time, len);
- for (c=0;c<C;c++)
- for (i=0;i<16;i++)
- in[C*(transient_time+i-16)+c] /= 1+gainWindow[i]*(transient_gain-1);
- gain_1 = 1./transient_gain;
- for (c=0;c<C;c++)
- for (i=transient_time;i<len;i++)
- in[C*i+c] *= gain_1;
- shortBlocks = 1;
- } else {
- ec_enc_bits(&st->enc, 0, 1);
- transient_time = -1;
- transient_gain = 1;
- shortBlocks = 0;
+ transient_gain = 4;
+ ec_enc_bits(&st->enc, 2, 2);
+ } else
+ {
+ transient_gain = 8;
+ ec_enc_bits(&st->enc, 3, 2);
}
+ ec_enc_uint(&st->enc, transient_time, N+st->overlap);
+ for (c=0;c<C;c++)
+ for (i=0;i<16;i++)
+ in[C*(transient_time+i-16)+c] /= 1+gainWindow[i]*(transient_gain-1);
+ gain_1 = 1./transient_gain;
+ for (c=0;c<C;c++)
+ for (i=transient_time;i<N+st->overlap;i++)
+ in[C*i+c] *= gain_1;
+ shortBlocks = 1;
+ } else {
+ ec_enc_bits(&st->enc, 0, 1);
+ transient_time = -1;
+ transient_gain = 1;
+ shortBlocks = 0;
}
/* Pitch analysis: we do it early to save on the peak stack space */
if (!shortBlocks)
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -87,7 +87,7 @@
fin = fopen(inFile, "rb");
if (!fin)
{
- fprintf (stderr, "Could not open input file %s\n", argv[6]);
+ fprintf (stderr, "Could not open input file %s\n", argv[5]);
return 1;
}
outFile = argv[6];
@@ -94,7 +94,7 @@
fout = fopen(outFile, "wb+");
if (!fout)
{
- fprintf (stderr, "Could not open output file %s\n", argv[7]);
+ fprintf (stderr, "Could not open output file %s\n", argv[6]);
return 1;
}