From 959ad216c8a54e9b98db71b944fc64a6024aac6d Mon Sep 17 00:00:00 2001 From: drowe67 Date: Mon, 16 Aug 2010 03:43:29 +0000 Subject: [PATCH] LSP quantising working with simplified lsp.c routines, found nasty bug - un-initialised weighting vector wt git-svn-id: https://svn.code.sf.net/p/freetel/code@170 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2/src/lsp.c | 59 ++++++++++++++++++++++++--- codec2/src/lsp.h | 4 +- codec2/src/quantise.c | 94 ++++++++++--------------------------------- 3 files changed, 77 insertions(+), 80 deletions(-) diff --git a/codec2/src/lsp.c b/codec2/src/lsp.c index 3f223e0e..029a5c8a 100644 --- a/codec2/src/lsp.c +++ b/codec2/src/lsp.c @@ -11,11 +11,49 @@ \*---------------------------------------------------------------------------*/ +#include "defines.h" #include "lsp.h" #include #include #include +/*---------------------------------------------------------------------------*\ + + Introduction to Line Spectrum Pairs (LSPs) + ------------------------------------------ + + LSPs are used to encode the LPC filter coefficients {ak} for + transmission over the channel. LSPs have several properties (like + less sensitivity to quantisation noise) that make them superior to + direct quantisation of {ak}. + + A(z) is a polynomial of order lpcrdr with {ak} as the coefficients. + + A(z) is transformed to P(z) and Q(z) (using a substitution and some + algebra), to obtain something like: + + A(z) = 0.5[P(z)(z+z^-1) + Q(z)(z-z^-1)] (1) + + As you can imagine A(z) has complex zeros all over the z-plane. P(z) + and Q(z) have the very neat property of only having zeros _on_ the + unit circle. So to find them we take a test point z=exp(jw) and + evaluate P (exp(jw)) and Q(exp(jw)) using a grid of points between 0 + and pi. + + The zeros (roots) of P(z) also happen to alternate, which is why we + swap coefficients as we find roots. So the process of finding the + LSP frequencies is basically finding the roots of 5th order + polynomials. + + The root so P(z) and Q(z) occur in symmetrical pairs at +/-w, hence + the name Line Spectrum Pairs (LSPs). + + To convert back to ak we just evaluate (1), "clocking" an impulse + thru it lpcrdr times gives us the impulse response of A(z) which is + {ak}. + +\*---------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------*\ FUNCTION....: cheb_poly_eva() @@ -81,10 +119,10 @@ float cheb_poly_eva(float *coef,float x,int m) \*---------------------------------------------------------------------------*/ -int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta) +int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta) /* float *a lpc coefficients */ /* int lpcrdr order of LPC coefficients (10) */ -/* float *freq LSP frequencies in the x domain */ +/* float *freq LSP frequencies in radians */ /* int nb number of sub-intervals (4) */ /* float delta grid spacing interval (0.02) */ { @@ -107,7 +145,7 @@ int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta) if((Q = (float *) malloc((m+1)*sizeof(float))) == NULL){ printf("not enough memory to allocate buffer\n"); - exit(1); + exit(1); } if((P = (float *) malloc((m+1)*sizeof(float))) == NULL){ @@ -200,6 +238,12 @@ int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta) free(P); /* free memory space */ free(Q); + /* convert from x domain to radians */ + + for(i=0; i {Am} LPC decode */ - #ifdef CLICKY - /* Adding a random component to low energy harmonic phase seems to - improve low pitch speakers. Adding a small random component to - low energy harmonic amplitudes also helps low pitch speakers after - LPC modelling (see LPC modelling/amplitude quantisation code). - */ - - maxA = 0.0; - for(i=1; i<=model->L; i++) { - if (model->A[i] > maxA) { - maxA = model->A[i]; - } - } - for(i=1; i<=model->L; i++) { - if (model->A[i] < 0.1*maxA) { - dB = 3.0 - 6.0*(float)rand()/RAND_MAX; - model->A[i] *= pow(10.0, dB/20.0); - } - } - #endif - return snr; } -- 2.25.1