ref: c994394fc3bb1a12df7c5b233318f537e30ad6d9
parent: 5c3bc67959790ea0339894c21ee25e81669f81a8
author: Jean-Marc Valin <[email protected]>
date: Fri Aug 29 20:55:07 EDT 2008
Added signalling bits for enabling/disabling pitch, short blocks, and folding. Also, making it possible to disable pitch for all frames.
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -63,6 +63,7 @@
0.5461342, 0.6368315, 0.7228692, 0.8013173, 0.8695045, 0.9251086, 0.9662361, 0.9914865};
#endif
+
/** Encoder state
@brief Encoder state
*/
@@ -73,6 +74,8 @@
int overlap;
int channels;
+ int pitch_enabled;
+
ec_byte_buffer buf;
ec_enc enc;
@@ -106,6 +109,8 @@
st->block_size = N;
st->overlap = mode->overlap;
+ st->pitch_enabled = 1;
+
ec_byte_writeinit(&st->buf);
ec_enc_init(&st->enc,&st->buf);
@@ -375,7 +380,7 @@
int has_pitch;
int pitch_index;
int bits;
- celt_word32_t curr_power, pitch_power;
+ celt_word32_t curr_power, pitch_power=0;
VARDECL(celt_sig_t, in);
VARDECL(celt_sig_t, freq);
VARDECL(celt_norm_t, X);
@@ -427,7 +432,8 @@
#ifndef FIXED_POINT
float gain_1;
#endif
- ec_enc_bits(&st->enc, 1, 1);
+ ec_enc_bits(&st->enc, 0, 1); //Pitch off
+ ec_enc_bits(&st->enc, 1, 1); //Transient on
ec_enc_bits(&st->enc, transient_shift, 2);
if (transient_shift)
ec_enc_uint(&st->enc, transient_time, N+st->overlap);
@@ -452,7 +458,6 @@
}
shortBlocks = 1;
} else {
- ec_enc_bits(&st->enc, 0, 1);
transient_time = -1;
transient_shift = 0;
shortBlocks = 0;
@@ -463,7 +468,7 @@
shortBlocks = 0;
}
/* Pitch analysis: we do it early to save on the peak stack space */
- if (!shortBlocks)
+ if (st->pitch_enabled && !shortBlocks)
find_spectral_pitch(st->mode, st->mode->fft, &st->mode->psy, in, st->out_mem, st->mode->window, 2*N-2*N4, MAX_PERIOD-(2*N-2*N4), &pitch_index);
ALLOC(freq, C*N, celt_sig_t); /**< Interleaved signal MDCTs */
@@ -511,12 +516,12 @@
/*for (i=0;i<N*B*C;i++)printf("%f ", X[i]);printf("\n");*/
/* Compute MDCTs of the pitch part */
- if (!shortBlocks)
- compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, freq);
-
+ if (st->pitch_enabled && !shortBlocks)
{
/* Normalise the pitch vector as well (discard the energies) */
VARDECL(celt_ener_t, bandEp);
+
+ compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, freq);
ALLOC(bandEp, st->mode->nbEBands*st->mode->nbChannels, celt_ener_t);
compute_band_energies(st->mode, freq, bandEp);
normalise_bands(st->mode, freq, P, bandEp);
@@ -524,7 +529,7 @@
}
curr_power = bandE[0]+bandE[1]+bandE[2];
/* Check if we can safely use the pitch (i.e. effective gain isn't too high) */
- if (!shortBlocks && (MULT16_32_Q15(QCONST16(.1f, 15),curr_power) + QCONST32(10.f,ENER_SHIFT) < pitch_power))
+ if (st->pitch_enabled && !shortBlocks && (MULT16_32_Q15(QCONST16(.1f, 15),curr_power) + QCONST32(10.f,ENER_SHIFT) < pitch_power))
{
/* Simulates intensity stereo */
/*for (i=30;i<N*B;i++)
@@ -536,10 +541,14 @@
if (has_pitch)
ec_enc_uint(&st->enc, pitch_index, MAX_PERIOD-(2*N-2*N4));
} else {
+ if (!shortBlocks)
+ {
+ ec_enc_bits(&st->enc, 0, 1); //Pitch off
+ ec_enc_bits(&st->enc, 0, 1); //Transient off
+ }
/* No pitch, so we just pretend we found a gain of zero */
for (i=0;i<st->mode->nbPBands;i++)
gains[i] = 0;
- ec_enc_bits(&st->enc, 0, 7);
for (i=0;i<C*N;i++)
P[i] = 0;
}
@@ -830,7 +839,7 @@
{
#endif
int i, c, N, N4;
- int has_pitch;
+ int has_pitch, has_fold;
int pitch_index;
int bits;
ec_dec dec;
@@ -880,7 +889,15 @@
if (st->mode->nbShortMdcts > 1)
{
- shortBlocks = ec_dec_bits(&dec, 1);
+ has_pitch = ec_dec_bits(&dec, 1);
+ if (has_pitch)
+ {
+ has_fold = ec_dec_bits(&dec, 1);
+ shortBlocks = 0;
+ } else {
+ shortBlocks = ec_dec_bits(&dec, 1);
+ has_fold = 1;
+ }
if (shortBlocks)
{
transient_shift = ec_dec_bits(&dec, 2);
@@ -893,21 +910,28 @@
transient_shift = 0;
}
} else {
+ has_pitch = ec_dec_bits(&dec, 1);
+ if (has_pitch)
+ has_fold = ec_dec_bits(&dec, 1);
+ else
+ has_fold = 1;
shortBlocks = 0;
transient_time = -1;
transient_shift = 0;
}
/* Get the pitch gains */
- has_pitch = unquant_pitch(gains, st->mode->nbPBands, &dec);
/* Get the pitch index */
if (has_pitch)
{
+ has_pitch = unquant_pitch(gains, st->mode->nbPBands, &dec);
pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(2*N-2*N4));
st->last_pitch_index = pitch_index;
} else {
/* FIXME: We could be more intelligent here and just not compute the MDCT */
pitch_index = 0;
+ for (i=0;i<st->mode->nbPBands;i++)
+ gains[i] = 0;
}
ALLOC(fine_quant, st->mode->nbEBands, int);
@@ -929,14 +953,19 @@
unquant_fine_energy(st->mode, bandE, st->oldBandE, fine_quant, &dec);
- /* Pitch MDCT */
- compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, freq);
+ if (has_pitch)
{
VARDECL(celt_ener_t, bandEp);
+
+ /* Pitch MDCT */
+ compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, freq);
ALLOC(bandEp, st->mode->nbEBands*C, celt_ener_t);
compute_band_energies(st->mode, freq, bandEp);
normalise_bands(st->mode, freq, P, bandEp);
+ } else {
+ for (i=0;i<C*N;i++)
+ P[i] = 0;
}
/* Apply pitch gains */
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -425,6 +425,7 @@
#endif
#endif
mdct_clear(&mode->mdct);
+ mdct_clear(&mode->shortMdct);
pitch_state_free(mode->fft);
quant_prob_free(mode->prob);
celt_free((celt_int16_t *)mode->energy_alloc);
--- a/libcelt/quant_pitch.c
+++ b/libcelt/quant_pitch.c
@@ -110,7 +110,15 @@
} else {
id = 0;
}
- ec_enc_bits(enc, id, 7);
+ if (id == 0)
+ {
+ ec_enc_bits(enc, 0, 1); //Pitch off
+ ec_enc_bits(enc, 0, 1); //Transient off
+ } else {
+ ec_enc_bits(enc, 1, 1); //Pitch on
+ ec_enc_bits(enc, 1, 1); //Folding on
+ ec_enc_bits(enc, id, 7);
+ }
/*for (i=0;i<len;i++) printf ("%f ", pgain_table[id*len+i]);printf ("\n");*/
id2gains(id, gains, len);
return id!=0;