Added signalling bits for enabling/disabling pitch, short blocks, and folding.

Also, making it possible to disable pitch for all frames.
This commit is contained in:
Jean-Marc Valin 2008-08-30 00:55:07 -04:00
parent 5c3bc67959
commit c994394fc3
3 changed files with 53 additions and 15 deletions

View file

@ -63,6 +63,7 @@ static const float transientWindow[16] = {
0.5461342, 0.6368315, 0.7228692, 0.8013173, 0.8695045, 0.9251086, 0.9662361, 0.9914865}; 0.5461342, 0.6368315, 0.7228692, 0.8013173, 0.8695045, 0.9251086, 0.9662361, 0.9914865};
#endif #endif
/** Encoder state /** Encoder state
@brief Encoder state @brief Encoder state
*/ */
@ -73,6 +74,8 @@ struct CELTEncoder {
int overlap; int overlap;
int channels; int channels;
int pitch_enabled;
ec_byte_buffer buf; ec_byte_buffer buf;
ec_enc enc; ec_enc enc;
@ -106,6 +109,8 @@ CELTEncoder *celt_encoder_create(const CELTMode *mode)
st->block_size = N; st->block_size = N;
st->overlap = mode->overlap; st->overlap = mode->overlap;
st->pitch_enabled = 1;
ec_byte_writeinit(&st->buf); ec_byte_writeinit(&st->buf);
ec_enc_init(&st->enc,&st->buf); ec_enc_init(&st->enc,&st->buf);
@ -375,7 +380,7 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
int has_pitch; int has_pitch;
int pitch_index; int pitch_index;
int bits; 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, in);
VARDECL(celt_sig_t, freq); VARDECL(celt_sig_t, freq);
VARDECL(celt_norm_t, X); VARDECL(celt_norm_t, X);
@ -427,7 +432,8 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
#ifndef FIXED_POINT #ifndef FIXED_POINT
float gain_1; float gain_1;
#endif #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); ec_enc_bits(&st->enc, transient_shift, 2);
if (transient_shift) if (transient_shift)
ec_enc_uint(&st->enc, transient_time, N+st->overlap); ec_enc_uint(&st->enc, transient_time, N+st->overlap);
@ -452,7 +458,6 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
} }
shortBlocks = 1; shortBlocks = 1;
} else { } else {
ec_enc_bits(&st->enc, 0, 1);
transient_time = -1; transient_time = -1;
transient_shift = 0; transient_shift = 0;
shortBlocks = 0; shortBlocks = 0;
@ -463,7 +468,7 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
shortBlocks = 0; shortBlocks = 0;
} }
/* Pitch analysis: we do it early to save on the peak stack space */ /* 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); 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 */ ALLOC(freq, C*N, celt_sig_t); /**< Interleaved signal MDCTs */
@ -511,12 +516,12 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
/*for (i=0;i<N*B*C;i++)printf("%f ", X[i]);printf("\n");*/ /*for (i=0;i<N*B*C;i++)printf("%f ", X[i]);printf("\n");*/
/* Compute MDCTs of the pitch part */ /* Compute MDCTs of the pitch part */
if (!shortBlocks) if (st->pitch_enabled && !shortBlocks)
compute_mdcts(st->mode, 0, st->out_mem+pitch_index*C, freq);
{ {
/* Normalise the pitch vector as well (discard the energies) */ /* Normalise the pitch vector as well (discard the energies) */
VARDECL(celt_ener_t, bandEp); 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); ALLOC(bandEp, st->mode->nbEBands*st->mode->nbChannels, celt_ener_t);
compute_band_energies(st->mode, freq, bandEp); compute_band_energies(st->mode, freq, bandEp);
normalise_bands(st->mode, freq, P, bandEp); normalise_bands(st->mode, freq, P, bandEp);
@ -524,7 +529,7 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
} }
curr_power = bandE[0]+bandE[1]+bandE[2]; curr_power = bandE[0]+bandE[1]+bandE[2];
/* Check if we can safely use the pitch (i.e. effective gain isn't too high) */ /* 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 */ /* Simulates intensity stereo */
/*for (i=30;i<N*B;i++) /*for (i=30;i<N*B;i++)
@ -536,10 +541,14 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
if (has_pitch) if (has_pitch)
ec_enc_uint(&st->enc, pitch_index, MAX_PERIOD-(2*N-2*N4)); ec_enc_uint(&st->enc, pitch_index, MAX_PERIOD-(2*N-2*N4));
} else { } 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 */ /* No pitch, so we just pretend we found a gain of zero */
for (i=0;i<st->mode->nbPBands;i++) for (i=0;i<st->mode->nbPBands;i++)
gains[i] = 0; gains[i] = 0;
ec_enc_bits(&st->enc, 0, 7);
for (i=0;i<C*N;i++) for (i=0;i<C*N;i++)
P[i] = 0; P[i] = 0;
} }
@ -830,7 +839,7 @@ int celt_decode_float(CELTDecoder * restrict st, unsigned char *data, int len, c
{ {
#endif #endif
int i, c, N, N4; int i, c, N, N4;
int has_pitch; int has_pitch, has_fold;
int pitch_index; int pitch_index;
int bits; int bits;
ec_dec dec; ec_dec dec;
@ -880,7 +889,15 @@ int celt_decode_float(CELTDecoder * restrict st, unsigned char *data, int len, c
if (st->mode->nbShortMdcts > 1) if (st->mode->nbShortMdcts > 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); shortBlocks = ec_dec_bits(&dec, 1);
has_fold = 1;
}
if (shortBlocks) if (shortBlocks)
{ {
transient_shift = ec_dec_bits(&dec, 2); transient_shift = ec_dec_bits(&dec, 2);
@ -893,21 +910,28 @@ int celt_decode_float(CELTDecoder * restrict st, unsigned char *data, int len, c
transient_shift = 0; transient_shift = 0;
} }
} else { } else {
has_pitch = ec_dec_bits(&dec, 1);
if (has_pitch)
has_fold = ec_dec_bits(&dec, 1);
else
has_fold = 1;
shortBlocks = 0; shortBlocks = 0;
transient_time = -1; transient_time = -1;
transient_shift = 0; transient_shift = 0;
} }
/* Get the pitch gains */ /* Get the pitch gains */
has_pitch = unquant_pitch(gains, st->mode->nbPBands, &dec);
/* Get the pitch index */ /* Get the pitch index */
if (has_pitch) if (has_pitch)
{ {
has_pitch = unquant_pitch(gains, st->mode->nbPBands, &dec);
pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(2*N-2*N4)); pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(2*N-2*N4));
st->last_pitch_index = pitch_index; st->last_pitch_index = pitch_index;
} else { } else {
/* FIXME: We could be more intelligent here and just not compute the MDCT */ /* FIXME: We could be more intelligent here and just not compute the MDCT */
pitch_index = 0; pitch_index = 0;
for (i=0;i<st->mode->nbPBands;i++)
gains[i] = 0;
} }
ALLOC(fine_quant, st->mode->nbEBands, int); ALLOC(fine_quant, st->mode->nbEBands, int);
@ -929,14 +953,19 @@ int celt_decode_float(CELTDecoder * restrict st, unsigned char *data, int len, c
unquant_fine_energy(st->mode, bandE, st->oldBandE, fine_quant, &dec); 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); 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); ALLOC(bandEp, st->mode->nbEBands*C, celt_ener_t);
compute_band_energies(st->mode, freq, bandEp); compute_band_energies(st->mode, freq, bandEp);
normalise_bands(st->mode, freq, P, bandEp); normalise_bands(st->mode, freq, P, bandEp);
} else {
for (i=0;i<C*N;i++)
P[i] = 0;
} }
/* Apply pitch gains */ /* Apply pitch gains */

View file

@ -425,6 +425,7 @@ void celt_mode_destroy(CELTMode *mode)
#endif #endif
#endif #endif
mdct_clear(&mode->mdct); mdct_clear(&mode->mdct);
mdct_clear(&mode->shortMdct);
pitch_state_free(mode->fft); pitch_state_free(mode->fft);
quant_prob_free(mode->prob); quant_prob_free(mode->prob);
celt_free((celt_int16_t *)mode->energy_alloc); celt_free((celt_int16_t *)mode->energy_alloc);

View file

@ -110,7 +110,15 @@ int quant_pitch(celt_pgain_t *gains, int len, ec_enc *enc)
} else { } else {
id = 0; id = 0;
} }
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); ec_enc_bits(enc, id, 7);
}
/*for (i=0;i<len;i++) printf ("%f ", pgain_table[id*len+i]);printf ("\n");*/ /*for (i=0;i<len;i++) printf ("%f ", pgain_table[id*len+i]);printf ("\n");*/
id2gains(id, gains, len); id2gains(id, gains, len);
return id!=0; return id!=0;