sigproc.c
来自「speech signal process tools」· C语言 代码 · 共 631 行 · 第 1/2 页
C
631 行
/* * 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-1996 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: Derek Lin, David Talkin * * Brief description: * A collection of pretty generic signal-processing routines. * * */static char *sccs_id = "@(#)sigproc.c 1.4 9/9/96 ERL";#include <math.h>#include <malloc.h>#include <esps/esps.h>#include "f0.h"#include "f0_structs.h"/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* Return a time-weighting window of type type and length n in dout. * Dout is assumed to be at least n elements long. Type is decoded in * the switch statement below. */int get_window(dout, n, type) register float *dout; register int n, type;{ static float *din = NULL; static int n0 = 0; float preemp = 0.0; if(n > n0) { register float *p; register int i; if(din) free(din); din = NULL; if(!(din = (float*)malloc(sizeof(float)*n))) { Fprintf(stderr,"Allocation problems in get_window()\n"); return(FALSE); } for(i=0, p=din; i++ < n; ) *p++ = 1; n0 = n; } return(window(din, dout, n, preemp, type));} /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* Apply a rectangular window (i.e. none). Optionally, preemphasize. */void rwindow(din, dout, n, preemp) register float *din; register float *dout, preemp; register int n;{ register float *p; /* If preemphasis is to be performed, this assumes that there are n+1 valid samples in the input buffer (din). */ if(preemp != 0.0) { for( p=din+1; n-- > 0; ) *dout++ = (float)(*p++) - (preemp * *din++); } else { for( ; n-- > 0; ) *dout++ = *din++; }}/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* Generate a cos^4 window, if one does not already exist. */void cwindow(din, dout, n, preemp) register float *din; register float *dout, preemp; register int n;{ register int i; register float *p; static int wsize = 0; static float *wind=NULL; register float *q, co; if(wsize != n) { /* Need to create a new cos**4 window? */ register double arg, half=0.5; if(wind) wind = (float*)realloc(wind,n*sizeof(float)); else wind = (float*)malloc(n*sizeof(float)); wsize = n; for(i=0, arg=3.1415927*2.0/(wsize), q=wind; i < n; ) { co = half*(1.0 - cos((half + (double)i++) * arg)); *q++ = co * co * co * co; } }/* If preemphasis is to be performed, this assumes that there are n+1 valid samples in the input buffer (din). */ if(preemp != 0.0) { for(i=n, p=din+1, q=wind; i--; ) *dout++ = *q++ * ((float)(*p++) - (preemp * *din++)); } else { for(i=n, q=wind; i--; ) *dout++ = *q++ * *din++; }}/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* Generate a Hamming window, if one does not already exist. */void hwindow(din, dout, n, preemp) register float *din; register float *dout, preemp; register int n;{ register int i; register float *p; static int wsize = 0; static float *wind=NULL; register float *q; if(wsize != n) { /* Need to create a new Hamming window? */ register double arg, half=0.5; if(wind) wind = (float*)realloc(wind,n*sizeof(float)); else wind = (float*)malloc(n*sizeof(float)); wsize = n; for(i=0, arg=3.1415927*2.0/(wsize), q=wind; i < n; ) *q++ = (.54 - .46 * cos((half + (double)i++) * arg)); }/* If preemphasis is to be performed, this assumes that there are n+1 valid samples in the input buffer (din). */ if(preemp != 0.0) { for(i=n, p=din+1, q=wind; i--; ) *dout++ = *q++ * ((float)(*p++) - (preemp * *din++)); } else { for(i=n, q=wind; i--; ) *dout++ = *q++ * *din++; }}/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* Generate a Hanning window, if one does not already exist. */void hnwindow(din, dout, n, preemp) register float *din; register float *dout, preemp; register int n;{ register int i; register float *p; static int wsize = 0; static float *wind=NULL; register float *q; if(wsize != n) { /* Need to create a new Hanning window? */ register double arg, half=0.5; if(wind) wind = (float*)realloc(wind,n*sizeof(float)); else wind = (float*)malloc(n*sizeof(float)); wsize = n; for(i=0, arg=3.1415927*2.0/(wsize), q=wind; i < n; ) *q++ = (half - half * cos((half + (double)i++) * arg)); }/* If preemphasis is to be performed, this assumes that there are n+1 valid samples in the input buffer (din). */ if(preemp != 0.0) { for(i=n, p=din+1, q=wind; i--; ) *dout++ = *q++ * ((float)(*p++) - (preemp * *din++)); } else { for(i=n, q=wind; i--; ) *dout++ = *q++ * *din++; }}/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* Apply a window of type type to the short PCM sequence of length n * in din. Return the floating-point result sequence in dout. If preemp * is non-zero, apply preemphasis to tha data as it is windowed. */int window(din, dout, n, preemp, type) register float *din; register float *dout, preemp; register int n; int type;{ switch(type) { case 0: /* rectangular */ rwindow(din, dout, n, preemp); break; case 1: /* Hamming */ hwindow(din, dout, n, preemp); break; case 2: /* cos^4 */ cwindow(din, dout, n, preemp); break; case 3: /* Hanning */ hnwindow(din, dout, n, preemp); break; default: Fprintf(stderr,"Unknown window type (%d) requested in window()\n",type); return(FALSE); } return(TRUE);}/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* Compute the pp+1 autocorrelation lags of the windowsize samples in s. * Return the normalized autocorrelation coefficients in r. * The rms is returned in e. */void autoc( windowsize, s, p, r, e ) register int p, windowsize; register float *s, *e; register float *r;{ register int i, j; register float *q, *t, sum, sum0; for( i=windowsize, q=s, sum0=0.0; i--;) { sum = *q++; sum0 += sum*sum; } *r = 1.; /* r[0] will always =1. */ if(sum0 == 0.0) { /* No energy: fake low-energy white noise. */ *e = 1.; /* Arbitrarily assign 1 to rms. */ /* Now fake autocorrelation of white noise. */ for ( i=1; i<=p; i++){ r[i] = 0.; } return; } *e = sqrt((double)(sum0/windowsize)); sum0 = 1.0/sum0; for( i=1; i <= p; i++){ for( sum=0.0, j=windowsize-i, q=s, t=s+i; j--; ) sum += (*q++) * (*t++); *(++r) = sum*sum0; }}/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* Using Durbin's recursion, convert the autocorrelation sequence in r * to reflection coefficients in k and predictor coefficients in a. * The prediction error energy (gain) is left in *ex. * Note: durbin returns the coefficients in normal sign format. * (i.e. a[0] is assumed to be = +1.) */void durbin ( r, k, a, p, ex) register int p; /* analysis order */ register float *r, *k, *a, *ex;{ float bb[BIGSORD]; register int i, j; register float e, s, *b = bb; e = *r; *k = -r[1]/e; *a = *k; e *= (1. - (*k) * (*k)); for ( i=1; i < p; i++){ s = 0; for ( j=0; j<i; j++){ s -= a[j] * r[i-j]; } k[i] = ( s - r[i+1] )/e; a[i] = k[i]; for ( j=0; j<=i; j++){ b[j] = a[j]; } for ( j=0; j<i; j++){ a[j] += k[i] * b[i-j-1]; } e *= ( 1. - (k[i] * k[i]) ); } *ex = e;}/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* Compute the autocorrelations of the p LP coefficients in a. * (a[0] is assumed to be = 1 and not explicitely accessed.) * The magnitude of a is returned in c. * 2* the other autocorrelation coefficients are returned in b. */void a_to_aca ( a, b, c, p )float *a, *b, *c;register int p;{ register float s, *ap, *a0; register int i, j; for ( s=1., ap=a, i = p; i--; ap++ ) s += *ap * *ap; *c = s; for ( i = 1; i <= p; i++){ s = a[i-1]; for (a0 = a, ap = a+i, j = p-i; j--; ) s += (*a0++ * *ap++); *b++ = 2. * s; }}/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* Compute the Itakura LPC distance between the model represented * by the signal autocorrelation (r) and its residual (gain) and * the model represented by an LPC autocorrelation (c, b). * Both models are of order p. * r is assumed normalized and r[0]=1 is not explicitely accessed. * Values returned by the function are >= 1.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?