📄 analys.c,v
字号:
i__1 = 720 - contrl_1.lframe; for (i__ = 181; i__ <= i__1; ++i__) { inbuf[i__ - 181] = inbuf[contrl_1.lframe + i__ - 181]; pebuf[i__ - 181] = pebuf[contrl_1.lframe + i__ - 181]; } i__1 = 540 - contrl_1.lframe; for (i__ = 229; i__ <= i__1; ++i__) { ivbuf[i__ - 229] = ivbuf[contrl_1.lframe + i__ - 229]; } i__1 = 720 - contrl_1.lframe; for (i__ = 25; i__ <= i__1; ++i__) { lpbuf[i__ - 25] = lpbuf[contrl_1.lframe + i__ - 25]; } j = 1; i__1 = (*osptr) - 1; for (i__ = 1; i__ <= i__1; ++i__) { if (osbuf[i__ - 1] > contrl_1.lframe) { osbuf[j - 1] = osbuf[i__ - 1] - contrl_1.lframe; ++j; } } *osptr = j; voibuf[0] = voibuf[2]; voibuf[1] = voibuf[3]; for (i__ = 1; i__ <= 2; ++i__) { vwin[(i__ << 1) - 2] = vwin[(i__ + 1 << 1) - 2] - contrl_1.lframe; vwin[(i__ << 1) - 1] = vwin[(i__ + 1 << 1) - 1] - contrl_1.lframe; awin[(i__ << 1) - 2] = awin[(i__ + 1 << 1) - 2] - contrl_1.lframe; awin[(i__ << 1) - 1] = awin[(i__ + 1 << 1) - 1] - contrl_1.lframe;/* EWIN(*,J) is unused for J .NE. AF, so the following shift is *//* unnecessary. It also causes error messages when the C version *//* of the code created from this by f2c is run with Purify. It *//* correctly complains that uninitialized memory is being read. *//* EWIN(1,I) = EWIN(1,I+1) - LFRAME *//* EWIN(2,I) = EWIN(2,I+1) - LFRAME */ obound[i__ - 1] = obound[i__]; voibuf[i__ * 2] = voibuf[(i__ + 1) * 2]; voibuf[(i__ << 1) + 1] = voibuf[(i__ + 1 << 1) + 1]; rmsbuf[i__ - 1] = rmsbuf[i__]; i__1 = contrl_1.order; for (j = 1; j <= i__1; ++j) { rcbuf[j + i__ * 10 - 11] = rcbuf[j + (i__ + 1) * 10 - 11]; } }/* Copy input speech, scale to sign+12 bit integers *//* Remove long term DC bias. *//* If the average value in the frame was over 1/4096 (after current *//* BIAS correction), then subtract that much more from samples in *//* next frame. If the average value in the frame was under *//* -1/4096, add 1/4096 more to samples in next frame. In all other *//* cases, keep BIAS the same. */ temp = 0.f; i__1 = contrl_1.lframe; for (i__ = 1; i__ <= i__1; ++i__) { inbuf[720 - contrl_1.lframe + i__ - 181] = speech[i__] * 4096.f - (*bias); temp += inbuf[720 - contrl_1.lframe + i__ - 181]; } if (temp > (real) contrl_1.lframe) { *bias += 1; } if (temp < (real) (-contrl_1.lframe)) { *bias += -1; }/* Place Voicing Window */ i__ = 721 - contrl_1.lframe; preemp_(&inbuf[i__ - 181], &pebuf[i__ - 181], &contrl_1.lframe, &precoef, zpre); onset_(pebuf, osbuf, osptr, &c__10, &c__181, &c__720, &contrl_1.lframe, st);/* MAXOSP is just a debugging variable. *//* MAXOSP = MAX( MAXOSP, OSPTR ) */ placev_(osbuf, osptr, &c__10, &obound[2], vwin, &c__3, &contrl_1.lframe, &c__90, &c__156, &c__307, &c__462);/* The Pitch Extraction algorithm estimates the pitch for a frame *//* of speech by locating the minimum of the average magnitude difference *//* function (AMDF). The AMDF operates on low-pass, inverse filtered *//* speech. (The low-pass filter is an 800 Hz, 19 tap, equiripple, FIR *//* filter and the inverse filter is a 2nd-order LPC filter.) The pitch *//* estimate is later refined by dynamic programming (DYPTRK). However, *//* since some of DYPTRK's parameters are a function of the voicing *//* decisions, a voicing decision must precede the final pitch estimation.*//* See subroutines LPFILT, IVFILT, and TBDM. *//* LPFILT reads indices LBUFH-LFRAME-29 = 511 through LBUFH = 720 *//* of INBUF, and writes indices LBUFH+1-LFRAME = 541 through LBUFH *//* = 720 of LPBUF. */ lpfilt_(&inbuf[228], &lpbuf[384], &c__312, &contrl_1.lframe);/* IVFILT reads indices (PWINH-LFRAME-7) = 353 through PWINH = 540 *//* of LPBUF, and writes indices (PWINH-LFRAME+1) = 361 through *//* PWINH = 540 of IVBUF. */ ivfilt_(&lpbuf[204], ivbuf, &c__312, &contrl_1.lframe, ivrc);/* TBDM reads indices PWINL = 229 through *//* (PWINL-1)+MAXWIN+(TAU(LTAU)-TAU(1))/2 = 452 of IVBUF, and writes *//* indices 1 through LTAU = 60 of AMDF. */ tbdm_(ivbuf, &c__156, tau, &c__60, amdf, &minptr, &maxptr, &mintau);/* Voicing decisions are made for each half frame of input speech. *//* An initial voicing classification is made for each half of the *//* analysis frame, and the voicing decisions for the present frame *//* are finalized. See subroutine VOICIN. *//* The voicing detector (VOICIN) classifies the input signal as *//* unvoiced (including silence) or voiced using the AMDF windowed *//* maximum-to-minimum ratio, the zero crossing rate, energy measures, *//* reflection coefficients, and prediction gains. *//* The pitch and voicing rules apply smoothing and isolated *//* corrections to the pitch and voicing estimates and, in the process, *//* introduce two frames of delay into the corrected pitch estimates and *//* voicing decisions. */ for (half = 1; half <= 2; ++half) { voicin_(&vwin[4], inbuf, lpbuf, buflim, &half, &amdf[minptr - 1], & amdf[maxptr - 1], &mintau, ivrc, obound, voibuf, &c__3, st); }/* Find the minimum cost pitch decision over several frames *//* given the current voicing decision and the AMDF array */ dyptrk_(amdf, &c__60, &minptr, &voibuf[7], pitch, &midx, st); ipitch = tau[midx - 1];/* Place spectrum analysis and energy windows */ placea_(&ipitch, voibuf, &obound[2], &c__3, vwin, awin, ewin, & contrl_1.lframe, &c__156);/* Remove short term DC bias over the analysis window, Put result in ABUF*/ lanal = awin[5] + 1 - awin[4]; dcbias_(&lanal, &pebuf[awin[4] - 181], abuf);/* ABUF(1:LANAL) is now defined. It is equal to *//* PEBUF(AWIN(1,AF):AWIN(2,AF)) corrected for short term DC bias. *//* Compute RMS over integer number of pitch periods within the *//* analysis window. *//* Note that in a hardware implementation this computation may be *//* simplified by using diagonal elements of PHI computed by MLOAD. */ i__1 = ewin[5] - ewin[4] + 1; energy_(&i__1, &abuf[ewin[4] - awin[4]], &rmsbuf[2]);/* Matrix load and invert, check RC's for stability */ mload_(&contrl_1.order, &c__1, &lanal, abuf, phi, psi); invert_(&contrl_1.order, phi, psi, &rcbuf[20]); rcchk_(&contrl_1.order, &rcbuf[10], &rcbuf[20]);/* Set return parameters */ voice[1] = voibuf[2]; voice[2] = voibuf[3]; *rms = rmsbuf[0]; i__1 = contrl_1.order; for (i__ = 1; i__ <= i__1; ++i__) { rc[i__] = rcbuf[i__ - 1]; } return 0;} /* analys_ */@1.1log@Initial revision@text@d3 4a6 1$Log$d11 1a11 3extern int analys_(real *speech, integer *voice, integer *pitch, real *rms, real *rc);extern int pitdec_(integer *pitch, integer *ptau);extern int initanalys_(void);d67 4a70 1/* $Log: analys.f,v $ */d160 2a161 2/* Subroutine */ int analys_0_(int n__, real *speech, integer *voice, integer *pitch, real *rms, real *rc, integer *ptau)a170 1 static logical first = TRUE_;d179 1a179 1 static real bias;d182 1a182 1 static integer awin[6] /* was [2][3] */;d185 2a186 2 static real zpre; static integer vwin[6] /* was [2][3] */;d190 4a193 3 static real pebuf[540], rcbuf[30] /* was [10][3] */, inbuf[540], lpbuf[ 696], ivbuf[312]; static integer osbuf[10];d195 3a197 3 , integer *, integer *, integer *); static integer osptr; extern /* Subroutine */ int initonset_(void), placea_(integer *, integer *d203 1a203 1 static integer obound[3];d206 3a208 3 real *, real *, integer *, real *, integer *, integer *, integer * ); static integer voibuf[8] /* was [2][4] */;d210 1a210 1 static real rmsbuf[3];d217 1a217 1 *, integer *, integer *), initvoicin_(void), initdyptrk_(void);d220 4a223 1/* $Log: config.fh,v $ */d237 4a240 1/* $Log: contrl.fh,v $ */a376 4 switch(n__) { case 1: goto L_pitdec; case 2: goto L_initanalys; }a377 4/* IF(LISTL.GE.3) THEN *//* WRITE(FDEBUG,900) NFRAME *//* 900 FORMAT(1X,//,65(2H- ),//,' ANALYSIS DATA -- FRAME',I6/) *//* END IF */d382 16a397 4 if (first) { initanalys_(); first = FALSE_; }d412 1a412 1 i__1 = osptr - 1;d419 1a419 1 osptr = j;d459 1a459 1 bias;d463 1a463 1 bias += 1;d466 1a466 1 bias += -1;d471 2a472 2 &zpre); onset_(pebuf, osbuf, &osptr, &c__10, &c__181, &c__720, &contrl_1.lframe);d478 1a478 1 placev_(osbuf, &osptr, &c__10, &obound[2], vwin, &c__3, &contrl_1.lframe, d527 1a527 1 amdf[maxptr - 1], &mintau, ivrc, obound, voibuf, &c__3);d531 1a531 1 dyptrk_(amdf, &c__60, &minptr, &voibuf[7], pitch, &midx);a541 12/* IF ((AWIN(1,AF) .LT. SBUFL) .OR. (SBUFH .LT. AWIN(2,AF))) THEN *//* WRITE (2,999) AWIN(1,AF), AWIN(2,AF), SBUFL, SBUFH *//* 999 FORMAT(1X,'AWIN (',I4,':',I4, *//* 1 ') goes outside of PEBUFs range (',I4,':',I4,')') *//* STOP *//* END IF *//* IF (MAXWIN .LT. LANAL) THEN *//* WRITE (2,998) LANAL, MAXWIN *//* 998 FORMAT(1X,'LANAL (',I4, *//* 1 ') goes outside of ABUFs range (1:',I4,')') *//* STOP *//* END IF */a545 7/* IF ( (EWIN(1,AF) .LT. AWIN(1,AF)) *//* 1 .OR. (AWIN(2,AF) .LT. EWIN(2,AF))) THEN *//* WRITE (2,997) EWIN(1,AF), EWIN(2,AF), AWIN(1,AF), AWIN(2,AF) *//* 997 FORMAT(1X,'EWIN (',I4,':',I4, *//* 1 ') goes outside of AWINs range (',I4,':',I4,')') *//* STOP *//* END IF */a548 7/* IF (LANAL .LT. ORDER) THEN *//* WRITE (2,996) LANAL, ORDER *//* 996 FORMAT(1X,'MLOAD will read outside of ABUFs defined range ', *//* 1 'of (1:LANAL=',I4,') because LANAL is less than', *//* 1 ' ORDER=',I4) *//* STOP *//* END IF */a559 103/* Print out test data *//* IF(LISTL.GE.3) THEN *//* IF(LISTL.GE.4) THEN *//* IF(LISTL.GE.6) THEN *//* WRITE(FDEBUG,980) 'INBUF:',INBUF *//* WRITE(FDEBUG,980) 'LPBUF:',LPBUF *//* WRITE(FDEBUG,980) 'IVBUF:',IVBUF *//* WRITE(FDEBUG,980) 'PEBUF:',PEBUF *//* END IF *//* WRITE(FDEBUG,980) 'AMDF:',AMDF *//* END IF *//* IF(OSPTR.GT.1) WRITE(FDEBUG,970) *//* 1 'OSBUF Onset Locations:', (OSBUF(I),I=1,OSPTR-1) *//* IF(LISTL.GE.4) THEN *//* WRITE(FDEBUG,980) 'PHI Matrix Values:', *//* 1 ((PHI(I,J),J=1,ORDER),I=1,ORDER) *//* WRITE(FDEBUG,980) 'PSI Vector Values:',PSI *//* 970 FORMAT(1X,A,100(/1X,20I6)) *//* 980 FORMAT(1X,A,100(/1X,10F12.1)) *//* END IF *//* WRITE(FDEBUG,990) *//* 990 FORMAT(' FRAME AWIN EWIN BIAS',T34, *//* 1 'V/UV Pitch RMS',T54, *//* 1 'RC1 RC2 RC3 RC4 RC5 ', *//* 1 'RC6 RC7 RC8 RC9 RC10') *//* WRITE(FDEBUG,992) NFRAME, AWIN(1,AF), AWIN(2,AF), *//* 1 EWIN(1,AF), EWIN(2,AF), BIAS, *//* 1 VOIBUF(2,AF), IPITCH, RMSBUF(AF), (RCBUF(I,AF),I=1,ORDER) *//* 992 FORMAT(1X,I6,2I4,1X,2I4,F6.1,T34,I2,I8,F6.0,T50,10F8.3) *//* END IF */ return 0;/* ******************************************************************* *//* Decode pitch index (PITCH) to pitch period (PTAU) *//* ******************************************************************* */L_pitdec: if (*pitch >= 1 && *pitch <= 60) { *ptau = tau[*pitch - 1]; } else { *ptau = 0; } return 0;L_initanalys:/* Set FIRST to .FALSE., so that just in case someone calls *//* INITANALYS before calling ANALYS for the first time, then this *//* entry will not be called by ANALYS itself. */ first = FALSE_;/* Initialize local state in all subroutines that have local state. */ initonset_(); initvoicin_(); initdyptrk_();/* INBUF, PEBUF, LPBUF, and IVBUF were not initialized in the *//* original code. Initial values of 0 appear to be safe. */ for (i__ = 181; i__ <= 720; ++i__) { inbuf[i__ - 181] = 0.f; pebuf[i__ - 181] = 0.f; } for (i__ = 25; i__ <= 720; ++i__) { lpbuf[i__ - 25] = 0.f; } for (i__ = 229; i__ <= 540; ++i__) { ivbuf[i__ - 229] = 0.f; } bias = 0.f;/* Although OSBUF is saved from one invocation to the next, it need *//* not have an initial defined value, because OSPTR is initialized *//* to 1, and only entries 1 through OSPTR-1 may be read without *//* writing them first. */ osptr = 1; for (i__ = 1; i__ <= 3; ++i__) { obound[i__ - 1] = 0; }/* Should other indices of VWIN and AWIN be initialized, or is this *//* unnecessary? If unnecessary, why? */ vwin[4] = 307; vwin[5] = 462; awin[4] = 307; awin[5] = 462;/* VOIBUF was not initialized in the original code. I believe *//* initializing it to all 0's is a safe decision, given that its *//* contents are always 0/1 truth values representing the decision *//* of whether a half-frame was voiced or not. */ for (i__ = 1; i__ <= 2; ++i__) { for (j = 0; j <= 3; ++j) { voibuf[i__ + (j << 1) - 1] = 0; } }/* RMSBUF and RCBUF were also not initialized in the original code. *//* Again, initial values of 0 appear to be safe. */ for (i__ = 1; i__ <= 3; ++i__) { rmsbuf[i__ - 1] = 0.f; i__1 = contrl_1.order; for (j = 1; j <= i__1; ++j) { rcbuf[j + i__ * 10 - 11] = 0.f; } } zpre = 0.f;a561 19/* Subroutine */ int analys_(real *speech, integer *voice, integer *pitch, real *rms, real *rc){ return analys_0_(0, speech, voice, pitch, rms, rc, (integer *)0); }/* Subroutine */ int pitdec_(integer *pitch, integer *ptau){ return analys_0_(1, (real *)0, (integer *)0, pitch, (real *)0, (real *)0, ptau); }/* Subroutine */ int initanalys_(void){ return analys_0_(2, (real *)0, (integer *)0, (integer *)0, (real *)0, ( real *)0, (integer *)0); }@
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -