📄 rcsynew.c
字号:
/* * This material contains unpublished, proprietary software of * Entropic Research Laboratory, Inc. Any reproduction, distribution, * or publication of this work must be authorized in writing by Entropic * Research Laboratory, Inc., and must bear the notice: * * "Copyright (c) 1990-1993 Entropic Research Laboratory, Inc. * All rights reserved" * * The copyright notice above does not evidence any actual or intended * publication of this source code. * * Written by: David Talkin * Checked by: * Revised by: * * Brief description: rcsyn.c * */static char *sccs_id = "%W% %G% ERL";#include <math.h>#include <stdio.h>#include <esps/lpsyn.h>double rc_gain(rc,n) register double *rc; register int n;{ register double sum, dif, *dp=rc; int i=n; for(sum = 1.0; n--;) { dif = *rc++; sum *= (1.0 - dif*dif); } if(sum < 0.0){ for(n=0;n<i;n++) printf("%f ",dp[n]); printf("\n"); return(0.0); } return(sqrt(sum));}double lattice(rc, order, lsstate, input, usr)register double *rc, *lsstate;register double input;register int order, usr;{ register int i, j; register double output, ki; output = input; for (i = order*usr, rc += order; i > 0; ) { ki = - *--rc; output += ki * lsstate[i]; lsstate[i+1] = lsstate[i] - ki * output; for(j=usr,i--;--j; i--) lsstate[i+1] = lsstate[i]; } lsstate[1] = output; return (output);}/* This one implements a Rosenberg polynomial source; open-phasedamping; adjustable open quotient; and period error diffusion. */rcsyn(pb,init,op, damp, intcc, usr) register short *op; register int init, usr; register double damp, intcc; Pblock *pb;{ register int k,j, ord, nper, pcnt, count, nopen, orat; register double out, ransize, g, input, input2, decay, *mp1, *cp, uc, ud, ue, uf, isq, pval, flow; double oq = 0.5, c; int decay_cnt=1; register short *ep; register LP_frame *rcf; double residp, residf, fnper, fk, ofreq, ginc, gold; static double lpm[MAX_ORD*10], rcold[MAX_ORD], drc[MAX_ORD], *mp2; ofreq = usr * pb->freq; /* output frequency */ ransize = 2 << 30; ransize *= 4; rcf = pb->head; ord = pb->head->order;/* if(intcc > .001) intcc = exp(log(intcc)/usr); */ if(init) for(decay_cnt=usr, k=MAX_ORD, out = 0.0, residf = residp = 0.0, gold=0.0, count = 0, pcnt = 10000, nper = 0, mp1=lpm, mp2 = rcold; k--; ) { *mp1++ = 0.0; *mp2++ = 0.0; } while(rcf) { if(rcf->next) fk = residp + ofreq*(rcf->next->time - rcf->time); else if(rcf->prev) fk = residp + ofreq*(rcf->time - rcf->prev->time); else fk = .01*ofreq; /* just force a 10ms frame */ if(fk < 0.0) fk = 0.0; k = fk; /* integerize samples generated by this frame */ residp = fk - k; /* compute deltas for interpolated RC's and level */ for(j=0, mp1 = rcold, mp2 = rcf->coef, cp = drc; j++ < ord;) *cp++ = (*mp2++ - *mp1++)/k; ginc = ((8.0*rcf->rms) - gold)/k; if(rcf->fr_type == VOICED) { fnper = residf + (ofreq * rcf->period); residf = fnper-((int)fnper); for( ; k--; count++,pcnt++) { g = (gold += ginc); if(pcnt >= nper) { /* reset the function generator */ nper = fnper; oq = .6 + .0017*((1.0/rcf->period) - 160.0); if(oq > .9) oq = .9; nopen = 0.5 + oq*fnper; uc = 2.0/(double)nopen; ud = 3.0/(2.0*nopen); c = .66667*nopen; /* time of peak flow */ ue = uc/2.0; uf = uc*ud/3.0; isq = c*c; pval = (ue*isq) - (uf*isq*c); /* value of peak flow */ pcnt = 1; } if(pcnt <= nopen) { /* output open-phase signal */ isq = pcnt*pcnt; input = uc*(pcnt - isq*ud); flow = (ue*isq) - (uf*isq*pcnt); decay = 1.0 - (damp*flow/pval); out = g*lattice(rcold, ord, lpm, rc_gain(rcold,ord)*input,usr); } else { /* output closed-phase signal */ input = 0.0; out = g*lattice(rcold, ord, lpm, input, usr); } for(j=ord, mp1 = rcold, cp = drc; j--; ) *mp1++ += *cp++; *op++ = (out > 0.0)? out + .5 : out - .5; if(--decay_cnt <= 0) { for(j=ord*usr, mp1=lpm; j--;) *mp1++ *= decay; decay_cnt = usr; } } } else { /* it is an unvoiced frame */ input = 0.0; for(nper=0, pcnt=10000 ; k--; count++) { g = 1.0/ransize;#ifdef OS5 input = g*(rand() - rand()) + intcc*input;#else input = g*(random() - random()) + intcc*input;#endif input2 = input * rc_gain(rcold, ord); out = (gold += ginc)*lattice(rcold, ord, lpm, input2, usr); for(j=ord, mp1 = rcold, cp = drc; j--; ) *mp1++ += *cp++; *op++ = (out > 0.0)? out + .5 : out - .5; } } rcf = rcf->next; } return(count);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -