ref: eafd8a7f1772ebb8b8608c0ce2e21afd0f971e0a
parent: 2293e4613ea075b28e83833406563259e5d56ca3
author: Jean-Marc Valin <[email protected]>
date: Sat Jan 22 19:24:45 EST 2011
Simple DTX/CNG implementation
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -45,7 +45,7 @@
#include "mathops.h"
#include "rate.h"
-static celt_uint32 lcg_rand(celt_uint32 seed)
+celt_uint32 lcg_rand(celt_uint32 seed)
{
return 1664525 * seed + 1013904223;
}
--- a/libcelt/bands.h
+++ b/libcelt/bands.h
@@ -97,4 +97,6 @@
int start, int end, celt_word16 *logE, celt_word16 *prev1logE,
celt_word16 *prev2logE, int *pulses, celt_uint32 seed);
+celt_uint32 lcg_rand(celt_uint32 seed);
+
#endif /* BANDS_H */
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -52,6 +52,7 @@
#include "float_cast.h"
#include <stdarg.h>
#include "plc.h"
+#include "vq.h"
static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0};
/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
@@ -1695,6 +1696,8 @@
celt_sig *decode_mem[2];
celt_sig *overlap_mem[2];
celt_word16 *lpc;
+ celt_word32 *out_syn[2];
+ celt_word16 *oldBandE, *oldLogE2, *backgroundLogE;
SAVE_STACK;
c=0; do {
@@ -1703,11 +1706,45 @@
overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE;
} while (++c<C);
lpc = (celt_word16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C);
+ oldBandE = lpc+C*LPC_ORDER;
+ oldLogE2 = oldBandE + C*st->mode->nbEBands;
+ backgroundLogE = oldLogE2 + C*st->mode->nbEBands;
+ out_syn[0] = out_mem[0]+MAX_PERIOD-N;
+ if (C==2)
+ out_syn[1] = out_mem[1]+MAX_PERIOD-N;
+
len = N+st->mode->overlap;
- if (st->loss_count == 0)
+ if (st->loss_count >= 5)
{
+ VARDECL(celt_sig, freq);
+ VARDECL(celt_norm, X);
+ VARDECL(celt_ener, bandE);
+ celt_uint32 seed;
+
+ ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
+ ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
+ ALLOC(bandE, st->mode->nbEBands*C, celt_ener);
+
+ log2Amp(st->mode, st->start, st->end, bandE, backgroundLogE, C);
+
+ seed = st->rng;
+ for (i=0;i<C*N;i++)
+ {
+ seed = lcg_rand(seed);
+ X[i] = (celt_int32)(seed)>>20;
+ }
+ st->rng = seed;
+ for (c=0;c<C;c++)
+ for (i=0;i<st->mode->nbEBands;i++)
+ renormalise_vector(X+N*c+(st->mode->eBands[i]<<LM), (st->mode->eBands[i+1]-st->mode->eBands[i])<<LM, Q15ONE);
+
+ denormalise_bands(st->mode, X, freq, bandE, st->mode->nbEBands, C, 1<<LM);
+
+ compute_inv_mdcts(st->mode, 0, freq, out_syn, overlap_mem, C, LM);
+ } else if (st->loss_count == 0)
+ {
celt_word16 pitch_buf[MAX_PERIOD>>1];
celt_word32 tmp=0;
celt_word32 mem0[2]={0,0};
@@ -1724,10 +1761,7 @@
st->last_pitch_index = pitch_index;
} else {
pitch_index = st->last_pitch_index;
- if (st->loss_count < 5)
- fade = QCONST16(.8f,15);
- else
- fade = 0;
+ fade = QCONST16(.8f,15);
}
c=0; do {
@@ -1866,13 +1900,7 @@
out_mem[c][MAX_PERIOD+i] = e[i];
} while (++c<C);
- {
- celt_word32 *out_syn[2];
- out_syn[0] = out_mem[0]+MAX_PERIOD-N;
- if (C==2)
- out_syn[1] = out_mem[1]+MAX_PERIOD-N;
- deemphasis(out_syn, pcm, N, C, st->mode->preemph, st->preemph_memD);
- }
+ deemphasis(out_syn, pcm, N, C, st->mode->preemph, st->preemph_memD);
st->loss_count++;