LMMS
Loading...
Searching...
No Matches
FIR.h
Go to the documentation of this file.
1/*
2 dsp/FIR.h
3
4 Copyright 2003-10 Tim Goetze <tim@quitte.de>
5
6 http://quitte.de/dsp/
7
8 finite impulse response filters, with options for up- and down-sampling.
9
10*/
11/*
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 as published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA or point your web browser to http://www.gnu.org.
26*/
27
28#ifndef _FIR_H_
29#define _FIR_H_
30
31#include "util.h"
32
33namespace DSP {
34
35/* brute-force FIR filter with downsampling method (decimating).
36 *
37 * CAVEAT: constructing it from another FIR makes the filter share the other's
38 * kernel data set. IOW, the other FIR must be valid throughout the lifetime
39 * of this instance.
40 */
41class FIR
42{
43 public:
44 /* kernel length, history length - 1 */
45 int n, m;
46
47 /* coefficients, history */
48 sample_t * c, * x;
50
51 /* history index */
52 int h;
53
54 FIR (int N)
55 {
56 c = 0;
57 init (N);
58 }
59
60 FIR (FIR & fir)
61 {
62 c = fir.c;
63 init (fir.n);
64 }
65
66 FIR (int n, sample_t * kernel)
67 {
68 c = 0;
69 init (n);
70 memcpy (c, kernel, n * sizeof (*c));
71 }
72
74 {
75 if (!borrowed_kernel)
76 free (c);
77 free (x);
78 }
79
80 void init (int N)
81 {
82 n = N;
83
84 /* keeping history size a power of 2 makes it possible to wrap the
85 * history pointer by & instead of %, saving a few cpu cycles. */
87
88 if (c)
89 borrowed_kernel = true;
90 else
91 borrowed_kernel = false,
92 c = (sample_t *) malloc (n * sizeof (sample_t));
93
94 x = (sample_t *) malloc (m * sizeof (sample_t));
95
96 m -= 1;
97
98 reset();
99 }
100
101 void reset()
102 {
103 h = 0;
104 memset (x, 0, n * sizeof (sample_t));
105 }
106
107 /* TODO: write an SSE-enabled version */
109 {
110 x[h] = s;
111
112 s *= c[0];
113
114 for (int Z = 1, z = h - 1; Z < n; --z, ++Z)
115 s += c[Z] * x[z & m];
116
117 h = (h + 1) & m;
118
119 return s;
120 }
121
122 /* Z is the time, in samples, since the last non-zero sample.
123 * OVER is the oversampling factor. just here for documentation, use
124 * a FIRUpsampler instead.
125 */
126 template <int Z, int OVER>
128 {
129 x[h] = s;
130
131 s = 0;
132
133 /* for the interpolation, iterate over the history in z ^ -OVER
134 * steps -- all the samples between are 0.
135 */
136 for (int j = Z, z = h - Z; j < n; --z, j += OVER)
137 s += c[j] * x[z & m];
138
139 h = (h + 1) & m;
140
141 return s;
142 }
143
144 /* used in downsampling */
145 inline void store (sample_t s)
146 {
147 x[h] = s;
148 h = (h + 1) & m;
149 }
150};
151
152/* close relative of FIR, but distinct enough to not justify inheritance.
153 *
154 * the difference to the FIR is the shorter history length. don't need
155 * to clutter the d-cache with interleaved 0s.
156 *
157 * however, an initial test shows this to be a fraction *slower* than a
158 * complete FIR for N = 32, OVER = 4.
159 */
161{
162 public:
163 /* kernel length, history length - 1 */
164 int n, m;
165
166 /* oversampling ratio */
167 int over;
168
169 /* coefficients, history */
171
172 /* history index */
173 int h;
174
175 FIRUpsampler (int _n, int _over)
176 {
177 c = x = 0;
178 init (_n, _over);
179 }
180
181 FIRUpsampler (FIR & fir, int _over)
182 {
183 c = x = 0;
184 init (fir.n, _over);
185 memcpy (c, fir.c, n * sizeof (sample_t));
186 }
187
189 {
190 if (c) free (c);
191 if (x) free (x);
192 }
193
194 void init (int _n, int _over)
195 {
196 /* oversampling ratio must be multiple of FIR kernel length */
197 // assert (_n % _over == 0);
198
199 n = _n;
200 over = _over;
201
202 /* like FIR, keep the history buffer a power of 2; additionally,
203 * compress and don't store the 0 samples inbetween.
204 */
205 m = next_power_of_2 ((n + over - 1) / over);
206
207 c = (sample_t *) malloc (n * sizeof (sample_t));
208 x = (sample_t *) malloc (m * sizeof (sample_t));
209
210 m -= 1;
211
212 reset();
213 }
214
215 void reset()
216 {
217 h = 0;
218 memset (x, 0, (m + 1) * sizeof (sample_t));
219 }
220
221 /* upsample the given sample */
223 {
224 x[h] = s;
225
226 s = 0;
227
228 for (int Z = 0, z = h; Z < n; --z, Z += over)
229 s += c[Z] * x[z & m];
230
231 h = (h + 1) & m;
232
233 return s;
234 }
235
236 /* upsample a zero sample (interleaving), Z being the time, in samples,
237 * since the last non-0 sample. */
238 inline sample_t pad (int Z)
239 {
240 sample_t s = 0;
241
242 for (int z = h - 1; Z < n; --z, Z += over)
243 s += c[Z] * x[z & m];
244
245 return s;
246 }
247
248};
249
250}; /* namespace DSP */
251
252#endif /* _FIR_H_ */
LADSPA_Data sample_t
Definition basics.h:100
Definition FIR.h:42
int n
Definition FIR.h:45
sample_t * c
Definition FIR.h:48
sample_t process(sample_t s)
Definition FIR.h:108
~FIR()
Definition FIR.h:73
void init(int N)
Definition FIR.h:80
int m
Definition FIR.h:45
bool borrowed_kernel
Definition FIR.h:49
void reset()
Definition FIR.h:101
FIR(int N)
Definition FIR.h:54
sample_t * x
Definition FIR.h:48
FIR(FIR &fir)
Definition FIR.h:60
sample_t upsample(sample_t s)
Definition FIR.h:127
int h
Definition FIR.h:52
FIR(int n, sample_t *kernel)
Definition FIR.h:66
void store(sample_t s)
Definition FIR.h:145
void reset()
Definition FIR.h:215
sample_t pad(int Z)
Definition FIR.h:238
sample_t * x
Definition FIR.h:170
void init(int _n, int _over)
Definition FIR.h:194
~FIRUpsampler()
Definition FIR.h:188
sample_t upsample(sample_t s)
Definition FIR.h:222
int m
Definition FIR.h:164
int n
Definition FIR.h:164
int h
Definition FIR.h:173
FIRUpsampler(int _n, int _over)
Definition FIR.h:175
int over
Definition FIR.h:167
FIRUpsampler(FIR &fir, int _over)
Definition FIR.h:181
sample_t * c
Definition FIR.h:170
unsigned z
Definition inflate.c:1589
register unsigned j
Definition inflate.c:1576
unsigned s
Definition inflate.c:1555
Definition BiQuad.h:31
int next_power_of_2(int n)
Definition util.h:33
#define N
Definition nseel-cfunc.c:36
memcpy(hh, h, RAND_HEAD_LEN)
ZCONST uch * init
Definition extract.c:2392
char * malloc()