From 4bf5fd8824ace42069a566441420695d94886131 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <Jean-Marc.Valin@csiro.au> Date: Fri, 30 Nov 2007 15:01:48 +1100 Subject: [PATCH] Pitch cleanup/bugfix --- libcelt/celt.c | 36 +++++++++++++++++++++++++++++++++++- libcelt/pitch.c | 19 ++++++++----------- libcelt/pitch.h | 2 +- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/libcelt/celt.c b/libcelt/celt.c index 75e601e2c..7cee4edfe 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -34,6 +34,7 @@ #include <math.h> #include "celt.h" #include "pitch.h" +#include "fftwrap.h" #define MAX_PERIOD 1024 @@ -46,6 +47,7 @@ struct CELTState_ { float preemph_mem; mdct_lookup mdct_lookup; + void *fft; float *window; float *in_mem; @@ -66,6 +68,7 @@ CELTState *celt_encoder_new(int blockSize, int blocksPerFrame) st->nb_blocks = blocksPerFrame; mdct_init(&st->mdct_lookup, 2*N); + st->fft = spx_fft_init(MAX_PERIOD); st->window = celt_alloc(2*N*sizeof(float)); st->in_mem = celt_alloc(N*sizeof(float)); @@ -84,6 +87,9 @@ void celt_encoder_destroy(CELTState *st) celt_warning("NULL passed to celt_encoder_destroy"); return; } + mdct_clear(&st->mdct_lookup); + spx_fft_destroy(st->fft); + celt_free(st->window); celt_free(st->in_mem); celt_free(st->mdct_overlap); @@ -98,6 +104,7 @@ int celt_encode(CELTState *st, short *pcm) B = st->nb_blocks; float in[(B+1)*N]; float X[B*N]; + float P[B*N]; int pitch_index; /* FIXME: Add preemphasis */ @@ -125,7 +132,34 @@ int celt_encode(CELTState *st, short *pcm) /* Pitch analysis */ - find_spectral_pitch(in, st->out_mem, MAX_PERIOD, (B+1)*N, &pitch_index, NULL); + for (i=0;i<N;i++) + { + in[i] *= st->window[i]; + in[B*N+i] *= st->window[N+i]; + } + find_spectral_pitch(st->fft, in, st->out_mem, MAX_PERIOD, (B+1)*N, &pitch_index, NULL); + + /* Compute MDCTs of the pitch part */ + for (i=0;i<B;i++) + { + int j; + float x[2*N]; + float tmp[N]; + for (j=0;j<2*N;j++) + x[j] = st->window[j]*st->out_mem[pitch_index+i*N+j]; + mdct_forward(&st->mdct_lookup, x, tmp); + /* Interleaving the sub-frames */ + for (j=0;j<N;j++) + P[B*j+i] = tmp[j]; + } + + /*int j; + for (j=0;j<B*N;j++) + printf ("%f ", X[j]); + for (j=0;j<B*N;j++) + printf ("%f ", P[j]); + printf ("\n");*/ + /* Band normalisation */ diff --git a/libcelt/pitch.c b/libcelt/pitch.c index 53a6d861c..28c9b52c6 100644 --- a/libcelt/pitch.c +++ b/libcelt/pitch.c @@ -26,14 +26,8 @@ #include "fftwrap.h" -void find_spectral_pitch(float *x, float *y, int lag, int len, int *pitch, float *curve) +void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int *pitch, float *curve) { - //FIXME: Yuck!!! - static void *fft; - - if (!fft) - fft = spx_fft_init(lag); - float xx[lag]; float X[lag]; float Y[lag]; @@ -49,16 +43,17 @@ void find_spectral_pitch(float *x, float *y, int lag, int len, int *pitch, float X[0] = X[0]*Y[0]; for (i=1;i<lag/2;i++) { - float n = 1.f/(1e1+sqrt((X[2*i-1]*X[2*i-1] + X[2*i ]*X[2*i ])*(Y[2*i-1]*Y[2*i-1] + Y[2*i ]*Y[2*i ]))); + float n = 1.f/(1e1+sqrt(sqrt((X[2*i-1]*X[2*i-1] + X[2*i ]*X[2*i ])*(Y[2*i-1]*Y[2*i-1] + Y[2*i ]*Y[2*i ])))); //n = 1; //n = 1.f/(1+curve[i]); - + if (i>lag/6) + n=0; float tmp = X[2*i-1]; X[2*i-1] = (X[2*i-1]*Y[2*i-1] + X[2*i ]*Y[2*i ])*n; X[2*i ] = (- X[2*i ]*Y[2*i-1] + tmp*Y[2*i ])*n; } - X[len-1] = 0; - X[0] = X[len-1] = 0; + X[lag-1] = 0; + X[0] = X[lag-1] = 0; spx_ifft(fft, X, xx); float max_corr=-1; @@ -73,5 +68,7 @@ void find_spectral_pitch(float *x, float *y, int lag, int len, int *pitch, float max_corr = xx[i]; } } + //printf ("\n"); + //printf ("%d %f\n", *pitch, max_corr); //printf ("%d\n", *pitch); } diff --git a/libcelt/pitch.h b/libcelt/pitch.h index 9b1bdf90a..026f08d47 100644 --- a/libcelt/pitch.h +++ b/libcelt/pitch.h @@ -23,6 +23,6 @@ #ifndef _PITCH_H #define _PITCH_H -void find_spectral_pitch(float *x, float *y, int lag, int len, int *pitch, float *curve); +void find_spectral_pitch(void *fft, float *x, float *y, int lag, int len, int *pitch, float *curve); #endif -- GitLab