From 527db5c4501a7c03b26ff1ab365e74da50250e90 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Tue, 2 Jun 2009 07:56:19 -0400 Subject: [PATCH] Adding a decision mechanism for turning folding on or off depending on the signal characteristics --- libcelt/bands.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ libcelt/bands.h | 2 ++ libcelt/celt.c | 8 ++++++- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/libcelt/bands.c b/libcelt/bands.c index 409f1379..bc41d23d 100644 --- a/libcelt/bands.c +++ b/libcelt/bands.c @@ -397,6 +397,69 @@ void deinterleave(celt_norm_t *x, int N) RESTORE_STACK; } +int folding_decision(const CELTMode *m, celt_norm_t *X, celt_word16_t *average, int *last_decision) +{ + int i; + int NR=0; + celt_word32_t ratio = EPSILON; + const celt_int16_t * restrict eBands = m->eBands; + for (i=0;inbEBands;i++) + { + int j, N; + int max_i=0; + celt_word16_t max_val=EPSILON; + celt_word32_t floor_ener=EPSILON; + celt_norm_t * restrict x = X+eBands[i]; + N = eBands[i+1]-eBands[i]; + for (j=0;jmax_val) + { + max_val = ABS16(x[j]); + max_i = j; + } + } +#if 0 + for (j=0;j2) + floor_ener += x[j]*x[j]; + } +#else + floor_ener = QCONST32(1.,28)-MULT16_16(max_val,max_val); + if (max_i < N-1) + floor_ener -= MULT16_16(x[max_i+1], x[max_i+1]); + if (max_i < N-2) + floor_ener -= MULT16_16(x[max_i+2], x[max_i+2]); + if (max_i > 0) + floor_ener -= MULT16_16(x[max_i-1], x[max_i-1]); + if (max_i > 1) + floor_ener -= MULT16_16(x[max_i-2], x[max_i-2]); + floor_ener = MAX32(floor_ener, EPSILON); +#endif + if (N>7 && eBands[i] >= m->pitchEnd) + { + celt_word16_t r; + celt_word16_t den = celt_sqrt(floor_ener); + den = MAX32(QCONST16(.02, 15), den); + r = DIV32_16(SHL32(EXTEND32(max_val),8),den); + ratio = ADD32(ratio, EXTEND32(r)); + NR++; + } + } + if (NR>0) + ratio = DIV32_16(ratio, NR); + ratio = ADD32(HALF32(ratio), HALF32(*average)); + if (!*last_decision) + { + *last_decision = (ratio < QCONST16(1.8,8)); + } else { + *last_decision = (ratio < QCONST16(3.,8)); + } + *average = EXTRACT16(ratio); + return *last_decision; +} + /* Quantisation of the residual */ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, int pitch_used, celt_pgain_t *pgains, const celt_ener_t *bandE, int *pulses, int shortBlocks, int fold, int total_bits, ec_enc *enc) { diff --git a/libcelt/bands.h b/libcelt/bands.h index ccaa7eec..98d9103f 100644 --- a/libcelt/bands.h +++ b/libcelt/bands.h @@ -73,6 +73,8 @@ void denormalise_bands(const CELTMode *m, const celt_norm_t * restrict X, celt_s */ int compute_pitch_gain(const CELTMode *m, const celt_norm_t *X, const celt_norm_t *P, celt_pgain_t *gains); +int folding_decision(const CELTMode *m, celt_norm_t *X, celt_word16_t *average, int *last_decision); + /** Quantisation/encoding of the residual spectrum * @param m Mode data * @param X Residual (normalised) diff --git a/libcelt/celt.c b/libcelt/celt.c index f6962142..ad916bda 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -78,6 +78,9 @@ struct CELTEncoder { int pitch_enabled; int pitch_available; int delayedIntra; + celt_word16_t tonal_average; + int fold_decision; + int VBR_rate; /* Target number of 16th bits per frame */ celt_word16_t * restrict preemph_memE; /* Input is 16-bit, so why bother with 32 */ celt_sig_t * restrict preemph_memD; @@ -113,6 +116,8 @@ CELTEncoder *celt_encoder_create(const CELTMode *mode) st->pitch_enabled = 1; st->pitch_available = 1; st->delayedIntra = 1; + st->tonal_average = QCONST16(1.,8); + st->fold_decision = 1; st->in_mem = celt_alloc(st->overlap*C*sizeof(celt_sig_t)); st->out_mem = celt_alloc((MAX_PERIOD+st->overlap)*C*sizeof(celt_sig_t)); @@ -652,7 +657,8 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_si /* Band normalisation */ normalise_bands(st->mode, freq, X, bandE); - + if (!shortBlocks && !folding_decision(st->mode, X, &st->tonal_average, &st->fold_decision)) + has_fold = 0; #ifdef EXP_PSY ALLOC(bandN,C*st->mode->nbEBands, celt_ener_t); ALLOC(bandM,st->mode->nbEBands, celt_ener_t);