ref: fddc521a5cf6ede6d249d028d129f74c7b171568
parent: 2b747c9817fe12f2123abad4861448dfddf033a0
author: Jean-Marc Valin <[email protected]>
date: Thu Dec 9 09:28:26 EST 2010
Completely new transient analysis algorithm Should be more robust to closely-spaced transients
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -186,15 +186,19 @@
static int transient_analysis(const celt_word32 * restrict in, int len, int C,
celt_word32 *frame_max, int overlap)
{
- int i, n;
- celt_word32 threshold;
- VARDECL(celt_word32, begin);
+ int i;
VARDECL(celt_word16, tmp);
celt_word32 mem0=0,mem1=0;
+ int is_transient = 0;
+ int block;
+ int N;
+ /* FIXME: Make that smaller */
+ celt_word16 bins[50];
SAVE_STACK;
ALLOC(tmp, len, celt_word16);
- ALLOC(begin, len+1, celt_word32);
+ block = overlap/2;
+ N=len/block;
if (C==1)
{
for (i=0;i<len;i++)
@@ -220,38 +224,50 @@
tmp[i] = EXTRACT16(SHR(y,2));
}
/* First few samples are bad because we don't propagate the memory */
- for (i=0;i<24;i++)
+ for (i=0;i<12;i++)
tmp[i] = 0;
- begin[0] = 0;
- for (i=0;i<len;i++)
- begin[i+1] = MAX32(begin[i], ABS32(tmp[i]));
-
- n = -1;
-
- threshold = MULT16_32_Q15(QCONST16(.4f,15),begin[len]);
- /* If the following condition isn't met, there's just no way
- we'll have a transient*/
- if (*frame_max < threshold)
+ for (i=0;i<N;i++)
{
- /* It's likely we have a transient, now find it */
- for (i=8;i<len-8;i++)
+ int j;
+ float max_abs=0;
+ for (j=0;j<block;j++)
+ max_abs = MAX32(max_abs, tmp[i*block+j]);
+ bins[i] = max_abs;
+ }
+ for (i=0;i<N;i++)
+ {
+ int j;
+ int conseq=0;
+ celt_word16 t1, t2, t3;
+
+ t1 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
+ t2 = MULT16_16_Q15(QCONST16(.4f, 15), bins[i]);
+ t3 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]);
+ for (j=0;j<i;j++)
{
- if (begin[i+1] < threshold)
- n=i;
+ if (bins[j] < t1)
+ conseq++;
+ if (bins[j] < t2)
+ conseq++;
+ else
+ conseq = 0;
}
+ if (conseq>=3)
+ is_transient=1;
+ conseq = 0;
+ for (j=i+1;j<N;j++)
+ {
+ if (bins[j] < t3)
+ conseq++;
+ else
+ conseq = 0;
+ }
+ if (conseq>=7)
+ is_transient=1;
}
-
- *frame_max = begin[len-overlap];
- /* Only consider the last 7.5 ms for the next transient */
- if (len>360+overlap)
- {
- *frame_max = 0;
- for (i=len-360-overlap;i<len-overlap;i++)
- *frame_max = MAX32(*frame_max, ABS32(tmp[i]));
- }
RESTORE_STACK;
- return n>=32;
+ return is_transient;
}
/** Apply window and compute the MDCT for all sub-frames and