[xiph-cvs] cvs commit: speex/libspeex cb_search.c vq.c vq.h
Jean-Marc Valin
jm at xiph.org
Tue Oct 22 22:18:29 PDT 2002
jm 02/10/23 01:18:29
Modified: libspeex cb_search.c vq.c vq.h
Log:
Re-wrote the signed search to be like the unsigned one (should make them
use the same code now)
Revision Changes Path
1.70 +297 -1 speex/libspeex/cb_search.c
Index: cb_search.c
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/cb_search.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- cb_search.c 23 Oct 2002 00:53:19 -0000 1.69
+++ cb_search.c 23 Oct 2002 05:18:29 -0000 1.70
@@ -326,6 +326,302 @@
+#if 1
+void split_cb_search_shape_sign(
+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,
+SpeexBits *bits,
+float *stack,
+int complexity
+)
+{
+ int i,j,k,m,n,q;
+ float *resp;
+ float *t, *r, *e, *E;
+ /*FIXME: Should make this dynamic*/
+ float *tmp, *_ot[20], *_nt[20];
+ float *ndist, *odist;
+ int *itmp, *_nind[20], *_oind[20];
+ float **ot, **nt;
+ int **nind, **oind;
+ int *ind;
+ float *shape_cb;
+ int shape_cb_size, subvect_size, nb_subvect;
+ split_cb_params *params;
+ int N=2;
+ int *best_index;
+ float *best_dist;
+
+ ot=_ot;
+ nt=_nt;
+ oind=_oind;
+ nind=_nind;
+ N=complexity;
+ if (N<1)
+ N=1;
+ if (N>10)
+ N=10;
+
+ 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;
+ resp = PUSH(stack, shape_cb_size*subvect_size);
+ t = PUSH(stack, nsf);
+ r = PUSH(stack, nsf);
+ e = PUSH(stack, nsf);
+ E = PUSH(stack, shape_cb_size);
+ /*FIXME: This breaks if sizeof(int) != sizeof(float) */
+ ind = (int*)PUSH(stack, nb_subvect);
+
+ tmp = PUSH(stack, 2*N*nsf);
+ for (i=0;i<N;i++)
+ {
+ ot[i]=tmp;
+ tmp += nsf;
+ nt[i]=tmp;
+ tmp += nsf;
+ }
+
+ /*FIXME: This breaks if sizeof(int) != sizeof(float) */
+ best_index = (int*)PUSH(stack, N);
+ best_dist = PUSH(stack, N);
+ ndist = PUSH(stack, N);
+ odist = PUSH(stack, N);
+
+ /*FIXME: This breaks if sizeof(int) != sizeof(float) */
+ itmp = (int*)PUSH(stack, 2*N*nb_subvect);
+ for (i=0;i<N;i++)
+ {
+ nind[i]=itmp;
+ itmp+=nb_subvect;
+ oind[i]=itmp;
+ itmp+=nb_subvect;
+ for (j=0;j<nb_subvect;j++)
+ nind[i][j]=oind[i][j]=-1;
+ }
+
+ for (j=0;j<N;j++)
+ for (i=0;i<nsf;i++)
+ ot[j][i]=target[i];
+
+ for (i=0;i<nsf;i++)
+ t[i]=target[i];
+
+ e[0]=1;
+ for (i=1;i<nsf;i++)
+ e[i]=0;
+ syn_percep_zero(e, ak, awk1, awk2, r, nsf,p, stack);
+
+ /* Pre-compute codewords response and energy */
+ for (i=0;i<shape_cb_size;i++)
+ {
+ float *res;
+ float *shape;
+ int k;
+ res = resp+i*subvect_size;
+ shape = shape_cb+i*subvect_size;
+ /* Compute codeword response */
+ k=0;
+#if 0
+ for(j=0;j<subvect_size;j++)
+ res[j]=0;
+ for(j=0;j<subvect_size;j++)
+ {
+#if 1
+ float s=shape[j];
+ float *rr;
+ int lim=subvect_size-j;
+ float *ress=res+j;
+ rr=r;
+ while(lim--)
+ *ress+++=s* *rr++;
+#else
+ for (k=j;k<subvect_size;k++)
+ res[k]+=shape_cb[i*subvect_size+j]*r[k-j];
+#endif
+ }
+#else
+ for(j=0;j<subvect_size;j++)
+ {
+ res[j]=0;
+ for (k=0;k<=j;k++)
+ res[j] += shape[k]*r[j-k];
+ }
+#endif
+ E[i]=0;
+ for(j=0;j<subvect_size;j++)
+ E[i]+=res[j]*res[j];
+ }
+
+ for (j=0;j<N;j++)
+ odist[j]=0;
+ /*For all subvectors*/
+ for (i=0;i<nb_subvect;i++)
+ {
+ /*"erase" nbest list*/
+ for (j=0;j<N;j++)
+ ndist[j]=-1;
+
+ /*For all n-bests of previous subvector*/
+ for (j=0;j<N;j++)
+ {
+ float *x=ot[j]+subvect_size*i;
+ /*Find new n-best based on previous n-best j*/
+ vq_nbest_sign(x, resp, subvect_size, shape_cb_size, E, N, best_index, best_dist);
+
+ /*For all new n-bests*/
+ for (k=0;k<N;k++)
+ {
+ float *ct;
+ float err=0;
+ ct = ot[j];
+ /*update target*/
+
+ /*previous target*/
+ for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
+ t[m]=ct[m];
+
+ /* New code: update only enough of the target to calculate error*/
+ {
+ int rind;
+ float *res;
+ float sign=1;
+ rind = best_index[k];
+ if (rind>shape_cb_size)
+ {
+ sign=-1;
+ rind-=shape_cb_size;
+ }
+ res = resp+rind*subvect_size;
+ if (sign>0)
+ for (m=0;m<subvect_size;m++)
+ t[subvect_size*i+m] -= res[m];
+ else
+ for (m=0;m<subvect_size;m++)
+ t[subvect_size*i+m] += res[m];
+ }
+
+ /*compute error (distance)*/
+ err=odist[j];
+ for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
+ err += t[m]*t[m];
+ /*update n-best list*/
+ if (err<ndist[N-1] || ndist[N-1]<-.5)
+ {
+
+ /*previous target (we don't care what happened before*/
+ for (m=(i+1)*subvect_size;m<nsf;m++)
+ t[m]=ct[m];
+ /* New code: update the rest of the target only if it's worth it */
+ for (m=0;m<subvect_size;m++)
+ {
+ float g;
+ int rind;
+ float sign=1;
+ rind = best_index[k];
+ if (rind>shape_cb_size)
+ {
+ sign=-1;
+ rind-=shape_cb_size;
+ }
+
+ g=sign*shape_cb[rind*subvect_size+m];
+ q=subvect_size-m;
+ for (n=subvect_size*(i+1);n<nsf;n++,q++)
+ t[n] -= g*r[q];
+ }
+
+
+ for (m=0;m<N;m++)
+ {
+ if (err < ndist[m] || ndist[m]<-.5)
+ {
+ for (n=N-1;n>m;n--)
+ {
+ for (q=0;q<nsf;q++)
+ nt[n][q]=nt[n-1][q];
+ for (q=0;q<nb_subvect;q++)
+ nind[n][q]=nind[n-1][q];
+ ndist[n]=ndist[n-1];
+ }
+ for (q=0;q<nsf;q++)
+ nt[m][q]=t[q];
+ for (q=0;q<nb_subvect;q++)
+ nind[m][q]=oind[j][q];
+ nind[m][i]=best_index[k];
+ ndist[m]=err;
+ break;
+ }
+ }
+ }
+ }
+ if (i==0)
+ break;
+ }
+
+ /*update old-new data*/
+#if 1
+ /* just swap pointers instead of a long copy */
+ {
+ float **tmp;
+ tmp=ot;
+ ot=nt;
+ nt=tmp;
+ }
+#else
+ for (j=0;j<N;j++)
+ for (m=0;m<nsf;m++)
+ ot[j][m]=nt[j][m];
+#endif
+ for (j=0;j<N;j++)
+ for (m=0;m<nb_subvect;m++)
+ oind[j][m]=nind[j][m];
+ for (j=0;j<N;j++)
+ odist[j]=ndist[j];
+ }
+
+ /*save indices*/
+ for (i=0;i<nb_subvect;i++)
+ {
+ ind[i]=nind[0][i];
+ speex_bits_pack(bits,ind[i],params->shape_bits+1);
+ }
+
+ /* Put everything back together */
+ for (i=0;i<nb_subvect;i++)
+ {
+ int rind;
+ float sign=1;
+ rind = ind[i];
+ if (rind>shape_cb_size)
+ {
+ sign=-1;
+ rind-=shape_cb_size;
+ }
+
+ for (j=0;j<subvect_size;j++)
+ e[subvect_size*i+j]=sign*shape_cb[rind*subvect_size+j];
+ }
+ /* Update excitation */
+ for (j=0;j<nsf;j++)
+ exc[j]+=e[j];
+
+ /* Update target */
+ syn_percep_zero(e, ak, awk1, awk2, r, nsf,p, stack);
+ for (j=0;j<nsf;j++)
+ target[j]-=r[j];
+
+}
+
+#else
void split_cb_search_shape_sign(
float target[], /* target vector */
@@ -542,7 +838,7 @@
}
-
+#endif
void split_cb_nogain_unquant(
float *exc,
<p><p>1.7 +40 -0 speex/libspeex/vq.c
Index: vq.c
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/vq.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- vq.c 11 Oct 2002 03:39:34 -0000 1.6
+++ vq.c 23 Oct 2002 05:18:29 -0000 1.7
@@ -86,3 +86,43 @@
}
}
+/*Finds the indices of the n-best entries in a codebook with sign*/
+void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist)
+{
+ int i,j,k, sign;
+ for (i=0;i<entries;i++)
+ {
+ float dist=0;
+ for (j=0;j<len;j++)
+ dist -= in[j]**codebook++;
+ if (dist>0)
+ {
+ sign=1;
+ dist=-dist;
+ } else
+ {
+ sign=0;
+ }
+ dist += .5*E[i];
+ if (i<N || dist<best_dist[N-1])
+ {
+
+ for (j=0;j<N;j++)
+ {
+ if (j >= i || dist < best_dist[j])
+ {
+ for (k=N-1;k>j;k--)
+ {
+ best_dist[k]=best_dist[k-1];
+ nbest[k] = nbest[k-1];
+ }
+ best_dist[j]=dist;
+ nbest[j]=i;
+ if (sign)
+ nbest[j]+=entries;
+ break;
+ }
+ }
+ }
+ }
+}
<p><p>1.7 +1 -0 speex/libspeex/vq.h
Index: vq.h
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/vq.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- vq.h 11 Oct 2002 03:39:34 -0000 1.6
+++ vq.h 23 Oct 2002 05:18:29 -0000 1.7
@@ -37,5 +37,6 @@
void vq_nbest(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist);
+void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist);
#endif
<p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list