annotate libao2/firfilter.c @ 12022:293141b57c01

Use MultiplyElement to control volume. Works with multiple videos at the same time and even when NAS does not control the mixer or it is unavailable. Show buffer underrun hint only once and add missing linebreaks.
author ranma
date Sat, 13 Mar 2004 21:54:35 +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