diff options
Diffstat (limited to 'sc4pd')
315 files changed, 39607 insertions, 0 deletions
diff --git a/sc4pd/build-max-msvc.bat b/sc4pd/build-max-msvc.bat new file mode 100644 index 0000000..130a3bc --- /dev/null +++ b/sc4pd/build-max-msvc.bat @@ -0,0 +1,4 @@ +@echo --- Building with MS Visual C++ --- + +nmake -f makefile.max-msvc clean +nmake -f makefile.max-msvc diff --git a/sc4pd/build-pd-bcc.bat b/sc4pd/build-pd-bcc.bat new file mode 100644 index 0000000..3dd2132 --- /dev/null +++ b/sc4pd/build-pd-bcc.bat @@ -0,0 +1,3 @@ +@echo --- Building with BorlandC++ --- + +make -f makefile.pd-bcc diff --git a/sc4pd/build-pd-cygwin.sh b/sc4pd/build-pd-cygwin.sh new file mode 100644 index 0000000..9477844 --- /dev/null +++ b/sc4pd/build-pd-cygwin.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +SYS=pd-cygwin + +. config-${SYS}.txt + +make -f makefile.${SYS} && +{ + if [ $INSTDIR != "" ]; then + make -f makefile.${SYS} install + fi + if [ $HELPDIR != "" ]; then + make -f makefile.${SYS} install-help + fi +} diff --git a/sc4pd/build-pd-darwin.sh b/sc4pd/build-pd-darwin.sh new file mode 100755 index 0000000..38814a9 --- /dev/null +++ b/sc4pd/build-pd-darwin.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +SYS=pd-darwin + +. config-${SYS}.txt + +make -f makefile.${SYS} && +{ + if [ $INSTDIR != "" ]; then + echo Now install as root + sudo make -f makefile.${SYS} install + fi + if [ $HELPDIR != "" ]; then + echo Now install help as root + sudo make -f makefile.${SYS} install-help + fi +} diff --git a/sc4pd/build-pd-linux.sh b/sc4pd/build-pd-linux.sh new file mode 100755 index 0000000..77c6e3f --- /dev/null +++ b/sc4pd/build-pd-linux.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +SYS=pd-linux + +. config-${SYS}.txt + +make -f makefile.${SYS} && +{ + if [ $INSTDIR != "" ]; then + echo Now install as root + su -c "make -f makefile.${SYS} install" + fi + if [ $HELPDIR != "" ]; then + echo Now install help as root + su -c "make -f makefile.${SYS} install-help" + fi +} diff --git a/sc4pd/build-pd-mingw.bat b/sc4pd/build-pd-mingw.bat new file mode 100644 index 0000000..fa8919a --- /dev/null +++ b/sc4pd/build-pd-mingw.bat @@ -0,0 +1,3 @@ +mingw32-make -f makefile.pd-mingw +mingw32-make -f makefile.pd-mingw install +mingw32-make -f makefile.pd-mingw install-help diff --git a/sc4pd/build-pd-msvc.bat b/sc4pd/build-pd-msvc.bat new file mode 100644 index 0000000..d6187f0 --- /dev/null +++ b/sc4pd/build-pd-msvc.bat @@ -0,0 +1,4 @@ +@echo --- Building with MS Visual C++ --- + +nmake -f makefile.pd-msvc clean +nmake -f makefile.pd-msvc diff --git a/sc4pd/config-max-msvc.txt b/sc4pd/config-max-msvc.txt new file mode 100644 index 0000000..95dfe38 --- /dev/null +++ b/sc4pd/config-max-msvc.txt @@ -0,0 +1,27 @@ +# config file for sc4pd, adapted from Thomas Grill's xsample makefile +# + +# where is the Max SDK? +# you should have the latest version! +MAXSDKPATH="F:\prog\audio\MaxWinSDK\c74support" + +# where do the flext libraries reside? +FLEXTPATH="%CommonProgramFiles%\Cycling '74\flext" + +# where is MS VC++? +# (need not be defined if the build is started with the compiler environment set) +# MSVCPATH="c:\programme\prog\microsoft visual studio\VC98" + + +# where should the external be built? +# (path for temporary files) +OUTPATH=max-msvc + +# where should the external be installed? +# (leave blank to omit installation) +INSTPATH="%CommonProgramFiles%\Cycling '74\externals\flext" + + +# some user-definable flags +# (check if they match your system!) +UFLAGS=/G6 /arch:SSE diff --git a/sc4pd/config-pd-bcc.txt b/sc4pd/config-pd-bcc.txt new file mode 100644 index 0000000..8f8ba75 --- /dev/null +++ b/sc4pd/config-pd-bcc.txt @@ -0,0 +1,23 @@ +# config file for sc4pd, adapted from Thomas Grill's xsample makefile +# + +# where is PD? +PDPATH=c:\programme\audio\pd + +# where do the flext libraries reside? +FLEXTPATH=$(PDPATH)\flext + +# where is BorlandC++? +BCCPATH=c:\programme\prog\bcc55 + +# where should the external(s) be built? +OUTPATH=.\pd-bcc + +# should the external be installed? (yes/no) +INSTALL=yes + +# where should the external be installed? +INSTDIR=$(PDPATH)\extra + +# additional compiler flags +UFLAGS=-6 -O2 -OS -ff diff --git a/sc4pd/config-pd-cygwin.txt b/sc4pd/config-pd-cygwin.txt new file mode 100644 index 0000000..feb8d31 --- /dev/null +++ b/sc4pd/config-pd-cygwin.txt @@ -0,0 +1,35 @@ +# config file for sc4pd, adapted from Thomas Grill's xsample makefile +# + +# your c++ compiler (define only if it's different than g++) +# CXX=g++ + +# where does the PD installation reside? +PD=/cygdrive/c/programme/audio/pd + +# where are the PD header files? +# leave it blank if it is a system directory (like /usr/local/include), +# since gcc 3.2 complains about it +PDINC=${PD}/src + +# where do the flext libraries reside? +FLEXTPATH=${PD}/flext + +# where should sc4pd objects be built? +TARGDIR=./pd-cygwin + +# where should sc4pd be installed? +# (leave blank to omit installation) +INSTDIR=${PD}/extra + +# where should the sc4pd help be installed? +# (leave blank to omit installation) +HELPDIR=${PD}/doc/5.reference + +# additional compiler flags +# (check whether they fit to your system!) +UFLAGS=-mcpu=pentium4 -msse -mfpmath=sse # gcc 3.2 +# UFLAGS=-mcpu=pentiumpro # gcc 2.95 + +# define to build with shared flext library +#FLEXT_SHARED=1 diff --git a/sc4pd/config-pd-darwin.txt b/sc4pd/config-pd-darwin.txt new file mode 100644 index 0000000..82c5b70 --- /dev/null +++ b/sc4pd/config-pd-darwin.txt @@ -0,0 +1,35 @@ +# config file for sc4pd, adapted from Thomas Grill's xsample makefile +# + +# your c++ compiler (if not g++) +#CXX=g++-3.3 + +# where does the PD installation reside? +PD=/usr/local/lib/pd + +# where are the PD header files? +# leave it blank if it is a system directory (like /usr/local/include), +# since gcc 3.2 complains about it +PDINC=${PD}/src + +# where is the PD executable? +PDBIN=/usr/local/bin/pd + +# where do the flext libraries reside? +FLEXTPATH=${PD}/flext + +# where should the sc4pd objects be built? +TARGDIR=./pd-darwin + +# where should sc4pd be installed? +# (leave blank to omit installation) +INSTDIR=${PD}/extra + +# where should the sc4pd help be installed? +# (leave blank to omit installation) +HELPDIR=${PD}/doc/5.reference + +# additional compiler flags +# (check whether they fit your system!) +UFLAGS=-malign-power -maltivec -faltivec + diff --git a/sc4pd/config-pd-linux.txt b/sc4pd/config-pd-linux.txt new file mode 100644 index 0000000..3d67664 --- /dev/null +++ b/sc4pd/config-pd-linux.txt @@ -0,0 +1,36 @@ +# config file for sc4pd, adapted from Thomas Grill's xsample makefile + +# your c++ compiler (if not g++) +# CXX=icc + + +# where does the PD installation reside? +PD=/usr/lib/pd + +# where are the PD header files? +# leave it blank if it is a system directory (like /usr/local/include), +# since gcc 3.2 complains about it +PDINC=/home/tim/pd/pd/src + +# where do the flext libraries reside? +FLEXTPATH=/usr/lib/flext + +# where should sc4pd objects be built? +TARGDIR=./pd-linux + +# where should sc4pd be installed? +# (leave blank to omit installation) +INSTDIR=${PD}/externs + +# where should the sc4pd help be installed? +# (leave blank to omit installation) +HELPDIR=${PD}/doc/5.reference + +# additional compiler flags +# (check whether they fit to your system!) +#UFLAGS=-xN -tpp7 -ip -ipo_obj # icc +UFLAGS=-march=pentium4 -mmmx -msse2 -msse -mfpmath=sse -g # gcc 3.2 + +# define to link against shared flext library (flext version >= 0.5.0) +FLEXT_SHARED=1 + diff --git a/sc4pd/config-pd-mingw.txt b/sc4pd/config-pd-mingw.txt new file mode 100644 index 0000000..d5352b7 --- /dev/null +++ b/sc4pd/config-pd-mingw.txt @@ -0,0 +1,35 @@ +# config file for sc4pd, adapted from Thomas Grill's xsample makefile +# + +# your c++ compiler (define only if it's different than g++) +# CXX=g++ + +# where does the PD installation reside? +PD=c:/programme/audio/pd + +# where are the PD header files? +# leave it blank if it is a system directory (like /usr/local/include), +# since gcc 3.2 complains about it +PDINC=${PD}/src + +# where do the flext libraries reside? +FLEXTPATH=${PD}/flext + +# where should sc4pd objects be built? +TARGDIR=./pd-mingw + +# where should sc4pd be installed? +# (leave blank to omit installation) +INSTDIR=${PD}/extra + +# where should the sc4pd help be installed? +# (leave blank to omit installation) +HELPDIR=${PD}/doc/5.reference + +# additional compiler flags +# (check whether they fit to your system!) +UFLAGS=-mcpu=pentium4 -msse -mfpmath=sse # gcc 3.2 +# UFLAGS=-mcpu=pentiumpro # gcc 2.95 + +# define to build with shared flext library +# FLEXT_SHARED=1
\ No newline at end of file diff --git a/sc4pd/config-pd-msvc.txt b/sc4pd/config-pd-msvc.txt new file mode 100644 index 0000000..9ba68f2 --- /dev/null +++ b/sc4pd/config-pd-msvc.txt @@ -0,0 +1,19 @@ +# config file for sc4pd, adapted from Thomas Grill's xsample makefile +# + +# where is PD? +PDPATH=c:\programme\audio\pd + +# where do the flext libraries reside? +FLEXTPATH=$(PDPATH)\flext + +# where is MS VC++? +# (not necessary if the build started with the compiler environment) +# MSVCPATH=c:\programme\prog\microsoft visual studio\VC98 + +# where should the external be built? +OUTPATH=pd-msvc + +# where should the external be installed? +# (leave blank to omit installation) +INSTDIR=$(PDPATH)\extra diff --git a/sc4pd/gpl.txt b/sc4pd/gpl.txt new file mode 100644 index 0000000..5ea29a7 --- /dev/null +++ b/sc4pd/gpl.txt @@ -0,0 +1,346 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 COPYING, 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 + + + 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. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. + + <signature of Ty Coon>, 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/sc4pd/headers/app/AIAttributedStringAdditions.h b/sc4pd/headers/app/AIAttributedStringAdditions.h new file mode 100644 index 0000000..ae81326 --- /dev/null +++ b/sc4pd/headers/app/AIAttributedStringAdditions.h @@ -0,0 +1,39 @@ +/*-------------------------------------------------------------------------------------------------------*\ +| Adium, Copyright (C) 2001-2003, Adam Iser (adamiser@mac.com | http://www.adiumx.com) | +\---------------------------------------------------------------------------------------------------------/ + | 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + \------------------------------------------------------------------------------------------------------ */ + +#import <Cocoa/Cocoa.h> +#import <Foundation/Foundation.h> + +@interface NSMutableAttributedString (AIAttributedStringAdditions) + +- (void)appendString:(NSString *)aString withAttributes:(NSDictionary *)attrs; +- (NSData *)dataRepresentation; +- (NSAttributedString *)safeString; +- (unsigned int)replaceOccurrencesOfString:(NSString *)target withString:(NSString*)replacement options:(unsigned)opts range:(NSRange)searchRange; +- (unsigned int)replaceOccurrencesOfString:(NSString *)target withString:(NSString*)replacement attributes:(NSDictionary*)attributes options:(unsigned)opts range:(NSRange)searchRange; +- (void)adjustColorsToShowOnBackground:(NSColor *)backgroundColor; +- (void)adjustColorsToShowOnBackgroundRelativeToOriginalBackground:(NSColor *)backgroundColor; +@end + +@interface NSAttributedString (AIAttributedStringAdditions) + +- (float)heightWithWidth:(float)width; +- (NSData *)dataRepresentation; ++ (NSAttributedString *)stringWithData:(NSData *)inData; +- (NSAttributedString *)safeString; + +@end + + diff --git a/sc4pd/headers/app/AIColorAdditions.h b/sc4pd/headers/app/AIColorAdditions.h new file mode 100644 index 0000000..6af9dc8 --- /dev/null +++ b/sc4pd/headers/app/AIColorAdditions.h @@ -0,0 +1,39 @@ +/*-------------------------------------------------------------------------------------------------------*\ +| Adium, Copyright (C) 2001-2003, Adam Iser (adamiser@mac.com | http://www.adiumx.com) | +\---------------------------------------------------------------------------------------------------------/ + | 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + \------------------------------------------------------------------------------------------------------ */ + +#import <Cocoa/Cocoa.h> +#import <Foundation/Foundation.h> + +@interface NSString (AIColorAdditions) + +- (NSColor *)hexColor; +- (NSColor *)representedColor; +- (NSColor *)representedColorWithAlpha:(float)alpha; + +@end + +@interface NSColor (AIColorAdditions) + +- (BOOL)equalToRGBColor:(NSColor *)inColor; +- (BOOL)colorIsDark; +- (NSColor *)darkenBy:(float)amount; +- (NSString *)hexString; +- (NSString *)stringRepresentation; +- (void)getHue:(float *)hue luminance:(float *)luminance saturation:(float *)saturation; ++ (NSColor *)colorWithCalibratedHue:(float)hue luminance:(float)luminance saturation:(float)saturation alpha:(float)alpha; +- (NSColor *)colorWithInvertedLuminance; +- (NSColor *)adjustHue:(float)dHue saturation:(float)dSat brightness:(float)dBrit; + +@end diff --git a/sc4pd/headers/app/AIHTMLDecoder.h b/sc4pd/headers/app/AIHTMLDecoder.h new file mode 100644 index 0000000..492d663 --- /dev/null +++ b/sc4pd/headers/app/AIHTMLDecoder.h @@ -0,0 +1,28 @@ +/*-------------------------------------------------------------------------------------------------------*\ +| Adium, Copyright (C) 2001-2003, Adam Iser (adamiser@mac.com | http://www.adiumx.com) | +\---------------------------------------------------------------------------------------------------------/ + | 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + \------------------------------------------------------------------------------------------------------ */ + +#import <Cocoa/Cocoa.h> +#import <Foundation/Foundation.h> +#import "AIStringAdditions.h" + +@interface AIHTMLDecoder : NSObject { + +} + ++ (NSAttributedString *)decodeHTML:(NSString *)inMessage; ++ (NSString *)encodeHTML:(NSAttributedString *)inMessage encodeFullString:(BOOL)encodeFullString; ++ (NSString *)encodeHTML:(NSAttributedString *)inMessage headers:(BOOL)includeHeaders fontTags:(BOOL)includeFontTags closeFontTags:(BOOL)closeFontTags styleTags:(BOOL)includeStyleTags closeStyleTagsOnFontChange:(BOOL)closeStyleTagsOnFontChange encodeNonASCII:(BOOL)encodeNonASCII; + +@end diff --git a/sc4pd/headers/app/AIStringAdditions.h b/sc4pd/headers/app/AIStringAdditions.h new file mode 100644 index 0000000..b0a5a64 --- /dev/null +++ b/sc4pd/headers/app/AIStringAdditions.h @@ -0,0 +1,25 @@ +/*-------------------------------------------------------------------------------------------------------*\ +| Adium, Copyright (C) 2001-2003, Adam Iser (adamiser@mac.com | http://www.adiumx.com) | +\---------------------------------------------------------------------------------------------------------/ + | 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + \------------------------------------------------------------------------------------------------------ */ + +#import <Cocoa/Cocoa.h> +#import <Foundation/Foundation.h> + +@interface NSString (AIStringAdditions) +- (NSString *)compactedString; +- (int)intValueFromHex; +- (NSString *)stringByExpandingBundlePath; +- (NSString *)stringByCollapsingBundlePath; +- (NSString *)stringByTruncatingTailToWidth:(float)inWidth; +@end diff --git a/sc4pd/headers/app/AITextAttributes.h b/sc4pd/headers/app/AITextAttributes.h new file mode 100644 index 0000000..02b0754 --- /dev/null +++ b/sc4pd/headers/app/AITextAttributes.h @@ -0,0 +1,44 @@ +/*-------------------------------------------------------------------------------------------------------*\ +| Adium, Copyright (C) 2001-2003, Adam Iser (adamiser@mac.com | http://www.adiumx.com) | +\---------------------------------------------------------------------------------------------------------/ + | 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + \------------------------------------------------------------------------------------------------------ */ + +#import <Cocoa/Cocoa.h> +#import <Foundation/Foundation.h> + +#define AIBodyColorAttributeName @"AIBodyColor" + +@interface AITextAttributes : NSObject { + + NSMutableDictionary *dictionary; + + NSString *fontFamilyName; + NSFontTraitMask fontTraitsMask; + int fontSize; + +} + ++ (id)textAttributesWithFontFamily:(NSString *)inFamilyName traits:(NSFontTraitMask)inTraits size:(int)inSize; +- (void)dealloc; +- (void)setFontFamily:(NSString *)inName; +- (void)setFontSize:(int)inSize; +- (void)enableTrait:(NSFontTraitMask)inTrait; +- (void)disableTrait:(NSFontTraitMask)inTrait; +- (NSDictionary *)dictionary; +- (void)setUnderline:(BOOL)inUnderline; +- (void)setTextColor:(NSColor *)inColor; +- (void)setTextBackgroundColor:(NSColor *)inColor; +- (void)setBackgroundColor:(NSColor *)inColor; +- (void)setLinkURL:(NSString *)inURL; + +@end diff --git a/sc4pd/headers/app/ChangeCounter.h b/sc4pd/headers/app/ChangeCounter.h new file mode 100644 index 0000000..db74fe5 --- /dev/null +++ b/sc4pd/headers/app/ChangeCounter.h @@ -0,0 +1,30 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +class ChangeCounter +{ + int changes, updates; +public: + ChangeCounter() { changes = updates = 0; } + bool NeedsUpdate() { return changes != updates; } + void Update() { updates = changes; } + void Change() { changes++; } +}; + diff --git a/sc4pd/headers/app/ControlSpec.h b/sc4pd/headers/app/ControlSpec.h new file mode 100644 index 0000000..7446759 --- /dev/null +++ b/sc4pd/headers/app/ControlSpec.h @@ -0,0 +1,36 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* +struct ControlSpec { + float minval, maxval, initial; + int numticks; + bool constrained; + + ControlSpec(); +}; + +inline ControlSpec() + : minval(0.), maxval(1.), initial(0.), numticks(11), constrained(false) +{ +} + + +*/
\ No newline at end of file diff --git a/sc4pd/headers/app/DrawBackground.h b/sc4pd/headers/app/DrawBackground.h new file mode 100644 index 0000000..e5fe040 --- /dev/null +++ b/sc4pd/headers/app/DrawBackground.h @@ -0,0 +1,83 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import "SCGeom.h" + +class DrawBackground +{ +public: + DrawBackground(); + virtual void draw(CGContextRef cgc, CGRect rect); + virtual void drawSelf(CGContextRef cgc, CGRect rect); +}; + + +class SolidColorBackground : public DrawBackground +{ +public: + SolidColorBackground(SCColor inColor); + virtual void drawSelf(CGContextRef cgc, CGRect rect); +private: + SCColor mColor; +}; + +enum { + grad_Horizontal, + grad_Vertical, + grad_Narrow, + grad_Wide +}; + +class GradientBackground : public DrawBackground +{ +public: + GradientBackground(SCColor inStartColor, SCColor inEndColor, int inDirection, int inSteps); + virtual void drawSelf(CGContextRef cgc, CGRect rect); + +protected: + SCColor mStartColor, mEndColor; + int mDirection, mSteps; +}; + +class HiliteGradientBackground : public GradientBackground +{ +public: + HiliteGradientBackground(SCColor inStartColor, SCColor inEndColor, int inDirection, int inSteps, float inFrac = .33); + + virtual void drawSelf(CGContextRef cgc, CGRect rect); + +protected: + float mFrac, mFrac1; +}; + +/* +class TiledBackground : public DrawBackground +{ +public: + TiledBackground(NSImage* inTile); + + virtual void drawSelf(CGContextRef cgc, CGRect rect); + +protected: + NSImage* mTile; + CGRect mTiledBounds; +}; + +*/ diff --git a/sc4pd/headers/app/GetStringFromUser.h b/sc4pd/headers/app/GetStringFromUser.h new file mode 100644 index 0000000..0e13d71 --- /dev/null +++ b/sc4pd/headers/app/GetStringFromUser.h @@ -0,0 +1,46 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#import <Cocoa/Cocoa.h> + +@interface GetStringFromUser : NSObject { + NSString *string; + id textField; + id promptField; + id okButton; + id cancelButton; +} + ++ (id)sharedInstance; + +/* Loads UI lazily */ +- (NSPanel *)getStringPanel; + +- (NSString *)string; +- (void)setString:(NSString *)string; + +- (void)setPrompt:(NSString *)string; + +/* Action methods, sent from the find panel UI; can also be connected to menu items */ +- (void)ok:(id)sender; +- (void)cancel:(id)sender; + +@end diff --git a/sc4pd/headers/app/GoToPanel.h b/sc4pd/headers/app/GoToPanel.h new file mode 100644 index 0000000..6808884 --- /dev/null +++ b/sc4pd/headers/app/GoToPanel.h @@ -0,0 +1,52 @@ +/* + * GoToPanel.M + * SC3lang + * + * Created by j. trutzschler on 02 sept 2003. + derived from TextFinder.m by Ali Ozer + + a panel that searches and selects a line + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#import <Cocoa/Cocoa.h> + +@interface GoToPanel : NSObject { + id findTextField; + id okButton; +} + +/* Common way to get a text finder. One instance of TextFinder per app is good enough. */ ++ (id)sharedInstance; + +/* Main method for external users; does a find in the first responder. Selects found range or beeps. */ +- (void)selectLine:(id)sender; +- (void) getAndDisplayCurrentLine; +- (void)prselectLine:(int)linenum; + +/* Loads UI lazily */ +- (NSPanel *)gotoLinePanel; + +/* Gets the first responder and returns it if it's an NSTextView */ +- (NSTextView *)textObjectToSelectIn; + +- (void)orderFrontGotoLinePanel:(id)sender; + +/* Misc internal methods */ +- (void)appDidActivate:(NSNotification *)notification; + + +@end diff --git a/sc4pd/headers/app/MyDocument.h b/sc4pd/headers/app/MyDocument.h new file mode 100644 index 0000000..d52eabc --- /dev/null +++ b/sc4pd/headers/app/MyDocument.h @@ -0,0 +1,107 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import <Cocoa/Cocoa.h> +#import "UserPanel.h" +#include "PyrObject.h" +#include "PyrKernel.h" +#include "GC.h" +#include "VMGlobals.h" + +extern pthread_mutex_t gLangMutex; +extern PyrSymbol *s_closed; + +@interface MyDocument : NSDocument +{ + IBOutlet NSTextView* initTextView; + IBOutlet NSTextView* textView; + IBOutlet NSScrollView* scrollView; + Boolean isRichText; + struct PyrObject *mWindowObj; +} + + +- (NSTextView*)makeTextView; +- (NSTextView*) textView; + +- (void)windowControllerDidLoadNib:(NSWindowController*) aController; + +- (void)addDocument; + +- (IBAction)openCode:(id)sender; +- (IBAction)methodTemplates: (id)sender; +- (IBAction)methodReferences: (id)sender; + +- (IBAction)balanceParens: (id)sender; + +- (IBAction)syntaxColorize: (id)sender; +- (void) insertText: (char*) text length: (int)length; +- (IBAction)shiftLeft: (id)sender; +- (IBAction)shiftRight: (id)sender; +- (IBAction)commentCode: (id)sender; +- (IBAction)uncommentCode:(id)sender; + +- (IBAction) executeSelection: (id) sender; +- (NSString*)currentlySelectedTextOrLine: (NSRange*) outRange; +-(void)selectRangeStart:(int)rangeStart size:(int)rangeSize; + +- (IBAction) showHelp: (id) sender; + +- (BOOL) textView: (NSTextView *) textView + clickedOnLink: (id) link + atIndex: (unsigned) charIndex; +- (IBAction) createLink: (id) sender; + +- (void)sendSelection: (char*) methodName; + +- (NSString *)windowNibName; + +- (BOOL)writeToFile:(NSString*) path ofType:(NSString *)aType; +- (BOOL)readFromFile:(NSString *)path ofType:(NSString *)aType; + +- (BOOL) shouldRunSavePanelWithAccessoryView; + +- (BOOL)windowShouldClose:(id)sender; +- (void)windowWillClose:(NSNotification *)aNotification; +- (IBAction) becomePostWindow: (id) sender; +- (BOOL) isDocumentEdited; + +- (void)doToggleRich; +// toggleRich: puts up an alert before ultimately calling doToggleRich +- (IBAction)toggleRich:(id)sender; +- (void)setRichText:(BOOL)flag; + +- (BOOL)validateMenuItem:(NSMenuItem *)aCell; + +- (void)setSCObject: (struct PyrObject*)inObject; +- (struct PyrObject*)getSCObject; +- (void) closeWindow; +- (void)setBackgroundColor:(NSColor *)color; +- (NSScrollView*) scrollView; +- (NSTextView*) initTextView; +-(void)selectLine:(int)linenum; +- (IBAction)selectLineWindow: (id) sender; +- (void) callSCLangWithMethod: (PyrSymbol*) method; + +@end + +NSString* pathOfHelpFileFor(NSString* selection); +void showHelpFor(NSString* selection); + diff --git a/sc4pd/headers/app/RendezvousClient.h b/sc4pd/headers/app/RendezvousClient.h new file mode 100644 index 0000000..e66f518 --- /dev/null +++ b/sc4pd/headers/app/RendezvousClient.h @@ -0,0 +1,39 @@ +// +// RendezvousClient.h +// SC3lang +// +// Created by C. Ramakrishnan on Mon Feb 24 2003. +// Copyright (c) 2003 __MyCompanyName__. All rights reserved. +// + +#import <Foundation/Foundation.h> + +@interface OSCService : NSObject { +// a glorified struct (declared as an Obj-C class so I can put it in NSArrays) +// stored in the oscServices ivar of RendezvousClient +@public + NSNetService* netService; + BOOL isResolved; + NSString* hostName; + const struct sockaddr_in* sockaddr; + unsigned hostAddress; + unsigned short port; + int refCount; +} + +@end + +@interface RendezvousClient : NSObject { + NSNetServiceBrowser* browser; + NSMutableArray* oscServices; +} + ++ (RendezvousClient*)sharedClient; + +// interface +- (void)findOSCServices; +- (OSCService*)oscServiceAtIndex:(unsigned)index; +- (unsigned)numberOfOSCServices; + +@end + diff --git a/sc4pd/headers/app/SCDialog.h b/sc4pd/headers/app/SCDialog.h new file mode 100644 index 0000000..fdebdbb --- /dev/null +++ b/sc4pd/headers/app/SCDialog.h @@ -0,0 +1,41 @@ +// +// SCDialogs.h +// SC3lang +// +// Created by cruxxial on Tue Dec 17 2002. +// Copyright (c) 2002 crucial-systems. All rights reserved. +// + +#import <Cocoa/Cocoa.h> + +#include "PyrPrimitive.h" +#include "PyrObject.h" +#include "PyrKernel.h" +#include "VMGlobals.h" +#include "GC.h" +#include "PyrSched.h" +#import "SCVirtualMachine.h" + +@interface SCDialog : NSObject { + PyrObject *receiver; + PyrObject *result; + NSOpenPanel *openPanel; +} + ++(id)receiver:(PyrObject*)argReceiver result:(PyrObject*)argResult; +-(id)initWithReceiver:(PyrObject*)argReceiver result:(PyrObject*)argResult; + +-(void)ok; +-(void)cancel; +-(void)error; + +-(void)returnPaths:(NSArray*)urls; +-(void)getPaths; +-(void)returnPath:(NSString*)path; + + +// call method on self when SCVM is ready for sclang usage +-(void)scvmDeferWithSelector:(SEL)selector; + + +@end diff --git a/sc4pd/headers/app/SCGeom.h b/sc4pd/headers/app/SCGeom.h new file mode 100644 index 0000000..04904a4 --- /dev/null +++ b/sc4pd/headers/app/SCGeom.h @@ -0,0 +1,90 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import <Carbon/Carbon.h> +#include "SC_BoundsMacros.h" + +struct SCColor { + float red, green, blue, alpha; +}; +typedef struct SCColor SCColor; + +inline SCColor SCMakeColor(float red, float green, float blue, float alpha) +{ + SCColor sccolor; + sccolor.red = red; + sccolor.green = green; + sccolor.blue = blue; + sccolor.alpha = alpha; + return sccolor; +} + +struct SCPoint { + float x, y; +}; + +inline SCPoint SCMakePoint(float x, float y) +{ + SCPoint p; + p.x = x; + p.y = y; + return p; +} + +struct SCRect { + float x, y, width, height; +}; + +inline SCRect SCRectUnion(SCRect a, SCRect b) +{ + if (a.height <= 0. && a.width <= 0.) return b; + if (b.height <= 0. && b.width <= 0.) return a; + + SCRect u; + u.x = sc_min(a.x, b.x); + u.y = sc_min(a.y, b.y); + u.width = sc_max(a.x + a.width, b.x + b.width) - u.x; + u.height = sc_max(a.y + a.height, b.y + b.height) - u.y; + return u; +} + +inline bool SCRectsDoIntersect(SCRect a, SCRect b) +{ + if (a.x + a.width < b.x) return false; + if (a.y + a.height < b.y) return false; + if (a.x > b.x + b.width) return false; + if (a.y > b.y + b.height) return false; + return true; +} + +inline SCRect SCMakeRect(float x, float y, float width, float height) +{ + SCRect r; + r.x = x; r.y = y; r.width = width; r.height = height; + return r; +} + +inline bool SCPointInRect(SCPoint p, SCRect r) +{ + return + p.x >= r.x && p.x <= r.x + r.width + && p.y >= r.y && p.y <= r.y + r.height; + +} diff --git a/sc4pd/headers/app/SCGraphView.h b/sc4pd/headers/app/SCGraphView.h new file mode 100644 index 0000000..84b259d --- /dev/null +++ b/sc4pd/headers/app/SCGraphView.h @@ -0,0 +1,55 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import <Cocoa/Cocoa.h> +#import "SCView.h" + +@interface SCGraphView : NSView +{ + struct PyrObject *mWindowObj; + SCTopView *mTopView; + bool mDragStarted; + SCView* mMenuView; + bool windowShouldClose; +} + +- (void)drawRect: (NSRect)bounds; +- (void) keyDown: (NSEvent*) event; +- (void) keyUp: (NSEvent*) event; +- (void) mouseDown: (NSEvent*) event; +- (void)setSCObject: (struct PyrObject*)inObject; +- (struct PyrObject*)getSCObject; +- (BOOL)isFlipped; +- (BOOL)mouseDownCanMoveWindow; + +- (void)setSCTopView: (SCTopView*)inView; +//- (void)dealloc; +- (void)closeWindow; +- (void)willClose; +- (void)setWindowShouldClose:(BOOL)boo; +- (BOOL)windowShouldClose; +- (void) beginDragFrom: (NSPoint)where of: (PyrSlot*)slot; + +- (NSMenu*) menuForEvent:(NSEvent*)event; +- (void)startMenuTracking: (SCView*) inView; + +- (IBAction) toggleUIEditMode: (id) sender; + +@end diff --git a/sc4pd/headers/app/SCService.h b/sc4pd/headers/app/SCService.h new file mode 100644 index 0000000..64a78a0 --- /dev/null +++ b/sc4pd/headers/app/SCService.h @@ -0,0 +1,16 @@ +// +// SCService.h +// SC3lang +// +// Created by C. Ramakrishnan on Mon Oct 20 2003. +// Copyright (c) 2003 __MyCompanyName__. All rights reserved. +// + +#import <Foundation/Foundation.h> + + +@interface SCService : NSObject { + +} + +@end diff --git a/sc4pd/headers/app/SCTextView.h b/sc4pd/headers/app/SCTextView.h new file mode 100644 index 0000000..b1b721c --- /dev/null +++ b/sc4pd/headers/app/SCTextView.h @@ -0,0 +1,33 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import <Cocoa/Cocoa.h> + +@interface SCTextView : NSTextView +{ + +} + + - (void) keyDown: (NSEvent*) event; + - (void) mouseDown: (NSEvent*) event; + - (void) autoIndent: (NSEvent*) event; + - (void) mouseDownAction; + +@end diff --git a/sc4pd/headers/app/SCView.h b/sc4pd/headers/app/SCView.h new file mode 100644 index 0000000..a752445 --- /dev/null +++ b/sc4pd/headers/app/SCView.h @@ -0,0 +1,784 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import "DrawBackground.h" +#include "PyrObject.h" + +enum { + layout_NoResize, + layout_Resize +}; + +enum { + // mHResize + layout_FixedLeft = -1, + layout_HElastic, + layout_FixedRight, +}; +enum { + // mVResize + layout_FixedTop = -1, + layout_VElastic, + layout_FixedBottom +}; + + +struct Layout +{ + Layout(); + + // layout params for dynamic layout views + float mMinWidth, mMaxWidth, mMinHeight, mMaxHeight; + float mWeight; + bool mShouldResize; + // layout params for composite views + char mHResize, mVResize; +}; + + + +class SCView; +class SCContainerView; +class SCTopView; + +typedef SCView* (*SCViewCtor)(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + +struct SCViewMaker +{ + SCViewMaker(const char* inName, SCViewCtor inCtor); + static SCView* MakeSCView(PyrObject* inObj, SCContainerView *inParent, SCRect inBounds, const char* classname); + + SCViewMaker *mNext; + SCViewCtor mCtor; + const char* mName; +}; + +extern SCViewMaker *gSCViewMakers; +extern SCView *gAnimatedViews; + +class SCView +{ +public: + SCView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCView(); + + virtual void draw(SCRect inDamage); + virtual void drawFocus(SCRect inDamage); + virtual void drawDisabled(SCRect inDamage); + virtual void drawDragHilite(SCRect inDamage); + virtual void drawIfNecessary(SCRect inDamage); + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseOver(SCPoint where); + virtual void keyDown(int character, int modifiers, unsigned short keycode); + virtual void keyUp(int character, int modifiers, unsigned short keycode); + virtual bool shouldDim(); + void beginDrag(SCPoint where); + + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + + bool isFocus() const; + bool hit(SCPoint p) const; + void refresh(); + void refreshFocus(); + void setDragHilite(bool inFlag); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + + virtual bool isDragSource() const; + virtual SCView* findView(SCPoint where); + virtual SCView* findViewByID(int32 inID); + virtual void makeFocus(bool focus); + virtual SCView* nextFocus(bool *foundFocus, bool canFocus); + virtual SCView* prevFocus(SCView **prevView, bool canFocus); + virtual bool canFocus(); + + void sendMessage(PyrSymbol *method, int numargs, PyrSlot *args, PyrSlot *result); + + virtual void setBounds(SCRect inBounds); + virtual SCRect getBounds(); + virtual Layout getLayout(); + + SCView* next() { return mNext; } + SCContainerView* parent() { return mParent; } + + virtual NSMenu* contextMenu(SCPoint inPoint); + + virtual void setMenuItemChosen(int inItem) {} + + PyrObject* GetSCObj() { return mObj; } + SCView* NextAnimatedView() const { return mNextAnimatedView; } + + void startAnimation(); + void stopAnimation(); + virtual void animate() { refresh(); } + +protected: + friend class SCContainerView; + + SCView *mNext; + SCView *mNextAnimatedView; + SCView *mPrevAnimatedView; + SCContainerView *mParent; + SCTopView *mTop; + PyrObject* mObj; + SCRect mBounds; + Layout mLayout; + DrawBackground* mBackground; + bool mVisible; + bool mEnabled; + bool mCanFocus; + bool mDragHilite; + int32 mID; +}; + + +class SCContainerView : public SCView +{ +public: + SCContainerView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCContainerView(); + + virtual void drawIfNecessary(SCRect inDamage); + + virtual void add(SCView *inChild); + virtual void remove(SCView *inChild); + virtual SCView* findView(SCPoint where); + virtual SCView* findViewByID(int32 inID); + virtual void makeFocus(bool focus); + virtual SCView* nextFocus(bool *foundFocus, bool canFocus); + virtual SCView* prevFocus(SCView **prevView, bool canFocus); + virtual bool canFocus(); + +protected: + SCView *mChildren; + int mNumChildren; +}; + +class SCCompositeView : public SCContainerView +{ +public: + SCCompositeView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCCompositeView(); + + virtual void setBounds(SCRect inBounds); + +protected: +}; + +class SCLayoutView : public SCContainerView +{ +public: + SCLayoutView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCLayoutView(); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + +protected: + float mSpacing; +}; + +class SCHLayoutView : public SCLayoutView +{ +public: + SCHLayoutView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCHLayoutView(); + + virtual void setBounds(SCRect inBounds); + +protected: +}; + +class SCVLayoutView : public SCLayoutView +{ +public: + SCVLayoutView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCVLayoutView(); + + virtual void setBounds(SCRect inBounds); + +protected: +}; + +// tell host to draw stuff. +typedef void (*DamageCallback)(SCRect inRect, void *inData); +typedef void (*DragCallback)(SCPoint where, PyrSlot* inSlot, void *inData); + +class SCTopView : public SCCompositeView +{ +public: + SCTopView(PyrObject* inObj, SCRect inBounds); + + SCView *focusView() { return mFocusView; } + + void resetFocus(); + void addDamage(SCRect inRect); + void beginDragCallback(SCPoint where, PyrSlot* slot); + + void setDamageCallback(DamageCallback inFunc, void *inHostData) + { mDamageCallback = inFunc; mHostData = inHostData; } + void setDragCallback(DragCallback inFunc) + { mDragCallback = inFunc; } + + void tabNextFocus(); + void tabPrevFocus(); + void setDragView(SCView *inView); + + NSView* GetNSView() { return mNSView; } + void SetNSView(NSView* inView) { mNSView = inView; } + + bool ConstructionMode() { return mConstructionMode; } + void SetConstructionMode(bool inFlag) { mConstructionMode = inFlag; } + + virtual void drawFocus(SCRect inDamage); + +protected: + friend class SCView; + void focusIs(SCView *inView) { mFocusView = inView; } + + DamageCallback mDamageCallback; + DragCallback mDragCallback; + void *mHostData; + SCView *mFocusView; + SCView *mDragView; + NSView *mNSView; + + bool mConstructionMode; +}; + +inline bool SCView::isFocus() const { return mTop->focusView() == this; } + +class SCSlider : public SCView +{ +public: + SCSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + virtual void draw(SCRect inDamage); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + + double value() { return mValue; } + bool setValue(double inValue, bool send); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + +protected: + virtual void setValueFromPoint(SCPoint point); + void calcThumbRect(); + + SCRect mThumbRect; + double mValue, mStepSize, mStepScale; + DrawBackground* mKnob; +}; +SCView* NewSCSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + +class SCRangeSlider : public SCView +{ +public: + SCRangeSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + virtual void draw(SCRect inDamage); + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + + bool setValue(double inLo, double inHi, bool send); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + +protected: + virtual void setValueFromPoint(SCPoint point); + // sc.solar addition + void moveRangeFromPoint(SCPoint point); + void adjustLoFromPoint(SCPoint point); + void adjustHiFromPoint(SCPoint point); + // sc.solar addition end + void calcRangeRect(); + + SCRect mRangeRect; + double mLo, mHi, mStepSize, mStepScale; + SCPoint mAnchor; + DrawBackground* mKnob; +}; +SCView* NewSCRangeSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + + +class SC2DSlider : public SCView +{ +public: + SC2DSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + virtual void draw(SCRect inDamage); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + + virtual bool setValue(double inLo, double inHi, bool send); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + +protected: + virtual void setValueFromPoint(SCPoint point); + void calcThumbRect(); + + SCRect mThumbRect; + double mX, mY; + double mStepSize, mStepScale; + DrawBackground* mKnob; +}; +SCView* NewSC2DSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + +class SC2DTabletSlider : public SC2DSlider +{ +public: + SC2DTabletSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + + virtual bool setValue(double inX, double inY,bool send); + +protected: + int mClipInBounds; + +}; +SCView* NewSC2DTabletSlider(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + +#include "SC_SndBuf.h" + +const int kMaxScopeChannels = 16; +class SCScope : public SCView +{ +public: + SCScope(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCScope(); + + virtual void draw(SCRect inDamage); + virtual void draw0(CGContextRef cgc); + virtual void draw1(CGContextRef cgc); + virtual void draw2(CGContextRef cgc); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void animate(); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + + SCPoint pixelToUnits(SCPoint p, SCRect r) + { + return SCMakePoint( + (p.x - r.x) * mZoom.x + mScroll.x, + (p.y - r.y) * mZoom.y + mScroll.y); + } + SCPoint unitsToPixel(SCPoint u, SCRect r) + { + return SCMakePoint( + (u.x - mScroll.x) * mInvZoom.x + r.x, + (u.y - mScroll.y) * mInvZoom.y + r.y); + } + +protected: + + int mBufNum; + SndBuf mSndBuf; + SCPoint mZoom, mInvZoom, mScroll; + int mStyle; // 0 = separate, 1 = overlay, 2 = x,y. + SCColor mWaveColors[kMaxScopeChannels]; + SCColor mGridColor; + bool mGridOn; +}; +SCView* NewSCScope(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + + +const int kLabelSize = 64; +struct SCButtonState +{ + char mLabel[kLabelSize]; + SCColor mLabelColor; + SCColor mButtonColor; +}; + +const int kFontNameSize = 80; + +class SCButton : public SCView +{ +public: + SCButton(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCButton(); + + virtual void draw(SCRect inDamage); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent); + + bool setValue(int inValue, bool send); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + +protected: + + int mValue; + char mFontName[kFontNameSize]; + float mFontSize; + int mNumStates; + SCButtonState *mStates; + bool mPushed; +}; +SCView* NewSCButton(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + +class SCPopUpMenu : public SCView +{ +public: + SCPopUpMenu(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCPopUpMenu(); + + virtual void draw(SCRect inDamage); + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + + bool setValue(int inValue, bool send); + virtual void setMenuItemChosen(int inItem) { setValue(inItem, true); } + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + +protected: + + int mValue; + MenuHandle mMenuH; + char mFontName[kFontNameSize]; + float mFontSize; + SCColor mStringColor; +}; +SCView* NewSCPopUpMenu(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + +class SCListView : public SCView +{ +public: + SCListView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCListView(); + + virtual void draw(SCRect inDamage); + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseTrack(SCPoint where, int modifiers, NSEvent *theEvent); + + bool setValue(int inValue, bool send); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + + void scrollToValue(); + +protected: + + int mValue; + CFMutableArrayRef mArray; + char mFontName[kFontNameSize]; + float mFontSize; + float mScroll; + float mAnchorScroll; + SCPoint mAnchor; + SCColor mStringColor; + SCColor mSelectedStringColor; + SCColor mHiliteColor; + int mAlignment; + NSSize mStrSize; + bool mScrolling; +}; +SCView* NewSCListView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + +//by jan trutzschler (jt@kandos.de) +class SCMultiSliderView : public SCView +{ +public: + SCMultiSliderView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCMultiSliderView(); + + virtual void draw(SCRect inDamage); + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + + void setSelection(SCPoint where); + bool setValue(int inX, double inY, bool send); + //virtual void setPoint(int x, double y, bool send); + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + void setVisibleSize(); + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + +protected: + int indexFromPoint(SCPoint where); +// int getVisibleMax(); + + double valueFromPoint(SCPoint where); + void setValueFromPoint(SCPoint point); + SCRect calcThumbRect(int xIn, double valIn, double step); + int mThumbSize, mThumbSizeY; // size of the rect + int mTabSize, mVisibleSize; // size of the table + SCColor mFillColor; + SCColor mStrokeColor; + SCRect mThumbRect; + double mCurrentY, mCurrentX; + int mCurrentIndex, mStartIndex, mSelectionSize; + double mStepSize, mStepScale; + double * mYValues; + double * mSecYValues; + DrawBackground* mKnob; + float mXOffset ; //space between points + bool mReadOnly, mDrawLinesActive, mShowIndex, mDrawRectsActive, mIsHorizontal, mIsFilled; + SCPoint mPrevPoint; + int mElasticMode; + double mElasticIndexStep; + +}; +SCView* NewSCMultiSliderView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); +//// +//by jan truetzschler jt@kandos.de +struct SCEnvObject { + SCColor mColor; //changes between selected and mObjectColor + SCColor mObjectColor; //if its not selected + SCRect mRect; + int mNumConnection; + SCPoint mDrawPoint; + double * mConnections; //tells to where it is connected + int mNumInputs, mNumOutputs; + double x, y; + bool mIsSelected, mIsVisible, mIsStatic; + char *mString; +}; +typedef struct SCEnvObject SCEnvObject; + +class SCEnvelopeView : public SCView +{ +public: + SCEnvelopeView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCEnvelopeView(); + virtual void draw(SCRect inDamage); + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + + void setSelection(SCPoint where, bool fixed, bool checkForConnection); + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + +protected: + + void setValueFromPoint(SCPoint point); + bool setValue(SCEnvObject * envob, double x, double y, bool send); + int allocSlotEnvObjArray(PyrSlot *slot, SCEnvObject **arr); + bool setEnvRect(double valX, double valY, SCEnvObject * envobIn); + + int mThumbSize, mThumbSizeY; // size of the rect + int mTabSize, mVisibleSize, mActiveSize; // size of the table + SCColor mFillColor, mSelectedColor, mStrokeColor; + SCRect mThumbRect; + double mCurrentY, mCurrentX, mAbsoluteX; + int mCurrentIndex, mStartIndex, mSelectionSize, mLastIndex; + double mStepSize, mStepScale; + SCEnvObject * mEnvObj; + //DrawBackground* mKnob; + bool mDrawLinesActive, mShowIndex, mDrawRectsActive, mIsFilled, mIsFixedSelection, mIsEnvView; + int mSelectedIndex; + SCPoint mMousePoint; + + double xGridMultiplier; + + //draw string in box + char mFontName[kFontNameSize]; + float mFontSize; + SCColor mStringColor; + int mAlignment; + bool mDrawCenteredConnection; + + +}; +SCView* NewSCEnvelopeView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + +// + +class SCUserView : public SCView +{ +public: + SCUserView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + virtual void draw(SCRect inDamage); + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void keyDown(int character, int modifiers); + virtual void keyUp(int character, int modifiers); + +protected: + void mouseAction(PyrSymbol *method, SCPoint where, int modifiers); +}; +SCView* NewSCUserView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + +enum { + kSCAlignLeft = -1, + kSCAlignCenter, + kSCAlignRight +}; + +class SCStaticText : public SCView +{ +public: + SCStaticText(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCStaticText(); + + virtual void draw(SCRect inDamage); + virtual bool shouldDim(); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + +protected: + virtual void drawString(SCRect bounds); + + char *mString; + char mFontName[kFontNameSize]; + float mFontSize; + SCColor mStringColor; + int mAlignment; + +}; +SCView* NewSCStaticText(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + +class SCNumberBox : public SCStaticText +{ +public: + SCNumberBox(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCNumberBox(); + + virtual void draw(SCRect inDamage); + virtual bool shouldDim(); + + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + //virtual void mouseEndTrack(SCPoint where, int modifiers); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + virtual int getProperty(PyrSymbol *symbol, PyrSlot *slot); + + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + +protected: + SCColor mBoxColor; +}; +SCView* NewSCNumberBox(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + +class SCDragSource : public SCStaticText +{ +public: + SCDragSource(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCDragSource(); + + virtual void draw(SCRect inDamage); + virtual bool shouldDim(); + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + +protected: +}; +SCView* NewSCDragSource(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + +class SCDragSink : public SCStaticText +{ +public: + SCDragSink(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCDragSink(); + + virtual void draw(SCRect inDamage); + virtual bool shouldDim(); + + virtual bool canReceiveDrag(); + virtual void receiveDrag(); + +protected: +}; +SCView* NewSCDragSink(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + +class SCDragBoth : public SCDragSink +{ +public: + SCDragBoth(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + virtual void draw(SCRect inDamage); + + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + +protected: +}; +SCView* NewSCDragBoth(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + + +//felix +class SCTabletView : public SCView +{ +public: + SCTabletView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + virtual ~SCTabletView(); + + virtual int setProperty(PyrSymbol *symbol, PyrSlot *slot); + + virtual void mouseBeginTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseTrack(SCPoint where, int modifiers,NSEvent *theEvent); + virtual void mouseEndTrack(SCPoint where, int modifiers,NSEvent *theEvent); +protected: + int mClipToBounds; +}; +SCView* NewSCTabletView(SCContainerView *inParent, PyrObject* inObj, SCRect inBounds); + diff --git a/sc4pd/headers/app/SCVirtualMachine.h b/sc4pd/headers/app/SCVirtualMachine.h new file mode 100644 index 0000000..354e8a5 --- /dev/null +++ b/sc4pd/headers/app/SCVirtualMachine.h @@ -0,0 +1,65 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import <Cocoa/Cocoa.h> + + +@interface SCVirtualMachine : NSObject { + NSMutableArray *deferredOperations; + NSMutableArray *guiWindows; + NSTimer *deferredTaskTimer; + NSTimer *appClockTimer; +} + ++ (id)sharedInstance; + +- (id)init; +- (void)start; +- (void)doPeriodicTask: (NSTimer*) timer; +- (void)doClockTask: (NSTimer*) timer; +- (void)setCmdLine: (const char*) text length: (int)length; +- (void)sendMain: (char*) methodName; + +- (void)defer: (NSInvocation*) action; +- (void)performDeferredOperations; +- (void)doAnimatedViews; + +- (void)addWindow: (NSWindow*)window; +- (void)closeAllGUIWindows; + +- (IBAction) runMain: (id) sender; +- (IBAction) stopMain: (id) sender; +- (IBAction) compileLibrary: (id) sender; +- (IBAction) newSCWindow: (id) sender; +- (IBAction)clearPostWindow:(id)sender; +- (void)postWindowToFront:(id)sender; + +// deferred primitives + + +- (void)becomeFullScreen: (NSWindow*)window; +- (void)endFullScreen: (NSWindow*)window; +- (void)loadUserPanel:(NSString*)filename SCObject: (void*)scobj; + + +-(IBAction)showHelp:(id)sender; + + +@end diff --git a/sc4pd/headers/app/TabletEvents.h b/sc4pd/headers/app/TabletEvents.h new file mode 100644 index 0000000..3607ab9 --- /dev/null +++ b/sc4pd/headers/app/TabletEvents.h @@ -0,0 +1,75 @@ +/*---------------------------------------------------------------------------- + +FILE NAME + +TabletEvents.h - Header file for TabletEvent Category. + This is an extension to the NSEvent class. + +COPYRIGHT + +Copyright WACOM Technology, Inc. 2001. + +All rights reserved. + +----------------------------------------------------------------------------*/ + +#import <Cocoa/Cocoa.h> +#import <Carbon/Carbon.h> + +@interface NSEvent ( TabletEvents ) + +- (void *)eventRef; +- (BOOL) isTabletPointerEvent; +- (BOOL) isTabletProximityEvent; +- (void) setLocation:(NSPoint)loc; +- (TabletPointerRec) tabletRec; +- (SInt32) absoluteX; +- (SInt32) absoluteY; +- (SInt32) absoluteZ; +- (void) getAbsoluteX:(SInt32*)absX Y:(SInt32*)absY Z:(SInt32*)absZ; +- (NSPoint) tilt; +- (UInt16) rawTabletPressure; +- (float) scaledTabletPressure; +- (float) rotationInDegrees; /* 0¡ <-> +359.9999¡ */ +- (float) rotationInRadians; /* 0 <-> 2¹ */ +- (UInt16) deviceID; + +@end + +/////////////////////////////////////////////////////////////////////////// +/* This is the name of the Notification sent when a proximity event is + captured by the application */ +extern NSString *kProximityNotification; + +/* vendor-defined ID - typically will be USB vendor ID */ +extern NSString *kVendorID; + +/* vendor-defined tablet ID */ +extern NSString *kTabletID; + +/* vendor-defined ID of the specific pointing device */ +extern NSString *kPointerID; + +/* unique device ID - matches to deviceID field in tablet event */ +extern NSString *kDeviceID; + +/* unique tablet ID */ +extern NSString *kSystemTabletID; + +/* vendor-defined pointer type */ +extern NSString *kVendorPointerType; + + /* vendor-defined serial number of the specific pointing device */ +extern NSString *kPointerSerialNumber; + + /* vendor-defined unique ID for this pointer */ +extern NSString *kUniqueID; + +/* mask representing the capabilities of the device */ +extern NSString *kCapabilityMask; + + /* type of pointing device - enum to be defined */ +extern NSString *kPointerType; + + /* non-zero = entering; zero = leaving */ +extern NSString *kEnterProximity; diff --git a/sc4pd/headers/app/TextFinder.h b/sc4pd/headers/app/TextFinder.h new file mode 100644 index 0000000..66de160 --- /dev/null +++ b/sc4pd/headers/app/TextFinder.h @@ -0,0 +1,64 @@ +/* + Reusable find panel functionality (find, replace). + Need one shared instance of TextFinder to which the menu items and widgets in the find panel are connected. + Loads UI lazily. + Works on first responder, assumed to be an NSTextView. +*/ + +#import <Cocoa/Cocoa.h> + +#define Forward YES +#define Backward NO + +@interface TextFinder : NSObject { + NSString *findString; + NSString *replaceString; + id findTextField; + id replaceTextField; + id ignoreCaseButton; + id findNextButton; + id replaceAllScopeMatrix; + id statusField; + BOOL lastFindWasSuccessful; +} + +/* Common way to get a text finder. One instance of TextFinder per app is good enough. */ ++ (id)sharedInstance; + +/* Main method for external users; does a find in the first responder. Selects found range or beeps. */ +- (BOOL)find:(BOOL)direction; + +/* Loads UI lazily */ +- (NSPanel *)findPanel; + +/* Gets the first responder and returns it if it's an NSTextView */ +- (NSTextView *)textObjectToSearchIn; + +/* Get/set the current find string. Will update UI if UI is loaded */ +- (NSString *)findString; +- (void)setFindString:(NSString *)string; +- (void)setFindString:(NSString *)string writeToPasteboard:(BOOL)flag; + +/* Get/set the current replace string. Will update UI if UI is loaded */ +- (NSString *)replaceString; +- (void)setReplaceString:(NSString *)string; + +/* Misc internal methods */ +- (void)appDidActivate:(NSNotification *)notification; +- (void)loadFindStringFromPasteboard; +- (void)loadStringToPasteboard:(NSString *)string; + +/* Action methods, sent from the find panel UI; can also be connected to menu items */ +- (void)findNext:(id)sender; +- (void)findPrevious:(id)sender; +- (void)findNextAndOrderFindPanelOut:(id)sender; +- (void)replace:(id)sender; +- (void)replaceAndFind:(id)sender; +- (void)replaceAll:(id)sender; +- (void)orderFrontFindPanel:(id)sender; +- (void)takeFindStringFromSelection:(id)sender; +- (void)takeReplaceStringFromSelection:(id)sender; +- (void)jumpToSelection:(id)sender; + +@end + diff --git a/sc4pd/headers/app/UserPanel.h b/sc4pd/headers/app/UserPanel.h new file mode 100644 index 0000000..4dd724b --- /dev/null +++ b/sc4pd/headers/app/UserPanel.h @@ -0,0 +1,40 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import <Cocoa/Cocoa.h> + +@interface UserPanel : NSObject +{ + IBOutlet id window; + void *scobject; +} + ++ (void)closeAll; + +- (id)init; +- (NSWindow*)window; +- (void)close; +- (void)windowWillClose:(NSNotification *)aNotification; +- (void)setSCObject: (void*)inObject; +- (void*) getSCObject; + +- (IBAction) panelAction: (id) sender; + +@end diff --git a/sc4pd/headers/common/SC_AllocPool.h b/sc4pd/headers/common/SC_AllocPool.h new file mode 100644 index 0000000..fc9d72a --- /dev/null +++ b/sc4pd/headers/common/SC_AllocPool.h @@ -0,0 +1,278 @@ + +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* +This is based on Doug Lea's allocator but rewritten so I can read and understand it... +also features of free all-at-once pools are added. +Now uses 16 byte alignment, which does increase the minimum allocation size to 32 bytes +including the overhead. +Improved bit block scanning by using a count leading zeroes instruction. + +*/ + +#ifndef _AllocPool_ +#define _AllocPool_ + +#include "SC_List.h" +#include "clz.h" +#include <stdlib.h> + +const int kNumAllocBins = 128; +const int kNumSmallBins = 64; +const int kMaxSmallBin = kNumSmallBins - 1; +const int kBinWidth = 8; +const int kMaxSmallBinSize = kNumSmallBins * kBinWidth; +const int kBinBlockWidth = 4; +const int kBinBlockMask = kBinBlockWidth - 1; + +const size_t kAlign = 16; +const size_t kAlignMask = kAlign - 1; +const size_t kChunkFree = 0; +const size_t kChunkInUse = 1; +const size_t kSizeBits = ~kChunkInUse; + +class AllocChunk; +class AllocPool; +typedef AllocChunk *AllocChunkPtr; +typedef Link<AllocChunk> AllocBin; +typedef AllocBin* AllocBinPtr; + +class AllocChunk : public Link<AllocChunk> +{ + friend class AllocPool; + + size_t Size() + { return mSize & kSizeBits; } + + size_t PrevSize() + { return mPrevSize & kSizeBits; } + + AllocChunkPtr ChunkAtOffset(size_t inSize) + { return AllocChunkPtr((char*)this + inSize); } + + AllocChunkPtr NextChunk() + { return ChunkAtOffset(Size()); } + + AllocChunkPtr PrevChunk() + { return ChunkAtOffset(-PrevSize()); } + + bool InUse() + { return (bool)(mSize & kChunkInUse); } + + bool PrevInUse() + { return (bool)(mPrevSize & kChunkInUse); } + + void SetSizeFree(size_t inSize) + { mSize = ChunkAtOffset(inSize)->mPrevSize = inSize; } + + void SetSizeInUse(size_t inSize) + { mSize = ChunkAtOffset(inSize)->mPrevSize = inSize | kChunkInUse; } + + void SetNeighborsInUse(size_t inOffset) + { mPrevSize = ChunkAtOffset(inOffset)->mSize = kChunkInUse; } + + bool IsArea() + { return mPrevSize == kChunkInUse && NextChunk()->mSize == kChunkInUse; } + + void* ToPtr() + { return (void*)((char*)this + sizeof(AllocChunk)); } + + size_t mPrevSize; + size_t mSize; +}; + +class AllocArea; +typedef AllocArea* AllocAreaPtr; + +class AllocAreaHdr /* for size calculations */ +{ +protected: + friend class AllocPool; + + AllocAreaPtr mPrev, mNext; + size_t mSize; + void *mUnalignedPointerToThis; +}; + +class AllocArea : public AllocAreaHdr +{ +public: + void SanityCheck(); + +private: + friend class AllocPool; + + AllocChunk mChunk; +}; + +const size_t kMinAllocSize = 2 * kAlign; +// FIXME: add kAlign to overhead? <sk> +const size_t kAreaOverhead = sizeof(AllocAreaHdr) + 2 * sizeof(AllocChunk); + +typedef void* (*NewAreaFunc)(size_t size); +typedef void (*FreeAreaFunc)(void *); + +class AllocPool +{ +public: + AllocPool(NewAreaFunc allocArea, FreeAreaFunc freeArea, + size_t areaInitSize, size_t areaMoreSize); + ~AllocPool(); + + void Reinit(); + + void *Alloc(size_t inBytes); + void *Realloc(void* inPtr, size_t inBytes); + void Free(void* inPtr); + void FreeAll(); + void FreeAllInternal(); + + // debugging + size_t TotalFree(); + size_t LargestFreeChunk(); + + void DoCheckPool(); + void DoCheckInUseChunk(AllocChunkPtr p); + + static AllocChunkPtr MemToChunk(void *inPtr) + { return (AllocChunkPtr)((char*)(inPtr) - sizeof(AllocChunk)); } + +private: + void InitAlloc(); + void InitBins(); + AllocAreaPtr NewArea(size_t inAreaSize); + void FreeArea(AllocChunkPtr chunk); + + // debugging + void DoCheckArea(AllocAreaPtr area); + void DoCheckBin(AllocChunkPtr bin, long idx); + void DoCheckChunk(AllocChunkPtr p); + void DoCheckFreeChunk(AllocChunkPtr p); + void DoCheckAllocedChunk(AllocChunkPtr p, size_t s); + void DoGarbageFill(AllocChunkPtr p); + void DoGarbageFill(AllocChunkPtr p, long size); + + // inlines + + static size_t RequestToSize(size_t inReqSize) + { + size_t sizePlusOverhead = inReqSize + sizeof(AllocChunk); + if (sizePlusOverhead <= kMinAllocSize) return kMinAllocSize; + else return (sizePlusOverhead + kAlignMask) & ~kAlignMask; + } + + static int SmallBinIndex(size_t inSize) + { return inSize >> 4; } + + static int BinIndex2(size_t inSize) + { + return + ((inSize < 1024) ? (inSize>>4): + (inSize < 2048) ? 56 + (inSize>>7): + (inSize < 4096) ? 64 + (inSize>>8): + (inSize < 8192) ? 72 + (inSize>>9): + (inSize < 16384) ? 80 + (inSize>>10): + (inSize < 32768) ? 88 + (inSize>>11): + (inSize < 65536) ? 96 + (inSize>>12): + (inSize < 131072) ? 104 + (inSize>>13): + (inSize < 262144) ? 112 + (inSize>>14):127); + } + + static int BinIndex(size_t inSize) + { + if (inSize < 1024) return inSize >> 4; + if (inSize >= 262144) return 127; + int bits = 28 - CLZ(inSize); + return (bits << 3) + (inSize >> bits) ; + } + + void MarkBinBlock(int inIndex) + { + unsigned long word = inIndex >> 5; + unsigned long bitPosition = inIndex & 31; + unsigned long bitValue = 1L << bitPosition; + mBinBlocks[word] |= bitValue; + } + + void ClearBinBlock(int inIndex) + { + unsigned long word = inIndex >> 5; + unsigned long bitPosition = inIndex & 31; + unsigned long bitValue = 1L << bitPosition; + mBinBlocks[word] &= ~bitValue; + } + + int NextFullBin(int inStartingBinIndex) + { + if (inStartingBinIndex >= 128) return -1; + int word = inStartingBinIndex >> 5; + int bitPosition = inStartingBinIndex & 31; + unsigned long bitValue = 1L << bitPosition; + unsigned long binBits = mBinBlocks[word]; + + if (binBits >= bitValue) { + binBits = (~(bitValue - 1) & binBits); + } else { + for (++word; word<4 && !mBinBlocks[word]; ++word) {} + if (word==4) return -1; + binBits = mBinBlocks[word]; + } + bitPosition = CTZ((int32)binBits); + + return (word << 5) + bitPosition; + } + + void LinkFree(AllocChunkPtr inChunk); + /* + { + size_t size = inChunk->Size(); + int index = BinIndex(size); + + AllocChunkPtr bin = mBins + index; + + if (index < kNumSmallBins || bin->IsEmpty()) { + inChunk->InsertAfter(bin); + MarkBinBlock(index); + } else { + AllocChunkPtr link = bin->Next(); + while (link != bin && size < link->Size()) link = link->Next(); + inChunk->InsertBefore(link); + } + } + */ + + void UnlinkFree(AllocChunkPtr inChunk) + { + inChunk->RemoveLeaveDangling(); + size_t size = inChunk->Size(); + int index = BinIndex(size); + AllocChunkPtr bin = mBins + index; + if (bin->IsEmpty()) ClearBinBlock(index); + } + + AllocChunk mBins[kNumAllocBins]; + AllocAreaPtr mAreas; + NewAreaFunc mAllocArea; + FreeAreaFunc mFreeArea; + size_t mAreaInitSize, mAreaMoreSize; + unsigned long mBinBlocks[4]; +}; + +#endif diff --git a/sc4pd/headers/common/SC_Altivec.h b/sc4pd/headers/common/SC_Altivec.h new file mode 100644 index 0000000..8ae3f66 --- /dev/null +++ b/sc4pd/headers/common/SC_Altivec.h @@ -0,0 +1,118 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2003 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_Altivec_ +#define _SC_Altivec_ + +#if defined(SC_LINUX) && defined(__ALTIVEC__) +# include <altivec.h> +#endif + +#if __VEC__ + +typedef vector signed int vint32; +typedef vector unsigned int vuint32; +typedef vector float vfloat32; + +// Since gcc 3.3 vector initializers are surrounded by brackets. <sk> +#if defined(__GNUC__) && (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 3) +# define vinit(x) { x, x, x, x } +#else +# define vinit(x) ( x ) +#endif + +//#define vload(x) (*vtempptr = (x), vec_splat(vtemp,0)) +#define define_vtemp vfloat32 vtemp; float *vtempptr = (float*)&vtemp; +#define define_vones vfloat32 vones = vec_ctf(vec_splat_s32(1),0); +#define define_vzero vfloat32 vzero = (vfloat32)vec_splat_s32(0); +#define vi0123 (vec_unpackh(vec_unpackh((vector signed char)vec_lvsl(0,(int*)0)))) +#define v0123 (vec_ctf(vec_unpackh(vec_unpackh((vector signed char)vec_lvsl(0,(int*)0))), 0)) +#define v0123_4ths (vec_ctf(vec_unpackh(vec_unpackh((vector signed char)vec_lvsl(0,(int*)0))), 2)) +#define vstart(x, vslope) (vec_madd(vslope, v0123_4ths, vload(x))) + +#define vec_not(a) (vtemp = (a); vec_nor(vtemp, vtemp)) +#define vec_cmplt(a, b) (vec_cmpgt(b, a)) +#define vec_cmple(a, b) (vec_cmpge(b, a)) +#define vec_mul(a, b) (vec_madd(a, b, vzero)) +#define vec_2sComp(x) (vec_sub(vec_sub (x, x), x)) + +#define USEVEC (ft->mAltivecAvailable && !(BUFLENGTH & 3)) + +typedef union vec_union { + int32 i[4]; + float32 f[4]; + vint32 vi; + vfloat32 vf; +} vec_union; + +inline vfloat32 vload( float f ) +{ + vec_union temp; + temp.f[0] = f; + return vec_splat( vec_lde( 0, temp.f ), 0 ); +} + +inline vint32 vload( int32 i ) +{ + vec_union temp; + temp.i[0] = i; + return vec_splat( vec_lde( 0, temp.i ), 0 ); +} + +inline vint32 vload( int32 a, int32 b, int32 c, int32 d ) +{ + vec_union temp; + temp.i[0] = a; + temp.i[1] = b; + temp.i[2] = c; + temp.i[3] = d; + return temp.vi; +} + +inline vector float vec_float_1( void ) +{ + return vec_ctf( vec_splat_u32(1), 0); +} + +inline vector float vec_reciprocal( vector float v ) +{ + vector float reciprocal = vec_re( v ); + return vec_madd( reciprocal, vec_nmsub( reciprocal, v, vec_float_1()), reciprocal ); //Newton Rapheson refinement +} + +#define vec_div(a, b) vec_mul(a, vec_reciprocal(b)) + +// seed = ((seed & mask) << shift1) ^ (((seed << shift2) ^ seed) >> shift3); + +#define define_trshifts \ + vuint32 trmask = ((vuint32)(0xFFFFFFFE,0xFFFFFFF8,0xFFFFFFF0,0)); \ + vuint32 trshift1 = ((vuint32)(12, 14, 7, 0)); \ + vuint32 trshift2 = ((vuint32)(13, 2, 3, 0)); \ + vuint32 trshift3 = ((vuint32)(19, 25, 11, 0)); + +inline vuint32 trands(vuint32 seed, vuint32 trmask, vuint32 shift1, vuint32 shift2, vuint32 shift3) +{ + return vec_xor(vec_sl(vec_and(seed, trmask),shift1), vec_sr(vec_xor(vec_sl(seed,shift2),seed),shift3)); +} + +#endif +#endif + + diff --git a/sc4pd/headers/common/SC_Endian.h b/sc4pd/headers/common/SC_Endian.h new file mode 100644 index 0000000..ba127f5 --- /dev/null +++ b/sc4pd/headers/common/SC_Endian.h @@ -0,0 +1,64 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* NOTE: This file should declare/define the following functions/macros: + + htonl + htons + ntohl + ntohs + + either explicitly or implicitly by including system headers. +*/ + +#ifndef SC_ENDIAN_H_INCLUDED +#define SC_ENDIAN_H_INCLUDED + +#ifdef SC_DARWIN + +# include <machine/endian.h> + +#elif defined(SC_WIN32) + +# define LITTLE_ENDIAN 1234 +# define BIG_ENDIAN 4321 +# define BYTE_ORDER LITTLE_ENDIAN +# include <winsock2.h> + +#else + +# include <endian.h> +# include <netinet/in.h> + +#endif + +#ifndef BYTE_ORDER +# error BYTE_ORDER undefined, check __FILE__ +#endif // BYTE_ORDER + +#ifndef BIG_ENDIAN +# error BIG_ENDIAN undefined, check __FILE__ +#endif // BIG_ENDIAN + +#ifndef LITTLE_ENDIAN +# error LITTLE_ENDIAN undefined, check __FILE__ +#endif // LITTLE_ENDIAN + +#endif // SC_ENDIAN_H_INCLUDED diff --git a/sc4pd/headers/common/SC_Sem.h b/sc4pd/headers/common/SC_Sem.h new file mode 100644 index 0000000..22a2ffa --- /dev/null +++ b/sc4pd/headers/common/SC_Sem.h @@ -0,0 +1,43 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Semaphore_ +#define _SC_Semaphore_ + +#include <pthread.h> + +class SC_Semaphore +{ +public: + SC_Semaphore(int initialCount); + ~SC_Semaphore(); + + void Acquire(); + void Release(); + +private: + pthread_cond_t available; + pthread_mutex_t mutex; + int count; +}; + +#endif + diff --git a/sc4pd/headers/common/SC_StringBuffer.h b/sc4pd/headers/common/SC_StringBuffer.h new file mode 100644 index 0000000..24bcd4d --- /dev/null +++ b/sc4pd/headers/common/SC_StringBuffer.h @@ -0,0 +1,67 @@ +// emacs: -*- c++ -*- +// file: SC_StringBuffer.h +// copyright: 2003 stefan kersten <steve@k-hornz.de> +// cvs: $Id: SC_StringBuffer.h,v 1.1.1.1 2004-07-14 16:21:36 timblech Exp $ + +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA + +#ifndef SC_STRINGBUFFER_H_INCLUDED +#define SC_STRINGBUFFER_H_INCLUDED + +#include <stdarg.h> +#include <stdlib.h> + +// ===================================================================== +// SC_StringBuffer - Autogrowing string buffer. +// ===================================================================== + +class SC_StringBuffer +{ +public: + SC_StringBuffer(size_t initialSize=0); + SC_StringBuffer(const SC_StringBuffer& other); + ~SC_StringBuffer(); + + size_t getCapacity() const { return mCapacity; } + size_t getSize() const { return mPtr - mData; } + size_t getRemaining() const { return mCapacity - getSize(); } + char* getData() const { return mData; } + + bool isEmpty() const { return getSize() == 0; } + + void finish() { append('\0'); } + void reset() { mPtr = mData; } + void append(const char* src, size_t len); + void append(char c); + void append(const char* str); + void vappendf(const char* fmt, va_list vargs); + void appendf(const char* fmt, ...); + +protected: + enum { + kGrowAlign = 256, + kGrowMask = kGrowAlign - 1 + }; + + void growBy(size_t request); + +private: + size_t mCapacity; + char* mPtr; + char* mData; +}; + +#endif // SC_STRINGBUFFER_H_INCLUDED diff --git a/sc4pd/headers/common/SC_StringParser.h b/sc4pd/headers/common/SC_StringParser.h new file mode 100644 index 0000000..f2d414e --- /dev/null +++ b/sc4pd/headers/common/SC_StringParser.h @@ -0,0 +1,40 @@ +// emacs: -*- c++ -*- +// file: SC_StringParser.h +// copyright: 2003 stefan kersten <steve@k-hornz.de> +// cvs: $Id: SC_StringParser.h,v 1.1.1.1 2004-07-14 16:21:37 timblech Exp $ + +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA + +#ifndef _SC_StringParser_ +#define _SC_StringParser_ + +#define SC_MAX_TOKEN_LENGTH 256 + +class SC_StringParser +{ + char *mSpec, *mStart, *mEnd; + char mSep, mBuf[SC_MAX_TOKEN_LENGTH]; + +public: + SC_StringParser(); + SC_StringParser(char *spec, char sep); + + bool AtEnd() const; + const char *NextToken(); +}; + +#endif + diff --git a/sc4pd/headers/common/dfftlib.h b/sc4pd/headers/common/dfftlib.h new file mode 100644 index 0000000..409267e --- /dev/null +++ b/sc4pd/headers/common/dfftlib.h @@ -0,0 +1,62 @@ +long dFFTInit(long *fftMptr, long fftN, double *Utbl); +/* Compute cosine table and check size for complex ffts */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ + +long drFFTInit(long *fftMptr, long fftN, double *Utbl); +/* Compute cosine table and check size for a real input fft */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ + +void dffts(double *ioptr, long M, long Rows, double *Utbl); +/* Compute in-place complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +void diffts(double *ioptr, long M, long Rows, double *Utbl); +/* Compute in-place inverse complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +void drffts(double *ioptr, long M, long Rows, double *Utbl); +/* Compute in-place real fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = real input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ + + +void driffts(double *ioptr, long M, long Rows, double *Utbl); +/* Compute in-place real ifft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = real output data array */ diff --git a/sc4pd/headers/common/fftlib.h b/sc4pd/headers/common/fftlib.h new file mode 100644 index 0000000..b03317d --- /dev/null +++ b/sc4pd/headers/common/fftlib.h @@ -0,0 +1,62 @@ +long FFTInit(long *fftMptr, long fftN, float *Utbl); +/* Compute cosine table and check size for complex ffts */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ + +long rFFTInit(long *fftMptr, long fftN, float *Utbl); +/* Compute cosine table and check size for a real input fft */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ + +void ffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +void iffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place inverse complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +void rffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place real fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = real input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ + + +void riffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place real ifft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = real output data array */ diff --git a/sc4pd/headers/common/scsynthsend.h b/sc4pd/headers/common/scsynthsend.h new file mode 100644 index 0000000..97f345b --- /dev/null +++ b/sc4pd/headers/common/scsynthsend.h @@ -0,0 +1,191 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _scpacket_ +#define _scpacket_ + +#include "SC_Endian.h" +#include "SC_Types.h" +#include <stdexcept> + +struct netaddr { + int socket; + int addr; + int port; +}; +typedef struct netaddr netaddr; + +#define kSCMaxPacketSize 8192 + +struct scpacket { + int32 *wrpos, *endpos, *msgsizepos; + char *tagwrpos; + int inbundle; + int32 buf[kSCMaxPacketSize]; + + scpacket(); + void reset(); + void addi(int i); + void addii(int64 ii); + void addf(float f); + void addd(double f); + void adds(char *cstr); + void adds(char *src, size_t len); + void addb(uint8 *src, size_t len); + void addtag(char c); + void skip(int n); + void maketags(int n); + int size() { return (char*)wrpos - (char*)buf; } + char* data() { return (char*)buf; } + + void sendudp(int socket, int addr, int port); + + void OpenBundle(int64 time); + void CloseBundle(); + + void BeginMsg(); + void EndMsg(); +}; + +inline scpacket::scpacket() { reset(); } + +// ways to fail +#define BUFFEROVERFLOW return +//#define BUFFEROVERFLOW throw std::runtime_error("buffer overflow") + +inline void scpacket::reset() +{ + wrpos = buf; + endpos = buf + kSCMaxPacketSize; + inbundle = 0; +} + +inline void scpacket::skip(int n) +{ + if (wrpos + n > endpos) BUFFEROVERFLOW; + wrpos += n; +} + +inline void scpacket::addtag(char c) +{ + *tagwrpos++ = c; +} + +inline void scpacket::maketags(int n) +{ + int size4 = (n + 4) >> 2; + tagwrpos = (char*)wrpos; + skip(size4); + wrpos[-1] = 0; +} + + +inline void scpacket::addi(int i) +{ + if (wrpos >= endpos) BUFFEROVERFLOW; + *wrpos++ = htonl(i); +} + +inline void scpacket::addii(int64 ii) +{ + int i; + i = (int)(ii >> 32); + addi(i); + i = (int)ii; + addi(i); +} + +inline void scpacket::addf(float f) +{ + if (wrpos >= endpos) BUFFEROVERFLOW; + elem32 slot; + slot.f = f; + *wrpos++ = htonl(slot.i); +} + +inline void scpacket::addd(double f) +{ + if (wrpos >= endpos) BUFFEROVERFLOW; + elem64 slot; + slot.f = f; + *wrpos++ = htonl(slot.i >> 32); + *wrpos++ = htonl(slot.i & 0x00000000FFFFFFFF); +} + +inline void scpacket::adds(char *src) +{ + size_t len = strlen(src); + size_t len4 = (len + 4) >> 2; + if (wrpos + len4 > endpos) BUFFEROVERFLOW; + wrpos[len4 - 1] = 0; + memcpy(wrpos, src, (size_t)len); + wrpos += len4; +} + +inline void scpacket::adds(char *src, size_t len) +{ + size_t len4 = (len + 4) >> 2; + if (wrpos + len4 > endpos) BUFFEROVERFLOW; + wrpos[len4 - 1] = 0; + memcpy(wrpos, src, (size_t)len); + wrpos += len4; +} + +// support binary objects +inline void scpacket::addb(uint8 *src, size_t len) +{ + size_t len4 = (len + 3) >> 2; + if (wrpos + (len4 + 1) > endpos) BUFFEROVERFLOW; + wrpos[len4 - 1] = 0; + int32 swaplen = len; + *wrpos++ = htonl(swaplen); + memcpy(wrpos, src, (size_t)len); + wrpos += len4; +} + +inline void scpacket::OpenBundle(int64 time) +{ + inbundle++; + adds("#bundle"); + addii(time); +} + +inline void scpacket::CloseBundle() +{ + if (inbundle) inbundle--; +} + +inline void scpacket::BeginMsg() +{ + if (inbundle) { + msgsizepos = wrpos; + addi(0); + } +} + +inline void scpacket::EndMsg() +{ + if (inbundle) { + *msgsizepos = htonl(((wrpos - msgsizepos) - 1) * sizeof(int32)); + } +} + +#endif + diff --git a/sc4pd/headers/lang/AdvancingAllocPool.h b/sc4pd/headers/lang/AdvancingAllocPool.h new file mode 100644 index 0000000..b89d69b --- /dev/null +++ b/sc4pd/headers/lang/AdvancingAllocPool.h @@ -0,0 +1,82 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +AdvancingAllocPool implements a simple advancing pointer allocation scheme. +There is no Free(). All objects in the pool are freed at once with FreeAll(). +Thus it is very fast. + +*/ + +#ifndef _AdvancingAllocPool_ +#define _AdvancingAllocPool_ + +#include <stdexcept> +#include <stdlib.h> + +class AllocPool; + +struct AdvancingAllocPoolChunk; + +typedef int int32; + +inline void FailNil(void *ptr) { + if (!ptr) throw std::runtime_error("alloc failed"); +} + +struct AdvancingAllocPoolChunkHdr { + AdvancingAllocPoolChunk *mNext; + size_t mSize; + int32 mPad1, mPad2; +}; + +struct AdvancingAllocPoolChunk { + AdvancingAllocPoolChunk *mNext; + size_t mSize; + int32 mPad1, mPad2; + char mSpace[16]; +}; + +class AdvancingAllocPool +{ +public: + AdvancingAllocPool(); + ~AdvancingAllocPool() { FreeAll(); } + + void Init(AllocPool *inAllocPool, size_t initSize, size_t growSize, size_t tooBigSize); + + void *Alloc(size_t inBytes); + void FreeAll(); + + bool SanityCheck(); + +private: + void AddChunk(size_t inSize); + + AllocPool* mAllocPool; + size_t mInitSize; + size_t mGrowSize; + size_t mCurSize; + size_t mTooBig; + AdvancingAllocPoolChunk *mChunks; + AdvancingAllocPoolChunk *mFatties; +}; + +#endif diff --git a/sc4pd/headers/lang/AllocPools.h b/sc4pd/headers/lang/AllocPools.h new file mode 100644 index 0000000..111f7c3 --- /dev/null +++ b/sc4pd/headers/lang/AllocPools.h @@ -0,0 +1,34 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +Pools for memory allocation. + +*/ + + +#ifndef _AllocPools_ +#define _AllocPools_ + +class AllocPool; +extern AllocPool *pyr_pool_compile; +extern AllocPool *pyr_pool_runtime; + +#endif diff --git a/sc4pd/headers/lang/ByteCodeArray.h b/sc4pd/headers/lang/ByteCodeArray.h new file mode 100644 index 0000000..5ec1520 --- /dev/null +++ b/sc4pd/headers/lang/ByteCodeArray.h @@ -0,0 +1,50 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +typedef unsigned char Byte; + +#define BYTE_CODE_CHUNK_SIZE 64 + +typedef struct { + Byte *bytes; + Byte *ptr; + long size; +} ByteCodeArray, *ByteCodes; + +extern ByteCodes gCompilingByteCodes; +extern long totalByteCodes; + +void initByteCodes(); +void compileByte(long byte); +void compileAndFreeByteCodes(ByteCodes byteCodes); +void copyByteCodes(Byte *dest, ByteCodes byteCodes); +ByteCodes getByteCodes(); +ByteCodes saveByteCodeArray(); +void restoreByteCodeArray(ByteCodes byteCodes); +int byteCodeLength(ByteCodes byteCodes); +void compileByteCodes(ByteCodes byteCodes); +ByteCodes allocByteCodes(); +void reallocByteCodes(ByteCodes byteCodes); +void freeByteCodes(ByteCodes byteCodes); +int compileOpcode(long opcode, long operand1); +void compileJump(long opcode, long jumplen); +int compileNumber(unsigned long value); +int compileNumber24(unsigned long value); + diff --git a/sc4pd/headers/lang/FIFOT.h b/sc4pd/headers/lang/FIFOT.h new file mode 100644 index 0000000..52b6203 --- /dev/null +++ b/sc4pd/headers/lang/FIFOT.h @@ -0,0 +1,75 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +A Fifo for sending/receiving some type of object. + +*/ + +#ifndef _FIFOT_ +#define _FIFOT_ + +template <class T, int N> class FIFOT +{ +public: + FIFOT() + : mMask(N-1), mReadHead(0), mWriteHead(0) + { + } + void MakeEmpty() { mReadHead = mWriteHead; } + bool IsEmpty() { return mReadHead == mWriteHead; } + int CanGet() { + int diff = mWriteHead - mReadHead; + return diff >= 0 ? diff : N - diff; + } + int CanPut() { return N-1-CanGet(); } + + int NextPos(int inPos) { return (inPos + 1) & mMask; } + + bool Put(const T& inItem) + { + long next = NextPos(mWriteHead); + if (next == mReadHead) return false; // fifo is full + mItems[next] = inItem; + mWriteHead = next; + return true; + } + + bool Get(T& outItem) // get next and advance + { + if (IsEmpty()) return false; + long next = NextPos(mReadHead); + outItem = mItems[next]; + mReadHead = next; + return true; + } + void DebugDump() + { + post("FIFO N %d mMask %d mReadHead %d mWriteHead%d\n", + N, mMask, mReadHead, mWriteHead); + } + +private: + long mMask; + volatile long mReadHead, mWriteHead;// mReclaimHead; + T mItems[N]; +}; + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/lang/GC.h b/sc4pd/headers/lang/GC.h new file mode 100644 index 0000000..4dc162a --- /dev/null +++ b/sc4pd/headers/lang/GC.h @@ -0,0 +1,263 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +The garbage collector for SuperCollider. +Based on Wilson and Johnstone's real time collector and the Baker treadmill. + +*/ + +#ifndef _GC_ +#define _GC_ + +#include "PyrObject.h" +#include "VMGlobals.h" +#include "AdvancingAllocPool.h" + +void DumpSimpleBackTrace(VMGlobals *g); + +const int kMaxPoolSet = 7; +const int kNumGCSizeClasses = 28; +const int kFinalizerSet = kNumGCSizeClasses; +const int kNumGCSets = kNumGCSizeClasses + 1; + +class GCSet +{ +public: + GCSet() {} + void Init(int inSizeClass); + + bool HasFree() { return mFree != &mBlack; } + +private: + friend class PyrGC; + + void MoveWhiteToFree(); + + PyrObjectHdr mBlack; + PyrObjectHdr mWhite; + PyrObjectHdr* mFree; +}; + +struct SlotRef { + SlotRef(PyrObject* inObj, int32 inIndex) : obj(inObj), slotIndex(inIndex) {} + + PyrObject *obj; + int32 slotIndex; +}; + +class PyrGC +{ +public: + PyrGC(VMGlobals *g, AllocPool *inPool, PyrClass *mainProcessClass, long poolSize); + + PyrObject* New(size_t inNumBytes, long inFlags, long inFormat, bool inCollect); + + static PyrObject* NewPermanent(size_t inNumBytes, + long inFlags, long inFormat); + + PyrObject* NewFinalizer(ObjFuncPtr finalizeFunc, PyrObject *inObject, bool inCollect); + + int32 ProcessID() { return mProcessID; } + +#if 0 +// Codewarrior is not inlining these.. why? + bool IsBlack(PyrObjectHdr* inObj) { return inObj->gc_color == mBlackColor; } + bool IsWhite(PyrObjectHdr* inObj) { return inObj->gc_color == mWhiteColor; } + bool IsGrey(PyrObjectHdr* inObj) { return inObj->gc_color == mGreyColor; } + bool IsMarker(PyrObjectHdr* inObj) { return inObj->gc_color == obj_gcmarker; } +#else + +#define IsBlack(inObj) ((inObj)->gc_color == mBlackColor) +#define IsWhite(inObj) ((inObj)->gc_color == mWhiteColor) +#define IsGrey(inObj) ((inObj)->gc_color == mGreyColor) +#define IsFree(inObj) (!(IsMarker(inObj) || inObj->IsPermanent() || \ + IsBlack(inObj) || IsWhite(inObj) || IsGrey(inObj))) +#define IsMarker(inObj) ((inObj)->gc_color == obj_gcmarker) +#endif + + bool ObjIsBlack(PyrObjectHdr* inObj) { return IsBlack(inObj); } + bool ObjIsGrey(PyrObjectHdr* inObj) { return IsGrey(inObj); } + bool ObjIsFree(PyrObjectHdr* inObj) { return IsFree(inObj); } + + + // general purpose write barriers: + void GCWrite(PyrObjectHdr* inParent, PyrSlot* inSlot) + { + if (IsBlack(inParent) && IsObj(inSlot) && IsWhite(inSlot->uo)) { + ToGrey(inSlot->uo); + } + } + void GCWrite(PyrObjectHdr* inParent, PyrObjectHdr* inChild) + { + if (IsBlack(inParent) && IsWhite(inChild)) { + ToGrey(inChild); + } + } + // when you know the parent is black: + void GCWriteBlack(PyrSlot* inSlot) + { + if (IsObj(inSlot)) { + if (IsWhite(inSlot->uo)) { + ToGrey(inSlot->uo); + } + } + } + void GCWriteBlack(PyrObjectHdr* inChild) + { + if (IsWhite(inChild)) { + ToGrey(inChild); + } + } + // when you know the child is white + void GCWriteNew(PyrObjectHdr* inParent, PyrObjectHdr* inChild) + { + if (IsBlack(inParent)) { + ToGrey(inChild); + } + } + +// users should not call anything below. + + void Collect(); + void Collect(int32 inNumToScan); + void FullCollection(); + void ScanFinalizers(); + GCSet* GetGCSet(PyrObjectHdr* inObj); + void CompletePartialScan(PyrObject *obj); + + void ToGrey(PyrObjectHdr* inObj); + void ToGrey2(PyrObjectHdr* inObj); + void ToBlack(PyrObjectHdr* inObj); + void ToWhite(PyrObjectHdr *obj); + + int32 StackDepth() { return mVMGlobals->sp - mStack->slots + 1; } + PyrObject* Stack() { return mStack; } + void SetStack(PyrObject* inStack) { mStack = inStack; } + + bool SanityCheck(); + bool SanityCheck2(); + bool LinkSanity(); + bool ListSanity(); + bool BlackToWhiteCheck(PyrObject *objA); + bool SanityMarkObj(PyrObject *objA, PyrObject *fromObj, int level); + bool SanityClearObj(PyrObject *objA, int level); + void DumpInfo(); + void DumpEverything(); + + void BecomePermanent(PyrObject *inObject); + void BecomeImmutable(PyrObject *inObject); + +private: + void Free(PyrObject* inObj); + void ScanSlots(PyrSlot *inSlots, long inNumToScan); + void SweepBigObjects(); + void DoPartialScan(int32 inObjSize); + bool ScanOneObj(); + void Flip(); + void ScanStack(); + void DLRemove(PyrObjectHdr *obj); + void DLInsertAfter(PyrObjectHdr *after, PyrObjectHdr *obj); + void DLInsertBefore(PyrObjectHdr *before, PyrObjectHdr *obj); + + void ClearMarks(); + void Finalize(PyrObject *obj); + + VMGlobals *mVMGlobals; + AllocPool *mPool; + AdvancingAllocPool mNewPool; + GCSet mSets[kNumGCSets]; + PyrProcess *mProcess; // the root is the pyrprocess which contains this struct + PyrObject *mStack; + PyrObject *mPartialScanObj; + PyrObjectHdr mGrey; + + GCSet *mPartialScanSet; + int32 mPartialScanSlot; + int32 mNumToScan; + int32 mNumGrey; + int32 mCurSet; + + int32 mFlips, mCollects, mAllocTotal, mScans, mNumAllocs; + + unsigned char mBlackColor, mGreyColor, mWhiteColor, mFreeColor; + int8 mProcessID; + bool mCanSweep; + bool mRunning; +}; + +inline void PyrGC::DLRemove(PyrObjectHdr *obj) +{ + obj->next->prev = obj->prev; + obj->prev->next = obj->next; +} + +inline void PyrGC::DLInsertAfter(PyrObjectHdr *after, PyrObjectHdr *obj) +{ + obj->next = after->next; + obj->prev = after; + after->next->prev = obj; + after->next = obj; +} + +inline void PyrGC::DLInsertBefore(PyrObjectHdr *before, PyrObjectHdr *obj) +{ + obj->prev = before->prev; + obj->next = before; + before->prev->next = obj; + before->prev = obj; +} + +inline GCSet* PyrGC::GetGCSet(PyrObjectHdr* inObj) +{ + return mSets + (inObj->classptr == class_finalizer ? kFinalizerSet : inObj->obj_sizeclass); +} + +inline void PyrGC::ToBlack(PyrObjectHdr *obj) +{ + if (IsGrey(obj)) { + mNumGrey--; + //post("ToBlack %d\n", mNumGrey); + } + + DLRemove(obj); + + GCSet *gcs = GetGCSet(obj); + DLInsertAfter(&gcs->mBlack, obj); + + obj->gc_color = mBlackColor; +} + +inline void PyrGC::ToWhite(PyrObjectHdr *obj) +{ + if (IsGrey(obj)) { + mNumGrey--; + //post("ToWhite %d\n", mNumGrey); + } + + DLRemove(obj); + + GCSet *gcs = GetGCSet(obj); + DLInsertAfter(&gcs->mWhite, obj); + + obj->gc_color = mWhiteColor; +} + +#endif diff --git a/sc4pd/headers/lang/HashTable.h b/sc4pd/headers/lang/HashTable.h new file mode 100644 index 0000000..835f593 --- /dev/null +++ b/sc4pd/headers/lang/HashTable.h @@ -0,0 +1,274 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _HashTable_ +#define _HashTable_ + +#include "SC_Types.h" +#include "SC_BoundsMacros.h" +#include "Hash.h" +#include <stddef.h> + +template<class T, class Allocator, class KeyType> +class HashTable +{ + Allocator *mPool; + int32 mNumItems, mMaxItems, mTableSize, mHashMask; + T** mItems; + bool mCanResize; + +public: + + HashTable(Allocator *inPool, int32 inMaxItems, bool inCanResize = true) + : mPool(inPool) + { + mNumItems = 0; + mMaxItems = inMaxItems; + mTableSize = mMaxItems << 1; + mItems = AllocTable(mTableSize); + mHashMask = mTableSize - 1; + mCanResize = inCanResize; + } + + ~HashTable() { + mPool->Free(mItems); + } + + int32 TableSize() const { return mTableSize; } + int32 MaxItems() const { return mMaxItems; } + int32 NumItems() const { return mNumItems; } + + T** AllocTable(int inTableSize) + { + size_t size = inTableSize * sizeof(T*); + T** items = static_cast<T**>(mPool->Alloc(size)); + for (int i=0; i<inTableSize; ++i) { + items[i] = 0; + } + return items; + } + + void Resize() + { + int32 newSize = sc_max(mTableSize << 1, 32); + T** oldItems = mItems; + mItems = AllocTable(newSize); + for (int i=0; i<mTableSize; ++i) { + T* item = oldItems[i]; + if (item) Add(item); + } + mTableSize = newSize; + mMaxItems = mTableSize >> 1; + mHashMask = mTableSize - 1; + mPool->Free(oldItems); + //printf("mMaxItems %d mTableSize %d newSize %d\n", mMaxItems, mTableSize, newSize); + } + + bool Add(T* inItem) + { + //printf("mNumItems %d\n", mNumItems); + //printf("mMaxItems %d\n", mMaxItems); + //printf("mCanResize %d\n", mCanResize); + if (mNumItems >= mMaxItems) { + if (!mCanResize) return false; + Resize(); + } + + //printf("GetHash(inItem) %d\n", GetHash(inItem)); + //printf("GetKey(inItem) %s\n", GetKey(inItem)); + int32 index = IndexFor(GetHash(inItem), GetKey(inItem)); + //printf("index %d\n", index); + + T *item = mItems[index]; + if (item) return item == inItem; + + mItems[index] = inItem; + mNumItems++; + return true; + } + + bool Remove(T* inItem) + { + int32 index = IndexFor(GetHash(inItem), GetKey(inItem)); + if (mItems[index] != inItem) return false; + mItems[index] = 0; + + FixCollisionsFrom(index); + mNumItems--; + return true; + } + + int32 IndexFor(int32 inHashID, KeyType inKey) const + { + int index = inHashID & mHashMask; + for(;;) { + T *item = mItems[index]; + if (!item) return index; + if (GetHash(item) == inHashID + && strcmp(inKey, GetKey(item)) == 0) return index; + index = (index + 1) & mHashMask; + } + } + + T* Get(KeyType inKey) const + { + return Get(Hash(inKey), inKey); + } + + T* Get(int32 inHashID, KeyType inKey) const + { + int32 index = IndexFor(inHashID, inKey); + return mItems[index]; + } + + bool Includes(T* inItem) const + { + return Get(GetHash(inItem), GetKey(inItem)) == inItem; + } + + T* AtIndex(int32 inIndex) const + { + return mItems[inIndex]; + } + +private: + void FixCollisionsFrom(int32 inIndex) + { + int oldIndex = inIndex; + for (;;) { + oldIndex = (oldIndex + 1) & mHashMask; + T *oldItem = mItems[oldIndex]; + if (!oldItem) break; + int newIndex = IndexFor(GetHash(oldItem), GetKey(oldItem)); + if (oldIndex != newIndex) { + mItems[oldIndex] = mItems[newIndex]; + mItems[newIndex] = oldItem; + } + } + } +}; + +template<class T, int kMaxItems, class KeyType> +class StaticHashTable +{ + int32 mNumItems, mTableSize, mHashMask; + T* mItems[kMaxItems*2]; + +public: + + StaticHashTable() + { + mNumItems = 0; + mTableSize = kMaxItems << 1; + ClearTable(); + mHashMask = mTableSize - 1; + } + + ~StaticHashTable() { + } + + int32 TableSize() const { return mTableSize; } + int32 MaxItems() const { return kMaxItems; } + int32 NumItems() const { return mNumItems; } + + void ClearTable() + { + for (int i=0; i<mTableSize; ++i) { + mItems[i] = 0; + } + } + + bool Add(T* inItem) + { + if (mNumItems >= kMaxItems) return false; + + int32 index = IndexFor(GetHash(inItem), GetKey(inItem)); + + T *item = mItems[index]; + if (item) return item == inItem; + + mItems[index] = inItem; + mNumItems++; + return true; + } + + bool Remove(T* inItem) + { + int32 index = IndexFor(GetHash(inItem), GetKey(inItem)); + if (mItems[index] != inItem) return false; + mItems[index] = 0; + + FixCollisionsFrom(index); + mNumItems--; + return true; + } + + int32 IndexFor(int32 inHashID, KeyType inKey) const + { + int index = inHashID & mHashMask; + for(;;) { + T *item = mItems[index]; + if (!item) return index; + if (GetHash(item) == inHashID + && strcmp(inKey, GetKey(item)) == 0) return index; + index = (index + 1) & mHashMask; + } + } + + T* Get(KeyType inKey) const + { + return Get(Hash(inKey), inKey); + } + + T* Get(int32 inHashID, KeyType inKey) const + { + int32 index = IndexFor(inHashID, inKey); + return mItems[index]; + } + + bool Includes(T* inItem) const + { + return Get(GetHash(inItem), GetKey(inItem)) == inItem; + } + + T* AtIndex(int32 inIndex) const + { + return mItems[inIndex]; + } + +private: + void FixCollisionsFrom(int32 inIndex) + { + int oldIndex = inIndex; + for (;;) { + oldIndex = (oldIndex + 1) & mHashMask; + T *oldItem = mItems[oldIndex]; + if (!oldItem) break; + int newIndex = IndexFor(GetHash(oldItem), GetKey(oldItem)); + if (oldIndex != newIndex) { + mItems[oldIndex] = mItems[newIndex]; + mItems[newIndex] = oldItem; + } + } + } +}; + + +#endif diff --git a/sc4pd/headers/lang/InitAlloc.h b/sc4pd/headers/lang/InitAlloc.h new file mode 100644 index 0000000..762b940 --- /dev/null +++ b/sc4pd/headers/lang/InitAlloc.h @@ -0,0 +1,32 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _InitAlloc_ +#define _InitAlloc_ + +#include "SCBase.h" +#include "SC_AllocPool.h" +#include <stdexcept> + +#define MEMFAIL(ptr) if (!(ptr)) { throw std::runtime_error("Out of memory!\n"); } +#define MEMFAILED throw std::runtime_error("Out of memory!\n"); + +#endif + diff --git a/sc4pd/headers/lang/MiscInlineMath.h b/sc4pd/headers/lang/MiscInlineMath.h new file mode 100644 index 0000000..6dd33ab --- /dev/null +++ b/sc4pd/headers/lang/MiscInlineMath.h @@ -0,0 +1,54 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#define NUMPRIMES 6542 +long nthPrime(int n); +long findPrime(int n); +long prevPrime(int n); +long nextPrime(int n); + + +inline double linlin(double x, double a, double b, double c, double d) +{ + if (x <= a) return c; + if (x >= b) return d; + return (x-a)/(b-a) * (d-c) + c; +} + +inline double explin(double x, double a, double b, double c, double d) +{ + if (x <= a) return c; + if (x >= b) return d; + return (log(x/a)) / (log(b/a)) * (d-c) + c; +} + +inline double expexp(double x, double a, double b, double c, double d) +{ + if (x <= a) return c; + if (x >= b) return d; + return pow(d/c, log(x/a)) / (log(b/a)) * c; +} + +inline double linexp(double x, double a, double b, double c, double d) +{ + if (x <= a) return c; + if (x >= b) return d; + return pow(d/c, (x-a)/(b-a)) * c; +} diff --git a/sc4pd/headers/lang/OSCData.h b/sc4pd/headers/lang/OSCData.h new file mode 100644 index 0000000..b2721b0 --- /dev/null +++ b/sc4pd/headers/lang/OSCData.h @@ -0,0 +1 @@ +/*
SuperCollider real time audio synthesis system
Copyright (c) 2002 James McCartney. All rights reserved.
http://www.audiosynth.com
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _OSCData_
#define _OSCData_
#include "PyrObject.h"
#include "FIFOT.h"
#include <netinet/in.h>
#endif
\ No newline at end of file diff --git a/sc4pd/headers/lang/Opcodes.h b/sc4pd/headers/lang/Opcodes.h new file mode 100644 index 0000000..c5e1c7a --- /dev/null +++ b/sc4pd/headers/lang/Opcodes.h @@ -0,0 +1,426 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _OPCODES_H_ +#define _OPCODES_H_ + +/* opcodes */ +enum { + opExtended, // 0 + opPushInstVar, + opPushTempVar, + opPushTempZeroVar, + opPushLiteral, + opPushClassVar, // 5 + opPushSpecialValue, + opStoreInstVar, + opStoreTempVar, + opStoreClassVar, + opSendMsg, // 10 + opSendSuper, + opSendSpecialMsg, + opSendSpecialUnaryArithMsg, + opSendSpecialBinaryArithMsg, + opSpecialOpcode, // 15 + + + opNumOpcodes +}; + +/* special opcodes */ +enum { + opcDrop, // 0 + opcDup, + opcFunctionReturn, + opcReturn, + opcReturnSelf, + opcReturnTrue, // 5 + opcReturnFalse, + opcReturnNil, + opcJumpIfFalse, // IF 3 args + opcJumpIfFalsePushNil, // IF 2 args + opcJumpIfFalsePushFalse, // AND: (10) + opcJumpIfTruePushTrue, // OR: + opcJumpFwd, + opcJumpBak, + opcSpecialBinaryOpWithAdverb, + opcSuperNew, // 15 + + opcNewList, + + opcNumSpecialOpcodes +/* + opcSlotAt, + opcByteAt, // 15 + opcShortAt, + opcInt32At, + opcColorAt, + opcFloatAt, + opcDoubleAt +*/ +}; + +/* special unary math operators */ +enum { + opNeg, + opNot, + opIsNil, + opNotNil, + opBitNot, + opAbs, + opAsFloat, + opAsInt, + opCeil, //5 + opFloor, + opFrac, + opSign, + opSquared, + opCubed, //10 + opSqrt, + opExp, + opRecip, + opMIDICPS, + opCPSMIDI, //15 + + opMIDIRatio, + opRatioMIDI, + opDbAmp, + opAmpDb, + opOctCPS, //20 + opCPSOct, + opLog, + opLog2, + opLog10, + opSin, //25 + opCos, + opTan, + opArcSin, + opArcCos, + opArcTan, + opSinH, + opCosH, //30 + opTanH, + opRand, + opRand2, + opLinRand, + opBiLinRand, + +// opExpRand, +// opBiExpRand, + opSum3Rand, +// opGammaRand, +// opGaussRand, +// opPoiRand, + + opDistort, + opSoftClip, + opCoin, + + opDigitValue, + opSilence, + opThru, + opRectWindow, + opHanWindow, + opWelchWindow, + opTriWindow, + + opRamp, + opSCurve, + + opNumUnarySelectors +}; + +#define IS_UNARY_BOOL_OP(op) ((op)>=opCoin && (op)<=opOdd) +#define IS_BINARY_BOOL_OP(op) ((op)>=opEQ && (op)<=opGE) + +/* special binary math operators */ +enum { + opAdd, + opSub, + opMul, + opIDiv, + opFDiv, + opMod, + opEQ, + opNE, + opLT, + opGT, + opLE, + opGE, + //opIdentical, + //opNotIdentical, + + opMin, + opMax, + opBitAnd, + opBitOr, + opBitXor, + opLCM, + opGCD, + opRound, + opRoundUp, + opTrunc, + opAtan2, + opHypot, + opHypotx, + opPow, + opShiftLeft, + opShiftRight, + opUnsignedShift, + opFill, + opRing1, // a * (b + 1) == a * b + a + opRing2, // a * b + a + b + opRing3, // a*a*b + opRing4, // a*a*b - a*b*b + opDifSqr, // a*a - b*b + opSumSqr, // a*a + b*b + opSqrSum, // (a + b)^2 + opSqrDif, // (a - b)^2 + opAbsDif, // |a - b| + opThresh, + opAMClip, + opScaleNeg, + opClip2, + opExcess, + opFold2, + opWrap2, + opFirstArg, + opRandRange, + opExpRandRange, + + opNumBinarySelectors +}; + +/* other special math operators */ +enum { + /* 3 operands */ + opDivz, + opClip, + opWrap, + opFold, + opRampMult, + opMix, + /* 4 operands */ + opPoly3, + /* 5 operands */ + opMapRange +}; + +enum { + opmNew, // 0 + opmInit, + opmAt, + opmPut, + opmNext, + opmReset, // 5 + opmValue, + opmCopyToEnd, // used by multi assign + opmAdd, // used by dynamic list + //opmIsNil, + //opmNotNil, // 10 + opmSize, + opmClass, + opmIf, + opmWhile, + opmFor, // 15 + opmAnd, + opmOr, + opmIdentical, + opmNotIdentical, + opmPrint, // 20 + opmRemove, + opmIndexOf, + opmWrapAt, + opmClipAt, + opmFoldAt, // 25 + opmWrapPut, + opmClipPut, + opmFoldPut, + opmDo, + opmCollect, // 30 + opmSelect, + opmReject, + opmAny, + opmEvery, + opmFind, + opmChoose, + opmValueList, + opmAddFirst, + opmPrimitiveFailed, + opmSubclassResponsibility, + opmShouldNotImplement, + opmNotYetImplemented, + opmDoesNotUnderstand, + + opmAtSign, + opmWrapAtSign, + opmClipAtSign, + opmFoldAtSign, + + opmNewClear, + opmNewCopyArgs, + opmMultiNew, + opmMultiNewList, + opmAR, + opmKR, + opmIR, + + opmCopy, + opmPerformList, + opmIsKindOf, + opmPostln, + opmAsString, + + opmEnvirGet, + opmEnvirPut, + + opmHalt, + opmForBy, + opmReverseDo, + opmLoop, + + opmNonBooleanError, + + opmPlusPlus, + opmLTLT, + opmQuestionMark, + opmDoubleQuestionMark, + + opmYield, + opmName, + opmMulAdd, + + opmNumSpecialSelectors +}; + +enum { + opsvSelf, // 0 + opsvMinusOne, + opsvNegOne, + opsvZero, + opsvOne, + opsvTwo, // 5 + opsvFHalf, + opsvFNegOne, + opsvFZero, + opsvFOne, + opsvFTwo, // 10 + opsvPlusOne, + opsvTrue, + opsvFalse, + opsvNil, + opsvInf, // 15 + + opsvNumSpecialValues +}; + +enum { + opgProcess, + opgMethod, + opgFunctionDef, + opgFunction, + opgThread, + //opgSampleRate, + //opgAudioClock, + //opgLogicalClock, + + opgNumPseudoVars +}; + +/* selector types */ +enum { + selNormal, + selSpecial, + selUnary, + selBinary, + selIf, + selWhile, + selAnd, + selOr, + selLoop, + selSuperNew, + + selNumSelectorTypes +}; + + + +/* + special classes: + Object, List, Number, Int, Float, Signal, Complex, Point +*/ +enum { + op_class_object, + op_class_symbol, + op_class_nil, + op_class_boolean, + op_class_true, + op_class_false, + op_class_magnitude, + op_class_char, + op_class_number, + op_class_complex, + op_class_simple_number, + op_class_int, + op_class_float, + op_class_method, + op_class_fundef, + op_class_stream, + op_class_func, + op_class_frame, + op_class_process, + op_class_main, + op_class_class, + op_class_string, + op_class_collection, + op_class_sequenceable_collection, + op_class_arrayed_collection, + op_class_array, + op_class_int8array, + op_class_int16array, + op_class_int32array, + op_class_floatarray, + op_class_signal, + op_class_doublearray, + op_class_symbolarray, + op_class_list, + op_class_linkedlist, + op_class_bag, + op_class_set, + op_class_identityset, + op_class_dictionary, + op_class_identitydictionary, + op_class_sortedlist, + op_class_synth, + op_class_ref, + op_class_environment, + op_class_wavetable, + op_class_env, + + op_class_routine, + op_class_color, + op_class_rect, + + op_NumSpecialClasses +}; + + + +#endif diff --git a/sc4pd/headers/lang/PowerOfTwoAllocPool.h b/sc4pd/headers/lang/PowerOfTwoAllocPool.h new file mode 100644 index 0000000..8dde18f --- /dev/null +++ b/sc4pd/headers/lang/PowerOfTwoAllocPool.h @@ -0,0 +1,154 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +// Implements a power of two size class allocator. +// There is no consolidation of free space. Once a chunk is allocated it +// remains at that size from then on whether free or allocated. +// It uses AdvancingAllocPool as its parent allocator. +// It is very fast. This is used to allocate Unit output buffers. + +#ifndef _PowerOfTwoAllocPool_ +#define _PowerOfTwoAllocPool_ + +#include <stdexcept> +#include <stdlib.h> +#include "clz.h" +#include "AdvancingAllocPool.h" +#include "SC_AllocPool.h" +void post(const char *fmt, ...); +void postbuf(const char *fmt, ...); + +template<class Hdr, class Obj, class Elem, int LargeObjSizeClass, int Align> +class PowerOfTwoAllocPool +{ +public: + PowerOfTwoAllocPool(::AllocPool *inPool, + size_t initSize = 64*1024, + size_t growSize = 64*1024 + ) + { + mLargeObjPool = inPool; + mNumLargeObjects = 0; + mNumAlloc = 0; + mNumFree = 0; + size_t tooBigSize = (sizeof(Hdr) + (sizeof(Elem) << (LargeObjSizeClass-1))) + 1; + mSmallObjPool.Init(inPool, initSize, growSize, tooBigSize); + Init(); + assert(SanityCheck()); + } + ~PowerOfTwoAllocPool() + { + assert(SanityCheck()); + assert(mNumLargeObjects == 0); // you have to free the big ones yourself + mSmallObjPool.FreeAll(); + } + + Obj* Alloc(int32 inNumElems) + { + //mNumAlloc++; + assert(SanityCheck()); + int sizeclass = LOG2CEIL(inNumElems); + if (sizeclass >= LargeObjSizeClass) { + mNumLargeObjects++; + size_t size = sizeof(Hdr) + (sizeof(Elem) * inNumElems); + return (Obj*)mLargeObjPool->Alloc(size); + } + + // get from free list + Obj* obj = mFreeLists[sizeclass]; + if (obj != NULL) { + // set free list to next element. + mFreeLists[sizeclass] = *(Obj**)obj; + } else { + // have to allocate it + size_t size = mSizes[sizeclass]; + obj = (Obj*)mSmallObjPool.Alloc(size); + if (!obj) throw runtime_error("PowerOfTwoAllocPool out of memory"); + } + //obj->mMagic = 'magk'; + assert(SanityCheck()); + return obj; + } + void Free(Obj* inObjPtr) + { + //mNumFree++; + assert(SanityCheck()); + if (inObjPtr == 0) return; /* free(0) has no effect */ + /*if (inObjPtr->mMagic != 'magk') { + postbuf("bad object\n"); + throw runtime_error("bad object"); + }*/ + int sizeclass = inObjPtr->SizeClass(); + if (sizeclass >= LargeObjSizeClass) { + mLargeObjPool->Free(inObjPtr); + mNumLargeObjects--; + } else { + Obj* nextfree = mFreeLists[sizeclass]; + mFreeLists[sizeclass] = inObjPtr; + *(Obj**)inObjPtr = nextfree; + } + assert(SanityCheck()); + } + void FreeAll() + { + assert(mNumLargeObjects == 0); // you have to free the big ones yourself + mSmallObjPool.FreeAll(); + Init(); + } + + bool SanityCheck() + { + //postbuf("PowerOfTwoAllocPool::SanityCheck %d %d\n", mNumAlloc, mNumFree); + mLargeObjPool->DoCheckPool(); + mSmallObjPool.SanityCheck(); + for (int i=0; i<LargeObjSizeClass; ++i) { + Obj* obj = mFreeLists[i]; + for (int j=0; obj; ++j) { + if (j>=1000) { + post("linked loop??\n"); + throw runtime_error("linked loop??\n"); + return false; + } + obj = *(Obj**)obj; + } + } + return true; + } +private: + void Init() + { + for (int i=0; i<LargeObjSizeClass; ++i) { + mFreeLists[i] = NULL; + size_t size = sizeof(Hdr) + (sizeof(Elem) << i); + mSizes[i] = (size + (Align-1)) & ~(Align-1); // alignment + } + } + + Obj* mFreeLists[LargeObjSizeClass]; + size_t mSizes[LargeObjSizeClass]; + AllocPool* mLargeObjPool; + AdvancingAllocPool mSmallObjPool; + int mNumLargeObjects; + int mNumAlloc, mNumFree; +}; + + +#endif + diff --git a/sc4pd/headers/lang/PredefinedSymbols.h b/sc4pd/headers/lang/PredefinedSymbols.h new file mode 100644 index 0000000..c6e09b9 --- /dev/null +++ b/sc4pd/headers/lang/PredefinedSymbols.h @@ -0,0 +1,29 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +extern PyrSymbol *s_func, *s_absfunc; +extern PyrSymbol *s_docmdline; +extern PyrSymbol *s_nocomprendo; +extern PyrSymbol *s_curProcess, *s_curMethod, *s_curBlock, *s_curClosure, *s_curThread; +extern PyrSymbol *s_startup; +extern PyrSymbol *s_hardwaresetup, *s_shutdown; +extern PyrSymbol *s_envirGet, *s_envirPut; + diff --git a/sc4pd/headers/lang/PriorityQueue.h b/sc4pd/headers/lang/PriorityQueue.h new file mode 100644 index 0000000..0bd19f1 --- /dev/null +++ b/sc4pd/headers/lang/PriorityQueue.h @@ -0,0 +1,90 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _PriorityQueue_ +#define _PriorityQueue_ + +#include <limits> + +template <class Event, class TimeType, int N> +class PriorityQueueT +{ +public: + PriorityQueueT() { + Empty(); + } + + bool Add(Event& inEvent) + { + if (mSize >= N) return false; + long mom = mSize++; + long me = mom; + for (; mom>0;) { /* percolate up heap */ + mom = mom - 1 >> 1; + if (inEvent.mTime < mEvents[mom].mTime) { + mEvents[me] = mEvents[mom]; + me = mom; + } else break; + } + mEvents[me] = inEvent; + return true; + } + void Perform(TimeType inNow) + { + while (NextTime() <= inNow) { + Event event = Remove(); + event.Perform(); + } + } + TimeType NextTime() { return mEvents[0].mTime; } + bool Ready(TimeType inTime) { return NextTime() <= inTime; } + void Flush() { Perform(std::numeric_limits<TimeType>::max()); } + void Empty() { mSize = 0; SetEmptyTime(); } + void SetEmptyTime() { mEvents[0].mTime = std::numeric_limits<TimeType>::max(); } + + Event Remove() + { + Event event = mEvents[0]; + if (--mSize == 0) SetEmptyTime(); + else { + Event temp = mEvents[mSize]; + long mom = 0; + long me = 1; + for (;me < mSize;) { /* demote heap */ + if (me+1 < mSize && mEvents[me].mTime > mEvents[me+1].mTime) { + me ++; + } + if (temp.mTime > mEvents[me].mTime) { + mEvents[mom] = mEvents[me]; + mom = me; + me = (me << 1) + 1; + } else break; + } + mEvents[mom] = temp; + } + return event; + } + +private: + long mSize; + Event mEvents[N]; +}; + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/lang/PyrArchiverT.h b/sc4pd/headers/lang/PyrArchiverT.h new file mode 100644 index 0000000..3beaa0c --- /dev/null +++ b/sc4pd/headers/lang/PyrArchiverT.h @@ -0,0 +1,619 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +An object archiving system for SuperCollider. + +*/ + + +#ifndef _PyrArchiver_ +#define _PyrArchiver_ + +#include "PyrObject.h" +#include "SC_AllocPool.h" + +#include "PyrKernel.h" +#include "PyrPrimitive.h" +#include "VMGlobals.h" +#include "GC.h" +#include "ReadWriteMacros.h" + +const int32 kArchHdrSize = 12; +const int32 kObjectArrayInitialCapacity = 32; + +template <class S> +class PyrArchiver +{ +public: + PyrArchiver(VMGlobals *inG, bool inSameAddressSpace = false) + : g(inG), mObjectArray(mInitialObjectArray), mNumObjects(0), + mObjectArrayCapacity( kObjectArrayInitialCapacity ), + mSameAddressSpace(inSameAddressSpace), mReadArchiveVersion(0) + { + } + + ~PyrArchiver() + { + if (mObjectArray != mInitialObjectArray) { + g->allocPool->Free(mObjectArray); + } + } + + void setStream(S s) { mStream.SetStream(s); } + + int32 calcArchiveSize() + { + PyrSlot *slot; + int32 size = kArchHdrSize; + if (mNumObjects == 0) { + size += sizeOfElem(&mTopSlot) + 1; + } else { + // object table size + for (int i=0; i<mNumObjects; ++i) { + PyrObject* obj = mObjectArray[i]; + size += obj->classptr->name.us->length + 1; // class name symbol + size += sizeof(int32); // size + if (obj->obj_format <= obj_slot) { + size += obj->size; // tags + slot = obj->slots; + for (int j=0; j<obj->size; ++j, ++slot) { + size += sizeOfElem(slot); + } + } else if (obj->obj_format == obj_symbol) { + PyrSymbol **symbol = ((PyrSymbolArray*)obj)->symbols; + for (int j=0; j<obj->size; ++j, ++symbol) { + size += (**symbol).length + 1; + } + } else { + size += obj->size * gFormatElemSize[obj->obj_format]; + } + } + } + return size; + } + + long prepareToWriteArchive(PyrSlot *objectSlot) + { + long err = errNone; + + try { + mTopSlot.ucopy = objectSlot->ucopy; + if (IsObj(objectSlot)) constructObjectArray(objectSlot->uo); + } catch (std::exception &ex) { + error(ex.what()); + err = errFailed; + } + return err; + } + + long writeArchive() + { + long err = errNone; + + try { + writeArchiveHeader(); + + if (mNumObjects == 0) { + writeSlot(&mTopSlot); + } else { + for (int i=0; i<mNumObjects; ++i) { + writeObjectHeader(mObjectArray[i]); + } + for (int i=0; i<mNumObjects; ++i) { + writeSlots(mObjectArray[i]); + } + } + } catch (std::exception &ex) { + error(ex.what()); + err = errFailed; + } + return err; + } + + long readArchive(PyrSlot *objectSlot) + { + //postfl("->readArchive\n"); + long err = errNone; + + + SetNil(objectSlot); + + try { + readArchiveHeader(); + //postfl("readObjectHeaders %d\n", mNumObjects); + if (mNumObjects == 0) { + readSlot(objectSlot); + } else { + for (int i=0; i<mNumObjects; ++i) { + mObjectArray[i] = readObjectHeader(); + } + //postfl("readSlots\n"); + for (int i=0; i<mNumObjects; ++i) { + readSlots(mObjectArray[i]); + } + //postfl("done reading\n"); + //postfl("SetObject\n"); + SetObject(objectSlot, mObjectArray[0]); + } + } catch (std::exception &ex) { + error(ex.what()); + err = errFailed; + } catch (...) { + err = errFailed; + } + //postfl("<-readArchive\n"); + return err; + } + +private: + + void writeArchiveHeader() + { + mStream.writeInt32_be('!SCa'); + mStream.writeInt32_be(2); // file version + mStream.writeInt32_be(mNumObjects); + } + + void readArchiveHeader() + { + int32 magicNumber = mStream.readInt32_be(); + if (magicNumber != '!SCa') { + throw std::runtime_error("not an SC archive.\n"); + } + mReadArchiveVersion = mStream.readInt32_be(); // file version + mNumObjects = mStream.readInt32_be(); + //post("readArchiveHeader %d %d\n", mReadArchiveVersion, mNumObjects); + + if (mNumObjects > kObjectArrayInitialCapacity) { + mObjectArray = (PyrObject**)g->allocPool->Alloc(mNumObjects * sizeof(PyrObject*)); + mObjectArrayCapacity = mNumObjects; + } + + } + + void recurse(PyrObject *obj, int n) + { + PyrSlot *slot = obj->slots; + for (int i=0; i<n; ++i, ++slot) { + if (IsObj(slot)) constructObjectArray(slot->uo); + } + } + + void growObjectArray() + { + int32 newObjectArrayCapacity = mObjectArrayCapacity << 1; + + int32 newSize = newObjectArrayCapacity * sizeof(PyrObject*); + PyrObject** newArray = (PyrObject**)g->allocPool->Alloc(newSize); + memcpy(newArray, mObjectArray, mNumObjects * sizeof(PyrObject*)); + if (mObjectArray != mInitialObjectArray) { + g->allocPool->Free(mObjectArray); + } + mObjectArrayCapacity = newObjectArrayCapacity; + mObjectArray = newArray; + } + + void putObject(PyrObject *obj) + { + obj->SetMark(); + obj->scratch1 = mNumObjects; + + // expand array if needed + if (mNumObjects >= mObjectArrayCapacity) growObjectArray(); + + // add to array + mObjectArray[mNumObjects++] = obj; + } + + void constructObjectArray(PyrObject *obj) + { + if (!obj->IsMarked()) { + if (isKindOf(obj, class_class)) { + } else if (isKindOf(obj, class_process)) { + } else if (isKindOf(obj, s_interpreter->u.classobj)) { + } else if (isKindOf(obj, class_method)) { + throw std::runtime_error("cannot archive Methods.\n"); + } else if (isKindOf(obj, class_thread)) { + throw std::runtime_error("cannot archive Threads.\n"); + } else if (isKindOf(obj, class_frame)) { + throw std::runtime_error("cannot archive Frames.\n"); + } else if (isKindOf(obj, class_func)) { + if (NotNil(&((PyrClosure*)obj)->block.uoblk->context)) { + throw std::runtime_error("open Function can not be archived.\n"); + } + putObject(obj); + recurse(obj, obj->size); + } else { + if (mSameAddressSpace && obj->IsPermanent()) { + // skip it + } else { + if (isKindOf(obj, class_rawarray)) { + putObject(obj); + } else if (isKindOf(obj, class_array)) { + putObject(obj); + recurse(obj, obj->size); + + } else { + putObject(obj); + recurse(obj, obj->size); + } + } + } + } + } + + int32 sizeOfElem(PyrSlot *slot) + { + //postfl("writeSlot %08X\n", slot->utag); + switch (slot->utag) { + case tagObj : + if (isKindOf(slot->uo, class_class)) { + return slot->uoc->name.us->length + 1; + } else if (isKindOf(slot->uo, class_process)) { + return 0; + } else if (isKindOf(slot->uo, s_interpreter->u.classobj)) { + return 0; + } else { + return sizeof(int32); + } + break; + case tagHFrame : + case tagSFrame : + return 0; + case tagInt : + return sizeof(int32); + case tagSym : + return slot->us->length + 1; + case tagChar : + return sizeof(int32); + case tagNil : + return 0; + case tagFalse : + return 0; + case tagTrue : + return 0; + case tagInf : + return 0; + case tagPtr : + throw std::runtime_error("cannot archive RawPointers."); + return 0; + default : + return sizeof(double); + } + } + + PyrSymbol* readSymbolID() + { + char str[256]; + mStream.readSymbol(str); + return getsym(str); + } + + + PyrObject* readObjectID() + { + int32 objID = mStream.readInt32_be(); + //postfl("readObjectID %d\n", objID); + return mObjectArray[objID]; + } + + void writeObjectHeader(PyrObject *obj) + { + obj->ClearMark(); + + //postfl("writeObjectHeader %s\n", obj->classptr->name.us->name); + mStream.writeSymbol(obj->classptr->name.us->name); + + mStream.writeInt32_be(obj->size); + } + + PyrObject* readObjectHeader() + { + PyrSymbol* classname = readSymbolID(); + //post("readObjectHeader %s\n", classname->name); + PyrObject *obj; + int32 size = mStream.readInt32_be(); + if (classname->u.classobj->classFlags.ui & classHasIndexableInstances) { + obj = instantiateObject(g->gc, classname->u.classobj, size, false, false); + obj->size = size; + } else { + obj = instantiateObject(g->gc, classname->u.classobj, 0, false, false); + } + return obj; + } + + void writeSlots(PyrObject *obj) + { + //postfl(" writeSlots %s\n", obj->classptr->name.us->name); + if (isKindOf(obj, class_rawarray)) { + writeRawArray(obj); + } else if (isKindOf(obj, class_func)) { + PyrClosure* closure = (PyrClosure*)obj; + writeSlot(&closure->block); + } else { + for (int i=0; i<obj->size; ++i) { + writeSlot(obj->slots + i); + } + } + } + + void readSlots(PyrObject *obj) + { + //postfl("readSlots\n"); + if (isKindOf(obj, class_rawarray)) { + readRawArray(obj); + } else if (isKindOf(obj, class_func)) { + PyrClosure* closure = (PyrClosure*)obj; + readSlot(&closure->block); + closure->context.ucopy = g->process->interpreter.uoi->context.ucopy; + } else { + for (int i=0; i<obj->size; ++i) { + readSlot(obj->slots + i); + } + } + } + + void writeSlot(PyrSlot *slot) + { + PyrObject *obj; + //postfl(" writeSlot %08X\n", slot->utag); + switch (slot->utag) { + case tagObj : + obj = slot->uo; + if (isKindOf(obj, class_class)) { + mStream.writeInt8('C'); + mStream.writeSymbol(slot->uoc->name.us->name); + } else if (isKindOf(obj, class_process)) { + mStream.writeInt8('P'); + } else if (isKindOf(obj, s_interpreter->u.classobj)) { + mStream.writeInt8('R'); + } else { + if (mSameAddressSpace && obj->IsPermanent()) { + mStream.writeInt8('z'); + mStream.writeInt32_be((int32)obj); + } else { + mStream.writeInt8('o'); + mStream.writeInt32_be(obj->scratch1); + } + } + break; + case tagHFrame : + case tagSFrame : + mStream.writeInt8('N'); + break; + case tagInt : + mStream.writeInt8('i'); + mStream.writeInt32_be(slot->ui); + break; + case tagSym : + mStream.writeInt8('s'); + mStream.writeSymbol(slot->us->name); + break; + case tagChar : + mStream.writeInt8('c'); + mStream.writeInt32_be(slot->ui); + break; + case tagNil : + mStream.writeInt8('N'); + break; + case tagFalse : + mStream.writeInt8('F'); + break; + case tagTrue : + mStream.writeInt8('T'); + break; + case tagInf : + mStream.writeInt8('I'); + break; + case tagPtr : + mStream.writeInt8('N'); + break; + default : + mStream.writeInt8('f'); + mStream.writeDouble_be(slot->uf); + break; + } + } + + void readSlot(PyrSlot *slot) + { + char tag = mStream.readInt8(); + switch (tag) { + case 'o' : + slot->utag = tagObj; + slot->uo = readObjectID(); + break; + case 'z' : + slot->utag = tagObj; + slot->ui = mStream.readInt32_be(); + break; + case 'C' : + slot->utag = tagObj; + slot->uo = (PyrObject*)readSymbolID()->u.classobj; + break; + case 'P' : + slot->utag = tagObj; + slot->uo = (PyrObject*)g->process; + break; + case 'R' : + slot->utag = tagObj; + slot->uo = g->process->interpreter.uo; + break; + case 'i' : + slot->utag = tagInt; + slot->ui = mStream.readInt32_be(); + break; + case 's' : + slot->utag = tagSym; + slot->us = readSymbolID(); + break; + case 'c' : + slot->utag = tagChar; + slot->ui = mStream.readInt32_be(); + break; + case 'f' : + slot->uf = mStream.readDouble_be(); + break; + case 'N' : + slot->utag = tagNil; + slot->ui = 0; + break; + case 'T' : + slot->utag = tagTrue; + slot->ui = 0; + break; + case 'F' : + slot->utag = tagFalse; + slot->ui = 0; + break; + case 'I' : + slot->utag = tagInf; + slot->ui = 0; + break; + default : + slot->utag = tagNil; + slot->ui = 0; + break; + } + } + + void writeRawArray(PyrObject *obj) + { + int32 size = obj->size; + //postfl("writeRawArray %d\n", size); + switch (obj->obj_format) { + case obj_char : + case obj_int8 : { + char *data = (char*)obj->slots; + mStream.writeData(data, size); + } break; + case obj_int16 : { + int16 *data = (int16*)obj->slots; + for (int i=0; i<size; ++i) { + mStream.writeInt16_be(data[i]); + } + } break; + case obj_int32 : + case obj_float : { + int32 *data = (int32*)obj->slots; + for (int i=0; i<size; ++i) { + mStream.writeInt32_be(data[i]); + } + } break; + case obj_double : { + double *data = (double*)obj->slots; + for (int i=0; i<size; ++i) { + mStream.writeDouble_be(data[i]); + } + } break; + case obj_symbol : { + PyrSymbol **data = (PyrSymbol**)obj->slots; + for (int i=0; i<size; ++i) { + mStream.writeSymbol(data[i]->name); + } + } break; + } + } + + void readRawArray(PyrObject *obj) + { + //postfl("readRawArray\n"); + int32 size = obj->size; + switch (obj->obj_format) { + case obj_char : + case obj_int8 : { + int8 *data = (int8*)obj->slots; + for (int i=0; i<size; ++i) { + data[i] = mStream.readInt8(); + } + } break; + case obj_int16 : { + int16 *data = (int16*)obj->slots; + for (int i=0; i<size; ++i) { + data[i] = mStream.readInt16_be(); + } + } break; + case obj_int32 : + case obj_float : { + int32 *data = (int32*)obj->slots; + for (int i=0; i<size; ++i) { + data[i] = mStream.readInt32_be(); + } + } break; + case obj_double : { + double *data = (double*)obj->slots; + for (int i=0; i<size; ++i) { + data[i] = mStream.readDouble_be(); + } + } break; + case obj_symbol : { + PyrSymbol **data = (PyrSymbol**)obj->slots; + for (int i=0; i<size; ++i) { + data[i] = readSymbolID(); + } + } break; + } + + } + + VMGlobals *g; + + PyrObject **mObjectArray; + int32 mNumObjects; + int32 mObjectArrayCapacity; + PyrSlot mTopSlot; + + bool mSameAddressSpace; + SC_IOStream<S> mStream; + int32 mReadArchiveVersion; + + PyrObject *mInitialObjectArray[kObjectArrayInitialCapacity]; +}; + +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +An object archiving system for SuperCollider. + +*/ + + + +#endif + diff --git a/sc4pd/headers/lang/PyrDeepCopier.h b/sc4pd/headers/lang/PyrDeepCopier.h new file mode 100644 index 0000000..3b46280 --- /dev/null +++ b/sc4pd/headers/lang/PyrDeepCopier.h @@ -0,0 +1,221 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +An object archiving system for SuperCollider. + +*/ + + +#ifndef _PyrDeepCopier_ +#define _PyrDeepCopier_ + +#include "PyrObject.h" +#include "SC_AllocPool.h" + +#include "PyrKernel.h" +#include "PyrPrimitive.h" +#include "VMGlobals.h" +#include "GC.h" +#include "ReadWriteMacros.h" + +const int32 kDeepCopierObjectArrayInitialCapacity = 32; + +class PyrDeepCopier +{ +public: + PyrDeepCopier(VMGlobals *inG) + : g(inG), objectArray(initialObjectArray), numObjects(0), + objectArrayCapacity( kDeepCopierObjectArrayInitialCapacity ) + { + } + + ~PyrDeepCopier() + { + if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) { + g->allocPool->Free(objectArray); + } + } + + long doDeepCopy(PyrSlot *objectSlot) + { + long err = errNone; + + try { + if (IsObj(objectSlot)) { + constructObjectArray(objectSlot->uo); + for (int i=0; i<numObjects; ++i) { + fixSlots(objectArray[i]); + } + fixObjSlot(objectSlot); + for (int i=0; i<numObjects; ++i) { + objectArray[i]->ClearMark(); + } + + } + } catch (std::exception &ex) { + error(ex.what()); + err = errFailed; + } + return err; + } + +private: + + void recurse(PyrObject *obj, int n) + { + //post("->recurse %s %08X\n", obj->classptr->name.us->name, obj); + PyrSlot *slot = obj->slots; + for (int i=0; i<n; ++i, ++slot) { + if (IsObj(slot)) constructObjectArray(slot->uo); + } + //post("<-recurse %s %08X\n", obj->classptr->name.us->name, obj); + } + + void growObjectArray() + { + int32 newObjectArrayCapacity = objectArrayCapacity << 1; + + int32 newSize = newObjectArrayCapacity * sizeof(PyrObject*); + PyrObject** newArray = (PyrObject**)g->allocPool->Alloc(newSize); + memcpy(newArray, objectArray, numObjects * sizeof(PyrObject*)); + if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) { + g->allocPool->Free(objectArray); + } + objectArrayCapacity = newObjectArrayCapacity; + objectArray = newArray; + } + + void putSelf(PyrObject *obj) + { + obj->SetMark(); + obj->scratch1 = numObjects; + + // expand array if needed + if (numObjects >= objectArrayCapacity) growObjectArray(); + + //post("putSelf %d %08X\n", numObjects, obj); + // add to array + objectArray[numObjects++] = obj; + } + + void putCopy(PyrObject *obj) + { + obj->SetMark(); + obj->scratch1 = numObjects; + + // expand array if needed + if (numObjects+2 >= objectArrayCapacity) growObjectArray(); + + // add a shallow copy to object array + PyrObject *copy = copyObject(g->gc, obj, false); + copy->ClearMark(); + + //post("putCopy %d %08X\n", numObjects, copy); + + // add to array + objectArray[numObjects++] = copy; + objectArray[numObjects++] = obj; + } + + void constructObjectArray(PyrObject *obj) + { + //post("->constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj); + if (!obj->IsMarked()) { + if (isKindOf(obj, class_class)) { + putSelf(obj); + } else if (isKindOf(obj, class_process)) { + putSelf(obj); + } else if (isKindOf(obj, s_interpreter->u.classobj)) { + putSelf(obj); + } else if (isKindOf(obj, class_rawarray)) { + putCopy(obj); + } else if (isKindOf(obj, class_array)) { + putCopy(obj); + recurse(obj, obj->size); + } else if (isKindOf(obj, class_func)) { + putSelf(obj); + } else if (isKindOf(obj, class_method)) { + putSelf(obj); + } else if (isKindOf(obj, class_thread)) { + putSelf(obj); + } else { + putCopy(obj); + recurse(obj, obj->size); + } + } + //post("<-constructObjectArray %s %08X\n", obj->classptr->name.us->name, obj); + } + + void fixObjSlot(PyrSlot* slot) + { + //post("fixObjSlot %s %08X %d %08X\n", slot->uo->classptr->name.us->name, slot->uo, slot->uo->scratch1, objectArray[slot->uo->scratch1]); + slot->uo = objectArray[slot->uo->scratch1]; + } + + void fixSlots(PyrObject *obj) + { + //post("fixSlots %s %08X %d\n", obj->classptr->name.us->name, obj, obj->IsMarked()); + if (!obj->IsMarked() && obj->obj_format <= obj_slot) { // it is a copy + PyrSlot *slot = obj->slots; + for (int i=0; i<obj->size; ++i, ++slot) { + if (IsObj(slot)) fixObjSlot(slot); + } + } + } + + VMGlobals *g; + + PyrObject **objectArray; + int32 numObjects; + int32 objectArrayCapacity; + + PyrObject *initialObjectArray[kDeepCopierObjectArrayInitialCapacity]; +}; + +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +An object archiving system for SuperCollider. + +*/ + + + +#endif + diff --git a/sc4pd/headers/lang/PyrDeepFreezer.h b/sc4pd/headers/lang/PyrDeepFreezer.h new file mode 100644 index 0000000..28d9a12 --- /dev/null +++ b/sc4pd/headers/lang/PyrDeepFreezer.h @@ -0,0 +1,178 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +An object archiving system for SuperCollider. + +*/ + +#ifndef _PyrDeepFreezer_ +#define _PyrDeepFreezer_ + +#include "PyrObject.h" +#include "SC_AllocPool.h" +#include "PyrKernel.h" +#include "PyrPrimitive.h" +#include "VMGlobals.h" +#include "GC.h" + +const int32 kDeepFreezerObjectArrayInitialCapacity = 32; + +class PyrDeepFreezer +{ +public: + PyrDeepFreezer(VMGlobals *inG) + : g(inG), objectArray(initialObjectArray), numObjects(0), + objectArrayCapacity( kDeepCopierObjectArrayInitialCapacity ) + { + } + + ~PyrDeepFreezer() + { + if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) { + g->allocPool->Free(objectArray); + } + } + + long doDeepFreeze(PyrSlot *objectSlot) + { + long err = errNone; + + try { + if (IsObj(objectSlot)) { + constructObjectArray(objectSlot->uo); + for (int i=0; i<numObjects; ++i) { + g->gc->BecomePermanent( objectArray[i] ); + } + } + } catch (std::exception &ex) { + error(ex.what()); + err = errFailed; + } + return err; + } + +private: + + void recurse(PyrObject *obj, int n) + { + PyrSlot *slot = obj->slots; + for (int i=0; i<n; ++i, ++slot) { + if (IsObj(slot)) constructObjectArray(slot->uo); + } + } + + void growObjectArray() + { + int32 newObjectArrayCapacity = objectArrayCapacity << 1; + + int32 newSize = newObjectArrayCapacity * sizeof(PyrObject*); + PyrObject** newArray = (PyrObject**)g->allocPool->Alloc(newSize); + memcpy(newArray, objectArray, numObjects * sizeof(PyrObject*)); + if (objectArrayCapacity > kDeepCopierObjectArrayInitialCapacity) { + g->allocPool->Free(objectArray); + } + objectArrayCapacity = newObjectArrayCapacity; + objectArray = newArray; + } + + void putObject(PyrObject *obj) + { + obj->SetMark(); + obj->scratch1 = numObjects; + + // expand array if needed + if (numObjects >= objectArrayCapacity) growObjectArray(); + + // add to array + objectArray[numObjects++] = obj; + } + + void constructObjectArray(PyrObject *obj) + { + if (obj->IsPermanent()) return; + + if (!obj->IsMarked()) { + if (isKindOf(obj, class_process)) { + throw std::runtime_error("cannot freeze Process.\n"); + } else if (isKindOf(obj, s_interpreter->u.classobj)) { + throw std::runtime_error("cannot freeze Interpreter.\n"); + } else if (isKindOf(obj, class_rawarray)) { + putObject(obj); + } else if (isKindOf(obj, class_array)) { + putObject(obj); + recurse(obj, obj->size); + } else if (isKindOf(obj, class_func)) { + if (NotNil(&((PyrClosure*)obj)->block.uoblk->context)) { + throw std::runtime_error("open Function can not be frozen.\n"); + } + putObject(obj); + recurse(obj, obj->size); + } else if (isKindOf(obj, class_method)) { + throw std::runtime_error("cannot freeze Methods.\n"); + } else if (isKindOf(obj, class_thread)) { + throw std::runtime_error("cannot freeze Threads.\n"); + } else if (isKindOf(obj, class_frame)) { + throw std::runtime_error("cannot freeze Frames.\n"); + } else { + putObject(obj); + recurse(obj, obj->size); + } + } + } + + VMGlobals *g; + + PyrObject **objectArray; + int32 numObjects; + int32 objectArrayCapacity; + + PyrObject *initialObjectArray[kDeepCopierObjectArrayInitialCapacity]; +}; + +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +An object archiving system for SuperCollider. + +*/ + + + +#endif + diff --git a/sc4pd/headers/lang/PyrErrors.h b/sc4pd/headers/lang/PyrErrors.h new file mode 100644 index 0000000..b2be76e --- /dev/null +++ b/sc4pd/headers/lang/PyrErrors.h @@ -0,0 +1,49 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +virtual machine error codes. + +*/ + +#ifndef _SCErrors_ +#define _SCErrors_ + +enum { // primitive errors + errReturn = -1, // not really an error.. primitive executed a non-local return + errNone, + errFailed = 5000, + errBadPrimitive, + errWrongType, + errIndexNotAnInteger, + errIndexOutOfRange, + errImmutableObject, + errNotAnIndexableObject, + errStackOverflow, + errOutOfMemory, + errCantCallOS, + errException, + + errPropertyNotFound = 6000, + + errLastError +}; + +#endif diff --git a/sc4pd/headers/lang/PyrFilePrim.h b/sc4pd/headers/lang/PyrFilePrim.h new file mode 100644 index 0000000..3574927 --- /dev/null +++ b/sc4pd/headers/lang/PyrFilePrim.h @@ -0,0 +1,62 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef _PYRFILEPRIM_H_ +#define _PYRFILEPRIM_H_ + +#include "PyrObject.h" + +struct PyrFile : public PyrObjectHdr +{ + PyrSlot fileptr; +}; + +void initFilePrimitives(); + +long prFileDelete(VMGlobals *g, long numArgsPushed); +long prFileOpen(VMGlobals *g, long numArgsPushed); +long prFileClose(VMGlobals *g, long numArgsPushed); +long prFileSeek(VMGlobals *g, long numArgsPushed); +long prFilePos(VMGlobals *g, long numArgsPushed); +long prFileLength(VMGlobals *g, long numArgsPushed); +long prFileWrite(VMGlobals *g, long numArgsPushed); +long prFileReadLine(VMGlobals *g, long numArgsPushed); + +long prFilePutRGB(VMGlobals *g, long numArgsPushed); +long prFilePutInt32(VMGlobals *g, long numArgsPushed); +long prFilePutInt16(VMGlobals *g, long numArgsPushed); +long prFilePutInt8(VMGlobals *g, long numArgsPushed); +long prFilePutChar(VMGlobals *g, long numArgsPushed); +long prFilePutFloat(VMGlobals *g, long numArgsPushed); +long prFilePutDouble(VMGlobals *g, long numArgsPushed); + +long prFileGetRGB(VMGlobals *g, long numArgsPushed); +long prFileGetInt32(VMGlobals *g, long numArgsPushed); +long prFileGetInt16(VMGlobals *g, long numArgsPushed); +long prFileGetInt8(VMGlobals *g, long numArgsPushed); +long prFileGetChar(VMGlobals *g, long numArgsPushed); +long prFileGetFloat(VMGlobals *g, long numArgsPushed); +long prFileGetDouble(VMGlobals *g, long numArgsPushed); + +long prFilePutString(VMGlobals *g, long numArgsPushed); +long prFileRead(VMGlobals *g, long numArgsPushed); + + +#endif + diff --git a/sc4pd/headers/lang/PyrFileUtils.h b/sc4pd/headers/lang/PyrFileUtils.h new file mode 100644 index 0000000..1fd682b --- /dev/null +++ b/sc4pd/headers/lang/PyrFileUtils.h @@ -0,0 +1,50 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +Some utils for file i/o. + +*/ + +#ifndef _PYRFILEUTIL_H_ +#define _PYRFILEUTIL_H_ + +int headerFormatFromSymbol(struct PyrSymbol *inSymbol); +int sampleFormatFromSymbol(struct PyrSymbol *inSymbol, int inHeaderFormat); + +#ifdef __MAC__ + +#include <Files.h> + +long setTypeCreator(unsigned char *filename, long type, long creator); +bool filelen(FILE *file, size_t *length); + +int allocasync(int fildes, int count, IOParam *pb, IOCompletionUPP completionFunc); +int createasync(unsigned char *path, int oflag, HParamBlockRec *hpb, IOCompletionUPP completionFunc); +int openasync(unsigned char *path, int oflag, HParamBlockRec *hpb, IOCompletionUPP completionFunc); +int closeasync(int fildes, HParamBlockRec *hpb, IOCompletionUPP completionFunc); +int writeasync(int fildes, const char *buf, int count, IOParam *pb, IOCompletionUPP completionFunc); +int readasync(int fildes, char *buf, int count, IOParam *pb, IOCompletionUPP completionFunc); +int seekwriteasync(int fildes, const char *buf, int count, int pos, IOParam *pb, IOCompletionUPP completionFunc); +int seekreadasync(int fildes, char *buf, int count, int pos, IOParam *pb, IOCompletionUPP completionFunc); + + +#endif +#endif diff --git a/sc4pd/headers/lang/PyrInterpreter.h b/sc4pd/headers/lang/PyrInterpreter.h new file mode 100644 index 0000000..a21126d --- /dev/null +++ b/sc4pd/headers/lang/PyrInterpreter.h @@ -0,0 +1,47 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _PYRINTERPRETER_H_ +#define _PYRINTERPRETER_H_ + +#include "PyrSlot.h" +#include "VMGlobals.h" + +extern bool gRunningInterpreterThread; + +extern int gNumClasses; + +bool initInterpreter(VMGlobals *g, PyrSymbol *selector, int numArgsPushed); +bool initRuntime(VMGlobals *g, int poolSize, AllocPool *inPool, int processID); +void Interpret(VMGlobals *g); +void endInterpreter(VMGlobals *g); + +int doSpecialUnaryArithMsg(VMGlobals *g, int numArgsPushed); +int prSpecialBinaryArithMsg(VMGlobals *g, int numArgsPushed); +int doSpecialBinaryArithMsg(VMGlobals *g, int numArgsPushed, bool isPrimitive); +void DumpBackTrace(VMGlobals *g); +void DumpStack(VMGlobals *g, PyrSlot *sp); +void DumpFrame(struct PyrFrame *frame); +bool FrameSanity(PyrFrame *frame, char *tagstr); +struct PyrProcess* newPyrProcess(VMGlobals *g, struct PyrClass *classobj); +void startProcess(VMGlobals *g, PyrSymbol *selector); +void runInterpreter(VMGlobals *g, PyrSymbol *selector, int numArgsPushed); + +#endif diff --git a/sc4pd/headers/lang/PyrKernel.h b/sc4pd/headers/lang/PyrKernel.h new file mode 100644 index 0000000..d5c6af7 --- /dev/null +++ b/sc4pd/headers/lang/PyrKernel.h @@ -0,0 +1,256 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +This file contains the definitions of the core objects that implement the class system. + +*/ + +#ifndef _PYRKERNEL_H_ +#define _PYRKERNEL_H_ + +#include "PyrObject.h" +#include "VMGlobals.h" + +#define classClassNumInstVars 16 + +enum { classIsIntrinsic = 1, classHasIndexableInstances = 2, classCompileUGen = 4 }; + +struct PyrClass : public PyrObjectHdr +{ + PyrSlot name; + PyrSlot nextclass; + PyrSlot superclass; + PyrSlot subclasses; + PyrSlot methods; + + PyrSlot instVarNames; + PyrSlot classVarNames; + PyrSlot iprototype; // instance prototype + PyrSlot cprototype; // class var prototype + + PyrSlot instanceFormat; + PyrSlot instanceFlags; + PyrSlot classIndex; + PyrSlot classFlags; + PyrSlot maxSubclassIndex; // used by isKindOf + PyrSlot filenameSym; + PyrSlot charPos; +}; + + + +inline bool isKindOf(PyrObjectHdr *obj, struct PyrClass *testclass) +{ + int objClassIndex = obj->classptr->classIndex.ui; + return objClassIndex >= testclass->classIndex.ui && objClassIndex <= testclass->maxSubclassIndex.ui; +} + +inline bool isKindOfSlot(PyrSlot *slot, struct PyrClass *testclass) +{ + return IsObj(slot) && isKindOf(slot->uo, testclass); +} + +/* + operations on class: + numInstVars() + numClassVars() + +*/ + +struct PyrFrame { + PyrSlot vars[1]; + PyrSlot myself; + PyrSlot method; + PyrSlot caller; + PyrSlot context; + PyrSlot homeContext; + PyrSlot ip; +}; + +#define FRAMESIZE 6 +#define USESTACKFRAMES 1 + +struct PyrProcess : public PyrObjectHdr +{ + + PyrSlot classVars; + PyrSlot interpreter; + PyrSlot curThread, mainThread; + PyrSlot processID; + PyrSlot sysSchedulerQueue; +}; + + +enum { tInit, tStart, tReady, tRunning, tSleeping, tBlocked, tYieldToChild, tYieldToParent, tDone }; + +struct PyrThread : public PyrObjectHdr +{ + + PyrSlot state, func, stack, stackSize, method, block, frame, ip, sp; + PyrSlot numpop, returnLevels, receiver, numArgsPushed; + PyrSlot parent, terminalValue; + PyrSlot primitiveError; + PyrSlot primitiveIndex; + PyrSlot randData; + PyrSlot beats, seconds, clock; + PyrSlot environment; + PyrSlot exceptionHandler; +}; + +#define EVALSTACKDEPTH 8192 + + + +struct PyrMethodRaw { + + unsigned short unused1; + unsigned short specialIndex; + unsigned short methType; + unsigned short frameSize; + + unsigned char unused2; + unsigned char numargs; + unsigned char varargs; + unsigned char numvars; + unsigned char numtemps; + unsigned char needsHeapContext; + unsigned char popSize; + unsigned char posargs; + +}; + + +#define METHRAW(obj) ((PyrMethodRaw*)&(((PyrBlock*)obj)->rawData1)) + +struct PyrBlock : public PyrObjectHdr +{ + + PyrSlot rawData1; + PyrSlot rawData2; + PyrSlot code; // byte codes, nil if inlined + PyrSlot selectors; // method selectors, class names, closures table + PyrSlot constants; // floating point constants table (to alleviate the literal table problem) + PyrSlot prototypeFrame; // prototype of an activation frame + PyrSlot context; // ***defining block context + PyrSlot argNames; // ***arguments to block + PyrSlot varNames; // ***variables in block + PyrSlot sourceCode; // source code if it is a closed function. +}; + +struct PyrMethod : public PyrBlock +{ + PyrSlot ownerclass; + PyrSlot name; + PyrSlot primitiveName; + PyrSlot filenameSym; + PyrSlot charPos; + //PyrSlot byteMeter; + //PyrSlot callMeter; +}; + +enum { + methNormal = 0, + methReturnSelf, + methReturnLiteral, + methReturnArg, + methReturnInstVar, + methAssignInstVar, + methReturnClassVar, + methAssignClassVar, + methRedirect, + methForward, + methPrimitive, + methBlock +}; + +struct PyrClosure : public PyrObjectHdr +{ + + PyrSlot block; + PyrSlot context; +}; + +struct PyrInterpreter : public PyrObjectHdr +{ + + PyrSlot cmdLine, context; + PyrSlot a, b, c, d, e, f, g, h, i, j; + PyrSlot k, l, m, n, o, p, q, r, s, t; + PyrSlot u, v, w, x, y, z; + PyrSlot codeDump; +}; + +/* special values */ +enum { + svNil, + svFalse, + svTrue, + svNegOne, + svZero, + svOne, + svTwo, + svFHalf, + svFNegOne, + svFZero, + svFOne, + svFTwo, + svInf, + + svNumSpecialValues +}; + +extern double gSpecialValues[svNumSpecialValues]; + +extern PyrMethod *gNullMethod; // used to fill row table + +PyrObject* instantiateObject(class PyrGC *gc, PyrClass* classobj, int size, + bool fill, bool collect); + +PyrObject* newPyrObject(class PyrGC *gc, size_t inNumBytes, int inFlags, int inFormat, bool inCollect); +PyrString* newPyrString(class PyrGC *gc, const char *s, int flags, bool collect); +PyrString* newPyrStringN(class PyrGC *gc, int size, int flags, bool collect); +PyrObject* newPyrArray(class PyrGC *gc, int size, int flags, bool collect); +PyrSymbolArray* newPyrSymbolArray(class PyrGC *gc, int size, int flags, bool collect); +PyrInt8Array* newPyrInt8Array(class PyrGC *gc, int size, int flags, bool collect); +PyrInt32Array* newPyrInt32Array(class PyrGC *gc, int size, int flags, bool collect); +PyrDoubleArray* newPyrDoubleArray(class PyrGC *gc, int size, int flags, bool collect); + +PyrObject* copyObject(class PyrGC *gc, PyrObject *inobj, bool collect); +PyrObject* copyObjectRange(class PyrGC *gc, PyrObject *inobj, int start, int end, bool collect); + +inline void SetFrame(PyrSlot* slot, PyrFrame* frame) +{ + (slot)->ui = ((int)(frame)); + (slot)->utag = tagSFrame - METHRAW((frame)->method.uoblk)->needsHeapContext; +} + +inline void SetFrameOrNil(PyrSlot* slot, PyrFrame* frame) +{ + if (frame) { + (slot)->ui = ((int)(frame)); + (slot)->utag = tagSFrame - METHRAW((frame)->method.uoblk)->needsHeapContext; + } else { + (slot)->utag = tagNil; + (slot)->ui = 0; + } +} + +#endif diff --git a/sc4pd/headers/lang/PyrKernelProto.h b/sc4pd/headers/lang/PyrKernelProto.h new file mode 100644 index 0000000..f040507 --- /dev/null +++ b/sc4pd/headers/lang/PyrKernelProto.h @@ -0,0 +1,62 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _PYRKERNELPROTO_H_ +#define _PYRKERNELPROTO_H_ + +PyrClass* newClassObj(PyrClass *classObjSuperClass, + PyrSymbol* className, PyrSymbol* superClassName, + int numInstVars, int numClassVars, int numInstMethods, + int instFormat, int instFlags); + +void reallocClassObj(PyrClass* classobj, + int numInstVars, int numClassVars, int numMethods, + int instFormat, int instFlags); + +int numInstVars(PyrClass* classobj); +int numClassVars(PyrClass* classobj); +int numSuperInstVars(PyrClass *superclassobj); +bool classFindInstVar(PyrClass* classobj, PyrSymbol *name, int *index); +bool classFindClassVar(PyrClass** classobj, PyrSymbol *name, int *index); + +void buildClassTree(); +void indexClassTree(PyrClass *classobj, int numSuperMethods); +void postClassTree(PyrClass *classobj, int level); +void setSelectorFlags(); +void buildBigMethodMatrix(); +void fillClassRow(PyrClass *classobj, struct PyrMethod** bigTable); + +bool funcFindArg(PyrBlock* func, PyrSymbol *name, int *index); +bool funcFindVar(PyrBlock* func, PyrSymbol *name, int *index); +void addMethod(PyrClass *classobj, PyrMethod *method); + + +PyrMethod* classFindDirectMethod(PyrClass* classobj, PyrSymbol *name); + +PyrBlock* newPyrBlock(int flags); +PyrMethod* newPyrMethod(); +PyrClass* makeIntrinsicClass(PyrSymbol *className, PyrSymbol *superClassName, + int numInstVars, int numClassVars); +void addIntrinsicVar(PyrClass *classobj, char *varName, PyrSlot *slot); + + + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/lang/PyrLexer.h b/sc4pd/headers/lang/PyrLexer.h new file mode 100644 index 0000000..5166337 --- /dev/null +++ b/sc4pd/headers/lang/PyrLexer.h @@ -0,0 +1,136 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _PYRLEXER_H_ +#define _PYRLEXER_H_ + +#include "PyrSymbol.h" + +extern int charno, lineno, linepos; +extern int *linestarts; + +struct ClassExtFile { + struct ClassExtFile *next; + PyrSymbol *fileSym; +}; + +typedef struct classdep { + struct classdep *next; + struct classdep *superClassDep; + struct classdep *subclasses; + PyrSymbol *className; + PyrSymbol *superClassName; + PyrSymbol *fileSym; +} ClassDependancy; + +extern PyrSymbol *gCompilingFileSym; + +ClassDependancy* newClassDependancy(PyrSymbol *className, PyrSymbol *superClassName, + PyrSymbol *fileSym); +bool parseOneClass(PyrSymbol *fileSym); +void initPassOne(); +void finiPassOne(); +bool passOne(); +void buildDepTree(); +void traverseFullDepTree(); +void traverseDepTree(ClassDependancy *classdep, int level); +void traverseFullDepTree2(); +void traverseDepTree2(ClassDependancy *classdep, int level); +void compileClassExtensions(); +void compileFileSym(PyrSymbol *fileSym); + +void runLibrary(PyrSymbol* selector); + +void interpretCmdLine(const char *textbuf, int textlen, char *methodname); + + +int input(); +int input0(); +void unput(int c); +void unput0(int c); + +void finiLexer() ; +bool startLexer(char* filename) ; +void startLexerCmdLine(char *textbuf, int textbuflen); +int yylex() ; +void yyerror(char *s) ; +void fatal() ; +bool isValidSourceFileName(char *filename); +bool passOne_ProcessOneFile(char *filename, int level); + +extern void asRelativePath(char *inPath,char *outPath); + +void initLexer(); +void init_SuperCollider(); + +int processbinop(char *token); +int processident(char *token); +int processfloat(char *token, int sawpi); +int processint(char *token); +int processchar(int c); +int processintradix(char *s); +int processfloatradix(char *s); +int processhex(char *s); +int processsymbol(char *token); +int processstring(char *token); +int processkeywordbinop(char *token); + +void postErrorLine(int linenum, int start, int charpos); +bool scanForClosingBracket(); +void parseClasses(); + +extern int parseFailed; +extern bool compilingCmdLine; +extern bool compilingCmdLineErrorWindow; +extern bool compiledOK; + +#define MAXYYLEN 8192 + +extern int gNumCompiledFiles; +extern int gClassCompileOrderNum; +extern ClassDependancy **gClassCompileOrder; +extern char curfilename[PATH_MAX]; + +extern int runcount; + +extern char *binopchars; +extern char yytext[MAXYYLEN]; +extern char linebuf[256]; +extern char curfilename[PATH_MAX]; + +extern int yylen; +extern int lexCmdLine; +extern bool compilingCmdLine; +extern bool compilingCmdLineErrorWindow; +extern long zzval; + +extern int lineno, charno, linepos; +extern int *linestarts; +extern int maxlinestarts; + +extern char *text; +extern int textlen; +extern int textpos; +extern int parseFailed; +extern bool compiledOK; +extern int radixcharpos, decptpos; + +#endif diff --git a/sc4pd/headers/lang/PyrListPrim.h b/sc4pd/headers/lang/PyrListPrim.h new file mode 100644 index 0000000..43288a7 --- /dev/null +++ b/sc4pd/headers/lang/PyrListPrim.h @@ -0,0 +1,34 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _PYRARRAYPRIM_H_ +#define _PYRARRAYPRIM_H_ + +void initArrayPrimitives(); + +int prArrayMultiChanExpand(VMGlobals *g, int numArgsPushed); + +int arrayAtIdentityHash(PyrObject *array, PyrSlot *key); +int arrayAtIdentityHashInPairs(PyrObject *array, PyrSlot *key); +int arrayAtIdentityHashInPairsWithHash(PyrObject *array, PyrSlot *key, int hash); + + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/lang/PyrMathPrim.h b/sc4pd/headers/lang/PyrMathPrim.h new file mode 100644 index 0000000..f4e2dd1 --- /dev/null +++ b/sc4pd/headers/lang/PyrMathPrim.h @@ -0,0 +1,51 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _PYRMATHPRIM_H_ +#define _PYRMATHPRIM_H_ + +void initMathPrimitives(); + +int prAddNum(VMGlobals *g, int numArgsPushed); +int prSubNum(VMGlobals *g, int numArgsPushed); +int prMulNum(VMGlobals *g, int numArgsPushed); + +int prAddInt(VMGlobals *g, int numArgsPushed); +int prSubInt(VMGlobals *g, int numArgsPushed); +int prMulInt(VMGlobals *g, int numArgsPushed); + +int prAddFloat(VMGlobals *g, int numArgsPushed); +int prSubFloat(VMGlobals *g, int numArgsPushed); +int prMulFloat(VMGlobals *g, int numArgsPushed); + +int mathClip(VMGlobals *g, int numArgsPushed); +int mathWrap(VMGlobals *g, int numArgsPushed); +int mathFold(VMGlobals *g, int numArgsPushed); +int mathClipInt(VMGlobals *g, int numArgsPushed); +int mathWrapInt(VMGlobals *g, int numArgsPushed); +int mathFoldInt(VMGlobals *g, int numArgsPushed); +int mathClipFloat(VMGlobals *g, int numArgsPushed); +int mathWrapFloat(VMGlobals *g, int numArgsPushed); +int mathFoldFloat(VMGlobals *g, int numArgsPushed); +int mathClipSignal(VMGlobals *g, int numArgsPushed); +int mathWrapSignal(VMGlobals *g, int numArgsPushed); +int mathFoldSignal(VMGlobals *g, int numArgsPushed); + +#endif diff --git a/sc4pd/headers/lang/PyrMessage.h b/sc4pd/headers/lang/PyrMessage.h new file mode 100644 index 0000000..436128a --- /dev/null +++ b/sc4pd/headers/lang/PyrMessage.h @@ -0,0 +1,55 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _PYRMESSAGE_H_ +#define _PYRMESSAGE_H_ + +#include "PyrKernel.h" + +#define MAXKEYSLOTS 128 +extern PyrSlot keywordstack[MAXKEYSLOTS]; +extern bool gKeywordError; +extern PyrMethod **gRowTable; + +void initUniqueMethods(); + +void sendMessageWithKeys(VMGlobals *g, PyrSymbol *selector, + long numArgsPushed, long numKeyArgsPushed); +void sendMessage(VMGlobals *g, PyrSymbol *selector, long numArgsPushed); +void sendSuperMessageWithKeys(VMGlobals *g, PyrSymbol *selector, + long numArgsPushed, long numKeyArgsPushed); +void sendSuperMessage(VMGlobals *g, PyrSymbol *selector, long numArgsPushed); +void doesNotUnderstandWithKeys(VMGlobals *g, PyrSymbol *selector, + long numArgsPushed, long numKeyArgsPushed); +void doesNotUnderstand(VMGlobals *g, PyrSymbol *selector, + long numArgsPushed); +void returnFromBlock(VMGlobals *g); +void returnFromMethod(VMGlobals *g); +void executeMethod(VMGlobals *g, PyrMethod *meth, long numArgsPushed); +void executeMethodWithKeys(VMGlobals *g, PyrMethod *meth, long allArgsPushed, + long numKeyArgsPushed); +void keywordFixStack(VMGlobals *g, PyrMethod *meth, PyrMethodRaw *methraw, long allArgsPushed, + long numKeyArgsPushed); + +#endif + + + diff --git a/sc4pd/headers/lang/PyrObject.h b/sc4pd/headers/lang/PyrObject.h new file mode 100644 index 0000000..05abf21 --- /dev/null +++ b/sc4pd/headers/lang/PyrObject.h @@ -0,0 +1,288 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +PyrObject represents the structure of all SC Objects. + +*/ + +#ifndef _PYROBJECT_H_ +#define _PYROBJECT_H_ + +#include "PyrSlot.h" + +/* special gc colors */ +enum { + obj_permanent = 1, // sent to gc->New as a flag + obj_gcmarker = 2 // gc treadmill marker +}; + +/* obj flag fields */ +enum { + obj_immutable = 16, + obj_marked = 128 +}; + +/* format types : */ +enum { + obj_notindexed, + obj_slot, + obj_double, + obj_float, + obj_int32, + obj_int16, + obj_int8, + obj_char, + obj_symbol, + + NUMOBJFORMATS +}; + + +/* + PyrObjectHdr : object header fields + prev, next : pointers in the GC treadmill + classptr : pointer to the object's class + size : number of slots or indexable elements. + + obj_format : what kind of data this object holds + obj_sizeclass : power of two size class of the object + obj_flags : + immutable : set if object may not be updated. + finalize : set if object requires finalization. + marked : used by garbage collector debug sanity check. may be used by primitives but must be cleared before exiting primitive. + gc_color : GC color : black, grey, white, free, permanent + scratch1 : undefined value. may be used within primitives as a temporary scratch value. +*/ + +struct PyrObjectHdr { + struct PyrObjectHdr *prev, *next; + struct PyrClass *classptr; + int size; + + unsigned char obj_format; + unsigned char obj_sizeclass; + unsigned char obj_flags; + unsigned char gc_color; + + int scratch1; + + int SizeClass() { return obj_sizeclass; } + + void SetMark() { obj_flags |= obj_marked; } + void ClearMark() { obj_flags &= ~obj_marked; } + bool IsMarked() { return obj_flags & obj_marked; } + bool IsPermanent() { return gc_color == obj_permanent; } +}; + +struct PyrObject : public PyrObjectHdr { + PyrSlot slots[1]; +}; + +struct PyrList : public PyrObjectHdr +{ + PyrSlot array; +}; + +struct PyrDoubleArray : public PyrObjectHdr +{ + double d[1]; +}; + +struct PyrFloatArray : public PyrObjectHdr +{ + float f[1]; +}; + +struct PyrInt32Array : public PyrObjectHdr +{ + uint32 i[1]; +}; + +struct PyrInt16Array : public PyrObjectHdr +{ + uint16 i[1]; +}; + +struct PyrInt8Array : public PyrObjectHdr +{ + uint8 b[1]; +}; + +struct PyrRGBArray : public PyrObjectHdr +{ + RGBColor8 r[1]; +}; + +struct PyrString : public PyrObjectHdr +{ + char s[1]; +}; + +struct PyrSymbolArray : public PyrObjectHdr +{ + PyrSymbol* symbols[1]; +}; + +extern struct PyrClass *class_object; +extern struct PyrClass *class_array; +extern struct PyrClass *class_list, *class_method, *class_fundef, *class_frame, *class_class; +extern struct PyrClass *class_symbol, *class_nil; +extern struct PyrClass *class_boolean, *class_true, *class_false; +extern struct PyrClass *class_int, *class_char, *class_float, *class_complex; +extern struct PyrClass *class_rawptr; +extern struct PyrClass *class_string; +extern struct PyrClass *class_magnitude, *class_number, *class_collection; +extern struct PyrClass *class_sequenceable_collection; +extern struct PyrClass *class_arrayed_collection; +extern struct PyrClass *class_simple_number; +extern struct PyrClass *class_signal; +extern struct PyrClass *class_wavetable; +extern struct PyrClass *class_rawarray; +extern struct PyrClass *class_int8array; +extern struct PyrClass *class_int16array; +extern struct PyrClass *class_int32array; +extern struct PyrClass *class_symbolarray; +extern struct PyrClass *class_floatarray; +extern struct PyrClass *class_doublearray; +extern struct PyrClass *class_func, *class_absfunc; +extern struct PyrClass *class_stream; +extern struct PyrClass *class_process; +extern struct PyrClass *class_thread; +extern struct PyrClass *class_routine; +extern struct PyrClass *class_inf; +extern struct PyrClass *class_finalizer; + +extern PyrSymbol *s_none; +extern PyrSymbol *s_object; +extern PyrSymbol *s_bag; +extern PyrSymbol *s_set; +extern PyrSymbol *s_identityset; +extern PyrSymbol *s_dictionary; +extern PyrSymbol *s_identitydictionary; +extern PyrSymbol *s_linkedlist; +extern PyrSymbol *s_sortedlist; +extern PyrSymbol *s_array; +extern PyrSymbol *s_list, *s_method, *s_fundef, *s_frame, *s_class; +extern PyrSymbol *s_symbol, *s_nil, *s_inf; +extern PyrSymbol *s_boolean, *s_true, *s_false; +extern PyrSymbol *s_int, *s_char, *s_color, *s_float, *s_complex; +extern PyrSymbol *s_rawptr, *s_objptr; +extern PyrSymbol *s_string; +extern PyrSymbol *s_magnitude, *s_number, *s_collection; +extern PyrSymbol *s_ordered_collection; +extern PyrSymbol *s_sequenceable_collection; +extern PyrSymbol *s_arrayed_collection; +extern PyrSymbol *s_simple_number; +extern PyrSymbol *s_signal; +extern PyrSymbol *s_wavetable; +extern PyrSymbol *s_int8array; +extern PyrSymbol *s_int16array; +extern PyrSymbol *s_int32array; +extern PyrSymbol *s_symbolarray; +extern PyrSymbol *s_floatarray; +extern PyrSymbol *s_doublearray; +extern PyrSymbol *s_point; +extern PyrSymbol *s_rect; +extern PyrSymbol *s_stream; +extern PyrSymbol *s_process; +extern PyrSymbol *s_main; +extern PyrSymbol *s_thread; +extern PyrSymbol *s_routine; +extern PyrSymbol *s_linear, *s_exponential, *s_gate; +extern PyrSymbol *s_env; + +extern PyrSymbol *s_audio, *s_control, *s_scalar; +extern PyrSymbol *s_run; +extern PyrSymbol *s_next; +extern PyrSymbol *s_at; +extern PyrSymbol *s_put; +extern PyrSymbol *s_series, *s_copyseries, *s_putseries; +extern PyrSymbol *s_value; +extern PyrSymbol *s_performList; +extern PyrSymbol *s_superPerformList; +extern PyrSymbol *s_ugen, *s_outputproxy; +extern PyrSymbol *s_new, *s_ref; +extern PyrSymbol *s_synth, *s_spawn, *s_environment, *s_event; +extern PyrSymbol *s_interpreter; +extern PyrSymbol *s_finalizer; +extern PyrSymbol *s_awake; +extern PyrSymbol *s_appclock; +extern PyrSymbol *s_systemclock; + + +extern int gFormatElemSize[NUMOBJFORMATS]; +extern int gFormatElemCapc[NUMOBJFORMATS]; +extern int gFormatElemTag[NUMOBJFORMATS]; + +void dumpObject(PyrObject *obj); +void dumpObjectSlot(PyrSlot *slot); + +bool respondsTo(PyrSlot *slot, PyrSymbol *selector); +bool isSubclassOf(struct PyrClass *classobj, struct PyrClass *testclass); + +const int kFloatTagIndex = 12; +extern struct PyrClass* gTagClassTable[16]; + +inline struct PyrClass* classOfSlot(PyrSlot *slot) +{ + PyrClass *classobj; + int tag; + if (IsFloat(slot)) classobj = gTagClassTable[kFloatTagIndex]; + else if ((tag = slot->utag & 0xF) == 1) classobj = slot->uo->classptr; + else classobj = gTagClassTable[tag]; + + return classobj; +} + +typedef int (*ObjFuncPtr)(struct VMGlobals*, struct PyrObject*); + +void stringFromPyrString(PyrString *obj, char *str, int maxlength); +void pstringFromPyrString(PyrString *obj, unsigned char *str, int maxlength); + +int instVarOffset(char *classname, char *instvarname); +int classVarOffset(char *classname, char *classvarname, PyrClass** classobj); + +void fillSlots(PyrSlot* slot, int size, PyrSlot* fillslot); +void nilSlots(PyrSlot* slot, int size); +void zeroSlots(PyrSlot* slot, int size); + +int calcHash(PyrSlot *a); +int getIndexedFloat(struct PyrObject *obj, int index, float *value); +int getIndexedDouble(struct PyrObject *obj, int index, double *value); +void getIndexedSlot(struct PyrObject *obj, PyrSlot *a, int index); +int putIndexedSlot(struct VMGlobals *g, struct PyrObject *obj, PyrSlot *c, int index); +int putIndexedFloat(PyrObject *obj, double val, int index); + +inline int ARRAYMAXINDEXSIZE(PyrObjectHdr* obj) +{ + return (1L << obj->obj_sizeclass); +} + +inline int MAXINDEXSIZE(PyrObjectHdr* obj) +{ + return ((1L << obj->obj_sizeclass) * gFormatElemCapc[ obj->obj_format ]); +} + +void InstallFinalizer(VMGlobals* g, PyrObject *inObj, int slotIndex, ObjFuncPtr inFunc); + +///// + +#endif diff --git a/sc4pd/headers/lang/PyrObjectProto.h b/sc4pd/headers/lang/PyrObjectProto.h new file mode 100644 index 0000000..b66ecc2 --- /dev/null +++ b/sc4pd/headers/lang/PyrObjectProto.h @@ -0,0 +1,44 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _PYROBJPROTO_H_ +#define _PYROBJPROTO_H_ + +#include "PyrObject.h" + +void initSymbols(); +void initClasses(); +void buildClassTree(); + +void freePyrSlot(PyrSlot *slot); +void freePyrObject(PyrObject* obj); + +bool objAddIndexedSlot(PyrObject *obj, PyrSlot *slot); +bool objAddIndexedSymbol(PyrSymbolArray *obj, PyrSymbol *symbol); +bool objAddIndexedObject(PyrObject *obj, PyrObject *obj2); + +void CallStackSanity(struct VMGlobals *g, char* tagstr); +bool FrameSanity(struct PyrFrame *frame, char* tagstr); + +void dumpBadObject(PyrObject *obj); +void initRawRegistry(); + +#endif + diff --git a/sc4pd/headers/lang/PyrParseNode.h b/sc4pd/headers/lang/PyrParseNode.h new file mode 100644 index 0000000..cd6688c --- /dev/null +++ b/sc4pd/headers/lang/PyrParseNode.h @@ -0,0 +1,456 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _PYRPARSENODE_H_ +#define _PYRPARSENODE_H_ + +#include "PyrSlot.h" +#include "PyrKernel.h" +#include "ByteCodeArray.h" +#include "Opcodes.h" +#include "AdvancingAllocPool.h" + +extern AdvancingAllocPool gParseNodePool; + +#define ALLOCNODE(type) (type*)gParseNodePool.Alloc(sizeof(type)) +//#define FREENODE(node) if (node) (*parseNodeClasses[(node)->classno]->deleteFunc)(node); +#define DUMPNODE(node, level) if (node) (*parseNodeClasses[(node)->classno]->dumpFunc)((node),(level)); +#define COMPILENODE(node, result) (*parseNodeClasses[(node)->classno]->compileFunc)((node),(result)); + +typedef void (*PyrCompileNodeFunc)(void*, void*); +typedef void (*PyrDumpNodeFunc)(void*,int); + +typedef struct pyrparsenodeclass { + int type; + PyrCompileNodeFunc compileFunc; + PyrDumpNodeFunc dumpFunc; +} PyrParseNodeClass; + + +struct PyrParseNode { + struct PyrParseNode *next; + struct PyrParseNode *tail; + short lineno; + unsigned char charno, classno; +}; + + +struct PyrSlotNode : public PyrParseNode { + PyrSlot slot; +}; + +extern PyrParseNodeClass *pyrSlotNodeClass; + +struct PyrPushNameNode : public PyrParseNode { + PyrSlot varName; +} ; + +extern PyrParseNodeClass *pyrPushNameNodeClass; + +struct PyrClassExtNode : public PyrParseNode { + struct PyrSlotNode* className; + struct PyrMethodNode *methods; +} ; + +extern PyrParseNodeClass *pyrClassExtNodeClass; + +struct PyrClassNode : public PyrParseNode { + struct PyrSlotNode* className; + struct PyrSlotNode* superClassName; + struct PyrSlotNode* indexType; + struct PyrVarListNode *varlists; + struct PyrMethodNode *methods; + int varTally[3]; + int numsuperinstvars; +} ; + +extern PyrParseNodeClass *pyrClassNodeClass; + +struct PyrMethodNode : public PyrParseNode { + struct PyrSlotNode* methodName; + struct PyrSlotNode* primitiveName; + struct PyrArgListNode *arglist; + struct PyrVarListNode *varlist; + struct PyrParseNode *body; + int isClassMethod; // is class method? + bool extension; +} ; + +extern PyrParseNodeClass *pyrMethodNodeClass; + +struct PyrVarListNode : public PyrParseNode { + struct PyrVarDefNode *varDefs; + int flags; +} ; + +extern PyrParseNodeClass *pyrVarListNodeClass; + +struct PyrVarDefNode : public PyrParseNode { + struct PyrSlotNode* varName; + struct PyrLiteralNode* defVal; + int flags; +} ; + +extern PyrParseNodeClass *pyrVarDefNodeClass; + +struct PyrCallNode : public PyrParseNode { + struct PyrSlotNode* selector; + struct PyrParseNode *arglist; + struct PyrParseNode *keyarglist; +} ; + +extern PyrParseNodeClass *pyrCallNodeClass; + +struct PyrBinopCallNode : public PyrParseNode { + struct PyrSlotNode* selector; + struct PyrParseNode *arg1; + struct PyrParseNode *arg2; + struct PyrParseNode *arg3; +} ; + +extern PyrParseNodeClass *pyrBinopCallNodeClass; + +struct PyrDropNode : public PyrParseNode { + struct PyrParseNode *expr1; + struct PyrParseNode *expr2; +} ; + +extern PyrParseNodeClass *pyrDropNodeClass; + +struct PyrPushLitNode : public PyrParseNode { + PyrSlot literalSlot; +} ; + +extern PyrParseNodeClass *pyrPushLitNodeClass; + +struct PyrPushKeyArgNode : public PyrParseNode { + struct PyrSlotNode* selector; + struct PyrParseNode *expr; +} ; + +extern PyrParseNodeClass *pyrPushKeyArgNodeClass; + +struct PyrLiteralNode : public PyrParseNode { + PyrSlot literalSlot; +} ; + +extern PyrParseNodeClass *pyrLiteralNodeClass; + + +struct PyrReturnNode : public PyrParseNode { + struct PyrParseNode *expr; // if null, return self +} ; + +extern PyrParseNodeClass *pyrReturnNodeClass; + +struct PyrBlockReturnNode : public PyrParseNode { + struct PyrParseNode *expr; // if null, return self +} ; + +extern PyrParseNodeClass *pyrBlockReturnNodeClass; + + +struct PyrAssignNode : public PyrParseNode { + struct PyrSlotNode* varName; + struct PyrParseNode *expr; + bool drop; // allow drop +} ; + +extern PyrParseNodeClass *pyrAssignNodeClass; + +struct PyrSetterNode : public PyrParseNode { + struct PyrSlotNode* selector; + struct PyrParseNode *expr1; + struct PyrParseNode *expr2; + int flags; // is a var def ? +} ; + +extern PyrParseNodeClass *pyrSetterNodeClass; + +struct PyrMultiAssignNode : public PyrParseNode { + struct PyrMultiAssignVarListNode *varList; + struct PyrParseNode *expr; + bool drop; // allow drop +} ; + +extern PyrParseNodeClass *pyrMultiAssignNodeClass; + +struct PyrMultiAssignVarListNode : public PyrParseNode { + struct PyrSlotNode *varNames; + struct PyrSlotNode *rest; +} ; + +extern PyrParseNodeClass *pyrMultiAssignVarListNodeClass; + +struct PyrBlockNode : public PyrParseNode { + struct PyrArgListNode *arglist; + struct PyrVarListNode *varlist; + struct PyrParseNode *body; + bool isTopLevel; + int beginCharNo; +} ; + + +extern PyrParseNodeClass *pyrBlockNodeClass; + +struct PyrArgListNode : public PyrParseNode { + struct PyrVarDefNode *varDefs; + struct PyrSlotNode *rest; +} ; + +extern PyrParseNodeClass *pyrArgListNodeClass; + +struct PyrDynListNode : public PyrParseNode { + struct PyrParseNode *classname; + struct PyrParseNode *elems; +} ; + +extern PyrParseNodeClass *pyrDynListNodeClass; + +struct PyrDynDictNode : public PyrParseNode { + struct PyrParseNode *elems; +} ; + +extern PyrParseNodeClass *pyrDynDictNodeClass; + +struct PyrLitListNode : public PyrParseNode { + struct PyrParseNode *classname; + struct PyrParseNode *elems; +} ; + +extern PyrParseNodeClass *pyrLitListNodeClass; + +extern PyrParseNode* gRootParseNode; +extern int gParserResult; + +enum { rwPrivate=0, rwReadOnly=1, rwWriteOnly=2, rwReadWrite=3 }; + +enum { varInst, varClass, varTemp, varPseudo }; + +enum { + /* structural units */ + pn_ClassNode, + pn_ClassExtNode, + pn_MethodNode, + pn_BlockNode, + pn_SlotNode, + + /* variable declarations */ + pn_VarListNode, + pn_VarDefNode, + pn_DynDictNode, + pn_DynListNode, + pn_LitListNode, + + pn_StaticVarListNode, + pn_InstVarListNode, + pn_PoolVarListNode, + pn_ArgListNode, + pn_SlotDefNode, + + /* selectors */ + pn_LiteralNode, + + /* code */ + pn_PushLitNode, + pn_PushNameNode, + pn_PushKeyArgNode, + pn_CallNode, + pn_BinopCallNode, + pn_DropNode, + pn_AssignNode, + pn_MultiAssignNode, + pn_MultiAssignVarListNode, + pn_SetterNode, + + pn_ReturnNode, + pn_BlockReturnNode, + + pn_NumTypes +}; + +extern char *parseNodeFormat[pn_NumTypes]; +extern PyrParseNodeClass* parseNodeClasses[pn_NumTypes]; + + +void initParseNodes(); + +PyrParseNodeClass* newParseNodeClass(int type, PyrCompileNodeFunc compileFunc, + PyrDumpNodeFunc dumpFunc); + +PyrSlotNode* newPyrSlotNode(PyrSlot *slot); +PyrClassNode* newPyrClassNode(PyrSlotNode* className, PyrSlotNode* superClassName, + PyrVarListNode* varlists, PyrMethodNode* methods, PyrSlotNode* indexType); +PyrClassExtNode* newPyrClassExtNode(PyrSlotNode* className, PyrMethodNode* methods); +PyrMethodNode* newPyrMethodNode(PyrSlotNode* methodName, PyrSlotNode* primitiveName, + PyrArgListNode* arglist, PyrVarListNode *varlist, PyrParseNode* body, int isClassMethod); +PyrArgListNode* newPyrArgListNode(PyrVarDefNode* varDefs, PyrSlotNode* rest); +PyrVarListNode* newPyrVarListNode(PyrVarDefNode* vardefs, int flags); +PyrVarDefNode* newPyrVarDefNode(PyrSlotNode* varName, PyrLiteralNode* defVal, int flags); +PyrCallNode* newPyrCallNode(PyrSlotNode* selector, PyrParseNode* arglist, + PyrParseNode* keyarglist, PyrParseNode* blocklist); +PyrBinopCallNode* newPyrBinopCallNode(PyrSlotNode* selector, + PyrParseNode* arg1, PyrParseNode* arg2, PyrParseNode* arg3); +PyrDropNode* newPyrDropNode(PyrParseNode* expr1, PyrParseNode* expr2); +PyrPushKeyArgNode* newPyrPushKeyArgNode(PyrSlotNode* selector, PyrParseNode* expr); +PyrPushLitNode* newPyrPushLitNode(PyrSlotNode* literalSlot, PyrParseNode* literalObj); +PyrLiteralNode* newPyrLiteralNode(PyrSlotNode* literalSlot, PyrParseNode* literalObj); +PyrReturnNode* newPyrReturnNode(PyrParseNode* expr); +PyrBlockReturnNode* newPyrBlockReturnNode(); +PyrAssignNode* newPyrAssignNode(PyrSlotNode* varName, PyrParseNode* expr, int flags); +PyrSetterNode* newPyrSetterNode(PyrSlotNode* varName, + PyrParseNode* expr1, PyrParseNode* expr2); +PyrMultiAssignNode* newPyrMultiAssignNode(PyrMultiAssignVarListNode* varList, + PyrParseNode* expr, int flags); +PyrPushNameNode* newPyrPushNameNode(PyrSlotNode *slotNode); +PyrDynDictNode* newPyrDynDictNode(PyrParseNode *elems); +PyrDynListNode* newPyrDynListNode(PyrParseNode *classname, PyrParseNode *elems); +PyrLitListNode* newPyrLitListNode(PyrParseNode *classname, PyrParseNode *elems); +PyrMultiAssignVarListNode* newPyrMultiAssignVarListNode(PyrSlotNode* varNames, + PyrSlotNode* rest); +PyrBlockNode* newPyrBlockNode(PyrArgListNode *arglist, PyrVarListNode *varlist, PyrParseNode *body, bool isTopLevel); + +void compilePyrSlotNode(PyrSlotNode* node, void *result); +void compilePyrClassNode(PyrClassNode* node, void *result); +void compilePyrClassExtNode(PyrClassExtNode* node, void *result); +void compilePyrMethodNode(PyrMethodNode* node, void *result); +void compilePyrArgListNode(PyrArgListNode* node, void *result); +void compilePyrVarListNode(PyrVarListNode* node, void *result); +void compilePyrVarDefNode(PyrVarDefNode* node, void *result); +void compilePyrCallNode(PyrCallNode* node, void *result); +void compilePyrBinopCallNode(PyrBinopCallNode* node, void *result); +void compilePyrPushLitNode(PyrPushLitNode* node, void *result); +void compilePyrLiteralNode(PyrLiteralNode* node, void *result); +void compilePyrReturnNode(PyrReturnNode* node, void *result); +void compilePyrBlockReturnNode(PyrBlockReturnNode* node, void *result); +void compilePyrAssignNode(PyrAssignNode* node, void *result); +void compilePyrSetterNode(PyrSetterNode* node, void* result); +void compilePyrMultiAssignNode(PyrMultiAssignNode* node, void *result); +void compilePyrMultiAssignVarListNode(PyrMultiAssignVarListNode* node, void *result); +void compilePyrDynDictNode(PyrDynDictNode* node, void *result); +void compilePyrDynListNode(PyrDynListNode* node, void *result); +void compilePyrLitListNode(PyrLitListNode* node, void *result); +void compilePyrBlockNode(PyrBlockNode* node, void *result); +void compilePyrPushNameNode(PyrPushNameNode* node, void *result); +void compilePyrDropNode(PyrDropNode* node, void *result); +void compilePyrPushKeyArgNode(PyrPushKeyArgNode* node, void *result); + +void dumpPyrSlotNode(PyrSlotNode* node, int level); +void dumpPyrClassNode(PyrClassNode* node, int level); +void dumpPyrClassExtNode(PyrClassExtNode* node, int level); +void dumpPyrMethodNode(PyrMethodNode* node, int level); +void dumpPyrArgListNode(PyrArgListNode* node, int level); +void dumpPyrVarListNode(PyrVarListNode* node, int level); +void dumpPyrVarDefNode(PyrVarDefNode* node, int level); +void dumpPyrCallNode(PyrCallNode* node, int level); +void dumpPyrBinopCallNode(PyrBinopCallNode* node, int level); +void dumpPyrPushLitNode(PyrPushLitNode* node, int level); +void dumpPyrLiteralNode(PyrLiteralNode* node, int level); +void dumpPyrReturnNode(PyrReturnNode* node, int level); +void dumpPyrBlockReturnNode(PyrBlockReturnNode* node, int level); +void dumpPyrAssignNode(PyrAssignNode* node, int level); +void dumpPyrSetterNode(PyrSetterNode* node, int level); +void dumpPyrMultiAssignNode(PyrMultiAssignNode* node, int level); +void dumpPyrMultiAssignVarListNode(PyrMultiAssignVarListNode* node, int level); +void dumpPyrDynDictNode(PyrDynDictNode* node, int level); +void dumpPyrDynListNode(PyrDynListNode* node, int level); +void dumpPyrLitListNode(PyrLitListNode* node, int level); +void dumpPyrBlockNode(PyrBlockNode* node, int level); +void dumpPyrPushNameNode(PyrPushNameNode* node, int level); +void dumpPyrPushKeyArgNode(PyrPushKeyArgNode* node, int level); +void dumpPyrDropNode(PyrDropNode* node, int level); + +PyrClass* getNodeSuperclass(PyrClassNode *node); +void countNodeMethods(PyrClassNode* node, int *numClassMethods, int *numInstMethods); +void compileExtNodeMethods(PyrClassExtNode* node); +void countVarDefs(PyrClassNode* node); +bool compareVarDefs(PyrClassNode* node, PyrClass* classobj); +void recompileSubclasses(PyrClass* classobj); +void compileNodeMethods(PyrClassNode* node); +void fillClassPrototypes(PyrClassNode *node, PyrClass *classobj, PyrClass *superclassobj); + +int nodeListLength(PyrParseNode *node); +bool isSuperObjNode(PyrParseNode *node); +bool isThisObjNode(PyrParseNode *node); +int conjureSelectorIndex(PyrParseNode *node, PyrBlock* func, + bool isSuper, PyrSymbol *selector, int *selType); +int conjureLiteralSlotIndex(PyrParseNode *node, PyrBlock* func, PyrSlot *slot); +bool findVarName(PyrBlock* func, PyrClass **classobj, PyrSymbol *name, + int *varType, int *level, int *index, PyrBlock** tempfunc); +void countClassVarDefs(PyrClassNode* node, int *numClassMethods, int *numInstMethods); +void compileNodeList(PyrParseNode *node); +void dumpNodeList(PyrParseNode *node); +int compareCallArgs(PyrMethodNode* node, PyrCallNode *cnode, int *varIndex); + +bool findSpecialClassName(PyrSymbol *className, int *index); +int getIndexType(PyrClassNode *classnode); + +void compileIfMsg(PyrCallNode* node); +void compileWhileMsg(PyrCallNode* node); +void compileLoopMsg(PyrCallNode* node); +void compileAndMsg(PyrParseNode* arg1, PyrParseNode* arg2); +void compileOrMsg(PyrParseNode* arg1, PyrParseNode* arg2); + +void compilePushInt(int value); +void compileAssignVar(PyrParseNode *node, PyrSymbol* varName, bool drop); +void compilePushVar(PyrParseNode *node, PyrSymbol *varName); +bool isAnInlineableBlock(PyrParseNode *node); +bool isWhileTrue(PyrParseNode *node); +void installByteCodes(PyrBlock *block); + +ByteCodes compileSubExpression(PyrPushLitNode* litnode); +ByteCodes compileSubExpressionWithGoto(PyrPushLitNode* litnode, int branchLen); +//ByteCodes compileDefaultValue(int litIndex, int realExprLen); + +void initParser(); +void finiParser(); +void initParserPool(); +void freeParserPool(); + +void initSpecialSelectors(); +void initSpecialClasses(); + +void nodePostErrorLine(PyrParseNode* node); + +PyrParseNode* linkNextNode(PyrParseNode* a, PyrParseNode* b); +PyrParseNode* linkAfterHead(PyrParseNode* a, PyrParseNode* b); + +extern int compileErrors; + +extern long zzval; +extern PyrSymbol *ps_newlist; +extern PyrSymbol *gSpecialUnarySelectors[opNumUnarySelectors]; +extern PyrSymbol *gSpecialBinarySelectors[opNumBinarySelectors]; +extern PyrSymbol *gSpecialSelectors[opmNumSpecialSelectors]; +extern PyrSymbol* gSpecialClasses[op_NumSpecialClasses]; + +extern PyrClass *gCurrentClass; +extern PyrClass *gCurrentMetaClass; +extern PyrClass *gCompilingClass; +extern PyrMethod *gCompilingMethod; +extern PyrBlock *gCompilingBlock; + +/* + compiling + "inlining" of special arithmetic opcodes. + inlining of IF, WHILE, AND, OR +*/ + +#endif diff --git a/sc4pd/headers/lang/PyrPrimitive.h b/sc4pd/headers/lang/PyrPrimitive.h new file mode 100644 index 0000000..4afe653 --- /dev/null +++ b/sc4pd/headers/lang/PyrPrimitive.h @@ -0,0 +1,42 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +Functions for defining language primitives. + +*/ + +#ifndef _PYRPRIMITIVE_H_ +#define _PYRPRIMITIVE_H_ + +#include "PyrSlot.h" + +typedef int (*PrimitiveHandler)(struct VMGlobals *g, int numArgsPushed); +typedef int (*PrimitiveWithKeysHandler)(struct VMGlobals *g, int numArgsPushed, int numKeyArgsPushed); + +int nextPrimitiveIndex(); +int definePrimitive(int base, int index, char *name, PrimitiveHandler handler, int numArgs, int varArgs); +int definePrimitiveWithKeys(int base, int index, char *name, + PrimitiveHandler handler, PrimitiveWithKeysHandler keyhandler, + int numArgs, int varArgs); +int getPrimitiveNumArgs(int index); +PyrSymbol* getPrimitiveName(int index); + +#endif diff --git a/sc4pd/headers/lang/PyrPrimitiveProto.h b/sc4pd/headers/lang/PyrPrimitiveProto.h new file mode 100644 index 0000000..43464a4 --- /dev/null +++ b/sc4pd/headers/lang/PyrPrimitiveProto.h @@ -0,0 +1,81 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _PYRPRIMITIVEPROTO_H_ +#define _PYRPRIMITIVEPROTO_H_ + +#include "PyrPrimitive.h" + +int basicNew(VMGlobals *g, int numArgsPushed); +int basicNewClear(VMGlobals *g, int numArgsPushed); +int basicSwap(VMGlobals *g, int numArgsPushed); +int instVarAt(VMGlobals *g, int numArgsPushed); +int instVarPut(VMGlobals *g, int numArgsPushed); +int instVarSize(VMGlobals *g, int numArgsPushed); +int objectHash(VMGlobals *g, int numArgsPushed); +int objectClass(VMGlobals *g, int numArgsPushed); +int blockValue(VMGlobals *g, int numArgsPushed); +int blockValueWithKeys(VMGlobals *g, int allArgsPushed, int numKeyArgsPushed); +int blockValueArray(VMGlobals *g, int numArgsPushed); +int blockSpawn(VMGlobals *g, int numArgsPushed); + +int objectIsKindOf(VMGlobals *g, int numArgsPushed); +int objectIsMemberOf(VMGlobals *g, int numArgsPushed); +int objectDump(VMGlobals *g, int numArgsPushed); +int haltInterpreter(VMGlobals *g, int numArgsPushed); +int objectIdentical(VMGlobals *g, int numArgsPushed); +int objectNotIdentical(VMGlobals *g, int numArgsPushed); +int objectPerform(VMGlobals *g, int numArgsPushed); +int objectPerformList(VMGlobals *g, int numArgsPushed); +int objectPerformSelList(VMGlobals *g, int numArgsPushed); +int undefinedPrimitive(VMGlobals *g, int numArgsPushed); + +int prObjectString(VMGlobals *g, int numArgsPushed); +int prClassString(VMGlobals *g, int numArgsPushed); +int prSymbolString(VMGlobals *g, int numArgsPushed); +int prSymbolClass(VMGlobals *g, int numArgsPushed); +int prPostString(VMGlobals *g, int numArgsPushed); +int prPostLine(VMGlobals *g, int numArgsPushed); +int prFlushPostBuf(VMGlobals *g, int numArgsPushed); + +int prPrimitiveError(VMGlobals *g, int numArgsPushed); +int prPrimitiveErrorString(VMGlobals *g, int numArgsPushed); +int prDumpStack(VMGlobals *g, int numArgsPushed); +int prDebugger(VMGlobals *g, int numArgsPushed); +int prPrimName(VMGlobals *g, int numArgsPushed); +int prObjectShallowCopy(VMGlobals *g, int numArgsPushed); +int prObjectCopyRange(VMGlobals *g, int numArgsPushed); +int prObjectPointsTo(VMGlobals *g, int numArgsPushed); +int prObjectRespondsTo(VMGlobals *g, int numArgsPushed); + +int prCompileString(VMGlobals *g, int numArgsPushed); +int prDumpBackTrace(VMGlobals *g, int numArgsPushed); +int prDumpByteCodes(VMGlobals *g, int numArgsPushed); +int prAllClasses(VMGlobals *g, int numArgsPushed); +int prPostClassTree(VMGlobals *g, int numArgsPushed); + +void initPrimitiveTable(); +void growPrimitiveTable(int newsize); + +void initPrimitives(); +void doPrimitive(VMGlobals* g, struct PyrMethod* meth, int numArgsPushed); +void doPrimitiveWithKeys(VMGlobals* g, struct PyrMethod* meth, int allArgsPushed, int numKeysPushed); + +#endif diff --git a/sc4pd/headers/lang/PyrSched.h b/sc4pd/headers/lang/PyrSched.h new file mode 100644 index 0000000..5102582 --- /dev/null +++ b/sc4pd/headers/lang/PyrSched.h @@ -0,0 +1,58 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _PYRSCHED_H_ +#define _PYRSCHED_H_ + +#include "VMGlobals.h" +#include <pthread.h> + +extern pthread_mutex_t gLangMutex; + +void schedInit(); +void schedCleanup(); + +void schedRun(); +void schedStop(); +void schedClear(); + +double elapsedTime(); +int64 OSCTime(); + +int64 ElapsedTimeToOSC(double elapsed); +double OSCToElapsedTime(int64 oscTime); + +void syncOSCOffsetWithTimeOfDay(); +void doubleToTimespec(double secs, struct timespec *spec); + + +bool addheap(VMGlobals *g, PyrObject *heap, double schedtime, PyrSlot *task); +bool lookheap(PyrObject *heap, double *schedtime, PyrSlot *task) ; +bool getheap(PyrObject *heap, double *schedtime, PyrSlot *task) ; +void offsetheap(VMGlobals *g, PyrObject *heap, double offset) ; +void dumpheap(PyrObject *heap); + +const double kSecondsToOSC = 4294967296.; // pow(2,32)/1 +const double kMicrosToOSC = 4294.967296; // pow(2,32)/1e6 +const double kNanosToOSC = 4.294967296; // pow(2,32)/1e9 +const double kOSCtoSecs = 2.328306436538696e-10; // 1/pow(2,32) +const double kOSCtoNanos = 0.2328306436538696; // 1e9/pow(2,32) + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/lang/PyrSignal.h b/sc4pd/headers/lang/PyrSignal.h new file mode 100644 index 0000000..ee57b38 --- /dev/null +++ b/sc4pd/headers/lang/PyrSignal.h @@ -0,0 +1,417 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#pragma once on + +#include "PyrObject.h" +#include "GC.h" + +#define UNROLL 1 + +enum { + kSignalRate = 0, // index of rate slot + kSignalNextNode +}; + +#define FSINESIZE 8192. +#define SINESIZE 8192 +#define SINEMASK 8191 +#define VERY_BIG_FLOAT (1.e10) +extern float *sineCycle; +extern float *invSineCycle; +extern float *pmSineCycle; +extern double phaseToSineIndex; +extern double sineIndexToPhase; + +//#define FRACTABLESIZE 4096 +//#define FRACMASK 0x3FFC +//extern float *gFracTable; + + +PyrObject* newPyrSignal(VMGlobals *g, long size); + +#if 0 +#define UNROLL8_CODE(size,var,stmt) \ + endptr = var + size; \ + switch (size & 7) { \ + while (var < endptr) { \ + stmt; \ + case 7 : stmt; \ + case 6 : stmt; \ + case 5 : stmt; \ + case 4 : stmt; \ + case 3 : stmt; \ + case 2 : stmt; \ + case 1 : stmt; \ + case 0 : ; \ + } \ + } +#else +#define UNROLL8_CODE(size,var,stmt) \ + { int tempi, tempend; \ + tempend = size>>3; \ + for (tempi=0; tempi<tempend; ++tempi) { \ + stmt;stmt;stmt;stmt; \ + stmt;stmt;stmt;stmt; \ + } \ + tempend = size&7; \ + for (tempi=0; tempi<tempend; ++tempi) { \ + stmt; \ + } \ + } +#endif + +#if 0 +#define UNROLL4_CODE(size,var,stmt) \ + endptr = var + size; \ + switch (size & 3) { \ + while (var < endptr) { \ + stmt; \ + case 3 : stmt; \ + case 2 : stmt; \ + case 1 : stmt; \ + case 0 : ; \ + } \ + } +#else +#define UNROLL4_CODE(size,var,stmt) \ + { int tempi, tempend; \ + tempend = size>>2; \ + for (tempi=0; tempi<tempend; ++tempi) { \ + stmt;stmt;stmt;stmt; \ + } \ + tempend = size&3; \ + for (tempi=0; tempi<tempend; ++tempi) { \ + stmt; \ + } \ + } +#endif + +#if 0 +#define FILTER_LOOP(size,var,stmt,stmt2) \ + endptr = var + size; \ + switch (size & 3) { \ + case 0 : while (var < endptr) { \ + stmt; \ + case 3 : stmt; \ + case 2 : stmt; \ + case 1 : stmt; \ + stmt2; \ + } \ + } +#else +#define FILTER_LOOP(size,var,stmt,stmt2) \ + { int tempi, tempend; \ + tempend = size>>2; \ + for (tempi=0; tempi<tempend; ++tempi) { \ + stmt;stmt;stmt;stmt; \ + stmt2; \ + } \ + tempend = size&3; \ + for (tempi=0; tempi<tempend; ++tempi) { \ + stmt; \ + } \ + } +#endif + +#define UNROLL1_CODE(size,var,stmt) \ + { int tempi, tempend; \ + tempend = size; \ + for (tempi=0; tempi<tempend; ++tempi) { \ + stmt; \ + } \ + } + + +#if UNROLL == 8 +#define UNROLL_CODE UNROLL8_CODE +#elif UNROLL == 4 +#define UNROLL_CODE UNROLL4_CODE +#else +#define UNROLL_CODE UNROLL1_CODE +#endif + +#if 0 + +#define BINOP_LOOP1(OP) +#define BINOP_LOOP2(STMT1, STMT2, STMT3) + +#else + +#define BINOP_LOOP1(OP) \ + float *a, *b, *c, *endptr; \ + PyrObject *outc; \ + long size; \ + a = (float*)(ina->slots) - 1; \ + b = (float*)(inb->slots) - 1; \ + size = sc_min(ina->size, inb->size); \ + outc = newPyrSignal(g, size); \ + c = (float*)(outc->slots) - 1; \ + endptr = c + size; \ + switch (size & 3) { \ + while (c < endptr) { \ + *++c = *++a OP *++b; \ + case 3 : *++c = *++a OP *++b; \ + case 2 : *++c = *++a OP *++b; \ + case 1 : *++c = *++a OP *++b; \ + case 0 : ; \ + } \ + } \ + return outc; \ + + +#define BINOP_LOOP2(STMT1) \ + float *a, *b, *c, *endptr; \ + PyrObject *outc; \ + long size; \ + a = (float*)(ina->slots) - 1; \ + b = (float*)(inb->slots) - 1; \ + size = sc_min(ina->size, inb->size); \ + outc = newPyrSignal(g, size); \ + c = (float*)(outc->slots) - 1; \ + endptr = c + size; \ + switch (size & 3) { \ + while (c < endptr) { \ + STMT1; \ + case 3 :STMT1; \ + case 2 :STMT1; \ + case 1 :STMT1; \ + case 0 : ; \ + } \ + } \ + return outc; \ + +#endif + +/* + compound formulas : + amclip out = B<=0 ? 0 : A*B; // two quadrant amplitude modulation + ring1 out = A*(B+1) = A*B + A; // amplitude modulation of a by b. + ring2 out = A*B + A + B; // ring modulation plus both original signals + ring3 out = A*A*B; // ring modulation variant + ring4 out = A*A*B - A*B*B; // ring modulation variant + difsqr out = A*A - B*B; // difference of squares + sumsqr out = A*A + B*B; // sum of squares + sqrdif out = (A - B)^2 // square of the difference = a^2 + b^2 - 2ab + sqrsum out = (A + B)^2 // square of the sum = a^2 + b^2 + 2ab +*/ + +void signal_init_globs(); +PyrObject* signal_fill(PyrObject *outSignal, float inValue); +PyrObject* signal_scale(PyrObject *outSignal, float inValue); +PyrObject* signal_offset(PyrObject *outSignal, float inValue); +PyrObject* signal_scale_offset(PyrObject *outSignal, float mul, float add); +PyrObject* signal_mix(PyrObject* ina, PyrObject* inb, float start, float end, float slopeFactor); +PyrObject* signal_add_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_sub_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_mul_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_mul_ds_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_add_ds_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_sub_ds_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_ring1_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_ring2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_ring3_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_ring4_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_thresh_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_amclip_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_div_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_difsqr_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_sumsqr_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_sqrsum_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_sqrdif_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_add_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_sub_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_mul_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_ring1_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_ring2_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_ring3_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_ring4_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_thresh_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_amclip_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_div_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_difsqr_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_sumsqr_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_sqrsum_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_sqrdif_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_ring1_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_ring2_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_ring3_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_ring4_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_thresh_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_amclip_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_sub_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_div_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_difsqr_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_sumsqr_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_sqrsum_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_sqrdif_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_min_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_max_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_min_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_max_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_invert(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_recip(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_squared(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_cubed(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_abs(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_sign(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_negative(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_positive(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_strictly_positive(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_nyqring(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_clip_f(VMGlobals *g, PyrObject *inPyrSignal, float lo, float hi); +PyrObject* signal_clip_f_ds(PyrObject *inPyrSignal, float lo, float hi); +PyrObject* signal_clip_x(VMGlobals *g, PyrObject *ina, PyrObject *inb, PyrObject *inc); +PyrObject* signal_wrap_f(VMGlobals *g, PyrObject *inPyrSignal, float lo, float hi); +PyrObject* signal_wrap_x(VMGlobals *g, PyrObject *ina, PyrObject *inb, PyrObject *inc); +PyrObject* signal_fold_f(VMGlobals *g, PyrObject *inPyrSignal, float lo, float hi); +PyrObject* signal_fold_x(VMGlobals *g, PyrObject *ina, PyrObject *inb, PyrObject *inc); +PyrObject* signal_log(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_log2(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_log10(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_sin(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_cos(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_tan(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_sinh(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_cosh(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_tanh(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_asin(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_acos(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_atan(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_exp(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_sqrt(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_distort(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_distortneg(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_softclip(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_softclipneg(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_fsin(VMGlobals *g, PyrObject *inPyrSignal); +PyrObject* signal_poly3(VMGlobals *g, PyrObject *inPyrSignal, float a, float b, float c); +PyrObject* signal_poly3r(VMGlobals *g, PyrObject *inPyrSignal, + float a1, float a2, float b1, float b2, float c1, float c2, float slopeFactor); +PyrObject* signal_integrate(VMGlobals *g, PyrObject *inPyrSignal, float *ioSum); +PyrObject* signal_leakdc(VMGlobals *g, PyrObject *inPyrSignal, float *ioDC, float leakFactor); +PyrObject* signal_ampflw1(VMGlobals *g, PyrObject *inPyrSignal, float *ioAmp, float leak1); +PyrObject* signal_ampflw2(VMGlobals *g, PyrObject *inPyrSignal, float *ioAmp, float leak1); +PyrObject* signal_differentiate(VMGlobals *g, PyrObject *inPyrSignal, float *ioPrev); +PyrObject* signal_rotate(VMGlobals *g, PyrObject* ina, int rot); +PyrObject* signal_reverse_ds(PyrObject* ina); +PyrObject* signal_cat(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_insert(VMGlobals *g, PyrObject* ina, PyrObject* inb, long index); +PyrObject* signal_overdub(VMGlobals *g, PyrObject* ina, PyrObject* inb, long index); +PyrObject* signal_overwrite(VMGlobals *g, PyrObject* ina, PyrObject* inb, long index); +PyrObject* signal_cat3(VMGlobals *g, PyrObject* ina, PyrObject* inb, PyrObject* inc); +PyrObject* signal_linen(VMGlobals *g, PyrObject* ina, long atk, long dcy, float amp); +PyrObject* signal_linen2(VMGlobals *g, PyrObject* ina, long atk, long dcy, float amp, float midamp); +PyrObject* signal_writesplice(VMGlobals *g, PyrObject* outc, PyrObject* ina, PyrObject* inb, + long indexc, long indexa, long indexb, long fadelen, float midamp); +PyrObject* signal_splice(VMGlobals *g, PyrObject* ina, PyrObject* inb, + long indexa, long indexb, long fadelen, float midamp); + +PyrObject* signal_invert_ds(PyrObject *inPyrSignal); +PyrObject* signal_recip_ds(PyrObject *inPyrSignal); +PyrObject* signal_squared_ds(PyrObject *inPyrSignal); +PyrObject* signal_cubed_ds(PyrObject *inPyrSignal); +PyrObject* signal_abs_ds(PyrObject *inPyrSignal); +PyrObject* signal_sign_ds(PyrObject *inPyrSignal); +PyrObject* signal_negative_ds(PyrObject *inPyrSignal); +PyrObject* signal_positive_ds(PyrObject *inPyrSignal); +PyrObject* signal_strictly_positive_ds(PyrObject *inPyrSignal); +PyrObject* signal_nyqring_ds(PyrObject *inPyrSignal); + +PyrObject* signal_clipneg_ds(PyrObject *inPyrSignal); +PyrObject* signal_distort_ds(PyrObject *inPyrSignal); +PyrObject* signal_distortneg_ds(PyrObject *inPyrSignal); +PyrObject* signal_softclip_ds(PyrObject *inPyrSignal); +PyrObject* signal_softclipneg_ds(PyrObject *inPyrSignal); +PyrObject* signal_fsin_ds(PyrObject *inPyrSignal); + +PyrObject* signal_log_ds(PyrObject *inPyrSignal); +PyrObject* signal_log2_ds(PyrObject *inPyrSignal); +PyrObject* signal_log10_ds(PyrObject *inPyrSignal); +PyrObject* signal_sin_ds(PyrObject *inPyrSignal); +PyrObject* signal_cos_ds(PyrObject *inPyrSignal); +PyrObject* signal_tan_ds(PyrObject *inPyrSignal); +PyrObject* signal_sinh_ds(PyrObject *inPyrSignal); +PyrObject* signal_cosh_ds(PyrObject *inPyrSignal); +PyrObject* signal_tanh_ds(PyrObject *inPyrSignal); +PyrObject* signal_asin_ds(PyrObject *inPyrSignal); +PyrObject* signal_acos_ds(PyrObject *inPyrSignal); +PyrObject* signal_atan_ds(PyrObject *inPyrSignal); +PyrObject* signal_exp_ds(PyrObject *inPyrSignal); +PyrObject* signal_sqrt_ds(PyrObject *inPyrSignal); + +float signal_findpeak(PyrObject *inPyrSignal); +PyrObject* signal_normalize(PyrObject *inPyrSignal); +PyrObject* signal_normalize_transfer_fn(PyrObject *inPyrSignal); +float signal_integral(PyrObject *inPyrSignal); +PyrObject* signal_combself(VMGlobals *g, PyrObject* ina, long rot); +PyrObject* signal_bilinen(VMGlobals *g, PyrObject* ina, long atk, long dcy, float amp, float midamp); +PyrObject* signal_lace2(VMGlobals *g, PyrObject* ina, PyrObject* inb); +void signal_unlace2(VMGlobals *g, PyrObject* ina, PyrObject** outb, PyrObject** outc); +void signal_convolve(VMGlobals *g, PyrObject* ina, PyrObject* ir, PyrObject* previn, long *ppos); +PyrObject* signal_thumbnail(VMGlobals *g, PyrObject* ina, long startpos, long length, int binsize); + +PyrObject* signal_scaleneg_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_scaleneg_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_scaleneg_fx(VMGlobals *g, float ina, PyrObject* inb); + +PyrObject* signal_clip2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_clip2_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_clip2_fx(VMGlobals *g, float ina, PyrObject* inb); + +PyrObject* signal_fold2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_fold2_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_fold2_fx(VMGlobals *g, float ina, PyrObject* inb); + +PyrObject* signal_wrap2_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_wrap2_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_wrap2_fx(VMGlobals *g, float ina, PyrObject* inb); + +PyrObject* signal_excess_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); +PyrObject* signal_excess_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_excess_fx(VMGlobals *g, float ina, PyrObject* inb); + +PyrObject* signal_absdif_fx(VMGlobals *g, float ina, PyrObject* inb); +PyrObject* signal_absdif_xf(VMGlobals *g, PyrObject* ina, float inb); +PyrObject* signal_absdif_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); + +bool signal_equal_xf(VMGlobals *g, PyrObject* ina, float inb); +bool signal_equal_xx(VMGlobals *g, PyrObject* ina, PyrObject* inb); + +void signal_get_bounds(PyrObject* ina, float *ominval, float *omaxval); + +void signal_smooth_ds(PyrObject* inPyrSignal); +void signal_hanning_ds(PyrObject* inPyrSignal); +void signal_welch_ds(PyrObject* inPyrSignal); +void signal_parzen_ds(PyrObject* inPyrSignal); + +PyrObject* signal_normalize_range(PyrObject* ina, long start, long end); +PyrObject* signal_zero_range(PyrObject* ina, long start, long end); +PyrObject* signal_invert_range(PyrObject* ina, long start, long end); +PyrObject* signal_reverse_range(PyrObject* ina, long start, long end); +PyrObject* signal_fade_in(PyrObject* ina, long start, long end); +PyrObject* signal_fade_out(PyrObject* ina, long start, long end); +PyrObject* signal_abs_range(PyrObject* ina, long start, long end); +PyrObject* signal_squared_range(PyrObject* ina, long start, long end); +PyrObject* signal_cubed_range(PyrObject* ina, long start, long end); +PyrObject* signal_distort_range(PyrObject* ina, long start, long end); + +PyrObject* signal_fade_range(PyrObject* ina, long start, long end, float lvl0, float lvl1); diff --git a/sc4pd/headers/lang/PyrSignalPrim.h b/sc4pd/headers/lang/PyrSignalPrim.h new file mode 100644 index 0000000..bea68ca --- /dev/null +++ b/sc4pd/headers/lang/PyrSignalPrim.h @@ -0,0 +1,56 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _PYRSIGNALPRIM_H_ +#define _PYRSIGNALPRIM_H_ + +extern PyrSymbol *s_wavetable; +extern struct PyrClass *class_wavetable; + +void initSignalPrimitives(); + +int prSignalCat(VMGlobals *g, int numArgsPushed); +int prSignalFill(VMGlobals *g, int numArgsPushed); +int prSignalRamp(VMGlobals *g, int numArgsPushed); +int prSignalScale(VMGlobals *g, int numArgsPushed); +int prSignalOffset(VMGlobals *g, int numArgsPushed); +int prSignalString(VMGlobals *g, int numArgsPushed); + +int prSignalPeak(VMGlobals *g, int numArgsPushed); +int prSignalNormalize(VMGlobals *g, int numArgsPushed); +int prSignalNormalizeTransferFn(VMGlobals *g, int numArgsPushed); +int prSignalIntegral(VMGlobals *g, int numArgsPushed); + +int prSignalOverDub(VMGlobals *g, int numArgsPushed); +int prSignalOverWrite(VMGlobals *g, int numArgsPushed); +int prSignalFade(VMGlobals *g, int numArgsPushed); +int prSignalAddHarmonic(VMGlobals *g, int numArgsPushed); +int prSignalAsWavetable(VMGlobals *g, int numArgsPushed); +int prWavetableAsSignal(VMGlobals *g, int numArgsPushed); + +int prSignalInvert(VMGlobals *g, int numArgsPushed); +int prSignalReverse(VMGlobals *g, int numArgsPushed); +int prSignalRotate(VMGlobals *g, int numArgsPushed); + +void signalAsWavetable(float *signal, float *wavetable, int size); +void wavetableAsSignal(float *wavetable, float *signal, int size); + +#endif diff --git a/sc4pd/headers/lang/PyrSlot.h b/sc4pd/headers/lang/PyrSlot.h new file mode 100644 index 0000000..78bcd12 --- /dev/null +++ b/sc4pd/headers/lang/PyrSlot.h @@ -0,0 +1,286 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +PyrSlot is a value holder for SC variables. +A PyrSlot is an 8-byte value which is either a double precision float or a +32-bit tag plus a 32-bit value. + +*/ + +#ifndef _PYRSLOT_H_ +#define _PYRSLOT_H_ + +#include "SC_Endian.h" +#include "PyrSymbol.h" + +/* + Pyrite slots are the size of an 8 byte double. If the upper bits + indicate that the double is a 'Not-A-Number' then the upper 32 + bits are used as a tag to indicate one of a number of other types + whose data is in the lower 32 bits. +*/ + +/* some DSPs like the TIC32 do not support 8 byte doubles */ +/* on such CPUs, set DOUBLESLOTS to zero */ + +#define DOUBLESLOTS 1 + +/* use the high order bits of an IEEE double NaN as a tag */ +enum { + tagObj = 0x7FF90001, + tagHFrame = 0x7FF90002, + tagSFrame = 0x7FF90003, + tagInt = 0x7FF90004, + tagSym = 0x7FF90005, + tagChar = 0x7FF90006, + tagNil = 0x7FF90007, // nil, false, and true are indicated by the tag alone. + tagFalse = 0x7FF90008, // the lower 32 bits are zero. + tagTrue = 0x7FF90009, + tagInf = 0x7FF9000A, + tagPtr = 0x7FF9000B, + /* anything else is a double */ + tagUnused = 0x7FF9000E + + +#if !DOUBLESLOTS + ,tagFloat = 0x7FF9000F /* used only to initialized 4 byte float tags, never compared with */ +#endif +}; + +struct RGBColor8 { + unsigned char c[4]; +}; + +typedef union pyrslot { + double f; + struct { +#if BYTE_ORDER == BIG_ENDIAN + int tag; +#endif // BIG_ENDIAN + union { + int c; /* char */ + int i; + float f; + void *ptr; + struct RGBColor8 r; + struct PyrObject *o; + PyrSymbol *s; + struct PyrMethod *om; + struct PyrBlock *oblk; + struct PyrClass *oc; + struct PyrFrame *of; + struct PyrList *ol; + struct PyrString *os; + struct PyrInt8Array *ob; + struct PyrDoubleArray *od; + struct PyrSymbolArray *osym; + struct PyrParseNode *opn; + struct PyrProcess *op; + struct PyrThread *ot; + struct PyrInterpreter *oi; + struct PyrPlug *plug; + } u; +#if BYTE_ORDER == LITTLE_ENDIAN + // need to swap on intel <sk> + int tag; +#endif // LITTLE_ENDIAN + } s; +} PyrSlot; + +/* + these are some defines to make accessing the structure less verbose. + obviously it polutes the namespace of identifiers beginning with 'u'. +*/ +#define utag s.tag +//int +#define ui s.u.i +//PyrObject +#define uo s.u.o +//PyrSymbol +#define us s.u.s +//RGBColor8 +#define ur s.u.r +#define uc s.u.c +#define uoc s.u.oc +#define uof s.u.of +#define uol s.u.ol +#define uod s.u.od +#define uob s.u.ob +#define uop s.u.op +#define uoi s.u.oi +#define uod s.u.od +//string +#define uos s.u.os +#define uot s.u.ot +//method +#define uom s.u.om +//symbol array +#define uosym s.u.osym +#define uoblk s.u.oblk +#define uopn s.u.opn +#define uptr s.u.ptr +#define uplug s.u.plug + +#if DOUBLESLOTS +#define uf f +#else +#define uf s.u.f +#endif + +#define ucopy f + +/* + Note that on the PowerPC, the fastest way to copy a slot is to + copy the double field, not the struct. +*/ + +/* some macros for setting values of slots */ +inline void SetInt(PyrSlot* slot, int val) { (slot)->utag = tagInt; (slot)->ui = (val); } +inline void SetObject(PyrSlot* slot, void* val) { (slot)->utag = tagObj; (slot)->uo = (PyrObject*)(val); } +inline void SetSymbol(PyrSlot* slot, PyrSymbol *val) { (slot)->utag = tagSym; (slot)->us = (val); } +inline void SetChar(PyrSlot* slot, char val) { (slot)->utag = tagChar; (slot)->uc = (val); } +inline void SetPtr(PyrSlot* slot, void* val) { (slot)->utag = tagPtr; (slot)->uptr = (void*)(val); } +inline void SetObjectOrNil(PyrSlot* slot, PyrObject* val) +{ + if (val) { + (slot)->utag = tagObj; + (slot)->uo = (val); + } else { + (slot)->utag = tagNil; + (slot)->ui = 0; + } +} + +inline void SetTrue(PyrSlot* slot) { (slot)->utag = tagTrue; (slot)->ui = 0; } +inline void SetFalse(PyrSlot* slot) { (slot)->utag = tagFalse; (slot)->ui = 0; } +inline void SetBool(PyrSlot* slot, bool test) { (slot)->utag = ((test) ? tagTrue : tagFalse); (slot)->ui = 0; } +inline void SetNil(PyrSlot* slot) { (slot)->utag = tagNil; (slot)->ui = 0; } +inline void SetInf(PyrSlot* slot) { (slot)->utag = tagInf; (slot)->ui = 0; } + +#if DOUBLESLOTS +inline void SetFloat(PyrSlot* slot, double val) { (slot)->uf = (val); } +#else +inline void SetFloat(PyrSlot* slot, double val) { (slot)->utag = s_float; (slot)->uf = (val); } +#endif + +inline bool IsObj(PyrSlot* slot) { return ((slot)->utag == tagObj); } +inline bool NotObj(PyrSlot* slot) { return ((slot)->utag != tagObj); } + +inline bool IsNil(PyrSlot* slot) { return ((slot)->utag == tagNil); } +inline bool NotNil(PyrSlot* slot) { return ((slot)->utag != tagNil); } + +inline bool IsFalse(PyrSlot* slot) { return ((slot)->utag == tagFalse); } +inline bool IsTrue(PyrSlot* slot) { return ((slot)->utag == tagTrue); } + +inline bool SlotEq(PyrSlot* a, PyrSlot* b) { return ((a)->ui == (b)->ui && (a)->utag == (b)->utag); } + +inline bool IsSym(PyrSlot* slot) { return ((slot)->utag == tagSym); } +inline bool NotSym(PyrSlot* slot) { return ((slot)->utag != tagSym); } + +inline bool IsInt(PyrSlot* slot) { return ((slot)->utag == tagInt); } +inline bool NotInt(PyrSlot* slot) { return ((slot)->utag != tagInt); } + +inline bool IsFloatTag(int tag) { return ((tag & 0xFFFFFFF0) != 0x7FF90000); } +inline bool IsFloat(PyrSlot* slot) { return (((slot)->utag & 0xFFFFFFF0) != 0x7FF90000); } +inline bool NotFloat(PyrSlot* slot) { return (((slot)->utag & 0xFFFFFFF0) == 0x7FF90000); } + +inline bool IsInf(PyrSlot* slot) { return ((slot)->utag == tagInf); } +inline bool IsPtr(PyrSlot* slot) { return ((slot)->utag == tagPtr); } + +inline bool IsFrame(PyrSlot* slot) { return ((slot)->utag == tagHFrame || (slot)->utag == tagSFrame); } + + +void dumpPyrSlot(PyrSlot* slot); +void slotString(PyrSlot *slot, char *str); +void slotOneWord(PyrSlot *slot, char *str); +bool postString(PyrSlot *slot, char *str); +char *slotSymString(PyrSlot* slot); +int asCompileString(PyrSlot *slot, char *str); + +int slotIntVal(PyrSlot* slot, int *value); +int slotFloatVal(PyrSlot* slot, float *value); +int slotDoubleVal(PyrSlot *slot, double *value); +int slotStrVal(PyrSlot *slot, char *str, int maxlen); +int slotPStrVal(PyrSlot *slot, unsigned char *str); +int slotSymbolVal(PyrSlot *slot, PyrSymbol **symbol); + +extern PyrSlot o_nil, o_true, o_false, o_inf; +extern PyrSlot o_pi, o_twopi; +extern PyrSlot o_fhalf, o_fnegone, o_fzero, o_fone, o_ftwo; +extern PyrSlot o_negtwo, o_negone, o_zero, o_one, o_two; +extern PyrSlot o_emptyarray, o_onenilarray, o_argnamethis; + +extern PyrSymbol *s_object; // "Object" +extern PyrSymbol *s_this; // "this" +extern PyrSymbol *s_super; // "super" + +inline int slotFloatVal(PyrSlot *slot, float *value) +{ + if (IsFloat(slot)) { + *value = slot->uf; + return errNone; + } else if (IsInt(slot)) { + *value = slot->ui; + return errNone; + } + return errWrongType; +} + +inline int slotIntVal(PyrSlot *slot, int *value) +{ + if (IsInt(slot)) { + *value = slot->ui; + return errNone; + } else if (IsFloat(slot)) { + *value = (int)slot->uf; + return errNone; + } + return errWrongType; +} + +inline int slotDoubleVal(PyrSlot *slot, double *value) +{ + if (IsFloat(slot)) { + *value = slot->uf; + return errNone; + } else if (IsInt(slot)) { + *value = slot->ui; + return errNone; + } + return errWrongType; +} + +inline int slotSymbolVal(PyrSlot *slot, PyrSymbol **symbol) +{ + if (!IsSym(slot)) return errWrongType; + *symbol = slot->us; + return errNone; +} + +inline void slotCopy(PyrSlot *dst, PyrSlot *src, int num) +{ + double *dstp = (double*)dst - 1; + double *srcp = (double*)src - 1; + for (int i=0;i<num;++i) { *++dstp = *++srcp; } +} + + +#endif diff --git a/sc4pd/headers/lang/PyrSymbol.h b/sc4pd/headers/lang/PyrSymbol.h new file mode 100644 index 0000000..621f7c2 --- /dev/null +++ b/sc4pd/headers/lang/PyrSymbol.h @@ -0,0 +1,59 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +A PyrSymbol is a unique string that resides in a global hash table. + +*/ + +#ifndef _PYRSYMBOL_H_ +#define _PYRSYMBOL_H_ + +#include "SCBase.h" + +struct PyrSymbol { + char *name; + long hash; + short specialIndex; + uint8 flags; + uint8 length; + union { + long index; // index in row table or primitive table + struct PyrClass *classobj; // pointer to class with this name. + } u; + struct classdep *classdep; +}; + +enum { + sym_Selector = 1, + sym_Class = 2, + sym_Compiled = 4, + sym_Called = 8, + sym_Primitive = 16, + sym_Setter = 32, + sym_MetaClass = 64, + sym_Filename = 128 +}; + +PyrSymbol* getsym(const char *name); +PyrSymbol* getmetasym(const char *name); +PyrSymbol* findsym(const char *name); + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/lang/PyrSymbolTable.h b/sc4pd/headers/lang/PyrSymbolTable.h new file mode 100644 index 0000000..7cc03cb --- /dev/null +++ b/sc4pd/headers/lang/PyrSymbolTable.h @@ -0,0 +1,78 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SymbolTable_ +#define _SymbolTable_ + +#include "PyrSymbol.h" +#include "AdvancingAllocPool.h" + +#define STRINGCHUNK 32000 +#define SYMBOLCHUNK 32000 + +class SymbolSpace +{ +public: + SymbolSpace(AllocPool *inPool); + PyrSymbol* NewSymbol(const char *inName, int inHash, int inLength); + +private: + AllocPool *mPool; + AdvancingAllocPool mStringPool; + AdvancingAllocPool mSymbolPool; +}; + +class SymbolTable +{ +public: + + SymbolTable(AllocPool *inPool, int inSize); + + void CopyFrom(SymbolTable& inTable); + + int NumItems() { return mNumItems; } + int TableSize() { return mMaxItems; } + PyrSymbol* Get(int inIndex) { return mTable[inIndex]; } + + void CheckSymbols(); + +private: + friend PyrSymbol* getsym(const char *name); + friend PyrSymbol* findsym(const char *name); + + PyrSymbol* Find(const char *inName); + PyrSymbol* Make(const char *inName); + PyrSymbol* MakeNew(const char *inName, int inHash, int inLength); + + int StrHash(const char *inName, int *outLength); + void AllocTable(); + void Grow(); + PyrSymbol* Find(const char *inName, int inHash); + void Add(PyrSymbol* inSymbol); + void Rehash(PyrSymbol** inTable, int inSize); + void MakeEmpty(); + + AllocPool *mPool; + SymbolSpace mSpace; + PyrSymbol **mTable; + int mNumItems, mMaxItems, mMask; +}; + +#endif diff --git a/sc4pd/headers/lang/ReadWriteMacros.h b/sc4pd/headers/lang/ReadWriteMacros.h new file mode 100644 index 0000000..2117fb6 --- /dev/null +++ b/sc4pd/headers/lang/ReadWriteMacros.h @@ -0,0 +1,336 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _ReadWriteMacros_ +#define _ReadWriteMacros_ + +#include "SC_Types.h" +#include "SC_Endian.h" +#include <stdio.h> +#include <string.h> + +template <class T> +class SC_IOStream +{ +protected: + T s; +public: + SC_IOStream() : s(0) {} + SC_IOStream(T inStream) : s(inStream) {} + + void SetStream(T inStream) { s = inStream; } + T GetStream() { return s; } + + // core routines + void readData(char *data, int size); + uint8 readUInt8(); + + void writeData(char *data, int size); + void writeUInt8(uint8 inInt); + + // built using core routines + void writeInt8(int8 inInt) + { + writeUInt8((uint8)inInt); + } + + void writeInt16_be(int16 inInt) + { + writeUInt8((uint8)(inInt >> 8)); + writeUInt8(inInt); + } + + void writeInt16_le(int16 inInt) + { + writeUInt8((uint8)inInt); + writeUInt8((uint8)(inInt >> 8)); + } + + void writeInt32_be(int32 inInt) + { + writeUInt8((uint8)(inInt >> 24)); + writeUInt8((uint8)(inInt >> 16)); + writeUInt8((uint8)(inInt >> 8)); + writeUInt8((uint8)inInt); + } + + void writeInt32_le(int32 inInt) + { + writeUInt8((uint8)inInt); + writeUInt8((uint8)(inInt >> 8)); + writeUInt8((uint8)(inInt >> 16)); + writeUInt8((uint8)(inInt >> 24)); + } + +#if BYTE_ORDER == BIG_ENDIAN + void writeFloat_be(float inFloat) +#else + void writeFloat_le(float inFloat) +#endif + { + union { + float f; + uint8 c[4]; + } u; + u.f = inFloat; + writeUInt8(u.c[0]); + writeUInt8(u.c[1]); + writeUInt8(u.c[2]); + writeUInt8(u.c[3]); + } + +#if BYTE_ORDER == BIG_ENDIAN + void writeFloat_le(float inFloat) +#else + void writeFloat_be(float inFloat) +#endif + { + union { + float f; + uint8 c[4]; + } u; + u.f = inFloat; + writeUInt8(u.c[3]); + writeUInt8(u.c[2]); + writeUInt8(u.c[1]); + writeUInt8(u.c[0]); + } + + +#if BYTE_ORDER == BIG_ENDIAN + void writeDouble_be(double inDouble) +#else + void writeDouble_le(double inDouble) +#endif + { + union { + double f; + uint8 c[8]; + } u; + u.f = inDouble; + writeUInt8(u.c[0]); + writeUInt8(u.c[1]); + writeUInt8(u.c[2]); + writeUInt8(u.c[3]); + writeUInt8(u.c[4]); + writeUInt8(u.c[5]); + writeUInt8(u.c[6]); + writeUInt8(u.c[7]); + } + +#if BYTE_ORDER == BIG_ENDIAN + void writeDouble_le(double inDouble) +#else + void writeDouble_be(double inDouble) +#endif + { + union { + double f; + uint8 c[8]; + } u; + u.f = inDouble; + writeUInt8(u.c[7]); + writeUInt8(u.c[6]); + writeUInt8(u.c[5]); + writeUInt8(u.c[4]); + writeUInt8(u.c[3]); + writeUInt8(u.c[2]); + writeUInt8(u.c[1]); + writeUInt8(u.c[0]); + } + + + int8 readInt8() + { + return (int8)readUInt8(); + } + + int16 readInt16_be() + { + uint8 a = readUInt8(); + uint8 b = readUInt8(); + return (int16)((a << 8) | b); + } + + int16 readInt16_le() + { + uint8 a = readUInt8(); + uint8 b = readUInt8(); + return (int16)((b << 8) | a); + } + + int32 readInt32_be() + { + uint8 a = readUInt8(); + uint8 b = readUInt8(); + uint8 c = readUInt8(); + uint8 d = readUInt8(); + return (int32)((a << 24) | (b << 16) | (c << 8) | d); + } + + int32 readInt32_le() + { + uint8 a = readUInt8(); + uint8 b = readUInt8(); + uint8 c = readUInt8(); + uint8 d = readUInt8(); + return (int32)((d << 24) | (c << 16) | (b << 8) | a); + } + +#if BYTE_ORDER == BIG_ENDIAN + float readFloat_be() +#else + float readFloat_le() +#endif + { + union { + float f; + uint8 c[4]; + } u; + u.c[0] = readUInt8(); + u.c[1] = readUInt8(); + u.c[2] = readUInt8(); + u.c[3] = readUInt8(); + return u.f; + } + +#if BYTE_ORDER == BIG_ENDIAN + float readFloat_le() +#else + float readFloat_be() +#endif + { + union { + float f; + uint8 c[4]; + } u; + u.c[3] = readUInt8(); + u.c[2] = readUInt8(); + u.c[1] = readUInt8(); + u.c[0] = readUInt8(); + return u.f; + } + + +#if BYTE_ORDER == BIG_ENDIAN + double readDouble_be() +#else + double readDouble_le() +#endif + { + union { + double f; + uint8 c[8]; + } u; + u.c[0] = readUInt8(); + u.c[1] = readUInt8(); + u.c[2] = readUInt8(); + u.c[3] = readUInt8(); + u.c[4] = readUInt8(); + u.c[5] = readUInt8(); + u.c[6] = readUInt8(); + u.c[7] = readUInt8(); + return u.f; + } + +#if BYTE_ORDER == BIG_ENDIAN + double readDouble_le() +#else + double readDouble_be() +#endif + { + union { + double f; + uint8 c[8]; + } u; + u.c[7] = readUInt8(); + u.c[6] = readUInt8(); + u.c[5] = readUInt8(); + u.c[4] = readUInt8(); + u.c[3] = readUInt8(); + u.c[2] = readUInt8(); + u.c[1] = readUInt8(); + u.c[0] = readUInt8(); + return u.f; + } + + void readSymbol(char *outString) + { + int length = readUInt8(); + readData(outString, length); + outString[length] = 0; + } + + void writeSymbol(char *inString) + { + int32 length = strlen(inString); + writeUInt8((uint8)length); + writeData(inString, length); + } +}; + + +// core routines +inline void SC_IOStream<FILE*>::readData(char *data, int size) +{ + fread(data, 1, size, s); +} + +inline uint8 SC_IOStream<FILE*>::readUInt8() +{ + return (uint8)fgetc(s); +} + +inline void SC_IOStream<FILE*>::writeData(char *data, int size) +{ + fwrite(data, 1, size, s); +} + +inline void SC_IOStream<FILE*>::writeUInt8(uint8 inInt) +{ + fputc(inInt, s); +} + +// core routines +inline void SC_IOStream<char*>::readData(char *data, int size) +{ + memcpy(data, s, size); + s += size; +} +inline uint8 SC_IOStream<char*>::readUInt8() +{ + return (uint8)*s++; +} + +inline void SC_IOStream<char*>::writeData(char *data, int size) +{ + memcpy(s, data, size); + s += size; +} + +inline void SC_IOStream<char*>::writeUInt8(uint8 inInt) +{ + *s++ = (inInt & 255); +} + + +#endif + diff --git a/sc4pd/headers/lang/SCBase.h b/sc4pd/headers/lang/SCBase.h new file mode 100644 index 0000000..10fe0ed --- /dev/null +++ b/sc4pd/headers/lang/SCBase.h @@ -0,0 +1,68 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +Contains the most common definitions. + +*/ + +#ifndef _SCBASE_ +#define _SCBASE_ + +#include <limits.h> +#include <stdio.h> + +#include "SC_BoundsMacros.h" +#include "SC_Types.h" +#include "PyrErrors.h" +#include "AllocPools.h" + +void postfl(const char *fmt, ...); +void post(const char *fmt, ...); +void error(const char *fmt, ...); +void postText(const char *text, long length); +void postChar(char c); +void flushPostBuf(); +void setPostFile(FILE *file); // If file is not NULL, causes all posted text to also be written to the file. + +void debugf(char *fmt, ...); +void pprintf(unsigned char *str, char *fmt, ...); + +#pragma export on + +extern "C" { +void schedInit(); +void init_OSC(int port); +bool pyr_init_mem_pools(int runtime_space, int runtime_grow); + +void schedRun(); +void schedStop(); +bool compileLibrary(); +void runLibrary(struct PyrSymbol* selector); +struct VMGlobals* scGlobals(); +void runInterpreter(struct VMGlobals *g, struct PyrSymbol *selector, int numArgsPushed); + +struct PyrSymbol* getsym(const char *inName); +struct PyrSymbol* findsym(const char *name); +} + +#pragma export off + +#endif diff --git a/sc4pd/headers/lang/SC_ComPort.h b/sc4pd/headers/lang/SC_ComPort.h new file mode 100644 index 0000000..bdbeabc --- /dev/null +++ b/sc4pd/headers/lang/SC_ComPort.h @@ -0,0 +1,118 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_ComPort_ +#define _SC_ComPort_ + +#include <sys/types.h> +#include <sys/socket.h> +#include "SC_Msg.h" +#include "SC_Sem.h" + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_CmdPort +{ +protected: + pthread_t mThread; + + void Start(); + virtual ReplyFunc GetReplyFunc()=0; +public: + SC_CmdPort(); + + virtual void* Run()=0; +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_ComPort : public SC_CmdPort +{ +protected: + int mPortNum; + int mSocket; + struct sockaddr_in mBindSockAddr; + +public: + SC_ComPort(int inPortNum); + virtual ~SC_ComPort(); + + int Socket() { return mSocket; } + + int PortNum() const { return mPortNum; } +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_UdpInPort : public SC_ComPort +{ +protected: + struct sockaddr_in mReplySockAddr; + virtual ReplyFunc GetReplyFunc(); + +public: + SC_UdpInPort(int inPortNum); + ~SC_UdpInPort(); + + int PortNum() const { return mPortNum; } + + void* Run(); +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_TcpInPort : public SC_ComPort +{ + SC_Semaphore mConnectionAvailable; + int mBacklog; + +protected: + virtual ReplyFunc GetReplyFunc(); + +public: + SC_TcpInPort(int inPortNum, int inMaxConnections, int inBacklog); + + virtual void* Run(); + + void ConnectionTerminated(); +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_TcpConnectionPort : public SC_ComPort +{ + SC_TcpInPort *mParent; + +protected: + virtual ReplyFunc GetReplyFunc(); + +public: + SC_TcpConnectionPort(SC_TcpInPort *inParent, int inSocket); + virtual ~SC_TcpConnectionPort(); + + virtual void* Run(); +}; + +const int kTextBufSize = 8192; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/sc4pd/headers/lang/SC_LanguageClient.h b/sc4pd/headers/lang/SC_LanguageClient.h new file mode 100644 index 0000000..b7a499c --- /dev/null +++ b/sc4pd/headers/lang/SC_LanguageClient.h @@ -0,0 +1,164 @@ +// emacs: -*- c++ -*- +// file: SC_LanguageClient.h +// copyright: 2003 stefan kersten <steve@k-hornz.de> +// cvs: $Id: SC_LanguageClient.h,v 1.1.1.1 2004-07-14 16:21:17 timblech Exp $ + +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA + +#ifndef SC_LANGUAGECLIENT_H_INCLUDED +#define SC_LANGUAGECLIENT_H_INCLUDED + +#include "SC_StringBuffer.h" +#include <pthread.h> +#include <stdarg.h> +#include <stdio.h> + +// ===================================================================== +// SC_LanguageClient - abstract sclang client. +// ===================================================================== + +struct PyrSymbol; +struct VMGlobals; + +extern long compiledOK; +extern pthread_mutex_t gLangMutex; +extern VMGlobals* gMainVMGlobals; + +class SC_LanguageClient +{ +public: + struct Options + { + Options() + : mMemSpace(2*1024*1024), + mMemGrow(256*1024), + mPort(57120), + mRuntimeDir(0) + { } + + int mMemSpace; // memory space in bytes + int mMemGrow; // memory growth in bytes + int mPort; // network port number + char* mRuntimeDir; // runtime directory + }; + +public: + // create singleton instance + SC_LanguageClient(const char* name); + virtual ~SC_LanguageClient(); + + // return the singleton instance + static SC_LanguageClient* instance() { return gInstance; } + + // initialize language runtime + void initRuntime(const Options& opt=Options()); + + // return application name + const char* getName() const { return mName; } + + // library startup/shutdown + bool readLibraryConfig(const char* filePath, const char* fileName=0); + bool readDefaultLibraryConfig(); + bool isLibraryCompiled() { return compiledOK; } + void compileLibrary(); + void shutdownLibrary(); + void recompileLibrary(); + + // interpreter access + void lock() { pthread_mutex_lock(&gLangMutex); } + bool trylock() { return pthread_mutex_trylock(&gLangMutex) == 0; } + void unlock() { pthread_mutex_unlock(&gLangMutex); } + + VMGlobals* getVMGlobals() { return gMainVMGlobals; } + + void setCmdLine(const char* buf, size_t size); + void setCmdLine(const char* str); + void setCmdLine(const SC_StringBuffer& strBuf); + void setCmdLinef(const char* fmt, ...); + void runLibrary(PyrSymbol* pyrSymbol); + void runLibrary(const char* methodName); + void interpretCmdLine() { runLibrary(s_interpretCmdLine); } + void interpretPrintCmdLine() { runLibrary(s_interpretPrintCmdLine); } + void executeFile(const char* fileName); + void runMain() { runLibrary(s_run); } + void stopMain() { runLibrary(s_stop); } + + // post file access + FILE* getPostFile() { return mPostFile; } + void setPostFile(FILE* file) { mPostFile = file; } + + // post buffer output (subclass responsibility) + // these routines should be thread-save. + virtual void post(const char *fmt, va_list ap, bool error) = 0; + virtual void post(char c) = 0; + virtual void post(const char* str, size_t len) = 0; + virtual void flush() = 0; + + // common symbols + // only valid after the library has been compiled. + static PyrSymbol* s_interpretCmdLine; + static PyrSymbol* s_interpretPrintCmdLine; + static PyrSymbol* s_run; + static PyrSymbol* s_stop; + + // command line argument handling utilities + static void snprintMemArg(char* dst, size_t size, int arg); + static bool parseMemArg(const char* arg, int* res); + static bool parsePortArg(const char* arg, int* res); + +protected: + // AppClock driver + // to be called from client mainloop. + void tick(); + + // language notifications, subclasses can override + + // called after language runtime has been initialized + virtual void onInitRuntime(); + // called after the library has been compiled + virtual void onLibraryStartup(); + // called before the library is shut down + virtual void onLibraryShutdown(); + // called after the interpreter has been started + virtual void onInterpStartup(); + +private: + friend void closeAllGUIScreens(); + friend void initGUIPrimitives(); + friend void initGUI(); + +private: + char* mName; + FILE* mPostFile; + SC_StringBuffer mScratch; + bool mRunning; + static SC_LanguageClient* gInstance; +}; + +// ===================================================================== +// library functions +// ===================================================================== + +extern void setPostFile(FILE* file); +extern "C" int vpost(const char *fmt, va_list vargs); +extern void post(const char *fmt, ...); +extern void postfl(const char *fmt, ...); +extern void postText(const char *text, long length); +extern void postChar(char c); +extern void error(const char *fmt, ...); +extern void flushPostBuf(); + +#endif // SC_LANGUAGECLIENT_H_INCLUDED diff --git a/sc4pd/headers/lang/SC_LibraryConfig.h b/sc4pd/headers/lang/SC_LibraryConfig.h new file mode 100644 index 0000000..5f7df3b --- /dev/null +++ b/sc4pd/headers/lang/SC_LibraryConfig.h @@ -0,0 +1,108 @@ +// emacs: -*- c++ -*- +// file: SC_LibraryConfig.h +// cvs: $Id: SC_LibraryConfig.h,v 1.1.1.1 2004-07-14 16:21:24 timblech Exp $ + +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA + +#ifndef SC_LIBRARYCONFIG_H_INCLUDED +#define SC_LIBRARYCONFIG_H_INCLUDED + +#include <stdarg.h> +#include <stdio.h> + +// ===================================================================== +// SC_LibraryConfigFile +// simple library configuration file parser +// ===================================================================== + +class SC_LibraryConfig; + +class SC_LibraryConfigFile +{ +public: + typedef void (*ErrorFunc)(const char* fmt, ...); + +public: + SC_LibraryConfigFile(ErrorFunc errorFunc=0); + + bool open(const char* filePath); + bool read(const char* fileName, SC_LibraryConfig* libConf); + void close(); + +protected: + enum State + { + kBegin, + kAction, + kPath, + kEscape, + kEnvVar, + kEnvVarName, + kEnd + }; + + enum + { + kMaxIncludeDepth = 10 + }; + + bool read(int depth, const char* fileName, SC_LibraryConfig* libConf); + bool parseLine(int depth, const char* fileName, int lineNumber, const char* line, SC_LibraryConfig* libConf); + static void defaultErrorFunc(const char* fmt, ...); + +private: + ErrorFunc mErrorFunc; + FILE* mFile; +}; + +// ===================================================================== +// SC_LibraryConfig +// library configuration management +// Copyright 2003 Maurizio Umberto Puxeddu +// ===================================================================== + +class SC_LibraryConfig +{ +public: + SC_LibraryConfig(void); + virtual ~SC_LibraryConfig(); + + char **includedDirectories(void); + char **excludedDirectories(void); + + void postExcludedDirectories(void); + bool forEachIncludedDirectory(bool (*func)(char *, int)); + + bool pathIsExcluded(const char *path); + + void addIncludedDirectory(char *name); + void addExcludedDirectory(char *name); + + // convenience functions to access the global library config + static bool readLibraryConfig(SC_LibraryConfigFile& file, const char* fileName); + static void freeLibraryConfig(); + +private: + int m_nIncludedDirectories; + char **m_includedDirectories; + int m_nExcludedDirectories; + char **m_excludedDirectories; +}; + +extern SC_LibraryConfig* gLibraryConfig; +extern char *unixStandardizePath(const char *path, char *newpath); + +#endif // SC_LIBRARYCONFIG_H_INCLUDED diff --git a/sc4pd/headers/lang/SC_List.h b/sc4pd/headers/lang/SC_List.h new file mode 100644 index 0000000..1713521 --- /dev/null +++ b/sc4pd/headers/lang/SC_List.h @@ -0,0 +1,229 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + +A doubly linked list template. + +*/ + +#ifndef _SC_List_ +#define _SC_List_ + +#include <stdexcept> +#ifndef NDEBUG +# define NDEBUG +#endif +#include <assert.h> + + +// A Link can be a node in a list or a list itself. + +template <class T> +class Link +{ +public: + Link() : mNext(this), mPrev(this) {} + + T* Prev() { return static_cast<T*>(mPrev); } + T* Next() { return static_cast<T*>(mNext); } + + void RemoveLeaveDangling() + { + mPrev->mNext = mNext; + mNext->mPrev = mPrev; + } + + void Remove() + { + RemoveLeaveDangling(); + mNext = mPrev = this; + } + + void InsertAfter(T *inLink) + { + mPrev = inLink; + mNext = inLink->mNext; + mNext->mPrev = this; + mPrev->mNext = this; + } + + void InsertBefore(T *inLink) + { + mNext = inLink; + mPrev = inLink->mPrev; + mNext->mPrev = this; + mPrev->mNext = this; + } + + T* Head() { return static_cast<T*>(mNext); } + T* Tail() { return static_cast<T*>(mPrev); } + + T* PopHead(); + T* PopTail(); + void PushHead(T* inBuf); + void PushTail(T* inBuf); + + bool ContainsBuf(T* inBuf); + bool IsEmpty() { return mNext == this; } + void BeEmpty() { mNext = mPrev = this; } + + void Cat(T* inLink); + + bool SanityCheck(); + void DebugDump(); + +//private: +// Codewarrior refuses to inline Next() in some places.. + Link<T> *mNext, *mPrev; +}; + +template <class T, class Alloc> +void MakeListEmpty(Link<T> *inLink, Alloc* inAlloc) +{ + Link<T>* link = inLink->mNext; + while (link != inLink) { + Link<T>* nextlink = link->mNext; + // SC uses placement new extensively, so here we do a 'placement delete'. + // Using DestructSelf allows me to have either virtual + // or non virtual destructors in subclasses at the discretion of the subclass. + ((T*)(link))->DestructSelf(); + inAlloc->Free(static_cast<T*>(link)); + link = nextlink; + } + inLink->mNext = inLink->mPrev = inLink; +} + +template <class T> +void Link<T>::PushHead(T* inLink) +{ + assert(SanityCheck()); + + Link<T>* link = static_cast<Link<T>*>(inLink); + link->InsertAfter(static_cast<T*>(this)); + + assert(SanityCheck()); +} + +template <class T> +T* Link<T>::PopHead() +{ + assert(SanityCheck()); + if (IsEmpty()) return 0; + + Link<T>* link = mNext; + + link->Remove(); + + assert(SanityCheck()); + return static_cast<T*>(link); +} + +template <class T> +void Link<T>::PushTail(T* inLink) +{ + assert(SanityCheck()); + + Link<T>* link = static_cast<Link<T>*>(inLink); + link->InsertBefore(static_cast<T*>(this)); + + assert(SanityCheck()); +} + +template <class T> +T* Link<T>::PopTail() +{ + assert(SanityCheck()); + if (IsEmpty()) return 0; + + Link<T>* link = mPrev; + link->Remove(); + + assert(SanityCheck()); + return static_cast<T*>(link); +} + +template <class T> +void Link<T>::Cat(T* inLink) +{ + assert(SanityCheck()); + + Link<T>* link = static_cast<Link<T>*>(inLink); + + if (link->IsEmpty()) return; + if (IsEmpty()) { + mNext = link->mNext; + mPrev = link->mPrev; + link->mNext->mPrev = this; + link->mPrev->mNext = this; + } else { + link->mNext->mPrev = mPrev; + link->mPrev->mNext = this; + mPrev->mNext = link->mNext; + mPrev = link->mPrev; + } + link->mPrev = link; + link->mNext = link; + + assert(SanityCheck()); +} + +template <class T> +bool Link<T>::ContainsBuf(T* inLink) +{ + Link<T>* link = static_cast<Link<T>*>(inLink); + Link<T>* curLink = mNext; + while (curLink != this) { + if (curLink == link) return true; + curLink = curLink->mNext; + } + return false; +} + +template <class T> +void Link<T>::DebugDump() +{ + Link<T>* link = mNext; + while (link != this) { + //post("Link-> %08X next %08X prev %08X\n", + // link, link->mNext, link->mPrev); + link = link->mNext; + } +} + +template <class T> +bool Link<T>::SanityCheck() +{ + Link<T>* link = mNext; + while (link != this) { + if (link->mPrev->mNext != link) { + throw std::runtime_error("Link: bad link <-,->"); + } + if (link->mNext->mPrev != link) { + throw std::runtime_error("Link: bad link ->,<-"); + } + link = link->mNext; + } + return true; +} + + + +#endif diff --git a/sc4pd/headers/lang/SC_LogFile.h b/sc4pd/headers/lang/SC_LogFile.h new file mode 100644 index 0000000..d94c4e2 --- /dev/null +++ b/sc4pd/headers/lang/SC_LogFile.h @@ -0,0 +1,29 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_LogFile_ +#define _SC_LogFile_ + +#include <stdio.h> + +extern FILE *gLogFile; + +#endif diff --git a/sc4pd/headers/lang/SC_Msg.h b/sc4pd/headers/lang/SC_Msg.h new file mode 100644 index 0000000..b187f09 --- /dev/null +++ b/sc4pd/headers/lang/SC_Msg.h @@ -0,0 +1,70 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Msg_ +#define _SC_Msg_ + +#include <stdio.h> +#include <stdlib.h> +#include <netinet/in.h> +#include "sc_msg_iter.h" + +class SC_Msg; + +enum { // Handler IDs + kUnknownAction = 0, + kRealTimeAction = 1, + kNonRealTimeAction = 2, + kEitherTimeAction = 3 +}; + +typedef void (*ReplyFunc)(struct ReplyAddress *inReplyAddr, char* inBuf, int inSize); + +struct ReplyAddress +{ + struct sockaddr_in mSockAddr; + int mSockAddrLen; + int mSocket; + ReplyFunc mReplyFunc; +}; + +inline void SendReply(ReplyAddress *inReplyAddr, char* inBuf, int inSize) +{ + (inReplyAddr->mReplyFunc)(inReplyAddr, inBuf, inSize); +} + +void DumpReplyAddress(ReplyAddress *inReplyAddress); +int32 Hash(ReplyAddress *inReplyAddress); + +struct OSC_Packet +{ + char *mData; + int32 mSize; + bool mIsBundle; + + ReplyAddress mReplyAddr; +}; + +void FreeOSCPacket(OSC_Packet *inPacket); + +#endif + + diff --git a/sc4pd/headers/lang/SC_SynthImpl.h b/sc4pd/headers/lang/SC_SynthImpl.h new file mode 100644 index 0000000..88411b3 --- /dev/null +++ b/sc4pd/headers/lang/SC_SynthImpl.h @@ -0,0 +1,42 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_SynthImpl_ +#define _SC_SynthImpl_ + +#include "SC_Synth.h" +#include "SC_SynthDef.h" +#include "HashTable.h" +#include "SC_AllocPool.h" +#include "SC_UnorderedList.h" + +extern SynthInterfaceTable gSynthInterfaceTable; +void InitSynthInterfaceTable(); + +typedef void (*SetupInterfaceFunc)(SynthInterfaceTable*); + +const int kMaxSynths = 1024; +extern StaticHashTable<Synth, kMaxSynths, const char*> gSynthTable; +extern AllocPool *gSynthAllocPool; + +extern float32 gSine[8193]; + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/lang/SC_TerminalClient.h b/sc4pd/headers/lang/SC_TerminalClient.h new file mode 100644 index 0000000..b0375d0 --- /dev/null +++ b/sc4pd/headers/lang/SC_TerminalClient.h @@ -0,0 +1,92 @@ +// emacs: -*- c++ -*- +// file: SC_TerminalClient.h +// copyright: 2003 stefan kersten <steve@k-hornz.de> +// cvs: $Id: SC_TerminalClient.h,v 1.1.1.1 2004-07-14 16:21:27 timblech Exp $ + +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA + +#ifndef SC_TERMINALCLIENT_H_INCLUDED +#define SC_TERMINALCLIENT_H_INCLUDED + +#include "SC_LanguageClient.h" +#include "SC_StringBuffer.h" + +// ===================================================================== +// SC_TerminalClient - command line sclang client. +// ===================================================================== + +class SC_TerminalClient : public SC_LanguageClient +{ +public: + enum + { + kInterpretCmdLine = 0x1b, + kInterpretPrintCmdLine = 0x0c + }; + + struct Options : public SC_LanguageClient::Options + { + Options() + : mLibraryConfigFile(0), + mDaemon(false), + mCallRun(false), + mCallStop(false), + mArgc(0), mArgv(0) + { } + + char* mLibraryConfigFile; + bool mDaemon; + bool mCallRun; + bool mCallStop; + int mArgc; + char** mArgv; + }; + + SC_TerminalClient(const char* name); + + const Options& options() const { return mOptions; } + bool shouldBeRunning() const { return mShouldBeRunning; } + + int run(int argc, char** argv); + void quit(int code); + + virtual void post(const char *fmt, va_list ap, bool error); + virtual void post(char c); + virtual void post(const char* str, size_t len); + virtual void flush(); + +protected: + bool parseOptions(int& argc, char**& argv, Options& opt); + void printUsage(); + + // fd is assumed to be non-blocking + bool readCmdLine(int fd, SC_StringBuffer& cmdLine); + void interpretCmdLine(PyrSymbol* method, SC_StringBuffer& cmdLine); + + // subclasses should override + virtual void commandLoop(); + virtual void daemonLoop(); + + static int prExit(struct VMGlobals* g, int); + virtual void onLibraryStartup(); + +private: + bool mShouldBeRunning; + int mReturnCode; + Options mOptions; +}; + +#endif // SC_TERMINALCLIENT_H_INCLUDED diff --git a/sc4pd/headers/lang/SC_UnorderedList.h b/sc4pd/headers/lang/SC_UnorderedList.h new file mode 100644 index 0000000..37ce8d9 --- /dev/null +++ b/sc4pd/headers/lang/SC_UnorderedList.h @@ -0,0 +1,60 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_UnorderedList_ +#define _SC_UnorderedList_ + +template <class T, int kMaxItems> +class SC_UnorderedList +{ + T* mList[kMaxItems]; + unsigned int mSize; +public: + SC_UnorderedList() : mSize(0) {} + + unsigned int Size() const { return mSize; } + Synth* GetAt(unsigned int inIndex) + { + if (inIndex >= mSize) return 0; + return mList[inIndex]; + } + + void Add(T *inItem) + { + if (mSize < kMaxItems) { + mList[mSize] = inItem; + SetListIndex(inItem, mSize++); + } + } + + void Remove(T *inItem) + { + --mSize; + unsigned int index = GetListIndex(inItem); + if (index < mSize) { + mList[index] = mList[mSize]; + SetListIndex(mList[index], index); + } + } +}; + +#endif + diff --git a/sc4pd/headers/lang/SFHeaders.h b/sc4pd/headers/lang/SFHeaders.h new file mode 100644 index 0000000..143652d --- /dev/null +++ b/sc4pd/headers/lang/SFHeaders.h @@ -0,0 +1,140 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SFHeaders_ +#define _SFHeaders_ + +#include "SCBase.h" +#include "ReadWriteMacros.h" + +enum { + unsupported_sound_file = -1, + AIFF_sound_file, + AIFC_sound_file, + RIFF_sound_file, + NeXT_sound_file, + IRCAM_sound_file, + SD2_sound_file, + raw_sound_file +}; + +enum { + snd_unsupported = -1, + snd_no_snd, + snd_16_linear, + snd_8_mulaw, + snd_8_linear, + snd_32_float, + snd_32_linear, + snd_8_alaw, + snd_8_unsigned, + snd_24_linear, + snd_64_double, + snd_16_linear_little_endian, + snd_32_linear_little_endian, + snd_32_float_little_endian, + snd_64_double_little_endian, + snd_16_unsigned, + snd_16_unsigned_little_endian, + snd_24_linear_little_endian, + snd_32_vax_float, + snd_12_linear, + snd_12_linear_little_endian, + snd_12_unsigned, + snd_12_unsigned_little_endian +}; + + +class SFHeaderInfo +{ +public: + SFHeaderInfo(); + + bool WriteHeader(FILE *inFile); + + void SetPath(char *inPath); + double SampleRate() { return mSampleRate; } + void SetSampleRate(double inSampleRate) { mSampleRate = inSampleRate; } + void SetFormat(int inHeaderFormat, int inSampleFormat, int inCreator); + + double Freq() { return mFreq; } + + uint8 LoNote() { return mLoNote; } + uint8 HiNote() { return mHiNote; } + uint8 LoVeloc() { return mLoVeloc; } + uint8 HiVeloc() { return mHiVeloc; } + + uint8 NumChannels() { return mNumChannels; } + int32 NumFramesInFile() { return mNumFramesInFile; } + + int makeSoundFileHeader(SC_IOStream<char*>& rw); + + int32 headerFileType(); + int headerSize(); + int sampleFormatSize(); + void newSoundFilePath(); + + bool ReadSoundFileHeader(FILE *fp); + + int32 CalcFrameSize(); + bool SetTypeCreator(); + + char mPath[256]; + double mSampleRate; + double mFreq; + int32 mNumFramesInFile; + int32 mDataOffset; + int32 mCreator; + void *mExtraStuff; + int16 mGain; + int8 mHeaderFormat; + int8 mSampleFormat; + uint8 mNumChannels; + uint8 mLoNote, mHiNote, mLoVeloc, mHiVeloc; + +private: + + + int make_AIFF_header(SC_IOStream<char*>& rw); + int make_AIFC_header(SC_IOStream<char*>& rw); + int make_RIFF_header(SC_IOStream<char*>& rw); + int make_Next_header(SC_IOStream<char*>& rw); + int make_IRCAM_header(SC_IOStream<char*>& rw); + + int sampleFormat_AIFF(); + int sampleFormat_AIFC(); + int sampleFormat_RIFF(); + int sampleFormat_Next(); + int sampleFormat_Next_inv(int inFormat); + void writeCompressionFormat_AIFC(SC_IOStream<char*>& rw); + + bool read_AIFF_Header(SC_IOStream<FILE*>& rw); + bool read_RIFF_Header(SC_IOStream<FILE*>& rw); + bool read_Next_Header(SC_IOStream<FILE*>& rw); +}; + + +extern char gDefaultSoundFolder[256]; +extern char gDefaultSoundFilePath[256]; + +int sampleFormatSize(int inSampleFormat); + +#endif diff --git a/sc4pd/headers/lang/Samp.h b/sc4pd/headers/lang/Samp.h new file mode 100644 index 0000000..7593ba8 --- /dev/null +++ b/sc4pd/headers/lang/Samp.h @@ -0,0 +1,46 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + +Samp is a typedef for the output sample type. +Should be defined to be either float or double. + +*/ + +#ifndef _Samp_ +#define _Samp_ + +#include "SC_Types.h" + +const long kSineSize = 8192; +const long kSineMask = kSineSize - 1; +const double kSinePhaseScale = kSineSize / (2.0 * 3.1415926535897932384626433832795); + +extern float32 gSine[kSineSize+1]; +extern float32 gPMSine[kSineSize+1]; +extern float32 gInvSine[kSineSize+1]; +extern float32 gSineWavetable[2*kSineSize]; + +void SignalAsWavetable(float32* signal, float32* wavetable, long inSize); +void WavetableAsSignal(float32* wavetable, float32* signal, long inSize); + +#endif + diff --git a/sc4pd/headers/lang/SimpleStack.h b/sc4pd/headers/lang/SimpleStack.h new file mode 100644 index 0000000..3313785 --- /dev/null +++ b/sc4pd/headers/lang/SimpleStack.h @@ -0,0 +1,32 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +typedef struct { + long *stak; + short num, maxsize; +} LongStack; + +void initLongStack(LongStack *self) ; +void freeLongStack(LongStack *self); +void growLongStack(LongStack *self); +void pushls(LongStack *self, long value); +long popls(LongStack *self); +int emptyls(LongStack *self); diff --git a/sc4pd/headers/lang/VMGlobals.h b/sc4pd/headers/lang/VMGlobals.h new file mode 100644 index 0000000..9b5f2e1 --- /dev/null +++ b/sc4pd/headers/lang/VMGlobals.h @@ -0,0 +1,94 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +Each virtual machine has a copy of VMGlobals, which contains the state of the virtual machine. + +*/ + +#ifndef _VMGLOBALS_H_ +#define _VMGLOBALS_H_ + +#include "PyrSlot.h" +#include "SC_AllocPool.h" +#include "SC_RGen.h" + +const int kNumProcesses = 1; +const int kMainProcessID = 0; + +typedef void (*FifoMsgFunc)(struct VMGlobals*, struct FifoMsg*); + +struct FifoMsg { + FifoMsg() : func(0), dataPtr(0) { dataWord[0] = dataWord[1] = 0; } + void Perform(struct VMGlobals* g); + void Free(struct VMGlobals* g); + + FifoMsgFunc func; + void* dataPtr; + long dataWord[2]; +}; + +struct VMGlobals { + VMGlobals(); + + // global context + class AllocPool *allocPool; + struct PyrProcess *process; + class SymbolTable *symbolTable; + class PyrGC *gc; // garbage collector for this process + PyrSlot *classvars; + bool canCallOS; + + // thread context + struct PyrThread *thread; + struct PyrMethod *method; + struct PyrBlock *block; + struct PyrFrame *frame; + struct PyrMethod *primitiveMethod; + unsigned char *ip; // current instruction pointer + PyrSlot *sp; // current stack ptr + PyrSlot *args; + PyrSlot receiver; // the receiver + PyrSlot result; + int numpop; // number of args to pop for primitive + long returnLevels; + long processID; + long primitiveIndex; + RGen *rgen; + + // scratch context + long execMethod; +} ; + +inline void FifoMsg::Perform(struct VMGlobals* g) + { + (func)(g, this); + } + +inline void FifoMsg::Free(struct VMGlobals* g) + { + g->allocPool->Free(dataPtr); + } + +extern VMGlobals gVMGlobals[kNumProcesses]; +extern VMGlobals *gMainVMGlobals; +extern VMGlobals *gCompilingVMGlobals; +#endif + diff --git a/sc4pd/headers/lang/bullet.h b/sc4pd/headers/lang/bullet.h new file mode 100644 index 0000000..463b062 --- /dev/null +++ b/sc4pd/headers/lang/bullet.h @@ -0,0 +1,7 @@ + +// this should be an outstanding character +// it is used in printing errors + +#define BULLET "¥" +#define BULLET_CHAR '¥' + diff --git a/sc4pd/headers/lang/libraryConfig.h b/sc4pd/headers/lang/libraryConfig.h new file mode 100644 index 0000000..b1f3844 --- /dev/null +++ b/sc4pd/headers/lang/libraryConfig.h @@ -0,0 +1,31 @@ +// Copyright 2003 Maurizio Umberto Puxeddu + +#ifndef _Supercollider_libraryConfig_h_ +#define _Supercollider_libraryConfig_h_ + +class LibraryConfig { + public: + LibraryConfig(void); + virtual ~LibraryConfig(); + + char **includedDirectories(void); + char **excludedDirectories(void); + + void postExcludedDirectories(void); + bool forEachIncludedDirectory(bool (*func)(char *, int)); + + bool pathIsExcluded(const char *path); + + void addIncludedDirectory(char *name); + void addExcludedDirectory(char *name); + + private: + int m_nIncludedDirectories; + char **m_includedDirectories; + int m_nExcludedDirectories; + char **m_excludedDirectories; +}; + +extern char *unixStandardizePath(const char *path, char *newpath); + +#endif // _Supercollider_libraryConfig_h_ diff --git a/sc4pd/headers/lang/readSamples.h b/sc4pd/headers/lang/readSamples.h new file mode 100644 index 0000000..835f975 --- /dev/null +++ b/sc4pd/headers/lang/readSamples.h @@ -0,0 +1 @@ +/*
SuperCollider real time audio synthesis system
Copyright (c) 2002 James McCartney. All rights reserved.
http://www.audiosynth.com
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _readSamples_
#define _readSamples_
long readSamplesInterleaved(FILE* fp, float *out, long numSamplesToRead, long format);
void convertSamplesIn(float **out, char *in, long numFramesToRead, long numChannels, long sampOffset, long format);
float convertSamplesOut(float **in, char *buffer, int numFramesToWrite, int numChannels, long sampOffset, int format);
void convertSamplesInInterleaved(float *out, char *buffer, long numSamplesToRead, long sampOffset, long format);
float convertSamplesOutInterleaved(float *in, char *buffer, long numSampsToWrite, int format);
#endif
\ No newline at end of file diff --git a/sc4pd/headers/plugin_interface/Hash.h b/sc4pd/headers/plugin_interface/Hash.h new file mode 100644 index 0000000..e42eaf4 --- /dev/null +++ b/sc4pd/headers/plugin_interface/Hash.h @@ -0,0 +1,152 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _Hash_ +#define _Hash_ + +#include "SC_Types.h" +#include "SC_Endian.h" + +// These hash functions are among the best there are in terms of both speed and quality. +// A good hash function makes a lot of difference. +// I have not used Bob Jenkins own hash function because the keys I use are relatively short. + + +// hash function for a string +inline int32 Hash(const char *inKey) +{ + // the one-at-a-time hash. + // a very good hash function. ref: a web page by Bob Jenkins. + // http://www.burtleburtle.net/bob/hash/doobs.html + int32 hash = 0; + while (*inKey) { + hash += *inKey++; + hash += hash << 10; + hash ^= hash >> 6; + } + hash += hash << 3; + hash ^= hash >> 11; + hash += hash << 15; + return hash; +} + +// hash function for a string that also returns the length +inline int32 Hash(const char *inKey, int32 *outLength) +{ + // the one-at-a-time hash. + // a very good hash function. ref: a web page by Bob Jenkins. + const char *origKey = inKey; + int32 hash = 0; + while (*inKey) { + hash += *inKey++; + hash += hash << 10; + hash ^= hash >> 6; + } + hash += hash << 3; + hash ^= hash >> 11; + hash += hash << 15; + *outLength = inKey - origKey; + return hash; +} + +// hash function for an array of char +inline int32 Hash(const char *inKey, int32 inLength) +{ + // the one-at-a-time hash. + // a very good hash function. ref: a web page by Bob Jenkins. + int32 hash = 0; + for (int i=0; i<inLength; ++i) { + hash += *inKey++; + hash += hash << 10; + hash ^= hash >> 6; + } + hash += hash << 3; + hash ^= hash >> 11; + hash += hash << 15; + return hash; +} + +// hash function for integers +inline int32 Hash(int32 inKey) +{ + // Thomas Wang's integer hash. + // http://www.concentric.net/~Ttwang/tech/inthash.htm + // a faster hash for integers. also very good. + uint32 hash = (uint32)inKey; + hash += ~(hash << 15); + hash ^= hash >> 10; + hash += hash << 3; + hash ^= hash >> 6; + hash += ~(hash << 11); + hash ^= hash >> 16; + return (int32)hash; +} + +inline int64 Hash64(int64 inKey) +{ + // Thomas Wang's 64 bit integer hash. + uint64 hash = (uint64)inKey; + hash += ~(hash << 32); + hash ^= (hash >> 22); + hash += ~(hash << 13); + hash ^= (hash >> 8); + hash += (hash << 3); + hash ^= (hash >> 15); + hash += ~(hash << 27); + hash ^= (hash >> 31); + return (int64)hash; +} + +inline int32 Hash(const int32 *inKey, int32 inLength) +{ + // one-at-a-time hashing of a string of int32's. + // uses Thomas Wang's integer hash for the combining step. + int32 hash = 0; + for (int i=0; i<inLength; ++i) { + hash = Hash(hash + *inKey++); + } + return hash; +} + +#ifndef _LASTCHAR_ +#define _LASTCHAR_ +#if BYTE_ORDER == LITTLE_ENDIAN +const int32 kLASTCHAR = 0xFF000000; +#else +const int32 kLASTCHAR = 0x000000FF; +#endif +#endif + +inline int32 Hash(const int32 *inKey) +{ + // hashing of a string of int32's. + // uses Thomas Wang's integer hash for the combining step. + int32 hash = 0; + int32 c; + do { + c = *inKey++; + hash = Hash(hash + c); + } while (c & kLASTCHAR); + return hash; +} + +#endif + diff --git a/sc4pd/headers/plugin_interface/SC_BoundsMacros.h b/sc4pd/headers/plugin_interface/SC_BoundsMacros.h new file mode 100644 index 0000000..6c65795 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_BoundsMacros.h @@ -0,0 +1,29 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_BoundsMacros_ +#define _SC_BoundsMacros_ + +#define sc_abs(a) ((a)>=0?(a) : -(a)) +#define sc_max(a,b) (((a) > (b)) ? (a) : (b)) +#define sc_min(a,b) (((a) < (b)) ? (a) : (b)) +#define sc_clip(x, lo, hi) ((x) > (hi) ? (hi) : ((x) < (lo) ? (lo) : (x))) + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_BufGen.h b/sc4pd/headers/plugin_interface/SC_BufGen.h new file mode 100644 index 0000000..9a275c1 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_BufGen.h @@ -0,0 +1,40 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _BufGen_ +#define _BufGen_ + +#include "SC_Types.h" + +typedef void (*BufGenFunc)(struct World *world, struct SndBuf *buf, struct sc_msg_iter *msg); + +struct BufGen +{ + int32 mBufGenName[kSCNameLen]; + int32 mHash; + + BufGenFunc mBufGenFunc; +}; + +extern "C" { +bool BufGen_Create(char *inName, BufGenFunc inFunc); +} + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_Constants.h b/sc4pd/headers/plugin_interface/SC_Constants.h new file mode 100644 index 0000000..b9e49bf --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_Constants.h @@ -0,0 +1,46 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_Constants_ +#define _SC_Constants_ + +#include <math.h> + +#ifndef __FP__ +const double pi = acos(-1.); +#endif +const double pi2 = pi * .5; +const double pi32 = pi * 1.5; +const double twopi = pi * 2.; +const double rtwopi = 1. / twopi; +const double log001 = log(0.001); +const double log01 = log(0.01); +const double log1 = log(0.1); +const double rlog2 = 1./log(2.); +const double sqrt2 = sqrt(2.); +const double rsqrt2 = 1. / sqrt2; + +// used to truncate precision +const float truncFloat = (float)(3. * pow(2,22)); +const double truncDouble = 3. * pow(2,51); + +const float kBadValue = 1e20f; // used in the secant table for values very close to 1/0 + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_DemandUnit.h b/sc4pd/headers/plugin_interface/SC_DemandUnit.h new file mode 100644 index 0000000..6f273b3 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_DemandUnit.h @@ -0,0 +1,54 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_DemandUnit_ +#define _SC_DemandUnit_ + +#include "SC_Unit.h" +#include "SC_Wire.h" + +// demand rate unit support. + +inline bool IsDemandInput(Unit* unit, int index) +{ + Unit* fromUnit = unit->mInput[index]->mFromUnit; + return fromUnit && fromUnit->mCalcRate == calc_DemandRate; +} + +inline float DemandInput(Unit* unit, int index) +{ + Unit* fromUnit = unit->mInput[index]->mFromUnit; + if (fromUnit && fromUnit->mCalcRate == calc_DemandRate) + (fromUnit->mCalcFunc)(fromUnit, 1); + return IN0(index); +} + +inline void ResetInput(Unit* unit, int index) +{ + Unit* fromUnit = unit->mInput[index]->mFromUnit; + if (fromUnit && fromUnit->mCalcRate == calc_DemandRate) + (fromUnit->mCalcFunc)(fromUnit, 0); +} + +#define ISDEMANDINPUT(index) IsDemandInput(unit, (index)) +#define DEMANDINPUT(index) DemandInput(unit, (index)) +#define RESETINPUT(index) ResetInput(unit, (index)) + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_Dimension.h b/sc4pd/headers/plugin_interface/SC_Dimension.h new file mode 100644 index 0000000..923b283 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_Dimension.h @@ -0,0 +1,31 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_Dimension_ +#define _SC_Dimension_ + +struct SC_Dimension +{ + long mWidth, mHeight, mNumPixels; + float mXSlopeFactor, mYSlopeFactor; +}; +typedef struct SC_Dimension SC_Dimension; + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_FifoMsg.h b/sc4pd/headers/plugin_interface/SC_FifoMsg.h new file mode 100644 index 0000000..7d83e0a --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_FifoMsg.h @@ -0,0 +1,59 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _FifoMsg_ +#define _FifoMsg_ + +typedef void (*FifoMsgFunc)(struct FifoMsg*); + +struct FifoMsg +{ + FifoMsg() : mPerformFunc(0), mFreeFunc(0), mData(0), mWorld(0) {} + + void Set(struct World *inWorld, FifoMsgFunc inPerform, FifoMsgFunc inFree, void* inData); + void Perform(); + void Free(); + + FifoMsgFunc mPerformFunc; + FifoMsgFunc mFreeFunc; + void* mData; + struct World *mWorld; +}; + +inline void FifoMsg::Set(World *inWorld, FifoMsgFunc inPerform, FifoMsgFunc inFree, void* inData) +{ + mWorld = inWorld; + mPerformFunc = inPerform; + mFreeFunc = inFree; + mData = inData; +} + +inline void FifoMsg::Perform() +{ + if (mPerformFunc) (mPerformFunc)(this); +} + +inline void FifoMsg::Free() +{ + if (mFreeFunc) (mFreeFunc)(this); +} + +#endif + diff --git a/sc4pd/headers/plugin_interface/SC_Graph.h b/sc4pd/headers/plugin_interface/SC_Graph.h new file mode 100644 index 0000000..68d3d59 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_Graph.h @@ -0,0 +1,53 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_Graph_ +#define _SC_Graph_ + +#include "SC_Node.h" +#include "SC_Rate.h" +#include "SC_Dimension.h" + +struct Graph +{ + Node mNode; + + uint32 mNumWires; + struct Wire *mWire; + + uint32 mNumControls; + float *mControls; + float **mMapControls; + + uint32 mNumUnits; + struct Unit **mUnits; + + int mNumCalcUnits; + struct Unit **mCalcUnits; // excludes i-rate units. + + int mSampleOffset; + struct RGen* mRGen; + + struct Unit *mLocalAudioBusUnit; + struct Unit *mLocalControlBusUnit; +}; +typedef struct Graph Graph; + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h b/sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h new file mode 100644 index 0000000..2d9668b --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_InlineBinaryOp.h @@ -0,0 +1,574 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _BinaryOpUGen_ +#define _BinaryOpUGen_ + +#include "SC_BoundsMacros.h" +#include <math.h> + +inline float sc_mod(float in, float hi) +{ + // avoid the divide if possible + const float lo = (float)0.; + if (in >= hi) { + in -= hi; + if (in < hi) return in; + } else if (in < lo) { + in += hi; + if (in >= lo) return in; + } else return in; + + if (hi == lo) return lo; + return in - hi*floor(in/hi); +} + +inline double sc_mod(double in, double hi) +{ + // avoid the divide if possible + const double lo = (double)0.; + if (in >= hi) { + in -= hi; + if (in < hi) return in; + } else if (in < lo) { + in += hi; + if (in >= lo) return in; + } else return in; + + if (hi == lo) return lo; + return in - hi*floor(in/hi); +} + +inline float sc_wrap(float in, float lo, float hi) +{ + float range; + // avoid the divide if possible + if (in >= hi) { + range = hi - lo; + in -= range; + if (in < hi) return in; + } else if (in < lo) { + range = hi - lo; + in += range; + if (in >= lo) return in; + } else return in; + + if (hi == lo) return lo; + return in - range * floor((in - lo)/range); +} + +inline double sc_wrap(double in, double lo, double hi) +{ + double range; + // avoid the divide if possible + if (in >= hi) { + range = hi - lo; + in -= range; + if (in < hi) return in; + } else if (in < lo) { + range = hi - lo; + in += range; + if (in >= lo) return in; + } else return in; + + if (hi == lo) return lo; + return in - range * floor((in - lo)/range); +} + +inline double sc_wrap(double in, double lo, double hi, double range) +{ + // avoid the divide if possible + if (in >= hi) { + in -= range; + if (in < hi) return in; + } else if (in < lo) { + in += range; + if (in >= lo) return in; + } else return in; + + if (hi == lo) return lo; + return in - range * floor((in - lo)/range); +} + +inline double sc_wrap(float in, float lo, float hi, float range) +{ + // avoid the divide if possible + if (in >= hi) { + in -= range; + if (in < hi) return in; + } else if (in < lo) { + in += range; + if (in >= lo) return in; + } else return in; + + if (hi == lo) return lo; + return in - range * floor((in - lo)/range); +} + +inline float sc_fold(float in, float lo, float hi) +{ + float x, c, range, range2; + x = in - lo; + + // avoid the divide if possible + if (in >= hi) { + in = hi + hi - in; + if (in >= lo) return in; + } else if (in < lo) { + in = lo + lo - in; + if (in < hi) return in; + } else return in; + + if (hi == lo) return lo; + // ok do the divide + range = hi - lo; + range2 = range + range; + c = x - range2 * floor(x / range2); + if (c>=range) c = range2 - c; + return c + lo; +} + +inline double sc_fold(double in, double lo, double hi) +{ + double x, c, range, range2; + x = in - lo; + + // avoid the divide if possible + if (in >= hi) { + in = hi + hi - in; + if (in >= lo) return in; + } else if (in < lo) { + in = lo + lo - in; + if (in < hi) return in; + } else return in; + + if (hi == lo) return lo; + // ok do the divide + range = hi - lo; + range2 = range + range; + c = x - range2 * floor(x / range2); + if (c>=range) c = range2 - c; + return c + lo; +} + +inline double sc_fold(float in, float lo, float hi, float range, float range2) +{ + float x, c; + x = in - lo; + + // avoid the divide if possible + if (in >= hi) { + in = hi + hi - in; + if (in >= lo) return in; + } else if (in < lo) { + in = lo + lo - in; + if (in < hi) return in; + } else return in; + + if (hi == lo) return lo; + // ok do the divide + c = x - range2 * floor(x / range2); + if (c>=range) c = range2 - c; + return c + lo; +} + +inline double sc_fold(double in, double lo, double hi, double range, double range2) +{ + double x, c; + x = in - lo; + + // avoid the divide if possible + if (in >= hi) { + in = hi + hi - in; + if (in >= lo) return in; + } else if (in < lo) { + in = lo + lo - in; + if (in < hi) return in; + } else return in; + + if (hi == lo) return lo; + // ok do the divide + c = x - range2 * floor(x / range2); + if (c>=range) c = range2 - c; + return c + lo; +} + +inline float sc_pow(float a, float b) +{ + return a >= 0.f ? pow(a, b) : -pow(-a, b); +} + +inline double sc_pow(double a, double b) +{ + return a >= 0.f ? pow(a, b) : -pow(-a, b); +} + +template <class T> +inline float sc_thresh(T a, T b) +{ + return a < b ? (T)0 : a; +} + +inline float sc_clip2(float a, float b) +{ + return sc_clip(a, -b, b); +} + +inline float sc_wrap2(float a, float b) +{ + return sc_wrap(a, -b, b); +} + +inline float sc_fold2(float a, float b) +{ + return sc_fold(a, -b, b); +} + +inline float sc_excess(float a, float b) +{ + return a - sc_clip(a, -b, b); +} + +inline float sc_round(float x, float quant) +{ + return quant==0. ? x : floor(x/quant + .5f) * quant; +} + +inline double sc_round(double x, double quant) +{ + return quant==0. ? x : floor(x/quant + .5) * quant; +} + +inline float sc_roundUp(float x, float quant) +{ + return quant==0. ? x : ceil(x/quant) * quant; +} + +inline double sc_roundUp(double x, double quant) +{ + return quant==0. ? x : ceil(x/quant) * quant; +} + +inline float sc_trunc(float x, float quant) +{ + return quant==0. ? x : floor(x/quant) * quant; +} + +inline double sc_trunc(double x, double quant) +{ + return quant==0. ? x : floor(x/quant) * quant; +} + +inline float sc_atan2(float a, float b) +{ + return atan2(a, b); +} + + +inline float sc_scaleneg(float a, float b) +{ + b = 0.5f * b + 0.5f; + return (fabs(a) - a) * b + a; +} + +inline float sc_amclip(float a, float b) +{ + return a * 0.5f * (b + fabs(b)); +} + +inline double sc_amclip(double a, double b) +{ + return a * 0.5 * (b + fabs(b)); +} + +const float kFSQRT2M1 = sqrt(2.) - 1.; +const double kDSQRT2M1 = sqrt(2.) - 1.; + +inline float sc_hypotx(float x, float y) +{ + float minxy; + + x = fabs(x); + y = fabs(y); + + minxy = sc_min(x,y); + + return x + y - kFSQRT2M1 * minxy; +} + +inline double sc_hypotx(double x, double y) +{ + double minxy; + + x = fabs(x); + y = fabs(y); + + minxy = sc_min(x,y); + + return x + y - kDSQRT2M1 * minxy; +} + +#pragma mark - + + +inline int sc_div(int a, int b) +{ + int c; + if (b) { + if (a<0) c = (a+1)/b - 1; + else c = a/b; + } else c = a; + return c; +} + +/* +inline int sc_mod(int a, int b) +{ + long c; + c = a % b; + if (c<0) c += b; + return c; +} +*/ + +inline int sc_mod(int in, int hi) +{ + // avoid the divide if possible + const int lo = 0; + if (in >= hi) { + in -= hi; + if (in < hi) return in; + } else if (in < lo) { + in += hi; + if (in >= lo) return in; + } else return in; + + if (hi == lo) return lo; + + int c; + c = in % hi; + if (c<0) c += hi; + return c; +} + +inline int sc_wrap(int in, int lo, int hi) +{ + return sc_mod(in - lo, hi - lo + 1) + lo; +} + +inline int sc_clip2(int a, int b) +{ + return sc_clip(a, -b, b); +} + +inline int sc_wrap2(int a, int b) +{ + return sc_wrap(a, -b, b); +} + +inline int sc_fold(int in, int lo, int hi) +{ + int b = hi - lo; + int b2 = b+b-2; + int c = sc_mod(in - lo, b2); + if (c>=b) c = b2-c; + return c + lo; +} + +inline int sc_fold2(int a, int b) +{ + return sc_fold(a, -b, b); +} + +inline int sc_excess(int a, int b) +{ + return a - sc_clip(a, -b, b); +} + +inline int sc_gcd(int u, int v) +{ + int t; + u = sc_abs(u); + v = sc_abs(v); + if (u <= 1 || v <= 1) return 1; + while (u>0) { + if (u<v) { t=u; u=v; v=t; } + u = u % v; + } + return v; +} + +inline int sc_lcm(int u, int v) +{ + return (u * v)/sc_gcd(u,v); +} + +inline int sc_thresh(int a, int b) +{ + return a < b ? 0 : a; +} + +inline int sc_bitAnd(int a, int b) +{ + return a & b; +} + +inline int sc_bitOr(int a, int b) +{ + return a | b; +} + +inline int sc_leftShift(int a, int b) +{ + return a << b; +} + +inline int sc_rightShift(int a, int b) +{ + return a >> b; +} + +inline int sc_unsignedRightShift(int a, int b) +{ + return (uint32)a >> b; +} + +inline int sc_round(int x, int quant) +{ + return quant==0 ? x : sc_div(x + quant/2, quant) * quant; +} + + +inline int sc_roundUp(int x, int quant) +{ + return quant==0 ? x : sc_div(x + quant - 1, quant) * quant; +} + +inline int sc_trunc(int x, int quant) +{ + return quant==0 ? x : sc_div(x, quant) * quant; +} + +#pragma mark - + +#if 0 + +inline long sc_div(long a, long b) +{ + int c; + if (b) { + if (a<0) c = (a+1)/b - 1; + else c = a/b; + } else c = a; + return c; +} + + +inline long sc_clip2(long a, long b) +{ + return sc_clip(a, -b, b); +} + +inline long sc_wrap(long in, long lo, long hi) +{ + return sc_mod(in - lo, hi - lo + 1) + lo; +} + +inline long sc_wrap2(long a, long b) +{ + return sc_wrap(a, -b, b); +} + +inline long sc_fold(long in, long lo, long hi) +{ + long b = hi - lo; + long b2 = b+b-2; + long c = sc_mod(in - lo, b2); + if (c>=b) c = b2-c; + return c + lo; +} + +inline long sc_fold2(long a, long b) +{ + return sc_fold(a, -b, b); +} + +inline long sc_thresh(long a, long b) +{ + return a < b ? 0 : a; +} + +inline long sc_bitAnd(long a, long b) +{ + return a & b; +} + +inline long sc_bitOr(long a, long b) +{ + return a | b; +} + +inline long sc_leftShift(long a, long b) +{ + return a << b; +} + +inline long sc_rightShift(long a, long b) +{ + return a >> b; +} + +inline long sc_unsignedRightShift(long a, long b) +{ + return (unsigned long)a >> b; +} + +inline long sc_gcd(long u, long v) +{ + long t; + u = sc_abs(u); + v = sc_abs(v); + if (u <= 1 || v <= 1) return 1; + while (u>0) { + if (u<v) { t=u; u=v; v=t; } + u = u % v; + } + return v; +} + +inline long sc_lcm(long u, long v) +{ + return (u * v)/sc_gcd(u,v); +} + +inline long sc_excess(long a, long b) +{ + return a - sc_clip(a, -b, b); +} + +inline long sc_round(long x, long quant) +{ + return quant==0 ? x : sc_div(x + quant/2, quant) * quant; +} + +#endif + +#endif + diff --git a/sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h b/sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h new file mode 100644 index 0000000..9ea2e0b --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_InlineUnaryOp.h @@ -0,0 +1,448 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _UnaryOpUGen_ +#define _UnaryOpUGen_ + +#include "SC_Types.h" +#include "SC_Constants.h" + +/////////////////////////////////////////////////////////////////////////////////////// + +inline bool sc_isnan(float x) +{ + return (!(x >= 0.f || x <= 0.f)); +} + +/////////////////////////////////////////////////////////////////////////////////////// + +// versions provided for float32 and float64 +// did not supply template because do not want to instantiate for integers. +// all constants explicitly cast to prevent PowerPC frsp instruction generation. + +/////////////////////////////////////////////////////////////////////////////////////// + +// this is a function for preventing pathological math operations in ugens. +// can be used at the end of a block to fix any recirculating filter values. +inline float32 zapgremlins(float32 x) +{ + float32 absx = fabs(x); + // very small numbers fail the first test, eliminating denormalized numbers + // (zero also fails the first test, but that is OK since it returns zero.) + // very large numbers fail the second test, eliminating infinities + // Not-a-Numbers fail both tests and are eliminated. + return (absx > (float32)1e-15 && absx < (float32)1e15) ? x : (float32)0.; +} + +inline float32 sc_log2(float32 x) +{ + return log(fabs(x)) * rlog2; +} + +inline float32 sc_log10(float32 x) +{ + return log10(fabs(x)); +} + +inline float32 sc_midicps(float32 note) +{ + return (float32)440. * pow((float32)2., (note - (float32)69.) * (float32)0.083333333333); +} + +inline float32 sc_cpsmidi(float32 freq) +{ + return sc_log2(freq * (float32)0.0022727272727) * (float32)12. + (float32)69.; +} + +inline float32 sc_midiratio(float32 midi) +{ + return pow((float32)2. , midi * (float32)0.083333333333); +} + +inline float32 sc_ratiomidi(float32 ratio) +{ + return (float32)12. * sc_log2(ratio); +} + +inline float32 sc_octcps(float32 note) +{ + return (float32)440. * pow((float32)2., note - (float32)4.75); +} + +inline float32 sc_cpsoct(float32 freq) +{ + return sc_log2(freq * (float32)0.0022727272727) + (float32)4.75; +} + +inline float32 sc_ampdb(float32 amp) +{ + return log10(amp) * (float32)20.; +} + +inline float32 sc_dbamp(float32 db) +{ + return pow((float32)10., db * (float32).05); +} + +inline float32 sc_squared(float32 x) +{ + return x * x; +} + +inline float32 sc_cubed(float32 x) +{ + return x * x * x; +} + +inline float32 sc_sqrt(float32 x) +{ + return x < (float32)0. ? -sqrt(-x) : sqrt(x); +} + + +inline float32 sc_hanwindow(float32 x) +{ + if (x < (float32)0. || x > (float32)1.) return (float32)0.; + return (float32)0.5 - (float32)0.5 * cos(x * twopi); +} + +inline float32 sc_welwindow(float32 x) +{ + if (x < (float32)0. || x > (float32)1.) return (float32)0.; + return sin(x * pi); +} + +inline float32 sc_triwindow(float32 x) +{ + if (x < (float32)0. || x > (float32)1.) return (float32)0.; + if (x < (float32)0.5) return (float32)2. * x; + else return (float32)-2. * x + (float32)2.; +} + +inline float32 sc_bitriwindow(float32 x) +{ + float32 ax = (float32)1. - fabs(x); + if (ax <= (float32)0.) return (float32)0.; + return ax; +} + +inline float32 sc_rectwindow(float32 x) +{ + if (x < (float32)0. || x > (float32)1.) return (float32)0.; + return (float32)1.; +} + +inline float32 sc_scurve(float32 x) +{ + if (x <= (float32)0.) return (float32)0.; + if (x >= (float32)1.) return (float32)1.; + return x * x * ((float32)3. - (float32)2. * x); +} + +inline float32 sc_scurve0(float32 x) +{ + // assumes that x is in range + return x * x * ((float32)3. - (float32)2. * x); +} + +inline float32 sc_ramp(float32 x) +{ + if (x <= (float32)0.) return (float32)0.; + if (x >= (float32)1.) return (float32)1.; + return x; +} + +inline float32 sc_distort(float32 x) +{ + return x / ((float32)1. + fabs(x)); +} + +inline float32 sc_softclip(float32 x) +{ + float32 absx = fabs(x); + if (absx <= (float32)0.5) return x; + else return (absx - (float32)0.25) / x; +} + +// Taylor expansion out to x**9/9! factored into multiply-adds +// from Phil Burk. +inline float32 taylorsin(float32 x) +{ + // valid range from -pi/2 to +3pi/2 + x = pi2 - fabs(pi2 - x); + float32 x2 = x * x; + return x*(x2*(x2*(x2*(x2*(1.0/362880.0) + - (1.0/5040.0)) + + (1.0/120.0)) + - (1.0/6.0)) + + 1.0); +} + +inline float32 sc_trunc(float32 x) +{ + // truncFloat is a number which causes a loss of precision of + // the fractional part. + // NOTE: this will only work if the FPU is set to round downward. + // That is NOT the default rounding mode. SC sets it to this mode. + float32 tmp1 = x + truncFloat; + float32 tmp2 = tmp1 - truncFloat; + return tmp2; +} + +inline float32 sc_frac(float32 x) +{ + return x - sc_trunc(x); +} + +inline float32 sc_lg3interp(float32 x1, float32 a, float32 b, float32 c, float32 d) +{ + // cubic lagrange interpolator + float32 x0 = x1 + 1.f; + float32 x2 = x1 - 1.f; + float32 x3 = x1 - 2.f; + + float32 x03 = x0 * x3 * 0.5f; + float32 x12 = x1 * x2 * 0.16666666666666667f; + + return x12 * (d * x0 - a * x3) + x03 * (b * x2 - c * x1); +} + +inline float32 sc_CalcFeedback(float32 delaytime, float32 decaytime) +{ + if (delaytime == 0.f) { + return 0.f; + } else if (decaytime > 0.f) { + return exp(log001 * delaytime / decaytime); + } else if (decaytime < 0.f) { + return -exp(log001 * delaytime / -decaytime); + } else { + return 0.f; + } +} + +inline float32 sc_wrap1(float32 x) +{ + if (x >= (float32) 1.) return x + (float32)-2.; + if (x < (float32)-1.) return x + (float32) 2.; + return x; +} + +inline float32 sc_fold1(float32 x) +{ + if (x >= (float32) 1.) return (float32) 2. - x; + if (x < (float32)-1.) return (float32)-2. - x; + return x; +} + + +/////////////////////////////////////////////////////////////////////////////////////// + +inline float64 zapgremlins(float64 x) +{ + float64 absx = fabs(x); + // very small numbers fail the first test, eliminating denormalized numbers + // (zero also fails the first test, but that is OK since it returns zero.) + // very large numbers fail the second test, eliminating infinities + // Not-a-Numbers fail both tests and are eliminated. + return (absx > (float64)1e-15 && absx < (float64)1e15) ? x : (float64)0.; +} + +inline float64 sc_log2(float64 x) +{ + return log(fabs(x)) * rlog2; +} + +inline float64 sc_log10(float64 x) +{ + return log10(fabs(x)); +} + +inline float64 sc_midicps(float64 note) +{ + return (float64)440. * pow((float64)2., (note - (float64)69.) * (float64)0.083333333333); +} + +inline float64 sc_cpsmidi(float64 freq) +{ + return sc_log2(freq * (float64)0.0022727272727) * (float64)12. + (float64)69.; +} + +inline float64 sc_midiratio(float64 midi) +{ + return pow((float64)2. , midi * (float64)0.083333333333); +} + +inline float64 sc_ratiomidi(float64 ratio) +{ + return (float64)12. * sc_log2(ratio); +} + +inline float64 sc_octcps(float64 note) +{ + return (float64)440. * pow((float64)2., note - (float64)4.75); +} + +inline float64 sc_cpsoct(float64 freq) +{ + return sc_log2(freq * (float64)0.0022727272727) + (float64)4.75; +} + +inline float64 sc_ampdb(float64 amp) +{ + return log10(amp) * (float64)20.; +} + +inline float64 sc_dbamp(float64 db) +{ + return pow((float64)10., db * (float64).05); +} + +inline float64 sc_squared(float64 x) +{ + return x * x; +} + +inline float64 sc_cubed(float64 x) +{ + return x * x * x; +} + +inline float64 sc_sqrt(float64 x) +{ + return x < (float64)0. ? -sqrt(-x) : sqrt(x); +} + +inline float64 sc_hanwindow(float64 x) +{ + if (x < (float64)0. || x > (float64)1.) return (float64)0.; + return (float64)0.5 - (float64)0.5 * cos(x * twopi); +} + +inline float64 sc_welwindow(float64 x) +{ + if (x < (float64)0. || x > (float64)1.) return (float64)0.; + return sin(x * pi); +} + +inline float64 sc_triwindow(float64 x) +{ + if (x < (float64)0. || x > (float64)1.) return (float64)0.; + if (x < (float64)0.5) return (float64)2. * x; + else return (float64)-2. * x + (float64)2.; +} + +inline float64 sc_bitriwindow(float64 x) +{ + float64 ax = fabs(x); + if (ax > (float64)1.) return (float64)0.; + return (float64)1. - ax; +} + +inline float64 sc_rectwindow(float64 x) +{ + if (x < (float64)0. || x > (float64)1.) return (float64)0.; + return (float64)1.; +} + +inline float64 sc_scurve(float64 x) +{ + if (x <= (float64)0.) return (float64)0.; + if (x >= (float64)1.) return (float64)1.; + return x * x * ((float64)3. - (float64)2. * x); +} + +inline float64 sc_scurve0(float64 x) +{ + // assumes that x is in range + return x * x * ((float64)3. - (float64)2. * x); +} + +inline float64 sc_ramp(float64 x) +{ + if (x <= (float64)0.) return (float64)0.; + if (x >= (float64)1.) return (float64)1.; + return x; +} + +inline float64 sc_distort(float64 x) +{ + return x / ((float64)1. + fabs(x)); +} + +inline float64 sc_softclip(float64 x) +{ + float64 absx = fabs(x); + if (absx <= (float64)0.5) return x; + else return (absx - (float64)0.25) / x; +} + +// Taylor expansion out to x**9/9! factored into multiply-adds +// from Phil Burk. +inline float64 taylorsin(float64 x) +{ + x = pi2 - fabs(pi2 - x); + float64 x2 = x * x; + return x*(x2*(x2*(x2*(x2*(1.0/362880.0) + - (1.0/5040.0)) + + (1.0/120.0)) + - (1.0/6.0)) + + 1.0); +} + +inline float64 sc_trunc(float64 x) +{ + // truncDouble is a number which causes a loss of precision of + // the fractional part. + // NOTE: this will only work if the FPU is set to round downward. + // That is NOT the default rounding mode. SC sets it to this mode. + float64 tmp1 = x + truncDouble; + float64 tmp2 = tmp1 - truncDouble; + return tmp2; +} + +inline float64 sc_frac(float64 x) +{ + return x - sc_trunc(x); +} + +inline float64 sc_wrap1(float64 x) +{ + if (x >= (float64) 1.) return x + (float64)-2.; + if (x < (float64)-1.) return x + (float64) 2.; + return x; +} + +inline float64 sc_fold1(float64 x) +{ + if (x >= (float64) 1.) return (float64) 2. - x; + if (x < (float64)-1.) return (float64)-2. - x; + return x; +} + +inline int32 sc_grayCode(int32 x) +{ + return x ^ (x >> 1); +} + + + +/////////////////////////////////////////////////////////////////////////////////////// + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_InterfaceTable.h b/sc4pd/headers/plugin_interface/SC_InterfaceTable.h new file mode 100644 index 0000000..20cb864 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_InterfaceTable.h @@ -0,0 +1,175 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_SynthInterfaceTable_ +#define _SC_SynthInterfaceTable_ + +#include "SC_Types.h" +#include "SC_SndBuf.h" +#include "SC_Unit.h" +#include "SC_BufGen.h" +#include "SC_FifoMsg.h" +#include <sndfile.h> + +struct World; + +typedef bool (*AsyncStageFn)(World *inWorld, void* cmdData); +typedef void (*AsyncFreeFn)(World *inWorld, void* cmdData); + +struct InterfaceTable +{ + unsigned int mSineSize; + float32 *mSineWavetable; + float32 *mSine; + float32 *mCosecant; + + // call printf for debugging. should not use in finished code. + int (*fPrint)(const char *fmt, ...); + + // get a seed for a random number generator + int32 (*fRanSeed)(); + + // define a unit def + bool (*fDefineUnit)(char *inUnitClassName, size_t inAllocSize, + UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags); + + // define a command /cmd + bool (*fDefinePlugInCmd)(char *inCmdName, PlugInCmdFunc inFunc, void* inUserData); + + // define a command for a unit generator /u_cmd + bool (*fDefineUnitCmd)(char *inUnitClassName, char *inCmdName, UnitCmdFunc inFunc); + + // define a buf gen + bool (*fDefineBufGen)(char *inName, BufGenFunc inFunc); + + // clear all of the unit's outputs. + void (*fClearUnitOutputs)(Unit *inUnit, int inNumSamples); + + // non real time memory allocation + void* (*fNRTAlloc)(size_t inSize); + void* (*fNRTRealloc)(void *inPtr, size_t inSize); + void (*fNRTFree)(void *inPtr); + + // real time memory allocation + void* (*fRTAlloc)(World *inWorld, size_t inSize); + void* (*fRTRealloc)(World *inWorld, void *inPtr, size_t inSize); + void (*fRTFree)(World *inWorld, void *inPtr); + + // call to set a Node to run or not. + void (*fNodeRun)(struct Node* node, int run); + + // call to stop a Graph after the next buffer. + void (*fNodeEnd)(struct Node* graph); + + // send a trigger from a Node to clients + void (*fSendTrigger)(struct Node* inNode, int triggerID, float value); + + // sending messages between real time and non real time levels. + bool (*fSendMsgFromRT)(World *inWorld, struct FifoMsg& inMsg); + bool (*fSendMsgToRT)(World *inWorld, struct FifoMsg& inMsg); + + // libsndfile support + int (*fSndFileFormatInfoFromStrings)(SF_INFO *info, + const char *headerFormatString, const char *sampleFormatString); + + // get nodes by id + struct Node* (*fGetNode)(World *inWorld, int inID); + struct Graph* (*fGetGraph)(World *inWorld, int inID); + + void (*fNRTLock)(World *inWorld); + void (*fNRTUnlock)(World *inWorld); + + bool mAltivecAvailable; + + void (*fGroup_DeleteAll)(struct Group* group); + void (*fDoneAction)(int doneAction, struct Unit *unit); + + int (*fDoAsynchronousCommand) + ( + World *inWorld, + void* replyAddr, + const char* cmdName, + void *cmdData, + AsyncStageFn stage2, // stage2 is non real time + AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true + AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true + AsyncFreeFn cleanup, + int completionMsgSize, + void* completionMsgData + ); + + + // fBufAlloc should only be called within a BufGenFunc + int (*fBufAlloc)(SndBuf *inBuf, int inChannels, int inFrames, double inSampleRate); +}; +typedef struct InterfaceTable InterfaceTable; + +#define Print (*ft->fPrint) +#define RanSeed (*ft->fRanSeed) +#define NodeEnd (*ft->fNodeEnd) +#define NodeRun (*ft->fNodeRun) +#define DefineUnit (*ft->fDefineUnit) +#define DefinePlugInCmd (*ft->fDefinePlugInCmd) +#define DefineUnitCmd (*ft->fDefineUnitCmd) +#define DefineBufGen (*ft->fDefineBufGen) +#define ClearUnitOutputs (*ft->fClearUnitOutputs) +#define SendTrigger (*ft->fSendTrigger) +#define SendMsgFromRT (*ft->fSendMsgFromRT) +#define SendMsgToRT (*ft->fSendMsgToRT) +#define DoneAction (*ft->fDoneAction) + +#define NRTAlloc (*ft->fNRTAlloc) +#define NRTRealloc (*ft->fNRTRealloc) +#define NRTFree (*ft->fNRTFree) + +#define RTAlloc (*ft->fRTAlloc) +#define RTRealloc (*ft->fRTRealloc) +#define RTFree (*ft->fRTFree) + +#define SC_GetNode (*ft->fGetNode) +#define SC_GetGraph (*ft->fGetGraph) + +#define NRTLock (*ft->fNRTLock) +#define NRTUnlock (*ft->fNRTUnlock) + +#define BufAlloc (*ft->fBufAlloc) + +#define GroupDeleteAll (*ft->fGroup_DeleteAll) + +#define SndFileFormatInfoFromStrings (*ft->fSndFileFormatInfoFromStrings) + +#define DoAsynchronousCommand (*ft->fDoAsynchronousCommand) + +#define DefineSimpleUnit(name) \ + (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, 0, 0); + +#define DefineDtorUnit(name) \ + (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, \ + (UnitDtorFunc)&name##_Dtor, 0); + +#define DefineSimpleCantAliasUnit(name) \ + (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, 0, kUnitDef_CantAliasInputsToOutputs); + +#define DefineDtorCantAliasUnit(name) \ + (*ft->fDefineUnit)(#name, sizeof(name), (UnitCtorFunc)&name##_Ctor, \ + (UnitDtorFunc)&name##_Dtor, kUnitDef_CantAliasInputsToOutputs); + + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_Node.h b/sc4pd/headers/plugin_interface/SC_Node.h new file mode 100644 index 0000000..36dd412 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_Node.h @@ -0,0 +1,48 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Node_ +#define _SC_Node_ + +#include "SC_Types.h" + +typedef void (*NodeCalcFunc)(struct Node *inNode); + +struct Node +{ + int32 mID; + int32 mHash; + + struct World *mWorld; + struct NodeDef *mDef; + NodeCalcFunc mCalcFunc; + + struct Node *mPrev, *mNext; + struct Group *mParent; + + int32 mIsGroup; +}; +typedef struct Node Node; + +enum { kNode_Go, kNode_End, kNode_On, kNode_Off, kNode_Move, kNode_Info }; + +#endif + diff --git a/sc4pd/headers/plugin_interface/SC_PlugIn.h b/sc4pd/headers/plugin_interface/SC_PlugIn.h new file mode 100644 index 0000000..4f01fd3 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_PlugIn.h @@ -0,0 +1,53 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "SC_World.h" +#include "SC_Graph.h" +#include "SC_Unit.h" +#include "SC_Wire.h" +#include "SC_InterfaceTable.h" +#include "Unroll.h" +#include "SC_InlineUnaryOp.h" +#include "SC_InlineBinaryOp.h" +#include "SC_BoundsMacros.h" +#include "SC_RGen.h" +#include "SC_DemandUnit.h" +#include "clz.h" +#include "sc_msg_iter.h" +#include "SC_Altivec.h" +#include <stdlib.h> + +#ifdef SC_WIN32 + +// temporarily override __attribute__ for (unused), later we'll remove it +#ifndef __GCC__ +#define __attribute__(x) +#endif + +// workaround for IN/OUT conflict with Win32 headers. see SC_Unit.h for details +#define IN SC_IN +#define OUT SC_OUT + +#ifdef _MSC_VER +#include <xmath.h> +#endif //_MSC_VER + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_RGen.h b/sc4pd/headers/plugin_interface/SC_RGen.h new file mode 100644 index 0000000..11f8c9a --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_RGen.h @@ -0,0 +1,288 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +//----------------------------------------------------------------------------// +// Ran088: L'Ecuyer's 1996 three-component Tausworthe generator "taus88" +//----------------------------------------------------------------------------// +// +// Returns an integer random number uniformly distributed within [0,4294967295] +// +// The period length is approximately 2^88 (which is 3*10^26). +// This generator is very fast and passes all standard statistical tests. +// +// Reference: +// (1) P. L'Ecuyer, Maximally equidistributed combined Tausworthe generators, +// Mathematics of Computation, 65, 203-213 (1996), see Figure 4. +// (2) recommended in: +// P. L'Ecuyer, Random number generation, chapter 4 of the +// Handbook on Simulation, Ed. Jerry Banks, Wiley, 1997. +// +//----------------------------------------------------------------------------// + +//----------------------------------------------------------------------------// +// I chose this random number generator for the following reasons: +// fast. +// easier and faster to seed than other high quality rng's such as Mersenne Twister. +// the internal state is only 12 bytes. +// the period is long enough for music/audio. +// possible to code in altivec in future if needed. +// - James McCartney +//----------------------------------------------------------------------------// + +#ifndef _SC_RGen_ +#define _SC_RGen_ + +#include "SC_Endian.h" +#include "SC_Types.h" +#include "SC_BoundsMacros.h" +#include "Hash.h" +#include <math.h> + +struct RGen +{ + void init(uint32 seed); + + uint32 trand(); + + int32 irand(int32 scale); + int32 irand2(int32 scale); + int32 ilinrand(int32 scale); + int32 ibilinrand(int32 scale); + + float fcoin(); + float frand(); + float frand2(); + float frand0(); + float frand8(); + double drand(); + double drand2(double scale); + double linrand(double scale); + double bilinrand(double scale); + double exprandrng(double lo, double hi); + double exprand(double scale); + double biexprand(double scale); + double sum3rand(double scale); + + uint32 s1, s2, s3; // random generator state +}; + +inline void RGen::init(uint32 seed) +{ + // humans tend to use small seeds - mess up the bits + seed = (uint32)Hash((int)seed); + + // initialize seeds using the given seed value taking care of + // the requirements. The constants below are arbitrary otherwise + s1 = 1243598713U ^ seed; if (s1 < 2) s1 = 1243598713U; + s2 = 3093459404U ^ seed; if (s2 < 8) s2 = 3093459404U; + s3 = 1821928721U ^ seed; if (s3 < 16) s3 = 1821928721U; +} + +inline uint32 trand( uint32& s1, uint32& s2, uint32& s3 ) +{ + // This function is provided for speed in inner loops where the + // state variables are loaded into registers. + // Thus updating the instance variables can + // be postponed until the end of the loop. + s1 = ((s1 & -2) << 12) ^ (((s1 << 13) ^ s1) >> 19); + s2 = ((s2 & -8) << 4) ^ (((s2 << 2) ^ s2) >> 25); + s3 = ((s3 & -16) << 17) ^ (((s3 << 3) ^ s3) >> 11); + return s1 ^ s2 ^ s3; +} + +inline uint32 RGen::trand() +{ + // generate a random 32 bit number + s1 = ((s1 & -2) << 12) ^ (((s1 << 13) ^ s1) >> 19); + s2 = ((s2 & -8) << 4) ^ (((s2 << 2) ^ s2) >> 25); + s3 = ((s3 & -16) << 17) ^ (((s3 << 3) ^ s3) >> 11); + return s1 ^ s2 ^ s3; +} + +inline double RGen::drand() +{ + // return a double from 0.0 to 0.999... +#if BYTE_ORDER == BIG_ENDIAN + union { struct { uint32 hi, lo; } i; double f; } du; +#else + union { struct { uint32 lo, hi; } i; double f; } du; +#endif + du.i.hi = 0x41300000; + du.i.lo = trand(); + return du.f - 1048576.; +} + +inline float RGen::frand() +{ + // return a float from 0.0 to 0.999... + union { uint32 i; float f; } u; // union for floating point conversion of result + u.i = 0x3F800000 | (trand() >> 9); + return u.f - 1.f; +} + +inline float RGen::frand0() +{ + // return a float from +1.0 to +1.999... + union { uint32 i; float f; } u; // union for floating point conversion of result + u.i = 0x3F800000 | (trand() >> 9); + return u.f; +} + +inline float RGen::frand2() +{ + // return a float from -1.0 to +0.999... + union { uint32 i; float f; } u; // union for floating point conversion of result + u.i = 0x40000000 | (trand() >> 9); + return u.f - 3.f; +} + +inline float RGen::frand8() +{ + // return a float from -0.125 to +0.124999... + union { uint32 i; float f; } u; // union for floating point conversion of result + u.i = 0x3E800000 | (trand() >> 9); + return u.f - 0.375f; +} + +inline float RGen::fcoin() +{ + // only return one of the two values -1.0 or +1.0 + union { uint32 i; float f; } u; // union for floating point conversion of result + u.i = 0x3F800000 | (0x80000000 & trand()); + return u.f; +} + +inline int32 RGen::irand(int32 scale) +{ + // return an int from 0 to scale - 1 + return (int32)floor(scale * drand()); +} + +inline int32 RGen::irand2(int32 scale) +{ + // return a int from -scale to +scale + return (int32)floor((2. * scale + 1.) * drand() - scale); +} + +inline int32 RGen::ilinrand(int32 scale) +{ + int32 a = irand(scale); + int32 b = irand(scale); + return sc_min(a,b); +} + +inline double RGen::linrand(double scale) +{ + double a = drand(); + double b = drand(); + return sc_min(a,b) * scale; +} + +inline int32 RGen::ibilinrand(int32 scale) +{ + int32 a = irand(scale); + int32 b = irand(scale); + return a - b; +} + +inline double RGen::bilinrand(double scale) +{ + double a = drand(); + double b = drand(); + return (a - b) * scale; +} + +inline double RGen::exprandrng(double lo, double hi) +{ + return lo * exp(log(hi / lo) * drand()); +} + +inline double RGen::exprand(double scale) +{ + double z; + while ((z = drand()) == 0.0) {} + return -log(z) * scale; +} + +inline double RGen::biexprand(double scale) +{ + double z; + while ((z = drand2(1.)) == 0.0 || z == -1.0) {} + if (z > 0.0) z = log(z); + else z = -log(-z); + return z * scale; +} + +inline double RGen::sum3rand(double scale) +{ + // larry polansky's poor man's gaussian generator + return (drand() + drand() + drand() - 1.5) * 0.666666667 * scale; +} + +inline double drand( uint32& s1, uint32& s2, uint32& s3 ) +{ + union { struct { uint32 hi, lo; } i; double f; } u; + u.i.hi = 0x41300000; + u.i.lo = trand(s1,s2,s3); + return u.f - 1048576.; +} + +inline float frand( uint32& s1, uint32& s2, uint32& s3 ) +{ + // return a float from 0.0 to 0.999... + union { uint32 i; float f; } u; + u.i = 0x3F800000 | (trand(s1,s2,s3) >> 9); + return u.f - 1.f; +} + +inline float frand0( uint32& s1, uint32& s2, uint32& s3 ) +{ + // return a float from +1.0 to +1.999... + union { uint32 i; float f; } u; + u.i = 0x3F800000 | (trand(s1,s2,s3) >> 9); + return u.f; +} + +inline float frand2( uint32& s1, uint32& s2, uint32& s3 ) +{ + // return a float from -1.0 to +0.999... + union { uint32 i; float f; } u; + u.i = 0x40000000 | (trand(s1,s2,s3) >> 9); + return u.f - 3.f; +} + +inline float frand8( uint32& s1, uint32& s2, uint32& s3 ) +{ + // return a float from -0.125 to +0.124999... + union { uint32 i; float f; } u; + u.i = 0x3E800000 | (trand(s1,s2,s3) >> 9); + return u.f - 0.375f; +} + +inline float fcoin( uint32& s1, uint32& s2, uint32& s3 ) +{ + // only return one of the two values -1.0 or +1.0 + union { uint32 i; float f; } u; + u.i = 0x3F800000 | (0x80000000 & trand(s1,s2,s3)); + return u.f; +} + +#endif + diff --git a/sc4pd/headers/plugin_interface/SC_Rate.h b/sc4pd/headers/plugin_interface/SC_Rate.h new file mode 100644 index 0000000..63c160d --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_Rate.h @@ -0,0 +1,42 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _Rate_ +#define _Rate_ + +enum { calc_ScalarRate, calc_BufRate, calc_FullRate, calc_DemandRate }; + +struct Rate +{ + double mSampleRate; // samples per second + double mSampleDur; // seconds per sample + double mBufDuration; // seconds per buffer + double mBufRate; // buffers per second + double mSlopeFactor; // 1. / NumSamples + double mRadiansPerSample; // 2pi / SampleRate + int mBufLength; // length of the buffer + // second order filter loops are often unrolled by 3 + int mFilterLoops, mFilterRemain; + double mFilterSlope; +}; +typedef struct Rate Rate; + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_SndBuf.h b/sc4pd/headers/plugin_interface/SC_SndBuf.h new file mode 100644 index 0000000..affd2b9 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_SndBuf.h @@ -0,0 +1,109 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SndBuf_ +#define _SndBuf_ + +#include <sys/types.h> +#include <sndfile.h> + +struct SndBuf +{ + double samplerate; + double sampledur; // = 1/ samplerate + float *data; + int channels; + int samples; + int frames; + int mask; // for delay lines + int mask1; // for interpolating oscillators. + int coord; // used by fft ugens + SNDFILE *sndfile; // used by disk i/o +}; +typedef struct SndBuf SndBuf; + +struct SndBufUpdates +{ + int reads; + int writes; +}; +typedef struct SndBufUpdates SndBufUpdates; + +enum { coord_None, coord_Complex, coord_Polar }; + + +inline float PhaseFrac(unsigned long inPhase) + { + union { unsigned long itemp; float ftemp; } u; + u.itemp = 0x3F800000 | (0x007FFF80 & ((inPhase)<<7)); + return u.ftemp - 1.f; + } + +inline float PhaseFrac1(unsigned long inPhase) + { + union { unsigned long itemp; float ftemp; } u; + u.itemp = 0x3F800000 | (0x007FFF80 & ((inPhase)<<7)); + return u.ftemp; + } + +inline float lookup(float *table, int32 phase, int32 mask) +{ + return table[(phase >> 16) & mask]; +} + + +#define xlobits 14 +#define xlobits1 13 + +inline float lookupi(float *table, uint32 phase, uint32 mask) +{ + float frac = PhaseFrac(phase); + float *tbl = table + ((phase >> 16) & mask); + float a = tbl[0]; + float b = tbl[1]; + return a + frac * (b - a); +} + +inline float lookupi2(float *table, uint32 phase, uint32 mask) +{ + float frac = PhaseFrac1(phase); + float *tbl = table + ((phase >> 16) & mask); + float a = tbl[0]; + float b = tbl[1]; + return a + frac * b; +} + +inline float lookupi1(float* table0, float* table1, uint32 pphase, int32 lomask) +{ + float pfrac = PhaseFrac1(pphase); + uint32 index = ((pphase >> xlobits1) & lomask); + float val1 = *(float*)((char*)table0 + index); + float val2 = *(float*)((char*)table1 + index); + return val1 + val2 * pfrac; +} + + +inline float lininterp(float x, float a, float b) +{ + return a + x * (b - a); +} + + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_Types.h b/sc4pd/headers/plugin_interface/SC_Types.h new file mode 100644 index 0000000..d635b07 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_Types.h @@ -0,0 +1,67 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_Types_ +#define _SC_Types_ + +#include <sys/types.h> + +typedef int SCErr; + +#ifdef SC_WIN32 +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +typedef long long int64; +typedef unsigned long long uint64; +#endif + +typedef int int32; +typedef unsigned int uint32; +#ifdef SC_DARWIN +typedef unsigned int ulong; +#endif + +typedef short int16; +typedef unsigned short uint16; + +typedef signed char int8; +typedef unsigned char uint8; + +typedef float float32; +typedef double float64; + +typedef union { + uint32 u; + int32 i; + float32 f; +} elem32; + +typedef union { + uint64 u; + int64 i; + float64 f; +} elem64; + +const unsigned int kSCNameLen = 8; +const unsigned int kSCNameByteLen = kSCNameLen * sizeof(int32); + +#endif + diff --git a/sc4pd/headers/plugin_interface/SC_Unit.h b/sc4pd/headers/plugin_interface/SC_Unit.h new file mode 100644 index 0000000..2ded017 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_Unit.h @@ -0,0 +1,101 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Unit_ +#define _SC_Unit_ + +#include "SC_Types.h" + +typedef void (*UnitCtorFunc)(struct Unit* inUnit); +typedef void (*UnitDtorFunc)(struct Unit* inUnit); + +typedef void (*UnitCalcFunc)(struct Unit *inThing, int inNumSamples); + +struct Unit +{ + struct World *mWorld; + struct UnitDef *mUnitDef; + struct Graph *mParent; + uint16 mNumInputs, mNumOutputs; + int16 mCalcRate; + int16 mSpecialIndex; // used by unary and binary ops + int16 mParentIndex; + int16 mDone; + + struct Wire **mInput, **mOutput; + struct Rate *mRate; + struct SC_Dimension *mDimension; + float **mInBuf, **mOutBuf; + + UnitCalcFunc mCalcFunc; + int mBufLength; +}; +typedef struct Unit Unit; + +enum { + kUnitDef_CantAliasInputsToOutputs = 1 +}; + +// easy macros, the unit variable must be named 'unit'. +#ifndef SC_WIN32 + +// These return float* pointers to input and output buffers. +#define IN(index) (unit->mInBuf[index]) +#define OUT(index) (unit->mOutBuf[index]) + +// These return a float value. Used for control rate inputs and outputs. +#define IN0(index) (IN(index)[0]) +#define OUT0(index) (OUT(index)[0]) + +#else + +// Win32 headers (included by C std library headers) define IN and OUT macros +// for their own purposes. To avoid problems we don't define IN and OUT here +// but define SC_IN and SC_OUT instead. Source files that use IN and OUT need +// to include definitions of IN, and OUT referencing SC_IN and SC_OUT after +// all headers have been included. +#define SC_IN(index) (unit->mInBuf[index]) +#define SC_OUT(index) (unit->mOutBuf[index]) +#define IN0(index) (SC_IN(index)[0]) +#define OUT0(index) (SC_OUT(index)[0]) + +#endif + +// get the rate of the input. +#define INRATE(index) (unit->mInput[index]->mCalcRate) + +// set the calculation function +#define SETCALC(func) (unit->mCalcFunc = (UnitCalcFunc)&func) + +// calculate a slope for control rate interpolation to audio rate. +#define CALCSLOPE(next,prev) ((next - prev) * unit->mRate->mSlopeFactor) + +// get useful values +#define SAMPLERATE (unit->mRate->mSampleRate) +#define SAMPLEDUR (unit->mRate->mSampleDur) +#define BUFLENGTH (unit->mBufLength) +#define BUFRATE (unit->mRate->mBufRate) +#define BUFDUR (unit->mRate->mBufDuration) + +typedef void (*UnitCmdFunc)(struct Unit *unit, struct sc_msg_iter *args); +typedef void (*PlugInCmdFunc)(World *inWorld, void* inUserData, struct sc_msg_iter *args, void *replyAddr); + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_Wire.h b/sc4pd/headers/plugin_interface/SC_Wire.h new file mode 100644 index 0000000..f2680ac --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_Wire.h @@ -0,0 +1,36 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Wire_ +#define _SC_Wire_ + +#include "SC_Types.h" + +struct Wire +{ + struct Unit *mFromUnit; + int32 mCalcRate; + float32 *mBuffer; + float32 mScalarValue; +}; +typedef struct Wire Wire; + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_World.h b/sc4pd/headers/plugin_interface/SC_World.h new file mode 100644 index 0000000..8586432 --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_World.h @@ -0,0 +1,105 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_World_ +#define _SC_World_ + +#include "SC_Types.h" +#include "SC_Rate.h" +#include "SC_SndBuf.h" +#include "SC_RGen.h" +#include "SC_Lock.h" + +struct World +{ + // a pointer to private implementation, not available to plug-ins. + struct HiddenWorld *hw; + + // a pointer to the table of function pointers that implement the plug-ins' + // interface to the server. + struct InterfaceTable *ft; + + // data accessible to plug-ins : + double mSampleRate; + int mBufLength; + int mBufCounter; + + uint32 mNumAudioBusChannels; + uint32 mNumControlBusChannels; + uint32 mNumInputs; + uint32 mNumOutputs; + + // vector of samples for all audio busses + float *mAudioBus; + + // vector of samples for all control busses + float *mControlBus; + + // these tell if a buss has been written to during a control period + // if the value is equal to mBufCounter then the buss has been touched + // this control period. + int32 *mAudioBusTouched; + int32 *mControlBusTouched; + + uint32 mNumSndBufs; + SndBuf *mSndBufs; + SndBuf *mSndBufsNonRealTimeMirror; + SndBufUpdates *mSndBufUpdates; + + struct Group *mTopGroup; + + Rate mFullRate, mBufRate; + + uint32 mNumRGens; + RGen *mRGen; + + uint32 mNumUnits, mNumGraphs, mNumGroups; + int mSampleOffset; // offset in the buffer of current event time. + + SC_Lock* mNRTLock; + + uint32 mNumSharedControls; + float *mSharedControls; + + bool mRealTime; + bool mRunning; + int mDumpOSC; +}; + +extern "C" { + int scprintf(const char *fmt, ...); +} + +inline SndBuf* World_GetBuf(struct World *inWorld, uint32 index) +{ + if (index > inWorld->mNumSndBufs) index = 0; + return inWorld->mSndBufs + index; +} + +inline SndBuf* World_GetNRTBuf(struct World *inWorld, uint32 index) +{ + if (index > inWorld->mNumSndBufs) index = 0; + return inWorld->mSndBufsNonRealTimeMirror + index; +} + +typedef void (*LoadPlugInFunc)(struct InterfaceTable *); + +#endif diff --git a/sc4pd/headers/plugin_interface/SC_WorldOptions.h b/sc4pd/headers/plugin_interface/SC_WorldOptions.h new file mode 100644 index 0000000..b04850f --- /dev/null +++ b/sc4pd/headers/plugin_interface/SC_WorldOptions.h @@ -0,0 +1,91 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_WorldOptions_ +#define _SC_WorldOptions_ + +#include <stdarg.h> +#include "SC_Types.h" + +typedef int (*PrintFunc)(const char *format, va_list ap); + +struct WorldOptions +{ + const char* mPassword; + uint32 mNumBuffers; + uint32 mMaxLogins; + uint32 mMaxNodes; + uint32 mMaxGraphDefs; + uint32 mMaxWireBufs; + uint32 mNumAudioBusChannels; + uint32 mNumInputBusChannels; + uint32 mNumOutputBusChannels; + uint32 mNumControlBusChannels; + uint32 mBufLength; + uint32 mRealTimeMemorySize; + + int mNumSharedControls; + float *mSharedControls; + + bool mRealTime; + + const char *mNonRealTimeCmdFilename; + const char *mNonRealTimeInputFilename; + const char *mNonRealTimeOutputFilename; + const char *mNonRealTimeOutputHeaderFormat; + const char *mNonRealTimeOutputSampleFormat; + + uint32 mPreferredSampleRate; + uint32 mNumRGens; + + uint32 mPreferredHardwareBufferFrameSize; + + uint32 mLoadGraphDefs; + +#ifdef SC_DARWIN + const char *mInputStreamsEnabled; + const char *mOutputStreamsEnabled; +#endif +}; + +const WorldOptions kDefaultWorldOptions = +{ + 0,1024,64,1024,1024,64,128,8,8,4096,64,8192, 0,0, 1, 0,0,0,0,0, 0, 64, 0, 1 +#ifdef SC_DARWIN + ,0,0 +#endif +}; + +#include "SC_Reply.h" + +extern "C" { + void SetPrintFunc(PrintFunc func); + struct World* World_New(WorldOptions *inOptions); + void World_OpenUDP(struct World *inWorld, int inPort); + void World_OpenTCP(struct World *inWorld, int inPort, int inMaxConnections, int inBacklog); + void World_WaitForQuit(struct World *inWorld); + bool World_SendPacket(struct World *inWorld, int inSize, char *inData, ReplyFunc inFunc); + int World_CopySndBuf(World *world, uint32 index, struct SndBuf *outBuf, bool onlyIfChanged, bool &didChange); + int scprintf(const char *fmt, ...); +} + +#endif + diff --git a/sc4pd/headers/plugin_interface/Unroll.h b/sc4pd/headers/plugin_interface/Unroll.h new file mode 100644 index 0000000..12ae864 --- /dev/null +++ b/sc4pd/headers/plugin_interface/Unroll.h @@ -0,0 +1,249 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + +These macros allow one to write code which can be compiled optimally depending on +what loop constructs the compiler can best generate code. + +*/ + +#ifndef _Unroll_ +#define _Unroll_ + +#if 1 + +// loop type +#define FOR_IS_FASTER 1 +#define WHILE_IS_FASTER 0 +// indexing type +#define PREINCREMENT_IS_FASTER 1 +#define POSTINCREMENT_IS_FASTER 0 + +#else + +// loop type +#define FOR_IS_FASTER 1 +#define WHILE_IS_FASTER 0 +// indexing type +#define PREINCREMENT_IS_FASTER 0 +#define POSTINCREMENT_IS_FASTER 1 + +#endif + + +// LOOPING MACROS : + +#if FOR_IS_FASTER + +#define LOOP(length, stmt) for (int xxi=0; xxi<(length); ++xxi) { stmt; } + +#elif WHILE_IS_FASTER + +#define LOOP(length, stmt) \ + { int xxn = (length); \ + while (--xxn) { \ + stmt; \ + } \ + } + +#endif + + + +// above macros are not friendly to the debugger +#if FOR_IS_FASTER + +#define LooP(length) for (int xxi=0; xxi<(length); ++xxi) + +#elif WHILE_IS_FASTER + +#define LooP(length) for (int xxi=(length); --xxi;) + +#endif + + +// LOOP INDEXING : + +/* +meanings of the indexing macros: + ZXP = dereference and pre or post increment + ZX = dereference + PZ = preincrement (if applicable) + ZP = postincrement (if applicable) + ZOFF = offset from the pointer of the first element of the array + (preincrement requires a ZOFF of 1 which is pre-subtracted from the + base pointer. For other indexing types ZOFF is zero) +*/ + +#if PREINCREMENT_IS_FASTER +#define ZXP(z) (*++(z)) +#define ZX(z) (*(z)) +#define PZ(z) (++(z)) +#define ZP(z) (z) +#define ZOFF (1) +#elif POSTINCREMENT_IS_FASTER +#define ZXP(z) (*(z)++) +#define ZX(z) (*(z)) +#define PZ(z) (z) +#define ZP(z) ((z)++) +#define ZOFF (0) +#endif + +// ACCESSING INLETS AND OUTLETS : + +// unit inputs +#define ZIN(i) (IN(i) - ZOFF) // get buffer pointer offset for iteration +#define ZIN0(i) (IN(i)[0]) // get first sample + +// unit outputs +#define ZOUT(i) (OUT(i) - ZOFF) // get buffer pointer offset for iteration +#define ZOUT0(i) (OUT(i)[0]) // get first sample + +#include "SC_BoundsMacros.h" + +#ifndef NDEBUG +# define NDEBUG +#endif +#include <assert.h> + +inline void Clear(int numSamples, float *out) +{ + //assert((((long)(out+ZOFF) & 7) == 0)); // pointer must be 8 byte aligned + + if ((numSamples & 1) == 0) { + // copying doubles is faster on powerpc. + double *outd = (double*)out - ZOFF; + LOOP(numSamples >> 1, ZXP(outd) = 0.; ); + } else { + out -= ZOFF; + LOOP(numSamples, ZXP(out) = 0.f; ); + } +} + +inline void Copy(int numSamples, float *out, float *in) +{ + // pointers must be 8 byte aligned + //assert((((long)(out+ZOFF) & 7) == 0) && (((long)(in+ZOFF) & 7) == 0)); + if (in == out) return; + if ((numSamples & 1) == 0) { + // copying doubles is faster on powerpc. + double *outd = (double*)out - ZOFF; + double *ind = (double*)in - ZOFF; + LOOP(numSamples >> 1, ZXP(outd) = ZXP(ind); ); + } else { + in -= ZOFF; + out -= ZOFF; + LOOP(numSamples, ZXP(out) = ZXP(in); ); + } +} + +inline void Fill(int numSamples, float *out, float level) +{ + out -= ZOFF; + LOOP(numSamples, ZXP(out) = level; ); +} + +inline void Fill(int numSamples, float *out, float level, float slope) +{ + out -= ZOFF; + LOOP(numSamples, ZXP(out) = level; level += slope; ); +} + +inline void Accum(int numSamples, float *out, float *in) +{ + in -= ZOFF; + out -= ZOFF; + LOOP(numSamples, ZXP(out) += ZXP(in); ); +} + +inline void Scale(int numSamples, float *out, float level) +{ + out -= ZOFF; + LOOP(numSamples, ZXP(out) *= level;); +} + +inline float Scale(int numSamples, float *out, float level, float slope) +{ + out -= ZOFF; + LOOP(numSamples, ZXP(out) *= level; level += slope;); + return level; +} + +inline float Scale(int numSamples, float *out, float *in, float level, float slope) +{ + in -= ZOFF; + out -= ZOFF; + LOOP(numSamples, ZXP(out) = ZXP(in) * level; level += slope;); + return level; +} + +inline float ScaleMix(int numSamples, float *out, float *in, float level, float slope) +{ + in -= ZOFF; + out -= ZOFF; + LOOP(numSamples, ZXP(out) += ZXP(in) * level; level += slope;); + return level; +} + +inline void Scale(int numSamples, float *out, float *in, float level) +{ + in -= ZOFF; + out -= ZOFF; + LOOP(numSamples, ZXP(out) = ZXP(in) * level; ); +} + +// in these the pointers are assumed to already have been pre-offset. +inline void ZCopy(int numSamples, float *out, float *in) +{ + // pointers must be 8 byte aligned + //assert((((long)(out+ZOFF) & 7) == 0) && (((long)(in+ZOFF) & 7) == 0)); + if (in == out) return; + if ((numSamples & 1) == 0) { + // copying doubles is faster on powerpc. + double *outd = (double*)(out + ZOFF) - ZOFF; + double *ind = (double*)(in + ZOFF) - ZOFF; + LOOP(numSamples >> 1, ZXP(outd) = ZXP(ind); ); + } else { + LOOP(numSamples, ZXP(out) = ZXP(in); ); + } +} + +inline void ZClear(int numSamples, float *out) +{ + // pointers must be 8 byte aligned + //assert((((long)(out+ZOFF) & 7) == 0) && (((long)(in+ZOFF) & 7) == 0)); + if ((numSamples & 1) == 0) { + // copying doubles is faster on powerpc. + double *outd = (double*)(out + ZOFF) - ZOFF; + LOOP(numSamples >> 1, ZXP(outd) = 0.; ); + } else { + LOOP(numSamples, ZXP(out) = 0.f; ); + } +} + +inline void ZAccum(int numSamples, float *out, float *in) +{ + LOOP(numSamples, ZXP(out) += ZXP(in); ); +} + + + +#endif diff --git a/sc4pd/headers/plugin_interface/clz.h b/sc4pd/headers/plugin_interface/clz.h new file mode 100644 index 0000000..f205c02 --- /dev/null +++ b/sc4pd/headers/plugin_interface/clz.h @@ -0,0 +1,195 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + +count leading zeroes function and those that can be derived from it + +*/ + + +#ifndef _CLZ_ +#define _CLZ_ + +#include "SC_Types.h" + +#ifdef __MWERKS__ + +#define __PPC__ 1 +#define __X86__ 0 + +// powerpc native count leading zeroes instruction: +#define CLZ(x) ((int)__cntlzw((unsigned int)x)) + +#elif defined(SC_WIN32) && !defined(__GCC__) + +static int32 CLZ( int32 arg ) +{ + __asm{ + bsr eax, arg + jnz non_zero + mov arg, 32 + jmp end +non_zero: + xor eax, 31 + mov arg, eax +end: + } + return arg; +} + +#elif defined(__ppc__) || defined(__powerpc__) || defined(__PPC__) + +static __inline__ int32 CLZ(int32 arg) { + __asm__ volatile("cntlzw %0, %1" : "=r" (arg) : "r" (arg)); + return arg; +} + +#elif defined(__i386__) || defined(__x86_64__) +static __inline__ int32 CLZ(int32 arg) { + if (arg) { + __asm__ volatile("bsrl %0, %0\nxorl $31, %0\n" + : "=r" (arg) : "0" (arg)); + } else { + arg = 32; + } + return arg; +} + +#else +# error "clz.h: Unsupported architecture" +#endif + +// count trailing zeroes +inline int32 CTZ(int32 x) +{ + return 32 - CLZ(~x & (x-1)); +} + +// count leading ones +inline int32 CLO(int32 x) +{ + return CLZ(~x); +} + +// count trailing ones +inline int32 CTO(int32 x) +{ + return 32 - CLZ(x & (~x-1)); +} + +// number of bits required to represent x. +inline int32 NUMBITS(int32 x) +{ + return 32 - CLZ(x); +} + +// log2 of the next power of two greater than or equal to x. +inline int32 LOG2CEIL(int32 x) +{ + return 32 - CLZ(x - 1); +} + +// next power of two greater than or equal to x +inline int32 NEXTPOWEROFTWO(int32 x) +{ + return 1L << LOG2CEIL(x); +} + +// is x a power of two +inline bool ISPOWEROFTWO(int32 x) +{ + return (x & (x-1)) == 0; +} + +// input a series of counting integers, outputs a series of gray codes . +inline int32 GRAYCODE(int32 x) +{ + return x & (x>>1); +} + +// find least significant bit +inline int32 LSBit(int32 x) +{ + return x & -x; +} + +// find least significant bit position +inline int32 LSBitPos(int32 x) +{ + return CTZ(x & -x); +} + +// find most significant bit position +inline int32 MSBitPos(int32 x) +{ + return 31 - CLZ(x); +} + +// find most significant bit +inline int32 MSBit(int32 x) +{ + return 1L << MSBitPos(x); +} + +// count number of one bits +inline uint32 ONES(uint32 x) +{ + uint32 t; + x = x - ((x >> 1) & 0x55555555); + t = ((x >> 2) & 0x33333333); + x = (x & 0x33333333) + t; + x = (x + (x >> 4)) & 0x0F0F0F0F; + x = x + (x << 8); + x = x + (x << 16); + return x >> 24; +} + +// count number of zero bits +inline uint32 ZEROES(uint32 x) +{ + return ONES(~x); +} + + +// reverse bits in a word +inline uint32 BitReverse(uint32 x) +{ + x = ((x & 0xAAAAAAAA) >> 1) | ((x & 0x55555555) << 1); + x = ((x & 0xCCCCCCCC) >> 2) | ((x & 0x33333333) << 2); + x = ((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4); + x = ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8); + return (x >> 16) | (x << 16); +} + +// barrel shifts +inline uint32 RotateRight (uint32 x, uint32 s) +{ + s = s & 31; + return (x << (32-s)) | (x >> s); +} + +inline uint32 RotateLeft (uint32 x, uint32 s) +{ + s = s & 31; + return (x >> (32-s)) | (x << s); +} + +#endif + diff --git a/sc4pd/headers/plugin_interface/sc_msg_iter.h b/sc4pd/headers/plugin_interface/sc_msg_iter.h new file mode 100644 index 0000000..240a30f --- /dev/null +++ b/sc4pd/headers/plugin_interface/sc_msg_iter.h @@ -0,0 +1,264 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _sc_msg_iter_ +#define _sc_msg_iter_ + +#include "SC_Endian.h" +#include "SC_Types.h" +#include <string.h> + +// return the ptr to the byte after the OSC string. +inline char* OSCstrskip(char *str) +{ +// while (str[3]) { str += 4; } +// return str + 4; + do { str += 4; } while (str[-1]); + return str; +} + +// returns the number of bytes (including padding) for an OSC string. +inline int OSCstrlen(char *strin) +{ + return OSCstrskip(strin) - strin; +} + +// returns a float, converting an int if necessary +inline float32 OSCfloat(char* inData) +{ + elem32* elem = (elem32*)inData; + elem->u = ntohl(elem->u); + return elem->f; +} + +inline int32 OSCint(char* inData) +{ + return (int32)ntohl(*(uint32*)inData); +} + +inline int64 OSCtime(char* inData) +{ + return ((int64)ntohl(*(uint32*)inData) << 32) + (ntohl(*(uint32*)(inData + 4))); +} + +inline float64 OSCdouble(char* inData) +{ + elem64 slot; + slot.i = ((int64)ntohl(*(uint32*)inData) << 32) + (ntohl(*(uint32*)(inData + 4))); + return slot.f; +} + +struct sc_msg_iter +{ + char *data, *rdpos, *endpos, *tags; + int size, count; + + sc_msg_iter(); + sc_msg_iter(int inSize, char* inData); + void init(int inSize, char* inData); + int32 geti(int32 defaultValue = 0); + float32 getf(float32 defaultValue = 0.f); + float64 getd(float64 defaultValue = 0.f); + char *gets(char* defaultValue = 0); + int32 *gets4(char* defaultValue = 0); + size_t getbsize(); + void getb(char* outData, size_t inSize); + void skipb(); + int remain() { return endpos - rdpos; } + + char nextTag(char defaultTag = 'f') { return tags ? tags[count] : defaultTag; } +}; + +inline sc_msg_iter::sc_msg_iter() +{ +} + +inline sc_msg_iter::sc_msg_iter(int inSize, char* inData) +{ + init(inSize, inData); +} + +inline void sc_msg_iter::init(int inSize, char* inData) +{ + data = inData; + size = inSize; + endpos = data + size; + count = 0; + if (data[0] == ',') { + tags = data+1; + rdpos = OSCstrskip(data); + } else { + tags = 0; + rdpos = data; + } +} + +inline int32 sc_msg_iter::geti(int32 defaultValue) +{ + int value; + if (remain() <= 0) return defaultValue; + if (tags) { + if (tags[count] == 'i') { + value = OSCint(rdpos); + rdpos += sizeof(int32); + } else if (tags[count] == 'f') { + value = (int32)OSCfloat(rdpos); + rdpos += sizeof(float32); +/* } else if (tags[count] == 's') { + value = atoi(rdpos); + rdpos = OSCstrskip(rdpos); +*/ + } else { + value = defaultValue; + } + } else { + value = (int)OSCint(rdpos); + rdpos += sizeof(int32); + } + count ++; + return value; +} + +inline float32 sc_msg_iter::getf(float32 defaultValue) +{ + float32 value; + if (remain() <= 0) return defaultValue; + if (tags) { + if (tags[count] == 'f') { + value = OSCfloat(rdpos); + rdpos += sizeof(float32); + } else if (tags[count] == 'd') { + value = (float64)OSCdouble(rdpos); + rdpos += sizeof(float64); + } else if (tags[count] == 'i') { + value = (float32)OSCint(rdpos); + rdpos += sizeof(int32); +/* } else if (tags[count] == 's') { + value = atof(rdpos); + rdpos = OSCstrskip(rdpos); +*/ + } else { + value = defaultValue; + } + } else { + value = OSCfloat(rdpos); + rdpos += sizeof(float32); + } + count ++; + return value; +} + +inline float64 sc_msg_iter::getd(float64 defaultValue) +{ + float64 value; + if (remain() <= 0) return defaultValue; + if (tags) { + if (tags[count] == 'f') { + value = (float64)OSCfloat(rdpos); + rdpos += sizeof(float32); + } else if (tags[count] == 'd') { + value = OSCdouble(rdpos); + rdpos += sizeof(float64); + } else if (tags[count] == 'i') { + value = (float64)OSCint(rdpos); + rdpos += sizeof(int32); +/* } else if (tags[count] == 's') { + value = atof(rdpos); + rdpos = OSCstrskip(rdpos); +*/ + } else { + value = defaultValue; + } + } else { + value = OSCdouble(rdpos); + rdpos += sizeof(float64); + } + count ++; + return value; +} + + +inline char* sc_msg_iter::gets(char* defaultValue) +{ + char* value; + if (remain() <= 0) return 0; + if (tags) { + if (tags[count] == 's') { + value = rdpos; + rdpos = OSCstrskip(rdpos); + } else { + value = defaultValue; + } + } else { + value = rdpos; + rdpos = OSCstrskip(rdpos); + } + count ++; + return value; +} + +inline int32* sc_msg_iter::gets4(char* defaultValue) +{ + int32* value; + if (remain() <= 0) return 0; + if (tags) { + if (tags[count] == 's') { + value = (int32*)rdpos; + rdpos = OSCstrskip(rdpos); + } else { + value = (int32*)defaultValue; + } + } else { + value = (int32*)rdpos; + rdpos = OSCstrskip(rdpos); + } + count ++; + return value; +} + +inline size_t sc_msg_iter::getbsize() +{ + if (remain() <= 0) return 0; + if (tags && tags[count] != 'b') return 0; + return (size_t)OSCint(rdpos); +} + +inline void sc_msg_iter::getb(char* outArray, size_t size) +{ + size_t len = OSCint(rdpos); + if (size < len) return; + rdpos += sizeof(int32); + size_t len4 = (len + 3) & -4; + memcpy(outArray, rdpos, size); + rdpos += len4; + count ++; +} + +inline void sc_msg_iter::skipb() +{ + size_t len = OSCint(rdpos); + rdpos += sizeof(int32); + size_t len4 = (len + 3) & -4; + rdpos += len4; + count ++; +} + +#endif diff --git a/sc4pd/headers/server/HashTable.h b/sc4pd/headers/server/HashTable.h new file mode 100644 index 0000000..85da92c --- /dev/null +++ b/sc4pd/headers/server/HashTable.h @@ -0,0 +1,356 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _HashTable_ +#define _HashTable_ + +#include "SC_Types.h" +#include "SC_BoundsMacros.h" +#include "SC_Str4.h" +#include "Hash.h" +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +template<class T, class Allocator> +class HashTable +{ + Allocator *mPool; + int32 mNumItems, mMaxItems, mTableSize, mHashMask; + T** mItems; + bool mCanResize; + +public: + + HashTable(Allocator *inPool, int32 inMaxItems, bool inCanResize = true) + : mPool(inPool) + { + mNumItems = 0; + mMaxItems = inMaxItems; + mTableSize = mMaxItems << 1; + mItems = AllocTable(mTableSize); + mHashMask = mTableSize - 1; + mCanResize = inCanResize; + } + + ~HashTable() { + mPool->Free(mItems); + } + + int32 TableSize() const { return mTableSize; } + int32 MaxItems() const { return mMaxItems; } + int32 NumItems() const { return mNumItems; } + + T** AllocTable(int inTableSize) + { + size_t size = inTableSize * sizeof(T*); + T** items = static_cast<T**>(mPool->Alloc(size)); + for (int i=0; i<inTableSize; ++i) { + items[i] = 0; + } + return items; + } + + void MakeEmpty() + { + for (int i=0; i<mTableSize; ++i) { + mItems[i] = 0; + } + mNumItems = 0; + } + + void Resize() + { + int32 newSize = sc_max(mTableSize << 1, 32); + int32 oldSize = mTableSize; + T** oldItems = mItems; + mItems = AllocTable(newSize); + mTableSize = newSize; + mMaxItems = mTableSize >> 1; + mHashMask = mTableSize - 1; + mNumItems = 0; + for (int i=0; i<oldSize; ++i) { + T* item = oldItems[i]; + if (item) Add(item); + } + mPool->Free(oldItems); + //printf("mMaxItems %d mTableSize %d newSize %d\n", mMaxItems, mTableSize, newSize); + } + + bool Add(T* inItem) + { + //printf("mNumItems %d\n", mNumItems); + //printf("mMaxItems %d\n", mMaxItems); + //printf("mCanResize %d\n", mCanResize); + if (mNumItems >= mMaxItems) { + if (!mCanResize) return false; + Resize(); + } + + //printf("GetHash(inItem) %d\n", GetHash(inItem)); + //printf("GetKey(inItem) %s\n", GetKey(inItem)); + int32 index = IndexFor(GetHash(inItem), (int32*)GetKey(inItem)); + //printf("index %d\n", index); + + T *item = mItems[index]; + if (item) return item == inItem; + + mItems[index] = inItem; + mNumItems++; + return true; + } + + bool Remove(T* inItem) + { + int32 index = IndexFor(GetHash(inItem), (int32*)GetKey(inItem)); + if (mItems[index] != inItem) return false; + mItems[index] = 0; + + FixCollisionsFrom(index); + mNumItems--; + return true; + } + + bool RemoveKey(int32* inKey) + { + T* item = Get(inKey); + if (!item) return false; + return Remove(item); + } + + int32 IndexFor(int32 inHashID, int32* inKey) const + { + int index = inHashID & mHashMask; + for(;;) { + T *item = mItems[index]; + if (!item) return index; + if (GetHash(item) == inHashID && str4eq(inKey, GetKey(item))) return index; + index = (index + 1) & mHashMask; + } + } + + T* Get(int32* inKey) const + { + return Get(Hash(inKey), inKey); + } + + T* Get(int32 inHashID, int32* inKey) const + { + //printf("Get hash %d %s\n", inHashID, inKey); + int32 index = IndexFor(inHashID, inKey); + //printf("index %d\n", index); + return mItems[index]; + } + + bool Includes(T* inItem) const + { + return Get(GetHash(inItem), GetKey(inItem)) == inItem; + } + + T* AtIndex(int32 inIndex) const + { + return mItems[inIndex]; + } + +private: + void FixCollisionsFrom(int32 inIndex) + { + int oldIndex = inIndex; + for (;;) { + oldIndex = (oldIndex + 1) & mHashMask; + T *oldItem = mItems[oldIndex]; + if (!oldItem) break; + int newIndex = IndexFor(GetHash(oldItem), (int32*)GetKey(oldItem)); + if (oldIndex != newIndex) { + mItems[oldIndex] = mItems[newIndex]; + mItems[newIndex] = oldItem; + } + } + } +}; + + +template<class T, class Allocator> +class IntHashTable +{ + Allocator *mPool; + int32 mNumItems, mMaxItems, mTableSize, mHashMask; + T** mItems; + bool mCanResize; + +public: + + IntHashTable(Allocator *inPool, int32 inMaxItems, bool inCanResize = true) + : mPool(inPool) + { + mNumItems = 0; + mMaxItems = inMaxItems; + mTableSize = mMaxItems << 1; + mItems = AllocTable(mTableSize); + mHashMask = mTableSize - 1; + mCanResize = inCanResize; + } + + ~IntHashTable() { + mPool->Free(mItems); + } + + int32 TableSize() const { return mTableSize; } + int32 MaxItems() const { return mMaxItems; } + int32 NumItems() const { return mNumItems; } + + T** AllocTable(int inTableSize) + { + size_t size = inTableSize * sizeof(T*); + T** items = static_cast<T**>(mPool->Alloc(size)); + for (int i=0; i<inTableSize; ++i) { + items[i] = 0; + } + return items; + } + + void Resize() + { + int32 newSize = sc_max(mTableSize << 1, 32); + T** oldItems = mItems; + mItems = AllocTable(newSize); + for (int i=0; i<mTableSize; ++i) { + T* item = oldItems[i]; + if (item) Add(item); + } + mTableSize = newSize; + mMaxItems = mTableSize >> 1; + mHashMask = mTableSize - 1; + mPool->Free(oldItems); + //printf("mMaxItems %d mTableSize %d newSize %d\n", mMaxItems, mTableSize, newSize); + } + + bool Add(T* inItem) + { + //printf("mNumItems %d\n", mNumItems); + //printf("mMaxItems %d\n", mMaxItems); + //printf("mCanResize %d\n", mCanResize); + if (mNumItems >= mMaxItems) { + if (!mCanResize) return false; + Resize(); + } + + //printf("GetHash(inItem) %d\n", GetHash(inItem)); + //printf("GetKey(inItem) %d\n", GetKey(inItem)); + int32 index = IndexFor(GetHash(inItem), GetKey(inItem)); + //printf("index %d\n", index); + + T *item = mItems[index]; + if (item) return item == inItem; + + mItems[index] = inItem; + mNumItems++; + return true; + } + + bool Remove(T* inItem) + { + int32 index = IndexFor(GetHash(inItem), GetKey(inItem)); + //printf("rmv index %d hash %d key %d\n", index, GetHash(inItem), GetKey(inItem)); + if (mItems[index] != inItem) return false; + mItems[index] = 0; + + FixCollisionsFrom(index); + mNumItems--; + return true; + } + + bool RemoveKey(int32 inKey) + { + T* item = Get(inKey); + if (!item) return false; + return Remove(item); + } + + int32 IndexFor(int32 inHashID, int32 inKey) const + { + int index = inHashID & mHashMask; + for(;;) { + T *item = mItems[index]; + if (!item) return index; + if (GetHash(item) == inHashID && inKey == GetKey(item)) return index; + index = (index + 1) & mHashMask; + } + } + + T* Get(int32 inKey) const + { + //printf("Get key %d\n", inKey); + return Get(Hash(inKey), inKey); + } + + T* Get(int32 inHashID, int32 inKey) const + { + int32 index = IndexFor(inHashID, inKey); + //printf("Get index %d hash %d key %d\n", index, inHashID, inKey); + return mItems[index]; + } + + bool Includes(T* inItem) const + { + return Get(GetHash(inItem), GetKey(inItem)) == inItem; + } + + T* AtIndex(int32 inIndex) const + { + return mItems[inIndex]; + } + + void Dump() + { + for (int i=0; i<mTableSize; ++i) { + T* item = mItems[i]; + if (item) { + printf("%4d %4d %08X %08X\n", i, GetKey(item), GetHash(item), item); + } + } + } + +private: + void FixCollisionsFrom(int32 inIndex) + { + //printf("FixCollisionsFrom %d\n", inIndex); + int oldIndex = inIndex; + for (;;) { + oldIndex = (oldIndex + 1) & mHashMask; + T *oldItem = mItems[oldIndex]; + if (!oldItem) break; + int newIndex = IndexFor(GetHash(oldItem), GetKey(oldItem)); + if (oldIndex != newIndex) { + //printf("swap %d %d\n", oldIndex, newIndex); + mItems[oldIndex] = mItems[newIndex]; + mItems[newIndex] = oldItem; + } + } + } +}; + +struct Malloc +{ + void Free(void* ptr) { free(ptr); } + void* Alloc(size_t size) { return malloc(size); } +}; + +#endif diff --git a/sc4pd/headers/server/IntFifo.h b/sc4pd/headers/server/IntFifo.h new file mode 100644 index 0000000..3dde5ec --- /dev/null +++ b/sc4pd/headers/server/IntFifo.h @@ -0,0 +1,87 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _IntFifo_ +#define _IntFifo_ + +#ifdef SC_DARWIN +# include <CoreServices/CoreServices.h> +#endif + +template <int N> +class IntFifo +{ +public: + IntFifo() + : mMask(N - 1), mReadHead(0), mWriteHead(0) + {} + + void MakeEmpty() { mReadHead = mWriteHead; } + bool IsEmpty() { return mReadHead == mWriteHead; } + bool HasData() { return mReadHead != mWriteHead; } + + bool Put(int data) + { + long next = NextPos(mWriteHead); + if (next == mReadHead) return false; // fifo is full + mItems[next] = data; +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mWriteHead, next, &mWriteHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mWriteHead),next); +#else + mWriteHead = next; +#endif + return true; + } + + int32 Get() + { + //assert(HasData()); + long next = NextPos(mReadHead); + out = mItems[next].Perform(); +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mReadHead, next, &mReadHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mReadHead),next); +#else + mReadHead = next; +#endif + } + +private: + int NextPos(int inPos) { return (inPos + 1) & mMask; } + + long mMask; +#ifdef SC_DARWIN + UInt32 mReadHead, mWriteHead; +#else + volatile int mReadHead, mWriteHead; +#endif + int32 mItems[N]; +}; + +#endif + + diff --git a/sc4pd/headers/server/MsgFifo.h b/sc4pd/headers/server/MsgFifo.h new file mode 100644 index 0000000..cdc8578 --- /dev/null +++ b/sc4pd/headers/server/MsgFifo.h @@ -0,0 +1,169 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _MsgFifo_ +#define _MsgFifo_ + +#ifdef SC_DARWIN +# include <CoreServices/CoreServices.h> +#endif + +///////////////////////////////////////////////////////////////////// + +template <class MsgType, int N> +class MsgFifo +{ +public: + MsgFifo() + : mReadHead(0), mWriteHead(0), mFreeHead(0) + {} + + void MakeEmpty() { mFreeHead = mReadHead = mWriteHead; } + bool IsEmpty() { return mReadHead == mWriteHead; } + bool HasData() { return mReadHead != mWriteHead; } + bool NeedsFree() { return mFreeHead != mReadHead; } + + bool Write(MsgType& data) + { + unsigned int next = NextPos(mWriteHead); + if (next == mFreeHead) return false; // fifo is full + mItems[next] = data; +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mWriteHead, next, &mWriteHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mWriteHead),next); +#else + mWriteHead = next; +#endif + return true; + } + + void Perform() // get next and advance + { + while (HasData()) { + unsigned int next = NextPos(mReadHead); + mItems[next].Perform(); +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mReadHead, next, &mReadHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mReadHead),next); +#else + mReadHead = next; +#endif + } + } + void Free() // reclaim messages + { + while (NeedsFree()) { + unsigned int next = NextPos(mFreeHead); + mItems[next].Free(); +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mFreeHead, next, &mFreeHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mFreeHead),next); +#else + mFreeHead = next; +#endif + } + } + +private: + int NextPos(int inPos) { return (inPos + 1) & (N - 1); } + +#ifdef SC_DARWIN + UInt32 mReadHead, mWriteHead, mFreeHead; +#else + volatile unsigned int mReadHead, mWriteHead, mFreeHead; +#endif + MsgType mItems[N]; +}; + +///////////////////////////////////////////////////////////////////// + +template <class MsgType, int N> +class MsgFifoNoFree +{ +public: + MsgFifoNoFree() + : mReadHead(0), mWriteHead(0) + { + } + + void MakeEmpty() { mReadHead = mWriteHead; } + bool IsEmpty() { return mReadHead == mWriteHead; } + bool HasData() { return mReadHead != mWriteHead; } + + bool Write(MsgType& data) + { + unsigned int next = NextPos(mWriteHead); + if (next == mReadHead) return false; // fifo is full + mItems[next] = data; +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mWriteHead, next, &mWriteHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mWriteHead),next); +#else + mWriteHead = next; +#endif + return true; + } + + void Perform() // get next and advance + { + while (HasData()) { + unsigned int next = NextPos(mReadHead); + mItems[next].Perform(); +#ifdef SC_DARWIN + // we don't really need a compare and swap, but this happens to call + // the PowerPC memory barrier instruction lwsync. + CompareAndSwap(mReadHead, next, &mReadHead); +#elif defined SC_WIN32 + InterlockedExchange(reinterpret_cast<volatile LONG*>(&mReadHead),next); +#else + mReadHead = next; +#endif + } + } + +private: + int NextPos(int inPos) { return (inPos + 1) & (N - 1); } + +#ifdef SC_DARWIN + UInt32 mReadHead, mWriteHead; +#else + volatile unsigned int mReadHead, mWriteHead; +#endif + MsgType mItems[N]; +}; + +///////////////////////////////////////////////////////////////////// + + +#endif + + diff --git a/sc4pd/headers/server/OSC_Packet.h b/sc4pd/headers/server/OSC_Packet.h new file mode 100644 index 0000000..5964e81 --- /dev/null +++ b/sc4pd/headers/server/OSC_Packet.h @@ -0,0 +1,43 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +/* + * OSC_Packet.h + * SC3synth + * + * Created by James McCartney on Sat Aug 24 2002. + * Copyright (c) 2001 __MyCompanyName__. All rights reserved. + * + */ + +#ifndef _OSC_Packet_ +#define _OSC_Packet_ + +#include "SC_Reply.h" + +struct OSC_Packet +{ + char *mData; + int32 mSize; + bool mIsBundle; + + ReplyAddress mReplyAddr; +}; + +#endif diff --git a/sc4pd/headers/server/PriorityQueue.h b/sc4pd/headers/server/PriorityQueue.h new file mode 100644 index 0000000..eb1064f --- /dev/null +++ b/sc4pd/headers/server/PriorityQueue.h @@ -0,0 +1,123 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _PriorityQueue_ +#define _PriorityQueue_ + +#include <stdio.h> +#include <math.h> +#include <stdexcept> + +#define SANITYCHECK 0 + +#ifdef SC_WIN32 +const int64 kMaxInt64 = 0x7FFFFFFFFFFFFFFF; +#else +const int64 kMaxInt64 = ~(1LL<<63); +#endif + +template <class Event, int N> +class PriorityQueueT +{ +public: + PriorityQueueT() { + Empty(); + } + + bool Add(Event& inEvent) + { + if (mSize >= N) return false; + long mom = mSize++; + long me = mom; + for (; mom>0;) { /* percolate up heap */ + mom = mom - 1 >> 1; + if (inEvent.mTime < mEvents[mom].mTime) { + mEvents[me] = mEvents[mom]; + me = mom; + } else break; + } + mEvents[me] = inEvent; +#if SANITYCHECK + SanityCheck(); +#endif + return true; + } + void Perform(int64 inTime) + { + while (NextTime() <= inTime) { + Event event = Remove(); + event.Perform(); + } + } + int64 NextTime() { return mEvents[0].mTime; } + bool Ready(int64 inTime) { return NextTime() <= inTime; } + void Flush() { Perform(kMaxInt64); } + void Empty() { mSize = 0; SetEmptyTime(); } + void SetEmptyTime() { mEvents[0].mTime = kMaxInt64; } + int Size() { return mSize; } + + Event Remove() + { + Event event = mEvents[0]; + if (--mSize == 0) SetEmptyTime(); + else { + Event temp = mEvents[mSize]; + long mom = 0; + long me = 1; + for (;me < mSize;) { /* demote heap */ + if (me+1 < mSize && mEvents[me].mTime > mEvents[me+1].mTime) { + me ++; + } + if (temp.mTime > mEvents[me].mTime) { + mEvents[mom] = mEvents[me]; + mom = me; + me = (me << 1) + 1; + } else break; + } + mEvents[mom] = temp; + } +#if SANITYCHECK + SanityCheck(); +#endif + return event; + } + void SanityCheck() + { + for (int i=0; i<mSize; ++i) + { + int j = (i<<1)+1; + int k = j+1; + //if (j<mSize && mEvents[i].mTime > mEvents[j].mTime) throw std::runtime_error("priority queue unsorted"); + //if (k<mSize && mEvents[i].mTime > mEvents[k].mTime) throw std::runtime_error("priority queue unsorted"); + } + } + void DebugDump() + { + for (int i=0; i<mSize; ++i) + { + printf("%d %016llX\n", i, mEvents[i].mTime); + } + } +private: + int mSize; + Event mEvents[N]; +}; + +#endif diff --git a/sc4pd/headers/server/ReadWriteMacros.h b/sc4pd/headers/server/ReadWriteMacros.h new file mode 100644 index 0000000..a1bd226 --- /dev/null +++ b/sc4pd/headers/server/ReadWriteMacros.h @@ -0,0 +1,430 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _ReadWriteMacros_ +#define _ReadWriteMacros_ + +#include "SC_Types.h" +#include <stdio.h> +#include <string.h> + +inline void writeData(char *&buf, char *data, int size) +{ + memcpy(buf, data, size); + buf += size; +} + +inline void writeZero(char *&buf, int len) +{ + for (int i=0; i<len; ++i) *buf++ = 0; +} + +inline void writeSkip(char *&buf, int len) +{ + buf += len; +} + +inline void writeInt8(char *&buf, int8 inInt) +{ + *buf++ = (char)(inInt & 255); +} + +inline void writeUInt8(char *&buf, uint8 inInt) +{ + *buf++ = (char)(inInt & 255); +} + +inline void writeInt16_be(char *&buf, int16 inInt) +{ + *buf++ = (char)((inInt >> 8) & 255); + *buf++ = (char)(inInt & 255); +} + +inline void writeInt16_le(char *&buf, int16 inInt) +{ + *buf++ = (char)(inInt & 255); + *buf++ = (char)((inInt >> 8) & 255); +} + +inline void writeInt32_be(char *&buf, int32 inInt) +{ + *buf++ = (char)((inInt >> 24) & 255); + *buf++ = (char)((inInt >> 16) & 255); + *buf++ = (char)((inInt >> 8) & 255); + *buf++ = (char)(inInt & 255); +} + +inline void writeInt32_le(char *&buf, int32 inInt) +{ + *buf++ = (char)(inInt & 255); + *buf++ = (char)((inInt >> 8) & 255); + *buf++ = (char)((inInt >> 16) & 255); + *buf++ = (char)((inInt >> 24) & 255); +} + +inline void writeSymbol(char *&buf, char *inString) +{ + size_t length = strlen(inString); + writeUInt8(buf, (uint8)length); + memcpy(buf, inString, length); + buf += length; +} + +inline void writeString(char *&buf, char *inString, size_t inLength) +{ + writeInt32_be(buf, inLength); + memcpy(buf, inString, inLength); + buf += inLength; +} + +inline void writeString(char *&buf, char *inString) +{ + size_t length = strlen(inString); + writeString(buf, inString, length); +} + + + +inline void writeData(FILE *file, char *data, size_t size) +{ + fwrite(data, 1, size, file); +} + +inline void writeInt8(FILE *file, int8 inInt) +{ + fputc(inInt & 255, file); +} + +inline void writeUInt8(FILE *file, uint8 inInt) +{ + fputc(inInt & 255, file); +} + +inline void writeInt16_be(FILE *file, int16 inInt) +{ + fputc((inInt >> 8) & 255, file); + fputc(inInt & 255, file); +} + +inline void writeInt16_le(FILE *file, int16 inInt) +{ + fputc(inInt & 255, file); + fputc((inInt >> 8) & 255, file); +} + +inline void writeInt32_be(FILE *file, int32 inInt) +{ + fputc((inInt >> 24) & 255, file); + fputc((inInt >> 16) & 255, file); + fputc((inInt >> 8) & 255, file); + fputc(inInt & 255, file); +} + +inline void writeInt64_be(FILE *file, int64 inInt) +{ + writeInt32_be(file, (int32)((inInt >> 32) & 0x00000000FFFFFFFF)); + writeInt32_be(file, (int32)(inInt)); +} + +inline void writeInt32_le(FILE *file, int32 inInt) +{ + fputc(inInt & 255, file); + fputc((inInt >> 8) & 255, file); + fputc((inInt >> 16) & 255, file); + fputc((inInt >> 24) & 255, file); +} + +inline void writeFloat_be(FILE *file, float inFloat) +{ + union { + float f; + int32 i; + } u; + u.f = inFloat; + writeInt32_be(file, u.i); +} + +inline void writeFloat_le(FILE *file, float inFloat) +{ + union { + float f; + int32 i; + } u; + u.f = inFloat; + writeInt32_le(file, u.i); +} + +inline void writeSymbol(FILE *file, char *inString) +{ + size_t length = strlen(inString); + writeUInt8(file, (uint8)length); + fwrite(inString, 1, length, file); +} + +inline void writeString(FILE *file, char *inString, size_t inLength) +{ + writeInt32_be(file, inLength); + fwrite(inString, 1, inLength, file); +} + +inline void writeString(FILE *file, char *inString) +{ + size_t length = strlen(inString); + writeString(file, inString, length); +} + +inline int32 readInt8(FILE *file) +{ + int32 res = fgetc(file); + + return res; +} + +inline uint32 readUInt8(FILE *file) +{ + uint32 res = (uint32)fgetc(file); + return res; +} + +inline int32 readInt16_be(FILE *file) +{ + int32 c = fgetc(file); + int32 d = fgetc(file); + + int32 res = ((c & 255) << 8) | (d & 255); + return res; +} + +inline int32 readInt16_le(FILE *file) +{ + int32 c = fgetc(file); + int32 d = fgetc(file); + + int32 res = ((d & 255) << 8) | (c & 255); + return res; +} + +inline int32 readInt32_be(FILE *file) +{ + int32 a = fgetc(file); + int32 b = fgetc(file); + int32 c = fgetc(file); + int32 d = fgetc(file); + + int32 res = ((a & 255) << 24) | ((b & 255) << 16) | ((c & 255) << 8) | (d & 255); + return res; +} + +inline int32 readInt32_le(FILE *file) +{ + int32 a = fgetc(file); + int32 b = fgetc(file); + int32 c = fgetc(file); + int32 d = fgetc(file); + + int32 res = ((d & 255) << 24) | ((c & 255) << 16) | ((b & 255) << 8) | (a & 255); + return res; +} + +inline int64 readInt64_be(FILE *file) +{ + int64 hi = readInt32_be(file); + int64 lo = readInt32_be(file); + return (hi << 32) | (lo & 0x00000000FFFFFFFF); +} + +inline float readFloat_be(FILE *file) +{ + union { + float f; + int32 i; + } u; + u.i = readInt32_be(file); + //post("readFloat %g\n", u.f); + return u.f; +} + +inline float readFloat_le(FILE *file) +{ + union { + float f; + int32 i; + } u; + u.i = readInt32_le(file); + //post("readFloat %g\n", u.f); + return u.f; +} + +inline void readString(FILE *file, char *outString, size_t inLength) +{ + fread(outString, 1, inLength, file); + outString[inLength] = 0; +} + +inline void readSymbol(FILE *file, char *outString) +{ + size_t length = (size_t)readUInt8(file); + readString(file, outString, length); +} + +inline void readData(FILE *file, char *outData, size_t inLength) +{ + fread(outData, 1, inLength, file); +} + + +inline int32 readInt8(char *&buf) +{ + int32 res = *buf++; + return res; +} + +inline uint32 readUInt8(char *&buf) +{ + uint32 res = *buf++; + return res; +} + +inline int32 readInt16_be(char *&buf) +{ + int32 c = readInt8(buf); + int32 d = readInt8(buf); + + int32 res = ((c & 255) << 8) | (d & 255); + return res; +} + +inline int32 readInt16_le(char *&buf) +{ + int32 c = readInt8(buf); + int32 d = readInt8(buf); + + int32 res = ((d & 255) << 8) | (c & 255); + return res; +} + + +inline int32 readInt32_be(char *&buf) +{ + int32 a = readInt8(buf); + int32 b = readInt8(buf); + int32 c = readInt8(buf); + int32 d = readInt8(buf); + + int32 res = ((a & 255) << 24) | ((b & 255) << 16) | ((c & 255) << 8) | (d & 255); + return res; +} + +inline int32 readInt32_le(char *&buf) +{ + int32 a = readInt8(buf); + int32 b = readInt8(buf); + int32 c = readInt8(buf); + int32 d = readInt8(buf); + + int32 res = ((d & 255) << 24) | ((c & 255) << 16) | ((b & 255) << 8) | (a & 255); + return res; +} + +inline float readFloat_be(char *&buf) +{ + union { + float f; + int32 i; + } u; + u.i = readInt32_be(buf); + //post("readFloat %g\n", u.f); + return u.f; +} + +inline float readFloat_le(char *&buf) +{ + union { + float f; + int32 i; + } u; + u.i = readInt32_le(buf); + //post("readFloat %g\n", u.f); + return u.f; +} + +inline double readDouble_be(char *&buf) +{ + //post("readDouble\n"); + union { + double f; + uint8 c[8]; + } u; + + u.c[0] = (uint8)readInt8(buf); + u.c[1] = (uint8)readInt8(buf); + u.c[2] = (uint8)readInt8(buf); + u.c[3] = (uint8)readInt8(buf); + u.c[4] = (uint8)readInt8(buf); + u.c[5] = (uint8)readInt8(buf); + u.c[6] = (uint8)readInt8(buf); + u.c[7] = (uint8)readInt8(buf); + //post("readDouble %g %08X %08X\n", u.f, u.f); + return u.f; +} + +inline double readDouble_le(char *&buf) +{ + //post("readDouble\n"); + union { + double f; + uint8 c[8]; + } u; + + u.c[7] = (uint8)readInt8(buf); + u.c[6] = (uint8)readInt8(buf); + u.c[5] = (uint8)readInt8(buf); + u.c[4] = (uint8)readInt8(buf); + u.c[3] = (uint8)readInt8(buf); + u.c[2] = (uint8)readInt8(buf); + u.c[1] = (uint8)readInt8(buf); + u.c[0] = (uint8)readInt8(buf); + + //post("readDouble %g\n", u.f); + return u.f; +} + +inline void readString(char *&buf, char *outString, size_t inLength) +{ + memcpy(outString, buf, inLength); + outString[inLength] = 0; + buf += inLength; +} + +inline void readSymbol(char *&buf, char *outString) +{ + size_t length = (size_t)readUInt8(buf); + readString(buf, outString, length); +} + +inline void readData(char *&buf, char *outData, size_t inLength) +{ + memcpy(outData, buf, inLength); + buf += inLength; +} + + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/server/Rendezvous.h b/sc4pd/headers/server/Rendezvous.h new file mode 100644 index 0000000..2067cd2 --- /dev/null +++ b/sc4pd/headers/server/Rendezvous.h @@ -0,0 +1,41 @@ +/* + * Rendezvous.h + * SC3synth + * + * Created by C. Ramakrishnan on Wed Dec 18 2002. + * Illposed Software + * + */ + +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _Rendezvous_ +#define _Rendezvous_ + +typedef enum { + kSCRendezvous_UDP, + kSCRendezvous_TCP +} SCRendezvousProtocol; + +void PublishPortToRendezvous(SCRendezvousProtocol protocol, short portNum); + +#endif + diff --git a/sc4pd/headers/server/SC_ComPort.h b/sc4pd/headers/server/SC_ComPort.h new file mode 100644 index 0000000..3674fd5 --- /dev/null +++ b/sc4pd/headers/server/SC_ComPort.h @@ -0,0 +1,144 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_ComPort_ +#define _SC_ComPort_ + +#if defined (__APPLE__) && defined (__GNUC__) +#define USE_RENDEZVOUS +#endif + +#include <sys/types.h> +#ifdef SC_WIN32 +# include <winsock2.h> +#else +# include <sys/socket.h> +#endif +#include "OSC_Packet.h" +#include "SC_Sem.h" + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_CmdPort +{ +protected: + pthread_t mThread; + struct World *mWorld; + + void Start(); + virtual ReplyFunc GetReplyFunc()=0; +public: + SC_CmdPort(struct World *inWorld); + + virtual void* Run()=0; +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_ComPort : public SC_CmdPort +{ +protected: + int mPortNum; + int mSocket; + struct sockaddr_in mBindSockAddr; + +#ifdef USE_RENDEZVOUS + pthread_t mRendezvousThread; +#endif + +public: + SC_ComPort(struct World *inWorld, int inPortNum); + virtual ~SC_ComPort(); + + int Socket() { return mSocket; } + + int PortNum() const { return mPortNum; } +#ifdef USE_RENDEZVOUS + // default implementation does nothing (this is correct for + // SC_TcpConnectionPort). Subclasses may override. + virtual void PublishToRendezvous() { }; +#endif +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_UdpInPort : public SC_ComPort +{ +protected: + struct sockaddr_in mReplySockAddr; + virtual ReplyFunc GetReplyFunc(); + +public: + SC_UdpInPort(struct World *inWorld, int inPortNum); + ~SC_UdpInPort(); + + int PortNum() const { return mPortNum; } + + void* Run(); +#ifdef USE_RENDEZVOUS + virtual void PublishToRendezvous(); +#endif + +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_TcpInPort : public SC_ComPort +{ + SC_Semaphore mConnectionAvailable; + int mBacklog; + +protected: + virtual ReplyFunc GetReplyFunc(); + +public: + SC_TcpInPort(struct World *inWorld, int inPortNum, int inMaxConnections, int inBacklog); + + virtual void* Run(); + + void ConnectionTerminated(); +#ifdef USE_RENDEZVOUS + virtual void PublishToRendezvous(); +#endif +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +class SC_TcpConnectionPort : public SC_ComPort +{ + SC_TcpInPort *mParent; + +protected: + virtual ReplyFunc GetReplyFunc(); + +public: + SC_TcpConnectionPort(struct World *inWorld, SC_TcpInPort *inParent, int inSocket); + virtual ~SC_TcpConnectionPort(); + + virtual void* Run(); +}; + +const int kPacketBufSize = 8192; // this seems to be the maximum size of a UDP packet + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/sc4pd/headers/server/SC_Complex.h b/sc4pd/headers/server/SC_Complex.h new file mode 100644 index 0000000..d4aed20 --- /dev/null +++ b/sc4pd/headers/server/SC_Complex.h @@ -0,0 +1,142 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Complex_ +#define _SC_Complex_ + +#include "SC_Types.h" +#include "float.h" + +//////////////////////////////////////////////////////////////////////////////// + +struct Polar; + +struct Complex +{ + Complex() {} + Complex(float r, float i) : real(r), imag(i) {} + void Set(float r, float i) { real = r; imag = i; } + + Complex& operator=(Complex b) { real = b.real; imag = b.imag; return *this; } + Complex& operator=(float b) { real = b; imag = 0.; return *this; } + + Polar ToPolar(); + Polar ToPolarApx(); + + void ToPolarInPlace(); + void ToPolarApxInPlace(); + + float real, imag; +}; + +struct Polar +{ + Polar() {} + Polar(float m, float p) : mag(m), phase(p) {} + void Set(float m, float p) { mag = m; phase = p; } + + Complex ToComplex(); + Complex ToComplexApx(); + + void ToComplexInPlace(); + void ToComplexApxInPlace(); + + float mag, phase; +}; + +struct ComplexFT +{ + float dc, nyq; + Complex complex[1]; +}; + +struct PolarFT +{ + float dc, nyq; + Polar polar[1]; +}; + +void ToComplex(Polar in, Complex& out); + +inline Complex operator+(Complex a, Complex b) { return Complex(a.real + b.real, a.imag + b.imag); } +inline Complex operator+(Complex a, float b) { return Complex(a.real + b, a.imag); } +inline Complex operator+(float a, Complex b) { return Complex(a + b.real, b.imag); } + +inline Complex& operator+=(Complex& a, const Complex& b) { a.real += b.real, a.imag += b.imag; return a; } +inline Complex& operator+=(Complex& a, float b) { a.real += b; return a; } + +inline Complex operator-(Complex a, Complex b) { return Complex(a.real - b.real, a.imag - b.imag); } +inline Complex operator-(Complex a, float b) { return Complex(a.real - b, a.imag); } +inline Complex operator-(float a, Complex b) { return Complex(a - b.real, b.imag); } + +inline Complex operator-=(Complex a, Complex b) { a.real -= b.real, a.imag -= b.imag; return a; } +inline Complex operator-=(Complex a, float b) { a.real -= b; return a; } + +inline Complex operator*(Complex a, Complex b) +{ + return Complex(a.real * b.real - a.imag * b.imag, a.real * b.imag + a.imag * b.real); +} + +inline Complex operator*(Complex a, float b) +{ + return Complex(a.real * b, a.imag * b); +} + +inline Complex operator*(float a, Complex b) +{ + return Complex(b.real * a, b.imag * a); +} + +inline Complex operator*=(Complex a, Complex b) +{ + a.Set( + a.real * b.real - a.imag * b.imag, + a.real * b.imag + a.imag * b.real + ); + return a; +} + +inline Complex operator*=(Complex a, float b) +{ + a.real *= b; + a.imag *= b; + return a; +} + + +inline Polar operator*(Polar a, float b) +{ + return Polar(a.mag * b, a.phase); +} + +inline Polar operator*(float a, Polar b) +{ + return Polar(a * b.mag, b.phase); +} + +inline Polar operator*=(Polar a, float b) +{ + a.mag *= b; + return a; +} + + +#endif diff --git a/sc4pd/headers/server/SC_CoreAudio.h b/sc4pd/headers/server/SC_CoreAudio.h new file mode 100644 index 0000000..fba5184 --- /dev/null +++ b/sc4pd/headers/server/SC_CoreAudio.h @@ -0,0 +1,263 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_CoreAudio_ +#define _SC_CoreAudio_ + +#include "MsgFifo.h" +#include "SC_FifoMsg.h" +#include "OSC_Packet.h" +#include "SC_SyncCondition.h" +#include "PriorityQueue.h" +#include "SC_Lock.h" + +#define SC_AUDIO_API_COREAUDIO 1 +#define SC_AUDIO_API_JACK 2 +#define SC_AUDIO_API_PORTAUDIO 3 + +#ifdef SC_WIN32 +# define SC_AUDIO_API SC_AUDIO_API_PORTAUDIO +#endif + +#ifndef SC_AUDIO_API +# define SC_AUDIO_API SC_AUDIO_API_COREAUDIO +#endif // SC_AUDIO_API + +#if SC_AUDIO_API == SC_AUDIO_API_COREAUDIO +# include <CoreAudio/AudioHardware.h> +# include <CoreAudio/HostTime.h> +#endif + +#if SC_AUDIO_API == SC_AUDIO_API_JACK +# include <jack/jack.h> +class SC_JackPortList; +#endif + +#if SC_AUDIO_API == SC_AUDIO_API_PORTAUDIO +#include "portaudio.h" +#endif + + +struct SC_ScheduledEvent +{ + SC_ScheduledEvent() : mTime(0), mPacket(0) {} + SC_ScheduledEvent(struct World *inWorld, int64 inTime, OSC_Packet *inPacket) + : mTime(inTime), mPacket(inPacket), mWorld(inWorld) {} + + int64 Time() { return mTime; } + void Perform(); + + int64 mTime; + OSC_Packet *mPacket; + struct World *mWorld; +}; + +typedef MsgFifo<FifoMsg, 1024> EngineFifo; + + +class SC_AudioDriver +{ +protected: + int64 mOSCincrement; + struct World *mWorld; + double mOSCtoSamples; + int mSampleTime; + + // Common members + uint32 mHardwareBufferSize; // bufferSize returned by kAudioDevicePropertyBufferSize + EngineFifo mFromEngine, mToEngine; + SC_SyncCondition mAudioSync; + pthread_t mThread; + bool mRunThreadFlag; + uint32 mSafetyOffset; + PriorityQueueT<SC_ScheduledEvent, 2048> mScheduler; + SC_Lock *mProcessPacketLock; + int mNumSamplesPerCallback; + uint32 mPreferredHardwareBufferFrameSize; + uint32 mPreferredSampleRate; + double mBuffersPerSecond; + double mAvgCPU, mPeakCPU; + int mPeakCounter, mMaxPeakCounter; + double mOSCincrementNumerator; + + double mStartHostSecs; + double mPrevHostSecs; + double mStartSampleTime; + double mPrevSampleTime; + double mSmoothSampleRate; + double mSampleRate; + + // Driver interface methods, implemented by subclasses + virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate) = 0; + virtual bool DriverStart() = 0; + virtual bool DriverStop() = 0; + +public: + // Common methods + SC_AudioDriver(struct World *inWorld); + virtual ~SC_AudioDriver(); + + int64 mOSCbuftime; + + bool Setup(); + bool Start(); + bool Stop(); + + void ClearSched() { mScheduler.Empty(); } + + void Lock() { mProcessPacketLock->Lock(); } + void Unlock() { mProcessPacketLock->Unlock(); } + + void RunNonRealTime(float *in, float *out, int numSamples, int64 oscTime); + void* RunThread(); + + int SafetyOffset() const { return mSafetyOffset; } + int NumSamplesPerCallback() const { return mNumSamplesPerCallback; } + void SetPreferredHardwareBufferFrameSize(int inSize) + { + mPreferredHardwareBufferFrameSize = inSize; + } + void SetPreferredSampleRate(int inRate) + { + mPreferredSampleRate = inRate; + } + + bool SendMsgToEngine(FifoMsg& inMsg); + bool SendMsgFromEngine(FifoMsg& inMsg); + + void AddEvent(SC_ScheduledEvent& event) { mScheduler.Add(event); } + + double GetAvgCPU() const { return mAvgCPU; } + double GetPeakCPU() const { return mPeakCPU; } + double GetSampleRate() const { return mSampleRate; } + double GetActualSampleRate() const { return mSmoothSampleRate; } +}; + + +// the following classes should be split out into separate source files. +#if SC_AUDIO_API == SC_AUDIO_API_COREAUDIO +class SC_CoreAudioDriver : public SC_AudioDriver +{ + + AudioBufferList * mInputBufList; + AudioDeviceID mInputDevice; + AudioDeviceID mOutputDevice; + + AudioStreamBasicDescription inputStreamDesc; // info about the default device + AudioStreamBasicDescription outputStreamDesc; // info about the default device + + friend OSStatus appIOProc ( AudioDeviceID inDevice, + const AudioTimeStamp* inNow, + const AudioBufferList* inInputData, + const AudioTimeStamp* inInputTime, + AudioBufferList* outOutputData, + const AudioTimeStamp* inOutputTime, + void* defptr); + +protected: + // Driver interface methods + virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate); + virtual bool DriverStart(); + virtual bool DriverStop(); + +public: + SC_CoreAudioDriver(struct World *inWorld); + virtual ~SC_CoreAudioDriver(); + + void Run(const AudioBufferList* inInputData, AudioBufferList* outOutputData, int64 oscTime); + + bool UseInput() { return mInputDevice != kAudioDeviceUnknown; } + bool UseSeparateIO() { return UseInput() && mInputDevice != mOutputDevice; } + AudioDeviceID InputDevice() { return mInputDevice; } + AudioDeviceID OutputDevice() { return mOutputDevice; } + + void SetInputBufferList(AudioBufferList * inBufList) { mInputBufList = inBufList; } + AudioBufferList* GetInputBufferList() const { return mInputBufList; } +}; + +inline SC_AudioDriver* SC_NewAudioDriver(struct World *inWorld) +{ + return new SC_CoreAudioDriver(inWorld); +} +#endif // SC_AUDIO_API_COREAUDIO + + +#if SC_AUDIO_API == SC_AUDIO_API_JACK +class SC_JackDriver : public SC_AudioDriver +{ + jack_client_t *mClient; + SC_JackPortList *mInputList; + SC_JackPortList *mOutputList; + int64 mMaxOutputLatency; + +protected: + // Driver interface methods + virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate); + virtual bool DriverStart(); + virtual bool DriverStop(); + +public: + SC_JackDriver(struct World *inWorld); + virtual ~SC_JackDriver(); + + void Run(); + void BufferSizeChanged(int numSamples); + void SampleRateChanged(double sampleRate); + void GraphOrderChanged(); +}; + +inline SC_AudioDriver* SC_NewAudioDriver(struct World *inWorld) +{ + return new SC_JackDriver(inWorld); +} +#endif // SC_AUDIO_API_JACK + + +#if SC_AUDIO_API == SC_AUDIO_API_PORTAUDIO +class SC_PortAudioDriver : public SC_AudioDriver +{ + + int mInputChannelCount, mOutputChannelCount; + PaStream *mStream; + +protected: + // Driver interface methods + virtual bool DriverSetup(int* outNumSamplesPerCallback, double* outSampleRate); + virtual bool DriverStart(); + virtual bool DriverStop(); + +public: + SC_PortAudioDriver(struct World *inWorld); + virtual ~SC_PortAudioDriver(); + + int PortAudioCallback( const void *input, void *output, + unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, + PaStreamCallbackFlags statusFlags ); +}; + +inline SC_AudioDriver* SC_NewAudioDriver(struct World *inWorld) +{ + return new SC_PortAudioDriver(inWorld); +} +#endif // SC_AUDIO_API_PORTAUDIO + + +#endif diff --git a/sc4pd/headers/server/SC_Errors.h b/sc4pd/headers/server/SC_Errors.h new file mode 100644 index 0000000..3d3459a --- /dev/null +++ b/sc4pd/headers/server/SC_Errors.h @@ -0,0 +1,58 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Errors_ +#define _SC_Errors_ + +typedef int SCErr; + +const char *SC_ErrorString(SCErr err); + +enum { + kSCErr_None, + kSCErr_Failed, + kSCErr_NodeNotFound, + kSCErr_TargetNodeNotFound, + kSCErr_GroupNotFound, + kSCErr_SynthDefNotFound, + kSCErr_NoSuchCommand, + kSCErr_WrongArgType, + kSCErr_IndexOutOfRange, + kSCErr_AccessDenied, + kSCErr_NoReplyPort, + kSCErr_InvalidControlIndex, + kSCErr_AlreadyLoggedIn, + kSCErr_NotLoggedIn, + kSCErr_TooManyUsers, + kSCErr_TooManyNodes, + kSCErr_DuplicateNodeID, + kSCErr_ReservedNodeID, + kSCErr_OutOfRealTimeMemory, + + kSCErr_UnsupportedHeaderFormat, + kSCErr_UnsupportedSampleFormat, + + kSCErr_BufGenNotFound, + + kSCErr_NumErrors +}; + +#endif diff --git a/sc4pd/headers/server/SC_GraphDef.h b/sc4pd/headers/server/SC_GraphDef.h new file mode 100644 index 0000000..dca6fd2 --- /dev/null +++ b/sc4pd/headers/server/SC_GraphDef.h @@ -0,0 +1,75 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_GraphDef_ +#define _SC_GraphDef_ + +#include "SC_SynthDef.h" +#include "HashTable.h" + +struct ParamSpec +{ + int32 mName[kSCNameLen]; + int32 mIndex; + int32 mHash; +}; + +typedef HashTable<ParamSpec, Malloc> ParamSpecTable; + +struct GraphDef +{ + NodeDef mNodeDef; + + uint32 mNumControls; + + uint32 mNumWires; + uint32 mNumConstants; + uint32 mNumUnitSpecs; + uint32 mNumWireBufs; + uint32 mNumCalcUnits; + + float32 *mInitialControlValues; + float32 *mConstants; + + struct UnitSpec *mUnitSpecs; + + size_t mWiresAllocSize, mUnitsAllocSize, mCalcUnitsAllocSize; + size_t mControlAllocSize, mMapControlsAllocSize; + + uint32 mNumParamSpecs; + ParamSpec *mParamSpecs; + ParamSpecTable *mParamSpecTable; + + int mRefCount; + struct GraphDef* mNext; +}; +typedef struct GraphDef GraphDef; + +GraphDef* GraphDef_Recv(World *inWorld, char *buffer, GraphDef *inList); +GraphDef* GraphDef_Load(struct World *inWorld, const char *filename, GraphDef* inList); +GraphDef* GraphDef_LoadDir(struct World *inWorld, char *dirname, GraphDef* inList); +GraphDef* GraphDef_LoadGlob(World *inWorld, const char *pattern, GraphDef *inList); +void GraphDef_DeleteMsg(struct World *inWorld, GraphDef *inDef); +void GraphDef_Dump(GraphDef *inGraphDef); +int32 GetHash(ParamSpec* inParamSpec); +int32* GetKey(ParamSpec* inParamSpec); + +#endif diff --git a/sc4pd/headers/server/SC_Group.h b/sc4pd/headers/server/SC_Group.h new file mode 100644 index 0000000..5a104a7 --- /dev/null +++ b/sc4pd/headers/server/SC_Group.h @@ -0,0 +1,34 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Group_ +#define _SC_Group_ + +#include "SC_Graph.h" + +struct Group { + Node mNode; + + Node *mHead, *mTail; +}; +typedef struct Group Group; + +#endif diff --git a/sc4pd/headers/server/SC_HiddenWorld.h b/sc4pd/headers/server/SC_HiddenWorld.h new file mode 100644 index 0000000..7776874 --- /dev/null +++ b/sc4pd/headers/server/SC_HiddenWorld.h @@ -0,0 +1,113 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_HiddenWorld_ +#define _SC_HiddenWorld_ + +#include "SC_Types.h" +#include "SC_Sem.h" +#include "SC_Rate.h" +#include "SC_SndBuf.h" +#include "SC_RGen.h" +#include "HashTable.h" +#include "SC_World.h" +#include "SC_Reply.h" +#include "MsgFifo.h" + +extern HashTable<struct UnitDef, Malloc> *gUnitDefLib; + + +struct TriggerMsg { + World *mWorld; + int32 mNodeID; + int32 mTriggerID; + float mValue; + + void Perform(); +}; + +struct NodeEndMsg { + World *mWorld; + int32 mNodeID; + int32 mGroupID; + int32 mPrevNodeID; + int32 mNextNodeID; + int32 mIsGroup; + int32 mHeadID; + int32 mTailID; + int32 mState; + + void Perform(); +}; + +struct DeleteGraphDefMsg { + struct GraphDef* mDef; + + void Perform(); +}; + + +typedef MsgFifoNoFree<TriggerMsg, 1024> TriggersFifo; +typedef MsgFifoNoFree<NodeEndMsg, 1024> NodeEndsFifo; +typedef MsgFifoNoFree<DeleteGraphDefMsg, 512> DeleteGraphDefsFifo; + +struct HiddenWorld +{ + + class AllocPool *mAllocPool; + IntHashTable<struct Node, AllocPool> *mNodeLib; + HashTable<struct GraphDef, Malloc> *mGraphDefLib; + uint32 mNumUsers, mMaxUsers; + ReplyAddress *mUsers; + + class SC_AudioDriver *mAudioDriver; + char mPassword[32]; + + uint32 mMaxWireBufs; + float *mWireBufSpace; + + TriggersFifo mTriggers; + NodeEndsFifo mNodeEnds; + DeleteGraphDefsFifo mDeleteGraphDefs; + + SC_Semaphore* mQuitProgram; + + SNDFILE *mNRTInputFile; + SNDFILE *mNRTOutputFile; + FILE *mNRTCmdFile; + + int32 mHiddenID; + int32 mRecentID; + +#ifdef SC_DARWIN + const char* mInputStreamsEnabled; + const char* mOutputStreamsEnabled; +#endif +}; + +typedef struct HiddenWorld HiddenWorld; + +inline SC_AudioDriver *AudioDriver(World *inWorld) +{ + return inWorld->hw->mAudioDriver; +} + +#endif diff --git a/sc4pd/headers/server/SC_Lib.h b/sc4pd/headers/server/SC_Lib.h new file mode 100644 index 0000000..552a231 --- /dev/null +++ b/sc4pd/headers/server/SC_Lib.h @@ -0,0 +1,62 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Lib_ +#define _SC_Lib_ + +#include "SC_Errors.h" +#include "SC_Lock.h" +#include "SC_Types.h" +#include "Hash.h" +#include "HashTable.h" +#include <stdlib.h> +#include <string.h> + +class SC_NamedObj +{ +public: + SC_NamedObj(); + virtual ~SC_NamedObj(); + + const int32* Name() const { return mName; } + void SetName(const char *inName); + void SetName(const int32 *inName); + +private: + friend int32 GetHash(const SC_NamedObj *inObj); + friend const int32* GetKey(const SC_NamedObj *inObj); + + int32 mName[kSCNameLen]; + int32 mHash; +}; + +inline int32 GetHash(const SC_NamedObj *inObj) +{ + return inObj->mHash; +} + +inline const int32 *GetKey(const SC_NamedObj *inObj) +{ + return inObj->mName; +} + +#endif + diff --git a/sc4pd/headers/server/SC_Lib_Cintf.h b/sc4pd/headers/server/SC_Lib_Cintf.h new file mode 100644 index 0000000..64eda5e --- /dev/null +++ b/sc4pd/headers/server/SC_Lib_Cintf.h @@ -0,0 +1,124 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Lib_Cintf_ +#define _SC_Lib_Cintf_ + +#include "SC_Lib.h" +#include "SC_Reply.h" + +typedef SCErr (*SC_CommandFunc)(struct World *inWorld, int inSize, char *inData, ReplyAddress *inReply); + +class SC_LibCmd : public SC_NamedObj +{ +public: + SC_LibCmd(SC_CommandFunc inFunc); + + SCErr Perform(struct World *inWorld, int inSize, char *inData, ReplyAddress *inReply); + +private: + SC_CommandFunc mFunc; +}; + +extern Malloc gMalloc; +extern HashTable<class SC_LibCmd, Malloc> *gCmdLib; + +void initialize_library(); +SCErr NewCommand(const char *inPath, uint32 inCommandNumber, SC_CommandFunc inFunc); + +// command numbers: +enum { + cmd_none = 0, + + cmd_notify = 1, + cmd_status = 2, + cmd_quit = 3, + cmd_cmd = 4, + + cmd_d_recv = 5, + cmd_d_load = 6, + cmd_d_loadDir = 7, + cmd_d_freeAll = 8, + + cmd_s_new = 9, + + cmd_n_trace = 10, + cmd_n_free = 11, + cmd_n_run = 12, + cmd_n_cmd = 13, + cmd_n_map = 14, + cmd_n_set = 15, + cmd_n_setn = 16, + cmd_n_fill = 17, + cmd_n_before = 18, + cmd_n_after = 19, + + cmd_u_cmd = 20, + + cmd_g_new = 21, + cmd_g_head = 22, + cmd_g_tail = 23, + cmd_g_freeAll = 24, + + cmd_c_set = 25, + cmd_c_setn = 26, + cmd_c_fill = 27, + + cmd_b_alloc = 28, + cmd_b_allocRead = 29, + cmd_b_read = 30, + cmd_b_write = 31, + cmd_b_free = 32, + cmd_b_close = 33, + cmd_b_zero = 34, + cmd_b_set = 35, + cmd_b_setn = 36, + cmd_b_fill = 37, + cmd_b_gen = 38, + + cmd_dumpOSC = 39, + + cmd_c_get = 40, + cmd_c_getn = 41, + cmd_b_get = 42, + cmd_b_getn = 43, + cmd_s_get = 44, + cmd_s_getn = 45, + + cmd_n_query = 46, + cmd_b_query = 47, + + cmd_n_mapn = 48, + cmd_s_noid = 49, + + cmd_g_deepFree = 50, + cmd_clearSched = 51, + + cmd_sync = 52, + + NUMBER_OF_COMMANDS = 53 +}; + +extern SC_LibCmd* gCmdArray[NUMBER_OF_COMMANDS]; + + +#endif + diff --git a/sc4pd/headers/server/SC_List.h b/sc4pd/headers/server/SC_List.h new file mode 100644 index 0000000..d5bed41 --- /dev/null +++ b/sc4pd/headers/server/SC_List.h @@ -0,0 +1,229 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + +A doubly linked list template. + +*/ + +#ifndef _SC_List_ +#define _SC_List_ + +#include <stdexcept> +#ifndef NDEBUG +# define NDEBUG +#endif +#include <assert.h> + + +// A Link can be a node in a list or a list itself. + +template <class T> +class Link +{ +public: + Link() : mNext(this), mPrev(this) {} + + T* Prev() { return static_cast<T*>(mPrev); } + T* Next() { return static_cast<T*>(mNext); } + + void RemoveLeaveDangling() + { + mPrev->mNext = mNext; + mNext->mPrev = mPrev; + } + + void Remove() + { + RemoveLeaveDangling(); + mNext = mPrev = this; + } + + void InsertAfter(T *inLink) + { + mPrev = inLink; + mNext = inLink->mNext; + mNext->mPrev = this; + mPrev->mNext = this; + } + + void InsertBefore(T *inLink) + { + mNext = inLink; + mPrev = inLink->mPrev; + mNext->mPrev = this; + mPrev->mNext = this; + } + + T* Head() { return static_cast<T*>(mNext); } + T* Tail() { return static_cast<T*>(mPrev); } + + T* PopHead(); + T* PopTail(); + void PushHead(T* inBuf); + void PushTail(T* inBuf); + + bool ContainsBuf(T* inBuf); + bool IsEmpty() { return mNext == this; } + void BeEmpty() { mNext = mPrev = this; } + + void Cat(T* inLink); + + bool SanityCheck(); + void DebugDump(); + +//private: +// Codewarrior refuses to inline Next() in some places.. + Link<T> *mNext, *mPrev; +}; + +template <class T, class Alloc> +void MakeListEmpty(Link<T> *inLink, Alloc* inAlloc) +{ + Link<T>* link = inLink->mNext; + while (link != inLink) { + Link<T>* nextlink = link->mNext; + // SC uses placement new extensively, so here we do a 'placement delete'. + // Using DestructSelf allows me to have either virtual + // or non virtual destructors in subclasses at the discretion of the subclass. + ((T*)(link))->DestructSelf(); + inAlloc->Free(static_cast<T*>(link)); + link = nextlink; + } + inLink->mNext = inLink->mPrev = inLink; +} + +template <class T> +void Link<T>::PushHead(T* inLink) +{ + assert(SanityCheck()); + + Link<T>* link = static_cast<Link<T>*>(inLink); + link->InsertAfter(static_cast<T*>(this)); + + assert(SanityCheck()); +} + +template <class T> +T* Link<T>::PopHead() +{ + assert(SanityCheck()); + if (IsEmpty()) return 0; + + Link<T>* link = mNext; + + link->Remove(); + + assert(SanityCheck()); + return static_cast<T*>(link); +} + +template <class T> +void Link<T>::PushTail(T* inLink) +{ + assert(SanityCheck()); + + Link<T>* link = static_cast<Link<T>*>(inLink); + link->InsertBefore(static_cast<T*>(this)); + + assert(SanityCheck()); +} + +template <class T> +T* Link<T>::PopTail() +{ + assert(SanityCheck()); + if (IsEmpty()) return 0; + + Link<T>* link = mPrev; + link->Remove(); + + assert(SanityCheck()); + return static_cast<T*>(link); +} + +template <class T> +void Link<T>::Cat(T* inLink) +{ + assert(SanityCheck()); + + Link<T>* link = static_cast<Link<T>*>(inLink); + + if (link->IsEmpty()) return; + if (IsEmpty()) { + mNext = link->mNext; + mPrev = link->mPrev; + link->mNext->mPrev = this; + link->mPrev->mNext = this; + } else { + link->mNext->mPrev = mPrev; + link->mPrev->mNext = this; + mPrev->mNext = link->mNext; + mPrev = link->mPrev; + } + link->mPrev = link; + link->mNext = link; + + assert(SanityCheck()); +} + +template <class T> +bool Link<T>::ContainsBuf(T* inLink) +{ + Link<T>* link = static_cast<Link<T>*>(inLink); + Link<T>* curLink = mNext; + while (curLink != this) { + if (curLink == link) return true; + curLink = curLink->mNext; + } + return false; +} + +template <class T> +void Link<T>::DebugDump() +{ + Link<T>* link = mNext; + while (link != this) { + //postbuf("Link-> %08X next %08X prev %08X\n", + // link, link->mNext, link->mPrev); + link = link->mNext; + } +} + +template <class T> +bool Link<T>::SanityCheck() +{ + Link<T>* link = mNext; + while (link != this) { + if (link->mPrev->mNext != link) { + throw std::runtime_error("Link: bad link <-,->"); + } + if (link->mNext->mPrev != link) { + throw std::runtime_error("Link: bad link ->,<-"); + } + link = link->mNext; + } + return true; +} + + + +#endif diff --git a/sc4pd/headers/server/SC_Lock.h b/sc4pd/headers/server/SC_Lock.h new file mode 100644 index 0000000..57635fe --- /dev/null +++ b/sc4pd/headers/server/SC_Lock.h @@ -0,0 +1,38 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Lock_ +#define _SC_Lock_ + +#include <pthread.h> + +class SC_Lock +{ +public: + SC_Lock() { pthread_mutex_init (&mutex, NULL); } + ~SC_Lock() { pthread_mutex_destroy (&mutex); } + void Lock() { pthread_mutex_lock (&mutex); } + void Unlock() { pthread_mutex_unlock (&mutex); } +private: + pthread_mutex_t mutex; +}; + +#endif diff --git a/sc4pd/headers/server/SC_Prototypes.h b/sc4pd/headers/server/SC_Prototypes.h new file mode 100644 index 0000000..c2f353e --- /dev/null +++ b/sc4pd/headers/server/SC_Prototypes.h @@ -0,0 +1,213 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Prototypes_ +#define _SC_Prototypes_ + +#include <ctype.h> // for size_t + +#include "SC_Types.h" + +//////////////////////////////////////////////////////////////////////// + +// replacement for calloc. +// calloc lazily zeroes memory on first touch. This is good for most purposes, but bad for realtime audio. +void* zalloc(size_t n, size_t size); + +//////////////////////////////////////////////////////////////////////// + +void World_Run(struct World *inWorld); +void World_Start(World *inWorld); +void World_Cleanup(World *inWorld); +void World_SetSampleRate(struct World *inWorld, double inSampleRate); + +extern "C" { +void* World_Alloc(struct World *inWorld, size_t inByteSize); +void* World_Realloc(struct World *inWorld, void *inPtr, size_t inByteSize); +void World_Free(struct World *inWorld, void *inPtr); +void World_NRTLock(World *world); +void World_NRTUnlock(World *world); +} + +size_t World_TotalFree(struct World *inWorld); +size_t World_LargestFreeChunk(struct World *inWorld); + + +int32 GetKey(struct Node *inNode); +int32 GetHash(struct Node *inNode); +bool World_AddNode(struct World *inWorld, struct Node* inNode); +bool World_RemoveNode(struct World *inWorld, struct Node* inNode); + +extern "C" { +struct Node* World_GetNode(struct World *inWorld, int32 inID); +struct Graph* World_GetGraph(struct World *inWorld, int32 inID); +} + +struct Group* World_GetGroup(struct World *inWorld, int32 inID); + +int32 *GetKey(struct UnitDef *inUnitDef); +int32 GetHash(struct UnitDef *inUnitDef); +bool AddUnitDef(struct UnitDef* inUnitDef); +bool RemoveUnitDef(struct UnitDef* inUnitDef); +struct UnitDef* GetUnitDef(int32* inKey); + +int32 *GetKey(struct BufGen *inBufGen); +int32 GetHash(struct BufGen *inBufGen); +bool AddBufGen(struct BufGen* inBufGen); +bool RemoveBufGen(struct BufGen* inBufGen); +struct BufGen* GetBufGen(int32* inKey); + +int32 *GetKey(struct PlugInCmd *inPlugInCmd); +int32 GetHash(struct PlugInCmd *inPlugInCmd); +bool AddPlugInCmd(struct PlugInCmd* inPlugInCmd); +bool RemovePlugInCmd(struct PlugInCmd* inPlugInCmd); +struct PlugInCmd* GetPlugInCmd(int32* inKey); +int PlugIn_DoCmd(struct World *inWorld, int inSize, char *inArgs, struct ReplyAddress *inReply); + +int32 *GetKey(struct GraphDef *inGraphDef); +int32 GetHash(struct GraphDef *inGraphDef); +bool World_AddGraphDef(struct World *inWorld, struct GraphDef* inGraphDef); +bool World_FreeGraphDef(struct World *inWorld, struct GraphDef* inGraphDef); +bool World_RemoveGraphDef(struct World *inWorld, struct GraphDef* inGraphDef); +struct GraphDef* World_GetGraphDef(struct World *inWorld, int32* inKey); +void World_FreeAllGraphDefs(World *inWorld); +void GraphDef_Free(GraphDef *inGraphDef); +void GraphDef_Define(World *inWorld, GraphDef *inList); +void GraphDef_FreeOverwritten(World *inWorld); + +SCErr bufAlloc(struct SndBuf* buf, int numChannels, int numFrames, double sampleRate); + +//////////////////////////////////////////////////////////////////////// + +void Rate_Init(struct Rate *inRate, double inSampleRate, int inBufLength); + +void Dimension_Init(struct SC_Dimension *inDimension, int inWidth, int inHeight); + +//////////////////////////////////////////////////////////////////////// + +#define GRAPHDEF(inGraph) ((GraphDef*)((inGraph)->mNode.mDef)) +#define GRAPH_PARAM_TABLE(inGraph) (GRAPHDEF(inGraph)->mParamSpecTable) + +int Graph_New(struct World *inWorld, struct GraphDef *def, int32 inID, struct sc_msg_iter* args, struct Graph** outGraph); +void Graph_Ctor(struct World *inWorld, struct GraphDef *inGraphDef, struct Graph *graph, struct sc_msg_iter *msg); +void Graph_Dtor(struct Graph *inGraph); +int Graph_GetControl(struct Graph* inGraph, uint32 inIndex, float& outValue); +int Graph_GetControl(struct Graph* inGraph, int32 inHash, int32 *inName, uint32 inIndex, float& outValue); +void Graph_SetControl(struct Graph* inGraph, uint32 inIndex, float inValue); +void Graph_SetControl(struct Graph* inGraph, int32 inHash, int32 *inName, uint32 inIndex, float inValue); +void Graph_MapControl(Graph* inGraph, uint32 inIndex, uint32 inBus); +void Graph_MapControl(Graph* inGraph, int32 inHash, int32 *inName, uint32 inIndex, uint32 inBus); +void Graph_Trace(Graph *inGraph); +void Graph_RemoveID(World* inWorld, Graph *inGraph); + +//////////////////////////////////////////////////////////////////////// + +int Node_New(struct World *inWorld, struct NodeDef *def, int32 inID, struct Node **outNode); +void Node_Dtor(struct Node *inNode); +void Node_Remove(struct Node* s); +void Node_Delete(struct Node* inNode); +void Node_AddAfter(struct Node* s, struct Node *afterThisOne); +void Node_AddBefore(struct Node* s, struct Node *beforeThisOne); +void Node_Replace(struct Node* s, struct Node *replaceThisOne); +void Node_SetControl(Node* inNode, int inIndex, float inValue); +void Node_SetControl(Node* inNode, int32 inHash, int32 *inName, int inIndex, float inValue); +void Node_MapControl(Node* inNode, int inIndex, int inBus); +void Node_MapControl(Node* inNode, int32 inHash, int32 *inName, int inIndex, int inBus); +void Node_StateMsg(Node* inNode, int inState); +void Node_Trace(Node* inNode); + +extern "C" { +void Node_SetRun(Node* inNode, int inRun); +void Node_SendTrigger(Node* inNode, int triggerID, float value); +void Node_End(struct Node* inNode); +void Node_NullCalc(struct Node* inNode); +void Unit_DoneAction(int doneAction, struct Unit* unit); +} + +//////////////////////////////////////////////////////////////////////// + +extern "C" { +void Group_Calc(Group *inGroup); +void Graph_Calc(struct Graph *inGraph); +} + +int Group_New(World *inWorld, int32 inID, Group** outGroup); +void Group_Dtor(Group *inGroup); +void Group_DeleteAll(Group *inGroup); +void Group_DeepFreeGraphs(Group *inGroup); +void Group_AddHead (Group *s, Node *child); +void Group_AddTail (Group *s, Node *child); +void Group_Insert(Group *s, Node *child, int inIndex); +void Group_SetControl(struct Group* inGroup, uint32 inIndex, float inValue); +void Group_SetControl(struct Group *inGroup, int32 inHash, int32 *inName, uint32 inIndex, float inValue); +void Group_MapControl(Group* inGroup, uint32 inIndex, uint32 inBus); +void Group_MapControl(Group* inGroup, int32 inHash, int32 *inName, uint32 inIndex, uint32 inBus); +void Group_Trace(Group* inGroup); + +//////////////////////////////////////////////////////////////////////// + +struct Unit* Unit_New(struct World *inWorld, struct UnitSpec *inUnitSpec, char*& memory); +void Unit_EndCalc(struct Unit *inUnit, int inNumSamples); +void Unit_End(struct Unit *inUnit); + +void Unit_Dtor(struct Unit *inUnit); + +extern "C" { +void Unit_ZeroOutputs(struct Unit *inUnit, int inNumSamples); +} + +//////////////////////////////////////////////////////////////////////// + +void SendDone(struct ReplyAddress *inReply, char *inCommandName); +void SendFailure(struct ReplyAddress *inReply, char *inCommandName, char *errString); +void ReportLateness(struct ReplyAddress *inReply, float32 seconds); +void DumpReplyAddress(struct ReplyAddress *inReplyAddress); +int32 Hash(struct ReplyAddress *inReplyAddress); + +//////////////////////////////////////////////////////////////////////// + +extern "C" { +int32 timeseed(); +} + +//////////////////////////////////////////////////////////////////////// + +typedef bool (*AsyncStageFn)(World *inWorld, void* cmdData); +typedef void (*AsyncFreeFn)(World *inWorld, void* cmdData); + +int PerformAsynchronousCommand + ( + World *inWorld, + void* replyAddr, + const char* cmdName, + void *cmdData, + AsyncStageFn stage2, // stage2 is non real time + AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true + AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true + AsyncFreeFn cleanup, + int completionMsgSize, + void* completionMsgData + ); + +//////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/sc4pd/headers/server/SC_Reply.h b/sc4pd/headers/server/SC_Reply.h new file mode 100644 index 0000000..0400747 --- /dev/null +++ b/sc4pd/headers/server/SC_Reply.h @@ -0,0 +1,55 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Msg_ +#define _SC_Msg_ + +#include <stdio.h> +#include <stdlib.h> +#ifdef SC_WIN32 +# include <winsock2.h> +#else +#include <netinet/in.h> +#endif +#include "sc_msg_iter.h" + +typedef void (*ReplyFunc)(struct ReplyAddress *inReplyAddr, char* inBuf, int inSize); + +void null_reply_func(struct ReplyAddress* addr, char* msg, int size); + +struct ReplyAddress +{ + struct sockaddr_in mSockAddr; + int mSockAddrLen; + int mSocket; + ReplyFunc mReplyFunc; +}; + +bool operator==(const ReplyAddress& a, const ReplyAddress& b); + +inline void SendReply(ReplyAddress *inReplyAddr, char* inBuf, int inSize) +{ + (inReplyAddr->mReplyFunc)(inReplyAddr, inBuf, inSize); +} + +#endif + + diff --git a/sc4pd/headers/server/SC_Samp.h b/sc4pd/headers/server/SC_Samp.h new file mode 100644 index 0000000..dde9159 --- /dev/null +++ b/sc4pd/headers/server/SC_Samp.h @@ -0,0 +1,38 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_Samp_ +#define _SC_Samp_ + +#include "SC_Types.h" + +const int kSineSize = 8192; +const int kSineMask = kSineSize - 1; + +extern float32 gSine[kSineSize+1]; +extern float32 gPMSine[kSineSize+1]; +extern float32 gInvSine[kSineSize+1]; +extern float32 gSineWavetable[2*kSineSize]; + +void SignalAsWavetable(float32* signal, float32* wavetable, long inSize); +void WavetableAsSignal(float32* wavetable, float32* signal, long inSize); + +#endif
\ No newline at end of file diff --git a/sc4pd/headers/server/SC_SequencedCommand.h b/sc4pd/headers/server/SC_SequencedCommand.h new file mode 100644 index 0000000..d1a7fb5 --- /dev/null +++ b/sc4pd/headers/server/SC_SequencedCommand.h @@ -0,0 +1,481 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Having SequencedCommands allows performing actions that might otherwise require + * taking a mutex, which is undesirable in a real time thread. + * Some commands require several stages of processing at both the real time + * and non real time levels. This class does the messaging between levels for you + * so that you only need to write the functions. + */ + +#ifndef _SC_SequencedCommand_ +#define _SC_SequencedCommand_ + +#include "OSC_Packet.h" +#include "SC_World.h" +#include "SC_BufGen.h" +#include "sc_msg_iter.h" +#include <sndfile.h> +#include <new> + +#define CallSequencedCommand(T, inWorld, inSize, inData, inReply) \ + void* space = World_Alloc(inWorld, sizeof(T)); \ + T *cmd = new (space) T(inWorld, inReply); \ + if (!cmd) return kSCErr_Failed; \ + int err = cmd->Init(inData, inSize); \ + if (err) { \ + cmd->~T(); \ + World_Free(inWorld, space); \ + return err; \ + } \ + if (inWorld->mRealTime) cmd->CallNextStage(); \ + else cmd->CallEveryStage(); + + +class SC_SequencedCommand +{ +public: + SC_SequencedCommand(World *inWorld, ReplyAddress *inReplyAddress); + virtual ~SC_SequencedCommand(); + + void Delete(); + + void CallEveryStage(); + void CallNextStage(); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage1(); // real time + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + + void SendDone(char *inCommandName); + +protected: + int mNextStage; + ReplyAddress mReplyAddress; + World *mWorld; + + int mMsgSize; + char *mMsgData; + + virtual void CallDestructor()=0; +}; + +/////////////////////////////////////////////////////////////////////////// + +class SyncCmd : public SC_SequencedCommand +{ +public: + SyncCmd(World *inWorld, ReplyAddress *inReplyAddress); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + virtual void CallDestructor(); + int mID; +}; + +/////////////////////////////////////////////////////////////////////////// + +class BufGenCmd : public SC_SequencedCommand +{ +public: + BufGenCmd(World *inWorld, ReplyAddress *inReplyAddress); + virtual ~BufGenCmd(); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + int mBufIndex; + BufGen *mBufGen; + sc_msg_iter mMsg; + char *mData; + int mSize; + SndBuf mSndBuf; + float *mFreeData; + + virtual void CallDestructor(); + +}; + +/////////////////////////////////////////////////////////////////////////// + +class BufAllocCmd : public SC_SequencedCommand +{ +public: + BufAllocCmd(World *inWorld, ReplyAddress *inReplyAddress); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + int mBufIndex; + SndBuf mSndBuf; + int mNumChannels, mNumFrames; + float *mFreeData; + + virtual void CallDestructor(); + +}; + +/////////////////////////////////////////////////////////////////////////// + + +class BufFreeCmd : public SC_SequencedCommand +{ +public: + BufFreeCmd(World *inWorld, ReplyAddress *inReplyAddress); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + int mBufIndex; + float *mFreeData; + + virtual void CallDestructor(); +}; + + +/////////////////////////////////////////////////////////////////////////// + + +class BufCloseCmd : public SC_SequencedCommand +{ +public: + BufCloseCmd(World *inWorld, ReplyAddress *inReplyAddress); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + int mBufIndex; + + virtual void CallDestructor(); +}; + + +/////////////////////////////////////////////////////////////////////////// + + +class BufZeroCmd : public SC_SequencedCommand +{ +public: + BufZeroCmd(World *inWorld, ReplyAddress *inReplyAddress); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + int mBufIndex; + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +class BufAllocReadCmd : public SC_SequencedCommand +{ +public: + BufAllocReadCmd(World *inWorld, ReplyAddress *inReplyAddress); + virtual ~BufAllocReadCmd(); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + int mBufIndex; + float *mFreeData; + SndBuf mSndBuf; + char *mFilename; + int mFileOffset, mNumFrames; + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +class BufReadCmd : public SC_SequencedCommand +{ +public: + BufReadCmd(World *inWorld, ReplyAddress *inReplyAddress); + virtual ~BufReadCmd(); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + int mBufIndex; + char *mFilename; + int mFileOffset, mNumFrames, mBufOffset; + bool mLeaveFileOpen; + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +class BufWriteCmd : public SC_SequencedCommand +{ +public: + BufWriteCmd(World *inWorld, ReplyAddress *inReplyAddress); + virtual ~BufWriteCmd(); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + int mBufIndex; + char *mFilename; + SF_INFO mFileInfo; + int mNumFrames, mBufOffset; + bool mLeaveFileOpen; + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +class AudioQuitCmd : public SC_SequencedCommand +{ +public: + AudioQuitCmd(World *inWorld, ReplyAddress *inReplyAddress); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +class AudioStatusCmd : public SC_SequencedCommand +{ +public: + AudioStatusCmd(World *inWorld, ReplyAddress *inReplyAddress); + + virtual bool Stage2(); // non real time + +protected: + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +class NotifyCmd : public SC_SequencedCommand +{ +public: + NotifyCmd(World *inWorld, ReplyAddress *inReplyAddress); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + +protected: + + virtual void CallDestructor(); + + int mOnOff; + int mID; +}; + + +/////////////////////////////////////////////////////////////////////////// + +#define CallSendFailureCommand(inWorld, inCmdName, inErrString, inReply) \ + void* space = World_Alloc(inWorld, sizeof(SendFailureCmd)); \ + SendFailureCmd *cmd = new (space) SendFailureCmd(inWorld, inReply); \ + if (!cmd) return kSCErr_Failed; \ + cmd->InitSendFailureCmd(inCmdName, inErrString); \ + if (inWorld->mRealTime) cmd->CallNextStage(); \ + else cmd->CallEveryStage(); \ + +class SendFailureCmd : public SC_SequencedCommand +{ +public: + SendFailureCmd(World *inWorld, ReplyAddress *inReplyAddress); + virtual ~SendFailureCmd(); + + virtual void InitSendFailureCmd(const char *inCmdName, const char* inErrString); + + virtual bool Stage2(); // non real time + +protected: + char *mCmdName, *mErrString; + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +#include "SC_GraphDef.h" + +class LoadSynthDefCmd : public SC_SequencedCommand +{ +public: + LoadSynthDefCmd(World *inWorld, ReplyAddress *inReplyAddress); + virtual ~LoadSynthDefCmd(); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + char *mFilename; + GraphDef *mDefs; + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +#include "SC_GraphDef.h" + +class RecvSynthDefCmd : public SC_SequencedCommand +{ +public: + RecvSynthDefCmd(World *inWorld, ReplyAddress *inReplyAddress); + virtual ~RecvSynthDefCmd(); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + char *mBuffer; + GraphDef *mDefs; + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +class LoadSynthDefDirCmd : public SC_SequencedCommand +{ +public: + LoadSynthDefDirCmd(World *inWorld, ReplyAddress *inReplyAddress); + virtual ~LoadSynthDefDirCmd(); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + char *mFilename; + GraphDef *mDefs; + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +class SendReplyCmd : public SC_SequencedCommand +{ +public: + SendReplyCmd(World *inWorld, ReplyAddress *inReplyAddress); + + virtual int Init(char *inData, int inSize); + + virtual bool Stage2(); // non real time + +protected: + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + + +typedef bool (*AsyncStageFn)(World *inWorld, void* cmdData); +typedef void (*AsyncFreeFn)(World *inWorld, void* cmdData); + +class AsyncPlugInCmd : public SC_SequencedCommand +{ +public: + AsyncPlugInCmd(World *inWorld, ReplyAddress *inReplyAddress, + const char* cmdName, + void *cmdData, + AsyncStageFn stage2, // stage2 is non real time + AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true + AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true + AsyncFreeFn cleanup, + int completionMsgSize, + void* completionMsgData); + + virtual ~AsyncPlugInCmd(); + + virtual bool Stage2(); // non real time + virtual bool Stage3(); // real time + virtual void Stage4(); // non real time + +protected: + const char *mCmdName; + void *mCmdData; + AsyncStageFn mStage2, mStage3, mStage4; + AsyncFreeFn mCleanup; + + virtual void CallDestructor(); +}; + +/////////////////////////////////////////////////////////////////////////// + +#endif + diff --git a/sc4pd/headers/server/SC_Str4.h b/sc4pd/headers/server/SC_Str4.h new file mode 100644 index 0000000..306b823 --- /dev/null +++ b/sc4pd/headers/server/SC_Str4.h @@ -0,0 +1,103 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* a 4 byte aligned and zero padded string allows faster string operations. */ + +#ifndef _SC_Str4_ +#define _SC_Str4_ + +#include "Hash.h" +#include <stdio.h> +#include <limits.h> + +#ifndef _LASTCHAR_ +#define _LASTCHAR_ +#if BYTE_ORDER == LITTLE_ENDIAN +const int32 kLASTCHAR = 0xFF000000; +#else +const int32 kLASTCHAR = 0x000000FF; +#endif +#endif + + +void str4cpy(int32 *dst, const char *src); +void mem4cpy(int32 *dst, const char *src, int charlen); + +// returns the number of pad bytes to add to a string of a given length +inline int str4padbytes(int charlen) +{ + return 4 - (charlen & 3); +} + +// converts length in bytes to length in words +inline int str4len(int charlen) +{ + return (charlen + 4) >> 2; +} + +// returns length in words of a char * +inline int str4len(const char *src) +{ + const char *src0 = src; + while (*src) { src++; } + return str4len(src - src0); +} + +// returns length in words of a int32 * +inline int str4len(const int32 *src) +{ + const int32 *src0 = src; + while (*src++ & kLASTCHAR) {} + int wordlen = src - src0; + return wordlen; +} + +// returns length in words of a int32 * +inline bool str4eq(const int32 *a, const int32 *b) +{ + while(true) { + if (*a != *b) return false; + if ((*a & kLASTCHAR) == 0) return true; + a++; b++; + } +} + +// copy an int32 * +inline void str4cpy(int32 *dst, const int32 *src) +{ + int32 c; + do { + *dst++ = c = *src++; + } while (c & kLASTCHAR); +} + +inline int sc_atoi(char *string) +{ + int value = 0; + if (*string == 0) return -1; + uint32 c; + while ((c = *string++ - '0') <= 9) { + value = value * 10 + c; + } + return value; +} + + +#endif diff --git a/sc4pd/headers/server/SC_SyncCondition.h b/sc4pd/headers/server/SC_SyncCondition.h new file mode 100644 index 0000000..a75fbaa --- /dev/null +++ b/sc4pd/headers/server/SC_SyncCondition.h @@ -0,0 +1,45 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#ifndef _SC_SyncCondition_ +#define _SC_SyncCondition_ + +#include <pthread.h> + +class SC_SyncCondition +{ +public: + SC_SyncCondition(); + ~SC_SyncCondition(); + + void WaitEach(); + void WaitOnce(); + void WaitNext(); + void Signal(); + +private: + pthread_cond_t available; + pthread_mutex_t mutex; + int read, write; +}; + +#endif + diff --git a/sc4pd/headers/server/SC_SynthDef.h b/sc4pd/headers/server/SC_SynthDef.h new file mode 100644 index 0000000..89d5e47 --- /dev/null +++ b/sc4pd/headers/server/SC_SynthDef.h @@ -0,0 +1,43 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SynthDef_ +#define _SynthDef_ + +#include "SC_Types.h" +#include "sc_msg_iter.h" + +typedef void (*NodeDtorFunc)(struct Node* inNode); + +struct NodeDef +{ + int32 mName[kSCNameLen]; + int32 mHash; + + size_t mAllocSize; +}; +typedef struct NodeDef NodeDef; + +extern NodeDef gGroupNodeDef; + +void GroupNodeDef_Init(); +void NodeDef_Dump(NodeDef *inNodeDef); + +#endif diff --git a/sc4pd/headers/server/SC_UnitDef.h b/sc4pd/headers/server/SC_UnitDef.h new file mode 100644 index 0000000..0f75490 --- /dev/null +++ b/sc4pd/headers/server/SC_UnitDef.h @@ -0,0 +1,69 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _UnitDef_ +#define _UnitDef_ + +#include "SC_Types.h" +#include "SC_Unit.h" +#include "HashTable.h" + +struct PlugInCmd +{ + int32 mCmdName[kSCNameLen]; + int32 mHash; + PlugInCmdFunc mFunc; + void *mUserData; +}; + +struct UnitCmd +{ + int32 mCmdName[kSCNameLen]; + int32 mHash; + UnitCmdFunc mFunc; +}; + +struct UnitDef +{ + int32 mUnitDefName[kSCNameLen]; + int32 mHash; + + size_t mAllocSize; + UnitCtorFunc mUnitCtorFunc; + UnitDtorFunc mUnitDtorFunc; + + HashTable<UnitCmd, Malloc>* mCmds; + uint32 mFlags; +}; + +extern "C" { +bool UnitDef_Create(char *inName, size_t inAllocSize, + UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags); +bool UnitDef_AddCmd(char *inUnitDefName, char *inCmdName, UnitCmdFunc inFunc); +bool PlugIn_DefineCmd(char *inCmdName, PlugInCmdFunc inFunc, void *inUserData); +} + +int Unit_DoCmd(World *inWorld, int inSize, char *inData); + +inline int32* GetKey(UnitCmd *inCmd) { return inCmd->mCmdName; } +inline int32 GetHash(UnitCmd *inCmd) { return inCmd->mHash; } + + +#endif diff --git a/sc4pd/headers/server/SC_UnitSpec.h b/sc4pd/headers/server/SC_UnitSpec.h new file mode 100644 index 0000000..c72e103 --- /dev/null +++ b/sc4pd/headers/server/SC_UnitSpec.h @@ -0,0 +1,41 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_UnitSpec_ +#define _SC_UnitSpec_ + +#include <ctype.h> // for size_t + +#include "SC_Unit.h" + +struct UnitSpec +{ + struct UnitDef* mUnitDef; + int16 mCalcRate; + uint16 mNumInputs, mNumOutputs; + int16 mSpecialIndex; + struct InputSpec* mInputSpec; + struct OutputSpec* mOutputSpec; + struct Rate* mRateInfo; + size_t mAllocSize; +}; +typedef struct UnitSpec UnitSpec; + +#endif diff --git a/sc4pd/headers/server/SC_WireSpec.h b/sc4pd/headers/server/SC_WireSpec.h new file mode 100644 index 0000000..33ea15c --- /dev/null +++ b/sc4pd/headers/server/SC_WireSpec.h @@ -0,0 +1,47 @@ +/* + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _SC_WireSpec_ +#define _SC_WireSpec_ + +#include "SC_Types.h" + +struct InputSpec +{ + // read from file: + int16 mFromUnitIndex; + int16 mFromOutputIndex; + // computed: + int16 mWireIndex; +}; +typedef struct InputSpec InputSpec; + +struct OutputSpec +{ + // read from file: + int16 mCalcRate; + // computed: + int16 mWireIndex; + int16 mBufferIndex; + int16 mNumConsumers; +}; +typedef struct OutputSpec OutputSpec; + +#endif diff --git a/sc4pd/make-files.txt b/sc4pd/make-files.txt new file mode 100644 index 0000000..486674f --- /dev/null +++ b/sc4pd/make-files.txt @@ -0,0 +1,19 @@ +# all the source files from the package +SRCDIR = source +SRCS= \ + main.cpp Dust.cpp MantissaMask.cpp Hasher.cpp Median.cpp \ + BrownNoise.cpp ClipNoise.cpp GrayNoise.cpp WhiteNoise.cpp \ + PinkNoise.cpp Dust2.cpp Crackle.cpp Rand.cpp TRand.cpp TExpRand.cpp \ + IRand.cpp TIRand.cpp CoinGate.cpp support.cpp LinRand.cpp NRand.cpp\ + ExpRand.cpp LFClipNoise.cpp LFNoise0.cpp LFNoise1.cpp LFNoise2.cpp \ + Logistic.cpp Latoocarfian.cpp LinCong.cpp amclip.cpp scaleneg.cpp \ + excess.cpp hypot.cpp ring1.cpp ring2.cpp ring3.cpp ring4.cpp \ + difsqr.cpp sumsqr.cpp sqrdif.cpp sqrsum.cpp absdif.cpp LFSaw.cpp \ + LFPulse.cpp Impulse.cpp Integrator.cpp Decay.cpp Decay2.cpp Lag.cpp \ + Lag2.cpp Lag3.cpp LinExp.cpp DelayUnit.cpp DelayN.cpp DelayL.cpp \ + DelayC.cpp CombN.cpp CombL.cpp CombC.cpp AllpassN.cpp AllpassL.cpp \ + AllpassC.cpp PitchShift.cpp Resonz.cpp OnePole.cpp OneZero.cpp \ + TwoPole.cpp TwoZero.cpp FOS.cpp SOS.cpp RLPF.cpp RHPF.cpp LPF.cpp \ + HPF.cpp BPF.cpp BRF.cpp LPZ1.cpp HPZ1.cpp LPZ2.cpp HPZ2.cpp \ + BPZ2.cpp BRZ2.cpp LFDNoise0.cpp LFDNoise1.cpp LFDNoise2.cpp \ + sc+.cpp sc-.cpp scmul.cpp scdiv.cpp Convolution.cpp diff --git a/sc4pd/makefile.max-msvc b/sc4pd/makefile.max-msvc new file mode 100644 index 0000000..8a1225f --- /dev/null +++ b/sc4pd/makefile.max-msvc @@ -0,0 +1,77 @@ +# makefile adapted from thomas grill's xsample makefile +# +# Makefile for MSVC++ 6 and .NET +# +# usage: +# to build run "make -f makefile.max-msvc" +# + +!include config-max-msvc.txt + +# includes +INCPATH=/I$(MAXSDKPATH)\max-includes /I$(MAXSDKPATH)\msp-includes /I$(FLEXTPATH) /I./headers/plugin_interface /I./headers/common /I./headers/server /I./headers/app /I./headers/lang +LDFLAGS=/LIBPATH:$(FLEXTPATH) + +!ifdef MSVCPATH +INCPATH=$(INCPATH) /I$(MSVCPATH)\include +LDFLAGS=$(LDFLAGS) /LIBPATH:$(MSVCPATH)\lib +!endif + +!ifdef _DEBUG +LIBS=flext_d-maxwin.lib +!else +LIBS=flext-maxwin.lib +!endif + +LDFLAGS=$(LDFLAGS) /LIBPATH:$(MAXSDKPATH)\max-includes /LIBPATH:$(MAXSDKPATH)\msp-includes + +LIBS=$(LIBS) maxapi.lib maxaudio.lib + +# compiler definitions and flags +DEFS=/DFLEXT_SYS=1 $(UFLAGS) + +CFLAGS=/ML /GR- /GD /Ox /GX /Zp2 + +# the rest can stay untouched +# ---------------------------------------------- + +# all the source files from the package +!include make-files.txt + +# ----------------------------------------------- + +NAME=sc4pd +EXT=mxe +DIR=source + +all: $(OUTPATH) $(OUTPATH)\$(NAME).$(EXT) + +# remove build +clean: + -del /q $(OUTPATH) > nul + -rmdir $(OUTPATH) > nul + +OBJS= $(SRCS:.c=.obj) +OBJS= $(OBJS:.objpp=.obj) + + +$(OUTPATH): + -mkdir $(OUTPATH) > nul + +{$(DIR)}.cpp{}.obj: + cl /c /LD $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(OUTPATH)/$@ + +{$(DIR)}.c{}.obj: + cl /c /LD $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(OUTPATH)/$@ + + +$(OUTPATH)\$(NAME).$(EXT): $(OBJS) + cd $(OUTPATH) + link /DLL $(LDFLAGS) /out:$(NAME).$(EXT) /INCREMENTAL:NO $** $(LIBS) $(LIBPATH) + @-del *.exp + @-del *.lib + cd .. +!ifdef INSTPATH + @-if not exist $(INSTPATH) mkdir $(INSTPATH) + copy $@ $(INSTPATH) > nul +!endif diff --git a/sc4pd/makefile.pd-bcc b/sc4pd/makefile.pd-bcc new file mode 100644 index 0000000..41c06c2 --- /dev/null +++ b/sc4pd/makefile.pd-bcc @@ -0,0 +1,73 @@ +# makefile adapted from thomas grill's xsample makefile +# +# Makefile for BorlandC++ +# +# usage: make -f makefile.pd-bcc +# +# --------------------------------------------- + +!include config-pd-bcc.txt + +# all the source files from the package +!include make-files.txt + +SETUPFUNCTION=$(NAME)_setup + +# flext stuff +TARGET=pdwin + +# includes, libs +INCPATH=-I$(BCCPATH)\include -I$(PDPATH)\src -I$(FLEXTPATH) ./headers/plugin_interface ./headers/common ./headers/server ./headers/app ./headers/lang +LIBPATH=-L$(BCCPATH)\lib -L$(PDPATH)\lib +LIBS=cw32.lib import32.lib C0D32.OBJ + +# compiler definitions and flags +DEFS=-DFLEXT_SYS=2 +CFLAGS=-tWD $(UFLAGS) + + +# the rest can stay untouched +# ---------------------------------------------- + +# default target +all: $(OUTPATH)\$(NAME).dll + +# remove build +clean: + -del /s /q $(OUTPATH) > nul + rmdir $(OUTPATH) + + +install: + cp $(OUTPATH)\$(NAME).dll $(INSTDIR) + +# ---------------------------------------------- + +OBJS= $(SRCS:.cpp=.obj) + +#.PATH.OBJ=$(OUTPATH) + +#$(SRCS): $(HDRS) +# -touch $< + +{$(SRCDIR)}.cpp.obj: + bcc32 -c $(CFLAGS) $(DEFS) $(INCPATH) -n$(OUTPATH) $< + +$(OUTPATH): + -@if not exist $< mkdir $< + +$(OUTPATH)\pd.lib: $(PDPATH)\bin\pd.dll + implib -a $< $** + +$(OUTPATH)\$(NAME).def: + @echo EXPORTS $(SETUPFUNCTION) = _$(SETUPFUNCTION) > $< +# this next line fixes a strange problem with implib - lacking underscore?! + @echo IMPORTS _rtext_retext=PD.rtext_retext >> $< + +$(OUTPATH)\$(NAME).dll :: $(OUTPATH) $(OUTPATH)\$(NAME).def $(OUTPATH)\pd.lib + +$(OUTPATH)\$(NAME).dll :: $(OBJS) + cd $(OUTPATH) + ilink32 -C -Tpd $(LIBPATH) $** ,..\$<,,$(LIBS) pd.lib $(FLEXTPATH)\flext-$(TARGET).lib ,$(NAME).def + cd .. +
\ No newline at end of file diff --git a/sc4pd/makefile.pd-cygwin b/sc4pd/makefile.pd-cygwin new file mode 100644 index 0000000..a04569d --- /dev/null +++ b/sc4pd/makefile.pd-cygwin @@ -0,0 +1,86 @@ +# makefile adapted from thomas grill's xsample makefile +# +# Makefile for gcc @ cygwin +# +# usage: +# to build run "make -f makefile.pd-cygwin" +# to install (as root), do "make -f makefile.pd-cygwin install" +# + +CONFIG=config-pd-cygwin.txt +MAKEFILE=makefile.pd-cygwin + +include ${CONFIG} + + +# compiler stuff +# /usr/include holds the cygwin pthread headers and must be first! +INCLUDES=/usr/include $(PDINC) ./headers/plugin_interface ./headers/common ./headers/server ./headers/app ./headers/lang + +FLAGS=-DFLEXT_SYS=2 +CFLAGS=-O2 -funroll-loops -fmove-all-movables -frerun-loop-opt -finline-functions -fno-rtti -fno-exceptions ${UFLAGS} + +PDLIBS=$(PD)/bin/pd.dll $(PD)/bin/pthreadVC.dll + + +ifdef FLEXT_SHARED + +CFLAGS+=-DFLEXT_SHARED +FLEXTLIB=$(FLEXTPATH)/flext.dll + +else + +FLEXTLIB=$(FLEXTPATH)/flext-pdwin.lib + +endif + + +# ---------------------------------------------- +# the rest can stay untouched +# ---------------------------------------------- + +NAME=sc4pd + +include make-files.txt + +TARGET=$(TARGDIR)/$(NAME).dll + +# default target +all: $(TARGDIR) $(TARGET) + +$(patsubst %,$(SRCDIR)/%,$(SRCS)): $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(MAKEFILE) $(CONFIG) + touch $(patsubst %,$(SRCDIR)/%,$(SRCS)) + +$(TARGDIR): + -mkdir $(TARGDIR) + +$(TARGDIR)/%.o : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(FLEXTPATH)) $< -o $@ + +$(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS)) $(FLEXTLIB) + $(CXX) -shared $(LDFLAGS) $^ ${PDLIBS} $(patsubst %,-l%,$(LIBS)) -o $@ + strip --strip-unneeded $@ + chmod 755 $@ + +$(INSTDIR): + -mkdir $(INSTDIR) + +install:: $(INSTDIR) + +install:: $(TARGET) + cp $^ $(INSTDIR) +# chown root.root $(patsubst %,$(INSTDIR)/%,$(notdir $^)) + +$(HELPDIR): + -mkdir $(HELPDIR) + +install-help:: $(HELPDIR) + +install-help:: ./pd + chmod 644 $^/*.* + cp $^/*.* $(HELPDIR) + + +.PHONY: clean +clean: + rm -f $(TARGDIR)/*.o $(TARGET) diff --git a/sc4pd/makefile.pd-darwin b/sc4pd/makefile.pd-darwin new file mode 100755 index 0000000..9523425 --- /dev/null +++ b/sc4pd/makefile.pd-darwin @@ -0,0 +1,77 @@ +# makefile adapted from thomas grill's xsample makefile +# +# Makefile for gcc @ OSX (darwin) +# +# usage: +# to build run "make -f makefile.pd-darwin" +# to install (as root), do "make -f makefile.pd-darwin install" +# to install help, do "make -f makefile.pd-darwin install-help" +# + +CONFIG=config-pd-darwin.txt + +include ${CONFIG} + +FLEXTLIB=$(FLEXTPATH)/libflext.a + +# compiler stuff +INCLUDES=$(PDINC) ./headers/plugin_interface ./headers/common ./headers/server ./headers/app ./headers/lang /usr/include/machine/ +FLAGS=-DFLEXT_SYS=2 +CFLAGS=${UFLAGS} -dynamic -O2 -Wno-unused -Wno-parentheses -Wno-switch -Wstrict-prototypes -funroll-loops -fmove-all-movables -frerun-loop-opt -fno-rtti -fno-exceptions +LIBS=m gcc +LDFLAGS=$(FLEXTLIB) -bundle -bundle_loader $(PDBIN) +FRAMEWORKS=Carbon veclib + +# ---------------------------------------------- +# the rest can stay untouched +# ---------------------------------------------- + +NAME=sc4pd + +include make-files.txt + +MAKEFILE=makefile.pd-darwin +TARGET=$(TARGDIR)/$(NAME).pd_darwin + + +# default target +all: $(TARGDIR) $(TARGET) + +$(patsubst %,$(SRCDIR)/%,$(SRCS)): $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(MAKEFILE) $(CONFIG) + touch $(patsubst %,$(SRCDIR)/%,$(SRCS)) + +$(TARGDIR): + -mkdir $(TARGDIR) + +$(TARGDIR)/%.o : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(FLEXTPATH)) $< -o $@ + +$(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS)) + $(CXX) $(LDFLAGS) $^ $(patsubst %,-framework %,$(FRAMEWORKS)) $(patsubst %,-L%,$(LIBPATH)) $(patsubst %,-l%,$(LIBS)) -o $@ + chmod 755 $@ + + +$(INSTDIR): + -mkdir $(INSTDIR) + +install:: $(INSTDIR) + +install:: $(TARGET) + cp -R $^ $(INSTDIR) +# chown -R root.root $(INSTDIR) + + +$(HELPDIR): + -mkdir $(HELPDIR) + +install-help:: $(HELPDIR) + +install-help:: ./pd + cp $^/*.* $(HELPDIR) +# chown -R root.root $(HELPDIR) + + +.PHONY: clean +clean: + rm -f $(TARGDIR)/*.o $(TARGET) + diff --git a/sc4pd/makefile.pd-linux b/sc4pd/makefile.pd-linux new file mode 100644 index 0000000..f1deedb --- /dev/null +++ b/sc4pd/makefile.pd-linux @@ -0,0 +1,94 @@ +# makefile adapted from thomas grill's xsample makefile +# +# Makefile for gcc @ linux +# +# usage: +# to build run "make -f makefile.pd-linux" +# to install (as root), do "make -f makefile.pd-linux install" +# + +CONFIG=config-pd-linux.txt + +include ${CONFIG} + +FLEXTLIB=$(FLEXTPATH)/flext.a + +# compiler stuff +INCLUDES=$(PDINC) ./headers/plugin_interface ./headers/common \ + ./headers/server ./headers/app ./headers/lang +FLAGS=-DFLEXT_SYS=2 +CFLAGS=${UFLAGS} -O3 -I/home/tim/pd/externals/grill/flext/source -funroll-loops -fmove-all-movables -frerun-loop-opt -finline-functions -fno-rtti -fno-exceptions + +LIBS=m + +ifdef FLEXT_SHARED +CFLAGS+=-DFLEXT_SHARED -DFLEXT_THREADS +LDFLAGS+=-Bdynamic +LINKFLEXT=-lflext_d +else +LINKFLEXT=$(FLEXTLIB) +endif + + +# ---------------------------------------------- +# the rest can stay untouched +# ---------------------------------------------- + +NAME=sc4pd + +include make-files.txt + +MAKEFILE=makefile.pd-linux +TARGET=$(TARGDIR)/$(NAME).pd_linux + +# default target +all: $(TARGDIR) $(TARGET) + +$(patsubst %,$(SRCDIR)/%,$(SRCS)): $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(MAKEFILE) $(CONFIG) +# touch $(patsubst %,$(SRCDIR)/%,$(SRCS)) + +$(TARGDIR): + -mkdir $(TARGDIR) + +$(TARGDIR)/%.o : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(FLEXTPATH)) $< -o $@ + +$(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS)) + $(CXX) $(LDFLAGS) -shared $^ $(patsubst %,-l%,$(LIBS)) -L$(FLEXTPATH) $(LINKFLEXT) -o $@ + strip --strip-unneeded $@ + chmod 755 $@ + +$(INSTDIR): + -mkdir $(INSTDIR) + +install:: $(INSTDIR) + +install:: $(TARGET) + cp $^ $(INSTDIR) + chown root.root $(patsubst %,$(INSTDIR)/%,$(notdir $^)) + +$(HELPDIR): + -mkdir $(HELPDIR) + +install-help:: $(HELPDIR) + +install-help:: ./pd + chmod 644 $^/*.* + cp $^/*.* $(HELPDIR) + + +.PHONY: clean +clean: + rm -f $(TARGDIR)/*.o $(TARGET) + + + + + + + + + + + + diff --git a/sc4pd/makefile.pd-mingw b/sc4pd/makefile.pd-mingw new file mode 100644 index 0000000..62cf1ae --- /dev/null +++ b/sc4pd/makefile.pd-mingw @@ -0,0 +1,85 @@ +# makefile adapted from thomas grill's xsample makefile +# +# Makefile for gcc @ minGW +# +# usage: +# to build run "make -f makefile.pd-mingw" +# to install (as root), do "make -f makefile.pd-mingw install" +# + +CONFIG=config-pd-mingw.txt +MAKEFILE=makefile.pd-mingw + +include ${CONFIG} + + +# compiler stuff +INCLUDES=$(PDINC) ./headers/plugin_interface ./headers/common ./headers/server ./headers/app ./headers/lang + +FLAGS=-DFLEXT_SYS=2 +CFLAGS=-O2 -funroll-loops -fmove-all-movables -frerun-loop-opt -finline-functions -fno-rtti -fno-exceptions ${UFLAGS} + +PDLIBS=$(PD)/bin/pd.dll $(PD)/bin/pthreadVC.dll + + +ifdef FLEXT_SHARED + +CFLAGS+=-DFLEXT_SHARED +FLEXTLIB=$(FLEXTPATH)/flext.dll + +else + +FLEXTLIB=$(FLEXTPATH)/flext-pdwin.lib + +endif + + +# ---------------------------------------------- +# the rest can stay untouched +# ---------------------------------------------- + +NAME=sc4pd + +include make-files.txt + +TARGET=$(TARGDIR)/$(NAME).dll + +# default target +all: $(TARGDIR) $(TARGET) + +$(patsubst %,$(SRCDIR)/%,$(SRCS)): $(patsubst %,$(SRCDIR)/%,$(HDRS)) $(MAKEFILE) $(CONFIG) +# echo touch $(patsubst %,$(SRCDIR)/%,$(SRCS)) # minGW has no touch + +$(TARGDIR): + -mkdir $(TARGDIR) + +$(TARGDIR)/%.o : $(SRCDIR)/%.cpp + $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(FLEXTPATH)) $< -o $@ + +$(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS)) $(FLEXTLIB) + $(CXX) -shared $(LDFLAGS) $^ ${PDLIBS} $(patsubst %,-l%,$(LIBS)) -o $@ + strip --strip-unneeded $@ + chmod 755 $@ + +$(INSTDIR): + -mkdir $(INSTDIR) + +install:: $(INSTDIR) + +install:: $(TARGET) + cp $^ $(INSTDIR) +# chown root.root $(patsubst %,$(INSTDIR)/%,$(notdir $^)) + +$(HELPDIR): + -mkdir $(HELPDIR) + +install-help:: $(HELPDIR) + +install-help:: ./pd + chmod 644 $^/*.* + cp $^/*.* $(HELPDIR) + + +.PHONY: clean +clean: + rm -f $(TARGDIR)/*.o $(TARGET) diff --git a/sc4pd/makefile.pd-msvc b/sc4pd/makefile.pd-msvc new file mode 100644 index 0000000..11ccda9 --- /dev/null +++ b/sc4pd/makefile.pd-msvc @@ -0,0 +1,53 @@ +# makefile adapted from thomas grill's xsample makefile +# +# Makefile for MSVC++ 6 +# +# usage: +# to build run "make -f makefile.pd-msvc" +# + +!include config-pd-msvc.txt + +# includes +INCPATH=/I"$(MSVCPATH)\include" /I"$(PDPATH)\src" /I"$(FLEXTPATH)" /I"./headers/plugin_interface" /I"./headers/common" /I"/headers/server" /I"./headers/app" /I"./headers/lang +LIBPATH=/LIBPATH:"$(MSVCPATH)\lib" /LIBPATH:"$(PDPATH)\bin" /LIBPATH:"$(FLEXTPATH)" +LIBS=pd.lib pthreadVC.lib flext-pdwin.lib + +# compiler definitions and flags +DEFS=/DFLEXT_SYS=2 + +CFLAGS=/GR- /GX- /GD /G6 /Ox /EHsc /ML + +# the rest can stay untouched +# ---------------------------------------------- + +NAME=sc4pd + +!include make-files.txt + + +all: $(OUTPATH) $(OUTPATH)\$(NAME).dll + +# remove build +clean: + -del /q $(OUTPATH) > nul + -rmdir $(OUTPATH) > nul + +OBJS= $(SRCS:.cpp=.obj) + +$(OUTPATH): + -mkdir $(OUTPATH) > nul + +{$(SRCDIR)}.cpp{}.obj: + cl /c /LD $(CFLAGS) $(DEFS) $(INCPATH) $** /Fo$(OUTPATH)\$@ + +$(OUTPATH)\$(NAME).dll: $(OBJS) + cd $(OUTPATH) + link /DLL /out:$(NAME).dll /INCREMENTAL:NO $** $(LIBS) $(LIBPATH) + @-del *.exp + @-del *.lib + cd .. +!ifdef INSTPATH + @-if not exist $(INSTPATH) mkdir $(INSTPATH) + copy $@ $(INSTPATH) > nul +!endif diff --git a/sc4pd/package.txt b/sc4pd/package.txt new file mode 100644 index 0000000..c366fee --- /dev/null +++ b/sc4pd/package.txt @@ -0,0 +1,24 @@ +NAME=sc4pd
+
+SRCDIR=source
+
+SRCS=main.cpp Dust.cpp MantissaMask.cpp Hasher.cpp Median.cpp \
+ BrownNoise.cpp ClipNoise.cpp GrayNoise.cpp WhiteNoise.cpp \
+ PinkNoise.cpp Dust2.cpp Crackle.cpp Rand.cpp TRand.cpp TExpRand.cpp \
+ IRand.cpp TIRand.cpp CoinGate.cpp support.cpp LinRand.cpp NRand.cpp\
+ ExpRand.cpp LFClipNoise.cpp LFNoise0.cpp LFNoise1.cpp LFNoise2.cpp \
+ Logistic.cpp Latoocarfian.cpp LinCong.cpp amclip.cpp scaleneg.cpp \
+ excess.cpp hypot.cpp ring1.cpp ring2.cpp ring3.cpp ring4.cpp \
+ difsqr.cpp sumsqr.cpp sqrdif.cpp sqrsum.cpp absdif.cpp LFSaw.cpp \
+ LFPulse.cpp Impulse.cpp Integrator.cpp Decay.cpp Decay2.cpp Lag.cpp \
+ Lag2.cpp Lag3.cpp LinExp.cpp DelayUnit.cpp DelayN.cpp DelayL.cpp \
+ DelayC.cpp CombN.cpp CombL.cpp CombC.cpp AllpassN.cpp AllpassL.cpp \
+ AllpassC.cpp PitchShift.cpp Resonz.cpp OnePole.cpp OneZero.cpp \
+ TwoPole.cpp TwoZero.cpp FOS.cpp SOS.cpp RLPF.cpp RHPF.cpp LPF.cpp \
+ HPF.cpp BPF.cpp BRF.cpp LPZ1.cpp HPZ1.cpp LPZ2.cpp HPZ2.cpp \
+ BPZ2.cpp BRZ2.cpp LFDNoise0.cpp LFDNoise1.cpp LFDNoise2.cpp \
+ sc+.cpp sc-.cpp scmul.cpp scdiv.cpp Convolution.cpp
+
+HDRS=DelayUnit.hpp fftlib.h sc4pd.hpp support.hpp
+
+INCPATH=-I./headers/plugin_interface -I./headers/common -I./headers/server
\ No newline at end of file diff --git a/sc4pd/pd/LinRand.pd b/sc4pd/pd/LinRand.pd new file mode 100644 index 0000000..30c610f --- /dev/null +++ b/sc4pd/pd/LinRand.pd @@ -0,0 +1,4 @@ +#N canvas 0 0 450 300 10; +#X obj 226 70 LinRand 1 2 3; +#X floatatom 226 95 5 0 0 0 - - -; +#X connect 0 0 1 0; diff --git a/sc4pd/pd/allpassc.pd b/sc4pd/pd/allpassc.pd new file mode 100644 index 0000000..297cb91 --- /dev/null +++ b/sc4pd/pd/allpassc.pd @@ -0,0 +1,20 @@ +#N canvas 0 0 450 300 10; +#X floatatom 188 40 5 0 0 0 - - -; +#X obj 67 187 dac~; +#X msg 185 88 delaytime \$1; +#X obj 111 190 print~; +#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 316 83 5 0 0 0 - - -; +#X msg 316 107 decaytime \$1; +#X obj 77 138 AllpassC~ 1 0.001 0.2; +#X obj 79 57 Dust~ 55; +#X connect 0 0 2 0; +#X connect 2 0 7 0; +#X connect 4 0 3 0; +#X connect 5 0 6 0; +#X connect 6 0 7 0; +#X connect 7 0 1 0; +#X connect 7 0 1 1; +#X connect 7 0 3 0; +#X connect 8 0 7 0; diff --git a/sc4pd/pd/allpassl.pd b/sc4pd/pd/allpassl.pd new file mode 100644 index 0000000..e2f3251 --- /dev/null +++ b/sc4pd/pd/allpassl.pd @@ -0,0 +1,20 @@ +#N canvas 0 0 450 300 10; +#X floatatom 188 40 5 0 0 0 - - -; +#X obj 67 187 dac~; +#X msg 185 88 delaytime \$1; +#X obj 111 190 print~; +#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 316 83 5 0 0 0 - - -; +#X msg 316 107 decaytime \$1; +#X obj 79 57 Dust~ 4; +#X obj 77 138 AllpassL~ 1 0.001 0.2; +#X connect 0 0 2 0; +#X connect 2 0 8 0; +#X connect 4 0 3 0; +#X connect 5 0 6 0; +#X connect 6 0 8 0; +#X connect 7 0 8 0; +#X connect 8 0 1 0; +#X connect 8 0 1 1; +#X connect 8 0 3 0; diff --git a/sc4pd/pd/allpassn.pd b/sc4pd/pd/allpassn.pd new file mode 100644 index 0000000..c0406b9 --- /dev/null +++ b/sc4pd/pd/allpassn.pd @@ -0,0 +1,20 @@ +#N canvas 0 0 450 300 10; +#X floatatom 188 40 5 0 0 0 - - -; +#X obj 67 187 dac~; +#X msg 185 88 delaytime \$1; +#X obj 111 190 print~; +#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 316 83 5 0 0 0 - - -; +#X msg 316 107 decaytime \$1; +#X obj 77 138 AllpassN~ 1 0.001 0.2; +#X obj 79 57 Dust~ 4; +#X connect 0 0 2 0; +#X connect 2 0 7 0; +#X connect 4 0 3 0; +#X connect 5 0 6 0; +#X connect 6 0 7 0; +#X connect 7 0 1 0; +#X connect 7 0 1 1; +#X connect 7 0 3 0; +#X connect 8 0 7 0; diff --git a/sc4pd/pd/amclip.pd b/sc4pd/pd/amclip.pd new file mode 100644 index 0000000..21cfb91 --- /dev/null +++ b/sc4pd/pd/amclip.pd @@ -0,0 +1,16 @@ +#N canvas 0 0 450 300 10; +#X obj 33 137 amclip~; +#X obj 26 88 osc~ 440; +#X obj 22 176 dac~; +#X floatatom 327 136 5 0 0 0 - - -; +#X obj 96 113 osc~ 40; +#X floatatom 222 99 5 0 0 0 - - -; +#X floatatom 263 228 5 0 0 0 - - -; +#X obj 263 181 amclip; +#X connect 0 0 2 0; +#X connect 0 0 2 1; +#X connect 1 0 0 0; +#X connect 3 0 7 1; +#X connect 4 0 0 1; +#X connect 5 0 7 0; +#X connect 7 0 6 0; diff --git a/sc4pd/pd/bpf.pd b/sc4pd/pd/bpf.pd new file mode 100644 index 0000000..5255af9 --- /dev/null +++ b/sc4pd/pd/bpf.pd @@ -0,0 +1,15 @@ +#N canvas 0 0 450 300 10; +#X obj 124 220 dac~; +#X floatatom 224 81 5 0 0 0 - - -; +#X obj 130 89 WhiteNoise~; +#X msg 201 121 kfreq \$1; +#X floatatom 294 81 5 0 0 0 - - -; +#X obj 130 147 BPF~ 440 0.5; +#X msg 271 121 krq \$1; +#X connect 1 0 3 0; +#X connect 2 0 5 0; +#X connect 3 0 5 0; +#X connect 4 0 6 0; +#X connect 5 0 0 0; +#X connect 5 0 0 1; +#X connect 6 0 5 0; diff --git a/sc4pd/pd/bpz2.pd b/sc4pd/pd/bpz2.pd new file mode 100644 index 0000000..ffa4c77 --- /dev/null +++ b/sc4pd/pd/bpz2.pd @@ -0,0 +1,12 @@ +#N canvas 0 0 450 300 10; +#X obj 12 159 dac~; +#X floatatom 265 37 9 0 0 0 - - -; +#X floatatom 266 110 9 0 0 0 - - -; +#X obj 18 28 WhiteNoise~; +#X obj 266 78 HPZ2; +#X obj 18 86 BPZ2~; +#X connect 1 0 4 0; +#X connect 3 0 5 0; +#X connect 4 0 2 0; +#X connect 5 0 0 0; +#X connect 5 0 0 1; diff --git a/sc4pd/pd/brf.pd b/sc4pd/pd/brf.pd new file mode 100644 index 0000000..df92c7c --- /dev/null +++ b/sc4pd/pd/brf.pd @@ -0,0 +1,15 @@ +#N canvas 0 0 450 300 10; +#X obj 124 220 dac~; +#X floatatom 224 81 5 0 0 0 - - -; +#X obj 130 89 WhiteNoise~; +#X msg 201 121 kfreq \$1; +#X floatatom 294 81 5 0 0 0 - - -; +#X msg 271 121 krq \$1; +#X obj 130 147 BRF~ 4440 4.3; +#X connect 1 0 3 0; +#X connect 2 0 6 0; +#X connect 3 0 6 0; +#X connect 4 0 5 0; +#X connect 5 0 6 0; +#X connect 6 0 0 0; +#X connect 6 0 0 1; diff --git a/sc4pd/pd/brz2.pd b/sc4pd/pd/brz2.pd new file mode 100644 index 0000000..5e61752 --- /dev/null +++ b/sc4pd/pd/brz2.pd @@ -0,0 +1,12 @@ +#N canvas 0 0 450 300 10; +#X obj 12 159 dac~; +#X floatatom 265 37 9 0 0 0 - - -; +#X floatatom 266 110 9 0 0 0 - - -; +#X obj 18 28 WhiteNoise~; +#X obj 18 86 BRZ2~; +#X obj 266 78 BRZ2; +#X connect 1 0 5 0; +#X connect 3 0 4 0; +#X connect 4 0 0 0; +#X connect 4 0 0 1; +#X connect 5 0 2 0; diff --git a/sc4pd/pd/clipnoise.pd b/sc4pd/pd/clipnoise.pd new file mode 100644 index 0000000..5a685b0 --- /dev/null +++ b/sc4pd/pd/clipnoise.pd @@ -0,0 +1,13 @@ +#N canvas 0 0 450 300 10; +#X obj 89 48 ClipNoise~; +#X obj 89 115 print~; +#X obj 141 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 246 55 ClipNoise; +#X floatatom 246 97 5 0 0 0 - - -; +#X obj 251 27 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X connect 0 0 1 0; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 5 0 3 0; diff --git a/sc4pd/pd/combc.pd b/sc4pd/pd/combc.pd new file mode 100644 index 0000000..4baf6ef --- /dev/null +++ b/sc4pd/pd/combc.pd @@ -0,0 +1,20 @@ +#N canvas 0 0 450 300 10; +#X floatatom 188 40 5 0 0 0 - - -; +#X obj 67 187 dac~; +#X msg 185 88 delaytime \$1; +#X obj 111 190 print~; +#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 316 83 5 0 0 0 - - -; +#X msg 316 107 decaytime \$1; +#X obj 79 57 WhiteNoise~; +#X obj 77 138 CombN~ 1 0.001 0.2; +#X connect 0 0 2 0; +#X connect 2 0 8 0; +#X connect 4 0 3 0; +#X connect 5 0 6 0; +#X connect 6 0 8 0; +#X connect 7 0 8 0; +#X connect 8 0 1 0; +#X connect 8 0 1 1; +#X connect 8 0 3 0; diff --git a/sc4pd/pd/combl.pd b/sc4pd/pd/combl.pd new file mode 100644 index 0000000..b8fb0d2 --- /dev/null +++ b/sc4pd/pd/combl.pd @@ -0,0 +1,20 @@ +#N canvas 0 0 450 300 10; +#X floatatom 188 40 5 0 0 0 - - -; +#X obj 67 187 dac~; +#X msg 185 88 delaytime \$1; +#X obj 111 190 print~; +#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 316 83 5 0 0 0 - - -; +#X msg 316 107 decaytime \$1; +#X obj 79 57 WhiteNoise~; +#X obj 77 138 CombL~ 1 0.001 0.2; +#X connect 0 0 2 0; +#X connect 2 0 8 0; +#X connect 4 0 3 0; +#X connect 5 0 6 0; +#X connect 6 0 8 0; +#X connect 7 0 8 0; +#X connect 8 0 1 0; +#X connect 8 0 1 1; +#X connect 8 0 3 0; diff --git a/sc4pd/pd/combn.pd b/sc4pd/pd/combn.pd new file mode 100644 index 0000000..4baf6ef --- /dev/null +++ b/sc4pd/pd/combn.pd @@ -0,0 +1,20 @@ +#N canvas 0 0 450 300 10; +#X floatatom 188 40 5 0 0 0 - - -; +#X obj 67 187 dac~; +#X msg 185 88 delaytime \$1; +#X obj 111 190 print~; +#X obj 128 170 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 316 83 5 0 0 0 - - -; +#X msg 316 107 decaytime \$1; +#X obj 79 57 WhiteNoise~; +#X obj 77 138 CombN~ 1 0.001 0.2; +#X connect 0 0 2 0; +#X connect 2 0 8 0; +#X connect 4 0 3 0; +#X connect 5 0 6 0; +#X connect 6 0 8 0; +#X connect 7 0 8 0; +#X connect 8 0 1 0; +#X connect 8 0 1 1; +#X connect 8 0 3 0; diff --git a/sc4pd/pd/crackle.pd b/sc4pd/pd/crackle.pd new file mode 100644 index 0000000..7cbb5a0 --- /dev/null +++ b/sc4pd/pd/crackle.pd @@ -0,0 +1,10 @@ +#N canvas 0 0 450 300 10; +#X obj 266 210 dac~; +#X obj 279 128 Crackle~ 2; +#X obj 369 196 print~; +#X obj 378 161 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X connect 1 0 0 0; +#X connect 1 0 0 1; +#X connect 1 0 2 0; +#X connect 3 0 2 0; diff --git a/sc4pd/pd/decay.pd b/sc4pd/pd/decay.pd new file mode 100644 index 0000000..4d54e30 --- /dev/null +++ b/sc4pd/pd/decay.pd @@ -0,0 +1,12 @@ +#N canvas 0 0 450 300 10; +#X obj 159 205 dac~; +#X obj 239 198 print~; +#X obj 244 171 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 149 72 Dust~ 440; +#X obj 156 130 Decay~ 0.01; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 0 0; +#X connect 4 0 0 1; +#X connect 4 0 1 0; diff --git a/sc4pd/pd/decay2.pd b/sc4pd/pd/decay2.pd new file mode 100644 index 0000000..98260f6 --- /dev/null +++ b/sc4pd/pd/decay2.pd @@ -0,0 +1,12 @@ +#N canvas 0 0 450 300 10; +#X obj 159 205 dac~; +#X obj 239 198 print~; +#X obj 244 171 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 149 72 Dust~ 440; +#X obj 156 130 Decay2~ 0.01 0.002; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 0 0; +#X connect 4 0 0 1; +#X connect 4 0 1 0; diff --git a/sc4pd/pd/delayc.pd b/sc4pd/pd/delayc.pd new file mode 100644 index 0000000..2f539ff --- /dev/null +++ b/sc4pd/pd/delayc.pd @@ -0,0 +1,11 @@ +#N canvas 0 0 450 300 10; +#X floatatom 188 40 5 0 0 0 - - -; +#X obj 67 187 dac~; +#X msg 185 88 delaytime \$1; +#X obj 77 138 CombN~ 0.01 0.003 3; +#X obj 79 57 Dust~ 440; +#X connect 0 0 2 0; +#X connect 2 0 3 0; +#X connect 3 0 1 0; +#X connect 3 0 1 1; +#X connect 4 0 3 0; diff --git a/sc4pd/pd/delayl.pd b/sc4pd/pd/delayl.pd new file mode 100644 index 0000000..690063b --- /dev/null +++ b/sc4pd/pd/delayl.pd @@ -0,0 +1,11 @@ +#N canvas 0 0 450 300 10; +#X floatatom 188 40 5 0 0 0 - - -; +#X obj 90 233 dac~; +#X msg 185 88 delaytime \$1; +#X obj 79 57 Dust~ 4; +#X obj 77 138 DelayL~ 1 3; +#X connect 0 0 2 0; +#X connect 2 0 4 0; +#X connect 3 0 1 1; +#X connect 3 0 4 0; +#X connect 4 0 1 0; diff --git a/sc4pd/pd/delayn.pd b/sc4pd/pd/delayn.pd new file mode 100644 index 0000000..37b0c29 --- /dev/null +++ b/sc4pd/pd/delayn.pd @@ -0,0 +1,11 @@ +#N canvas 0 0 450 300 10; +#X obj 77 138 DelayN~ 1 3; +#X floatatom 188 40 5 0 0 0 - - -; +#X obj 90 233 dac~; +#X msg 185 88 delaytime \$1; +#X obj 79 57 Dust~ 4; +#X connect 0 0 2 0; +#X connect 1 0 3 0; +#X connect 3 0 0 0; +#X connect 4 0 0 0; +#X connect 4 0 2 1; diff --git a/sc4pd/pd/dust.pd b/sc4pd/pd/dust.pd new file mode 100644 index 0000000..6a709ec --- /dev/null +++ b/sc4pd/pd/dust.pd @@ -0,0 +1,11 @@ +#N canvas 0 0 450 300 10; +#X obj 96 130 dac~; +#X floatatom 264 119 5 0 0 0 - - -; +#X obj 123 109 Median~ 20; +#X obj 72 51 Dust~ 600; +#X obj 123 82 Dust~ 1000; +#X obj 264 82 Dust 1; +#X connect 2 0 0 1; +#X connect 3 0 0 0; +#X connect 4 0 2 0; +#X connect 5 0 1 0; diff --git a/sc4pd/pd/excess.pd b/sc4pd/pd/excess.pd new file mode 100644 index 0000000..3edde5e --- /dev/null +++ b/sc4pd/pd/excess.pd @@ -0,0 +1,16 @@ +#N canvas 0 0 450 300 10; +#X obj 26 88 osc~ 440; +#X obj 22 176 dac~; +#X floatatom 327 136 5 0 0 0 - - -; +#X floatatom 222 99 5 0 0 0 - - -; +#X floatatom 263 228 5 0 0 0 - - -; +#X obj 33 137 excess~; +#X obj 96 113 osc~ 45; +#X obj 263 181 excess; +#X connect 0 0 5 0; +#X connect 2 0 7 1; +#X connect 3 0 7 0; +#X connect 5 0 1 0; +#X connect 5 0 1 1; +#X connect 6 0 5 1; +#X connect 7 0 4 0; diff --git a/sc4pd/pd/fos.pd b/sc4pd/pd/fos.pd new file mode 100644 index 0000000..f03f45b --- /dev/null +++ b/sc4pd/pd/fos.pd @@ -0,0 +1,45 @@ +#N canvas 0 0 539 300 10; +#X obj 12 159 dac~; +#X floatatom 112 20 5 0 0 0 - - -; +#X obj 18 28 WhiteNoise~; +#X obj 37 269 dac~; +#X obj 95 174 Dust~ 444; +#X obj 18 86 FOS~ 0.3 0.3 0.3; +#X msg 89 60 a0 \$1; +#X floatatom 161 20 5 0 0 0 - - -; +#X msg 138 60 a1 \$1; +#X floatatom 215 20 5 0 0 0 - - -; +#X msg 192 60 b1 \$1; +#X obj 46 229 FOS~ 0.3 0.3 0.3 ar; +#X floatatom 374 26 5 0 0 0 - - -; +#X msg 351 66 a0 \$1; +#X floatatom 423 26 5 0 0 0 - - -; +#X msg 400 66 a1 \$1; +#X floatatom 477 26 5 0 0 0 - - -; +#X msg 454 66 b1 \$1; +#X obj 280 92 FOS 0.3 0.3 0.3; +#X floatatom 282 129 5 0 0 0 - - -; +#X floatatom 283 36 5 0 0 0 - - -; +#X connect 1 0 6 0; +#X connect 2 0 5 0; +#X connect 4 0 11 1; +#X connect 4 0 11 0; +#X connect 4 0 11 2; +#X connect 4 0 11 3; +#X connect 5 0 0 0; +#X connect 5 0 0 1; +#X connect 6 0 5 0; +#X connect 7 0 8 0; +#X connect 8 0 5 0; +#X connect 9 0 10 0; +#X connect 10 0 5 0; +#X connect 11 0 3 0; +#X connect 11 0 3 1; +#X connect 12 0 13 0; +#X connect 13 0 18 0; +#X connect 14 0 15 0; +#X connect 15 0 18 0; +#X connect 16 0 17 0; +#X connect 17 0 18 0; +#X connect 18 0 19 0; +#X connect 20 0 18 0; diff --git a/sc4pd/pd/hasher.pd b/sc4pd/pd/hasher.pd new file mode 100644 index 0000000..532f032 --- /dev/null +++ b/sc4pd/pd/hasher.pd @@ -0,0 +1,17 @@ +#N canvas 0 0 450 300 10; +#X obj 18 28 osc~ 441; +#X obj 12 159 dac~; +#X obj 89 131 print~; +#X obj 144 112 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 265 37 9 0 0 0 - - -; +#X floatatom 266 110 9 0 0 0 - - -; +#X obj 266 78 Hasher; +#X obj 18 86 Hasher~; +#X connect 0 0 7 0; +#X connect 3 0 2 0; +#X connect 4 0 6 0; +#X connect 6 0 5 0; +#X connect 7 0 2 0; +#X connect 7 0 1 0; +#X connect 7 0 1 1; diff --git a/sc4pd/pd/hpf.pd b/sc4pd/pd/hpf.pd new file mode 100644 index 0000000..82de175 --- /dev/null +++ b/sc4pd/pd/hpf.pd @@ -0,0 +1,11 @@ +#N canvas 0 0 450 300 10; +#X obj 124 220 dac~; +#X floatatom 224 81 5 0 0 0 - - -; +#X obj 130 89 WhiteNoise~; +#X msg 201 121 kfreq \$1; +#X obj 130 147 HPF~ 10000; +#X connect 1 0 3 0; +#X connect 2 0 4 0; +#X connect 3 0 4 0; +#X connect 4 0 0 0; +#X connect 4 0 0 1; diff --git a/sc4pd/pd/hpz1.pd b/sc4pd/pd/hpz1.pd new file mode 100644 index 0000000..1396d40 --- /dev/null +++ b/sc4pd/pd/hpz1.pd @@ -0,0 +1,12 @@ +#N canvas 0 0 450 300 10; +#X obj 12 159 dac~; +#X floatatom 265 37 9 0 0 0 - - -; +#X floatatom 266 110 9 0 0 0 - - -; +#X obj 266 78 HPZ1; +#X obj 18 86 HPZ1~; +#X obj 18 28 WhiteNoise~; +#X connect 1 0 3 0; +#X connect 3 0 2 0; +#X connect 4 0 0 0; +#X connect 4 0 0 1; +#X connect 5 0 4 0; diff --git a/sc4pd/pd/impulse.pd b/sc4pd/pd/impulse.pd new file mode 100644 index 0000000..5381863 --- /dev/null +++ b/sc4pd/pd/impulse.pd @@ -0,0 +1,31 @@ +#N canvas 0 0 782 300 10; +#X obj 93 170 dac~; +#X obj 108 75 sig~ 440; +#X floatatom 227 53 5 0 0 0 - - -; +#X msg 20 31 kr; +#X msg 62 30 ar; +#X floatatom 363 150 5 0 0 0 - - -; +#X obj 343 235 timer; +#X floatatom 343 267 5 0 0 0 - - -; +#X obj 353 197 t b b; +#X msg 402 29 0.1; +#X msg 451 39 kr 10; +#X msg 223 88 freq \$1; +#X obj 373 128 change; +#X obj 107 117 Impulse~ 440 ar; +#X obj 376 89 Impulse 1 20; +#X connect 1 0 13 0; +#X connect 2 0 11 0; +#X connect 3 0 13 0; +#X connect 4 0 13 0; +#X connect 5 0 8 0; +#X connect 6 0 7 0; +#X connect 8 0 6 0; +#X connect 8 1 6 1; +#X connect 9 0 14 0; +#X connect 10 0 14 0; +#X connect 11 0 13 0; +#X connect 12 0 5 0; +#X connect 13 0 0 0; +#X connect 13 0 0 1; +#X connect 14 0 12 0; diff --git a/sc4pd/pd/integrator.pd b/sc4pd/pd/integrator.pd new file mode 100644 index 0000000..3c8719d --- /dev/null +++ b/sc4pd/pd/integrator.pd @@ -0,0 +1,21 @@ +#N canvas 0 0 450 300 10; +#X obj 12 159 dac~; +#X obj 89 131 print~; +#X obj 144 112 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 112 20 5 0 0 0 - - -; +#X floatatom 265 37 9 0 0 0 - - -; +#X floatatom 266 110 9 0 0 0 - - -; +#X obj 18 86 Integrator~ 0.3; +#X msg 89 60 leak \$1; +#X obj 18 28 Dust~ 441; +#X obj 266 78 Integrator 0.5; +#X connect 2 0 1 0; +#X connect 3 0 7 0; +#X connect 4 0 9 0; +#X connect 6 0 1 0; +#X connect 6 0 0 0; +#X connect 6 0 0 1; +#X connect 7 0 6 0; +#X connect 8 0 6 0; +#X connect 9 0 5 0; diff --git a/sc4pd/pd/lag.pd b/sc4pd/pd/lag.pd new file mode 100644 index 0000000..206a07b --- /dev/null +++ b/sc4pd/pd/lag.pd @@ -0,0 +1,17 @@ +#N canvas 0 0 450 300 10; +#X obj 159 205 dac~; +#X obj 239 198 print~; +#X obj 244 171 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 257 82 hsl 128 15 1e-04 1 1 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 0; +#X msg 254 102 lagTime \$1; +#X obj 155 61 WhiteNoise~; +#X obj 156 130 Lag~ 0.0004; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 6 0; +#X connect 5 0 6 0; +#X connect 6 0 0 0; +#X connect 6 0 0 1; +#X connect 6 0 1 0; diff --git a/sc4pd/pd/lag2.pd b/sc4pd/pd/lag2.pd new file mode 100644 index 0000000..0398109 --- /dev/null +++ b/sc4pd/pd/lag2.pd @@ -0,0 +1,17 @@ +#N canvas 0 0 450 300 10; +#X obj 159 205 dac~; +#X obj 239 198 print~; +#X obj 244 171 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 257 82 hsl 128 15 1e-04 1 1 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 0; +#X msg 254 102 lagTime \$1; +#X obj 155 61 WhiteNoise~; +#X obj 156 130 Lag2~ 0.0004; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 6 0; +#X connect 5 0 6 0; +#X connect 6 0 0 0; +#X connect 6 0 0 1; +#X connect 6 0 1 0; diff --git a/sc4pd/pd/lag3.pd b/sc4pd/pd/lag3.pd new file mode 100644 index 0000000..206a07b --- /dev/null +++ b/sc4pd/pd/lag3.pd @@ -0,0 +1,17 @@ +#N canvas 0 0 450 300 10; +#X obj 159 205 dac~; +#X obj 239 198 print~; +#X obj 244 171 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 257 82 hsl 128 15 1e-04 1 1 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 0; +#X msg 254 102 lagTime \$1; +#X obj 155 61 WhiteNoise~; +#X obj 156 130 Lag~ 0.0004; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 6 0; +#X connect 5 0 6 0; +#X connect 6 0 0 0; +#X connect 6 0 0 1; +#X connect 6 0 1 0; diff --git a/sc4pd/pd/latoocarfian.pd b/sc4pd/pd/latoocarfian.pd new file mode 100644 index 0000000..a3fb7e1 --- /dev/null +++ b/sc4pd/pd/latoocarfian.pd @@ -0,0 +1,18 @@ +#N canvas 0 0 450 300 10; +#X obj 89 115 print~; +#X obj 141 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 128 161 dac~; +#X obj 89 48 Latoocarfian~ 0.88 1.8 1.2 1.3; +#X obj 231 125 Latoocarfian 0.88 1.8 1.2 1.3; +#X floatatom 247 154 5 0 0 0 - - -; +#X floatatom 410 152 5 0 0 0 - - -; +#X obj 275 97 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X connect 1 0 0 0; +#X connect 3 0 0 0; +#X connect 3 0 2 0; +#X connect 3 1 2 1; +#X connect 4 0 5 0; +#X connect 4 1 6 0; +#X connect 7 0 4 0; diff --git a/sc4pd/pd/lfclipnoise.pd b/sc4pd/pd/lfclipnoise.pd new file mode 100644 index 0000000..63f2eb7 --- /dev/null +++ b/sc4pd/pd/lfclipnoise.pd @@ -0,0 +1,13 @@ +#N canvas 0 0 450 300 10; +#X floatatom 246 97 5 0 0 0 - - -; +#X obj 246 55 LFClipNoise 10; +#X obj 139 179 dac~; +#X obj 89 154 *~ 0.1; +#X obj 161 124 LFClipNoise~ 1001; +#X obj 89 48 LFClipNoise~ 999; +#X obj 161 151 *~ 0.1; +#X connect 1 0 0 0; +#X connect 3 0 2 0; +#X connect 4 0 6 0; +#X connect 5 0 3 0; +#X connect 6 0 2 1; diff --git a/sc4pd/pd/lfdnoise0.pd b/sc4pd/pd/lfdnoise0.pd new file mode 100644 index 0000000..138cd66 --- /dev/null +++ b/sc4pd/pd/lfdnoise0.pd @@ -0,0 +1,5 @@ +#N canvas 0 0 450 300 10; +#X obj 133 22 LFDNoise0~ 100; +#X obj 131 56 dac~; +#X connect 0 0 1 0; +#X connect 0 0 1 1; diff --git a/sc4pd/pd/lfnoise0.pd b/sc4pd/pd/lfnoise0.pd new file mode 100644 index 0000000..afcc0a3 --- /dev/null +++ b/sc4pd/pd/lfnoise0.pd @@ -0,0 +1,17 @@ +#N canvas 0 0 450 300 10; +#X obj 89 115 print~; +#X obj 141 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 246 97 5 0 0 0 - - -; +#X obj 89 48 LFNoise0~ 1000; +#X obj 246 143 timer; +#X obj 246 123 t b b; +#X floatatom 246 168 5 0 0 0 - - -; +#X obj 246 55 LFNoise0 10; +#X connect 1 0 0 0; +#X connect 2 0 5 0; +#X connect 3 0 0 0; +#X connect 4 0 6 0; +#X connect 5 0 4 0; +#X connect 5 1 4 1; +#X connect 7 0 2 0; diff --git a/sc4pd/pd/lfnoise1.pd b/sc4pd/pd/lfnoise1.pd new file mode 100644 index 0000000..6e401f1 --- /dev/null +++ b/sc4pd/pd/lfnoise1.pd @@ -0,0 +1,17 @@ +#N canvas 0 0 450 300 10; +#X obj 89 115 print~; +#X obj 141 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 246 97 5 0 0 0 - - -; +#X obj 246 143 timer; +#X obj 246 123 t b b; +#X floatatom 246 168 5 0 0 0 - - -; +#X obj 89 48 LFNoise1~ 100; +#X obj 246 55 LFNoise1 10; +#X connect 1 0 0 0; +#X connect 2 0 4 0; +#X connect 3 0 5 0; +#X connect 4 0 3 0; +#X connect 4 1 3 1; +#X connect 6 0 0 0; +#X connect 7 0 2 0; diff --git a/sc4pd/pd/lfnoise2.pd b/sc4pd/pd/lfnoise2.pd new file mode 100644 index 0000000..3874d41 --- /dev/null +++ b/sc4pd/pd/lfnoise2.pd @@ -0,0 +1,17 @@ +#N canvas 0 0 450 300 10; +#X obj 89 115 print~; +#X obj 141 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 246 97 5 0 0 0 - - -; +#X obj 246 143 timer; +#X obj 246 123 t b b; +#X floatatom 246 168 5 0 0 0 - - -; +#X obj 246 55 LFNoise2 10; +#X obj 89 48 LFNoise2~ 100; +#X connect 1 0 0 0; +#X connect 2 0 4 0; +#X connect 3 0 5 0; +#X connect 4 0 3 0; +#X connect 4 1 3 1; +#X connect 6 0 2 0; +#X connect 7 0 0 0; diff --git a/sc4pd/pd/lfpulse.pd b/sc4pd/pd/lfpulse.pd new file mode 100644 index 0000000..f8cdec5 --- /dev/null +++ b/sc4pd/pd/lfpulse.pd @@ -0,0 +1,42 @@ +#N canvas 0 0 782 300 10; +#X obj 93 170 dac~; +#X obj 108 75 sig~ 440; +#X floatatom 227 53 5 0 0 0 - - -; +#X msg 20 31 kr; +#X msg 62 30 ar; +#X floatatom 363 150 5 0 0 0 - - -; +#X obj 343 235 timer; +#X floatatom 343 267 5 0 0 0 - - -; +#X obj 353 197 t b b; +#X msg 402 29 0.1; +#X msg 451 39 kr 10; +#X msg 223 88 freq \$1; +#X obj 107 117 LFPulse~ 440 0.3 ar; +#X msg 162 48 width \$1; +#X floatatom 162 20 5 0 0 0 - - -; +#X obj 373 128 change; +#X obj 376 89 LFPulse 1 0.5 20; +#X msg 162 48 width \$1; +#X floatatom 162 20 5 0 0 0 - - -; +#X msg 598 46 width \$1; +#X floatatom 598 18 5 0 0 0 - - -; +#X connect 1 0 12 0; +#X connect 2 0 11 0; +#X connect 3 0 12 0; +#X connect 4 0 12 0; +#X connect 5 0 8 0; +#X connect 6 0 7 0; +#X connect 8 0 6 0; +#X connect 8 1 6 1; +#X connect 9 0 16 0; +#X connect 10 0 16 0; +#X connect 11 0 12 0; +#X connect 12 0 0 0; +#X connect 12 0 0 1; +#X connect 13 0 12 0; +#X connect 14 0 13 0; +#X connect 15 0 5 0; +#X connect 16 0 15 0; +#X connect 18 0 17 0; +#X connect 19 0 16 0; +#X connect 20 0 19 0; diff --git a/sc4pd/pd/lfsaw.pd b/sc4pd/pd/lfsaw.pd new file mode 100644 index 0000000..ed3f7b3 --- /dev/null +++ b/sc4pd/pd/lfsaw.pd @@ -0,0 +1,29 @@ +#N canvas 0 0 782 300 10; +#X obj 93 170 dac~; +#X obj 107 117 LFSaw~ 440 ar; +#X obj 108 75 sig~ 440; +#X floatatom 227 53 5 0 0 0 - - -; +#X msg 20 31 kr; +#X msg 62 30 ar; +#X floatatom 349 176 5 0 0 0 - - -; +#X obj 343 235 timer; +#X floatatom 343 267 5 0 0 0 - - -; +#X obj 353 197 t b b; +#X obj 376 89 LFSaw 2 50; +#X msg 402 29 0.1; +#X msg 451 39 kr 10; +#X msg 223 88 freq \$1; +#X connect 1 0 0 0; +#X connect 1 0 0 1; +#X connect 2 0 1 0; +#X connect 3 0 13 0; +#X connect 4 0 1 0; +#X connect 5 0 1 0; +#X connect 6 0 9 0; +#X connect 7 0 8 0; +#X connect 9 0 7 0; +#X connect 9 1 7 1; +#X connect 10 0 6 0; +#X connect 11 0 10 0; +#X connect 12 0 10 0; +#X connect 13 0 1 0; diff --git a/sc4pd/pd/lincong.pd b/sc4pd/pd/lincong.pd new file mode 100644 index 0000000..c777695 --- /dev/null +++ b/sc4pd/pd/lincong.pd @@ -0,0 +1,17 @@ +#N canvas 257 167 708 300 10; +#X obj 132 247 dac~; +#X obj 228 253 print~; +#X obj 309 229 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 286 73 LinCong 100 103 140 120002; +#X obj 267 32 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 295 110 10 0 0 0 - - -; +#X obj 577 226 block~ 64; +#X obj 22 142 LinCong~ 13437 1433.34 1.34233e+06 4.33243e+09; +#X connect 2 0 1 0; +#X connect 3 0 5 0; +#X connect 4 0 3 0; +#X connect 7 0 0 0; +#X connect 7 0 0 1; +#X connect 7 0 1 0; diff --git a/sc4pd/pd/linexp.pd b/sc4pd/pd/linexp.pd new file mode 100644 index 0000000..5a7fc04 --- /dev/null +++ b/sc4pd/pd/linexp.pd @@ -0,0 +1,17 @@ +#N canvas 0 0 450 300 10; +#X obj 31 230 dac~; +#X obj 111 223 print~; +#X obj 116 196 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 27 86 osc~ 440; +#X obj 27 142 LinExp~ 0 1 0.001 2; +#X floatatom 252 204 5 0 0 0 - - -; +#X obj 246 151 LinExp 0 100 0.001 2; +#X floatatom 248 123 5 0 0 0 - - -; +#X connect 2 0 1 0; +#X connect 3 0 4 0; +#X connect 4 0 0 0; +#X connect 4 0 0 1; +#X connect 4 0 1 0; +#X connect 6 0 5 0; +#X connect 7 0 6 0; diff --git a/sc4pd/pd/logistic.pd b/sc4pd/pd/logistic.pd new file mode 100644 index 0000000..2bb42d6 --- /dev/null +++ b/sc4pd/pd/logistic.pd @@ -0,0 +1,24 @@ +#N canvas 0 0 450 300 10; +#X obj 89 115 print~; +#X floatatom 246 97 5 0 0 0 - - -; +#X obj 246 143 timer; +#X obj 246 123 t b b; +#X floatatom 246 168 5 0 0 0 - - -; +#X obj 246 55 Logistic 1 0.5; +#X obj 246 17 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 74 159 dac~; +#X obj 89 134 Logistic~ 1000 4 0.4; +#X obj 116 90 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 89 48 Logistic~ 1000 4 0.4; +#X connect 1 0 3 0; +#X connect 2 0 4 0; +#X connect 3 0 2 0; +#X connect 3 1 2 1; +#X connect 5 0 1 0; +#X connect 6 0 5 0; +#X connect 8 0 7 1; +#X connect 9 0 0 0; +#X connect 10 0 0 0; +#X connect 10 0 7 0; diff --git a/sc4pd/pd/lpf.pd b/sc4pd/pd/lpf.pd new file mode 100644 index 0000000..1b952d6 --- /dev/null +++ b/sc4pd/pd/lpf.pd @@ -0,0 +1,11 @@ +#N canvas 0 0 450 300 10; +#X obj 124 220 dac~; +#X floatatom 224 81 5 0 0 0 - - -; +#X obj 130 89 WhiteNoise~; +#X msg 201 121 kfreq \$1; +#X obj 130 147 LPF~ 440; +#X connect 1 0 3 0; +#X connect 2 0 4 0; +#X connect 3 0 4 0; +#X connect 4 0 0 0; +#X connect 4 0 0 1; diff --git a/sc4pd/pd/lpz1.pd b/sc4pd/pd/lpz1.pd new file mode 100644 index 0000000..fa413b3 --- /dev/null +++ b/sc4pd/pd/lpz1.pd @@ -0,0 +1,12 @@ +#N canvas 0 0 450 300 10; +#X obj 12 159 dac~; +#X floatatom 265 37 9 0 0 0 - - -; +#X floatatom 266 110 9 0 0 0 - - -; +#X obj 18 86 LPZ1~; +#X obj 266 78 LPZ1; +#X obj 18 28 WhiteNoise~; +#X connect 1 0 4 0; +#X connect 3 0 0 0; +#X connect 3 0 0 1; +#X connect 4 0 2 0; +#X connect 5 0 3 0; diff --git a/sc4pd/pd/lpz2.pd b/sc4pd/pd/lpz2.pd new file mode 100644 index 0000000..a665b96 --- /dev/null +++ b/sc4pd/pd/lpz2.pd @@ -0,0 +1,12 @@ +#N canvas 0 0 450 300 10; +#X obj 12 159 dac~; +#X floatatom 265 37 9 0 0 0 - - -; +#X floatatom 266 110 9 0 0 0 - - -; +#X obj 18 28 WhiteNoise~; +#X obj 18 86 LPZ2~; +#X obj 266 78 LPZ2; +#X connect 1 0 5 0; +#X connect 3 0 4 0; +#X connect 4 0 0 0; +#X connect 4 0 0 1; +#X connect 5 0 2 0; diff --git a/sc4pd/pd/mantissamask.pd b/sc4pd/pd/mantissamask.pd new file mode 100644 index 0000000..b99ca00 --- /dev/null +++ b/sc4pd/pd/mantissamask.pd @@ -0,0 +1,21 @@ +#N canvas 0 0 450 300 10; +#X obj 18 28 osc~ 441; +#X obj 12 159 dac~; +#X obj 89 131 print~; +#X obj 144 112 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 112 20 5 0 0 0 - - -; +#X floatatom 265 37 9 0 0 0 - - -; +#X floatatom 266 110 9 0 0 0 - - -; +#X obj 266 78 MantissaMask 0; +#X obj 18 86 MantissaMask~ 3; +#X msg 89 60 set \$1; +#X connect 0 0 8 0; +#X connect 3 0 2 0; +#X connect 4 0 9 0; +#X connect 5 0 7 0; +#X connect 7 0 6 0; +#X connect 8 0 2 0; +#X connect 8 0 1 0; +#X connect 8 0 1 1; +#X connect 9 0 8 0; diff --git a/sc4pd/pd/onepole.pd b/sc4pd/pd/onepole.pd new file mode 100644 index 0000000..cd816f5 --- /dev/null +++ b/sc4pd/pd/onepole.pd @@ -0,0 +1,28 @@ +#N canvas 0 0 450 300 10; +#X obj 12 159 dac~; +#X obj 89 131 print~; +#X obj 144 112 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 112 20 5 0 0 0 - - -; +#X floatatom 265 37 9 0 0 0 - - -; +#X floatatom 266 110 9 0 0 0 - - -; +#X obj 18 28 WhiteNoise~; +#X msg 89 60 coef \$1; +#X obj 18 86 OnePole~ 0.3; +#X obj 85 251 dac~; +#X obj 94 211 OnePole~ 0.3 ar; +#X obj 94 171 Dust~ 444; +#X obj 266 78 OnePole 0.3; +#X connect 2 0 1 0; +#X connect 3 0 7 0; +#X connect 4 0 12 0; +#X connect 6 0 8 0; +#X connect 7 0 8 0; +#X connect 8 0 1 0; +#X connect 8 0 0 0; +#X connect 8 0 0 1; +#X connect 10 0 9 0; +#X connect 10 0 9 1; +#X connect 11 0 10 1; +#X connect 11 0 10 0; +#X connect 12 0 5 0; diff --git a/sc4pd/pd/onezero.pd b/sc4pd/pd/onezero.pd new file mode 100644 index 0000000..2d68a0b --- /dev/null +++ b/sc4pd/pd/onezero.pd @@ -0,0 +1,21 @@ +#N canvas 0 0 450 300 10; +#X obj 12 159 dac~; +#X obj 89 131 print~; +#X obj 144 112 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X floatatom 112 20 5 0 0 0 - - -; +#X floatatom 265 37 9 0 0 0 - - -; +#X floatatom 266 110 9 0 0 0 - - -; +#X obj 18 28 WhiteNoise~; +#X msg 89 60 coef \$1; +#X obj 18 86 OneZero~ 0.3; +#X obj 266 78 OneZero 0.3; +#X connect 2 0 1 0; +#X connect 3 0 7 0; +#X connect 4 0 9 0; +#X connect 6 0 8 0; +#X connect 7 0 8 0; +#X connect 8 0 1 0; +#X connect 8 0 0 0; +#X connect 8 0 0 1; +#X connect 9 0 5 0; diff --git a/sc4pd/pd/pitchshift.pd b/sc4pd/pd/pitchshift.pd new file mode 100644 index 0000000..e7653bc --- /dev/null +++ b/sc4pd/pd/pitchshift.pd @@ -0,0 +1,19 @@ +#N canvas 317 183 450 300 10; +#X floatatom 152 51 5 0 0 0 - - -; +#X obj 67 187 dac~; +#X floatatom 264 55 5 0 0 0 - - -; +#X obj 76 55 osc~ 440; +#X msg 152 80 pitchRatio \$1; +#X msg 264 79 pitchDispersion \$1; +#X floatatom 264 101 5 0 0 0 - - -; +#X msg 264 125 timeDispersion \$1; +#X obj 62 129 PitchShift~ 0.02 0.5 0 0; +#X connect 0 0 4 0; +#X connect 2 0 5 0; +#X connect 3 0 8 0; +#X connect 4 0 8 0; +#X connect 5 0 8 0; +#X connect 6 0 7 0; +#X connect 7 0 8 0; +#X connect 8 0 1 0; +#X connect 8 0 1 1; diff --git a/sc4pd/pd/resonz.pd b/sc4pd/pd/resonz.pd new file mode 100644 index 0000000..e23cf4e --- /dev/null +++ b/sc4pd/pd/resonz.pd @@ -0,0 +1,15 @@ +#N canvas 0 0 450 300 10; +#X floatatom 188 40 5 0 0 0 - - -; +#X obj 67 187 dac~; +#X floatatom 316 83 5 0 0 0 - - -; +#X msg 185 88 freq \$1; +#X msg 316 107 rq \$1; +#X obj 79 57 Dust~ 44; +#X obj 77 138 Resonz~ 440 20; +#X connect 0 0 3 0; +#X connect 2 0 4 0; +#X connect 3 0 6 0; +#X connect 4 0 6 0; +#X connect 5 0 6 0; +#X connect 6 0 1 0; +#X connect 6 0 1 1; diff --git a/sc4pd/pd/rhpf.pd b/sc4pd/pd/rhpf.pd new file mode 100644 index 0000000..228f368 --- /dev/null +++ b/sc4pd/pd/rhpf.pd @@ -0,0 +1,15 @@ +#N canvas 0 0 450 300 10; +#X obj 124 220 dac~; +#X floatatom 224 81 5 0 0 0 - - -; +#X obj 130 89 WhiteNoise~; +#X msg 201 121 kfreq \$1; +#X floatatom 294 81 5 0 0 0 - - -; +#X msg 271 121 kradius \$1; +#X obj 130 147 RHPF~ 10000 0; +#X connect 1 0 3 0; +#X connect 2 0 6 0; +#X connect 3 0 6 0; +#X connect 4 0 5 0; +#X connect 5 0 6 0; +#X connect 6 0 0 0; +#X connect 6 0 0 1; diff --git a/sc4pd/pd/rlpf.pd b/sc4pd/pd/rlpf.pd new file mode 100644 index 0000000..1203edb --- /dev/null +++ b/sc4pd/pd/rlpf.pd @@ -0,0 +1,15 @@ +#N canvas 0 0 450 300 10; +#X obj 124 220 dac~; +#X floatatom 224 81 5 0 0 0 - - -; +#X obj 130 89 WhiteNoise~; +#X msg 201 121 kfreq \$1; +#X floatatom 294 81 5 0 0 0 - - -; +#X msg 271 121 kradius \$1; +#X obj 130 147 RLPF~ 440 0.5; +#X connect 1 0 3 0; +#X connect 2 0 6 0; +#X connect 3 0 6 0; +#X connect 4 0 5 0; +#X connect 5 0 6 0; +#X connect 6 0 0 0; +#X connect 6 0 0 1; diff --git a/sc4pd/pd/scaleneg.pd b/sc4pd/pd/scaleneg.pd new file mode 100644 index 0000000..70e6f14 --- /dev/null +++ b/sc4pd/pd/scaleneg.pd @@ -0,0 +1,16 @@ +#N canvas 0 0 450 300 10; +#X obj 26 88 osc~ 440; +#X obj 22 176 dac~; +#X floatatom 327 136 5 0 0 0 - - -; +#X floatatom 222 99 5 0 0 0 - - -; +#X floatatom 263 228 5 0 0 0 - - -; +#X obj 33 137 scaleneg~; +#X obj 263 181 scaleneg; +#X obj 96 113 osc~ 230; +#X connect 0 0 5 0; +#X connect 2 0 6 1; +#X connect 3 0 6 0; +#X connect 5 0 1 0; +#X connect 5 0 1 1; +#X connect 6 0 4 0; +#X connect 7 0 5 1; diff --git a/sc4pd/pd/sos.pd b/sc4pd/pd/sos.pd new file mode 100644 index 0000000..b09be69 --- /dev/null +++ b/sc4pd/pd/sos.pd @@ -0,0 +1,38 @@ +#N canvas 0 0 539 300 10; +#X obj 12 159 dac~; +#X floatatom 112 20 5 0 0 0 - - -; +#X obj 18 28 WhiteNoise~; +#X obj 90 262 dac~; +#X obj 206 145 Dust~ 444; +#X msg 89 60 a0 \$1; +#X floatatom 161 20 5 0 0 0 - - -; +#X msg 138 60 a1 \$1; +#X floatatom 262 20 5 0 0 0 - - -; +#X msg 239 60 b1 \$1; +#X obj 18 87 SOS~ 0.3 0.3 0.3 0.3 0.3; +#X floatatom 212 20 5 0 0 0 - - -; +#X floatatom 313 20 5 0 0 0 - - -; +#X msg 189 60 a2 \$1; +#X msg 290 60 b2 \$1; +#X obj 85 208 SOS~ 0.3 0.3 0.3 0.3 0.3 ar; +#X connect 1 0 5 0; +#X connect 2 0 10 0; +#X connect 4 0 15 0; +#X connect 4 0 15 1; +#X connect 4 0 15 2; +#X connect 4 0 15 3; +#X connect 4 0 15 4; +#X connect 4 0 15 5; +#X connect 5 0 10 0; +#X connect 6 0 7 0; +#X connect 7 0 10 0; +#X connect 8 0 9 0; +#X connect 9 0 10 0; +#X connect 10 0 0 0; +#X connect 10 0 0 1; +#X connect 11 0 13 0; +#X connect 12 0 14 0; +#X connect 13 0 10 0; +#X connect 14 0 10 0; +#X connect 15 0 3 1; +#X connect 15 0 3 0; diff --git a/sc4pd/pd/trand.pd b/sc4pd/pd/trand.pd new file mode 100644 index 0000000..3f9cbde --- /dev/null +++ b/sc4pd/pd/trand.pd @@ -0,0 +1,16 @@ +#N canvas 0 0 450 300 10; +#X obj 277 115 TRand 2 3; +#X floatatom 280 143 6 0 0 0 - - -; +#X obj 275 88 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 144 74 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +-1; +#X obj 144 96 t b b; +#X obj 144 154 print~; +#X obj 174 118 TRand~ 1 3; +#X connect 0 0 1 0; +#X connect 2 0 0 0; +#X connect 3 0 4 0; +#X connect 4 0 5 0; +#X connect 4 1 6 0; +#X connect 6 0 5 0; diff --git a/sc4pd/pd/twopole.pd b/sc4pd/pd/twopole.pd new file mode 100644 index 0000000..b781655 --- /dev/null +++ b/sc4pd/pd/twopole.pd @@ -0,0 +1,15 @@ +#N canvas 0 0 450 300 10; +#X obj 124 220 dac~; +#X floatatom 224 81 5 0 0 0 - - -; +#X obj 130 89 WhiteNoise~; +#X obj 130 147 TwoPole~ 440 0.5; +#X msg 201 121 kfreq \$1; +#X floatatom 294 81 5 0 0 0 - - -; +#X msg 271 121 kradius \$1; +#X connect 1 0 4 0; +#X connect 2 0 3 0; +#X connect 3 0 0 0; +#X connect 3 0 0 1; +#X connect 4 0 3 0; +#X connect 5 0 6 0; +#X connect 6 0 3 0; diff --git a/sc4pd/pd/twozero.pd b/sc4pd/pd/twozero.pd new file mode 100644 index 0000000..3cd2c63 --- /dev/null +++ b/sc4pd/pd/twozero.pd @@ -0,0 +1,15 @@ +#N canvas 0 0 450 300 10; +#X obj 124 220 dac~; +#X floatatom 224 81 5 0 0 0 - - -; +#X obj 130 89 WhiteNoise~; +#X msg 201 121 kfreq \$1; +#X floatatom 294 81 5 0 0 0 - - -; +#X msg 271 121 kradius \$1; +#X obj 130 160 TwoZero~ 440 0.5; +#X connect 1 0 3 0; +#X connect 2 0 6 0; +#X connect 3 0 6 0; +#X connect 4 0 5 0; +#X connect 5 0 6 0; +#X connect 6 0 0 0; +#X connect 6 0 0 1; diff --git a/sc4pd/readme.txt b/sc4pd/readme.txt new file mode 100644 index 0000000..9a09b43 --- /dev/null +++ b/sc4pd/readme.txt @@ -0,0 +1,26 @@ +sc4pd: SuperCollider for PureData +(c) 2004 Tim Blechmann + +sc4pd includes the SuperCollider header files and is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + +Both SuperCollider and sc4pd are released under the GPL + + +sc4pd is a port of some SuperCollider UGens to PD objects. If you want to link +both applications, it's better to use jack. +sc4pd is using thomas grill's flext and should be portable to max/msp. + + +thanks to: + James McCartney for SuperCollider + Miller Puckette for PureData + Thomas Grill for Flext + three great pieces of software... + + thanks for bug reports: + Gerard (0001@ooo000ooo.org) + +bugs, suggestions, complains to: TimBlechmann@gmx.de
\ No newline at end of file diff --git a/sc4pd/source/AllpassC.cpp b/sc4pd/source/AllpassC.cpp new file mode 100644 index 0000000..72c05f5 --- /dev/null +++ b/sc4pd/source/AllpassC.cpp @@ -0,0 +1,315 @@ +/* sc4pd + AllpassC~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Rashid Ali & Frank Lowe: Duo Exchange + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class AllpassC_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(AllpassC_ar,FeedbackDelay_ar); + + AllpassC_ar (int argc, t_atom *argv); + ~AllpassC_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("AllpassC~",AllpassC_ar); + +AllpassC_ar::AllpassC_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +AllpassC_ar::~AllpassC_ar () +{ + DelayUnit_Dtor(); +} + +void AllpassC_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + float d0, d1, d2, d3; + + if (delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + if (irdphase0 < 0) + { + dlybuf[iwrphase & mask] = ZXP(nin); + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + float value = cubicinterp(frac, d0, d1, d2, d3); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for (int i = 0; i!= n;++i) + { + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + if (irdphase0 < 0) + { + dlybuf[iwrphase & mask] = ZXP(nin); + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + float value = cubicinterp(frac, d0, d1, d2, d3); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + iwrphase++; + } + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void AllpassC_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + float d0, d1, d2, d3; + + if(delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + float value = cubicinterp(frac, d0, d1, d2, d3); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + for(int i=0; i!= n;++i) + { + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + float value = cubicinterp(frac, d0, d1, d2, d3); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + iwrphase++; + } + } + m_iwrphase = iwrphase; +} + +/* todo: AllpassC for control rate ? */ diff --git a/sc4pd/source/AllpassL.cpp b/sc4pd/source/AllpassL.cpp new file mode 100644 index 0000000..2353df3 --- /dev/null +++ b/sc4pd/source/AllpassL.cpp @@ -0,0 +1,276 @@ +/* sc4pd + AllpassL~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Rashid Ali & Frank Lowe: Duo Exchange + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class AllpassL_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(AllpassL_ar,FeedbackDelay_ar); + + AllpassL_ar (int argc, t_atom *argv); + ~AllpassL_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("AllpassL~",AllpassL_ar); + +AllpassL_ar::AllpassL_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +AllpassL_ar::~AllpassL_ar () +{ + DelayUnit_Dtor(); +} + +void AllpassL_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if (delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + float zin = ZXP(nin); + if (irdphase < 0) + { + dlybuf[iwrphase & mask] = zin; + ZXP(nout) = - feedbk * zin; //check: probably a bug = 0? + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + float value = d1 - frac * d1; + float dwr = zin + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + float dwr = zin + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + float zin = ZXP(nin); + for (int i = 0; i!= n;++i) + { + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + float zin = ZXP(nin); + if (irdphase < 0) + { + dlybuf[iwrphase & mask] = zin; + ZXP(nout) = - feedbk * zin; + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + float value = d1 - frac * d1; + float dwr = zin + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + float dwr = zin + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + iwrphase++; + } + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void AllpassL_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if(delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for(int i=0; i!= n;++i) + { + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + float dwr = ZXP(nin) + feedbk * value; + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + iwrphase++; + } + } + m_iwrphase = iwrphase; +} + +/* todo: AllpassL for control rate ? */ diff --git a/sc4pd/source/AllpassN.cpp b/sc4pd/source/AllpassN.cpp new file mode 100644 index 0000000..a03130b --- /dev/null +++ b/sc4pd/source/AllpassN.cpp @@ -0,0 +1,348 @@ +/* sc4pd + AllpassN~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Efzeg: Boogie + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class AllpassN_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(AllpassN_ar,FeedbackDelay_ar); + + AllpassN_ar (int argc, t_atom *argv); + ~AllpassN_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("AllpassN~",AllpassN_ar); + +AllpassN_ar::AllpassN_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +AllpassN_ar::~AllpassN_ar () +{ + DelayUnit_Dtor(); +} + +void AllpassN_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if (delay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long irdphase = iwrphase - (long)dsamp; + + if (irdphase < 0) + { + float dwr = ZXP(nin); + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = -feedbk * dwr; + } + else + { + float value = dlybuf[irdphase & mask]; + float dwr = feedbk * value + ZXP(nin); + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + } + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyN = dlybuf1 + m_idelaylen; + if (decay_changed) + { + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + long remain = n; + while (remain) + { + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyrd = dlybuf1 + (irdphase & mask); + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + if (irdphase < 0) + { + dlyrd += nsmps; + for (int i = 0; i!= nsmps;++i) + { + float dwr = ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = -feedbk * dwr; + feedbk += feedbk_slope; + } + } + else + { + for (int i = 0; i!= nsmps;++i) + { + float x1 = ZXP(dlyrd); + float dwr = x1 * feedbk + ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = x1 - feedbk * dwr; + feedbk += feedbk_slope; + } + } + iwrphase += nsmps; + irdphase += nsmps; + } + decay_changed=false; + } + else + { + long remain = n; + while (remain) + { + float* dlyrd = dlybuf1 + (irdphase & mask); + float* dlywr = dlybuf1 + (iwrphase & mask); + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + if (irdphase < 0) + { + feedbk = -feedbk; + for (int i = 0; i!= nsmps;++i) + { + float dwr = ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = feedbk * dwr; + } + feedbk = -feedbk; + } + else + { + for (int i = 0; i!= nsmps;++i) + { + float x1 = ZXP(dlyrd); + float dwr = x1 * feedbk + ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = x1 - feedbk * dwr; + } + } + iwrphase += nsmps; + irdphase += nsmps; + } + m_feedbk = feedbk; + } + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void AllpassN_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if(delay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + ++iwrphase; + long irdphase = iwrphase - (long)dsamp; + float value = dlybuf[irdphase & mask]; + float dwr = value * feedbk + ZXP(nin); + dlybuf[iwrphase & mask] = dwr; + ZXP(nout) = value - feedbk * dwr; + feedbk += feedbk_slope; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyrd = dlybuf1 + (irdphase & mask); + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyN = dlybuf1 + m_idelaylen; + + if(decay_changed) + { + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + long remain = n; + while (remain) + { + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + for(int i=0; i!= nsmps;++i) + { + float value = ZXP(dlyrd); + float dwr = value * feedbk + ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = value - feedbk * dwr; + feedbk += feedbk_slope; + } + if (dlyrd == dlyN) dlyrd = dlybuf1; + if (dlywr == dlyN) dlywr = dlybuf1; + } + m_feedbk = feedbk; + decay_changed = false; + } + else + { + long remain = n; + while (remain) + { + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + for (int i = 0; i!= nsmps; ++i) + { + float value = ZXP(dlyrd); + float dwr = value * feedbk + ZXP(nin); + ZXP(dlywr) = dwr; + ZXP(nout) = value - feedbk * dwr; + } + if (dlyrd == dlyN) dlyrd = dlybuf1; + if (dlywr == dlyN) dlywr = dlybuf1; + } + + } + iwrphase += n; + } + m_iwrphase = iwrphase; +} + +/* todo: AllpassN for control rate ? */ diff --git a/sc4pd/source/BPF.cpp b/sc4pd/source/BPF.cpp new file mode 100644 index 0000000..f998dd4 --- /dev/null +++ b/sc4pd/source/BPF.cpp @@ -0,0 +1,190 @@ +/* sc4pd + BPF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Jo Kondo: Works For Piano + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ BPF~ -------------------------------*/ + +class BPF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(BPF_ar,sc4pd_dsp); + +public: + BPF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_rq(float f) + { + m_bw=f; + changed = true; + } + + +private: + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_bw; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_rq); +}; + +FLEXT_LIB_DSP_V("BPF~",BPF_ar); + +BPF_ar::BPF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"krq",m_set_rq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_bw = sc_getfloatarg(Args,1); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void BPF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed) + { + float pfreq = m_freq * mRadiansPerSample; + float pbw = m_bw * pfreq * 0.5; + + float C = 1.f / tan(pbw); + float D = 2.f * cos(pfreq); + + float next_a0 = 1.f / (1.f + C); + float next_b1 = C * D * next_a0 ; + float next_b2 = (1.f - C) * next_a0; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - y0); + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - y0); + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate BPF filter */ diff --git a/sc4pd/source/BPZ2.cpp b/sc4pd/source/BPZ2.cpp new file mode 100644 index 0000000..a18a9dc --- /dev/null +++ b/sc4pd/source/BPZ2.cpp @@ -0,0 +1,140 @@ +/* sc4pd + BPZ2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ BPZ2~ -------------------------------*/ + +class BPZ2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(BPZ2_ar,sc4pd_dsp); + +public: + BPZ2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mFilterLoops=sc_filterloops(); + mFilterRemain=sc_filterremain(); + } + +private: + float m_x1, m_x2; + int mFilterLoops, mFilterRemain; +}; + +FLEXT_LIB_DSP_V("BPZ2~",BPZ2_ar); + +BPZ2_ar::BPZ2_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; + m_x2=0; +} + +void BPZ2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + float x2 = m_x2; + + for (int i = 0; i!=mFilterLoops ;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 - x2) * 0.5f; + x2 = ZXP(nin); + ZXP(nout) = (x2 - x1) * 0.5f; + x1 = ZXP(nin); + ZXP(nout) = (x1 - x0) * 0.5f; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 - x2) * 0.5f; + x2 = x1; + x1 = x0; + } + m_x1 = x1; + m_x2 = x2; +} + +/* ------------------------ BPZ2 -------------------------------*/ + +class BPZ2_kr: + public flext_base +{ + FLEXT_HEADER(BPZ2_kr,flext_base); + +public: + BPZ2_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + float m_x2; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("BPZ2",BPZ2_kr); + +BPZ2_kr::BPZ2_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x2 = m_x1 = 0; +} + +void BPZ2_kr::m_perform(float f) +{ + ToOutFloat(0,(f - m_x2) * 0.5f); + m_x2=m_x1; + m_x1=f; +} + diff --git a/sc4pd/source/BRF.cpp b/sc4pd/source/BRF.cpp new file mode 100644 index 0000000..e6db680 --- /dev/null +++ b/sc4pd/source/BRF.cpp @@ -0,0 +1,199 @@ +/* sc4pd + BRF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Jo Kondo: Works For Piano + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ BRF~ -------------------------------*/ + +class BRF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(BRF_ar,sc4pd_dsp); + +public: + BRF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_rq(float f) + { + m_bw=f; + changed = true; + } + + +private: + float m_y1, m_y2, m_a0, m_a1, m_b2, m_freq, m_bw; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_rq); +}; + +FLEXT_LIB_DSP_V("BRF~",BRF_ar); + +BRF_ar::BRF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"krq",m_set_rq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_bw = sc_getfloatarg(Args,1); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_a1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void BRF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float ay; + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float a1 = m_a1; + float b2 = m_b2; + + if (changed) + { + float pfreq = m_freq * mRadiansPerSample; + float pbw = m_bw * pfreq * 0.5; + + float C = tan(pbw); + float D = 2.f * cos(pfreq); + + float next_a0 = 1.f / (1.f + C); + float next_a1 = -D * next_a0; + float next_b2 = (1.f - C) * next_a0; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float a1_slope = (next_a1 - a1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + ay = a1 * y1; + y0 = ZXP(nin) - ay - b2 * y2; + ZXP(nout) = a0 * (y0 + y2) + ay; + + ay = a1 * y0; + y2 = ZXP(nin) - ay - b2 * y1; + ZXP(nout) = a0 * (y2 + y1) + ay; + + ay = a1 * y2; + y1 = ZXP(nin) - ay - b2 * y0; + ZXP(nout) = a0 * (y1 + y0) + ay; + + a0 += a0_slope; + a1 += a1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + ay = a1 * y1; + y0 = ZXP(nin) - ay - b2 * y2; + ZXP(nout) = a0 * (y0 + y2) + ay; + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_a1 = a1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + ay = a1 * y1; + y0 = ZXP(nin) - ay - b2 * y2; + ZXP(nout) = a0 * (y0 + y2) + ay; + + ay = a1 * y0; + y2 = ZXP(nin) - ay - b2 * y1; + ZXP(nout) = a0 * (y2 + y1) + ay; + + ay = a1 * y2; + y1 = ZXP(nin) - ay - b2 * y0; + ZXP(nout) = a0 * (y1 + y0) + ay; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + ay = a1 * y1; + y0 = ZXP(nin) - ay - b2 * y2; + ZXP(nout) = a0 * (y0 + y2) + ay; + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate BRF filter */ diff --git a/sc4pd/source/BRZ2.cpp b/sc4pd/source/BRZ2.cpp new file mode 100644 index 0000000..4c14fa2 --- /dev/null +++ b/sc4pd/source/BRZ2.cpp @@ -0,0 +1,140 @@ +/* sc4pd + BRZ2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ BRZ2~ -------------------------------*/ + +class BRZ2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(BRZ2_ar,sc4pd_dsp); + +public: + BRZ2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mFilterLoops=sc_filterloops(); + mFilterRemain=sc_filterremain(); + } + +private: + float m_x1, m_x2; + int mFilterLoops, mFilterRemain; +}; + +FLEXT_LIB_DSP_V("BRZ2~",BRZ2_ar); + +BRZ2_ar::BRZ2_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; + m_x2=0; +} + +void BRZ2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + float x2 = m_x2; + + for (int i = 0; i!=mFilterLoops ;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 + x2) * 0.5f; + x2 = ZXP(nin); + ZXP(nout) = (x2 + x1) * 0.5f; + x1 = ZXP(nin); + ZXP(nout) = (x1 + x0) * 0.5f; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 + x2) * 0.5f; + x2 = x1; + x1 = x0; + } + m_x1 = x1; + m_x2 = x2; +} + +/* ------------------------ BRZ2 -------------------------------*/ + +class BRZ2_kr: + public flext_base +{ + FLEXT_HEADER(BRZ2_kr,flext_base); + +public: + BRZ2_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + float m_x2; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("BRZ2",BRZ2_kr); + +BRZ2_kr::BRZ2_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x2 = m_x1 = 0; +} + +void BRZ2_kr::m_perform(float f) +{ + ToOutFloat(0,(f + m_x2) * 0.5f); + m_x2=m_x1; + m_x1=f; +} + diff --git a/sc4pd/source/BrownNoise.cpp b/sc4pd/source/BrownNoise.cpp new file mode 100644 index 0000000..316ee42 --- /dev/null +++ b/sc4pd/source/BrownNoise.cpp @@ -0,0 +1,156 @@ +/* sc4pd + BrownNoise, BrownNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: AMM: Laminal + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ BrownNoise~ -------------------------------*/ + +class BrownNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(BrownNoise_ar,sc4pd_dsp); + +public: + BrownNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_level; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("BrownNoise~",BrownNoise_ar); + +BrownNoise_ar::BrownNoise_ar(int argc, t_atom *argv) +{ + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + m_level=rgen.frand2(); + + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AddOutSignal(); +} + + +void BrownNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + + float z = m_level; + + for (int i = 0; i!= n;++i) + { + z += frand8(s1, s2, s3); + if (z > 1.f) + z = 2.f - z; + else + if (z < -1.f) + z = -2.f - z; + (*(nout)++) = z; + } + m_level = z; + + RPUT; +} + + +/* ------------------------ BrownNoise ---------------------------------*/ + +class BrownNoise_kr: + public flext_base +{ + FLEXT_HEADER(BrownNoise_kr,flext_base); + +public: + BrownNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_level; + RGen rgen; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("BrownNoise",BrownNoise_kr); + +BrownNoise_kr::BrownNoise_kr(int argc, t_atom *argv) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + m_level=rgen.frand2(); + + AddOutFloat(); +} + +void BrownNoise_kr::m_perform() +{ + float z = m_level + rgen.frand8(); + if (z > 1.f) + z = 2.f - z; + else + if (z < -1.f) + z = -2.f - z; + ToOutFloat(0,z); + m_level = z; +} diff --git a/sc4pd/source/ClipNoise.cpp b/sc4pd/source/ClipNoise.cpp new file mode 100644 index 0000000..39c0d61 --- /dev/null +++ b/sc4pd/source/ClipNoise.cpp @@ -0,0 +1,136 @@ +/* sc4pd + ClipNoise, ClipNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Henry Threadgill: Everybodys Mouth's A Book + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ ClipNoise~ -------------------------------*/ + +class ClipNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(ClipNoise_ar,sc4pd_dsp); + +public: + ClipNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("ClipNoise~",ClipNoise_ar); + +ClipNoise_ar::ClipNoise_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutSignal(); +} + + +void ClipNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = fcoin(s1, s2, s3); + } + + RPUT; +} + + +/* ------------------------ ClipNoise ---------------------------------*/ + +class ClipNoise_kr: + public flext_base +{ + FLEXT_HEADER(ClipNoise_kr,flext_base); + +public: + ClipNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + RGen rgen; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("ClipNoise",ClipNoise_kr); + +ClipNoise_kr::ClipNoise_kr(int argc, t_atom *argv) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutInt(); +} + +void ClipNoise_kr::m_perform() +{ + ToOutInt(0,rgen.fcoin()); +} diff --git a/sc4pd/source/CoinGate.cpp b/sc4pd/source/CoinGate.cpp new file mode 100644 index 0000000..fc47aca --- /dev/null +++ b/sc4pd/source/CoinGate.cpp @@ -0,0 +1,84 @@ +/* sc4pd + CoinGate + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: the sounds coming through my open window + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ CoinGate ---------------------------------*/ + +class CoinGate_kr: + public flext_base +{ + FLEXT_HEADER(CoinGate_kr,flext_base); + +public: + CoinGate_kr(int argc, t_atom *argv); + +protected: + void m_bang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float prob; + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_I(m_seed); + RGen rgen; +}; + +FLEXT_LIB_V("CoinGate",CoinGate_kr); + +CoinGate_kr::CoinGate_kr(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + prob = sc_getfloatarg(Args,0); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + AddOutBang(); +} + +void CoinGate_kr::m_bang() +{ + if(rgen.frand() < prob) + ToOutBang(0); +} diff --git a/sc4pd/source/CombC.cpp b/sc4pd/source/CombC.cpp new file mode 100644 index 0000000..bed7384 --- /dev/null +++ b/sc4pd/source/CombC.cpp @@ -0,0 +1,314 @@ +/* sc4pd + CombC~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Butcher/Charles/Doerner: The Contest Of Pleasures + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class CombC_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(CombC_ar,FeedbackDelay_ar); + + CombC_ar (int argc, t_atom *argv); + ~CombC_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("CombC~",CombC_ar); + +CombC_ar::CombC_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +CombC_ar::~CombC_ar () +{ + DelayUnit_Dtor(); +} + +void CombC_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + float d0, d1, d2, d3; + + if (delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + + if (irdphase0 < 0) + { + dlybuf[iwrphase & mask] = ZXP(nin); + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + float value = cubicinterp(frac, d0, d1, d2, d3); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + } + + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for (int i = 0; i!= n;++i) + { + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + if (irdphase0 < 0) + { + dlybuf[iwrphase & mask] = ZXP(nin); + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + float value = cubicinterp(frac, d0, d1, d2, d3); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + } + iwrphase++; + } + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void CombC_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + float d0, d1, d2, d3; + + if(delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + float value = cubicinterp(frac, d0, d1, d2, d3); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for(int i=0; i!= n;++i) + { + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + float value = cubicinterp(frac, d0, d1, d2, d3); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + iwrphase++; + } + } + m_iwrphase = iwrphase; +} + +/* todo: CombC for control rate ? */ diff --git a/sc4pd/source/CombL.cpp b/sc4pd/source/CombL.cpp new file mode 100644 index 0000000..9af21ae --- /dev/null +++ b/sc4pd/source/CombL.cpp @@ -0,0 +1,272 @@ +/* sc4pd + CombL~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Butcher/Charles/Doerner: The Contest Of Pleasures + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class CombL_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(CombL_ar,FeedbackDelay_ar); + + CombL_ar (int argc, t_atom *argv); + ~CombL_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("CombL~",CombL_ar); + +CombL_ar::CombL_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +CombL_ar::~CombL_ar () +{ + DelayUnit_Dtor(); +} + +void CombL_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if (delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + float zin = ZXP(nin); + if (irdphase < 0) + { + dlybuf[iwrphase & mask] = zin; + ZXP(nout) = 0.f; + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + float value = d1 - frac * d1; + dlybuf[iwrphase & mask] = zin + feedbk * value; + ZXP(nout) = value; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + dlybuf[iwrphase & mask] = zin + feedbk * value; + ZXP(nout) = value; + } + + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for (int i = 0; i!= n;++i) + { + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + float zin = ZXP(nin); + if (irdphase < 0) + { + dlybuf[iwrphase & mask] = zin; + ZXP(nout) = 0.f; + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + float value = d1 - frac * d1; + dlybuf[iwrphase & mask] = zin + feedbk * value; + ZXP(nout) = value; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + dlybuf[iwrphase & mask] = zin + feedbk * value; + ZXP(nout) = value; + } + iwrphase++; + } + + + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void CombL_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if(delay_changed || decay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + + for(int i=0; i!= n;++i) + { + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + float value = lininterp(frac, d1, d2); + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + iwrphase++; + + } + } + m_iwrphase = iwrphase; +} + +/* todo: CombL for control rate ? */ diff --git a/sc4pd/source/CombN.cpp b/sc4pd/source/CombN.cpp new file mode 100644 index 0000000..9c6f33e --- /dev/null +++ b/sc4pd/source/CombN.cpp @@ -0,0 +1,341 @@ +/* sc4pd + CombN~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & John Tilbury: Duos For Doris + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class CombN_ar : public FeedbackDelay_ar +{ + FLEXT_HEADER(CombN_ar,FeedbackDelay_ar); + + CombN_ar (int argc, t_atom *argv); + ~CombN_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + delay_changed = decay_changed = false; + FeedbackDelay_Reset(); + } + + void m_delay(float f) + { + m_delaytime=f; + delay_changed = true; + } + + void m_decay(float f) + { + m_decaytime=f; + decay_changed = true; + } + +private: + bool delay_changed, decay_changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_delay); + FLEXT_CALLBACK_F(m_decay); +}; + +FLEXT_LIB_DSP_V("CombN~",CombN_ar); + +CombN_ar::CombN_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_delay); + FLEXT_ADDMETHOD_(0,"decaytime",m_decay); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("3 arguments are needed"); + return; + } + + m_maxdelaytime = sc_getfloatarg(Args,0); + m_delaytime = sc_getfloatarg(Args,1); + m_decaytime = sc_getfloatarg(Args,2); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +CombN_ar::~CombN_ar () +{ + DelayUnit_Dtor(); +} + +void CombN_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if (delay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long irdphase = iwrphase - (long)dsamp; + + if (irdphase < 0) + { + dlybuf[iwrphase & mask] = ZXP(nin); + ZXP(nout) = 0.f; + } + else + { + float value = dlybuf[irdphase & mask]; + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + } + feedbk += feedbk_slope; + iwrphase++; + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyN = dlybuf1 + m_idelaylen; + if (decay_changed) + { + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + long remain = n; + while (remain) + { + float* dlyrd = dlybuf1 + (irdphase & mask); + float* dlywr = dlybuf1 + (iwrphase & mask); + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + if (irdphase < 0) + { + feedbk += nsmps * feedbk_slope; + dlyrd += nsmps; + for (int i = 0; i!= nsmps;++i) + { + ZXP(dlywr) = ZXP(nin); + ZXP(nout) = 0.f; + } + } + else + { + for (int i = 0; i!= nsmps;++i) + { + float value = ZXP(dlyrd); + ZXP(dlywr) = value * feedbk + ZXP(nin); + ZXP(nout) = value; + feedbk += feedbk_slope; + } + } + iwrphase += nsmps; + irdphase += nsmps; + } + m_feedbk = feedbk; + decay_changed=false; + } + else + { + long remain = n; + while (remain) + { + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyrd = dlybuf1 + (irdphase & mask); + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + if (irdphase < 0) + { + for (int i = 0; i!= nsmps;++i) + { + ZXP(dlywr) = ZXP(nin); + ZXP(nout) = 0.f; + } + } + else + { + for (int i = 0; i!= nsmps;++i) + { + float value = ZXP(dlyrd); + ZXP(dlywr) = value * feedbk + ZXP(nin); + ZXP(nout) = value; + } + } + iwrphase += nsmps; + irdphase += nsmps; + } + + } + } + + m_iwrphase = iwrphase; + m_numoutput += n; + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void CombN_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + float feedbk = m_feedbk; + long mask = m_mask; + + if(delay_changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + + for(int i=0; i!= n;++i) + { + dsamp += dsamp_slope; + ++iwrphase; + long irdphase = iwrphase - (long)dsamp; + float value = dlybuf[irdphase & mask]; + dlybuf[iwrphase & mask] = ZXP(nin) + feedbk * value; + ZXP(nout) = value; + feedbk += feedbk_slope; + + } + m_feedbk = feedbk; + m_dsamp = dsamp; + delay_changed = decay_changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyrd = dlybuf1 + (irdphase & mask); + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyN = dlybuf1 + m_idelaylen; + + if(decay_changed) + { + float next_feedbk = CalcFeedback(m_delaytime, m_decaytime); + float feedbk_slope = CALCSLOPE(next_feedbk, feedbk); + long remain = n; + while (remain) + { + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + for(int i=0; i!= nsmps;++i) + { + float value = ZXP(dlyrd); + ZXP(dlywr) = value * feedbk + ZXP(nin); + ZXP(nout) = value; + feedbk += feedbk_slope; + } + if (dlyrd == dlyN) dlyrd = dlybuf1; + if (dlywr == dlyN) dlywr = dlybuf1; + } + m_feedbk = feedbk; + decay_changed = false; + } + else + { + long remain = n; + while (remain) + { + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + + for (int i = 0; i!= nsmps; ++i) + { + float value = ZXP(dlyrd); + ZXP(dlywr) = value * feedbk + ZXP(nin); + ZXP(nout) = value; + } + if (dlyrd == dlyN) dlyrd = dlybuf1; + if (dlywr == dlyN) dlywr = dlybuf1; + } + + } + iwrphase += n; + + + } + m_iwrphase = iwrphase; +} + +/* todo: CombN for control rate ? */ diff --git a/sc4pd/source/Convolution.cpp b/sc4pd/source/Convolution.cpp new file mode 100644 index 0000000..0026b01 --- /dev/null +++ b/sc4pd/source/Convolution.cpp @@ -0,0 +1,222 @@ +/* sc4pd + Convolution~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Ambarchi/Muller/Voice Crack: Oystered + +*/ + +#include "sc4pd.hpp" +#include "fftlib.h" + +/* ------------------------ Convolution~ -------------------------------*/ + +class Convolution_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Convolution_ar,sc4pd_dsp); + +public: + Convolution_ar(int argc, t_atom *argv); + ~Convolution_ar(); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + +private: + int m_pos, m_insize, m_fftsize,m_mask; + int m_log2n; + + float *m_inbuf1,*m_inbuf2, *m_fftbuf1, *m_fftbuf2, *m_outbuf,*m_overlapbuf; + +}; + +FLEXT_LIB_DSP_V("Convolution~",Convolution_ar); + +Convolution_ar::Convolution_ar(int argc, t_atom *argv) +{ + + //parse arguments + AtomList Args(argc,argv); + + m_insize = sc_getfloatarg(Args,0); + + AddInSignal("signal"); + AddInSignal("kernel"); + AddOutSignal(); + + + //require size N+M-1 to be a power of two + + m_fftsize=2*(m_insize); + + //just use memory for the input buffers and fft buffers + int insize = m_insize * sizeof(float); + int fftsize = m_fftsize * sizeof(float); + + m_inbuf1 = new float[m_insize]; + m_inbuf2 = new float[m_insize]; + + m_fftbuf1 = new float[m_fftsize]; + m_fftbuf2 = new float[m_fftsize]; + + m_outbuf = new float[m_fftsize]; + m_overlapbuf = new float[m_insize]; + + memset(m_outbuf, 0, fftsize); + memset(m_overlapbuf, 0, insize); + + m_log2n = LOG2CEIL(m_fftsize); + + //test for full input buffer + m_mask = m_insize; + m_pos = 0; +} + +Convolution_ar::~Convolution_ar() +{ + delete m_inbuf1; + delete m_inbuf2; + + delete m_fftbuf1; + delete m_fftbuf2; + + delete m_outbuf; + delete m_overlapbuf; +} + +void Convolution_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + +} + +extern float* cosTable[32]; + +void Convolution_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + float *in1 = in[0]; + float *in2 = in[1]; + + float *out1 = m_inbuf1 + m_pos; + float *out2 = m_inbuf2 + m_pos; + + int numSamples = 2*n; //??? mWorld->mFullRate.mBufLength; + + // copy input + CopySamples(out1, in1, numSamples); + CopySamples(out2, in2, numSamples); + + m_pos += numSamples; + + if (m_pos & m_insize) + { + + //have collected enough samples to transform next frame + m_pos = 0; //reset collection counter + + // copy to fftbuf + + uint32 insize=m_insize * sizeof(float); + memcpy(m_fftbuf1, m_inbuf1, insize); + memcpy(m_fftbuf2, m_inbuf2, insize); + + //zero pad second part of buffer to allow for convolution + memset(m_fftbuf1+m_insize, 0, insize); + memset(m_fftbuf2+m_insize, 0, insize); + + int log2n = m_log2n; + + + // do windowing + DoWindowing(log2n, m_fftbuf1, m_fftsize); + DoWindowing(log2n, m_fftbuf2, m_fftsize); + + // do fft +/* #if __VEC__ + ctoz(m_fftbuf1, 2, outbuf1, 1, 1L<<log2n); ctoz(m_fftbuf2, 2, outbuf2, 1, 1L<<log2n); + #else */ + +//in place transform for now + rffts(m_fftbuf1, log2n, 1, cosTable[log2n]); + rffts(m_fftbuf2, log2n, 1, cosTable[log2n]); +//#endif + +//complex multiply time + int numbins = m_fftsize >> 1; //m_fftsize - 2 >> 1; + + float * p1= m_fftbuf1; + float * p2= m_fftbuf2; + + p1[0] *= p2[0]; + p1[1] *= p2[1]; + + //complex multiply + for (int i=1; i<numbins; ++i) { + float real,imag; + int realind,imagind; + realind= 2*i; imagind= realind+1; + real= p1[realind]*p2[realind]- p1[imagind]*p2[imagind]; + imag= p1[realind]*p2[imagind]+ p1[imagind]*p2[realind]; + p1[realind] = real; //p2->bin[i]; + p1[imagind]= imag; + } + + //copy second part from before to overlap + memcpy(m_overlapbuf, m_outbuf+m_insize, m_insize * sizeof(float)); + + //inverse fft into outbuf + memcpy(m_outbuf, m_fftbuf1, m_fftsize * sizeof(float)); + + //in place + riffts(m_outbuf, log2n, 1, cosTable[log2n]); + + DoWindowing(log2n, m_outbuf, m_fftsize); + } + + //write out samples copied from outbuf, with overlap added in + + float *output = out[0]; + float *nout= m_outbuf+m_pos; + float *overlap= m_overlapbuf+m_pos; + + for (int i=0; i<numSamples; ++i) + { + *++output = *++nout + *++overlap; + } + +} + + + + diff --git a/sc4pd/source/Crackle.cpp b/sc4pd/source/Crackle.cpp new file mode 100644 index 0000000..8f6c28f --- /dev/null +++ b/sc4pd/source/Crackle.cpp @@ -0,0 +1,153 @@ +/* sc4pd + Crackle, Crackle~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: David S. Ware: Threads + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Crackle~ -------------------------------*/ + +class Crackle_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Crackle_ar,sc4pd_dsp); + +public: + Crackle_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_paramf = f; + } + +private: + FLEXT_CALLBACK_F(m_set); + float m_paramf; + float m_y1, m_y2; +}; + +FLEXT_LIB_DSP_V("Crackle~",Crackle_ar); + +Crackle_ar::Crackle_ar(int argc, t_atom *argv) + : m_y1(0.3f),m_y2(0.f) +{ + FLEXT_ADDMETHOD_(0,"parameter",m_set); + //parse arguments + AtomList Args(argc,argv); + m_paramf=sc_getfloatarg(Args,0); + + if (m_paramf == 0) + m_paramf = 1; + + AddOutSignal(); +} + + +void Crackle_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float paramf = m_paramf; + float y1 = m_y1; + float y2 = m_y2; + float y0; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = y0 = fabs(y1 * paramf - y2 - 0.05f); + y2 = y1; + y1 = y0; + } + + m_y1=y1; + m_y2=y2; +} + + +/* ------------------------ Crackle ---------------------------------*/ + +class Crackle_kr: + public flext_base +{ + FLEXT_HEADER(Crackle_kr,flext_base); + +public: + Crackle_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_set(float f) + { + m_paramf = f; + } + +private: + float m_paramf; + float m_y1, m_y2; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("Crackle",Crackle_kr); + +Crackle_kr::Crackle_kr(int argc, t_atom *argv) + : m_y1(0.3f),m_y2(0.f) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"parameter",m_set); + + //parse arguments + AtomList Args(argc,argv); + m_paramf=sc_getfloatarg(Args,0); + + if (m_paramf == 0) + m_paramf = 1; + + AddOutFloat(); +} + +void Crackle_kr::m_perform() +{ + float y0 = fabs(m_y1 * m_paramf - m_y2 - 0.05f); + m_y2 = m_y1; + m_y1 = y0; + + ToOutFloat(0,y0); +} diff --git a/sc4pd/source/Decay.cpp b/sc4pd/source/Decay.cpp new file mode 100644 index 0000000..c11a7a8 --- /dev/null +++ b/sc4pd/source/Decay.cpp @@ -0,0 +1,212 @@ +/* sc4pd + Decay~, Decay + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: AMM: AMMMusic 1966 + +*/ + +#include "sc4pd.hpp" + +/* todo: linear interpolation is broken */ +/* ------------------------ Decay~ -----------------------------*/ + +class Decay_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Decay_ar,sc4pd_dsp); + +public: + Decay_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + float m_b1; //leak + float m_y1; //z-1 + float decayTime; +}; + +FLEXT_LIB_DSP_V("Decay~",Decay_ar); + +Decay_ar::Decay_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"decayTime",m_set); + + AtomList Args(argc,argv); + + decayTime = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_y1 = 0.f; +} + +void Decay_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float b1 = m_b1; + float y1 = m_y1; + + if (b1 == m_b1) + { + if (b1 == 1.f) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + y1; + } + + } + else if (b1 == 0.f) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * y1; + } + } + } + else + { + float b1_slope = CALCSLOPE(m_b1, b1); + if (b1 >= 0.f && m_b1 >= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * (y1 - y0); + b1 += b1_slope; + } + } + else if (b1 <= 0.f && m_b1 <= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * (y1 + y0); + b1 += b1_slope; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = (1.f - fabs(b1)) * y0 + b1 * y1; + b1 += b1_slope; + } + } + } + m_y1 = zapgremlins(y1); +} + +void Decay_ar::m_set(float f) +{ + decayTime = f; + m_b1= f == 0.f ? 0.f : exp(log001 / (decayTime * Samplerate())); +} + +void Decay_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + m_b1= decayTime == 0.f ? 0.f : exp(log001 / (decayTime * Samplerate())); +} + +/* todo: does it make sense to implement a message-based Decay? + Probably not... */ + + +/* ------------------------ Decay ------------------------------*/ + +// class Decay_kr +// :public flext_base +// { +// FLEXT_HEADER(Decay_kr,flext_base); + +// public: +// Decay_kr(int argc,t_atom * argv); + +// protected: +// void m_set(float f); +// void m_perform(float f); + +// private: +// float m_b1; //leak +// float m_y1; //z-1 + +// FLEXT_CALLBACK_F(m_set); +// FLEXT_CALLBACK_F(m_perform); +// }; + +// FLEXT_LIB_V("Decay",Decay_kr); + +// Decay_kr::Decay_kr(int argc,t_atom * argv) +// { +// AtomList Args(argc,argv); + +// m_b1 = sc_getfloatarg(Args,0); +// m_y1 = 0.f; + + +// AddInFloat(); +// AddOutFloat(); + +// FLEXT_ADDMETHOD(0,m_perform); +// FLEXT_ADDMETHOD_(0,"leak",m_set); +// } + +// void Decay_kr::m_perform(float f) +// { +// m_y1 = f + m_y1 * m_b1; +// ToOutFloat(0,m_y1); +// } + +// void Decay_kr::m_set(float f) +// { +// m_b1=f; +// } diff --git a/sc4pd/source/Decay2.cpp b/sc4pd/source/Decay2.cpp new file mode 100644 index 0000000..a78a180 --- /dev/null +++ b/sc4pd/source/Decay2.cpp @@ -0,0 +1,154 @@ +/* sc4pd + Decay2~, Decay2 + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: AMM: AMMMusic 1966 + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ Decay2~ -----------------------------*/ + +class Decay2_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Decay2_ar,sc4pd_dsp); + +public: + Decay2_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + void m_attack(float f); + void m_decay(float f); + +private: + FLEXT_CALLBACK_F(m_decay); + FLEXT_CALLBACK_F(m_attack); + float m_attackTime, m_y1a, m_b1a, n_b1a; + float m_decayTime, m_y1b, m_b1b, n_b1b; + bool changed; +}; + +FLEXT_LIB_DSP_V("Decay2~",Decay2_ar); + +Decay2_ar::Decay2_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"decayTime",m_decay); + FLEXT_ADDMETHOD_(0,"attackTime",m_attack); + + AtomList Args(argc,argv); + + m_decayTime = sc_getfloatarg(Args,1); //decay + m_attackTime = sc_getfloatarg(Args,0);//attack + + AddOutSignal(); + + m_y1a = m_y1b = 0.f; //different than in sc + +} + +void Decay2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float y1a = m_y1a; + float y1b = m_y1b; + float b1a = m_b1a; + float b1b = m_b1b; + + if(changed) + { + float b1a_slope = CALCSLOPE(n_b1a, b1a); + float b1b_slope = CALCSLOPE(n_b1b, b1b); + m_b1a = n_b1a; + m_b1b = n_b1b; + + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + y1a = y0 + b1a * y1a; + y1b = y0 + b1b * y1b; + + ZXP (nout) = y1a - y1b; + b1a += b1a_slope; + b1b += b1b_slope; + } + changed = false; + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + y1a = y0 + b1a * y1a; + y1b = y0 + b1b * y1b; + + ZXP (nout) = y1a - y1b; + } + } + + m_y1a = zapgremlins(y1a); + m_y1b = zapgremlins(y1b); +} + +void Decay2_ar::m_decay(float f) +{ + m_decayTime = f; + n_b1a = f == 0.f ? 0.f : exp(log001 / (f * Samplerate())); + changed = true; +} + +void Decay2_ar::m_attack(float f) +{ + m_attackTime = f; + n_b1b = f == 0.f ? 0.f : exp(log001 / (f * Samplerate())); + changed = true; +} + +void Decay2_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + m_b1a = m_decayTime == 0.f ? 0.f : exp(log001 / + (m_decayTime * Samplerate())); + m_b1b = m_attackTime == 0.f ? 0.f : exp(log001 / + (m_attackTime * Samplerate())); + changed = false; +} + +/* todo: does it make sense to implement a message-based Decay2? + Probably not... */ + diff --git a/sc4pd/source/DelayC.cpp b/sc4pd/source/DelayC.cpp new file mode 100644 index 0000000..50ab366 --- /dev/null +++ b/sc4pd/source/DelayC.cpp @@ -0,0 +1,287 @@ +/* sc4pd + DelayC~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Tom Cora: Halleluja, Anyway + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class DelayC_ar : private DelayUnit_ar +{ + FLEXT_HEADER(DelayC_ar,DelayUnit_ar); + + DelayC_ar (int argc, t_atom *argv); + ~DelayC_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + changed = false; + DelayUnit_Reset(); + } + + void m_set(float f) + { + m_delaytime=f; + changed = true; + } + +private: + bool changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("DelayC~",DelayC_ar); + +DelayC_ar::DelayC_ar (int argc, t_atom *argv) +{ + + FLEXT_ADDMETHOD_(0,"delaytime",m_set); + + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("2 arguments are needed"); + return; + } + + m_delaytime = sc_getfloatarg(Args,0); + m_maxdelaytime = sc_getfloatarg(Args,1); + + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +DelayC_ar::~DelayC_ar () +{ + DelayUnit_Dtor(); +} + +void DelayC_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + float d0, d1, d2, d3; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + dlybuf[iwrphase & mask] = ZXP(nin); + if (irdphase0 < 0) + { + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3); + } + iwrphase++; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + for (int i = 0; i!= n;++i) + { + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + + dlybuf[iwrphase & mask] = ZXP(nin); + if (irdphase0 < 0) + { + ZXP(nout) = 0.f; + } + else + { + if (irdphase1 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + } + else if (irdphase2 < 0) + { + d1 = d2 = d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + } + else if (irdphase3 < 0) + { + d3 = 0.f; + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + } + else + { + d0 = dlybuf[irdphase0 & mask]; + d1 = dlybuf[irdphase1 & mask]; + d2 = dlybuf[irdphase2 & mask]; + d3 = dlybuf[irdphase3 & mask]; + } + ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3); + } + iwrphase++; + } + } + + m_iwrphase = iwrphase; + + m_numoutput += n; + + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void DelayC_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dlybuf[iwrphase & mask] = ZXP(nin); + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3); + iwrphase++; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + for (int i = 0; i!= n;++i) + { + dlybuf[iwrphase & mask] = ZXP(nin); + long irdphase1 = iwrphase - idsamp; + long irdphase2 = irdphase1 - 1; + long irdphase3 = irdphase1 - 2; + long irdphase0 = irdphase1 + 1; + float d0 = dlybuf[irdphase0 & mask]; + float d1 = dlybuf[irdphase1 & mask]; + float d2 = dlybuf[irdphase2 & mask]; + float d3 = dlybuf[irdphase3 & mask]; + ZXP(nout) = cubicinterp(frac, d0, d1, d2, d3); + iwrphase++; + } + } + m_iwrphase = iwrphase; +} + +/* todo: DelayC for control rate ? */ diff --git a/sc4pd/source/DelayL.cpp b/sc4pd/source/DelayL.cpp new file mode 100644 index 0000000..46b5458 --- /dev/null +++ b/sc4pd/source/DelayL.cpp @@ -0,0 +1,236 @@ +/* sc4pd + DelayL~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Tom Cora: Halleluja, Anyway + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class DelayL_ar : private DelayUnit_ar +{ + FLEXT_HEADER(DelayL_ar,DelayUnit_ar); + + DelayL_ar (int argc, t_atom *argv); + ~DelayL_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + changed = false; + DelayUnit_Reset(); + } + + void m_set(float f) + { + m_delaytime=f; + changed = true; + } + +private: + bool changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("DelayL~",DelayL_ar); + +DelayL_ar::DelayL_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_set); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("2 arguments are needed"); + return; + } + + m_delaytime = sc_getfloatarg(Args,0); + m_maxdelaytime = sc_getfloatarg(Args,1); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +DelayL_ar::~DelayL_ar () +{ + DelayUnit_Dtor(); +} + +void DelayL_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + dlybuf[iwrphase & mask] = ZXP(nin); + if (irdphase < 0) + { + ZXP(nout) = 0.f; + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + ZXP(nout) = d1 - frac * d1; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + ZXP(nout) = lininterp(frac, d1, d2); + } + iwrphase++; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + for (int i = 0; i!= n;++i) + { + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + + dlybuf[iwrphase & mask] = ZXP(nin); + if (irdphase < 0) + { + ZXP(nout) = 0.f; + } + else if (irdphaseb < 0) + { + float d1 = dlybuf[irdphase & mask]; + ZXP(nout) = d1 - frac * d1; + } + else + { + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + ZXP(nout) = lininterp(frac, d1, d2); + } + iwrphase++; + } + } + + m_iwrphase = iwrphase; + + m_numoutput += n; + + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void DelayL_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dlybuf[iwrphase & mask] = ZXP(nin); + dsamp += dsamp_slope; + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + ZXP(nout) = lininterp(frac, d1, d2); + iwrphase++; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long idsamp = (long)dsamp; + float frac = dsamp - idsamp; + for (int i = 0; i!= n;++i) + { + dlybuf[iwrphase & mask] = ZXP(nin); + long irdphase = iwrphase - idsamp; + long irdphaseb = irdphase - 1; + float d1 = dlybuf[irdphase & mask]; + float d2 = dlybuf[irdphaseb & mask]; + ZXP(nout) = lininterp(frac, d1, d2); + iwrphase++; + } + + } + m_iwrphase = iwrphase; +} + +/* todo: DelayL for control rate ? */ diff --git a/sc4pd/source/DelayN.cpp b/sc4pd/source/DelayN.cpp new file mode 100644 index 0000000..6bbbb18 --- /dev/null +++ b/sc4pd/source/DelayN.cpp @@ -0,0 +1,238 @@ +/* sc4pd + DelayN~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +class DelayN_ar : private DelayUnit_ar +{ + FLEXT_HEADER(DelayN_ar,DelayUnit_ar); + + DelayN_ar (int argc, t_atom *argv); + ~DelayN_ar (); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + changed = false; + DelayUnit_Reset(); + } + + void m_set(float f) + { + m_delaytime=f; + changed = true; + } + +private: + bool changed; + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("DelayN~",DelayN_ar); + +DelayN_ar::DelayN_ar (int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"delaytime",m_set); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("2 arguments are needed"); + return; + } + + m_delaytime = sc_getfloatarg(Args,0); + m_maxdelaytime = sc_getfloatarg(Args,1); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + + AddOutSignal(); +} + +DelayN_ar::~DelayN_ar () +{ + DelayUnit_Dtor(); +} + +void DelayN_ar::m_signal_z(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dsamp += dsamp_slope; + long irdphase = iwrphase - (long)dsamp; + + dlybuf[iwrphase & mask] = ZXP(nin); + if (irdphase < 0) + { + ZXP(nout) = 0.f; + } + else + { + ZXP(nout) = dlybuf[irdphase & mask]; + } + iwrphase++; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyN = dlybuf1 + m_idelaylen; + long remain = n; + + while (remain) + { + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyrd = dlybuf1 + (irdphase & mask); + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + if (irdphase < 0) + { + for (int i = 0; i!= nsmps;++i) + { + ZXP(dlywr) = ZXP(nin); + ZXP(nout) = 0.f; + } + } + else + { + for (int i = 0; i!= nsmps;++i) + { + ZXP(dlywr) = ZXP(nin); + ZXP(nout) = ZXP(dlyrd); + } + } + iwrphase += nsmps; + irdphase += nsmps; + } + } + + m_iwrphase = iwrphase; + + m_numoutput += n; + + if (m_numoutput >= m_idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_)); + } +} + +void DelayN_ar::m_signal_(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float *dlybuf = m_dlybuf; + long iwrphase = m_iwrphase; + float dsamp = m_dsamp; + long mask = m_mask; + + if (changed) + { + float next_dsamp = CalcDelay(m_delaytime); + float dsamp_slope = CALCSLOPE(next_dsamp, dsamp); + + for (int i = 0; i!= n;++i) + { + dlybuf[iwrphase & mask] = ZXP(nin); + dsamp += dsamp_slope; + ++iwrphase; + long irdphase = iwrphase - (long)dsamp; + ZXP(nout) = dlybuf[irdphase & mask]; + } + m_dsamp = dsamp; + changed = false; + } + else + { + long irdphase = iwrphase - (long)dsamp; + float* dlybuf1 = dlybuf - ZOFF; + float* dlyrd = dlybuf1 + (irdphase & mask); + float* dlywr = dlybuf1 + (iwrphase & mask); + float* dlyN = dlybuf1 + m_idelaylen; + long remain = n; + while (remain) + { + long rdspace = dlyN - dlyrd; + long wrspace = dlyN - dlywr; + long nsmps = sc_min(rdspace, wrspace); + nsmps = sc_min(remain, nsmps); + remain -= nsmps; + for (int i = 0; i!= nsmps;++i) + { + ZXP(dlywr) = ZXP(nin); + ZXP(nout) = ZXP(dlyrd); + } + if (dlyrd == dlyN) dlyrd = dlybuf1; + if (dlywr == dlyN) dlywr = dlybuf1; + } + iwrphase += n; + } + m_iwrphase = iwrphase; +} + +/* todo: DelayN for control rate ? */ diff --git a/sc4pd/source/DelayUnit.cpp b/sc4pd/source/DelayUnit.cpp new file mode 100644 index 0000000..bd57f7d --- /dev/null +++ b/sc4pd/source/DelayUnit.cpp @@ -0,0 +1,81 @@ +/* sc4pd + public class for several delay objects + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: + +*/ + +#include "sc4pd.hpp" +#include "DelayUnit.hpp" + +void DelayUnit_ar::DelayUnit_AllocDelayLine() +{ + long delaybufsize = (long)ceil(m_maxdelaytime * Samplerate() + 1.f); + delaybufsize = delaybufsize + Blocksize(); + delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two + m_fdelaylen = m_idelaylen = delaybufsize; + + delete[] m_dlybuf; + m_dlybuf = new float[delaybufsize] ; + m_mask = delaybufsize - 1; +} + +void DelayUnit_ar::DelayUnit_Dtor() +{ + delete[] m_dlybuf; +} + +float DelayUnit_ar::CalcDelay(float delaytime) +{ + float next_dsamp = delaytime * Samplerate(); + return sc_clip(next_dsamp, 1.f, m_fdelaylen); +} + +void DelayUnit_ar::DelayUnit_Reset() +{ + m_dlybuf = 0; + + DelayUnit_AllocDelayLine(); + + m_dsamp = CalcDelay(m_delaytime); + + m_numoutput = 0; + m_iwrphase = 0; +} + +void FeedbackDelay_ar::FeedbackDelay_Reset() +{ + DelayUnit_Reset(); + + m_feedbk = CalcFeedback(m_delaytime, m_decaytime); +} diff --git a/sc4pd/source/DelayUnit.hpp b/sc4pd/source/DelayUnit.hpp new file mode 100644 index 0000000..a5951e5 --- /dev/null +++ b/sc4pd/source/DelayUnit.hpp @@ -0,0 +1,67 @@ +/* sc4pd + public class for several delay objects + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: + +*/ + +//#include "sc4pd.hpp" + +class DelayUnit_ar + : public sc4pd_dsp +{ + FLEXT_HEADER(DelayUnit_ar,sc4pd_dsp); + +public: + /* functions */ + void DelayUnit_AllocDelayLine(); + void DelayUnit_Reset(); + float CalcDelay(float delaytime); + void DelayUnit_Dtor(); + + /* data */ + float *m_dlybuf; + float m_dsamp, m_fdelaylen; + float m_delaytime, m_maxdelaytime; + long m_iwrphase, m_idelaylen, m_mask; + long m_numoutput; +}; + +/* todo: a delay for control messages? */ + +class FeedbackDelay_ar : public DelayUnit_ar +{ + FLEXT_HEADER(FeedbackDelay_ar,DelayUnit_ar); + float m_feedbk, m_decaytime; + void FeedbackDelay_Reset(); +}; diff --git a/sc4pd/source/Dust.cpp b/sc4pd/source/Dust.cpp new file mode 100644 index 0000000..f7b27a1 --- /dev/null +++ b/sc4pd/source/Dust.cpp @@ -0,0 +1,188 @@ +/* sc4pd: + Dust, Dust~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Assif Tsahar & Tatsuya Nakatani: Come Sunday +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Dust~ -------------------------------------*/ + +class Dust_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Dust_ar,sc4pd_dsp); + +public: + Dust_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp (int n,t_signalvec const * insigs, + t_signalvec const * outsigs); + + void m_set(float f) + { + m_density = f; + m_thresh = m_density/Samplerate(); + m_scale = m_thresh > 0.f ? 1.f / m_thresh : 0.f; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_I(m_seed); + float m_density, m_thresh, m_scale; + RGen rgen; + +}; + +FLEXT_LIB_DSP_V("Dust~",Dust_ar); + +Dust_ar::Dust_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + m_density=sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + + AddOutSignal(); +} + +void Dust_ar::m_dsp(int n,t_signalvec const * insigs, + t_signalvec const * outsigs) +{ + m_thresh = m_density/Samplerate(); + m_scale = m_thresh > 0.f ? 1.f / m_thresh : 0.f; +} + +void Dust_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + float thresh = m_thresh; + float scale = m_scale; + + for (int i = 0; i!= n;++i) + { + float z = frand(s1,s2,s3); + if (z < thresh) + (*(nout)++) = z * scale; + else + (*(nout)++) = 0.f; + } + + RPUT; +} + + +/* ------------------------ Dust ---------------------------------------*/ + +class Dust_kr: + public flext_base +{ + FLEXT_HEADER(Dust_kr,flext_base); + +public: + Dust_kr(int argc, t_atom *argv); + +protected: + void m_set(float f); + Timer Dust_timer; + void m_doit(void*); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_density, m_scale; + float mtbt; //medium time between trigger + RGen rgen; + FLEXT_CALLBACK_1(m_set,float); + FLEXT_CALLBACK_T(m_doit); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("Dust",Dust_kr); + +Dust_kr::Dust_kr(int argc, t_atom *argv) + : Dust_timer(false) +{ + FLEXT_ADDMETHOD(0,m_set); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + m_density=sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + AddOutFloat(); + + FLEXT_ADDTIMER(Dust_timer,m_doit); + + m_set(m_density); +} + +void Dust_kr::m_set(float f) +{ + Dust_timer.Reset(); + + if(f==0) + { + return; + } + m_density = f; + mtbt = 1/f*1000; + + Dust_timer.Delay(mtbt * 0.002 * rgen.frand()); +} + +void Dust_kr::m_doit(void*) +{ + ToOutFloat(0,rgen.frand()); + + Dust_timer.Delay(mtbt * 0.002 * rgen.frand()); +} diff --git a/sc4pd/source/Dust2.cpp b/sc4pd/source/Dust2.cpp new file mode 100644 index 0000000..2db7981 --- /dev/null +++ b/sc4pd/source/Dust2.cpp @@ -0,0 +1,188 @@ +/* sc4pd: + Dust2, Dust2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Herbert Eimert: Epitaph für Aikichi Kuboyama + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Dust2~ -------------------------------------*/ + +class Dust2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Dust2_ar,sc4pd_dsp); + +public: + Dust2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp (int n,t_signalvec const * insigs, + t_signalvec const * outsigs); + + void m_set(float f) + { + m_density = f; + m_thresh = m_density/Samplerate(); + m_scale = m_thresh > 0.f ? 1.f / m_thresh : 0.f; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_I(m_seed); + float m_density, m_thresh, m_scale; + RGen rgen; + +}; + +FLEXT_LIB_DSP_V("Dust2~",Dust2_ar); + +Dust2_ar::Dust2_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + m_density=sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void Dust2_ar::m_dsp(int n,t_signalvec const * insigs, + t_signalvec const * outsigs) +{ + m_thresh = m_density/Samplerate(); + m_scale = m_thresh > 0.f ? 2.f / m_thresh : 0.f; +} + +void Dust2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + float thresh = m_thresh; + float scale = m_scale; + + for (int i = 0; i!= n;++i) + { + float z = frand(s1,s2,s3); + if (z < thresh) + (*(nout)++) = z * scale - 1.f; + else + (*(nout)++) = 0.f; + } + + RPUT; +} + + +/* ------------------------ Dust2 ---------------------------------------*/ + +class Dust2_kr: + public flext_base +{ + FLEXT_HEADER(Dust2_kr,flext_base); + +public: + Dust2_kr(int argc, t_atom *argv); + +protected: + void m_set(float f); + Timer Dust2_timer; + void m_doit(void*); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_density, m_scale; + float mtbt; //medium time between trigger + RGen rgen; + FLEXT_CALLBACK_1(m_set,float); + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_T(m_doit); +}; + +FLEXT_LIB_V("Dust2",Dust2_kr); + +Dust2_kr::Dust2_kr(int argc, t_atom *argv) + : Dust2_timer(false) +{ + FLEXT_ADDMETHOD(0,m_set); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + m_density=sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + AddOutFloat(); + + FLEXT_ADDTIMER(Dust2_timer,m_doit); + + m_set(m_density); +} + +void Dust2_kr::m_set(float f) +{ + Dust2_timer.Reset(); + + if(f==0) + { + return; + } + m_density = f; + mtbt = 1/f*1000; + + Dust2_timer.Delay(mtbt * 0.002 * rgen.frand()); +} + +void Dust2_kr::m_doit(void*) +{ + ToOutFloat(0,2*rgen.frand() - 1 ); + + Dust2_timer.Delay(mtbt * 0.002 * rgen.frand()); +} diff --git a/sc4pd/source/ExpRand.cpp b/sc4pd/source/ExpRand.cpp new file mode 100644 index 0000000..a08f6fa --- /dev/null +++ b/sc4pd/source/ExpRand.cpp @@ -0,0 +1,160 @@ +/* sc4pd + ExpRand, ExpRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Jim O'Rourke & Loren Mazzacane Connors: In Bern + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ ExpRand~ -------------------------------*/ + +class ExpRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(ExpRand_ar,sc4pd_dsp); + +public: + ExpRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("ExpRand~",ExpRand_ar); + +ExpRand_ar::ExpRand_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void ExpRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + float ratio = hi / lo; + m_sample = pow(ratio,rgen.frand()) * lo; +} + + +void ExpRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + + +/* ------------------------ ExpRand ---------------------------------*/ + +class ExpRand_kr: + public flext_base +{ + FLEXT_HEADER(ExpRand_kr,flext_base); + +public: + ExpRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("ExpRand",ExpRand_kr); + +ExpRand_kr::ExpRand_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void ExpRand_kr::m_loadbang() +{ + float ratio = hi / lo; + ToOutFloat(0,pow(ratio,rgen.frand()) * lo); +} diff --git a/sc4pd/source/FOS.cpp b/sc4pd/source/FOS.cpp new file mode 100644 index 0000000..6bd3c26 --- /dev/null +++ b/sc4pd/source/FOS.cpp @@ -0,0 +1,258 @@ +/* sc4pd + FOS, FOS~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Susie Ibarra & Assif Tsahar: Home Cookin' + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ FOS~ -------------------------------*/ + +class FOS_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(FOS_ar,sc4pd_dsp); + +public: + FOS_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + void m_set_a0(float f) + { + next_a0=f; + } + + void m_set_a1(float f) + { + next_a1=f; + } + + void m_set_b1(float f) + { + next_b1=f; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + +private: + float next_a0, next_a1, next_b1; + float m_y1, m_a0, m_a1, m_b1; + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set_a0); + FLEXT_CALLBACK_F(m_set_a1); + FLEXT_CALLBACK_F(m_set_b1); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("FOS~",FOS_ar); + +FOS_ar::FOS_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"a0",m_set_a0); + FLEXT_ADDMETHOD_(0,"a1",m_set_a1); + FLEXT_ADDMETHOD_(0,"b1",m_set_b1); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count()<3) + { + post("needs at least 3 arguments"); + return; + } + m_a0 = sc_getfloatarg(Args,0); + m_a1 = sc_getfloatarg(Args,1); + m_b1 = sc_getfloatarg(Args,2); + + if(sc_ar(Args)) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + AddInSignal(); + AddInSignal(); + AddInSignal(); + AddInSignal(); + } + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); + + m_y1 = 0.f; + m_a0 = 0.f; + m_a1 = 0.f; + m_b1 = 0.f; +} + +void FOS_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + float *a0 = *(in+1); + float *a1 = *(in+2); + float *b1 = *(in+3); + + float y1 = m_y1; + + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin) + ZXP(b1) * y1; + ZXP(nout) = ZXP(a0) * y0 + ZXP(a1) * y1; + y1 = y0; + } + m_y1 = zapgremlins(y1); +} + + +void FOS_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y1 = m_y1; + float a0 = m_a0; + float a1 = m_a1; + float b1 = m_b1; + float a0_slope = CALCSLOPE(next_a0, a0); + float a1_slope = CALCSLOPE(next_a1, a1); + float b1_slope = CALCSLOPE(next_b1, b1); + + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin) + b1 * y1; + ZXP(nout) = a0 * y0 + a1 * y1; + y1 = y0; + + a0 += a0_slope; + a1 += a1_slope; + b1 += b1_slope; + } +} + +/* ------------------------ FOS ---------------------------------*/ + + +class FOS_kr: + public flext_base +{ + FLEXT_HEADER(FOS_kr,flext_base); + +public: + FOS_kr(int argc, t_atom *argv); + +protected: + void m_perform(float f); + + void m_set_a0(float f) + { + m_a0=f; + } + + void m_set_a1(float f) + { + m_a1=f; + } + + void m_set_b1(float f) + { + m_b1=f; + } + + +private: + float m_y1, m_a0, m_a1, m_b1; + + FLEXT_CALLBACK_F(m_set_a0); + FLEXT_CALLBACK_F(m_set_a1); + FLEXT_CALLBACK_F(m_set_b1); + FLEXT_CALLBACK_F(m_perform); +}; + + +FLEXT_LIB_V("FOS",FOS_kr); + +FOS_kr::FOS_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"a0",m_set_a0); + FLEXT_ADDMETHOD_(0,"a1",m_set_a1); + FLEXT_ADDMETHOD_(0,"b1",m_set_b1); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count()!=3) + { + post("needs 3 arguments"); + return; + } + + m_a0 = sc_getfloatarg(Args,0); + m_a1 = sc_getfloatarg(Args,1); + m_b1 = sc_getfloatarg(Args,2); + + m_y1 = 0.f; + m_a0 = 0.f; + m_a1 = 0.f; + m_b1 = 0.f; +} + +void FOS_kr::m_perform(float f) +{ + m_y1 = m_a0 * (f + m_b1 * m_y1) + m_a1 * m_y1; + ToOutFloat(0,m_y1); +} diff --git a/sc4pd/source/GrayNoise.cpp b/sc4pd/source/GrayNoise.cpp new file mode 100644 index 0000000..b9c3e40 --- /dev/null +++ b/sc4pd/source/GrayNoise.cpp @@ -0,0 +1,143 @@ +/* sc4pd + GrayNoise, GrayNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe: Harsh + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ GrayNoise~ -------------------------------*/ + +class GrayNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(GrayNoise_ar,sc4pd_dsp); + +public: + GrayNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + int m_counter; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("GrayNoise~",GrayNoise_ar); + +GrayNoise_ar::GrayNoise_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutSignal(); +} + + +void GrayNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + int counter = m_counter; + + for (int i = 0; i!= n;++i) + { + counter ^= 1L << (trand(s1,s2,s3) & 31); + (*(nout)++) = counter * 4.65661287308e-10f; + } + + m_counter=counter; + RPUT; +} + + +/* ------------------------ GrayNoise ---------------------------------*/ + +class GrayNoise_kr: + public flext_base +{ + FLEXT_HEADER(GrayNoise_kr,flext_base); + +public: + GrayNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + int m_counter; + RGen rgen; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("GrayNoise",GrayNoise_kr); + +GrayNoise_kr::GrayNoise_kr(int argc, t_atom *argv) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void GrayNoise_kr::m_perform() +{ + m_counter ^= 1L << (rgen.trand() & 31); + m_counter * 4.65661287308e-10f; + ToOutFloat(0,m_counter * 4.65661287308e-10f); +} diff --git a/sc4pd/source/HPF.cpp b/sc4pd/source/HPF.cpp new file mode 100644 index 0000000..85de643 --- /dev/null +++ b/sc4pd/source/HPF.cpp @@ -0,0 +1,180 @@ +/* sc4pd + HPF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Peter Kowald & Tatsuya Nakatani: + 13 Definitions of Truth + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ HPF~ -------------------------------*/ + +class HPF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(HPF_ar,sc4pd_dsp); + +public: + HPF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + +private: + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); +}; + +FLEXT_LIB_DSP_V("HPF~",HPF_ar); + +HPF_ar::HPF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void HPF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed) + { + float pfreq = m_freq * mRadiansPerSample * 0.5; + + float C = tan(pfreq); + float C2 = C * C; + float sqrt2C = C * sqrt2; + float next_a0 = 1.f / (1.f + sqrt2C + C2); + float next_b1 = 2.f * (1.f - C2) * next_a0 ; + float next_b2 = -(1.f - sqrt2C + C2) * next_a0; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - 2.f * y1 + y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - 2.f * y0 + y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - 2.f * y2 + y0); + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - 2.f * y1 + y2); + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - 2.f * y1 + y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - 2.f * y0 + y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - 2.f * y2 + y0); + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - 2.f * y1 + y2); + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate HPF filter */ diff --git a/sc4pd/source/HPZ1.cpp b/sc4pd/source/HPZ1.cpp new file mode 100644 index 0000000..0ab5f91 --- /dev/null +++ b/sc4pd/source/HPZ1.cpp @@ -0,0 +1,132 @@ +/* sc4pd + HPZ1~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ HPZ1~ -------------------------------*/ + +class HPZ1_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(HPZ1_ar,sc4pd_dsp); + +public: + HPZ1_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + float m_x1; +}; + +FLEXT_LIB_DSP_V("HPZ1~",HPZ1_ar); + +HPZ1_ar::HPZ1_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; +} + +void HPZ1_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + + int t = n >> 2; + for (int i = 0; i!= t;++i) + { + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 - x1); + x1 = ZXP(nin); + ZXP(nout) = 0.5f * (x1 - x0); + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 - x1); + x1 = ZXP(nin); + ZXP(nout) = 0.5f * (x1 - x0); + } + + t = n & 3; + for (int i = 0; i!= t;++i) + { + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 - x1); + x1 = x0; + } + m_x1 = x1; +} + +/* ------------------------ HPZ1 -------------------------------*/ + +class HPZ1_kr: + public flext_base +{ + FLEXT_HEADER(HPZ1_kr,flext_base); + +public: + HPZ1_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("HPZ1",HPZ1_kr); + +HPZ1_kr::HPZ1_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x1=0; +} + +void HPZ1_kr::m_perform(float f) +{ + ToOutFloat(0,0.5f * (f - m_x1)); + m_x1=f; +} + diff --git a/sc4pd/source/HPZ2.cpp b/sc4pd/source/HPZ2.cpp new file mode 100644 index 0000000..c561455 --- /dev/null +++ b/sc4pd/source/HPZ2.cpp @@ -0,0 +1,140 @@ +/* sc4pd + HPZ2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ HPZ2~ -------------------------------*/ + +class HPZ2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(HPZ2_ar,sc4pd_dsp); + +public: + HPZ2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mFilterLoops=sc_filterloops(); + mFilterRemain=sc_filterremain(); + } + +private: + float m_x1, m_x2; + int mFilterLoops, mFilterRemain; +}; + +FLEXT_LIB_DSP_V("HPZ2~",HPZ2_ar); + +HPZ2_ar::HPZ2_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; + m_x2=0; +} + +void HPZ2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + float x2 = m_x2; + + for (int i = 0; i!=mFilterLoops ;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 - 2.f * x1 + x2) * 0.25f; + x2 = ZXP(nin); + ZXP(nout) = (x2 - 2.f * x0 + x1) * 0.25f; + x1 = ZXP(nin); + ZXP(nout) = (x1 - 2.f * x2 + x0) * 0.25f; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 - 2.f * x1 + x2) * 0.25f; + x2 = x1; + x1 = x0; + } + m_x1 = x1; + m_x2 = x2; +} + +/* ------------------------ HPZ2 -------------------------------*/ + +class HPZ2_kr: + public flext_base +{ + FLEXT_HEADER(HPZ2_kr,flext_base); + +public: + HPZ2_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + float m_x2; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("HPZ2",HPZ2_kr); + +HPZ2_kr::HPZ2_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x2 = m_x1 = 0; +} + +void HPZ2_kr::m_perform(float f) +{ + ToOutFloat(0,(f - 2.f * m_x1 + m_x2) * 0.25f); + m_x2=m_x1; + m_x1=f; +} + diff --git a/sc4pd/source/Hasher.cpp b/sc4pd/source/Hasher.cpp new file mode 100644 index 0000000..1fc8085 --- /dev/null +++ b/sc4pd/source/Hasher.cpp @@ -0,0 +1,115 @@ +/* sc4pd + Hasher~, Hasher + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Philip Jeck: Stoke + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Hasher~ -----------------------------------*/ + +class Hasher_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Hasher_ar,sc4pd_dsp); + +public: + Hasher_ar(); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); +private: + +}; + +FLEXT_LIB_DSP("Hasher~",Hasher_ar); + +Hasher_ar::Hasher_ar() +{ + AddOutSignal(); +} + +void Hasher_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + int32 *nin = (int32*)*in; + t_sample *nout = *out; + + for (int i = 0; i!= n;++i) + { + union { float f; int i; } u; + int z = (*(nin)++); + u.i = 0x40000000 | ((uint32)Hash(z) >> 9); + (*(nout)++) = u.f -3.f; + } +} + + +/* ------------------------ Hasher ------------------------------------*/ + +class Hasher_kr + :public flext_base +{ + FLEXT_HEADER(Hasher_kr,flext_base); + +public: + Hasher_kr(); + +protected: + void m_perform(float f); + +private: + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB("Hasher",Hasher_kr); + +Hasher_kr::Hasher_kr() +{ + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); +} + +void Hasher_kr::m_perform(float f) +{ + int32 * fi = (int32*) &f; + + union { float f; int i; } u; + int z = *fi; + u.i = 0x40000000 | ((uint32)Hash(z) >> 9); + + ToOutFloat(0,u.f -3.f); +} diff --git a/sc4pd/source/IRand.cpp b/sc4pd/source/IRand.cpp new file mode 100644 index 0000000..8b5c723 --- /dev/null +++ b/sc4pd/source/IRand.cpp @@ -0,0 +1,159 @@ +/* sc4pd + IRand, IRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Assif Tsahar: Open Systems + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ IRand~ -------------------------------*/ + +class IRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(IRand_ar,sc4pd_dsp); + +public: + IRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + int lo; + int hi; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("IRand~",IRand_ar); + +IRand_ar::IRand_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=int(sc_getfloatarg(Args,0)); + hi=int(sc_getfloatarg(Args,1)); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void IRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + int range = hi - lo; + m_sample = float(rgen.irand(range) + lo); +} + + +void IRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + + +/* ------------------------ IRand ---------------------------------*/ + +class IRand_kr: + public flext_base +{ + FLEXT_HEADER(IRand_kr,flext_base); + +public: + IRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + int lo; + int hi; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("IRand",IRand_kr); + +IRand_kr::IRand_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=int(sc_getfloatarg(Args,0)); + hi=int(sc_getfloatarg(Args,1)); + + rgen.init(timeseed()); + + AddOutInt(); +} + +void IRand_kr::m_loadbang() +{ + int range = hi - lo; + + ToOutInt(0,rgen.irand(range) + lo); +} diff --git a/sc4pd/source/Impulse.cpp b/sc4pd/source/Impulse.cpp new file mode 100644 index 0000000..86ca165 --- /dev/null +++ b/sc4pd/source/Impulse.cpp @@ -0,0 +1,264 @@ +/* sc4pd + Impulse, Impulse~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: AMM: AMMMusic 1966 + +*/ + +#include "sc4pd.hpp" + +/* todo: implement phase offset as in sc3 +/* ------------------------ Impulse~ -------------------------------*/ + +class Impulse_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Impulse_ar,sc4pd_dsp); + +public: + Impulse_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_freq=f; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + +private: + double mPhase, mPhaseOffset; + float mFreqMul; + float m_freq; //for kr arguments + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("Impulse~",Impulse_ar); + +Impulse_ar::Impulse_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"freq",m_set); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + if(sc_ar(Args)) + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); +} + +void Impulse_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + mFreqMul = 1 / Samplerate(); + +} + +void Impulse_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *freq = *in; + t_sample *xout = *out; + + float freqmul = mFreqMul; + double phase = mPhase; + + for (int i = 0; i!= n;++i) + { + float z; + if (phase >= 1.f) + { + phase -= 1.f; + z = 1.f; + } + else + { + z = 0.f; + } + phase += (*(freq)++) * freqmul; + (*(xout)++) = z; + } + + mPhase=phase; +} + + +void Impulse_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *xout = *out; + + float freq = m_freq * mFreqMul; + float freqmul = mFreqMul; + double phase = mPhase; + + for (int i = 0; i!= n;++i) + { + float z; + if (phase >= 1.f) + { + phase -= 1.f; + z = 1.f; + } + else + { + z = 0.f; + } + phase += freq; + (*(xout)++) = z; + } + + mPhase=phase; +} + +/* ------------------------ Impulse ---------------------------------*/ + +/* todo: remove obsolete messages */ + +class Impulse_kr: + public flext_base +{ + FLEXT_HEADER(Impulse_kr,flext_base); + +public: + Impulse_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_set(float f) + { + m_freq_set = f; + m_freq = f * mFreqMul; + } + + void m_set_kr(float f) + { + if (f != 0) + { + dt = f * 0.001; + mFreqMul = dt; + m_freq = m_freq_set * mFreqMul; + m_timer.Reset(); + m_timer.Periodic(dt); + } + } + +private: + + double mPhase, mPhaseOffset; + float mFreqMul; + float m_freq; //for kr arguments + + float dt; + float m_freq_set; + + Timer m_timer; + + FLEXT_CALLBACK_F(m_set_kr); + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_T(m_perform); +}; + + +FLEXT_LIB_V("Impulse",Impulse_kr); + +Impulse_kr::Impulse_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_set); + FLEXT_ADDMETHOD_(0,"kr",m_set_kr); + + FLEXT_ADDTIMER(m_timer,m_perform); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + m_freq_set = sc_getfloatarg(Args,0); + + dt = sc_getfloatarg(Args,1) * 0.001; + + if (dt == 0) + dt = 0.02; // 20 ms as default control rate as in line + mFreqMul = dt; + + m_freq = m_freq_set * mFreqMul; + + m_timer.Periodic(dt); + +} + +void Impulse_kr::m_perform(void*) +{ + float z; + if (mPhase >= 1.f) + { + mPhase -= 1.f; + z = 1.f; + } + else + { + z = 0.f; + } + + mPhase += m_freq; + ToOutFloat(0,z); +} diff --git a/sc4pd/source/Integrator.cpp b/sc4pd/source/Integrator.cpp new file mode 100644 index 0000000..85253ee --- /dev/null +++ b/sc4pd/source/Integrator.cpp @@ -0,0 +1,199 @@ +/* sc4pd + Integrator~, Integrator + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: AMM: AMMMusic 1966 + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Integrator~ -----------------------------*/ + +class Integrator_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Integrator_ar,sc4pd_dsp); + +public: + Integrator_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + float m_b1; //leak + float m_y1; //z-1 +}; + +FLEXT_LIB_DSP_V("Integrator~",Integrator_ar); + +Integrator_ar::Integrator_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"leak",m_set); + + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_y1 = 0.f; +} + +void Integrator_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float b1 = m_b1; + float y1 = m_y1; + + if (b1 == m_b1) + { + if (b1 == 1.f) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + y1; + } + + } + else if (b1 == 0.f) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * y1; + } + } + } + else + { + float b1_slope = CALCSLOPE(m_b1, b1); + if (b1 >= 0.f && m_b1 >= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * (y1 - y0); + b1 += b1_slope; + } + } + else if (b1 <= 0.f && m_b1 <= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = y0 + b1 * (y1 + y0); + b1 += b1_slope; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = (*(nin)++); + (*(nout)++) = y1 = (1.f - fabs(b1)) * y0 + b1 * y1; + b1 += b1_slope; + } + } + } + m_y1 = zapgremlins(y1); +} + +void Integrator_ar::m_set(float f) +{ + m_b1=f; +} + +/* ------------------------ Integrator ------------------------------*/ + +class Integrator_kr + :public flext_base +{ + FLEXT_HEADER(Integrator_kr,flext_base); + +public: + Integrator_kr(int argc,t_atom * argv); + +protected: + void m_set(float f); + void m_perform(float f); + +private: + float m_b1; //leak + float m_y1; //z-1 + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("Integrator",Integrator_kr); + +Integrator_kr::Integrator_kr(int argc,t_atom * argv) +{ + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + m_y1 = 0.f; + + + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"leak",m_set); +} + +void Integrator_kr::m_perform(float f) +{ + m_y1 = f + m_y1 * m_b1; + ToOutFloat(0,m_y1); +} + +void Integrator_kr::m_set(float f) +{ + m_b1=f; +} diff --git a/sc4pd/source/LFClipNoise.cpp b/sc4pd/source/LFClipNoise.cpp new file mode 100644 index 0000000..1583431 --- /dev/null +++ b/sc4pd/source/LFClipNoise.cpp @@ -0,0 +1,195 @@ +/* sc4pd + LFClipNoise, LFClipNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Elliott Sharp: Revenge Of The Stuttering Child + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFClipNoise~ -------------------------------*/ + +class LFClipNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFClipNoise_ar,sc4pd_dsp); + +public: + LFClipNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_level; + int m_counter; + int m_sr; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFClipNoise~",LFClipNoise_ar); + +LFClipNoise_ar::LFClipNoise_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + m_counter=0; + m_level=0; + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void LFClipNoise_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_sr = Samplerate(); +} + + +void LFClipNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float level = m_level; + int32 counter = m_counter; + + RGET; + + int remain = n; + do + { + if (counter<=0) + { + counter = (int)(m_sr / sc_max(m_freq, .001f)); + counter = sc_max(1, counter); + level = fcoin(s1,s2,s3); + } + int nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + (*(nout)++)=level; + } + } + while(remain); + + m_level = level; + m_counter = counter; + + RPUT; +} + + +/* ------------------------ LFClipNoise ---------------------------------*/ + +class LFClipNoise_kr: + public flext_base +{ + FLEXT_HEADER(LFClipNoise_kr,flext_base); + +public: + LFClipNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + double dt = sc_max(1/f, .001f); + m_timer.Reset(); + m_timer.Periodic(dt); + } + +private: + RGen rgen; + Timer m_timer; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_T(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("LFClipNoise",LFClipNoise_kr); + +LFClipNoise_kr::LFClipNoise_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDTIMER(m_timer,m_perform); + + //parse arguments + AtomList Args(argc,argv); + + double dt = sc_max(1/sc_getfloatarg(Args,0), .001f); + + rgen.init(timeseed()); + + m_timer.Periodic(dt); + + AddOutFloat(); +} + +void LFClipNoise_kr::m_perform(void*) +{ + ToOutFloat(0,rgen.fcoin()); +} diff --git a/sc4pd/source/LFDNoise0.cpp b/sc4pd/source/LFDNoise0.cpp new file mode 100644 index 0000000..316b5a4 --- /dev/null +++ b/sc4pd/source/LFDNoise0.cpp @@ -0,0 +1,166 @@ +/* sc4pd + LFDNoise0~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + * + * DynNoiseUGens.cpp + * xSC3plugins + * + * Created by Alberto de Campo, Sekhar Ramacrishnan, Julian Rohrhuber on Sun May 30 2004. + * Copyright (c) 2004 HfbK. All rights reserved. + * + * + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways Past + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFDNoise0~ -------------------------------*/ + +class LFDNoise0_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFDNoise0_ar,sc4pd_dsp); + +public: + LFDNoise0_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_level; + float m_phase; + float m_smpdur; + + bool m_ar; + + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFDNoise0~",LFDNoise0_ar); + +LFDNoise0_ar::LFDNoise0_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + m_phase=0.f; + m_level=0.f; + + rgen.init(timeseed()); + + m_ar = sc_ar(Args); + + if (m_ar) + AddInSignal("freqency"); + else + AddInSignal("\"set\" frequency"); + AddOutSignal(); +} + +void LFDNoise0_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_smpdur = sc_sampledur(); +} + + +void LFDNoise0_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float level = m_level; + float phase = m_phase; + + RGET; + + if (m_ar) + { + t_sample *nin = *in; + float smpdur = m_smpdur; + for (int i = 0; i!= n; ++i) + { + phase -= ZXP(nin) * smpdur; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + level = frand2(s1,s2,s3); + } + ZXP(nout) = level; + } + } + else + { + float dphase = m_smpdur * m_freq; + for (int i = 0; i!= n; ++i) + { + phase -= dphase; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + level = frand2(s1,s2,s3); + } + ZXP(nout) = level; + } + } + + + m_level = level; + m_phase = phase; + + RPUT; +} + + diff --git a/sc4pd/source/LFDNoise1.cpp b/sc4pd/source/LFDNoise1.cpp new file mode 100644 index 0000000..8336b80 --- /dev/null +++ b/sc4pd/source/LFDNoise1.cpp @@ -0,0 +1,172 @@ +/* sc4pd + LFDNoise1~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + * + * DynNoiseUGens.cpp + * xSC3plugins + * + * Created by Alberto de Campo, Sekhar Ramacrishnan, Julian Rohrhuber on Sun May 30 2004. + * Copyright (c) 2004 HfbK. All rights reserved. + * + * + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways Past + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFDNoise1~ -------------------------------*/ + +class LFDNoise1_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFDNoise1_ar,sc4pd_dsp); + +public: + LFDNoise1_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_prevlevel; + float m_nextlevel; + float m_phase; + float m_smpdur; + + bool m_ar; + + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFDNoise1~",LFDNoise1_ar); + +LFDNoise1_ar::LFDNoise1_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + m_phase=0.f; + m_prevlevel=0.f; + m_nextlevel = rgen.frand2(); + + + m_ar = sc_ar(Args); + + if (m_ar) + AddInSignal("freqency"); + else + AddInSignal("\"set\" frequency"); + AddOutSignal(); +} + +void LFDNoise1_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_smpdur = sc_sampledur(); +} + + +void LFDNoise1_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float prevLevel = m_prevlevel; + float nextLevel = m_nextlevel; + float phase = m_phase; + + RGET; + + if (m_ar) + { + t_sample *nin = *in; + float smpdur = m_smpdur; + for (int i = 0; i!= n; ++i) + { + phase -= ZXP(nin) * smpdur; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + prevLevel = nextLevel; + nextLevel = frand2(s1,s2,s3); + } + ZXP(nout) = nextLevel + ( phase * (prevLevel - nextLevel) ); + } + } + else + { + float dphase = m_smpdur * m_freq; + for (int i = 0; i!= n; ++i) + { + phase -= dphase; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + prevLevel = nextLevel; + nextLevel = frand2(s1,s2,s3); + } + ZXP(nout) = nextLevel + ( phase * (prevLevel - nextLevel) ); + } + } + + m_prevlevel = prevLevel; + m_nextlevel = nextLevel; + m_phase = phase; + + RPUT; +} + + diff --git a/sc4pd/source/LFDNoise2.cpp b/sc4pd/source/LFDNoise2.cpp new file mode 100644 index 0000000..136b1c9 --- /dev/null +++ b/sc4pd/source/LFDNoise2.cpp @@ -0,0 +1,188 @@ +/* sc4pd + LFDNoise2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + * + * DynNoiseUGens.cpp + * xSC3plugins + * + * Created by Alberto de Campo, Sekhar Ramacrishnan, Julian Rohrhuber on Sun May 30 2004. + * Copyright (c) 2004 HfbK. All rights reserved. + * + * + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways Past + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFDNoise2~ -------------------------------*/ + +class LFDNoise2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFDNoise2_ar,sc4pd_dsp); + +public: + LFDNoise2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_levela, m_levelb, m_levelc, m_leveld; + float m_phase; + float m_smpdur; + + bool m_ar; + + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFDNoise2~",LFDNoise2_ar); + +LFDNoise2_ar::LFDNoise2_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + RGET; + + m_phase=0.f; + m_levela = frand2(s1, s2, s3) * 0.8f;// limits max interpol. overshoot to 1. + m_levelb = frand2(s1, s2, s3) * 0.8f; + m_levelc = frand2(s1, s2, s3) * 0.8f; + m_leveld = frand2(s1, s2, s3) * 0.8f; + + RPUT; + + m_ar = sc_ar(Args); + + if (m_ar) + AddInSignal("freqency"); + else + AddInSignal("\"set\" frequency"); + AddOutSignal(); +} + +void LFDNoise2_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_smpdur = sc_sampledur(); +} + + +void LFDNoise2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float a = m_levela; + float b = m_levelb; + float c = m_levelc; + float d = m_leveld; + + float phase = m_phase; + + RGET; + + if (m_ar) + { + t_sample *nin = *in; + float smpdur = m_smpdur; + for (int i = 0; i!= n; ++i) + { + phase -= ZXP(nin) * smpdur; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + a = b; + b = c; + c = d; + d = frand2(s1,s2,s3) * 0.8f; // limits max interpol. overshoot to 1. + + } + ZXP(nout) = cubicinterp(1.f - phase, a, b, c, d); + } + } + else + { + float dphase = m_smpdur * m_freq; + for (int i = 0; i!= n; ++i) + { + phase -= dphase; + if (phase <= 0) + { + phase = sc_wrap(phase, 0.f, 1.f); + a = b; + b = c; + c = d; + d = frand2(s1,s2,s3) * 0.8f; // limits max interpol. overshoot to 1. + } + ZXP(nout) = cubicinterp(1.f - phase, a, b, c, d); + } + } + + + m_phase = phase; + + m_levela = a; + m_levelb = b; + m_levelc = c; + m_leveld = d; + + RPUT; +} + + diff --git a/sc4pd/source/LFNoise0.cpp b/sc4pd/source/LFNoise0.cpp new file mode 100644 index 0000000..9ee9ff6 --- /dev/null +++ b/sc4pd/source/LFNoise0.cpp @@ -0,0 +1,195 @@ +/* sc4pd + LFNoise0, LFNoise0~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Elliott Sharp: Revenge Of The Stuttering Child + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFNoise0~ -------------------------------*/ + +class LFNoise0_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFNoise0_ar,sc4pd_dsp); + +public: + LFNoise0_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_level; + int m_counter; + int m_sr; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFNoise0~",LFNoise0_ar); + +LFNoise0_ar::LFNoise0_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + m_counter=0; + m_level=0; + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void LFNoise0_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_sr = Samplerate(); +} + + +void LFNoise0_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float level = m_level; + int32 counter = m_counter; + + RGET; + + int remain = n; + do + { + if (counter<=0) + { + counter = (int)(m_sr / sc_max(m_freq, .001f)); + counter = sc_max(1, counter); + level = frand2(s1,s2,s3); + } + int nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + (*(nout)++)=level; + } + } + while(remain); + + m_level = level; + m_counter = counter; + + RPUT; +} + + +/* ------------------------ LFNoise0 ---------------------------------*/ + +class LFNoise0_kr: + public flext_base +{ + FLEXT_HEADER(LFNoise0_kr,flext_base); + +public: + LFNoise0_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + double dt = sc_max(1/f, .001f); + m_timer.Reset(); + m_timer.Periodic(dt); + } + +private: + RGen rgen; + Timer m_timer; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_T(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("LFNoise0",LFNoise0_kr); + +LFNoise0_kr::LFNoise0_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDTIMER(m_timer,m_perform); + + //parse arguments + AtomList Args(argc,argv); + + double dt = sc_max(1/sc_getfloatarg(Args,0), .001f); + + rgen.init(timeseed()); + + m_timer.Periodic(dt); + + AddOutFloat(); +} + +void LFNoise0_kr::m_perform(void*) +{ + ToOutFloat(0,rgen.frand2()); +} diff --git a/sc4pd/source/LFNoise1.cpp b/sc4pd/source/LFNoise1.cpp new file mode 100644 index 0000000..c164942 --- /dev/null +++ b/sc4pd/source/LFNoise1.cpp @@ -0,0 +1,232 @@ +/* sc4pd + LFNoise1, LFNoise1~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Fred Frith: Gravity + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFNoise1~ -------------------------------*/ + +class LFNoise1_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFNoise1_ar,sc4pd_dsp); + +public: + LFNoise1_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_level; + float m_slope; + int m_counter; + int m_sr; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFNoise1~",LFNoise1_ar); + +LFNoise1_ar::LFNoise1_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + m_counter=0; + m_level=rgen.frand2(); + m_slope=0; + + AddOutSignal(); +} + +void LFNoise1_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_sr = Samplerate(); +} + + +void LFNoise1_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float level = m_level; + int32 counter = m_counter; + float slope = m_slope; + + RGET; + + int remain = n; + do + { + if (counter<=0) + { + counter = (int)(m_sr / sc_max(m_freq, .001f)); + counter = sc_max(1, counter); + float nextlevel = frand2(s1,s2,s3); + slope = (nextlevel - level) / counter; + } + int nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + (*(nout)++)=level; + level+=slope; + } + } + while(remain); + + m_level = level; + m_counter = counter; + m_slope = slope; + + RPUT; +} + + +/* ------------------------ LFNoise1 ---------------------------------*/ + +class LFNoise1_kr: + public flext_base +{ + FLEXT_HEADER(LFNoise1_kr,flext_base); + +public: + LFNoise1_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float); + +private: + RGen rgen; + float m_level; + float m_slope; + + float dt; //in s + float tick; //in s + int counter; + + Timer m_timer; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_T(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("LFNoise1",LFNoise1_kr); + +LFNoise1_kr::LFNoise1_kr(int argc, t_atom *argv) + : tick(0.01) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDTIMER(m_timer,m_perform); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + m_level=rgen.frand2(); + + AddOutFloat(); + + m_set(sc_getfloatarg(Args,0)); +} + +void LFNoise1_kr::m_set(float f) +{ + dt = sc_max(1/f, .001f); + counter = (dt/tick); + + float nextlevel = rgen.frand2(); + m_slope = (nextlevel - m_level) / counter; + + m_timer.Reset(); + m_timer.Delay(tick); +} + +void LFNoise1_kr::m_perform(void*) +{ + m_level+=m_slope; + ToOutFloat(0,m_level); + if (--counter) + { + m_timer.Reset(); + m_timer.Delay(tick); + } + else + { + counter = (dt/tick); + float nextlevel = rgen.frand2(); + m_slope = (nextlevel - m_level) / counter; + + m_timer.Reset(); + m_timer.Delay(tick); + + } +} diff --git a/sc4pd/source/LFNoise2.cpp b/sc4pd/source/LFNoise2.cpp new file mode 100644 index 0000000..3b1fd37 --- /dev/null +++ b/sc4pd/source/LFNoise2.cpp @@ -0,0 +1,271 @@ +/* sc4pd + LFNoise2, LFNoise2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Guenther Mueller & Toshimaru Nakamura: Tint + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFNoise2~ -------------------------------*/ + +class LFNoise2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFNoise2_ar,sc4pd_dsp); + +public: + LFNoise2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float f) + { + m_freq = f; + } + +private: + RGen rgen; + float m_freq; + float m_level; + float m_slope; + float m_curve; + int m_counter; + int m_sr; + float m_nextvalue; + float m_nextmidpt; + + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("LFNoise2~",LFNoise2_ar); + +LFNoise2_ar::LFNoise2_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + rgen.init(timeseed()); + + m_counter=0; + m_level=rgen.frand2(); + m_slope=0; + m_curve=0; + m_nextvalue=0; + m_nextmidpt=0; + + AddOutSignal(); +} + +void LFNoise2_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_sr = Samplerate(); +} + + +void LFNoise2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float level = m_level; + int32 counter = m_counter; + float slope = m_slope; + float curve = m_curve; + + RGET; + + int remain = n; + do + { + if (counter<=0) + { + float value = m_nextvalue; + m_nextvalue = frand2(s1,s2,s3); + level = m_nextmidpt; + m_nextmidpt = (m_nextvalue + value) * .5; + + counter = (int32)(m_sr / sc_max(m_freq, .001f)); + counter = sc_max(2, counter); + float fseglen = (float)counter; + curve = 2.f * (m_nextmidpt - level - fseglen * slope) + / (fseglen * fseglen + fseglen); + } + int nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + (*(nout)++)=level; + slope+=curve; + level+=slope; + } + } + while(remain); + + m_level = level; + m_counter = counter; + m_slope = slope; + m_curve = curve; + + RPUT; +} + + +/* ------------------------ LFNoise2 ---------------------------------*/ + +class LFNoise2_kr: + public flext_base +{ + FLEXT_HEADER(LFNoise2_kr,flext_base); + +public: + LFNoise2_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_seed(int i) + { + rgen.init(i); + } + + void m_set(float); + +private: + RGen rgen; + float m_level; + float m_slope; + float m_curve; + float m_nextvalue; + float m_nextmidpt; + + float dt; //in s + float tick; //in s + int counter; + + Timer m_timer; + FLEXT_CALLBACK_I(m_seed); + FLEXT_CALLBACK_T(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("LFNoise2",LFNoise2_kr); + +LFNoise2_kr::LFNoise2_kr(int argc, t_atom *argv) + : tick(0.01) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDTIMER(m_timer,m_perform); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + m_level=rgen.frand2(); + + AddOutFloat(); + + m_set(sc_getfloatarg(Args,0)); +} + + +void LFNoise2_kr::m_set(float f) +{ + dt = sc_max(1/f, .001f); + counter = (dt/tick); + counter = sc_max(2, counter); + + float value = m_nextvalue; + m_nextvalue = rgen.frand2(); + m_level = m_nextmidpt; + m_nextmidpt = (m_nextvalue + value) * .5; + + float fseglen = (float)counter; + m_curve = 2.f * (m_nextmidpt - m_level - fseglen * m_slope) + / (fseglen * fseglen + fseglen); + + + m_timer.Reset(); + m_timer.Delay(tick); +} + +void LFNoise2_kr::m_perform(void*) +{ + m_slope+=m_curve; + m_level+=m_slope; + ToOutFloat(0,m_level); + if (--counter) + { + m_timer.Reset(); + m_timer.Delay(tick); + } + else + { + counter = (dt/tick); + + counter = sc_max(2, counter); + + float value = m_nextvalue; + m_nextvalue = rgen.frand2(); + m_level = m_nextmidpt; + m_nextmidpt = (m_nextvalue + value) * .5; + + float fseglen = (float)counter; + m_curve = 2.f * (m_nextmidpt - m_level - fseglen * m_slope) / + (fseglen * fseglen + fseglen); + + m_timer.Reset(); + m_timer.Delay(tick); + + } +} + diff --git a/sc4pd/source/LFPulse.cpp b/sc4pd/source/LFPulse.cpp new file mode 100644 index 0000000..ad16e65 --- /dev/null +++ b/sc4pd/source/LFPulse.cpp @@ -0,0 +1,292 @@ +/* sc4pd + LFPulse, LFPulse~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Oren Ambarchi: Flypaper + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFPulse~ -------------------------------*/ + +class LFPulse_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFPulse_ar,sc4pd_dsp); + +public: + LFPulse_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_freq=f; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + + void m_width (float f) + { + nextDuty = f; + } + + +private: + double mPhase; + float mFreqMul; + float m_freq; //for kr arguments + float mDuty; + float nextDuty; + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_width); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("LFPulse~",LFPulse_ar); + +LFPulse_ar::LFPulse_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"freq",m_set); + FLEXT_ADDMETHOD_(0,"width",m_width); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + nextDuty = sc_getfloatarg(Args,1); + + if(sc_ar(Args)) + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); +} + +void LFPulse_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + mFreqMul = 1 / Samplerate(); + +} + +void LFPulse_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *freq = *in; + t_sample *xout = *out; + + float freqmul = mFreqMul; + double phase = mPhase; + float duty = mDuty; + + for (int i = 0; i!= n;++i) + { + float z; + if (phase >= 1.f) + { + phase -= 1.f; + duty = mDuty = nextDuty; + // output at least one sample from the opposite polarity + z = duty < 0.5 ? 1.f : 0.f; + } + else + { + z = phase < duty ? 1.f : 0.f; + } + + phase += (*(freq)++) * freqmul; + (*(xout)++) = z; + } + + mPhase=phase; +} + + +void LFPulse_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *xout = *out; + + double phase = mPhase; + float duty = mDuty; + float freq = m_freq * mFreqMul; + + for (int i = 0; i!= n;++i) + { + float z; + if (phase >= 1.f) + { + phase -= 1.f; + duty = mDuty = nextDuty; + // output at least one sample from the opposite polarity + z = duty < 0.5 ? 1.f : 0.f; + } + else + { + z = phase < duty ? 1.f : 0.f; + } + + phase += freq; + (*(xout)++) = z; + } + mPhase=phase; +} + +/* ------------------------ LFPulse ---------------------------------*/ + +/* todo: remove obsolete messages */ + +class LFPulse_kr: + public flext_base +{ + FLEXT_HEADER(LFPulse_kr,flext_base); + +public: + LFPulse_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_set(float f) + { + m_freq_set = f; + m_freq = f * mFreqMul; + } + + void m_set_kr(float f) + { + if (f != 0) + { + dt = f * 0.001; + mFreqMul = dt; + m_freq = m_freq_set * mFreqMul; + m_timer.Reset(); + m_timer.Periodic(dt); + } + } + + void m_set_width(float f) + { + nextDuty=f; + } + +private: + double mPhase; + float mFreqMul; + float mDuty; + float nextDuty; + float m_freq; + float dt; + float m_freq_set; + + Timer m_timer; + + FLEXT_CALLBACK_F(m_set_kr); + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_set_width); + FLEXT_CALLBACK_T(m_perform); +}; + + +FLEXT_LIB_V("LFPulse",LFPulse_kr); + +LFPulse_kr::LFPulse_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_set); + FLEXT_ADDMETHOD_(0,"kr",m_set_kr); + FLEXT_ADDMETHOD_(0,"width",m_set_width); + + FLEXT_ADDTIMER(m_timer,m_perform); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + m_freq_set = sc_getfloatarg(Args,0); + + nextDuty = sc_getfloatarg(Args,1); + + dt = sc_getfloatarg(Args,2) * 0.001; + + if (dt == 0) + dt = 0.02; // 20 ms as default control rate as in line + mFreqMul = dt; + + m_freq = m_freq_set * mFreqMul; + + m_timer.Periodic(dt); + +} + +void LFPulse_kr::m_perform(void*) +{ + float z; + if (mPhase >= 1.f) + { + mPhase -= 1.f; + mDuty = nextDuty; + // output at least one sample from the opposite polarity + z = mDuty < 0.5 ? 1.f : 0.f; + } + else + { + z = mPhase < mDuty ? 1.f : 0.f; + } + mPhase += m_freq; + ToOutFloat(0,z); +} diff --git a/sc4pd/source/LFSaw.cpp b/sc4pd/source/LFSaw.cpp new file mode 100644 index 0000000..0e406d0 --- /dev/null +++ b/sc4pd/source/LFSaw.cpp @@ -0,0 +1,256 @@ +/* sc4pd + LFSaw, LFSaw~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Oren Ambarchi: Flypaper + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LFSaw~ -------------------------------*/ + +class LFSaw_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LFSaw_ar,sc4pd_dsp); + +public: + LFSaw_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_freq=f; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + +private: + double mPhase; + float mFreqMul; + float m_freq; //for kr arguments + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("LFSaw~",LFSaw_ar); + +LFSaw_ar::LFSaw_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"freq",m_set); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + + if(sc_ar(Args)) + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); +} + +void LFSaw_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + mFreqMul = 2 / Samplerate(); +} + +void LFSaw_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *freq = *in; + t_sample *xout = *out; + + float freqmul = mFreqMul; + double phase = mPhase; + + for (int i = 0; i!= n;++i) + { + float z = phase; // out must be written last for in place operation + phase += (*(freq)++) * freqmul; + if (phase >= 1.f) + phase -= 2.f; + else + if (phase <= -1.f) + phase += 2.f; + (*(xout)++) = z; + } + + mPhase=phase; +} + + +void LFSaw_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *xout = *out; + + float freq = m_freq * mFreqMul; + double phase = mPhase; + + if (freq >= 0.f) + { + for (int i = 0; i!= n;++i) + { + (*(xout)++) = phase; + phase += freq; + if (phase >= 1.f) phase -= 2.f; + } + } + else + { + for (int i = 0; i!= n;++i) + { + (*(xout)++) = phase; + phase += freq; + if (phase <= -1.f) phase += 2.f; + } + } + + mPhase=phase; +} + +/* ------------------------ LFSaw ---------------------------------*/ + +class LFSaw_kr: + public flext_base +{ + FLEXT_HEADER(LFSaw_kr,flext_base); + +public: + LFSaw_kr(int argc, t_atom *argv); + +protected: + void m_perform(void*); + + void m_set(float f) + { + m_freq_set = f; + m_freq = f * mFreqMul; + } + + void m_set_kr(float f) + { + if (f != 0) + { + dt = f * 0.001; + mFreqMul = 2*dt; + m_freq = m_freq_set * mFreqMul; + m_timer.Reset(); + m_timer.Periodic(dt); + } + } + +private: + double mPhase; + float mFreqMul; + float m_freq; + float dt; + float m_freq_set; + + Timer m_timer; + + FLEXT_CALLBACK_F(m_set_kr); + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_T(m_perform); +}; + + +FLEXT_LIB_V("LFSaw",LFSaw_kr); + +LFSaw_kr::LFSaw_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_set); + FLEXT_ADDMETHOD_(0,"kr",m_set_kr); + // FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDTIMER(m_timer,m_perform); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + m_freq_set = sc_getfloatarg(Args,0); + + dt = sc_getfloatarg(Args,1) * 0.001; + + if (dt == 0 ) + dt = 0.02; // 20 ms as default control rate as in line + mFreqMul = 2 * dt; /* test this !!! */ + + m_freq = m_freq_set * mFreqMul; + + m_timer.Periodic(dt); + +} + +void LFSaw_kr::m_perform(void*) +{ + if (m_freq >= 0.f) + { + ToOutFloat(0,mPhase); + mPhase += m_freq; + if (mPhase >= 1.f) mPhase -= 2.f; + } + else + { + ToOutFloat(0,mPhase); + mPhase += m_freq; + if (mPhase <= -1.f) mPhase += 2.f; + } +} diff --git a/sc4pd/source/LPF.cpp b/sc4pd/source/LPF.cpp new file mode 100644 index 0000000..a11e784 --- /dev/null +++ b/sc4pd/source/LPF.cpp @@ -0,0 +1,180 @@ +/* sc4pd + LPF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Peter Kowald & Tatsuya Nakatani: + 13 Definitions of Truth + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ LPF~ -------------------------------*/ + +class LPF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LPF_ar,sc4pd_dsp); + +public: + LPF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + +private: + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); +}; + +FLEXT_LIB_DSP_V("LPF~",LPF_ar); + +LPF_ar::LPF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void LPF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed) + { + float pfreq = m_freq * mRadiansPerSample * 0.5; + + float C = 1.f / tan(pfreq); + float C2 = C * C; + float sqrt2C = C * sqrt2; + float next_a0 = 1.f / (1.f + sqrt2C + C2); + float next_b1 = -2.f * (1.f - C2) * next_a0 ; + float next_b2 = -(1.f - sqrt2C + C2) * next_a0; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 + 2.f * y1 + y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 + 2.f * y0 + y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 + 2.f * y2 + y0); + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 + 2.f * y1 + y2); + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 + 2.f * y1 + y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 + 2.f * y0 + y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 + 2.f * y2 + y0); + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 + 2.f * y1 + y2); + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate LPF filter */ diff --git a/sc4pd/source/LPZ1.cpp b/sc4pd/source/LPZ1.cpp new file mode 100644 index 0000000..70e495b --- /dev/null +++ b/sc4pd/source/LPZ1.cpp @@ -0,0 +1,132 @@ +/* sc4pd + LPZ1~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ LPZ1~ -------------------------------*/ + +class LPZ1_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LPZ1_ar,sc4pd_dsp); + +public: + LPZ1_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + float m_x1; +}; + +FLEXT_LIB_DSP_V("LPZ1~",LPZ1_ar); + +LPZ1_ar::LPZ1_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; +} + +void LPZ1_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + + int t = n >> 2; + for (int i = 0; i!= t;++i) + { + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 + x1); + x1 = ZXP(nin); + ZXP(nout) = 0.5f * (x1 + x0); + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 + x1); + x1 = ZXP(nin); + ZXP(nout) = 0.5f * (x1 + x0); + } + + t = n & 3; + for (int i = 0; i!= t;++i) + { + x0 = ZXP(nin); + ZXP(nout) = 0.5f * (x0 + x1); + x1 = x0; + } + m_x1 = x1; +} + +/* ------------------------ LPZ1 -------------------------------*/ + +class LPZ1_kr: + public flext_base +{ + FLEXT_HEADER(LPZ1_kr,flext_base); + +public: + LPZ1_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("LPZ1",LPZ1_kr); + +LPZ1_kr::LPZ1_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x1=0; +} + +void LPZ1_kr::m_perform(float f) +{ + ToOutFloat(0,0.5f * (f + m_x1)); + m_x1=f; +} + diff --git a/sc4pd/source/LPZ2.cpp b/sc4pd/source/LPZ2.cpp new file mode 100644 index 0000000..4165690 --- /dev/null +++ b/sc4pd/source/LPZ2.cpp @@ -0,0 +1,140 @@ +/* sc4pd + LPZ2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: William Parker: Compassion Seizes Bed-Stuy + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ LPZ2~ -------------------------------*/ + +class LPZ2_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LPZ2_ar,sc4pd_dsp); + +public: + LPZ2_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mFilterLoops=sc_filterloops(); + mFilterRemain=sc_filterremain(); + } + +private: + float m_x1, m_x2; + int mFilterLoops, mFilterRemain; +}; + +FLEXT_LIB_DSP_V("LPZ2~",LPZ2_ar); + +LPZ2_ar::LPZ2_ar(int argc, t_atom *argv) +{ + AddOutSignal(); + + m_x1=0; + m_x2=0; +} + +void LPZ2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + float x2 = m_x2; + + for (int i = 0; i!=mFilterLoops ;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 + 2.f * x1 + x2) * 0.25f; + x2 = ZXP(nin); + ZXP(nout) = (x2 + 2.f * x0 + x1) * 0.25f; + x1 = ZXP(nin); + ZXP(nout) = (x1 + 2.f * x2 + x0) * 0.25f; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = (x0 + 2.f * x1 + x2) * 0.25f; + x2 = x1; + x1 = x0; + } + m_x1 = x1; + m_x2 = x2; +} + +/* ------------------------ LPZ2 -------------------------------*/ + +class LPZ2_kr: + public flext_base +{ + FLEXT_HEADER(LPZ2_kr,flext_base); + +public: + LPZ2_kr(int argc, t_atom *argv); + +protected: + void m_perform (float f); + +private: + float m_x1; + float m_x2; + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("LPZ2",LPZ2_kr); + +LPZ2_kr::LPZ2_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + + AddOutFloat(); + + m_x2 = m_x1 = 0; +} + +void LPZ2_kr::m_perform(float f) +{ + ToOutFloat(0,(f + 2.f * m_x1 + m_x2) * 0.25f); + m_x2=m_x1; + m_x1=f; +} + diff --git a/sc4pd/source/Lag.cpp b/sc4pd/source/Lag.cpp new file mode 100644 index 0000000..5daf6d1 --- /dev/null +++ b/sc4pd/source/Lag.cpp @@ -0,0 +1,124 @@ +/* sc4pd + Lag~, Lag + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: VA: Live from the Vision Festival + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Lag~ -----------------------------*/ + +class Lag_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Lag_ar,sc4pd_dsp); + +public: + Lag_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + float m_b1, n_b1; + float m_y1; + float m_lag; + bool changed; +}; + +FLEXT_LIB_DSP_V("Lag~",Lag_ar); + +Lag_ar::Lag_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"lagTime",m_set); + + AtomList Args(argc,argv); + + m_lag = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_y1 = 0.f; +} + +void Lag_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + changed = false; + m_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); +} + +void Lag_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float y1 = m_y1; + float b1 = m_b1; + + if (changed) + { + float b1_slope = CALCSLOPE(m_b1, n_b1); + m_b1 = n_b1; + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 - y0); + b1 += b1_slope; + } + changed = false; + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 - y0); + } + } + m_y1 = zapgremlins(y1); +} + +void Lag_ar::m_set(float f) +{ + m_lag = f; + n_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); + changed = true; +} + +/* todo: does a control rate Lag make sense? */ diff --git a/sc4pd/source/Lag2.cpp b/sc4pd/source/Lag2.cpp new file mode 100644 index 0000000..dc85fcb --- /dev/null +++ b/sc4pd/source/Lag2.cpp @@ -0,0 +1,132 @@ +/* sc4pd + Lag2~, Lag2 + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: DKV Trio: Baraka + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Lag2~ -----------------------------*/ + +class Lag2_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Lag2_ar,sc4pd_dsp); + +public: + Lag2_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + float m_b1, n_b1; + float m_y1a, m_y1b; + float m_lag; + bool changed; +}; + +FLEXT_LIB_DSP_V("Lag2~",Lag2_ar); + +Lag2_ar::Lag2_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"lagTime",m_set); + + AtomList Args(argc,argv); + + m_lag = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_b1 = 0.f; + m_y1a = 0.f; + m_y1b = 0.f; +} + +void Lag2_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + changed = false; + m_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); +} + +void Lag2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float y1a = m_y1a; + float y1b = m_y1b; + float b1 = m_b1; + + if (changed) + { + float b1_slope = CALCSLOPE(m_b1, n_b1); + m_b1 = n_b1; + for (int i = 0; i!= n;++i) + { + float y0a = ZXP(nin); + y1a = y0a + b1 * (y1a - y0a); + y1b = y1a + b1 * (y1b - y1a); + ZXP(nout) = y1b; + b1 += b1_slope; + } + changed = false; + } + else + { + for (int i = 0; i!= n;++i) + { + float y0a = ZXP(nin); + y1a = y0a + b1 * (y1a - y0a); + y1b = y1a + b1 * (y1b - y1a); + ZXP(nout) = y1b; + } + } + m_y1a = zapgremlins(y1a); + m_y1b = zapgremlins(y1b); +} + +void Lag2_ar::m_set(float f) +{ + m_lag = f; + n_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); + changed = true; +} + +/* todo: does a control rate Lag2 make sense? */ diff --git a/sc4pd/source/Lag3.cpp b/sc4pd/source/Lag3.cpp new file mode 100644 index 0000000..8865555 --- /dev/null +++ b/sc4pd/source/Lag3.cpp @@ -0,0 +1,137 @@ +/* sc4pd + Lag3~, Lag3 + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: DKV Trio: Baraka + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Lag3~ -----------------------------*/ + +class Lag3_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Lag3_ar,sc4pd_dsp); + +public: + Lag3_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + float m_b1, n_b1; + float m_y1a, m_y1b,m_y1c; + float m_lag; + bool changed; +}; + +FLEXT_LIB_DSP_V("Lag3~",Lag3_ar); + +Lag3_ar::Lag3_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"lagTime",m_set); + + AtomList Args(argc,argv); + + m_lag = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_b1 = 0.f; + m_y1a = 0.f; + m_y1b = 0.f; + m_y1c = 0.f; +} + +void Lag3_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + changed = false; + m_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); +} + +void Lag3_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float y1a = m_y1a; + float y1b = m_y1b; + float y1c = m_y1c; + float b1 = m_b1; + + if (changed) + { + float b1_slope = CALCSLOPE(m_b1, n_b1); + m_b1 = n_b1; + for (int i = 0; i!= n;++i) + { + float y0a = ZXP(nin); + y1a = y0a + b1 * (y1a - y0a); + y1b = y1a + b1 * (y1b - y1a); + y1c = y1b + b1 * (y1c - y1b); + ZXP(nout) = y1c; + b1 += b1_slope; + } + changed = false; + } + else + { + for (int i = 0; i!= n;++i) + { + float y0a = ZXP(nin); + y1a = y0a + b1 * (y1a - y0a); + y1b = y1a + b1 * (y1b - y1a); + y1c = y1b + b1 * (y1c - y1b); + ZXP(nout) = y1c; + } + } + m_y1a = zapgremlins(y1a); + m_y1b = zapgremlins(y1b); + m_y1b = zapgremlins(y1c); +} + +void Lag3_ar::m_set(float f) +{ + m_lag = f; + n_b1 = m_lag == 0.f ? 0.f : exp(log001 / (m_lag * Samplerate())); + changed = true; +} + +/* todo: does a control rate Lag3 make sense? */ diff --git a/sc4pd/source/Latoocarfian.cpp b/sc4pd/source/Latoocarfian.cpp new file mode 100644 index 0000000..1e20632 --- /dev/null +++ b/sc4pd/source/Latoocarfian.cpp @@ -0,0 +1,217 @@ +/* sc4pd + Latoocarfian, Latoocarfian~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & John Tilbury: Duos For Doris + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ Latoocarfian~ -------------------------------*/ + +class Latoocarfian_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Latoocarfian_ar,sc4pd_dsp); + +public: + Latoocarfian_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set_a(float f) + { + m_a = f; + } + + void m_set_b(float f) + { + m_b = f; + } + + void m_set_c(float f) + { + m_c = f; + } + + void m_set_d(float f) + { + m_d = f; + } + +private: + float m_x, m_y; //state + float m_a, m_b, m_c, m_d; //parameters + + FLEXT_CALLBACK_F(m_set_a); + FLEXT_CALLBACK_F(m_set_b); + FLEXT_CALLBACK_F(m_set_c); + FLEXT_CALLBACK_F(m_set_d); +}; + +FLEXT_LIB_DSP_V("Latoocarfian~",Latoocarfian_ar); + +Latoocarfian_ar::Latoocarfian_ar(int argc, t_atom *argv) + :m_x(4),m_y(1) +{ + FLEXT_ADDMETHOD_(0,"a",m_set_a); + FLEXT_ADDMETHOD_(0,"b",m_set_b); + FLEXT_ADDMETHOD_(0,"c",m_set_c); + FLEXT_ADDMETHOD_(0,"d",m_set_d); + + //parse arguments + AtomList Args(argc,argv); + if (Args.Count()!=4) + { + post("4 arguments needed"); + } + m_a = sc_getfloatarg(Args,0); + m_b = sc_getfloatarg(Args,1); + m_c = sc_getfloatarg(Args,2); + m_d = sc_getfloatarg(Args,3); + + AddOutSignal(); + AddOutSignal(); // supercollider is only using the x coordinate +} + + +void Latoocarfian_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *xout = *out; + t_sample *yout = *(out+1); + + float a = m_a; + float b = m_b; + float c = m_c; + float d = m_d; + + float x = m_x; + float y = m_y; + + for (int i = 0; i!= n;++i) + { + float x_new=sin(y*b)+c*sin(x*b); + float y_new=sin(x*a)+d*sin(y*a); + (*(xout)++)=x=x_new; + (*(yout)++)=y=y_new; + } + m_x = x; + m_y = y; +} + + + +/* ------------------------ Latoocarfian ---------------------------------*/ + +class Latoocarfian_kr: + public flext_base +{ + FLEXT_HEADER(Latoocarfian_kr,flext_base); + +public: + Latoocarfian_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_set_a(float f) + { + m_a = f; + } + + void m_set_b(float f) + { + m_b = f; + } + + void m_set_c(float f) + { + m_c = f; + } + + void m_set_d(float f) + { + m_d = f; + } + +private: + float m_x, m_y; //state + float m_a, m_b, m_c, m_d; //parameters + + FLEXT_CALLBACK_F(m_set_a); + FLEXT_CALLBACK_F(m_set_b); + FLEXT_CALLBACK_F(m_set_c); + FLEXT_CALLBACK_F(m_set_d); + FLEXT_CALLBACK(m_perform); +}; + + +FLEXT_LIB_V("Latoocarfian",Latoocarfian_kr); + +Latoocarfian_kr::Latoocarfian_kr(int argc, t_atom *argv) + :m_x(1),m_y(1) +{ + FLEXT_ADDMETHOD_(0,"a",m_set_a); + FLEXT_ADDMETHOD_(0,"b",m_set_b); + FLEXT_ADDMETHOD_(0,"c",m_set_c); + FLEXT_ADDMETHOD_(0,"d",m_set_d); + + FLEXT_ADDBANG(0,m_perform); + + //parse arguments + AtomList Args(argc,argv); + if (Args.Count()!=4) + { + post("4 arguments needed"); + } + m_a = sc_getfloatarg(Args,0); + m_b = sc_getfloatarg(Args,1); + m_c = sc_getfloatarg(Args,2); + m_d = sc_getfloatarg(Args,3); + + + AddOutFloat(); + AddOutFloat(); // one outlet more than sc +} + +void Latoocarfian_kr::m_perform() +{ + m_x=sin(m_y*m_b)+m_c*sin(m_x*m_b); + m_y=sin(m_x*m_a)+m_d*sin(m_y*m_a); + + ToOutFloat(0,m_x); + ToOutFloat(1,m_y); +} diff --git a/sc4pd/source/LinCong.cpp b/sc4pd/source/LinCong.cpp new file mode 100644 index 0000000..fdead9c --- /dev/null +++ b/sc4pd/source/LinCong.cpp @@ -0,0 +1,211 @@ +/* sc4pd + LinCong, LinCong~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & John Tilbury: Duos For Doris + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LinCong~ -------------------------------*/ + +class LinCong_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LinCong_ar,sc4pd_dsp); + +public: + LinCong_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set_seed(float f) + { + m_seed = (int)f; + } + + void m_set_mul(float f) + { + m_mul = (int)f; + } + + void m_set_add(float f) + { + m_add = (int)f; + } + + void m_set_mod(float f) + { + m_mod = (int)f; + m_scale = 2/f; //output between -1 and 1 + } + +private: + unsigned int m_seed; //seed + unsigned int m_mul, m_add, m_mod; //parameters + + float m_scale; + + FLEXT_CALLBACK_F(m_set_seed); + FLEXT_CALLBACK_F(m_set_mul); + FLEXT_CALLBACK_F(m_set_add); + FLEXT_CALLBACK_F(m_set_mod); +}; + +FLEXT_LIB_DSP_V("LinCong~",LinCong_ar); + +LinCong_ar::LinCong_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_set_seed); + FLEXT_ADDMETHOD_(0,"mul",m_set_mul); + FLEXT_ADDMETHOD_(0,"add",m_set_add); + FLEXT_ADDMETHOD_(0,"mod",m_set_mod); + + //parse arguments + AtomList Args(argc,argv); + if (Args.Count()!=4) + { + post("4 arguments needed"); + } + m_seed = sc_getfloatarg(Args,0); + m_mul = sc_getfloatarg(Args,1); + m_add = sc_getfloatarg(Args,2); + m_set_mod(sc_getfloatarg(Args,3)); + + AddOutSignal(); +} + + +void LinCong_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *xout = *out; + + + unsigned int seed = m_seed; + unsigned int mul = m_mul; + unsigned int add = m_add; + unsigned int mod = m_mod; + + float scale = m_scale; + + for (int i = 0; i!= n;++i) + { + seed=(seed * mul + add) % mod; + (*(xout)++)=float(seed)*scale - 1; + } + + m_seed = seed; +} + + + +/* ------------------------ LinCong ---------------------------------*/ + +class LinCong_kr: + public flext_base +{ + FLEXT_HEADER(LinCong_kr,flext_base); + +public: + LinCong_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_set_seed(float f) + { + m_seed = (int)f; + } + + void m_set_mul(float f) + { + m_mul = (int)f; + } + + void m_set_add(float f) + { + m_add = (int)f; + } + + void m_set_mod(float f) + { + m_mod = (int)f; + m_scale = 2/f; //output between -1 and 1 + } + +private: + unsigned int m_seed; //seed + unsigned int m_mul, m_add, m_mod; //parameters + + float m_scale; + + FLEXT_CALLBACK_F(m_set_seed); + FLEXT_CALLBACK_F(m_set_mul); + FLEXT_CALLBACK_F(m_set_add); + FLEXT_CALLBACK_F(m_set_mod); + FLEXT_CALLBACK(m_perform); +}; + + +FLEXT_LIB_V("LinCong",LinCong_kr); + +LinCong_kr::LinCong_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_set_seed); + FLEXT_ADDMETHOD_(0,"mul",m_set_mul); + FLEXT_ADDMETHOD_(0,"add",m_set_add); + FLEXT_ADDMETHOD_(0,"mod",m_set_mod); + FLEXT_ADDBANG(0,m_perform); + + //parse arguments + AtomList Args(argc,argv); + if (Args.Count()!=4) + { + post("4 arguments needed"); + } + m_seed = sc_getfloatarg(Args,0); + m_mul = sc_getfloatarg(Args,1); + m_add = sc_getfloatarg(Args,2); + m_set_mod(sc_getfloatarg(Args,3)); + + AddOutFloat(); +} + +void LinCong_kr::m_perform() +{ + m_seed=(m_seed * m_mul + m_add) % m_mod; + ToOutFloat(0,float(m_seed) * m_scale - 1); +} diff --git a/sc4pd/source/LinExp.cpp b/sc4pd/source/LinExp.cpp new file mode 100644 index 0000000..69e9e0a --- /dev/null +++ b/sc4pd/source/LinExp.cpp @@ -0,0 +1,223 @@ +/* sc4pd + LinExp~, LinExp + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: The Ex & Tom Cora - And The Weathermen Shrug + Their Shoulders + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LinExp~ -----------------------------*/ + +class LinExp_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(LinExp_ar,sc4pd_dsp); + +public: + LinExp_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set_srclo(float f) + { + m_srclo = f; + m_reset(); + } + + void m_set_srchi(float f) + { + m_srchi = f; + m_reset(); + } + + void m_set_dstlo(float f) + { + m_dstlo = f; + m_reset(); + } + + void m_set_dsthi(float f) + { + m_dsthi = f; + m_reset(); + } + + void m_reset() + { + m_dstratio = m_dsthi/m_dstlo; + m_rsrcrange = 1. / (m_srchi - m_srclo); + m_rrminuslo = m_rsrcrange * -m_srclo; + } + +private: + FLEXT_CALLBACK_F(m_set_srclo); + FLEXT_CALLBACK_F(m_set_srchi); + FLEXT_CALLBACK_F(m_set_dstlo); + FLEXT_CALLBACK_F(m_set_dsthi); + float m_dstratio, m_rsrcrange, m_rrminuslo, m_dstlo; + float m_srclo, m_srchi, m_dsthi; //we will be able to reset the values +}; + +FLEXT_LIB_DSP_V("LinExp~",LinExp_ar); + +LinExp_ar::LinExp_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"srclo",m_set_srclo); + FLEXT_ADDMETHOD_(0,"srchi",m_set_srchi); + FLEXT_ADDMETHOD_(0,"dstlo",m_set_dstlo); + FLEXT_ADDMETHOD_(0,"dsthi",m_set_dsthi); + + AtomList Args(argc,argv); + + if (Args.Count() != 4) + post("4 arguments are required"); + else + { + m_srclo = sc_getfloatarg(Args,0); + m_srchi = sc_getfloatarg(Args,1); + m_dstlo = sc_getfloatarg(Args,2); + m_dsthi = sc_getfloatarg(Args,3); + + m_reset(); + AddOutSignal(); + } +} + +void LinExp_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float dstlo = m_dstlo; + float dstratio = m_dstratio; + float rsrcrange = m_rsrcrange; + float rrminuslo = m_rrminuslo; + + for (int i = 0; i!= n;++i) + { + ZXP(nout) = dstlo * pow(dstratio, ZXP(nin) * rsrcrange + rrminuslo); + } +} + +/* ------------------------ LinExp ------------------------------*/ + +class LinExp_kr + :public flext_base +{ + FLEXT_HEADER(LinExp_kr,flext_base); + +public: + LinExp_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + + void m_set_srclo(float f) + { + m_srclo = f; + m_reset(); + } + + void m_set_srchi(float f) + { + m_srchi = f; + m_reset(); + } + + void m_set_dstlo(float f) + { + m_dstlo = f; + m_reset(); + } + + void m_set_dsthi(float f) + { + m_dsthi = f; + m_reset(); + } + + void m_reset() + { + m_dstratio = m_dsthi/m_dstlo; + m_rsrcrange = 1. / (m_srchi - m_srclo); + m_rrminuslo = m_rsrcrange * -m_srclo; + } + +private: + FLEXT_CALLBACK_F(m_set_srclo); + FLEXT_CALLBACK_F(m_set_srchi); + FLEXT_CALLBACK_F(m_set_dstlo); + FLEXT_CALLBACK_F(m_set_dsthi); + float m_dstratio, m_rsrcrange, m_rrminuslo, m_dstlo; + float m_srclo, m_srchi, m_dsthi; //we will be able to reset the values + + FLEXT_CALLBACK_F(m_perform); +}; + +FLEXT_LIB_V("LinExp",LinExp_kr); + +LinExp_kr::LinExp_kr(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"srclo",m_set_srclo); + FLEXT_ADDMETHOD_(0,"srchi",m_set_srchi); + FLEXT_ADDMETHOD_(0,"dstlo",m_set_dstlo); + FLEXT_ADDMETHOD_(0,"dsthi",m_set_dsthi); + + AtomList Args(argc,argv); + + if (Args.Count() != 4) + post("4 arguments are required"); + else + { + m_srclo = sc_getfloatarg(Args,0); + m_srchi = sc_getfloatarg(Args,1); + m_dstlo = sc_getfloatarg(Args,2); + m_dsthi = sc_getfloatarg(Args,3); + + m_reset(); + + AddInFloat(); + AddOutFloat(); + } +} + +void LinExp_kr::m_perform(float f) +{ + ToOutFloat(0,m_dstlo * pow(m_dstratio, f * m_rsrcrange + m_rrminuslo)); +} diff --git a/sc4pd/source/LinRand.cpp b/sc4pd/source/LinRand.cpp new file mode 100644 index 0000000..80266f1 --- /dev/null +++ b/sc4pd/source/LinRand.cpp @@ -0,0 +1,177 @@ +/* sc4pd + LinRand, LinRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Jim O'Rourke & Loren Mazzacane Connors: In Bern + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ LinRand~ -------------------------------*/ + +class LinRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(LinRand_ar,sc4pd_dsp); + +public: + LinRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("LinRand~",LinRand_ar); + +LinRand_ar::LinRand_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + sc_n=sc_getfloatarg(Args,2); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void LinRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + float range = hi - lo; + float a, b; + a = rgen.frand(); + b = rgen.frand(); + if (sc_n <= 0) { + m_sample = sc_min(a, b) * range + lo; + } else { + m_sample = sc_max(a, b) * range + lo; + } +} + + +void LinRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + + +/* ------------------------ LinRand ---------------------------------*/ + +class LinRand_kr: + public flext_base +{ + FLEXT_HEADER(LinRand_kr,flext_base); + +public: + LinRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("LinRand",LinRand_kr); + +LinRand_kr::LinRand_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + if (Args.Count() != 3) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + sc_n=sc_getfloatarg(Args,2); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void LinRand_kr::m_loadbang() +{ + float range = hi - lo; + float a, b; + a = rgen.frand(); + b = rgen.frand(); + if (sc_n <= 0) { + ToOutFloat(0,sc_min(a, b) * range + lo); + } else { + ToOutFloat(0,sc_max(a, b) * range + lo); + } +} diff --git a/sc4pd/source/Logistic.cpp b/sc4pd/source/Logistic.cpp new file mode 100644 index 0000000..a956fda --- /dev/null +++ b/sc4pd/source/Logistic.cpp @@ -0,0 +1,198 @@ +/* sc4pd + Logistic, Logistic~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Fred Frith: Gravity + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ Logistic~ -------------------------------*/ + +class Logistic_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Logistic_ar,sc4pd_dsp); + +public: + Logistic_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_freq = sc_min(f,m_sr); + } + + void m_param(float f) + { + m_paramf = f; + } + +private: + int m_freq; + float m_paramf; + + int m_sr; + double m_y1; + int m_counter; + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_param); +}; + +FLEXT_LIB_DSP_V("Logistic~",Logistic_ar); + +Logistic_ar::Logistic_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDMETHOD_(0,"parameter",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_paramf = sc_getfloatarg(Args,1); + m_y1 = sc_getfloatarg(Args,2); + + m_sr=48000; // this is just a guess (i'll think about this later) + + AddOutSignal(); +} + +void Logistic_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + m_sr = Samplerate(); + m_paramf = sc_min(m_paramf,m_sr); +} + + +void Logistic_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + if(m_sr == m_paramf) + { + /* it might be possible to implement this without the branch */ + + double y1 = m_y1; + double paramf = m_paramf; + for (int i = 0; i!= n;++i) + { + (*(nout)++)= y1 = paramf * y1 * (1.0 - y1); + } + m_y1 = y1; + } + else + { + double y1 = m_y1; + double paramf = m_paramf; + int counter = m_counter; + int remain = n; + do + { + if (counter<=0) + { + counter = (int)(m_sr / sc_max(m_freq, .001f)); + counter = sc_max(1, counter); + y1 = paramf * y1 * (1.0 - y1); + } + + int nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + (*(nout)++)=y1; + } + } + while(remain); + m_y1 = y1; + m_counter = counter; + } +} + + +/* ------------------------ Logistic ---------------------------------*/ + +class Logistic_kr: + public flext_base +{ + FLEXT_HEADER(Logistic_kr,flext_base); + +public: + Logistic_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_param(float f) + { + m_paramf = f; + } + +private: + float m_paramf; + double m_y1; + + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_F(m_param); +}; + +FLEXT_LIB_V("Logistic",Logistic_kr); + +Logistic_kr::Logistic_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"parameter",m_param); + FLEXT_ADDBANG(0,m_perform); + + //parse arguments + AtomList Args(argc,argv); + + m_paramf = sc_getfloatarg(Args,0); + m_y1 = sc_getfloatarg(Args,1); + + AddOutFloat(); +} + +void Logistic_kr::m_perform() +{ + m_y1 = m_paramf * m_y1 * (1.0 - m_y1); + ToOutFloat(0,m_y1); +} diff --git a/sc4pd/source/MantissaMask.cpp b/sc4pd/source/MantissaMask.cpp new file mode 100644 index 0000000..c7c70c2 --- /dev/null +++ b/sc4pd/source/MantissaMask.cpp @@ -0,0 +1,153 @@ +/* sc4pd + MantissaMask~, MantissaMask + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Wolfgang Mitterer: Amusie + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ MantissaMask~ -----------------------------*/ + +class MantissaMask_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(MantissaMask_ar,sc4pd_dsp); + +public: + MantissaMask_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + void m_set(float f); + +private: + FLEXT_CALLBACK_F(m_set); + int32 mask; + +}; + +FLEXT_LIB_DSP_V("MantissaMask~",MantissaMask_ar); + +MantissaMask_ar::MantissaMask_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + + AtomList Args(argc,argv); + int bits = sc_getfloatarg(Args,0); + + AddOutSignal(); + + mask = -1 << (23 - bits); + +} + +void MantissaMask_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + int32 *nout = (int32*)*out; + int32 *nin = (int32*)*in; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = mask & (*(nin)++); + } +} + +void MantissaMask_ar::m_set(float f) +{ + int bits = (int) f; + if ( bits < 0 || bits > 23) + { + post("value doesn't make sense"); + return; + } + mask = -1 << (23 - bits); +} + +/* ------------------------ MantissaMask ------------------------------*/ + +class MantissaMask_kr + :public flext_base +{ + FLEXT_HEADER(MantissaMask_kr,flext_base); + +public: + MantissaMask_kr(int argc,t_atom * argv); + +protected: + void m_set(float f); + void m_perform(float f); + +private: + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_perform); + int32 mask; +}; + +FLEXT_LIB_V("MantissaMask",MantissaMask_kr); + +MantissaMask_kr::MantissaMask_kr(int argc,t_atom * argv) +{ + + AtomList Args(argc,argv); + int bits = sc_getfloatarg(Args,0); + + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"set",m_set); + mask = -1 << (23 - bits); +} + +void MantissaMask_kr::m_perform(float f) +{ + float g; + int32 *gp = (int32*) &g; + + *(gp) = mask & *((int32*) &f); + + ToOutFloat(0,g); +} + +void MantissaMask_kr::m_set(float f) +{ + int bits = (int) f; + if ( bits < 0 || bits > 23) + { + post("value doesn't make sense"); + return; + } + mask = -1 << (23 - bits); +} diff --git a/sc4pd/source/Median.cpp b/sc4pd/source/Median.cpp new file mode 100644 index 0000000..4383a1b --- /dev/null +++ b/sc4pd/source/Median.cpp @@ -0,0 +1,213 @@ +/* sc4pd + Median, Median~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Morton Feldman: For John Cage + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Median(~) ---------------------------------*/ + + +const int kMAXMEDIANSIZE = 32; + +class median_shared +{ +public: + + inline void Init(long size, float value); + inline float Insert(float value); + +private: + float m_medianValue[kMAXMEDIANSIZE]; + long m_medianAge[kMAXMEDIANSIZE]; + long m_medianSize, m_medianIndex; +}; + +void median_shared::Init(long size, float value) +{ + // initialize the arrays with the first value + m_medianSize = size; + for (int i=0; i<size; ++i) { + m_medianValue[i] = value; + m_medianAge[i] = i; + } +} + +inline float median_shared::Insert(float value) +{ + long i, last, pos=-1; + + // keeps a sorted list of the previous n=size values + // the oldest is removed and the newest is inserted. + // values between the oldest and the newest are shifted over by one. + + // values and ages are both arrays that are 'size' long. + // the median value is always values[size>>1] + + last = m_medianSize - 1; + // find oldest bin and age the other bins. + for (i=0; i<m_medianSize; ++i) { + if (m_medianAge[i] == last) { // is it the oldest bin ? + pos = i; + } else { + m_medianAge[i]++; // age the bin + } + } + // move values to fill in place of the oldest and make a space for the newest + // search lower if value is too small for the open space + while (pos != 0 && value < m_medianValue[pos-1]) { + m_medianValue[pos] = m_medianValue[pos-1]; + m_medianAge[pos] = m_medianAge[pos-1]; + pos--; + } + // search higher if value is too big for the open space + while (pos != last && value > m_medianValue[pos+1]) { + m_medianValue[pos] = m_medianValue[pos+1]; + m_medianAge[pos] = m_medianAge[pos+1]; + pos++; + } + m_medianValue[pos] = value; + m_medianAge[pos] = 0; // this is the newest bin, age = 0 + return m_medianValue[m_medianSize>>1]; +} + + +/* ------------------------ Median~ -----------------------------------*/ + +class Median_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Median_ar,sc4pd_dsp); + +public: + Median_ar(int argc, t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp (int n,t_signalvec const * insigs, + t_signalvec const * outsigs); + + void m_set(float f) + { + m_size=(int)f; + Median.Init(m_size,Median.Insert(0)); /* this is not beautiful, but i'm not + aware of a nicer way */ + } + +private: + FLEXT_CALLBACK_F(m_set); + + median_shared Median; //median + int m_size; //median size +}; + +FLEXT_LIB_DSP_V("Median~",Median_ar); + +Median_ar::Median_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + + AtomList Args(argc,argv); + m_size=sc_getfloatarg(Args,0); + + AddOutSignal(); +} + +void Median_ar::m_dsp(int n,t_signalvec const * insigs, + t_signalvec const * outsigs) +{ + Median.Init(m_size,0); //how is this done in SuperCollider? +} + +void Median_ar::m_signal(int n, t_sample *const *in, t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = Median.Insert(*(nin)++); + } +} + + +/* ------------------------ Median ------------------------------------*/ + +class Median_kr + :public sc4pd_dsp +{ + FLEXT_HEADER(Median_kr,sc4pd_dsp); + +public: + Median_kr(int argc, t_atom * argv); + +protected: + void m_set(float f) + { + m_size=(int)f; + Median.Init(m_size,Median.Insert(0)); /* this is not beautiful, but i'm not + aware of a nicer way */ + } + void m_perform(float f); + +private: + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_perform); + + median_shared Median; //median + int m_size; //median size +}; + +FLEXT_LIB_V("Median",Median_kr); + +Median_kr::Median_kr(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"set",m_set); + FLEXT_ADDMETHOD(0,m_perform); + + + AtomList Args(argc,argv); + m_size=(int)sc_getfloatarg(Args,0); + + float m_set=sc_getfloatarg(Args,1); + + Median.Init(m_size,m_set); + AddOutFloat(); +} + +void Median_kr::m_perform(float f) +{ + ToOutFloat(0,Median.Insert(f)); +} diff --git a/sc4pd/source/NRand.cpp b/sc4pd/source/NRand.cpp new file mode 100644 index 0000000..e91ad71 --- /dev/null +++ b/sc4pd/source/NRand.cpp @@ -0,0 +1,173 @@ +/* sc4pd + NRand, NRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Jim O'Rourke & Loren Mazzacane Connors: In Bern + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ NRand~ -------------------------------*/ + +class NRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(NRand_ar,sc4pd_dsp); + +public: + NRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("NRand~",NRand_ar); + +NRand_ar::NRand_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + + if (Args.Count() != 3) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + sc_n=sc_getfloatarg(Args,2); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void NRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + float range = hi - lo; + float sum = 0; + for (int i=0; i<sc_n; ++i) + { + sum += rgen.frand(); + } + m_sample = (sum/sc_n) * range + lo; +} + + +void NRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + + +/* ------------------------ NRand ---------------------------------*/ + +class NRand_kr: + public flext_base +{ + FLEXT_HEADER(NRand_kr,flext_base); + +public: + NRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + int sc_n; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("NRand",NRand_kr); + +NRand_kr::NRand_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + if (Args.Count() != 3) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + sc_n=sc_getfloatarg(Args,2); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void NRand_kr::m_loadbang() +{ + float range = hi - lo; + float sum = 0; + for (int i=0; i<sc_n; ++i) + { + sum += rgen.frand(); + } + ToOutFloat(0,(sum/sc_n) * range + lo); +} diff --git a/sc4pd/source/OnePole.cpp b/sc4pd/source/OnePole.cpp new file mode 100644 index 0000000..3de6ef4 --- /dev/null +++ b/sc4pd/source/OnePole.cpp @@ -0,0 +1,245 @@ +/* sc4pd + OnePole, OnePole~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Goh Lee Kwang: Internal Pleasures + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ OnePole~ -------------------------------*/ + +class OnePole_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(OnePole_ar,sc4pd_dsp); + +public: + OnePole_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + void m_set(float f) + { + n_b1=f; + changed = true; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + +private: + float m_b1, m_y1; + float n_b1; + bool changed; + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("OnePole~",OnePole_ar); + +OnePole_ar::OnePole_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"coef",m_set); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + + if(sc_ar(Args)) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + AddInSignal(); + AddInSignal(); + } + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); + + m_y1 = 0.f; +} + +void OnePole_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + float *b1p = *(in+1); + + float y1 = m_y1; + + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + float b1 = ZXP(b1p); + ZXP(nout) = y1 = y0 + b1 * (y1 - y0); + } + m_y1 = zapgremlins(y1); +} + + +void OnePole_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float b1 = m_b1; + float y1 = m_y1; + + if (changed) + { + m_b1=n_b1; + float b1_slope = CALCSLOPE(m_b1, b1); + if (b1 >= 0.f && m_b1 >= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 - y0); + b1 += b1_slope; + } + } + else if (b1 <= 0.f && m_b1 <= 0) + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 + y0); + b1 += b1_slope; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = (1.f - fabs(b1)) * y0 + b1 * y1; + b1 += b1_slope; + } + } + changed = false; + } + else + { + if (b1 >= 0.f) + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 - y0); + } + } + else + { + for (int i = 0; i!= n;++i) + { + float y0 = ZXP(nin); + ZXP(nout) = y1 = y0 + b1 * (y1 + y0); + } + } + + } + m_y1 = zapgremlins(y1); +} + +/* ------------------------ OnePole ---------------------------------*/ + + +class OnePole_kr: + public flext_base +{ + FLEXT_HEADER(OnePole_kr,flext_base); + +public: + OnePole_kr(int argc, t_atom *argv); + +protected: + void m_perform(float f); + + void m_set(float f) + { + m_b1=f; + } + +private: + float m_b1, m_y1; + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_perform); +}; + + +FLEXT_LIB_V("OnePole",OnePole_kr); + +OnePole_kr::OnePole_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"set",m_set); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + + m_y1=0; +} + +void OnePole_kr::m_perform(float f) +{ + m_y1= ((1-abs(m_b1))*f)+m_b1*m_y1; + ToOutFloat(0,m_y1); +} diff --git a/sc4pd/source/OneZero.cpp b/sc4pd/source/OneZero.cpp new file mode 100644 index 0000000..82c9ad5 --- /dev/null +++ b/sc4pd/source/OneZero.cpp @@ -0,0 +1,200 @@ +/* sc4pd + OneZero, OneZero~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Goh Lee Kwang: Internal Pleasures + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ OneZero~ -------------------------------*/ + +class OneZero_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(OneZero_ar,sc4pd_dsp); + +public: + OneZero_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + n_b1=f; + changed = true; + } + +private: + float m_b1, m_x1; + float n_b1; + bool changed; + + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_DSP_V("OneZero~",OneZero_ar); + +OneZero_ar::OneZero_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"coef",m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + + AddOutSignal(); + + m_x1 = 0.f; +} + +void OneZero_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float b1 = m_b1; + float x1 = m_x1; + + if (changed) + { + m_b1=n_b1; + float b1_slope = CALCSLOPE(m_b1, b1); + if (b1 >= 0.f && m_b1 >= 0) + { + for (int i = 0; i!= n;++i) + { + float x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * (x1 - x0); + x1 = x0; + b1 += b1_slope; + } + } + else if (b1 <= 0.f && m_b1 <= 0) + { + for (int i = 0; i!= n;++i) + { + float x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * (x1 + x0); + x1 = x0; + b1 += b1_slope; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float x0 = ZXP(nin); + ZXP(nout) = (1.f - fabs(b1)) * x0 + b1 * x1; + x1 = x0; + b1 += b1_slope; + } + } + changed = false; + } + else + { + if (b1 >= 0.f) + { + for (int i = 0; i!= n;++i) + { + float x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * (x1 - x0); + x1 = x0; + } + } + else + { + for (int i = 0; i!= n;++i) + { + float x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * (x1 + x0); + x1 = x0; + } + } + } + m_x1 = x1; +} + +/* ------------------------ OneZero ---------------------------------*/ + + +class OneZero_kr: + public flext_base +{ + FLEXT_HEADER(OneZero_kr,flext_base); + +public: + OneZero_kr(int argc, t_atom *argv); + +protected: + void m_perform(float f); + + void m_set(float f) + { + m_b1=f; + } + +private: + float m_b1, m_x1; + + FLEXT_CALLBACK_F(m_set); + FLEXT_CALLBACK_F(m_perform); +}; + + +FLEXT_LIB_V("OneZero",OneZero_kr); + +OneZero_kr::OneZero_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD_(0,"set",m_set); + + AddOutFloat(); + + //parse arguments + AtomList Args(argc,argv); + + m_b1 = sc_getfloatarg(Args,0); + + m_x1=0; +} + +void OneZero_kr::m_perform(float f) +{ + ToOutFloat(0,((1-abs(m_b1))*f)+m_b1*m_x1); + m_x1=f; +} diff --git a/sc4pd/source/PinkNoise.cpp b/sc4pd/source/PinkNoise.cpp new file mode 100644 index 0000000..296f383 --- /dev/null +++ b/sc4pd/source/PinkNoise.cpp @@ -0,0 +1,174 @@ +/* sc4pd + PinkNoise, PinkNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Gottfried Michael Koenig: Klangfiguren II + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ PinkNoise~ -------------------------------*/ + +class PinkNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(PinkNoise_ar,sc4pd_dsp); + +public: + PinkNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + uint32 m_dice[16]; + int32 m_total; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("PinkNoise~",PinkNoise_ar); + +PinkNoise_ar::PinkNoise_ar(int argc, t_atom *argv) + : m_total(0) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + for (int i=0; i<16; ++i) + { + uint32 newrand = rgen.trand() >> 13; + m_total += newrand; + m_dice[i] = newrand; + } + + AddOutSignal(); +} + + +void PinkNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + uint32 total = m_total; + uint32 *dice = m_dice; + + for (int i = 0; i!= n;++i) + { + uint32 counter = trand(s1,s2,s3); // Magnus Jonsson's suggestion. + uint32 newrand = counter >> 13; + int k = (CTZ(counter)) & 15; + uint32 prevrand = dice[k]; + dice[k] = newrand; + total += (newrand - prevrand); + newrand = trand(s1,s2,s3) >> 13; + uint32 ifval = (total + newrand) | 0x40000000; + (*(nout)++) = ((*(float*)&ifval) - 3.0f); + } + RPUT; +} + + +/* ------------------------ PinkNoise ---------------------------------*/ + +class PinkNoise_kr: + public flext_base +{ + FLEXT_HEADER(PinkNoise_kr,flext_base); + +public: + PinkNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + uint32 m_dice[16]; + int32 m_total; + RGen rgen; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("PinkNoise",PinkNoise_kr); + +PinkNoise_kr::PinkNoise_kr(int argc, t_atom *argv) + : m_total(0) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + for (int i=0; i<16; ++i) + { + uint32 newrand = rgen.trand() >> 13; + m_total += newrand; + m_dice[i] = newrand; + } + + AddOutFloat(); +} + +void PinkNoise_kr::m_perform() +{ + uint32 counter = rgen.trand(); // Magnus Jonsson's suggestion. + uint32 newrand = counter >> 13; + int k = (CTZ(counter)) & 15; + uint32 prevrand = m_dice[k]; + m_dice[k] = newrand; + m_total += (newrand - prevrand); + newrand = rgen.trand() >> 13; + uint32 ifval = (m_total + newrand) | 0x40000000; + + ToOutFloat(0,((*(float*)&ifval) - 3.0f)); +} diff --git a/sc4pd/source/PitchShift.cpp b/sc4pd/source/PitchShift.cpp new file mode 100644 index 0000000..8a3f265 --- /dev/null +++ b/sc4pd/source/PitchShift.cpp @@ -0,0 +1,629 @@ +/* sc4pd + PitchShift~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Bernhard Lang: Differenz / Wiederholung 2 + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ PitchShift~ -----------------------------*/ + +class PitchShift_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(PitchShift_ar,sc4pd_dsp); + +public: + PitchShift_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set_pitchratio (float f) + { + m_pitchratio = f; + } + + void m_set_pitchdispersion (float f) + { + m_pitchdispersion = f; + } + + void m_set_timedispersion (float f) + { + m_timedispersion = f; + } + +private: + float m_windowsize,m_pitchratio,m_pitchdispersion,m_timedispersion; + RGen rgen; + + + float *m_dlybuf; + float m_dsamp1, m_dsamp1_slope, m_ramp1, m_ramp1_slope; + float m_dsamp2, m_dsamp2_slope, m_ramp2, m_ramp2_slope; + float m_dsamp3, m_dsamp3_slope, m_ramp3, m_ramp3_slope; + float m_dsamp4, m_dsamp4_slope, m_ramp4, m_ramp4_slope; + float m_fdelaylen, m_slope; + long m_iwrphase, m_idelaylen, m_mask; + long m_counter, m_stage, m_numoutput, m_framesize; + + DEFSIGCALL(m_signal_fun); + DEFSIGFUN(m_signal_); + DEFSIGFUN(m_signal_z); + + FLEXT_CALLBACK_F(m_set_pitchratio); + FLEXT_CALLBACK_F(m_set_pitchdispersion); + FLEXT_CALLBACK_F(m_set_timedispersion); +}; + +FLEXT_LIB_DSP_V("PitchShift~",PitchShift_ar); + +PitchShift_ar::PitchShift_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"pitchRatio",m_set_pitchratio); + FLEXT_ADDMETHOD_(0,"pitchDispersion",m_set_pitchdispersion); + FLEXT_ADDMETHOD_(0,"timeDispersion",m_set_timedispersion); + + AtomList Args(argc,argv); + + if (Args.Count() != 4) + { + post("4 arguments needed"); + return; + } + + m_windowsize = sc_getfloatarg(Args,0); + m_pitchratio = sc_getfloatarg(Args,1); + m_pitchdispersion = sc_getfloatarg(Args,2); + m_timedispersion = sc_getfloatarg(Args,3); + + rgen.init(timeseed()); + + AddOutSignal(); + + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); +} + +void PitchShift_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + /* initialization from PitchShift_Ctor(PitchShift *unit) */ + + long delaybufsize; + float *dlybuf; + float pchratio; + float fdelaylen, slope; + long framesize, last; + + //out = ZOUT(0); + //in = ZIN(0); + pchratio = m_pitchratio; + + delaybufsize = (long)ceil(m_windowsize * SAMPLERATE * 3.f + 3.f); + fdelaylen = delaybufsize - 3; + + delaybufsize = delaybufsize + BUFLENGTH; + delaybufsize = NEXTPOWEROFTWO(delaybufsize); // round up to next power of two + dlybuf = new float[delaybufsize]; + //(float*)RTAlloc(unit->mWorld, delaybufsize * sizeof(float)); + + *dlybuf = 0; + + m_dlybuf = dlybuf; + m_idelaylen = delaybufsize; + m_fdelaylen = fdelaylen; + m_iwrphase = 0; + m_numoutput = 0; + m_mask = last = (delaybufsize - 1); + + m_framesize = framesize = ((long)(m_windowsize * SAMPLERATE) + 2) & ~3; + m_slope = slope = 2.f / framesize; + m_stage = 3; + m_counter = framesize >> 2; + m_ramp1 = 0.5; + m_ramp2 = 1.0; + m_ramp3 = 0.5; + m_ramp4 = 0.0; + + m_ramp1_slope = -slope; + m_ramp2_slope = -slope; + m_ramp3_slope = slope; + m_ramp4_slope = slope; + + dlybuf[last ] = 0.f; // put a few zeroes where we start the read heads + dlybuf[last-1] = 0.f; + dlybuf[last-2] = 0.f; + + m_numoutput = 0; + + // start all read heads 2 samples behind the write head + m_dsamp1 = m_dsamp2 = m_dsamp3 = m_dsamp4 = 2.f; + // pch ratio is initially zero for the read heads + m_dsamp1_slope = m_dsamp2_slope = m_dsamp3_slope = m_dsamp4_slope = 1.f; +} + + +void PitchShift_ar::m_signal_z(int n, t_sample *const *in, + t_sample *const *out) +{ + + float *nout, *nin, *dlybuf; + float disppchratio, pchratio, pchratio1, value; + float dsamp1, dsamp1_slope, ramp1, ramp1_slope; + float dsamp2, dsamp2_slope, ramp2, ramp2_slope; + float dsamp3, dsamp3_slope, ramp3, ramp3_slope; + float dsamp4, dsamp4_slope, ramp4, ramp4_slope; + float fdelaylen, d1, d2, frac, slope, samp_slope, startpos, + pchdisp, timedisp; + long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase; + long mask, idsamp; + long counter, stage, framesize, numoutput; + + RGET; + + nout = *out; + nin = *in; + + pchratio = m_pitchratio; + pchdisp = m_pitchdispersion; + timedisp = m_timedispersion; + timedisp = sc_clip(timedisp, 0.f, m_windowsize) * SAMPLERATE; + + dlybuf = m_dlybuf; + fdelaylen = m_fdelaylen; + idelaylen = m_idelaylen; + iwrphase = m_iwrphase; + numoutput = m_numoutput; + + counter = m_counter; + stage = m_stage; + mask = m_mask; + framesize = m_framesize; + + dsamp1 = m_dsamp1; + dsamp2 = m_dsamp2; + dsamp3 = m_dsamp3; + dsamp4 = m_dsamp4; + + dsamp1_slope = m_dsamp1_slope; + dsamp2_slope = m_dsamp2_slope; + dsamp3_slope = m_dsamp3_slope; + dsamp4_slope = m_dsamp4_slope; + + ramp1 = m_ramp1; + ramp2 = m_ramp2; + ramp3 = m_ramp3; + ramp4 = m_ramp4; + + ramp1_slope = m_ramp1_slope; + ramp2_slope = m_ramp2_slope; + ramp3_slope = m_ramp3_slope; + ramp4_slope = m_ramp4_slope; + + slope = m_slope; + + remain = n; + while (remain) + { + if (counter <= 0) + { + counter = framesize >> 2; + m_stage = stage = (stage + 1) & 3; + disppchratio = pchratio; + if (pchdisp != 0.f) + { + disppchratio += (pchdisp * frand2(s1,s2,s3)); + } + disppchratio = sc_clip(disppchratio, 0.f, 4.f); + pchratio1 = disppchratio - 1.f; + samp_slope = -pchratio1; + startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f; + startpos += (timedisp * frand(s1,s2,s3)); + switch(stage) + { + case 0 : + m_dsamp1_slope = dsamp1_slope = samp_slope; + dsamp1 = startpos; + ramp1 = 0.0; + m_ramp1_slope = ramp1_slope = slope; + m_ramp3_slope = ramp3_slope = -slope; + break; + case 1 : + m_dsamp2_slope = dsamp2_slope = samp_slope; + dsamp2 = startpos; + ramp2 = 0.0; + m_ramp2_slope = ramp2_slope = slope; + m_ramp4_slope = ramp4_slope = -slope; + break; + case 2 : + m_dsamp3_slope = dsamp3_slope = samp_slope; + dsamp3 = startpos; + ramp3 = 0.0; + m_ramp3_slope = ramp3_slope = slope; + m_ramp1_slope = ramp1_slope = -slope; + break; + case 3 : + m_dsamp4_slope = dsamp4_slope = samp_slope; + dsamp4 = startpos; + ramp4 = 0.0; + m_ramp2_slope = ramp2_slope = -slope; + m_ramp4_slope = ramp4_slope = slope; + break; + } + } + nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + while (nsmps--) { + numoutput++; + iwrphase = (iwrphase + 1) & mask; + + dsamp1 += dsamp1_slope; + idsamp = (long)dsamp1; + frac = dsamp1 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + if (numoutput < idelaylen) + { + if (irdphase > iwrphase) + { + value = 0.f; + } + else if (irdphaseb > iwrphase) + { + d1 = dlybuf[irdphase]; + value = (d1 - frac * d1) * ramp1; + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value = (d1 + frac * (d2 - d1)) * ramp1; + } + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value = (d1 + frac * (d2 - d1)) * ramp1; + } + ramp1 += ramp1_slope; + + dsamp2 += dsamp2_slope; + idsamp = (long)dsamp2; + frac = dsamp2 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + if (numoutput < idelaylen) + { + if (irdphase > iwrphase) + { + //value += 0.f; + } + else if (irdphaseb > iwrphase) + { + d1 = dlybuf[irdphase]; + value += (d1 - frac * d1) * ramp2; + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp2; + + } + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp2; + } + ramp2 += ramp2_slope; + + dsamp3 += dsamp3_slope; + idsamp = (long)dsamp3; + frac = dsamp3 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + if (numoutput < idelaylen) + { + if (irdphase > iwrphase) + { + //value += 0.f; + } + else if (irdphaseb > iwrphase) + { + d1 = dlybuf[irdphase]; + value += (d1 - frac * d1) * ramp3; + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp3; + } + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp3; + } + ramp3 += ramp3_slope; + + dsamp4 += dsamp4_slope; + idsamp = (long)dsamp4; + frac = dsamp4 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + + if (numoutput < idelaylen) + { + if (irdphase > iwrphase) + { + //value += 0.f; + } else if (irdphaseb > iwrphase) { + d1 = dlybuf[irdphase]; + value += (d1 - frac * d1) * ramp4; + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp4; + } + } + else + { + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp4; + } + ramp4 += ramp4_slope; + + dlybuf[iwrphase] = ZXP(nin); + ZXP(nout) = value *= 0.5; + } + } + + m_counter = counter; + m_stage = stage; + m_mask = mask; + + m_dsamp1 = dsamp1; + m_dsamp2 = dsamp2; + m_dsamp3 = dsamp3; + m_dsamp4 = dsamp4; + + m_ramp1 = ramp1; + m_ramp2 = ramp2; + m_ramp3 = ramp3; + m_ramp4 = ramp4; + + m_numoutput = numoutput; + m_iwrphase = iwrphase; + + if (numoutput >= idelaylen) + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_z)); + } + RPUT; +} + +void PitchShift_ar::m_signal_(int n, t_sample *const *in, + t_sample *const *out) +{ + float *nout, *nin, *dlybuf; + float disppchratio, pchratio, pchratio1, value; + float dsamp1, dsamp1_slope, ramp1, ramp1_slope; + float dsamp2, dsamp2_slope, ramp2, ramp2_slope; + float dsamp3, dsamp3_slope, ramp3, ramp3_slope; + float dsamp4, dsamp4_slope, ramp4, ramp4_slope; + float fdelaylen, d1, d2, frac, slope, samp_slope, startpos, + pchdisp, timedisp; + long remain, nsmps, idelaylen, irdphase, irdphaseb, iwrphase, mask, idsamp; + long counter, stage, framesize; + + RGET; + + nout = *out; + nin = *in; + + pchratio = m_pitchratio; + pchdisp = m_pitchdispersion; + timedisp = m_timedispersion; + + timedisp = sc_clip(timedisp, 0.f, m_windowsize) * SAMPLERATE; + + dlybuf = m_dlybuf; + fdelaylen = m_fdelaylen; + idelaylen = m_idelaylen; + iwrphase = m_iwrphase; + + counter = m_counter; + stage = m_stage; + mask = m_mask; + framesize = m_framesize; + + dsamp1 = m_dsamp1; + dsamp2 = m_dsamp2; + dsamp3 = m_dsamp3; + dsamp4 = m_dsamp4; + + dsamp1_slope = m_dsamp1_slope; + dsamp2_slope = m_dsamp2_slope; + dsamp3_slope = m_dsamp3_slope; + dsamp4_slope = m_dsamp4_slope; + + ramp1 = m_ramp1; + ramp2 = m_ramp2; + ramp3 = m_ramp3; + ramp4 = m_ramp4; + + ramp1_slope = m_ramp1_slope; + ramp2_slope = m_ramp2_slope; + ramp3_slope = m_ramp3_slope; + ramp4_slope = m_ramp4_slope; + + slope = m_slope; + + remain = n; + while (remain) + { + if (counter <= 0) + { + counter = framesize >> 2; + m_stage = stage = (stage + 1) & 3; + disppchratio = pchratio; + if (pchdisp != 0.f) + { + disppchratio += (pchdisp * frand2(s1,s2,s3)); + } + disppchratio = sc_clip(disppchratio, 0.f, 4.f); + pchratio1 = disppchratio - 1.f; + samp_slope = -pchratio1; + startpos = pchratio1 < 0.f ? 2.f : framesize * pchratio1 + 2.f; + startpos += (timedisp * frand(s1,s2,s3)); + switch(stage) + { + case 0 : + m_dsamp1_slope = dsamp1_slope = samp_slope; + dsamp1 = startpos; + ramp1 = 0.0; + m_ramp1_slope = ramp1_slope = slope; + m_ramp3_slope = ramp3_slope = -slope; + break; + case 1 : + m_dsamp2_slope = dsamp2_slope = samp_slope; + dsamp2 = startpos; + ramp2 = 0.0; + m_ramp2_slope = ramp2_slope = slope; + m_ramp4_slope = ramp4_slope = -slope; + break; + case 2 : + m_dsamp3_slope = dsamp3_slope = samp_slope; + dsamp3 = startpos; + ramp3 = 0.0; + m_ramp3_slope = ramp3_slope = slope; + m_ramp1_slope = ramp1_slope = -slope; + break; + case 3 : + m_dsamp4_slope = dsamp4_slope = samp_slope; + dsamp4 = startpos; + ramp4 = 0.0; + m_ramp2_slope = ramp2_slope = -slope; + m_ramp4_slope = ramp4_slope = slope; + break; + } + } + + nsmps = sc_min(remain, counter); + remain -= nsmps; + counter -= nsmps; + + for (int i = 0; i!= nsmps;++i) + { + iwrphase = (iwrphase + 1) & mask; + + dsamp1 += dsamp1_slope; + idsamp = (long)dsamp1; + frac = dsamp1 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value = (d1 + frac * (d2 - d1)) * ramp1; + ramp1 += ramp1_slope; + + dsamp2 += dsamp2_slope; + idsamp = (long)dsamp2; + frac = dsamp2 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp2; + ramp2 += ramp2_slope; + + dsamp3 += dsamp3_slope; + idsamp = (long)dsamp3; + frac = dsamp3 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp3; + ramp3 += ramp3_slope; + + dsamp4 += dsamp4_slope; + idsamp = (long)dsamp4; + frac = dsamp4 - idsamp; + irdphase = (iwrphase - idsamp) & mask; + irdphaseb = (irdphase - 1) & mask; + d1 = dlybuf[irdphase]; + d2 = dlybuf[irdphaseb]; + value += (d1 + frac * (d2 - d1)) * ramp4; + ramp4 += ramp4_slope; + + dlybuf[iwrphase] = ZXP(nin); + ZXP(nout) = value *= 0.5; + } + } + + m_counter = counter; + + m_dsamp1 = dsamp1; + m_dsamp2 = dsamp2; + m_dsamp3 = dsamp3; + m_dsamp4 = dsamp4; + + m_ramp1 = ramp1; + m_ramp2 = ramp2; + m_ramp3 = ramp3; + m_ramp4 = ramp4; + + m_iwrphase = iwrphase; + + RPUT; +} + + +/* a control rate PitchShift doesn't make sense */ diff --git a/sc4pd/source/RHPF.cpp b/sc4pd/source/RHPF.cpp new file mode 100644 index 0000000..fb79d2b --- /dev/null +++ b/sc4pd/source/RHPF.cpp @@ -0,0 +1,192 @@ +/* sc4pd + RHPF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Peter Kowald & Tatsuya Nakatani: + 13 Definitions of Truth + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ RHPF~ -------------------------------*/ + +class RHPF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(RHPF_ar,sc4pd_dsp); + +public: + RHPF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_rq(float f) + { + m_reson=f; + changed = true; + } + + +private: + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_reson; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_rq); +}; + +FLEXT_LIB_DSP_V("RHPF~",RHPF_ar); + +RHPF_ar::RHPF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"krq",m_set_rq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_reson = sc_getfloatarg(Args,1); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void RHPF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed) + { + float qres = sc_max(0.001, m_reson); + float pfreq = m_freq * mRadiansPerSample; + + float D = tan(pfreq * qres * 0.5); + float C = ((1.f-D)/(1.f+D)); + float cosf = cos(pfreq); + + float next_b1 = (1.f + C) * cosf; + float next_b2 = -C; + float next_a0 = (1.f + C + next_b1) * .25; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 - 2.f * y1 + y2; + + y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y2 - 2.f * y0 + y1; + + y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = y1 - 2.f * y2 + y0; + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 - 2.f * y1 + y2; + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 - 2.f * y1 + y2; + + y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y2 - 2.f * y0 + y1; + + y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = y1 - 2.f * y2 + y0; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 - 2.f * y1 + y2; + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate RHPF filter */ diff --git a/sc4pd/source/RLPF.cpp b/sc4pd/source/RLPF.cpp new file mode 100644 index 0000000..89fc46c --- /dev/null +++ b/sc4pd/source/RLPF.cpp @@ -0,0 +1,192 @@ +/* sc4pd + RLPF~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Peter Kowald & Tatsuya Nakatani: + 13 Definitions of Truth + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ RLPF~ -------------------------------*/ + +class RLPF_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(RLPF_ar,sc4pd_dsp); + +public: + RLPF_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_rq(float f) + { + m_reson=f; + changed = true; + } + + +private: + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_reson; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_rq); +}; + +FLEXT_LIB_DSP_V("RLPF~",RLPF_ar); + +RLPF_ar::RLPF_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"rq",m_set_rq); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_reson = sc_getfloatarg(Args,1); + changed = true; + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void RLPF_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed) + { + float qres = sc_max(0.001, m_reson); + float pfreq = m_freq * mRadiansPerSample; + + float D = tan(pfreq * qres * 0.5); + float C = ((1.f-D)/(1.f+D)); + float cosf = cos(pfreq); + + float next_b1 = (1.f + C) * cosf; + float next_b2 = -C; + float next_a0 = (1.f + C - next_b1) * .25; + + float a0_slope = (next_a0 - a0) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 + 2.f * y1 + y2; + + y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y2 + 2.f * y0 + y1; + + y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = y1 + 2.f * y2 + y0; + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 + 2.f * y1 + y2; + y2 = y1; + y1 = y0; + } + + m_a0 = a0; + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 + 2.f * y1 + y2; + + y2 = a0 * ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y2 + 2.f * y0 + y1; + + y1 = a0 * ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = y1 + 2.f * y2 + y0; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = a0 * ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y0 + 2.f * y1 + y2; + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate RLPF filter */ diff --git a/sc4pd/source/Rand.cpp b/sc4pd/source/Rand.cpp new file mode 100644 index 0000000..c310aa9 --- /dev/null +++ b/sc4pd/source/Rand.cpp @@ -0,0 +1,160 @@ +/* sc4pd + Rand, Rand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: the sounds coming through my open window + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ Rand~ -------------------------------*/ + +class Rand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(Rand_ar,sc4pd_dsp); + +public: + Rand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("Rand~",Rand_ar); + +Rand_ar::Rand_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + + rgen.init(timeseed()); + + AddOutSignal(); +} + +void Rand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + float range = hi - lo; + m_sample = rgen.frand() * range + lo; +} + + +void Rand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + + +/* ------------------------ Rand ---------------------------------*/ + +class Rand_kr: + public flext_base +{ + FLEXT_HEADER(Rand_kr,flext_base); + +public: + Rand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("Rand",Rand_kr); + +Rand_kr::Rand_kr(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void Rand_kr::m_loadbang() +{ + float range = hi - lo; + + ToOutFloat(0,rgen.frand() * range + lo); +} diff --git a/sc4pd/source/Resonz.cpp b/sc4pd/source/Resonz.cpp new file mode 100644 index 0000000..4561b9a --- /dev/null +++ b/sc4pd/source/Resonz.cpp @@ -0,0 +1,190 @@ +/* sc4pd + Resonz~, Resonz + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: MIMEO: Electric Chair And Table + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ Resonz~ -----------------------------*/ + +class Resonz_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(Resonz_ar,sc4pd_dsp); + +public: + Resonz_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_set_freq(float f) + { + m_freq = f; + m_ffreq = m_freq * mRadiansPerSample; + changed = true; + } + void m_set_rq(float f) + { + m_rq = f; + changed = true; + } + +private: + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_rq); + float m_y1, m_y2, m_a0, m_b1, m_b2, m_freq, m_rq, m_ffreq; + bool changed; + + float mRadiansPerSample, mFilterSlope, mFilterLoops, mFilterRemain; +}; + +FLEXT_LIB_DSP_V("Resonz~",Resonz_ar); + +Resonz_ar::Resonz_ar(int argc,t_atom * argv) +{ + FLEXT_ADDMETHOD_(0,"freq",m_set_freq); + FLEXT_ADDMETHOD_(0,"rq",m_set_rq); + + AtomList Args(argc,argv); + m_freq = sc_getfloatarg(Args,0); + m_rq = sc_getfloatarg(Args,1); + + AddOutSignal(); + + m_a0 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; + changed = false; +} + +void Resonz_ar::m_dsp(int n, t_sample *const *in, + t_sample *const *out) +{ + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + + m_ffreq = m_freq * mRadiansPerSample; +} + +void Resonz_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin = *in; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float b1 = m_b1; + float b2 = m_b2; + + if (changed = true) + { + float B = m_ffreq * m_rq; + float R = 1.f - B * 0.5f; + float twoR = 2.f * R; + float R2 = R * R; + float cost = (twoR * cos(m_ffreq)) / (1.f + R2); + float b1_next = twoR * cost; + float b2_next = -R2; + float a0_next = (1.f - R2) * 0.5f; + float a0_slope = (a0_next - a0) * mFilterSlope; + float b1_slope = (b1_next - b1) * mFilterSlope; + float b2_slope = (b2_next - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - y0); + + a0 += a0_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + y2 = y1; + y1 = y0; + } + + m_a0 = a0_next; + m_b1 = b1_next; + m_b2 = b2_next; + changed = false; + } + else + { + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * (y2 - y1); + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * (y1 - y0); + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * (y0 - y2); + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + + +/* no control rate resonz */ diff --git a/sc4pd/source/SOS.cpp b/sc4pd/source/SOS.cpp new file mode 100644 index 0000000..29aaecb --- /dev/null +++ b/sc4pd/source/SOS.cpp @@ -0,0 +1,258 @@ +/* sc4pd + SOS~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Susie Ibarra & Assif Tsahar: Home Cookin' + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ SOS~ -------------------------------*/ + +class SOS_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(SOS_ar,sc4pd_dsp); + +public: + SOS_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out) + { + m_signal_fun(n,in,out); + } + + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + mFilterSlope = sc_filterslope(); + } + + void m_set_a0(float f) + { + next_a0=f; + } + + void m_set_a1(float f) + { + next_a1=f; + } + + void m_set_a2(float f) + { + next_a2=f; + } + + void m_set_b1(float f) + { + next_b1=f; + } + + void m_set_b2(float f) + { + next_b2=f; + } + + void m_ar() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + + void m_kr() + { + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + } + +private: + float next_a0, next_a1, next_a2, next_b1, next_b2; + float m_y1, m_y2, m_a0, m_a1, m_a2, m_b1, m_b2; + + float mFilterSlope; + int mFilterLoops, mFilterRemain; + + DEFSIGCALL (m_signal_fun); + DEFSIGFUN (m_signal_ar); + DEFSIGFUN (m_signal_kr); + + FLEXT_CALLBACK_F(m_set_a0); + FLEXT_CALLBACK_F(m_set_a1); + FLEXT_CALLBACK_F(m_set_a2); + FLEXT_CALLBACK_F(m_set_b1); + FLEXT_CALLBACK_F(m_set_b2); + FLEXT_CALLBACK(m_ar); + FLEXT_CALLBACK(m_kr); +}; + +FLEXT_LIB_DSP_V("SOS~",SOS_ar); + +SOS_ar::SOS_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"a0",m_set_a0); + FLEXT_ADDMETHOD_(0,"a1",m_set_a1); + FLEXT_ADDMETHOD_(0,"a2",m_set_a2); + FLEXT_ADDMETHOD_(0,"b1",m_set_b1); + FLEXT_ADDMETHOD_(0,"b2",m_set_b2); + FLEXT_ADDMETHOD_(0,"ar",m_ar); + FLEXT_ADDMETHOD_(0,"kr",m_kr); + + //parse arguments + AtomList Args(argc,argv); + + if (Args.Count()<5) + { + post("needs at least 5 arguments"); + return; + } + m_a0 = sc_getfloatarg(Args,0); + m_a1 = sc_getfloatarg(Args,1); + m_a2 = sc_getfloatarg(Args,2); + m_b1 = sc_getfloatarg(Args,3); + m_b2 = sc_getfloatarg(Args,4); + + if(sc_ar(Args)) + { + AddInSignal(); + AddInSignal(); + AddInSignal(); + AddInSignal(); + AddInSignal(); + AddInSignal(); + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_ar)); + } + else // if not given, use control rate + SETSIGFUN(m_signal_fun,SIGFUN(m_signal_kr)); + + AddOutSignal(); + + m_y1 = 0.f; + m_a0 = 0.f; + m_a1 = 0.f; + m_a2 = 0.f; + m_b1 = 0.f; + m_b2 = 0.f; +} + +void SOS_ar::m_signal_ar(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + float *a0 = *(in+1); + float *a1 = *(in+2); + float *a2 = *(in+3); + float *b1 = *(in+4); + float *b2 = *(in+5); + + float y0; + float y1 = m_y1; + float y2 = m_y2; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + ZXP(b1) * y1 + ZXP(b2) * y2; + ZXP(nout) = ZXP(a0) * y0 + ZXP(a1) * y1 + ZXP(a2) * y2; + + y2 = ZXP(nin) + ZXP(b1) * y0 + ZXP(b2) * y1; + ZXP(nout) = ZXP(a0) * y2 + ZXP(a1) * y0 + ZXP(a2) * y1; + + y1 = ZXP(nin) + ZXP(b1) * y2 + ZXP(b2) * y0; + ZXP(nout) = ZXP(a0) * y1 + ZXP(a1) * y2 + ZXP(a2) * y0; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + ZXP(b1) * y1 + ZXP(b2) * y2; + ZXP(nout) = ZXP(a0) * y0 + ZXP(a1) * y1 + ZXP(a2) * y2; + y2 = y1; + y1 = y0; + } + + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); + +} + + +void SOS_ar::m_signal_kr(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + float a0 = m_a0; + float a1 = m_a1; + float a2 = m_a2; + float b1 = m_b1; + float b2 = m_b2; + float a0_slope = (next_a0 - a0) * mFilterSlope; + float a1_slope = (next_a1 - a1) * mFilterSlope; + float a2_slope = (next_a2 - a2) * mFilterSlope; + float b1_slope = (next_b1 - b1) * mFilterSlope; + float b2_slope = (next_b2 - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * y0 + a1 * y1 + a2 * y2; + + y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = a0 * y2 + a1 * y0 + a2 * y1; + + y1 = ZXP(nin) + b1 * y2 + b2 * y0; + ZXP(nout) = a0 * y1 + a1 * y2 + a2 * y0; + + a0 += a0_slope; + a1 += a1_slope; + a2 += a2_slope; + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = a0 * y0 + a1 * y1 + a2 * y2; + y2 = y1; + y1 = y0; + } + + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no kr SOS */ diff --git a/sc4pd/source/TExpRand.cpp b/sc4pd/source/TExpRand.cpp new file mode 100644 index 0000000..a0087e7 --- /dev/null +++ b/sc4pd/source/TExpRand.cpp @@ -0,0 +1,210 @@ +/* sc4pd + TExpRand, TExpRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Assif Tsahar: Open Systems + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ TExpRand~ -------------------------------*/ + +class TExpRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(TExpRand_ar,sc4pd_dsp); + +public: + TExpRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_bang(); + + void m_sethi(float f) + { + hi = f; + ratio = hi / lo; + } + + void m_setlo(float f) + { + lo = f; + ratio = hi / lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + float ratio; + RGen rgen; + + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_F(m_setlo); + FLEXT_CALLBACK_F(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("TExpRand~",TExpRand_ar); + +TExpRand_ar::TExpRand_ar(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + ratio = hi / lo; + + rgen.init(timeseed()); + + AddOutSignal(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TExpRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + m_sample = pow(ratio, rgen.frand()) * lo; +} + + +void TExpRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + +void TExpRand_ar::m_bang() +{ + m_sample = pow(ratio, rgen.frand()) * lo; +} + +/* ------------------------ TExpRand ---------------------------------*/ + +class TExpRand_kr: + public flext_base +{ + FLEXT_HEADER(TExpRand_kr,flext_base); + +public: + TExpRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + void m_bang(); + + void m_sethi(float f) + { + hi = f; + ratio = hi / lo; + } + + void m_setlo(float f) + { + lo = f; + ratio = hi / lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + float ratio; + RGen rgen; + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_F(m_setlo); + FLEXT_CALLBACK_F(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("TExpRand",TExpRand_kr); + +TExpRand_kr::TExpRand_kr(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + ratio = hi / lo; + + rgen.init(timeseed()); + + AddOutFloat(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TExpRand_kr::m_loadbang() +{ + ToOutFloat(0,pow(ratio, rgen.frand()) * lo); +} + +void TExpRand_kr::m_bang() +{ + ToOutFloat(0,pow(ratio, rgen.frand()) * lo); +} diff --git a/sc4pd/source/TIRand.cpp b/sc4pd/source/TIRand.cpp new file mode 100644 index 0000000..1c59a6e --- /dev/null +++ b/sc4pd/source/TIRand.cpp @@ -0,0 +1,210 @@ +/* sc4pd + TIRand, TIRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Sachiko M: Debris + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ TIRand~ -------------------------------*/ + +class TIRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(TIRand_ar,sc4pd_dsp); + +public: + TIRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_bang(); + + void m_sethi(int i) + { + hi = i; + range = hi - lo; + } + + void m_setlo(int i) + { + lo = i; + range = hi - lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + int lo; + int hi; + int range; + RGen rgen; + + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_I(m_setlo); + FLEXT_CALLBACK_I(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("TIRand~",TIRand_ar); + +TIRand_ar::TIRand_ar(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=int(sc_getfloatarg(Args,0)); + hi=int(sc_getfloatarg(Args,1)); + range = hi - lo; + + rgen.init(timeseed()); + + AddOutSignal(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TIRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + m_sample = float(rgen.irand(range) + lo); +} + + +void TIRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + +void TIRand_ar::m_bang() +{ + m_sample = float(rgen.irand(range) + lo); +} + +/* ------------------------ TIRand ---------------------------------*/ + +class TIRand_kr: + public flext_base +{ + FLEXT_HEADER(TIRand_kr,flext_base); + +public: + TIRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + void m_bang(); + + void m_sethi(int i) + { + hi = i; + range = hi - lo; + } + + void m_setlo(int i) + { + lo = i; + range = hi - lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + int lo; + int hi; + int range; + RGen rgen; + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_I(m_setlo); + FLEXT_CALLBACK_I(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("TIRand",TIRand_kr); + +TIRand_kr::TIRand_kr(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=int(sc_getfloatarg(Args,0)); + hi=int(sc_getfloatarg(Args,1)); + range = hi - lo; + + rgen.init(timeseed()); + + AddOutInt(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TIRand_kr::m_loadbang() +{ + ToOutInt(0,rgen.irand(range) + lo); +} + +void TIRand_kr::m_bang() +{ + ToOutInt(0,rgen.irand(range) + lo); +} diff --git a/sc4pd/source/TRand.cpp b/sc4pd/source/TRand.cpp new file mode 100644 index 0000000..d54c196 --- /dev/null +++ b/sc4pd/source/TRand.cpp @@ -0,0 +1,210 @@ +/* sc4pd + TRand, TRand~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Annette Krebs & Taku Sugimoto: A Duo In Berlin + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ TRand~ -------------------------------*/ + +class TRand_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(TRand_ar,sc4pd_dsp); + +public: + TRand_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out); + + void m_bang(); + + void m_sethi(float f) + { + hi = f; + range = hi - lo; + } + + void m_setlo(float f) + { + lo = f; + range = hi - lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float m_sample; + float lo; + float hi; + float range; + RGen rgen; + + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_F(m_setlo); + FLEXT_CALLBACK_F(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("TRand~",TRand_ar); + +TRand_ar::TRand_ar(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + range = hi - lo; + + rgen.init(timeseed()); + + AddOutSignal(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TRand_ar::m_dsp(int n, t_sample *const *in, t_sample *const *out) +{ + m_sample = rgen.frand() * range + lo; +} + + +void TRand_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + float sample = m_sample; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = sample; + } +} + +void TRand_ar::m_bang() +{ + m_sample = rgen.frand() * range + lo; +} + +/* ------------------------ TRand ---------------------------------*/ + +class TRand_kr: + public flext_base +{ + FLEXT_HEADER(TRand_kr,flext_base); + +public: + TRand_kr(int argc, t_atom *argv); + +protected: + void m_loadbang(); + void m_bang(); + + void m_sethi(float f) + { + hi = f; + range = hi - lo; + } + + void m_setlo(float f) + { + lo = f; + range = hi - lo; + } + + void m_seed(int i) + { + rgen.init(i); + } + +private: + float lo; + float hi; + float range; + RGen rgen; + FLEXT_CALLBACK(m_bang); + FLEXT_CALLBACK_F(m_setlo); + FLEXT_CALLBACK_F(m_sethi); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("TRand",TRand_kr); + +TRand_kr::TRand_kr(int argc, t_atom *argv) +{ + AtomList Args(argc,argv); + if (Args.Count() != 2) + { + post("not enough arguments"); + return; + } + lo=sc_getfloatarg(Args,0); + hi=sc_getfloatarg(Args,1); + range = hi - lo; + + rgen.init(timeseed()); + + AddOutFloat(); + + FLEXT_ADDBANG(0,m_bang); + FLEXT_ADDMETHOD_(0,"setlo",m_setlo); + FLEXT_ADDMETHOD_(0,"sethi",m_sethi); + FLEXT_ADDMETHOD_(0,"seed",m_seed); +} + +void TRand_kr::m_loadbang() +{ + ToOutFloat(0,rgen.frand() * range + lo); +} + +void TRand_kr::m_bang() +{ + ToOutFloat(0,rgen.frand() * range + lo); +} diff --git a/sc4pd/source/TwoPole.cpp b/sc4pd/source/TwoPole.cpp new file mode 100644 index 0000000..b37d17f --- /dev/null +++ b/sc4pd/source/TwoPole.cpp @@ -0,0 +1,167 @@ +/* sc4pd + TwoPole~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: VA: Insight + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ TwoPole~ -------------------------------*/ + +class TwoPole_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(TwoPole_ar,sc4pd_dsp); + +public: + TwoPole_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_radius(float f) + { + m_reson=f; + changed = true; + } + + +private: + float m_b1, m_b2, m_y1, m_y2, m_freq, m_reson; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_radius); +}; + +FLEXT_LIB_DSP_V("TwoPole~",TwoPole_ar); + +TwoPole_ar::TwoPole_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"kradius",m_set_radius); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_reson = sc_getfloatarg(Args,1); + changed = false; + + AddOutSignal(); + + m_b1 = 0.f; + m_b2 = 0.f; + m_y1 = 0.f; + m_y2 = 0.f; +} + +void TwoPole_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float y0; + float y1 = m_y1; + float y2 = m_y2; + + if (changed) + { + float b1 = m_b1; + float b2 = m_b2; + float b1_next = 2.f * m_reson * cos(m_freq * mRadiansPerSample); + float b2_next = -(m_reson * m_reson); + float b1_slope = (b1_next - b1) * mFilterSlope; + float b2_slope = (b2_next - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y1 = ZXP(nin) + b1 * y2 + b2 * y0; + + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2; + y2 = y1; + y1 = y0; + } + + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + float b1 = m_b1; + float b2 = m_b2; + + for (int i = 0; i!= mFilterLoops;++i) + { + ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2; + ZXP(nout) = y2 = ZXP(nin) + b1 * y0 + b2 * y1; + ZXP(nout) = y1 = ZXP(nin) + b1 * y2 + b2 * y0; + } + for (int i = 0; i!= mFilterRemain;++i) + { + ZXP(nout) = y0 = ZXP(nin) + b1 * y1 + b2 * y2; + y2 = y1; + y1 = y0; + } + } + m_y1 = zapgremlins(y1); + m_y2 = zapgremlins(y2); +} + +/* no control rate two pole filter */ diff --git a/sc4pd/source/TwoZero.cpp b/sc4pd/source/TwoZero.cpp new file mode 100644 index 0000000..85a7633 --- /dev/null +++ b/sc4pd/source/TwoZero.cpp @@ -0,0 +1,175 @@ +/* sc4pd + TwoZero~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: VA: Insight + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ TwoZero~ -------------------------------*/ + +class TwoZero_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(TwoZero_ar,sc4pd_dsp); + +public: + TwoZero_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + virtual void m_dsp(int n, t_sample *const *in, t_sample *const *out) + { + mRadiansPerSample = sc_radianspersample(); + mFilterSlope = sc_filterslope(); + mFilterLoops = sc_filterloops(); + mFilterRemain = sc_filterremain(); + } + + void m_set_freq(float f) + { + m_freq=f; + changed = true; + } + + void m_set_radius(float f) + { + m_reson=f; + changed = true; + } + + +private: + float m_b1, m_b2, m_x1, m_x2, m_freq, m_reson; + bool changed; + float mRadiansPerSample, mFilterSlope; + int mFilterLoops, mFilterRemain; + + FLEXT_CALLBACK_F(m_set_freq); + FLEXT_CALLBACK_F(m_set_radius); +}; + +FLEXT_LIB_DSP_V("TwoZero~",TwoZero_ar); + +TwoZero_ar::TwoZero_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"kfreq",m_set_freq); + FLEXT_ADDMETHOD_(0,"kradius",m_set_radius); + + //parse arguments + AtomList Args(argc,argv); + + m_freq = sc_getfloatarg(Args,0); + m_reson = sc_getfloatarg(Args,1); + changed = false; + + AddOutSignal(); + + m_b1 = 0.f; + m_b2 = 0.f; + m_x1 = 0.f; + m_x2 = 0.f; +} + +void TwoZero_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + float x0; + float x1 = m_x1; + float x2 = m_x2; + + if (changed) + { + float b1 = m_b1; + float b2 = m_b2; + float b1_next = -2.f * m_reson * cos(m_freq * mRadiansPerSample); + float b2_next = (m_reson * m_reson); + float b1_slope = (b1_next - b1) * mFilterSlope; + float b2_slope = (b2_next - b2) * mFilterSlope; + + for (int i = 0; i!= mFilterLoops;++i) + { + x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * x1 + b2 * x2; + x2 = ZXP(nin); + ZXP(nout) = x2 + b1 * x0 + b2 * x1; + x1 = ZXP(nin); + ZXP(nout) = x1 + b1 * x2 + b2 * x0; + + b1 += b1_slope; + b2 += b2_slope; + } + + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * x1 + b2 * x2; + x2 = x1; + x1 = x0; + } + + m_b1 = b1; + m_b2 = b2; + changed = false; + } + else + { + float b1 = m_b1; + float b2 = m_b2; + + for (int i = 0; i!= mFilterLoops;++i) + { + x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * x1 + b2 * x2; + x2 = ZXP(nin); + ZXP(nout) = x2 + b1 * x0 + b2 * x1; + x1 = ZXP(nin); + ZXP(nout) = x1 + b1 * x2 + b2 * x0; + } + for (int i = 0; i!= mFilterRemain;++i) + { + x0 = ZXP(nin); + ZXP(nout) = x0 + b1 * x1 + b2 * x2; + x2 = x1; + x1 = x0; + } + } + m_x1 = x1; + m_x2 = x2; +} + +/* no control rate twozero filter */ diff --git a/sc4pd/source/WhiteNoise.cpp b/sc4pd/source/WhiteNoise.cpp new file mode 100644 index 0000000..5def735 --- /dev/null +++ b/sc4pd/source/WhiteNoise.cpp @@ -0,0 +1,137 @@ +/* sc4pd + WhiteNoise, WhiteNoise~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Otomo Yoshihide: Ensemble Cathode + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ WhiteNoise~ -------------------------------*/ + +class WhiteNoise_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(WhiteNoise_ar,sc4pd_dsp); + +public: + WhiteNoise_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + RGen rgen; + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_DSP_V("WhiteNoise~",WhiteNoise_ar); + +WhiteNoise_ar::WhiteNoise_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutSignal(); +} + + +void WhiteNoise_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + + RGET; + + for (int i = 0; i!= n;++i) + { + (*(nout)++) = frand2(s1, s2, s3); + } + + RPUT +} + + +/* ------------------------ WhiteNoise ---------------------------------*/ + +class WhiteNoise_kr: + public flext_base +{ + FLEXT_HEADER(WhiteNoise_kr,flext_base); + +public: + WhiteNoise_kr(int argc, t_atom *argv); + +protected: + void m_perform(); + + void m_seed(int i) + { + rgen.init(i); + } + +private: + RGen rgen; + FLEXT_CALLBACK(m_perform); + FLEXT_CALLBACK_I(m_seed); +}; + +FLEXT_LIB_V("WhiteNoise",WhiteNoise_kr); + +WhiteNoise_kr::WhiteNoise_kr(int argc, t_atom *argv) +{ + FLEXT_ADDBANG(0,m_perform); + FLEXT_ADDMETHOD_(0,"seed",m_seed); + + //parse arguments + AtomList Args(argc,argv); + + rgen.init(timeseed()); + + AddOutFloat(); +} + +void WhiteNoise_kr::m_perform() +{ + ToOutFloat(0,rgen.frand2()); +} diff --git a/sc4pd/source/absdif.cpp b/sc4pd/source/absdif.cpp new file mode 100644 index 0000000..e31a3dd --- /dev/null +++ b/sc4pd/source/absdif.cpp @@ -0,0 +1,132 @@ +/* sc4pd + absdif, absdif~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_absdif (float a, float b) +{ + float f=a-b; + return fabsf(f); +} + + +/* ------------------------ absdif~ -----------------------------*/ + +class absdif_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(absdif_ar,sc4pd_dsp); + +public: + absdif_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("absdif~",absdif_ar); + +absdif_ar::absdif_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void absdif_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_absdif( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ absdif ------------------------------*/ + +class absdif_kr + :public flext_base +{ + FLEXT_HEADER(absdif_kr,flext_base); + +public: + absdif_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("absdif",absdif_kr); + +absdif_kr::absdif_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void absdif_kr::m_perform(float f) +{ + ToOutFloat(0,sc_absdif(f,b)); +} + +void absdif_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/amclip.cpp b/sc4pd/source/amclip.cpp new file mode 100644 index 0000000..8bd2edf --- /dev/null +++ b/sc4pd/source/amclip.cpp @@ -0,0 +1,128 @@ +/* sc4pd + amclip, amclip(~) + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ amclip~ -----------------------------*/ + +class amclip_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(amclip_ar,sc4pd_dsp); + +public: + amclip_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("amclip~",amclip_ar); + +amclip_ar::amclip_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void amclip_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_amclip( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ amclip ------------------------------*/ + +class amclip_kr + :public flext_base +{ + FLEXT_HEADER(amclip_kr,flext_base); + +public: + amclip_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("amclip",amclip_kr); + +amclip_kr::amclip_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void amclip_kr::m_perform(float f) +{ + ToOutFloat(0,f*b); +} + +void amclip_kr::m_set(float f) +{ + if (f>0) + b=f; + else + b=0; +} diff --git a/sc4pd/source/difsqr.cpp b/sc4pd/source/difsqr.cpp new file mode 100644 index 0000000..26051f4 --- /dev/null +++ b/sc4pd/source/difsqr.cpp @@ -0,0 +1,131 @@ +/* sc4pd + difsqr, difsqr~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_difsqr (float a, float b) +{ + return a*a-b*b; +} + + +/* ------------------------ difsqr~ -----------------------------*/ + +class difsqr_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(difsqr_ar,sc4pd_dsp); + +public: + difsqr_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("difsqr~",difsqr_ar); + +difsqr_ar::difsqr_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void difsqr_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_difsqr( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ difsqr ------------------------------*/ + +class difsqr_kr + :public flext_base +{ + FLEXT_HEADER(difsqr_kr,flext_base); + +public: + difsqr_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("difsqr",difsqr_kr); + +difsqr_kr::difsqr_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void difsqr_kr::m_perform(float f) +{ + ToOutFloat(0,sc_difsqr(f,b)); +} + +void difsqr_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/excess.cpp b/sc4pd/source/excess.cpp new file mode 100644 index 0000000..eeefb3d --- /dev/null +++ b/sc4pd/source/excess.cpp @@ -0,0 +1,124 @@ +/* sc4pd + excess, excess~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky + +*/ + +#include "sc4pd.hpp" + +/* ------------------------ excess~ -----------------------------*/ + +class excess_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(excess_ar,sc4pd_dsp); + +public: + excess_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("excess~",excess_ar); + +excess_ar::excess_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void excess_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_excess( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ excess ------------------------------*/ + +class excess_kr + :public flext_base +{ + FLEXT_HEADER(excess_kr,flext_base); + +public: + excess_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("excess",excess_kr); + +excess_kr::excess_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void excess_kr::m_perform(float f) +{ + ToOutFloat(0,sc_excess(f,b)); +} + +void excess_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/fftlib.c b/sc4pd/source/fftlib.c new file mode 100644 index 0000000..4bbdcb1 --- /dev/null +++ b/sc4pd/source/fftlib.c @@ -0,0 +1,3306 @@ +/* FFT library */ +/* Library of in-place fast fourier transforms */ +/* Forward and inverse complex transforms */ +/* and real forward transform */ +/* Optimized for RISC processors with many registers */ +/* Version 1.1 John Green NUWC New London CT January 96 */ +/* Version 1.1 renamed as fftlib from fftbig */ +/* Version 1.1 removed (float *)((char *) ptr) optimization */ +/* Version 1.0 John Green NUWC New London CT December 95 */ +/* (John Green) green_jt@vsdec.nl.nuwc.navy.mil */ +/* green_jt@vsdec.nl.nuwc.navy.mil */ + +#include <math.h> +#include "fftlib.h" + +#define MAXMROOT 9 /* 2^(MAXMROOT-1) = # of elements in BRcnt */ + +/* Bit reversed counter */ +static const unsigned char BRcnt[256] = { + 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, + 48, 176, 112, 240, 8, 136, 72, 200, 40, 168, 104, 232, + 24, 152, 88, 216, 56, 184, 120, 248, 4, 132, 68, 196, + 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244, + 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, + 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, 98, 226, + 18, 146, 82, 210, 50, 178, 114, 242, 10, 138, 74, 202, + 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250, + 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, + 54, 182, 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, + 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, 65, 193, + 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241, + 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, + 57, 185, 121, 249, 5, 133, 69, 197, 37, 165, 101, 229, + 21, 149, 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, + 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253, + 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, + 51, 179, 115, 243, 11, 139, 75, 203, 43, 171, 107, 235, + 27, 155, 91, 219, 59, 187, 123, 251, 7, 135, 71, 199, + 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, + 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, + 63, 191, 127, 255 }; + +/* Table of powers of 2 */ +static const long Ntbl[21] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, + 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576}; + +long FFTInit(long *fftMptr, long fftN, float *Utbl){ +/* Compute cosine table and check size for complex ffts */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ +long i1, ErrVal; +ErrVal = 0; +*fftMptr = (long)(log(fftN)/log(2.0) + 0.5); +if ((*fftMptr >= 3) & (*fftMptr <= 19) & (int)(pow(2,*fftMptr)+.5) == fftN) + for (i1 = 0; i1 <= fftN/4; i1++) + Utbl[i1] = cos( ( 3.1415926535897932384626433832795 * 2.0 * i1 ) / fftN ); +else + ErrVal = 1; +return ErrVal; +} + +long rFFTInit(long *fftMptr, long fftN, float *Utbl){ +/* Compute cosine table and check size for a real input fft */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ +long i1, ErrVal; +ErrVal = 0; +*fftMptr = (long)(log(fftN)/log(2.0) + 0.5); +if ((*fftMptr >= 4) & (*fftMptr <= 20) & (int)(pow(2,*fftMptr)+.5) == fftN) + + for (i1 = 0; i1 <= fftN/4; i1++) + Utbl[i1] = cos( ( 3.1415926535897932384626433832795 * 2.0 * i1 ) / fftN ); +else + ErrVal = 1; +return ErrVal; +} + +void ffts(float *ioptr, long M, long Rows, float *Utbl){ +/* Compute in-place complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +long Flyinc; +long FlyOffsetA; +long FlyOffsetAIm; +long FlyOffsetB; +long FlyOffsetBIm; +long NsameU1; +long NsameU2; +long NsameU4; +long diffUcnt; +long LoopCnt; + +float scale; +float fly0r; +float fly0i; +float fly1r; +float fly1i; +float fly2r; +float fly2i; +float fly3r; +float fly3i; +float fly4r; +float fly4i; +float fly5r; +float fly5i; +float fly6r; +float fly6i; +float fly7r; +float fly7i; +float U0r; +float U0i; +float U1r; +float U1i; +float U2r; +float U2i; +float U3r; +float U3i; +float t0r; +float t0i; +float t1r; +float t1i; + +float *fly0P; +float *fly1P; +float *fly2P; +float *fly3P; + +float *U0rP; +float *U0iP; +float *U1rP; +float *U1iP; +float *U2rP; +float *U2iP; +float *IOP; +long U3offset; + +long stage; +long NdiffU; +long LoopN; + +const long BRshift = MAXMROOT - (M>>1); +const long Nrems2 = Ntbl[M-(M>>1)+1]; +const long Nroot_1_ColInc = (Ntbl[M-1]-Ntbl[M-(M>>1)])*2; + +scale = 2.0; +for (;Rows>0;Rows--){ + +FlyOffsetA = Ntbl[M] * (2/2); +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetB = FlyOffsetA + 2; +FlyOffsetBIm = FlyOffsetB + 1; + +/* BitrevR2 ** bit reverse and first radix 2 stage ******/ + +for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){ + for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){ + LoopCnt = (Ntbl[(M>>1)-1]-1); + fly0P = ioptr+ Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage; + IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage; + fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2); + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + for (; LoopCnt > LoopN;){ + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + fly4r = *(fly1P); + fly4i = *(fly1P+1); + fly5r = *(fly1P+FlyOffsetA); + fly5i = *(fly1P+FlyOffsetAIm); + fly6r = *(fly1P+2); + fly6i = *(fly1P+(2+1)); + fly7r = *(fly1P+FlyOffsetB); + fly7i = *(fly1P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + fly0r = fly4r + fly5r; + fly0i = fly4i + fly5i; + fly5r = fly4r - fly5r; + fly5i = fly4i - fly5i; + fly2r = fly6r + fly7r; + fly2i = fly6i + fly7i; + fly7r = fly6r - fly7r; + fly7i = fly6i - fly7i; + + *(fly1P) = t0r; + *(fly1P+1) = t0i; + *(fly1P+2) = fly1r; + *(fly1P+(2+1)) = fly1i; + *(fly1P+FlyOffsetA) = t1r; + *(fly1P+FlyOffsetAIm) = t1i; + *(fly1P+FlyOffsetB) = fly3r; + *(fly1P+FlyOffsetBIm) = fly3i; + *(fly0P) = fly0r; + *(fly0P+1) = fly0i; + *(fly0P+2) = fly5r; + *(fly0P+(2+1)) = fly5i; + *(fly0P+FlyOffsetA) = fly2r; + *(fly0P+FlyOffsetAIm) = fly2i; + *(fly0P+FlyOffsetB) = fly7r; + *(fly0P+FlyOffsetBIm) = fly7i; + + fly0P -= Nrems2; + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + LoopCnt -= 1; + fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2)); + }; + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + + *(fly0P) = t0r; + *(fly0P+1) = t0i; + *(fly0P+2) = fly1r; + *(fly0P+(2+1)) = fly1i; + *(fly0P+FlyOffsetA) = t1r; + *(fly0P+FlyOffsetAIm) = t1i; + *(fly0P+FlyOffsetB) = fly3r; + *(fly0P+FlyOffsetBIm) = fly3i; + + }; +}; + + + +/**** FFTC **************/ + +NdiffU = 2; +Flyinc = (NdiffU); + +NsameU4 = Ntbl[M]/4; +LoopN = Ntbl[M-3]; + +stage = ((M-1)/3); +if ( (M-1-(stage * 3)) != 0 ){ + FlyOffsetA = Flyinc << 2; + FlyOffsetB = FlyOffsetA << 1; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + if ( (M-1-(stage * 3)) == 1 ){ + /* 1 radix 2 stage */ + + IOP = ioptr; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 + t1 - - t1 + f2 - 1- f5 + f1 - -i- f7 + f4 - - f4 + f0 - - f0 + f6 - 1- f2 + f3 - -i- f1 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r - fly1i; + fly7i = t1i + fly1r; + t1r = t1r + fly1i; + t1i = t1i - fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r - fly3i; + fly1i = fly0i + fly3r; + fly0r = fly0r + fly3i; + fly0i = fly0i - fly3r; + + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly0P + FlyOffsetA) = fly4r; + *(fly0P + FlyOffsetAIm) = fly4i; + *(fly3P + FlyOffsetA) = fly1r; + *(fly3P + FlyOffsetAIm) = fly1i; + *(fly1P + FlyOffsetA) = fly0r; + *(fly1P + FlyOffsetAIm) = fly0i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + + NsameU4 >>= 1; + LoopN >>= 1; + NdiffU <<= 1; + Flyinc = Flyinc << 1; + } + else{ + /* 1 radix 4 stage */ + IOP = ioptr; + + U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */ + U3i = U3r; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 - - t0 + t1 - - t1 - - t1 + f2 - 1- f5 - - f5 + f1 - -i- f7 - - f7 + f4 - - f4 - 1- f6 + f0 - - f0 -U3 - f3 + f6 - 1- f2 - -i- f4 + f3 - -i- f1 -U3a- f2 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r - fly1i; + fly7i = t1i + fly1r; + t1r = t1r + fly1i; + t1i = t1i - fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r - fly3i; + fly1i = fly0i + fly3r; + fly0r = fly0r + fly3i; + fly0i = fly0i - fly3r; + + + fly6r = t0r - fly4r; + fly6i = t0i - fly4i; + t0r = t0r + fly4r; + t0i = t0i + fly4i; + + fly3r = fly5r - fly2i; + fly3i = fly5i + fly2r; + fly5r = fly5r + fly2i; + fly5i = fly5i - fly2r; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly2r = fly7r + U3i * fly1r; + fly2r = fly2r - U3r * fly1i; + fly2i = fly7i + U3r * fly1r; + fly2i = fly2i + U3i * fly1i; + fly7r = scale * fly7r - fly2r; + fly7i = scale * fly7i - fly2i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P + FlyOffsetA) = fly3r; + *(fly2P + FlyOffsetAIm) = fly3i; + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly3P + FlyOffsetA) = fly2r; + *(fly3P + FlyOffsetAIm) = fly2i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + + NsameU4 >>= 2; + LoopN >>= 2; + NdiffU <<= 2; + Flyinc = Flyinc << 2; + }; +}; + +NsameU2 = NsameU4 >> 1; +NsameU1 = NsameU2 >> 1; +Flyinc <<= 1; +FlyOffsetA = Flyinc << 2; +FlyOffsetB = FlyOffsetA << 1; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetBIm = FlyOffsetB + 1; +LoopN >>= 1; +/* ****** RADIX 8 Stages */ +for (stage = stage<<1; stage > 0 ; stage--){ + + /* an fft stage is done in two parts to ease use of the single quadrant cos table */ + +/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */ + if(!(stage&1)){ + U0rP = &Utbl[0]; + U0iP = &Utbl[Ntbl[M-2]]; + U1rP = U0rP; + U1iP = U0iP; + U2rP = U0rP; + U2iP = U0iP; + U3offset = (Ntbl[M]) / 8; + + IOP = ioptr; + + U0r = *U0rP, + U0i = *U0iP; + U1r = *U1rP, + U1i = *U1iP; + U2r = *U2rP, + U2i = *U2iP; + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + } + + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + for (diffUcnt = (NdiffU)>>1; diffUcnt != 0; diffUcnt--){ + + /* Butterflys */ + /* + f0 - - t0 - - t0 - - t0 + f1 -U0 - t1 - - t1 - - t1 + f2 - - f2 -U1 - f5 - - f3 + f3 -U0 - f1 -U1a- f7 - - f7 + f4 - - f4 - - f4 -U2 - f6 + f5 -U0 - f0 - - f0 -U3 - f4 + f6 - - f6 -U1 - f2 -U2a- f2 + f7 -U0 - f3 -U1a- f1 -U3a- f5 + */ + + fly0r = *(IOP); + fly0i = *(IOP+1); + fly1r = *(fly1P); + fly1i = *(fly1P+1); + + for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){ + + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r - U0i * fly1i; + t1i = fly0i + U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r - U0i * fly3i; + fly1i = fly2i + U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r - U0i * fly5i; + fly0i = fly4i + U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r - U0i * fly7i; + fly3i = fly6i + U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r - U1i * fly2i; + fly5i = t0i + U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r - U1r * fly1i; + fly7i = t1i + U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r - U1i * fly6i; + fly2i = fly4i + U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r - U1r * fly3i; + fly1i = fly0i + U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r - U2i * fly4i; + fly6i = t0i + U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r + U2r * fly2i; + fly3i = fly5i - U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r - U3r * fly1i; + fly5i = fly7i + U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + + fly0r = *(fly0P + FlyOffsetB); + fly0i = *(fly0P + FlyOffsetBIm); + + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + fly1r = *(fly1P + FlyOffsetB); + fly1i = *(fly1P + FlyOffsetBIm); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r - U0i * fly1i; + t1i = fly0i + U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r - U0i * fly3i; + fly1i = fly2i + U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r - U0i * fly5i; + fly0i = fly4i + U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r - U0i * fly7i; + fly3i = fly6i + U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r - U1i * fly2i; + fly5i = t0i + U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r - U1r * fly1i; + fly7i = t1i + U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r - U1i * fly6i; + fly2i = fly4i + U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r - U1r * fly3i; + fly1i = fly0i + U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + U0i = *(U0iP = (U0iP - NsameU4)); + U0r = *(U0rP = (U0rP + NsameU4)); + U1r = *(U1rP = (U1rP + NsameU2)); + U1i = *(U1iP = (U1iP - NsameU2)); + if(stage&1) + U0r = -U0r; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r - U2i * fly4i; + fly6i = t0i + U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r + U2r * fly2i; + fly3i = fly5i - U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r - U3r * fly1i; + fly5i = fly7i + U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + + U2r = *(U2rP = (U2rP + NsameU1)); + U2i = *(U2iP = (U2iP - NsameU1)); + + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + IOP = IOP + 2; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + }; + NsameU4 = -NsameU4; + + if(stage&1){ + LoopN >>= 3; + NsameU1 >>= 3; + NsameU2 >>= 3; + NsameU4 >>= 3; + NdiffU <<= 3; + Flyinc <<= 3; + FlyOffsetA <<= 3; + FlyOffsetB <<= 3; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + } +} +ioptr += 2*Ntbl[M]; +} +} + +void iffts(float *ioptr, long M, long Rows, float *Utbl){ +/* Compute in-place inverse complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +long Flyinc; +long FlyOffsetA; +long FlyOffsetAIm; +long FlyOffsetB; +long FlyOffsetBIm; +long NsameU1; +long NsameU2; +long NsameU4; +long diffUcnt; +long LoopCnt; + +float scale; +float fly0r; +float fly0i; +float fly1r; +float fly1i; +float fly2r; +float fly2i; +float fly3r; +float fly3i; +float fly4r; +float fly4i; +float fly5r; +float fly5i; +float fly6r; +float fly6i; +float fly7r; +float fly7i; +float U0r; +float U0i; +float U1r; +float U1i; +float U2r; +float U2i; +float U3r; +float U3i; +float t0r; +float t0i; +float t1r; +float t1i; + +float *fly0P; +float *fly1P; +float *fly2P; +float *fly3P; +float *U0rP; +float *U0iP; +float *U1rP; +float *U1iP; +float *U2rP; +float *U2iP; +float *IOP; +long U3offset; + +long stage; +long NdiffU; +long LoopN; + +const long BRshift = MAXMROOT - (M>>1); +const long Nrems2 = Ntbl[M-(M>>1)+1]; +const long Nroot_1_ColInc = (Ntbl[M-1]-Ntbl[M-(M>>1)])*2; + +for (;Rows>0;Rows--){ + +FlyOffsetA = Ntbl[M] * 2/2; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetB = FlyOffsetA + 2; +FlyOffsetBIm = FlyOffsetB + 1; + +/* BitrevR2 ** bit reverse and first radix 2 stage ******/ + +scale = 1./Ntbl[M]; +for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){ + for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){ + LoopCnt = (Ntbl[(M>>1)-1]-1); + fly0P = ioptr + Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage; + IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage; + fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2); + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + for (; LoopCnt > LoopN;){ + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + fly4r = *(fly1P); + fly4i = *(fly1P+1); + fly5r = *(fly1P+FlyOffsetA); + fly5i = *(fly1P+FlyOffsetAIm); + fly6r = *(fly1P+2); + fly6i = *(fly1P+(2+1)); + fly7r = *(fly1P+FlyOffsetB); + fly7i = *(fly1P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + fly0r = fly4r + fly5r; + fly0i = fly4i + fly5i; + fly5r = fly4r - fly5r; + fly5i = fly4i - fly5i; + fly2r = fly6r + fly7r; + fly2i = fly6i + fly7i; + fly7r = fly6r - fly7r; + fly7i = fly6i - fly7i; + + *(fly1P) = scale*t0r; + *(fly1P+1) = scale*t0i; + *(fly1P+2) = scale*fly1r; + *(fly1P+(2+1)) = scale*fly1i; + *(fly1P+FlyOffsetA) = scale*t1r; + *(fly1P+FlyOffsetAIm) = scale*t1i; + *(fly1P+FlyOffsetB) = scale*fly3r; + *(fly1P+FlyOffsetBIm) = scale*fly3i; + *(fly0P) = scale*fly0r; + *(fly0P+1) = scale*fly0i; + *(fly0P+2) = scale*fly5r; + *(fly0P+(2+1)) = scale*fly5i; + *(fly0P+FlyOffsetA) = scale*fly2r; + *(fly0P+FlyOffsetAIm) = scale*fly2i; + *(fly0P+FlyOffsetB) = scale*fly7r; + *(fly0P+FlyOffsetBIm) = scale*fly7i; + + fly0P -= Nrems2; + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + LoopCnt -= 1; + fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2)); + }; + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + + *(fly0P) = scale*t0r; + *(fly0P+1) = scale*t0i; + *(fly0P+2) = scale*fly1r; + *(fly0P+(2+1)) = scale*fly1i; + *(fly0P+FlyOffsetA) = scale*t1r; + *(fly0P+FlyOffsetAIm) = scale*t1i; + *(fly0P+FlyOffsetB) = scale*fly3r; + *(fly0P+FlyOffsetBIm) = scale*fly3i; + + }; +}; + +/**** FFTC **************/ + +scale = 2.0; + +NdiffU = 2; +Flyinc = (NdiffU); + +NsameU4 = Ntbl[M]/4; +LoopN = Ntbl[M-3]; + +stage = ((M-1)/3); +if ( (M-1-(stage * 3)) != 0 ){ + FlyOffsetA = Flyinc << 2; + FlyOffsetB = FlyOffsetA << 1; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + if ( (M-1-(stage * 3)) == 1 ){ + /* 1 radix 2 stage */ + + IOP = ioptr; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 + t1 - - t1 + f2 - 1- f5 + f1 - -i- f7 + f4 - - f4 + f0 - - f0 + f6 - 1- f2 + f3 - -i- f1 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r + fly1i; + fly7i = t1i - fly1r; + t1r = t1r - fly1i; + t1i = t1i + fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r + fly3i; + fly1i = fly0i - fly3r; + fly0r = fly0r - fly3i; + fly0i = fly0i + fly3r; + + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly0P + FlyOffsetA) = fly4r; + *(fly0P + FlyOffsetAIm) = fly4i; + *(fly3P + FlyOffsetA) = fly1r; + *(fly3P + FlyOffsetAIm) = fly1i; + *(fly1P + FlyOffsetA) = fly0r; + *(fly1P + FlyOffsetAIm) = fly0i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + + NsameU4 >>= 1; + LoopN >>= 1; + NdiffU <<= 1; + Flyinc = Flyinc << 1; + } + else{ + /* 1 radix 4 stage */ + IOP = ioptr; + + U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */ + U3i = U3r; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 - - t0 + t1 - - t1 - - t1 + f2 - 1- f5 - - f5 + f1 - -i- f7 - - f7 + f4 - - f4 - 1- f6 + f0 - - f0 -U3 - f3 + f6 - 1- f2 - -i- f4 + f3 - -i- f1 -U3a- f2 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r + fly1i; + fly7i = t1i - fly1r; + t1r = t1r - fly1i; + t1i = t1i + fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r + fly3i; + fly1i = fly0i - fly3r; + fly0r = fly0r - fly3i; + fly0i = fly0i + fly3r; + + fly6r = t0r - fly4r; + fly6i = t0i - fly4i; + t0r = t0r + fly4r; + t0i = t0i + fly4i; + + fly3r = fly5r + fly2i; + fly3i = fly5i - fly2r; + fly5r = fly5r - fly2i; + fly5i = fly5i + fly2r; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly2r = fly7r + U3i * fly1r; + fly2r = fly2r + U3r * fly1i; + fly2i = fly7i - U3r * fly1r; + fly2i = fly2i + U3i * fly1i; + fly7r = scale * fly7r - fly2r; + fly7i = scale * fly7i - fly2i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P + FlyOffsetA) = fly3r; + *(fly2P + FlyOffsetAIm) = fly3i; + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly3P + FlyOffsetA) = fly2r; + *(fly3P + FlyOffsetAIm) = fly2i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + + NsameU4 >>= 2; + LoopN >>= 2; + NdiffU <<= 2; + Flyinc = Flyinc << 2; + }; +}; + +NsameU2 = NsameU4 >> 1; +NsameU1 = NsameU2 >> 1; +Flyinc <<= 1; +FlyOffsetA = Flyinc << 2; +FlyOffsetB = FlyOffsetA << 1; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetBIm = FlyOffsetB + 1; +LoopN >>= 1; + +/* ****** RADIX 8 Stages */ +for (stage = stage<<1; stage > 0 ; stage--){ + + /* an fft stage is done in two parts to ease use of the single quadrant cos table */ + +/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */ + if(!(stage&1)){ + U0rP = &Utbl[0]; + U0iP = &Utbl[Ntbl[M-2]]; + U1rP = U0rP; + U1iP = U0iP; + U2rP = U0rP; + U2iP = U0iP; + U3offset = (Ntbl[M]) / 8; + + IOP = ioptr; + + U0r = *U0rP, + U0i = *U0iP; + U1r = *U1rP, + U1i = *U1iP; + U2r = *U2rP, + U2i = *U2iP; + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + } + + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + for (diffUcnt = (NdiffU)>>1; diffUcnt > 0; diffUcnt--){ + + /* Butterflys */ + /* + f0 - - t0 - - t0 - - t0 + f1 -U0 - t1 - - t1 - - t1 + f2 - - f2 -U1 - f5 - - f3 + f3 -U0 - f1 -U1a- f7 - - f7 + f4 - - f4 - - f4 -U2 - f6 + f5 -U0 - f0 - - f0 -U3 - f4 + f6 - - f6 -U1 - f2 -U2a- f2 + f7 -U0 - f3 -U1a- f1 -U3a- f5 + */ + + fly0r = *(IOP); + fly0i = *(IOP+1); + fly1r = *(fly1P); + fly1i = *(fly1P+1); + + for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){ + + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r + U0i * fly1i; + t1i = fly0i - U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r + U0i * fly3i; + fly1i = fly2i - U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r + U0i * fly5i; + fly0i = fly4i - U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r + U0i * fly7i; + fly3i = fly6i - U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r + U1i * fly2i; + fly5i = t0i - U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r + U1r * fly1i; + fly7i = t1i - U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r + U1i * fly6i; + fly2i = fly4i - U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r + U1r * fly3i; + fly1i = fly0i - U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r + U2i * fly4i; + fly6i = t0i - U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r - U2r * fly2i; + fly3i = fly5i + U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r + U3r * fly1i; + fly5i = fly7i - U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + + fly0r = *(fly0P + FlyOffsetB); + fly0i = *(fly0P + FlyOffsetBIm); + + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + fly1r = *(fly1P + FlyOffsetB); + fly1i = *(fly1P + FlyOffsetBIm); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r + U0i * fly1i; + t1i = fly0i - U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r + U0i * fly3i; + fly1i = fly2i - U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r + U0i * fly5i; + fly0i = fly4i - U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r + U0i * fly7i; + fly3i = fly6i - U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r + U1i * fly2i; + fly5i = t0i - U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r + U1r * fly1i; + fly7i = t1i - U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r + U1i * fly6i; + fly2i = fly4i - U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r + U1r * fly3i; + fly1i = fly0i - U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + U0i = *(U0iP = (U0iP - NsameU4)); + U0r = *(U0rP = (U0rP + NsameU4)); + U1r = *(U1rP = (U1rP + NsameU2)); + U1i = *(U1iP = (U1iP - NsameU2)); + if(stage&1) + U0r = - U0r; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r + U2i * fly4i; + fly6i = t0i - U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r - U2r * fly2i; + fly3i = fly5i + U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r + U3r * fly1i; + fly5i = fly7i - U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + + U2r = *(U2rP = (U2rP + NsameU1)); + U2i = *(U2iP = (U2iP - NsameU1)); + + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + IOP = IOP + 2; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + }; + NsameU4 = -NsameU4; + + if(stage&1){ + LoopN >>= 3; + NsameU1 >>= 3; + NsameU2 >>= 3; + NsameU4 >>= 3; + NdiffU <<= 3; + Flyinc = Flyinc << 3; + FlyOffsetA <<= 3; + FlyOffsetB <<= 3; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + } +} +ioptr += 2*Ntbl[M]; +} +} + +/* rffts */ +/* compute multiple real input FFTs on 'Rows' consecutively stored arrays */ +/* ioptr = pointer to the data in and out */ +/* M = log2 of fft size */ +/* Rows = number of FFTs to compute */ +/* Utbl = Pointer to cosine table */ + +void rffts(float *ioptr, long M, long Rows, float *Utbl){ +/* Compute in-place real fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = real input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ + +long Flyinc; +long FlyOffsetA; +long FlyOffsetAIm; +long FlyOffsetB; +long FlyOffsetBIm; +long NsameU1; +long NsameU2; +long NsameU4; +long diffUcnt; +long LoopCnt; +float scale; +float fly0r; +float fly0i; +float fly1r; +float fly1i; +float fly2r; +float fly2i; +float fly3r; +float fly3i; +float fly4r; +float fly4i; +float fly5r; +float fly5i; +float fly6r; +float fly6i; +float fly7r; +float fly7i; +float U0r; +float U0i; +float U1r; +float U1i; +float U2r; +float U2i; +float U3r; +float U3i; +float t0r; +float t0i; +float t1r; +float t1i; + +float *fly0P; +float *fly1P; +float *fly2P; +float *fly3P; + +float *U0rP; +float *U0iP; +float *U1rP; +float *U1iP; +float *U2rP; +float *U2iP; +float *IOP; +long U3offset; + +long stage; +long NdiffU; +long LoopN; + +const long BRshift = MAXMROOT - ((M-1)>>1); /* for RFFT */ +const long Nrems2 = Ntbl[(M-1)-((M-1)>>1)+1]; /* for RFFT */ +const long Nroot_1_ColInc = (Ntbl[(M-1)-1]-Ntbl[(M-1)-((M-1)>>1)])*2; /* for RFFT */ + +for (;Rows>0;Rows--){ + +M=M-1; /* for RFFT */ + +FlyOffsetA = Ntbl[M] * 2/2; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetB = FlyOffsetA + 2; +FlyOffsetBIm = FlyOffsetB + 1; + +/* BitrevR2 ** bit reverse shuffle and first radix 2 stage ******/ + +scale = 0.5; +for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){ + for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){ + LoopCnt = (Ntbl[(M>>1)-1]-1); + fly0P = ioptr + Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage; + IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage; + fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2); + fly0r = *fly0P; + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + for (; LoopCnt > LoopN;){ + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + fly4r = *fly1P; + fly4i = *(fly1P+1); + fly5r = *(fly1P+FlyOffsetA); + fly5i = *(fly1P+FlyOffsetAIm); + fly6r = *(fly1P+2); + fly6i = *(fly1P+(2+1)); + fly7r = *(fly1P+FlyOffsetB); + fly7i = *(fly1P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + fly0r = fly4r + fly5r; + fly0i = fly4i + fly5i; + fly5r = fly4r - fly5r; + fly5i = fly4i - fly5i; + fly2r = fly6r + fly7r; + fly2i = fly6i + fly7i; + fly7r = fly6r - fly7r; + fly7i = fly6i - fly7i; + + *fly1P = scale*t0r; + *(fly1P+1) = scale*t0i; + *(fly1P+2) = scale*fly1r; + *(fly1P+(2+1)) = scale*fly1i; + *(fly1P+FlyOffsetA) = scale*t1r; + *(fly1P+FlyOffsetAIm) = scale*t1i; + *(fly1P+FlyOffsetB) = scale*fly3r; + *(fly1P+FlyOffsetBIm) = scale*fly3i; + *fly0P = scale*fly0r; + *(fly0P+1) = scale*fly0i; + *(fly0P+2) = scale*fly5r; + *(fly0P+(2+1)) = scale*fly5i; + *(fly0P+FlyOffsetA) = scale*fly2r; + *(fly0P+FlyOffsetAIm) = scale*fly2i; + *(fly0P+FlyOffsetB) = scale*fly7r; + *(fly0P+FlyOffsetBIm) = scale*fly7i; + + fly0P -= Nrems2; + fly0r = *fly0P; + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + LoopCnt -= 1; + fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2)); + }; + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + + *fly0P = scale*t0r; + *(fly0P+1) = scale*t0i; + *(fly0P+2) = scale*fly1r; + *(fly0P+(2+1)) = scale*fly1i; + *(fly0P+FlyOffsetA) = scale*t1r; + *(fly0P+FlyOffsetAIm) = scale*t1i; + *(fly0P+FlyOffsetB) = scale*fly3r; + *(fly0P+FlyOffsetBIm) = scale*fly3i; + + }; +}; + + + +/**** FFTC **************/ + +scale = 2.0; + +NdiffU = 2; +Flyinc = (NdiffU); + +NsameU4 = Ntbl[M+1]/4; /* for RFFT */ +LoopN = Ntbl[M-3]; + +stage = ((M-1)/3); +if ( (M-1-(stage * 3)) != 0 ){ + FlyOffsetA = Flyinc << 2; + FlyOffsetB = FlyOffsetA << 1; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + if ( (M-1-(stage * 3)) == 1 ){ + /* 1 radix 2 stage */ + + IOP = ioptr; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 + t1 - - t1 + f2 - 1- f5 + f1 - -i- f7 + f4 - - f4 + f0 - - f0 + f6 - 1- f2 + f3 - -i- f1 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r - fly1i; + fly7i = t1i + fly1r; + t1r = t1r + fly1i; + t1i = t1i - fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r - fly3i; + fly1i = fly0i + fly3r; + fly0r = fly0r + fly3i; + fly0i = fly0i - fly3r; + + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly0P + FlyOffsetA) = fly4r; + *(fly0P + FlyOffsetAIm) = fly4i; + *(fly3P + FlyOffsetA) = fly1r; + *(fly3P + FlyOffsetAIm) = fly1i; + *(fly1P + FlyOffsetA) = fly0r; + *(fly1P + FlyOffsetAIm) = fly0i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + + NsameU4 >>= 1; + LoopN >>= 1; + NdiffU <<= 1; + Flyinc = Flyinc << 1; + } + else{ + /* 1 radix 4 stage */ + IOP = ioptr; + + U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */ + U3i = U3r; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 - - t0 + t1 - - t1 - - t1 + f2 - 1- f5 - - f5 + f1 - -i- f7 - - f7 + f4 - - f4 - 1- f6 + f0 - - f0 -U3 - f3 + f6 - 1- f2 - -i- f4 + f3 - -i- f1 -U3a- f2 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r - fly1i; + fly7i = t1i + fly1r; + t1r = t1r + fly1i; + t1i = t1i - fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r - fly3i; + fly1i = fly0i + fly3r; + fly0r = fly0r + fly3i; + fly0i = fly0i - fly3r; + + fly6r = t0r - fly4r; + fly6i = t0i - fly4i; + t0r = t0r + fly4r; + t0i = t0i + fly4i; + + fly3r = fly5r - fly2i; + fly3i = fly5i + fly2r; + fly5r = fly5r + fly2i; + fly5i = fly5i - fly2r; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly2r = fly7r + U3i * fly1r; + fly2r = fly2r - U3r * fly1i; + fly2i = fly7i + U3r * fly1r; + fly2i = fly2i + U3i * fly1i; + fly7r = scale * fly7r - fly2r; + fly7i = scale * fly7i - fly2i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P + FlyOffsetA) = fly3r; + *(fly2P + FlyOffsetAIm) = fly3i; + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly3P + FlyOffsetA) = fly2r; + *(fly3P + FlyOffsetAIm) = fly2i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + + NsameU4 >>= 2; + LoopN >>= 2; + NdiffU <<= 2; + Flyinc = Flyinc << 2; + }; +}; + +NsameU2 = NsameU4 >> 1; +NsameU1 = NsameU2 >> 1; +Flyinc <<= 1; +FlyOffsetA = Flyinc << 2; +FlyOffsetB = FlyOffsetA << 1; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetBIm = FlyOffsetB + 1; +LoopN >>= 1; + +/* ****** RADIX 8 Stages */ +for (stage = stage<<1; stage > 0 ; stage--){ + + /* an fft stage is done in two parts to ease use of the single quadrant cos table */ + +/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */ + if(!(stage&1)){ + U0rP = &Utbl[0]; + U0iP = &Utbl[Ntbl[M-1]]; /* for RFFT */ + U1rP = U0rP; + U1iP = U0iP; + U2rP = U0rP; + U2iP = U0iP; + U3offset = (Ntbl[M+1]) / 8; /* for RFFT */ + + IOP = ioptr; + + U0r = *U0rP, + U0i = *U0iP; + U1r = *U1rP, + U1i = *U1iP; + U2r = *U2rP, + U2i = *U2iP; + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + } + + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + for (diffUcnt = (NdiffU)>>1; diffUcnt > 0; diffUcnt--){ + + /* Butterflys */ + /* + f0 - - t0 - - t0 - - t0 + f1 -U0 - t1 - - t1 - - t1 + f2 - - f2 -U1 - f5 - - f3 + f3 -U0 - f1 -U1a- f7 - - f7 + f4 - - f4 - - f4 -U2 - f6 + f5 -U0 - f0 - - f0 -U3 - f4 + f6 - - f6 -U1 - f2 -U2a- f2 + f7 -U0 - f3 -U1a- f1 -U3a- f5 + */ + + fly0r = *(IOP); + fly0i = *(IOP+1); + fly1r = *(fly1P); + fly1i = *(fly1P+1); + + for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){ + + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r - U0i * fly1i; + t1i = fly0i + U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r - U0i * fly3i; + fly1i = fly2i + U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r - U0i * fly5i; + fly0i = fly4i + U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r - U0i * fly7i; + fly3i = fly6i + U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r - U1i * fly2i; + fly5i = t0i + U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r - U1r * fly1i; + fly7i = t1i + U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r - U1i * fly6i; + fly2i = fly4i + U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r - U1r * fly3i; + fly1i = fly0i + U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r - U2i * fly4i; + fly6i = t0i + U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r + U2r * fly2i; + fly3i = fly5i - U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r - U3r * fly1i; + fly5i = fly7i + U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + + fly0r = *(fly0P + FlyOffsetB); + fly0i = *(fly0P + FlyOffsetBIm); + + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + fly1r = *(fly1P + FlyOffsetB); + fly1i = *(fly1P + FlyOffsetBIm); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r - U0i * fly1i; + t1i = fly0i + U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r - U0i * fly3i; + fly1i = fly2i + U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r - U0i * fly5i; + fly0i = fly4i + U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r - U0i * fly7i; + fly3i = fly6i + U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r - U1i * fly2i; + fly5i = t0i + U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r - U1r * fly1i; + fly7i = t1i + U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r - U1i * fly6i; + fly2i = fly4i + U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r - U1r * fly3i; + fly1i = fly0i + U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + U0i = *(U0iP = (U0iP - NsameU4)); + U0r = *(U0rP = (U0rP + NsameU4)); + U1r = *(U1rP = (U1rP + NsameU2)); + U1i = *(U1iP = (U1iP - NsameU2)); + if(stage&1) + U0r = -U0r; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r - U2i * fly4i; + fly6i = t0i + U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r + U2r * fly2i; + fly3i = fly5i - U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r - U3i * fly0i; + fly4i = t1i + U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r - U3r * fly1i; + fly5i = fly7i + U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + + U2r = *(U2rP = (U2rP + NsameU1)); + U2i = *(U2iP = (U2iP - NsameU1)); + + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + IOP = IOP + 2; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + }; + NsameU4 = -NsameU4; + + if(stage&1){ + LoopN >>= 3; + NsameU1 >>= 3; + NsameU2 >>= 3; + NsameU4 >>= 3; + NdiffU <<= 3; + Flyinc = Flyinc << 3; + FlyOffsetA <<= 3; + FlyOffsetB <<= 3; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + } +} + +/* Finish RFFT */ +M=M+1; + +FlyOffsetA = Ntbl[M] * 2/4; +FlyOffsetAIm = Ntbl[M] * 2/4 + 1; + +IOP = ioptr; + +fly0P = (IOP + Ntbl[M]*2/4); +fly1P = (IOP + Ntbl[M]*2/8); + +U0rP = &Utbl[Ntbl[M-3]]; + +U0r = *U0rP, + +fly0r = *(IOP); +fly0i = *(IOP + 1); +fly1r = *(fly0P); +fly1i = *(fly0P + 1); +fly2r = *(fly1P); +fly2i = *(fly1P + 1); +fly3r = *(fly1P + FlyOffsetA); +fly3i = *(fly1P + FlyOffsetAIm); + + t0r = scale * fly0r + scale * fly0i; /* compute Re(x[0]) */ + t0i = scale * fly0r - scale * fly0i; /* compute Re(x[N/2]) */ + t1r = scale * fly1r; + t1i = -scale * fly1i; + + fly0r = fly2r + fly3r; + fly0i = fly2i - fly3i; + fly1r = fly2i + fly3i; + fly1i = fly3r - fly2r; + + fly2r = fly0r + U0r * fly1r; + fly2r = fly2r + U0r * fly1i; + fly2i = fly0i - U0r * fly1r; + fly2i = fly2i + U0r * fly1i; + fly3r = scale * fly0r - fly2r; + fly3i = fly2i - scale * fly0i; + +*(IOP) = t0r; +*(IOP + 1) = t0i; +*(fly0P) = t1r; +*(fly0P + 1) = t1i; +*(fly1P) = fly2r; +*(fly1P + 1) = fly2i; +*(fly1P + FlyOffsetA) = fly3r; +*(fly1P + FlyOffsetAIm) = fly3i; + +U0rP = &Utbl[1]; +U0iP = &Utbl[Ntbl[M-2]-1]; + +U0r = *U0rP, +U0i = *U0iP; + +fly0P = (IOP + 2); +fly1P = (IOP + (Ntbl[M-2]-1)*2); + + /* Butterflys */ + /* + f0 - t0 - - f2 + f1 - t1 -U0 - f3 + f2 - f0 - - t0 + f3 - f1 -U0a- t1 + */ + +for (diffUcnt = Ntbl[M-3]-1; diffUcnt > 0 ; diffUcnt--){ + + fly0r = *(fly0P); + fly0i = *(fly0P + 1); + fly1r = *(fly1P + FlyOffsetA); + fly1i = *(fly1P + FlyOffsetAIm); + fly2r = *(fly1P); + fly2i = *(fly1P + 1); + fly3r = *(fly0P + FlyOffsetA); + fly3i = *(fly0P + FlyOffsetAIm); + + t0r = fly0r + fly1r; + t0i = fly0i - fly1i; + t1r = fly0i + fly1i; + t1i = fly1r - fly0r; + + fly0r = fly2r + fly3r; + fly0i = fly2i - fly3i; + fly1r = fly2i + fly3i; + fly1i = fly3r - fly2r; + + fly2r = t0r + U0r * t1r; + fly2r = fly2r + U0i * t1i; + fly2i = t0i - U0i * t1r; + fly2i = fly2i + U0r * t1i; + fly3r = scale * t0r - fly2r; + fly3i = fly2i - scale * t0i; + + t0r = fly0r + U0i * fly1r; + t0r = t0r + U0r * fly1i; + t0i = fly0i - U0r * fly1r; + t0i = t0i + U0i * fly1i; + t1r = scale * fly0r - t0r; + t1i = t0i - scale * fly0i; + + *(fly0P) = fly2r; + *(fly0P + 1) = fly2i; + *(fly1P + FlyOffsetA) = fly3r; + *(fly1P + FlyOffsetAIm) = fly3i; + + U0r = *(U0rP = (U0rP + 1)); + U0i = *(U0iP = (U0iP - 1)); + + *(fly1P) = t0r; + *(fly1P + 1) = t0i; + *(fly0P + FlyOffsetA) = t1r; + *(fly0P + FlyOffsetAIm) = t1i; + + fly0P += 2; + fly1P -= 2; +}; + +ioptr += Ntbl[M]; +} +} + +void riffts(float *ioptr, long M, long Rows, float *Utbl){ +/* Compute in-place real ifft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = real output data array */ + +long Flyinc; +long FlyOffsetA; +long FlyOffsetAIm; +long FlyOffsetB; +long FlyOffsetBIm; +long NsameU1; +long NsameU2; +long NsameU4; +long diffUcnt; +long LoopCnt; +float scale; +float fly0r; +float fly0i; +float fly1r; +float fly1i; +float fly2r; +float fly2i; +float fly3r; +float fly3i; +float fly4r; +float fly4i; +float fly5r; +float fly5i; +float fly6r; +float fly6i; +float fly7r; +float fly7i; +float U0r; +float U0i; +float U1r; +float U1i; +float U2r; +float U2i; +float U3r; +float U3i; +float t0r; +float t0i; +float t1r; +float t1i; + +float *fly0P; +float *fly1P; +float *fly2P; +float *fly3P; + +float *U0rP; +float *U0iP; +float *U1rP; +float *U1iP; +float *U2rP; +float *U2iP; +float *IOP; +long U3offset; + +long stage; +long NdiffU; +long LoopN; + +const long BRshift = MAXMROOT - ((M-1)>>1); /* for RIFFT */ +const long Nrems2 = Ntbl[(M-1)-((M-1)>>1)+1]; /* for RIFFT */ +const long Nroot_1_ColInc = (Ntbl[(M-1)-1]-Ntbl[(M-1)-((M-1)>>1)])*2; /* for RIFFT */ + +for (;Rows>0;Rows--){ + +/* Start RIFFT */ + +FlyOffsetA = Ntbl[M] * 2/4; +FlyOffsetAIm = Ntbl[M] * 2/4 + 1; + +IOP = ioptr; + +fly0P = (IOP + Ntbl[M]*2/4); +fly1P = (IOP + Ntbl[M]*2/8); + +U0rP = &Utbl[Ntbl[M-3]]; + +U0r = *U0rP, + +fly0r = *(IOP); +fly0i = *(IOP + 1); +fly1r = *(fly0P); +fly1i = *(fly0P + 1); +fly2r = *(fly1P); +fly2i = *(fly1P + 1); +fly3r = *(fly1P + FlyOffsetA); +fly3i = *(fly1P + FlyOffsetAIm); + + t0r = fly0r + fly0i; + t0i = fly0r - fly0i; + t1r = fly1r + fly1r; + t1i = -fly1i - fly1i; + + fly0r = fly2r + fly3r; + fly0i = fly2i - fly3i; + fly1r = fly2r - fly3r; + fly1i = fly2i + fly3i; + + fly3r = fly1r * U0r; + fly3r = fly3r - U0r * fly1i; + fly3i = fly1r * U0r; + fly3i = fly3i + U0r * fly1i; + + fly2r = fly0r - fly3i; + fly2i = fly0i + fly3r; + fly1r = fly0r + fly3i; + fly1i = -fly0i + fly3r; + +*(IOP) = t0r; +*(IOP + 1) = t0i; +*(fly0P) = t1r; +*(fly0P + 1) = t1i; +*(fly1P) = fly2r; +*(fly1P + 1) = fly2i; +*(fly1P + FlyOffsetA) = fly1r; +*(fly1P + FlyOffsetAIm) = fly1i; + +U0rP = &Utbl[1]; +U0iP = &Utbl[Ntbl[M-2]-1]; + +U0r = *U0rP, +U0i = *U0iP; + +fly0P = (IOP + 2); +fly1P = (IOP + (Ntbl[M-2]-1)*2); + + /* Butterflys */ + /* + f0 - t0 - f2 + f1 -t1 -U0- f3 - f1 + f2 - f0 - t0 + f3 -f1 -U0a t1 - f3 + */ + +for (diffUcnt = Ntbl[M-3]-1; diffUcnt > 0 ; diffUcnt--){ + + fly0r = *(fly0P); + fly0i = *(fly0P + 1); + fly1r = *(fly1P + FlyOffsetA); + fly1i = *(fly1P + FlyOffsetAIm); + fly2r = *(fly1P); + fly2i = *(fly1P + 1); + fly3r = *(fly0P + FlyOffsetA); + fly3i = *(fly0P + FlyOffsetAIm); + + t0r = fly0r + fly1r; + t0i = fly0i - fly1i; + t1r = fly0r - fly1r; + t1i = fly0i + fly1i; + + fly0r = fly2r + fly3r; + fly0i = fly2i - fly3i; + fly1r = fly2r - fly3r; + fly1i = fly2i + fly3i; + + + fly3r = t1r * U0r; + fly3r = fly3r - U0i * t1i; + fly3i = t1r * U0i; + fly3i = fly3i + U0r * t1i; + + t1r = fly1r * U0i; + t1r = t1r - U0r * fly1i; + t1i = fly1r * U0r; + t1i = t1i + U0i * fly1i; + + + fly2r = t0r - fly3i; + fly2i = t0i + fly3r; + fly1r = t0r + fly3i; + fly1i = -t0i + fly3r; + + t0r = fly0r - t1i; + t0i = fly0i + t1r; + fly3r = fly0r + t1i; + fly3i = -fly0i + t1r; + + + *(fly0P) = fly2r; + *(fly0P + 1) = fly2i; + *(fly1P + FlyOffsetA) = fly1r; + *(fly1P + FlyOffsetAIm) = fly1i; + + U0r = *(U0rP = (U0rP + 1)); + U0i = *(U0iP = (U0iP - 1)); + + *(fly1P) = t0r; + *(fly1P + 1) = t0i; + *(fly0P + FlyOffsetA) = fly3r; + *(fly0P + FlyOffsetAIm) = fly3i; + + fly0P += 2; + fly1P -= 2; +}; + +M=M-1; /* for RIFFT */ + +FlyOffsetA = Ntbl[M] * 2/2; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetB = FlyOffsetA + 2; +FlyOffsetBIm = FlyOffsetB + 1; + +/* BitrevR2 ** bit reverse shuffle and first radix 2 stage ******/ + +scale = 1./Ntbl[M+1]; +for (stage = 0; stage < Ntbl[M-(M>>1)]*2; stage += Ntbl[M>>1]*2){ + for (LoopN = (Ntbl[(M>>1)-1]-1); LoopN >= 0; LoopN--){ + LoopCnt = (Ntbl[(M>>1)-1]-1); + fly0P = ioptr + Nroot_1_ColInc + ((int)BRcnt[LoopN] >> BRshift)*(2*2) + stage; + IOP = ioptr + (LoopN<<(M+1)/2) * 2 + stage; + fly1P = IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2); + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + for (; LoopCnt > LoopN;){ + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + fly4r = *(fly1P); + fly4i = *(fly1P+1); + fly5r = *(fly1P+FlyOffsetA); + fly5i = *(fly1P+FlyOffsetAIm); + fly6r = *(fly1P+2); + fly6i = *(fly1P+(2+1)); + fly7r = *(fly1P+FlyOffsetB); + fly7i = *(fly1P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + fly0r = fly4r + fly5r; + fly0i = fly4i + fly5i; + fly5r = fly4r - fly5r; + fly5i = fly4i - fly5i; + fly2r = fly6r + fly7r; + fly2i = fly6i + fly7i; + fly7r = fly6r - fly7r; + fly7i = fly6i - fly7i; + + *(fly1P) = scale*t0r; + *(fly1P+1) = scale*t0i; + *(fly1P+2) = scale*fly1r; + *(fly1P+(2+1)) = scale*fly1i; + *(fly1P+FlyOffsetA) = scale*t1r; + *(fly1P+FlyOffsetAIm) = scale*t1i; + *(fly1P+FlyOffsetB) = scale*fly3r; + *(fly1P+FlyOffsetBIm) = scale*fly3i; + *(fly0P) = scale*fly0r; + *(fly0P+1) = scale*fly0i; + *(fly0P+2) = scale*fly5r; + *(fly0P+(2+1)) = scale*fly5i; + *(fly0P+FlyOffsetA) = scale*fly2r; + *(fly0P+FlyOffsetAIm) = scale*fly2i; + *(fly0P+FlyOffsetB) = scale*fly7r; + *(fly0P+FlyOffsetBIm) = scale*fly7i; + + fly0P -= Nrems2; + fly0r = *(fly0P); + fly0i = *(fly0P+1); + fly1r = *(fly0P+FlyOffsetA); + fly1i = *(fly0P+FlyOffsetAIm); + LoopCnt -= 1; + fly1P = (IOP + ((int)BRcnt[LoopCnt] >> BRshift)*(2*2)); + }; + fly2r = *(fly0P+2); + fly2i = *(fly0P+(2+1)); + fly3r = *(fly0P+FlyOffsetB); + fly3i = *(fly0P+FlyOffsetBIm); + + t0r = fly0r + fly1r; + t0i = fly0i + fly1i; + fly1r = fly0r - fly1r; + fly1i = fly0i - fly1i; + t1r = fly2r + fly3r; + t1i = fly2i + fly3i; + fly3r = fly2r - fly3r; + fly3i = fly2i - fly3i; + + *(fly0P) = scale*t0r; + *(fly0P+1) = scale*t0i; + *(fly0P+2) = scale*fly1r; + *(fly0P+(2+1)) = scale*fly1i; + *(fly0P+FlyOffsetA) = scale*t1r; + *(fly0P+FlyOffsetAIm) = scale*t1i; + *(fly0P+FlyOffsetB) = scale*fly3r; + *(fly0P+FlyOffsetBIm) = scale*fly3i; + + }; +}; + +/**** FFTC **************/ + +scale = 2.0; + +NdiffU = 2; +Flyinc = (NdiffU); + +NsameU4 = Ntbl[M+1]/4; /* for RIFFT */ +LoopN = Ntbl[M-3]; + +stage = ((M-1)/3); +if ( (M-1-(stage * 3)) != 0 ){ + FlyOffsetA = Flyinc << 2; + FlyOffsetB = FlyOffsetA << 1; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + if ( (M-1-(stage * 3)) == 1 ){ + /* 1 radix 2 stage */ + + IOP = ioptr; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 + t1 - - t1 + f2 - 1- f5 + f1 - -i- f7 + f4 - - f4 + f0 - - f0 + f6 - 1- f2 + f3 - -i- f1 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r + fly1i; + fly7i = t1i - fly1r; + t1r = t1r - fly1i; + t1i = t1i + fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r + fly3i; + fly1i = fly0i - fly3r; + fly0r = fly0r - fly3i; + fly0i = fly0i + fly3r; + + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly0P + FlyOffsetA) = fly4r; + *(fly0P + FlyOffsetAIm) = fly4i; + *(fly3P + FlyOffsetA) = fly1r; + *(fly3P + FlyOffsetAIm) = fly1i; + *(fly1P + FlyOffsetA) = fly0r; + *(fly1P + FlyOffsetAIm) = fly0i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + }; + + NsameU4 >>= 1; + LoopN >>= 1; + NdiffU <<= 1; + Flyinc = Flyinc << 1; + } + else{ + /* 1 radix 4 stage */ + IOP = ioptr; + + U3r = 0.7071067811865475244008443621; /* sqrt(0.5); */ + U3i = U3r; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + /* Butterflys */ + /* + t0 - - t0 - - t0 + t1 - - t1 - - t1 + f2 - 1- f5 - - f5 + f1 - -i- f7 - - f7 + f4 - - f4 - 1- f6 + f0 - - f0 -U3 - f3 + f6 - 1- f2 - -i- f4 + f3 - -i- f1 -U3a- f2 + */ + + for (LoopCnt = LoopN; LoopCnt > 0 ; LoopCnt--){ + t0r = *(fly0P); + t0i = *(fly0P + 1); + t1r = *(fly1P); + t1i = *(fly1P + 1); + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly1r = *(fly3P); + fly1i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly0r = *(fly1P + FlyOffsetA); + fly0i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly3r = *(fly3P + FlyOffsetA); + fly3i = *(fly3P + FlyOffsetAIm); + + fly5r = t0r - fly2r; + fly5i = t0i - fly2i; + t0r = t0r + fly2r; + t0i = t0i + fly2i; + + fly7r = t1r + fly1i; + fly7i = t1i - fly1r; + t1r = t1r - fly1i; + t1i = t1i + fly1r; + + fly2r = fly4r - fly6r; + fly2i = fly4i - fly6i; + fly4r = fly4r + fly6r; + fly4i = fly4i + fly6i; + + fly1r = fly0r + fly3i; + fly1i = fly0i - fly3r; + fly0r = fly0r - fly3i; + fly0i = fly0i + fly3r; + + fly6r = t0r - fly4r; + fly6i = t0i - fly4i; + t0r = t0r + fly4r; + t0i = t0i + fly4i; + + fly3r = fly5r + fly2i; + fly3i = fly5i - fly2r; + fly5r = fly5r - fly2i; + fly5i = fly5i + fly2r; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly2r = fly7r + U3i * fly1r; + fly2r = fly2r + U3r * fly1i; + fly2i = fly7i - U3r * fly1r; + fly2i = fly2i + U3i * fly1i; + fly7r = scale * fly7r - fly2r; + fly7i = scale * fly7i - fly2i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P + FlyOffsetA) = fly3r; + *(fly2P + FlyOffsetAIm) = fly3i; + *(fly2P) = fly5r; + *(fly2P + 1) = fly5i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + *(fly3P + FlyOffsetA) = fly2r; + *(fly3P + FlyOffsetAIm) = fly2i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + + NsameU4 >>= 2; + LoopN >>= 2; + NdiffU <<= 2; + Flyinc = Flyinc << 2; + }; +}; + +NsameU2 = NsameU4 >> 1; +NsameU1 = NsameU2 >> 1; +Flyinc <<= 1; +FlyOffsetA = Flyinc << 2; +FlyOffsetB = FlyOffsetA << 1; +FlyOffsetAIm = FlyOffsetA + 1; +FlyOffsetBIm = FlyOffsetB + 1; +LoopN >>= 1; + +/* ****** RADIX 8 Stages */ +for (stage = stage<<1; stage > 0 ; stage--){ + + /* an fft stage is done in two parts to ease use of the single quadrant cos table */ + +/* fftcalc1(iobuf, Utbl, N, NdiffU, LoopN); */ + if(!(stage&1)){ + U0rP = &Utbl[0]; + U0iP = &Utbl[Ntbl[M-1]]; /* for RIFFT */ + U1rP = U0rP; + U1iP = U0iP; + U2rP = U0rP; + U2iP = U0iP; + U3offset = (Ntbl[M+1]) / 8; /* for RIFFT */ + + IOP = ioptr; + + U0r = *U0rP, + U0i = *U0iP; + U1r = *U1rP, + U1i = *U1iP; + U2r = *U2rP, + U2i = *U2iP; + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + } + + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + + for (diffUcnt = (NdiffU)>>1; diffUcnt > 0; diffUcnt--){ + + /* Butterflys */ + /* + f0 - - t0 - - t0 - - t0 + f1 -U0 - t1 - - t1 - - t1 + f2 - - f2 -U1 - f5 - - f3 + f3 -U0 - f1 -U1a- f7 - - f7 + f4 - - f4 - - f4 -U2 - f6 + f5 -U0 - f0 - - f0 -U3 - f4 + f6 - - f6 -U1 - f2 -U2a- f2 + f7 -U0 - f3 -U1a- f1 -U3a- f5 + */ + + fly0r = *(IOP); + fly0i = *(IOP+1); + fly1r = *(fly1P); + fly1i = *(fly1P+1); + + for (LoopCnt = LoopN-1; LoopCnt > 0 ; LoopCnt--){ + + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r + U0i * fly1i; + t1i = fly0i - U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r + U0i * fly3i; + fly1i = fly2i - U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r + U0i * fly5i; + fly0i = fly4i - U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r + U0i * fly7i; + fly3i = fly6i - U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r + U1i * fly2i; + fly5i = t0i - U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r + U1r * fly1i; + fly7i = t1i - U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r + U1i * fly6i; + fly2i = fly4i - U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r + U1r * fly3i; + fly1i = fly0i - U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r + U2i * fly4i; + fly6i = t0i - U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r - U2r * fly2i; + fly3i = fly5i + U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r + U3r * fly1i; + fly5i = fly7i - U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + + fly0r = *(fly0P + FlyOffsetB); + fly0i = *(fly0P + FlyOffsetBIm); + + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + fly1r = *(fly1P + FlyOffsetB); + fly1i = *(fly1P + FlyOffsetBIm); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + fly0P = (fly0P + FlyOffsetB); + fly1P = (fly1P + FlyOffsetB); + fly2P = (fly2P + FlyOffsetB); + fly3P = (fly3P + FlyOffsetB); + + }; + fly2r = *(fly2P); + fly2i = *(fly2P + 1); + fly3r = *(fly3P); + fly3i = *(fly3P + 1); + fly4r = *(fly0P + FlyOffsetA); + fly4i = *(fly0P + FlyOffsetAIm); + fly5r = *(fly1P + FlyOffsetA); + fly5i = *(fly1P + FlyOffsetAIm); + fly6r = *(fly2P + FlyOffsetA); + fly6i = *(fly2P + FlyOffsetAIm); + fly7r = *(fly3P + FlyOffsetA); + fly7i = *(fly3P + FlyOffsetAIm); + + t1r = fly0r - U0r * fly1r; + t1r = t1r + U0i * fly1i; + t1i = fly0i - U0i * fly1r; + t1i = t1i - U0r * fly1i; + t0r = scale * fly0r - t1r; + t0i = scale * fly0i - t1i; + + fly1r = fly2r - U0r * fly3r; + fly1r = fly1r + U0i * fly3i; + fly1i = fly2i - U0i * fly3r; + fly1i = fly1i - U0r * fly3i; + fly2r = scale * fly2r - fly1r; + fly2i = scale * fly2i - fly1i; + + fly0r = fly4r - U0r * fly5r; + fly0r = fly0r + U0i * fly5i; + fly0i = fly4i - U0i * fly5r; + fly0i = fly0i - U0r * fly5i; + fly4r = scale * fly4r - fly0r; + fly4i = scale * fly4i - fly0i; + + fly3r = fly6r - U0r * fly7r; + fly3r = fly3r + U0i * fly7i; + fly3i = fly6i - U0i * fly7r; + fly3i = fly3i - U0r * fly7i; + fly6r = scale * fly6r - fly3r; + fly6i = scale * fly6i - fly3i; + + fly5r = t0r - U1r * fly2r; + fly5r = fly5r + U1i * fly2i; + fly5i = t0i - U1i * fly2r; + fly5i = fly5i - U1r * fly2i; + t0r = scale * t0r - fly5r; + t0i = scale * t0i - fly5i; + + fly7r = t1r + U1i * fly1r; + fly7r = fly7r + U1r * fly1i; + fly7i = t1i - U1r * fly1r; + fly7i = fly7i + U1i * fly1i; + t1r = scale * t1r - fly7r; + t1i = scale * t1i - fly7i; + + fly2r = fly4r - U1r * fly6r; + fly2r = fly2r + U1i * fly6i; + fly2i = fly4i - U1i * fly6r; + fly2i = fly2i - U1r * fly6i; + fly4r = scale * fly4r - fly2r; + fly4i = scale * fly4i - fly2i; + + fly1r = fly0r + U1i * fly3r; + fly1r = fly1r + U1r * fly3i; + fly1i = fly0i - U1r * fly3r; + fly1i = fly1i + U1i * fly3i; + fly0r = scale * fly0r - fly1r; + fly0i = scale * fly0i - fly1i; + + U0i = *(U0iP = (U0iP - NsameU4)); + U0r = *(U0rP = (U0rP + NsameU4)); + U1r = *(U1rP = (U1rP + NsameU2)); + U1i = *(U1iP = (U1iP - NsameU2)); + if(stage&1) + U0r = - U0r; + + fly6r = t0r - U2r * fly4r; + fly6r = fly6r + U2i * fly4i; + fly6i = t0i - U2i * fly4r; + fly6i = fly6i - U2r * fly4i; + t0r = scale * t0r - fly6r; + t0i = scale * t0i - fly6i; + + fly3r = fly5r - U2i * fly2r; + fly3r = fly3r - U2r * fly2i; + fly3i = fly5i + U2r * fly2r; + fly3i = fly3i - U2i * fly2i; + fly2r = scale * fly5r - fly3r; + fly2i = scale * fly5i - fly3i; + + fly4r = t1r - U3r * fly0r; + fly4r = fly4r + U3i * fly0i; + fly4i = t1i - U3i * fly0r; + fly4i = fly4i - U3r * fly0i; + t1r = scale * t1r - fly4r; + t1i = scale * t1i - fly4i; + + fly5r = fly7r + U3i * fly1r; + fly5r = fly5r + U3r * fly1i; + fly5i = fly7i - U3r * fly1r; + fly5i = fly5i + U3i * fly1i; + fly7r = scale * fly7r - fly5r; + fly7i = scale * fly7i - fly5i; + + *(fly0P + FlyOffsetA) = fly6r; + *(fly0P + FlyOffsetAIm) = fly6i; + *(fly0P) = t0r; + *(fly0P + 1) = t0i; + + U2r = *(U2rP = (U2rP + NsameU1)); + U2i = *(U2iP = (U2iP - NsameU1)); + + *(fly2P) = fly3r; + *(fly2P + 1) = fly3i; + *(fly2P + FlyOffsetA) = fly2r; + *(fly2P + FlyOffsetAIm) = fly2i; + *(fly1P + FlyOffsetA) = fly4r; + *(fly1P + FlyOffsetAIm) = fly4i; + *(fly1P) = t1r; + *(fly1P + 1) = t1i; + + U3r = *( U2rP + U3offset); + U3i = *( U2iP - U3offset); + + *(fly3P + FlyOffsetA) = fly5r; + *(fly3P + FlyOffsetAIm) = fly5i; + *(fly3P) = fly7r; + *(fly3P + 1) = fly7i; + + IOP = IOP + 2; + fly0P = IOP; + fly1P = (IOP+Flyinc); + fly2P = (fly1P+Flyinc); + fly3P = (fly2P+Flyinc); + }; + NsameU4 = -NsameU4; + + if(stage&1){ + LoopN >>= 3; + NsameU1 >>= 3; + NsameU2 >>= 3; + NsameU4 >>= 3; + NdiffU <<= 3; + Flyinc = Flyinc << 3; + FlyOffsetA <<= 3; + FlyOffsetB <<= 3; + FlyOffsetAIm = FlyOffsetA + 1; + FlyOffsetBIm = FlyOffsetB + 1; + } +} +M=M+1; /* for RIFFT */ + +ioptr += Ntbl[M]; +} +} diff --git a/sc4pd/source/fftlib.h b/sc4pd/source/fftlib.h new file mode 100644 index 0000000..b03317d --- /dev/null +++ b/sc4pd/source/fftlib.h @@ -0,0 +1,62 @@ +long FFTInit(long *fftMptr, long fftN, float *Utbl); +/* Compute cosine table and check size for complex ffts */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ + +long rFFTInit(long *fftMptr, long fftN, float *Utbl); +/* Compute cosine table and check size for a real input fft */ +/* INPUTS */ +/* fftN = size of fft */ +/* OUTPUTS */ +/* *fftMptr = log2 of fft size */ +/* *Utbl = cosine table with fftN/4 + 1 entries (angles = 0 to pi/2 inclusive) */ +/* RETURNS */ +/* 1 if fftN is invalid, 0 otherwise */ + +void ffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +void iffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place inverse complex fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array */ + +void rffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place real fft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = real input data array */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = output data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ + + +void riffts(float *ioptr, long M, long Rows, float *Utbl); +/* Compute in-place real ifft on the rows of the input array */ +/* INPUTS */ +/* M = log2 of fft size */ +/* *ioptr = input data array in the following order */ +/* Re(x[0]), Re(x[N/2]), Re(x[1]), Im(x[1]), Re(x[2]), Im(x[2]), ... Re(x[N/2-1]), Im(x[N/2-1]). */ +/* *Utbl = cosine table */ +/* Rows = number of rows in ioptr array (use Rows of 1 if ioptr is a 1 dimensional array) */ +/* OUTPUTS */ +/* *ioptr = real output data array */ diff --git a/sc4pd/source/hypot.cpp b/sc4pd/source/hypot.cpp new file mode 100644 index 0000000..83f9a89 --- /dev/null +++ b/sc4pd/source/hypot.cpp @@ -0,0 +1,125 @@ +/* sc4pd + hypot, hypot~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ hypot~ -----------------------------*/ + +class hypot_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(hypot_ar,sc4pd_dsp); + +public: + hypot_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("hypot~",hypot_ar); + +hypot_ar::hypot_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void hypot_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = hypot( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ hypot ------------------------------*/ + +class hypot_kr + :public flext_base +{ + FLEXT_HEADER(hypot_kr,flext_base); + +public: + hypot_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("hypot",hypot_kr); + +hypot_kr::hypot_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void hypot_kr::m_perform(float f) +{ + ToOutFloat(0,hypot(f,b)); +} + +void hypot_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/main.cpp b/sc4pd/source/main.cpp new file mode 100644 index 0000000..fa81e2e --- /dev/null +++ b/sc4pd/source/main.cpp @@ -0,0 +1,308 @@ + +/* sc4pd + library initialization + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phosphor +*/ + +#include "sc4pd.hpp" + +#define SC4PD_VERSION "0.01" + + +void sc4pd_library_setup() +{ + post("\nsc4pd: by tim blechmann"); + post("based on SuperCollider by James McCartney"); + post("version "SC4PD_VERSION); + post("compiled on "__DATE__); + post("contains: Dust(~), MantissaMask(~), Hasher(~), Median(~), " + "BrownNoise(~),\n" + " ClipNoise(~), GrayNoise(~), Dust2(~), WhiteNoise(~), " + "PinkNoise(~), \n Crackle(~), Rand(~), TRand(~), " + "TExpRand(~), IRand(~), TIRand(~),\n CoinGate, " + "LinRand(~), NRand(~), ExpRand(~), LFClipNoise(~),\n" + " LFNoise0(~), LFNoise1(~), LFNoise2(~), Logistic(~), " + "Latoocarfian(~),\n" + " LinCong(~), amclip(~), scaleneg(~), excess(~), hypot(~), " + "ring1(~),\n" + " ring2(~), ring3(~), ring4(~), difsqr(~), sumsqr(~), " + "sqrdif(~),\n" + " sqrsum(~), absdif(~), LFSaw(~), LFPulse(~), Impulse(~),\n" + " Integrator(~), Decay~, Decay2~, Lag~, Lag2~, LinExp(~), " + "DelayN~,\n" + " DelayL~, DelayC~, CombN~, CombL~, CombC~, AllpassN~, " + "AllpassL~,\n" + " AllpassC~, PitchShift~, Resonz~, OnePole(~), OneZero(~), " + "TwoPole~, \n" + " TwoZero~, FOS(~), SOS~, RLPF~, RHPF~, LPF~, HPF~, BPF~, " + "BRF~,\n" + " LPZ1(~), HPZ1(~), LPZ2(~), HPZ2(~), BPZ2(~), BRZ2(~), " + "LFDNoise0~,\n" + " LFDNoise1~, LFDNoise2~, sc+~, sc-~, sc*~, sc/~, " + "Convolution~\n" + ); + + //initialize objects + FLEXT_DSP_SETUP(Dust_ar); + FLEXT_SETUP(Dust_kr); + + FLEXT_DSP_SETUP(MantissaMask_ar); + FLEXT_SETUP(MantissaMask_kr); + + FLEXT_DSP_SETUP(Hasher_ar); + FLEXT_SETUP(Hasher_kr); + + FLEXT_DSP_SETUP(Median_ar); + FLEXT_SETUP(Median_kr); + + FLEXT_DSP_SETUP(BrownNoise_ar); + FLEXT_SETUP(BrownNoise_kr); + + FLEXT_DSP_SETUP(ClipNoise_ar); + FLEXT_SETUP(ClipNoise_kr); + + FLEXT_DSP_SETUP(GrayNoise_ar); + FLEXT_SETUP(GrayNoise_kr); + + FLEXT_DSP_SETUP(WhiteNoise_ar); + FLEXT_SETUP(WhiteNoise_kr); + + FLEXT_DSP_SETUP(PinkNoise_ar); + FLEXT_SETUP(PinkNoise_kr); + + FLEXT_DSP_SETUP(Dust2_ar); + FLEXT_SETUP(Dust2_kr); + + FLEXT_DSP_SETUP(Crackle_ar); + FLEXT_SETUP(Crackle_kr); + + FLEXT_DSP_SETUP(Rand_ar); + FLEXT_SETUP(Rand_kr); + + FLEXT_DSP_SETUP(TRand_ar); + FLEXT_SETUP(TRand_kr); + + FLEXT_DSP_SETUP(TExpRand_ar); + FLEXT_SETUP(TExpRand_kr); + + FLEXT_DSP_SETUP(IRand_ar); + FLEXT_SETUP(IRand_kr); + + FLEXT_DSP_SETUP(TIRand_ar); + FLEXT_SETUP(TIRand_kr); + + FLEXT_SETUP(CoinGate_kr); + + FLEXT_DSP_SETUP(LinRand_ar); + FLEXT_SETUP(LinRand_kr); + + FLEXT_DSP_SETUP(NRand_ar); + FLEXT_SETUP(NRand_kr); + + FLEXT_DSP_SETUP(ExpRand_ar); + FLEXT_SETUP(ExpRand_kr); + + FLEXT_DSP_SETUP(LFClipNoise_ar); + FLEXT_SETUP(LFClipNoise_kr); + + FLEXT_DSP_SETUP(LFNoise0_ar); + FLEXT_SETUP(LFNoise0_kr); + + FLEXT_DSP_SETUP(LFNoise1_ar); + FLEXT_SETUP(LFNoise1_kr); + + FLEXT_DSP_SETUP(LFNoise2_ar); + FLEXT_SETUP(LFNoise2_kr); + + FLEXT_DSP_SETUP(Logistic_ar); + FLEXT_SETUP(Logistic_kr); + + FLEXT_DSP_SETUP(Latoocarfian_ar); + FLEXT_SETUP(Latoocarfian_kr); + + FLEXT_DSP_SETUP(LinCong_ar); + FLEXT_SETUP(LinCong_kr); + + FLEXT_DSP_SETUP(amclip_ar); + FLEXT_SETUP(amclip_kr); + + FLEXT_DSP_SETUP(scaleneg_ar); + FLEXT_SETUP(scaleneg_kr); + + FLEXT_DSP_SETUP(excess_ar); + FLEXT_SETUP(excess_kr); + + FLEXT_DSP_SETUP(hypot_ar); + FLEXT_SETUP(hypot_kr); + + FLEXT_DSP_SETUP(ring1_ar); + FLEXT_SETUP(ring1_kr); + + FLEXT_DSP_SETUP(ring2_ar); + FLEXT_SETUP(ring2_kr); + + FLEXT_DSP_SETUP(ring3_ar); + FLEXT_SETUP(ring3_kr); + + FLEXT_DSP_SETUP(ring4_ar); + FLEXT_SETUP(ring4_kr); + + FLEXT_DSP_SETUP(difsqr_ar); + FLEXT_SETUP(difsqr_kr); + + FLEXT_DSP_SETUP(sumsqr_ar); + FLEXT_SETUP(sumsqr_kr); + + FLEXT_DSP_SETUP(sqrsum_ar); + FLEXT_SETUP(sqrsum_kr); + + FLEXT_DSP_SETUP(sqrdif_ar); + FLEXT_SETUP(sqrdif_kr); + + FLEXT_DSP_SETUP(absdif_ar); + FLEXT_SETUP(absdif_kr); + + FLEXT_DSP_SETUP(LFSaw_ar); + FLEXT_SETUP(LFSaw_kr); + + FLEXT_DSP_SETUP(LFPulse_ar); + FLEXT_SETUP(LFPulse_kr); + + FLEXT_DSP_SETUP(Impulse_ar); + FLEXT_SETUP(Impulse_kr); + + FLEXT_DSP_SETUP(Integrator_ar); + FLEXT_SETUP(Integrator_kr); + + FLEXT_DSP_SETUP(Decay_ar); + + FLEXT_DSP_SETUP(Decay2_ar); + + FLEXT_DSP_SETUP(Lag_ar); + + FLEXT_DSP_SETUP(Lag2_ar); + + FLEXT_DSP_SETUP(Lag3_ar); + + FLEXT_DSP_SETUP(LinExp_ar); + FLEXT_SETUP(LinExp_kr); + + FLEXT_DSP_SETUP(DelayN_ar); + + FLEXT_DSP_SETUP(DelayL_ar); + + FLEXT_DSP_SETUP(DelayC_ar); + + FLEXT_DSP_SETUP(CombN_ar); + + FLEXT_DSP_SETUP(CombL_ar); + + FLEXT_DSP_SETUP(CombC_ar); + + FLEXT_DSP_SETUP(AllpassN_ar); + + FLEXT_DSP_SETUP(AllpassL_ar); + + FLEXT_DSP_SETUP(AllpassC_ar); + + FLEXT_DSP_SETUP(PitchShift_ar); + + FLEXT_DSP_SETUP(Resonz_ar); + + FLEXT_DSP_SETUP(OnePole_ar); + FLEXT_SETUP(OnePole_kr); + + FLEXT_DSP_SETUP(OneZero_ar); + FLEXT_SETUP(OneZero_kr); + + FLEXT_DSP_SETUP(TwoPole_ar); + + FLEXT_DSP_SETUP(TwoZero_ar); + + FLEXT_DSP_SETUP(FOS_ar); + FLEXT_SETUP(FOS_kr); + + FLEXT_DSP_SETUP(SOS_ar); + + FLEXT_DSP_SETUP(RLPF_ar); + + FLEXT_DSP_SETUP(RHPF_ar); + + FLEXT_DSP_SETUP(LPF_ar); + + FLEXT_DSP_SETUP(HPF_ar); + + FLEXT_DSP_SETUP(BPF_ar); + + FLEXT_DSP_SETUP(BRF_ar); + + FLEXT_DSP_SETUP(LPZ1_ar); + FLEXT_SETUP(LPZ1_kr); + + FLEXT_DSP_SETUP(HPZ1_ar); + FLEXT_SETUP(HPZ1_kr); + + FLEXT_DSP_SETUP(LPZ2_ar); + FLEXT_SETUP(LPZ2_kr); + + FLEXT_DSP_SETUP(HPZ2_ar); + FLEXT_SETUP(HPZ2_kr); + + FLEXT_DSP_SETUP(BRZ2_ar); + FLEXT_SETUP(BRZ2_kr); + + FLEXT_DSP_SETUP(BPZ2_ar); + FLEXT_SETUP(BPZ2_kr); + + FLEXT_DSP_SETUP(LFDNoise0_ar); + + FLEXT_DSP_SETUP(LFDNoise1_ar); + + FLEXT_DSP_SETUP(LFDNoise2_ar); + + FLEXT_DSP_SETUP(scadd_ar); + + FLEXT_DSP_SETUP(scsub_ar); + + FLEXT_DSP_SETUP(scmul_ar); + + FLEXT_DSP_SETUP(scdiv_ar); + + FLEXT_DSP_SETUP(Convolution_ar); + + //init ffts + init_ffts(); +} + +FLEXT_LIB_SETUP(sc4pd,sc4pd_library_setup); diff --git a/sc4pd/source/ring1.cpp b/sc4pd/source/ring1.cpp new file mode 100644 index 0000000..9c09e40 --- /dev/null +++ b/sc4pd/source/ring1.cpp @@ -0,0 +1,130 @@ +/* sc4pd + ring1, ring1~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + +inline float sc_ring1 (float a, float b) +{ + return a*b+a; +} + + +/* ------------------------ ring1~ -----------------------------*/ + +class ring1_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(ring1_ar,sc4pd_dsp); + +public: + ring1_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("ring1~",ring1_ar); + +ring1_ar::ring1_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void ring1_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_ring1( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ ring1 ------------------------------*/ + +class ring1_kr + :public flext_base +{ + FLEXT_HEADER(ring1_kr,flext_base); + +public: + ring1_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("ring1",ring1_kr); + +ring1_kr::ring1_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void ring1_kr::m_perform(float f) +{ + ToOutFloat(0,sc_ring1(f,b)); +} + +void ring1_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/ring2.cpp b/sc4pd/source/ring2.cpp new file mode 100644 index 0000000..c2432e9 --- /dev/null +++ b/sc4pd/source/ring2.cpp @@ -0,0 +1,130 @@ +/* sc4pd + ring2, ring2~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + +inline float sc_ring2 (float a, float b) +{ + return a*b+a+b; +} + + +/* ------------------------ ring2~ -----------------------------*/ + +class ring2_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(ring2_ar,sc4pd_dsp); + +public: + ring2_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("ring2~",ring2_ar); + +ring2_ar::ring2_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void ring2_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_ring2( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ ring2 ------------------------------*/ + +class ring2_kr + :public flext_base +{ + FLEXT_HEADER(ring2_kr,flext_base); + +public: + ring2_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("ring2",ring2_kr); + +ring2_kr::ring2_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void ring2_kr::m_perform(float f) +{ + ToOutFloat(0,sc_ring2(f,b)); +} + +void ring2_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/ring3.cpp b/sc4pd/source/ring3.cpp new file mode 100644 index 0000000..d8de166 --- /dev/null +++ b/sc4pd/source/ring3.cpp @@ -0,0 +1,130 @@ +/* sc4pd + ring3, ring3~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + +inline float sc_ring3 (float a, float b) +{ + return a*a*b; +} + + +/* ------------------------ ring3~ -----------------------------*/ + +class ring3_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(ring3_ar,sc4pd_dsp); + +public: + ring3_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("ring3~",ring3_ar); + +ring3_ar::ring3_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void ring3_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_ring3( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ ring3 ------------------------------*/ + +class ring3_kr + :public flext_base +{ + FLEXT_HEADER(ring3_kr,flext_base); + +public: + ring3_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("ring3",ring3_kr); + +ring3_kr::ring3_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void ring3_kr::m_perform(float f) +{ + ToOutFloat(0,sc_ring3(f,b)); +} + +void ring3_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/ring4.cpp b/sc4pd/source/ring4.cpp new file mode 100644 index 0000000..f9c6035 --- /dev/null +++ b/sc4pd/source/ring4.cpp @@ -0,0 +1,131 @@ +/* sc4pd + ring4, ring4~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_ring4 (float a, float b) +{ + return (a*a*b)-(a*b*b); +} + + +/* ------------------------ ring4~ -----------------------------*/ + +class ring4_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(ring4_ar,sc4pd_dsp); + +public: + ring4_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("ring4~",ring4_ar); + +ring4_ar::ring4_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void ring4_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_ring4( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ ring4 ------------------------------*/ + +class ring4_kr + :public flext_base +{ + FLEXT_HEADER(ring4_kr,flext_base); + +public: + ring4_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("ring4",ring4_kr); + +ring4_kr::ring4_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void ring4_kr::m_perform(float f) +{ + ToOutFloat(0,sc_ring4(f,b)); +} + +void ring4_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/sc+.cpp b/sc4pd/source/sc+.cpp new file mode 100644 index 0000000..e1a7e26 --- /dev/null +++ b/sc4pd/source/sc+.cpp @@ -0,0 +1,113 @@ +/* sc4pd + sc+~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways Past + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ sc+~ -------------------------------*/ + +class scadd_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(scadd_ar,sc4pd_dsp); + +public: + scadd_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_nextsummand = f; + changed = true; + } + + float m_nextsummand, m_summand; + bool changed; + +private: + FLEXT_CALLBACK_1(m_set,float); +}; + +FLEXT_LIB_DSP_V("sc+~",scadd_ar); + +scadd_ar::scadd_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(1,m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_summand = sc_getfloatarg(Args,0); + + AddInSignal("signal"); + AddInFloat("scalar"); + AddOutSignal(); + + changed = false; +} + +void scadd_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + if (changed) + { + float xb = m_nextsummand; + float slope = CALCSLOPE(xb, m_summand); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) + xb; + xb += slope; + } + m_summand = xb; + changed = false; + } + else + { + float xb = m_summand; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) + xb; + } + } +} + + diff --git a/sc4pd/source/sc-.cpp b/sc4pd/source/sc-.cpp new file mode 100644 index 0000000..0dfd2ce --- /dev/null +++ b/sc4pd/source/sc-.cpp @@ -0,0 +1,142 @@ +/* sc4pd + sc-~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ sc-~ -------------------------------*/ + +class scsub_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(scsub_ar,sc4pd_dsp); + +public: + scsub_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_nextsubtrahend = f; + changed = true; + } + + float m_nextsubtrahend, m_subtrahend; + bool changed; + bool invert; + +private: + FLEXT_CALLBACK_1(m_set,float); +}; + +FLEXT_LIB_DSP_V("sc-~",scsub_ar); + +scsub_ar::scsub_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(1,m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_subtrahend = sc_getfloatarg(Args,0); + + invert = sc_inv(Args); + + AddInSignal("signal"); + AddInFloat("scalar"); + AddOutSignal(); + + changed = false; +} + +void scsub_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + if (invert) + { + if (changed) + { + float xb = m_nextsubtrahend; + float slope = CALCSLOPE(xb, m_subtrahend); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = xb - ZXP(nin); + xb += slope; + } + m_subtrahend = xb; + changed = false; + } + else + { + float xb = m_subtrahend; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = xb - ZXP(nin); + } + } + } + else + { + if (changed) + { + float xb = m_nextsubtrahend; + float slope = CALCSLOPE(xb, m_subtrahend); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) - xb; + xb += slope; + } + m_subtrahend = xb; + changed = false; + } + else + { + float xb = m_subtrahend; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) - xb; + } + } + } +} + diff --git a/sc4pd/source/sc4pd.hpp b/sc4pd/source/sc4pd.hpp new file mode 100644 index 0000000..13d82c0 --- /dev/null +++ b/sc4pd/source/sc4pd.hpp @@ -0,0 +1,128 @@ +/* sc4pd: + support functions + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Morton Feldman: For John Cage + +*/ + +#ifndef _SC4PD_HPP + +#include <flext.h> + +#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 406) +#error You need at least FLEXT version 0.4.6 +#endif + +#include "SC_PlugIn.h" +#include "support.hpp" + +/* this macro has to be redefined to work with flext */ + +// calculate a slope for control rate interpolation to audio rate. +//#define CALCSLOPE(next,prev) ((next - prev) * unit->mRate->mSlopeFactor) +#undef CALCSLOPE +#define CALCSLOPE(next,prev) ((next - prev) * 1/ Blocksize()) + + + +//#define SAMPLERATE (unit->mRate->mSampleRate) +#undef SAMPLERATE +#define SAMPLERATE Samplerate() + +//#define BUFLENGTH (unit->mBufLength) +#undef BUFLENGTH +#define BUFLENGTH Blocksize() + +/* to make sure the behaviour is consistent: */ + +#undef ZXP +#define ZXP(z) (*(z)++) + + + +class sc4pd_dsp + : public flext_dsp +{ + FLEXT_HEADER(sc4pd_dsp,flext_dsp); + + +/* some initialisation functions, adapted from SC_Rate.cpp*/ + + inline float sc_sampledur() + { + return 1 / Samplerate(); + } + + inline float sc_radianspersample() + { + return twopi / Samplerate(); + } + + inline float sc_bufduration() + { + return Blocksize() / Samplerate(); + } + + inline float sc_bufrate() + { + return 1 / sc_bufduration(); + } + + inline float sc_slopefactor() + { + return 1 / Blocksize(); + } + + inline int sc_filterloops() + { + return Blocksize() / 3; + } + + inline int sc_filterremain() + { + return Blocksize() % 3; + } + + inline float sc_filterslope() + { + float f = sc_filterloops(); + if (f == 0) + return 0; + else + return 1. / f; + } + +}; + + +#define _SC4PD_HPP +#endif diff --git a/sc4pd/source/scaleneg.cpp b/sc4pd/source/scaleneg.cpp new file mode 100644 index 0000000..d91b324 --- /dev/null +++ b/sc4pd/source/scaleneg.cpp @@ -0,0 +1,125 @@ +/* sc4pd + scaleneg, scaleneg(~) + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Keith Rowe & Toshimaru Nakamura: Weather Sky + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ scaleneg~ -----------------------------*/ + +class scaleneg_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(scaleneg_ar,sc4pd_dsp); + +public: + scaleneg_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("scaleneg~",scaleneg_ar); + +scaleneg_ar::scaleneg_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void scaleneg_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_scaleneg( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ scaleneg ------------------------------*/ + +class scaleneg_kr + :public flext_base +{ + FLEXT_HEADER(scaleneg_kr,flext_base); + +public: + scaleneg_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("scaleneg",scaleneg_kr); + +scaleneg_kr::scaleneg_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void scaleneg_kr::m_perform(float f) +{ + ToOutFloat(0,sc_scaleneg(f,b)); +} + +void scaleneg_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/scdiv.cpp b/sc4pd/source/scdiv.cpp new file mode 100644 index 0000000..045d1b4 --- /dev/null +++ b/sc4pd/source/scdiv.cpp @@ -0,0 +1,142 @@ +/* sc4pd + sc/~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ sc/~ -------------------------------*/ + +class scdiv_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(scdiv_ar,sc4pd_dsp); + +public: + scdiv_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_nextdivisor = f; + changed = true; + } + + float m_nextdivisor, m_divisor; + bool changed; + bool invert; + +private: + FLEXT_CALLBACK_1(m_set,float); +}; + +FLEXT_LIB_DSP_V("sc/~",scdiv_ar); + +scdiv_ar::scdiv_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(1,m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_divisor = sc_getfloatarg(Args,0); + + invert = sc_inv(Args); + + AddInSignal("signal"); + AddInFloat("scalar"); + AddOutSignal(); + + changed = false; +} + +void scdiv_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + if (invert) + { + if (changed) + { + float xb = m_nextdivisor; + float slope = CALCSLOPE(xb, m_divisor); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = xb / ZXP(nin); + xb += slope; + } + m_divisor = xb; + changed = false; + } + else + { + float xb = m_divisor; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = xb / ZXP(nin); + } + } + } + else + { + if (changed) + { + float xb = m_nextdivisor; + float slope = CALCSLOPE(xb, m_divisor); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) / xb; + xb += slope; + } + m_divisor = xb; + changed = false; + } + else + { + float xb = m_divisor; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) / xb; + } + } + } +} + diff --git a/sc4pd/source/scmul.cpp b/sc4pd/source/scmul.cpp new file mode 100644 index 0000000..55ac074 --- /dev/null +++ b/sc4pd/source/scmul.cpp @@ -0,0 +1,113 @@ +/* sc4pd + sc*~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phil Minton & Veryan Weston: Ways + +*/ + +#include "sc4pd.hpp" + + +/* ------------------------ sc*~ -------------------------------*/ + +class scmul_ar: + public sc4pd_dsp +{ + FLEXT_HEADER(scmul_ar,sc4pd_dsp); + +public: + scmul_ar(int argc, t_atom *argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + + void m_set(float f) + { + m_nextfactor = f; + changed = true; + } + + float m_nextfactor, m_factor; + bool changed; + +private: + FLEXT_CALLBACK_1(m_set,float); +}; + +FLEXT_LIB_DSP_V("sc*~",scmul_ar); + +scmul_ar::scmul_ar(int argc, t_atom *argv) +{ + FLEXT_ADDMETHOD(1,m_set); + + //parse arguments + AtomList Args(argc,argv); + + m_factor = sc_getfloatarg(Args,0); + + AddInSignal("signal"); + AddInFloat("scalar"); + AddOutSignal(); + + changed = false; +} + +void scmul_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nin = *in; + t_sample *nout = *out; + + if (changed) + { + float xb = m_nextfactor; + float slope = CALCSLOPE(xb, m_factor); + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) * xb; + xb += slope; + } + m_factor = xb; + changed = false; + } + else + { + float xb = m_factor; + + for (int i = 0; i!=n; ++i) + { + ZXP(nout) = ZXP(nin) * xb; + } + } +} + + diff --git a/sc4pd/source/sqrdif.cpp b/sc4pd/source/sqrdif.cpp new file mode 100644 index 0000000..165ee2b --- /dev/null +++ b/sc4pd/source/sqrdif.cpp @@ -0,0 +1,132 @@ +/* sc4pd + sqrdif, sqrdif~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_sqrdif (float a, float b) +{ + float f=a-b; + return f*f; +} + + +/* ------------------------ sqrdif~ -----------------------------*/ + +class sqrdif_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(sqrdif_ar,sc4pd_dsp); + +public: + sqrdif_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("sqrdif~",sqrdif_ar); + +sqrdif_ar::sqrdif_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void sqrdif_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_sqrdif( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ sqrdif ------------------------------*/ + +class sqrdif_kr + :public flext_base +{ + FLEXT_HEADER(sqrdif_kr,flext_base); + +public: + sqrdif_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("sqrdif",sqrdif_kr); + +sqrdif_kr::sqrdif_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void sqrdif_kr::m_perform(float f) +{ + ToOutFloat(0,sc_sqrdif(f,b)); +} + +void sqrdif_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/sqrsum.cpp b/sc4pd/source/sqrsum.cpp new file mode 100644 index 0000000..756c07e --- /dev/null +++ b/sc4pd/source/sqrsum.cpp @@ -0,0 +1,132 @@ +/* sc4pd + sqrsum, sqrsum~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_sqrsum (float a, float b) +{ + float f=a+b; + return f*f; +} + + +/* ------------------------ sqrsum~ -----------------------------*/ + +class sqrsum_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(sqrsum_ar,sc4pd_dsp); + +public: + sqrsum_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("sqrsum~",sqrsum_ar); + +sqrsum_ar::sqrsum_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void sqrsum_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_sqrsum( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ sqrsum ------------------------------*/ + +class sqrsum_kr + :public flext_base +{ + FLEXT_HEADER(sqrsum_kr,flext_base); + +public: + sqrsum_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("sqrsum",sqrsum_kr); + +sqrsum_kr::sqrsum_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void sqrsum_kr::m_perform(float f) +{ + ToOutFloat(0,sc_sqrsum(f,b)); +} + +void sqrsum_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/sumsqr.cpp b/sc4pd/source/sumsqr.cpp new file mode 100644 index 0000000..518eb01 --- /dev/null +++ b/sc4pd/source/sumsqr.cpp @@ -0,0 +1,131 @@ +/* sc4pd + sumsqr, sumsqr~ + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Evan Parker & Keith Rowe: Dark Rags + +*/ + +#include "sc4pd.hpp" + + +inline float sc_sumsqr (float a, float b) +{ + return a*a+b*b; +} + + +/* ------------------------ sumsqr~ -----------------------------*/ + +class sumsqr_ar + :public sc4pd_dsp +{ + FLEXT_HEADER(sumsqr_ar,sc4pd_dsp); + +public: + sumsqr_ar(int argc,t_atom * argv); + +protected: + virtual void m_signal(int n, t_sample *const *in, t_sample *const *out); + +private: + +}; + +FLEXT_LIB_DSP_V("sumsqr~",sumsqr_ar); + +sumsqr_ar::sumsqr_ar(int argc,t_atom * argv) +{ + AddInSignal(); + AddInSignal(); + AddOutSignal(); +} + +void sumsqr_ar::m_signal(int n, t_sample *const *in, + t_sample *const *out) +{ + t_sample *nout = *out; + t_sample *nin1 = *in; + t_sample *nin2 = *(in+1); + + for (int i = 0; i!= n;++i) + { + if( *nin2 > 0) + (*(nout)++) = sc_sumsqr( (*(nin1)++), (*(nin2)++) ); + } +} + + + +/* ------------------------ sumsqr ------------------------------*/ + +class sumsqr_kr + :public flext_base +{ + FLEXT_HEADER(sumsqr_kr,flext_base); + +public: + sumsqr_kr(int argc,t_atom * argv); + +protected: + void m_perform(float f); + void m_set(float f); + +private: + float b; + FLEXT_CALLBACK_F(m_perform); + FLEXT_CALLBACK_F(m_set); +}; + +FLEXT_LIB_V("sumsqr",sumsqr_kr); + +sumsqr_kr::sumsqr_kr(int argc,t_atom * argv) + :b(0) +{ + + AddInFloat(); + AddInFloat(); + AddOutFloat(); + + FLEXT_ADDMETHOD(0,m_perform); + FLEXT_ADDMETHOD(1,m_set); +} + +void sumsqr_kr::m_perform(float f) +{ + ToOutFloat(0,sc_sumsqr(f,b)); +} + +void sumsqr_kr::m_set(float f) +{ + b=f; +} diff --git a/sc4pd/source/support.cpp b/sc4pd/source/support.cpp new file mode 100644 index 0000000..e753056 --- /dev/null +++ b/sc4pd/source/support.cpp @@ -0,0 +1,184 @@ +/* sc4pd: + support functions + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Nmperign & Guenter Mueller: More Gloom, More Light + +*/ + +#include "sc4pd.hpp" + +#include <flsupport.h> + + +bool sc_add (flext::AtomList& a) +{ + for (int i = 0; i!=a.Count();++i) + { + if ( flext::IsSymbol(a[i]) ) + { + const char * teststring; + teststring = flext::GetString(a[i]); + if((strcmp(teststring,"add"))==0) + return true; + } + } + return false; +} + +float sc_getfloatarg (flext::AtomList& a,int i) +{ + if (a.Count() > 0 && a.Count() > i) + return flext::GetAFloat(a[i]); + else + return 0; +} + +bool sc_ar(flext::AtomList& a) +{ + for (int i = 0; i!=a.Count();++i) + { + if ( flext::IsSymbol(a[i]) ) + { + const char * teststring; + teststring = flext::GetString(a[i]); + if((strcmp(teststring,"ar"))==0) + return true; + } + } + return false; +} + +bool sc_inv(flext::AtomList& a) +{ + for (int i = 0; i!=a.Count();++i) + { + if ( flext::IsSymbol(a[i]) ) + { + const char * teststring; + teststring = flext::GetString(a[i]); + if((strcmp(teststring,"inv"))==0) + return true; + } + } + return false; +} + +int32 timeseed() +{ + static int32 count = 0; + + double time = flext::GetOSTime(); + + double sec = trunc(time); + double usec = (time-sec)*1e6; + + time_t tsec = sec; + useconds_t tusec =usec; /* not exacty the way, it's calculated + in SuperCollider, but it's only + the seed */ + + return (int32)tsec ^ (int32)tusec ^ count--; +} + +/* from Convolution.cpp */ +extern "C" +{ + float *cosTable[32]; + float *fftWindow[32]; +} + + +float* create_cosTable(int log2n) +{ + int size = 1 << log2n; + int size2 = size / 4 + 1; + float *win = (float*)malloc(size2 * sizeof(float)); + double winc = twopi / size; + for (int i=0; i<size2; ++i) { + double w = i * winc; + win[i] = cos(w); + } + return win; +} + +float* create_fftwindow(int log2n) +{ + int size = 1 << log2n; + float *win = (float*)malloc(size * sizeof(float)); + //double winc = twopi / size; + double winc = pi / size; + for (int i=0; i<size; ++i) { + double w = i * winc; + //win[i] = 0.5 - 0.5 * cos(w); + win[i] = sin(w); + } + return win; +} + +void init_ffts() +{ +#if __VEC__ + + for (int i=0; i<32; ++i) { + fftsetup[i] = 0; + } + for (int i=0; i<15; ++i) { + fftsetup[i] = create_fftsetup(i, kFFTRadix2); + } +#else + for (int i=0; i<32; ++i) { + cosTable[i] = 0; + fftWindow[i] = 0; + } + for (int i=3; i<15; ++i) { + cosTable[i] = create_cosTable(i); + fftWindow[i] = create_fftwindow(i); + } +#endif +} + +void DoWindowing(int log2n, float * fftbuf, int bufsize) +{ + float *win = fftWindow[log2n]; + + //printf("fail? %i %d /n", log2n, win); + + if (!win) return; + float *in = fftbuf - 1; + win--; + + for (int i=0; i<bufsize; ++i) { + *++in *= *++win; + } +} + +#include "fftlib.c" diff --git a/sc4pd/source/support.hpp b/sc4pd/source/support.hpp new file mode 100644 index 0000000..12885cb --- /dev/null +++ b/sc4pd/source/support.hpp @@ -0,0 +1,124 @@ +/* sc4pd: + support functions + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: Phosphor + +*/ + +#ifndef _SUPPORT_HPP +#define _SUPPORT_HPP + +#include <flext.h> +#include "SC_PlugIn.h" + + +#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 406) +#error You need at least FLEXT version 0.4.6 +#endif + + +/* for argument parsing */ +bool sc_add (flext::AtomList& a); +float sc_getfloatarg (flext::AtomList& a,int i); +bool sc_ar(flext::AtomList& a); +bool sc_inv(flext::AtomList& a); + + +/* for rngs */ + +// macros to put rgen state in registers +#define RGET \ + uint32 s1 = rgen.s1; \ + uint32 s2 = rgen.s2; \ + uint32 s3 = rgen.s3; + +#define RPUT \ + rgen.s1 = s1; \ + rgen.s2 = s2; \ + rgen.s3 = s3; + +int32 timeseed(); + +/* cubic interpolation from DelayUGens.cpp */ +inline float cubicinterp(float x, float y0, float y1, float y2, float y3) +{ + // 4-point, 3rd-order Hermite (x-form) + float c0 = y1; + float c1 = 0.5f * (y2 - y0); + float c2 = y0 - 2.5f * y1 + 2.f * y2 - 0.5f * y3; + float c3 = 0.5f * (y3 - y0) + 1.5f * (y1 - y2); + + return ((c3 * x + c2) * x + c1) * x + c0; +} + +/* feedback calculation from DelayUGens.cpp */ +inline float CalcFeedback(float delaytime, float decaytime) +{ + if (delaytime == 0.f) { + return 0.f; + } else if (decaytime > 0.f) { + return exp(log001 * delaytime / decaytime); + } else if (decaytime < 0.f) { + return -exp(log001 * delaytime / -decaytime); + } else { + return 0.f; + } +} + + +/* this is adapted from thomas grill's xsample: +xsample - extended sample objects for Max/MSP and pd (pure data) + +Copyright (c) 2001-2004 Thomas Grill (xovo@gmx.net) +For information on usage and redistribution, and for a DISCLAIMER OF ALL +WARRANTIES, see the file, "license.txt," in this distribution. +*/ + +#define SETSIGFUN(VAR,FUN) v_##VAR = FUN + +#define DEFSIGFUN(NAME) void NAME(int n,t_sample *const *in,t_sample *const *out) + +#define DEFSIGCALL(NAME) \ + inline void NAME(int n,t_sample *const *in,t_sample *const *out) \ + { (this->*v_##NAME)(n,in,out); } \ + void (thisType::*v_##NAME)(int n,t_sample *const *invecs,t_sample *const *outvecs) + +#define SIGFUN(FUN) &thisType::FUN + + +/* from Convolution.cpp */ +void init_ffts(); +float* create_fftwindow(int log2n); +float* create_cosTable(int log2n); +void DoWindowing(int log2n, float * fftbuf, int bufsize); + +#endif diff --git a/sc4pd/source/template.cpp b/sc4pd/source/template.cpp new file mode 100644 index 0000000..15d9f06 --- /dev/null +++ b/sc4pd/source/template.cpp @@ -0,0 +1,37 @@ +/* sc4pd + + Copyright (c) 2004 Tim Blechmann. + + This code is derived from: + SuperCollider real time audio synthesis system + Copyright (c) 2002 James McCartney. All rights reserved. + http://www.audiosynth.com + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Based on: + PureData by Miller Puckette and others. + http://www.crca.ucsd.edu/~msp/software.html + FLEXT by Thomas Grill + http://www.parasitaere-kapazitaeten.net/ext + SuperCollider by James McCartney + http://www.audiosynth.com + + Coded while listening to: + +*/ + +#include "sc4pd.hpp" |