-
Notifications
You must be signed in to change notification settings - Fork 0
/
fidlib.txt
650 lines (506 loc) · 24.7 KB
/
fidlib.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
Fidlib: Run-time filter design and execution library
----------------------------------------------------
Copyright (c) 2002-2004 Jim Peters <http://uazu.net/>. This library
is released under the GNU Lesser General Public License (LGPL) version
2.1 as published by the Free Software Foundation. See the file
COPYING_LIB, or visit <http://www.fsf.org/licenses/licenses.html>.
"This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
This library was originally designed as a backend for the 'Fiview'
application, and to provide performance filtering services to EEG
applications, such as those in the OpenEEG project:
http://uazu.net/fiview/
http://openeeg.sf.net/
See Fiview for a more interactive introduction to the filters, more
related documentation, and for the opportunity to generate even higher
performing filters through generating C code for a single class of
filters, compiling it, and at run-time filling in the coefficients
using fidlib.
Jim
--
Jim Peters (_)/=\~/_(_) jim/uazu.net
(_) /=\ ~/_ (_)
Uazú (_) /=\ ~/_ (_) http://
Brighton, UK (_) ____ /=\ ____ ~/_ ____ (_) uazu.net
------------------------------------------------------------------------
0. Contents
===========
1. General notes
1.1 Building
1.2 Fidlib predefined filter specifications
1.3 Fidlib extended filter specification
2. Fidlib C API
2.1 Housekeeping routines
2.2 Filter creation
2.3 Operations on filters
2.4 Running the filter
3. Predefined filter notes
3.1 Filters from Dr Tony Fisher's "mkfilter"
3.2 Filters from Robert Bristow-Johnson's "audio EQ cookbook"
3.3 Miscellaneous filters
4. Changelog
------------------------------------------------------------------------
1. General notes
================
1.1 Building
------------
To include this library in your application, build fidlib.c along with
your other C files. The fidlib.c file #includes all the other source
files it needs. You will also need to #include "fidlib.h" in your
source files to get the structure and function declarations.
There are three choices for the filter engine, but only one of these
(the default) is actually useful. The 'combined' option can be slower
and is unstable for larger filters (this is the equivalent to the
original 'mkfilter' method) and the JIT compiler option is no longer
maintained as it was only slightly faster than the 'cmdlist' option.
This leaves 'cmdlist' as the recommended and default option. The
'cmdlist' option should be portable to other processors as well (tested
on ix86 and PowerPC), which the JIT option certainly wasn't.
Target-specific fixes are selected according to which of the T_*
macros is defined at build-time. See the source. Targets defined so
far are:
T_LINUX
T_MINGW
T_MSVC
1.2 Fidlib predefined filter specifications
-------------------------------------------
The filter specification string can be used to completely specify a
predefined filter, or for fid_design() it can also be used with the
frequency or frequency range missing, in which case default values are
picked up from values passed directly to the routine.
The spec consists of a series of letters usually followed by the order
of the filter and then by any other parameters required, preceded by
slashes. For example:
LpBu4/20.4 Lowpass butterworth, 4th order, -3.01dB at 20.4Hz
BpBu2/3-4 Bandpass butterworth, 2nd order, from 3 to 4Hz
BpBu2/=3-4 Same filter, but adjusted exactly to the range given
BsRe/1000/10 Bandstop resonator, Q=1000, frequency 10Hz
The routines fid_design() or fid_parse() are used to convert this
spec-string into filter coefficients and a description (if required).
The list of available filters can be generated with 'firun -L'. For
more details of the predefined filter types, see section 3 of this
document.
Note that filter frequencies should be specified in the same units as
the sampling rate, i.e. normally in Hz. However, all filters work
internally with the ratio of freq/sampling_rate, so you can use a
sampling rate of 1.0 and frequency values of 0 to 0.5 (Nyquist) if you
prefer.
The auto-adjust option, selected by prefixing the frequency or frequency
range with '=', automatically adjusts the -3.01dB points to the given
frequencies with a kind of binary search. See Fiview for more details
on this. This might be useful with some lower-order filters where the
-3.01dB points don't come out quite right otherwise.
1.3 Fidlib extended filter specification
----------------------------------------
With fid_parse() and the 'fiview' and 'firun' tools it is possible to
define filters that consist of chains of predefined filters and/or raw
IIR/FIR filters. It is perhaps easier to demonstrate this with
examples before explaining the format:
Just using coefficients:
0.9972 / -1 1.9955 -0.9971 x 1 -1.9985 1 / -1 1.9959 -0.9973 x 1 -1.9985 1
or using a predefined filter types:
LpBe3/0.05
BpBu5/=0.05-0.08
or using combinations:
0.9972 / -1 1.9955 -0.9971 x 1 -1.9985 1 x LpBe3/0.05
LpBe3/0.05 x LpBe5/0.03
BsBu10/139-147 x HsBq/0.8/-15/12000
When a filter is given in terms of FIR/IIR coefficients, use 'x' to
start an FIR list, and '/' to start an IIR list. The first list is
assumed to be an FIR list if no 'x' or '/' is included. The order of
coefficients compared to time zero is closest first to farthest last.
So 'x 0 0 1' would be a delay of two samples.
To make this clearer, the filter "x A B C" corresponds to:
y[n] == A.x[n] + B.x[n-1] + C.x[n-2]
and "/ D E F" corresponds to:
D.y[n] + E.y[n-1] + F.y[n-2] == x[n]
where y[] is the output, and x[] is the input. This is the most
symmetrical way of expressing the filters, although obviously the IIR
expression has to be rearranged for computation.
It is good to keep IIR/FIR filters in pairs because they can share
buffers that way, allowing them to run faster. For examples, see the
output of the predefined filters in Fiview or with 'firun -D'.
------------------------------------------------------------------------
2. Fidlib C API
===============
2.1 Housekeeping routines
-------------------------
str= fid_version();
Return a static string containing the fidlib version number, for
example "0.9.9".
void my_error_func(char *err) { ... };
fid_set_error_handler(&my_error_func);
Setup a routine that will be called if there is a fatal error in
fidlib. The string passed to the error function describes the
error. You can handle the error in your own way (e.g. doing a
longjmp() or whatever). If your routine returns, then fidlib will
follow its default fatal error procedure, i.e. dump the error to
'stderr' and call exit(1).
fid_list_filters(stdout);
okay= fid_list_filters_buf(buf, buf+sizeof(buf));
List all the known filter types to either a FILE* or to a buffer.
'okay' is true if the text fitted inside the buffer provided. This
is the output of the 'firun -L' command.
2.2 Filter creation
-------------------
Filters are generated from specifications of various types, resulting
in a FidFilter object in memory. This should be free()d when no
longer required.
char *p;
FidFilter *ff;
double rate;
char *err;
err= fid_parse(rate, &p, &ff);
This is the most general-purpose filter-creation routine. It parses
an extended filter specification, possibly containing a chain of
several predefined and/or directly-specified FIR/IIR filters. It
stops at the first comma, semicolon, or unmatched closing ")]}"
brace. (This allows filter specifications to be used as part of a
higher level specification or configuration language). 'rate' is
the sampling rate. 'p' is the pointer to data to parse, and is
updated to point to the next character on successful return. 'ff'
points to the new FidFilter on successful return, which should be
free()d once finished with. On success, the 'err' return is zero.
Otherwise 'err' contains a strdup'd error string describing the
problem with the filter spec, which should be free()d once reported.
char *spec;
double rate, freq0, freq1;
int adj;
char *desc;
filt= fid_design(spec, rate, freq0, freq1, adj, &desc);
This routine may be changed/removed in a future version (it is here
to support Fiview at the moment).
Create a FidFilter based on a single predefined filter, specifying
sampling rate and default freq0/1 parameters (pass -ve values if
there is no default) and adjust flag 'adj'. Returns a strdup'd
description of the filter in 'desc' if a non-zero pointer is passed.
This routine drops dead with a fatal error if there is any problem
at all with the filter spec.
#define N_COEF <whatever>
double coef[N_COEF], gain;
gain= fid_design_coef(coef, N_COEF, spec, rate, freq0, freq1, adj);
Design a filter and dump out all the non-constant coefficients to
the given array. This is a support routine for the code generated
by Fiview. It allows a class of filters to be generated at
run-time, but using a hard-coded (Fiview-generated) filter
processing routine to run them, for maximum speed. The generated
code picks up all the non-constant coefficients from the coef[]
array filled in by this routine.
double arr[]= { ... };
filt= fid_cv_array(arr);
Generate a filter from a list of IIR and FIR coefficients in the
given double-array. Each sub-list of coefficients should take the
form:
'I' or 'F', <number-of-coeffs>, <coeff1>, <coeff2>, ...
Use 'I' for a list of IIR coefficients ('/ A B C ...') or 'F' for a
list for FIR coefficients ('x A B C ...'). Many 'I' or 'F'
sub-lists may be chained, and the end of the double[] list is marked
with a 0.0.
The purpose of this routine is to allow pre-prepared filters to be
included conveniently in C source as a double array. The returned
filter should be free()d once finished with.
char *spec, *fullspec, *minspec;
double freq0, freq1, minfreq0, minfreq1;
int minadj;
fid_rewrite_spec(spec, freq0, freq1, adj,
&fullspec, &minspec, &minfreq0, &minfreq1, &minadj);
free(fullspec);
free(minspec);
This is a support routine for Fiview, and may be adjusted in future.
It helps with handling incomplete filter-specs, merging in default
values and returning the result as both a fully-specified filter
'fullspec', and also as a minimally-specified filter and associated
default values: 'minspec' plus 'minfreq0', 'minfreq1', 'minadj'.
2.3 Operations on filters
-------------------------
filt= fid_cat(freeme, filt1, filt2, filt3, ..., NULL);
Merge a list of existing FidFilters into one FidFilter by chaining
them serially. If 'freeme' is non-0, the original filters
'filt1'/etc are free()d once read. The resulting filter should be
free()d once finished with.
filt2= fid_flatten(filt);
Flatten a filter, merging all component FIRs into one FIR, and all
component IIRs into one IIR. The resulting filter may run slightly
faster, but it will suffer from lower accuracy, and will be unstable
for higher-order filters. This is the equivalent of the original
'mkfilter' filter-running code. Really it is better to leave the
filter unflattened. The new filter returned should be free()d when
finished with. The original filter 'filt' is untouched.
double resp, freq, phase;
resp= fid_response(filt, freq);
resp= fid_response_pha(filt, freq, &phase);
Calculate the response of the filter at the given frequency. Note
that the frequency should be given as (freq/rate) in the range 0 to
0.5, i.e. expressed as a proportion of the sampling rate, from 0 to
the Nyquist frequency. The response at that frequency is returned.
In the case of fid_response_pha(), the phase is also returned in
'phase'. The phase is scaled to the range 0 to 1, for 0 to two-PI.
int delay;
delay= fid_calc_delay(filt);
Calculate the approximate signal delay that the filter introduces,
in samples. This searches the impulse response for the time at
which 50% of the weighted filter calculations are complete. Delays
longer than about 8,000,000 samples are not reported accurately.
2.4 Running the filter
----------------------
Fidlib's filter-running code is designed to go as fast as possible in a
general-purpose way. Two approaches were attempted, a JIT-compiler
approach, based on writing ix86 instructions to memory for the filter
core, and a command-list method, switching between fragments of
pre-generated code. The JIT version only gave a 20% advantage and was
non-portable, so it was abandoned. The command-list version has been
tested on ix86 and PowerPC and should be portable anywhere. For really
time-critical applications, though, to gain maximum speed for a
particular filter type, Fiview can be used to generate a special-purpose
routine.
To run a filter with 'fidlib' requires setting up a filter-run
instance and a buffer for each channel you wish to run through that
filter. A function pointer is returned that should be used to process
each input sample through its buffer to produce an output sample.
Here is an illustration of typical code:
FidRun *run;
FidFunc *funcp;
void *fbuf1, *fbuf2;
run= fid_run_new(filt, &funcp);
fbuf1= fid_run_newbuf(run);
fbuf2= fid_run_newbuf(run);
while (...) {
out_1= funcp(fbuf1, in_1);
out_2= funcp(fbuf2, in_2);
if (restart_required) fid_run_zapbuf(fbuf1);
...
}
fid_run_freebuf(fbuf2);
fid_run_freebuf(fbuf1);
fid_run_free(run);
If you are running hundreds of filters in parallel, you may prefer to
allocate your own buffer memory separately (e.g. as a large block).
In which case, use it in this way (assuming malloc() doesn't fail):
FidRun *run;
FidFunc *funcp;
int len;
void *fbuf1, *fbuf2;
run= fid_run_new(filt, &funcp);
len= fid_run_bufsize(run);
fbuf1= malloc(len); fid_run_initbuf(run, fbuf1);
fbuf2= malloc(len); fid_run_initbuf(run, fbuf2);
while (...) {
out_1= funcp(fbuf1, in_1);
out_2= funcp(fbuf2, in_2);
if (restart_required) fid_run_zapbuf(fbuf1);
...
}
free(fbuf2);
free(fbuf1);
fid_run_free(run);
------------------------------------------------------------------------
3. Predefined filter notes
==========================
The full list of filters as of fidlib 0.9.9 is as follows. This list
can also be generated with the fid_list_filters() call and the 'firun
-L' command:
BpRe/<value>/<freq>
Bandpass resonator, Q=<value> (0 means Inf), frequency <freq>
BsRe/<value>/<freq>
Bandstop resonator, Q=<value> (0 means Inf), frequency <freq>
ApRe/<value>/<freq>
Allpass resonator, Q=<value> (0 means Inf), frequency <freq>
Pi/<freq>
Proportional-integral filter, frequency <freq>
PiZ/<freq>
Proportional-integral filter, matched z-transform, frequency <freq>
LpBe<order>/<freq>
Lowpass Bessel filter, order <order>, -3.01dB frequency <freq>
HpBe<order>/<freq>
Highpass Bessel filter, order <order>, -3.01dB frequency <freq>
BpBe<order>/<range>
Bandpass Bessel filter, order <order>, -3.01dB frequencies <range>
BsBe<order>/<range>
Bandstop Bessel filter, order <order>, -3.01dB frequencies <range>
LpBu<order>/<freq>
Lowpass Butterworth filter, order <order>, -3.01dB frequency <freq>
HpBu<order>/<freq>
Highpass Butterworth filter, order <order>, -3.01dB frequency <freq>
BpBu<order>/<range>
Bandpass Butterworth filter, order <order>, -3.01dB frequencies <range>
BsBu<order>/<range>
Bandstop Butterworth filter, order <order>, -3.01dB frequencies <range>
LpCh<order>/<value>/<freq>
Lowpass Chebyshev filter, order <order>, passband ripple <value>dB,
-3.01dB frequency <freq>
HpCh<order>/<value>/<freq>
Highpass Chebyshev filter, order <order>, passband ripple <value>dB,
-3.01dB frequency <freq>
BpCh<order>/<value>/<range>
Bandpass Chebyshev filter, order <order>, passband ripple <value>dB,
-3.01dB frequencies <range>
BsCh<order>/<value>/<range>
Bandstop Chebyshev filter, order <order>, passband ripple <value>dB,
-3.01dB frequencies <range>
LpBeZ<order>/<freq>
Lowpass Bessel filter, matched z-transform, order <order>, -3.01dB
frequency <freq>
HpBeZ<order>/<freq>
Highpass Bessel filter, matched z-transform, order <order>, -3.01dB
frequency <freq>
BpBeZ<order>/<range>
Bandpass Bessel filter, matched z-transform, order <order>, -3.01dB
frequencies <range>
BsBeZ<order>/<range>
Bandstop Bessel filter, matched z-transform, order <order>, -3.01dB
frequencies <range>
LpBuZ<order>/<freq>
Lowpass Butterworth filter, matched z-transform, order <order>, -3.01dB
frequency <freq>
HpBuZ<order>/<freq>
Highpass Butterworth filter, matched z-transform, order <order>, -3.01dB
frequency <freq>
BpBuZ<order>/<range>
Bandpass Butterworth filter, matched z-transform, order <order>, -3.01dB
frequencies <range>
BsBuZ<order>/<range>
Bandstop Butterworth filter, matched z-transform, order <order>, -3.01dB
frequencies <range>
LpChZ<order>/<value>/<freq>
Lowpass Chebyshev filter, matched z-transform, order <order>, passband
ripple <value>dB, -3.01dB frequency <freq>
HpChZ<order>/<value>/<freq>
Highpass Chebyshev filter, matched z-transform, order <order>, passband
ripple <value>dB, -3.01dB frequency <freq>
BpChZ<order>/<value>/<range>
Bandpass Chebyshev filter, matched z-transform, order <order>, passband
ripple <value>dB, -3.01dB frequencies <range>
BsChZ<order>/<value>/<range>
Bandstop Chebyshev filter, matched z-transform, order <order>, passband
ripple <value>dB, -3.01dB frequencies <range>
LpBuBe<order>/<value>/<freq>
Lowpass Butterworth-Bessel <value>% cross, order <order>, -3.01dB
frequency <freq>
LpBq<optional-order>/<value>/<freq>
Lowpass biquad filter, order <order>, Q=<value>, -3.01dB frequency <freq>
HpBq<optional-order>/<value>/<freq>
Highpass biquad filter, order <order>, Q=<value>, -3.01dB frequency
<freq>
BpBq<optional-order>/<value>/<freq>
Bandpass biquad filter, order <order>, Q=<value>, centre frequency <freq>
BsBq<optional-order>/<value>/<freq>
Bandstop biquad filter, order <order>, Q=<value>, centre frequency <freq>
ApBq<optional-order>/<value>/<freq>
Allpass biquad filter, order <order>, Q=<value>, centre frequency <freq>
PkBq<optional-order>/<value>/<value>/<freq>
Peaking biquad filter, order <order>, Q=<value>, dBgain=<value>,
frequency <freq>
LsBq<optional-order>/<value>/<value>/<freq>
Lowpass shelving biquad filter, S=<value>, dBgain=<value>, frequency
<freq>
HsBq<optional-order>/<value>/<value>/<freq>
Highpass shelving biquad filter, S=<value>, dBgain=<value>, frequency
<freq>
LpBl/<freq>
Lowpass Blackman window, -3.01dB frequency <freq>
LpHm/<freq>
Lowpass Hamming window, -3.01dB frequency <freq>
LpHn/<freq>
Lowpass Hann window, -3.01dB frequency <freq>
LpBa/<freq>
Lowpass Bartlet (triangular) window, -3.01dB frequency <freq>
3.1 Filters from Dr Tony Fisher's "mkfilter"
--------------------------------------------
See fidmkf.h for details of the derivation of these filters from Dr
Fisher's code. Tony Fisher died in Feb-2000, aged 43, but his
mkfilter code is still available and in use on his site. See his
pages below:
http://www-users.cs.york.ac.uk/~fisher/
http://www-users.cs.york.ac.uk/~fisher/tribute.html
http://www-users.cs.york.ac.uk/~fisher/mkfilter/
Bessel: This IIR filter gives a nice domed response in frequency, and
also a nice domed response in time. This is something approaching
the ideal balance between time-locality and frequency-locality for
an IIR filter.
Butterworth: This IIR filter gives flat responses away from the
transition areas and sharp transitions, especially as the order
increases. However, this sharp frequency response is paid for with
a wider and wider time-response. In other words it gives sharply
defined frequency-locality, but less well-defined time-locality.
Chebychev: This IIR filter exchanges some of the flatness in the
passband of the Butterworth filter for a sharper fall-off at the
cut-off frequency. The resulting filter also has a less
well-defined time-locality (see the time response). The amount of
permitted passband ripple is specified in dB, and should be
negative, for example: "LpCh4/-0.1/100" or "LpCh4/-1/100".
All of these types come also in a matched-Z version (LpBeZ,HpBuZ,etc)
which uses the matched-Z transform instead of the bilinear transform.
This eliminates the FIR part of the filter for low-pass filters, making
them pure IIR. You really need to read what Tony Fisher has to say
about this on his site to understand whether to use it or not. Briefly
he suggests this option is useful for generating Bessel filters with
optimally linear phase response, or for generating filters that execute
slightly faster, but the bilinear transform is otherwise superior.
Resonators: These IIR filters are based on oscillators, equivalent to
a tuned circuit. The <value> gives the narrowness of the resonator
response. Low values give wider response and faster decay to the
oscillations. Infinity can be represented using a value of '0',
which gives a pure oscillator -- for example: "BpRe/0/0.1". The
all-pass version (ApRe) has unit response, but the phase varies with
frequency, changing rapidly around the resonant frequency. These
are all from mkfilter -- Tony Fisher there suggests that band-stop
and band-pass filters made with resonators are often more efficient
and better-behaved than Butterworth filters. See the mkfilter docs
for more info on all of this.
Proportional-integral: I don't know what these are for, and they're
not documented on the mkfilter site either. The IIR part, at least,
just totals up all the samples received (an 'integral'). I guess
you'll know if you want this. This is probably the digital version
of some analogue op-amp technique. Also note that they don't
display at all well in either mkfilter or Fiview!
"LpBuBe" is an experiment of mine, producing a low-pass filter that is a
percentage cross between a Butterworth and a Bessel filter. Whether
this has any practical signal-processing use, I'm not sure.
3.2 Filters from Robert Bristow-Johnson's "audio EQ cookbook"
-------------------------------------------------------------
These filters are designed for manipulating audio -- they provide
peaking and shelving filters in addition to more conventional
low-pass/high-pass filters. The filters are documented here:
http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
Although an order may be specified for these filters, it is optional.
Without an order, or with order == 1, the original filters from the
document are reproduced. If you specify an order N, then N identical
biquad filters are placed in series. (Actually the order is really 2N,
as a the base biquad filters are 2nd order.)
Biquad low-pass and high-pass filters: For a low-pass filter, the
significant Q values are Q=0.5, which is the maximum value to give no
overshoot in the time response, and Q=0.707, which gives the most
flat-topped frequency response without having a resonance 'lip'.
Biquad band-pass, band-stop, all-pass and peaking filters: For these,
larger Q values are good -- try up to Q=10 or more. The peaking
filter is designed to emphasise a frequency range. The second value
in this case is the peak gain in dB. For example: PkBq1/3/10/0.1
Biquad audio shelving filters: These use a 'shelf slope' parameter
instead of Q. S=1 gives the steepest slope without a lip, and lower
values give lower values of slope. The second parameter is the gain
in the affected area in dB.
3.3 Miscellaneous filters
-------------------------
Window functions: Bartlett, Hann, Hamming and Blackman window functions are
available here. These act as FIR low-pass filters. To understand these
filters better, it is good to try them in Fiview with a log display: type
'L5' and adjust to view the full frequency range. Also compare these
filters to Bessel IIR filters (e.g. LpBe6).
Note that fidlib doesn't provide a huge comprehensive list of filter
types, just the ones that seemed useful to add, mostly oriented towards
IIR filters, and building on Dr Tony Fisher's 'mkfilter' as a base. You
can construct other types of filters in coefficient form and run them
through fidlib directly using a call to fid_cv_array(). Other filters
may be added in future.
Note that for pure FIR filters, especially longer ones, fidlib may be
useful for calculating their response, however they may be better
processed using other code. For example, you might not need to apply
the FIR on every sample, or maybe you can use an FFT-based
acceleration of a convolution instead of calculating it the slow way,
sample by sample.
4. Changelog
------------
0.9.10 Fixed compilation warnings on GCC 4
0.9.9 First release separate from fiview
------------------------------------------------------------------------