From cdf8ded57019d5c905f16422d40be7b1a18ab3bc Mon Sep 17 00:00:00 2001 From: Tom Schouten Date: Tue, 21 Jan 2003 10:18:19 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r350, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/creb/; revision=351 --- COPYING | 340 +++++++++++++++++ Makefile | 49 +++ Makefile.config | 20 + Makefile.config_darwin | 25 ++ Makefile.pd_darwin | 27 ++ README | 45 +++ README.darwin | 8 + abs/64k.pd | 96 +++++ abs/bdft.pd | 16 + abs/bdfts.pd | 18 + abs/bhip~.pd | 10 + abs/blop~.pd | 10 + abs/bpm.pd | 18 + abs/count.pd | 20 + abs/eadh~.pd | 22 ++ abs/eadsrh~.pd | 27 ++ abs/fblock.pd | 25 ++ abs/inv.pd | 8 + abs/pdynwav~.pd | 10 + abs/scale7.pd | 40 ++ abs/vols~.pd | 24 ++ abs/vol~.pd | 18 + doc/bdiag~.pd | 97 +++++ doc/bfft~.pd | 18 + doc/biquadseries~.pd | 22 ++ doc/cheby~.pd | 43 +++ doc/dist~.pd | 17 + doc/dwt~.pd | 72 ++++ doc/dynwav~.pd | 25 ++ doc/eadsr~.pd | 41 +++ doc/ead~.pd | 29 ++ doc/ear~.pd | 35 ++ doc/examples/xfmdelay.pd | 106 ++++++ doc/ffpoly.pd | 35 ++ doc/filterortho~.pd | 58 +++ doc/fwarp.pd | 37 ++ doc/lattice~.pd | 63 ++++ doc/matrix~.pd | 10 + doc/permut~.pd | 19 + doc/qmult~.pd | 63 ++++ doc/qnorm~.pd | 35 ++ doc/ratio.pd | 18 + doc/reference.txt | 49 +++ doc/tabreadmix~.pd | 45 +++ doc/xfm~.pd | 106 ++++++ include/Makefile | 5 + include/dspi/DSPI.h | 16 + include/dspi/DSPIcomplex.h | 191 ++++++++++ include/dspi/DSPIfilters.h | 496 +++++++++++++++++++++++++ include/extlib_util.h | 31 ++ modules++/Makefile | 10 + modules++/biquadseries.cc | 128 +++++++ modules++/filterortho.cc | 131 +++++++ modules/Makefile | 11 + modules/abs.c | 64 ++++ modules/bdiag.c | 272 ++++++++++++++ modules/bfft.c | 304 +++++++++++++++ modules/cheby.c | 138 +++++++ modules/diag.c | 218 +++++++++++ modules/dist.c | 262 +++++++++++++ modules/dwt.c | 893 +++++++++++++++++++++++++++++++++++++++++++++ modules/dynwav.c | 318 ++++++++++++++++ modules/ead.c | 153 ++++++++ modules/eadsr.c | 171 +++++++++ modules/ear.c | 134 +++++++ modules/ffpoly.c | 173 +++++++++ modules/fwarp.c | 61 ++++ modules/lattice.c | 143 ++++++++ modules/matrix.c | 154 ++++++++ modules/permut.c | 177 +++++++++ modules/qmult.c | 165 +++++++++ modules/qnorm.c | 137 +++++++ modules/ramp.c | 118 ++++++ modules/ratio.c | 66 ++++ modules/statwav.c | 149 ++++++++ modules/tabreadmix.c | 271 ++++++++++++++ modules/xfm.c | 271 ++++++++++++++ system/Makefile | 8 + system/envelope_util.c | 33 ++ system/setup.c | 64 ++++ 80 files changed, 7855 insertions(+) create mode 100644 COPYING create mode 100644 Makefile create mode 100644 Makefile.config create mode 100644 Makefile.config_darwin create mode 100644 Makefile.pd_darwin create mode 100644 README create mode 100644 README.darwin create mode 100644 abs/64k.pd create mode 100644 abs/bdft.pd create mode 100644 abs/bdfts.pd create mode 100644 abs/bhip~.pd create mode 100644 abs/blop~.pd create mode 100644 abs/bpm.pd create mode 100644 abs/count.pd create mode 100644 abs/eadh~.pd create mode 100644 abs/eadsrh~.pd create mode 100644 abs/fblock.pd create mode 100644 abs/inv.pd create mode 100644 abs/pdynwav~.pd create mode 100644 abs/scale7.pd create mode 100644 abs/vols~.pd create mode 100644 abs/vol~.pd create mode 100644 doc/bdiag~.pd create mode 100644 doc/bfft~.pd create mode 100644 doc/biquadseries~.pd create mode 100644 doc/cheby~.pd create mode 100644 doc/dist~.pd create mode 100644 doc/dwt~.pd create mode 100644 doc/dynwav~.pd create mode 100644 doc/eadsr~.pd create mode 100644 doc/ead~.pd create mode 100644 doc/ear~.pd create mode 100644 doc/examples/xfmdelay.pd create mode 100644 doc/ffpoly.pd create mode 100644 doc/filterortho~.pd create mode 100644 doc/fwarp.pd create mode 100644 doc/lattice~.pd create mode 100644 doc/matrix~.pd create mode 100644 doc/permut~.pd create mode 100644 doc/qmult~.pd create mode 100644 doc/qnorm~.pd create mode 100644 doc/ratio.pd create mode 100644 doc/reference.txt create mode 100644 doc/tabreadmix~.pd create mode 100644 doc/xfm~.pd create mode 100644 include/Makefile create mode 100644 include/dspi/DSPI.h create mode 100644 include/dspi/DSPIcomplex.h create mode 100644 include/dspi/DSPIfilters.h create mode 100644 include/extlib_util.h create mode 100644 modules++/Makefile create mode 100644 modules++/biquadseries.cc create mode 100644 modules++/filterortho.cc create mode 100644 modules/Makefile create mode 100644 modules/abs.c create mode 100644 modules/bdiag.c create mode 100644 modules/bfft.c create mode 100644 modules/cheby.c create mode 100644 modules/diag.c create mode 100644 modules/dist.c create mode 100644 modules/dwt.c create mode 100644 modules/dynwav.c create mode 100644 modules/ead.c create mode 100644 modules/eadsr.c create mode 100644 modules/ear.c create mode 100644 modules/ffpoly.c create mode 100644 modules/fwarp.c create mode 100644 modules/lattice.c create mode 100644 modules/matrix.c create mode 100644 modules/permut.c create mode 100644 modules/qmult.c create mode 100644 modules/qnorm.c create mode 100644 modules/ramp.c create mode 100644 modules/ratio.c create mode 100644 modules/statwav.c create mode 100644 modules/tabreadmix.c create mode 100644 modules/xfm.c create mode 100644 system/Makefile create mode 100644 system/envelope_util.c create mode 100644 system/setup.c diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..7f87ef8 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR PDP.LICENSE, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d03e9f8 --- /dev/null +++ b/Makefile @@ -0,0 +1,49 @@ +include Makefile.config + +CREB_DISTRO = $(CREB_DIR)/../creb-$(CREB_VERSION) +CREB_TARBALL = $(CREB_DISTRO).tar.gz +CREB_WWWDIR = /net/zwizwa/www/zwizwa.fartit.com/pd/creb + +LIBNAME=creb.pd_linux + +current: + make -C system + make -C modules + make -C modules++ + + rm -f $(LIBNAME) + $(CPLUSPLUS) -export_dynamic -shared -o $(LIBNAME) system/*.o modules/*.o modules++/*.o -lm + strip --strip-unneeded $(LIBNAME) + +clean: + make -C include clean + make -C modules clean + make -C modules++ clean + make -C system clean + rm -f $(LIBNAME) + rm -f *~ + +tags: + etags --language=auto include/*.h system/*.c modules/*.c modules++/*.cpp + +tagsclean: + rm -f TAGS + + +distro: clean + rm -rf $(CREB_DISTRO) + mkdir $(CREB_DISTRO) + cp -av $(CREB_DIR)/* $(CREB_DISTRO) + rm -rf $(CREB_DISTRO)/CVS + rm -rf $(CREB_DISTRO)/*/CVS + rm -rf $(CREB_DISTRO)/*/*/CVS + rm -rf $(CREB_DISTRO)/*/*.o + rm -rf $(CREB_DISTRO)/*/TAGS + cd $(CREB_DISTRO)/.. && tar vczf creb-$(CREB_VERSION).tar.gz creb-$(CREB_VERSION) + rm -rf $(CREB_DISTRO) + +www: $(PDP_TARBALL) + cp -av $(CREB_TARBALL) $(CREB_WWWDIR) + cp -av $(CREB_DIR)/README $(CREB_WWWDIR)/README.txt + cp -av $(CREB_DIR)/doc/reference.txt $(CREB_WWWDIR) + diff --git a/Makefile.config b/Makefile.config new file mode 100644 index 0000000..5dee604 --- /dev/null +++ b/Makefile.config @@ -0,0 +1,20 @@ +PD_DIR = /home/tom/pd/distro/pd/src +CREB_DIR = /home/tom/pd/extlib +CREB_VERSION = 0.6 + +DEFS = -DPD -DCREB_VERSION=\"$(CREB_VERSION)\" + +LINUXCFLAGS = $(DEFS) -O2 -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch # -Wshadow + +LINUXINCLUDE = -I$(PD_DIR) -I../include -I../include/dspi + +CC = gcc +CPLUSPLUS = g++ + +.c.o: + $(CC) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.c +.cc.o: + $(CPLUSPLUS) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.o -c $*.cc + diff --git a/Makefile.config_darwin b/Makefile.config_darwin new file mode 100644 index 0000000..b9c49eb --- /dev/null +++ b/Makefile.config_darwin @@ -0,0 +1,25 @@ +PD_DIR = /usr/local/pd/src +PD_EXECUTABLE = /usr/local/pd/bin/pd + +CREB_VERSION = 0.5 + +LIBNAME = creb.pd_darwin + +DEFS = -DPD -DCREB_VERSION=\"$(CREB_VERSION)\" + +CFLAGS = $(DEFS) -O2 -funroll-loops -fomit-frame-pointer \ + -Wall -W -Wstrict-prototypes -Werror \ + -Wno-unused -Wno-parentheses -Wno-switch # -Wshadow + +INCLUDE = -I$(PD_DIR) -I../include -I../include/dspi + +LIBFLAGS = -bundle -bundle_loader $(PD_EXECUTABLE) + +CC = gcc +CPLUSPLUS = g++ + +.c.o: + $(CC) $(CFLAGS) $(INCLUDE) -o $*.o -c $*.c +.cc.o: + $(CPLUSPLUS) $(CFLAGS) $(INCLUDE) -o $*.o -c $*.cc + diff --git a/Makefile.pd_darwin b/Makefile.pd_darwin new file mode 100644 index 0000000..7dad28d --- /dev/null +++ b/Makefile.pd_darwin @@ -0,0 +1,27 @@ +CONFIGFILE = Makefile.config_darwin +include $(CONFIGFILE) + +current: + make -C system + make -C modules + make -C modules++ + + rm -f $(LIBNAME) + $(CPLUSPLUS) $(LIBFLAGS) -o $(LIBNAME) system/*.o modules/*.o modules++/*.o -lm +# strip --strip-unneeded $(LIBNAME) + +clean: + make -C include clean + make -C modules clean + make -C modules++ clean + make -C system clean + rm -f $(LIBNAME) + rm -f *~ + +tags: + etags --language=auto include/*.h system/*.c modules/*.c modules++/*.cpp + +tagsclean: + rm -f TAGS + + diff --git a/README b/README new file mode 100644 index 0000000..8f2bb32 --- /dev/null +++ b/README @@ -0,0 +1,45 @@ +CREB - compl. red. ext. blk. +some externals for pure data + +Copyright (c) by Tom Schouten + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +The GNU Public Licence can be found in the file COPYING + + +------------------------------------------------------------------ + +This is a collection of pd externals. No fancy stuff, just my +personal bag of (ahem) tricks... + +Edit Makefile.config, type make. + +add the library to the pd startup line, and specify the +path for the included abstractions (/abs) + +Documentation packages in doc/ +See doc/reference.txt for a list of objects + +The package only includes linux + darwin makefiles. It is plain c/c++ so +porting should be relatively simple. + +For compilation on OSX, see README.darwin (thanks to Adam Lindsay for +the darwin makefiles) + +Enjoy, + +Tom + diff --git a/README.darwin b/README.darwin new file mode 100644 index 0000000..0edef42 --- /dev/null +++ b/README.darwin @@ -0,0 +1,8 @@ +Create a symbolic link to Makefile.config_darwin: + + ln -s Makefile.config_darwin Makefile.config + +Make the file using the pd_darwin file: + + make -f Makefile.pd_darwin + diff --git a/abs/64k.pd b/abs/64k.pd new file mode 100644 index 0000000..7dc4933 --- /dev/null +++ b/abs/64k.pd @@ -0,0 +1,96 @@ +#N canvas 50 0 979 783 10; +#X obj 501 74 soundfiler; +#X obj 45 125 * 65536; +#X obj 91 649 +~; +#X obj 106 618 *~ 65536; +#X obj 289 309 metro 62.5; +#X obj 116 580 phasor~ 1; +#X obj 279 460 sel 0; +#X msg 279 527 0; +#X obj 561 181 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 +-1 -1; +#X obj 45 35 +; +#X obj 45 10 *; +#X obj 391 276 bpm; +#X msg 286 254 reset; +#X obj 202 164 count 32; +#X obj 478 -63 loadbang; +#X obj 265 55 mod 16; +#X obj 257 2 *; +#X obj 45 97 +; +#X obj 257 79 / 16; +#X text 41 -46 sample shuffle; +#X text 257 -44 beat shuffle; +#X obj 265 28 +; +#X obj 497 -16 symbol \$1; +#X obj 273 -23 inlet; +#X obj 498 99 / 65536; +#X obj 499 128 - 1; +#X obj 45 62 mod; +#X obj 61 -25 inlet; +#X obj 171 -25 inlet; +#X text 151 -46 sample offset; +#X obj 377 -23 inlet; +#X text 357 -44 beat offset; +#X obj 116 535 f; +#X obj 681 144 inlet; +#X text 688 123 bpm; +#X msg 500 43 read -resize -raw 0 1 2 l \$1 \$2; +#X obj 501 17 pack s s; +#X obj 571 -47 t b b; +#X obj 589 144 inlet; +#X text 589 123 reset; +#X obj 91 704 outlet~; +#X obj 580 -17 symbol \$0-table; +#X obj 795 95 table \$0-table; +#X obj 91 675 tabread4~ \$0-table; +#X text 608 612 reset; +#X obj 608 633 outlet; +#X obj 387 644 outlet; +#X text 387 623 counter; +#X connect 0 0 24 0; +#X connect 1 0 2 0; +#X connect 2 0 43 0; +#X connect 3 0 2 1; +#X connect 4 0 13 0; +#X connect 5 0 3 0; +#X connect 6 0 7 0; +#X connect 7 0 5 1; +#X connect 7 0 45 0; +#X connect 8 0 4 0; +#X connect 8 0 7 0; +#X connect 8 0 12 0; +#X connect 8 0 32 0; +#X connect 9 0 26 0; +#X connect 10 0 9 0; +#X connect 11 0 4 1; +#X connect 11 1 32 0; +#X connect 12 0 13 0; +#X connect 13 0 6 0; +#X connect 13 0 10 0; +#X connect 13 0 16 0; +#X connect 13 0 46 0; +#X connect 14 0 8 0; +#X connect 14 0 37 0; +#X connect 15 0 18 0; +#X connect 16 0 21 0; +#X connect 17 0 1 0; +#X connect 18 0 17 1; +#X connect 21 0 15 0; +#X connect 22 0 36 0; +#X connect 23 0 16 1; +#X connect 24 0 25 0; +#X connect 25 0 26 1; +#X connect 26 0 17 0; +#X connect 27 0 10 1; +#X connect 28 0 9 1; +#X connect 30 0 21 1; +#X connect 32 0 5 0; +#X connect 33 0 11 0; +#X connect 35 0 0 0; +#X connect 36 0 35 0; +#X connect 37 0 22 0; +#X connect 37 1 41 0; +#X connect 38 0 8 0; +#X connect 41 0 36 1; +#X connect 43 0 40 0; diff --git a/abs/bdft.pd b/abs/bdft.pd new file mode 100644 index 0000000..a979df4 --- /dev/null +++ b/abs/bdft.pd @@ -0,0 +1,16 @@ +#N canvas 520 402 300 195 10; +#X obj 106 9 inlet; +#X obj 169 11 inlet; +#X obj 121 90 pack \$1 0 0; +#X obj 136 150 outlet; +#X obj 167 41 t b f; +#X obj 110 41 t b f; +#X msg 100 125 timefreq \$1 \$2 \$3; +#X connect 0 0 5 0; +#X connect 1 0 4 0; +#X connect 2 0 6 0; +#X connect 4 0 2 0; +#X connect 4 1 2 1; +#X connect 5 0 2 0; +#X connect 5 1 2 2; +#X connect 6 0 3 0; diff --git a/abs/bdfts.pd b/abs/bdfts.pd new file mode 100644 index 0000000..1926d4f --- /dev/null +++ b/abs/bdfts.pd @@ -0,0 +1,18 @@ +#N canvas 520 402 300 195 10; +#X obj 106 9 inlet; +#X obj 169 11 inlet; +#X obj 121 90 pack \$1 0 0; +#X obj 136 150 outlet; +#X obj 166 60 t b f; +#X obj 109 60 t b f; +#X msg 100 125 timefreq \$1 \$2 \$3; +#X obj 170 36 * 1000; +#X connect 0 0 5 0; +#X connect 1 0 7 0; +#X connect 2 0 6 0; +#X connect 4 0 2 0; +#X connect 4 1 2 1; +#X connect 5 0 2 0; +#X connect 5 1 2 2; +#X connect 6 0 3 0; +#X connect 7 0 4 0; diff --git a/abs/bhip~.pd b/abs/bhip~.pd new file mode 100644 index 0000000..f7c925f --- /dev/null +++ b/abs/bhip~.pd @@ -0,0 +1,10 @@ +#N canvas 399 553 450 300 10; +#X obj 87 196 biquadseries~ \$1; +#X obj 81 134 inlet~; +#X obj 138 134 inlet; +#X obj 82 236 outlet~; +#X msg 107 162 butterHP \$1; +#X connect 0 0 3 0; +#X connect 1 0 0 0; +#X connect 2 0 4 0; +#X connect 4 0 0 0; diff --git a/abs/blop~.pd b/abs/blop~.pd new file mode 100644 index 0000000..5a32c98 --- /dev/null +++ b/abs/blop~.pd @@ -0,0 +1,10 @@ +#N canvas 399 553 450 300 10; +#X obj 87 196 biquadseries~ \$1; +#X msg 107 162 butterLP \$1; +#X obj 81 134 inlet~; +#X obj 138 134 inlet; +#X obj 82 236 outlet~; +#X connect 0 0 4 0; +#X connect 1 0 0 0; +#X connect 2 0 0 0; +#X connect 3 0 1 0; diff --git a/abs/bpm.pd b/abs/bpm.pd new file mode 100644 index 0000000..97d31e6 --- /dev/null +++ b/abs/bpm.pd @@ -0,0 +1,18 @@ +#N canvas 385 419 372 239 10; +#X obj 48 40 inlet; +#X obj 52 155 outlet; +#X obj 213 157 outlet; +#X text 30 185 quarter note time; +#X text 184 188 measure frequency; +#X text 46 18 bpm input; +#X obj 55 126 /; +#X obj 36 67 t b f; +#X obj 200 101 / 240; +#X msg 44 99 15000; +#X connect 0 0 7 0; +#X connect 0 0 8 0; +#X connect 6 0 1 0; +#X connect 7 0 9 0; +#X connect 7 1 6 1; +#X connect 8 0 2 0; +#X connect 9 0 6 0; diff --git a/abs/count.pd b/abs/count.pd new file mode 100644 index 0000000..44001b5 --- /dev/null +++ b/abs/count.pd @@ -0,0 +1,20 @@ +#N canvas 245 395 450 300 10; +#X obj 51 24 inlet; +#X obj 63 144 f 0; +#X obj 64 180 + 1; +#X obj 99 144 mod \$1; +#X msg 75 108 0; +#X obj 41 246 outlet; +#X obj 44 66 route reset; +#X msg 13 109 bang; +#X obj 161 20 inlet; +#X connect 0 0 6 0; +#X connect 1 0 2 0; +#X connect 1 0 5 0; +#X connect 2 0 3 0; +#X connect 3 0 1 1; +#X connect 4 0 1 1; +#X connect 6 0 4 0; +#X connect 6 1 7 0; +#X connect 7 0 1 0; +#X connect 8 0 3 1; diff --git a/abs/eadh~.pd b/abs/eadh~.pd new file mode 100644 index 0000000..0f00345 --- /dev/null +++ b/abs/eadh~.pd @@ -0,0 +1,22 @@ +#N canvas 127 436 262 228 10; +#X obj 34 27 inlet; +#X obj 84 27 inlet; +#X obj 133 27 inlet; +#X msg 44 108 start; +#X msg 92 107 stop; +#X obj 179 27 inlet; +#X msg 34 49 bang; +#X obj 44 187 outlet~; +#X text 14 6 trigger - attack - decay - hold; +#X obj 44 144 ear~ \$1 \$2; +#X obj 68 78 del \$3; +#X connect 0 0 6 0; +#X connect 1 0 9 1; +#X connect 2 0 9 2; +#X connect 3 0 9 0; +#X connect 4 0 9 0; +#X connect 5 0 10 1; +#X connect 6 0 3 0; +#X connect 6 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 4 0; diff --git a/abs/eadsrh~.pd b/abs/eadsrh~.pd new file mode 100644 index 0000000..a1c7da5 --- /dev/null +++ b/abs/eadsrh~.pd @@ -0,0 +1,27 @@ +#N canvas 127 436 524 279 10; +#X obj 34 27 inlet; +#X obj 84 27 inlet; +#X obj 133 27 inlet; +#X msg 44 108 start; +#X msg 306 113 stop; +#X obj 354 31 inlet; +#X msg 34 49 bang; +#X obj 44 187 outlet~; +#X text 13 6 trigger - attack - decay - sustain - release - duration +; +#X obj 44 144 eadsr~ \$1 \$2 \$3 \$4; +#X obj 306 84 del \$5; +#X obj 211 27 inlet; +#X obj 260 27 inlet; +#X connect 0 0 6 0; +#X connect 1 0 9 1; +#X connect 2 0 9 2; +#X connect 3 0 9 0; +#X connect 4 0 9 0; +#X connect 5 0 10 1; +#X connect 6 0 3 0; +#X connect 6 0 10 0; +#X connect 9 0 7 0; +#X connect 10 0 4 0; +#X connect 11 0 9 3; +#X connect 12 0 9 4; diff --git a/abs/fblock.pd b/abs/fblock.pd new file mode 100644 index 0000000..dbbf41e --- /dev/null +++ b/abs/fblock.pd @@ -0,0 +1,25 @@ +#N canvas 73 29 617 246 10; +#X obj 36 36 inlet; +#X obj 101 35 inlet; +#X obj 42 196 outlet; +#X obj 104 83 samplerate~; +#X obj 101 115 / \$1; +#X obj 59 158 +; +#X obj 103 144 *; +#X obj 103 59 t b b f; +#X text 200 35 fblock: compute block relative frequencies; +#X text 200 79 right inlet is also "active"; +#X text 201 119 main usage is to compute block synchronous frequencies +; +#X text 200 134 for spectral domain processing; +#X text 201 49 out = left + right * (sys samplerate / sys blocksize) +; +#X connect 0 0 5 0; +#X connect 1 0 7 0; +#X connect 3 0 4 0; +#X connect 4 0 6 0; +#X connect 5 0 2 0; +#X connect 6 0 5 1; +#X connect 7 0 5 0; +#X connect 7 1 3 0; +#X connect 7 2 6 1; diff --git a/abs/inv.pd b/abs/inv.pd new file mode 100644 index 0000000..b465178 --- /dev/null +++ b/abs/inv.pd @@ -0,0 +1,8 @@ +#N canvas 329 434 450 300 10; +#X obj 68 45 inlet; +#X obj 67 130 outlet; +#X obj 68 71 + 1; +#X obj 68 96 mod 2; +#X connect 0 0 2 0; +#X connect 2 0 3 0; +#X connect 3 0 1 0; diff --git a/abs/pdynwav~.pd b/abs/pdynwav~.pd new file mode 100644 index 0000000..a4da3f1 --- /dev/null +++ b/abs/pdynwav~.pd @@ -0,0 +1,10 @@ +#N canvas 164 313 194 151 10; +#X obj 30 24 inlet~; +#X obj 110 23 inlet; +#X obj 30 98 outlet~; +#X obj 110 49 phasor~; +#X obj 30 67 dynwav~; +#X connect 0 0 4 0; +#X connect 1 0 3 0; +#X connect 3 0 4 1; +#X connect 4 0 2 0; diff --git a/abs/scale7.pd b/abs/scale7.pd new file mode 100644 index 0000000..b4f0935 --- /dev/null +++ b/abs/scale7.pd @@ -0,0 +1,40 @@ +#N canvas 647 521 450 373 10; +#X obj 152 175 select 0 1 2 3 4 5 6; +#X obj 224 115 unpack 0 0 0 0 0 0 0; +#X obj 225 59 inlet; +#X obj 57 51 inlet; +#X obj 154 97 mod 7; +#X text 219 37 scale input; +#X text 48 29 note input; +#X obj 224 287 outlet; +#X obj 153 220 f; +#X obj 185 221 f; +#X obj 217 221 f; +#X obj 248 220 f; +#X obj 280 218 f; +#X obj 311 214 f; +#X obj 343 212 f; +#X connect 0 0 8 0; +#X connect 0 1 9 0; +#X connect 0 2 10 0; +#X connect 0 3 11 0; +#X connect 0 4 12 0; +#X connect 0 5 13 0; +#X connect 0 6 14 0; +#X connect 1 0 8 1; +#X connect 1 1 9 1; +#X connect 1 2 10 1; +#X connect 1 3 11 1; +#X connect 1 4 12 1; +#X connect 1 5 13 1; +#X connect 1 6 14 1; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 0 0; +#X connect 8 0 7 0; +#X connect 9 0 7 0; +#X connect 10 0 7 0; +#X connect 11 0 7 0; +#X connect 12 0 7 0; +#X connect 13 0 7 0; +#X connect 14 0 7 0; diff --git a/abs/vols~.pd b/abs/vols~.pd new file mode 100644 index 0000000..aa87a8d --- /dev/null +++ b/abs/vols~.pd @@ -0,0 +1,24 @@ +#N canvas 441 433 450 300 10; +#X obj 68 21 inlet~; +#X obj 122 22 inlet; +#X obj 80 104 *~; +#X obj 77 141 outlet~; +#X obj 116 42 dbtorms; +#X obj 114 92 line~; +#X msg 112 66 \$1 5; +#X obj 215 34 loadbang; +#X obj 218 66 f \$1; +#X obj 6 22 inlet~; +#X obj 18 105 *~; +#X obj 15 142 outlet~; +#X connect 0 0 2 0; +#X connect 1 0 4 0; +#X connect 2 0 3 0; +#X connect 4 0 6 0; +#X connect 5 0 2 1; +#X connect 5 0 10 1; +#X connect 6 0 5 0; +#X connect 7 0 8 0; +#X connect 8 0 4 0; +#X connect 9 0 10 0; +#X connect 10 0 11 0; diff --git a/abs/vol~.pd b/abs/vol~.pd new file mode 100644 index 0000000..2fcc995 --- /dev/null +++ b/abs/vol~.pd @@ -0,0 +1,18 @@ +#N canvas 441 433 450 300 10; +#X obj 68 21 inlet~; +#X obj 122 22 inlet; +#X obj 80 104 *~; +#X obj 77 141 outlet~; +#X obj 116 42 dbtorms; +#X obj 114 92 line~; +#X msg 112 66 \$1 5; +#X obj 215 34 loadbang; +#X obj 218 66 f \$1; +#X connect 0 0 2 0; +#X connect 1 0 4 0; +#X connect 2 0 3 0; +#X connect 4 0 6 0; +#X connect 5 0 2 1; +#X connect 6 0 5 0; +#X connect 7 0 8 0; +#X connect 8 0 4 0; diff --git a/doc/bdiag~.pd b/doc/bdiag~.pd new file mode 100644 index 0000000..f5e835f --- /dev/null +++ b/doc/bdiag~.pd @@ -0,0 +1,97 @@ +#N canvas 34 203 724 407 10; +#X obj 34 45 metro; +#X msg 34 20 bang; +#X floatatom 76 20 5 0 0; +#X obj 34 327 dist~ 1; +#X obj 24 359 dac~; +#N canvas 731 115 262 403 systemparams 1; +#X floatatom 81 47 5 0 0; +#X floatatom 125 47 5 0 0; +#X floatatom 81 74 5 0 0; +#X floatatom 125 74 5 0 0; +#X floatatom 81 102 5 0 0; +#X floatatom 125 102 5 0 0; +#X floatatom 81 129 5 0 0; +#X floatatom 125 129 5 0 0; +#X floatatom 81 157 5 0 0; +#X floatatom 125 157 5 0 0; +#X floatatom 81 184 5 0 0; +#X floatatom 125 184 5 0 0; +#X floatatom 81 212 5 0 0; +#X floatatom 125 212 5 0 0; +#X floatatom 81 239 5 0 0; +#X floatatom 125 239 5 0 0; +#X obj 28 65 bdft 1; +#X obj 27 93 bdft 2; +#X obj 28 120 bdft 3; +#X obj 28 175 bdft 7; +#X obj 28 202 bdft 11; +#X obj 28 230 bdft 17; +#X obj 28 257 bdft 30; +#X obj 28 319 outlet; +#X text 20 23 frequency detune and damping; +#X text 49 283 bdft argument = harmonic; +#X obj 28 147 bdft 5; +#X connect 0 0 16 0; +#X connect 1 0 16 1; +#X connect 2 0 17 0; +#X connect 3 0 17 1; +#X connect 4 0 18 0; +#X connect 5 0 18 1; +#X connect 6 0 26 0; +#X connect 7 0 26 1; +#X connect 8 0 19 0; +#X connect 9 0 19 1; +#X connect 10 0 20 0; +#X connect 11 0 20 1; +#X connect 12 0 21 0; +#X connect 13 0 21 1; +#X connect 14 0 22 0; +#X connect 15 0 22 1; +#X connect 16 0 23 0; +#X connect 17 0 23 0; +#X connect 18 0 23 0; +#X connect 19 0 23 0; +#X connect 20 0 23 0; +#X connect 21 0 23 0; +#X connect 22 0 23 0; +#X connect 26 0 23 0; +#X restore 89 76 pd systemparams; +#X obj 34 93 bdiag~; +#X obj 34 129 ibfft~; +#X obj 34 232 dynwav~; +#X obj 34 283 vol~; +#X floatatom 57 257 5 0 0; +#X floatatom 78 168 5 0 0; +#X obj 78 196 phasor~; +#X text 258 168 the [eig ] message sets the eigenvalue +for the corresponding block. there are n/2 blocks \, with n the dsp +blocksize.; +#X text 259 223 you can use [timefreq <60dB time> ] +for a more appropriate initialization of the eigenvalues using decay +time in milliseconds and oscillation frequency in Hz.; +#X text 256 18 bdiag~: parallel block diagonal state space model (parallel +2d rotations) see bdiag.c for more info. the state equations for one +block are:; +#X text 300 70 state1 = real * state1 - imag * state2 + input1; +#X text 300 85 state2 = real * state2 + imag * state1 + input2; +#X text 258 121 this module is intended to "filter" spectral data produced +by bfft or other short time spectral transforms like dwt.; +#X text 256 279 [bang] or [random] set the state vector to a random +value. [reset] sets it to 0; +#X text 256 327 this patch uses of bdiag~ \, ibfft~ and dynwav~ to +build a 32 voice harmonic modal synth \, with the state excited with +white noise on bang.; +#X connect 0 0 6 0; +#X connect 1 0 0 0; +#X connect 2 0 0 1; +#X connect 3 0 4 0; +#X connect 3 0 4 1; +#X connect 5 0 6 0; +#X connect 6 0 7 0; +#X connect 7 0 8 0; +#X connect 8 0 9 0; +#X connect 9 0 3 0; +#X connect 10 0 9 1; +#X connect 11 0 12 0; +#X connect 12 0 8 1; diff --git a/doc/bfft~.pd b/doc/bfft~.pd new file mode 100644 index 0000000..62507f9 --- /dev/null +++ b/doc/bfft~.pd @@ -0,0 +1,18 @@ +#N canvas 488 64 480 309 10; +#X obj 17 62 osc~ 500; +#X floatatom 17 -11 5 0 0; +#X obj 17 23 * 187.5; +#X obj 17 180 tabsend~ scope; +#N canvas 0 0 450 300 graph2 0; +#X array scope 64 float 0; +#X coords 0 1 63 -1 200 140 1; +#X restore 233 16 graph; +#X obj 18 113 bfft~; +#X obj 71 112 ibfft~; +#X text 12 -60 spectrum: (DC \, NY) \, (R1 \, I1) \, ...(RN-1 \, IN-1) +; +#X text 13 -74 like fft~ but normalized and; +#X connect 0 0 5 0; +#X connect 1 0 2 0; +#X connect 2 0 0 0; +#X connect 5 0 3 0; diff --git a/doc/biquadseries~.pd b/doc/biquadseries~.pd new file mode 100644 index 0000000..89d7ce0 --- /dev/null +++ b/doc/biquadseries~.pd @@ -0,0 +1,22 @@ +#N canvas 389 207 533 299 10; +#X obj 37 246 dac~; +#X msg 81 132 butterLP \$1; +#X msg 173 131 butterHP \$1; +#X floatatom 81 105 5 0 0; +#X floatatom 173 104 5 0 0; +#X obj 48 78 *~; +#X floatatom 82 55 5 0 0; +#X obj 48 35 noise~; +#X text 269 132 butterworth lowpass and highpass; +#X text 181 178 creation argument: number of 2nd order sections; +#X obj 48 178 biquadseries~ 4; +#X text 173 22 biquadseries~ second order iir series section; +#X connect 1 0 10 0; +#X connect 2 0 10 0; +#X connect 3 0 1 0; +#X connect 4 0 2 0; +#X connect 5 0 10 0; +#X connect 6 0 5 1; +#X connect 7 0 5 0; +#X connect 10 0 0 0; +#X connect 10 0 0 1; diff --git a/doc/cheby~.pd b/doc/cheby~.pd new file mode 100644 index 0000000..30bb77e --- /dev/null +++ b/doc/cheby~.pd @@ -0,0 +1,43 @@ +#N canvas 262 87 566 348 10; +#X obj 130 230 cheby~ 4; +#X msg 147 149 coef 1 \$1; +#X floatatom 147 93 5 0 0; +#X obj 147 117 dbtorms; +#X obj 124 313 dac~; +#X obj 130 281 vol~; +#X floatatom 156 261 5 0 0; +#X obj 40 113 osc~; +#X floatatom 40 88 5 0 0; +#X floatatom 226 94 5 0 0; +#X obj 226 118 dbtorms; +#X floatatom 305 94 5 0 0; +#X obj 305 118 dbtorms; +#X floatatom 384 93 5 0 0; +#X obj 384 117 dbtorms; +#X msg 226 150 coef 2 \$1; +#X msg 305 150 coef 3 \$1; +#X msg 384 150 coef 4 \$1; +#X text 96 3 chebychev waveshaper; +#X text 207 229 creation argument: order of polynomial; +#X text 135 47 coef n x sets coefficient of nth order cheby poly to +x; +#X text 135 60 if the input is a sine wave \, these are the amplitudes +for the harmonics.; +#X connect 0 0 5 0; +#X connect 1 0 0 0; +#X connect 2 0 3 0; +#X connect 3 0 1 0; +#X connect 5 0 4 1; +#X connect 5 0 4 0; +#X connect 6 0 5 1; +#X connect 7 0 0 0; +#X connect 8 0 7 0; +#X connect 9 0 10 0; +#X connect 10 0 15 0; +#X connect 11 0 12 0; +#X connect 12 0 16 0; +#X connect 13 0 14 0; +#X connect 14 0 17 0; +#X connect 15 0 0 0; +#X connect 16 0 0 0; +#X connect 17 0 0 0; diff --git a/doc/dist~.pd b/doc/dist~.pd new file mode 100644 index 0000000..3533471 --- /dev/null +++ b/doc/dist~.pd @@ -0,0 +1,17 @@ +#N canvas 497 336 450 300 10; +#X text 156 35 dist~ waveshaper; +#X text 154 53 creation argument: type (see dist.c); +#X floatatom 136 120 5 0 0; +#X obj 64 121 osc~; +#X obj 66 206 dac~; +#X floatatom 63 84 5 0 0; +#X text 189 119 right inlet: pre gain; +#X obj 148 95 hsl 128 15 0.5 20 0 0 empty empty empty -2 -6 32 8 -262144 +-1 -1 7000 1; +#X obj 64 157 dist~ 1; +#X connect 2 0 8 1; +#X connect 3 0 8 0; +#X connect 5 0 3 0; +#X connect 7 0 2 0; +#X connect 8 0 4 0; +#X connect 8 0 4 1; diff --git a/doc/dwt~.pd b/doc/dwt~.pd new file mode 100644 index 0000000..52986e1 --- /dev/null +++ b/doc/dwt~.pd @@ -0,0 +1,72 @@ +#N canvas 47 99 994 611 10; +#X obj 17 62 osc~ 500; +#X msg 83 -115 predict 0.5 0.5 \, update 0.25 0.25; +#X msg 83 -76 predict -0.0625 0.5625 0.5625 -0.0625 \, update -0.03125 +0.28125 0.28125 -0.03125; +#X floatatom 24 10 5 0 0; +#X msg 201 144 mask -1 9 9 -1; +#X obj 67 279 r coef; +#X obj 82 -30 s coef; +#X obj 195 337 s coef; +#X msg 201 167 mask 3 -25 150 150 -25 3; +#X msg 216 189 mask -5 49 -245 1225 1225 -245 49 -5; +#X obj 196 39 pack; +#X floatatom 222 8 5 0 0; +#X floatatom 166 -4 5 0 0; +#X msg 171 64 coef \$1 \$2; +#X msg 191 120 mask 1 1; +#X msg 228 212 mask 35 -405 2268 -8820 39690 39690 -8820 2268 -405 +35; +#X msg 244 246 mask -63 847 -5445 22869 -76230 320166 320166 -76230 +22869 -5445 847 -63; +#X msg 245 306 predict 1 0 \, update 0 0.5; +#X obj 36 31 * 187.5; +#X obj 26 341 dwt~ 1; +#X obj 80 343 idwt~ 1; +#X msg 469 376 mask 0 0 0 35 140 -70 28 -5; +#X msg 469 352 mask 7 -45 126 -210 315 63 0 0 0 0; +#X msg 469 328 mask -21 154 -495 924 -1155 1386 231 0 0 0 0 0; +#X obj 26 443 tabsend~ scope; +#N canvas 0 0 450 300 graph2 0; +#X array scope 256 float 0; +#X coords 0 1 255 -1 200 140 1; +#X restore 718 -98 graph; +#X text 61 165 print out coefs; +#X msg 100 184 print; +#X text 315 -24 dwt~ performs a discrete wavelet transform; +#X text 315 -10 idwt~ performs the inverse transform; +#X text 309 105 mask sets the predict mask \, and uses the corresponding +update mask; +#X text 266 63 coef sets half of a symmetric predict mask; +#X text 243 286 predict and update masks can be specified explicitly +; +#X text 433 307 haar wavelet; +#X msg 672 189 even \$1; +#X floatatom 672 167 5 0 0; +#X text 570 134 even is the order symmetric interpolating biorthogonal +wavelet with n vanishing moments.; +#X connect 0 0 19 0; +#X connect 1 0 6 0; +#X connect 2 0 6 0; +#X connect 3 0 18 0; +#X connect 4 0 7 0; +#X connect 5 0 20 0; +#X connect 5 0 19 0; +#X connect 8 0 7 0; +#X connect 9 0 7 0; +#X connect 10 0 13 0; +#X connect 11 0 10 1; +#X connect 12 0 10 0; +#X connect 13 0 7 0; +#X connect 14 0 7 0; +#X connect 15 0 7 0; +#X connect 16 0 7 0; +#X connect 17 0 7 0; +#X connect 18 0 0 0; +#X connect 19 0 24 0; +#X connect 21 0 7 0; +#X connect 22 0 7 0; +#X connect 23 0 7 0; +#X connect 27 0 7 0; +#X connect 34 0 7 0; +#X connect 35 0 34 0; diff --git a/doc/dynwav~.pd b/doc/dynwav~.pd new file mode 100644 index 0000000..59f86bd --- /dev/null +++ b/doc/dynwav~.pd @@ -0,0 +1,25 @@ +#N canvas 193 151 450 300 10; +#X text 96 6 dynwav~: dynamic wavetable oscillator; +#X obj 61 98 osc~; +#X floatatom 60 56 5 0 0; +#X obj 60 151 dynwav~; +#X obj 60 214 vol~; +#X floatatom 85 190 5 0 0; +#X obj 50 256 dac~; +#X obj 172 105 phasor~; +#X floatatom 172 80 5 0 0; +#X obj 107 54 bang~; +#X text 171 22 (scanned synthesis); +#X text 165 143 left inlet's dsp block = wavetable; +#X msg 107 78 0.25; +#X text 242 157 right inlet = phase (0-1); +#X connect 1 0 3 0; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 6 1; +#X connect 4 0 6 0; +#X connect 5 0 4 1; +#X connect 7 0 3 1; +#X connect 8 0 7 0; +#X connect 9 0 12 0; +#X connect 12 0 1 1; diff --git a/doc/eadsr~.pd b/doc/eadsr~.pd new file mode 100644 index 0000000..220ea54 --- /dev/null +++ b/doc/eadsr~.pd @@ -0,0 +1,41 @@ +#N canvas 478 386 580 306 10; +#X obj 89 227 *~; +#X obj 105 40 metro; +#X obj 105 12 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 +-1; +#X obj 26 203 osc~; +#X floatatom 26 171 5 0 0; +#X floatatom 135 12 5 0 0; +#X floatatom 209 117 5 0 0; +#X floatatom 208 139 5 0 0; +#X obj 77 265 dac~; +#X msg 58 12 stop; +#X msg 26 124 start; +#X msg 71 123 stop; +#X obj 105 77 del; +#X floatatom 159 50 5 0 0; +#X obj 105 197 eadsr~ 0 0; +#X text 191 81 exponential attack/decay/sustain/release envelope; +#X text 265 125 60db attack and decay time; +#X text 265 182 60db attack and decay time; +#X floatatom 209 160 5 0 0; +#X floatatom 209 180 5 0 0; +#X text 264 159 sustain level; +#X connect 0 0 8 0; +#X connect 0 0 8 1; +#X connect 1 0 10 0; +#X connect 1 0 12 0; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X connect 4 0 3 0; +#X connect 5 0 1 1; +#X connect 6 0 14 1; +#X connect 7 0 14 2; +#X connect 9 0 1 0; +#X connect 10 0 14 0; +#X connect 11 0 14 0; +#X connect 12 0 11 0; +#X connect 13 0 12 1; +#X connect 14 0 0 1; +#X connect 18 0 14 3; +#X connect 19 0 14 4; diff --git a/doc/ead~.pd b/doc/ead~.pd new file mode 100644 index 0000000..9d9bc5f --- /dev/null +++ b/doc/ead~.pd @@ -0,0 +1,29 @@ +#N canvas 478 386 459 306 10; +#X obj 105 111 ead~ 0 0; +#X obj 89 179 *~; +#X obj 105 40 metro; +#X obj 105 12 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 +-1; +#X obj 41 144 osc~; +#X floatatom 41 112 5 0 0; +#X floatatom 135 12 5 0 0; +#X floatatom 130 64 5 0 0; +#X floatatom 156 86 5 0 0; +#X obj 77 217 dac~; +#X text 202 71 60db attack and decay time; +#X obj 70 76 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 +-1; +#X msg 58 12 stop; +#X text 201 51 exponential attack/decay envelope; +#X connect 0 0 1 1; +#X connect 1 0 9 0; +#X connect 1 0 9 1; +#X connect 2 0 0 0; +#X connect 3 0 2 0; +#X connect 4 0 1 0; +#X connect 5 0 4 0; +#X connect 6 0 2 1; +#X connect 7 0 0 1; +#X connect 8 0 0 2; +#X connect 11 0 0 0; +#X connect 12 0 2 0; diff --git a/doc/ear~.pd b/doc/ear~.pd new file mode 100644 index 0000000..8527a12 --- /dev/null +++ b/doc/ear~.pd @@ -0,0 +1,35 @@ +#N canvas 478 386 459 306 10; +#X obj 89 227 *~; +#X obj 105 40 metro; +#X obj 105 12 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 +-1; +#X obj 41 192 osc~; +#X floatatom 41 160 5 0 0; +#X floatatom 135 12 5 0 0; +#X floatatom 130 112 5 0 0; +#X floatatom 157 134 5 0 0; +#X obj 77 265 dac~; +#X msg 58 12 stop; +#X msg 26 124 start; +#X msg 71 123 stop; +#X obj 105 159 ear~ 0 0; +#X obj 105 77 del; +#X floatatom 159 50 5 0 0; +#X text 201 99 exponential attack/release envelope; +#X text 202 119 60db attack and release time; +#X connect 0 0 8 0; +#X connect 0 0 8 1; +#X connect 1 0 10 0; +#X connect 1 0 13 0; +#X connect 2 0 1 0; +#X connect 3 0 0 0; +#X connect 4 0 3 0; +#X connect 5 0 1 1; +#X connect 6 0 12 1; +#X connect 7 0 12 2; +#X connect 9 0 1 0; +#X connect 10 0 12 0; +#X connect 11 0 12 0; +#X connect 12 0 0 1; +#X connect 13 0 11 0; +#X connect 14 0 13 1; diff --git a/doc/examples/xfmdelay.pd b/doc/examples/xfmdelay.pd new file mode 100644 index 0000000..078733a --- /dev/null +++ b/doc/examples/xfmdelay.pd @@ -0,0 +1,106 @@ +#N canvas 25 206 921 653 10; +#X obj 289 329 xfm~ 0 0 0 0; +#X obj 279 280 *~; +#X obj 398 233 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 +-262144 -1 -1 862.744 256; +#X obj 306 279 *~; +#X obj 398 250 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 +-262144 -1 -1 795.103 256; +#X obj 332 279 *~; +#X obj 399 266 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 +-262144 -1 -1 23.7527 256; +#X obj 359 278 *~; +#X obj 398 284 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 +-262144 -1 -1 224.294 256; +#X obj 251 170 xfm~ 0 0 0 0; +#X obj 392 111 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 +-262144 -1 -1 703.454 256; +#X obj 392 132 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 +-262144 -1 -1 675.315 256; +#X obj 304 138 *~; +#X obj 393 148 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 +-262144 -1 -1 51.5902 256; +#X obj 331 137 *~; +#X obj 392 166 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 +-262144 -1 -1 49.5265 256; +#X obj 191 403 vols~; +#X floatatom 233 374 5 0 0; +#X obj 195 525 dac~; +#X obj 274 51 vd~ del1; +#X obj 274 24 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 +-262144 -1 -1 73 256; +#X obj 339 23 nbx 5 14 -1e+37 1e+37 0 1 empty empty empty 0 -6 0 10 +-262144 -1 -1 339 256; +#X obj 339 50 vd~ del2; +#X obj 296 393 delwrite~ del1 1000; +#X obj 448 393 delwrite~ del2 1000; +#X msg 136 125 type 0; +#X msg 137 146 type 1; +#X obj 464 110 hsl 300 15 0.1 20000 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 21700 1; +#X obj 464 130 hsl 300 15 0.1 20000 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 21600 1; +#X obj 463 150 hsl 300 15 0.1 20000 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 15300 1; +#X obj 464 168 hsl 300 15 0.1 20000 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 15200 1; +#X obj 465 232 hsl 300 15 0.1 20000 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 22200 1; +#X obj 465 252 hsl 300 15 0.1 20000 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 22000 1; +#X obj 464 271 hsl 300 15 0.1 20000 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 13400 1; +#X obj 465 289 hsl 300 15 0.1 20000 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 18900 1; +#X text 479 29 2 xfm oscillators coupled by 2 delay lines; +#X obj 188 475 *~; +#X obj 217 474 *~; +#X obj 270 458 osc~; +#X obj 269 433 hsl 300 15 0.1 20000 1 1 empty empty empty -2 -6 0 8 +-262144 -1 -1 18900 1; +#X connect 0 0 23 0; +#X connect 0 1 24 0; +#X connect 1 0 0 0; +#X connect 2 0 1 1; +#X connect 3 0 0 1; +#X connect 4 0 3 1; +#X connect 5 0 0 2; +#X connect 6 0 5 1; +#X connect 7 0 0 3; +#X connect 8 0 7 1; +#X connect 9 0 3 0; +#X connect 9 0 5 0; +#X connect 9 0 16 0; +#X connect 9 1 1 0; +#X connect 9 1 7 0; +#X connect 9 1 16 1; +#X connect 10 0 9 0; +#X connect 11 0 9 1; +#X connect 12 0 9 2; +#X connect 13 0 12 1; +#X connect 14 0 9 3; +#X connect 15 0 14 1; +#X connect 16 0 36 0; +#X connect 16 1 37 0; +#X connect 17 0 16 2; +#X connect 19 0 12 0; +#X connect 20 0 19 0; +#X connect 21 0 22 0; +#X connect 22 0 14 0; +#X connect 25 0 9 0; +#X connect 25 0 0 0; +#X connect 26 0 9 0; +#X connect 26 0 0 0; +#X connect 27 0 10 0; +#X connect 28 0 11 0; +#X connect 29 0 13 0; +#X connect 30 0 15 0; +#X connect 31 0 2 0; +#X connect 32 0 4 0; +#X connect 33 0 6 0; +#X connect 34 0 8 0; +#X connect 36 0 18 0; +#X connect 37 0 18 1; +#X connect 38 0 37 1; +#X connect 38 0 36 1; +#X connect 39 0 38 0; diff --git a/doc/ffpoly.pd b/doc/ffpoly.pd new file mode 100644 index 0000000..7ec8886 --- /dev/null +++ b/doc/ffpoly.pd @@ -0,0 +1,35 @@ +#N canvas 372 77 515 425 10; +#X text 85 14 ffpoly - compute a finite field polynomial; +#X msg 103 89 coef 0 \$1; +#X floatatom 103 65 5 0 0; +#X floatatom 181 65 5 0 0; +#X floatatom 257 65 5 0 0; +#X floatatom 334 64 5 0 0; +#X msg 181 89 coef 1 \$1; +#X msg 257 89 coef 2 \$1; +#X msg 334 89 coef 3 \$1; +#X floatatom 38 106 5 0 0; +#X obj 38 350 ffpoly 3 5; +#X text 125 350 creation args: ; +#X floatatom 38 384 5 0 0; +#X msg 334 150 order \$1; +#X floatatom 334 125 5 0 0; +#X text 332 174 finite field order; +#X floatatom 335 217 5 0 0; +#X msg 335 242 coefficients \$1; +#X text 271 279 set coefs in packed form; +#X text 203 292 digit representation in base = field order; +#X connect 1 0 10 0; +#X connect 2 0 1 0; +#X connect 3 0 6 0; +#X connect 4 0 7 0; +#X connect 5 0 8 0; +#X connect 6 0 10 0; +#X connect 7 0 10 0; +#X connect 8 0 10 0; +#X connect 9 0 10 0; +#X connect 10 0 12 0; +#X connect 13 0 10 0; +#X connect 14 0 13 0; +#X connect 16 0 17 0; +#X connect 17 0 10 0; diff --git a/doc/filterortho~.pd b/doc/filterortho~.pd new file mode 100644 index 0000000..e120101 --- /dev/null +++ b/doc/filterortho~.pd @@ -0,0 +1,58 @@ +#N canvas 634 361 578 534 10; +#X obj 146 452 dac~; +#X floatatom 255 83 7 0 0; +#X floatatom 194 83 7 0 0; +#X obj 158 405 filterortho~; +#X obj 194 123 t b f; +#X floatatom 29 31 5 0 0; +#X obj 13 9 noise~; +#X floatatom 133 83 7 0 0; +#X obj 150 123 t b f; +#X obj 13 52 *~; +#X text 333 9 orthogonal biquad object; +#X obj 157 330 pack s 0 0 0; +#X obj 237 122 t b f; +#X text 137 61 freq; +#X text 213 61 Q; +#X msg 335 126 setEQ; +#X msg 335 150 setLP; +#X msg 158 363 \$1 \$2 \$3 \$4; +#X msg 336 175 setHP; +#X msg 336 201 setBP; +#X msg 336 225 setBR; +#X msg 336 251 setHS; +#X msg 337 275 setLS; +#X msg 338 299 setAP; +#X text 391 127 parametric equalizer; +#X text 390 150 lowpass; +#X text 391 175 highpass; +#X text 391 201 bandpass; +#X text 391 224 bandreject; +#X text 390 252 highshelf; +#X text 390 277 lowshelf; +#X text 391 300 allpass; +#X text 265 62 gain (only for EQ \, LS \, HS); +#X connect 1 0 12 0; +#X connect 2 0 4 0; +#X connect 3 0 0 0; +#X connect 3 0 0 1; +#X connect 4 0 11 0; +#X connect 4 1 11 2; +#X connect 5 0 9 1; +#X connect 6 0 9 0; +#X connect 7 0 8 0; +#X connect 8 0 11 0; +#X connect 8 1 11 1; +#X connect 9 0 3 0; +#X connect 11 0 17 0; +#X connect 12 0 11 0; +#X connect 12 1 11 3; +#X connect 15 0 11 0; +#X connect 16 0 11 0; +#X connect 17 0 3 0; +#X connect 18 0 11 0; +#X connect 19 0 11 0; +#X connect 20 0 11 0; +#X connect 21 0 11 0; +#X connect 22 0 11 0; +#X connect 23 0 11 0; diff --git a/doc/fwarp.pd b/doc/fwarp.pd new file mode 100644 index 0000000..d43a5a3 --- /dev/null +++ b/doc/fwarp.pd @@ -0,0 +1,37 @@ +#N canvas 403 309 522 388 10; +#X obj 18 85 fwarp; +#X floatatom 18 53 5 0 0; +#X floatatom 18 121 7 0 0; +#X text 112 49 fwarp - warps a frequency using the formula; +#X obj 173 261 xfm~ 0 0 0 0; +#X obj 173 218 fwarp; +#X floatatom 173 186 5 0 0; +#X obj 117 260 osc~; +#X obj 152 324 vol~; +#X obj 152 350 dac~; +#X floatatom 212 298 5 0 0; +#X obj 351 263 xfm~ 0 0 0 0; +#X floatatom 351 188 5 0 0; +#X obj 295 262 osc~; +#X obj 330 326 vol~; +#X obj 330 352 dac~; +#X floatatom 390 300 5 0 0; +#X text 132 126 example: xfm~ uses warped frequencies; +#X text 112 67 out = tan(2pi*in/sr) * (sr/2pi); +#X connect 0 0 2 0; +#X connect 1 0 0 0; +#X connect 4 0 8 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 6 0 7 0; +#X connect 7 0 8 0; +#X connect 8 0 9 0; +#X connect 8 0 9 1; +#X connect 10 0 8 1; +#X connect 11 0 14 0; +#X connect 12 0 13 0; +#X connect 12 0 11 0; +#X connect 13 0 14 0; +#X connect 14 0 15 0; +#X connect 14 0 15 1; +#X connect 16 0 14 1; diff --git a/doc/lattice~.pd b/doc/lattice~.pd new file mode 100644 index 0000000..4545470 --- /dev/null +++ b/doc/lattice~.pd @@ -0,0 +1,63 @@ +#N canvas 338 162 527 557 10; +#X obj 57 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144 +-1 -1 12100 1; +#X msg 57 223 rc 0 \$1; +#X obj 88 -78 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144 +-1 -1 7150 1; +#X obj 119 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144 +-1 -1 5150 1; +#X obj 149 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144 +-1 -1 8100 1; +#X obj 179 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144 +-1 -1 11850 1; +#X obj 210 -78 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144 +-1 -1 15850 1; +#X obj 241 -78 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144 +-1 -1 17550 1; +#X obj 271 -77 vsl 15 250 -1 1 0 1 empty empty empty 20 8 32 8 -262144 +-1 -1 15050 1; +#X msg 86 199 rc 1 \$1; +#X msg 118 224 rc 2 \$1; +#X msg 147 200 rc 3 \$1; +#X msg 179 223 rc 4 \$1; +#X msg 208 199 rc 5 \$1; +#X msg 240 224 rc 6 \$1; +#X msg 269 200 rc 7 \$1; +#X floatatom 154 -125 5 -1 1; +#X obj 64 302 lattice~ 8; +#X obj 6 254 noise~; +#X obj 63 363 vol~; +#X obj 63 397 dac~; +#X floatatom 85 333 5 0 0; +#X text 159 298 lattice~ a lattice filter; +#X text 139 333 [rc ] sets reflection coefficient; +#X text 159 311 creation argument sets order; +#X connect 0 0 1 0; +#X connect 1 0 17 0; +#X connect 2 0 9 0; +#X connect 3 0 10 0; +#X connect 4 0 11 0; +#X connect 5 0 12 0; +#X connect 6 0 13 0; +#X connect 7 0 14 0; +#X connect 8 0 15 0; +#X connect 9 0 17 0; +#X connect 10 0 17 0; +#X connect 11 0 17 0; +#X connect 12 0 17 0; +#X connect 13 0 17 0; +#X connect 14 0 17 0; +#X connect 15 0 17 0; +#X connect 16 0 0 0; +#X connect 16 0 2 0; +#X connect 16 0 3 0; +#X connect 16 0 4 0; +#X connect 16 0 5 0; +#X connect 16 0 6 0; +#X connect 16 0 7 0; +#X connect 16 0 8 0; +#X connect 17 0 19 0; +#X connect 18 0 17 0; +#X connect 19 0 20 1; +#X connect 19 0 20 0; +#X connect 21 0 19 1; diff --git a/doc/matrix~.pd b/doc/matrix~.pd new file mode 100644 index 0000000..5a6e9d5 --- /dev/null +++ b/doc/matrix~.pd @@ -0,0 +1,10 @@ +#N canvas 523 376 560 300 10; +#X obj 30 165 matrix~; +#X text 29 23 matrix multiplies a signal block with an arbitrary matrix +; +#X msg 69 127 load matrix.bin; +#X text 27 39 added for completeness. mainly intended for spectral +transfos; +#X text 26 73 the file format is binary floating point \, column encoded. +; +#X connect 2 0 0 0; diff --git a/doc/permut~.pd b/doc/permut~.pd new file mode 100644 index 0000000..c8aa822 --- /dev/null +++ b/doc/permut~.pd @@ -0,0 +1,19 @@ +#N canvas 523 376 560 300 10; +#X text 29 10 permut~ performs a random permutation on a signal block +; +#X text 30 27 mainly intended for shuffling spectral data (dynwav) +; +#X obj 73 127 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 -1 +-1; +#X msg 96 126 random; +#X text 154 124 bang or random create a new random permutation; +#X obj 30 91 osc~; +#X obj 30 166 permut~; +#X obj 29 210 dac~; +#X floatatom 30 61 5 0 0; +#X connect 2 0 6 0; +#X connect 3 0 6 0; +#X connect 5 0 6 0; +#X connect 6 0 7 0; +#X connect 6 0 7 1; +#X connect 8 0 5 0; diff --git a/doc/qmult~.pd b/doc/qmult~.pd new file mode 100644 index 0000000..674df3e --- /dev/null +++ b/doc/qmult~.pd @@ -0,0 +1,63 @@ +#N canvas 195 283 786 398 10; +#X obj 111 145 qnorm~; +#X obj 38 71 osc~ 30; +#X obj 101 71 osc~ 40; +#X obj 163 70 osc~ 50; +#X obj 229 71 osc~ 60; +#X obj 143 319 dac~; +#X obj 123 244 vol~; +#X obj 163 244 vol~; +#X floatatom 230 230 5 0 0; +#X floatatom 58 36 5 0 0; +#X floatatom 107 36 5 0 0; +#X floatatom 159 36 5 0 0; +#X floatatom 208 36 5 0 0; +#X obj 167 282 hip~ 10; +#X obj 103 281 hip~ 10; +#X text 402 190 qmult multiplies 2 quaternion signals; +#X floatatom 347 35 5 0 0; +#X floatatom 396 35 5 0 0; +#X floatatom 448 35 5 0 0; +#X floatatom 497 35 5 0 0; +#X obj 327 70 osc~ 70; +#X obj 390 70 osc~ 80; +#X obj 452 69 osc~ 90; +#X obj 518 70 osc~ 100; +#X obj 410 136 qnorm~; +#X obj 106 195 qmult~ 0 0 0 0 0; +#X text 410 208 "quaternion ring modulation"; +#X text 403 245 the inlets are in 1 x real 3 x imag form; +#X connect 0 0 25 0; +#X connect 0 1 25 1; +#X connect 0 2 25 2; +#X connect 0 3 25 3; +#X connect 1 0 0 0; +#X connect 2 0 0 1; +#X connect 3 0 0 2; +#X connect 4 0 0 3; +#X connect 6 0 14 0; +#X connect 7 0 13 0; +#X connect 8 0 7 1; +#X connect 8 0 6 1; +#X connect 9 0 1 0; +#X connect 10 0 2 0; +#X connect 11 0 3 0; +#X connect 12 0 4 0; +#X connect 13 0 5 1; +#X connect 14 0 5 0; +#X connect 16 0 20 0; +#X connect 17 0 21 0; +#X connect 18 0 22 0; +#X connect 19 0 23 0; +#X connect 20 0 24 0; +#X connect 21 0 24 1; +#X connect 22 0 24 2; +#X connect 23 0 24 3; +#X connect 24 0 25 4; +#X connect 24 1 25 5; +#X connect 24 2 25 6; +#X connect 24 3 25 7; +#X connect 25 0 6 0; +#X connect 25 1 6 0; +#X connect 25 2 7 0; +#X connect 25 3 7 0; diff --git a/doc/qnorm~.pd b/doc/qnorm~.pd new file mode 100644 index 0000000..3f6a8d0 --- /dev/null +++ b/doc/qnorm~.pd @@ -0,0 +1,35 @@ +#N canvas 334 368 513 350 10; +#X obj 119 137 qnorm~; +#X obj 96 68 osc~ 30; +#X obj 159 68 osc~ 40; +#X obj 221 67 osc~ 50; +#X obj 287 68 osc~ 60; +#X obj 131 265 dac~; +#X obj 111 190 vol~; +#X obj 151 190 vol~; +#X floatatom 185 154 5 0 0; +#X floatatom 116 33 5 0 0; +#X floatatom 165 33 5 0 0; +#X floatatom 217 33 5 0 0; +#X floatatom 266 33 5 0 0; +#X obj 155 228 hip~ 10; +#X obj 91 227 hip~ 10; +#X text 45 -2 qnorm normalizes a quaternion signal to unit norm; +#X connect 0 0 6 0; +#X connect 0 1 6 0; +#X connect 0 2 7 0; +#X connect 0 3 7 0; +#X connect 1 0 0 0; +#X connect 2 0 0 1; +#X connect 3 0 0 2; +#X connect 4 0 0 3; +#X connect 6 0 14 0; +#X connect 7 0 13 0; +#X connect 8 0 7 1; +#X connect 8 0 6 1; +#X connect 9 0 1 0; +#X connect 10 0 2 0; +#X connect 11 0 3 0; +#X connect 12 0 4 0; +#X connect 13 0 5 1; +#X connect 14 0 5 0; diff --git a/doc/ratio.pd b/doc/ratio.pd new file mode 100644 index 0000000..9750058 --- /dev/null +++ b/doc/ratio.pd @@ -0,0 +1,18 @@ +#N canvas 328 388 450 300 10; +#X obj 75 99 ratio; +#X obj 103 192 osc~; +#X floatatom 131 122 5 0 0; +#X obj 103 150 *; +#X obj 103 223 dac~; +#X floatatom 75 51 5 0 0; +#X floatatom 35 135 5 0 0; +#X text 189 32 ratio is an octave shifter.; +#X text 188 46 output is between 1 and 2; +#X text 189 62 it computes 2^(log2(x)-int(log2(x))); +#X connect 0 0 3 0; +#X connect 0 0 6 0; +#X connect 1 0 4 0; +#X connect 1 0 4 1; +#X connect 2 0 3 1; +#X connect 3 0 1 0; +#X connect 5 0 0 0; diff --git a/doc/reference.txt b/doc/reference.txt new file mode 100644 index 0000000..6485266 --- /dev/null +++ b/doc/reference.txt @@ -0,0 +1,49 @@ +abstractions + +64k a beat shuffler using raw 64k/break sample banks +bdft,bdfts set decay time (ms/sec) and osc frequency (for bdiag~) +bhip~ butterworth high pass filter +blop~ butterworth low pass filter +bpm convert bpm to metro time and phasor freq +count modulo counter +eadh~ exponential attack decay (with hold == duration) +eadsrh~ exponential attack decay sustain release (..) +fblock block relative frequency conversion +inv inverse +pdynwav~ phasor~ + dynwav~ +scale7 arbitrary 7 tone scale +vols~ volume for a stereo signal +vol~ volume for a mono signal + +externs + +ffpoly finite field polynomial +fwarp tangent warp frequency +ratio multiply by 2^k so result is 1<=r<2 (transposer) + + +tilde externs + +abs~ absolute value +bdiag~ block diagonal state space system (spectral processor) +bfft~ reordered fft +cheby~ chebychev polynomial waveshaper +diag~ diagonal state space system (spectral processor) +dist~ several distortions & waveshaping functions +dwt~ discrete wavelet transform +idwt~ inverse +dynwav~ dynamic wavetable: use a signal block as wavetable +ead~ exp. attack decay +eadsr~ exp. attack decay sustain release +ear~ exp. attack release +lattice~ lattice filter +matrix~ multiply a signal block with an arbitrary matrix +permut~ random permute a signal block +qmult~ multiply 2 quaternion signals +qnorm~ normalize a quaternion signal (or any 4 channel sig) +ramp~ generates an integer ramp +statwav~ a tabread4~ clone with 8 point interpolation +tabreadmix~ a tabread~ clone with overlap add (for smooth time stretch) +xfm~ coupled frequency modulation +biquadseries~ biquad second order sections (i.e. butterworth) +filterortho~ several biquad filters, orthogonal implementation diff --git a/doc/tabreadmix~.pd b/doc/tabreadmix~.pd new file mode 100644 index 0000000..aad25ab --- /dev/null +++ b/doc/tabreadmix~.pd @@ -0,0 +1,45 @@ +#N canvas 466 143 551 422 10; +#X floatatom 199 254 5 0 0; +#X obj 48 315 dac~; +#X floatatom 38 40 5 0 0; +#X text 135 7 tabreadmix~ an overlap add tabread clone; +#X obj 288 362 soundfiler; +#X text 203 236 right inlet: window hop size; +#X text 249 247 (window size = 2x hop size); +#X obj 38 77 phasor~; +#X obj 38 124 *~; +#X text 136 40 usage analogous to tabread~; +#X text 136 58 only sample adressing is modulo length; +#X obj 288 311 openpanel; +#X obj 288 291 bng 15 250 50 0 empty empty empty 0 -6 32 8 -262144 +-1 -1; +#X msg 171 97 bang; +#X text 219 97 reset windowing; +#X msg 171 150 pitch \$1; +#X floatatom 171 132 5 0 0; +#X text 245 151 set window hop size corresponding to pitch; +#X floatatom 172 178 5 0 0; +#X msg 172 196 chunks \$1; +#X text 246 196 set hop size to 1/xth of length; +#X obj 374 304 table sample123; +#X msg 288 338 read -resize \$1 sample123; +#X obj 288 386 s length; +#X obj 54 100 r length; +#X obj 57 275 tabreadmix~ sample123; +#X text 136 24 simple (sample rate synchronous) playback; +#X connect 0 0 25 1; +#X connect 2 0 7 0; +#X connect 4 0 23 0; +#X connect 7 0 8 0; +#X connect 8 0 25 0; +#X connect 11 0 22 0; +#X connect 12 0 11 0; +#X connect 13 0 25 0; +#X connect 15 0 25 0; +#X connect 16 0 15 0; +#X connect 18 0 19 0; +#X connect 19 0 25 0; +#X connect 22 0 4 0; +#X connect 24 0 8 1; +#X connect 25 0 1 0; +#X connect 25 0 1 1; diff --git a/doc/xfm~.pd b/doc/xfm~.pd new file mode 100644 index 0000000..6b59329 --- /dev/null +++ b/doc/xfm~.pd @@ -0,0 +1,106 @@ +#N canvas 182 174 656 604 10; +#X text 298 24 xfm~ cross frequency modulation; +#X msg 180 308 reset; +#X floatatom 231 255 5 0 0; +#X floatatom 282 255 5 0 0; +#X floatatom 332 255 5 0 0; +#X floatatom 382 255 5 0 0; +#X obj 287 514 dac~; +#X obj 231 282 lop~ 1; +#X obj 282 282 lop~ 1; +#X obj 332 282 lop~ 1; +#X obj 382 282 lop~ 1; +#X floatatom 444 268 5 0 0; +#X text 228 232 freq1; +#X text 279 232 freq2; +#X text 337 233 fb1; +#X text 381 234 fb2; +#X text 297 43 freq_osc1 = freq1 + wave_out2*fb1; +#X text 297 58 freq_osc2 = freq2 + wave_out1*fb2; +#X obj 275 99 hsl 300 15 1 20000 1 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 15200 1; +#X obj 275 121 hsl 300 15 1 20000 1 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 14400 1; +#X obj 276 146 hsl 300 15 1 20000 1 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 18938 1; +#X obj 276 171 hsl 300 15 1 20000 1 1 empty empty empty -2 -6 0 8 -262144 +-1 -1 21000 1; +#X floatatom 487 377 5 0 0; +#X floatatom 534 375 5 0 0; +#X obj 462 348 metro; +#X floatatom 534 335 5 0 0; +#X obj 463 324 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X msg 534 306 500; +#X msg 565 305 125; +#X msg 444 241 0.1; +#X msg 495 306 1000; +#X msg 150 223 type 0; +#X msg 151 263 type 1; +#X text 42 213 square phasor; +#X text 45 158 algo type; +#X text 37 257 circular phasor; +#X text 7 371 remark: all frequencies are warped; +#X text 8 388 (f_real = arctan(2pi*f_in)/2pi); +#X obj 288 485 vols~; +#X floatatom 352 453 5 0 0; +#X text 7 416 for frequencies under 1000Hz; +#X text 8 430 this effect is minimal; +#X text 9 465 use the fwarp to convert from; +#X text 9 478 real to warped; +#X text 9 505 the square phasor type is warped too; +#X text 9 520 but not in such a nice way as the; +#X text 9 534 circular phasor; +#X text 36 229 (chaotic 4DOF); +#X text 5 272 (quasiperiodic 2DOF); +#X obj 277 325 xfm~; +#X obj 462 411 ead~ 0 0; +#X obj 442 517 dac~; +#X obj 435 451 *~; +#X obj 472 451 *~; +#X obj 443 488 vols~; +#X floatatom 507 456 5 0 0; +#X text 2 173 (can be set by creation argument); +#X connect 1 0 49 0; +#X connect 2 0 7 0; +#X connect 3 0 8 0; +#X connect 4 0 9 0; +#X connect 5 0 10 0; +#X connect 7 0 49 0; +#X connect 8 0 49 1; +#X connect 9 0 49 2; +#X connect 10 0 49 3; +#X connect 11 0 10 1; +#X connect 11 0 9 1; +#X connect 11 0 7 1; +#X connect 11 0 8 1; +#X connect 18 0 2 0; +#X connect 19 0 3 0; +#X connect 20 0 4 0; +#X connect 21 0 5 0; +#X connect 22 0 50 1; +#X connect 23 0 50 2; +#X connect 24 0 50 0; +#X connect 25 0 24 1; +#X connect 25 0 23 0; +#X connect 26 0 24 0; +#X connect 27 0 25 0; +#X connect 28 0 25 0; +#X connect 29 0 11 0; +#X connect 30 0 25 0; +#X connect 31 0 49 0; +#X connect 32 0 49 0; +#X connect 38 0 6 0; +#X connect 38 1 6 1; +#X connect 39 0 38 2; +#X connect 49 0 52 0; +#X connect 49 0 38 0; +#X connect 49 1 53 0; +#X connect 49 1 38 1; +#X connect 50 0 52 1; +#X connect 50 0 53 1; +#X connect 52 0 54 0; +#X connect 53 0 54 1; +#X connect 54 0 51 0; +#X connect 54 1 51 1; +#X connect 55 0 54 2; diff --git a/include/Makefile b/include/Makefile new file mode 100644 index 0000000..33d4426 --- /dev/null +++ b/include/Makefile @@ -0,0 +1,5 @@ +all: +clean: + rm -f *~ + rm -f dspi/*~ + diff --git a/include/dspi/DSPI.h b/include/dspi/DSPI.h new file mode 100644 index 0000000..d9e2acf --- /dev/null +++ b/include/dspi/DSPI.h @@ -0,0 +1,16 @@ +#ifndef DSPI_h +#define DSPI_h + +#define DSPImin(x,y) (((x)<(y)) ? (x) : (y)) +#define DSPImax(x,y) (((x)>(y)) ? (x) : (y)) +#define DSPIclip(min, x, max) (DSPImin(DSPImax((min), (x)), max)) + + +// test if floating point number is denormal +#define DSPI_IS_DENORMAL(f) (((*(unsigned int *)&(f))&0x7f800000) == 0) + +// test if almost denormal, choose whichever is fastest +#define DSPI_IS_ALMOST_DENORMAL(f) (((*(unsigned int *)&(f))&0x7f800000) < 0x08000000) +//#define DSPI_IS_ALMOST_DENORMAL(f) (fabs(f) < 3.e-34) + +#endif diff --git a/include/dspi/DSPIcomplex.h b/include/dspi/DSPIcomplex.h new file mode 100644 index 0000000..c0e2d63 --- /dev/null +++ b/include/dspi/DSPIcomplex.h @@ -0,0 +1,191 @@ +/* + * DSPIcomplex.h - Quick and dirty inline class for complex numbers + * (mainly to compute filter poles/zeros, not to be used inside loops) + * Copyright (c) 2000 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DSPIcomplex_h +#define DSPIcomplex_h + +#include +#include + +class DSPIcomplex +{ + public: + inline DSPIcomplex() {_r = _i = 0;} + inline DSPIcomplex(const float &a, const float &b) {setCart(a, b);} + inline DSPIcomplex(const float &phasor) {setAngle(phasor);} + + inline void setAngle(const float &angle) {_r = cos(angle); _i = sin(angle);} + inline void setPolar(const float &phasor, const float &norm) + {_r = norm * cos(phasor); _i = norm * sin(phasor);} + inline void setCart(const float &a, const float &b) {_r = a; _i = b;} + + inline const float& r() const {return _r;} + inline const float& i() const {return _i;} + + inline float norm2() const {return _r*_r+_i*_i;} + inline float norm() const {return sqrt(norm2());} + inline void normalize() {float n = 1.0f / norm(); _r *= n; _i *= n;} + + inline DSPIcomplex conj() const {return DSPIcomplex(_r, -_i);} + + inline float angle() const {return atan2(_i, _r);} + + + inline DSPIcomplex operator+ (const DSPIcomplex &a) const + { + return DSPIcomplex(_r + a.r(), _i + a.i()); + } + inline DSPIcomplex operator+ (float f) const + { + return DSPIcomplex(_r + f, _i); + } + inline DSPIcomplex operator- (const DSPIcomplex &a) const + { + return DSPIcomplex(_r - a.r(), _i - a.i()); + } + inline DSPIcomplex operator- (float f) const + { + return DSPIcomplex(_r - f, _i); + } + + inline DSPIcomplex operator* (const DSPIcomplex &a) const + { + return DSPIcomplex(_r * a.r() - _i * a.i(), _i * a.r() + _r * a.i()); + } + inline DSPIcomplex operator* (float f) const + { + return DSPIcomplex(_r * f, _i * f); + } + inline DSPIcomplex operator/ (const DSPIcomplex &a) const + { + float n_t = 1.0f / a.norm2(); + return DSPIcomplex(n_t * (_r * a.r() + _i * a.i()), n_t * (_i * a.r() - _r * a.i())); + } + inline DSPIcomplex operator/ (float f) const + { + float n_t = 1.0f / f; + return DSPIcomplex(n_t * _r, n_t * _i); + } + + inline friend std::ostream& operator<< (std::ostream& o, DSPIcomplex& a) + { + return o << "(" << a.r() << "," << a.i() << ")"; + } + + inline friend DSPIcomplex operator+ (float f, DSPIcomplex& a) + { + return(DSPIcomplex(a.r() + f, a.i())); + } + + inline friend DSPIcomplex operator- (float f, DSPIcomplex& a) + { + return(DSPIcomplex(f - a.r(), - a.i())); + } + + inline friend DSPIcomplex operator/ (float f, DSPIcomplex& a) + { + return(DSPIcomplex(f,0) / a); + } + + // ???? + inline friend DSPIcomplex operator* (float f, DSPIcomplex& a) + { + return(DSPIcomplex(f*a.r(), f*a.i())); + } + + + inline DSPIcomplex& operator *= (float f) + { + _r *= f; + _i *= f; + return *this; + } + + inline DSPIcomplex& operator /= (float f) + { + _r /= f; + _i /= f; + return *this; + } + + inline DSPIcomplex& operator *= (DSPIcomplex& a) + { + float r_t = _r * a.r() - _i * a.i(); + _i = _r * a.i() + _i * a.r(); + _r = r_t; + + return *this; + } + + inline DSPIcomplex& operator /= (DSPIcomplex& a) + { + float n_t = a.norm2(); + float r_t = n_t * (_r * a.r() + _i * a.i()); + _i = n_t * (_i * a.r() - _r * a.i()); + _r = r_t; + + return *this; + } + + + float _r; + float _i; +}; + + +// COMPLEX LOG + +inline DSPIcomplex dspilog(DSPIcomplex a) /* complex log */ +{ + float r_t = log(a.norm()); + float i_t = a.angle(); + return DSPIcomplex(r_t, i_t); +} + +// COMPLEX EXP + +inline DSPIcomplex dspiexp(DSPIcomplex a) /* complex exp */ +{ + return (DSPIcomplex(a.i()) * exp(a.r())); +} + +// BILINEAR TRANSFORM analog -> digital + +inline DSPIcomplex bilin_stoz(DSPIcomplex a) +{ + DSPIcomplex a2 = a * 0.5f; + return((1.0f + a2)/(1.0f - a2)); +} + +// BILINEAR TRANSFORM digital -> analog + +inline DSPIcomplex bilin_ztos(DSPIcomplex a) +{ + return ((a - 1.0f) / (a + 1.0f))*2.0f; +} + +// not really a complex function but a nice complement to the bilinear routines + +inline float bilin_prewarp(float freq) +{ + return 2.0f * tan(M_PI * freq); +} + +#endif //DSPIcomplex_h diff --git a/include/dspi/DSPIfilters.h b/include/dspi/DSPIfilters.h new file mode 100644 index 0000000..09268de --- /dev/null +++ b/include/dspi/DSPIfilters.h @@ -0,0 +1,496 @@ +/* + * DSPIfilters.h - Inline classes for biquad filters + * Copyright (c) 2000 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DSPIfilters_h +#define DSPIfilters_h + + +#include "DSPIcomplex.h" +#include "DSPI.h" +//#include + +/* orthogonal biquad */ + +class DSPIfilterOrtho { + public: + + inline DSPIfilterOrtho(){resetState();resetCoef();resetSCoef();} + inline ~DSPIfilterOrtho(){} + + inline void resetState(){d1A = d1B = d2A = d2B = 0.0f;} + inline void resetCoef(){ai = ar = c0 = c1 = c2 = 0.0f;} + inline void resetSCoef(){s_ai = s_ar = s_c0 = s_c1 = s_c2 = 0.0f;} + + /* + * Biquad filters remarks + * + * Q is defined with reference to the analog prototype: + * poles/zeros = w0 * (1/Q +- sqrt(1 - 1/Q^2)) + * + * the num/den polynomial then has the form: + * 1 + 2s/Qw0 + (s/w0)^2 + * + * if Q < 1 => real valued poles/zeros + * if Q > 1 => complex values poles/zeros + * if Q = inf => imaginary poles/zeros + * if Q = sqrt(2) => 'maximally flat' poles/zeros + * + * the analog prototypes are converted to the digital domain + * using the bilinear transform. hence the prewarping. + */ + + // make sure freq and Q are positive and within bounds + inline void checkBounds(float &freq, float &Q) + { + freq = fabs(freq); + Q = fabs(Q); + + float epsilon = .0001f; // stability guard + float fmin = 0.0f + epsilon; + float fmax = 0.5f - epsilon; + float Qmin = 1.1f; + + if (freq < fmin) freq = fmin; + if (freq > fmax) freq = fmax; + + if (Q < Qmin) Q = Qmin; + + } + + inline void setAP(float freq, float Q) // allpass + { + + // prototype: H(s) = (1 - 2s/Qw0 + (s/w0)^2) / (1 + 2s/Qw0 + (s/w0)^2) + // s_p = - s_z (analog: symmetric wrt. im axis) + // z_p = 1/z_z (digiatl: summ wrt. unit circle) + checkBounds(freq, Q); + + // prewarp for bilin transfo + freq = bilin_prewarp(freq); + float zeta = 1.0f/Q; + + DSPIcomplex p = bilin_stoz(DSPIcomplex(-zeta, (1.0f-zeta*zeta))*freq); + DSPIcomplex z = 1.0f / p; + setPoleZeroNormalized(p, z, DSPIcomplex(1,0)); + + + } + inline void setLP(float freq, float Q) // low pass + { + // prototype: H(s) = 1 / (1 + 2s/Qw0 + (s/w0)^2) + // the bilinear transform has 2 zeros at NY + + checkBounds(freq, Q); + freq = bilin_prewarp(freq); + float zeta = 1/Q; + + DSPIcomplex p = bilin_stoz(DSPIcomplex(-zeta, (1.0f-zeta*zeta))*freq); + setPoleZeroNormalized(p, DSPIcomplex(-1, 0), DSPIcomplex(1, 0)); + + } + inline void setHP(float freq, float Q) // hi pass + { + // prototype: H(s) = (s/w0)^2 / (1 + 2s/Qw0 + (s/w0)^2) + // the bilinear transform has 2 zeros at DC + + checkBounds(freq, Q); + freq = bilin_prewarp(freq); + float zeta = 1/Q; + + DSPIcomplex p = bilin_stoz(DSPIcomplex(-zeta, (1.0f-zeta*zeta))*freq); + setPoleZeroNormalized(p, DSPIcomplex(1, 0), DSPIcomplex(-1, 0)); + + } + + inline void setBP(float freq, float Q) // band pass (1-allpass) + { + // prototype: 1/2 * (1 - H_allpass(z)) + setAP(freq, Q); + float h = -0.5f; + c0 *= h; + c1 *= h; + c2 *= h; + c0 -= h; + + } + + inline void setBR(float freq, float Q) // band reject + { + // prototype: H(s) = (1 - (s/w0)^2) / (1 + 2s/Qw0 + (s/w0)^2) + checkBounds(freq, Q); + // pole phasor + DSPIcomplex z = DSPIcomplex(2.0f * M_PI * freq); + + // prewarp for bilin transfo + freq = bilin_prewarp(freq); + float zeta = 1/Q; + + DSPIcomplex p = bilin_stoz(DSPIcomplex(-zeta, (1.0f-zeta*zeta))*freq); + setPoleZeroNormalized(p, z, DSPIcomplex(1,0)); + } + + inline void setHS(float freq, float gain) // low shelf + { + // hi shelf = LP - g(LP-1) + float Q = M_SQRT2; + setLP(freq, Q); + c0 -= gain * (c0 - 1.0f); + c1 -= gain * (c1); + c2 -= gain * (c2); + } + + inline void setLS(float freq, float gain) // low shelf + { + // hi shelf = HP - g(HP-1) + float Q = M_SQRT2; + setHP(freq, Q); + c0 -= gain * (c0 - 1.0f); + c1 -= gain * (c1); + c2 -= gain * (c2); + } + inline void setEQ(float freq, float Q, float gain)// param EQ + { + // EQ = (1+A)/2 + (1-A)/2 AP + + float a0 = 0.5f * (1.0f + gain); + float a1 = 0.5f * (1.0f - gain); + setAP(freq, Q); + c0 *= a1; + c1 *= a1; + c2 *= a1; + c0 += a0; + } + + inline void setPoleZero + ( + const DSPIcomplex& a, // pole + const DSPIcomplex& b // zero + ) + { + ar = a.r(); + ai = a.i(); + + c0 = 1.0f; + c1 = 2.0f * (a.r() - b.r()); + c2 = (a.norm2() - b.norm2() - c1 * a.r()) / a.i(); + } + + + inline void setPoleZeroNormalized + ( + const DSPIcomplex& a, // pole + const DSPIcomplex& b, // zero + const DSPIcomplex& c // gain = 1 at this freq + ) + { + setPoleZero(a, b); + DSPIcomplex invComplexGain = ((c-a)*(c-a.conj()))/((c-b)*(c-b.conj())); + float invGain = invComplexGain.norm(); + c0 *= invGain; + c1 *= invGain; + c2 *= invGain; + + } + + + // one channel bang + inline void Bang + ( + float &input, + float &output + ) + { + float d1t = ar * d1A + ai * d2A + input; + float d2t = ar * d2A - ai * d1A; + output = c0 * input + c1 * d1A + c2 * d2A; + d1A = d1t; + d2A = d2t; + } + + // one channel bang smooth + // a default s could be s = (1 - (.1)^(1/n)) + inline void BangSmooth + ( + float &input, // input ref + float &output, // output ref + float s // smooth pole + ) + { + float d1t = s_ar * d1A + s_ai * d2A + input; + float d2t = s_ar * d2A - s_ai * d1A; + s_ar += s * (ar - s_ar); + s_ai += s * (ai - s_ai); + output = s_c0 * input + s_c1 * d1A + s_c2 * d2A; + d1A = d1t; + d2A = d2t; + s_c0 += s * (c0 - s_c0); + s_c1 += s * (c1 - s_c1); + s_c2 += s * (c2 - s_c2); + } + + // two channel bang + inline void Bang2 + ( + float &input1, + float &input2, + float &output1, + float &output2 + ) + { + float d1tA = ar * d1A + ai * d2A + input1; + float d1tB = ar * d1B + ai * d2B + input2; + float d2tA = ar * d2A - ai * d1A; + float d2tB = ar * d2B - ai * d1B; + output1 = c0 * input1 + d1A * c1 + d2A * c2; + output2 = c0 * input2 + d1B * c1 + d2B * c2; + d1A = d1tA; + d2A = d2tA; + d1B = d1tB; + d2B = d2tB; + } + + // two channel bang smooth + inline void Bang2Smooth + ( + float &input1, + float &input2, + float &output1, + float &output2, + float s + ) + { + float d1tA = s_ar * d1A + s_ai * d2A + input1; + float d1tB = s_ar * d1B + s_ai * d2B + input2; + float d2tA = s_ar * d2A - s_ai * d1A; + float d2tB = s_ar * d2B - s_ai * d1B; + s_ar += s * (ar - s_ar); + s_ai += s * (ai - s_ai); + output1 = s_c0 * input1 + d1A * s_c1 + d2A * s_c2; + output2 = s_c0 * input2 + d1B * s_c1 + d2B * s_c2; + d1A = d1tA; + d2A = d2tA; + d1B = d1tB; + d2B = d2tB; + s_c0 += s * (c0 - s_c0); + s_c1 += s * (c1 - s_c1); + s_c2 += s * (c2 - s_c2); + } + + inline void killDenormals() + { + + // state data + float zero = 0.0f; + + d1A = DSPI_IS_DENORMAL(d1A) ? zero : d1A; + d2A = DSPI_IS_DENORMAL(d2A) ? zero : d2A; + d1B = DSPI_IS_DENORMAL(d1B) ? zero : d1B; + d2B = DSPI_IS_DENORMAL(d2B) ? zero : d2B; + + + /* test on athlon showed nuking smooth data does not + * present a noticable difference in performance however + * nuking state data is really necessary + + + // smooth data + float dai = ai - s_ai; + float dar = ar - s_ar; + float dc0 = c0 - s_c0; + float dc1 = c1 - s_c1; + float dc2 = c2 - s_c2; + + + s_ai = DSPI_IS_DENORMAL(dai) ? ai : s_ai; + s_ar = DSPI_IS_DENORMAL(dar) ? ar : s_ar; + s_c0 = DSPI_IS_DENORMAL(dc0) ? c0 : s_c0; + s_c1 = DSPI_IS_DENORMAL(dc0) ? c1 : s_c1; + s_c2 = DSPI_IS_DENORMAL(dc0) ? c2 : s_c2; + + */ + + + + } + + private: + + // state data + float d1A; + float d2A; + + float d1B; + float d2B; + + // pole data + float ai; + float s_ai; + float ar; + float s_ar; + + // zero data + float c0; + float s_c0; + float c1; + float s_c1; + float c2; + float s_c2; + + +}; + + + +class DSPIfilterSeries{ + public: + inline DSPIfilterSeries() {DSPIfilterSeries(1);} + inline ~DSPIfilterSeries() {delete [] biquad;}; + + inline DSPIfilterSeries(int numberOfSections) + { + // create a set of biquads + sections = numberOfSections; + biquad = new DSPIfilterOrtho[numberOfSections]; + } + + inline void setButterHP(float freq) + { + /* This member function computes the poles for a highpass butterworth filter. + * The filter is transformed to the digital domain using a bilinear transform. + * Every biquad section is normalized at NY. + */ + + float epsilon = .0001f; // stability guard + float min = 0.0f + epsilon; + float max = 0.5f - epsilon; + + if (freq < min) freq = min; + if (freq > max) freq = max; + + // prewarp cutoff frequency + float omega = bilin_prewarp(freq); + + DSPIcomplex NY(-1,0); //normalize at NY + DSPIcomplex DC(1,0); //all zeros will be at DC + DSPIcomplex pole( (2*sections + 1) * M_PI / (4*sections)); // first pole of lowpass filter with omega == 1 + DSPIcomplex pole_inc(M_PI / (2*sections)); // phasor to get to next pole, see Porat p. 331 + + for (int i=0; i HP -> digital transfo + DC, // all zeros at DC + NY); // normalized (gain == 1) at NY + pole *= pole_inc; // compe next (lowpass) pole + } + + } + + inline void setButterLP(float freq) + { + /* This member function computes the poles for a lowpass butterworth filter. + * The filter is transformed to the digital domain using a bilinear transform. + * Every biquad section is normalized at DC. + * Doing it this way, only the pole locations need to be transformed. + * The constant gain factor can be computed by setting the DC gain of every section to 1. + * An analog butterworth is all-pole, meaning the bilinear transform has all zeros at -1 + */ + + + float epsilon = .0001f; // stability guard + float min = 0.0f + epsilon; + float max = 0.5f - epsilon; + + + if (freq < min) freq = min; + if (freq > max) freq = max; + + // prewarp cutoff frequency + float omega = bilin_prewarp(freq); + + DSPIcomplex DC(1,0); //normalize at DC + DSPIcomplex NY(-1,0); //all zeros will be at NY + DSPIcomplex pole( (2*sections + 1) * M_PI / (4*sections)); + pole *= omega; // first pole, see Porat p. 331 + DSPIcomplex pole_inc(M_PI / (2*sections)); // phasor to get to next pole, see Porat p. 331 + + for (int i=0; i +#include "m_pd.h" + +/* envelope stuff */ + +/* exponential range for envelopes is 60dB */ +#define ENVELOPE_RANGE 0.001f +#define ENVELOPE_MAX (1.0f - ENVELOPE_RANGE) +#define ENVELOPE_MIN ENVELOPE_RANGE + +/* convert milliseconds to 1-p, with p a real pole */ +float milliseconds_2_one_minus_realpole(float time); diff --git a/modules++/Makefile b/modules++/Makefile new file mode 100644 index 0000000..1329f4b --- /dev/null +++ b/modules++/Makefile @@ -0,0 +1,10 @@ +include ../Makefile.config +current: all + +all: biquadseries.o filterortho.o + + +clean: + rm -f *~ + rm -f *.o + diff --git a/modules++/biquadseries.cc b/modules++/biquadseries.cc new file mode 100644 index 0000000..40b3aef --- /dev/null +++ b/modules++/biquadseries.cc @@ -0,0 +1,128 @@ +/* + * biquadseries.cc - second order section filter pd interface + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "m_pd.h" +#include + +#include "DSPIcomplex.h" +#include "DSPIfilters.h" + + + +typedef struct biquadseries_struct +{ + t_object x_obj; + t_float x_f; + DSPIfilterSeries* biquadseries; +} t_biquadseries; + +void biquadseries_bang(t_biquadseries *x) +{ + +} + +void biquadseries_butterLP(t_biquadseries *x, t_floatarg f) +{ + x->biquadseries->setButterLP(f / sys_getsr()); +} + +void biquadseries_butterHP(t_biquadseries *x, t_floatarg f) +{ + x->biquadseries->setButterHP(f / sys_getsr()); +} + + + +static t_int *biquadseries_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + DSPIfilterSeries* biquadseries = (DSPIfilterSeries *)(w[1]); + t_int n = (t_int)(w[2]); + t_int i; + t_float x; + + // dit kan beter + float smooth = .01; + //1.0f - pow(.9f,1.0f/(float)(n)); + + for (i = 0; i < n; i++) + { + x = *in++; + biquadseries->BangSmooth(x, x, smooth); + *out++ = x; + } + + return (w+5); +} + +static void biquadseries_dsp(t_biquadseries *x, t_signal **sp) +{ + dsp_add(biquadseries_perform, 4, x->biquadseries, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + +} +void biquadseries_free(void) +{ + +} + +t_class *biquadseries_class; + +void *biquadseries_new(t_floatarg fsections) +{ + t_biquadseries *x = (t_biquadseries *)pd_new(biquadseries_class); + + int sections = (int)fsections; + if (sections < 1) sections = 1; + // post("biquadseries~: %d sections", sections); + x->biquadseries = new DSPIfilterSeries(sections); + + // inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("freq")); + outlet_new(&x->x_obj, gensym("signal")); + + biquadseries_butterLP(x, 10000); + + return (void *)x; +} + + +extern "C" { + +void biquadseries_tilde_setup(void) +{ + //post("biquadseries~ v0.1"); + + biquadseries_class = class_new(gensym("biquadseries~"), (t_newmethod)biquadseries_new, + (t_method)biquadseries_free, sizeof(t_biquadseries), 0, A_DEFFLOAT, 0); + + CLASS_MAINSIGNALIN(biquadseries_class, t_biquadseries, x_f); + + class_addmethod(biquadseries_class, (t_method)biquadseries_bang, gensym("bang"), (t_atomtype)0); + + class_addmethod(biquadseries_class, (t_method)biquadseries_dsp, gensym("dsp"), (t_atomtype)0); + + class_addmethod(biquadseries_class, (t_method)biquadseries_butterLP, gensym("butterLP"), A_FLOAT, A_NULL); + class_addmethod(biquadseries_class, (t_method)biquadseries_butterHP, gensym("butterHP"), A_FLOAT, A_NULL); + +} + +} diff --git a/modules++/filterortho.cc b/modules++/filterortho.cc new file mode 100644 index 0000000..11c6aac --- /dev/null +++ b/modules++/filterortho.cc @@ -0,0 +1,131 @@ +/* + * filterortho.cc - orthogonal biquad filter pd interface + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "m_pd.h" +#include + +#include "DSPIcomplex.h" +#include "DSPIfilters.h" + + + +typedef struct filterortho_struct +{ + t_object x_obj; + t_float x_f; + DSPIfilterOrtho filterortho; +} t_filterortho; + +void filterortho_bang(t_filterortho *x) +{ + +} + + +static t_int *filterortho_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + DSPIfilterOrtho* filterortho = (DSPIfilterOrtho *)(w[1]); + t_int n = (t_int)(w[2]); + t_int i; + t_float x; + + + // dit kan beter + float smooth = 1.0f - pow(.05f,1.0f/(float)(n)); + + for (i = 0; i < n; i++) + { + x = *in++; + filterortho->BangSmooth(x, x, smooth); + *out++ = x; + } + + filterortho->killDenormals(); + + return (w+5); +} + +static void filterortho_dsp(t_filterortho *x, t_signal **sp) +{ + dsp_add(filterortho_perform, 4, &(x->filterortho), sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + +} +void filterortho_free(void) +{ + +} + +t_class *filterortho_class; + + + +void setLP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho.setLP(f / sys_getsr(), Q);} +void setHP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho.setHP(f / sys_getsr(), Q);} +void setBP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho.setBP(f / sys_getsr(), Q);} +void setBR(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho.setBR(f / sys_getsr(), Q);} +void setAP(t_filterortho *x, t_floatarg f, t_floatarg Q) {x->filterortho.setAP(f / sys_getsr(), Q);} + +void setLS(t_filterortho *x, t_floatarg f, t_floatarg A) {x->filterortho.setLS(f / sys_getsr(), A);} +void setHS(t_filterortho *x, t_floatarg f, t_floatarg A) {x->filterortho.setHS(f / sys_getsr(), A);} + +void setEQ(t_filterortho *x, t_floatarg f, t_floatarg Q, t_floatarg A) {x->filterortho.setEQ(f / sys_getsr(), Q, A);} + + +void *filterortho_new() +{ + t_filterortho *x = (t_filterortho *)pd_new(filterortho_class); + outlet_new(&x->x_obj, gensym("signal")); + setLP(x, 10000, 2); + return (void *)x; +} + + + +extern "C" { + +void filterortho_tilde_setup(void) +{ + //post("filterortho~ v0.1"); + + filterortho_class = class_new(gensym("filterortho~"), (t_newmethod)filterortho_new, + (t_method)filterortho_free, sizeof(t_filterortho), 0, A_NULL); + + CLASS_MAINSIGNALIN(filterortho_class, t_filterortho, x_f); + + class_addmethod(filterortho_class, (t_method)filterortho_bang, gensym("bang"), A_NULL); + + class_addmethod(filterortho_class, (t_method)filterortho_dsp, gensym("dsp"), A_NULL); + + class_addmethod(filterortho_class, (t_method)setLP, gensym("setLP"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(filterortho_class, (t_method)setHP, gensym("setHP"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(filterortho_class, (t_method)setBP, gensym("setBP"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(filterortho_class, (t_method)setBR, gensym("setBR"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(filterortho_class, (t_method)setAP, gensym("setAP"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(filterortho_class, (t_method)setLS, gensym("setLS"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(filterortho_class, (t_method)setHS, gensym("setHS"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(filterortho_class, (t_method)setEQ, gensym("setEQ"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL); + +} + +} diff --git a/modules/Makefile b/modules/Makefile new file mode 100644 index 0000000..4e1cabd --- /dev/null +++ b/modules/Makefile @@ -0,0 +1,11 @@ +include ../Makefile.config + +current: ead.o ear.o eadsr.o dist.o tabreadmix.o xfm.o qmult.o qnorm.o \ + cheby.o abs.o ramp.o dwt.o bfft.o dynwav.o statwav.o bdiag.o \ + diag.o matrix.o permut.o lattice.o ratio.o ffpoly.o fwarp.o + + +clean: + rm -f *.o + rm -f *~ + diff --git a/modules/abs.c b/modules/abs.c new file mode 100644 index 0000000..4d8b8eb --- /dev/null +++ b/modules/abs.c @@ -0,0 +1,64 @@ +/* + * abs.c - computes absolute value of a signal + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "m_pd.h" +#include + +/* ------------------------- abs~ -------------------------- */ +static t_class *abs_class; + +typedef struct _abs +{ + t_object x_obj; +} t_abs; + +static t_int *abs_perform(t_int *w) +{ + t_abs *x = (t_abs *)(w[1]); + t_float *in = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + int n = (int)(w[4]); + while (n--) + { + float f = *in++; + if (f < 0) f = -f; + *out++ = f; + } + return (w+5); +} + +static void abs_dsp(t_abs *x, t_signal **sp) +{ + dsp_add(abs_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + +static void *abs_new(void) +{ + t_abs *x = (t_abs *)pd_new(abs_class); + outlet_new(&x->x_obj, &s_signal); + return (x); +} + +void abs_tilde_setup(void) +{ + abs_class = class_new(gensym("abs~"), (t_newmethod)abs_new, 0, + sizeof(t_abs), 0, A_NULL); + class_addmethod(abs_class, (t_method)nullfn, &s_signal, A_NULL); + class_addmethod(abs_class, (t_method)abs_dsp, gensym("dsp"), A_NULL); +} diff --git a/modules/bdiag.c b/modules/bdiag.c new file mode 100644 index 0000000..37a0349 --- /dev/null +++ b/modules/bdiag.c @@ -0,0 +1,272 @@ +/* + * bdiag.c - block diagonal state space system + * treats input dsp block as n parallel signals + * + * s1 = (a * s1) + (b * s2) + u1; + * s2 = (a * s2) - (b * s1) + u2; + * + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "m_pd.h" +#include +#include +#include + +#define MAXORDER 64 + +typedef struct bdiagctl +{ + t_float *c_state; + t_float *c_eigen; + t_int c_order; +} t_bdiagctl; + +typedef struct bdiag +{ + t_object x_obj; + t_float x_f; + t_bdiagctl x_ctl; +} t_bdiag; + + +static float randfloat(void){ + float r = rand (); + r /= (RAND_MAX/2); + r -= 1; + return r; + +} + +static void bdiag_random(t_bdiag *x) +{ + int i; + + for (i=0; ix_ctl.c_order; i++) + { + x->x_ctl.c_state[i] = randfloat(); + } + +} + + +static void bdiag_reset(t_bdiag *x) +{ + int i; + + for (i=0; ix_ctl.c_order; i++) + { + x->x_ctl.c_state[i] = 0; + } + +} + + + + + + +static void bdiag_eigen(t_bdiag *x, t_floatarg index, t_floatarg aval, t_floatarg bval) +{ + int i = (int)index; + if (i<0) return; + if (i>=x->x_ctl.c_order/2) return; + x->x_ctl.c_eigen[2*i+0] = aval; + x->x_ctl.c_eigen[2*i+1] = bval; + +} + +/* set decay time and frequency of pole at index */ +static void bdiag_timefreq(t_bdiag *x, t_floatarg index, t_floatarg time, t_floatarg freq) +{ + float r,a,b,n; + float sr = sys_getsr() / (float)x->x_ctl.c_order; + + /* time in ms */ + time *= 0.001; + + if (time < 0.0f) time = 0.0f; + r = pow(0.001f, 1.0f / (time * sr)); + if (r < 0.0f) r = 0.0f; + if (r > 1.0f) r = 1.0f; + + a = cos(2*M_PI*freq/sr); + b = sin(2*M_PI*freq/sr); + + /* normalize to be sure */ + n = 1.0f / sqrt(a*a + b*b); + a *= n; + b *= n; + + bdiag_eigen(x, index, r*a, r*b); +} + +static void bdiag_preset(t_bdiag *x, t_floatarg preset) +{ + int p = preset; + int i; + float a, b, w, r; + + switch(p){ + case 0: + post("preset 0"); + for (i=0; ix_ctl.c_order/2; i++){ + w = randfloat() * .001; + r = 1. - (((float)i + 1.)/1000.); + a = cos(w) * r; + b = sin(w) * r; + post("%f %f %f %f", w, r, a, b); + bdiag_eigen(x,i,a,b); + } + break; + case 1: + default: + break; + + } +} + +static t_int *bdiag_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_bdiagctl *ctl = (t_bdiagctl *)(w[1]); + + t_float *eigen = ctl->c_eigen; + t_float *state = ctl->c_state; + t_int n = (t_int)(w[2]); + + t_float u1,u2,a,b,s1,s2,s1new,s2new; + + int i; + + for (i=0; is_n; + int i; + + if (n == 1) + { + post("bdiag: doesnt work with blocksize == 1"); + dsp_add_copy(sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); + } + else + { + if (x->x_ctl.c_order != n) + { + if (x->x_ctl.c_state) free(x->x_ctl.c_state); + if (x->x_ctl.c_eigen) free(x->x_ctl.c_eigen); + + x->x_ctl.c_state = (t_float *)malloc(n*sizeof(t_float)); + x->x_ctl.c_eigen = (t_float *)malloc(n*sizeof(t_float)); + + for(i=0;ix_ctl.c_state[i] = 0; + x->x_ctl.c_eigen[i] = 0; + } + + x->x_ctl.c_order = n; + } + + + dsp_add(bdiag_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + } + +} + +static void bdiag_free(t_bdiag *x) +{ + + if (x->x_ctl.c_state) free(x->x_ctl.c_state); + if (x->x_ctl.c_eigen) free(x->x_ctl.c_eigen); + + +} + +t_class *bdiag_class; + + +static void *bdiag_new(t_floatarg permute) +{ + t_bdiag *x = (t_bdiag *)pd_new(bdiag_class); + int i, n=64; + + outlet_new(&x->x_obj, gensym("signal")); + + x->x_ctl.c_state = (t_float *)malloc(n*sizeof(t_float)); + x->x_ctl.c_eigen = (t_float *)malloc(n*sizeof(t_float)); + + for(i=0;ix_ctl.c_state[i] = 0; + x->x_ctl.c_eigen[i] = 0; + } + + x->x_ctl.c_order = n; + + + return (void *)x; + + +} + + +void bdiag_tilde_setup(void) +{ + //post("bdiag~ v0.1"); + bdiag_class = class_new(gensym("bdiag~"), (t_newmethod)bdiag_new, + (t_method)bdiag_free, sizeof(t_bdiag), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(bdiag_class, t_bdiag, x_f); + class_addmethod(bdiag_class, (t_method)bdiag_random, gensym("random"), 0); + class_addmethod(bdiag_class, (t_method)bdiag_random, gensym("bang"), 0); + class_addmethod(bdiag_class, (t_method)bdiag_reset, gensym("reset"), 0); + class_addmethod(bdiag_class, (t_method)bdiag_dsp, gensym("dsp"), 0); + + class_addmethod(bdiag_class, (t_method)bdiag_eigen, gensym("eigen"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(bdiag_class, (t_method)bdiag_timefreq, gensym("timefreq"), A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(bdiag_class, (t_method)bdiag_preset, gensym("preset"), A_DEFFLOAT, 0); +} + diff --git a/modules/bfft.c b/modules/bfft.c new file mode 100644 index 0000000..76b0254 --- /dev/null +++ b/modules/bfft.c @@ -0,0 +1,304 @@ +/* + * bfft.c - code for fourrier transform + * data organization is in (real, imag) pairs + * the first 2 components are (DC, NY) + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "m_pd.h" +#include +#include +#include + +#define MAXORDER 64 + +typedef struct bfftctl +{ + t_int c_levels; + char c_name[16]; + t_int *c_clutter; + t_int *c_unclutter; +} t_bfftctl; + +typedef struct bfft +{ + t_object x_obj; + t_float x_f; + t_bfftctl x_ctl; +} t_bfft; + +t_class *bfft_class, *ibfft_class, *fht_class; + + +static inline void bfft_perform_permutation(t_float *S, int n, t_int *f) +{ + t_int k,l; + t_float swap; + for(k=0; kx_ctl; + int i; + + if (ctl->c_clutter) free(ctl->c_clutter); + if (ctl->c_unclutter) free(ctl->c_unclutter); + + ctl->c_clutter = (t_int *)malloc(n*sizeof(t_int)); + ctl->c_unclutter = (t_int *)malloc(n*sizeof(t_int)); + + + ctl->c_unclutter[0] = 0; + ctl->c_unclutter[1] = n/2; + for (i=1; ic_unclutter[2*i] = i; + ctl->c_unclutter[2*i+1] = n-i; + } + + for(i=0; ic_clutter[ctl->c_unclutter[i]] = i; + + return; + + /* debug */ + /* for(k=0; kc_clutter[k]); + ** for(k=0; kc_unclutter[k]); + ** + ** exit(1); + */ +} + + + +static t_int *bfft_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_bfftctl *ctl = (t_bfftctl *)(w[1]); + t_int n = (t_int)(w[2]); + t_float scale = sqrt(1.0f / (float)(n)); + + mayer_fht(out, n); + bfft_perform_permutation(out, n, ctl->c_unclutter); + + while (n--) *out++ *= scale; + + return (w+5); +} + + + + +static t_int *ibfft_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_bfftctl *ctl = (t_bfftctl *)(w[1]); + t_int n = (t_int)(w[2]); + t_float scale = sqrt(1.0f / (float)(n)); + + + bfft_perform_permutation(out, n, ctl->c_clutter); + mayer_fht(out, n); + while (n--) *out++ *= scale; + + + return (w+5); +} + + +static t_int *fht_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_bfftctl *ctl = (t_bfftctl *)(w[1]); + + + t_int n = (t_int)(w[2]); + + mayer_fht(out, n); + + return (w+5); +} + + +static void bfft_dsp(t_bfft *x, t_signal **sp) +{ + + int n = sp[0]->s_n; + t_float *in = sp[0]->s_vec; + t_float *out = sp[1]->s_vec; + + bfft_permutation(x, n); + + if (in != out) + { + dsp_add_copy(in,out,n); + in = out; + } + + dsp_add(bfft_perform, 4, &x->x_ctl, n, in, out); + +} + +static void ibfft_dsp(t_bfft *x, t_signal **sp) +{ + + int n = sp[0]->s_n; + t_float *in = sp[0]->s_vec; + t_float *out = sp[1]->s_vec; + + bfft_permutation(x, n); + + if (in != out) + { + dsp_add_copy(in,out,n); + in = out; + } + + dsp_add(ibfft_perform, 4, &x->x_ctl, n, in, out); + +} + +static void fht_dsp(t_bfft *x, t_signal **sp) +{ + + int n = sp[0]->s_n; + t_float *in = sp[0]->s_vec; + t_float *out = sp[1]->s_vec; + + + if (in != out) + { + dsp_add_copy(in,out,n); + in = out; + } + + dsp_add(fht_perform, 4, &x->x_ctl, n, in, out); + +} + + + +static void bfft_free(t_bfft *x) +{ + + if (x->x_ctl.c_clutter) free(x->x_ctl.c_clutter); + if (x->x_ctl.c_unclutter) free(x->x_ctl.c_unclutter); + +} + + + + +static void *bfft_new(void) +{ + t_bfft *x = (t_bfft *)pd_new(bfft_class); + int i; + + outlet_new(&x->x_obj, gensym("signal")); + + + sprintf(x->x_ctl.c_name,"bfft"); + + x->x_ctl.c_clutter = NULL; + x->x_ctl.c_unclutter = NULL; + + return (void *)x; + + +} + +static void *ibfft_new(void) +{ + t_bfft *x = (t_bfft *)pd_new(ibfft_class); + int i; + + outlet_new(&x->x_obj, gensym("signal")); + + + x->x_ctl.c_clutter = NULL; + x->x_ctl.c_unclutter = NULL; + + sprintf(x->x_ctl.c_name,"ibfft"); + + return (void *)x; +} + +static void *fht_new(void) +{ + t_bfft *x = (t_bfft *)pd_new(fht_class); + int i; + + outlet_new(&x->x_obj, gensym("signal")); + + + x->x_ctl.c_clutter = NULL; + x->x_ctl.c_unclutter = NULL; + + sprintf(x->x_ctl.c_name,"fht"); + + return (void *)x; +} + + + + +void bfft_tilde_setup(void) +{ + //post("bfft~ v0.1"); + bfft_class = class_new(gensym("bfft~"), (t_newmethod)bfft_new, + (t_method)bfft_free, sizeof(t_bfft), 0, 0); + CLASS_MAINSIGNALIN(bfft_class, t_bfft, x_f); + class_addmethod(bfft_class, (t_method)bfft_dsp, gensym("dsp"), 0); + + + + ibfft_class = class_new(gensym("ibfft~"), (t_newmethod)ibfft_new, + (t_method)bfft_free, sizeof(t_bfft), 0, 0); + + CLASS_MAINSIGNALIN(ibfft_class, t_bfft, x_f); + class_addmethod(ibfft_class, (t_method)ibfft_dsp, gensym("dsp"), 0); + + + + fht_class = class_new(gensym("fht~"), (t_newmethod)fht_new, + (t_method)bfft_free, sizeof(t_bfft), 0, 0); + + CLASS_MAINSIGNALIN(fht_class, t_bfft, x_f); + class_addmethod(fht_class, (t_method)fht_dsp, gensym("dsp"), 0); + + + +} diff --git a/modules/cheby.c b/modules/cheby.c new file mode 100644 index 0000000..2c32d68 --- /dev/null +++ b/modules/cheby.c @@ -0,0 +1,138 @@ +/* + * cheby.c - chebychev polynomial evaluation + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "m_pd.h" +#include + + +#define MAX_ORDER 1024 +#define DEFAULT_ORDER 4 + +typedef struct chebyctl +{ + t_float c_gain[MAX_ORDER]; + t_int c_order; +} t_chebyctl; + +typedef struct cheby +{ + t_object x_obj; + t_float x_f; + t_chebyctl x_ctl; +} t_cheby; + +static void cheby_bang(t_cheby *x) +{ + +} + +static void cheby_coef(t_cheby *x, t_floatarg coef, t_floatarg f) +{ + int i = (int)coef; + if ((i > 0) && (i < x->x_ctl.c_order + 1)){ + x->x_ctl.c_gain[i-1] = f; + /* post("cheby: harmonic %d set to %f", i, f); */ + } +} + + +static t_int *cheby_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_chebyctl *ctl = (t_chebyctl *)(w[1]); + t_float *gain = ctl->c_gain; + t_int i; + t_int n = (t_int)(w[2]), k; + t_float x,y,t1,t2,t,acc; + + + for (i = 0; i < n; i++) + { + x = *in++; + + gain = ctl->c_gain; + t2 = 1; /* T_0 */ + t1 = x; /* T_1 */ + + acc = *gain++ * x; /* a_1 T_1 */ + for (k=2; k<=ctl->c_order; k++){ + t = 2*x*t1 - t2; /* T_k = 2 x T_{k-1} - T_{k-2} */ + acc += *gain++ * t; /* a_k T_k */ + t2 = t1; + t1 = t; + } + + *out++ = acc; + + } + + + return (w+5); +} + +static void cheby_dsp(t_cheby *x, t_signal **sp) +{ + dsp_add(cheby_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + +} +static void cheby_free(void) +{ + +} + +t_class *cheby_class; + +static void *cheby_new(t_floatarg order_f) +{ + int i; + int order = (int)order_f; + + t_cheby *x = (t_cheby *)pd_new(cheby_class); + outlet_new(&x->x_obj, gensym("signal")); + + if (order < 1) order = DEFAULT_ORDER; /* default */ + if (order > MAX_ORDER) order = MAX_ORDER; /* maximum */ + + + //post("cheby: order = %d", order); + + x->x_ctl.c_order = order; + cheby_coef(x, 1, 1); + for (i=2; i +#include +#include + +#define MAXORDER 64 + +typedef struct diagctl +{ + t_float *c_state; + t_float *c_eigen; + t_int c_order; +} t_diagctl; + +typedef struct diag +{ + t_object x_obj; + t_float x_f; + t_diagctl x_ctl; +} t_diag; + + +static float randfloat(void){ + float r = rand (); + r /= (RAND_MAX/2); + r -= 1; + return r; + +} + +static void diag_eigen(t_diag *x, t_floatarg index, t_floatarg val) +{ + int i = (int)index; + if (i<0) return; + if (i>=x->x_ctl.c_order) return; + x->x_ctl.c_eigen[i] = val; +} + +/* set decay time of pole at index */ +static void diag_time(t_diag *x, t_floatarg index, t_floatarg time) +{ + float r; + + /* time in ms */ + time *= 0.001; + + if (time < 0.0f) time = 0.0f; + r = pow(0.001f, (float)x->x_ctl.c_order / (time * sys_getsr())); + if (r < 0.0f) r = 0.0f; + if (r > 1.0f) r = 1.0f; + + diag_eigen(x, index, r); +} + + + +static void diag_reset(t_diag *x) +{ + int i; + + for (i=0; ix_ctl.c_order; i++) + { + x->x_ctl.c_state[i] = 0; + } + +} + +static void diag_random(t_diag *x) +{ + int i; + + for (i=0; ix_ctl.c_order; i++) + { + x->x_ctl.c_state[i] = randfloat(); + } + +} + + + +static t_int *diag_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_diagctl *ctl = (t_diagctl *)(w[1]); + + t_float *eigen = ctl->c_eigen; + t_float *state = ctl->c_state; + t_int n = (t_int)(w[2]); + + t_float x; + + int i; + + for (i=0; is_n; + int i; + + if (x->x_ctl.c_order != n) + { + if (x->x_ctl.c_state) free(x->x_ctl.c_state); + if (x->x_ctl.c_eigen) free(x->x_ctl.c_eigen); + + x->x_ctl.c_state = (t_float *)malloc(n*sizeof(t_float)); + x->x_ctl.c_eigen = (t_float *)malloc(n*sizeof(t_float)); + + for(i=0;ix_ctl.c_state[i] = 0; + x->x_ctl.c_eigen[i] = 0; + } + + x->x_ctl.c_order = n; + } + + + + dsp_add(diag_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + +} + +static void diag_free(t_diag *x) +{ + + if (x->x_ctl.c_state) free(x->x_ctl.c_state); + if (x->x_ctl.c_eigen) free(x->x_ctl.c_eigen); + + +} + +t_class *diag_class; + + +static void *diag_new(t_floatarg permute) +{ + t_diag *x = (t_diag *)pd_new(diag_class); + int i, n=64; + + outlet_new(&x->x_obj, gensym("signal")); + + x->x_ctl.c_state = (t_float *)malloc(n*sizeof(t_float)); + x->x_ctl.c_eigen = (t_float *)malloc(n*sizeof(t_float)); + + for(i=0;ix_ctl.c_state[i] = 0; + x->x_ctl.c_eigen[i] = 0; + } + + x->x_ctl.c_order = n; + + + return (void *)x; +} + + +void diag_tilde_setup(void) +{ + //post("diag~ v0.1"); + diag_class = class_new(gensym("diag~"), (t_newmethod)diag_new, + (t_method)diag_free, sizeof(t_diag), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(diag_class, t_diag, x_f); + class_addmethod(diag_class, (t_method)diag_dsp, gensym("dsp"), 0); + class_addmethod(diag_class, (t_method)diag_reset, gensym("reset"), 0); + class_addmethod(diag_class, (t_method)diag_random, gensym("random"), 0); + class_addmethod(diag_class, (t_method)diag_random, gensym("bang"), 0); + class_addmethod(diag_class, (t_method)diag_eigen, gensym("eigen"), A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(diag_class, (t_method)diag_time, gensym("time"), A_DEFFLOAT, A_DEFFLOAT, 0); + +} + diff --git a/modules/dist.c b/modules/dist.c new file mode 100644 index 0000000..578e2ef --- /dev/null +++ b/modules/dist.c @@ -0,0 +1,262 @@ +/* + * dist.c - wave shaping extern + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "extlib_util.h" + + +#define CLIP 0 +#define INVERSE 1 +#define INVERSESQ 2 +#define INVERSECUB 3 +#define RAT1 4 +#define RAT2 5 +#define FULLRECT 6 +#define HALFRECT 7 +#define PULSE 8 +#define NEWTON1 9 +#define UPPERCLIP 10 + + + + +typedef struct distctl +{ + t_float c_gain; + t_float c_delay; + char c_type; +} t_distctl; + +typedef struct dist +{ + t_object x_obj; + t_float x_f; + t_distctl x_ctl; +} t_dist; + +void dist_bang(t_dist *x) +{ + +} + +void dist_gain(t_dist *x, t_floatarg f) +{ + x->x_ctl.c_gain = f; + +} + + +static t_int *dist_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_distctl *ctl = (t_distctl *)(w[1]); + t_float gain = ctl->c_gain; + t_int i; + t_int n = (t_int)(w[2]); + t_float x,y,v; + t_float z = ctl->c_delay; + + switch(ctl->c_type){ + case CLIP: + for (i = 0; i < n; i++) + { + x = *in++ * gain; + x = (x > 1) ? ( 1.) : x; + x = (x < -1) ? (-1.) : x; + *out++ = 0.9999 * x; + + } + break; + + case INVERSE: + for (i = 0; i < n; i++) + { + x = *in++ * gain; + x = (x > 1) ? (2. - 1/x) : x; + x = (x < -1) ? (-2. - 1/x) : x; + *out++ = x/2.0001; + + } + break; + + case INVERSESQ: + for (i = 0; i < n; i++) + { + x = *in++ * gain; + x = (x > 1) ? (2. - 1/x) : x; + x = (x < -1) ? (-2. - 1/x) : x; + x /= 2; + *out++ = 1.999*x*x-1; + + } + break; + + case INVERSECUB: + for (i = 0; i < n; i++) + { + x = *in++ * gain; + x = (x > 1) ? (2. - 1/x) : x; + x = (x < -1) ? (-2. - 1/x) : x; + x /= 2; + *out++ = .9999 * x*x*x; + + } + break; + + case RAT1: /*(2*d./((1+(d).^2)))*/ + for (i = 0; i < n; i++) + { + x = *in++ * gain; + y = (1. + x*x); + x = 1.9999*x/y; + *out++ = x; + } + break; + + case RAT2: /*(2*d./((1+(d).^16)))*/ + for (i = 0; i < n; i++) + { + x = *in++ * gain; + y = x*x; + y *= y; + y *= y; + y *= y; + y = (1. + y); + x = 1.2*x/y; + *out++ = x; + } + break; + + case FULLRECT: + for (i = 0; i < n; i++) + { + x = *in++ * gain; + x = (x>0) ? x : -x; + x = (x>1) ? 1 : x; + *out++ = 1.9999*(x-.5); + } + break; + + case HALFRECT: + for (i = 0; i < n; i++) + { + x = *in++ * gain; + x = (x>0) ? x : 0; + x = (x>1) ? 1 : x; + *out++ = 1.9999*(x-.5); + } + break; + + case PULSE: + for (i = 0; i < n; i++) + { + x = *in++ * gain; + y = (x>0) ? (1):(-1); + x = (z*y > 0) ? (0) : (y); + *out++ = .9999 * x; + z = x; + + } + ctl->c_delay = z; + break; + + case NEWTON1: + for (i = 0; i < n; i++) + { + x = *in++ * gain; + y = 1./(1.+x*x); + + z = .5; + z = .5*(y/z + z); + z = .5*(y/z + z); + z = .5*(y/z + z); + + /* z = .5*(y/z + z); + * z = .5*(y/z + z); + * z = .5*(y/z + z); + */ + + *out++ = x * z; + + } + ctl->c_delay = z; + break; + + case UPPERCLIP: + for (i = 0; i < n; i++) + { + x = *in++ * gain; + + x = (x < 0.0f) ? 0.0f : x; + x = (x > 0.9999f) ? 0.9999f : x; + + *out++ = x; + + } + break; + + default: + + for (i = 0; i < n; i++) *out++ = *in++; + break; + + } + + return (w+5); +} + +static void dist_dsp(t_dist *x, t_signal **sp) +{ + dsp_add(dist_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + +} +void dist_free(void) +{ + +} + +t_class *dist_class; + +void *dist_new(t_floatarg type) +{ + t_dist *x = (t_dist *)pd_new(dist_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("gain")); + outlet_new(&x->x_obj, gensym("signal")); + + dist_gain(x, 1); + x->x_ctl.c_type = (char)type; + x->x_ctl.c_delay = 0; + + return (void *)x; +} + +void dist_tilde_setup(void) +{ + //post("dist~ v0.1"); + dist_class = class_new(gensym("dist~"), (t_newmethod)dist_new, + (t_method)dist_free, sizeof(t_dist), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(dist_class, t_dist, x_f); + class_addmethod(dist_class, (t_method)dist_bang, gensym("bang"), 0); + class_addmethod(dist_class, (t_method)dist_dsp, gensym("dsp"), 0); + class_addmethod(dist_class, (t_method)dist_gain, gensym("gain"), A_FLOAT, 0); + +} + diff --git a/modules/dwt.c b/modules/dwt.c new file mode 100644 index 0000000..caa75ff --- /dev/null +++ b/modules/dwt.c @@ -0,0 +1,893 @@ +/* + * dwt.c - code for discrete wavelet transform + * (symmetric interpolating biorthogonal wavelets using the lifting transform) + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "m_pd.h" +#include +#include +#include +#include + +#define MAXORDER 64 + +typedef enum{DWT,IDWT,DWT16,IDWT16} t_dwttype; + +typedef struct dwtctl +{ + t_float c_update[MAXORDER]; + t_float c_predict[MAXORDER]; + t_int c_nupdate; + t_int c_npredict; + t_int c_levels; + t_int c_fakein; + t_float c_fakeval; + t_int c_mask; + char c_name[16]; + t_int *c_clutter; + t_int *c_unclutter; + t_int c_permute; + t_dwttype c_type; +} t_dwtctl; + +typedef struct dwt +{ + t_object x_obj; + t_float x_f; + t_dwtctl x_ctl; +} t_dwt; + + +static void dwt_even(t_dwt *x, t_floatarg f) +{ + int k = (int)f; + int i, j; + float *p = x->x_ctl.c_predict; + float *u = x->x_ctl.c_update; + float l, xi, xj; + + if ((k>0) && (kx_ctl.c_npredict = 2*k; + x->x_ctl.c_nupdate = 2*k; + } +} + +static void dwt_wavelet(t_dwt *x, t_floatarg f) +{ + int k = (int)f; + t_float *p = x->x_ctl.c_predict; + t_float *u = x->x_ctl.c_update; + t_int *np = &x->x_ctl.c_npredict; + t_int *nu = &x->x_ctl.c_nupdate; + + switch(k) + { + default: + case 1: /* haar */ + *np = *nu = 2; /* actual order is one */ + p[0] = 1; + p[1] = 0; + u[0] = 0; + u[1] = .5; + break; + + case 2: /* hat */ + case 3: + *np = *nu = 2; + p[0] = .5; + p[1] = .5; + u[0] = .25; + u[1] = .25; + break; + + case 4: /* N = 4, N~ = 4 */ + case 5: + *np = *nu = 4; + p[0] = -0.0625; + p[1] = 0.5625; + p[2] = 0.5625; + p[3] = -0.0625; + u[0] = -0.03125; + u[1] = 0.28125; + u[2] = 0.28125; + u[3] = -0.03125; + break; + + case 6: + case 7: + *np = *nu = 6; + p[0] = 0.01171875000000; + p[1] = -0.09765625000000; + p[2] = 0.58593750000000; + p[3] = 0.58593750000000; + p[4] = -0.09765625000000; + p[5] = 0.01171875000000; + u[0] = 0.00585937500000; + u[1] = -0.04882812500000; + u[2] = 0.29296875000000; + u[3] = 0.29296875000000; + u[4] = -0.04882812500000; + u[5] = 0.00585937500000; + break; + } +} + +static inline void dwt_perform_permutation(t_float *S, int n, t_int *f) +{ + t_int k,l; + t_float swap; + for(k=0; kx_ctl; + t_int k, L=0, l, start, power; + t_int nsave = n; + + while(nsave>>=1) L++; + + if (ctl->c_clutter) free(ctl->c_clutter); + if (ctl->c_unclutter) free(ctl->c_unclutter); + + ctl->c_clutter = (t_int *)malloc(n*sizeof(t_int)); + ctl->c_unclutter = (t_int *)malloc(n*sizeof(t_int)); + + + for(l = L, start = n/2, power=1; l>0; l--, start /=2, power *=2) + { + for(k=0; kc_unclutter[start+k] = (1 + 2*k) * power; + } + } + ctl->c_unclutter[0] = 0; + + for(k=0; kc_clutter[ctl->c_unclutter[k]] = k; + + return; + + /* debug */ + for(k=0; kc_clutter[k]); + for(k=0; kc_unclutter[k]); + + exit(1); +} + + + +static void idwt_coef(t_dwt *x, t_floatarg index, t_floatarg value) +{ + x->x_ctl.c_fakein = (int)index; + x->x_ctl.c_fakeval = value; + +} + +static void dwt_print(t_dwt *x) +{ + int i; + + printf("%s: predict: [ ", x->x_ctl.c_name); + for (i=0; ix_ctl.c_npredict; i++) printf("%f ", x->x_ctl.c_predict[i]); + printf("], "); + + printf("update: [ "); + for (i=0; ix_ctl.c_nupdate; i++) printf("%f ", x->x_ctl.c_update[i]); + printf("]\n"); + + + +} + + +static void dwt_filter(t_dwt *x, t_symbol *s, int argc, t_atom *argv) +{ + int invalid_argument = 0; + int i; + + char *name = x->x_ctl.c_name; + + float *pfilter = x->x_ctl.c_predict; + float *ufilter = x->x_ctl.c_update; + float *mask = NULL; + + int *length = NULL; + float sum = 0; + + if (s == gensym("predict")) + { + mask = pfilter; + length = &(x->x_ctl.c_npredict); + } + else if (s == gensym("update")) + { + mask = ufilter; + length = &(x->x_ctl.c_nupdate); + } + else if (s == gensym("mask")) + { + mask = NULL; + } + else + { + return; + } + + if (argc >= MAXORDER) post("%s: error, maximum order exceeded.",name); + else if ((x->x_ctl.c_type == DWT16 || x->x_ctl.c_type == IDWT16 ) && (argc != 16)) + post("%s: error, need to have 16 coefficients.",name); + else if (argc == 0) post("%s: no arguments given.",name); + else if (argc & 1) post("%s: error, only an even number of coefficients is allowed.", name); + else + { + for (i=0; ix_ctl.c_npredict = argc; + x->x_ctl.c_nupdate = argc; + } + } + + } + +} + + + +static inline void dwtloop(float *vector, + int source, + int dest, + int increment, + int backup, + int numcoef, + int mask, + float *filter, + int filtlength, + float sign) +{ + + int k,m; + float acc; + + for (k = 0; k < numcoef; k++) + { + acc = 0; + for (m = 0; m < filtlength; m++) + { + + acc += filter[m] * vector[source]; + source += increment; + source &= mask; + } + vector[dest] += sign * acc; + dest += increment; + source -= backup; + source &= mask; + } + +} + +static inline void dwtloop16(float *vector, + int source, + int dest, + int increment, + int backup, + int numcoef, + int mask, + float *filter, + int filtlength, /* ignored, set to 16 */ + float sign) +{ + + int k,m; + float acc; + + for (k = 0; k < numcoef; k++) + { + acc = 0; + + acc += filter[0] * vector[source]; + source += increment; + source &= mask; + + acc += filter[1] * vector[source]; + source += increment; + source &= mask; + + acc += filter[2] * vector[source]; + source += increment; + source &= mask; + + acc += filter[3] * vector[source]; + source += increment; + source &= mask; + + acc += filter[4] * vector[source]; + source += increment; + source &= mask; + + acc += filter[5] * vector[source]; + source += increment; + source &= mask; + + acc += filter[6] * vector[source]; + source += increment; + source &= mask; + + acc += filter[7] * vector[source]; + source += increment; + source &= mask; + + acc += filter[8] * vector[source]; + source += increment; + source &= mask; + + acc += filter[9] * vector[source]; + source += increment; + source &= mask; + + acc += filter[10] * vector[source]; + source += increment; + source &= mask; + + acc += filter[11] * vector[source]; + source += increment; + source &= mask; + + acc += filter[12] * vector[source]; + source += increment; + source &= mask; + + acc += filter[13] * vector[source]; + source += increment; + source &= mask; + + acc += filter[14] * vector[source]; + source += increment; + source &= mask; + + acc += filter[15] * vector[source]; + source += increment; + source &= mask; + + vector[dest] += sign * acc; + dest += increment; + source -= backup; + source &= mask; + } + +} + + + + + +static t_int *dwt_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_dwtctl *ctl = (t_dwtctl *)(w[1]); + + + t_int n = (t_int)(w[2]); + + int i; + + int numcoef = n/2; + /* int source_u = ((1 - ctl->c_nupdate)/2 - 1); + * int source_p = ((1 - ctl->c_npredict)/2); + */ + int source_u = ((2 - ctl->c_nupdate) - 1); + int source_p = ((2 - ctl->c_npredict)); + int increment = 2; + int dest = 1; + int backup_u = (ctl->c_nupdate-1)*2; + int backup_p = (ctl->c_npredict-1)*2; + + /* copy input to output */ + if (in != out) + for (i=0; ic_levels; i++){ + + + /* foreward predict */ + dwtloop(out, (source_p & (n-1)), dest, increment, backup_p, numcoef, n-1, ctl->c_predict, ctl->c_npredict, -1); + + + /* foreward update */ + dwtloop(out, (source_u & (n-1)), 0, increment, backup_u, numcoef, n-1, ctl->c_update, ctl->c_nupdate, +1); + + + /* update control parameters */ + numcoef /= 2; + source_p *= 2; + source_u *= 2; + backup_p *= 2; + backup_u *= 2; + increment *= 2; + dest *= 2; + } + + if (ctl->c_permute) + dwt_perform_permutation(out, n, ctl->c_unclutter); + + + return (w+5); +} + + + + +static t_int *idwt_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_dwtctl *ctl = (t_dwtctl *)(w[1]); + + + t_int n = (t_int)(w[2]); + + int i; + + int numcoef = 1; + int source_u = ((2 - ctl->c_nupdate) - 1) * (n/2); + int source_p = ((2 - ctl->c_npredict)) * (n/2); + int increment = n; + int dest = n/2; + int backup_u = (ctl->c_nupdate-1)*n; + int backup_p = (ctl->c_npredict-1)*n; + int fake_in = ctl->c_fakein; + float fake_val = ctl->c_fakeval; + + /* copy input to output */ + if (in != out) + for (i=0; i= 0) && (fake_inc_permute) + dwt_perform_permutation(out, n, ctl->c_clutter); + + + /* backward transform */ + + + /* iterate over all levels */ + for (i=0; i < ctl->c_levels; i++){ + + /* backward update */ + dwtloop(out, (source_u & (n-1)), 0, increment, backup_u, numcoef, n-1, ctl->c_update, ctl->c_nupdate, -1); + + + /* backward predict */ + dwtloop(out, (source_p & (n-1)), dest, increment, backup_p, numcoef, n-1, ctl->c_predict, ctl->c_npredict, +1); + + /* update control parameters */ + numcoef *= 2; + source_p /= 2; + source_u /= 2; + backup_p /= 2; + backup_u /= 2; + increment /= 2; + dest /= 2; + } + + + + return (w+5); +} + +static t_int *dwt16_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_dwtctl *ctl = (t_dwtctl *)(w[1]); + + + t_int n = (t_int)(w[2]); + + int i; + + int numcoef = n/2; + /* int source_u = ((1 - ctl->c_nupdate)/2 - 1); + * int source_p = ((1 - ctl->c_npredict)/2); + */ + int source_u = ((2 - ctl->c_nupdate) - 1); + int source_p = ((2 - ctl->c_npredict)); + int increment = 2; + int dest = 1; + int backup_u = (ctl->c_nupdate-1)*2; + int backup_p = (ctl->c_npredict-1)*2; + + /* copy input to output */ + if (in != out) + for (i=0; ic_levels; i++){ + + + /* foreward predict */ + dwtloop16(out, (source_p & (n-1)), dest, increment, backup_p, numcoef, n-1, ctl->c_predict, 16, -1); + + + /* foreward update */ + dwtloop16(out, (source_u & (n-1)), 0, increment, backup_u, numcoef, n-1, ctl->c_update, 16, +1); + + + /* update control parameters */ + numcoef /= 2; + source_p *= 2; + source_u *= 2; + backup_p *= 2; + backup_u *= 2; + increment *= 2; + dest *= 2; + } + + if (ctl->c_permute) + dwt_perform_permutation(out, n, ctl->c_unclutter); + + + return (w+5); +} + + + + +static t_int *idwt16_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_dwtctl *ctl = (t_dwtctl *)(w[1]); + + + t_int n = (t_int)(w[2]); + + int i; + + int numcoef = 1; + int source_u = ((2 - ctl->c_nupdate) - 1) * (n/2); + int source_p = ((2 - ctl->c_npredict)) * (n/2); + int increment = n; + int dest = n/2; + int backup_u = (ctl->c_nupdate-1)*n; + int backup_p = (ctl->c_npredict-1)*n; + int fake_in = ctl->c_fakein; + float fake_val = ctl->c_fakeval; + + /* copy input to output */ + if (in != out) + for (i=0; i= 0) && (fake_inc_permute) + dwt_perform_permutation(out, n, ctl->c_clutter); + + + /* backward transform */ + + + /* iterate over all levels */ + for (i=0; i < ctl->c_levels; i++){ + + /* backward update */ + dwtloop16(out, (source_u & (n-1)), 0, increment, backup_u, numcoef, n-1, ctl->c_update, 16, -1); + + + /* backward predict */ + dwtloop16(out, (source_p & (n-1)), dest, increment, backup_p, numcoef, n-1, ctl->c_predict, 16, +1); + + /* update control parameters */ + numcoef *= 2; + source_p /= 2; + source_u /= 2; + backup_p /= 2; + backup_u /= 2; + increment /= 2; + dest /= 2; + } + + + + return (w+5); +} + + + +static void dwt_dsp(t_dwt *x, t_signal **sp) +{ + + int n = sp[0]->s_n; + int ln = 0; + + dwt_permutation(x, n); + + x->x_ctl.c_mask = n-1; + while (n >>= 1) ln++; + x->x_ctl.c_levels = ln; + + switch(x->x_ctl.c_type){ + case DWT: + dsp_add(dwt_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + break; + case IDWT: + dsp_add(idwt_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + break; + case DWT16: + dsp_add(dwt16_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + break; + case IDWT16: + dsp_add(idwt16_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + break; + + + } +} + + +void dwt_free(t_dwt *x) +{ + + if (x->x_ctl.c_clutter) free(x->x_ctl.c_clutter); + if (x->x_ctl.c_unclutter) free(x->x_ctl.c_unclutter); + + +} + +t_class *dwt_class, *idwt_class, *dwt16_class, *idwt16_class; + + +static void dwt_reset(t_dwt *x) +{ + bzero(x->x_ctl.c_update, 16*sizeof(t_float)); + bzero(x->x_ctl.c_predict, 16*sizeof(t_float)); + + x->x_ctl.c_update[7] = .25; + x->x_ctl.c_update[8] = .25; + x->x_ctl.c_nupdate = 16; + + x->x_ctl.c_predict[7] = .5; + x->x_ctl.c_predict[8] = .5; + x->x_ctl.c_npredict = 16; + + x->x_ctl.c_fakein = -1; + x->x_ctl.c_fakeval = 0; + +} + + +static void *dwt_new_common(t_floatarg permute) +{ + t_dwt *x = (t_dwt *)pd_new(dwt_class); + int i; + + outlet_new(&x->x_obj, gensym("signal")); + + /* init data */ + dwt_reset(x); + + x->x_ctl.c_clutter = NULL; + x->x_ctl.c_unclutter = NULL; + x->x_ctl.c_permute = (t_int) permute; + + return (void *)x; + + +} + +static void *dwt_new(t_floatarg permute) +{ + t_dwt *x = dwt_new_common(permute); + sprintf(x->x_ctl.c_name,"dwt"); + x->x_ctl.c_type = DWT; + return (void *)x; +} + + +static void *idwt_new(t_floatarg permute) +{ + t_dwt *x = dwt_new_common(permute); + sprintf(x->x_ctl.c_name,"idwt"); + x->x_ctl.c_type = IDWT; + return (void *)x; +} + +static void *dwt16_new(t_floatarg permute) +{ + t_dwt *x = dwt_new_common(permute); + sprintf(x->x_ctl.c_name,"dwt16"); + x->x_ctl.c_type = DWT16; + return (void *)x; +} + + +static void *idwt16_new(t_floatarg permute) +{ + t_dwt *x = dwt_new_common(permute); + sprintf(x->x_ctl.c_name,"idwt16"); + x->x_ctl.c_type = IDWT16; + return (void *)x; +} + + +void dwt_tilde_setup(void) +{ + //post("dwt~ v0.1"); + + + dwt_class = class_new(gensym("dwt~"), (t_newmethod)dwt_new, + (t_method)dwt_free, sizeof(t_dwt), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(dwt_class, t_dwt, x_f); + class_addmethod(dwt_class, (t_method)dwt_print, gensym("print"), 0); + class_addmethod(dwt_class, (t_method)dwt_reset, gensym("reset"), 0); + class_addmethod(dwt_class, (t_method)dwt_dsp, gensym("dsp"), 0); + + class_addmethod(dwt_class, (t_method)dwt_filter, gensym("predict"), A_GIMME, 0); + class_addmethod(dwt_class, (t_method)dwt_filter, gensym("update"), A_GIMME, 0); + class_addmethod(dwt_class, (t_method)dwt_filter, gensym("mask"), A_GIMME, 0); + + class_addmethod(dwt_class, (t_method)dwt_even, gensym("even"), A_DEFFLOAT, 0); + class_addmethod(dwt_class, (t_method)idwt_coef, gensym("coef"), A_DEFFLOAT, A_DEFFLOAT, 0); + + + + /*class_addmethod(dwt_class, (t_method)dwt_wavelet, gensym("wavelet"), A_DEFFLOAT, 0); */ + + + idwt_class = class_new(gensym("idwt~"), (t_newmethod)idwt_new, + (t_method)dwt_free, sizeof(t_dwt), 0, A_DEFFLOAT, 0); + + CLASS_MAINSIGNALIN(idwt_class, t_dwt, x_f); + class_addmethod(idwt_class, (t_method)dwt_print, gensym("print"), 0); + class_addmethod(idwt_class, (t_method)dwt_dsp, gensym("dsp"), 0); + + class_addmethod(idwt_class, (t_method)dwt_filter, gensym("predict"), A_GIMME, 0); + class_addmethod(idwt_class, (t_method)dwt_filter, gensym("update"), A_GIMME, 0); + class_addmethod(idwt_class, (t_method)dwt_filter, gensym("mask"), A_GIMME, 0); + + class_addmethod(idwt_class, (t_method)idwt_coef, gensym("coef"), A_DEFFLOAT, A_DEFFLOAT, 0); + + class_addmethod(idwt_class, (t_method)dwt_even, gensym("even"), A_DEFFLOAT, 0); + + + + dwt16_class = class_new(gensym("dwt16~"), (t_newmethod)dwt16_new, + (t_method)dwt_free, sizeof(t_dwt), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(dwt16_class, t_dwt, x_f); + class_addmethod(dwt16_class, (t_method)dwt_print, gensym("print"), 0); + class_addmethod(dwt16_class, (t_method)dwt_reset, gensym("reset"), 0); + class_addmethod(dwt16_class, (t_method)dwt_dsp, gensym("dsp"), 0); + + class_addmethod(dwt16_class, (t_method)dwt_filter, gensym("predict"), A_GIMME, 0); + class_addmethod(dwt16_class, (t_method)dwt_filter, gensym("update"), A_GIMME, 0); + class_addmethod(dwt16_class, (t_method)dwt_filter, gensym("mask"), A_GIMME, 0); + + + + + idwt16_class = class_new(gensym("idwt16~"), (t_newmethod)idwt16_new, + (t_method)dwt_free, sizeof(t_dwt), 0, A_DEFFLOAT, 0); + + CLASS_MAINSIGNALIN(idwt16_class, t_dwt, x_f); + class_addmethod(idwt16_class, (t_method)dwt_print, gensym("print"), 0); + class_addmethod(idwt16_class, (t_method)dwt_dsp, gensym("dsp"), 0); + + class_addmethod(idwt16_class, (t_method)dwt_filter, gensym("predict"), A_GIMME, 0); + class_addmethod(idwt16_class, (t_method)dwt_filter, gensym("update"), A_GIMME, 0); + class_addmethod(idwt16_class, (t_method)dwt_filter, gensym("mask"), A_GIMME, 0); + + class_addmethod(idwt16_class, (t_method)idwt_coef, gensym("coef"), A_DEFFLOAT, A_DEFFLOAT, 0); + + + + +} + diff --git a/modules/dynwav.c b/modules/dynwav.c new file mode 100644 index 0000000..0ff75f3 --- /dev/null +++ b/modules/dynwav.c @@ -0,0 +1,318 @@ +/* + * dynwav.c - dynamic wavetable oscillator + * data organization is in (real, imag) pairs + * the first 2 components are (DC, NY) + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "m_pd.h" +#include +#include +#include +#include + +#define MAXORDER 1024 + +typedef struct dynwavctl +{ + t_float *c_buf1; /* current */ + t_float *c_buf2; /* old */ + t_int c_order; + +} t_dynwavctl; + +typedef struct dynwav +{ + t_object x_obj; + t_float x_f; + t_dynwavctl x_ctl; +} t_dynwav; + + +static t_int *dynwav_perform(t_int *w) +{ + + + t_float *wave = (float *)(w[3]); + t_float *freq = (float *)(w[4]); + t_float *out = (float *)(w[5]); + t_dynwavctl *ctl = (t_dynwavctl *)(w[1]); + t_int n = (t_int)(w[2]); + + t_float *buf, *dbuf, *swap; + + int i; + int mask = n-1; + + + /* swap buffer pointers */ + swap = ctl->c_buf1; /* this is the last one stored */ + buf = ctl->c_buf1 = ctl->c_buf2; /* put oldest in newest to overwrite */ + dbuf = ctl->c_buf2 = swap; /* put last one in oldest */ + + + if (buf && dbuf) + { + + /* store input wavetable in buffer */ + memcpy(buf, wave, n*sizeof(t_float)); + + + for (i = 0; i < n; i++) + { + float findex = *freq++ * (t_float)n; + int index = findex; + float frac, a, b, c, d, cminusb, q, r; + int ia, ib, ic, id; + + frac = findex - index; + + ia = (index-1) & mask; + ib = (index ) & mask; + ic = (index+1) & mask; + id = (index+2) & mask; + + q = i+1; + q /= n; + + r = n-1-i; + r /= n; + + /* get 4 points, wrap index */ + a = q * buf[ia] + r * dbuf[ia]; + b = q * buf[ib] + r * dbuf[ib]; + c = q * buf[ic] + r * dbuf[ic]; + d = q * buf[id] + r * dbuf[id]; + + cminusb = c-b; + *out++ = b + frac * (cminusb - 0.5f * (frac-1.) * + ((a - d + 3.0f * cminusb) * frac + + (b - a - cminusb))); + } + + } + return (w+6); +} + +static t_int *dynwav_perform_8point(t_int *w) /* werkt nog nie tegoei */ +{ + + + t_float *wave = (float *)(w[3]); + t_float *freq = (float *)(w[4]); + t_float *out = (float *)(w[5]); + t_dynwavctl *ctl = (t_dynwavctl *)(w[1]); + t_int n = (t_int)(w[2]); + + t_float *buf, *dbuf, *swap; + + int i; + int mask = n-1; + + + /* swap buffer pointers */ + swap = ctl->c_buf1; /* this is the last one stored */ + buf = ctl->c_buf1 = ctl->c_buf2; /* put oldest in newest to overwrite */ + dbuf = ctl->c_buf2 = swap; /* put last one in oldest */ + + + if (buf && dbuf) + { + + /* const float N1 = 1 / ( 2 * (1-(1/9)) * (1-(1/25)) * (1-(1/49)) ); + ** const float N2 = 1 / ( (1-(9)) * 2 * (1-(9/25)) * (1-(9/49)) ); + ** const float N3 = 1 / ( (1-(25)) * (1-(25/9)) * 2 * (1-(25/49)) ); + ** const float N4 = 1 / ( (1-(49)) * (1-(49/9)) * (1-(49/25)) * 2 ); + */ + + const float N1 = 0.59814453125; + const float N2 = -0.11962890625; + const float N3 = 0.02392578125; + const float N4 = -0.00244140625; + + + /* store input wavetable in buffer */ + memcpy(buf, wave, n*sizeof(t_float)); + + + for (i = 0; i < n; i++) + { + float findex = *freq++ * (t_float)n; + int index = findex; + float frac, q, r, fm, fp, fe, fo; + float x1, x2, x3, x4; + float g1, g2, g3, g4; + float gg, g2g3g4, g1g3g4, g1g2g4, g1g2g3; + float acc; + int im, ip; + + frac = 2 *(findex - index) - 1; + + x1 = frac; + x2 = frac/3; + x3 = frac/5; + x4 = frac/7; + + g1 = 1 - x1*x1; + g2 = 1 - x2*x2; + g3 = 1 - x3*x3; + g4 = 1 - x4*x4; + + gg = g3 * g4; + g2g3g4 = g2 * gg; /* 1 */ + g1g3g4 = g1 * gg; /* 2 */ + gg = g1 * g2; + g1g2g4 = g4 * gg; /* 3 */ + g1g2g3 = g3 * gg; /* 4 */ + + + /* triangle interpolation between current and past wavetable*/ + q = i+1; + q /= n; + + r = n-1-i; + r /= n; + + + /* 1, -1*/ + im = (index ) & mask; + ip = (index+1) & mask; + fm = q * buf[im] + r * dbuf[im]; + fp = q * buf[ip] + r * dbuf[ip]; + fe = fp + fm; + fo = fp - fm; + + acc = N1 * g2g3g4 * (fe + x1*fo); + + /* 2, -2 */ + im = (index-1) & mask; + ip = (index+2) & mask; + fm = q * buf[im] + r * dbuf[im]; + fp = q * buf[ip] + r * dbuf[ip]; + fe = fp + fm; + fo = fp - fm; + + acc += N2 * g1g3g4 * (fe + x2*fo); + + /* 3, -3 */ + im = (index-2) & mask; + ip = (index+3) & mask; + fm = q * buf[im] + r * dbuf[im]; + fp = q * buf[ip] + r * dbuf[ip]; + fe = fp + fm; + fo = fp - fm; + + acc += N3 * g1g2g4 * (fe + x3*fo); + + /* 4, -4 */ + im = (index-3) & mask; + ip = (index+4) & mask; + fm = q * buf[im] + r * dbuf[im]; + fp = q * buf[ip] + r * dbuf[ip]; + fe = fp + fm; + fo = fp - fm; + + acc += N4 * g1g2g3 * (fe + x4*fo); + + + *out++ = acc; + + } + + } + return (w+6); +} + + +static void dynwav_dsp(t_dynwav *x, t_signal **sp) +{ + int n = sp[0]->s_n; + int k; + + if (x->x_ctl.c_order != n) + { + if (x->x_ctl.c_buf1) free (x->x_ctl.c_buf1); + if (x->x_ctl.c_buf2) free (x->x_ctl.c_buf2); + + x->x_ctl.c_buf1 = (t_float *)malloc(n*sizeof(t_float)); + x->x_ctl.c_buf2 = (t_float *)malloc(n*sizeof(t_float)); + + for(k=0; kx_ctl.c_buf1[k] = 0; + x->x_ctl.c_buf2[k] = 0; + } + + x->x_ctl.c_order = n; + } + + + dsp_add(dynwav_perform_8point, 5, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec); + + +} +static void dynwav_free(t_dynwav *x) +{ + + if (x->x_ctl.c_buf1) free (x->x_ctl.c_buf1); + if (x->x_ctl.c_buf2) free (x->x_ctl.c_buf2); + +} + +t_class *dynwav_class; + +static void *dynwav_new(t_floatarg order) +{ + t_dynwav *x = (t_dynwav *)pd_new(dynwav_class); + int iorder = (int)order; + int i, n=64, k; + + /* in 2 */ + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); + + /* out 1 */ + outlet_new(&x->x_obj, gensym("signal")); + + + + /* init data */ + x->x_ctl.c_buf1 = (t_float *)malloc(n*sizeof(t_float)); + x->x_ctl.c_buf2 = (t_float *)malloc(n*sizeof(t_float)); + + for(k=0; kx_ctl.c_buf1[k] = 0; + x->x_ctl.c_buf2[k] = 0; + } + + x->x_ctl.c_order = n; + + return (void *)x; +} + +void dynwav_tilde_setup(void) +{ + //post("dynwav~ v0.1"); + dynwav_class = class_new(gensym("dynwav~"), (t_newmethod)dynwav_new, + (t_method)dynwav_free, sizeof(t_dynwav), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(dynwav_class, t_dynwav, x_f); + class_addmethod(dynwav_class, (t_method)dynwav_dsp, gensym("dsp"), 0); + + +} + diff --git a/modules/ead.c b/modules/ead.c new file mode 100644 index 0000000..8b93faa --- /dev/null +++ b/modules/ead.c @@ -0,0 +1,153 @@ +/* + * ead.c - exponential attack decay envelope + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "extlib_util.h" + +/* pointer to */ +t_class *ead_class; + + +/* state data fpr attack/decay dsp plugin */ +typedef struct eadctl +{ + t_float c_attack; + t_float c_decay; + t_float c_state; + t_float c_target; +} t_eadctl; + + +/* object data structure */ +typedef struct ead +{ + t_object x_obj; + t_eadctl x_ctl; +} t_ead; + + + +static void ead_attack(t_ead *x, t_floatarg f) +{ + x->x_ctl.c_attack = milliseconds_2_one_minus_realpole(f); +} + +static void ead_decay(t_ead *x, t_floatarg f) +{ + x->x_ctl.c_decay = milliseconds_2_one_minus_realpole(f); +} + +static void ead_start(t_ead *x) +{ + x->x_ctl.c_target = 1; +} + + +/* dsp callback function, not a method */ +static t_int *ead_perform(t_int *w) +{ + + /* interprete arguments */ + t_float *out = (float *)(w[3]); + t_eadctl *ctl = (t_eadctl *)(w[1]); + t_float attack = ctl->c_attack; + t_float decay = ctl->c_decay; + t_float state = ctl->c_state; + t_float target = ctl->c_target; + t_int n = (t_int)(w[2]); + + t_int i; + + + /* A/D code */ + + if (target == 1) + /* attack phase */ + { + for (i = 0; i < n; i++) + { + *out++ = state; + state += attack*(1 - state); + } + if (state > ENVELOPE_MAX) + ctl->c_target = 0; + } + + else + /* decay phase */ + for (i = 0; i < n; i++) + { + *out++ = state; + state -= decay*state; + } + + ctl->c_state = state; + + return (w+4); /* pd quirk: pointer for sequencer */ +} + + +static void ead_dsp(t_ead *x, t_signal **sp) +{ + dsp_add(ead_perform, 3, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec); +} + +/* destructor */ +static void ead_free(void) +{ + +} + + + +/* constructor */ +static void *ead_new(t_floatarg attack, t_floatarg decay, t_floatarg sustain, t_floatarg release) +{ + /* create instance */ + t_ead *x = (t_ead *)pd_new(ead_class); + /* create new inlets, convert incoming message float to attack/decay */ + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("attack")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("decay")); + /* create a dsp outlet */ + outlet_new(&x->x_obj, gensym("signal")); + + /* initialize */ + x->x_ctl.c_state = 0; + x->x_ctl.c_target = 0; + ead_attack(x, attack); + ead_decay(x, decay); + + /* return instance */ + return (void *)x; +} + +void ead_tilde_setup(void) +{ + //post("ead~ v0.1"); + + ead_class = class_new(gensym("ead~"), (t_newmethod)ead_new, + (t_method)ead_free, sizeof(t_ead), 0, A_DEFFLOAT, A_DEFFLOAT, 0); + + + class_addmethod(ead_class, (t_method)ead_start, gensym("start"), 0); + class_addmethod(ead_class, (t_method)ead_start, gensym("bang"), 0); + class_addmethod(ead_class, (t_method)ead_dsp, gensym("dsp"), 0); + class_addmethod(ead_class, (t_method)ead_attack, gensym("attack"), A_FLOAT, 0); + class_addmethod(ead_class, (t_method)ead_decay, gensym("decay"), A_FLOAT, 0); +} + diff --git a/modules/eadsr.c b/modules/eadsr.c new file mode 100644 index 0000000..0e0b9db --- /dev/null +++ b/modules/eadsr.c @@ -0,0 +1,171 @@ +/* + * eadsr.c - exponential attack decay sustain release envelope + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "extlib_util.h" + +typedef struct eadsrctl +{ + t_float c_attack; + t_float c_decay; + t_float c_sustain; + t_float c_release; + t_float c_state; + t_float c_target; +} t_eadsrctl; + +typedef struct eadsr +{ + t_object x_obj; + t_float x_sr; + t_eadsrctl x_ctl; +} t_eadsr; + +void eadsr_attack(t_eadsr *x, t_floatarg f) +{ + x->x_ctl.c_attack = milliseconds_2_one_minus_realpole(f); +} + +void eadsr_decay(t_eadsr *x, t_floatarg f) +{ + x->x_ctl.c_decay = milliseconds_2_one_minus_realpole(f); +} + +void eadsr_sustain(t_eadsr *x, t_floatarg f) +{ + if (f>ENVELOPE_MAX) f = ENVELOPE_MAX; + if (fx_ctl.c_sustain = f; +} + +void eadsr_release(t_eadsr *x, t_floatarg f) +{ + x->x_ctl.c_release = milliseconds_2_one_minus_realpole(f); + +} + +void eadsr_start(t_eadsr *x) +{ + x->x_ctl.c_target = 1; + +} + +void eadsr_stop(t_eadsr *x) +{ + x->x_ctl.c_target = 0; + +} + +static t_int *eadsr_perform(t_int *w) +{ + t_float *out = (float *)(w[3]); + t_eadsrctl *ctl = (t_eadsrctl *)(w[1]); + t_float attack = ctl->c_attack; + t_float decay = ctl->c_decay; + t_float sustain = ctl->c_sustain; + t_float release = ctl->c_release; + t_float state = ctl->c_state; + t_float target = ctl->c_target; + t_int n = (t_int)(w[2]); + + t_int i; + + + if (target == 1) + /* attack phase */ + { + for (i = 0; i < n; i++) + { + *out++ = state; + state += attack*(1 - state); + } + if (state > ENVELOPE_MAX) + ctl->c_target = sustain; + } + + else if (target == 0) + /* release phase */ + for (i = 0; i < n; i++) + { + *out++ = state; + state -= release*state; + } + + else + /* decay phase */ + for (i = 0; i < n; i++) + { + *out++ = state; + state -= decay*(state-sustain); + } + + ctl->c_state = state; + return (w+4); +} + +static void eadsr_dsp(t_eadsr *x, t_signal **sp) +{ + x->x_sr = sp[0]->s_sr; + dsp_add(eadsr_perform, 3, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec); + +} +void eadsr_free(void) +{ + +} + +t_class *eadsr_class; + +void *eadsr_new(t_floatarg attack, t_floatarg decay, t_floatarg sustain, t_floatarg release) +{ + t_eadsr *x = (t_eadsr *)pd_new(eadsr_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("attack")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("decay")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("sustain")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("release")); + outlet_new(&x->x_obj, gensym("signal")); + + x->x_ctl.c_state = 0; + x->x_ctl.c_target = 0; + eadsr_attack(x, attack); + eadsr_decay(x, decay); + eadsr_sustain(x, sustain); + eadsr_release(x, release); + + + return (void *)x; +} + +void eadsr_tilde_setup(void) +{ + //post("eadsr~ v0.1"); + eadsr_class = class_new(gensym("eadsr~"), (t_newmethod)eadsr_new, + (t_method)eadsr_free, sizeof(t_eadsr), 0, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(eadsr_class, (t_method)eadsr_start, gensym("start"), 0); + class_addmethod(eadsr_class, (t_method)eadsr_start, gensym("bang"), 0); + class_addmethod(eadsr_class, (t_method)eadsr_stop, gensym("stop"), 0); + class_addmethod(eadsr_class, (t_method)eadsr_dsp, gensym("dsp"), 0); + class_addmethod(eadsr_class, (t_method)eadsr_attack, gensym("attack"), A_FLOAT, 0); + class_addmethod(eadsr_class, (t_method)eadsr_decay, gensym("decay"), A_FLOAT, 0); + class_addmethod(eadsr_class, (t_method)eadsr_sustain, gensym("sustain"), A_FLOAT, 0); + class_addmethod(eadsr_class, (t_method)eadsr_release, gensym("release"), A_FLOAT, 0); + + +} + diff --git a/modules/ear.c b/modules/ear.c new file mode 100644 index 0000000..efe9b3f --- /dev/null +++ b/modules/ear.c @@ -0,0 +1,134 @@ +/* + * ear.c - exponential attack release envelope + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "extlib_util.h" + +typedef struct earctl +{ + t_float c_attack; + t_float c_release; + t_float c_state; + t_float c_target; +} t_earctl; + +typedef struct ear +{ + t_object x_obj; + t_float x_sr; + t_earctl x_ctl; +} t_ear; + +void ear_attack(t_ear *x, t_floatarg f) +{ + x->x_ctl.c_attack = milliseconds_2_one_minus_realpole(f); +} + +void ear_release(t_ear *x, t_floatarg f) +{ + x->x_ctl.c_release = milliseconds_2_one_minus_realpole(f); +} + +void ear_start(t_ear *x) +{ + x->x_ctl.c_target = 1; + +} + +void ear_stop(t_ear *x) +{ + x->x_ctl.c_target = 0; + +} + +static t_int *ear_perform(t_int *w) +{ + t_float *out = (float *)(w[3]); + t_earctl *ctl = (t_earctl *)(w[1]); + t_float attack = ctl->c_attack; + t_float release = ctl->c_release; + t_float state = ctl->c_state; + t_float target = ctl->c_target; + t_int n = (t_int)(w[2]); + + t_int i; + + if (target) /* attack phase */ + for (i = 0; i < n; i++) + { + *out++ = state; + state += attack*(1 - state); + } + else /* release phase */ + for (i = 0; i < n; i++) + { + *out++ = state; + state -= release*state; + } + + ctl->c_state = state; + return (w+4); +} + +static void ear_dsp(t_ear *x, t_signal **sp) +{ + x->x_sr = sp[0]->s_sr; + dsp_add(ear_perform, 3, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec); + +} +void ear_free(void) +{ + +} + + +t_class *ear_class; /* attack - release */ + +void *ear_new(t_floatarg attack, t_floatarg release) +{ + t_ear *x = (t_ear *)pd_new(ear_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("attack")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("release")); + outlet_new(&x->x_obj, gensym("signal")); + + ear_attack(x,attack); + ear_release(x,release); + x->x_ctl.c_state = 0; + x->x_ctl.c_target = 0; + + return (void *)x; +} + + +void ear_tilde_setup(void) +{ + //post("ear~ v0.1"); + ear_class = class_new(gensym("ear~"), (t_newmethod)ear_new, + (t_method)ear_free, sizeof(t_ear), 0, A_DEFFLOAT, A_DEFFLOAT, 0); + class_addmethod(ear_class, (t_method)ear_start, gensym("start"), 0); + class_addmethod(ear_class, (t_method)ear_start, gensym("bang"), 0); + class_addmethod(ear_class, (t_method)ear_stop, gensym("stop"), 0); + class_addmethod(ear_class, (t_method)ear_dsp, gensym("dsp"), 0); + class_addmethod(ear_class, + (t_method)ear_attack, gensym("attack"), A_FLOAT, 0); + class_addmethod(ear_class, + (t_method)ear_release, gensym("release"), A_FLOAT, 0); + + +} + diff --git a/modules/ffpoly.c b/modules/ffpoly.c new file mode 100644 index 0000000..023f29d --- /dev/null +++ b/modules/ffpoly.c @@ -0,0 +1,173 @@ +/* + * ffpoly.c - compute a finite field polynomial + * Copyright (c) by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include "m_pd.h" +#include + + + + +typedef struct ffpoly_struct +{ + t_object x_obj; + t_float x_f; + + t_outlet *x_outlet; + t_int *x_coef; + t_int x_poly_order; + t_int x_field_order; + + t_int x_lastpackedcoef; + + + +} t_ffpoly; + + + + +static void ffpoly_compute(t_ffpoly *x, t_floatarg fcoef) +{ + int in = (int)fcoef; + int fo = x->x_field_order; + int po = x->x_poly_order; + int* c = x->x_coef; + int i, out; + + in %= fo; + if (in < 0) in += fo; + + out = c[po]; + for (i=po-1; i>=0; i--){ + out *= in; + out += c[i]; + out %= fo; + } + + + outlet_float(x->x_outlet, (float)out); +} + + +/* this sets all coefficients given one float */ +static void ffpoly_coefficients(t_ffpoly *x, t_floatarg fcoef) +{ + int coef = (int)fcoef; + int i; + if (coef < 0) coef = -coef; + + x->x_lastpackedcoef = coef; + + for (i=0; ix_poly_order + 1; i++){ + x->x_coef[i] = coef % x->x_field_order; + coef = coef / x->x_field_order; + } + + +} + +/* this sets one coefficient */ +static void ffpoly_coef(t_ffpoly *x, t_floatarg index, t_floatarg val) +{ + int i = (int)index; + int v = (int)val; + if (i<0) return; + if (i>x->x_poly_order) return; + + v %= x->x_field_order; + if (v<0) v += x->x_field_order; + + x->x_coef[i] = v; + + +} + +static void ffpoly_fieldorder(t_ffpoly *x, t_floatarg ffieldorder) +{ + int i; + int order = (int)ffieldorder; + if (order < 2) order = 2; + x->x_field_order = order; + + for (i=0; ix_poly_order+1; i++) + x->x_coef[i] %= x->x_field_order; + + //ffpoly_coefficients(x, x->x_lastpackedcoef); +} + +static void ffpoly_free(t_ffpoly *x) +{ + free (x->x_coef); +} + +t_class *ffpoly_class; + + + +static void *ffpoly_new(t_floatarg fpolyorder, t_floatarg ffieldorder) +{ + t_int polyorder = (int)fpolyorder; + t_int fieldorder = (int)ffieldorder; + + t_ffpoly *x = (t_ffpoly *)pd_new(ffpoly_class); + + if (polyorder < 1) polyorder = 1; + if (fieldorder < 2) fieldorder = 2; + + x->x_poly_order = polyorder; + x->x_field_order = fieldorder; + + x->x_coef = (int *)malloc((x->x_poly_order + 1) * sizeof(int)); + + /* set poly to f(x) = x */ + ffpoly_coefficients(x, x->x_field_order); + + x->x_outlet = outlet_new(&x->x_obj, &s_float); + + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void ffpoly_setup(void) +{ + + + ffpoly_class = class_new(gensym("ffpoly"), (t_newmethod)ffpoly_new, + (t_method)ffpoly_free, sizeof(t_ffpoly), 0, A_DEFFLOAT, A_DEFFLOAT, A_NULL); + + class_addmethod(ffpoly_class, (t_method)ffpoly_coefficients, gensym("coefficients"), A_FLOAT, A_NULL); + + class_addmethod(ffpoly_class, (t_method)ffpoly_coef, gensym("coef"), A_FLOAT, A_FLOAT, A_NULL); + class_addmethod(ffpoly_class, (t_method)ffpoly_fieldorder, gensym("order"), A_FLOAT, A_NULL); + class_addfloat(ffpoly_class, (t_method)ffpoly_compute); + + +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/fwarp.c b/modules/fwarp.c new file mode 100644 index 0000000..28fe024 --- /dev/null +++ b/modules/fwarp.c @@ -0,0 +1,61 @@ +/* + * fwarp.c - converts a frequency to a "standard" tangent warped freq + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "m_pd.h" +#include + +#define SEQL 16 + + +typedef struct fwarp +{ + t_object t_ob; + t_outlet *x_out; +} t_fwarp; + +static void fwarp_float(t_fwarp *x, t_floatarg f) +{ + float twopi = 2.0f * M_PI; + float sr = sys_getsr(); + f /= sr; + f = tan(twopi * f) / twopi; + outlet_float(x->x_out, f * sr); +} + +static void fwarp_free(void) +{ +} + +t_class *fwarp_class; + +static void *fwarp_new(void) +{ + t_fwarp *x = (t_fwarp *)pd_new(fwarp_class); + x->x_out = outlet_new(&x->t_ob, gensym("float")); + return (void *)x; +} + +void fwarp_setup(void) +{ + fwarp_class = class_new(gensym("fwarp"), (t_newmethod)fwarp_new, + (t_method)fwarp_free, sizeof(t_fwarp), 0, 0); + class_addfloat(fwarp_class, fwarp_float); +} + diff --git a/modules/lattice.c b/modules/lattice.c new file mode 100644 index 0000000..9403393 --- /dev/null +++ b/modules/lattice.c @@ -0,0 +1,143 @@ +/* + * lattice.c - a lattice filter for pd + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + + +#include "m_pd.h" +#include + +#define maxorder 1024 + +typedef struct latticesegment +{ + t_float delay; // delay element + t_float rc; // reflection coefficient +} t_latticesegment; + +typedef struct latticectl +{ + t_latticesegment c_segment[maxorder]; // array of lattice segment data + t_int c_segments; +} t_latticectl; + +typedef struct lattice +{ + t_object x_obj; + t_float x_f; + t_latticectl x_ctl; +} t_lattice; + + + +static t_int *lattice_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_latticectl *ctl = (t_latticectl *)(w[1]); + t_int i,j; + t_int n = (t_int)(w[2]); + t_float x,rc,d; + + t_latticesegment* seg = ctl->c_segment; + t_int segments = ctl->c_segments; + for (i=0; ix_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + +} +static void lattice_free(void) +{ + +} + +t_class *lattice_class; + +static void lattice_rc(t_lattice *x, t_float segment, t_float refco) +{ + t_int seg = (t_float)segment; + if ((seg >= 0) && (seg < x->x_ctl.c_segments)){ + if (refco > 1.0f) refco = 1.0f; + if (refco < -1.0f) refco = -1.0f; + x->x_ctl.c_segment[seg].rc = refco; + } +} + +static void lattice_reset(t_lattice *x) +{ + t_float* buf = (t_float *)x->x_ctl.c_segment; + t_int n = x->x_ctl.c_segments; + t_int i; + for (i=0; ix_obj, gensym("signal")); + + if (seg < 1) seg = 1; + if (seg > maxorder) seg = maxorder; + + x->x_ctl.c_segments = seg; + + lattice_reset(x); + + return (void *)x; +} + +void lattice_tilde_setup(void) +{ + //post("lattice~ v0.1"); + lattice_class = class_new(gensym("lattice~"), (t_newmethod)lattice_new, + (t_method)lattice_free, sizeof(t_lattice), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(lattice_class, t_lattice, x_f); + class_addmethod(lattice_class, (t_method)lattice_dsp, gensym("dsp"), 0); + class_addmethod(lattice_class, (t_method)lattice_reset, gensym("reset"), 0); + class_addmethod(lattice_class, (t_method)lattice_rc, gensym("rc"), A_FLOAT, A_FLOAT, 0); + +} + diff --git a/modules/matrix.c b/modules/matrix.c new file mode 100644 index 0000000..6fd55b7 --- /dev/null +++ b/modules/matrix.c @@ -0,0 +1,154 @@ +/* + * matrix.c - applies a matrix transform to a signal block + * intended for spectral processing, dynwav + * + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "m_pd.h" +#include +#include +#include +#include + +#define MAXORDER 1024 + +typedef struct matrixctl +{ + t_float *c_A; /* matrix */ + t_float *c_x; /* vector */ + t_int c_order; + +} t_matrixctl; + +typedef struct matrix +{ + t_object x_obj; + t_float x_f; + t_matrixctl x_ctl; +} t_matrix; + +static void matrix_load(t_matrix *x, t_symbol *s) +{ + FILE *matrix; + + if(s && s->s_name) + { + post("matrix: loading %s",s->s_name); + if(matrix = fopen(s->s_name, "r")) + { + int n = x->x_ctl.c_order; + fread(x->x_ctl.c_A, sizeof(float), n*n, matrix); + } + else post("matrix: error, cant open file."); + } +} + + +static t_int *matrix_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_matrixctl *ctl = (t_matrixctl *)(w[1]); + t_int n = (t_int)(w[2]); + + t_int i,j; + t_float *A = ctl->c_A; + t_float *x = ctl->c_x; + + if (in == out) /* store input if ness. */ + { + memcpy(x, in, sizeof(t_float)*n); + in = x; + } + bzero(out, sizeof(t_float)*n); /* init output */ + + for (j=0; js_n; + int k,i; + + if (x->x_ctl.c_order != n) + { + if (x->x_ctl.c_A) free (x->x_ctl.c_A); + + x->x_ctl.c_A = (t_float *)calloc(n*n,sizeof(t_float)); + x->x_ctl.c_x = (t_float *)calloc(n,sizeof(t_float)); + x->x_ctl.c_order = n; + } + + for (i=0;ix_ctl.c_A[i] = 1; + + dsp_add(matrix_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + + +} +static void matrix_free(t_matrix *x) +{ + + if (x->x_ctl.c_A) free (x->x_ctl.c_A); + if (x->x_ctl.c_x) free (x->x_ctl.c_x); + +} + +t_class *matrix_class; + +static void *matrix_new(t_floatarg order) +{ + t_matrix *x = (t_matrix *)pd_new(matrix_class); + int iorder = (int)order; + int i, n=64, k; + + + /* out 1 */ + outlet_new(&x->x_obj, gensym("signal")); + + + + /* init data */ + + x->x_ctl.c_A = (t_float *)calloc(n*n,sizeof(t_float)); + x->x_ctl.c_x = (t_float *)calloc(n,sizeof(t_float)); + + + for (i=0;ix_ctl.c_A[i] = 1; + x->x_ctl.c_order = n; + + return (void *)x; +} + +void matrix_tilde_setup(void) +{ + //post("matrix~ v0.1"); + matrix_class = class_new(gensym("matrix~"), (t_newmethod)matrix_new, + (t_method)matrix_free, sizeof(t_matrix), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(matrix_class, t_matrix, x_f); + class_addmethod(matrix_class, (t_method)matrix_dsp, gensym("dsp"), 0); + class_addmethod(matrix_class, (t_method)matrix_load, gensym("load"), A_SYMBOL,0); + + +} + diff --git a/modules/permut.c b/modules/permut.c new file mode 100644 index 0000000..bc143d2 --- /dev/null +++ b/modules/permut.c @@ -0,0 +1,177 @@ +/* + * permut.c - applies a (random) permutation on a signal block + * intended for spectral processing, dynwav + * + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "m_pd.h" +#include +#include + + + +typedef struct permutctl +{ + char c_type; + int *c_permutationtable; + int c_blocksize; +} t_permutctl; + +typedef struct permut +{ + t_object x_obj; + t_float x_f; + t_permutctl x_ctl; +} t_permut; + + +static inline void permut_perform_permutation(t_float *S, int n, t_int *f) +{ + t_int k,l; + t_float swap; + for(k=0; kx_ctl.c_blocksize; + int mask = N-1; + int *p = x->x_ctl.c_permutationtable; + int r, last = 0; + + srand(* ((unsigned int *)(&seed))); + + if(p) + { + p[0] = rand() & mask; + for (i=1;ix_ctl.c_blocksize != size) + { + if (x->x_ctl.c_permutationtable) + free(x->x_ctl.c_permutationtable); + x->x_ctl.c_permutationtable = (int *)malloc(sizeof(int)*size); + x->x_ctl.c_blocksize = size; + + /* make sure it's initialized */ + permut_bang(x); + + + } +} + + + + +static t_int *permut_perform(t_int *w) +{ + + + t_float *in = (float *)(w[3]); + t_float *out = (float *)(w[4]); + t_permutctl *ctl = (t_permutctl *)(w[1]); + t_int i; + t_int n = (t_int)(w[2]); + t_float x,y; + t_int *p = ctl->c_permutationtable; + + + if (in != out) + for (i=0; is_n); + dsp_add(permut_perform, 4, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec, sp[1]->s_vec); + +} + +static void permut_free(t_permut *x) +{ + if (x->x_ctl.c_permutationtable) free(x->x_ctl.c_permutationtable); + +} + +t_class *permut_class; + +static void *permut_new(void) +{ + t_permut *x = (t_permut *)pd_new(permut_class); + outlet_new(&x->x_obj, gensym("signal")); + + x->x_ctl.c_permutationtable = 0; + x->x_ctl.c_blocksize = 0; + permut_resize_table(x, 64); + permut_random(x, 0); + + return (void *)x; +} + +void permut_tilde_setup(void) +{ + //post("permut~ v0.1"); + permut_class = class_new(gensym("permut~"), (t_newmethod)permut_new, + (t_method)permut_free, sizeof(t_permut), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(permut_class, t_permut, x_f); + class_addmethod(permut_class, (t_method)permut_random, gensym("random"), A_FLOAT, 0); + class_addmethod(permut_class, (t_method)permut_bang, gensym("bang"), 0); + class_addmethod(permut_class, (t_method)permut_dsp, gensym("dsp"), 0); + +} + diff --git a/modules/qmult.c b/modules/qmult.c new file mode 100644 index 0000000..94766e1 --- /dev/null +++ b/modules/qmult.c @@ -0,0 +1,165 @@ +/* + * qmult.c - quaternion multiplication dsp object + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "m_pd.h" +#include +#include +#include +#include + + +typedef struct qmultctl +{ + t_float *c_inputleft[4]; + t_float *c_inputright[4]; + t_float *c_output[4]; +} t_qmultctl; + +typedef struct qmult +{ + t_object x_obj; + t_float x_f; + t_qmultctl x_ctl; +} t_qmult; + + +static t_int *qmult_perform(t_int *word) +{ + + + + t_qmultctl *ctl = (t_qmultctl *)(word[1]); + t_int n = (t_int)(word[2]); + t_int i; + + t_float *in0l = ctl->c_inputleft[0]; + t_float *in1l = ctl->c_inputleft[1]; + t_float *in2l = ctl->c_inputleft[2]; + t_float *in3l = ctl->c_inputleft[3]; + + t_float *in0r = ctl->c_inputright[0]; + t_float *in1r = ctl->c_inputright[1]; + t_float *in2r = ctl->c_inputright[2]; + t_float *in3r = ctl->c_inputright[3]; + + t_float *out0 = ctl->c_output[0]; + t_float *out1 = ctl->c_output[1]; + t_float *out2 = ctl->c_output[2]; + t_float *out3 = ctl->c_output[3]; + + t_float wl, xl, yl, zl; + t_float wr, xr, yr, zr; + t_float w, x, y, z; + + for (i=0;ix_ctl.c_inputleft[i] = sp[i]->s_vec; + x->x_ctl.c_inputright[i] = sp[i+4]->s_vec; + x->x_ctl.c_output[i] = sp[i+8]->s_vec; + } + + dsp_add(qmult_perform, 2, &x->x_ctl, sp[0]->s_n); + + +} + + +static void qmult_free(t_qmult *x) +{ + +} + +t_class *qmult_class; + +static void *qmult_new(t_floatarg channels) +{ + int i; + t_qmult *x = (t_qmult *)pd_new(qmult_class); + + for (i=1;i<8;i++) inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); + for (i=0;i<4;i++) outlet_new(&x->x_obj, gensym("signal")); + + return (void *)x; +} + +void qmult_tilde_setup(void) +{ + //post("qmult~ v0.1"); + qmult_class = class_new(gensym("qmult~"), (t_newmethod)qmult_new, + (t_method)qmult_free, sizeof(t_qmult), 0, 0); + CLASS_MAINSIGNALIN(qmult_class, t_qmult, x_f); + class_addmethod(qmult_class, (t_method)qmult_dsp, gensym("dsp"), 0); + +} + diff --git a/modules/qnorm.c b/modules/qnorm.c new file mode 100644 index 0000000..e826b1b --- /dev/null +++ b/modules/qnorm.c @@ -0,0 +1,137 @@ +/* + * qnorm.c - quaternion normalization dsp object + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "m_pd.h" +#include +#include +#include +#include + + +typedef struct qnormctl +{ + t_float *c_input[4]; + t_float *c_output[4]; +} t_qnormctl; + +typedef struct qnorm +{ + t_object x_obj; + t_float x_f; + t_qnormctl x_ctl; +} t_qnorm; + + +static t_int *qnorm_perform(t_int *word) +{ + + + + t_qnormctl *ctl = (t_qnormctl *)(word[1]); + t_int n = (t_int)(word[2]); + t_int i; + + t_float *in0 = ctl->c_input[0]; + t_float *in1 = ctl->c_input[1]; + t_float *in2 = ctl->c_input[2]; + t_float *in3 = ctl->c_input[3]; + + t_float *out0 = ctl->c_output[0]; + t_float *out1 = ctl->c_output[1]; + t_float *out2 = ctl->c_output[2]; + t_float *out3 = ctl->c_output[3]; + + t_float w, x, y, z; + t_float norm; + t_float inorm; + + for (i=0;ix_ctl.c_input[i] = sp[i]->s_vec; + x->x_ctl.c_output[i] = sp[i+4]->s_vec; + } + + dsp_add(qnorm_perform, 2, &x->x_ctl, sp[0]->s_n); + + +} + + +static void qnorm_free(t_qnorm *x) +{ + +} + +t_class *qnorm_class; + +static void *qnorm_new(t_floatarg channels) +{ + int i; + t_qnorm *x = (t_qnorm *)pd_new(qnorm_class); + + for (i=1;i<4;i++) inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); + for (i=0;i<4;i++) outlet_new(&x->x_obj, gensym("signal")); + + return (void *)x; +} + +void qnorm_tilde_setup(void) +{ + //post("qnorm~ v0.1"); + qnorm_class = class_new(gensym("qnorm~"), (t_newmethod)qnorm_new, + (t_method)qnorm_free, sizeof(t_qnorm), 0, 0); + CLASS_MAINSIGNALIN(qnorm_class, t_qnorm, x_f); + class_addmethod(qnorm_class, (t_method)qnorm_dsp, gensym("dsp"), 0); + +} + diff --git a/modules/ramp.c b/modules/ramp.c new file mode 100644 index 0000000..ad13582 --- /dev/null +++ b/modules/ramp.c @@ -0,0 +1,118 @@ +/* + * ramp.c - retriggerable counter for dsp signals + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "m_pd.h" +#include + + +typedef struct rampctl +{ + t_float c_offset; + t_float c_looppoint; +} t_rampctl; + +typedef struct ramp +{ + t_object x_obj; + t_float x_f; + t_rampctl x_ctl; +} t_ramp; + + +void ramp_offset(t_ramp *x, t_floatarg f) +{ + + x->x_ctl.c_offset = f; + +} + +void ramp_looppoint(t_ramp *x, t_floatarg f) +{ + + x->x_ctl.c_looppoint = f; + +} + + +void ramp_bang(t_ramp *x) +{ + ramp_offset(x, 0); + +} + + + +static t_int *ramp_perform(t_int *w) +{ + + + t_float *out = (float *)(w[3]); + t_rampctl *ctl = (t_rampctl *)(w[1]); + t_int i; + t_int n = (t_int)(w[2]); + t_float x; + + + + x = ctl->c_offset; + + for (i = 0; i < n; i++) + { + *out++ = (float)x++; + } + + ctl->c_offset = x; /* save state */ + + + return (w+4); +} + +static void ramp_dsp(t_ramp *x, t_signal **sp) +{ + dsp_add(ramp_perform, 3, &x->x_ctl, sp[0]->s_n, sp[0]->s_vec); + +} +void ramp_free(void) +{ + +} + +t_class *ramp_class; + +void *ramp_new(void) +{ + t_ramp *x = (t_ramp *)pd_new(ramp_class); + /* inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("looppoint"));*/ + outlet_new(&x->x_obj, gensym("signal")); + + ramp_bang(x); + return (void *)x; +} + +void ramp_tilde_setup(void) +{ + //post("ramp~ v0.1"); + ramp_class = class_new(gensym("ramp~"), (t_newmethod)ramp_new, + (t_method)ramp_free, sizeof(t_ramp), 0, 0); + class_addmethod(ramp_class, (t_method)ramp_bang, gensym("bang"), 0); + class_addmethod(ramp_class, (t_method)ramp_dsp, gensym("dsp"), 0); + class_addfloat(ramp_class, (t_method)ramp_offset); +} + diff --git a/modules/ratio.c b/modules/ratio.c new file mode 100644 index 0000000..777f2b9 --- /dev/null +++ b/modules/ratio.c @@ -0,0 +1,66 @@ +/* + * ratio.c - multiplies by 2^k such that output is between 1 and 2 + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "m_pd.h" + +#define SEQL 16 + +typedef struct{ +} t_ratio_data; + +typedef struct ratio +{ + t_object t_ob; + t_outlet *x_out; + t_ratio_data x_c; +} t_ratio; + +static void ratio_float(t_ratio *x, t_floatarg f) +{ + f = (f<0)?(-f):(f); + if (f) + { + while (f < 1.0f) f *= 2.0f; + while (f >= 2.0f) f *= 0.5f; + } + outlet_float(x->x_out, f); + +} + +static void ratio_free(void) +{ +} + +t_class *ratio_class; + +static void *ratio_new(void) +{ + t_ratio *x = (t_ratio *)pd_new(ratio_class); + x->x_out = outlet_new(&x->t_ob, gensym("float")); + return (void *)x; +} + +void ratio_setup(void) +{ + ratio_class = class_new(gensym("ratio"), (t_newmethod)ratio_new, + (t_method)ratio_free, sizeof(t_ratio), 0, 0); + class_addfloat(ratio_class, ratio_float); +} + diff --git a/modules/statwav.c b/modules/statwav.c new file mode 100644 index 0000000..52c6a0b --- /dev/null +++ b/modules/statwav.c @@ -0,0 +1,149 @@ +/* + * dynwav.c - static wavetable oscillator (scale + tabread) + * data organization is in (real, imag) pairs + * the first 2 components are (DC, NY) + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "m_pd.h" +#include +#include +#include +#include + +static t_class *statwav_tilde_class; + +typedef struct _statwav_tilde +{ + t_object x_obj; + int x_npoints; + float *x_vec; + t_symbol *x_arrayname; + float x_f; +} t_statwav_tilde; + +static void *statwav_tilde_new(t_symbol *s) +{ + t_statwav_tilde *x = (t_statwav_tilde *)pd_new(statwav_tilde_class); + x->x_arrayname = s; + x->x_vec = 0; + outlet_new(&x->x_obj, gensym("signal")); + x->x_f = 0; + return (x); +} + +static t_int *statwav_tilde_perform(t_int *w) +{ + t_statwav_tilde *x = (t_statwav_tilde *)(w[1]); + t_float *in = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + int n = (int)(w[4]); + float maxindex; + int imaxindex; + float *buf = x->x_vec, *fp; + int i; + + maxindex = x->x_npoints; + imaxindex = x->x_npoints; + + if (!buf) goto zero; + + + for (i = 0; i < n; i++) + { + float phase = *in++; + float modphase = phase - (int)phase; + float findex = modphase * maxindex; + int index = findex; + int ia, ib, ic, id; + float frac, a, b, c, d, cminusb; + static int count; + + + frac = findex - index; + ia = (imaxindex+index-1) % imaxindex; + ib = index; + ic = (index+1) % imaxindex; + id = (index+2) % imaxindex; + + a = buf[ia]; + b = buf[ib]; + c = buf[ic]; + d = buf[id]; + /* if (!i && !(count++ & 1023)) + post("fp = %lx, shit = %lx, b = %f", fp, buf->b_shit, b); */ + cminusb = c-b; + + *out++ = b + frac * ( + cminusb - 0.5f * (frac-1.) * ( + (a - d + 3.0f * cminusb) * frac + (b - a - cminusb) + ) + ); + } + + return (w+5); + zero: + while (n--) *out++ = 0; + + return (w+5); +} + +static void statwav_tilde_set(t_statwav_tilde *x, t_symbol *s) +{ + t_garray *a; + + x->x_arrayname = s; + if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) + { + if (*s->s_name) + error("statwav~: %s: no such array", x->x_arrayname->s_name); + x->x_vec = 0; + } + else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec)) + { + error("%s: bad template for statwav~", x->x_arrayname->s_name); + x->x_vec = 0; + } + else garray_usedindsp(a); +} + +static void statwav_tilde_dsp(t_statwav_tilde *x, t_signal **sp) +{ + statwav_tilde_set(x, x->x_arrayname); + + dsp_add(statwav_tilde_perform, 4, x, + sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); + +} + +static void statwav_tilde_free(t_statwav_tilde *x) +{ +} + +void statwav_tilde_setup(void) +{ + //post("statwav~ v0.1"); + statwav_tilde_class = class_new(gensym("statwav~"), + (t_newmethod)statwav_tilde_new, (t_method)statwav_tilde_free, + sizeof(t_statwav_tilde), 0, A_DEFSYM, 0); + CLASS_MAINSIGNALIN(statwav_tilde_class, t_statwav_tilde, x_f); + class_addmethod(statwav_tilde_class, (t_method)statwav_tilde_dsp, + gensym("dsp"), 0); + class_addmethod(statwav_tilde_class, (t_method)statwav_tilde_set, + gensym("set"), A_SYMBOL, 0); +} + diff --git a/modules/tabreadmix.c b/modules/tabreadmix.c new file mode 100644 index 0000000..91181c5 --- /dev/null +++ b/modules/tabreadmix.c @@ -0,0 +1,271 @@ +/* + * tabreadmix.c - an overlap add tabread~ clone + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "extlib_util.h" + +/******************** tabreadmix~ ***********************/ + +static t_class *tabreadmix_tilde_class; + +typedef struct _tabreadmix_tilde +{ + t_object x_obj; + int x_npoints; + float *x_vec; + t_symbol *x_arrayname; + float x_f; + + /* file position vars */ + int x_currpos; + int x_prevpos; + + /* cross fader state vars */ + int x_xfade_size; + int x_xfade_phase; + float x_xfade_cos; + float x_xfade_sin; + float x_xfade_state_c; + float x_xfade_state_s; + +} t_tabreadmix_tilde; + + + +inline void tabreadmix_tilde_wrapindices(t_tabreadmix_tilde *x) +{ + int max; + + /* modulo */ + x->x_currpos %= x->x_npoints; + x->x_prevpos %= x->x_npoints; + + /* make sure 0<=..x_npoints */ + //if (x->x_currpos < 0) x->x_currpos += x->x_npoints; + //if (x->x_prevpos < 0) x->x_prevpos += x->x_npoints; + x->x_currpos += (x->x_currpos < 0) * x->x_npoints; + x->x_prevpos += (x->x_prevpos < 0) * x->x_npoints; + +} + + + +#define min(x,y) ((x)<(y)?(x):(y)) + +static t_int *tabreadmix_tilde_perform(t_int *w) +{ + t_tabreadmix_tilde *x = (t_tabreadmix_tilde *)(w[1]); + t_float *pos = (t_float *)(w[2]); + t_float *out = (t_float *)(w[3]); + int n = (int)(w[4]); + int maxxindex; + float *buf = x->x_vec; + int i; + float currgain, prevgain; + float c,s; + int chunk; + int leftover; + int newpos = (int)*pos; + + maxxindex = x->x_npoints; + if (!buf) goto zero; + if (maxxindex <= 0) goto zero; + + + while (n){ + + /* process as much data as possible */ + leftover = x->x_xfade_size - x->x_xfade_phase; + chunk = min(n, leftover); + + for (i = 0; i < chunk; i++){ + /* compute crossfade gains from oscillator state */ + currgain = 0.5f - x->x_xfade_state_c; + prevgain = 0.5f + x->x_xfade_state_c; + + /* check indices & wrap */ + tabreadmix_tilde_wrapindices(x); + + /* mix and write */ + newpos = (int)(*pos++); + *out++ = currgain * buf[x->x_currpos++] + prevgain * buf[x->x_prevpos++]; + + /* advance oscillator */ + c = x->x_xfade_state_c * x->x_xfade_cos - x->x_xfade_state_s * x->x_xfade_sin; + s = x->x_xfade_state_c * x->x_xfade_sin + x->x_xfade_state_s * x->x_xfade_cos; + x->x_xfade_state_c = c; + x->x_xfade_state_s = s; + } + + /* update indices */ + x->x_xfade_phase += chunk; + n -= chunk; + //pos += chunk; + + /* check if prev chunk is finished */ + if (x->x_xfade_size == x->x_xfade_phase){ + x->x_prevpos = x->x_currpos; + x->x_currpos = newpos; + x->x_xfade_state_c = 0.5f; + x->x_xfade_state_s = 0.0f; + x->x_xfade_phase = 0; + } + + } + + /* return if we ran out of data */ + return (w+5); + + + zero: + while (n--) *out++ = 0; + return (w+5); +} + + +static void tabreadmix_tilde_blocksize(t_tabreadmix_tilde *x, t_float size) +{ + double prev_phase; + int max; + float fmax = (float)x->x_npoints * 0.5f; + + if (size < 1.0) size = 1.0; + + prev_phase = (double)x->x_xfade_phase; + prev_phase *= size; + prev_phase /= (double)x->x_xfade_size; + + + /* preserve the crossfader state */ + x->x_xfade_phase = (int)prev_phase; + x->x_xfade_size = (int)size; + + + x->x_xfade_cos = cos(M_PI / (float)x->x_xfade_size); + x->x_xfade_sin = sin(M_PI / (float)x->x_xfade_size); + + + /* make sure indices are inside array */ + if (x->x_npoints == 0){ + x->x_currpos = 0; + x->x_prevpos = 0; + } + + //else tabreadmix_tilde_wrapindices(x); + + + +} + +void tabreadmix_tilde_pitch(t_tabreadmix_tilde *x, t_float f) +{ + if (f < 1) f = 1; + + tabreadmix_tilde_blocksize(x, sys_getsr() / f); +} + +void tabreadmix_tilde_chunks(t_tabreadmix_tilde *x, t_float f) +{ + if (f < 1.0f) f = 1.0f; + tabreadmix_tilde_blocksize(x, (float)x->x_npoints / f); +} + +void tabreadmix_tilde_bang(t_tabreadmix_tilde *x, t_float f) +{ + //trigger a chunk reset on next dsp call + x->x_xfade_phase = x->x_xfade_size; +} + +void tabreadmix_tilde_set(t_tabreadmix_tilde *x, t_symbol *s) +{ + t_garray *a; + + x->x_arrayname = s; + if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class))) + { + if (*s->s_name) + error("tabreadmix~: %s: no such array", x->x_arrayname->s_name); + x->x_vec = 0; + } + else if (!garray_getfloatarray(a, &x->x_npoints, &x->x_vec)) + { + error("%s: bad template for tabreadmix~", x->x_arrayname->s_name); + x->x_vec = 0; + } + else garray_usedindsp(a); + + /* make sure indices are inside array */ + if (x->x_npoints == 0){ + x->x_currpos = 0; + x->x_prevpos = 0; + } + + //else tabreadmix_tilde_wrapindices(x); + +} + +static void tabreadmix_tilde_dsp(t_tabreadmix_tilde *x, t_signal **sp) +{ + tabreadmix_tilde_set(x, x->x_arrayname); + + dsp_add(tabreadmix_tilde_perform, 4, x, + sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); + +} + +static void tabreadmix_tilde_free(t_tabreadmix_tilde *x) +{ +} + +static void *tabreadmix_tilde_new(t_symbol *s) +{ + t_tabreadmix_tilde *x = (t_tabreadmix_tilde *)pd_new(tabreadmix_tilde_class); + x->x_arrayname = s; + x->x_vec = 0; + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("blocksize")); + outlet_new(&x->x_obj, gensym("signal")); + x->x_f = 0; + x->x_xfade_phase = 0; + x->x_xfade_size = 1024; + x->x_currpos = 0; + x->x_prevpos = 0; + x->x_xfade_state_c = 0.5f; + x->x_xfade_state_s = 0.0f; + tabreadmix_tilde_blocksize(x, 1024); + return (x); +} + +void tabreadmix_tilde_setup(void) +{ + tabreadmix_tilde_class = class_new(gensym("tabreadmix~"), + (t_newmethod)tabreadmix_tilde_new, (t_method)tabreadmix_tilde_free, + sizeof(t_tabreadmix_tilde), 0, A_DEFSYM, 0); + CLASS_MAINSIGNALIN(tabreadmix_tilde_class, t_tabreadmix_tilde, x_f); + class_addmethod(tabreadmix_tilde_class, (t_method)tabreadmix_tilde_dsp, + gensym("dsp"), 0); + class_addmethod(tabreadmix_tilde_class, (t_method)tabreadmix_tilde_set, + gensym("set"), A_SYMBOL, 0); + class_addmethod(tabreadmix_tilde_class, (t_method)tabreadmix_tilde_blocksize, + gensym("blocksize"), A_FLOAT, 0); + class_addmethod(tabreadmix_tilde_class, (t_method)tabreadmix_tilde_pitch, + gensym("pitch"), A_FLOAT, 0); + class_addmethod(tabreadmix_tilde_class, (t_method)tabreadmix_tilde_chunks, + gensym("chunks"), A_FLOAT, 0); + class_addmethod(tabreadmix_tilde_class, (t_method)tabreadmix_tilde_bang, + gensym("bang"), 0); +} diff --git a/modules/xfm.c b/modules/xfm.c new file mode 100644 index 0000000..63c79ab --- /dev/null +++ b/modules/xfm.c @@ -0,0 +1,271 @@ +/* + * xfm.c - cross frequency modulation object + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +/* +coupled fm. osc state equations: + +phasor for system i = + + [ 1 -phi ] +(1+phi^2)^(1/2) * [ phi 1 ] + + +with phi = 2*pi*(freq_base + freq_mod * out_other) / sr + + +ideal phasor would be + +[ cos(phi) - sin(phi) ] +[ sin(phi) cos(phi) ] + + +this means frequencies are warped: + +2*pi*f_real = atan(2*pi*f) + +some (possible) enhancements: + + add an integrator to get phase modulation + + undo the frequency warping + +*/ + +#include "m_pd.h" +#include +#include +#include +#include + +#define SINSAMPLES 512 +#define MYPI 3.1415927 + + +#define DISTORTED 0 +#define NORMALIZED 1 + + +typedef struct xfmctl +{ + //t_float c_sintab[SINSAMPLES + 1]; + t_float c_x1, c_y1; /* state osc 1 */ + t_float c_x2, c_y2; /* state osc 2 */ + t_int c_type; /* type of algo */ + +} t_xfmctl; + +typedef struct xfm +{ + t_object x_obj; + t_float x_f; + t_xfmctl x_ctl; +} t_xfm; + +void xfm_type(t_xfm *x, t_float f) +{ + int t = (int)f; + + if (t == DISTORTED) x->x_ctl.c_type = t; + if (t == NORMALIZED) x->x_ctl.c_type = t; + +} + + +static inline t_float xfm_sat(t_float x) +{ + const float max = 1; + const float min = -1; + + x = (x > max) ? (max) : (x); + x = (x < min) ? (min) : (x); + + return(x); +} + +static t_int *xfm_perform(t_int *w) +{ + + + t_float *inA = (float *)(w[3]); + t_float *inB = (float *)(w[4]); + t_float *fbA = (float *)(w[5]); + t_float *fbB = (float *)(w[6]); + t_float *outA = (float *)(w[7]); + t_float *outB = (float *)(w[8]); + t_xfmctl *ctl = (t_xfmctl *)(w[1]); + t_int n = (t_int)(w[2]); + //t_float *tab = ctl->c_sintab; + + t_float x1 = ctl->c_x1, y1 = ctl->c_y1, z1, dx1, dy1, inv_norm1; + t_float x2 = ctl->c_x2, y2 = ctl->c_y2, z2, dx2, dy2, inv_norm2; + + t_float scale = 2 * M_PI / sys_getsr(); + + t_int i; + + switch(ctl->c_type){ + default: + case DISTORTED: + + /* this is a 4 degree of freedom hyperchaotic system */ + /* two coupled saturated unstable oscillators */ + + for (i=0; ic_x1 = x1; + ctl->c_y1 = y1; + ctl->c_x2 = x2; + ctl->c_y2 = y2; + + return (w+9); +} + +static void xfm_dsp(t_xfm *x, t_signal **sp) +{ + int n = sp[0]->s_n; + int k; + + + dsp_add(xfm_perform, + 8, + &x->x_ctl, + sp[0]->s_n, + sp[0]->s_vec, + sp[1]->s_vec, + sp[2]->s_vec, + sp[3]->s_vec, + sp[4]->s_vec, + sp[5]->s_vec); + + +} +static void xfm_free(t_xfm *x) +{ + + +} + + + + +static void xfm_reset(t_xfm *x) +{ + x->x_ctl.c_x1 = 1; + x->x_ctl.c_y1 = 0; + x->x_ctl.c_x2 = 1; + x->x_ctl.c_y2 = 0; + +} + + +t_class *xfm_class; + +static void *xfm_new(t_floatarg algotype) +{ + t_xfm *x = (t_xfm *)pd_new(xfm_class); + + /* ins */ + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("signal"), gensym("signal")); + + /* outs */ + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); + + + + /* init data */ + xfm_reset(x); + xfm_type(x, algotype); + + return (void *)x; +} + +void xfm_tilde_setup(void) +{ + //post("xfm~ v0.1"); + xfm_class = class_new(gensym("xfm~"), (t_newmethod)xfm_new, + (t_method)xfm_free, sizeof(t_xfm), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(xfm_class, t_xfm, x_f); + class_addmethod(xfm_class, (t_method)xfm_type, gensym("type"), A_FLOAT, 0); + class_addmethod(xfm_class, (t_method)xfm_dsp, gensym("dsp"), 0); + class_addmethod(xfm_class, (t_method)xfm_reset, gensym("reset"), 0); + + +} + diff --git a/system/Makefile b/system/Makefile new file mode 100644 index 0000000..12666a4 --- /dev/null +++ b/system/Makefile @@ -0,0 +1,8 @@ +include ../Makefile.config + +all: setup.o envelope_util.o + +clean: + rm -f *.o + rm -f *~ + diff --git a/system/envelope_util.c b/system/envelope_util.c new file mode 100644 index 0000000..7117149 --- /dev/null +++ b/system/envelope_util.c @@ -0,0 +1,33 @@ +/* + * Utility functions for exponential decay + * Copyright (c) 2000-2003 by Tom Schouten + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "extlib_util.h" + +float milliseconds_2_one_minus_realpole(float time) +{ + float r; + + if (time < 0.0f) time = 0.0f; + r = -expm1(1000.0f * log(ENVELOPE_RANGE) / (sys_getsr() * time)); + if (!(r < 1.0f)) r = 1.0f; + + //post("%f",r); + return r; +} diff --git a/system/setup.c b/system/setup.c new file mode 100644 index 0000000..b425f84 --- /dev/null +++ b/system/setup.c @@ -0,0 +1,64 @@ +#include "m_pd.h" + +void ead_tilde_setup(void); +void ear_tilde_setup(void); +void eadsr_tilde_setup(void); +void dist_tilde_setup(void); +void tabreadmix_tilde_setup(void); +void xfm_tilde_setup(void); +void biquadseries_tilde_setup(void); +void filterortho_tilde_setup(void); +void qmult_tilde_setup(void); +void qnorm_tilde_setup(void); +void cheby_tilde_setup(void); +void abs_tilde_setup(void); +void ramp_tilde_setup(void); +void dwt_tilde_setup(void); +void bfft_tilde_setup(void); +void dynwav_tilde_setup(void); +void statwav_tilde_setup(void); +void bdiag_tilde_setup(void); +void diag_tilde_setup(void); +void matrix_tilde_setup(void); +void permut_tilde_setup(void); +void lattice_tilde_setup(void); +void ratio_setup(void); +void ffpoly_setup(void); +void fwarp_setup(void); + +void creb_setup(void) +{ + post("CREB: version " CREB_VERSION); + + /* setup tilde objects */ + ead_tilde_setup(); + ear_tilde_setup(); + eadsr_tilde_setup(); + dist_tilde_setup(); + tabreadmix_tilde_setup(); + xfm_tilde_setup(); + qmult_tilde_setup(); + qnorm_tilde_setup(); + cheby_tilde_setup(); + abs_tilde_setup(); + ramp_tilde_setup(); + dwt_tilde_setup(); + bfft_tilde_setup(); + dynwav_tilde_setup(); + statwav_tilde_setup(); + bdiag_tilde_setup(); + diag_tilde_setup(); + matrix_tilde_setup(); + permut_tilde_setup(); + lattice_tilde_setup(); + + /* setup other objects */ + ratio_setup(); + ffpoly_setup(); + fwarp_setup(); + + /* setup c++ modules */ + biquadseries_tilde_setup(); + filterortho_tilde_setup(); + +} -- cgit v1.2.1