📄 cb_search.c
字号:
ALLOC(oind, N, int*); ALLOC(nind, N, int*); params = (const 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; have_sign = params->have_sign; ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);#ifdef _USE_SSE ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128); ALLOC(E, shape_cb_size>>2, __m128);#else resp2 = resp; ALLOC(E, shape_cb_size, spx_word32_t);#endif ALLOC(t, nsf, spx_word16_t); ALLOC(e, nsf, spx_sig_t); ALLOC(r2, nsf, spx_sig_t); ALLOC(ind, nb_subvect, int); ALLOC(tmp, 2*N*nsf, spx_word16_t); for (i=0;i<N;i++) { ot2[i]=tmp+2*i*nsf; nt2[i]=tmp+(2*i+1)*nsf; } ot=ot2; nt=nt2; ALLOC(best_index, N, int); ALLOC(best_dist, N, spx_word32_t); ALLOC(best_nind, N, int); ALLOC(best_ntarget, N, int); ALLOC(ndist, N, spx_word32_t); ALLOC(odist, N, spx_word32_t); ALLOC(itmp, 2*N*nb_subvect, int); for (i=0;i<N;i++) { nind[i]=itmp+2*i*nb_subvect; oind[i]=itmp+(2*i+1)*nb_subvect; } /* FIXME: make that adaptive? */ for (i=0;i<nsf;i++) t[i]=EXTRACT16(PSHR32(target[i],6)); for (j=0;j<N;j++) speex_move(&ot[j][0], t, nsf*sizeof(spx_word16_t)); /* Pre-compute codewords response and energy */ compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack); 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]=VERY_LARGE32; /*For all n-bests of previous subvector*/ for (j=0;j<N;j++) { spx_word16_t *x=ot[j]+subvect_size*i; spx_word32_t tener = 0; for (m=0;m<subvect_size;m++) tener = MAC16_16(tener, x[m],x[m]);#ifdef FIXED_POINT tener = SHR32(tener,1);#else tener *= .5;#endif /*Find new n-best based on previous n-best j*/ if (have_sign) vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack); else vq_nbest(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack); /*For all new n-bests*/ for (k=0;k<N;k++) { /* Compute total distance (including previous sub-vectors */ spx_word32_t err = ADD32(ADD32(odist[j],best_dist[k]),tener); /*update n-best list*/ if (err<ndist[N-1]) { for (m=0;m<N;m++) { if (err < ndist[m]) { for (n=N-1;n>m;n--) { ndist[n] = ndist[n-1]; best_nind[n] = best_nind[n-1]; best_ntarget[n] = best_ntarget[n-1]; } ndist[m] = err; best_nind[n] = best_index[k]; best_ntarget[n] = j; break; } } } } if (i==0) break; } for (j=0;j<N;j++) { //spx_word16_t *ct = ot[best_ntarget[j]]; /*previous target (we don't care what happened before*/ for (m=(i+1)*subvect_size;m<nsf;m++) nt[j][m]=ot[best_ntarget[j]][m]; /* New code: update the rest of the target only if it's worth it */ for (m=0;m<subvect_size;m++) { spx_word16_t g; int rind; spx_word16_t sign=1; rind = best_nind[j]; if (rind>=shape_cb_size) { sign=-1; rind-=shape_cb_size; } q=subvect_size-m;#ifdef FIXED_POINT g=sign*shape_cb[rind*subvect_size+m]; target_update(nt[j]+subvect_size*(i+1), g, r+q, nsf-subvect_size*(i+1));#else g=sign*0.03125*shape_cb[rind*subvect_size+m]; /*FIXME: I think that one too can be replaced by target_update */ for (n=subvect_size*(i+1);n<nsf;n++,q++) nt[j][n] = SUB32(nt[j][n],g*r[q]);#endif } for (q=0;q<nb_subvect;q++) nind[j][q]=oind[best_ntarget[j]][q]; nind[j][i]=best_nind[j]; } /*update old-new data*/ /* just swap pointers instead of a long copy */ { spx_word16_t **tmp2; tmp2=ot; ot=nt; nt=tmp2; } 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+have_sign); } /* Put everything back together */ for (i=0;i<nb_subvect;i++) { int rind; spx_word16_t sign=1; rind = ind[i]; if (rind>=shape_cb_size) { sign=-1; rind-=shape_cb_size; }#ifdef FIXED_POINT if (sign==1) { for (j=0;j<subvect_size;j++) e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5); } else { for (j=0;j<subvect_size;j++) e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5)); }#else for (j=0;j<subvect_size;j++) e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];#endif } /* Update excitation */ for (j=0;j<nsf;j++) exc[j]=ADD32(exc[j],e[j]); /* Update target: only update target if necessary */ if (update_target) { syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack); for (j=0;j<nsf;j++) target[j]=SUB32(target[j],r2[j]); }}void split_cb_shape_sign_unquant(spx_sig_t *exc,const void *par, /* non-overlapping codebook */int nsf, /* number of samples in subframe */SpeexBits *bits,char *stack){ int i,j; VARDECL(int *ind); VARDECL(int *signs); const signed char *shape_cb; int shape_cb_size, subvect_size, nb_subvect; const split_cb_params *params; int have_sign; params = (const 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; have_sign = params->have_sign; ALLOC(ind, nb_subvect, int); ALLOC(signs, nb_subvect, int); /* Decode codewords and gains */ for (i=0;i<nb_subvect;i++) { if (have_sign) signs[i] = speex_bits_unpack_unsigned(bits, 1); else signs[i] = 0; ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits); } /* Compute decoded excitation */ for (i=0;i<nb_subvect;i++) { spx_word16_t s=1; if (signs[i]) s=-1;#ifdef FIXED_POINT if (s==1) { for (j=0;j<subvect_size;j++) exc[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5); } else { for (j=0;j<subvect_size;j++) exc[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5)); }#else for (j=0;j<subvect_size;j++) exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j]; #endif }}void noise_codebook_quant(spx_sig_t target[], /* target vector */spx_coef_t ak[], /* LPCs for this subframe */spx_coef_t awk1[], /* Weighted LPCs for this subframe */spx_coef_t awk2[], /* Weighted LPCs for this subframe */const void *par, /* Codebook/search parameters*/int p, /* number of LPC coeffs */int nsf, /* number of samples in subframe */spx_sig_t *exc,spx_word16_t *r,SpeexBits *bits,char *stack,int complexity,int update_target){ int i; VARDECL(spx_sig_t *tmp); ALLOC(tmp, nsf, spx_sig_t); residue_percep_zero(target, ak, awk1, awk2, tmp, nsf, p, stack); for (i=0;i<nsf;i++) exc[i]+=tmp[i]; for (i=0;i<nsf;i++) target[i]=0;}void noise_codebook_unquant(spx_sig_t *exc,const void *par, /* non-overlapping codebook */int nsf, /* number of samples in subframe */SpeexBits *bits,char *stack){ speex_rand_vec(1, exc, nsf);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -