[xiph-commits] r10734 - trunk/ghost/libghost
jm at svn.xiph.org
jm at svn.xiph.org
Mon Jan 16 17:29:31 PST 2006
Author: jm
Date: 2006-01-16 17:29:28 -0800 (Mon, 16 Jan 2006)
New Revision: 10734
Modified:
trunk/ghost/libghost/ghost.c
trunk/ghost/libghost/ghost.h
Log:
spectral (FFT+LPC) analysis of residual. checked in some more Speex stuff.
Modified: trunk/ghost/libghost/ghost.c
===================================================================
--- trunk/ghost/libghost/ghost.c 2006-01-17 00:47:12 UTC (rev 10733)
+++ trunk/ghost/libghost/ghost.c 2006-01-17 01:29:28 UTC (rev 10734)
@@ -34,6 +34,69 @@
#define SINUSOIDS 30
+void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+ int i,j;
+ spx_word32_t xi,yi;
+
+ for (i=0;i<N;i++)
+ {
+ xi=SATURATE(x[i],805306368);
+ yi = xi + SHL32(mem[0],2);
+ for (j=0;j<ord-1;j++)
+ {
+ mem[j] = MAC16_32_Q15(mem[j+1], num[j],xi);
+ }
+ mem[ord-1] = MULT16_32_Q15(num[ord-1],xi);
+ y[i] = SATURATE(yi,805306368);
+ }
+}
+
+spx_word32_t _spx_lpc(
+spx_coef_t *lpc, /* out: [0...p-1] LPC coefficients */
+const spx_word16_t *ac, /* in: [0...p] autocorrelation values */
+int p
+ )
+{
+ int i, j;
+ spx_word16_t r;
+ spx_word16_t error = ac[0];
+
+ if (ac[0] == 0)
+ {
+ for (i = 0; i < p; i++)
+ lpc[i] = 0;
+ return 0;
+ }
+
+ for (i = 0; i < p; i++) {
+
+ /* Sum up this iteration's reflection coefficient */
+ spx_word32_t rr = NEG32(SHL32(EXTEND32(ac[i + 1]),13));
+ for (j = 0; j < i; j++)
+ rr = SUB32(rr,MULT16_16(lpc[j],ac[i - j]));
+#ifdef FIXED_POINT
+ r = DIV32_16(rr,ADD16(error,16));
+#else
+ r = rr/(error+.003*ac[0]);
+#endif
+ /* Update LPC coefficients and total error */
+ lpc[i] = r;
+ for (j = 0; j < i>>1; j++)
+ {
+ spx_word16_t tmp = lpc[j];
+ lpc[j] = MAC16_16_Q13(lpc[j],r,lpc[i-1-j]);
+ lpc[i-1-j] = MAC16_16_Q13(lpc[i-1-j],r,tmp);
+ }
+ if (i & 1)
+ lpc[j] = MAC16_16_Q13(lpc[j],lpc[j],r);
+
+ error = SUB16(error,MULT16_16_Q13(r,MULT16_16_Q13(error,r)));
+ }
+ return error;
+}
+
+
GhostEncState *ghost_encoder_state_new(int sampling_rate)
{
int i;
@@ -53,7 +116,10 @@
st->analysis_window = calloc(st->length,sizeof(float));
st->synthesis_window = calloc(st->length,sizeof(float));
st->big_window = calloc(PCM_BUF_SIZE,sizeof(float));
+ st->lpc_window = calloc(st->lpc_length,sizeof(float));
+
st->syn_memory = calloc(st->overlap,sizeof(float));
+ st->noise_mem = calloc(st->lpc_order,sizeof(float));
for (i=0;i<st->length;i++)
{
st->analysis_window[i] = 1;
@@ -64,7 +130,11 @@
st->synthesis_window[i] = .5-.5*cos(M_PI*i/st->overlap);
st->synthesis_window[st->length-i-1] = .5-.5*cos(M_PI*(i+1)/st->overlap);
}
+ for (i=0;i<st->lpc_length;i++)
+ st->lpc_window[i] = .5-.5*cos(M_PI*i/st->lpc_length);
+
st->big_fft = spx_fft_init(PCM_BUF_SIZE);
+ st->lpc_fft = spx_fft_init(st->lpc_length);
for (i=0;i<PCM_BUF_SIZE;i++)
st->big_window[i] = .5-.5*cos(2*M_PI*(i+1)/PCM_BUF_SIZE);
return st;
@@ -138,10 +208,36 @@
for (i=st->advance;i<st->length;i++)
st->syn_memory[i-st->advance]=y[i];*/
+ float noise_ac[st->lpc_length];
+ float noise_psd[st->lpc_length];
+ for (i=0;i<st->lpc_length;i++)
+ noise_ac[i] = st->lpc_window[i]*st->new_noise[i];
+ spx_fft_float(st->lpc_fft, noise_ac, noise_psd);
+ /*for (i=1;i<(st->lpc_length>>1);i++)
+ {
+ noise_psd[i] = noise_psd[2*i-1]*noise_psd[2*i-1] + noise_psd[2*i]*noise_psd[2*i];
+ }
+ noise_psd[0] = noise_psd[0]*noise_psd[0];
+ noise_psd[(st->lpc_length>>1)-1] = noise_psd[st->lpc_length-1]*noise_psd[st->lpc_length-1];
+ */
- for (i=0;i<st->length-st->overlap;i++)
- pcm[i] = st->current_frame[i]-st->new_noise[i];
+ noise_psd[0] *= noise_psd[0];
+ for (i=1;i<st->lpc_length-1;i+=2)
+ {
+ noise_psd[i] = noise_psd[i]*noise_psd[i] + noise_psd[i+1]*noise_psd[i+1];
+ }
+ noise_psd[st->lpc_length-1] *= noise_psd[st->lpc_length-1];
+ spx_ifft_float(st->lpc_fft, noise_psd, noise_ac);
+ noise_ac[0] *= 1.0001;
+ float lpc[st->lpc_order];
+ _spx_lpc(lpc, noise_ac, st->lpc_order);
+ fir_mem2(st->new_noise, lpc, pcm, st->advance, st->lpc_order, st->noise_mem);
+ //iir_mem2(st->new_noise, lpc, pcm, st->advance, st->lpc_order, st->noise_mem);
+
+ for (i=0;i<st->advance;i++)
+ pcm[i] = st->current_frame[i]-st->new_noise[i];
+
}
}
Modified: trunk/ghost/libghost/ghost.h
===================================================================
--- trunk/ghost/libghost/ghost.h 2006-01-17 00:47:12 UTC (rev 10733)
+++ trunk/ghost/libghost/ghost.h 2006-01-17 01:29:28 UTC (rev 10734)
@@ -34,6 +34,7 @@
float *big_window;
float *syn_memory;
+ float *noise_mem;
float *noise_buf;
float *new_noise;
@@ -46,6 +47,7 @@
int lpc_order;
void *big_fft;
+ void *lpc_fft;
} GhostEncState;
GhostEncState *ghost_encoder_state_new(int sampling_rate);
More information about the commits
mailing list