ref: 24c9cdaca1b497a4d4637dfbc60774b86143fc6c
parent: a1bb9c707faf6b70a5b42959909772228bbfd901
author: Jean-Marc Valin <[email protected]>
date: Fri May 2 06:34:07 EDT 2008
Fixed a bug in the PLC and added code to estimate the pitch from the synthesis instead of relying on the one previously transmitted by the encoder.
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -69,8 +69,6 @@
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 @@
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 @@
ec_byte_writeclear(&st->buf);
- pitch_state_free(st->fft);
-
celt_free(st->in_mem);
celt_free(st->out_mem);
@@ -257,7 +251,7 @@
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 @@
{
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);
--- a/libcelt/dump_modes.c
+++ b/libcelt/dump_modes.c
@@ -157,6 +157,7 @@
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");
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -339,6 +339,8 @@
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 @@
#endif
#endif
mdct_clear(&mode->mdct);
+ pitch_state_free(mode->fft);
quant_prob_free(mode->prob);
celt_free((CELTMode *)mode);
}
--- 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 @@
/* 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;
--- a/libcelt/pitch.c
+++ b/libcelt/pitch.c
@@ -104,7 +104,7 @@
#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 @@
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;
}
--- a/libcelt/pitch.h
+++ b/libcelt/pitch.h
@@ -48,6 +48,6 @@
/** 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