Merge lp:~alex.barker/mixxx/mixxx-libs into lp:~mixxxdevelopers/mixxx/trunk

Proposed by KWhat
Status: Merged
Merged at revision: 2953
Proposed branch: lp:~alex.barker/mixxx/mixxx-libs
Merge into: lp:~mixxxdevelopers/mixxx/trunk
Diff against target: 26249 lines (+12270/-13561)
72 files modified
mixxx/build/depends.py (+8/-23)
mixxx/build/qtcreator/mixxx.pro (+1/-1)
mixxx/lib/fidlib-0.9.10/COPYING (+340/-0)
mixxx/lib/fidlib-0.9.10/COPYING_LIB (+504/-0)
mixxx/lib/fidlib-0.9.10/fidlib.c (+2304/-0)
mixxx/lib/fidlib-0.9.10/fidlib.h (+77/-0)
mixxx/lib/fidlib-0.9.10/fidmkf.h (+846/-0)
mixxx/lib/fidlib-0.9.10/fidrf_cmdlist.h (+479/-0)
mixxx/lib/fidlib-0.9.10/fidrf_combined.h (+151/-0)
mixxx/lib/fidlib-0.9.10/fidrf_jit.h (+792/-0)
mixxx/lib/fidlib-0.9.9/COPYING (+0/-340)
mixxx/lib/fidlib-0.9.9/COPYING_LIB (+0/-504)
mixxx/lib/fidlib-0.9.9/fidlib.c (+0/-2302)
mixxx/lib/fidlib-0.9.9/fidlib.h (+0/-77)
mixxx/lib/fidlib-0.9.9/fidmkf.h (+0/-844)
mixxx/lib/fidlib-0.9.9/fidrf_cmdlist.h (+0/-479)
mixxx/lib/fidlib-0.9.9/fidrf_combined.h (+0/-150)
mixxx/lib/fidlib-0.9.9/fidrf_jit.h (+0/-792)
mixxx/lib/soundtouch-1.5.0/3dnow_win.cpp (+0/-349)
mixxx/lib/soundtouch-1.5.0/AAFilter.cpp (+0/-184)
mixxx/lib/soundtouch-1.5.0/AAFilter.h (+0/-91)
mixxx/lib/soundtouch-1.5.0/BPMDetect.cpp (+0/-308)
mixxx/lib/soundtouch-1.5.0/BPMDetect.h (+0/-161)
mixxx/lib/soundtouch-1.5.0/COPYING.TXT (+0/-458)
mixxx/lib/soundtouch-1.5.0/FIFOSampleBuffer.cpp (+0/-262)
mixxx/lib/soundtouch-1.5.0/FIFOSampleBuffer.h (+0/-174)
mixxx/lib/soundtouch-1.5.0/FIFOSamplePipe.h (+0/-221)
mixxx/lib/soundtouch-1.5.0/FIRFilter.cpp (+0/-269)
mixxx/lib/soundtouch-1.5.0/FIRFilter.h (+0/-164)
mixxx/lib/soundtouch-1.5.0/PeakFinder.cpp (+0/-239)
mixxx/lib/soundtouch-1.5.0/PeakFinder.h (+0/-93)
mixxx/lib/soundtouch-1.5.0/README.html (+0/-752)
mixxx/lib/soundtouch-1.5.0/RateTransposer.cpp (+0/-628)
mixxx/lib/soundtouch-1.5.0/RateTransposer.h (+0/-159)
mixxx/lib/soundtouch-1.5.0/STTypes.h (+0/-158)
mixxx/lib/soundtouch-1.5.0/SoundTouch.cpp (+0/-480)
mixxx/lib/soundtouch-1.5.0/SoundTouch.h (+0/-252)
mixxx/lib/soundtouch-1.5.0/TDStretch.cpp (+0/-1045)
mixxx/lib/soundtouch-1.5.0/TDStretch.h (+0/-275)
mixxx/lib/soundtouch-1.5.0/cpu_detect.h (+0/-62)
mixxx/lib/soundtouch-1.5.0/cpu_detect_x64_gcc.cpp (+0/-80)
mixxx/lib/soundtouch-1.5.0/cpu_detect_x64_win.cpp (+0/-85)
mixxx/lib/soundtouch-1.5.0/cpu_detect_x86_gcc.cpp (+0/-135)
mixxx/lib/soundtouch-1.5.0/cpu_detect_x86_win.cpp (+0/-129)
mixxx/lib/soundtouch-1.5.0/mmx_optimized.cpp (+0/-320)
mixxx/lib/soundtouch-1.5.0/sse_optimized.cpp (+0/-510)
mixxx/lib/soundtouch-1.6.0/AAFilter.cpp (+184/-0)
mixxx/lib/soundtouch-1.6.0/AAFilter.h (+91/-0)
mixxx/lib/soundtouch-1.6.0/BPMDetect.cpp (+377/-0)
mixxx/lib/soundtouch-1.6.0/BPMDetect.h (+170/-0)
mixxx/lib/soundtouch-1.6.0/COPYING.TXT (+458/-0)
mixxx/lib/soundtouch-1.6.0/FIFOSampleBuffer.cpp (+262/-0)
mixxx/lib/soundtouch-1.6.0/FIFOSampleBuffer.h (+174/-0)
mixxx/lib/soundtouch-1.6.0/FIFOSamplePipe.h (+221/-0)
mixxx/lib/soundtouch-1.6.0/FIRFilter.cpp (+260/-0)
mixxx/lib/soundtouch-1.6.0/FIRFilter.h (+145/-0)
mixxx/lib/soundtouch-1.6.0/PeakFinder.cpp (+239/-0)
mixxx/lib/soundtouch-1.6.0/PeakFinder.h (+93/-0)
mixxx/lib/soundtouch-1.6.0/RateTransposer.cpp (+628/-0)
mixxx/lib/soundtouch-1.6.0/RateTransposer.h (+159/-0)
mixxx/lib/soundtouch-1.6.0/STTypes.h (+146/-0)
mixxx/lib/soundtouch-1.6.0/SoundTouch.cpp (+486/-0)
mixxx/lib/soundtouch-1.6.0/SoundTouch.h (+277/-0)
mixxx/lib/soundtouch-1.6.0/TDStretch.cpp (+1026/-0)
mixxx/lib/soundtouch-1.6.0/TDStretch.h (+277/-0)
mixxx/lib/soundtouch-1.6.0/cpu_detect.h (+62/-0)
mixxx/lib/soundtouch-1.6.0/cpu_detect_x86_gcc.cpp (+140/-0)
mixxx/lib/soundtouch-1.6.0/cpu_detect_x86_win.cpp (+139/-0)
mixxx/lib/soundtouch-1.6.0/mmx_optimized.cpp (+320/-0)
mixxx/lib/soundtouch-1.6.0/sse_optimized.cpp (+428/-0)
mixxx/src/engine/enginefilter.h (+5/-5)
mixxx/src/engine/enginefilterbutterworth8.cpp (+1/-1)
To merge this branch: bzr merge lp:~alex.barker/mixxx/mixxx-libs
Reviewer Review Type Date Requested Status
RJ Skerry-Ryan Approve
Review via email: mp+69026@code.launchpad.net

Description of the change

Update of libsoundtouch to 1.6 and fidlib 0.9.10

To post a comment you must log in.
Revision history for this message
RJ Skerry-Ryan (rryan) wrote :

