diff options
author | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2005-11-10 14:35:13 +0000 |
---|---|---|
committer | Hans-Christoph Steiner <eighthave@users.sourceforge.net> | 2005-11-10 14:35:13 +0000 |
commit | d1af9e9a4ef6a567eb1f8e3af7d90d975fb77548 (patch) | |
tree | 5e22f0f26d47c1362af2d22580d7414b9bea45ba |
imported Olaf Matthes' Max version 1.2svn2git-root
svn path=/trunk/externals/freeverb~/; revision=3869
-rw-r--r-- | LICENSE | 346 | ||||
-rw-r--r-- | README | 40 | ||||
-rw-r--r-- | freeverb~.cpp | 837 | ||||
-rw-r--r-- | freeverb~.dsp | 118 |
4 files changed, 1341 insertions, 0 deletions
@@ -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.
+
@@ -0,0 +1,40 @@ +freeverb~ version 1.2
+reverb external for Pure Data and Max/MSP
+written by Olaf Matthes <olaf.matthes@gmx.de>
+
+based on Freeverb, the free, studio-quality reverb SOURCE CODE in the public
+domain, Written by Jezar at Dreampoint - http://www.dreampoint.co.uk
+
+This software is published under GPL terms, see file LICENSE.
+
+This is software with ABSOLUTELY NO WARRANTY.
+Use it at your OWN RISK. It's possible to damage e.g. hardware or your hearing
+due to a bug or for other reasons.
+
+Recent changes:
+- added check for NANs
+- added a hand unrolled version of the perform routine for DSP vector sizes that
+ are a multiple of 8. This should speed up things a bit
+
+
+Below some notes taken from Freeverb readme:
+-------------------------------------------------------------------------------------
+
+Note that this version of Freeverb doesn't contain predelay, or any EQ. I thought
+that might make it difficult to understand the "reverb" part of the code. Once you
+figure out how Freeverb works, you should find it trivial to add such features with
+little CPU overhead.
+
+Technical Explanation
+---------------------
+
+Freeverb is a simple implementation of the standard Schroeder/Moorer reverb model.
+I guess the only reason why it sounds better than other reverbs, is simply because
+I spent a long while doing listening tests in order to create the values found in "tuning.h". It uses 8 comb filters on both the left and right channels), and you
+might possibly be able to get away with less if CPU power is a serious constraint
+for you. It then feeds the result of the reverb through 4 allpass filters on both
+the left and right channels. These "smooth" the sound. Adding more than four allpasses
+doesn't seem to add anything significant to the sound, and if you use less, the sound
+gets a bit "grainy". The filters on the right channel are slightly detuned compared
+to the left channel in order to create a stereo effect.
+
diff --git a/freeverb~.cpp b/freeverb~.cpp new file mode 100644 index 0000000..53e2c0a --- /dev/null +++ b/freeverb~.cpp @@ -0,0 +1,837 @@ +/* -------------------------- freeverb~ --------------------------------------- */ +/* */ +/* Tilde object that implements the Schroeder/Moorer reverb model. */ +/* Written by Olaf Matthes <olaf.matthes@gmx.de>. */ +/* Get source at http://www.akustische-kunst.org/ */ +/* */ +/* 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. */ +/* Also compiles for Max/MSP. */ +/* */ +/* ---------------------------------------------------------------------------- */ + +#ifdef NT
+#pragma warning( disable : 4091 )
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+#ifdef PD +#include "m_pd.h" +#else // Max/MSP +#include "ext.h" +#include "z_dsp.h" +#define t_floatarg double +#endif + +#include <math.h> +#include <string.h> + +#define LOGTEN 2.302585092994 + +#define numcombs 8 +#define numallpasses 4 +#define muted 0 +#define fixedgain 0.015 +#define scalewet 3.0 +#define scaledry 2.0 +#define scaledamp 0.4 +#define scaleroom 0.28 +#define offsetroom 0.7 +#define initialroom 0.5 +#define initialdamp 0.5 +#define initialwet 1.0/scalewet +#define initialdry 0.0 +#define initialwidth 1.0 +#define initialmode 0 +#define initialbypass 0 +#define freezemode 0.5 +#define stereospread 23 + +/* these values assume 44.1KHz sample rate + they will probably be OK for 48KHz sample rate + but would need scaling for 96KHz (or other) sample rates. + the values were obtained by listening tests. */ +static const int combtuningL[numcombs] + = { 1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 }; +static const int combtuningR[numcombs] + = { 1116+stereospread, 1188+stereospread, 1277+stereospread, 1356+stereospread, + 1422+stereospread, 1491+stereospread, 1557+stereospread, 1617+stereospread }; + +static const int allpasstuningL[numallpasses] + = { 556, 441, 341, 225 }; +static const int allpasstuningR[numallpasses] + = { 556+stereospread, 441+stereospread, 341+stereospread, 225+stereospread }; + +static char *version = "freeverb~ v1.2"; + +#ifdef PD +static t_class *freeverb_class; + +typedef struct _freeverb +{ + t_object x_obj; +#else // Max/MSP +void *freeverb_class; + +typedef struct _freeverb +{ + t_pxobject x_obj; +#endif + /* freeverb stuff */ + t_float x_gain; + t_float x_roomsize,x_roomsize1; + t_float x_damp,x_damp1; + t_float x_wet,x_wet1,x_wet2; + t_float x_dry; + t_float x_width; + t_float x_mode; + t_float x_bypass; + int x_skip; + + t_float x_allpassfeedback; /* feedback of allpass filters */ + t_float x_combfeedback; /* feedback of comb filters */ + t_float x_combdamp1; + t_float x_combdamp2; + t_float x_filterstoreL[numcombs]; /* stores last sample value */ + t_float x_filterstoreR[numcombs]; + + /* buffers for the combs */ + t_float *x_bufcombL[numcombs]; + t_float *x_bufcombR[numcombs]; + int x_combidxL[numcombs]; + int x_combidxR[numcombs]; + + /* buffers for the allpasses */ + t_float *x_bufallpassL[numallpasses]; + t_float *x_bufallpassR[numallpasses]; + int x_allpassidxL[numallpasses]; + int x_allpassidxR[numallpasses]; + + /* we'll make local copies adjusted to fit our sample rate */ + int x_combtuningL[numcombs]; + int x_combtuningR[numcombs]; + + int x_allpasstuningL[numallpasses]; + int x_allpasstuningR[numallpasses]; + +#ifdef PD + t_float x_float; +#endif +} t_freeverb; + +#ifndef IRIX +#define IS_DENORM_FLOAT(v) ((((*(unsigned long*)&(v))&0x7f800000)==0)&&((v)!=0.f))
+#define IS_NAN_FLOAT(v) (((*(unsigned long*)&(v))&0x7f800000)==0x7f800000)
+#define IS_DENORM_NAN_FLOAT(v) (IS_DENORM_FLOAT(v)||IS_NAN_FLOAT(v))
+#define FIX_DENORM_NAN_FLOAT(v) ((v)=IS_DENORM_NAN_FLOAT(v)?0.f:(v))
+#else +#define FIX_DENORM_NAN_FLOAT(v); +#endif + + /* we need prototypes for Mac for everything */ +static void comb_setdamp(t_freeverb *x, t_floatarg val); +static void comb_setfeedback(t_freeverb *x, t_floatarg val); +static inline t_float comb_processL(t_freeverb *x, int filteridx, t_float input); +static inline t_float comb_processR(t_freeverb *x, int filteridx, t_float input); +static void allpass_setfeedback(t_freeverb *x, t_floatarg val); +static inline t_float allpass_processL(t_freeverb *x, int filteridx, t_float input); +static inline t_float allpass_processR(t_freeverb *x, int filteridx, t_float input); +t_int *freeverb_perform(t_int *w); +t_int *freeverb_perf8(t_int *w);
+static void dsp_add_freeverb(t_freeverb *x, t_sample *in1, t_sample *in2, t_sample *out1, t_sample *out2, int n);
+void freeverb_dsp(t_freeverb *x, t_signal **sp); +static void freeverb_update(t_freeverb *x); +static void freeverb_setroomsize(t_freeverb *x, t_floatarg value); +static float freeverb_getroomsize(t_freeverb *x); +static void freeverb_setdamp(t_freeverb *x, t_floatarg value); +static float freeverb_getdamp(t_freeverb *x); +static void freeverb_setwet(t_freeverb *x, t_floatarg value); +static float freeverb_getwet(t_freeverb *x); +static void freeverb_setdry(t_freeverb *x, t_floatarg value); +static float freeverb_getdry(t_freeverb *x); +static void freeverb_setwidth(t_freeverb *x, t_floatarg value); +static float freeverb_getwidth(t_freeverb *x); +static void freeverb_setmode(t_freeverb *x, t_floatarg value); +static float freeverb_getmode(t_freeverb *x); +static void freeverb_setbypass(t_freeverb *x, t_floatarg value); +static void freeverb_mute(t_freeverb *x); +static float freeverb_getdb(float f); +static void freeverb_print(t_freeverb *x); +#ifndef PD +void freeverb_assist(t_freeverb *x, void *b, long m, long a, char *s); +#endif +static void freeverb_free(t_freeverb *x); +void *freeverb_new(t_floatarg val); + +/* -------------------- comb filter stuff ----------------------- */ +static void comb_setdamp(t_freeverb *x, t_floatarg val) +{ + x->x_combdamp1 = val; + x->x_combdamp2 = 1-val; +} + +static void comb_setfeedback(t_freeverb *x, t_floatarg val) +{ + x->x_combfeedback = val; +} + +// Big to inline - but crucial for speed
+static inline t_float comb_processL(t_freeverb *x, int filteridx, t_float input) +{ + t_float output; + int bufidx = x->x_combidxL[filteridx]; + + output = x->x_bufcombL[filteridx][bufidx]; + FIX_DENORM_NAN_FLOAT(output); + + x->x_filterstoreL[filteridx] = (output*x->x_combdamp2) + (x->x_filterstoreL[filteridx]*x->x_combdamp1); + FIX_DENORM_NAN_FLOAT(x->x_filterstoreL[filteridx]); + + x->x_bufcombL[filteridx][bufidx] = input + (x->x_filterstoreL[filteridx]*x->x_combfeedback); + + if(++x->x_combidxL[filteridx] >= x->x_combtuningL[filteridx]) x->x_combidxL[filteridx] = 0; + + return output; +} + +static inline t_float comb_processR(t_freeverb *x, int filteridx, t_float input) +{ + t_float output; + int bufidx = x->x_combidxR[filteridx]; + + output = x->x_bufcombR[filteridx][bufidx]; + FIX_DENORM_NAN_FLOAT(output); + + x->x_filterstoreR[filteridx] = (output*x->x_combdamp2) + (x->x_filterstoreR[filteridx]*x->x_combdamp1); + FIX_DENORM_NAN_FLOAT(x->x_filterstoreR[filteridx]); + + x->x_bufcombR[filteridx][bufidx] = input + (x->x_filterstoreR[filteridx]*x->x_combfeedback); + + if(++x->x_combidxR[filteridx] >= x->x_combtuningR[filteridx]) x->x_combidxR[filteridx] = 0; + + return output; +} + +/* -------------------- allpass filter stuff ----------------------- */ +static void allpass_setfeedback(t_freeverb *x, t_floatarg val) +{ + x->x_allpassfeedback = val; +} + +// Big to inline - but crucial for speed
+static inline t_float allpass_processL(t_freeverb *x, int filteridx, t_float input) +{ + t_float output; + t_float bufout; + int bufidx = x->x_allpassidxL[filteridx]; + + bufout = (t_float)x->x_bufallpassL[filteridx][bufidx]; + FIX_DENORM_NAN_FLOAT(bufout); + + output = -input + bufout; + x->x_bufallpassL[filteridx][bufidx] = input + (bufout*x->x_allpassfeedback); + + if(++x->x_allpassidxL[filteridx] >= x->x_allpasstuningL[filteridx]) + x->x_allpassidxL[filteridx] = 0; + + return output; +} + +static inline t_float allpass_processR(t_freeverb *x, int filteridx, t_float input) +{ + t_float output; + t_float bufout; + int bufidx = x->x_allpassidxR[filteridx]; + + bufout = (t_float)x->x_bufallpassR[filteridx][bufidx]; + FIX_DENORM_NAN_FLOAT(bufout); + + output = -input + bufout; + x->x_bufallpassR[filteridx][bufidx] = input + (bufout*x->x_allpassfeedback); + + if(++x->x_allpassidxR[filteridx] >= x->x_allpasstuningR[filteridx]) + x->x_allpassidxR[filteridx] = 0; + + return output; +} + +/* -------------------- general DSP stuff ----------------------- */ +t_int *freeverb_perform(t_int *w) +{ + // assign from parameters + t_freeverb *x = (t_freeverb *)(w[1]); + t_float *in1 = (t_float *)(w[2]); + t_float *in2 = (t_float *)(w[3]); + t_float *out1 = (t_float *)(w[4]); + t_float *out2 = (t_float *)(w[5]); + int n = (int)(w[6]); + int i; + t_float outL, outR, inL, inR, input; + +#ifndef PD + if (x->x_obj.z_disabled) + goto out; +#endif + + if(x->x_bypass) + { + // Bypass, so just copy input to output + while(n--) + { + inL = *in1++; // We have to copy first before we can write to output + inR = *in2++; // since this might be at the same memory position + *out1++ = inL; + *out2++ = inR; + } + } + else + { + // DSP loop + while(n--) + { + outL = outR = 0.; + inL = *in1++; + inR = *in2++; + input = (inL + inR) * x->x_gain; + + // Accumulate comb filters in parallel + for(i=0; i < numcombs; i++) + { + outL += comb_processL(x, i, input); + outR += comb_processR(x, i, input); + } + + // Feed through allpasses in series + for(i=0; i < numallpasses; i++) + { + outL = allpass_processL(x, i, outL); + outR = allpass_processR(x, i, outR); + } + + // Calculate output REPLACING anything already there + *out1++ = outL*x->x_wet1 + outR*x->x_wet2 + inL*x->x_dry; + *out2++ = outR*x->x_wet1 + outL*x->x_wet2 + inR*x->x_dry; + } + }
+#ifndef PD +out:
+#endif + return(w + 7); +} + +// This is a hand unrolled version of the perform routine for
+// DSP vector sizes that are multiples of 8
+t_int *freeverb_perf8(t_int *w)
+{
+ // assign from parameters
+ t_freeverb *x = (t_freeverb *)(w[1]);
+ t_float *in1 = (t_float *)(w[2]);
+ t_float *in2 = (t_float *)(w[3]);
+ t_float *out1 = (t_float *)(w[4]);
+ t_float *out2 = (t_float *)(w[5]);
+ int n = (int)(w[6]);
+ int i;
+ t_float outL[8], outR[8], inL[8], inR[8], input[8];
+
+#ifndef PD
+ if (x->x_obj.z_disabled)
+ goto out;
+#endif
+
+ if(x->x_bypass)
+ {
+ // Bypass, so just copy input to output
+ for(; n; n -= 8, out1 += 8, out2 += 8, in1 += 8, in2 += 8)
+ {
+ inL[0] = in1[0]; // We have to copy first before we can write to output
+ inR[0] = in2[0]; // since this might be at the same memory position
+ out1[0] = inL[0];
+ out2[0] = inR[0];
+ inL[1] = in1[1];
+ inR[1] = in2[1];
+ out1[1] = inL[1];
+ out2[1] = inR[1];
+ inL[2] = in1[2];
+ inR[2] = in2[2];
+ out1[2] = inL[2];
+ out2[2] = inR[2];
+ inL[3] = in1[3];
+ inR[3] = in2[3];
+ out1[3] = inL[3];
+ out2[3] = inR[3];
+ inL[4] = in1[4];
+ inR[4] = in2[4];
+ out1[4] = inL[4];
+ out2[4] = inR[4];
+ inL[5] = in1[5];
+ inR[5] = in2[5];
+ out1[5] = inL[5];
+ out2[5] = inR[5];
+ inL[6] = in1[6];
+ inR[6] = in2[6];
+ out1[6] = inL[6];
+ out2[6] = inR[6];
+ inL[7] = in1[7];
+ inR[7] = in2[7];
+ out1[7] = inL[7];
+ out2[7] = inR[7];
+ }
+ }
+ else
+ {
+ // DSP loop
+ for(; n; n -= 8, out1 += 8, out2 += 8, in1 += 8, in2 += 8)
+ {
+ outL[0] = outR [0]= 0.;
+ inL[0] = in1[0];
+ inR[0] = in2[0];
+ input[0] = (inL[0] + inR[0]) * x->x_gain;
+
+ outL[1] = outR [1]= 0.;
+ inL[1] = in1[1];
+ inR[1] = in2[1];
+ input[1] = (inL[1] + inR[1]) * x->x_gain;
+
+ outL[2] = outR [2]= 0.;
+ inL[2] = in1[2];
+ inR[2] = in2[2];
+ input[2] = (inL[2] + inR[2]) * x->x_gain;
+
+ outL[3] = outR [3]= 0.;
+ inL[3] = in1[3];
+ inR[3] = in2[3];
+ input[3] = (inL[3] + inR[3]) * x->x_gain;
+
+ outL[4] = outR [4]= 0.;
+ inL[4] = in1[4];
+ inR[4] = in2[4];
+ input[4] = (inL[4] + inR[4]) * x->x_gain;
+
+ outL[5] = outR [5]= 0.;
+ inL[5] = in1[5];
+ inR[5] = in2[5];
+ input[5] = (inL[5] + inR[5]) * x->x_gain;
+
+ outL[6] = outR [6]= 0.;
+ inL[6] = in1[6];
+ inR[6] = in2[6];
+ input[6] = (inL[6] + inR[6]) * x->x_gain;
+
+ outL[7] = outR [7]= 0.;
+ inL[7] = in1[7];
+ inR[7] = in2[7];
+ input[7] = (inL[7] + inR[7]) * x->x_gain;
+
+ // Accumulate comb filters in parallel
+ for(i=0; i < numcombs; i++)
+ {
+ outL[0] += comb_processL(x, i, input[0]);
+ outR[0] += comb_processR(x, i, input[0]);
+ outL[1] += comb_processL(x, i, input[1]);
+ outR[1] += comb_processR(x, i, input[1]);
+ outL[2] += comb_processL(x, i, input[2]);
+ outR[2] += comb_processR(x, i, input[2]);
+ outL[3] += comb_processL(x, i, input[3]);
+ outR[3] += comb_processR(x, i, input[3]);
+ outL[4] += comb_processL(x, i, input[4]);
+ outR[4] += comb_processR(x, i, input[4]);
+ outL[5] += comb_processL(x, i, input[5]);
+ outR[5] += comb_processR(x, i, input[5]);
+ outL[6] += comb_processL(x, i, input[6]);
+ outR[6] += comb_processR(x, i, input[6]);
+ outL[7] += comb_processL(x, i, input[7]);
+ outR[7] += comb_processR(x, i, input[7]);
+ }
+
+ // Feed through allpasses in series
+ for(i=0; i < numallpasses; i++)
+ {
+ outL[0] = allpass_processL(x, i, outL[0]);
+ outR[0] = allpass_processR(x, i, outR[0]);
+ outL[1] = allpass_processL(x, i, outL[1]);
+ outR[1] = allpass_processR(x, i, outR[1]);
+ outL[2] = allpass_processL(x, i, outL[2]);
+ outR[2] = allpass_processR(x, i, outR[2]);
+ outL[3] = allpass_processL(x, i, outL[3]);
+ outR[3] = allpass_processR(x, i, outR[3]);
+ outL[4] = allpass_processL(x, i, outL[4]);
+ outR[4] = allpass_processR(x, i, outR[4]);
+ outL[5] = allpass_processL(x, i, outL[5]);
+ outR[5] = allpass_processR(x, i, outR[5]);
+ outL[6] = allpass_processL(x, i, outL[6]);
+ outR[6] = allpass_processR(x, i, outR[6]);
+ outL[7] = allpass_processL(x, i, outL[7]);
+ outR[7] = allpass_processR(x, i, outR[7]);
+ }
+
+ // Calculate output REPLACING anything already there
+ out1[0] = outL[0]*x->x_wet1 + outR[0]*x->x_wet2 + inL[0]*x->x_dry;
+ out2[0] = outR[0]*x->x_wet1 + outL[0]*x->x_wet2 + inR[0]*x->x_dry;
+
+ out1[1] = outL[1]*x->x_wet1 + outR[1]*x->x_wet2 + inL[1]*x->x_dry;
+ out2[1] = outR[1]*x->x_wet1 + outL[1]*x->x_wet2 + inR[1]*x->x_dry;
+ out1[2] = outL[2]*x->x_wet1 + outR[2]*x->x_wet2 + inL[2]*x->x_dry;
+ out2[2] = outR[2]*x->x_wet1 + outL[2]*x->x_wet2 + inR[2]*x->x_dry;
+ out1[3] = outL[3]*x->x_wet1 + outR[3]*x->x_wet2 + inL[3]*x->x_dry;
+ out2[3] = outR[3]*x->x_wet1 + outL[3]*x->x_wet2 + inR[3]*x->x_dry;
+ out1[4] = outL[4]*x->x_wet1 + outR[4]*x->x_wet2 + inL[4]*x->x_dry;
+ out2[4] = outR[4]*x->x_wet1 + outL[4]*x->x_wet2 + inR[4]*x->x_dry;
+ out1[5] = outL[5]*x->x_wet1 + outR[5]*x->x_wet2 + inL[5]*x->x_dry;
+ out2[5] = outR[5]*x->x_wet1 + outL[5]*x->x_wet2 + inR[5]*x->x_dry;
+ out1[6] = outL[6]*x->x_wet1 + outR[6]*x->x_wet2 + inL[6]*x->x_dry;
+ out2[6] = outR[6]*x->x_wet1 + outL[6]*x->x_wet2 + inR[6]*x->x_dry;
+ out1[7] = outL[7]*x->x_wet1 + outR[7]*x->x_wet2 + inL[7]*x->x_dry;
+ out2[7] = outR[7]*x->x_wet1 + outL[7]*x->x_wet2 + inR[7]*x->x_dry;
+ }
+ }
+#ifndef PD
+out:
+#endif
+ return(w + 7);
+}
+
+static void dsp_add_freeverb(t_freeverb *x, t_sample *in1, t_sample *in2,
+ t_sample *out1, t_sample *out2, int n)
+{
+ if(n & 7) // check whether block size is multiple of 8
+ dsp_add(freeverb_perform, 6, x, in1, in2, out1, out2, n);
+ else
+ dsp_add(freeverb_perf8, 6, x, in1, in2, out1, out2, n);
+}
+
+void freeverb_dsp(t_freeverb *x, t_signal **sp)
+{
+ dsp_add_freeverb(x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[0]->s_n);
+}
+ +// ----------- general parameter & calculation stuff ----------- + + // recalculate internal values after parameter change +static void freeverb_update(t_freeverb *x) +{ + + int i; + + x->x_wet1 = x->x_wet*(x->x_width/2 + 0.5); + x->x_wet2 = x->x_wet*((1-x->x_width)/2); + + if (x->x_mode >= freezemode) + { + x->x_roomsize1 = 1.; + x->x_damp1 = 0.; + x->x_gain = muted; + } + else + { + x->x_roomsize1 = x->x_roomsize; + x->x_damp1 = x->x_damp; + x->x_gain = (float)fixedgain; + } + + comb_setfeedback(x, x->x_roomsize1); + comb_setdamp(x, x->x_damp1); +} + + // the following functions set / get the parameters +static void freeverb_setroomsize(t_freeverb *x, t_floatarg value) +{ + x->x_roomsize = (value*scaleroom) + offsetroom; + freeverb_update(x); +} + +static float freeverb_getroomsize(t_freeverb *x) +{ + return (x->x_roomsize-offsetroom)/scaleroom; +} + +static void freeverb_setdamp(t_freeverb *x, t_floatarg value) +{ + x->x_damp = value*scaledamp; + freeverb_update(x); +} + +static float freeverb_getdamp(t_freeverb *x) +{ + return x->x_damp/scaledamp; +} + +static void freeverb_setwet(t_freeverb *x, t_floatarg value) +{ + x->x_wet = value*scalewet; + freeverb_update(x); +} + +static float freeverb_getwet(t_freeverb *x) +{ + return (x->x_wet/scalewet); +} + +static void freeverb_setdry(t_freeverb *x, t_floatarg value) +{ + x->x_dry = value*scaledry; +} + +static float freeverb_getdry(t_freeverb *x) +{ + return (x->x_dry/scaledry); +} + +static void freeverb_setwidth(t_freeverb *x, t_floatarg value) +{ + x->x_width = value; + freeverb_update(x); +} + +static float freeverb_getwidth(t_freeverb *x) +{ + return x->x_width; +} + +static void freeverb_setmode(t_freeverb *x, t_floatarg value) +{ + x->x_mode = value; + freeverb_update(x); +} + +static float freeverb_getmode(t_freeverb *x) +{ + if (x->x_mode >= freezemode) + return 1; + else + return 0; +} + +static void freeverb_setbypass(t_freeverb *x, t_floatarg value) +{ + x->x_bypass = value; + if(x->x_bypass)freeverb_mute(x); +} + + // fill delay lines with silence +static void freeverb_mute(t_freeverb *x) +{ + int i; + + if (freeverb_getmode(x) >= freezemode) + return; + + for (i=0;i<numcombs;i++) + { + memset(x->x_bufcombL[i], 0x0, x->x_combtuningL[i]*sizeof(t_float)); + memset(x->x_bufcombR[i], 0x0, x->x_combtuningR[i]*sizeof(t_float)); + } + for (i=0;i<numallpasses;i++) + { + memset(x->x_bufallpassL[i], 0x0, x->x_allpasstuningL[i]*sizeof(t_float)); + memset(x->x_bufallpassR[i], 0x0, x->x_allpasstuningR[i]*sizeof(t_float)); + } +} + + // convert gain factor into dB +static float freeverb_getdb(float f) +{ + if (f <= 0) // equation does not work for 0... + { + return (-96); // ...so we output max. damping + } + else + { + float val = (20./LOGTEN * log(f)); + return (val); + } +} + +static void freeverb_print(t_freeverb *x) +{ + post("freeverb~:"); + if(x->x_bypass) { + post(" bypass: on"); + } else post(" bypass: off"); + if(!freeverb_getmode(x)) { + post(" mode: normal"); + } else post(" mode: freeze"); + post(" roomsize: %g", freeverb_getroomsize(x)*scaleroom+offsetroom); + post(" damping: %g %%", freeverb_getdamp(x)*100); + post(" width: %g %%", x->x_width * 100); + post(" wet level: %g dB", freeverb_getdb(freeverb_getwet(x)*scalewet)); + post(" dry level: %g dB", freeverb_getdb(freeverb_getdry(x)*scaledry)); +} + + // clean up +static void freeverb_free(t_freeverb *x) +{ + int i; +#ifndef PD
+ dsp_free((t_pxobject *)x); // Free the object
+#endif
+ // free memory used by delay lines + for(i = 0; i < numcombs; i++) + { + t_freebytes(x->x_bufcombL[i], x->x_combtuningL[i]*sizeof(t_float)); + t_freebytes(x->x_bufcombR[i], x->x_combtuningR[i]*sizeof(t_float)); + } + + for(i = 0; i < numallpasses; i++) + { + t_freebytes(x->x_bufallpassL[i], x->x_allpasstuningL[i]*sizeof(t_float)); + t_freebytes(x->x_bufallpassR[i], x->x_allpasstuningR[i]*sizeof(t_float)); + } +} + +void *freeverb_new(t_floatarg f) +{ + int i; + int sr = (int)sys_getsr(); + +#ifdef PD + t_freeverb *x = (t_freeverb *)pd_new(freeverb_class); + + // add additional signal inlets and signal outlets + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); + + outlet_new(&x->x_obj, gensym("signal")); + outlet_new(&x->x_obj, gensym("signal")); +#else // Max/MSP + t_freeverb *x = (t_freeverb *)newobject(freeverb_class); + + // zero out the struct, to be careful + if(x) + { + for(i = sizeof(t_pxobject); i < sizeof(t_freeverb); i++) + ((char*)x)[i] = 0; + } + + dsp_setup((t_pxobject *)x,2); // two signal inlets + + // two signal outlets + outlet_new((t_object *)x, "signal"); + outlet_new((t_object *)x, "signal"); +#endif + // recalculate the reverb parameters in case we don't run at 44.1kHz + for(i = 0; i < numcombs; i++) + { + x->x_combtuningL[i] = (int)(combtuningL[i] * sr / 44100); + x->x_combtuningR[i] = (int)(combtuningR[i] * sr / 44100); + } + for(i = 0; i < numallpasses; i++) + { + x->x_allpasstuningL[i] = (int)(allpasstuningL[i] * sr / 44100); + x->x_allpasstuningR[i] = (int)(allpasstuningL[i] * sr / 44100); + } + + // get memory for delay lines + for(i = 0; i < numcombs; i++) + { + x->x_bufcombL[i] = (t_float*) t_getbytes(x->x_combtuningL[i]*sizeof(t_float)); + x->x_bufcombR[i] = (t_float*) t_getbytes(x->x_combtuningR[i]*sizeof(t_float)); + x->x_combidxL[i] = 0; + x->x_combidxR[i] = 0; + } + for(i = 0; i < numallpasses; i++) + { + x->x_bufallpassL[i] = (t_float*) t_getbytes(x->x_allpasstuningL[i]*sizeof(t_float)); + x->x_bufallpassR[i] = (t_float*) t_getbytes(x->x_allpasstuningR[i]*sizeof(t_float)); + x->x_allpassidxL[i] = 0; + x->x_allpassidxR[i] = 0; + } + + // set default values + x->x_allpassfeedback = 0.5; + x->x_skip = 1; // we use every sample + freeverb_setwet(x, initialwet); + freeverb_setroomsize(x, initialroom); + freeverb_setdry(x, initialdry); + freeverb_setdamp(x, initialdamp); + freeverb_setwidth(x, initialwidth); + freeverb_setmode(x, initialmode); + freeverb_setbypass(x, initialbypass); + + // buffers will be full of rubbish - so we MUST mute them + freeverb_mute(x); + + return (x); +} + +#ifdef PD +extern "C" void freeverb_tilde_setup(void) +{ + freeverb_class = class_new(gensym("freeverb~"), (t_newmethod)freeverb_new, (t_method)freeverb_free, + sizeof(t_freeverb), 0, A_DEFFLOAT, 0); + CLASS_MAINSIGNALIN(freeverb_class, t_freeverb, x_float); + class_addmethod(freeverb_class, (t_method)freeverb_dsp, gensym("dsp"), A_NULL);
+ class_addmethod(freeverb_class, (t_method)freeverb_setroomsize, gensym("roomsize"), A_FLOAT, A_NULL); + class_addmethod(freeverb_class, (t_method)freeverb_setdamp, gensym("damping"), A_FLOAT, A_NULL); + class_addmethod(freeverb_class, (t_method)freeverb_setwidth, gensym("width"), A_FLOAT, A_NULL); + class_addmethod(freeverb_class, (t_method)freeverb_setwet, gensym("wet"), A_FLOAT, A_NULL); + class_addmethod(freeverb_class, (t_method)freeverb_setdry, gensym("dry"), A_FLOAT, A_NULL); + class_addmethod(freeverb_class, (t_method)freeverb_setmode, gensym("freeze"), A_FLOAT, A_NULL); + class_addmethod(freeverb_class, (t_method)freeverb_setbypass, gensym("bypass"), A_FLOAT, A_NULL); + class_addmethod(freeverb_class, (t_method)freeverb_mute, gensym("clear"), A_NULL); + class_addmethod(freeverb_class, (t_method)freeverb_print, gensym("print"), A_NULL); + class_sethelpsymbol(freeverb_class, gensym("help-freeverb~.pd")); + post(version); +} + +#else +// ----------- Max/MSP ----------- +void freeverb_assist(t_freeverb *x, void *b, long m, long a, char *s) +{ + switch(m) { + case 1: // inlet + switch(a) { + case 0: + sprintf(s, "(signal/message) Left Input & Control Messages"); + break; + case 1: + sprintf(s, "(signal) Right Input"); + break; + } + break; + case 2: // outlet + switch(a) { + case 0: + sprintf(s, "(signal) Left Output"); + break; + case 1: + sprintf(s, "(signal) Right Output"); + break; + } + break; + } + +} + +extern "C" void main(void) +{ + setup((t_messlist **)&freeverb_class,(method)freeverb_new, (method)freeverb_free, + (short)sizeof(t_freeverb), 0L, A_DEFFLOAT, 0); + addmess((method)freeverb_dsp, "dsp", A_CANT, 0); + addmess((method)freeverb_assist, "assist", A_CANT, 0); + addmess((method)freeverb_setroomsize, "roomsize", A_FLOAT, 0); + addmess((method)freeverb_setdamp, "damping", A_FLOAT, 0); + addmess((method)freeverb_setwidth, "width", A_FLOAT, 0); + addmess((method)freeverb_setwet, "wet", A_FLOAT, 0); + addmess((method)freeverb_setdry, "dry", A_FLOAT, 0); + addmess((method)freeverb_setmode, "freeze", A_FLOAT, 0); + addmess((method)freeverb_setbypass, "bypass", A_FLOAT, 0); + addmess((method)freeverb_mute, "clear", 0); + addmess((method)freeverb_print, "print", 0); + dsp_initclass(); + finder_addclass("MSP Delays","freeverb~"); + post(version); +} +#endif
\ No newline at end of file diff --git a/freeverb~.dsp b/freeverb~.dsp new file mode 100644 index 0000000..1aada56 --- /dev/null +++ b/freeverb~.dsp @@ -0,0 +1,118 @@ +# Microsoft Developer Studio Project File - Name="freeverb~" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=freeverb~ - WIN32 RELEASE
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "freeverb~.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "freeverb~.mak" CFG="freeverb~ - WIN32 RELEASE"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "freeverb~ - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "freeverb~ - Win32 Intel Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 1
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=xicl6.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "freeverb~ - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "build-win\"
+# PROP Intermediate_Dir "obj\"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "freeverb~_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /G6 /Zp2 /MT /W3 /GX /O2 /Ob2 /I "..\..\c74support\max-includes" /I "..\..\c74support\msp-includes" /D "WIN_VERSION" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "WIN_EXT_VERSION" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /win32
+# SUBTRACT MTL /mktyplib203
+# ADD BASE RSC /l 0xc07 /d "NDEBUG"
+# ADD RSC /l 0xc07
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 ..\..\c74support\max-includes\win-includes\release\MaxAPI.lib ..\..\c74support\max-includes\win-includes\release\MaxExt.lib ..\..\c74support\msp-includes\win-includes\release\MaxAudio.lib /nologo /dll /machine:I386 /out:"freeverb~.mxe" /libpath:"../../bin" /export:main
+# SUBTRACT LINK32 /pdb:none /incremental:yes /nodefaultlib
+
+!ELSEIF "$(CFG)" == "freeverb~ - Win32 Intel Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "freeverb____Win32_Intel_Release"
+# PROP BASE Intermediate_Dir "freeverb____Win32_Intel_Release"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "build-intel\"
+# PROP Intermediate_Dir "obj\"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /Zp2 /MT /W3 /GX /O2 /Ob2 /I "..\..\c74support\max-includes" /I "..\..\c74support\msp-includes" /D "WIN_VERSION" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "WIN_EXT_VERSION" /D "_LANGUAGE_C_PLUS_PLUS" /YX /FD /c
+# ADD CPP /nologo /Zp2 /MT /W3 /GX /I "..\..\c74support\max-includes" /I "..\..\c74support\msp-includes" /D "WIN_VERSION" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "WIN_EXT_VERSION" /D "_LANGUAGE_C_PLUS_PLUS" /YX /FD /O3 /G7 /QaxW /c
+# ADD BASE MTL /nologo /win32
+# SUBTRACT BASE MTL /mktyplib203
+# ADD MTL /nologo /win32
+# SUBTRACT MTL /mktyplib203
+# ADD BASE RSC /l 0xc07
+# ADD RSC /l 0xc07
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=xilink6.exe
+# ADD BASE LINK32 ..\..\c74support\max-includes\win-includes\release\MaxAPI.lib ..\..\c74support\max-includes\win-includes\release\MaxExt.lib ..\..\c74support\msp-includes\win-includes\release\MaxAudio.lib /nologo /dll /machine:I386 /out:"freeverb~.mxe" /libpath:"../../bin" /export:main
+# SUBTRACT BASE LINK32 /pdb:none /incremental:yes /nodefaultlib
+# ADD LINK32 ..\..\c74support\max-includes\win-includes\release\MaxAPI.lib ..\..\c74support\max-includes\win-includes\release\MaxExt.lib ..\..\c74support\msp-includes\win-includes\release\MaxAudio.lib /nologo /dll /machine:I386 /out:"freeverb~.mxe" /libpath:"../../bin" /export:main
+# SUBTRACT LINK32 /pdb:none /incremental:yes /nodefaultlib
+
+!ENDIF
+
+# Begin Target
+
+# Name "freeverb~ - Win32 Release"
+# Name "freeverb~ - Win32 Intel Release"
+# Begin Group "Quellcodedateien"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\freeverb~.c
+# End Source File
+# End Group
+# Begin Group "Header-Dateien"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE="..\..\c74support\max-includes\ext.h"
+# End Source File
+# Begin Source File
+
+SOURCE="..\..\c74support\msp-includes\z_dsp.h"
+# End Source File
+# End Group
+# End Target
+# End Project
|