📄 voicin.c
字号:
/*$Log: voicin.c,v $Revision 1.1.1.1 2001/11/19 19:50:17 smorlatFirst cvs.Revision 1.1.1.1 2001/08/08 21:29:08 simonFirst import * Revision 1.2 1996/08/20 20:45:00 jaf * Removed all static local variables that were SAVE'd in the Fortran * code, and put them in struct lpc10_encoder_state that is passed as an * argument. * * Removed init function, since all initialization is now done in * init_lpc10_encoder_state(). * * Revision 1.1 1996/08/19 22:30:14 jaf * Initial revision **/#ifdef P_R_O_T_O_T_Y_P_E_Sextern 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, struct lpc10_encoder_state *st);/* comlen contrl_ 12 *//*:ref: vparms_ 14 14 4 6 6 4 4 6 4 4 4 4 6 6 6 6 */#endif/* -- translated by f2c (version 19951025). You must link the resulting object file with the libraries: -lf2c -lm (in that order)*/#include "f2c.h"/* Common Block Declarations */extern struct { integer order, lframe; logical corrp;} contrl_;#define contrl_1 contrl_/****************************************************************************//* VOICIN Version 52 *//* $Log: voicin.c,v $/* Revision 1.1.1.1 2001/11/19 19:50:17 smorlat/* First cvs./*/* Revision 1.1.1.1 2001/08/08 21:29:08 simon/* First import/* * Revision 1.2 1996/08/20 20:45:00 jaf * Removed all static local variables that were SAVE'd in the Fortran * code, and put them in struct lpc10_encoder_state that is passed as an * argument. * * Removed init function, since all initialization is now done in * init_lpc10_encoder_state(). * * Revision 1.1 1996/08/19 22:30:14 jaf * Initial revision * *//* Revision 1.10 1996/03/29 17:59:14 jaf *//* Avoided using VALUE(9), although it shouldn't affect the function of *//* the code at all, because it was always multiplied by VDC(9,SNRL), *//* which is 0 for all values of SNRL. Still, if VALUE(9) had an initial *//* value of IEEE NaN, it might cause trouble (I don't know how IEEE *//* defines Nan * 0. It should either be NaN or 0.) *//* Revision 1.9 1996/03/29 17:54:46 jaf *//* Added a few comments about the accesses made to argument array VOIBUF *//* and the local saved array VOICE. *//* Revision 1.8 1996/03/27 18:19:54 jaf *//* Added an assignment to VSTATE that does not affect the function of the *//* program at all. The only reason I put it in was so that the tracing *//* statements at the end, when enabled, will print a consistent value for *//* VSTATE when HALF .EQ. 1, rather than a garbage value that could change *//* from one call to the next. *//* Revision 1.7 1996/03/26 20:00:06 jaf *//* Removed the inclusion of the file "vcomm.fh", and put its contents *//* into this file. It was included nowhere else but here. *//* Revision 1.6 1996/03/26 19:38:09 jaf *//* Commented out trace statements. *//* Revision 1.5 1996/03/19 20:43:45 jaf *//* Added comments about which indices of OBOUND and VOIBUF can be *//* accessed, and whether they are read or written. VOIBUF is fairly *//* messy. *//* Revision 1.4 1996/03/19 15:00:58 jaf *//* Moved the DATA statements for the *VDC* variables later, as it is *//* apparently illegal to have DATA statements before local variable *//* declarations. *//* Revision 1.3 1996/03/19 00:10:49 jaf *//* Heavily commented the local variables that are saved from one *//* invocation to the next, and how the local variable FIRST is used to *//* avoid the need to assign most of them initial values with DATA *//* statements. *//* A few should be initialized, but aren't. I've guessed initial values *//* for two of these, SFBUE and SLBUE, and I've convinced myself that for *//* VOICE, the effects of uninitialized values will die out after 2 or 3 *//* frame times. It would still be good to choose initial values for *//* these, but I don't know what reasonable values would be (0 comes to *//* mind). *//* Revision 1.2 1996/03/13 16:09:28 jaf *//* Comments added explaining which of the local variables of this *//* subroutine need to be saved from one invocation to the next, and which *//* do not. *//* WARNING! Some of them that should are never given initial values in *//* this code. Hopefully, Fortran 77 defines initial values for them, but *//* even so, giving them explicit initial values is preferable. *//* WARNING! VALUE(9) is used, but never assigned a value. It should *//* probably be eliminated from the code. *//* Revision 1.1 1996/02/07 14:50:28 jaf *//* Initial revision *//****************************************************************************//* Voicing Detection (VOICIN) makes voicing decisions for each half *//* frame of input speech. Tentative voicing decisions are made two frames*//* in the future (2F) for each half frame. These decisions are carried *//* through one frame in the future (1F) to the present (P) frame where *//* they are examined and smoothed, resulting in the final voicing *//* decisions for each half frame. *//* The voicing parameter (signal measurement) column vector (VALUE) *//* is based on a rectangular window of speech samples determined by the *//* window placement algorithm. The voicing parameter vector contains the*//* AMDF windowed maximum-to-minimum ratio, the zero crossing rate, energy*//* measures, reflection coefficients, and prediction gains. The voicing *//* window is placed to avoid contamination of the voicing parameter vector*//* with speech onsets. *//* The input signal is then classified as unvoiced (including *//* silence) or voiced. This decision is made by a linear discriminant *//* function consisting of a dot product of the voicing decision *//* coefficient (VDC) row vector with the measurement column vector *//* (VALUE). The VDC vector is 2-dimensional, each row vector is optimized*//* for a particular signal-to-noise ratio (SNR). So, before the dot *//* product is performed, the SNR is estimated to select the appropriate *//* VDC vector. *//* The smoothing algorithm is a modified median smoother. The *//* voicing discriminant function is used by the smoother to determine how*//* strongly voiced or unvoiced a signal is. The smoothing is further *//* modified if a speech onset and a voicing decision transition occur *//* within one half frame. In this case, the voicing decision transition *//* is extended to the speech onset. For transmission purposes, there are*//* constraints on the duration and transition of voicing decisions. The *//* smoother takes these constraints into account. *//* Finally, the energy estimates are updated along with the dither *//* threshold used to calculate the zero crossing rate (ZC). *//* Inputs: *//* VWIN - Voicing window limits *//* The indices read of arrays VWIN, INBUF, LPBUF, and BUFLIM *//* are the same as those read by subroutine VPARMS. *//* INBUF - Input speech buffer *//* LPBUF - Low-pass filtered speech buffer *//* BUFLIM - INBUF and LPBUF limits *//* HALF - Present analysis half frame number *//* MINAMD - Minimum value of the AMDF *//* MAXAMD - Maximum value of the AMDF *//* MINTAU - Pointer to the lag of the minimum AMDF value *//* IVRC(2) - Inverse filter's RC's *//* Only index 2 of array IVRC read under normal operation. *//* (Index 1 is also read when debugging is turned on.) *//* OBOUND - Onset boundary descriptions *//* Indices 1 through 3 read if (HALF .NE. 1), otherwise untouched.*//* AF - The analysis frame number *//* Output: *//* VOIBUF(2,0:AF) - Buffer of voicing decisions *//* Index (HALF,3) written. *//* If (HALF .EQ. 1), skip down to "Read (HALF,3)" below. *//* Indices (1,2), (2,1), (1,2), and (2,2) read. *//* One of the following is then done: *//* read (1,3) and possibly write (1,2) *//* read (1,3) and write (1,2) or (2,2) *//* write (2,1) *//* write (2,1) or (1,2) *//* read (1,0) and (1,3) and then write (2,2) or (1,1) *//* no reads or writes on VOIBUF *//* Finally, read (HALF,3) *//* Internal: *//* QS - Ratio of preemphasized to full-band energies *//* RC1 - First reflection coefficient *//* AR_B - Product of the causal forward and reverse pitch prediction gains*//* AR_F - Product of the noncausal forward and rev. pitch prediction gains*//* ZC - Zero crossing rate *//* DITHER - Zero crossing threshold level *//* MAXMIN - AMDF's 1 octave windowed maximum-to-minimum ratio *//* MINPTR - Location of minimum AMDF value *//* NVDC - Number of elements in each VDC vector *//* NVDCL - Number of VDC vectors *//* VDCL - SNR values corresponding to the set of VDC's *//* VDC - 2-D voicing decision coefficient vector *//* VALUE(9) - Voicing Parameters *//* VOICE(2,3)- History of LDA results *//* On every call when (HALF .EQ. 1), VOICE(*,I+1) is *//* shifted back to VOICE(*,I), for I=1,2. *//* VOICE(HALF,3) is written on every call. *//* Depending on several conditions, one or more of *//* (1,1), (1,2), (2,1), and (2,2) might then be read. *//* LBE - Ratio of low-band instantaneous to average energies *//* FBE - Ratio of full-band instantaneous to average energies *//* LBVE - Low band voiced energy *//* LBUE - Low band unvoiced energy *//* FBVE - Full band voiced energy *//* FBUE - Full band unvoiced energy *//* OFBUE - Previous full-band unvoiced energy *//* OLBUE - Previous low-band unvoiced energy *//* REF - Reference energy for initialization and DITHER threshold *//* SNR - Estimate of signal-to-noise ratio *//* SNR2 - Estimate of low-band signal-to-noise ratio *//* SNRL - SNR level number *//* OT - Onset transition present *//* VSTATE - Decimal interpretation of binary voicing classifications *//* FIRST - First call flag *//* This subroutine maintains local state from one call to the next. If *//* you want to switch to using a new audio stream for this filter, or *//* reinitialize its state for any other reason, call the ENTRY *//* INITVOICIN. *//* 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, struct lpc10_encoder_state *st){ /* Initialized data */ real *dither; static real vdc[100] /* was [10][10] */ = { 0.f,1714.f,-110.f, 334.f,-4096.f,-654.f,3752.f,3769.f,0.f,1181.f,0.f,874.f,-97.f, 300.f,-4096.f,-1021.f,2451.f,2527.f,0.f,-500.f,0.f,510.f,-70.f, 250.f,-4096.f,-1270.f,2194.f,2491.f,0.f,-1500.f,0.f,500.f,-10.f, 200.f,-4096.f,-1300.f,2e3f,2e3f,0.f,-2e3f,0.f,500.f,0.f,0.f, -4096.f,-1300.f,2e3f,2e3f,0.f,-2500.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f, 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f, 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f, 0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f }; static integer nvdcl = 5; static real vdcl[10] = { 600.f,450.f,300.f,200.f,0.f,0.f,0.f,0.f,0.f,0.f } ; /* System generated locals */ integer inbuf_offset, lpbuf_offset, i__1, i__2; real r__1, r__2; /* Builtin functions */ integer i_nint(real *); double sqrt(doublereal); /* Local variables */ real ar_b__, ar_f__; integer *lbve, *lbue, *fbve, *fbue; integer snrl, i__; integer *ofbue, *sfbue; real *voice; integer *olbue, *slbue; real value[9]; integer zc; logical ot; real qs; real *maxmin; integer vstate; real rc1; extern /* Subroutine */ int vparms_(integer *, real *, real *, integer *, integer *, real *, integer *, integer *, integer *, integer *, real *, real *, real *, real *); integer fbe, lbe; real *snr; real snr2;/* Global Variables: *//* Arguments *//* $Log: voicin.c,v $/* Revision 1.1.1.1 2001/11/19 19:50:17 smorlat/* First cvs./*/* Revision 1.1.1.1 2001/08/08 21:29:08 simon/* First import/* * Revision 1.2 1996/08/20 20:45:00 jaf * Removed all static local variables that were SAVE'd in the Fortran * code, and put them in struct lpc10_encoder_state that is passed as an * argument. * * Removed init function, since all initialization is now done in * init_lpc10_encoder_state(). * * Revision 1.1 1996/08/19 22:30:14 jaf * Initial revision * *//* Revision 1.3 1996/03/29 22:05:55 jaf *//* Commented out the common block variables that are not needed by the *//* embedded version. *//* Revision 1.2 1996/03/26 19:34:50 jaf *//* Added comments indicating which constants are not needed in an *//* application that uses the LPC-10 coder. *//* Revision 1.1 1996/02/07 14:44:09 jaf *//* Initial revision *//* LPC Processing control variables: *//* *** Read-only: initialized in setup *//* Files for Speech, Parameter, and Bitstream Input & Output, *//* and message and debug outputs. *//* Here are the only files which use these variables: *//* lpcsim.f setup.f trans.f error.f vqsetup.f *//* Many files which use fdebug are not listed, since it is only used in *//* those other files conditionally, to print trace statements. *//* integer fsi, fso, fpi, fpo, fbi, fbo, pbin, fmsg, fdebug *//* LPC order, Frame size, Quantization rate, Bits per frame, *//* Error correction *//* Subroutine SETUP is the only place where order is assigned a value, *//* and that value is 10. It could increase efficiency 1% or so to *//* declare order as a constant (i.e., a Fortran PARAMETER) instead of as *//* a variable in a COMMON block, since it is used in many places in the *//* core of the coding and decoding routines. Actually, I take that back. *//* At least when compiling with f2c, the upper bound of DO loops is *//* stored in a local variable before the DO loop begins, and then that is *//* compared against on each iteration. *//* Similarly for lframe, which is given a value of MAXFRM in SETUP. *//* Similarly for quant, which is given a value of 2400 in SETUP. quant *//* is used in only a few places, and never in the core coding and *//* decoding routines, so it could be eliminated entirely. *//* nbits is similar to quant, and is given a value of 54 in SETUP. *//* corrp is given a value of .TRUE. in SETUP, and is only used in the *//* subroutines ENCODE and DECODE. It doesn't affect the speed of the *//* coder significantly whether it is .TRUE. or .FALSE., or whether it is *//* a constant or a variable, since it is only examined once per frame. *//* Leaving it as a variable that is set to .TRUE. seems like a good *//* idea, since it does enable some error-correction capability for *//* unvoiced frames, with no change in the coding rate, and no noticeable *//* quality difference in the decoded speech. *//* integer quant, nbits *//* *** Read/write: variables for debugging, not needed for LPC algorithm *//* Current frame, Unstable frames, Output clip count, Max onset buffer, *//* Debug listing detail level, Line count on listing page *//* nframe is not needed for an embedded LPC10 at all. *//* nunsfm is initialized to 0 in SETUP, and incremented in subroutine *//* ERROR, which is only called from RCCHK. When LPC10 is embedded into *//* an application, I would recommend removing the call to ERROR in RCCHK, *//* and remove ERROR and nunsfm completely. *//* iclip is initialized to 0 in SETUP, and incremented in entry SWRITE in *//* sread.f. When LPC10 is embedded into an application, one might want *//* to cause it to be incremented in a routine that takes the output of */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -