diff --git a/libcelt/celt.c b/libcelt/celt.c index 3ea92566..46a94778 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -69,8 +69,6 @@ struct CELTEncoder { celt_word16_t * restrict preemph_memE; /* Input is 16-bit, so why bother with 32 */ celt_sig_t * restrict preemph_memD; - kiss_fftr_cfg fft; - celt_sig_t *in_mem; celt_sig_t *out_mem; @@ -97,8 +95,6 @@ CELTEncoder EXPORT *celt_encoder_create(const CELTMode *mode) ec_byte_writeinit(&st->buf); ec_enc_init(&st->enc,&st->buf); - st->fft = pitch_state_alloc(MAX_PERIOD); - 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)); @@ -122,8 +118,6 @@ void EXPORT celt_encoder_destroy(CELTEncoder *st) ec_byte_writeclear(&st->buf); - pitch_state_free(st->fft); - celt_free(st->in_mem); celt_free(st->out_mem); @@ -257,7 +251,7 @@ int EXPORT celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, u CELT_COPY(st->in_mem, in+C*(2*N-2*N4-st->overlap), C*st->overlap); /* Pitch analysis: we do it early to save on the peak stack space */ - find_spectral_pitch(st->mode, st->fft, &st->mode->psy, in, st->out_mem, st->mode->window, 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 */ @@ -496,18 +490,35 @@ static void celt_decode_lost(CELTDecoder * restrict st, short * restrict pcm) { int c, N; int pitch_index; + int i, len; VARDECL(celt_sig_t, freq); const int C = CHANNELS(st->mode); + int offset; SAVE_STACK; N = st->block_size; ALLOC(freq,C*N, celt_sig_t); /**< Interleaved signal MDCTs */ + len = N+st->mode->overlap; +#if 0 pitch_index = st->last_pitch_index; /* Use the pitch MDCT as the "guessed" signal */ compute_mdcts(st->mode, st->mode->window, st->out_mem+pitch_index*C, freq); - CELT_MOVE(st->out_mem, st->out_mem+C*N, C*(MAX_PERIOD-N)); +#else + find_spectral_pitch(st->mode, st->mode->fft, &st->mode->psy, st->out_mem+MAX_PERIOD-len, st->out_mem, st->mode->window, len, MAX_PERIOD-len-100, &pitch_index); + pitch_index = MAX_PERIOD-len-pitch_index; + offset = MAX_PERIOD-pitch_index; + while (offset+len >= MAX_PERIOD) + offset -= pitch_index; + compute_mdcts(st->mode, st->mode->window, st->out_mem+offset*C, freq); + for (i=0;iout_mem, st->out_mem+C*N, C*(MAX_PERIOD+st->mode->overlap-N)); /* Compute inverse MDCTs */ compute_inv_mdcts(st->mode, st->mode->window, freq, st->out_mem); diff --git a/libcelt/dump_modes.c b/libcelt/dump_modes.c index 86885bd5..6a190869 100644 --- a/libcelt/dump_modes.c +++ b/libcelt/dump_modes.c @@ -157,6 +157,7 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes) fprintf(file, "allocVectors%d_%d,\t/* allocVectors */\n", mode->Fs, mode->mdctSize); fprintf(file, "allocCache%d_%d_%d,\t/* bits */\n", mode->Fs, mode->mdctSize, mode->nbChannels); fprintf(file, "{%d, 0, 0},\t/* mdct */\n", 2*mode->mdctSize); + fprintf(file, "0,\t/* fft */\n"); fprintf(file, "window%d,\t/* window */\n", mode->overlap); fprintf(file, "{psy_decayR_%d},\t/* psy */\n", mode->Fs); fprintf(file, "0,\t/* prob */\n"); diff --git a/libcelt/modes.c b/libcelt/modes.c index bc553464..b1a0f884 100644 --- a/libcelt/modes.c +++ b/libcelt/modes.c @@ -339,6 +339,8 @@ CELTMode EXPORT *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, mode->marker_end = MODEVALID; #endif /* !STATIC_MODES */ mdct_init(&mode->mdct, 2*mode->mdctSize); + mode->fft = pitch_state_alloc(MAX_PERIOD); + mode->prob = quant_prob_alloc(mode); if (error) *error = CELT_OK; @@ -374,6 +376,7 @@ void EXPORT celt_mode_destroy(CELTMode *mode) #endif #endif mdct_clear(&mode->mdct); + pitch_state_free(mode->fft); quant_prob_free(mode->prob); celt_free((CELTMode *)mode); } diff --git a/libcelt/modes.h b/libcelt/modes.h index fe29f138..d7b59f08 100644 --- a/libcelt/modes.h +++ b/libcelt/modes.h @@ -37,6 +37,7 @@ #include "arch.h" #include "mdct.h" #include "psy.h" +#include "pitch.h" #ifdef STATIC_MODES #include "static_modes.h" @@ -88,7 +89,8 @@ struct CELTMode { /* Stuff that could go in the {en,de}coder, but we save space this way */ mdct_lookup mdct; - + kiss_fftr_cfg fft; + const celt_word16_t *window; struct PsyDecay psy; diff --git a/libcelt/pitch.c b/libcelt/pitch.c index 422f1d2f..25ee4755 100644 --- a/libcelt/pitch.c +++ b/libcelt/pitch.c @@ -104,7 +104,7 @@ static void normalise16(celt_word16_t *x, int len, celt_word16_t val) #define INPUT_SHIFT 15 -void find_spectral_pitch(const CELTMode *m, kiss_fftr_cfg fft, const struct PsyDecay *decay, const celt_sig_t * restrict x, const celt_sig_t * restrict y, const celt_word16_t * restrict window, int len, int *pitch) +void find_spectral_pitch(const CELTMode *m, kiss_fftr_cfg fft, const struct PsyDecay *decay, const celt_sig_t * restrict x, const celt_sig_t * restrict y, const celt_word16_t * restrict window, int len, int max_pitch, int *pitch) { int c, i; VARDECL(celt_word16_t, _X); @@ -224,6 +224,6 @@ void find_spectral_pitch(const CELTMode *m, kiss_fftr_cfg fft, const struct PsyD real16_ifft(fft, X, Y, lag); /* The peak in the correlation gives us the pitch */ - *pitch = find_max16(Y, lag-len); + *pitch = find_max16(Y, max_pitch); RESTORE_STACK; } diff --git a/libcelt/pitch.h b/libcelt/pitch.h index abb0d865..8d6998b4 100644 --- a/libcelt/pitch.h +++ b/libcelt/pitch.h @@ -48,6 +48,6 @@ void pitch_state_free(kiss_fftr_cfg st); /** Find the optimal delay for the pitch prediction. Computation is done in the frequency domain, both to save time and to make it easier to apply psychoacoustic weighting */ -void find_spectral_pitch(const CELTMode *m, kiss_fftr_cfg fft, const struct PsyDecay *decay, const celt_sig_t *x, const celt_sig_t *y, const celt_word16_t *window, int len, int *pitch); +void find_spectral_pitch(const CELTMode *m, kiss_fftr_cfg fft, const struct PsyDecay *decay, const celt_sig_t *x, const celt_sig_t *y, const celt_word16_t *window, int len, int max_pitch, int *pitch); #endif