annotate libao2/firfilter.c @ 6214:0398cb49fe5e

aRts audio out support by Michele Balistreri <brain at email.it>
author atmos4
date Tue, 28 May 2002 01:52:40 +0000
parents f99944f9f427
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3848
f99944f9f427 fix for qnx
alex
parents: 3495
diff changeset
1 #include <inttypes.h>
3495
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
2 #include <math.h>
3483
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
3
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
4 static double desired_7kHz_lowpass[] = {1.0, 0.0};
3495
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
5 static double weights_7kHz_lowpass[] = {0.2, 2.0};
3483
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
6
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
7 double *calc_coefficients_7kHz_lowpass(int rate)
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
8 {
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
9 double *result = (double *)malloc(32*sizeof(double));
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
10 double bands[4];
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
11
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
12 bands[0] = 0.0; bands[1] = 6800.0/rate;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
13 bands[2] = 8500.0/rate; bands[3] = 0.5;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
14
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
15 remez(result, 32, 2, bands,
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
16 desired_7kHz_lowpass, weights_7kHz_lowpass, BANDPASS);
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
17
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
18 return result;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
19 }
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
20
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
21 #if 0
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
22
3495
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
23 static double desired_125Hz_lowpass[] = {1.0, 0.0};
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
24 static double weights_125Hz_lowpass[] = {0.2, 2.0};
3483
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
25
3495
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
26 double *calc_coefficients_125Hz_lowpass(int rate)
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
27 {
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
28 double *result = (double *)malloc(256*sizeof(double));
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
29 double bands[4];
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
30
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
31 bands[0] = 0.0; bands[1] = 125.0/rate;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
32 bands[2] = 175.0/rate; bands[3] = 0.5;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
33
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
34 remez(result, 256, 2, bands,
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
35 desired_125Hz_lowpass, weights_125Hz_lowpass, BANDPASS);
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
36
3483
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
37 return result;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
38 }
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
39
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
40 #endif
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
41
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
42 int16_t firfilter(int16_t *buf, int pos, int len, int count, double *coefficients)
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
43 {
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
44 double result = 0.0;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
45 int count1, count2;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
46 int16_t *ptr;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
47
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
48 if (pos >= count) {
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
49 pos -= count;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
50 count1 = count; count2 = 0;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
51 }
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
52 else {
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
53 count2 = pos;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
54 count1 = count - pos;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
55 pos = len - count1;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
56 }
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
57 //fprintf(stderr, "pos=%d, count1=%d, count2=%d\n", pos, count1, count2);
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
58
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
59 // high part of window
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
60 ptr = &buf[pos];
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
61 while (count1--) result += *ptr++ * *coefficients++;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
62 // wrapped part of window
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
63 while (count2--) result += *buf++ * *coefficients++;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
64 return result;
f1c6716e7554 FIR filter implementation for surround sound lowpass
steve
parents:
diff changeset
65 }
3495
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
66
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
67 void dump_filter_coefficients(double *coefficients)
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
68 {
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
69 int i;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
70 fprintf(stderr, "pl_surround: Filter coefficients are: \n");
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
71 for (i=0; (i<32); i++) {
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
72 fprintf(stderr, " [%2d]: %23.20f\n", i, coefficients[i]);
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
73 }
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
74 }
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
75
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
76 #ifdef TESTING
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
77
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
78 #define PI 3.1415926536
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
79
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
80 // For testing purposes, fill a buffer with some sine-wave tone
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
81 void sinewave(int16_t *output, int samples, int incr, int freq, double phase, int samplerate)
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
82 {
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
83 double radians_per_sample = 2*PI / ((0.0+samplerate) / freq), r;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
84
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
85 //fprintf(stderr, "samples=%d tone freq=%d, samplerate=%d, radians/sample=%f\n",
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
86 // samples, freq, samplerate, radians_per_sample);
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
87 r = phase;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
88 while (samples--) {
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
89 *output = sin(r)*10000; output = &output[incr];
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
90 r += radians_per_sample;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
91 }
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
92 }
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
93
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
94 // Pass various frequencies through a FIR filter and report amplitudes
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
95 void testfilter(double *coefficients, int count, int samplerate)
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
96 {
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
97 int16_t wavein[8192]; //, waveout[2048];
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
98 int sample, samples, maxsample, minsample, totsample;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
99 int nyquist=samplerate/2;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
100 int freq, i;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
101
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
102 for (freq=25; freq<nyquist; freq+=25) {
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
103 // Make input tone
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
104 sinewave(wavein, 8192, 1, freq, 0.0, samplerate);
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
105 //for (i=0; i<32; i++)
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
106 // fprintf(stderr, "%5d\n", wavein[i]);
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
107 // Filter through the filter, measure results
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
108 maxsample=0; minsample=1000000; totsample=0; samples=0;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
109 for (i=2048; i<8192; i++) {
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
110 //waveout[i] = wavein[i];
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
111 sample = abs(firfilter(wavein, i, 8192, count, coefficients));
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
112 if (sample > maxsample) maxsample=sample;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
113 if (sample < minsample) minsample=sample;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
114 totsample += sample; samples++;
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
115 }
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
116 // Report results
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
117 fprintf(stderr, "%5d %5d %5d %5d %f\n", freq, totsample/samples, maxsample, minsample, 10*log((totsample/samples)/6500.0));
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
118 }
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
119 }
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
120
cc1c879533ee tweaked surround lowpass filter, included some new test code
steve
parents: 3483
diff changeset
121 #endif