ref: 98046cadcfc1160df434d97b0bdd40f3116f3161
parent: abe40f02a93968c2a2e4f8a19c1deceaff9567c3
author: Gregory Maxwell <[email protected]>
date: Sat Dec 13 15:42:03 EST 2008
Add a SET_LTP call to allow on the fly activation/deactivation of the long term predictor even in high complexity mode (LTP off is more loss robust), fix the case where turning on LTP on a running stream can cause prediction against bogus data by delaying the usage of the LTP until enough data has been encoded.
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -77,6 +77,7 @@
int channels;
int pitch_enabled;
+ int pitch_available;
celt_word16_t * restrict preemph_memE; /* Input is 16-bit, so why bother with 32 */
celt_sig_t * restrict preemph_memD;
@@ -109,6 +110,7 @@
st->overlap = mode->overlap;
st->pitch_enabled = 1;
+ st->pitch_available = 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));
@@ -378,7 +380,6 @@
int has_fold=1;
ec_byte_buffer buf;
ec_enc enc;
- celt_word32_t curr_power, pitch_power=0;
VARDECL(celt_sig_t, in);
VARDECL(celt_sig_t, freq);
VARDECL(celt_norm_t, X);
@@ -477,6 +478,8 @@
}
/* Pitch analysis: we do it early to save on the peak stack space */
+ /* Don't use pitch if there isn't enough data available yet, or if we're using shortBlocks */
+ has_pitch = st->pitch_enabled && (st->pitch_available >= MAX_PERIOD) && (!shortBlocks);
#ifdef EXP_PSY
ALLOC(tonality, MAX_PERIOD/4, celt_word16_t);
{
@@ -486,7 +489,7 @@
compute_tonality(st->mode, X, st->psy_mem, MAX_PERIOD, tonality, MAX_PERIOD/4);
}
#else
- if (st->pitch_enabled && !shortBlocks)
+ if (has_pitch)
{
find_spectral_pitch(st->mode, st->mode->fft, &st->mode->psy, in, st->out_mem, st->mode->window, NULL, 2*N-2*N4, MAX_PERIOD-(2*N-2*N4), &pitch_index);
}
@@ -541,8 +544,9 @@
#endif
/* Compute MDCTs of the pitch part */
- if (st->pitch_enabled && !shortBlocks)
+ if (has_pitch)
{
+ celt_word32_t curr_power, pitch_power=0;
/* Normalise the pitch vector as well (discard the energies) */
VARDECL(celt_ener_t, bandEp);
@@ -551,19 +555,18 @@
compute_band_energies(st->mode, freq, bandEp);
normalise_bands(st->mode, freq, P, bandEp);
pitch_power = bandEp[0]+bandEp[1]+bandEp[2];
+ /* Check if we can safely use the pitch (i.e. effective gain isn't too high) */
+ curr_power = bandE[0]+bandE[1]+bandE[2];
+ id=-1;
+ if ((MULT16_32_Q15(QCONST16(.1f, 15),curr_power) + QCONST32(10.f,ENER_SHIFT) < pitch_power))
+ {
+ /* Pitch prediction */
+ compute_pitch_gain(st->mode, X, P, gains);
+ id = quant_pitch(gains, st->mode->nbPBands);
+ }
+ if (id == -1)
+ has_pitch = 0;
}
-
- /* Check if we can safely use the pitch (i.e. effective gain isn't too high) */
- curr_power = bandE[0]+bandE[1]+bandE[2];
- has_pitch = 0;
- if (st->pitch_enabled && !shortBlocks && (MULT16_32_Q15(QCONST16(.1f, 15),curr_power) + QCONST32(10.f,ENER_SHIFT) < pitch_power))
- {
- /* Pitch prediction */
- compute_pitch_gain(st->mode, X, P, gains);
- id = quant_pitch(gains, st->mode->nbPBands);
- if (id > -1)
- has_pitch = 1;
- }
if (has_pitch)
{
@@ -626,8 +629,11 @@
quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, has_fold, nbCompressedBytes*8, &enc);
/* Re-synthesis of the coded audio if required */
- if (st->pitch_enabled || optional_synthesis!=NULL)
+ if (st->pitch_available>0 || optional_synthesis!=NULL)
{
+ if (st->pitch_available>0 && st->pitch_available<MAX_PERIOD)
+ st->pitch_available+=st->frame_size;
+
if (C==2)
renormalise_bands(st->mode, X);
/* Synthesis */
@@ -743,7 +749,22 @@
int value = va_arg(ap, int);
if (value<0 || value>10)
goto bad_arg;
- if (value<=2)
+ if (value<=2) {
+ st->pitch_enabled = 0;
+ st->pitch_available = 0;
+ } else {
+ st->pitch_enabled = 1;
+ if (st->pitch_available<1)
+ st->pitch_available = 1;
+ }
+ }
+ break;
+ case CELT_SET_LTP_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ if (value<0 || value>1 || (value==1 && st->pitch_available==0))
+ goto bad_arg;
+ if (value==0)
st->pitch_enabled = 0;
else
st->pitch_enabled = 1;
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -71,6 +71,9 @@
#define CELT_SET_COMPLEXITY_REQUEST 2
/** Controls the complexity from 0-10 (int) */
#define CELT_SET_COMPLEXITY(x) CELT_SET_COMPLEXITY_REQUEST, _celt_check_int(x)
+#define CELT_SET_LTP_REQUEST 3
+/** Activate or deactivate the use of the long term predictor (PITCH) from 0 or 1 (int) */
+#define CELT_SET_LTP(x) CELT_SET_LTP_REQUEST, _celt_check_int(x)
/** GET the frame size used in the current mode */
#define CELT_GET_FRAME_SIZE 1000