diff options
author | jmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800> | 2002-04-08 10:23:54 +0400 |
---|---|---|
committer | jmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800> | 2002-04-08 10:23:54 +0400 |
commit | f7e1127153d5daa3ea189c9fb801e37b35d5f3b1 (patch) | |
tree | 88e171cf744b005ae951fe8bc16879762886db7f /libspeex | |
parent | 4d1eaf158132f7c874da217e81f81020d7938080 (diff) |
Re-wrote the gain quantization for split-VQ excitation. Added more bits
and quantize one at a time.
git-svn-id: http://svn.xiph.org/trunk/speex@3223 0101bb08-14d6-0310-b084-bc0e0c8e3800
Diffstat (limited to 'libspeex')
-rw-r--r-- | libspeex/Makefile.am | 5 | ||||
-rw-r--r-- | libspeex/cb_search.c | 432 | ||||
-rw-r--r-- | libspeex/cb_search.h | 2 | ||||
-rw-r--r-- | libspeex/exc_sb_table.c | 128 | ||||
-rw-r--r-- | libspeex/modes.c | 22 | ||||
-rw-r--r-- | libspeex/mpulse.c | 62 | ||||
-rw-r--r-- | libspeex/mpulse.h | 2 | ||||
-rw-r--r-- | libspeex/sb_celp.c | 72 | ||||
-rw-r--r-- | libspeex/sb_celp.h | 4 | ||||
-rw-r--r-- | libspeex/speex.c | 7 |
10 files changed, 326 insertions, 410 deletions
diff --git a/libspeex/Makefile.am b/libspeex/Makefile.am index 810c796..d78dcdd 100644 --- a/libspeex/Makefile.am +++ b/libspeex/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in. -*-Makefile-*- -# $Id: Makefile.am,v 1.18 2002/04/02 22:58:12 jmvalin Exp $ +# $Id: Makefile.am,v 1.19 2002/04/08 06:23:54 jmvalin Exp $ # Disable automatic dependency tracking if using other tools than gcc and gmake #AUTOMAKE_OPTIONS = no-dependencies @@ -29,7 +29,8 @@ libspeex_la_SOURCES = speex.c \ exc_gains_wb2_table.c \ vq.c \ matrix.c \ - mpulse.c + mpulse.c \ + exc_sb_table.c include_HEADERS = speex.h \ diff --git a/libspeex/cb_search.c b/libspeex/cb_search.c index 7e43e41..d91b3be 100644 --- a/libspeex/cb_search.c +++ b/libspeex/cb_search.c @@ -38,7 +38,17 @@ #include "vq.h" #include "matrix.h" -extern float exc_gains_wb2_table[]; +static float scal_gains4[16] = { + 0.27713, + 0.49282, + 0.69570, + 0.90786, + 1.14235, + 1.42798, + 1.80756, + 2.42801 +}; + /*---------------------------------------------------------------------------*\ void overlap_cb_search() @@ -128,6 +138,7 @@ int nsf /* number of samples in subframe */ } + void split_cb_search( float target[], /* target vector */ float ak[], /* LPCs for this subframe */ @@ -143,11 +154,12 @@ float *stack { int i,j; float *resp, *E, *Ee; - float *t, *r, *e; + float *t, *r, *e, *tresp; float *gains; int *ind; - float *shape_cb, *gain_cb; - int shape_cb_size, gain_cb_size, subvect_size, nb_subvect; + float *shape_cb; + int shape_cb_size, subvect_size, nb_subvect; + float exc_energy=0; split_cb_params *params; params = (split_cb_params *) par; @@ -155,9 +167,8 @@ float *stack nb_subvect = params->nb_subvect; shape_cb_size = 1<<params->shape_bits; shape_cb = params->shape_cb; - gain_cb_size = 1<<params->gain_bits; - gain_cb = params->gain_cb; resp = PUSH(stack, shape_cb_size*subvect_size); + tresp = PUSH(stack, shape_cb_size*nsf); E = PUSH(stack, shape_cb_size); Ee = PUSH(stack, shape_cb_size); t = PUSH(stack, nsf); @@ -165,7 +176,25 @@ float *stack e = PUSH(stack, nsf); gains = PUSH(stack, nb_subvect); ind = (int*)PUSH(stack, nb_subvect); - + + syn_filt_zero(target, awk1, e, nsf, p); + residue_zero(e, ak, e, nsf, p); + residue_zero(e, awk2, e, nsf, p); + for (i=0;i<nsf;i++) + exc_energy += e[i]*e[i]; + exc_energy=sqrt(.125*exc_energy); + + /* Quantize global (average) gain */ + { + float q; + q=log(exc_energy+.1); + q=floor(.5+2*(q-2)); + if (q<0) + q=0; + if (q>15) + q=15; + exc_energy=exp(.5*q+2); + } for (i=0;i<nsf;i++) t[i]=target[i]; @@ -183,6 +212,7 @@ float *stack Ee[i]+=shape_cb[i*subvect_size+j]*shape_cb[i*subvect_size+j]; } + for (i=0;i<nb_subvect;i++) { int best_index=0; @@ -199,259 +229,32 @@ float *stack best_gain=corr/(.001+E[j]); } } - frame_bits_pack(bits,best_index,params->shape_bits); - if (best_gain>0) - frame_bits_pack(bits,0,1); - else - frame_bits_pack(bits,1,1); - ind[i]=best_index; - gains[i]=best_gain*Ee[ind[i]]; - - for (j=0;j<nsf;j++) - e[j]=0; - for (j=0;j<subvect_size;j++) - e[subvect_size*i+j]=best_gain*shape_cb[best_index*subvect_size+j]; - residue_zero(e, awk1, r, nsf, p); - syn_filt_zero(r, ak, r, nsf, p); - syn_filt_zero(r, awk2, r, nsf,p); - for (j=0;j<nsf;j++) - t[j]-=r[j]; - } - - { - int best_vq_index=0, max_index; - float max_gain=0, log_max, min_dist=0, *sign; - - if (gain_cb) /*If no gain codebook, do not quantize (for testing/debugging) */ { - sign = PUSH(stack, nb_subvect); - for (i=0;i<nb_subvect;i++) + int s=0, best_id, j; + float best_dist; + best_gain /= .01+exc_energy; + if (best_gain<0) { - if (gains[i]<0) - { - gains[i]=-gains[i]; - sign[i]=-1; - } else { - sign[i]=1; - } + best_gain=-best_gain; + s=1; } - for (i=0;i<nb_subvect;i++) - if (gains[i]>max_gain) - max_gain=gains[i]; - log_max=log(max_gain+1); - max_index = (int)(floor(.5+log_max-3)); - if (max_index>7) - max_index=7; - if (max_index<0) - max_index=0; - max_gain=1/exp(max_index+3.0); - for (i=0;i<nb_subvect;i++) - gains[i]*=max_gain; - frame_bits_pack(bits,max_index,3); - - /*Vector quantize gains[i]*/ - if (nb_subvect<=5) + best_dist=(best_gain-scal_gains4[0])*(best_gain-scal_gains4[0]); + best_id=0; + for (j=1;j<8;j++) { - best_vq_index = vq_index(gains, gain_cb, nb_subvect, gain_cb_size); - frame_bits_pack(bits,best_vq_index,params->gain_bits); - printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index); - for (i=0;i<nb_subvect;i++) - gains[i]= sign[i]*gain_cb[best_vq_index*nb_subvect+i]/max_gain/(Ee[ind[i]]+.001); - } else - { - float tmp[5]; - int best_vq_index2; - best_vq_index = vq_index(gains, gain_cb, nb_subvect/2, gain_cb_size); - for (i=0;i<5;i++) - tmp[i]=gains[i]-gain_cb[best_vq_index*nb_subvect/2+i]; - best_vq_index2 = vq_index(tmp, exc_gains_wb2_table, nb_subvect/2, 256); - - frame_bits_pack(bits,best_vq_index,params->gain_bits); - printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index); - for (i=0;i<nb_subvect/2;i++) - gains[i]= sign[i]*(gain_cb[best_vq_index*nb_subvect/2+i]+exc_gains_wb2_table[best_vq_index2*nb_subvect/2+i])/max_gain/(Ee[ind[i]]+.001); - - - best_vq_index = vq_index(gains+5, gain_cb, nb_subvect/2, gain_cb_size); - frame_bits_pack(bits,best_vq_index,params->gain_bits); - for (i=0;i<5;i++) - tmp[i]=gains[i+5]-gain_cb[best_vq_index*nb_subvect/2+i]; - best_vq_index2 = vq_index(tmp, exc_gains_wb2_table, nb_subvect/2, 256); - - printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index); - for (i=0;i<nb_subvect/2;i++) - gains[i+5]= sign[i+5]*(gain_cb[best_vq_index*nb_subvect/2+i]+exc_gains_wb2_table[best_vq_index2*nb_subvect/2+i])/max_gain/(Ee[ind[i+5]]+.001); - } - - - - POP(stack); - } else { - printf ("exc: "); - for (i=0;i<nb_subvect;i++) - printf ("%f ", gains[i]); - printf ("\n"); - for (i=0;i<nb_subvect;i++) - gains[i]= gains[i]/(Ee[ind[i]]+.001); - } - - for (i=0;i<nb_subvect;i++) - for (j=0;j<subvect_size;j++) - exc[subvect_size*i+j]+=gains[i]*shape_cb[ind[i]*subvect_size+j]; - - } - - /*TODO: Perform joint optimization of gains*/ - - for (i=0;i<nsf;i++) - target[i]=t[i]; - - POP(stack); - POP(stack); - POP(stack); - POP(stack); - POP(stack); - POP(stack); - POP(stack); - POP(stack); -} - - - - -void split_cb_search_wb( -float target[], /* target vector */ -float ak[], /* LPCs for this subframe */ -float awk1[], /* Weighted LPCs for this subframe */ -float awk2[], /* Weighted LPCs for this subframe */ -void *par, /* Codebook/search parameters*/ -int p, /* number of LPC coeffs */ -int nsf, /* number of samples in subframe */ -float *exc, -FrameBits *bits, -float *stack -) -{ - int i,j; - float *resp, *E, *Ee; - float *t, *r, *e, *tresp; - float *gains; - int *ind; - float *shape_cb, *gain_cb; - int shape_cb_size, gain_cb_size, subvect_size, nb_subvect; - split_cb_params *params; - - params = (split_cb_params *) par; - subvect_size = params->subvect_size; - nb_subvect = params->nb_subvect; - shape_cb_size = 1<<params->shape_bits; - shape_cb = params->shape_cb; - gain_cb_size = 1<<params->gain_bits; - gain_cb = params->gain_cb; - resp = PUSH(stack, shape_cb_size*subvect_size); - tresp = PUSH(stack, shape_cb_size*nsf); - E = PUSH(stack, shape_cb_size); - Ee = PUSH(stack, shape_cb_size); - t = PUSH(stack, nsf); - r = PUSH(stack, nsf); - e = PUSH(stack, nsf); - gains = PUSH(stack, nb_subvect); - ind = (int*)PUSH(stack, nb_subvect); - - - for (i=0;i<nsf;i++) - t[i]=target[i]; - for (i=0;i<shape_cb_size;i++) - { - float *res = resp+i*subvect_size; - residue_zero(shape_cb+i*subvect_size, awk1, res, subvect_size, p); - syn_filt_zero(res, ak, res, subvect_size, p); - syn_filt_zero(res, awk2, res, subvect_size,p); - E[i]=0; - for(j=0;j<subvect_size;j++) - E[i]+=res[j]*res[j]; - Ee[i]=0; - for(j=0;j<subvect_size;j++) - Ee[i]+=shape_cb[i*subvect_size+j]*shape_cb[i*subvect_size+j]; - - } -#if 0 - { - int half,k; - for (half=0;half<2;half++) - { - int nb_half=nb_subvect/2; - int max_subvect=0; - float max_energy=0; - syn_filt_zero(t+half*nsf/2, awk1, r, nsf/2, p); - residue_zero(r, ak, r, nsf/2, p); - residue_zero(r, awk2, r, nsf/2,p); - for (i=0;i<nb_half;i++) - { - float energy=0; - for (k=0;k<subvect_size;k++) - energy+=r[subvect_size*i+k]*r[subvect_size*i+k]; - if (energy>max_energy) - { - max_subvect=i; - max_energy=energy; - } - } - printf ("max_energy: %d %f\n", max_subvect, max_energy); - - for (i=0;i<nb_half;i++) - { - int nb_times=1; - if (i==max_subvect) - nb_times++; - - for (k=0;k<nb_times;k++) - { - int best_index=0; - float g, corr, best_gain=0, score, best_score=-1; - for (j=0;j<shape_cb_size;j++) - { - corr=xcorr(resp+j*subvect_size,t+subvect_size*(i+half*nb_half),subvect_size); - score=corr*corr/(.001+E[j]); - g = corr/(.001+E[j]); - if (score>best_score) + float dist; + dist=(best_gain-scal_gains4[j])*(best_gain-scal_gains4[j]); + if (dist<best_dist) { - best_index=j; - best_score=score; - best_gain=corr/(.001+E[j]); + best_id=j; + best_dist=dist; } } - for (j=0;j<nsf;j++) - e[j]=0; - for (j=0;j<subvect_size;j++) - e[subvect_size*(i+half*nb_half)+j]=best_gain*shape_cb[best_index*subvect_size+j]; - residue_zero(e, awk1, r, nsf, p); - syn_filt_zero(r, ak, r, nsf, p); - syn_filt_zero(r, awk2, r, nsf,p); - for (j=0;j<nsf;j++) - t[j]-=r[j]; - for (j=0;j<nsf;j++) - exc[j]+=e[j]; - } - } - } - } -#else - for (i=0;i<nb_subvect;i++) - { - int best_index=0; - float g, corr, best_gain=0, score, best_score=-1; - for (j=0;j<shape_cb_size;j++) - { - corr=xcorr(resp+j*subvect_size,t+subvect_size*i,subvect_size); - score=corr*corr/(.001+E[j]); - g = corr/(.001+E[j]); - if (score>best_score) - { - best_index=j; - best_score=score; - best_gain=corr/(.001+E[j]); - } + best_gain=scal_gains4[best_id]; + printf ("gain_quant: %f %d %f\n", best_gain, best_id, scal_gains4[best_id]); + if (s) + best_gain=-best_gain; + best_gain *= exc_energy; } frame_bits_pack(bits,best_index,params->shape_bits); if (best_gain>0) @@ -476,101 +279,11 @@ float *stack exc[j]+=e[j];*/ } { - float A[10][10]; - float b[10]; - float c[10]; - for (i=0;i<10;i++) - for (j=0;j<10;j++) - A[i][j]=xcorr(tresp+i*nsf, tresp+j*nsf, nsf); - for (i=0;i<10;i++) - b[i]=xcorr(target,tresp+i*nsf,nsf); - for (i=0;i<10;i++) - A[i][i]+=.01; - - - solve(&A[0][0],b,c, 10); - for (i=0;i<10;i++) - gains[i]*=c[i]; - - for (i=0;i<10;i++) - gains[i]*=Ee[ind[i]]; - - - - { - int best_vq_index=0, max_index; - float max_gain=0, log_max, min_dist=0, *sign; - - if (gain_cb) /*If no gain codebook, do not quantize (for testing/debugging) */ - { - sign = PUSH(stack, nb_subvect); - for (i=0;i<nb_subvect;i++) - { - if (gains[i]<0) - { - gains[i]=-gains[i]; - sign[i]=-1; - } else { - sign[i]=1; - } - } - for (i=0;i<nb_subvect;i++) - if (gains[i]>max_gain) - max_gain=gains[i]; - log_max=log(max_gain+1); - max_index = (int)(floor(.5+log_max-3)); - if (max_index>7) - max_index=7; - if (max_index<0) - max_index=0; - max_gain=1/exp(max_index+3.0); - for (i=0;i<nb_subvect;i++) - gains[i]*=max_gain; - frame_bits_pack(bits,max_index,3); - - /*Vector quantize gains[i]*/ - if (nb_subvect<=5) - { - best_vq_index = vq_index(gains, gain_cb, nb_subvect, gain_cb_size); - frame_bits_pack(bits,best_vq_index,params->gain_bits); - printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index); + printf ("exc_gains"); for (i=0;i<nb_subvect;i++) - gains[i]= sign[i]*gain_cb[best_vq_index*nb_subvect+i]/max_gain/(Ee[ind[i]]+.001); - } else - { - float tmp[5]; - int best_vq_index2; - best_vq_index = vq_index(gains, gain_cb, nb_subvect/2, gain_cb_size); - for (i=0;i<5;i++) - tmp[i]=gains[i]-gain_cb[best_vq_index*nb_subvect/2+i]; - best_vq_index2 = vq_index(tmp, exc_gains_wb2_table, nb_subvect/2, 256); - - frame_bits_pack(bits,best_vq_index,params->gain_bits); - printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index); - for (i=0;i<nb_subvect/2;i++) - gains[i]= sign[i]*(gain_cb[best_vq_index*nb_subvect/2+i]+exc_gains_wb2_table[best_vq_index2*nb_subvect/2+i])/max_gain/(Ee[ind[i]]+.001); - - - best_vq_index = vq_index(gains+5, gain_cb, nb_subvect/2, gain_cb_size); - frame_bits_pack(bits,best_vq_index,params->gain_bits); - for (i=0;i<5;i++) - tmp[i]=gains[i+5]-gain_cb[best_vq_index*nb_subvect/2+i]; - best_vq_index2 = vq_index(tmp, exc_gains_wb2_table, nb_subvect/2, 256); - - printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index); - for (i=0;i<nb_subvect/2;i++) - gains[i+5]= sign[i+5]*(gain_cb[best_vq_index*nb_subvect/2+i]+exc_gains_wb2_table[best_vq_index2*nb_subvect/2+i])/max_gain/(Ee[ind[i+5]]+.001); - } - - - } else { - - for (i=0;i<10;i++) - gains[i]/=Ee[ind[i]]+.001; - - } - } - for (i=0;i<10;i++) + printf (" %f", gains[i]/(.01f+exc_energy)); + printf ("\n"); + for (i=0;i<nb_subvect;i++) for (j=0;j<subvect_size;j++) e[subvect_size*i+j]=gains[i]*shape_cb[ind[i]*subvect_size+j]; @@ -583,13 +296,8 @@ float *stack target[j]-=r[j]; } -#endif - /*TODO: Perform joint optimization of gains*/ - - /*for (i=0;i<nsf;i++) - target[i]=t[i]; - */ + POP(stack); POP(stack); POP(stack); @@ -617,8 +325,8 @@ float *stack float *sign; int max_gain_ind, vq_gain_ind; float max_gain, *Ee; - float *shape_cb, *gain_cb; - int shape_cb_size, gain_cb_size, subvect_size, nb_subvect; + float *shape_cb; + int shape_cb_size, subvect_size, nb_subvect; split_cb_params *params; params = (split_cb_params *) par; @@ -626,8 +334,6 @@ float *stack nb_subvect = params->nb_subvect; shape_cb_size = 1<<params->shape_bits; shape_cb = params->shape_cb; - gain_cb_size = 1<<params->gain_bits; - gain_cb = params->gain_cb; ind = (int*)PUSH(stack, nb_subvect); gains = PUSH(stack, nb_subvect); @@ -645,18 +351,10 @@ float *stack for (j=0;j<subvect_size;j++) Ee[i]+=shape_cb[ind[i]*subvect_size+j]*shape_cb[ind[i]*subvect_size+j]; } - max_gain_ind = frame_bits_unpack_unsigned(bits, 3); - vq_gain_ind = frame_bits_unpack_unsigned(bits, params->gain_bits); - printf ("unquant gains ind: %d %d\n", max_gain_ind, vq_gain_ind); - max_gain=exp(max_gain_ind+3.0); - for (i=0;i<nb_subvect;i++) - gains[i] = sign[i]*gain_cb[vq_gain_ind*nb_subvect+i]*max_gain/Ee[i]; - - printf ("unquant gains: "); + /*FIXME: Gain quantization changed, need to re-write that part */ for (i=0;i<nb_subvect;i++) - printf ("%f ", gains[i]); - printf ("\n"); + gains[i]=0; for (i=0;i<nb_subvect;i++) for (j=0;j<subvect_size;j++) diff --git a/libspeex/cb_search.h b/libspeex/cb_search.h index 3e702ae..94e167a 100644 --- a/libspeex/cb_search.h +++ b/libspeex/cb_search.h @@ -27,8 +27,6 @@ typedef struct split_cb_params { int nb_subvect; float *shape_cb; int shape_bits; - float *gain_cb; - int gain_bits; } split_cb_params; float overlap_cb_search( diff --git a/libspeex/exc_sb_table.c b/libspeex/exc_sb_table.c new file mode 100644 index 0000000..f332203 --- /dev/null +++ b/libspeex/exc_sb_table.c @@ -0,0 +1,128 @@ +float exc_sb_table[128][5]={{-0.102624,-0.054111,-0.150332,0.925474,-0.073627}, +{0.0334537,0.427829,0.534788,-0.188438,0.604833}, +{0.139761,0.666278,0.0654791,0.629374,-0.0485821}, +{0.381103,-0.348657,-0.223198,0.754575,-0.162999}, +{0.139871,-0.65616,0.567975,0.365822,0.0199881}, +{0.238787,-0.663805,0.412313,-0.011008,0.504689}, +{-0.255037,-0.268362,0.337979,0.00543153,0.800096}, +{0.0157631,0.0546008,-0.587497,0.43831,0.602686}, +{0.266576,0.454332,-0.287143,0.543867,0.4675}, +{0.539929,-0.211438,0.544636,-0.19762,0.497794}, +{0.790626,0.281386,-0.434619,0.0150189,0.0396688}, +{0.537489,-0.697916,0.358457,0.137981,0.0744294}, +{-0.171602,0.661162,0.530261,-0.141799,-0.34708}, +{0.550564,-0.357929,0.47943,-0.486588,0.234207}, +{-0.522763,0.70251,-0.180435,0.0110766,0.34005}, +{0.290646,-0.486299,-0.0267554,0.0195369,0.765342}, +{-0.510804,0.543264,-0.0113427,0.559072,-0.214979}, +{-0.054281,0.296506,0.227583,-0.663565,0.585474}, +{0.281311,0.410409,-0.589923,0.514236,-0.24451}, +{0.352187,-0.681431,0.0409394,0.529577,0.180429}, +{0.335686,0.152943,0.340562,0.350725,-0.716269}, +{-0.184544,-0.493059,0.709312,0.0789398,0.333809}, +{0.36807,0.398848,0.439442,0.469874,0.426293}, +{-0.074492,-0.067026,-0.220689,0.0949041,0.911539}, +{-0.0244626,0.599877,-0.664436,0.337101,0.102803}, +{0.507241,0.299874,0.67683,-0.183245,0.1731}, +{-0.158717,0.687196,0.0106936,-0.49428,0.40757}, +{0.18848,-0.206213,0.859075,-0.0790016,-0.271342}, +{-0.481602,0.268191,0.761241,-0.0182754,-0.102577}, +{0.654972,-0.254684,-0.0536777,-0.326449,0.566277}, +{-0.311018,0.468055,-0.518803,0.260996,0.508674}, +{0.409175,-0.0381644,-0.507158,-0.00951909,0.694244}, +{-0.246701,0.0131884,0.376172,0.718583,-0.416487}, +{-0.483561,0.409034,0.162806,-0.293085,0.631156}, +{0.158998,0.813405,-0.0109502,0.0180112,-0.445918}, +{0.705327,-0.410767,-0.241706,0.433087,-0.00413281}, +{0.600455,-0.479235,0.23816,0.379886,-0.3432}, +{0.301259,-0.582477,0.700397,-0.0832768,0.0474716}, +{-0.281273,-0.426036,0.296623,0.708078,0.198903}, +{0.405234,0.466206,-0.612542,-0.124835,0.369165}, +{-0.211322,0.835041,-0.341256,0.212979,-0.112143}, +{0.00691859,0.220931,0.802972,-0.420141,-0.163715}, +{0.665906,0.121232,-0.357705,-0.342484,0.451004}, +{0.659969,-0.509186,-0.178865,0.147746,0.408789}, +{-0.52733,0.627687,0.394084,-0.203386,0.184659}, +{0.561308,-0.582705,0.43265,-0.259265,0.219455}, +{-0.478271,0.78833,0.1123,0.166179,-0.128496}, +{0.257733,0.0106463,0.364816,-0.0231152,0.831136}, +{-0.206288,0.304049,-0.176448,0.781093,-0.380172}, +{-0.282692,0.0171014,0.501923,-0.470113,0.608837}, +{0.640325,0.422174,-0.139084,0.14123,-0.503401}, +{0.278649,-0.375512,-0.352527,0.432341,0.606905}, +{-0.259996,-0.24862,0.754151,0.402793,-0.161873}, +{0.176409,-0.37323,0.272941,-0.332164,0.760739}, +{0.219157,0.591943,0.619522,0.281972,-0.111015}, +{0.355112,0.0542548,0.0346132,-0.572545,0.682399}, +{0.302553,-0.0692851,-0.581226,0.676379,0.140197}, +{0.158078,0.634064,0.347225,-0.569978,-0.118974}, +{0.233516,0.790668,-0.266387,-0.37779,0.0894651}, +{0.88696,0.0427845,0.0771191,-0.275171,-0.177864}, +{-0.20828,0.401446,0.661027,0.416781,0.244633}, +{0.444848,-0.0251255,0.339661,-0.659061,0.42588}, +{-0.392048,0.144615,-0.28817,0.665781,0.441333}, +{0.664287,0.0737455,-0.54894,0.376551,-0.144804}, +{-0.564502,0.128396,0.0865737,0.728833,0.120127}, +{-0.57034,0.0979681,0.585372,-0.0564536,0.460319}, +{-0.168581,0.587204,0.220691,0.365764,-0.58274}, +{0.559779,-0.0715092,-0.152879,0.567635,-0.49618}, +{0.114242,-0.456576,0.288872,0.736407,-0.231899}, +{0.00837993,-0.595792,0.218303,0.425367,0.55763}, +{-0.331547,-0.329078,-0.0551475,0.490597,0.661246}, +{0.0816829,0.304182,-0.544833,-0.0409868,0.719706}, +{0.344068,0.274524,-0.736783,0.315036,0.275653}, +{0.228404,-0.315749,0.768149,-0.422216,0.106815}, +{0.662165,0.486676,-0.276654,-0.386017,0.0209953}, +{0.80392,-0.513347,0.138384,0.0246297,-0.0146162}, +{0.301751,0.449556,0.488575,-0.163447,-0.571901}, +{0.781474,-0.371342,0.196756,-0.318678,0.22194}, +{-0.726348,0.441955,0.208678,0.257971,0.249602}, +{0.589172,-0.58137,0.177834,-0.0952224,0.457552}, +{-0.457955,0.582895,-0.357162,0.486044,0.0770756}, +{0.0950343,-0.109581,0.345219,-0.587601,0.677624}, +{0.19224,0.115768,-0.408221,0.771759,-0.332153}, +{0.517119,-0.256665,0.185316,0.643863,0.309937}, +{0.540099,0.105316,0.53074,0.490803,-0.210116}, +{0.249416,-0.140204,0.725332,0.3115,0.40436}, +{-0.151338,0.655717,0.0959581,0.334807,0.543585}, +{-0.11283,0.0734222,0.0532614,-0.370352,0.872759}, +{-0.125588,0.314843,-0.574553,0.687819,0.0452927}, +{0.538183,0.031037,0.541285,-0.550722,-0.120951}, +{0.153766,0.427132,-0.291862,-0.49462,0.613839}, +{0.652598,-0.0458756,0.463965,-0.0682286,-0.493205}, +{-0.531497,0.318335,0.53472,0.409559,-0.237859}, +{0.48061,-0.422219,0.294698,-0.43837,0.517025}, +{-0.103654,0.744761,-0.474463,-0.0720102,0.340483}, +{0.628206,-0.13234,-0.545444,0.258424,0.366585}, +{0.148394,-0.0425618,0.0865729,0.759242,-0.544229}, +{-0.260555,0.434974,-0.259427,-0.205655,0.740156}, +{0.60187,0.540709,0.113835,-0.315797,-0.351679}, +{0.849773,-0.142091,-0.0420795,0.211852,-0.34112}, +{0.277191,-0.376379,0.613516,0.320655,-0.451303}, +{0.636778,-0.429747,0.529245,-0.187377,-0.141152}, +{-0.580468,-0.11628,0.481246,0.428717,0.340724}, +{0.402818,0.52967,-0.0272272,-0.0541325,0.655869}, +{0.324038,0.710271,-0.503013,0.131347,-0.125574}, +{-0.220883,-0.103133,0.882013,-0.207169,0.146864}, +{0.766691,0.0705879,0.0825369,-0.502545,0.228221}, +{0.895274,-0.197354,-0.234603,-0.0232927,0.131917}, +{-0.257596,0.412843,0.566726,-0.544417,0.226161}, +{0.296013,-0.541693,0.559311,-0.348357,0.375752}, +{-0.255127,0.882802,0.0156524,-0.25512,0.0153832}, +{0.668598,0.0427881,-0.000316741,0.194706,0.627481}, +{-0.150822,0.60525,-0.383042,0.535514,-0.329319}, +{0.0835202,0.0230119,0.619825,-0.662472,0.304508}, +{0.228531,0.43578,-0.163453,0.526958,-0.600919}, +{-0.024975,0.0622987,0.21989,0.57448,0.702719}, +{-0.0771633,0.170254,0.718226,0.226328,-0.532113}, +{-0.031851,-0.316799,0.649984,-0.375654,0.513181}, +{0.720653,0.52339,0.203987,0.167927,0.0998602}, +{0.22968,-0.101649,-0.158635,-0.324444,0.853797}, +{0.0138676,-0.311507,-0.253608,0.790742,0.326826}, +{0.404968,0.458736,0.124864,-0.662365,0.25065}, +{0.247051,0.851768,0.234943,-0.0360821,0.174313}, +{0.820181,-0.142236,0.401901,0.092983,0.171547}, +{-0.0234138,0.102285,0.470282,0.792313,0.112344}, +{0.276176,-0.323481,0.500884,-0.559456,0.4644}, +{-0.535225,0.156369,-0.0102809,0.197816,0.733569}, +{0.609358,0.217827,-0.0926352,0.661177,0.0951336}}; diff --git a/libspeex/modes.c b/libspeex/modes.c index fa0cc38..e6cb418 100644 --- a/libspeex/modes.c +++ b/libspeex/modes.c @@ -32,6 +32,7 @@ extern float exc_gains_table[]; extern float exc_table[]; extern float exc_wb_table[]; extern float exc_gains_wb_table[]; +extern float exc_sb_table[]; ltp_params ltp_params_nb = { gain_cdbk_nb, 7, @@ -49,8 +50,13 @@ split_cb_params split_cb_nb = { 5, /*nb_subvect*/ exc_table, /*shape_cb*/ 7, /*shape_bits*/ - exc_gains_table, /*gain_cb*/ - 8 /*gain_bits*/ +}; + +split_cb_params split_cb_sb = { + 5, /*subvect_size*/ + 8, /*nb_subvect*/ + exc_sb_table, /*shape_cb*/ + 7, /*shape_bits*/ }; split_cb_params split_cb_wb = { @@ -58,8 +64,6 @@ split_cb_params split_cb_wb = { 10, /*nb_subvect*/ exc_wb_table, /*shape_cb*/ 7, /*shape_bits*/ - exc_gains_wb_table, /*gain_cb*/ - 8 /*gain_bits*/ }; mpulse_params mpulse_nb = { @@ -160,7 +164,7 @@ SpeexMode wb_mode = { pitch_unquant_3tap, <p_params_wb, /*Innovation quantization*/ - split_cb_search_wb, + split_cb_search, split_cb_unquant, &split_cb_wb }; @@ -202,7 +206,7 @@ SpeexMode mp_sb_mode = { 17, /*pitchStart*/ 144, /*pitchEnd*/ 0.9, /*gamma1*/ - 0.4, /*gamma2*/ + 0.6, /*gamma2*/ .002, /*lag_factor*/ 1.0001, /*lpc_floor*/ 0.0, /*preemph*/ @@ -214,7 +218,13 @@ SpeexMode mp_sb_mode = { pitch_unquant_3tap, <p_params_nb, /*Innovation quantization*/ +#if 1 + split_cb_search, + split_cb_unquant, + &split_cb_sb +#else mpulse_search, mpulse_unquant, &mpulse_sb +#endif }; diff --git a/libspeex/mpulse.c b/libspeex/mpulse.c index 80ba16e..689e364 100644 --- a/libspeex/mpulse.c +++ b/libspeex/mpulse.c @@ -26,7 +26,7 @@ #include "filters.h" #include <math.h> -#define MAX_PULSE 30 +#define MAX_PULSE 60 #define MAX_POS 100 int porder(int *p, int *s, int *o, int len) @@ -216,7 +216,7 @@ float *stack int i,j, nb_pulse; float *resp, *resp2, *energy, *t, *e, *pulses; float te=0,ee=0; - float g; + float g, gain_coef; int nb_tracks, track_ind_bits; int *tracks, *signs, *tr, *nb; mpulse_params *params; @@ -227,6 +227,7 @@ float *stack nb_tracks=params->nb_tracks; pulses_per_track=nb_pulse/nb_tracks; track_ind_bits=params->track_ind_bits; + gain_coef=params->gain_coef; tracks = (int*)PUSH(stack,nb_pulse); signs = (int*)PUSH(stack,nb_pulse); @@ -251,7 +252,7 @@ float *stack ee+=e[i]*e[i]; } /*Compute global gain (coef found from linear regression and tweaking)*/ - g=2.2/sqrt(nb_pulse)*exp(0.18163*log(te+1)+0.17293*log(ee+1)); + g=gain_coef/sqrt(nb_pulse)*exp(0.18163*log(te+1)+0.17293*log(ee+1)); e[0]=1; for (i=1;i<nsf;i++) @@ -291,37 +292,43 @@ float *stack float dist; float *base=t+j; /*Fill any track until it's full*/ - /*if (nb[j%nb_tracks]==pulses_per_track) - continue;*/ + if (nb[j%nb_tracks]==pulses_per_track) + continue; /*Constrain search in alternating tracks*/ /*FIXME: Should get rid of this, it's *really* slow*/ - if ((i%nb_tracks) != (j%nb_tracks)) - continue; + /*if ((i%nb_tracks) != (j%nb_tracks)) + continue;*/ /*Try for positive sign*/ - dist=energy[j]; - for (k=0;k<nsf-j;k++) - { - float tmp=(base[k]-resp2[k]); - dist+=tmp*tmp; - } - if (dist<best_score || j==0) + if (pulses[j]>=0) { - best_score=dist; - best_gain=g; - best_ind=j; + dist=energy[j]; + for (k=0;k<nsf-j;k++) + { + float tmp=(base[k]-resp2[k]); + dist+=tmp*tmp; + } + if (dist<best_score || j==0) + { + best_score=dist; + best_gain=g; + best_ind=j; + } } /*Try again for negative sign*/ - dist=energy[j]; - for (k=0;k<nsf-j;k++) + if (pulses[j]<=0) { - float tmp=(base[k]+resp2[k]); - dist+=tmp*tmp; - } - if (dist<best_score || j==0) - { - best_score=dist; - best_gain=-g; - best_ind=j; + dist=energy[j]; + for (k=0;k<nsf-j;k++) + { + float tmp=(base[k]+resp2[k]); + dist+=tmp*tmp; + } + if (dist<best_score) + { + best_score=dist; + best_gain=-g; + best_ind=j; + } } } #ifdef DEBUG @@ -352,6 +359,7 @@ float *stack syn_filt_zero(resp, awk2, resp, nsf, p); f=((.1+(xcorr(resp,target,nsf)))/(.1+xcorr(resp,resp,nsf))); + printf ("gain correction %f\n", f); /*for (i=0;i<nsf;i++) e[i]*=f;*/ g *= f; diff --git a/libspeex/mpulse.h b/libspeex/mpulse.h index 881e705..9075350 100644 --- a/libspeex/mpulse.h +++ b/libspeex/mpulse.h @@ -27,7 +27,7 @@ typedef struct mpulse_params { int nb_pulse; int nb_tracks; - int gain_coef; + float gain_coef; int track_ind_bits; } mpulse_params; diff --git a/libspeex/sb_celp.c b/libspeex/sb_celp.c index 629241d..4b00a89 100644 --- a/libspeex/sb_celp.c +++ b/libspeex/sb_celp.c @@ -182,6 +182,7 @@ void sb_encoder_init(SBEncState *st, SpeexMode *mode) st->buf=calloc(st->windowSize, sizeof(float)); st->excBuf=calloc(2*st->frame_size, sizeof(float)); st->exc=st->excBuf+st->frame_size; + st->exc_alias=calloc(st->frame_size, sizeof(float)); st->res=calloc(st->frame_size, sizeof(float)); st->sw=calloc(st->frame_size, sizeof(float)); @@ -190,6 +191,10 @@ void sb_encoder_init(SBEncState *st, SpeexMode *mode) for (i=0;i<st->windowSize;i++) st->window[i]=.5*(1-cos(2*M_PI*i/st->windowSize)); + st->exc_window=calloc(st->frame_size, sizeof(float)); + for (i=0;i<st->frame_size;i++) + st->exc_window[i]=.5*(1-cos(2*M_PI*i/st->frame_size)); + st->lagWindow = malloc((st->lpcSize+1)*sizeof(float)); for (i=0;i<st->lpcSize+1;i++) st->lagWindow[i]=exp(-.5*sqr(2*M_PI*st->lag_factor*i)); @@ -209,7 +214,9 @@ void sb_encoder_init(SBEncState *st, SpeexMode *mode) st->interp_qlpc = malloc((st->lpcSize+1)*sizeof(float)); st->mem_sp = calloc(st->lpcSize, sizeof(float)); + st->mem_sp2 = calloc(st->lpcSize, sizeof(float)); st->mem_sw = calloc(st->lpcSize, sizeof(float)); + st->mem_exc = calloc(st->lpcSize, sizeof(float)); } @@ -306,6 +313,30 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits) exit(1); } + { + for (i=0;i<st->frame_size;i++) + st->buf[i] = st->st_low.exc[i] * st->exc_window[i]; + + /* Compute auto-correlation */ + autocorr(st->buf, st->autocorr, st->lpcSize+1, st->frame_size); + + st->autocorr[0] += 1; /* prevents NANs */ + st->autocorr[0] *= st->lpc_floor; /* Noise floor in auto-correlation domain */ + /* Lag windowing: equivalent to filtering in the power-spectrum domain */ + for (i=0;i<st->lpcSize+1;i++) + st->autocorr[i] *= st->lagWindow[i]; + + /* Levinson-Durbin */ + wld(st->lpc+1, st->autocorr, st->rc, st->lpcSize); + st->lpc[0]=1; + printf ("exc_lpc: "); + for(i=0;i<=st->lpcSize;i++) + printf ("%f ", st->lpc[i]); + printf ("\n"); + residue_mem(st->st_low.exc, st->lpc, st->exc_alias, st->frame_size, st->lpcSize, st->mem_exc); + } + + /* x-domain to angle domain*/ for (i=0;i<st->lpcSize;i++) st->lsp[i] = acos(st->lsp[i]); @@ -353,20 +384,32 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits) bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); -#if 1 /* 1 for spectral folding excitation, 0 for stochastic */ +#if 0 /* 1 for spectral folding excitation, 0 for stochastic */ for (i=0;i<st->lpcSize;i++) mem[i]=st->mem_sp[i]; residue_mem(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp); { float el=0,eh=0,g; + printf ("exca"); + for (i=0;i<st->subframeSize;i++) + printf (" %f", exc[i]); + printf ("\n"); for (i=0;i<st->subframeSize;i++) eh+=sqr(exc[i]); + /*for (i=0;i<st->subframeSize;i++) + el+=sqr(st->exc_alias[offset+i]);*/ for (i=0;i<st->subframeSize;i++) - el+=sqr(st->st_low.exc[offset+i]); + el+=sqr(st->st_low.exc[offset+i]); g=eh/(.01+el); g=sqrt(g); for (i=0;i<st->subframeSize;i++) - exc[i]=g*st->st_low.exc[offset+i]; + exc[i]=g*st->st_low.exc[offset+i]; + /*for (i=0;i<st->subframeSize;i++) + exc[i]=g*st->exc_alias[offset+i];*/ + printf ("excb"); + for (i=0;i<st->subframeSize;i++) + printf (" %f", exc[i]); + printf ("\n"); } syn_filt_mem(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, mem); @@ -401,13 +444,31 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits) int ind; float gain; #if 0 + + float el=0,eh=0,g; + residue_mem(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2); + + for (i=0;i<st->subframeSize;i++) + eh+=sqr(exc[i]); overlap_cb_search(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, &stoc[0], 512, &gain, &ind, st->lpcSize, st->subframeSize); for (i=0;i<st->subframeSize;i++) exc[i]=gain*stoc[ind+i]; + for (i=0;i<st->subframeSize;i++) + el+=sqr(exc[i]); + g=sqrt(eh/(el+.001)); + for (i=0;i<st->subframeSize;i++) + exc[i]*=g; + #else int k,N=2; + float el=0,eh=0,g; + residue_mem(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2); + + for (i=0;i<st->subframeSize;i++) + eh+=sqr(exc[i]); + for (i=0;i<st->subframeSize;i++) exc[i]=0; for (k=0;k<N;k++) @@ -428,6 +489,11 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits) for (i=0;i<st->subframeSize/N;i++) exc[of+i]+=gain*stoc[ind+i]; } + for (i=0;i<st->subframeSize;i++) + el+=sqr(exc[i]); + g=sqrt(eh/(el+.001)); + for (i=0;i<st->subframeSize;i++) + exc[i]*=g; #endif } diff --git a/libspeex/sb_celp.h b/libspeex/sb_celp.h index ac3fe43..7068c3e 100644 --- a/libspeex/sb_celp.h +++ b/libspeex/sb_celp.h @@ -47,11 +47,13 @@ typedef struct SBEncState { float *excBuf; float *exc; + float *exc_alias; float *buf; float *res; float *sw; float *target; float *window; + float *exc_window; float *lagWindow; float *autocorr; float *rc; @@ -68,7 +70,9 @@ typedef struct SBEncState { float *bw_lpc2; float *mem_sp; + float *mem_sp2; float *mem_sw; + float *mem_exc; } SBEncState; diff --git a/libspeex/speex.c b/libspeex/speex.c index 491793b..6b2a841 100644 --- a/libspeex/speex.c +++ b/libspeex/speex.c @@ -354,16 +354,19 @@ void encode(EncState *st, float *in, FrameBits *bits) syn_filt_zero(target, st->bw_lpc1, res, st->subframeSize, st->lpcSize); residue_zero(res, st->interp_qlpc, st->buf2, st->subframeSize, st->lpcSize); residue_zero(st->buf2, st->bw_lpc2, st->buf2, st->subframeSize, st->lpcSize); - if (1||(snr>9 && (rand()%10==0))) + if (1||(snr>9 && (rand()%6==0))) { + float ener=0; printf ("exc "); for (i=0;i<st->subframeSize;i++) { - if (0&&i && i%8==0) + ener+=st->buf2[i]*st->buf2[i]; + if (i && i%5==0) printf ("\nexc "); printf ("%f ", st->buf2[i]); } printf ("\n"); + printf ("innovation_energy = %f\n", ener); } for (i=0;i<st->subframeSize;i++) exc[i]+=st->buf2[i]; |