### Definition of the Simplest Low-Pass

The simplest (and by no means ideal) low-pass filter is given by the following*difference equation*:

where is the filter input amplitude at time (or sample) , and is the output amplitude at time . The

*signal flow graph*(or

*simulation diagram*) for this little filter is given in Fig.1.2. The symbol ``'' means a delay of one sample,

*i.e.*, . It is important when working with spectra to be able to convert time from sample-numbers, as in Eq.(1.1) above, to seconds. A more ``physical'' way of writing the filter equation is

*seconds*by thinking . Be careful with integer expressions, however, such as , which would be seconds, not . Further discussion of signal representation and notation appears in §A.1. To further our appreciation of this example, let's write a computer subroutine to implement Eq.(1.1). In the computer, and are data arrays and is an array index. Since sound files may be larger than what the computer can hold in memory all at once, we typically process the data in blocks of some reasonable size. Therefore, the complete filtering operation consists of two loops, one within the other. The outer loop fills the input array and empties the output array , while the inner loop does the actual filtering of the array to produce . Let denote the block size (

*i.e.*, the number of samples to be processed on each iteration of the outer loop). In the C programming language, the inner loop of the subroutine might appear as shown in Fig.1.3. The outer loop might read something like ``fill from the input file,'' ``call

`simplp`,'' and ``write out .''

/* C function implementing the simplest lowpass: * * y(n) = x(n) + x(n-1) * */ double simplp (double *x, double *y, int M, double xm1) { int n; y[0] = x[0] + xm1; for (n=1; n < M ; n++) { y[n] = x[n] + x[n-1]; } return x[M-1]; } |

`xm1`. That way, both and can have the same array bounds ( ). For convenience, the value of

`xm1`appropriate for the

*next*call to

`simplp`is returned as the procedure's value. We may call

`xm1`the filter's

*state*. It is the current ``memory'' of the filter upon calling

`simplp`. Since this filter has only one sample of state, it is a

*first order*filter. When a filter is applied to successive blocks of a signal, it is necessary to save the filter state after processing each block. The filter state after processing block is then the starting state for block . Figure 1.4 illustrates a simple main program which calls

`simplp`. The length 10 input signal

`x`is processed in two blocks of length 5.

/* C main program for testing simplp */ main() { double x[10] = {1,2,3,4,5,6,7,8,9,10}; double y[10]; int i; int N=10; int M=N/2; /* block size */ double xm1 = 0; xm1 = simplp(x, y, M, xm1); xm1 = simplp(&x[M], &y[M], M, xm1); for (i=0;i<N;i++) { printf("x[%d]=%f\ty[%d]=%f\n",i,x[i],i,y[i]); } exit(0); } /* Output: * x[0]=1.000000 y[0]=1.000000 * x[1]=2.000000 y[1]=3.000000 * x[2]=3.000000 y[2]=5.000000 * x[3]=4.000000 y[3]=7.000000 * x[4]=5.000000 y[4]=9.000000 * x[5]=6.000000 y[5]=11.000000 * x[6]=7.000000 y[6]=13.000000 * x[7]=8.000000 y[7]=15.000000 * x[8]=9.000000 y[8]=17.000000 * x[9]=10.000000 y[9]=19.000000 */ |

*frequency response*of this filter.

**Next Section:**

Sine-Wave Analysis

**Previous Section:**

Why learn about filters?