Looks good! Thanks Alex.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'mixxx/build/depends.py'
2--- mixxx/build/depends.py 2011-07-19 18:12:33 +0000
3+++ mixxx/build/depends.py 2011-07-25 04:35:51 +0000
4@@ -208,11 +208,11 @@
5 else:
6 symbol = 'T_LINUX'
7
8- return [build.env.StaticObject('#lib/fidlib-0.9.9/fidlib.c',
9+ return [build.env.StaticObject('#lib/fidlib-0.9.10/fidlib.c',
10 CPPDEFINES=symbol)]
11
12 def configure(self, build, conf):
13- build.env.Append(CPPPATH='#lib/fidlib-0.9.9/')
14+ build.env.Append(CPPPATH='#lib/fidlib-0.9.10/')
15
16 class KissFFT(Dependence):
17
18@@ -231,7 +231,7 @@
19 build.env.Append(CPPPATH="#lib/replaygain")
20
21 class SoundTouch(Dependence):
22- SOUNDTOUCH_PATH = 'soundtouch-1.5.0'
23+ SOUNDTOUCH_PATH = 'soundtouch-1.6.0'
24
25 def sources(self, build):
26 sources = ['engine/enginebufferscalest.cpp',
27@@ -244,21 +244,11 @@
28 '#lib/%s/PeakFinder.cpp' % self.SOUNDTOUCH_PATH,
29 '#lib/%s/BPMDetect.cpp' % self.SOUNDTOUCH_PATH]
30 if build.platform_is_windows and build.toolchain_is_msvs:
31- if build.machine_is_64bit:
32- sources.append(
33- '#lib/%s/cpu_detect_x64_win.cpp' % self.SOUNDTOUCH_PATH)
34- elif build.machine == 'x86':
35- sources.append(
36- '#lib/%s/cpu_detect_x86_win.cpp' % self.SOUNDTOUCH_PATH)
37- else:
38- raise Exception("Unhandled CPU configuration for SoundTouch")
39+ sources.append(
40+ '#lib/%s/cpu_detect_x86_win.cpp' % self.SOUNDTOUCH_PATH)
41 elif build.toolchain_is_gnu:
42- if build.machine == 'x86_64':
43- sources.append(
44- '#lib/%s/cpu_detect_x64_gcc.cpp' % self.SOUNDTOUCH_PATH)
45- else:
46- sources.append(
47- '#lib/%s/cpu_detect_x86_gcc.cpp' % self.SOUNDTOUCH_PATH)
48+ sources.append(
49+ '#lib/%s/cpu_detect_x86_gcc.cpp' % self.SOUNDTOUCH_PATH)
50 else:
51 raise Exception("Unhandled CPU configuration for SoundTouch")
52
53@@ -268,16 +258,11 @@
54 if build.machine_is_64bit or \
55 (build.toolchain_is_msvs and optimize > 1) or \
56 (build.toolchain_is_gnu and optimize > 2):
57+ # FIXME -DSOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS needs to be passed somewhere some how.
58 sources.extend(
59 ['#lib/%s/mmx_optimized.cpp' % self.SOUNDTOUCH_PATH,
60 '#lib/%s/sse_optimized.cpp' % self.SOUNDTOUCH_PATH,
61 ])
62- if build.toolchain_is_msvs and not build.machine_is_64bit:
63- sources.append('#lib/%s/3dnow_win.cpp' % self.SOUNDTOUCH_PATH)
64- else:
65- # TODO(XXX) the docs refer to a 3dnow_gcc, but we don't seem to have
66- # it.
67- pass
68
69 return sources
70
71
72=== modified file 'mixxx/build/qtcreator/mixxx.pro'
73--- mixxx/build/qtcreator/mixxx.pro 2011-02-24 21:21:09 +0000
74+++ mixxx/build/qtcreator/mixxx.pro 2011-07-25 04:35:51 +0000
75@@ -609,7 +609,7 @@
76 $$BASE_DIR/lib/soundtouch-1.4.1/cpu_detect_x86_gcc.cpp
77
78 # Fidlib
79-SOURCES += $$BASE_DIR/lib/fidlib-0.9.9/fidlib.c
80+SOURCES += $$BASE_DIR/lib/fidlib-0.9.10/fidlib.c
81 win32-g++ {
82 DEFINES += T_MINGW
83 }
84
85=== added directory 'mixxx/lib/fidlib-0.9.10'
86=== added file 'mixxx/lib/fidlib-0.9.10/COPYING'
87--- mixxx/lib/fidlib-0.9.10/COPYING 1970-01-01 00:00:00 +0000
88+++ mixxx/lib/fidlib-0.9.10/COPYING 2011-07-25 04:35:51 +0000
89@@ -0,0 +1,340 @@
90+ GNU GENERAL PUBLIC LICENSE
91+ Version 2, June 1991
92+
93+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
94+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
95+ Everyone is permitted to copy and distribute verbatim copies
96+ of this license document, but changing it is not allowed.
97+
98+ Preamble
99+
100+ The licenses for most software are designed to take away your
101+freedom to share and change it. By contrast, the GNU General Public
102+License is intended to guarantee your freedom to share and change free
103+software--to make sure the software is free for all its users. This
104+General Public License applies to most of the Free Software
105+Foundation's software and to any other program whose authors commit to
106+using it. (Some other Free Software Foundation software is covered by
107+the GNU Library General Public License instead.) You can apply it to
108+your programs, too.
109+
110+ When we speak of free software, we are referring to freedom, not
111+price. Our General Public Licenses are designed to make sure that you
112+have the freedom to distribute copies of free software (and charge for
113+this service if you wish), that you receive source code or can get it
114+if you want it, that you can change the software or use pieces of it
115+in new free programs; and that you know you can do these things.
116+
117+ To protect your rights, we need to make restrictions that forbid
118+anyone to deny you these rights or to ask you to surrender the rights.
119+These restrictions translate to certain responsibilities for you if you
120+distribute copies of the software, or if you modify it.
121+
122+ For example, if you distribute copies of such a program, whether
123+gratis or for a fee, you must give the recipients all the rights that
124+you have. You must make sure that they, too, receive or can get the
125+source code. And you must show them these terms so they know their
126+rights.
127+
128+ We protect your rights with two steps: (1) copyright the software, and
129+(2) offer you this license which gives you legal permission to copy,
130+distribute and/or modify the software.
131+
132+ Also, for each author's protection and ours, we want to make certain
133+that everyone understands that there is no warranty for this free
134+software. If the software is modified by someone else and passed on, we
135+want its recipients to know that what they have is not the original, so
136+that any problems introduced by others will not reflect on the original
137+authors' reputations.
138+
139+ Finally, any free program is threatened constantly by software
140+patents. We wish to avoid the danger that redistributors of a free
141+program will individually obtain patent licenses, in effect making the
142+program proprietary. To prevent this, we have made it clear that any
143+patent must be licensed for everyone's free use or not licensed at all.
144+
145+ The precise terms and conditions for copying, distribution and
146+modification follow.
147+
148
149+ GNU GENERAL PUBLIC LICENSE
150+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
151+
152+ 0. This License applies to any program or other work which contains
153+a notice placed by the copyright holder saying it may be distributed
154+under the terms of this General Public License. The "Program", below,
155+refers to any such program or work, and a "work based on the Program"
156+means either the Program or any derivative work under copyright law:
157+that is to say, a work containing the Program or a portion of it,
158+either verbatim or with modifications and/or translated into another
159+language. (Hereinafter, translation is included without limitation in
160+the term "modification".) Each licensee is addressed as "you".
161+
162+Activities other than copying, distribution and modification are not
163+covered by this License; they are outside its scope. The act of
164+running the Program is not restricted, and the output from the Program
165+is covered only if its contents constitute a work based on the
166+Program (independent of having been made by running the Program).
167+Whether that is true depends on what the Program does.
168+
169+ 1. You may copy and distribute verbatim copies of the Program's
170+source code as you receive it, in any medium, provided that you
171+conspicuously and appropriately publish on each copy an appropriate
172+copyright notice and disclaimer of warranty; keep intact all the
173+notices that refer to this License and to the absence of any warranty;
174+and give any other recipients of the Program a copy of this License
175+along with the Program.
176+
177+You may charge a fee for the physical act of transferring a copy, and
178+you may at your option offer warranty protection in exchange for a fee.
179+
180+ 2. You may modify your copy or copies of the Program or any portion
181+of it, thus forming a work based on the Program, and copy and
182+distribute such modifications or work under the terms of Section 1
183+above, provided that you also meet all of these conditions:
184+
185+ a) You must cause the modified files to carry prominent notices
186+ stating that you changed the files and the date of any change.
187+
188+ b) You must cause any work that you distribute or publish, that in
189+ whole or in part contains or is derived from the Program or any
190+ part thereof, to be licensed as a whole at no charge to all third
191+ parties under the terms of this License.
192+
193+ c) If the modified program normally reads commands interactively
194+ when run, you must cause it, when started running for such
195+ interactive use in the most ordinary way, to print or display an
196+ announcement including an appropriate copyright notice and a
197+ notice that there is no warranty (or else, saying that you provide
198+ a warranty) and that users may redistribute the program under
199+ these conditions, and telling the user how to view a copy of this
200+ License. (Exception: if the Program itself is interactive but
201+ does not normally print such an announcement, your work based on
202+ the Program is not required to print an announcement.)
203+
204
205+These requirements apply to the modified work as a whole. If
206+identifiable sections of that work are not derived from the Program,
207+and can be reasonably considered independent and separate works in
208+themselves, then this License, and its terms, do not apply to those
209+sections when you distribute them as separate works. But when you
210+distribute the same sections as part of a whole which is a work based
211+on the Program, the distribution of the whole must be on the terms of
212+this License, whose permissions for other licensees extend to the
213+entire whole, and thus to each and every part regardless of who wrote it.
214+
215+Thus, it is not the intent of this section to claim rights or contest
216+your rights to work written entirely by you; rather, the intent is to
217+exercise the right to control the distribution of derivative or
218+collective works based on the Program.
219+
220+In addition, mere aggregation of another work not based on the Program
221+with the Program (or with a work based on the Program) on a volume of
222+a storage or distribution medium does not bring the other work under
223+the scope of this License.
224+
225+ 3. You may copy and distribute the Program (or a work based on it,
226+under Section 2) in object code or executable form under the terms of
227+Sections 1 and 2 above provided that you also do one of the following:
228+
229+ a) Accompany it with the complete corresponding machine-readable
230+ source code, which must be distributed under the terms of Sections
231+ 1 and 2 above on a medium customarily used for software interchange; or,
232+
233+ b) Accompany it with a written offer, valid for at least three
234+ years, to give any third party, for a charge no more than your
235+ cost of physically performing source distribution, a complete
236+ machine-readable copy of the corresponding source code, to be
237+ distributed under the terms of Sections 1 and 2 above on a medium
238+ customarily used for software interchange; or,
239+
240+ c) Accompany it with the information you received as to the offer
241+ to distribute corresponding source code. (This alternative is
242+ allowed only for noncommercial distribution and only if you
243+ received the program in object code or executable form with such
244+ an offer, in accord with Subsection b above.)
245+
246+The source code for a work means the preferred form of the work for
247+making modifications to it. For an executable work, complete source
248+code means all the source code for all modules it contains, plus any
249+associated interface definition files, plus the scripts used to
250+control compilation and installation of the executable. However, as a
251+special exception, the source code distributed need not include
252+anything that is normally distributed (in either source or binary
253+form) with the major components (compiler, kernel, and so on) of the
254+operating system on which the executable runs, unless that component
255+itself accompanies the executable.
256+
257+If distribution of executable or object code is made by offering
258+access to copy from a designated place, then offering equivalent
259+access to copy the source code from the same place counts as
260+distribution of the source code, even though third parties are not
261+compelled to copy the source along with the object code.
262+
263
264+ 4. You may not copy, modify, sublicense, or distribute the Program
265+except as expressly provided under this License. Any attempt
266+otherwise to copy, modify, sublicense or distribute the Program is
267+void, and will automatically terminate your rights under this License.
268+However, parties who have received copies, or rights, from you under
269+this License will not have their licenses terminated so long as such
270+parties remain in full compliance.
271+
272+ 5. You are not required to accept this License, since you have not
273+signed it. However, nothing else grants you permission to modify or
274+distribute the Program or its derivative works. These actions are
275+prohibited by law if you do not accept this License. Therefore, by
276+modifying or distributing the Program (or any work based on the
277+Program), you indicate your acceptance of this License to do so, and
278+all its terms and conditions for copying, distributing or modifying
279+the Program or works based on it.
280+
281+ 6. Each time you redistribute the Program (or any work based on the
282+Program), the recipient automatically receives a license from the
283+original licensor to copy, distribute or modify the Program subject to
284+these terms and conditions. You may not impose any further
285+restrictions on the recipients' exercise of the rights granted herein.
286+You are not responsible for enforcing compliance by third parties to
287+this License.
288+
289+ 7. If, as a consequence of a court judgment or allegation of patent
290+infringement or for any other reason (not limited to patent issues),
291+conditions are imposed on you (whether by court order, agreement or
292+otherwise) that contradict the conditions of this License, they do not
293+excuse you from the conditions of this License. If you cannot
294+distribute so as to satisfy simultaneously your obligations under this
295+License and any other pertinent obligations, then as a consequence you
296+may not distribute the Program at all. For example, if a patent
297+license would not permit royalty-free redistribution of the Program by
298+all those who receive copies directly or indirectly through you, then
299+the only way you could satisfy both it and this License would be to
300+refrain entirely from distribution of the Program.
301+
302+If any portion of this section is held invalid or unenforceable under
303+any particular circumstance, the balance of the section is intended to
304+apply and the section as a whole is intended to apply in other
305+circumstances.
306+
307+It is not the purpose of this section to induce you to infringe any
308+patents or other property right claims or to contest validity of any
309+such claims; this section has the sole purpose of protecting the
310+integrity of the free software distribution system, which is
311+implemented by public license practices. Many people have made
312+generous contributions to the wide range of software distributed
313+through that system in reliance on consistent application of that
314+system; it is up to the author/donor to decide if he or she is willing
315+to distribute software through any other system and a licensee cannot
316+impose that choice.
317+
318+This section is intended to make thoroughly clear what is believed to
319+be a consequence of the rest of this License.
320+
321
322+ 8. If the distribution and/or use of the Program is restricted in
323+certain countries either by patents or by copyrighted interfaces, the
324+original copyright holder who places the Program under this License
325+may add an explicit geographical distribution limitation excluding
326+those countries, so that distribution is permitted only in or among
327+countries not thus excluded. In such case, this License incorporates
328+the limitation as if written in the body of this License.
329+
330+ 9. The Free Software Foundation may publish revised and/or new versions
331+of the General Public License from time to time. Such new versions will
332+be similar in spirit to the present version, but may differ in detail to
333+address new problems or concerns.
334+
335+Each version is given a distinguishing version number. If the Program
336+specifies a version number of this License which applies to it and "any
337+later version", you have the option of following the terms and conditions
338+either of that version or of any later version published by the Free
339+Software Foundation. If the Program does not specify a version number of
340+this License, you may choose any version ever published by the Free Software
341+Foundation.
342+
343+ 10. If you wish to incorporate parts of the Program into other free
344+programs whose distribution conditions are different, write to the author
345+to ask for permission. For software which is copyrighted by the Free
346+Software Foundation, write to the Free Software Foundation; we sometimes
347+make exceptions for this. Our decision will be guided by the two goals
348+of preserving the free status of all derivatives of our free software and
349+of promoting the sharing and reuse of software generally.
350+
351+ NO WARRANTY
352+
353+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
354+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
355+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
356+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
357+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
358+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
359+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
360+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
361+REPAIR OR CORRECTION.
362+
363+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
364+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
365+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
366+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
367+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
368+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
369+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
370+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
371+POSSIBILITY OF SUCH DAMAGES.
372+
373+ END OF TERMS AND CONDITIONS
374+
375
376+ How to Apply These Terms to Your New Programs
377+
378+ If you develop a new program, and you want it to be of the greatest
379+possible use to the public, the best way to achieve this is to make it
380+free software which everyone can redistribute and change under these terms.
381+
382+ To do so, attach the following notices to the program. It is safest
383+to attach them to the start of each source file to most effectively
384+convey the exclusion of warranty; and each file should have at least
385+the "copyright" line and a pointer to where the full notice is found.
386+
387+ <one line to give the program's name and a brief idea of what it does.>
388+ Copyright (C) <year> <name of author>
389+
390+ This program is free software; you can redistribute it and/or modify
391+ it under the terms of the GNU General Public License as published by
392+ the Free Software Foundation; either version 2 of the License, or
393+ (at your option) any later version.
394+
395+ This program is distributed in the hope that it will be useful,
396+ but WITHOUT ANY WARRANTY; without even the implied warranty of
397+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
398+ GNU General Public License for more details.
399+
400+ You should have received a copy of the GNU General Public License
401+ along with this program; if not, write to the Free Software
402+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
403+
404+
405+Also add information on how to contact you by electronic and paper mail.
406+
407+If the program is interactive, make it output a short notice like this
408+when it starts in an interactive mode:
409+
410+ Gnomovision version 69, Copyright (C) year name of author
411+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
412+ This is free software, and you are welcome to redistribute it
413+ under certain conditions; type `show c' for details.
414+
415+The hypothetical commands `show w' and `show c' should show the appropriate
416+parts of the General Public License. Of course, the commands you use may
417+be called something other than `show w' and `show c'; they could even be
418+mouse-clicks or menu items--whatever suits your program.
419+
420+You should also get your employer (if you work as a programmer) or your
421+school, if any, to sign a "copyright disclaimer" for the program, if
422+necessary. Here is a sample; alter the names:
423+
424+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
425+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
426+
427+ <signature of Ty Coon>, 1 April 1989
428+ Ty Coon, President of Vice
429+
430+This General Public License does not permit incorporating your program into
431+proprietary programs. If your program is a subroutine library, you may
432+consider it more useful to permit linking proprietary applications with the
433+library. If this is what you want to do, use the GNU Library General
434+Public License instead of this License.
435
436=== added file 'mixxx/lib/fidlib-0.9.10/COPYING_LIB'
437--- mixxx/lib/fidlib-0.9.10/COPYING_LIB 1970-01-01 00:00:00 +0000
438+++ mixxx/lib/fidlib-0.9.10/COPYING_LIB 2011-07-25 04:35:51 +0000
439@@ -0,0 +1,504 @@
440+ GNU LESSER GENERAL PUBLIC LICENSE
441+ Version 2.1, February 1999
442+
443+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
444+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
445+ Everyone is permitted to copy and distribute verbatim copies
446+ of this license document, but changing it is not allowed.
447+
448+[This is the first released version of the Lesser GPL. It also counts
449+ as the successor of the GNU Library Public License, version 2, hence
450+ the version number 2.1.]
451+
452+ Preamble
453+
454+ The licenses for most software are designed to take away your
455+freedom to share and change it. By contrast, the GNU General Public
456+Licenses are intended to guarantee your freedom to share and change
457+free software--to make sure the software is free for all its users.
458+
459+ This license, the Lesser General Public License, applies to some
460+specially designated software packages--typically libraries--of the
461+Free Software Foundation and other authors who decide to use it. You
462+can use it too, but we suggest you first think carefully about whether
463+this license or the ordinary General Public License is the better
464+strategy to use in any particular case, based on the explanations below.
465+
466+ When we speak of free software, we are referring to freedom of use,
467+not price. Our General Public Licenses are designed to make sure that
468+you have the freedom to distribute copies of free software (and charge
469+for this service if you wish); that you receive source code or can get
470+it if you want it; that you can change the software and use pieces of
471+it in new free programs; and that you are informed that you can do
472+these things.
473+
474+ To protect your rights, we need to make restrictions that forbid
475+distributors to deny you these rights or to ask you to surrender these
476+rights. These restrictions translate to certain responsibilities for
477+you if you distribute copies of the library or if you modify it.
478+
479+ For example, if you distribute copies of the library, whether gratis
480+or for a fee, you must give the recipients all the rights that we gave
481+you. You must make sure that they, too, receive or can get the source
482+code. If you link other code with the library, you must provide
483+complete object files to the recipients, so that they can relink them
484+with the library after making changes to the library and recompiling
485+it. And you must show them these terms so they know their rights.
486+
487+ We protect your rights with a two-step method: (1) we copyright the
488+library, and (2) we offer you this license, which gives you legal
489+permission to copy, distribute and/or modify the library.
490+
491+ To protect each distributor, we want to make it very clear that
492+there is no warranty for the free library. Also, if the library is
493+modified by someone else and passed on, the recipients should know
494+that what they have is not the original version, so that the original
495+author's reputation will not be affected by problems that might be
496+introduced by others.
497+
498
499+ Finally, software patents pose a constant threat to the existence of
500+any free program. We wish to make sure that a company cannot
501+effectively restrict the users of a free program by obtaining a
502+restrictive license from a patent holder. Therefore, we insist that
503+any patent license obtained for a version of the library must be
504+consistent with the full freedom of use specified in this license.
505+
506+ Most GNU software, including some libraries, is covered by the
507+ordinary GNU General Public License. This license, the GNU Lesser
508+General Public License, applies to certain designated libraries, and
509+is quite different from the ordinary General Public License. We use
510+this license for certain libraries in order to permit linking those
511+libraries into non-free programs.
512+
513+ When a program is linked with a library, whether statically or using
514+a shared library, the combination of the two is legally speaking a
515+combined work, a derivative of the original library. The ordinary
516+General Public License therefore permits such linking only if the
517+entire combination fits its criteria of freedom. The Lesser General
518+Public License permits more lax criteria for linking other code with
519+the library.
520+
521+ We call this license the "Lesser" General Public License because it
522+does Less to protect the user's freedom than the ordinary General
523+Public License. It also provides other free software developers Less
524+of an advantage over competing non-free programs. These disadvantages
525+are the reason we use the ordinary General Public License for many
526+libraries. However, the Lesser license provides advantages in certain
527+special circumstances.
528+
529+ For example, on rare occasions, there may be a special need to
530+encourage the widest possible use of a certain library, so that it becomes
531+a de-facto standard. To achieve this, non-free programs must be
532+allowed to use the library. A more frequent case is that a free
533+library does the same job as widely used non-free libraries. In this
534+case, there is little to gain by limiting the free library to free
535+software only, so we use the Lesser General Public License.
536+
537+ In other cases, permission to use a particular library in non-free
538+programs enables a greater number of people to use a large body of
539+free software. For example, permission to use the GNU C Library in
540+non-free programs enables many more people to use the whole GNU
541+operating system, as well as its variant, the GNU/Linux operating
542+system.
543+
544+ Although the Lesser General Public License is Less protective of the
545+users' freedom, it does ensure that the user of a program that is
546+linked with the Library has the freedom and the wherewithal to run
547+that program using a modified version of the Library.
548+
549+ The precise terms and conditions for copying, distribution and
550+modification follow. Pay close attention to the difference between a
551+"work based on the library" and a "work that uses the library". The
552+former contains code derived from the library, whereas the latter must
553+be combined with the library in order to run.
554+
555
556+ GNU LESSER GENERAL PUBLIC LICENSE
557+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
558+
559+ 0. This License Agreement applies to any software library or other
560+program which contains a notice placed by the copyright holder or
561+other authorized party saying it may be distributed under the terms of
562+this Lesser General Public License (also called "this License").
563+Each licensee is addressed as "you".
564+
565+ A "library" means a collection of software functions and/or data
566+prepared so as to be conveniently linked with application programs
567+(which use some of those functions and data) to form executables.
568+
569+ The "Library", below, refers to any such software library or work
570+which has been distributed under these terms. A "work based on the
571+Library" means either the Library or any derivative work under
572+copyright law: that is to say, a work containing the Library or a
573+portion of it, either verbatim or with modifications and/or translated
574+straightforwardly into another language. (Hereinafter, translation is
575+included without limitation in the term "modification".)
576+
577+ "Source code" for a work means the preferred form of the work for
578+making modifications to it. For a library, complete source code means
579+all the source code for all modules it contains, plus any associated
580+interface definition files, plus the scripts used to control compilation
581+and installation of the library.
582+
583+ Activities other than copying, distribution and modification are not
584+covered by this License; they are outside its scope. The act of
585+running a program using the Library is not restricted, and output from
586+such a program is covered only if its contents constitute a work based
587+on the Library (independent of the use of the Library in a tool for
588+writing it). Whether that is true depends on what the Library does
589+and what the program that uses the Library does.
590+
591+ 1. You may copy and distribute verbatim copies of the Library's
592+complete source code as you receive it, in any medium, provided that
593+you conspicuously and appropriately publish on each copy an
594+appropriate copyright notice and disclaimer of warranty; keep intact
595+all the notices that refer to this License and to the absence of any
596+warranty; and distribute a copy of this License along with the
597+Library.
598+
599+ You may charge a fee for the physical act of transferring a copy,
600+and you may at your option offer warranty protection in exchange for a
601+fee.
602+
603
604+ 2. You may modify your copy or copies of the Library or any portion
605+of it, thus forming a work based on the Library, and copy and
606+distribute such modifications or work under the terms of Section 1
607+above, provided that you also meet all of these conditions:
608+
609+ a) The modified work must itself be a software library.
610+
611+ b) You must cause the files modified to carry prominent notices
612+ stating that you changed the files and the date of any change.
613+
614+ c) You must cause the whole of the work to be licensed at no
615+ charge to all third parties under the terms of this License.
616+
617+ d) If a facility in the modified Library refers to a function or a
618+ table of data to be supplied by an application program that uses
619+ the facility, other than as an argument passed when the facility
620+ is invoked, then you must make a good faith effort to ensure that,
621+ in the event an application does not supply such function or
622+ table, the facility still operates, and performs whatever part of
623+ its purpose remains meaningful.
624+
625+ (For example, a function in a library to compute square roots has
626+ a purpose that is entirely well-defined independent of the
627+ application. Therefore, Subsection 2d requires that any
628+ application-supplied function or table used by this function must
629+ be optional: if the application does not supply it, the square
630+ root function must still compute square roots.)
631+
632+These requirements apply to the modified work as a whole. If
633+identifiable sections of that work are not derived from the Library,
634+and can be reasonably considered independent and separate works in
635+themselves, then this License, and its terms, do not apply to those
636+sections when you distribute them as separate works. But when you
637+distribute the same sections as part of a whole which is a work based
638+on the Library, the distribution of the whole must be on the terms of
639+this License, whose permissions for other licensees extend to the
640+entire whole, and thus to each and every part regardless of who wrote
641+it.
642+
643+Thus, it is not the intent of this section to claim rights or contest
644+your rights to work written entirely by you; rather, the intent is to
645+exercise the right to control the distribution of derivative or
646+collective works based on the Library.
647+
648+In addition, mere aggregation of another work not based on the Library
649+with the Library (or with a work based on the Library) on a volume of
650+a storage or distribution medium does not bring the other work under
651+the scope of this License.
652+
653+ 3. You may opt to apply the terms of the ordinary GNU General Public
654+License instead of this License to a given copy of the Library. To do
655+this, you must alter all the notices that refer to this License, so
656+that they refer to the ordinary GNU General Public License, version 2,
657+instead of to this License. (If a newer version than version 2 of the
658+ordinary GNU General Public License has appeared, then you can specify
659+that version instead if you wish.) Do not make any other change in
660+these notices.
661+
662
663+ Once this change is made in a given copy, it is irreversible for
664+that copy, so the ordinary GNU General Public License applies to all
665+subsequent copies and derivative works made from that copy.
666+
667+ This option is useful when you wish to copy part of the code of
668+the Library into a program that is not a library.
669+
670+ 4. You may copy and distribute the Library (or a portion or
671+derivative of it, under Section 2) in object code or executable form
672+under the terms of Sections 1 and 2 above provided that you accompany
673+it with the complete corresponding machine-readable source code, which
674+must be distributed under the terms of Sections 1 and 2 above on a
675+medium customarily used for software interchange.
676+
677+ If distribution of object code is made by offering access to copy
678+from a designated place, then offering equivalent access to copy the
679+source code from the same place satisfies the requirement to
680+distribute the source code, even though third parties are not
681+compelled to copy the source along with the object code.
682+
683+ 5. A program that contains no derivative of any portion of the
684+Library, but is designed to work with the Library by being compiled or
685+linked with it, is called a "work that uses the Library". Such a
686+work, in isolation, is not a derivative work of the Library, and
687+therefore falls outside the scope of this License.
688+
689+ However, linking a "work that uses the Library" with the Library
690+creates an executable that is a derivative of the Library (because it
691+contains portions of the Library), rather than a "work that uses the
692+library". The executable is therefore covered by this License.
693+Section 6 states terms for distribution of such executables.
694+
695+ When a "work that uses the Library" uses material from a header file
696+that is part of the Library, the object code for the work may be a
697+derivative work of the Library even though the source code is not.
698+Whether this is true is especially significant if the work can be
699+linked without the Library, or if the work is itself a library. The
700+threshold for this to be true is not precisely defined by law.
701+
702+ If such an object file uses only numerical parameters, data
703+structure layouts and accessors, and small macros and small inline
704+functions (ten lines or less in length), then the use of the object
705+file is unrestricted, regardless of whether it is legally a derivative
706+work. (Executables containing this object code plus portions of the
707+Library will still fall under Section 6.)
708+
709+ Otherwise, if the work is a derivative of the Library, you may
710+distribute the object code for the work under the terms of Section 6.
711+Any executables containing that work also fall under Section 6,
712+whether or not they are linked directly with the Library itself.
713+
714
715+ 6. As an exception to the Sections above, you may also combine or
716+link a "work that uses the Library" with the Library to produce a
717+work containing portions of the Library, and distribute that work
718+under terms of your choice, provided that the terms permit
719+modification of the work for the customer's own use and reverse
720+engineering for debugging such modifications.
721+
722+ You must give prominent notice with each copy of the work that the
723+Library is used in it and that the Library and its use are covered by
724+this License. You must supply a copy of this License. If the work
725+during execution displays copyright notices, you must include the
726+copyright notice for the Library among them, as well as a reference
727+directing the user to the copy of this License. Also, you must do one
728+of these things:
729+
730+ a) Accompany the work with the complete corresponding
731+ machine-readable source code for the Library including whatever
732+ changes were used in the work (which must be distributed under
733+ Sections 1 and 2 above); and, if the work is an executable linked
734+ with the Library, with the complete machine-readable "work that
735+ uses the Library", as object code and/or source code, so that the
736+ user can modify the Library and then relink to produce a modified
737+ executable containing the modified Library. (It is understood
738+ that the user who changes the contents of definitions files in the
739+ Library will not necessarily be able to recompile the application
740+ to use the modified definitions.)
741+
742+ b) Use a suitable shared library mechanism for linking with the
743+ Library. A suitable mechanism is one that (1) uses at run time a
744+ copy of the library already present on the user's computer system,
745+ rather than copying library functions into the executable, and (2)
746+ will operate properly with a modified version of the library, if
747+ the user installs one, as long as the modified version is
748+ interface-compatible with the version that the work was made with.
749+
750+ c) Accompany the work with a written offer, valid for at
751+ least three years, to give the same user the materials
752+ specified in Subsection 6a, above, for a charge no more
753+ than the cost of performing this distribution.
754+
755+ d) If distribution of the work is made by offering access to copy
756+ from a designated place, offer equivalent access to copy the above
757+ specified materials from the same place.
758+
759+ e) Verify that the user has already received a copy of these
760+ materials or that you have already sent this user a copy.
761+
762+ For an executable, the required form of the "work that uses the
763+Library" must include any data and utility programs needed for
764+reproducing the executable from it. However, as a special exception,
765+the materials to be distributed need not include anything that is
766+normally distributed (in either source or binary form) with the major
767+components (compiler, kernel, and so on) of the operating system on
768+which the executable runs, unless that component itself accompanies
769+the executable.
770+
771+ It may happen that this requirement contradicts the license
772+restrictions of other proprietary libraries that do not normally
773+accompany the operating system. Such a contradiction means you cannot
774+use both them and the Library together in an executable that you
775+distribute.
776+
777
778+ 7. You may place library facilities that are a work based on the
779+Library side-by-side in a single library together with other library
780+facilities not covered by this License, and distribute such a combined
781+library, provided that the separate distribution of the work based on
782+the Library and of the other library facilities is otherwise
783+permitted, and provided that you do these two things:
784+
785+ a) Accompany the combined library with a copy of the same work
786+ based on the Library, uncombined with any other library
787+ facilities. This must be distributed under the terms of the
788+ Sections above.
789+
790+ b) Give prominent notice with the combined library of the fact
791+ that part of it is a work based on the Library, and explaining
792+ where to find the accompanying uncombined form of the same work.
793+
794+ 8. You may not copy, modify, sublicense, link with, or distribute
795+the Library except as expressly provided under this License. Any
796+attempt otherwise to copy, modify, sublicense, link with, or
797+distribute the Library is void, and will automatically terminate your
798+rights under this License. However, parties who have received copies,
799+or rights, from you under this License will not have their licenses
800+terminated so long as such parties remain in full compliance.
801+
802+ 9. You are not required to accept this License, since you have not
803+signed it. However, nothing else grants you permission to modify or
804+distribute the Library or its derivative works. These actions are
805+prohibited by law if you do not accept this License. Therefore, by
806+modifying or distributing the Library (or any work based on the
807+Library), you indicate your acceptance of this License to do so, and
808+all its terms and conditions for copying, distributing or modifying
809+the Library or works based on it.
810+
811+ 10. Each time you redistribute the Library (or any work based on the
812+Library), the recipient automatically receives a license from the
813+original licensor to copy, distribute, link with or modify the Library
814+subject to these terms and conditions. You may not impose any further
815+restrictions on the recipients' exercise of the rights granted herein.
816+You are not responsible for enforcing compliance by third parties with
817+this License.
818+
819
820+ 11. If, as a consequence of a court judgment or allegation of patent
821+infringement or for any other reason (not limited to patent issues),
822+conditions are imposed on you (whether by court order, agreement or
823+otherwise) that contradict the conditions of this License, they do not
824+excuse you from the conditions of this License. If you cannot
825+distribute so as to satisfy simultaneously your obligations under this
826+License and any other pertinent obligations, then as a consequence you
827+may not distribute the Library at all. For example, if a patent
828+license would not permit royalty-free redistribution of the Library by
829+all those who receive copies directly or indirectly through you, then
830+the only way you could satisfy both it and this License would be to
831+refrain entirely from distribution of the Library.
832+
833+If any portion of this section is held invalid or unenforceable under any
834+particular circumstance, the balance of the section is intended to apply,
835+and the section as a whole is intended to apply in other circumstances.
836+
837+It is not the purpose of this section to induce you to infringe any
838+patents or other property right claims or to contest validity of any
839+such claims; this section has the sole purpose of protecting the
840+integrity of the free software distribution system which is
841+implemented by public license practices. Many people have made
842+generous contributions to the wide range of software distributed
843+through that system in reliance on consistent application of that
844+system; it is up to the author/donor to decide if he or she is willing
845+to distribute software through any other system and a licensee cannot
846+impose that choice.
847+
848+This section is intended to make thoroughly clear what is believed to
849+be a consequence of the rest of this License.
850+
851+ 12. If the distribution and/or use of the Library is restricted in
852+certain countries either by patents or by copyrighted interfaces, the
853+original copyright holder who places the Library under this License may add
854+an explicit geographical distribution limitation excluding those countries,
855+so that distribution is permitted only in or among countries not thus
856+excluded. In such case, this License incorporates the limitation as if
857+written in the body of this License.
858+
859+ 13. The Free Software Foundation may publish revised and/or new
860+versions of the Lesser General Public License from time to time.
861+Such new versions will be similar in spirit to the present version,
862+but may differ in detail to address new problems or concerns.
863+
864+Each version is given a distinguishing version number. If the Library
865+specifies a version number of this License which applies to it and
866+"any later version", you have the option of following the terms and
867+conditions either of that version or of any later version published by
868+the Free Software Foundation. If the Library does not specify a
869+license version number, you may choose any version ever published by
870+the Free Software Foundation.
871+
872
873+ 14. If you wish to incorporate parts of the Library into other free
874+programs whose distribution conditions are incompatible with these,
875+write to the author to ask for permission. For software which is
876+copyrighted by the Free Software Foundation, write to the Free
877+Software Foundation; we sometimes make exceptions for this. Our
878+decision will be guided by the two goals of preserving the free status
879+of all derivatives of our free software and of promoting the sharing
880+and reuse of software generally.
881+
882+ NO WARRANTY
883+
884+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
885+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
886+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
887+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
888+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
889+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
890+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
891+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
892+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
893+
894+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
895+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
896+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
897+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
898+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
899+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
900+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
901+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
902+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
903+DAMAGES.
904+
905+ END OF TERMS AND CONDITIONS
906+
907
908+ How to Apply These Terms to Your New Libraries
909+
910+ If you develop a new library, and you want it to be of the greatest
911+possible use to the public, we recommend making it free software that
912+everyone can redistribute and change. You can do so by permitting
913+redistribution under these terms (or, alternatively, under the terms of the
914+ordinary General Public License).
915+
916+ To apply these terms, attach the following notices to the library. It is
917+safest to attach them to the start of each source file to most effectively
918+convey the exclusion of warranty; and each file should have at least the
919+"copyright" line and a pointer to where the full notice is found.
920+
921+ <one line to give the library's name and a brief idea of what it does.>
922+ Copyright (C) <year> <name of author>
923+
924+ This library is free software; you can redistribute it and/or
925+ modify it under the terms of the GNU Lesser General Public
926+ License as published by the Free Software Foundation; either
927+ version 2.1 of the License, or (at your option) any later version.
928+
929+ This library is distributed in the hope that it will be useful,
930+ but WITHOUT ANY WARRANTY; without even the implied warranty of
931+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
932+ Lesser General Public License for more details.
933+
934+ You should have received a copy of the GNU Lesser General Public
935+ License along with this library; if not, write to the Free Software
936+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
937+
938+Also add information on how to contact you by electronic and paper mail.
939+
940+You should also get your employer (if you work as a programmer) or your
941+school, if any, to sign a "copyright disclaimer" for the library, if
942+necessary. Here is a sample; alter the names:
943+
944+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
945+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
946+
947+ <signature of Ty Coon>, 1 April 1990
948+ Ty Coon, President of Vice
949+
950+That's all there is to it!
951+
952+
953
954=== added file 'mixxx/lib/fidlib-0.9.10/fidlib.c'
955--- mixxx/lib/fidlib-0.9.10/fidlib.c 1970-01-01 00:00:00 +0000
956+++ mixxx/lib/fidlib-0.9.10/fidlib.c 2011-07-25 04:35:51 +0000
957@@ -0,0 +1,2304 @@
958+//
959+// Fidlib digital filter designer code
960+// -----------------------------------
961+//
962+// Copyright (c) 2002-2004 Jim Peters <http://uazu.net/>. This
963+// file is released under the GNU Lesser General Public License
964+// (LGPL) version 2.1 as published by the Free Software
965+// Foundation. See the file COPYING_LIB for details, or visit
966+// <http://www.fsf.org/licenses/licenses.html>.
967+//
968+// The code in this file was written to go with the Fiview app
969+// (http://uazu.net/fiview/), but it may be used as a library for
970+// other applications. The idea behind this library is to allow
971+// filters to be designed at run-time, which gives much greater
972+// flexibility to filtering applications.
973+//
974+// This file depends on the fidmkf.h file which provides the
975+// filter types from Tony Fisher's 'mkfilter' package. See that
976+// file for references and links used there.
977+//
978+//
979+// Here are some of the sources I used whilst writing this code:
980+//
981+// Robert Bristow-Johnson's EQ cookbook formulae:
982+// http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt
983+//
984+
985+#define VERSION "0.9.10"
986+
987+//
988+// Filter specification string
989+// ---------------------------
990+//
991+// The filter specification string can be used to completely
992+// specify the filter, or it can be used with the frequency or
993+// frequency range missing, in which case default values are
994+// picked up from values passed directly to the routine.
995+//
996+// The spec consists of a series of letters usually followed by
997+// the order of the filter and then by any other parameters
998+// required, preceded by slashes. For example:
999+//
1000+// LpBu4/20.4 Lowpass butterworth, 4th order, -3.01dB at 20.4Hz
1001+// BpBu2/3-4 Bandpass butterworth, 2nd order, from 3 to 4Hz
1002+// BpBu2/=3-4 Same filter, but adjusted exactly to the range given
1003+// BsRe/1000/10 Bandstop resonator, Q=1000, frequency 10Hz
1004+//
1005+// The routines fid_design() or fid_parse() are used to convert
1006+// this spec-string into filter coefficients and a description
1007+// (if required).
1008+//
1009+//
1010+// Typical usage:
1011+// -------------
1012+//
1013+// FidFilter *filt, *filt2;
1014+// char *desc;
1015+// FidRun *run;
1016+// FidFunc *funcp;
1017+// void *fbuf1, *fbuf2;
1018+// int delay;
1019+// void my_error_func(char *err);
1020+//
1021+// // Design a filter, and optionally get its long description
1022+// filt= fid_design(spec, rate, freq0, freq1, adj, &desc);
1023+//
1024+// // List all the possible filter types
1025+// fid_list_filters(stdout);
1026+// okay= fid_list_filters_buf(buf, buf+sizeof(buf));
1027+//
1028+// // Calculate the response of the filter at a given frequency
1029+// // (frequency is given as a proportion of the sampling rate, in
1030+// // the range 0 to 0.5). If phase is returned, then this is
1031+// // given in the range 0 to 1 (for 0 to 2*pi).
1032+// resp= fid_response(filt, freq);
1033+// resp= fid_response_pha(filt, freq, &phase);
1034+//
1035+// // Estimate the signal delay caused by a particular filter, in samples
1036+// delay= fid_calc_delay(filt);
1037+//
1038+// // Run a given filter (this will do JIT filter compilation if this is
1039+// // implemented for this processor / OS)
1040+// run= fid_run_new(filt, &funcp);
1041+// fbuf1= fid_run_newbuf(run);
1042+// fbuf2= fid_run_newbuf(run);
1043+// while (...) {
1044+// out_1= funcp(fbuf1, in_1);
1045+// out_2= funcp(fbuf2, in_2);
1046+// if (restart_required) fid_run_zapbuf(fbuf1);
1047+// ...
1048+// }
1049+// fid_run_freebuf(fbuf2);
1050+// fid_run_freebuf(fbuf1);
1051+// fid_run_free(run);
1052+//
1053+// // If you need to allocate your own buffers separately for some
1054+// // reason, then do it this way:
1055+// run= fid_run_new(filt, &funcp);
1056+// len= fid_run_bufsize(run);
1057+// fbuf1= Alloc(len); fid_run_initbuf(run, fbuf1);
1058+// fbuf2= Alloc(len); fid_run_initbuf(run, fbuf2);
1059+// while (...) {
1060+// out_1= funcp(fbuf1, in_1);
1061+// out_2= funcp(fbuf2, in_2);
1062+// if (restart_required) fid_run_zapbuf(fbuf1);
1063+// ...
1064+// }
1065+// free(fbuf2);
1066+// free(fbuf1);
1067+// fid_run_free(run);
1068+//
1069+// // Convert an arbitrary filter into a new filter which is a single
1070+// // IIR/FIR pair. This is done by convolving the coefficients. This
1071+// // flattened filter will give the same result, in theory. However,
1072+// // in practice this will be less accurate, especially in cases where
1073+// // the limits of the floating point format are being reached (e.g.
1074+// // subtracting numbers with small highly significant differences).
1075+// // The routine also ensures that the IIR first coefficient is 1.0.
1076+// filt2= fid_flatten(filt);
1077+// free(filt);
1078+//
1079+// // Parse an entire filter-spec string possibly containing several FIR,
1080+// // IIR and predefined filters and return it as a FidFilter at the given
1081+// // location. Stops at the first ,; or unmatched )]} character, or the end
1082+// // of the string. Returns a strdup'd error string on error, or else 0.
1083+// err= fid_parse(double rate, char **pp, FidFilter **ffp);
1084+//
1085+// // Set up your own fatal-error handler (default is to dump a message
1086+// // to STDERR and exit on fatal conditions)
1087+// fid_set_error_handler(&my_error_func);
1088+//
1089+// // Get the version number of the library as a string (e.g. "1.0.0")
1090+// txt= fid_version();
1091+//
1092+// // Design a filter and reduce it to a list of all the non-const
1093+// // coefficients, which is returned in the given double[]. The number
1094+// // of coefficients expected must be provided (as a check).
1095+// #define N_COEF <whatever>
1096+// double coef[N_COEF], gain;
1097+// gain= fid_design_coef(coef, N_COEF, spec, rate, freq0, freq1, adj);
1098+//
1099+// // Rewrite a filter spec in a full and/or separated-out form
1100+// char *full, *min;
1101+// double minf0, minf1;
1102+// int minadj;
1103+// fid_rewrite_spec(spec, freq0, freq1, adj, &full, &min, &minf0, &minf1, &minadj);
1104+// ...
1105+// free(full); free(min);
1106+//
1107+// // Create a FidFilter based on coefficients provided in the
1108+// // given double array.
1109+// static double array[]= { 'I', 3, 1.0, 0.55, 0.77, 'F', 3, 1, -2, 1, 0 };
1110+// filt= fid_cv_array(array);
1111+//
1112+// // Join a number of filters into a single filter (and free them too,
1113+// // if the first argument is 1)
1114+// filt= fid_cat(0, filt1, filt2, filt3, filt4, 0);
1115+//
1116+//
1117+
1118+//
1119+// Format of returned filter
1120+// -------------------------
1121+//
1122+// The filter returned is a single chunk of allocated memory in
1123+// which is stored a number of FidFilter instances. Each
1124+// instance has variable length according to the coefficients
1125+// contained in it. It is probably easier to think of this as a
1126+// stream of items in memory. Each sub-filter starts with its
1127+// type as a short -- either 'I' for IIR filters, or 'F' for FIR
1128+// filters. (Other types may be added later, e.g. AM modulation
1129+// elements, or whatever). This is followed by a short bitmap
1130+// which indicates which of the coefficients are constants,
1131+// aiding code-generation. Next comes the count of the following
1132+// coefficients, as an int. (These header fields normally takes 8
1133+// bytes, the same as a double, but this might depend on the
1134+// platform). Then follow the coefficients, as doubles. The next
1135+// sub-filter follows on straight after that. The end of the list
1136+// is marked by 8 zero bytes, meaning typ==0, cbm==0 and len==0.
1137+//
1138+// The filter can be read with the aid of the FidFilter structure
1139+// (giving typ, cbm, len and val[] elements) and the FFNEXT()
1140+// macro: using ff= FFNEXT(ff) steps to the next FidFilter
1141+// structure along the chain.
1142+//
1143+// Note that within the sub-filters, coefficients are listed in
1144+// the order that they apply to data, from current-sample
1145+// backwards in time, i.e. most recent first (so an FIR val[] of
1146+// 0, 0, 1 represents a two-sample delay FIR filter). IIR
1147+// filters are *not* necessarily adjusted so that their first
1148+// coefficient is 1.
1149+//
1150+// Most filters have their gain pre-adjusted so that some
1151+// suitable part of the response is at gain==1.0. However, this
1152+// depends on the filter type.
1153+//
1154+
1155+//
1156+// Check that a target macro has been set. This macro selects
1157+// various fixes required on various platforms:
1158+//
1159+// T_LINUX Linux, or probably any UNIX-like platform with GCC
1160+// T_MINGW MinGW -- either building on Win32 or cross-compiling
1161+// T_MSVC Microsoft Visual C
1162+//
1163+// (On MSVC, add "T_MSVC" to the preprocessor definitions in the
1164+// project settings, or add /D "T_MSVC" to the compiler
1165+// command-line.)
1166+//
1167+
1168+#ifndef T_LINUX
1169+#ifndef T_MINGW
1170+#ifndef T_MSVC
1171+#error Please define one of the T_* target macros (e.g. -DT_LINUX); see fidlib.c
1172+#endif
1173+#endif
1174+#endif
1175+
1176+
1177+//
1178+// Select which method of filter execution is preferred.
1179+// RF_CMDLIST is recommended (and is the default).
1180+//
1181+// RF_COMBINED -- easy to understand code, lower accuracy
1182+// RF_CMDLIST -- faster pre-compiled code
1183+// RF_JIT -- fastest JIT run-time generated code (no longer supported)
1184+//
1185+
1186+#ifndef RF_COMBINED
1187+#ifndef RF_CMDLIST
1188+#ifndef RF_JIT
1189+
1190+#define RF_CMDLIST
1191+
1192+#endif
1193+#endif
1194+#endif
1195+
1196+//
1197+// Includes
1198+//
1199+
1200+#include <stdlib.h>
1201+#include <stdarg.h>
1202+#include <stdio.h>
1203+#include <string.h>
1204+#include <ctype.h>
1205+#include <math.h>
1206+#include "fidlib.h"
1207+
1208+#ifndef M_PI
1209+#define M_PI 3.14159265358979323846
1210+#endif
1211+
1212+extern FidFilter *mkfilter(char *, ...);
1213+
1214+//
1215+// Target-specific fixes
1216+//
1217+
1218+// Macro for local inline routines that shouldn't be visible externally
1219+#ifdef T_MSVC
1220+ #define STATIC_INLINE static __inline
1221+#else
1222+ #define STATIC_INLINE static inline
1223+#endif
1224+
1225+// MinGW and MSVC fixes
1226+#if defined(T_MINGW) || defined(T_MSVC)
1227+ #ifndef vsnprintf
1228+ #define vsnprintf _vsnprintf
1229+ #endif
1230+ #ifndef snprintf
1231+ #define snprintf _snprintf
1232+ #endif
1233+// Not sure if we strictly need this still
1234+ STATIC_INLINE double
1235+ my_asinh(double val) {
1236+ return log(val + sqrt(val*val + 1.0));
1237+ }
1238+ #define asinh(xx) my_asinh(xx)
1239+#endif
1240+
1241+
1242+//
1243+// Support code
1244+//
1245+
1246+static void (*error_handler)(char *err)= 0;
1247+
1248+static void
1249+error(char *fmt, ...) {
1250+ char buf[1024];
1251+ va_list ap;
1252+ va_start(ap, fmt);
1253+
1254+ vsnprintf(buf, sizeof(buf), fmt, ap); // Ignore overflow
1255+ buf[sizeof(buf)-1]= 0;
1256+ if (error_handler) error_handler(buf);
1257+
1258+ // If error handler routine returns, we dump to STDERR and exit anyway
1259+ fprintf(stderr, "fidlib error: %s\n", buf);
1260+ exit(1);
1261+}
1262+
1263+static char *
1264+strdupf(char *fmt, ...) {
1265+ va_list ap;
1266+ char buf[1024], *rv;
1267+ int len;
1268+ va_start(ap, fmt);
1269+ len= vsnprintf(buf, sizeof(buf), fmt, ap);
1270+ if (len < 0 || len >= sizeof(buf)-1)
1271+ error("strdupf exceeded buffer");
1272+ rv= strdup(buf);
1273+ if (!rv) error("Out of memory");
1274+ return rv;
1275+}
1276+
1277+static void *
1278+Alloc(int size) {
1279+ void *vp= calloc(1, size);
1280+ if (!vp) error("Out of memory");
1281+ return vp;
1282+}
1283+
1284+#define ALLOC(type) ((type*)Alloc(sizeof(type)))
1285+#define ALLOC_ARR(cnt, type) ((type*)Alloc((cnt) * sizeof(type)))
1286+
1287+
1288+//
1289+// Complex multiply: aa *= bb;
1290+//
1291+
1292+STATIC_INLINE void
1293+cmul(double *aa, double *bb) {
1294+ double rr= aa[0] * bb[0] - aa[1] * bb[1];
1295+ double ii= aa[0] * bb[1] + aa[1] * bb[0];
1296+ aa[0]= rr;
1297+ aa[1]= ii;
1298+}
1299+
1300+//
1301+// Complex square: aa *= aa;
1302+//
1303+
1304+STATIC_INLINE void
1305+csqu(double *aa) {
1306+ double rr= aa[0] * aa[0] - aa[1] * aa[1];
1307+ double ii= 2 * aa[0] * aa[1];
1308+ aa[0]= rr;
1309+ aa[1]= ii;
1310+}
1311+
1312+//
1313+// Complex multiply by real: aa *= bb;
1314+//
1315+
1316+STATIC_INLINE void
1317+cmulr(double *aa, double fact) {
1318+ aa[0] *= fact;
1319+ aa[1] *= fact;
1320+}
1321+
1322+//
1323+// Complex conjugate: aa= aa*
1324+//
1325+
1326+STATIC_INLINE void
1327+cconj(double *aa) {
1328+ aa[1]= -aa[1];
1329+}
1330+
1331+//
1332+// Complex divide: aa /= bb;
1333+//
1334+
1335+STATIC_INLINE void
1336+cdiv(double *aa, double *bb) {
1337+ double rr= aa[0] * bb[0] + aa[1] * bb[1];
1338+ double ii= -aa[0] * bb[1] + aa[1] * bb[0];
1339+ double fact= 1.0 / (bb[0] * bb[0] + bb[1] * bb[1]);
1340+ aa[0]= rr * fact;
1341+ aa[1]= ii * fact;
1342+}
1343+
1344+//
1345+// Complex reciprocal: aa= 1/aa
1346+//
1347+
1348+STATIC_INLINE void
1349+crecip(double *aa) {
1350+ double fact= 1.0 / (aa[0] * aa[0] + aa[1] * aa[1]);
1351+ aa[0] *= fact;
1352+ aa[1] *= -fact;
1353+}
1354+
1355+//
1356+// Complex assign: aa= bb
1357+//
1358+
1359+STATIC_INLINE void
1360+cass(double *aa, double *bb) {
1361+ memcpy(aa, bb, 2*sizeof(double)); // Assigning doubles is really slow
1362+}
1363+
1364+//
1365+// Complex assign: aa= (rr + ii*j)
1366+//
1367+
1368+STATIC_INLINE void
1369+cassz(double *aa, double rr, double ii) {
1370+ aa[0]= rr;
1371+ aa[1]= ii;
1372+}
1373+
1374+//
1375+// Complex add: aa += bb
1376+//
1377+
1378+STATIC_INLINE void
1379+cadd(double *aa, double *bb) {
1380+ aa[0] += bb[0];
1381+ aa[1] += bb[1];
1382+}
1383+
1384+//
1385+// Complex add: aa += (rr + ii*j)
1386+//
1387+
1388+STATIC_INLINE void
1389+caddz(double *aa, double rr, double ii) {
1390+ aa[0] += rr;
1391+ aa[1] += ii;
1392+}
1393+
1394+//
1395+// Complex subtract: aa -= bb
1396+//
1397+
1398+STATIC_INLINE void
1399+csub(double *aa, double *bb) {
1400+ aa[0] -= bb[0];
1401+ aa[1] -= bb[1];
1402+}
1403+
1404+//
1405+// Complex subtract: aa -= (rr + ii*j)
1406+//
1407+
1408+STATIC_INLINE void
1409+csubz(double *aa, double rr, double ii) {
1410+ aa[0] -= rr;
1411+ aa[1] -= ii;
1412+}
1413+
1414+//
1415+// Complex negate: aa= -aa
1416+//
1417+
1418+STATIC_INLINE void
1419+cneg(double *aa) {
1420+ aa[0]= -aa[0];
1421+ aa[1]= -aa[1];
1422+}
1423+
1424+//
1425+// Evaluate a complex polynomial given the coefficients.
1426+// rv[0]+i*rv[1] is the result, in[0]+i*in[1] is the input value.
1427+// Coefficients are real values.
1428+//
1429+
1430+STATIC_INLINE void
1431+evaluate(double *rv, double *coef, int n_coef, double *in) {
1432+ double pz[2]; // Powers of Z
1433+
1434+ // Handle first iteration by hand
1435+ rv[0]= *coef++;
1436+ rv[1]= 0;
1437+
1438+ if (--n_coef > 0) {
1439+ // Handle second iteration by hand
1440+ pz[0]= in[0];
1441+ pz[1]= in[1];
1442+ rv[0] += *coef * pz[0];
1443+ rv[1] += *coef * pz[1];
1444+ coef++; n_coef--;
1445+
1446+ // Loop for remainder
1447+ while (n_coef > 0) {
1448+ cmul(pz, in);
1449+ rv[0] += *coef * pz[0];
1450+ rv[1] += *coef * pz[1];
1451+ coef++;
1452+ n_coef--;
1453+ }
1454+ }
1455+}
1456+
1457+
1458+//
1459+// Housekeeping
1460+//
1461+
1462+void
1463+fid_set_error_handler(void (*rout)(char*)) {
1464+ error_handler= rout;
1465+}
1466+
1467+char *
1468+fid_version() {
1469+ return VERSION;
1470+}
1471+
1472+
1473+//
1474+// Get the response and phase of a filter at the given frequency
1475+// (expressed as a proportion of the sampling rate, 0->0.5).
1476+// Phase is returned as a number from 0 to 1, representing a
1477+// phase between 0 and two-pi.
1478+//
1479+
1480+double
1481+fid_response_pha(FidFilter *filt, double freq, double *phase) {
1482+ double top[2], bot[2];
1483+ double theta= freq * 2 * M_PI;
1484+ double zz[2];
1485+
1486+ top[0]= 1;
1487+ top[1]= 0;
1488+ bot[0]= 1;
1489+ bot[1]= 0;
1490+ zz[0]= cos(theta);
1491+ zz[1]= sin(theta);
1492+
1493+ while (filt->len) {
1494+ double resp[2];
1495+ int cnt= filt->len;
1496+ evaluate(resp, filt->val, cnt, zz);
1497+ if (filt->typ == 'I')
1498+ cmul(bot, resp);
1499+ else if (filt->typ == 'F')
1500+ cmul(top, resp);
1501+ else
1502+ error("Unknown filter type %d in fid_response_pha()", filt->typ);
1503+ filt= FFNEXT(filt);
1504+ }
1505+
1506+ cdiv(top, bot);
1507+
1508+ if (phase) {
1509+ double pha= atan2(top[1], top[0]) / (2 * M_PI);
1510+ if (pha < 0) pha += 1.0;
1511+ *phase= pha;
1512+ }
1513+
1514+ return hypot(top[1], top[0]);
1515+}
1516+
1517+//
1518+// Get the response of a filter at the given frequency (expressed
1519+// as a proportion of the sampling rate, 0->0.5).
1520+//
1521+// Code duplicate, as I didn't want the overhead of a function
1522+// call to fid_response_pha. Almost every call in this routine
1523+// can be inlined.
1524+//
1525+
1526+double
1527+fid_response(FidFilter *filt, double freq) {
1528+ double top[2], bot[2];
1529+ double theta= freq * 2 * M_PI;
1530+ double zz[2];
1531+
1532+ top[0]= 1;
1533+ top[1]= 0;
1534+ bot[0]= 1;
1535+ bot[1]= 0;
1536+ zz[0]= cos(theta);
1537+ zz[1]= sin(theta);
1538+
1539+ while (filt->len) {
1540+ double resp[2];
1541+ int cnt= filt->len;
1542+ evaluate(resp, filt->val, cnt, zz);
1543+ if (filt->typ == 'I')
1544+ cmul(bot, resp);
1545+ else if (filt->typ == 'F')
1546+ cmul(top, resp);
1547+ else
1548+ error("Unknown filter type %d in fid_response()", filt->typ);
1549+ filt= FFNEXT(filt);
1550+ }
1551+
1552+ cdiv(top, bot);
1553+
1554+ return hypot(top[1], top[0]);
1555+}
1556+
1557+
1558+//
1559+// Estimate the delay that a filter causes to the signal by
1560+// looking for the point at which 50% of the filter calculations
1561+// are complete. This involves running test impulses through the
1562+// filter several times. The estimated delay in samples is
1563+// returned.
1564+//
1565+// Delays longer than 8,000,000 samples are not handled well, as
1566+// the code drops out at this point rather than get stuck in an
1567+// endless loop.
1568+//
1569+
1570+int
1571+fid_calc_delay(FidFilter *filt) {
1572+ FidRun *run;
1573+ FidFunc *dostep;
1574+ void *f1, *f2;
1575+ double tot, tot100, tot50;
1576+ int cnt;
1577+
1578+ run= fid_run_new(filt, &dostep);
1579+
1580+ // Run through to find at least the 99.9% point of filter; the r2
1581+ // (tot100) filter runs at 4x the speed of the other one to act as
1582+ // a reference point much further ahead in the impulse response.
1583+ f1= fid_run_newbuf(run);
1584+ f2= fid_run_newbuf(run);
1585+
1586+ tot= fabs(dostep(f1, 1.0));
1587+ tot100= fabs(dostep(f2, 1.0));
1588+ tot100 += fabs(dostep(f2, 0.0));
1589+ tot100 += fabs(dostep(f2, 0.0));
1590+ tot100 += fabs(dostep(f2, 0.0));
1591+
1592+ for (cnt= 1; cnt < 0x1000000; cnt++) {
1593+ tot += fabs(dostep(f1, 0.0));
1594+ tot100 += fabs(dostep(f2, 0.0));
1595+ tot100 += fabs(dostep(f2, 0.0));
1596+ tot100 += fabs(dostep(f2, 0.0));
1597+ tot100 += fabs(dostep(f2, 0.0));
1598+
1599+ if (tot/tot100 >= 0.999) break;
1600+ }
1601+ fid_run_freebuf(f1);
1602+ fid_run_freebuf(f2);
1603+
1604+ // Now find the 50% point
1605+ tot50= tot100/2;
1606+ f1= fid_run_newbuf(run);
1607+ tot= fabs(dostep(f1, 1.0));
1608+ for (cnt= 0; tot < tot50; cnt++)
1609+ tot += fabs(dostep(f1, 0.0));
1610+ fid_run_freebuf(f1);
1611+
1612+ // Clean up, return
1613+ fid_run_free(run);
1614+ return cnt;
1615+}
1616+
1617+
1618+//
1619+// 'mkfilter'-derived code
1620+//
1621+
1622+#include "fidmkf.h"
1623+
1624+
1625+//
1626+// Stack a number of identical filters, generating the required
1627+// FidFilter* return value
1628+//
1629+
1630+static FidFilter*
1631+stack_filter(int order, int n_head, int n_val, ...) {
1632+ FidFilter *rv= FFALLOC(n_head * order, n_val * order);
1633+ FidFilter *p, *q;
1634+ va_list ap;
1635+ int a, b, len;
1636+
1637+ if (order == 0) return rv;
1638+
1639+ // Copy from ap
1640+ va_start(ap, n_val);
1641+ p= q= rv;
1642+ for (a= 0; a<n_head; a++) {
1643+ p->typ= va_arg(ap, int);
1644+ p->cbm= va_arg(ap, int);
1645+ p->len= va_arg(ap, int);
1646+ for (b= 0; b<p->len; b++)
1647+ p->val[b]= va_arg(ap, double);
1648+ p= FFNEXT(p);
1649+ }
1650+ order--;
1651+
1652+ // Check length
1653+ len= ((char*)p)-((char*)q);
1654+ if (len != FFCSIZE(n_head-1, n_val))
1655+ error("Internal error; bad call to stack_filter(); length mismatch (%d,%d)",
1656+ len, FFCSIZE(n_head-1, n_val));
1657+
1658+ // Make as many additional copies as necessary
1659+ while (order-- > 0) {
1660+ memcpy(p, q, len);
1661+ p= (FidFilter*)(len + (char*)p);
1662+ }
1663+
1664+ // List is already terminated due to zeroed allocation
1665+ return rv;
1666+}
1667+
1668+//
1669+// Search for a peak between two given frequencies. It is
1670+// assumed that the gradient goes upwards from 'f0' to the peak,
1671+// and then down again to 'f3'. If there are any other curves,
1672+// this routine will get confused and will come up with some
1673+// frequency, although probably not the right one.
1674+//
1675+// Returns the frequency of the peak.
1676+//
1677+
1678+static double
1679+search_peak(FidFilter *ff, double f0, double f3) {
1680+ double f1, f2;
1681+ double r1, r2;
1682+ int a;
1683+
1684+ // Binary search, modified, taking two intermediate points. Do 20
1685+ // subdivisions, which should give 1/2^20 == 1e-6 accuracy compared
1686+ // to original range.
1687+ for (a= 0; a<20; a++) {
1688+ f1= 0.51 * f0 + 0.49 * f3;
1689+ f2= 0.49 * f0 + 0.51 * f3;
1690+ if (f1 == f2) break; // We're hitting FP limit
1691+ r1= fid_response(ff, f1);
1692+ r2= fid_response(ff, f2);
1693+ if (r1 > r2) // Peak is either to the left, or between f1/f2
1694+ f3= f2;
1695+ else // Peak is either to the right, or between f1/f2
1696+ f0= f1;
1697+ }
1698+ return (f0+f3)*0.5;
1699+}
1700+
1701+//
1702+// Handle the different 'back-ends' for Bessel, Butterworth and
1703+// Chebyshev filters. First argument selects between bilinear
1704+// (0) and matched-Z (non-0). The BL and MZ macros makes this a
1705+// bit more obvious in the code.
1706+//
1707+// Overall filter gain is adjusted to give the peak at 1.0. This
1708+// is easy for all types except for band-pass, where a search is
1709+// required to find the precise peak. This is much slower than
1710+// the other types.
1711+//
1712+
1713+#define BL 0
1714+#define MZ 1
1715+
1716+static FidFilter*
1717+do_lowpass(int mz, double freq) {
1718+ FidFilter *rv;
1719+ lowpass(prewarp(freq));
1720+ if (mz) s2z_matchedZ(); else s2z_bilinear();
1721+ rv= z2fidfilter(1.0, ~0); // FIR is constant
1722+ rv->val[0]= 1.0 / fid_response(rv, 0.0);
1723+ return rv;
1724+}
1725+
1726+static FidFilter*
1727+do_highpass(int mz, double freq) {
1728+ FidFilter *rv;
1729+ highpass(prewarp(freq));
1730+ if (mz) s2z_matchedZ(); else s2z_bilinear();
1731+ rv= z2fidfilter(1.0, ~0); // FIR is constant
1732+ rv->val[0]= 1.0 / fid_response(rv, 0.5);
1733+ return rv;
1734+}
1735+
1736+static FidFilter*
1737+do_bandpass(int mz, double f0, double f1) {
1738+ FidFilter *rv;
1739+ bandpass(prewarp(f0), prewarp(f1));
1740+ if (mz) s2z_matchedZ(); else s2z_bilinear();
1741+ rv= z2fidfilter(1.0, ~0); // FIR is constant
1742+ rv->val[0]= 1.0 / fid_response(rv, search_peak(rv, f0, f1));
1743+ return rv;
1744+}
1745+
1746+static FidFilter*
1747+do_bandstop(int mz, double f0, double f1) {
1748+ FidFilter *rv;
1749+ bandstop(prewarp(f0), prewarp(f1));
1750+ if (mz) s2z_matchedZ(); else s2z_bilinear();
1751+ rv= z2fidfilter(1.0, 5); // FIR second coefficient is *non-const* for bandstop
1752+ rv->val[0]= 1.0 / fid_response(rv, 0.0); // Use 0Hz response as reference
1753+ return rv;
1754+}
1755+
1756+
1757+//
1758+// Information passed to individual filter design routines:
1759+//
1760+// double* rout(double rate, double f0, double f1,
1761+// int order, int n_arg, double *arg);
1762+//
1763+// 'rate' is the sampling rate, or 1 if not set
1764+// 'f0' and 'f1' give the frequency or frequency range as a
1765+// proportion of the sampling rate
1766+// 'order' is the order of the filter (the integer passed immediately
1767+// after the name)
1768+// 'n_arg' is the number of additional arguments for the filter
1769+// 'arg' gives the additional argument values: arg[n]
1770+//
1771+// Note that #O #o #F and #R are mapped to the f0/f1/order
1772+// arguments, and are not included in the arg[] array.
1773+//
1774+// See the previous description for the required meaning of the
1775+// return value FidFilter list.
1776+//
1777+
1778+//
1779+// Filter design routines and supporting code
1780+//
1781+
1782+static FidFilter*
1783+des_bpre(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1784+ bandpass_res(f0, arg[0]);
1785+ return z2fidfilter(1.0, ~0); // FIR constant
1786+}
1787+
1788+static FidFilter*
1789+des_bsre(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1790+ bandstop_res(f0, arg[0]);
1791+ return z2fidfilter(1.0, 0); // FIR not constant, depends on freq
1792+}
1793+
1794+static FidFilter*
1795+des_apre(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1796+ allpass_res(f0, arg[0]);
1797+ return z2fidfilter(1.0, 0); // FIR not constant, depends on freq
1798+}
1799+
1800+static FidFilter*
1801+des_pi(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1802+ prop_integral(prewarp(f0));
1803+ s2z_bilinear();
1804+ return z2fidfilter(1.0, 0); // FIR not constant, depends on freq
1805+}
1806+
1807+static FidFilter*
1808+des_piz(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1809+ prop_integral(prewarp(f0));
1810+ s2z_matchedZ();
1811+ return z2fidfilter(1.0, 0); // FIR not constant, depends on freq
1812+}
1813+
1814+static FidFilter*
1815+des_lpbe(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1816+ bessel(order);
1817+ return do_lowpass(BL, f0);
1818+}
1819+
1820+static FidFilter*
1821+des_hpbe(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1822+ bessel(order);
1823+ return do_highpass(BL, f0);
1824+}
1825+
1826+static FidFilter*
1827+des_bpbe(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1828+ bessel(order);
1829+ return do_bandpass(BL, f0, f1);
1830+}
1831+
1832+static FidFilter*
1833+des_bsbe(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1834+ bessel(order);
1835+ return do_bandstop(BL, f0, f1);
1836+}
1837+
1838+static FidFilter*
1839+des_lpbez(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1840+ bessel(order);
1841+ return do_lowpass(MZ, f0);
1842+}
1843+
1844+static FidFilter*
1845+des_hpbez(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1846+ bessel(order);
1847+ return do_highpass(MZ, f0);
1848+}
1849+
1850+static FidFilter*
1851+des_bpbez(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1852+ bessel(order);
1853+ return do_bandpass(MZ, f0, f1);
1854+}
1855+
1856+static FidFilter*
1857+des_bsbez(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1858+ bessel(order);
1859+ return do_bandstop(MZ, f0, f1);
1860+}
1861+
1862+static FidFilter* // Butterworth-Bessel cross
1863+des_lpbube(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1864+ double tmp[MAXPZ];
1865+ int a;
1866+ bessel(order); memcpy(tmp, pol, order * sizeof(double));
1867+ butterworth(order);
1868+ for (a= 0; a<order; a++) pol[a] += (tmp[a]-pol[a]) * 0.01 * arg[0];
1869+ //for (a= 1; a<order; a+=2) pol[a] += arg[1] * 0.01;
1870+ return do_lowpass(BL, f0);
1871+}
1872+
1873+static FidFilter*
1874+des_lpbu(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1875+ butterworth(order);
1876+ return do_lowpass(BL, f0);
1877+}
1878+
1879+static FidFilter*
1880+des_hpbu(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1881+ butterworth(order);
1882+ return do_highpass(BL, f0);
1883+}
1884+
1885+static FidFilter*
1886+des_bpbu(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1887+ butterworth(order);
1888+ return do_bandpass(BL, f0, f1);
1889+}
1890+
1891+static FidFilter*
1892+des_bsbu(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1893+ butterworth(order);
1894+ return do_bandstop(BL, f0, f1);
1895+}
1896+
1897+static FidFilter*
1898+des_lpbuz(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1899+ butterworth(order);
1900+ return do_lowpass(MZ, f0);
1901+}
1902+
1903+static FidFilter*
1904+des_hpbuz(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1905+ butterworth(order);
1906+ return do_highpass(MZ, f0);
1907+}
1908+
1909+static FidFilter*
1910+des_bpbuz(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1911+ butterworth(order);
1912+ return do_bandpass(MZ, f0, f1);
1913+}
1914+
1915+static FidFilter*
1916+des_bsbuz(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1917+ butterworth(order);
1918+ return do_bandstop(MZ, f0, f1);
1919+}
1920+
1921+static FidFilter*
1922+des_lpch(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1923+ chebyshev(order, arg[0]);
1924+ return do_lowpass(BL, f0);
1925+}
1926+
1927+static FidFilter*
1928+des_hpch(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1929+ chebyshev(order, arg[0]);
1930+ return do_highpass(BL, f0);
1931+}
1932+
1933+static FidFilter*
1934+des_bpch(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1935+ chebyshev(order, arg[0]);
1936+ return do_bandpass(BL, f0, f1);
1937+}
1938+
1939+static FidFilter*
1940+des_bsch(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1941+ chebyshev(order, arg[0]);
1942+ return do_bandstop(BL, f0, f1);
1943+}
1944+
1945+static FidFilter*
1946+des_lpchz(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1947+ chebyshev(order, arg[0]);
1948+ return do_lowpass(MZ, f0);
1949+}
1950+
1951+static FidFilter*
1952+des_hpchz(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1953+ chebyshev(order, arg[0]);
1954+ return do_highpass(MZ, f0);
1955+}
1956+
1957+static FidFilter*
1958+des_bpchz(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1959+ chebyshev(order, arg[0]);
1960+ return do_bandpass(MZ, f0, f1);
1961+}
1962+
1963+static FidFilter*
1964+des_bschz(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1965+ chebyshev(order, arg[0]);
1966+ return do_bandstop(MZ, f0, f1);
1967+}
1968+
1969+static FidFilter*
1970+des_lpbq(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1971+ double omega= 2 * M_PI * f0;
1972+ double cosv= cos(omega);
1973+ double alpha= sin(omega) / 2 / arg[0];
1974+ return stack_filter(order, 3, 7,
1975+ 'I', 0x0, 3, 1 + alpha, -2 * cosv, 1 - alpha,
1976+ 'F', 0x7, 3, 1.0, 2.0, 1.0,
1977+ 'F', 0x0, 1, (1-cosv) * 0.5);
1978+}
1979+
1980+static FidFilter*
1981+des_hpbq(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1982+ double omega= 2 * M_PI * f0;
1983+ double cosv= cos(omega);
1984+ double alpha= sin(omega) / 2 / arg[0];
1985+ return stack_filter(order, 3, 7,
1986+ 'I', 0x0, 3, 1 + alpha, -2 * cosv, 1 - alpha,
1987+ 'F', 0x7, 3, 1.0, -2.0, 1.0,
1988+ 'F', 0x0, 1, (1+cosv) * 0.5);
1989+}
1990+
1991+static FidFilter*
1992+des_bpbq(double rate, double f0, double f1, int order, int n_arg, double *arg) {
1993+ double omega= 2 * M_PI * f0;
1994+ double cosv= cos(omega);
1995+ double alpha= sin(omega) / 2 / arg[0];
1996+ return stack_filter(order, 3, 7,
1997+ 'I', 0x0, 3, 1 + alpha, -2 * cosv, 1 - alpha,
1998+ 'F', 0x7, 3, 1.0, 0.0, -1.0,
1999+ 'F', 0x0, 1, alpha);
2000+}
2001+
2002+static FidFilter*
2003+des_bsbq(double rate, double f0, double f1, int order, int n_arg, double *arg) {
2004+ double omega= 2 * M_PI * f0;
2005+ double cosv= cos(omega);
2006+ double alpha= sin(omega) / 2 / arg[0];
2007+ return stack_filter(order, 2, 6,
2008+ 'I', 0x0, 3, 1 + alpha, -2 * cosv, 1 - alpha,
2009+ 'F', 0x5, 3, 1.0, -2 * cosv, 1.0);
2010+}
2011+
2012+static FidFilter*
2013+des_apbq(double rate, double f0, double f1, int order, int n_arg, double *arg) {
2014+ double omega= 2 * M_PI * f0;
2015+ double cosv= cos(omega);
2016+ double alpha= sin(omega) / 2 / arg[0];
2017+ return stack_filter(order, 2, 6,
2018+ 'I', 0x0, 3, 1 + alpha, -2 * cosv, 1 - alpha,
2019+ 'F', 0x0, 3, 1 - alpha, -2 * cosv, 1 + alpha);
2020+}
2021+
2022+static FidFilter*
2023+des_pkbq(double rate, double f0, double f1, int order, int n_arg, double *arg) {
2024+ double omega= 2 * M_PI * f0;
2025+ double cosv= cos(omega);
2026+ double alpha= sin(omega) / 2 / arg[0];
2027+ double A= pow(10, arg[1]/40);
2028+ return stack_filter(order, 2, 6,
2029+ 'I', 0x0, 3, 1 + alpha/A, -2 * cosv, 1 - alpha/A,
2030+ 'F', 0x0, 3, 1 + alpha*A, -2 * cosv, 1 - alpha*A);
2031+}
2032+
2033+static FidFilter*
2034+des_lsbq(double rate, double f0, double f1, int order, int n_arg, double *arg) {
2035+ double omega= 2 * M_PI * f0;
2036+ double cosv= cos(omega);
2037+ double sinv= sin(omega);
2038+ double A= pow(10, arg[1]/40);
2039+ double beta= sqrt((A*A+1)/arg[0] - (A-1)*(A-1));
2040+ return stack_filter(order, 2, 6,
2041+ 'I', 0x0, 3,
2042+ (A+1) + (A-1)*cosv + beta*sinv,
2043+ -2 * ((A-1) + (A+1)*cosv),
2044+ (A+1) + (A-1)*cosv - beta*sinv,
2045+ 'F', 0x0, 3,
2046+ A*((A+1) - (A-1)*cosv + beta*sinv),
2047+ 2*A*((A-1) - (A+1)*cosv),
2048+ A*((A+1) - (A-1)*cosv - beta*sinv));
2049+}
2050+
2051+static FidFilter*
2052+des_hsbq(double rate, double f0, double f1, int order, int n_arg, double *arg) {
2053+ double omega= 2 * M_PI * f0;
2054+ double cosv= cos(omega);
2055+ double sinv= sin(omega);
2056+ double A= pow(10, arg[1]/40);
2057+ double beta= sqrt((A*A+1)/arg[0] - (A-1)*(A-1));
2058+ return stack_filter(order, 2, 6,
2059+ 'I', 0x0, 3,
2060+ (A+1) - (A-1)*cosv + beta*sinv,
2061+ 2 * ((A-1) - (A+1)*cosv),
2062+ (A+1) - (A-1)*cosv - beta*sinv,
2063+ 'F', 0x0, 3,
2064+ A*((A+1) + (A-1)*cosv + beta*sinv),
2065+ -2*A*((A-1) + (A+1)*cosv),
2066+ A*((A+1) + (A-1)*cosv - beta*sinv));
2067+}
2068+
2069+static FidFilter*
2070+des_lpbl(double rate, double f0, double f1, int order, int n_arg, double *arg) {
2071+ double wid= 0.4109205/f0;
2072+ double tot, adj;
2073+ int max= (int)floor(wid);
2074+ int a;
2075+ FidFilter *ff= (FidFilter*)Alloc(FFCSIZE(1, max*2+1));
2076+ ff->typ= 'F';
2077+ ff->cbm= 0;
2078+ ff->len= max*2+1;
2079+ ff->val[max]= tot= 1.0;
2080+ for (a= 1; a<=max; a++) {
2081+ double val= 0.42 +
2082+ 0.5 * cos(M_PI * a / wid) +
2083+ 0.08 * cos(M_PI * 2.0 * a / wid);
2084+ ff->val[max-a]= val;
2085+ ff->val[max+a]= val;
2086+ tot += val * 2.0;
2087+ }
2088+ adj= 1/tot;
2089+ for (a= 0; a<=max*2; a++) ff->val[a] *= adj;
2090+ return ff;
2091+}
2092+
2093+static FidFilter*
2094+des_lphm(double rate, double f0, double f1, int order, int n_arg, double *arg) {
2095+ double wid= 0.3262096/f0;
2096+ double tot, adj;
2097+ int max= (int)floor(wid);
2098+ int a;
2099+ FidFilter *ff= (FidFilter*)Alloc(FFCSIZE(1, max*2+1));
2100+ ff->typ= 'F';
2101+ ff->cbm= 0;
2102+ ff->len= max*2+1;
2103+ ff->val[max]= tot= 1.0;
2104+ for (a= 1; a<=max; a++) {
2105+ double val= 0.54 +
2106+ 0.46 * cos(M_PI * a / wid);
2107+ ff->val[max-a]= val;
2108+ ff->val[max+a]= val;
2109+ tot += val * 2.0;
2110+ }
2111+ adj= 1/tot;
2112+ for (a= 0; a<=max*2; a++) ff->val[a] *= adj;
2113+ return ff;
2114+}
2115+
2116+static FidFilter*
2117+des_lphn(double rate, double f0, double f1, int order, int n_arg, double *arg) {
2118+ double wid= 0.360144/f0;
2119+ double tot, adj;
2120+ int max= (int)floor(wid);
2121+ int a;
2122+ FidFilter *ff= (FidFilter*)Alloc(FFCSIZE(1, max*2+1));
2123+ ff->typ= 'F';
2124+ ff->cbm= 0;
2125+ ff->len= max*2+1;
2126+ ff->val[max]= tot= 1.0;
2127+ for (a= 1; a<=max; a++) {
2128+ double val= 0.5 +
2129+ 0.5 * cos(M_PI * a / wid);
2130+ ff->val[max-a]= val;
2131+ ff->val[max+a]= val;
2132+ tot += val * 2.0;
2133+ }
2134+ adj= 1/tot;
2135+ for (a= 0; a<=max*2; a++) ff->val[a] *= adj;
2136+ return ff;
2137+}
2138+
2139+static FidFilter*
2140+des_lpba(double rate, double f0, double f1, int order, int n_arg, double *arg) {
2141+ double wid= 0.3189435/f0;
2142+ double tot, adj;
2143+ int max= (int)floor(wid);
2144+ int a;
2145+ FidFilter *ff= (FidFilter*)Alloc(FFCSIZE(1, max*2+1));
2146+ ff->typ= 'F';
2147+ ff->cbm= 0;
2148+ ff->len= max*2+1;
2149+ ff->val[max]= tot= 1.0;
2150+ for (a= 1; a<=max; a++) {
2151+ double val= 1.0 - a/wid;
2152+ ff->val[max-a]= val;
2153+ ff->val[max+a]= val;
2154+ tot += val * 2.0;
2155+ }
2156+ adj= 1/tot;
2157+ for (a= 0; a<=max*2; a++) ff->val[a] *= adj;
2158+ return ff;
2159+}
2160+
2161+
2162+//
2163+// Filter table
2164+//
2165+
2166+static struct {
2167+ FidFilter *(*rout)(double,double,double,int,int,double*); // Designer routine address
2168+ char *fmt; // Format for spec-string
2169+ char *txt; // Human-readable description of filter
2170+} filter[]= {
2171+ { des_bpre, "BpRe/#V/#F",
2172+ "Bandpass resonator, Q=#V (0 means Inf), frequency #F" },
2173+ { des_bsre, "BsRe/#V/#F",
2174+ "Bandstop resonator, Q=#V (0 means Inf), frequency #F" },
2175+ { des_apre, "ApRe/#V/#F",
2176+ "Allpass resonator, Q=#V (0 means Inf), frequency #F" },
2177+ { des_pi, "Pi/#F",
2178+ "Proportional-integral filter, frequency #F" },
2179+ { des_piz, "PiZ/#F",
2180+ "Proportional-integral filter, matched z-transform, frequency #F" },
2181+ { des_lpbe, "LpBe#O/#F",
2182+ "Lowpass Bessel filter, order #O, -3.01dB frequency #F" },
2183+ { des_hpbe, "HpBe#O/#F",
2184+ "Highpass Bessel filter, order #O, -3.01dB frequency #F" },
2185+ { des_bpbe, "BpBe#O/#R",
2186+ "Bandpass Bessel filter, order #O, -3.01dB frequencies #R" },
2187+ { des_bsbe, "BsBe#O/#R",
2188+ "Bandstop Bessel filter, order #O, -3.01dB frequencies #R" },
2189+ { des_lpbu, "LpBu#O/#F",
2190+ "Lowpass Butterworth filter, order #O, -3.01dB frequency #F" },
2191+ { des_hpbu, "HpBu#O/#F",
2192+ "Highpass Butterworth filter, order #O, -3.01dB frequency #F" },
2193+ { des_bpbu, "BpBu#O/#R",
2194+ "Bandpass Butterworth filter, order #O, -3.01dB frequencies #R" },
2195+ { des_bsbu, "BsBu#O/#R",
2196+ "Bandstop Butterworth filter, order #O, -3.01dB frequencies #R" },
2197+ { des_lpch, "LpCh#O/#V/#F",
2198+ "Lowpass Chebyshev filter, order #O, passband ripple #VdB, -3.01dB frequency #F" },
2199+ { des_hpch, "HpCh#O/#V/#F",
2200+ "Highpass Chebyshev filter, order #O, passband ripple #VdB, -3.01dB frequency #F" },
2201+ { des_bpch, "BpCh#O/#V/#R",
2202+ "Bandpass Chebyshev filter, order #O, passband ripple #VdB, -3.01dB frequencies #R" },
2203+ { des_bsch, "BsCh#O/#V/#R",
2204+ "Bandstop Chebyshev filter, order #O, passband ripple #VdB, -3.01dB frequencies #R" },
2205+ { des_lpbez, "LpBeZ#O/#F",
2206+ "Lowpass Bessel filter, matched z-transform, order #O, -3.01dB frequency #F" },
2207+ { des_hpbez, "HpBeZ#O/#F",
2208+ "Highpass Bessel filter, matched z-transform, order #O, -3.01dB frequency #F" },
2209+ { des_bpbez, "BpBeZ#O/#R",
2210+ "Bandpass Bessel filter, matched z-transform, order #O, -3.01dB frequencies #R" },
2211+ { des_bsbez, "BsBeZ#O/#R",
2212+ "Bandstop Bessel filter, matched z-transform, order #O, -3.01dB frequencies #R" },
2213+ { des_lpbuz, "LpBuZ#O/#F",
2214+ "Lowpass Butterworth filter, matched z-transform, order #O, -3.01dB frequency #F" },
2215+ { des_hpbuz, "HpBuZ#O/#F",
2216+ "Highpass Butterworth filter, matched z-transform, order #O, -3.01dB frequency #F" },
2217+ { des_bpbuz, "BpBuZ#O/#R",
2218+ "Bandpass Butterworth filter, matched z-transform, order #O, -3.01dB frequencies #R" },
2219+ { des_bsbuz, "BsBuZ#O/#R",
2220+ "Bandstop Butterworth filter, matched z-transform, order #O, -3.01dB frequencies #R" },
2221+ { des_lpchz, "LpChZ#O/#V/#F",
2222+ "Lowpass Chebyshev filter, matched z-transform, order #O, "
2223+ "passband ripple #VdB, -3.01dB frequency #F" },
2224+ { des_hpchz, "HpChZ#O/#V/#F",
2225+ "Highpass Chebyshev filter, matched z-transform, order #O, "
2226+ "passband ripple #VdB, -3.01dB frequency #F" },
2227+ { des_bpchz, "BpChZ#O/#V/#R",
2228+ "Bandpass Chebyshev filter, matched z-transform, order #O, "
2229+ "passband ripple #VdB, -3.01dB frequencies #R" },
2230+ { des_bschz, "BsChZ#O/#V/#R",
2231+ "Bandstop Chebyshev filter, matched z-transform, order #O, "
2232+ "passband ripple #VdB, -3.01dB frequencies #R" },
2233+ { des_lpbube, "LpBuBe#O/#V/#F",
2234+ "Lowpass Butterworth-Bessel #V% cross, order #O, -3.01dB frequency #F" },
2235+ { des_lpbq, "LpBq#o/#V/#F",
2236+ "Lowpass biquad filter, order #O, Q=#V, -3.01dB frequency #F" },
2237+ { des_hpbq, "HpBq#o/#V/#F",
2238+ "Highpass biquad filter, order #O, Q=#V, -3.01dB frequency #F" },
2239+ { des_bpbq, "BpBq#o/#V/#F",
2240+ "Bandpass biquad filter, order #O, Q=#V, centre frequency #F" },
2241+ { des_bsbq, "BsBq#o/#V/#F",
2242+ "Bandstop biquad filter, order #O, Q=#V, centre frequency #F" },
2243+ { des_apbq, "ApBq#o/#V/#F",
2244+ "Allpass biquad filter, order #O, Q=#V, centre frequency #F" },
2245+ { des_pkbq, "PkBq#o/#V/#V/#F",
2246+ "Peaking biquad filter, order #O, Q=#V, dBgain=#V, frequency #F" },
2247+ { des_lsbq, "LsBq#o/#V/#V/#F",
2248+ "Lowpass shelving biquad filter, S=#V, dBgain=#V, frequency #F" },
2249+ { des_hsbq, "HsBq#o/#V/#V/#F",
2250+ "Highpass shelving biquad filter, S=#V, dBgain=#V, frequency #F" },
2251+ { des_lpbl, "LpBl/#F",
2252+ "Lowpass Blackman window, -3.01dB frequency #F" },
2253+ { des_lphm, "LpHm/#F",
2254+ "Lowpass Hamming window, -3.01dB frequency #F" },
2255+ { des_lphn, "LpHn/#F",
2256+ "Lowpass Hann window, -3.01dB frequency #F" },
2257+ { des_lpba, "LpBa/#F",
2258+ "Lowpass Bartlet (triangular) window, -3.01dB frequency #F" },
2259+ { 0, 0, 0 }
2260+};
2261+
2262+//
2263+// Design a filter. Spec and range are passed as arguments. The
2264+// return value is a pointer to a FidFilter as documented earlier
2265+// in this file. This needs to be free()d once finished with.
2266+//
2267+// If 'f_adj' is set, then the frequencies fed to the design code
2268+// are adjusted automatically to get true sqrt(0.5) (-3.01dB)
2269+// values at the provided frequencies. (This is obviously a
2270+// slower operation)
2271+//
2272+// If 'descp' is non-0, then a long description of the filter is
2273+// generated and returned as a strdup'd string at the given
2274+// location.
2275+//
2276+// Any problem with the spec causes the program to die with an
2277+// error message.
2278+//
2279+// 'spec' gives the specification string. The 'rate' argument
2280+// gives the sampling rate for the data that will be passed to
2281+// the filter. This is only used to interpret the frequencies
2282+// given in the spec or given in 'freq0' and 'freq1'. Use 1.0 if
2283+// the frequencies are given as a proportion of the sampling
2284+// rate, in the range 0 to 0.5. 'freq0' and 'freq1' provide the
2285+// default frequency or frequency range if this is not included
2286+// in the specification string. These should be -ve if there is
2287+// no default range (causing an error if they are omitted from
2288+// the 'spec').
2289+//
2290+
2291+typedef struct Spec Spec;
2292+static char* parse_spec(Spec*);
2293+static FidFilter *auto_adjust_single(Spec *sp, double rate, double f0);
2294+static FidFilter *auto_adjust_dual(Spec *sp, double rate, double f0, double f1);
2295+struct Spec {
2296+#define MAXARG 10
2297+ char *spec;
2298+ double in_f0, in_f1;
2299+ int in_adj;
2300+ double argarr[MAXARG];
2301+ double f0, f1;
2302+ int adj;
2303+ int n_arg;
2304+ int order;
2305+ int minlen; // Minimum length of spec-string, assuming f0/f1 passed separately
2306+ int n_freq; // Number of frequencies provided: 0,1,2
2307+ int fi; // Filter index (filter[fi])
2308+};
2309+
2310+FidFilter *
2311+fid_design(const char *spec, double rate, double freq0, double freq1, int f_adj, char **descp) {
2312+ FidFilter *rv;
2313+ Spec sp;
2314+ double f0, f1;
2315+ char *err;
2316+
2317+ // Parse the filter-spec
2318+ sp.spec= spec;
2319+ sp.in_f0= freq0;
2320+ sp.in_f1= freq1;
2321+ sp.in_adj= f_adj;
2322+ err= parse_spec(&sp);
2323+ if (err) error("%s", err);
2324+ f0= sp.f0;
2325+ f1= sp.f1;
2326+
2327+ // Adjust frequencies to range 0-0.5, and check them
2328+ f0 /= rate;
2329+ if (f0 > 0.5) error("Frequency of %gHz out of range with sampling rate of %gHz", f0*rate, rate);
2330+ f1 /= rate;
2331+ if (f1 > 0.5) error("Frequency of %gHz out of range with sampling rate of %gHz", f1*rate, rate);
2332+
2333+ // Okay we now have a successful spec-match to filter[sp.fi], and sp.n_arg
2334+ // args are now in sp.argarr[]
2335+
2336+ // Generate the filter
2337+ if (!sp.adj)
2338+ rv= filter[sp.fi].rout(rate, f0, f1, sp.order, sp.n_arg, sp.argarr);
2339+ else if (strstr(filter[sp.fi].fmt, "#R"))
2340+ rv= auto_adjust_dual(&sp, rate, f0, f1);
2341+ else
2342+ rv= auto_adjust_single(&sp, rate, f0);
2343+
2344+ // Generate a long description if required
2345+ if (descp) {
2346+ char *fmt= filter[sp.fi].txt;
2347+ int max= strlen(fmt) + 60 + sp.n_arg * 20;
2348+ char *desc= (char*)Alloc(max);
2349+ char *p= desc;
2350+ char ch;
2351+ double *arg= sp.argarr;
2352+ int n_arg= sp.n_arg;
2353+
2354+ while ((ch= *fmt++)) {
2355+ if (ch != '#') {
2356+ *p++= ch;
2357+ continue;
2358+ }
2359+
2360+ switch (*fmt++) {
2361+ case 'O':
2362+ p += sprintf(p, "%d", sp.order);
2363+ break;
2364+ case 'F':
2365+ p += sprintf(p, "%g", f0*rate);
2366+ break;
2367+ case 'R':
2368+ p += sprintf(p, "%g-%g", f0*rate, f1*rate);
2369+ break;
2370+ case 'V':
2371+ if (n_arg <= 0)
2372+ error("Internal error -- disagreement between filter short-spec\n"
2373+ " and long-description over number of arguments");
2374+ n_arg--;
2375+ p += sprintf(p, "%g", *arg++);
2376+ break;
2377+ default:
2378+ error("Internal error: unknown format in long description: #%c", fmt[-1]);
2379+ }
2380+ }
2381+ *p++= 0;
2382+ if (p-desc >= max) error("Internal error: exceeded estimated description buffer");
2383+ *descp= desc;
2384+ }
2385+
2386+ return rv;
2387+}
2388+
2389+//
2390+// Auto-adjust input frequency to give correct sqrt(0.5)
2391+// (~-3.01dB) point to 6 figures
2392+//
2393+
2394+#define M301DB (0.707106781186548)
2395+
2396+static FidFilter *
2397+auto_adjust_single(Spec *sp, double rate, double f0) {
2398+ double a0, a1, a2;
2399+ FidFilter *(*design)(double,double,double,int,int,double*)= filter[sp->fi].rout;
2400+ FidFilter *rv= 0;
2401+ double resp;
2402+ double r0, r2;
2403+ int incr; // Increasing (1) or decreasing (0)
2404+ int a;
2405+
2406+#define DESIGN(aa) design(rate, aa, aa, sp->order, sp->n_arg, sp->argarr)
2407+#define TEST(aa) { if (rv) {free(rv);rv= 0;} rv= DESIGN(aa); resp= fid_response(rv, f0); }
2408+
2409+ // Try and establish a range within which we can find the point
2410+ a0= f0; TEST(a0); r0= resp;
2411+ for (a= 2; 1; a*=2) {
2412+ a2= f0/a; TEST(a2); r2= resp;
2413+ if ((r0 < M301DB) != (r2 < M301DB)) break;
2414+ a2= 0.5-((0.5-f0)/a); TEST(a2); r2= resp;
2415+ if ((r0 < M301DB) != (r2 < M301DB)) break;
2416+ if (a == 32) // No success
2417+ error("auto_adjust_single internal error -- can't establish enclosing range");
2418+ }
2419+
2420+ incr= r2 > r0;
2421+ if (a0 > a2) {
2422+ a1= a0; a0= a2; a2= a1;
2423+ incr= !incr;
2424+ }
2425+
2426+ // Binary search
2427+ while (1) {
2428+ a1= 0.5 * (a0 + a2);
2429+ if (a1 == a0 || a1 == a2) break; // Limit of double, sanity check
2430+ TEST(a1);
2431+ if (resp >= 0.9999995 * M301DB && resp < 1.0000005 * M301DB) break;
2432+ if (incr == (resp > M301DB))
2433+ a2= a1;
2434+ else
2435+ a0= a1;
2436+ }
2437+
2438+#undef TEST
2439+#undef DESIGN
2440+
2441+ return rv;
2442+}
2443+
2444+
2445+//
2446+// Auto-adjust input frequencies to give response of sqrt(0.5)
2447+// (~-3.01dB) correct to 6sf at the given frequency-points
2448+//
2449+
2450+static FidFilter *
2451+auto_adjust_dual(Spec *sp, double rate, double f0, double f1) {
2452+ double mid= 0.5 * (f0+f1);
2453+ double wid= 0.5 * fabs(f1-f0);
2454+ FidFilter *(*design)(double,double,double,int,int,double*)= filter[sp->fi].rout;
2455+ FidFilter *rv= 0;
2456+ int bpass= -1;
2457+ double delta;
2458+ double mid0, mid1;
2459+ double wid0, wid1;
2460+ double r0, r1, err0, err1;
2461+ double perr;
2462+ int cnt;
2463+ int cnt_design= 0;
2464+
2465+#define DESIGN(mm,ww) { if (rv) {free(rv);rv= 0;} \
2466+ rv= design(rate, mm-ww, mm+ww, sp->order, sp->n_arg, sp->argarr); \
2467+ r0= fid_response(rv, f0); r1= fid_response(rv, f1); \
2468+ err0= fabs(M301DB-r0); err1= fabs(M301DB-r1); cnt_design++; }
2469+
2470+#define INC_WID ((r0+r1 < 1.0) == bpass)
2471+#define INC_MID ((r0 > r1) == bpass)
2472+#define MATCH (err0 < 0.000000499 && err1 < 0.000000499)
2473+#define PERR (err0+err1)
2474+
2475+ DESIGN(mid, wid);
2476+ bpass= (fid_response(rv, 0) < 0.5);
2477+ delta= wid * 0.5;
2478+
2479+ // Try delta changes until we get there
2480+ for (cnt= 0; 1; cnt++, delta *= 0.51) {
2481+ DESIGN(mid, wid); // I know -- this is redundant
2482+ perr= PERR;
2483+
2484+ mid0= mid;
2485+ wid0= wid;
2486+ mid1= mid + (INC_MID ? delta : -delta);
2487+ wid1= wid + (INC_WID ? delta : -delta);
2488+
2489+ if (mid0 - wid1 > 0.0 && mid0 + wid1 < 0.5) {
2490+ DESIGN(mid0, wid1);
2491+ if (MATCH) break;
2492+ if (PERR < perr) { perr= PERR; mid= mid0; wid= wid1; }
2493+ }
2494+
2495+ if (mid1 - wid0 > 0.0 && mid1 + wid0 < 0.5) {
2496+ DESIGN(mid1, wid0);
2497+ if (MATCH) break;
2498+ if (PERR < perr) { perr= PERR; mid= mid1; wid= wid0; }
2499+ }
2500+
2501+ if (mid1 - wid1 > 0.0 && mid1 + wid1 < 0.5) {
2502+ DESIGN(mid1, wid1);
2503+ if (MATCH) break;
2504+ if (PERR < perr) { perr= PERR; mid= mid1; wid= wid1; }
2505+ }
2506+
2507+ if (cnt > 1000)
2508+ error("auto_adjust_dual -- design not converging");
2509+ }
2510+
2511+#undef INC_WID
2512+#undef INC_MID
2513+#undef MATCH
2514+#undef PERR
2515+#undef DESIGN
2516+
2517+ return rv;
2518+}
2519+
2520+
2521+//
2522+// Expand a specification string to the given buffer; if out of
2523+// space, drops dead
2524+//
2525+
2526+static void
2527+expand_spec(char *buf, char *bufend, char *str) {
2528+ int ch;
2529+ char *p= buf;
2530+
2531+ while ((ch= *str++)) {
2532+ if (p + 10 >= bufend)
2533+ error("Buffer overflow in fidlib expand_spec()");
2534+ if (ch == '#') {
2535+ switch (*str++) {
2536+ case 'o': p += sprintf(p, "<optional-order>"); break;
2537+ case 'O': p += sprintf(p, "<order>"); break;
2538+ case 'F': p += sprintf(p, "<freq>"); break;
2539+ case 'R': p += sprintf(p, "<range>"); break;
2540+ case 'V': p += sprintf(p, "<value>"); break;
2541+ default: p += sprintf(p, "<%c>", str[-1]); break;
2542+ }
2543+ } else {
2544+ *p++= ch;
2545+ }
2546+ }
2547+ *p= 0;
2548+}
2549+
2550+//
2551+// Design a filter and reduce it to a list of all the non-const
2552+// coefficients. Arguments are as for fid_filter(). The
2553+// coefficients are written into the given double array. If the
2554+// number of coefficients doesn't match the array length given,
2555+// then a fatal error is generated.
2556+//
2557+// Note that all 1-element FIRs and IIR first-coefficients are
2558+// merged into a single gain coefficient, which is returned
2559+// rather than being included in the coefficient list. This is
2560+// to allow it to be merged with other gains within a stack of
2561+// filters.
2562+//
2563+// The algorithm used here (merging 1-element FIRs and adjusting
2564+// IIR first-coefficients) must match that used in the code-
2565+// generating code, or else the coefficients won't match up. The
2566+// 'n_coef' argument provides a partial safeguard.
2567+//
2568+
2569+double
2570+fid_design_coef(double *coef, int n_coef, const char *spec, double rate,
2571+ double freq0, double freq1, int adj) {
2572+ FidFilter *filt= fid_design(spec, rate, freq0, freq1, adj, 0);
2573+ FidFilter *ff= filt;
2574+ int a, len;
2575+ int cnt= 0;
2576+ double gain= 1.0;
2577+ double *iir, *fir, iir_adj;
2578+ static double const_one= 1;
2579+ int n_iir, n_fir;
2580+ int iir_cbm, fir_cbm;
2581+
2582+ while (ff->typ) {
2583+ if (ff->typ == 'F' && ff->len == 1) {
2584+ gain *= ff->val[0];
2585+ ff= FFNEXT(ff);
2586+ continue;
2587+ }
2588+
2589+ if (ff->typ != 'I' && ff->typ != 'F')
2590+ error("fid_design_coef can't handle FidFilter type: %c", ff->typ);
2591+
2592+ // Initialise to safe defaults
2593+ iir= fir= &const_one;
2594+ n_iir= n_fir= 1;
2595+ iir_cbm= fir_cbm= ~0;
2596+
2597+ // See if we have an IIR filter
2598+ if (ff->typ == 'I') {
2599+ iir= ff->val;
2600+ n_iir= ff->len;
2601+ iir_cbm= ff->cbm;
2602+ iir_adj= 1.0 / ff->val[0];
2603+ ff= FFNEXT(ff);
2604+ gain *= iir_adj;
2605+ }
2606+
2607+ // See if we have an FIR filter
2608+ if (ff->typ == 'F') {
2609+ fir= ff->val;
2610+ n_fir= ff->len;
2611+ fir_cbm= ff->cbm;
2612+ ff= FFNEXT(ff);
2613+ }
2614+
2615+ // Dump out all non-const coefficients in reverse order
2616+ len= n_fir > n_iir ? n_fir : n_iir;
2617+ for (a= len-1; a>=0; a--) {
2618+ // Output IIR if present and non-const
2619+ if (a < n_iir && a>0 &&
2620+ !(iir_cbm & (1<<(a<15?a:15)))) {
2621+ if (cnt++ < n_coef) *coef++= iir_adj * iir[a];
2622+ }
2623+
2624+ // Output FIR if present and non-const
2625+ if (a < n_fir &&
2626+ !(fir_cbm & (1<<(a<15?a:15)))) {
2627+ if (cnt++ < n_coef) *coef++= fir[a];
2628+ }
2629+ }
2630+ }
2631+
2632+ if (cnt != n_coef)
2633+ error("fid_design_coef called with the wrong number of coefficients.\n"
2634+ " Given %d, expecting %d: (\"%s\",%g,%g,%g,%d)",
2635+ n_coef, cnt, spec, rate, freq0, freq1, adj);
2636+
2637+ free(filt);
2638+ return gain;
2639+}
2640+
2641+//
2642+// List all the known filters to the given file handle
2643+//
2644+
2645+void
2646+fid_list_filters(FILE *out) {
2647+ int a;
2648+
2649+ for (a= 0; filter[a].fmt; a++) {
2650+ char buf[4096];
2651+ expand_spec(buf, buf+sizeof(buf), filter[a].fmt);
2652+ fprintf(out, "%s\n ", buf);
2653+ expand_spec(buf, buf+sizeof(buf), filter[a].txt);
2654+ fprintf(out, "%s\n", buf);
2655+ }
2656+}
2657+
2658+//
2659+// List all the known filters to the given buffer; the buffer is
2660+// NUL-terminated; returns 1 okay, 0 not enough space
2661+//
2662+
2663+int
2664+fid_list_filters_buf(char *buf, char *bufend) {
2665+ int a, cnt;
2666+ char tmp[4096];
2667+
2668+ for (a= 0; filter[a].fmt; a++) {
2669+ expand_spec(tmp, tmp+sizeof(tmp), filter[a].fmt);
2670+ buf += (cnt= snprintf(buf, bufend-buf, "%s\n ", tmp));
2671+ if (cnt < 0 || buf >= bufend) return 0;
2672+ expand_spec(tmp, tmp+sizeof(tmp), filter[a].txt);
2673+ buf += (cnt= snprintf(buf, bufend-buf, "%s\n", tmp));
2674+ if (cnt < 0 || buf >= bufend) return 0;
2675+ }
2676+ return 1;
2677+}
2678+
2679+//
2680+// Do a convolution of parameters in place
2681+//
2682+
2683+STATIC_INLINE int
2684+convolve(double *dst, int n_dst, double *src, int n_src) {
2685+ int len= n_dst + n_src - 1;
2686+ int a, b;
2687+
2688+ for (a= len-1; a>=0; a--) {
2689+ double val= 0;
2690+ for (b= 0; b<n_src; b++)
2691+ if (a-b >= 0 && a-b < n_dst)
2692+ val += src[b] * dst[a-b];
2693+ dst[a]= val;
2694+ }
2695+
2696+ return len;
2697+}
2698+
2699+//
2700+// Generate a combined filter -- merge all the IIR/FIR
2701+// sub-filters into a single IIR/FIR pair, and make sure the IIR
2702+// first coefficient is 1.0.
2703+//
2704+
2705+FidFilter *
2706+fid_flatten(FidFilter *filt) {
2707+ int m_fir= 1; // Maximum values
2708+ int m_iir= 1;
2709+ int n_fir, n_iir; // Stored counts during convolution
2710+ FidFilter *ff;
2711+ FidFilter *rv;
2712+ double *fir, *iir;
2713+ double adj;
2714+ int a;
2715+
2716+ // Find the size of the output filter
2717+ ff= filt;
2718+ while (ff->len) {
2719+ if (ff->typ == 'I')
2720+ m_iir += ff->len-1;
2721+ else if (ff->typ == 'F')
2722+ m_fir += ff->len-1;
2723+ else
2724+ error("fid_flatten doesn't know about type %d", ff->typ);
2725+ ff= FFNEXT(ff);
2726+ }
2727+
2728+ // Setup the output array
2729+ rv= FFALLOC(2, m_iir + m_fir);
2730+ rv->typ= 'I';
2731+ rv->len= m_iir;
2732+ iir= rv->val;
2733+ ff= FFNEXT(rv);
2734+ ff->typ= 'F';
2735+ ff->len= m_fir;
2736+ fir= ff->val;
2737+
2738+ iir[0]= 1.0; n_iir= 1;
2739+ fir[0]= 1.0; n_fir= 1;
2740+
2741+ // Do the convolution
2742+ ff= filt;
2743+ while (ff->len) {
2744+ if (ff->typ == 'I')
2745+ n_iir= convolve(iir, n_iir, ff->val, ff->len);
2746+ else
2747+ n_fir= convolve(fir, n_fir, ff->val, ff->len);
2748+ ff= FFNEXT(ff);
2749+ }
2750+
2751+ // Sanity check
2752+ if (n_iir != m_iir ||
2753+ n_fir != m_fir)
2754+ error("Internal error in fid_combine() -- array under/overflow");
2755+
2756+ // Fix iir[0]
2757+ adj= 1.0/iir[0];
2758+ for (a= 0; a<n_iir; a++) iir[a] *= adj;
2759+ for (a= 0; a<n_fir; a++) fir[a] *= adj;
2760+
2761+ return rv;
2762+}
2763+
2764+//
2765+// Parse a filter-spec and freq0/freq1 arguments. Returns a
2766+// strdup'd error string on error, or else 0.
2767+//
2768+
2769+static char *
2770+parse_spec(Spec *sp) {
2771+ double *arg;
2772+ int a;
2773+
2774+ arg= sp->argarr;
2775+ sp->n_arg= 0;
2776+ sp->order= 0;
2777+ sp->f0= 0;
2778+ sp->f1= 0;
2779+ sp->adj= 0;
2780+ sp->minlen= -1;
2781+ sp->n_freq= 0;
2782+
2783+ for (a= 0; 1; a++) {
2784+ char *fmt= filter[a].fmt;
2785+ char *p= sp->spec;
2786+ char ch, *q;
2787+
2788+ if (!fmt) return strdupf("Spec-string \"%s\" matches no known format", sp->spec);
2789+
2790+ while (*p && (ch= *fmt++)) {
2791+ if (ch != '#') {
2792+ if (ch == *p++) continue;
2793+ p= 0; break;
2794+ }
2795+
2796+ if (isalpha(*p)) { p= 0; break; }
2797+
2798+ // Handling a format character
2799+ switch (ch= *fmt++) {
2800+ default:
2801+ return strdupf("Internal error: Unknown format #%c in format: %s",
2802+ fmt[-1], filter[a].fmt);
2803+ case 'o':
2804+ case 'O':
2805+ sp->order= (int)strtol(p, &q, 10);
2806+ if (p == q) {
2807+ if (ch == 'O') goto bad;
2808+ sp->order= 1;
2809+ }
2810+ if (sp->order <= 0)
2811+ return strdupf("Bad order %d in spec-string \"%s\"", sp->order, sp->spec);
2812+ p= q; break;
2813+ case 'V':
2814+ sp->n_arg++;
2815+ *arg++= strtod(p, &q);
2816+ if (p == q) goto bad;
2817+ p= q; break;
2818+ case 'F':
2819+ sp->minlen= p-1-sp->spec;
2820+ sp->n_freq= 1;
2821+ sp->adj= (p[0] == '=');
2822+ if (sp->adj) p++;
2823+ sp->f0= strtod(p, &q);
2824+ sp->f1= 0;
2825+ if (p == q) goto bad;
2826+ p= q; break;
2827+ case 'R':
2828+ sp->minlen= p-1-sp->spec;
2829+ sp->n_freq= 2;
2830+ sp->adj= (p[0] == '=');
2831+ if (sp->adj) p++;
2832+ sp->f0= strtod(p, &q);
2833+ if (p == q) goto bad;
2834+ p= q;
2835+ if (*p++ != '-') goto bad;
2836+ sp->f1= strtod(p, &q);
2837+ if (p == q) goto bad;
2838+ if (sp->f0 > sp->f1)
2839+ return strdupf("Backwards frequency range in spec-string \"%s\"", sp->spec);
2840+ p= q; break;
2841+ }
2842+ }
2843+
2844+ if (p == 0) continue;
2845+
2846+ if (fmt[0] == '/' && fmt[1] == '#' && fmt[2] == 'F') {
2847+ sp->minlen= p-sp->spec;
2848+ sp->n_freq= 1;
2849+ if (sp->in_f0 < 0.0)
2850+ return strdupf("Frequency omitted from filter-spec, and no default provided");
2851+ sp->f0= sp->in_f0;
2852+ sp->f1= 0;
2853+ sp->adj= sp->in_adj;
2854+ fmt += 3;
2855+ } else if (fmt[0] == '/' && fmt[1] == '#' && fmt[2] == 'R') {
2856+ sp->minlen= p-sp->spec;
2857+ sp->n_freq= 2;
2858+ if (sp->in_f0 < 0.0 || sp->in_f1 < 0.0)
2859+ return strdupf("Frequency omitted from filter-spec, and no default provided");
2860+ sp->f0= sp->in_f0;
2861+ sp->f1= sp->in_f1;
2862+ sp->adj= sp->in_adj;
2863+ fmt += 3;
2864+ }
2865+
2866+ // Check for trailing unmatched format characters
2867+ if (*fmt) {
2868+ bad:
2869+ return strdupf("Bad match of spec-string \"%s\" to format \"%s\"",
2870+ sp->spec, filter[a].fmt);
2871+ }
2872+ if (sp->n_arg > MAXARG)
2873+ return strdupf("Internal error -- maximum arguments exceeded");
2874+
2875+ // Set the minlen to the whole string if unset
2876+ if (sp->minlen < 0) sp->minlen= p-sp->spec;
2877+
2878+ // Save values, return
2879+ sp->fi= a;
2880+ return 0;
2881+ }
2882+ return 0;
2883+}
2884+
2885+
2886+//
2887+// Parse a filter-spec and freq0/freq1 arguments and rewrite them
2888+// to give an all-in-one filter spec and/or a minimum spec plus
2889+// separate freq0/freq1 arguments. The all-in-one spec is
2890+// returned in *spec1p (strdup'd), and the minimum separated-out
2891+// spec is returned in *spec2p (strdup'd), *freq0p and *freq1p.
2892+// If either of spec1p or spec2p is 0, then that particular
2893+// spec-string is not generated.
2894+//
2895+
2896+void
2897+fid_rewrite_spec(const char *spec, double freq0, double freq1, int adj,
2898+ char **spec1p,
2899+ char **spec2p, double *freq0p, double *freq1p, int *adjp) {
2900+ Spec sp;
2901+ char *err;
2902+ sp.spec= spec;
2903+ sp.in_f0= freq0;
2904+ sp.in_f1= freq1;
2905+ sp.in_adj= adj;
2906+ err= parse_spec(&sp);
2907+ if (err) error("%s", err);
2908+
2909+ if (spec1p) {
2910+ char buf[128];
2911+ int len;
2912+ char *rv;
2913+ switch (sp.n_freq) {
2914+ case 1: sprintf(buf, "/%s%.15g", sp.adj ? "=" : "", sp.f0); break;
2915+ case 2: sprintf(buf, "/%s%.15g-%.15g", sp.adj ? "=" : "", sp.f0, sp.f1); break;
2916+ default: buf[0]= 0;
2917+ }
2918+ len= strlen(buf);
2919+ rv= (char*)Alloc(sp.minlen + len + 1);
2920+ memcpy(rv, spec, sp.minlen);
2921+ strcpy(rv+sp.minlen, buf);
2922+ *spec1p= rv;
2923+ }
2924+
2925+ if (spec2p) {
2926+ char *rv= (char*)Alloc(sp.minlen + 1);
2927+ memcpy(rv, spec, sp.minlen);
2928+ *spec2p= rv;
2929+ *freq0p= sp.f0;
2930+ *freq1p= sp.f1;
2931+ *adjp= sp.adj;
2932+ }
2933+}
2934+
2935+//
2936+// Create a FidFilter from the given double array. The double[]
2937+// should contain one or more sections, each starting with the
2938+// filter type (either 'I' or 'F', as a double), then a count of
2939+// the number of coefficients following, then the coefficients
2940+// themselves. The end of the list is marked with a type of 0.
2941+//
2942+// This is really just a convenience function, allowing a filter
2943+// to be conveniently dumped to C source code and then
2944+// reconstructed.
2945+//
2946+// Note that for more general filter generation, FidFilter
2947+// instances can be created simply by allocating the memory and
2948+// filling them in (see fidlib.h).
2949+//
2950+
2951+FidFilter *
2952+fid_cv_array(double *arr) {
2953+ double *dp;
2954+ FidFilter *ff, *rv;
2955+ int n_head= 0;
2956+ int n_val= 0;
2957+
2958+ // Scan through for sizes
2959+ for (dp= arr; *dp; ) {
2960+ int len, typ;
2961+
2962+ typ= (int)(*dp++);
2963+ if (typ != 'F' && typ != 'I')
2964+ error("Bad type in array passed to fid_cv_array: %g", dp[-1]);
2965+
2966+ len= (int)(*dp++);
2967+ if (len < 1)
2968+ error("Bad length in array passed to fid_cv_array: %g", dp[-1]);
2969+
2970+ n_head++;
2971+ n_val += len;
2972+ dp += len;
2973+ }
2974+
2975+ rv= ff= (FidFilter*)Alloc(FFCSIZE(n_head, n_val));
2976+
2977+ // Scan through to fill in FidFilter
2978+ for (dp= arr; *dp; ) {
2979+ int len, typ;
2980+ typ= (int)(*dp++);
2981+ len= (int)(*dp++);
2982+
2983+ ff->typ= typ;
2984+ ff->cbm= ~0;
2985+ ff->len= len;
2986+ memcpy(ff->val, dp, len * sizeof(double));
2987+ dp += len;
2988+ ff= FFNEXT(ff);
2989+ }
2990+
2991+ // Final element already zero'd thanks to allocation
2992+
2993+ return rv;
2994+}
2995+
2996+//
2997+// Create a single filter from the given list of filters in
2998+// order. If 'freeme' is set, then all the listed filters are
2999+// free'd once read; otherwise they are left untouched. The
3000+// newly allocated resultant filter is returned, which should be
3001+// released with free() when finished with.
3002+//
3003+
3004+FidFilter *
3005+fid_cat(int freeme, ...) {
3006+ va_list ap;
3007+ FidFilter *rv, *ff, *ff0;
3008+ int len= 0;
3009+ int cnt;
3010+ char *dst;
3011+
3012+ // Find the memory required to store the combined filter
3013+ va_start(ap, freeme);
3014+ while ((ff0= va_arg(ap, FidFilter*))) {
3015+ for (ff= ff0; ff->typ; ff= FFNEXT(ff))
3016+ ;
3017+ len += ((char*)ff) - ((char*)ff0);
3018+ }
3019+ va_end(ap);
3020+
3021+ rv= (FidFilter*)Alloc(FFCSIZE(0,0) + len);
3022+ dst= (char*)rv;
3023+
3024+ va_start(ap, freeme);
3025+ while ((ff0= va_arg(ap, FidFilter*))) {
3026+ for (ff= ff0; ff->typ; ff= FFNEXT(ff))
3027+ ;
3028+ cnt= ((char*)ff) - ((char*)ff0);
3029+ memcpy(dst, ff0, cnt);
3030+ dst += cnt;
3031+ if (freeme) free(ff0);
3032+ }
3033+ va_end(ap);
3034+
3035+ // Final element already zero'd
3036+ return rv;
3037+}
3038+
3039+//
3040+// Support for fid_parse
3041+//
3042+
3043+// Skip white space (including comments)
3044+static void
3045+skipWS(char **pp) {
3046+ char *p= *pp;
3047+
3048+ while (*p) {
3049+ if (isspace(*p)) { p++; continue; }
3050+ if (*p == '#') {
3051+ while (*p && *p != '\n') p++;
3052+ continue;
3053+ }
3054+ break;
3055+ }
3056+ *pp= p;
3057+}
3058+
3059+// Grab a word from the input into the given buffer. Returns 0: end
3060+// of file or error, else 1: success. Error is indicated when the
3061+// word doesn't fit in the buffer.
3062+static int
3063+grabWord(char **pp, char *buf, int buflen) {
3064+ char *p, *q;
3065+ int len;
3066+
3067+ skipWS(pp);
3068+ p= *pp;
3069+ if (!*p) return 0;
3070+
3071+ q= p;
3072+ if (*q == ',' || *q == ';' || *q == ')' || *q == ']' || *q == '}') {
3073+ q++;
3074+ } else {
3075+ while (*q && *q != '#' && !isspace(*q) &&
3076+ (*q != ',' && *q != ';' && *q != ')' && *q != ']' && *q != '}'))
3077+ q++;
3078+ }
3079+ len= q-p;
3080+ if (len >= buflen) return 0;
3081+
3082+ memcpy(buf, p, len);
3083+ buf[len]= 0;
3084+
3085+ *pp= q;
3086+ return 1;
3087+}
3088+
3089+//
3090+// Parse an entire filter specification, perhaps consisting of
3091+// several FIR, IIR and predefined filters. Stops at the first
3092+// ,; or unmatched )]}. Returns either 0 on success, or else a
3093+// strdup'd error string.
3094+//
3095+// This duplicates code from Fiview filter.c, I know, but this
3096+// may have to expand in the future to handle '+' operations, and
3097+// special filter types like tunable heterodyne filters. At that
3098+// point, the filter.c code will have to be modified to call a
3099+// version of this routine.
3100+//
3101+
3102+char *
3103+fid_parse(double rate, char **pp, FidFilter **ffp) {
3104+ char buf[128];
3105+ char *p= *pp, *rew;
3106+#define INIT_LEN 128
3107+ char *rv= (char*)Alloc(INIT_LEN);
3108+ char *rvend= rv + INIT_LEN;
3109+ char *rvp= rv;
3110+ char *tmp;
3111+#undef INIT_LEN
3112+ FidFilter *curr;
3113+ int xtra= FFCSIZE(0,0);
3114+ int typ= -1; // First time through
3115+ double val;
3116+ char dmy;
3117+
3118+#define ERR(ptr, msg) { *pp= ptr; *ffp= 0; return msg; }
3119+#define INCBUF { tmp= (char*)realloc(rv, (rvend-rv) * 2); if (!tmp) error("Out of memory"); \
3120+ rvend= (rvend-rv) * 2 + tmp; rvp= (rvp-rv) + tmp; \
3121+ curr= (FidFilter*)(((char*)curr) - rv + tmp); rv= tmp; }
3122+
3123+ while (1) {
3124+ rew= p;
3125+ if (!grabWord(&p, buf, sizeof(buf))) {
3126+ if (*p) ERR(p, strdupf("Filter element unexpectedly long -- syntax error?"));
3127+ buf[0]= 0;
3128+ }
3129+ if (!buf[0] || !buf[1]) switch (buf[0]) {
3130+ default:
3131+ break;
3132+ case 0:
3133+ case ',':
3134+ case ';':
3135+ case ')':
3136+ case ']':
3137+ case '}':
3138+ // End of filter, return it
3139+ tmp= (char*)realloc(rv, (rvp-rv) + xtra);
3140+ if (!tmp) error("Out of memory");
3141+ curr= (FidFilter*)((rvp-rv) + tmp);
3142+ curr->typ= 0; curr->cbm= 0; curr->len= 0;
3143+ *pp= buf[0] ? (p-1) : p;
3144+ *ffp= (FidFilter*)tmp;
3145+ return 0;
3146+ case '/':
3147+ if (typ > 0) ERR(rew, strdupf("Filter syntax error; unexpected '/'"));
3148+ typ= 'I';
3149+ continue;
3150+ case 'x':
3151+ if (typ > 0) ERR(rew, strdupf("Filter syntax error; unexpected 'x'"));
3152+ typ= 'F';
3153+ continue;
3154+ }
3155+
3156+ if (typ < 0) typ= 'F'; // Assume 'x' if missing
3157+ if (!typ) ERR(p, strdupf("Expecting a 'x' or '/' before this"));
3158+
3159+ if (1 != sscanf(buf, "%lf %c", &val, &dmy)) {
3160+ // Must be a predefined filter
3161+ FidFilter *ff;
3162+ FidFilter *ff1;
3163+ Spec sp;
3164+ double f0, f1;
3165+ char *err;
3166+ int len;
3167+
3168+ if (typ != 'F') ERR(rew, strdupf("Predefined filters cannot be used with '/'"));
3169+
3170+ // Parse the filter-spec
3171+ memset(&sp, 0, sizeof(sp));
3172+ sp.spec= buf;
3173+ sp.in_f0= sp.in_f1= -1;
3174+ if ((err= parse_spec(&sp))) ERR(rew, err);
3175+ f0= sp.f0;
3176+ f1= sp.f1;
3177+
3178+ // Adjust frequencies to range 0-0.5, and check them
3179+ f0 /= rate;
3180+ if (f0 > 0.5) ERR(rew, strdupf("Frequency of %gHz out of range with "
3181+ "sampling rate of %gHz", f0*rate, rate));
3182+ f1 /= rate;
3183+ if (f1 > 0.5) ERR(rew, strdupf("Frequency of %gHz out of range with "
3184+ "sampling rate of %gHz", f1*rate, rate));
3185+
3186+ // Okay we now have a successful spec-match to filter[sp.fi], and sp.n_arg
3187+ // args are now in sp.argarr[]
3188+
3189+ // Generate the filter
3190+ if (!sp.adj)
3191+ ff= filter[sp.fi].rout(rate, f0, f1, sp.order, sp.n_arg, sp.argarr);
3192+ else if (strstr(filter[sp.fi].fmt, "#R"))
3193+ ff= auto_adjust_dual(&sp, rate, f0, f1);
3194+ else
3195+ ff= auto_adjust_single(&sp, rate, f0);
3196+
3197+ // Append it to our FidFilter to return
3198+ for (ff1= ff; ff1->typ; ff1= FFNEXT(ff1)) ;
3199+ len= ((char*)ff1-(char*)ff);
3200+ while (rvp + len + xtra >= rvend) INCBUF;
3201+ memcpy(rvp, ff, len); rvp += len;
3202+ free(ff);
3203+ typ= 0;
3204+ continue;
3205+ }
3206+
3207+ // Must be a list of coefficients
3208+ curr= (FidFilter*)rvp;
3209+ rvp += xtra;
3210+ while (rvp + sizeof(double) >= rvend) INCBUF;
3211+ curr->typ= typ;
3212+ curr->cbm= ~0;
3213+ curr->len= 1;
3214+ *(double*)rvp= val;
3215+ rvp += sizeof(double);
3216+
3217+ // See how many more coefficients we can pick up
3218+ while (1) {
3219+ rew= p;
3220+ if (!grabWord(&p, buf, sizeof(buf))) {
3221+ if (*p) ERR(p, strdupf("Filter element unexpectedly long -- syntax error?"));
3222+ buf[0]= 0;
3223+ }
3224+ if (1 != sscanf(buf, "%lf %c", &val, &dmy)) {
3225+ p= rew;
3226+ break;
3227+ }
3228+ while (rvp + sizeof(double) >= rvend) INCBUF;
3229+ curr->len++;
3230+ *(double*)rvp= val;
3231+ rvp += sizeof(double);
3232+ }
3233+ typ= 0;
3234+ continue;
3235+ }
3236+
3237+#undef INCBUF
3238+#undef ERR
3239+
3240+ return strdupf("Internal error, shouldn't reach here");
3241+}
3242+
3243+
3244+//
3245+// Filter-running code
3246+//
3247+
3248+#ifdef RF_COMBINED
3249+#include "fidrf_combined.h"
3250+#endif
3251+
3252+#ifdef RF_CMDLIST
3253+#include "fidrf_cmdlist.h"
3254+#endif
3255+
3256+#ifdef RF_JIT
3257+#include "fidrf_jit.h"
3258+#endif
3259+
3260+
3261+// END //
3262
3263=== added file 'mixxx/lib/fidlib-0.9.10/fidlib.h'
3264--- mixxx/lib/fidlib-0.9.10/fidlib.h 1970-01-01 00:00:00 +0000
3265+++ mixxx/lib/fidlib-0.9.10/fidlib.h 2011-07-25 04:35:51 +0000
3266@@ -0,0 +1,77 @@
3267+//
3268+// fidlib include file
3269+//
3270+#ifndef FIDLIB_H
3271+#define FIDLIB_H
3272+typedef struct FidFilter FidFilter;
3273+struct FidFilter {
3274+ short typ; // Type of filter element 'I' IIR, 'F' FIR, or 0 for end of list
3275+ short cbm; // Constant bitmap. Bits 0..14, if set, indicate that val[0..14]
3276+ // is a constant across changes in frequency for this filter type
3277+ // Bit 15, if set, indicates that val[15..inf] are constant.
3278+ int len; // Number of doubles stored in val[], or 0 for end of list
3279+ double val[1];
3280+};
3281+
3282+// Lets you write: for (; ff->typ; ff= FFNEXT(ff)) { ... }
3283+#define FFNEXT(ff) ((FidFilter*)((ff)->val + (ff)->len))
3284+
3285+// Size of a sub-filter with 'cnt' double values attached
3286+#define FFSIZE(cnt) (sizeof(FidFilter) + ((cnt)-1)*sizeof(double))
3287+
3288+// Size required for the memory chunk to contain the given number
3289+// headers and values, plus termination
3290+#define FFCSIZE(n_head,n_val) ((sizeof(FidFilter)-sizeof(double))*((n_head)+1) + sizeof(double)*(n_val))
3291+
3292+// Allocate the chunk of memory to hold a list of FidFilters, with
3293+// n_head FidFilters and n_val total double values in the whole list.
3294+// Includes space for the final termination, and zeros the memory.
3295+#define FFALLOC(n_head,n_val) (FidFilter*)Alloc(FFCSIZE(n_head, n_val))
3296+
3297+// These are so you can use easier names to refer to running filters
3298+typedef void FidRun;
3299+typedef double (FidFunc)(void*, double);
3300+
3301+
3302+//
3303+// Prototypes
3304+//
3305+#ifdef MIXXX
3306+extern "C" {
3307+#endif
3308+
3309+extern void fid_set_error_handler(void(*rout)(char *));
3310+extern char *fid_version();
3311+extern double fid_response_pha(FidFilter *filt, double freq, double *phase);
3312+extern double fid_response(FidFilter *filt, double freq);
3313+extern int fid_calc_delay(FidFilter *filt);
3314+extern FidFilter *fid_design(const char *spec, double rate, double freq0, double freq1,
3315+ int f_adj, char **descp);
3316+extern double fid_design_coef(double *coef, int n_coef, const char *spec,
3317+ double rate, double freq0, double freq1, int adj);
3318+extern void fid_list_filters(FILE *out);
3319+extern int fid_list_filters_buf(char *buf, char *bufend);
3320+extern FidFilter *fid_flatten(FidFilter *filt);
3321+extern void fid_rewrite_spec(const char *spec, double freq0, double freq1, int adj,
3322+ char **spec1p, char **spec2p,
3323+ double *freq0p, double *freq1p, int *adjp);
3324+extern FidFilter *fid_cv_array(double *arr);
3325+extern FidFilter *fid_cat(int freeme, ...);
3326+extern char *fid_parse(double rate, char **pp, FidFilter **ffp);
3327+
3328+//
3329+// Filter running prototypes
3330+//
3331+
3332+extern void *fid_run_new(FidFilter *filt, double(**funcpp)(void *, double));
3333+extern void *fid_run_newbuf(void *run);
3334+extern int fid_run_bufsize(void *run);
3335+extern void fid_run_initbuf(void *run, void *buf);
3336+extern void fid_run_zapbuf(void *buf);
3337+extern void fid_run_freebuf(void *runbuf);
3338+extern void fid_run_free(void *run);
3339+
3340+#ifdef MIXXX
3341+}
3342+#endif
3343+#endif
3344
3345=== added file 'mixxx/lib/fidlib-0.9.10/fidmkf.h'
3346--- mixxx/lib/fidlib-0.9.10/fidmkf.h 1970-01-01 00:00:00 +0000
3347+++ mixxx/lib/fidlib-0.9.10/fidmkf.h 2011-07-25 04:35:51 +0000
3348@@ -0,0 +1,846 @@
3349+//
3350+// mkfilter-derived code
3351+// ---------------------
3352+//
3353+// Copyright (c) 2002-2004 Jim Peters <http://uazu.net/>. This
3354+// file is released under the GNU Lesser General Public License
3355+// (LGPL) version 2.1 as published by the Free Software
3356+// Foundation. See the file COPYING_LIB for details, or visit
3357+// <http://www.fsf.org/licenses/licenses.html>.
3358+//
3359+// This is all code derived from 'mkfilter' by Tony Fisher of the
3360+// University of York. I've rewritten it all in C, and given it
3361+// a thorough overhaul, so there is actually none of his code
3362+// here any more, but it is all still very strongly based on the
3363+// algorithms and techniques that he used in 'mkfilter'.
3364+//
3365+// For those who didn't hear, Tony Fisher died in February 2000
3366+// at the age of 43. See his web-site for information and a
3367+// tribute:
3368+//
3369+// http://www-users.cs.york.ac.uk/~fisher/
3370+// http://www-users.cs.york.ac.uk/~fisher/tribute.html
3371+//
3372+// The original C++ sources and the rest of the mkfilter tool-set
3373+// are still available from his site:
3374+//
3375+// http://www-users.cs.york.ac.uk/~fisher/mkfilter/
3376+//
3377+//
3378+// I've made a number of improvements and changes whilst
3379+// rewriting the code in C. For example, I halved the
3380+// calculations required in designing the filters by storing only
3381+// one complex pole/zero out of each conjugate pair. This also
3382+// made it much easier to output the filter as a list of
3383+// sub-filters without lots of searching around to match up
3384+// conjugate pairs later on. Outputting as a list of subfilters
3385+// permits greater accuracy in calculation of the response, and
3386+// also in the execution of the final filter. Also, some FIR
3387+// coefficients can be marked as 'constant', allowing optimised
3388+// routines to be generated for whole classes of filters, with
3389+// just the variable coefficients filled in at run-time.
3390+//
3391+// On the down-side, complex numbers are not portably available
3392+// in C before C99, so complex calculations here are done on
3393+// double[] arrays with inline functions, which ends up looking
3394+// more like assembly language than C. Never mind.
3395+//
3396+
3397+//
3398+// LEGAL STUFF
3399+// -----------
3400+//
3401+// Tony Fisher released his software on his University of York
3402+// pages for free use and free download. The software itself has
3403+// no licence terms attached, nor copyright messages, just the
3404+// author's name, E-mail address and date. Nor are there any
3405+// licence terms indicated on the website. I understand that
3406+// under the Berne convention copyright does not have to be
3407+// claimed explicitly, so these are in fact copyright files by
3408+// legal default. However, the intention was obviously that
3409+// these files should be used by others.
3410+//
3411+// None of this really helps, though, if we're going to try to be
3412+// 100% legally correct, so I wrote to Anthony Moulds who is the
3413+// contact name on Tony Fisher's pages now. I explained what I
3414+// planned to do with the code, and he answered as follows:
3415+//
3416+// (Note that I was planning to use it 'as-is' at that time,
3417+// rather than rewrite it as I have done now)
3418+//
3419+// > To: "Jim Peters" <jim@uazu.net>
3420+// > From: "Anthony Moulds" <anthony@cs.york.ac.uk>
3421+// > Subject: RE: mkfilter source
3422+// > Date: Tue, 29 Oct 2002 15:30:19 -0000
3423+// >
3424+// > Hi Jim,
3425+// >
3426+// > Thanks for your email.
3427+// >
3428+// > The University will be happy to let you use Dr Fisher's mkfilter
3429+// > code since your intention is not to profit financially from his work.
3430+// >
3431+// > It would be nice if in some way you could acknowledge his contribution.
3432+// >
3433+// > Best wishes and good luck with your work,
3434+// >
3435+// > Anthony Moulds
3436+// > Senior Experimental Officer,
3437+// > Computer Science Department, University of York,
3438+// > York, England, UK. Tel: 44(0)1904 434758 Fax: 44(0)19042767
3439+// > ============================================================
3440+// >
3441+// >
3442+// > > -----Original Message-----
3443+// > > From: Jim Peters [mailto:jim@uazu.net]
3444+// > > Sent: Monday, October 28, 2002 12:36 PM
3445+// > > To: anthony@cs.york.ac.uk
3446+// > > Subject: mkfilter source
3447+// > >
3448+// > >
3449+// > > I'm very sorry to hear (rather late, I know) that Tony Fisher died --
3450+// > > I've always gone straight to the filter page, rather than through his
3451+// > > home page. I hope his work remains available for the future.
3452+// > >
3453+// > > Anyway, the reason I'm writing is to clarify the status of the
3454+// > > mkfilter source code. Because copyright is not claimed on the web
3455+// > > page nor in the source distribution, I guess that Tony's intention was
3456+// > > that this code should be in the public domain. However, I would like
3457+// > > to check this now to avoid complications later.
3458+// > >
3459+// > > I am using his code, modified, to provide a library of filter-design
3460+// > > routines for a GPL'd filter design app, which is not yet released.
3461+// > > The library could also be used standalone, permitting apps to design
3462+// > > filters at run-time rather than using hard-coded compile-time filters.
3463+// > > My interest in filters is as a part of my work on the OpenEEG project
3464+//
3465+// So this looks pretty clear to me. I am not planning to profit
3466+// from the work, so everything is fine with the University. I
3467+// guess others might profit from the work, indirectly, as with
3468+// any free software release, but so long as I don't, we're fine.
3469+//
3470+// I hope this is watertight enough for Debian/etc. Otherwise
3471+// I'll have to go back to Anthony Moulds for clarification.
3472+//
3473+// Even though there is no code cut-and-pasted from 'mkfilter'
3474+// here, it is all very obviously based on that code, so it
3475+// probably counts as a derived work -- although as ever "I Am
3476+// Not A Lawyer".
3477+//
3478+
3479+#ifndef FIDMK_H
3480+#define FIDMK_H
3481+
3482+#ifndef T_MSVC
3483+ #ifdef HUGE_VAL
3484+ #define INF HUGE_VAL
3485+ #else
3486+ #define INF (1.0/0.0)
3487+ #endif
3488+#endif
3489+
3490+//Hacks for crappy linker error in MSVC... - Albert
3491+#ifdef T_MSVC
3492+ #undef HUGE_VAL
3493+ #define HUGE_VAL 1.797693134862315E+308
3494+ #define INF HUGE_VAL
3495+#endif
3496+
3497+#define TWOPI (2*M_PI)
3498+
3499+
3500+//
3501+// Complex square root: aa= aa^0.5
3502+//
3503+
3504+STATIC_INLINE double
3505+my_sqrt(double aa) {
3506+ return aa <= 0.0 ? 0.0 : sqrt(aa);
3507+}
3508+
3509+// 'csqrt' clashes with builtin in GCC 4, so call it 'c_sqrt'
3510+STATIC_INLINE void
3511+c_sqrt(double *aa) {
3512+ double mag= hypot(aa[0], aa[1]);
3513+ double rr= my_sqrt((mag + aa[0]) * 0.5);
3514+ double ii= my_sqrt((mag - aa[0]) * 0.5);
3515+ if (aa[1] < 0.0) ii= -ii;
3516+ aa[0]= rr;
3517+ aa[1]= ii;
3518+}
3519+
3520+//
3521+// Complex imaginary exponent: aa= e^i.theta
3522+//
3523+
3524+STATIC_INLINE void
3525+cexpj(double *aa, double theta) {
3526+ aa[0]= cos(theta);
3527+ aa[1]= sin(theta);
3528+}
3529+
3530+//
3531+// Complex exponent: aa= e^aa
3532+//
3533+
3534+// 'cexp' clashes with builtin in GCC 4, so call it 'c_exp'
3535+STATIC_INLINE void
3536+c_exp(double *aa) {
3537+ double mag= exp(aa[0]);
3538+ aa[0]= mag * cos(aa[1]);
3539+ aa[1]= mag * sin(aa[1]);
3540+}
3541+
3542+//
3543+// Global temp buffer for generating filters. *NOT THREAD SAFE*
3544+//
3545+// Note that the poles and zeros are stored in a strange way.
3546+// Rather than storing both a pole (or zero) and its complex
3547+// conjugate, I'm storing just one of the pair. Also, for real
3548+// poles, I'm not storing the imaginary part (which is zero).
3549+// This results in a list of numbers exactly half the length you
3550+// might otherwise expect. However, since some of these numbers
3551+// are in pairs, and some are single, we need a separate flag
3552+// array to indicate which is which. poltyp[] serves this
3553+// purpose. An entry is 1 if the corresponding offset is a real
3554+// pole, or 2 if it is the first of a pair of values making up a
3555+// complex pole. The second value of the pair has an entry of 0
3556+// attached. (Similarly for zeros in zertyp[])
3557+//
3558+
3559+#define MAXPZ 64
3560+
3561+static int n_pol; // Number of poles
3562+static double pol[MAXPZ]; // Pole values (see above)
3563+static char poltyp[MAXPZ]; // Pole value types: 1 real, 2 first of complex pair, 0 second
3564+static int n_zer; // Same for zeros ...
3565+static double zer[MAXPZ];
3566+static char zertyp[MAXPZ];
3567+
3568+
3569+//
3570+// Pre-warp a frequency
3571+//
3572+
3573+STATIC_INLINE double
3574+prewarp(double val) {
3575+ return tan(val * M_PI) / M_PI;
3576+}
3577+
3578+
3579+//
3580+// Bessel poles; final one is a real value for odd numbers of
3581+// poles
3582+//
3583+
3584+static double bessel_1[]= {
3585+ -1.00000000000e+00
3586+};
3587+
3588+static double bessel_2[]= {
3589+ -1.10160133059e+00, 6.36009824757e-01,
3590+};
3591+
3592+static double bessel_3[]= {
3593+ -1.04740916101e+00, 9.99264436281e-01,
3594+ -1.32267579991e+00,
3595+};
3596+
3597+static double bessel_4[]= {
3598+ -9.95208764350e-01, 1.25710573945e+00,
3599+ -1.37006783055e+00, 4.10249717494e-01,
3600+};
3601+
3602+static double bessel_5[]= {
3603+ -9.57676548563e-01, 1.47112432073e+00,
3604+ -1.38087732586e+00, 7.17909587627e-01,
3605+ -1.50231627145e+00,
3606+};
3607+
3608+static double bessel_6[]= {
3609+ -9.30656522947e-01, 1.66186326894e+00,
3610+ -1.38185809760e+00, 9.71471890712e-01,
3611+ -1.57149040362e+00, 3.20896374221e-01,
3612+};
3613+
3614+static double bessel_7[]= {
3615+ -9.09867780623e-01, 1.83645135304e+00,
3616+ -1.37890321680e+00, 1.19156677780e+00,
3617+ -1.61203876622e+00, 5.89244506931e-01,
3618+ -1.68436817927e+00,
3619+};
3620+
3621+static double bessel_8[]= {
3622+ -8.92869718847e-01, 1.99832584364e+00,
3623+ -1.37384121764e+00, 1.38835657588e+00,
3624+ -1.63693941813e+00, 8.22795625139e-01,
3625+ -1.75740840040e+00, 2.72867575103e-01,
3626+};
3627+
3628+static double bessel_9[]= {
3629+ -8.78399276161e-01, 2.14980052431e+00,
3630+ -1.36758830979e+00, 1.56773371224e+00,
3631+ -1.65239648458e+00, 1.03138956698e+00,
3632+ -1.80717053496e+00, 5.12383730575e-01,
3633+ -1.85660050123e+00,
3634+};
3635+
3636+static double bessel_10[]= {
3637+ -8.65756901707e-01, 2.29260483098e+00,
3638+ -1.36069227838e+00, 1.73350574267e+00,
3639+ -1.66181024140e+00, 1.22110021857e+00,
3640+ -1.84219624443e+00, 7.27257597722e-01,
3641+ -1.92761969145e+00, 2.41623471082e-01,
3642+};
3643+
3644+static double *bessel_poles[10]= {
3645+ bessel_1, bessel_2, bessel_3, bessel_4, bessel_5,
3646+ bessel_6, bessel_7, bessel_8, bessel_9, bessel_10
3647+};
3648+
3649+//
3650+// Generate Bessel poles for the given order.
3651+//
3652+
3653+static void
3654+bessel(int order) {
3655+ int a;
3656+
3657+ if (order > 10) error("Maximum Bessel order is 10");
3658+ n_pol= order;
3659+ memcpy(pol, bessel_poles[order-1], n_pol * sizeof(double));
3660+
3661+ for (a= 0; a<order-1; ) {
3662+ poltyp[a++]= 2;
3663+ poltyp[a++]= 0;
3664+ }
3665+ if (a < order)
3666+ poltyp[a++]= 1;
3667+}
3668+
3669+//
3670+// Generate Butterworth poles for the given order. These are
3671+// regularly-spaced points on the unit circle to the left of the
3672+// real==0 line.
3673+//
3674+
3675+static void
3676+butterworth(int order) {
3677+ int a;
3678+ if (order > MAXPZ)
3679+ error("Maximum butterworth/chebyshev order is %d", MAXPZ);
3680+ n_pol= order;
3681+ for (a= 0; a<order-1; a += 2) {
3682+ poltyp[a]= 2;
3683+ poltyp[a+1]= 0;
3684+ cexpj(pol+a, M_PI - (order-a-1) * 0.5 * M_PI / order);
3685+ }
3686+ if (a < order) {
3687+ poltyp[a]= 1;
3688+ pol[a]= -1.0;
3689+ }
3690+}
3691+
3692+//
3693+// Generate Chebyshev poles for the given order and ripple.
3694+//
3695+
3696+static void
3697+chebyshev(int order, double ripple) {
3698+ double eps, y;
3699+ double sh, ch;
3700+ int a;
3701+
3702+ butterworth(order);
3703+ if (ripple >= 0.0) error("Chebyshev ripple in dB should be -ve");
3704+
3705+ eps= sqrt(-1.0 + pow(10.0, -0.1 * ripple));
3706+ y= asinh(1.0 / eps) / order;
3707+ if (y <= 0.0) error("Internal error; chebyshev y-value <= 0.0: %g", y);
3708+ sh= sinh(y);
3709+ ch= cosh(y);
3710+
3711+ for (a= 0; a<n_pol; ) {
3712+ if (poltyp[a] == 1)
3713+ pol[a++] *= sh;
3714+ else {
3715+ pol[a++] *= sh;
3716+ pol[a++] *= ch;
3717+ }
3718+ }
3719+}
3720+
3721+
3722+//
3723+// Adjust raw poles to LP filter
3724+//
3725+
3726+static void
3727+lowpass(double freq) {
3728+ int a;
3729+
3730+ // Adjust poles
3731+ freq *= TWOPI;
3732+ for (a= 0; a<n_pol; a++)
3733+ pol[a] *= freq;
3734+
3735+ // Add zeros
3736+ n_zer= n_pol;
3737+ for (a= 0; a<n_zer; a++) {
3738+ zer[a]= -INF;
3739+ zertyp[a]= 1;
3740+ }
3741+}
3742+
3743+//
3744+// Adjust raw poles to HP filter
3745+//
3746+
3747+static void
3748+highpass(double freq) {
3749+ int a;
3750+
3751+ // Adjust poles
3752+ freq *= TWOPI;
3753+ for (a= 0; a<n_pol; ) {
3754+ if (poltyp[a] == 1) {
3755+ pol[a]= freq / pol[a];
3756+ a++;
3757+ } else {
3758+ crecip(pol + a);
3759+ pol[a++] *= freq;
3760+ pol[a++] *= freq;
3761+ }
3762+ }
3763+
3764+ // Add zeros
3765+ n_zer= n_pol;
3766+ for (a= 0; a<n_zer; a++) {
3767+ zer[a]= 0.0;
3768+ zertyp[a]= 1;
3769+ }
3770+}
3771+
3772+//
3773+// Adjust raw poles to BP filter. The number of poles is
3774+// doubled.
3775+//
3776+
3777+static void
3778+bandpass(double freq1, double freq2) {
3779+ double w0= TWOPI * sqrt(freq1*freq2);
3780+ double bw= 0.5 * TWOPI * (freq2-freq1);
3781+ int a, b;
3782+
3783+ if (n_pol * 2 > MAXPZ)
3784+ error("Maximum order for bandpass filters is %d", MAXPZ/2);
3785+
3786+ // Run through the list backwards, expanding as we go
3787+ for (a= n_pol, b= n_pol*2; a>0; ) {
3788+ // hba= pole * bw;
3789+ // temp= c_sqrt(1.0 - square(w0 / hba));
3790+ // pole1= hba * (1.0 + temp);
3791+ // pole2= hba * (1.0 - temp);
3792+
3793+ if (poltyp[a-1] == 1) {
3794+ double hba;
3795+ a--; b -= 2;
3796+ poltyp[b]= 2; poltyp[b+1]= 0;
3797+ hba= pol[a] * bw;
3798+ cassz(pol+b, 1.0 - (w0 / hba) * (w0 / hba), 0.0);
3799+ c_sqrt(pol+b);
3800+ caddz(pol+b, 1.0, 0.0);
3801+ cmulr(pol+b, hba);
3802+ } else { // Assume poltyp[] data is valid
3803+ double hba[2];
3804+ a -= 2; b -= 4;
3805+ poltyp[b]= 2; poltyp[b+1]= 0;
3806+ poltyp[b+2]= 2; poltyp[b+3]= 0;
3807+ cass(hba, pol+a);
3808+ cmulr(hba, bw);
3809+ cass(pol+b, hba);
3810+ crecip(pol+b);
3811+ cmulr(pol+b, w0);
3812+ csqu(pol+b);
3813+ cneg(pol+b);
3814+ caddz(pol+b, 1.0, 0.0);
3815+ c_sqrt(pol+b);
3816+ cmul(pol+b, hba);
3817+ cass(pol+b+2, pol+b);
3818+ cneg(pol+b+2);
3819+ cadd(pol+b, hba);
3820+ cadd(pol+b+2, hba);
3821+ }
3822+ }
3823+ n_pol *= 2;
3824+
3825+ // Add zeros
3826+ n_zer= n_pol;
3827+ for (a= 0; a<n_zer; a++) {
3828+ zertyp[a]= 1;
3829+ zer[a]= (a<n_zer/2) ? 0.0 : -INF;
3830+ }
3831+}
3832+
3833+//
3834+// Adjust raw poles to BS filter. The number of poles is
3835+// doubled.
3836+//
3837+
3838+static void
3839+bandstop(double freq1, double freq2) {
3840+ double w0= TWOPI * sqrt(freq1*freq2);
3841+ double bw= 0.5 * TWOPI * (freq2-freq1);
3842+ int a, b;
3843+
3844+ if (n_pol * 2 > MAXPZ)
3845+ error("Maximum order for bandstop filters is %d", MAXPZ/2);
3846+
3847+ // Run through the list backwards, expanding as we go
3848+ for (a= n_pol, b= n_pol*2; a>0; ) {
3849+ // hba= bw / pole;
3850+ // temp= c_sqrt(1.0 - square(w0 / hba));
3851+ // pole1= hba * (1.0 + temp);
3852+ // pole2= hba * (1.0 - temp);
3853+
3854+ if (poltyp[a-1] == 1) {
3855+ double hba;
3856+ a--; b -= 2;
3857+ poltyp[b]= 2; poltyp[b+1]= 0;
3858+ hba= bw / pol[a];
3859+ cassz(pol+b, 1.0 - (w0 / hba) * (w0 / hba), 0.0);
3860+ c_sqrt(pol+b);
3861+ caddz(pol+b, 1.0, 0.0);
3862+ cmulr(pol+b, hba);
3863+ } else { // Assume poltyp[] data is valid
3864+ double hba[2];
3865+ a -= 2; b -= 4;
3866+ poltyp[b]= 2; poltyp[b+1]= 0;
3867+ poltyp[b+2]= 2; poltyp[b+3]= 0;
3868+ cass(hba, pol+a);
3869+ crecip(hba);
3870+ cmulr(hba, bw);
3871+ cass(pol+b, hba);
3872+ crecip(pol+b);
3873+ cmulr(pol+b, w0);
3874+ csqu(pol+b);
3875+ cneg(pol+b);
3876+ caddz(pol+b, 1.0, 0.0);
3877+ c_sqrt(pol+b);
3878+ cmul(pol+b, hba);
3879+ cass(pol+b+2, pol+b);
3880+ cneg(pol+b+2);
3881+ cadd(pol+b, hba);
3882+ cadd(pol+b+2, hba);
3883+ }
3884+ }
3885+ n_pol *= 2;
3886+
3887+ // Add zeros
3888+ n_zer= n_pol;
3889+ for (a= 0; a<n_zer; a+=2) {
3890+ zertyp[a]= 2; zertyp[a+1]= 0;
3891+ zer[a]= 0.0; zer[a+1]= w0;
3892+ }
3893+}
3894+
3895+//
3896+// Convert list of poles+zeros from S to Z using bilinear
3897+// transform
3898+//
3899+
3900+static void
3901+s2z_bilinear() {
3902+ int a;
3903+ for (a= 0; a<n_pol; ) {
3904+ // Calculate (2 + val) / (2 - val)
3905+ if (poltyp[a] == 1) {
3906+ if (pol[a] == -INF)
3907+ pol[a]= -1.0;
3908+ else
3909+ pol[a]= (2 + pol[a]) / (2 - pol[a]);
3910+ a++;
3911+ } else {
3912+ double val[2];
3913+ cass(val, pol+a);
3914+ cneg(val);
3915+ caddz(val, 2, 0);
3916+ caddz(pol+a, 2, 0);
3917+ cdiv(pol+a, val);
3918+ a += 2;
3919+ }
3920+ }
3921+ for (a= 0; a<n_zer; ) {
3922+ // Calculate (2 + val) / (2 - val)
3923+ if (zertyp[a] == 1) {
3924+ if (zer[a] == -INF)
3925+ zer[a]= -1.0;
3926+ else
3927+ zer[a]= (2 + zer[a]) / (2 - zer[a]);
3928+ a++;
3929+ } else {
3930+ double val[2];
3931+ cass(val, zer+a);
3932+ cneg(val);
3933+ caddz(val, 2, 0);
3934+ caddz(zer+a, 2, 0);
3935+ cdiv(zer+a, val);
3936+ a += 2;
3937+ }
3938+ }
3939+}
3940+
3941+//
3942+// Convert S to Z using matched-Z transform
3943+//
3944+
3945+static void
3946+s2z_matchedZ() {
3947+ int a;
3948+
3949+ for (a= 0; a<n_pol; ) {
3950+ // Calculate cexp(val)
3951+ if (poltyp[a] == 1) {
3952+ if (pol[a] == -INF)
3953+ pol[a]= 0.0;
3954+ else
3955+ pol[a]= exp(pol[a]);
3956+ a++;
3957+ } else {
3958+ c_exp(pol+a);
3959+ a += 2;
3960+ }
3961+ }
3962+
3963+ for (a= 0; a<n_zer; ) {
3964+ // Calculate cexp(val)
3965+ if (zertyp[a] == 1) {
3966+ if (zer[a] == -INF)
3967+ zer[a]= 0.0;
3968+ else
3969+ zer[a]= exp(zer[a]);
3970+ a++;
3971+ } else {
3972+ c_exp(zer+a);
3973+ a += 2;
3974+ }
3975+ }
3976+}
3977+
3978+//
3979+// Generate a FidFilter for the current set of poles and zeros.
3980+// The given gain is inserted at the start of the FidFilter as a
3981+// one-coefficient FIR filter. This is positioned to be easily
3982+// adjusted later to correct the filter gain.
3983+//
3984+// 'cbm' should be a bitmap indicating which FIR coefficients are
3985+// constants for this filter type. Normal values are ~0 for all
3986+// constant, or 0 for none constant, or some other bitmask for a
3987+// mixture. Filters generated with lowpass(), highpass() and
3988+// bandpass() above should pass ~0, but bandstop() requires 0x5.
3989+//
3990+// This routine requires that any lone real poles/zeros are at
3991+// the end of the list. All other poles/zeros are handled in
3992+// pairs (whether pairs of real poles/zeros, or conjugate pairs).
3993+//
3994+
3995+static FidFilter*
3996+z2fidfilter(double gain, int cbm) {
3997+ int n_head, n_val;
3998+ int a;
3999+ FidFilter *rv;
4000+ FidFilter *ff;
4001+
4002+ n_head= 1 + n_pol + n_zer; // Worst case: gain + 2-element IIR/FIR
4003+ n_val= 1 + 2 * (n_pol+n_zer); // for each pole/zero
4004+
4005+ rv= ff= FFALLOC(n_head, n_val);
4006+
4007+ ff->typ= 'F';
4008+ ff->len= 1;
4009+ ff->val[0]= gain;
4010+ ff= FFNEXT(ff);
4011+
4012+ // Output as much as possible as 2x2 IIR/FIR filters
4013+ for (a= 0; a <= n_pol-2 && a <= n_zer-2; a += 2) {
4014+ // Look for a pair of values for an IIR
4015+ if (poltyp[a] == 1 && poltyp[a+1] == 1) {
4016+ // Two real values
4017+ ff->typ= 'I';
4018+ ff->len= 3;
4019+ ff->val[0]= 1;
4020+ ff->val[1]= -(pol[a] + pol[a+1]);
4021+ ff->val[2]= pol[a] * pol[a+1];
4022+ ff= FFNEXT(ff);
4023+ } else if (poltyp[a] == 2) {
4024+ // A complex value and its conjugate pair
4025+ ff->typ= 'I';
4026+ ff->len= 3;
4027+ ff->val[0]= 1;
4028+ ff->val[1]= -2 * pol[a];
4029+ ff->val[2]= pol[a] * pol[a] + pol[a+1] * pol[a+1];
4030+ ff= FFNEXT(ff);
4031+ } else error("Internal error -- bad poltyp[] values for z2fidfilter()");
4032+
4033+ // Look for a pair of values for an FIR
4034+ if (zertyp[a] == 1 && zertyp[a+1] == 1) {
4035+ // Two real values
4036+ // Skip if constant and 0/0
4037+ if (!cbm || zer[a] != 0.0 || zer[a+1] != 0.0) {
4038+ ff->typ= 'F';
4039+ ff->cbm= cbm;
4040+ ff->len= 3;
4041+ ff->val[0]= 1;
4042+ ff->val[1]= -(zer[a] + zer[a+1]);
4043+ ff->val[2]= zer[a] * zer[a+1];
4044+ ff= FFNEXT(ff);
4045+ }
4046+ } else if (zertyp[a] == 2) {
4047+ // A complex value and its conjugate pair
4048+ // Skip if constant and 0/0
4049+ if (!cbm || zer[a] != 0.0 || zer[a+1] != 0.0) {
4050+ ff->typ= 'F';
4051+ ff->cbm= cbm;
4052+ ff->len= 3;
4053+ ff->val[0]= 1;
4054+ ff->val[1]= -2 * zer[a];
4055+ ff->val[2]= zer[a] * zer[a] + zer[a+1] * zer[a+1];
4056+ ff= FFNEXT(ff);
4057+ }
4058+ } else error("Internal error -- bad zertyp[] values");
4059+ }
4060+
4061+ // Clear up any remaining bits and pieces. Should only be a 1x1
4062+ // IIR/FIR.
4063+ if (n_pol-a == 0 && n_zer-a == 0)
4064+ ;
4065+ else if (n_pol-a == 1 && n_zer-a == 1) {
4066+ if (poltyp[a] != 1 || zertyp[a] != 1)
4067+ error("Internal error; bad poltyp or zertyp for final pole/zero");
4068+ ff->typ= 'I';
4069+ ff->len= 2;
4070+ ff->val[0]= 1;
4071+ ff->val[1]= -pol[a];
4072+ ff= FFNEXT(ff);
4073+
4074+ // Skip FIR if it is constant and zero
4075+ if (!cbm || zer[a] != 0.0) {
4076+ ff->typ= 'F';
4077+ ff->cbm= cbm;
4078+ ff->len= 2;
4079+ ff->val[0]= 1;
4080+ ff->val[1]= -zer[a];
4081+ ff= FFNEXT(ff);
4082+ }
4083+ } else
4084+ error("Internal error: unexpected poles/zeros at end of list");
4085+
4086+ // End of list
4087+ ff->typ= 0;
4088+ ff->len= 0;
4089+ ff= FFNEXT(ff);
4090+
4091+ rv= (FidFilter*)realloc(rv, ((char*)ff)-((char*)rv));
4092+ if (!rv) error("Out of memory");
4093+ return rv;
4094+}
4095+
4096+//
4097+// Setup poles/zeros for a band-pass resonator. 'qfact' gives
4098+// the Q-factor; 0 is a special value indicating +infinity,
4099+// giving an oscillator.
4100+//
4101+
4102+static void
4103+bandpass_res(double freq, double qfact) {
4104+ double mag;
4105+ double th0, th1, th2;
4106+ double theta= freq * TWOPI;
4107+ double val[2];
4108+ double tmp1[2], tmp2[2], tmp3[2], tmp4[2];
4109+ int cnt;
4110+
4111+ n_pol= 2;
4112+ poltyp[0]= 2; poltyp[1]= 0;
4113+ n_zer= 2;
4114+ zertyp[0]= 1; zertyp[1]= 1;
4115+ zer[0]= 1; zer[1]= -1;
4116+
4117+ if (qfact == 0.0) {
4118+ cexpj(pol, theta);
4119+ return;
4120+ }
4121+
4122+ // Do a full binary search, rather than seeding it as Tony Fisher does
4123+ cexpj(val, theta);
4124+ mag= exp(-theta / (2.0 * qfact));
4125+ th0= 0; th2= M_PI;
4126+ for (cnt= 60; cnt > 0; cnt--) {
4127+ th1= 0.5 * (th0 + th2);
4128+ cexpj(pol, th1);
4129+ cmulr(pol, mag);
4130+
4131+ // Evaluate response of filter for Z= val
4132+ memcpy(tmp1, val, 2*sizeof(double));
4133+ memcpy(tmp2, val, 2*sizeof(double));
4134+ memcpy(tmp3, val, 2*sizeof(double));
4135+ memcpy(tmp4, val, 2*sizeof(double));
4136+ csubz(tmp1, 1, 0);
4137+ csubz(tmp2, -1, 0);
4138+ cmul(tmp1, tmp2);
4139+ csub(tmp3, pol); cconj(pol);
4140+ csub(tmp4, pol); cconj(pol);
4141+ cmul(tmp3, tmp4);
4142+ cdiv(tmp1, tmp3);
4143+
4144+ if (fabs(tmp1[1] / tmp1[0]) < 1e-10) break;
4145+
4146+ //printf("%-24.16g%-24.16g -> %-24.16g%-24.16g\n", th0, th2, tmp1[0], tmp1[1]);
4147+
4148+ if (tmp1[1] > 0.0) th2= th1;
4149+ else th0= th1;
4150+ }
4151+
4152+ if (cnt <= 0) fprintf(stderr, "Resonator binary search failed to converge");
4153+}
4154+
4155+//
4156+// Setup poles/zeros for a bandstop resonator
4157+//
4158+
4159+static void
4160+bandstop_res(double freq, double qfact) {
4161+ bandpass_res(freq, qfact);
4162+ zertyp[0]= 2; zertyp[1]= 0;
4163+ cexpj(zer, TWOPI * freq);
4164+}
4165+
4166+//
4167+// Setup poles/zeros for an allpass resonator
4168+//
4169+
4170+static void
4171+allpass_res(double freq, double qfact) {
4172+ bandpass_res(freq, qfact);
4173+ zertyp[0]= 2; zertyp[1]= 0;
4174+ memcpy(zer, pol, 2*sizeof(double));
4175+ cmulr(zer, 1.0 / (zer[0]*zer[0] + zer[1]*zer[1]));
4176+}
4177+
4178+//
4179+// Setup poles/zeros for a proportional-integral filter
4180+//
4181+
4182+static void
4183+prop_integral(double freq) {
4184+ n_pol= 1;
4185+ poltyp[0]= 1;
4186+ pol[0]= 0.0;
4187+ n_zer= 1;
4188+ zertyp[0]= 1;
4189+ zer[0]= -TWOPI * freq;
4190+}
4191+
4192+// END //
4193+#endif
4194+
4195
4196=== added file 'mixxx/lib/fidlib-0.9.10/fidrf_cmdlist.h'
4197--- mixxx/lib/fidlib-0.9.10/fidrf_cmdlist.h 1970-01-01 00:00:00 +0000
4198+++ mixxx/lib/fidlib-0.9.10/fidrf_cmdlist.h 2011-07-25 04:35:51 +0000
4199@@ -0,0 +1,479 @@
4200+//
4201+// Command-list based filter-running code.
4202+//
4203+// Copyright (c) 2002-2003 Jim Peters <http://uazu.net/>. This
4204+// file is released under the GNU Lesser General Public License
4205+// (LGPL) version 2.1 as published by the Free Software
4206+// Foundation. See the file COPYING_LIB for details, or visit
4207+// <http://www.fsf.org/licenses/licenses.html>.
4208+//
4209+// This version of the filter-running code is based on getting
4210+// the filter to go as fast as possible with a pre-compiled
4211+// routine, but without flattening the filter structure. This
4212+// gives greater accuracy than the combined filter. The result
4213+// is mostly faster than the combined filter (tested on ix86 with
4214+// gcc -O6), except where the combined filter gets a big
4215+// advantage from flattening the filter list. This code is also
4216+// portable (unlike the JIT option).
4217+//
4218+
4219+typedef struct Run {
4220+ int magic; // Magic: 0x64966325
4221+ int buf_size; // Length of working buffer required in doubles
4222+ double *coef; // Coefficient list
4223+ char *cmd; // Command list
4224+} Run;
4225+
4226+typedef struct RunBuf {
4227+ double *coef;
4228+ char *cmd;
4229+ int mov_cnt; // Number of bytes to memmove
4230+ double buf[0];
4231+} RunBuf;
4232+
4233+
4234+//
4235+// Filter processing routine. This is designed to avoid too many
4236+// branches, and references are very localized in the code,
4237+// keeping the optimizer from trying to store and remember old
4238+// values.
4239+//
4240+
4241+//
4242+// Step commands:
4243+// 0 END
4244+// 1 IIR coefficient (1+0)
4245+// 2 2x IIR coefficient (2+0)
4246+// 3 3x IIR coefficient (3+0)
4247+// 4 4Nx IIR coefficient (4N+0)
4248+// 5 FIR coefficient (0+1)
4249+// 6 2x FIR coefficient (0+2)
4250+// 7 3x FIR coefficient (0+3)
4251+// 8 4Nx FIR coefficient (0+4N)
4252+// 9 IIR+FIR coefficients (1+1)
4253+// 10 2x IIR+FIR coefficients (2+2)
4254+// 11 3x IIR+FIR coefficients (3+3)
4255+// 12 4Nx IIR+FIR coefficients (4N+4N)
4256+// 13 End-stage, pure IIR, assume no FIR done at all (1+0)
4257+// 14 End-stage with just FIR coeff (0+2)
4258+// 15 End-stage with IIR+FIR coeff (1+2)
4259+// 16 IIR + pure-IIR endstage (2+0)
4260+// 17 FIR + FIR end-stage (0+3)
4261+// 18 IIR+FIR + IIR+FIR end-stage (2+3)
4262+// 19 Nx (IIR + pure-IIR endstage) (2+0)
4263+// 20 Nx (FIR + FIR end-stage) (0+3)
4264+// 21 Nx (IIR+FIR + IIR+FIR end-stage) (2+3)
4265+// 22 Gain coefficient (0+1)
4266+//
4267+// Most filters are made up of 2x2 IIR/FIR pairs, which means a
4268+// list of command 18 bytes. The other big job would be long FIR
4269+// filters. These have to be handled with a list of 7,6,5
4270+// commands, plus a 13 command.
4271+//
4272+
4273+typedef unsigned char uchar;
4274+
4275+static double
4276+filter_step(void *fbuf, double iir) {
4277+ double *coef= ((RunBuf*)fbuf)->coef;
4278+ uchar *cmd= ((RunBuf*)fbuf)->cmd;
4279+ double *buf= &((RunBuf*)fbuf)->buf[0];
4280+ uchar ch;
4281+ double fir= 0;
4282+ double tmp= buf[0];
4283+ int cnt;
4284+
4285+ // Using a memmove first is faster on gcc -O6 / ix86 than moving
4286+ // the values whilst working through the buffers.
4287+ memmove(buf, buf+1, ((RunBuf*)fbuf)->mov_cnt);
4288+
4289+#define IIR \
4290+ iir -= *coef++ * tmp; \
4291+ tmp= *buf++;
4292+#define FIR \
4293+ fir += *coef++ * tmp; \
4294+ tmp= *buf++;
4295+#define BOTH \
4296+ iir -= *coef++ * tmp; \
4297+ fir += *coef++ * tmp; \
4298+ tmp= *buf++;
4299+#define ENDIIR \
4300+ iir -= *coef++ * tmp; \
4301+ tmp= *buf++; \
4302+ buf[-1]= iir;
4303+#define ENDFIR \
4304+ fir += *coef++ * tmp; \
4305+ tmp= *buf++; \
4306+ buf[-1]= iir; \
4307+ iir= fir + *coef++ * iir; \
4308+ fir= 0
4309+#define ENDBOTH \
4310+ iir -= *coef++ * tmp; \
4311+ fir += *coef++ * tmp; \
4312+ tmp= *buf++; \
4313+ buf[-1]= iir; \
4314+ iir= fir + *coef++ * iir; \
4315+ fir= 0
4316+#define GAIN \
4317+ iir *= *coef++
4318+
4319+ while ((ch= *cmd++)) switch (ch) {
4320+ case 1:
4321+ IIR; break;
4322+ case 2:
4323+ IIR; IIR; break;
4324+ case 3:
4325+ IIR; IIR; IIR; break;
4326+ case 4:
4327+ cnt= *cmd++;
4328+ do { IIR; IIR; IIR; IIR; } while (--cnt > 0);
4329+ break;
4330+ case 5:
4331+ FIR; break;
4332+ case 6:
4333+ FIR; FIR; break;
4334+ case 7:
4335+ FIR; FIR; FIR; break;
4336+ case 8:
4337+ cnt= *cmd++;
4338+ do { FIR; FIR; FIR; FIR; } while (--cnt > 0);
4339+ break;
4340+ case 9:
4341+ BOTH; break;
4342+ case 10:
4343+ BOTH; BOTH; break;
4344+ case 11:
4345+ BOTH; BOTH; BOTH; break;
4346+ case 12:
4347+ cnt= *cmd++;
4348+ do { BOTH; BOTH; BOTH; BOTH; } while (--cnt > 0);
4349+ break;
4350+ case 13:
4351+ ENDIIR; break;
4352+ case 14:
4353+ ENDFIR; break;
4354+ case 15:
4355+ ENDBOTH; break;
4356+ case 16:
4357+ IIR; ENDIIR; break;
4358+ case 17:
4359+ FIR; ENDFIR; break;
4360+ case 18:
4361+ BOTH; ENDBOTH; break;
4362+ case 19:
4363+ cnt= *cmd++;
4364+ do { IIR; ENDIIR; } while (--cnt > 0);
4365+ break;
4366+ case 20:
4367+ cnt= *cmd++;
4368+ do { FIR; ENDFIR; } while (--cnt > 0);
4369+ break;
4370+ case 21:
4371+ cnt= *cmd++;
4372+ do { BOTH; ENDBOTH; } while (--cnt > 0);
4373+ break;
4374+ case 22:
4375+ GAIN; break;
4376+ }
4377+
4378+#undef IIR
4379+#undef FIR
4380+#undef BOTH
4381+#undef ENDIIR
4382+#undef ENDFIR
4383+#undef ENDBOTH
4384+#undef GAIN
4385+
4386+ return iir;
4387+}
4388+
4389+
4390+//
4391+// Create an instance of a filter, ready to run. This returns a
4392+// void* handle, and a function to call to execute the filter.
4393+// Working buffers for the filter instances must be allocated
4394+// separately using fid_run_newbuf(). This allows many
4395+// simultaneous instances of the filter to be run.
4396+//
4397+// The sub-filters are executed in the precise order that they
4398+// are given. This may lead to some inefficiency. Normally when
4399+// an IIR filter is followed by an FIR filter, the buffers can be
4400+// shared. However, if the sub-filters are not in IIR/FIR pairs,
4401+// then extra memory accesses are required.
4402+//
4403+// In any case, factors are extracted from IIR filters (so that
4404+// the first coefficient is 1), and single-element FIR filters
4405+// are merged into the global gain factor, and are ignored.
4406+//
4407+// The returned handle must be released using fid_run_free().
4408+//
4409+
4410+void *
4411+fid_run_new(FidFilter *filt, double (**funcpp)(void *,double)) {
4412+ int buf_size= 0;
4413+ uchar *cp, prev;
4414+ FidFilter *ff;
4415+ double *dp;
4416+ double gain= 1.0;
4417+ int a;
4418+ double *coef_tmp;
4419+ uchar *cmd_tmp;
4420+ int coef_cnt, coef_max;
4421+ int cmd_cnt, cmd_max;
4422+ int filt_cnt= 0;
4423+ Run *rr;
4424+
4425+ for (ff= filt; ff->len; ff= FFNEXT(ff))
4426+ filt_cnt += ff->len;
4427+
4428+ // Allocate worst-case sizes for temporary arrays
4429+ coef_tmp= ALLOC_ARR(coef_max= filt_cnt + 1, double);
4430+ cmd_tmp= (uchar*)ALLOC_ARR(cmd_max= filt_cnt + 4, char);
4431+ dp= coef_tmp;
4432+ cp= cmd_tmp;
4433+ prev= 0;
4434+
4435+ // Generate command and coefficient lists
4436+ while (filt->len) {
4437+ int n_iir, n_fir, cnt;
4438+ double *iir, *fir;
4439+ double adj;
4440+ if (filt->typ == 'F' && filt->len == 1) {
4441+ gain *= filt->val[0];
4442+ filt= FFNEXT(filt);
4443+ continue;
4444+ }
4445+ if (filt->typ == 'F') {
4446+ iir= 0; n_iir= 0;
4447+ fir= filt->val; n_fir= filt->len;
4448+ filt= FFNEXT(filt);
4449+ } else if (filt->typ == 'I') {
4450+ iir= filt->val; n_iir= filt->len;
4451+ fir= 0; n_fir= 0;
4452+ filt= FFNEXT(filt);
4453+ while (filt->typ == 'F' && filt->len == 1) {
4454+ gain *= filt->val[0];
4455+ filt= FFNEXT(filt);
4456+ }
4457+ if (filt->typ == 'F') {
4458+ fir= filt->val; n_fir= filt->len;
4459+ filt= FFNEXT(filt);
4460+ }
4461+ } else
4462+ error("Internal error: fid_run_new can only handle IIR + FIR types");
4463+
4464+ // Okay, we now have an IIR/FIR pair to process, possibly with
4465+ // n_iir or n_fir == 0 if one half is missing
4466+ cnt= n_iir > n_fir ? n_iir : n_fir;
4467+ buf_size += cnt-1;
4468+ if (n_iir) {
4469+ adj= 1.0 / iir[0];
4470+ gain *= adj;
4471+ }
4472+ if (n_fir == 3 && n_iir == 3) {
4473+ if (prev == 18) { cp[-1]= prev= 21; *cp++= 2; }
4474+ else if (prev == 21) { cp[-1]++; }
4475+ else *cp++= prev= 18;
4476+ *dp++= iir[2]*adj; *dp++= fir[2];
4477+ *dp++= iir[1]*adj; *dp++= fir[1];
4478+ *dp++= fir[0];
4479+ } else if (n_fir == 3 && n_iir == 0) {
4480+ if (prev == 17) { cp[-1]= prev= 20; *cp++= 2; }
4481+ else if (prev == 20) { cp[-1]++; }
4482+ else *cp++= prev= 17;
4483+ *dp++= fir[2];
4484+ *dp++= fir[1];
4485+ *dp++= fir[0];
4486+ } else if (n_fir == 0 && n_iir == 3) {
4487+ if (prev == 16) { cp[-1]= prev= 19; *cp++= 2; }
4488+ else if (prev == 19) { cp[-1]++; }
4489+ else *cp++= prev= 16;
4490+ *dp++= iir[2]*adj;
4491+ *dp++= iir[1]*adj;
4492+ } else {
4493+ prev= 0; // Just cancel 'prev' as we only use it for 16-18,19-21
4494+ if (cnt > n_fir) {
4495+ a= 0;
4496+ while (cnt > n_fir && cnt > 2) {
4497+ *dp++= iir[--cnt] * adj; a++;
4498+ }
4499+ while (a >= 4) {
4500+ int nn= a/4; if (nn > 255) nn= 255;
4501+ *cp++= 4; *cp++= nn; a -= nn*4;
4502+ }
4503+ if (a) *cp++= a;
4504+ }
4505+ if (cnt > n_iir) {
4506+ a= 0;
4507+ while (cnt > n_iir && cnt > 2) {
4508+ *dp++= fir[--cnt]; a++;
4509+ }
4510+ while (a >= 4) {
4511+ int nn= a/4; if (nn > 255) nn= 255;
4512+ *cp++= 8; *cp++= nn; a -= nn*4;
4513+ }
4514+ if (a) *cp++= 4+a;
4515+ }
4516+ a= 0;
4517+ while (cnt > 2) {
4518+ cnt--; a++;
4519+ *dp++= iir[cnt]*adj; *dp++= fir[cnt];
4520+ }
4521+ while (a >= 4) {
4522+ int nn= a/4; if (nn > 255) nn= 255;
4523+ *cp++= 12; *cp++= nn; a -= nn*4;
4524+ }
4525+ if (a) *cp++= 8+a;
4526+
4527+ if (!n_fir) {
4528+ *cp++= 13;
4529+ *dp++= iir[1];
4530+ } else if (!n_iir) {
4531+ *cp++= 14;
4532+ *dp++= fir[1];
4533+ *dp++= fir[0];
4534+ } else {
4535+ *cp++= 15;
4536+ *dp++= iir[1];
4537+ *dp++= fir[1];
4538+ *dp++= fir[0];
4539+ }
4540+ }
4541+ }
4542+
4543+ if (gain != 1.0) {
4544+ *cp++= 22;
4545+ *dp++= gain;
4546+ }
4547+ *cp++= 0;
4548+
4549+ // Sanity checks
4550+ coef_cnt= dp-coef_tmp;
4551+ cmd_cnt= cp-cmd_tmp;
4552+ if (coef_cnt > coef_max ||
4553+ cmd_cnt > cmd_max)
4554+ error("fid_run_new internal error; arrays exceeded");
4555+
4556+ // Allocate the final Run structure to return
4557+ rr= (Run*)Alloc(sizeof(Run) +
4558+ coef_cnt*sizeof(double) +
4559+ cmd_cnt*sizeof(char));
4560+ rr->magic= 0x64966325;
4561+ rr->buf_size= buf_size;
4562+ rr->coef= (double*)(rr+1);
4563+ rr->cmd= (char*)(rr->coef + coef_cnt);
4564+ memcpy(rr->coef, coef_tmp, coef_cnt*sizeof(double));
4565+ memcpy(rr->cmd, cmd_tmp, cmd_cnt*sizeof(char));
4566+
4567+ //DEBUG {
4568+ //DEBUG int a;
4569+ //DEBUG for (cp= cmd_tmp; *cp; cp++) printf("%d ", *cp);
4570+ //DEBUG printf("\n");
4571+ //DEBUG //for (a= 0; a<coef_cnt; a++) printf("%g ", coef_tmp[a]);
4572+ //DEBUG //printf("\n");
4573+ //DEBUG }
4574+
4575+ free(coef_tmp);
4576+ free(cmd_tmp);
4577+
4578+ *funcpp= filter_step;
4579+ return rr;
4580+}
4581+
4582+//
4583+// Create a new instance of the given filter
4584+//
4585+
4586+void *
4587+fid_run_newbuf(void *run) {
4588+ Run *rr= (Run*)run;
4589+ RunBuf *rb;
4590+ int siz;
4591+
4592+ if (rr->magic != 0x64966325)
4593+ error("Bad handle passed to fid_run_newbuf()");
4594+
4595+ siz= rr->buf_size ? rr->buf_size : 1; // Minimum one element to avoid problems
4596+ rb= (RunBuf*)Alloc(sizeof(RunBuf) + siz * sizeof(double));
4597+ rb->coef= rr->coef;
4598+ rb->cmd= rr->cmd;
4599+ rb->mov_cnt= (siz-1) * sizeof(double);
4600+ // rb->buf[] already zerod
4601+
4602+ return rb;
4603+}
4604+
4605+//
4606+// Find the space required for a filter buffer
4607+//
4608+
4609+int
4610+fid_run_bufsize(void *run) {
4611+ Run *rr= (Run*)run;
4612+ int siz;
4613+
4614+ if (rr->magic != 0x64966325)
4615+ error("Bad handle passed to fid_run_bufsize()");
4616+
4617+ siz= rr->buf_size ? rr->buf_size : 1; // Minimum one element to avoid problems
4618+ return sizeof(RunBuf) + siz * sizeof(double);
4619+}
4620+
4621+//
4622+// Initialise a filter buffer allocated separately. Usually
4623+// fid_run_newbuf() is easier, but in the case where filter
4624+// buffers must be allocated as part of a larger structure, a
4625+// call to fid_run_newbuf can be replaced with a call to
4626+// fid_run_bufsize() to get the space required, and then a call
4627+// to fid_run_initbuf() once it has been allocated.
4628+//
4629+
4630+void
4631+fid_run_initbuf(void *run, void *buf) {
4632+ Run *rr= (Run*)run;
4633+ RunBuf *rb= (RunBuf*)buf;
4634+ int siz;
4635+
4636+ if (rr->magic != 0x64966325)
4637+ error("Bad handle passed to fid_run_initbuf()");
4638+
4639+ siz= rr->buf_size ? rr->buf_size : 1; // Minimum one element to avoid problems
4640+ rb->coef= rr->coef;
4641+ rb->cmd= rr->cmd;
4642+ rb->mov_cnt= (siz-1) * sizeof(double);
4643+ memset(rb->buf, 0, rb->mov_cnt + sizeof(double));
4644+}
4645+
4646+//
4647+// Reinitialise an instance of the filter, allowing it to start
4648+// afresh. It assumes that the buffer was correctly initialised
4649+// previously, either through a call to fid_run_newbuf() or
4650+// fid_run_initbuf().
4651+//
4652+
4653+void
4654+fid_run_zapbuf(void *buf) {
4655+ RunBuf *rb= (RunBuf*)buf;
4656+ memset(rb->buf, 0, rb->mov_cnt + sizeof(double));
4657+}
4658+
4659+
4660+//
4661+// Delete an instance
4662+//
4663+
4664+void
4665+fid_run_freebuf(void *runbuf) {
4666+ free(runbuf);
4667+}
4668+
4669+//
4670+// Delete the filter
4671+//
4672+
4673+void
4674+fid_run_free(void *run) {
4675+ free(run);
4676+}
4677+
4678+// END //
4679
4680=== added file 'mixxx/lib/fidlib-0.9.10/fidrf_combined.h'
4681--- mixxx/lib/fidlib-0.9.10/fidrf_combined.h 1970-01-01 00:00:00 +0000
4682+++ mixxx/lib/fidlib-0.9.10/fidrf_combined.h 2011-07-25 04:35:51 +0000
4683@@ -0,0 +1,151 @@
4684+//
4685+// Combined-filter based filter-running code.
4686+//
4687+// Copyright (c) 2002-2003 Jim Peters <http://uazu.net/>. This
4688+// file is released under the GNU Lesser General Public License
4689+// (LGPL) version 2.1 as published by the Free Software
4690+// Foundation. See the file COPYING_LIB for details, or visit
4691+// <http://www.fsf.org/licenses/licenses.html>.
4692+//
4693+// Convolves all the filters into a single IIR/FIR pair, and runs
4694+// that directly through static code. Compiled with GCC -O6 on
4695+// ix86 this is surprisingly fast -- at worst half the speed of
4696+// assember code, at best matching it. The downside of
4697+// convolving all the sub-filters together like this is loss of
4698+// accuracy and instability in some kinds of filters, especially
4699+// high-order ones. The one big advantage of this approach is
4700+// that the code is easy to understand.
4701+//
4702+
4703+#ifndef FIDCOMBINED_H
4704+#define FIDCOMBINED_H
4705+
4706+typedef struct Run {
4707+ int magic; // Magic: 0x64966325
4708+ double *fir; // FIR parameters
4709+ int n_fir; // Number of FIR parameters
4710+ double *iir; // IIR parameters
4711+ int n_iir; // Number of IIR parameters
4712+ int n_buf; // Number of entries in buffer
4713+ FidFilter *filt; // Combined filter
4714+} Run;
4715+
4716+typedef struct RunBuf {
4717+ Run *run;
4718+ double buf[0];
4719+} RunBuf;
4720+
4721+static double
4722+filter_step(void *rb, double val) {
4723+ Run *rr= ((RunBuf*)rb)->run;
4724+ double *buf= ((RunBuf*)rb)->buf;
4725+ int a;
4726+
4727+ // Shift the whole internal array up one
4728+ memmove(buf+1, buf, (rr->n_buf-1)*sizeof(buf[0]));
4729+
4730+ // Do IIR
4731+ for (a= 1; a<rr->n_iir; a++) val -= rr->iir[a] * buf[a];
4732+ buf[0]= val;
4733+
4734+ // Do FIR
4735+ val= 0;
4736+ for (a= 0; a<rr->n_fir; a++) val += rr->fir[a] * buf[a];
4737+
4738+ return val;
4739+}
4740+
4741+
4742+//
4743+// Create an instance of a filter, ready to run. This returns a
4744+// void* handle, and a function to call to execute the filter.
4745+// Working buffers for the filter instances must be allocated
4746+// separately using fid_run_newbuf(). This allows many
4747+// simultaneous instances of the filter to be run.
4748+//
4749+// The returned handle must be released using fid_run_free().
4750+//
4751+
4752+void *
4753+fid_run_new(FidFilter *filt, double (**funcpp)(void *,double)) {
4754+ Run *rr= ALLOC(Run);
4755+ FidFilter *ff;
4756+
4757+ rr->magic= 0x64966325;
4758+ rr->filt= fid_flatten(filt);
4759+
4760+ ff= rr->filt;
4761+ if (ff->typ != 'I') goto bad;
4762+ rr->n_iir= ff->len;
4763+ rr->iir= ff->val;
4764+ ff= FFNEXT(ff);
4765+ if (ff->typ != 'F') goto bad;
4766+ rr->n_fir= ff->len;
4767+ rr->fir= ff->val;
4768+ ff= FFNEXT(ff);
4769+ if (ff->len) goto bad;
4770+
4771+ rr->n_buf= rr->n_fir > rr->n_iir ? rr->n_fir : rr->n_iir;
4772+
4773+ *funcpp= filter_step;
4774+
4775+ return rr;
4776+
4777+ bad:
4778+ error("Internal error: fid_run_new() expecting IIR+FIR in flattened filter");
4779+ return 0;
4780+}
4781+
4782+//
4783+// Create a new instance of the given filter
4784+//
4785+
4786+void *
4787+fid_run_newbuf(void *run) {
4788+ Run *rr= run;
4789+ RunBuf *rb;
4790+
4791+ if (rr->magic != 0x64966325)
4792+ error("Bad handle passed to fid_run_newbuf()");
4793+
4794+ rb= Alloc(sizeof(RunBuf) + rr->n_buf * sizeof(double));
4795+ rb->run= run;
4796+ // rb->buf[] already zerod
4797+
4798+ return rb;
4799+}
4800+
4801+//
4802+// Reinitialise an instance ready to start afresh
4803+//
4804+
4805+void
4806+fid_run_zapbuf(void *buf) {
4807+ RunBuf *rb;
4808+ Run *rr= rb->run;
4809+ memset(rb->buf, 0, rr->n_buf * sizeof(double));
4810+}
4811+
4812+//
4813+// Delete an instance
4814+//
4815+
4816+void
4817+fid_run_freebuf(void *runbuf) {
4818+ free(runbuf);
4819+}
4820+
4821+//
4822+// Delete the filter
4823+//
4824+
4825+void
4826+fid_run_free(void *run) {
4827+ Run *rr= run;
4828+ free(rr->filt);
4829+ free(rr);
4830+}
4831+
4832+// END //
4833+#endif
4834+
4835
4836=== added file 'mixxx/lib/fidlib-0.9.10/fidrf_jit.h'
4837--- mixxx/lib/fidlib-0.9.10/fidrf_jit.h 1970-01-01 00:00:00 +0000
4838+++ mixxx/lib/fidlib-0.9.10/fidrf_jit.h 2011-07-25 04:35:51 +0000
4839@@ -0,0 +1,792 @@
4840+#error "JIT code is no longer maintained -- cmdlist is almost as fast on ix86"
4841+
4842+//
4843+// JIT-compiled filter-running code.
4844+//
4845+// Copyright (c) 2002-2003 Jim Peters <http://uazu.net/>. This
4846+// file is released under the GNU Lesser General Public License
4847+// (LGPL) version 2.1 as published by the Free Software
4848+// Foundation. See the file COPYING_LIB for details, or visit
4849+// <http://www.fsf.org/licenses/licenses.html>.
4850+//
4851+// The aim of this version of the filter-running code is to go as
4852+// fast as possible (without flattening the sub-filters together)
4853+// by generating the necessary code at run-time.
4854+//
4855+// This runs the filter exactly as specified, without convolving
4856+// the sub-filters together or changing their order. The only
4857+// rearrangement performed is making the IIR first coefficient
4858+// 1.0, and gathering any lone 1-coefficient FIR filters together
4859+// into a single initial gain adjustment. For this reason, the
4860+// routine runs fastest if IIR and FIR sub-filters are grouped
4861+// together in IIR/FIR pairs, as these can then share common
4862+// working buffers.
4863+//
4864+// The generated code is cached, and is reused for more than one
4865+// filter if possible. This means that a bank of 1000s of
4866+// filters of similar types will probably all end up sharing the
4867+// same generated routine, which improves processor cache and
4868+// memory usage.
4869+//
4870+// Probably the generated code could be improved, but it is not
4871+// too bad. Copying the buffer values using 'rep movsl' turned
4872+// out to be much faster than loading and storing the floating
4873+// point values individually whilst working through the buffer.
4874+//
4875+// The generated code was tested for speed on a Celeron-900 and
4876+// on a Pentium-133. It always beats the RF_CMDLIST option. It
4877+// can be slightly slower than the RF_COMBINED option, but only
4878+// where that option gets a big advantage from flattening the
4879+// sub-filters. For pre-flattened filters, it is faster.
4880+//
4881+// The generated code can be dumped out at any point in .s format
4882+// using fid_run_dump(). This can be assembled using 'gas' and
4883+// then disassembled with 'objdump -d' to see all the generated
4884+// code.
4885+//
4886+// Things that could be improved:
4887+//
4888+// - Don't keep the fir running total on the stack at all times.
4889+// Instead create it at the first FIR operation. This means
4890+// generating about 10 new special-case macros. This would save
4891+// an add for every filter stage, and some of the messing around
4892+// at start and end currently done to set up / clean up this
4893+// value on the FP stack.
4894+//
4895+
4896+typedef struct Routine Routine;
4897+struct Routine {
4898+ Routine *nxt; // Next in list, or 0
4899+ int ref; // Reference count
4900+ int hash; // Hash of routine
4901+ char *code; // Routine itself
4902+ int len; // Length of code in bytes
4903+};
4904+
4905+typedef struct Run {
4906+ int magic; // Magic: 0x64966325
4907+ int n_buf; // Length of working buffer required in doubles
4908+ double *coef; // Coefficient list
4909+ Routine *rout; // Routine used
4910+} Run;
4911+
4912+typedef struct RunBuf {
4913+ double *coef; // Coefficient array
4914+ int mov_cnt; // Number of 4-byte chunks to copy from &buf[1] to &buf[0]
4915+ double buf[0]; // Buffer itself
4916+} RunBuf;
4917+
4918+static unsigned long int do_hash(unsigned char *, unsigned long int, unsigned long int);
4919+#define HASH(p,len) ((int)do_hash((unsigned char *)p, (unsigned long int)len, 0))
4920+
4921+
4922+// Code generation
4923+//
4924+// %edx is the working buffer pointer
4925+// %eax is the coefficient pointer
4926+// %ecx is the loop counter
4927+// floating point stack contains working values at the top, then
4928+// previous buffer value, then running iir total, then running
4929+// fir total
4930+//
4931+// Codes in the add() string:
4932+//
4933+// %C 4-byte long value count for loop
4934+// %L Label -- remember this address for looping back to
4935+// %R 1-byte relative jump back to %L address
4936+// %D 1-byte relative address of buffer value. If zero, this adjusts the
4937+// previous byte by ^=0x40 to make it a pure (%edx) form instead of 0(%edx)
4938+// %D+ 1-byte relative address of buffer value as above, plus increment %edx
4939+// if we are getting close to the end of the range
4940+// %A 1-byte relative address of coefficient value. If zero does same as for %D.
4941+// %A+ 1-byte relative address of coefficient value, plus %eax inc
4942+// if necessary
4943+// %= Insert code to update %edx and %eax to point to the given offsets
4944+//
4945+// Startup code
4946+//
4947+// pushl %ebp
4948+// movl %esp,%ebp
4949+// movl 8(%ebp),%edx
4950+// movl (%edx),%eax
4951+// movl 4(%edx),%ecx
4952+// fldz
4953+// fldl 12(%ebp)
4954+// fldl 8(%edx)
4955+// fmull (%eax)
4956+// leal 8(%edx),%edi
4957+// leal 16(%edx),%esi
4958+// cld
4959+// rep movsl
4960+
4961+#define STARTUP add("55 89E5 8B5508 8B02 8B4A04 D9EE DD450C DD4208 DC08 8D7A08 8D7210 FC F3A5")
4962+
4963+// Return
4964+//
4965+// fstp %st(0) // pop
4966+// fstp %st(1)
4967+// leave
4968+// ret
4969+
4970+#define RETURN add("DDD8 DDD9 C9 C3")
4971+
4972+// Looping
4973+//
4974+// movl $100,%ecx
4975+// .LXX
4976+// ...
4977+// loop .LXX
4978+//
4979+// //WAS decl %ecx
4980+// //WAS testl %ecx,%ecx
4981+// //WAS jg .LXX
4982+
4983+#define FOR(xx, nnd, nna) add("B9%C %= %L", xx, (nnd)*8, (nna)*8)
4984+//WAS #define NEXT(nnd, nna) add("%= 49 85C9 7F%R", (nnd)*8, (nna)*8)
4985+#define NEXT(nnd, nna) add("%= E2%R", (nnd)*8, (nna)*8)
4986+
4987+// Fetching/storing buffer values
4988+//
4989+// tmp= buf[n];
4990+// fldl nn(%edx)
4991+//
4992+// buf[nn]= iir;
4993+// fld %st(1)
4994+// fstpl nn(%edx)
4995+
4996+#define GETB(nn) add("DD42%D+", (nn)*8)
4997+#define PUTB(nn) add("D9C1 DD5A%D+", (nn)*8)
4998+
4999+// FIR element with following IIR element
5000+//
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches