📄 voicin.c,v
字号:
/* Parameter adjustments */ if (vwin) { --vwin; } if (buflim) { --buflim; } if (inbuf) { inbuf_offset = buflim[1]; inbuf -= inbuf_offset; } if (lpbuf) { lpbuf_offset = buflim[3]; lpbuf -= lpbuf_offset; } if (ivrc) { --ivrc; } if (obound) { --obound; } if (voibuf) { --voibuf; } /* Function Body *//* The following variables are saved from one invocation to the *//* next, but are not initialized with DATA statements. This is *//* acceptable, because FIRST is initialized ot .TRUE., and the *//* first time that this subroutine is then called, they are all *//* given initial values. *//* SNR *//* LBVE, LBUE, FBVE, FBUE, OFBUE, OLBUE *//* MAXMIN is initialized on the first call, assuming that HALF *//* .EQ. 1 on first call. This is how ANALYS calls this subroutine. *//* Voicing Decision Parameter vector (* denotes zero coefficient): *//* * MAXMIN *//* LBE/LBVE *//* ZC *//* RC1 *//* QS *//* IVRC2 *//* aR_B *//* aR_F *//* * LOG(LBE/LBVE) *//* Define 2-D voicing decision coefficient vector according to the voicing*//* parameter order above. Each row (VDC vector) is optimized for a specific*//* SNR. The last element of the vector is the constant. *//* E ZC RC1 Qs IVRC2 aRb aRf c *//* The VOICE array contains the result of the linear discriminant function*//* (analog values). The VOIBUF array contains the hard-limited binary *//* voicing decisions. The VOICE and VOIBUF arrays, according to FORTRAN *//* memory allocation, are addressed as: *//* (half-frame number, future-frame number) *//* | Past | Present | Future1 | Future2 | *//* | 1,0 | 2,0 | 1,1 | 2,1 | 1,2 | 2,2 | 1,3 | 2,3 | ---> time *//* Update linear discriminant function history each frame: */ if (*half == 1) { voice[0] = voice[2]; voice[1] = voice[3]; voice[2] = voice[4]; voice[3] = voice[5]; *maxmin = *maxamd / max(*minamd,1.f); }/* Calculate voicing parameters twice per frame: */ vparms_(&vwin[1], &inbuf[inbuf_offset], &lpbuf[lpbuf_offset], &buflim[1], half, dither, mintau, &zc, &lbe, &fbe, &qs, &rc1, &ar_b__, & ar_f__);/* Estimate signal-to-noise ratio to select the appropriate VDC vector. *//* The SNR is estimated as the running average of the ratio of the *//* running average full-band voiced energy to the running average *//* full-band unvoiced energy. SNR filter has gain of 63. */ r__1 = (*snr + *fbve / (real) max(*fbue,1)) * 63 / 64.f; *snr = (real) i_nint(&r__1); snr2 = *snr * *fbue / max(*lbue,1);/* Quantize SNR to SNRL according to VDCL thresholds. */ snrl = 1; i__1 = nvdcl - 1; for (snrl = 1; snrl <= i__1; ++snrl) { if (snr2 > vdcl[snrl - 1]) { goto L69; } }/* (Note: SNRL = NVDCL here) */L69:/* Linear discriminant voicing parameters: */ value[0] = *maxmin; value[1] = (real) lbe / max(*lbve,1); value[2] = (real) zc; value[3] = rc1; value[4] = qs; value[5] = ivrc[2]; value[6] = ar_b__; value[7] = ar_f__;/* Evaluation of linear discriminant function: */ voice[*half + 3] = vdc[snrl * 10 - 1]; for (i__ = 1; i__ <= 8; ++i__) { voice[*half + 3] += vdc[i__ + snrl * 10 - 11] * value[i__ - 1]; }/* Classify as voiced if discriminant > 0, otherwise unvoiced *//* Voicing decision for current half-frame: 1 = Voiced; 0 = Unvoiced */ if (voice[*half + 3] > 0.f) { voibuf[*half + 6] = 1; } else { voibuf[*half + 6] = 0; }/* Skip voicing decision smoothing in first half-frame: *//* Give a value to VSTATE, so that trace statements below will print *//* a consistent value from one call to the next when HALF .EQ. 1. *//* The value of VSTATE is not used for any other purpose when this is *//* true. */ vstate = -1; if (*half == 1) { goto L99; }/* Voicing decision smoothing rules (override of linear combination): *//* Unvoiced half-frames: At least two in a row. *//* -------------------- *//* Voiced half-frames: At least two in a row in one frame. *//* ------------------- Otherwise at least three in a row. *//* (Due to the way transition frames are encoded) *//* In many cases, the discriminant function determines how to smooth. *//* In the following chart, the decisions marked with a * may be overridden.*//* Voicing override of transitions at onsets: *//* If a V/UV or UV/V voicing decision transition occurs within one-half *//* frame of an onset bounding a voicing window, then the transition is *//* moved to occur at the onset. *//* P 1F *//* ----- ----- *//* 0 0 0 0 *//* 0 0 0* 1 (If there is an onset there) *//* 0 0 1* 0* (Based on 2F and discriminant distance) *//* 0 0 1 1 *//* 0 1* 0 0 (Always) *//* 0 1* 0* 1 (Based on discriminant distance) *//* 0* 1 1 0* (Based on past, 2F, and discriminant distance) *//* 0 1* 1 1 (If there is an onset there) *//* 1 0* 0 0 (If there is an onset there) *//* 1 0 0 1 *//* 1 0* 1* 0 (Based on discriminant distance) *//* 1 0* 1 1 (Always) *//* 1 1 0 0 *//* 1 1 0* 1* (Based on 2F and discriminant distance) *//* 1 1 1* 0 (If there is an onset there) *//* 1 1 1 1 *//* Determine if there is an onset transition between P and 1F. *//* OT (Onset Transition) is true if there is an onset between *//* P and 1F but not after 1F. */ ot = ((obound[1] & 2) != 0 || obound[2] == 1) && (obound[3] & 1) == 0;/* Multi-way dispatch on voicing decision history: */ vstate = (voibuf[3] << 3) + (voibuf[4] << 2) + (voibuf[5] << 1) + voibuf[ 6]; switch (vstate + 1) { case 1: goto L99; case 2: goto L1; case 3: goto L2; case 4: goto L99; case 5: goto L4; case 6: goto L5; case 7: goto L6; case 8: goto L7; case 9: goto L8; case 10: goto L99; case 11: goto L10; case 12: goto L11; case 13: goto L99; case 14: goto L13; case 15: goto L14; case 16: goto L99; }L1: if (ot && voibuf[7] == 1) { voibuf[5] = 1; } goto L99;L2: if (voibuf[7] == 0 || voice[2] < -voice[3]) { voibuf[5] = 0; } else { voibuf[6] = 1; } goto L99;L4: voibuf[4] = 0; goto L99;L5: if (voice[1] < -voice[2]) { voibuf[4] = 0; } else { voibuf[5] = 1; } goto L99;/* VOIBUF(2,0) must be 0 */L6: if (voibuf[1] == 1 || voibuf[7] == 1 || voice[3] > voice[0]) { voibuf[6] = 1; } else { voibuf[3] = 1; } goto L99;L7: if (ot) { voibuf[4] = 0; } goto L99;L8: if (ot) { voibuf[4] = 1; } goto L99;L10: if (voice[2] < -voice[1]) { voibuf[5] = 0; } else { voibuf[4] = 1; } goto L99;L11: voibuf[4] = 1; goto L99;L13: if (voibuf[7] == 0 && voice[3] < -voice[2]) { voibuf[6] = 0; } else { voibuf[5] = 1; } goto L99;L14: if (ot && voibuf[7] == 0) { voibuf[5] = 0; }/* GOTO 99 */L99:/* Now update parameters: *//* ---------------------- *//* During unvoiced half-frames, update the low band and full band unvoiced*//* energy estimates (LBUE and FBUE) and also the zero crossing *//* threshold (DITHER). (The input to the unvoiced energy filters is *//* restricted to be less than 10dB above the previous inputs of the *//* filters.) *//* During voiced half-frames, update the low-pass (LBVE) and all-pass *//* (FBVE) voiced energy estimates. */ if (voibuf[*half + 6] == 0) {/* Computing MIN */ i__1 = fbe, i__2 = *ofbue * 3; r__1 = (*sfbue * 63 + (min(i__1,i__2) << 3)) / 64.f; *sfbue = i_nint(&r__1); *fbue = *sfbue / 8; *ofbue = fbe;/* Computing MIN */ i__1 = lbe, i__2 = *olbue * 3; r__1 = (*slbue * 63 + (min(i__1,i__2) << 3)) / 64.f; *slbue = i_nint(&r__1); *lbue = *slbue / 8; *olbue = lbe; } else { r__1 = (*lbve * 63 + lbe) / 64.f; *lbve = i_nint(&r__1); r__1 = (*fbve * 63 + fbe) / 64.f; *fbve = i_nint(&r__1); }/* Set dither threshold to yield proper zero crossing rates in the *//* presence of low frequency noise and low level signal input. *//* NOTE: The divisor is a function of REF, the expected energies. *//* Computing MIN *//* Computing MAX */ r__2 = sqrt((real) (*lbue * *lbve)) * 64 / 3000; r__1 = max(r__2,1.f); *dither = min(r__1,20.f);/* Voicing decisions are returned in VOIBUF. */ return 0;} /* voicin_ */@1.1log@Initial revision@text@d3 4a6 1$Log$d11 1a11 2extern int voicin_(integer *vwin, real *inbuf, real *lpbuf, integer *buflim, integer *half, real *minamd, real *maxamd, integer *mintau, real *ivrc, integer *obound, integer *voibuf, integer *af);extern int initvoicin_(void);d36 4a39 1/* $Log: voicin.f,v $ */d212 1a212 1/* Subroutine */ int voicin_0_(int n__, integer *vwin, real *inbuf, real *d215 1a215 1 integer *af)d219 1a219 2 static logical first = TRUE_; static real dither = 20.f;d243 1a243 1 static integer fbue, fbve, lbue, lbve;d245 3a247 3 static integer ofbue, sfbue; static real voice[6] /* was [2][3] */; static integer olbue, slbue;d252 1a252 1 static real maxmin;d259 1a259 1 static real snr;d264 4a267 1/* $Log: contrl.fh,v $ */d404 14a443 4 switch(n__) { case 1: goto L_initvoicin; }d475 1a475 12 if (first) { lbve = 3000; fbve = 3000; fbue = 187; ofbue = 187; sfbue = 187; lbue = 93; olbue = 93; slbue = 93; snr = (real) (fbve / fbue << 6); first = FALSE_; }d495 1a495 1 maxmin = *maxamd / max(*minamd,1.f);d499 1a499 1 half, &dither, mintau, &zc, &lbe, &fbe, &qs, &rc1, &ar_b__, &d506 3a508 3 r__1 = (snr + fbve / (real) max(fbue,1)) * 63 / 64.f; snr = (real) i_nint(&r__1); snr2 = snr * fbue / max(lbue,1);d520 2a521 2 value[0] = maxmin; value[1] = (real) lbe / max(lbve,1);d690 5a694 5 i__1 = fbe, i__2 = ofbue * 3; r__1 = (sfbue * 63 + (min(i__1,i__2) << 3)) / 64.f; sfbue = i_nint(&r__1); fbue = sfbue / 8; ofbue = fbe;d696 5a700 5 i__1 = lbe, i__2 = olbue * 3; r__1 = (slbue * 63 + (min(i__1,i__2) << 3)) / 64.f; slbue = i_nint(&r__1); lbue = slbue / 8; olbue = lbe;d702 4a705 4 r__1 = (lbve * 63 + lbe) / 64.f; lbve = i_nint(&r__1); r__1 = (fbve * 63 + fbe) / 64.f; fbve = i_nint(&r__1);d712 1a712 1 r__2 = sqrt((real) (lbue * lbve)) * 64 / 3000;d714 1a714 16 dither = min(r__1,20.f);/* Print Test Data *//* IF( LISTL.GE.3 ) THEN *//* IF(HALF.EQ.1) WRITE(FDEBUG,930) VWIN,MINAMD,MAXAMD,MINTAU,IVRC *//* 930 FORMAT(' Voicing:VWIN MINA MAXA MINTAU IVRC1 IVRC2'/ *//* 1 5X,2I4,2F9.1,I8,2F7.3/ *//* 1 ' HALF DISCR MAX/MIN LE/LVE ZC RC1 QS IVRC2' *//* 1 ' aR_B aR_F : DITH LBE FBE LBVE FBVE LBUE FBUE', *//* 1 ' SNR SNRL VS OT') *//* WRITE(FDEBUG,940) HALF, VOICE(HALF,3), (VALUE(I),I=1,8), DITHER, *//* 1 LBE, FBE, LBVE, FBVE, LBUE, FBUE, *//* 1 SNR, SNRL, VSTATE, OT *//* 940 FORMAT(1X,I3,':',F8.0,F9.1,F7.3,F7.2,5F7.3,F5.1,6I6,F9.1,2I3,L3) *//* END IF */a716 5L_initvoicin: first = TRUE_; dither = 20.f; return 0;a717 16/* Subroutine */ int voicin_(integer *vwin, real *inbuf, real *lpbuf, integer *buflim, integer *half, real *minamd, real *maxamd, integer *mintau, real *ivrc, integer *obound, integer *voibuf, integer *af){ return voicin_0_(0, vwin, inbuf, lpbuf, buflim, half, minamd, maxamd, mintau, ivrc, obound, voibuf, af); }/* Subroutine */ int initvoicin_(void){ return voicin_0_(1, (integer *)0, (real *)0, (real *)0, (integer *)0, ( integer *)0, (real *)0, (real *)0, (integer *)0, (real *)0, ( integer *)0, (integer *)0, (integer *)0); }@
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -