ref: aa9362564d27daf54e43539f5f5e4d8c2e4401ea
parent: 2b73a27ecebafe55755f569680031ac5759e9f74
author: Jean-Marc Valin <[email protected]>
date: Fri May 29 18:14:20 EDT 2009
New transient handling code that weights the MDCTs directly unless there's a really big amplitude change, in which case the original time-domain window is used.
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -212,14 +212,12 @@
if (ratio > 1000)
ratio = 1000;
ratio *= ratio;
- if (ratio < 50)
- *transient_shift = 0;
- else if (ratio < 256)
- *transient_shift = 1;
- else if (ratio < 4096)
- *transient_shift = 2;
- else
+
+ if (ratio > 2048)
*transient_shift = 3;
+ else
+ *transient_shift = 0;
+
*transient_time = n;
RESTORE_STACK;
@@ -466,6 +464,8 @@
int transient_time;
int transient_shift;
const int C = CHANNELS(st->mode);
+ int mdct_weight_shift = 0;
+ int mdct_weight_pos=0;
SAVE_STACK;
if (check_mode(st->mode) != CELT_OK)
@@ -545,6 +545,63 @@
ALLOC(bandE,st->mode->nbEBands*C, celt_ener_t);
/* Compute MDCTs */
compute_mdcts(st->mode, shortBlocks, in, freq);
+ if (shortBlocks && !transient_shift)
+ {
+ celt_word32_t sum[4];
+ int m=0;
+ do {
+ sum[m] = 1;
+ celt_word32_t tmp=0;
+ for (i=m;i<N;i+=st->mode->nbShortMdcts)
+ tmp += ABS32(freq[i]);
+ sum[m++] = tmp;
+ } while (m<st->mode->nbShortMdcts);
+ m=0;
+#ifdef FIXED_POINT
+ do {
+ if (SHR32(sum[m+1],3) > sum[m])
+ {
+ mdct_weight_shift=2;
+ mdct_weight_pos = m;
+ } else if (SHR32(sum[m+1],1) > sum[m] && mdct_weight_shift < 2)
+ {
+ mdct_weight_shift=1;
+ mdct_weight_pos = m;
+ }
+ m++;
+ } while (m<st->mode->nbShortMdcts-1);
+ for (i=1;i<N;i+=2)
+ freq[i] = SHR32(freq[i],mdct_weight_shift);
+#else
+ do {
+ if (sum[m+1] > 8*sum[m])
+ {
+ mdct_weight_shift=2;
+ mdct_weight_pos = m;
+ } else if (sum[m+1] > 2*sum[m] && mdct_weight_shift < 2)
+ {
+ mdct_weight_shift=1;
+ mdct_weight_pos = m;
+ }
+ m++;
+ } while (m<st->mode->nbShortMdcts-1);
+ if (mdct_weight_shift)
+ {
+ for (m=mdct_weight_pos+1;m<st->mode->nbShortMdcts;m++)
+ for (i=m;i<N;i+=st->mode->nbShortMdcts)
+ freq[i] = (1./(1<<mdct_weight_shift))*freq[i];
+ }
+#endif
+ /*printf ("%f\n", short_ratio);*/
+ /*if (short_ratio < 1)
+ short_ratio = 1;
+ short_ratio = 1<<(int)floor(.5+log2(short_ratio));
+ if (short_ratio>4)
+ short_ratio = 4;*/
+ }/* else if (transient_shift)
+ printf ("8\n");
+ else printf ("1\n");*/
+
compute_band_energies(st->mode, freq, bandE);
intra_ener = st->delayedIntra;
@@ -647,9 +704,15 @@
}
if (shortBlocks)
{
- ec_enc_bits(&enc, transient_shift, 2);
if (transient_shift)
+ {
+ ec_enc_bits(&enc, transient_shift, 2);
ec_enc_uint(&enc, transient_time, N+st->overlap);
+ } else {
+ ec_enc_bits(&enc, mdct_weight_shift, 2);
+ if (mdct_weight_shift && st->mode->nbShortMdcts!=2)
+ ec_enc_uint(&enc, mdct_weight_pos, st->mode->nbShortMdcts-1);
+ }
}
#ifdef STDIN_TUNING2
@@ -727,6 +790,17 @@
CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->overlap-N));
+ if (mdct_weight_shift)
+ {
+ int m;
+ for (m=mdct_weight_pos+1;m<st->mode->nbShortMdcts;m++)
+ for (i=m;i<N;i+=st->mode->nbShortMdcts)
+#ifdef FIXED_POINT
+ freq[i] = SHL32(freq[i], mdct_weight_shift);
+#else
+ freq[i] = (1<<mdct_weight_shift)*freq[i];
+#endif
+ }
compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);
/* De-emphasis and put everything back at the right place in the synthesis history */
if (optional_synthesis != NULL) {
@@ -1061,7 +1135,9 @@
int intra_ener;
int transient_time;
int transient_shift;
+ int mdct_weight_shift=0;
const int C = CHANNELS(st->mode);
+ int mdct_weight_pos=0;
SAVE_STACK;
if (check_mode(st->mode) != CELT_OK)
@@ -1099,10 +1175,16 @@
if (shortBlocks)
{
transient_shift = ec_dec_bits(&dec, 2);
- if (transient_shift)
+ if (transient_shift == 3)
+ {
transient_time = ec_dec_uint(&dec, N+st->mode->overlap);
- else
+ } else {
+ mdct_weight_shift = transient_shift;
+ if (mdct_weight_shift && st->mode->nbShortMdcts>2)
+ mdct_weight_pos = ec_dec_uint(&dec, st->mode->nbShortMdcts-1);
+ transient_shift = 0;
transient_time = 0;
+ }
} else {
transient_time = -1;
transient_shift = 0;
@@ -1166,6 +1248,17 @@
CELT_MOVE(st->decode_mem, st->decode_mem+C*N, C*(DECODE_BUFFER_SIZE+st->overlap-N));
+ if (mdct_weight_shift)
+ {
+ int m;
+ for (m=mdct_weight_pos+1;m<st->mode->nbShortMdcts;m++)
+ for (i=m;i<N;i+=st->mode->nbShortMdcts)
+#ifdef FIXED_POINT
+ freq[i] = SHL32(freq[i], mdct_weight_shift);
+#else
+ freq[i] = (1<<mdct_weight_shift)*freq[i];
+#endif
+ }
/* Compute inverse MDCTs */
compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);