Fixed a bug in the PLC and added code to estimate the pitch from the synthesis
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Fri, 2 May 2008 00:34:07 +0000 (10:34 +1000)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Fri, 2 May 2008 00:34:07 +0000 (10:34 +1000)
instead of relying on the one previously transmitted by the encoder.

libcelt/celt.c
libcelt/dump_modes.c
libcelt/modes.c
libcelt/modes.h
libcelt/pitch.c
libcelt/pitch.h

index 3ea9256..46a9477 100644 (file)
@@ -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;i<N;i++)
+      freq[i] = MULT16_32_Q15(QCONST16(.9f,15),freq[i]);
+#endif
+   
+   
+   
+   CELT_MOVE(st->out_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);
 
index 86885bd..6a19086 100644 (file)
@@ -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");
index bc55346..b1a0f88 100644 (file)
@@ -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);
 }
index fe29f13..d7b59f0 100644 (file)
@@ -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;
index 422f1d2..25ee475 100644 (file)
@@ -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;
 }
index abb0d86..8d6998b 100644 (file)
@@ -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