aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormusil <tmusil@users.sourceforge.net>2006-03-10 03:05:55 +0000
committermusil <tmusil@users.sourceforge.net>2006-03-10 03:05:55 +0000
commit8c5d0621d0d305bb62997b4ad12af874ec253432 (patch)
tree2143632f92074a112b52b1260eef056c336dda30
initial check insvn2git-root
svn path=/trunk/externals/iem/iem_tab/; revision=4683
-rw-r--r--GnuGPL.txt340
-rw-r--r--LICENSE.txt27
-rw-r--r--READ_ME.txt5
-rw-r--r--help/tab_abs-help.pd49
-rw-r--r--help/tab_add-help.pd70
-rw-r--r--help/tab_add_scalar-help.pd51
-rw-r--r--help/tab_complex_mul-help.pd109
-rw-r--r--help/tab_const-help.pd43
-rw-r--r--help/tab_copy-help.pd48
-rw-r--r--help/tab_counter-help.pd45
-rw-r--r--help/tab_cross_corr-help.pd74
-rw-r--r--help/tab_div-help.pd70
-rw-r--r--help/tab_eq-help.pd70
-rw-r--r--help/tab_eq_scalar-help.pd50
-rw-r--r--help/tab_fft-help.pd181
-rw-r--r--help/tab_find_peaks-help.pd63
-rw-r--r--help/tab_ge-help.pd70
-rw-r--r--help/tab_ge_scalar-help.pd50
-rw-r--r--help/tab_gt-help.pd70
-rw-r--r--help/tab_gt_scalar-help.pd50
-rw-r--r--help/tab_ifft-help.pd154
-rw-r--r--help/tab_le-help.pd70
-rw-r--r--help/tab_le_scalar-help.pd50
-rw-r--r--help/tab_lt-help.pd70
-rw-r--r--help/tab_lt_scalar-help.pd50
-rw-r--r--help/tab_max_index-help.pd52
-rw-r--r--help/tab_min_index-help.pd52
-rw-r--r--help/tab_min_max-help.pd52
-rw-r--r--help/tab_mul-help.pd70
-rw-r--r--help/tab_mul_scalar-help.pd51
-rw-r--r--help/tab_ne-help.pd70
-rw-r--r--help/tab_ne_scalar-help.pd50
-rw-r--r--help/tab_reverse-help.pd50
-rw-r--r--help/tab_rfft-help.pd180
-rw-r--r--help/tab_rifft-help.pd152
-rw-r--r--help/tab_sqrt-help.pd49
-rw-r--r--help/tab_sub-help.pd70
-rw-r--r--help/tab_sum-help.pd43
-rw-r--r--src/iem_tab.c134
-rw-r--r--src/iem_tab.dsp85
-rw-r--r--src/iem_tab.dsw29
-rw-r--r--src/iem_tab.h18
-rw-r--r--src/iemlib.h102
-rw-r--r--src/makefile83
-rw-r--r--src/makefile_win73
-rw-r--r--src/tab_abs.c170
-rw-r--r--src/tab_add.c196
-rw-r--r--src/tab_add_scalar.c173
-rw-r--r--src/tab_complex_inv.c246
-rw-r--r--src/tab_complex_mul.c298
-rw-r--r--src/tab_const.c169
-rw-r--r--src/tab_conv.c228
-rw-r--r--src/tab_copy.c170
-rw-r--r--src/tab_counter.c208
-rw-r--r--src/tab_cross_corr.c222
-rw-r--r--src/tab_div.c206
-rw-r--r--src/tab_eq.c206
-rw-r--r--src/tab_eq_scalar.c183
-rw-r--r--src/tab_fft.c400
-rw-r--r--src/tab_find_peaks.c389
-rw-r--r--src/tab_ge.c206
-rw-r--r--src/tab_ge_scalar.c183
-rw-r--r--src/tab_gt.c206
-rw-r--r--src/tab_gt_scalar.c183
-rw-r--r--src/tab_ifft.c414
-rw-r--r--src/tab_le.c206
-rw-r--r--src/tab_le_scalar.c183
-rw-r--r--src/tab_lt.c206
-rw-r--r--src/tab_lt_scalar.c183
-rw-r--r--src/tab_max_index.c155
-rw-r--r--src/tab_mean.c143
-rw-r--r--src/tab_min_index.c155
-rw-r--r--src/tab_min_max.c153
-rw-r--r--src/tab_mls.c256
-rw-r--r--src/tab_mul.c196
-rw-r--r--src/tab_mul_scalar.c173
-rw-r--r--src/tab_ne.c206
-rw-r--r--src/tab_ne_scalar.c183
-rw-r--r--src/tab_reverse.c170
-rw-r--r--src/tab_rfft.c391
-rw-r--r--src/tab_rifft.c406
-rw-r--r--src/tab_sin.c221
-rw-r--r--src/tab_sqrt.c221
-rw-r--r--src/tab_sub.c196
-rw-r--r--src/tab_sum.c143
85 files changed, 12196 insertions, 0 deletions
diff --git a/GnuGPL.txt b/GnuGPL.txt
new file mode 100644
index 0000000..d60c31a
--- /dev/null
+++ b/GnuGPL.txt
@@ -0,0 +1,340 @@
+ 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) <year> <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) year 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/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..a38e9e8
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,27 @@
+iem_tab - dynamic library for pd; handle array operations
+
+Copyright (C) 2000-2006 Thomas MUSIL [musil_at_iem.at]
+
+IEM - Institute of Electronic Music and Acoustics, Graz
+Inffeldgasse 10/3, 8010 Graz, Austria
+http://iem.at
+
+
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details ( GnuGPL.txt ).
+ (e.g. http://www.gnu.org/copyleft/gpl.html)
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Graz, 15 June 2005
+ Thomas Musil \ No newline at end of file
diff --git a/READ_ME.txt b/READ_ME.txt
new file mode 100644
index 0000000..6bda311
--- /dev/null
+++ b/READ_ME.txt
@@ -0,0 +1,5 @@
+This library extends the performance of miller puckette's pure data (pd).
+
+The objects of iem_tab manipulate tables or arrays;
+you can set constant, copy, fft, ifft, reverse, find minimum or maximum, compare, add, subtrct, multiplicate, divide arrays.
+
diff --git a/help/tab_abs-help.pd b/help/tab_abs-help.pd
new file mode 100644
index 0000000..e216100
--- /dev/null
+++ b/help/tab_abs-help.pd
@@ -0,0 +1,49 @@
+#N canvas 116 92 778 405 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 156 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 301 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 59 211 50 20 50;
+#X text 44 154 list of 3 floats:;
+#X text 56 165 src-onset;
+#X text 56 175 dst-onset;
+#X text 139 299 1.arg: <symbol> source-name;
+#X text 139 312 2.arg: <symbol> destination-name;
+#X text 130 40 the minimum-size of arrays;
+#X msg 142 217 src src;
+#X msg 202 226 dst dst;
+#X obj 61 78 tab_abs src dst;
+#X text 90 29 <bang> copy absolute-value from zero-onset to zero-onset
+;
+#X text 58 184 n samples to copy absolute;
+#X obj 59 264 tab_abs src dst;
+#X connect 2 0 14 0;
+#X connect 5 0 17 0;
+#X connect 12 0 17 0;
+#X connect 13 0 17 0;
+#X connect 14 0 3 0;
+#X connect 17 0 4 0;
diff --git a/help/tab_add-help.pd b/help/tab_add-help.pd
new file mode 100644
index 0000000..aa14afd
--- /dev/null
+++ b/help/tab_add-help.pd
@@ -0,0 +1,70 @@
+#N canvas 116 92 847 552 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src1 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 358 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 57 173 dst-onset;
+#X msg 286 234 dst dst;
+#N canvas 0 0 450 300 graph1 0;
+#X array src2 100 float 1;
+#A 0 0.557135 0.57142 0.557135 0.528564 0.499992 0.428564 0.357136
+0.299994 0.0999951 -0.0571467 -0.157146 -0.228574 -0.300002 -0.328573
+-0.357145 -0.385716 -0.400001 -0.400001 -0.385716 -0.385716 -0.37143
+-0.364287 -0.357145 -0.328573 -0.300002 -0.271431 -0.24286 -0.214288
+-0.14286 -0.085718 -0.0428611 -4.28595e-006 0.0428526 0.099995 0.171423
+0.21428 0.257137 0.328565 0.371422 0.428564 0.457135 0.485707 0.499992
+0.514278 0.499992 0.471421 0.44285 0.414279 0.357136 0.285708 0.171423
+0.0999952 0.0142815 -0.100003 -0.214288 -0.314288 -0.385716 -0.457144
+-0.471429 -0.514286 -0.500001 -0.47143 -0.442858 -0.414287 -0.37143
+-0.300002 -0.228574 -0.157146 -0.0714324 0.0571381 0.128566 0.199994
+0.271422 0.34285 0.414278 0.457135 0.485707 0.499992 0.528563 0.542849
+0.499992 0.457135 0.428564 0.371422 0.314279 0.242851 0.0857095 -0.0857178
+-0.271431 -0.400001 -0.514286 -0.542858 -0.557143 -0.585714 -0.585714
+-0.6 -0.6 -0.614286 -0.614286 -0.614286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 161 graph;
+#X msg 142 217 src1 src1;
+#X msg 218 223 src2 src2;
+#X msg 59 211 50 50 20 50;
+#X text 45 139 list of 4 floats:;
+#X text 57 153 src1-onset;
+#X text 56 163 src2-onset;
+#X text 212 333 3.arg: <symbol> destination-name;
+#X text 126 42 with the minimum-size of arrays;
+#X text 90 29 <bang> add the 2 src-arrays to dst-array;
+#X text 57 183 n samples to add;
+#X obj 61 78 tab_add src1 src2 dst;
+#X obj 59 271 tab_add src1 src2 dst;
+#X text 211 306 1.arg: <symbol> source1-name;
+#X text 211 319 2.arg: <symbol> source2-name;
+#X connect 2 0 18 0;
+#X connect 6 0 19 0;
+#X connect 8 0 19 0;
+#X connect 9 0 19 0;
+#X connect 10 0 19 0;
+#X connect 18 0 3 0;
+#X connect 19 0 4 0;
diff --git a/help/tab_add_scalar-help.pd b/help/tab_add_scalar-help.pd
new file mode 100644
index 0000000..3f9aa57
--- /dev/null
+++ b/help/tab_add_scalar-help.pd
@@ -0,0 +1,51 @@
+#N canvas 115 92 852 556 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 176 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 325 graph;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 45 185 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X msg 255 235 dst dst;
+#X text 33 161 list of 4 floats:;
+#X text 165 42 with the minimum-size of arrays;
+#X msg 47 36 0.5;
+#X msg 159 229 src src;
+#X msg 82 37 -0.5;
+#X obj 61 78 tab_add_scalar src dst;
+#X obj 59 271 tab_add_scalar src dst;
+#X msg 48 227 50 20 50 -0.8;
+#X text 46 195 n samples to add;
+#X text 45 175 src-onset;
+#X text 45 206 add-scalar;
+#X text 211 319 2.arg: <symbol> destination-name;
+#X text 129 29 <float> add the src-array with this scalar to dst-array
+;
+#X connect 6 0 13 0;
+#X connect 9 0 12 0;
+#X connect 10 0 13 0;
+#X connect 11 0 12 0;
+#X connect 12 0 2 0;
+#X connect 13 0 3 0;
+#X connect 14 0 13 0;
diff --git a/help/tab_complex_mul-help.pd b/help/tab_complex_mul-help.pd
new file mode 100644
index 0000000..8ef7a5c
--- /dev/null
+++ b/help/tab_complex_mul-help.pd
@@ -0,0 +1,109 @@
+#N canvas 132 30 854 626 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array re1 100 float 0;
+#X coords 0 1 99 -1 100 40 1;
+#X restore 451 29 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 62 583 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 90 29 <bang> copy from zero-onset to zero-onset;
+#X text 130 40 the minimum-size of arrays;
+#N canvas 0 0 450 300 graph1 0;
+#X array im1 100 float 0;
+#X coords 0 1 99 -1 100 40 1;
+#X restore 451 71 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array re2 100 float 0;
+#X coords 0 1 99 -1 100 40 1;
+#X restore 596 29 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array im2 100 float 0;
+#X coords 0 1 99 -1 100 40 1;
+#X restore 596 71 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array re3 100 float 0;
+#X coords 0 1 99 -1 100 40 1;
+#X restore 735 28 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array im3 100 float 0;
+#X coords 0 1 99 -1 100 40 1;
+#X restore 735 70 graph;
+#X msg 501 210 \; re1 const 0.9 \; im1 const 0.6 \; re2 const 0.7 \;
+im2 const -0.8;
+#X obj 61 78 tab_complex_mul re1 im1 re2 im2 re3 im3;
+#X obj 671 243 tabread re3;
+#X obj 744 243 tabread im3;
+#X msg 681 199 2;
+#X floatatom 671 266 5 0 0 0 - - -;
+#X floatatom 744 267 5 0 0 0 - - -;
+#X obj 269 243 *;
+#X obj 298 243 *;
+#X obj 371 242 *;
+#X obj 400 242 *;
+#X obj 377 273 +;
+#X obj 278 274 -;
+#X msg 234 217 0.9 0.7;
+#X msg 290 217 0.6 -0.8;
+#X floatatom 279 297 5 0 0 0 - - -;
+#X msg 359 215 0.9 -0.8;
+#X msg 415 215 0.6 0.7;
+#X floatatom 377 295 5 0 0 0 - - -;
+#X obj 62 562 tab_complex_mul re1 im1 re2 im2 re3 im3;
+#X msg 82 402 src1_re re1;
+#X msg 199 512 dst_re re3;
+#X msg 240 535 dst_im im3;
+#X msg 99 428 src1_im im1;
+#X msg 151 453 src2_re re2;
+#X msg 169 479 src2_im im2;
+#X msg 48 378 0 0 0 0 0 0 64;
+#X text 37 275 list of 7 floats:;
+#X text 39 327 dst_re-onset;
+#X text 39 337 dst_im-onset;
+#X text 39 287 src1_re-onset;
+#X text 39 297 src1_im-onset;
+#X text 39 307 src2_re-onset;
+#X text 39 317 src2_im-onset;
+#X text 39 350 number of samples to multiply;
+#X text 327 516 1.arg: <symbol> real_source1-name;
+#X text 327 528 2.arg: <symbol> imag_source1-name;
+#X text 327 540 3.arg: <symbol> real_source2-name;
+#X text 328 551 4.arg: <symbol> imag_source2-name;
+#X text 328 563 5.arg: <symbol> real_destination-name;
+#X text 328 574 6.arg: <symbol> imag_destination-name;
+#X obj 305 174 t b b b b;
+#X obj 305 150 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 500 188 loadbang;
+#X connect 1 0 12 0;
+#X connect 12 0 2 0;
+#X connect 13 0 16 0;
+#X connect 14 0 17 0;
+#X connect 15 0 13 0;
+#X connect 15 0 14 0;
+#X connect 18 0 23 0;
+#X connect 19 0 23 1;
+#X connect 20 0 22 0;
+#X connect 21 0 22 1;
+#X connect 22 0 29 0;
+#X connect 23 0 26 0;
+#X connect 24 0 18 0;
+#X connect 25 0 19 0;
+#X connect 27 0 20 0;
+#X connect 28 0 21 0;
+#X connect 30 0 3 0;
+#X connect 31 0 30 0;
+#X connect 32 0 30 0;
+#X connect 33 0 30 0;
+#X connect 34 0 30 0;
+#X connect 35 0 30 0;
+#X connect 36 0 30 0;
+#X connect 37 0 30 0;
+#X connect 52 0 24 0;
+#X connect 52 1 25 0;
+#X connect 52 2 27 0;
+#X connect 52 3 28 0;
+#X connect 53 0 52 0;
+#X connect 54 0 11 0;
diff --git a/help/tab_const-help.pd b/help/tab_const-help.pd
new file mode 100644
index 0000000..c853ef9
--- /dev/null
+++ b/help/tab_const-help.pd
@@ -0,0 +1,43 @@
+#N canvas 116 92 778 405 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 1;
+#A 0 0 0 0 0 0 0 0.0428571 0.1 0.128571 0.185714 0.257143 0.3 0.371429
+0.428571 0.471429 0.557143 0.614286 0.671429 0.4 0.171429 0.0714286
+-0.0857142 -0.285714 -0.557143 -0.542857 -0.485714 -0.457143 -0.428571
+-0.357143 -0.314286 -0.271429 -0.221429 -0.171429 -0.128571 -0.0857143
+-0.0428571 1.49012e-008 0.0428572 0.0857143 0.128571 0.171429 0.271429
+0.357143 0.442857 0.471429 -0.514286 -0.514286 -0.485714 -0.428571
+-0.342857 -0.292857 -0.242857 -0.2 -0.157143 -0.0285715 0.0357142 0.1
+0.152381 0.204762 0.257143 0.321429 0.385714 0.435714 0.485714 0.528571
+0.571429 0.621429 -0.242857 -0.414286 -0.414286 -0.4 -0.357143 -0.328571
+-0.3 -0.257143 -0.214286 -0.185714 -0.157143 -0.128571 -0.0785714 -0.0285714
+0.00476191 0.0380952 0.0714286 0.114286 0.157143 0.2 0.242857 0.278571
+0.314286 -0.228571 -0.242857 -0.214286 -0.2 -0.142857 -0.114286 -0.0714285
+-0.0285714 3.53903e-008 0.114286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 518 36 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 120 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 301 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 44 154 list of 3 floats:;
+#X text 57 165 dst-onset;
+#X msg 162 222 dst dst;
+#X obj 61 92 tab_const dst;
+#X msg 59 211 30 50 0.5;
+#X text 90 29 <bang> set all samples of array zero;
+#X text 59 174 n samples to set constant;
+#X text 57 183 constant-value;
+#X text 201 282 1.arg: <symbol> destination-name;
+#X obj 60 261 tab_const dst;
+#X msg 82 59 -0.7;
+#X msg 133 66 0.8;
+#X connect 1 0 7 0;
+#X connect 6 0 13 0;
+#X connect 7 0 2 0;
+#X connect 8 0 13 0;
+#X connect 13 0 3 0;
+#X connect 14 0 7 0;
+#X connect 15 0 7 0;
diff --git a/help/tab_copy-help.pd b/help/tab_copy-help.pd
new file mode 100644
index 0000000..8746cfa
--- /dev/null
+++ b/help/tab_copy-help.pd
@@ -0,0 +1,48 @@
+#N canvas 116 92 776 403 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 156 graph;
+#X obj 61 78 tab_copy src dst;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 301 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 59 211 50 20 50;
+#X text 44 154 list of 3 floats:;
+#X text 56 165 src-onset;
+#X text 56 175 dst-onset;
+#X text 58 184 n samples to copy;
+#X text 211 306 1.arg: <symbol> source-name;
+#X text 211 319 2.arg: <symbol> destination-name;
+#X text 90 29 <bang> copy from zero-onset to zero-onset;
+#X text 130 40 the minimum-size of arrays;
+#X msg 142 217 src src;
+#X msg 202 226 dst dst;
+#X obj 59 262 tab_copy src dst;
+#X connect 2 0 4 0;
+#X connect 3 0 2 0;
+#X connect 6 0 17 0;
+#X connect 15 0 17 0;
+#X connect 16 0 17 0;
+#X connect 17 0 5 0;
diff --git a/help/tab_counter-help.pd b/help/tab_counter-help.pd
new file mode 100644
index 0000000..e300826
--- /dev/null
+++ b/help/tab_counter-help.pd
@@ -0,0 +1,45 @@
+#N canvas 115 92 856 560 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 0 0 0 0 0 0 0 0 0 0.9 0 0 0 0 0 0 0 0 0 0.9 0 0 0 0 0 0 0 0 0
+0.9 0 0 0 0 0 0 0 0 0 0.9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0;
+#X coords 0 1 99 0 200 140 1;
+#X restore 527 176 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 10 99 0 200 140 1;
+#X restore 527 325 graph;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 45 185 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X msg 255 235 dst dst;
+#X msg 159 229 src src;
+#X text 45 175 src-onset;
+#X text 211 319 2.arg: <symbol> destination-name;
+#X obj 59 271 tab_gt_scalar src dst;
+#X obj 61 78 tab_counter src dst;
+#X msg 125 37 reset;
+#X msg 504 103 \; src const 0;
+#X msg 417 101 \; src \$1 0.9;
+#X floatatom 418 74 5 0 0 0 - - -;
+#X obj 53 33 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 48 228 0 0 100;
+#X text 46 195 n samples to control n counters;
+#X text 33 161 list of 3 floats:;
+#X text 212 22 <bang> controls with src-array the counter-state of
+dst-array (0 = reset counter \, 1 = increment counter);
+#X text 213 47 only the minimum-size of arrays;
+#X connect 6 0 10 0;
+#X connect 7 0 10 0;
+#X connect 10 0 3 0;
+#X connect 11 0 2 0;
+#X connect 12 0 11 0;
+#X connect 15 0 14 0;
+#X connect 16 0 11 0;
+#X connect 17 0 10 0;
diff --git a/help/tab_cross_corr-help.pd b/help/tab_cross_corr-help.pd
new file mode 100644
index 0000000..8c1c9ff
--- /dev/null
+++ b/help/tab_cross_corr-help.pd
@@ -0,0 +1,74 @@
+#N canvas 42 76 923 536 10;
+#X obj 12 36 dsp;
+#X obj 12 17 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X floatatom 12 78 5 0 0 0 - - -;
+#X floatatom 25 60 5 0 0 0 - - -;
+#X obj 171 88 noise~;
+#X obj 56 305 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 63 11 701 593 tables 0;
+#N canvas 0 0 450 300 graph1 0;
+#X array ref 200 float 0;
+#X coords 0 1 199 -1 398 140 1;
+#X restore 52 19 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array meas 100 float 0;
+#X coords 0 1 99 -1 198 140 1;
+#X restore 52 161 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array cross_corr 100 float 0;
+#X coords 0 1 99 -1 198 140 1;
+#X restore 53 411 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array win 100 float 0;
+#X coords 0 1 99 -1 198 140 1;
+#X restore 307 183 graph;
+#X restore 417 82 pd tables;
+#X obj 411 322 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 76 346 tabwrite~ ref;
+#X obj 170 346 tabwrite~ meas;
+#X obj 412 371 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 75 203 z~ 50;
+#X obj 411 341 tab_cross_corr ref meas cross_corr 0.01 1;
+#X obj 214 168 z~ 10;
+#X obj 268 178 z~ 20;
+#X obj 658 226 tabwrite win;
+#X obj 658 46 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 658 67 for++ 0 99 0.1;
+#X obj 658 88 t f f;
+#X obj 658 115 / 100;
+#X obj 658 137 * 3.14159;
+#X obj 658 159 sin;
+#X msg 658 181 \$1 \$1;
+#X obj 658 202 *;
+#X obj 489 171 tab_mul meas win meas;
+#X obj 489 151 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X connect 0 0 2 0;
+#X connect 0 1 3 0;
+#X connect 1 0 0 0;
+#X connect 4 0 9 0;
+#X connect 4 0 11 0;
+#X connect 4 0 13 0;
+#X connect 4 0 14 0;
+#X connect 5 0 8 0;
+#X connect 5 0 9 0;
+#X connect 7 0 12 0;
+#X connect 11 0 8 0;
+#X connect 12 0 10 0;
+#X connect 13 0 9 0;
+#X connect 14 0 9 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 0;
+#X connect 18 0 19 0;
+#X connect 18 1 15 1;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 22 0;
+#X connect 22 0 23 0;
+#X connect 23 0 15 0;
+#X connect 25 0 24 0;
diff --git a/help/tab_div-help.pd b/help/tab_div-help.pd
new file mode 100644
index 0000000..f8b4e68
--- /dev/null
+++ b/help/tab_div-help.pd
@@ -0,0 +1,70 @@
+#N canvas 116 92 843 548 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src1 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 358 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 57 173 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X msg 286 234 dst dst;
+#N canvas 0 0 450 300 graph1 0;
+#X array src2 100 float 1;
+#A 0 0.557135 0.57142 0.557135 0.528564 0.499992 0.428564 0.357136
+0.299994 0.0999951 -0.0571467 -0.157146 -0.228574 -0.300002 -0.328573
+-0.357145 -0.385716 -0.400001 -0.400001 -0.385716 -0.385716 -0.385716
+-0.357145 -0.342859 -0.342859 -0.328573 -0.300002 -0.257145 -0.185717
+-0.128575 -0.0428612 0.0142812 0.142852 0.228565 0.271422 0.314279
+0.357136 0.371422 0.414278 0.428564 0.44285 0.44285 0.457135 0.499992
+0.514278 0.499992 0.471421 0.44285 0.414279 0.357136 0.285708 0.171423
+0.0999952 0.0142815 -0.100003 -0.214288 -0.314288 -0.385716 -0.457144
+-0.471429 -0.514286 -0.500001 -0.47143 -0.442858 -0.414287 -0.37143
+-0.300002 -0.228574 -0.157146 -0.0714324 0.0571381 0.128566 0.199994
+0.271422 0.34285 0.414278 0.457135 0.485707 0.499992 0.528563 0.542849
+0.499992 0.457135 0.428564 0.371422 0.314279 0.242851 0.0857095 -0.0857178
+-0.271431 -0.400001 -0.514286 -0.542858 -0.557143 -0.585714 -0.585714
+-0.6 -0.6 -0.614286 -0.614286 -0.614286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 161 graph;
+#X msg 142 217 src1 src1;
+#X msg 218 223 src2 src2;
+#X msg 59 211 50 50 20 50;
+#X text 45 139 list of 4 floats:;
+#X text 57 153 src1-onset;
+#X text 56 163 src2-onset;
+#X text 212 333 3.arg: <symbol> destination-name;
+#X text 211 319 2.arg: <symbol> source-name;
+#X text 126 42 with the minimum-size of arrays;
+#X obj 61 78 tab_div src1 src2 dst;
+#X text 90 29 <bang> divide the 2 src-arrays to dst-array;
+#X obj 59 271 tab_div src1 src2 dst;
+#X text 57 183 n samples to divide;
+#X connect 2 0 18 0;
+#X connect 7 0 20 0;
+#X connect 9 0 20 0;
+#X connect 10 0 20 0;
+#X connect 11 0 20 0;
+#X connect 18 0 3 0;
+#X connect 20 0 4 0;
diff --git a/help/tab_eq-help.pd b/help/tab_eq-help.pd
new file mode 100644
index 0000000..05e8769
--- /dev/null
+++ b/help/tab_eq-help.pd
@@ -0,0 +1,70 @@
+#N canvas 116 92 855 560 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src1 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 358 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 57 173 dst-onset;
+#X msg 286 234 dst dst;
+#N canvas 0 0 450 300 graph1 0;
+#X array src2 100 float 1;
+#A 0 0.557135 0.57142 0.557135 0.528564 0.499992 0.428564 0.357136
+0.299994 0.0999951 -0.0571467 -0.157146 -0.228574 -0.300002 -0.328573
+-0.357145 -0.385716 -0.400001 -0.400001 -0.385716 -0.385716 -0.37143
+-0.364287 -0.357145 -0.328573 -0.300002 -0.271431 -0.24286 -0.214288
+-0.14286 -0.085718 -0.0428611 -4.28595e-006 0.0428526 0.099995 0.171423
+0.21428 0.257137 0.328565 0.371422 0.428564 0.457135 0.485707 0.499992
+0.514278 0.499992 0.471421 0.44285 0.414279 0.357136 0.285708 0.171423
+0.0999952 0.0142815 -0.100003 -0.214288 -0.314288 -0.385716 -0.457144
+-0.471429 -0.514286 -0.500001 -0.47143 -0.442858 -0.414287 -0.37143
+-0.300002 -0.228574 -0.157146 -0.0714324 0.0571381 0.128566 0.199994
+0.271422 0.34285 0.414278 0.457135 0.485707 0.499992 0.528563 0.542849
+0.499992 0.457135 0.428564 0.371422 0.314279 0.242851 0.0857095 -0.0857178
+-0.271431 -0.400001 -0.514286 -0.542858 -0.557143 -0.585714 -0.585714
+-0.6 -0.6 -0.614286 -0.614286 -0.614286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 161 graph;
+#X msg 142 217 src1 src1;
+#X msg 218 223 src2 src2;
+#X msg 59 211 50 50 20 50;
+#X text 45 139 list of 4 floats:;
+#X text 57 153 src1-onset;
+#X text 56 163 src2-onset;
+#X text 212 333 3.arg: <symbol> destination-name;
+#X text 211 306 1.arg: <symbol> source1-name;
+#X text 211 319 2.arg: <symbol> source2-name;
+#X text 58 182 n samples to compare;
+#X obj 61 78 tab_eq src1 src2 dst;
+#X obj 59 271 tab_eq src1 src2 dst;
+#X text 97 26 <float> compare "equal to" 2 src-arrays to dst-array
+with the minimum-size of arrays;
+#X connect 2 0 18 0;
+#X connect 6 0 19 0;
+#X connect 8 0 19 0;
+#X connect 9 0 19 0;
+#X connect 10 0 19 0;
+#X connect 18 0 3 0;
+#X connect 19 0 4 0;
diff --git a/help/tab_eq_scalar-help.pd b/help/tab_eq_scalar-help.pd
new file mode 100644
index 0000000..8a08865
--- /dev/null
+++ b/help/tab_eq_scalar-help.pd
@@ -0,0 +1,50 @@
+#N canvas 75 200 868 572 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 176 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 325 graph;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 45 185 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X msg 255 235 dst dst;
+#X text 33 161 list of 4 floats:;
+#X msg 159 229 src src;
+#X text 45 175 src-onset;
+#X text 211 319 2.arg: <symbol> destination-name;
+#X msg 47 36 0.3;
+#X msg 82 37 -0.3;
+#X msg 48 228 0 0 100 0.3;
+#X text 46 195 n samples to compare;
+#X text 164 29 <float> compare "equal to" the src-array with this scalar
+to dst-array with the minimum-size of arrays;
+#X obj 61 78 tab_eq_scalar src dst;
+#X text 45 206 compare "equal to"-scalar;
+#X obj 59 271 tab_eq_scalar src dst;
+#X connect 6 0 18 0;
+#X connect 8 0 18 0;
+#X connect 11 0 16 0;
+#X connect 12 0 16 0;
+#X connect 13 0 18 0;
+#X connect 16 0 2 0;
+#X connect 18 0 3 0;
diff --git a/help/tab_fft-help.pd b/help/tab_fft-help.pd
new file mode 100644
index 0000000..754b416
--- /dev/null
+++ b/help/tab_fft-help.pd
@@ -0,0 +1,181 @@
+#N canvas 37 27 949 628 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0;
+#X coords 0 1 99 -1 300 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst_re 100 float 0;
+#X coords 0 1 99 -1 300 140 1;
+#X restore 534 155 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 62 583 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 35 387 list of 3 floats:;
+#X text 47 398 src-onset;
+#X text 443 484 1.arg: <symbol> source-name;
+#X text 90 29 <bang> copy from zero-onset to zero-onset;
+#X text 130 40 the minimum-size of arrays;
+#X msg 99 470 src src;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst_im 100 float 0;
+#X coords 0 1 99 -1 300 140 1;
+#X restore 534 299 graph;
+#X obj 397 142 tab_const src;
+#N canvas 98 77 887 548 fft~ 0;
+#N canvas 0 0 450 300 graph1 0;
+#X array src9 67 float 1;
+#A 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0;
+#X coords 0 1 66 -1 260 140 1;
+#X restore 480 -8 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst_re9 65 float 0;
+#X coords 0 1 64 -1 260 140 1;
+#X restore 480 166 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst_im9 65 float 0;
+#X coords 0 1 64 -1 260 140 1;
+#X restore 479 314 graph;
+#X obj 152 -8 tabreceive~ src9;
+#X obj 152 18 rfft~;
+#X obj 160 78 tabsend~ dst_re9;
+#X obj 183 52 tabsend~ dst_im9;
+#X msg 19 402 \; src9 sinesum 64 0 0 0 0 1 \; src9 cosinesum 64 0 0
+0 0 0 0 0 1;
+#X msg 11 327 \; src9 sinesum 64 0 1;
+#X msg 168 333 \; src9 cosinesum 64 0 0 1;
+#X obj 42 -7 for++ 0 63 1;
+#X obj 42 16 t f f;
+#X obj 42 51 / 32;
+#X obj 42 72 * 3.14159;
+#X obj 42 123 sin;
+#X obj 42 166 tabwrite src9;
+#X msg 29 194 \; src9 const 0;
+#X obj 42 -27 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 42 97 * 5;
+#X msg 31 239 \; src9 const 1;
+#X obj 339 7 for++ 0 63 1;
+#X obj 339 30 t f f;
+#X obj 339 65 / 32;
+#X obj 339 86 * 3.14159;
+#X obj 339 161 tabwrite src9;
+#X obj 339 -13 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 339 137 cos;
+#X obj 339 111 * 8.3;
+#X obj 42 145 / 32;
+#X msg 183 238 \$1 1 1;
+#X obj 183 215 t f b;
+#X obj 183 194 clip 0 31;
+#X floatatom 183 170 5 0 31 0 - - -;
+#X obj 208 274 tab_const src9;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 4 1 6 0;
+#X connect 10 0 11 0;
+#X connect 11 0 12 0;
+#X connect 11 1 15 1;
+#X connect 12 0 13 0;
+#X connect 13 0 18 0;
+#X connect 14 0 28 0;
+#X connect 17 0 10 0;
+#X connect 18 0 14 0;
+#X connect 20 0 21 0;
+#X connect 21 0 22 0;
+#X connect 21 1 24 1;
+#X connect 22 0 23 0;
+#X connect 23 0 27 0;
+#X connect 25 0 20 0;
+#X connect 26 0 24 0;
+#X connect 27 0 26 0;
+#X connect 28 0 15 0;
+#X connect 29 0 33 0;
+#X connect 30 0 29 0;
+#X connect 30 1 33 0;
+#X connect 31 0 30 0;
+#X connect 32 0 31 0;
+#X restore 293 433 pd fft~;
+#X obj 124 139 for++ 0 63 1;
+#X obj 124 162 t f f;
+#X obj 124 197 / 32;
+#X obj 124 218 * 3.14159;
+#X obj 124 269 sin;
+#X obj 124 119 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 124 243 * 5;
+#X msg 122 349 \; src const 0;
+#X obj 124 323 tabwrite src;
+#X msg 244 355 \; src const 1;
+#X obj 242 127 for++ 0 63 1;
+#X obj 242 150 t f f;
+#X obj 242 185 / 32;
+#X obj 242 206 * 3.14159;
+#X obj 242 107 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 242 257 cos;
+#X obj 242 305 tabwrite src;
+#X text 444 497 2.arg: <symbol> real_destination-name;
+#X text 445 511 3.arg: <symbol> imag_destination-name;
+#X text 446 524 4.arg: <float> fft-size;
+#X text 47 407 dst_re-onset;
+#X text 47 417 dst_im-onset;
+#X msg 111 494 dst_re dst_re;
+#X msg 152 517 dst_im dst_im;
+#X msg 242 527 fftsize 64;
+#X msg 372 106 \$1 1 1;
+#X obj 372 83 t f b;
+#X obj 372 62 clip 0 31;
+#X floatatom 372 38 5 0 31 0 - - -;
+#X obj 124 293 / 32;
+#X obj 242 231 * 8;
+#X obj 242 282 / 32;
+#X msg 362 281 \; src const \$1;
+#X obj 362 253 /;
+#X msg 362 221 1 32;
+#X msg 194 449 \; dst_re const 0 \; dst_im const 0;
+#X msg 63 445 20 30 30;
+#X obj 534 445 table dummy 100;
+#X obj 61 78 tab_fft src dummy dst_re dst_im 64;
+#X obj 62 560 tab_fft src dummy dst_re dst_im 64;
+#X connect 2 0 52 0;
+#X connect 10 0 53 0;
+#X connect 14 0 15 0;
+#X connect 15 0 16 0;
+#X connect 15 1 22 1;
+#X connect 16 0 17 0;
+#X connect 17 0 20 0;
+#X connect 18 0 43 0;
+#X connect 19 0 14 0;
+#X connect 20 0 18 0;
+#X connect 24 0 25 0;
+#X connect 25 0 26 0;
+#X connect 25 1 30 1;
+#X connect 26 0 27 0;
+#X connect 27 0 44 0;
+#X connect 28 0 24 0;
+#X connect 29 0 45 0;
+#X connect 36 0 53 0;
+#X connect 37 0 53 0;
+#X connect 38 0 53 0;
+#X connect 39 0 12 0;
+#X connect 40 0 39 0;
+#X connect 40 1 12 0;
+#X connect 41 0 40 0;
+#X connect 42 0 41 0;
+#X connect 43 0 22 0;
+#X connect 44 0 29 0;
+#X connect 45 0 30 0;
+#X connect 47 0 46 0;
+#X connect 48 0 47 0;
+#X connect 50 0 53 0;
+#X connect 52 0 3 0;
+#X connect 53 0 4 0;
diff --git a/help/tab_find_peaks-help.pd b/help/tab_find_peaks-help.pd
new file mode 100644
index 0000000..cf390d6
--- /dev/null
+++ b/help/tab_find_peaks-help.pd
@@ -0,0 +1,63 @@
+#N canvas 116 92 812 439 10;
+#X obj 60 52 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 31 195 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 176 168 1.arg: <symbol> source-name;
+#X floatatom 94 236 5 0 0 0 - - -;
+#X floatatom 143 237 5 0 0 0 - - -;
+#X text 163 60 to the end of array;
+#X text 89 50 <bang> calculate max. and max_index from zero-onset;
+#X msg 88 78 src src;
+#X msg 172 91 amp_sort;
+#X msg 178 114 freq_sort;
+#X obj 60 166 tab_find_peaks src;
+#X floatatom 198 235 5 0 0 0 - - -;
+#X obj 51 288 pack 0 0 0;
+#X obj 51 311 print;
+#X msg 253 90 abs_min_height_diff 10;
+#X text 69 249 sort_index;
+#X text 204 246 amp;
+#X text 147 251 index;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 9.99997 9.28569 9.28569 10.7143 7.14284 7.85712 8.5714 39 10 11
+38 8.5714 7.85712 8.5714 9.28569 8.5714 9.99997 39 40 41 38 12.8571
+12.8571 14.2857 12.8571 11.4285 12.1428 11.4285 9.99997 10.7143 11.4285
+9.99997 9.28569 9.28569 9.99997 10.7143 10.7143 45 9.99997 9.99997
+10.7143 11.4285 12.1428 10.7143 11.4285 12.1428 11.4285 46 11.4285
+11.4285 11.4285 12.1428 12.8571 11.4285 11.4285 12.1428 12.8571 12.1428
+12.1428 12.1428 12.1428 12.1428 11.4285 11.4285 11.4285 11.4285 10.7143
+48 49 43 11.4285 12.1428 13.5714 15 13.5714 13.5714 14.2857 14.2857
+15 15 14.2857 14.2857 14.2857 15 15 15.7142 15.7142 51 53 15 15 15
+15 15 14.2857 14.2857 15 15.7142 16.4285 16.4285;
+#X coords 0 100 99 0 200 140 1;
+#X restore 442 95 graph;
+#X msg 262 123 max_peaks 9;
+#X text 20 211 ready;
+#X msg 270 150 width_range 1 4;
+#N canvas 0 0 454 304 init 0;
+#X msg 233 52 \; src const 0;
+#X msg 234 94 \; src 37 45;
+#X msg 236 133 \; src 47 46;
+#X msg 187 177 \; src 67 48 49 43;
+#X msg 180 218 \; src 87 51 53;
+#X msg 44 223 \; src 7 39 10 11 38;
+#X msg 50 181 \; src 17 39 40 41 38;
+#X restore 450 267 pd init;
+#X text 21 6 tab_find_peaks;
+#X connect 0 0 10 0;
+#X connect 7 0 10 0;
+#X connect 8 0 10 0;
+#X connect 9 0 10 0;
+#X connect 10 0 1 0;
+#X connect 10 1 3 0;
+#X connect 10 1 12 0;
+#X connect 10 2 4 0;
+#X connect 10 2 12 1;
+#X connect 10 3 11 0;
+#X connect 10 3 12 2;
+#X connect 12 0 13 0;
+#X connect 14 0 10 0;
+#X connect 19 0 10 0;
+#X connect 21 0 10 0;
diff --git a/help/tab_ge-help.pd b/help/tab_ge-help.pd
new file mode 100644
index 0000000..ed5f5d8
--- /dev/null
+++ b/help/tab_ge-help.pd
@@ -0,0 +1,70 @@
+#N canvas 116 92 851 556 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src1 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 358 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 57 173 dst-onset;
+#X msg 286 234 dst dst;
+#N canvas 0 0 450 300 graph1 0;
+#X array src2 100 float 1;
+#A 0 0.557135 0.57142 0.557135 0.528564 0.499992 0.428564 0.357136
+0.299994 0.0999951 -0.0571467 -0.157146 -0.228574 -0.300002 -0.328573
+-0.357145 -0.385716 -0.400001 -0.400001 -0.385716 -0.385716 -0.37143
+-0.364287 -0.357145 -0.328573 -0.300002 -0.271431 -0.24286 -0.214288
+-0.14286 -0.085718 -0.0428611 -4.28595e-006 0.0428526 0.099995 0.171423
+0.21428 0.257137 0.328565 0.371422 0.428564 0.457135 0.485707 0.499992
+0.514278 0.499992 0.471421 0.44285 0.414279 0.357136 0.285708 0.171423
+0.0999952 0.0142815 -0.100003 -0.214288 -0.314288 -0.385716 -0.457144
+-0.471429 -0.514286 -0.500001 -0.47143 -0.442858 -0.414287 -0.37143
+-0.300002 -0.228574 -0.157146 -0.0714324 0.0571381 0.128566 0.199994
+0.271422 0.34285 0.414278 0.457135 0.485707 0.499992 0.528563 0.542849
+0.499992 0.457135 0.428564 0.371422 0.314279 0.242851 0.0857095 -0.0857178
+-0.271431 -0.400001 -0.514286 -0.542858 -0.557143 -0.585714 -0.585714
+-0.6 -0.6 -0.614286 -0.614286 -0.614286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 161 graph;
+#X msg 142 217 src1 src1;
+#X msg 218 223 src2 src2;
+#X msg 59 211 50 50 20 50;
+#X text 45 139 list of 4 floats:;
+#X text 57 153 src1-onset;
+#X text 56 163 src2-onset;
+#X text 212 333 3.arg: <symbol> destination-name;
+#X text 211 306 1.arg: <symbol> source1-name;
+#X text 211 319 2.arg: <symbol> source2-name;
+#X text 58 182 n samples to compare;
+#X text 97 26 <float> compare "greater equal" 2 src-arrays to dst-array
+with the minimum-size of arrays;
+#X obj 61 78 tab_ge src1 src2 dst;
+#X obj 59 271 tab_ge src1 src2 dst;
+#X connect 2 0 19 0;
+#X connect 6 0 20 0;
+#X connect 8 0 20 0;
+#X connect 9 0 20 0;
+#X connect 10 0 20 0;
+#X connect 19 0 3 0;
+#X connect 20 0 4 0;
diff --git a/help/tab_ge_scalar-help.pd b/help/tab_ge_scalar-help.pd
new file mode 100644
index 0000000..88c3d0e
--- /dev/null
+++ b/help/tab_ge_scalar-help.pd
@@ -0,0 +1,50 @@
+#N canvas 75 200 868 572 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 176 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 325 graph;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 45 185 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X msg 255 235 dst dst;
+#X text 33 161 list of 4 floats:;
+#X msg 159 229 src src;
+#X text 45 175 src-onset;
+#X text 211 319 2.arg: <symbol> destination-name;
+#X msg 47 36 0.3;
+#X msg 82 37 -0.3;
+#X msg 48 228 0 0 100 0.3;
+#X text 46 195 n samples to compare;
+#X text 164 29 <float> compare "greater equal" the src-array with this
+scalar to dst-array with the minimum-size of arrays;
+#X text 45 206 compare "greater equal"-scalar;
+#X obj 61 78 tab_ge_scalar src dst;
+#X obj 59 271 tab_ge_scalar src dst;
+#X connect 6 0 18 0;
+#X connect 8 0 18 0;
+#X connect 11 0 17 0;
+#X connect 12 0 17 0;
+#X connect 13 0 18 0;
+#X connect 17 0 2 0;
+#X connect 18 0 3 0;
diff --git a/help/tab_gt-help.pd b/help/tab_gt-help.pd
new file mode 100644
index 0000000..baae6df
--- /dev/null
+++ b/help/tab_gt-help.pd
@@ -0,0 +1,70 @@
+#N canvas 116 92 851 556 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src1 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 358 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 57 173 dst-onset;
+#X msg 286 234 dst dst;
+#N canvas 0 0 450 300 graph1 0;
+#X array src2 100 float 1;
+#A 0 0.557135 0.57142 0.557135 0.528564 0.499992 0.428564 0.357136
+0.299994 0.0999951 -0.0571467 -0.157146 -0.228574 -0.300002 -0.328573
+-0.357145 -0.385716 -0.400001 -0.400001 -0.385716 -0.385716 -0.37143
+-0.364287 -0.357145 -0.328573 -0.300002 -0.271431 -0.24286 -0.214288
+-0.14286 -0.085718 -0.0428611 -4.28595e-006 0.0428526 0.099995 0.171423
+0.21428 0.257137 0.328565 0.371422 0.428564 0.457135 0.485707 0.499992
+0.514278 0.499992 0.471421 0.44285 0.414279 0.357136 0.285708 0.171423
+0.0999952 0.0142815 -0.100003 -0.214288 -0.314288 -0.385716 -0.457144
+-0.471429 -0.514286 -0.500001 -0.47143 -0.442858 -0.414287 -0.37143
+-0.300002 -0.228574 -0.157146 -0.0714324 0.0571381 0.128566 0.199994
+0.271422 0.34285 0.414278 0.457135 0.485707 0.499992 0.528563 0.542849
+0.499992 0.457135 0.428564 0.371422 0.314279 0.242851 0.0857095 -0.0857178
+-0.271431 -0.400001 -0.514286 -0.542858 -0.557143 -0.585714 -0.585714
+-0.6 -0.6 -0.614286 -0.614286 -0.614286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 161 graph;
+#X msg 142 217 src1 src1;
+#X msg 218 223 src2 src2;
+#X msg 59 211 50 50 20 50;
+#X text 45 139 list of 4 floats:;
+#X text 57 153 src1-onset;
+#X text 56 163 src2-onset;
+#X text 212 333 3.arg: <symbol> destination-name;
+#X text 211 306 1.arg: <symbol> source1-name;
+#X text 211 319 2.arg: <symbol> source2-name;
+#X obj 61 78 tab_gt src1 src2 dst;
+#X obj 59 271 tab_gt src1 src2 dst;
+#X text 58 182 n samples to compare;
+#X text 97 26 <float> compare "greater than" 2 src-arrays to dst-array
+with the minimum-size of arrays;
+#X connect 2 0 17 0;
+#X connect 6 0 18 0;
+#X connect 8 0 18 0;
+#X connect 9 0 18 0;
+#X connect 10 0 18 0;
+#X connect 17 0 3 0;
+#X connect 18 0 4 0;
diff --git a/help/tab_gt_scalar-help.pd b/help/tab_gt_scalar-help.pd
new file mode 100644
index 0000000..f6c23ec
--- /dev/null
+++ b/help/tab_gt_scalar-help.pd
@@ -0,0 +1,50 @@
+#N canvas 75 200 864 568 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 176 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 325 graph;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 45 185 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X msg 255 235 dst dst;
+#X text 33 161 list of 4 floats:;
+#X msg 159 229 src src;
+#X text 45 175 src-onset;
+#X text 211 319 2.arg: <symbol> destination-name;
+#X obj 61 78 tab_gt_scalar src dst;
+#X obj 59 271 tab_gt_scalar src dst;
+#X msg 47 36 0.3;
+#X msg 82 37 -0.3;
+#X msg 48 228 0 0 100 0.3;
+#X text 164 29 <float> compare "greater than" the src-array with this
+scalar to dst-array with the minimum-size of arrays;
+#X text 45 206 compare "greater than"-scalar;
+#X text 46 195 n samples to compare;
+#X connect 6 0 12 0;
+#X connect 8 0 12 0;
+#X connect 11 0 2 0;
+#X connect 12 0 3 0;
+#X connect 13 0 11 0;
+#X connect 14 0 11 0;
+#X connect 15 0 12 0;
diff --git a/help/tab_ifft-help.pd b/help/tab_ifft-help.pd
new file mode 100644
index 0000000..0412a81
--- /dev/null
+++ b/help/tab_ifft-help.pd
@@ -0,0 +1,154 @@
+#N canvas 9 14 951 630 10;
+#N canvas 0 0 452 302 graph1 0;
+#X array spec_real 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 85 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array spec_imag 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 188 graph;
+#X obj 38 115 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 38 165 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 62 583 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 35 387 list of 3 floats:;
+#X text 47 398 src-onset;
+#X text 288 499 1.arg: <symbol> source-name;
+#X text 90 29 <bang> copy from zero-onset to zero-onset;
+#X text 130 40 the minimum-size of arrays;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 291 graph;
+#X obj 397 142 tab_const src;
+#X msg 122 349 \; src const 0;
+#X msg 244 355 \; src const 1;
+#X text 289 512 2.arg: <symbol> real_destination-name;
+#X text 290 526 3.arg: <symbol> imag_destination-name;
+#X text 291 541 4.arg: <float> fft-size;
+#X text 47 407 dst_re-onset;
+#X text 47 417 dst_im-onset;
+#X msg 189 527 fftsize 64;
+#X msg 372 106 \$1 1 1;
+#X obj 372 83 t f b;
+#X obj 372 62 clip 0 31;
+#X floatatom 372 38 5 0 31 0 - - -;
+#X msg 362 281 \; src const \$1;
+#X obj 362 253 /;
+#X msg 362 221 1 32;
+#X msg 63 445 20 30 30;
+#X msg 99 470 src_re src_re;
+#X msg 111 493 src_im src_im;
+#X msg 131 517 dst dst;
+#X msg 393 353 \; src_im const 0;
+#X msg 384 413 \; dst const 0;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 -18 graph;
+#X msg 169 162 \; spec_real const 0 \; spec_imag const 0 \; dst const
+0;
+#X obj 38 43 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 38 93 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 0 0 450 300 graph1 0;
+#X array mul 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 394 graph;
+#X obj 128 301 tab_const mul;
+#X msg 128 281 0 64 \$1;
+#X obj 128 260 /;
+#X msg 128 239 1 64;
+#X msg 53 305 0 0 0 64;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst2 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 497 graph;
+#X obj 53 326 tab_mul dst mul dst2;
+#N canvas 98 77 889 550 fft_ifft~ 0;
+#N canvas 0 0 450 300 graph1 0;
+#X array src9 100 float 1;
+#A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 505 -29 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array spec_real9 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 505 73 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array spec_imag9 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 505 176 graph;
+#X obj 56 35 tabreceive~ src9;
+#X obj 56 61 rfft~;
+#X msg 260 29 \$1 1 1;
+#X obj 260 6 t f b;
+#X obj 260 -15 clip 0 31;
+#X floatatom 260 -39 5 0 31 0 - - -;
+#X obj 285 65 tab_const src9;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst9 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 505 278 graph;
+#X obj 47 144 rifft~;
+#X obj 47 188 tabsend~ dst9;
+#X obj 64 121 tabsend~ spec_real9;
+#X obj 87 95 tabsend~ spec_imag9;
+#X obj 47 166 /~ 64;
+#X obj 25 -84 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 25 -59 dsp;
+#X floatatom 25 -18 5 0 0 0 - - -;
+#X floatatom 38 -36 5 0 0 0 - - -;
+#X connect 3 0 4 0;
+#X connect 4 0 11 0;
+#X connect 4 0 13 0;
+#X connect 4 1 11 1;
+#X connect 4 1 14 0;
+#X connect 5 0 9 0;
+#X connect 6 0 5 0;
+#X connect 6 1 9 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 0;
+#X connect 11 0 15 0;
+#X connect 15 0 12 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 0;
+#X connect 17 1 19 0;
+#X restore 293 433 pd fft_ifft~;
+#X obj 38 65 tab_fft src dummy1 spec_real spec_imag 64;
+#X obj 381 -5 table dummy1 100;
+#X obj 380 16 table dummy2 100;
+#X obj 38 137 tab_ifft spec_real spec_imag dst dummy2 64;
+#X obj 62 560 tab_fft src_re src_im dst dummy2 64;
+#X connect 2 0 49 0;
+#X connect 19 0 50 0;
+#X connect 20 0 11 0;
+#X connect 21 0 20 0;
+#X connect 21 1 11 0;
+#X connect 22 0 21 0;
+#X connect 23 0 22 0;
+#X connect 25 0 24 0;
+#X connect 26 0 25 0;
+#X connect 27 0 50 0;
+#X connect 28 0 50 0;
+#X connect 29 0 50 0;
+#X connect 30 0 50 0;
+#X connect 35 0 46 0;
+#X connect 39 0 38 0;
+#X connect 40 0 39 0;
+#X connect 41 0 40 0;
+#X connect 42 0 44 0;
+#X connect 46 0 36 0;
+#X connect 49 0 3 0;
+#X connect 50 0 4 0;
diff --git a/help/tab_le-help.pd b/help/tab_le-help.pd
new file mode 100644
index 0000000..4945cd6
--- /dev/null
+++ b/help/tab_le-help.pd
@@ -0,0 +1,70 @@
+#N canvas 116 92 851 556 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src1 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 358 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 57 173 dst-onset;
+#X msg 286 234 dst dst;
+#N canvas 0 0 450 300 graph1 0;
+#X array src2 100 float 1;
+#A 0 0.557135 0.57142 0.557135 0.528564 0.499992 0.428564 0.357136
+0.299994 0.0999951 -0.0571467 -0.157146 -0.228574 -0.300002 -0.328573
+-0.357145 -0.385716 -0.400001 -0.400001 -0.385716 -0.385716 -0.37143
+-0.364287 -0.357145 -0.328573 -0.300002 -0.271431 -0.24286 -0.214288
+-0.14286 -0.085718 -0.0428611 -4.28595e-006 0.0428526 0.099995 0.171423
+0.21428 0.257137 0.328565 0.371422 0.428564 0.457135 0.485707 0.499992
+0.514278 0.499992 0.471421 0.44285 0.414279 0.357136 0.285708 0.171423
+0.0999952 0.0142815 -0.100003 -0.214288 -0.314288 -0.385716 -0.457144
+-0.471429 -0.514286 -0.500001 -0.47143 -0.442858 -0.414287 -0.37143
+-0.300002 -0.228574 -0.157146 -0.0714324 0.0571381 0.128566 0.199994
+0.271422 0.34285 0.414278 0.457135 0.485707 0.499992 0.528563 0.542849
+0.499992 0.457135 0.428564 0.371422 0.314279 0.242851 0.0857095 -0.0857178
+-0.271431 -0.400001 -0.514286 -0.542858 -0.557143 -0.585714 -0.585714
+-0.6 -0.6 -0.614286 -0.614286 -0.614286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 161 graph;
+#X msg 142 217 src1 src1;
+#X msg 218 223 src2 src2;
+#X msg 59 211 50 50 20 50;
+#X text 45 139 list of 4 floats:;
+#X text 57 153 src1-onset;
+#X text 56 163 src2-onset;
+#X text 212 333 3.arg: <symbol> destination-name;
+#X text 211 306 1.arg: <symbol> source1-name;
+#X text 211 319 2.arg: <symbol> source2-name;
+#X text 58 182 n samples to compare;
+#X text 97 26 <float> compare "less equal" 2 src-arrays to dst-array
+with the minimum-size of arrays;
+#X obj 61 78 tab_le src1 src2 dst;
+#X obj 59 271 tab_le src1 src2 dst;
+#X connect 2 0 19 0;
+#X connect 6 0 20 0;
+#X connect 8 0 20 0;
+#X connect 9 0 20 0;
+#X connect 10 0 20 0;
+#X connect 19 0 3 0;
+#X connect 20 0 4 0;
diff --git a/help/tab_le_scalar-help.pd b/help/tab_le_scalar-help.pd
new file mode 100644
index 0000000..1b5a0a5
--- /dev/null
+++ b/help/tab_le_scalar-help.pd
@@ -0,0 +1,50 @@
+#N canvas 75 200 868 572 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 176 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 325 graph;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 45 185 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X msg 255 235 dst dst;
+#X text 33 161 list of 4 floats:;
+#X msg 159 229 src src;
+#X text 45 175 src-onset;
+#X text 211 319 2.arg: <symbol> destination-name;
+#X msg 47 36 0.3;
+#X msg 82 37 -0.3;
+#X msg 48 228 0 0 100 0.3;
+#X text 46 195 n samples to compare;
+#X obj 61 78 tab_le_scalar src dst;
+#X obj 59 271 tab_le_scalar src dst;
+#X text 45 206 compare "less equal"-scalar;
+#X text 164 29 <float> compare "less equal" the src-array with this
+scalar to dst-array with the minimum-size of arrays;
+#X connect 6 0 16 0;
+#X connect 8 0 16 0;
+#X connect 11 0 15 0;
+#X connect 12 0 15 0;
+#X connect 13 0 16 0;
+#X connect 15 0 2 0;
+#X connect 16 0 3 0;
diff --git a/help/tab_lt-help.pd b/help/tab_lt-help.pd
new file mode 100644
index 0000000..9b36f9c
--- /dev/null
+++ b/help/tab_lt-help.pd
@@ -0,0 +1,70 @@
+#N canvas 116 92 855 560 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src1 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 358 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 57 173 dst-onset;
+#X msg 286 234 dst dst;
+#N canvas 0 0 450 300 graph1 0;
+#X array src2 100 float 1;
+#A 0 0.557135 0.57142 0.557135 0.528564 0.499992 0.428564 0.357136
+0.299994 0.0999951 -0.0571467 -0.157146 -0.228574 -0.300002 -0.328573
+-0.357145 -0.385716 -0.400001 -0.400001 -0.385716 -0.385716 -0.37143
+-0.364287 -0.357145 -0.328573 -0.300002 -0.271431 -0.24286 -0.214288
+-0.14286 -0.085718 -0.0428611 -4.28595e-006 0.0428526 0.099995 0.171423
+0.21428 0.257137 0.328565 0.371422 0.428564 0.457135 0.485707 0.499992
+0.514278 0.499992 0.471421 0.44285 0.414279 0.357136 0.285708 0.171423
+0.0999952 0.0142815 -0.100003 -0.214288 -0.314288 -0.385716 -0.457144
+-0.471429 -0.514286 -0.500001 -0.47143 -0.442858 -0.414287 -0.37143
+-0.300002 -0.228574 -0.157146 -0.0714324 0.0571381 0.128566 0.199994
+0.271422 0.34285 0.414278 0.457135 0.485707 0.499992 0.528563 0.542849
+0.499992 0.457135 0.428564 0.371422 0.314279 0.242851 0.0857095 -0.0857178
+-0.271431 -0.400001 -0.514286 -0.542858 -0.557143 -0.585714 -0.585714
+-0.6 -0.6 -0.614286 -0.614286 -0.614286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 161 graph;
+#X msg 142 217 src1 src1;
+#X msg 218 223 src2 src2;
+#X msg 59 211 50 50 20 50;
+#X text 45 139 list of 4 floats:;
+#X text 57 153 src1-onset;
+#X text 56 163 src2-onset;
+#X text 212 333 3.arg: <symbol> destination-name;
+#X text 211 306 1.arg: <symbol> source1-name;
+#X text 211 319 2.arg: <symbol> source2-name;
+#X text 58 182 n samples to compare;
+#X obj 61 78 tab_lt src1 src2 dst;
+#X obj 59 271 tab_lt src1 src2 dst;
+#X text 97 26 <float> compare "less than" 2 src-arrays to dst-array
+with the minimum-size of arrays;
+#X connect 2 0 18 0;
+#X connect 6 0 19 0;
+#X connect 8 0 19 0;
+#X connect 9 0 19 0;
+#X connect 10 0 19 0;
+#X connect 18 0 3 0;
+#X connect 19 0 4 0;
diff --git a/help/tab_lt_scalar-help.pd b/help/tab_lt_scalar-help.pd
new file mode 100644
index 0000000..fccbf2b
--- /dev/null
+++ b/help/tab_lt_scalar-help.pd
@@ -0,0 +1,50 @@
+#N canvas 75 200 868 572 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 176 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 325 graph;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 45 185 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X msg 255 235 dst dst;
+#X text 33 161 list of 4 floats:;
+#X msg 159 229 src src;
+#X text 45 175 src-onset;
+#X text 211 319 2.arg: <symbol> destination-name;
+#X msg 47 36 0.3;
+#X msg 82 37 -0.3;
+#X msg 48 228 0 0 100 0.3;
+#X text 46 195 n samples to compare;
+#X obj 61 78 tab_lt_scalar src dst;
+#X obj 59 271 tab_lt_scalar src dst;
+#X text 45 206 compare "less than"-scalar;
+#X text 164 29 <float> compare "less than" the src-array with this
+scalar to dst-array with the minimum-size of arrays;
+#X connect 6 0 16 0;
+#X connect 8 0 16 0;
+#X connect 11 0 15 0;
+#X connect 12 0 15 0;
+#X connect 13 0 16 0;
+#X connect 15 0 2 0;
+#X connect 16 0 3 0;
diff --git a/help/tab_max_index-help.pd b/help/tab_max_index-help.pd
new file mode 100644
index 0000000..6a80e8a
--- /dev/null
+++ b/help/tab_max_index-help.pd
@@ -0,0 +1,52 @@
+#N canvas 116 92 780 407 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.185715 0.185715 0.200001 0.214286 0.214286 0.214286
+0.228572 0.228572 0.214286 0.200001 0.185715 0.171429 0.142857 0.1
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 294 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 56 165 src-onset;
+#X text 269 299 1.arg: <symbol> source-name;
+#X msg 137 212 src src;
+#X floatatom 109 103 5 0 0 0 - - -;
+#X floatatom 158 104 5 0 0 0 - - -;
+#X text 166 118 max;
+#X floatatom 116 292 5 0 0 0 - - -;
+#X floatatom 174 291 5 0 0 0 - - -;
+#X text 183 308 max;
+#X msg 59 211 35 50;
+#X text 164 39 to the end of array;
+#X text 44 154 list of 2 floats:;
+#X obj 61 78 tab_max_index src;
+#X text 97 117 max_index;
+#X text 104 307 max_index;
+#X text 90 29 <bang> calculate max. and max_index from zero-onset;
+#X text 58 175 n samples to calc. max. and max_index;
+#X obj 59 262 tab_max_index src;
+#X connect 1 0 16 0;
+#X connect 6 0 21 0;
+#X connect 13 0 21 0;
+#X connect 16 0 2 0;
+#X connect 16 1 7 0;
+#X connect 16 2 8 0;
+#X connect 21 0 3 0;
+#X connect 21 1 10 0;
+#X connect 21 2 11 0;
diff --git a/help/tab_min_index-help.pd b/help/tab_min_index-help.pd
new file mode 100644
index 0000000..9614499
--- /dev/null
+++ b/help/tab_min_index-help.pd
@@ -0,0 +1,52 @@
+#N canvas 116 92 782 409 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.185715 0.185715 0.200001 0.214286 0.214286 0.214286
+0.228572 0.228572 0.214286 0.200001 0.185715 0.171429 0.142857 0.1
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 294 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 56 165 src-onset;
+#X text 269 299 1.arg: <symbol> source-name;
+#X msg 137 212 src src;
+#X floatatom 109 103 5 0 0 0 - - -;
+#X floatatom 158 104 5 0 0 0 - - -;
+#X floatatom 116 292 5 0 0 0 - - -;
+#X floatatom 174 291 5 0 0 0 - - -;
+#X msg 59 211 35 50;
+#X text 164 39 to the end of array;
+#X text 44 154 list of 2 floats:;
+#X text 90 29 <bang> calculate min. and min_index from zero-onset;
+#X obj 61 78 tab_min_index src;
+#X obj 59 262 tab_min_index src;
+#X text 58 175 n samples to calc. min. and min_index;
+#X text 97 117 min_index;
+#X text 166 118 min;
+#X text 183 308 min;
+#X text 104 307 min_index;
+#X connect 1 0 15 0;
+#X connect 6 0 16 0;
+#X connect 11 0 16 0;
+#X connect 15 0 2 0;
+#X connect 15 1 7 0;
+#X connect 15 2 8 0;
+#X connect 16 0 3 0;
+#X connect 16 1 9 0;
+#X connect 16 2 10 0;
diff --git a/help/tab_min_max-help.pd b/help/tab_min_max-help.pd
new file mode 100644
index 0000000..e71fc15
--- /dev/null
+++ b/help/tab_min_max-help.pd
@@ -0,0 +1,52 @@
+#N canvas 116 92 778 405 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.185715 0.185715 0.200001 0.214286 0.214286 0.214286
+0.228572 0.228572 0.214286 0.200001 0.185715 0.171429 0.142857 0.1
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 294 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 56 165 src-onset;
+#X text 269 299 1.arg: <symbol> source-name;
+#X msg 183 222 src src;
+#X obj 61 78 tab_min_max src;
+#X floatatom 103 101 5 0 0 0 - - -;
+#X floatatom 146 100 5 0 0 0 - - -;
+#X text 110 115 min;
+#X text 155 117 max;
+#X floatatom 110 295 5 0 0 0 - - -;
+#X floatatom 162 294 5 0 0 0 - - -;
+#X text 117 309 min;
+#X text 171 311 max;
+#X msg 59 211 35 50;
+#X text 90 29 <bang> calculate min. and max. from zero-onset;
+#X text 164 39 to the end of array;
+#X text 44 154 list of 2 floats:;
+#X text 58 175 n samples to calc. min. and max.;
+#X obj 59 262 tab_min_max src;
+#X connect 1 0 7 0;
+#X connect 6 0 21 0;
+#X connect 7 0 2 0;
+#X connect 7 1 8 0;
+#X connect 7 2 9 0;
+#X connect 16 0 21 0;
+#X connect 21 0 3 0;
+#X connect 21 1 12 0;
+#X connect 21 2 13 0;
diff --git a/help/tab_mul-help.pd b/help/tab_mul-help.pd
new file mode 100644
index 0000000..e5a470f
--- /dev/null
+++ b/help/tab_mul-help.pd
@@ -0,0 +1,70 @@
+#N canvas 116 92 845 550 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src1 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 358 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 57 173 dst-onset;
+#X msg 286 234 dst dst;
+#N canvas 0 0 450 300 graph1 0;
+#X array src2 100 float 1;
+#A 0 0.557135 0.57142 0.557135 0.528564 0.499992 0.428564 0.357136
+0.299994 0.0999951 -0.0571467 -0.157146 -0.228574 -0.300002 -0.328573
+-0.357145 -0.385716 -0.400001 -0.400001 -0.385716 -0.385716 -0.37143
+-0.364287 -0.357145 -0.328573 -0.300002 -0.271431 -0.24286 -0.214288
+-0.14286 -0.085718 -0.0428611 -4.28595e-006 0.0428526 0.099995 0.171423
+0.21428 0.257137 0.328565 0.371422 0.428564 0.457135 0.485707 0.499992
+0.514278 0.499992 0.471421 0.44285 0.414279 0.357136 0.285708 0.171423
+0.0999952 0.0142815 -0.100003 -0.214288 -0.314288 -0.385716 -0.457144
+-0.471429 -0.514286 -0.500001 -0.47143 -0.442858 -0.414287 -0.37143
+-0.300002 -0.228574 -0.157146 -0.0714324 0.0571381 0.128566 0.199994
+0.271422 0.34285 0.414278 0.457135 0.485707 0.499992 0.528563 0.542849
+0.499992 0.457135 0.428564 0.371422 0.314279 0.242851 0.0857095 -0.0857178
+-0.271431 -0.400001 -0.514286 -0.542858 -0.557143 -0.585714 -0.585714
+-0.6 -0.6 -0.614286 -0.614286 -0.614286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 161 graph;
+#X obj 61 78 tab_mul src1 src2 dst;
+#X msg 142 217 src1 src1;
+#X msg 218 223 src2 src2;
+#X msg 59 211 50 50 20 50;
+#X text 45 139 list of 4 floats:;
+#X text 57 153 src1-onset;
+#X text 56 163 src2-onset;
+#X text 57 183 n samples to multiply;
+#X text 212 333 3.arg: <symbol> destination-name;
+#X text 90 29 <bang> multiply the 2 src-arrays to dst-array;
+#X text 126 42 with the minimum-size of arrays;
+#X obj 59 271 tab_mul src1 src2 dst;
+#X text 211 306 1.arg: <symbol> source1-name;
+#X text 211 319 2.arg: <symbol> source2-name;
+#X connect 2 0 8 0;
+#X connect 6 0 19 0;
+#X connect 8 0 3 0;
+#X connect 9 0 19 0;
+#X connect 10 0 19 0;
+#X connect 11 0 19 0;
+#X connect 19 0 4 0;
diff --git a/help/tab_mul_scalar-help.pd b/help/tab_mul_scalar-help.pd
new file mode 100644
index 0000000..0c2c158
--- /dev/null
+++ b/help/tab_mul_scalar-help.pd
@@ -0,0 +1,51 @@
+#N canvas 115 92 852 556 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 176 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 325 graph;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 43 184 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X msg 255 235 dst dst;
+#X text 31 160 list of 4 floats:;
+#X text 44 193 n samples to multiply;
+#X text 165 42 with the minimum-size of arrays;
+#X obj 61 78 tab_mul_scalar src dst;
+#X msg 47 36 0.5;
+#X msg 82 37 2;
+#X msg 48 227 50 20 50 0.5;
+#X msg 159 229 src src;
+#X obj 59 271 tab_mul_scalar src dst;
+#X text 43 174 src-onset;
+#X text 43 204 mul_scalar;
+#X text 122 28 <float> multiply the src-array with this scalar to dst-array
+;
+#X text 211 320 2.arg: <symbol> destination-name;
+#X connect 6 0 15 0;
+#X connect 10 0 2 0;
+#X connect 11 0 10 0;
+#X connect 12 0 10 0;
+#X connect 13 0 15 0;
+#X connect 14 0 15 0;
+#X connect 15 0 3 0;
diff --git a/help/tab_ne-help.pd b/help/tab_ne-help.pd
new file mode 100644
index 0000000..1aa2434
--- /dev/null
+++ b/help/tab_ne-help.pd
@@ -0,0 +1,70 @@
+#N canvas 116 92 855 560 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src1 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 358 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 57 173 dst-onset;
+#X msg 286 234 dst dst;
+#N canvas 0 0 450 300 graph1 0;
+#X array src2 100 float 1;
+#A 0 0.557135 0.57142 0.557135 0.528564 0.499992 0.428564 0.357136
+0.299994 0.0999951 -0.0571467 -0.157146 -0.228574 -0.300002 -0.328573
+-0.357145 -0.385716 -0.400001 -0.400001 -0.385716 -0.385716 -0.37143
+-0.364287 -0.357145 -0.328573 -0.300002 -0.271431 -0.24286 -0.214288
+-0.14286 -0.085718 -0.0428611 -4.28595e-006 0.0428526 0.099995 0.171423
+0.21428 0.257137 0.328565 0.371422 0.428564 0.457135 0.485707 0.499992
+0.514278 0.499992 0.471421 0.44285 0.414279 0.357136 0.285708 0.171423
+0.0999952 0.0142815 -0.100003 -0.214288 -0.314288 -0.385716 -0.457144
+-0.471429 -0.514286 -0.500001 -0.47143 -0.442858 -0.414287 -0.37143
+-0.300002 -0.228574 -0.157146 -0.0714324 0.0571381 0.128566 0.199994
+0.271422 0.34285 0.414278 0.457135 0.485707 0.499992 0.528563 0.542849
+0.499992 0.457135 0.428564 0.371422 0.314279 0.242851 0.0857095 -0.0857178
+-0.271431 -0.400001 -0.514286 -0.542858 -0.557143 -0.585714 -0.585714
+-0.6 -0.6 -0.614286 -0.614286 -0.614286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 161 graph;
+#X msg 142 217 src1 src1;
+#X msg 218 223 src2 src2;
+#X msg 59 211 50 50 20 50;
+#X text 45 139 list of 4 floats:;
+#X text 57 153 src1-onset;
+#X text 56 163 src2-onset;
+#X text 212 333 3.arg: <symbol> destination-name;
+#X text 211 306 1.arg: <symbol> source1-name;
+#X text 211 319 2.arg: <symbol> source2-name;
+#X text 58 182 n samples to compare;
+#X text 97 26 <float> compare "not equal" 2 src-arrays to dst-array
+with the minimum-size of arrays;
+#X obj 61 78 tab_ne src1 src2 dst;
+#X obj 59 271 tab_ne src1 src2 dst;
+#X connect 2 0 19 0;
+#X connect 6 0 20 0;
+#X connect 8 0 20 0;
+#X connect 9 0 20 0;
+#X connect 10 0 20 0;
+#X connect 19 0 3 0;
+#X connect 20 0 4 0;
diff --git a/help/tab_ne_scalar-help.pd b/help/tab_ne_scalar-help.pd
new file mode 100644
index 0000000..e7637bc
--- /dev/null
+++ b/help/tab_ne_scalar-help.pd
@@ -0,0 +1,50 @@
+#N canvas 75 200 868 572 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 176 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 527 325 graph;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 45 185 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X msg 255 235 dst dst;
+#X text 33 161 list of 4 floats:;
+#X msg 159 229 src src;
+#X text 45 175 src-onset;
+#X text 211 319 2.arg: <symbol> destination-name;
+#X msg 47 36 0.3;
+#X msg 82 37 -0.3;
+#X msg 48 228 0 0 100 0.3;
+#X text 46 195 n samples to compare;
+#X text 164 29 <float> compare "not equal" the src-array with this
+scalar to dst-array with the minimum-size of arrays;
+#X text 45 206 compare "not equal"-scalar;
+#X obj 59 271 tab_ne_scalar src dst;
+#X obj 61 78 tab_ne_scalar src dst;
+#X connect 6 0 17 0;
+#X connect 8 0 17 0;
+#X connect 11 0 18 0;
+#X connect 12 0 18 0;
+#X connect 13 0 17 0;
+#X connect 17 0 3 0;
+#X connect 18 0 2 0;
diff --git a/help/tab_reverse-help.pd b/help/tab_reverse-help.pd
new file mode 100644
index 0000000..5ef3985
--- /dev/null
+++ b/help/tab_reverse-help.pd
@@ -0,0 +1,50 @@
+#N canvas 116 92 778 405 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 156 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 130 40 the minimum-size of arrays;
+#X text 90 29 <bang> copy reversal from zero-onset to zero-onset;
+#X obj 61 78 tab_reverse src dst;
+#X obj 59 301 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 59 211 50 20 50;
+#X text 44 154 list of 3 floats:;
+#X text 56 165 src-onset;
+#X text 56 175 dst-onset;
+#X text 211 306 1.arg: <symbol> source-name;
+#X text 211 319 2.arg: <symbol> destination-name;
+#X msg 142 217 src src;
+#X msg 202 226 dst dst;
+#X msg 264 236 time 10;
+#X text 58 184 n samples to copy reversal;
+#X obj 59 262 tab_reverse src dst;
+#X connect 2 0 6 0;
+#X connect 6 0 3 0;
+#X connect 8 0 18 0;
+#X connect 14 0 18 0;
+#X connect 15 0 18 0;
+#X connect 16 0 18 0;
+#X connect 18 0 7 0;
diff --git a/help/tab_rfft-help.pd b/help/tab_rfft-help.pd
new file mode 100644
index 0000000..c7cf1d4
--- /dev/null
+++ b/help/tab_rfft-help.pd
@@ -0,0 +1,180 @@
+#N canvas 37 27 949 628 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0;
+#X coords 0 1 99 -1 300 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst_re 100 float 0;
+#X coords 0 1 99 -1 300 140 1;
+#X restore 534 155 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 62 583 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 35 387 list of 3 floats:;
+#X text 47 398 src-onset;
+#X text 391 515 1.arg: <symbol> source-name;
+#X text 90 29 <bang> copy from zero-onset to zero-onset;
+#X text 130 40 the minimum-size of arrays;
+#X msg 99 470 src src;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst_im 100 float 0;
+#X coords 0 1 99 -1 300 140 1;
+#X restore 534 299 graph;
+#X obj 397 142 tab_const src;
+#N canvas 98 77 891 552 fft~ 0;
+#N canvas 0 0 450 300 graph1 0;
+#X array src9 67 float 1;
+#A 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0;
+#X coords 0 1 66 -1 260 140 1;
+#X restore 480 -8 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst_re9 65 float 0;
+#X coords 0 1 64 -1 260 140 1;
+#X restore 480 166 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst_im9 65 float 0;
+#X coords 0 1 64 -1 260 140 1;
+#X restore 479 314 graph;
+#X obj 152 -8 tabreceive~ src9;
+#X obj 152 18 rfft~;
+#X obj 160 78 tabsend~ dst_re9;
+#X obj 183 52 tabsend~ dst_im9;
+#X msg 19 402 \; src9 sinesum 64 0 0 0 0 1 \; src9 cosinesum 64 0 0
+0 0 0 0 0 1;
+#X msg 11 327 \; src9 sinesum 64 0 1;
+#X msg 168 333 \; src9 cosinesum 64 0 0 1;
+#X obj 42 -7 for++ 0 63 1;
+#X obj 42 16 t f f;
+#X obj 42 51 / 32;
+#X obj 42 72 * 3.14159;
+#X obj 42 123 sin;
+#X obj 42 166 tabwrite src9;
+#X msg 29 194 \; src9 const 0;
+#X obj 42 -27 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 42 97 * 5;
+#X msg 31 239 \; src9 const 1;
+#X obj 339 7 for++ 0 63 1;
+#X obj 339 30 t f f;
+#X obj 339 65 / 32;
+#X obj 339 86 * 3.14159;
+#X obj 339 161 tabwrite src9;
+#X obj 339 -13 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 339 137 cos;
+#X obj 339 111 * 8.3;
+#X obj 42 145 / 32;
+#X msg 183 238 \$1 1 1;
+#X obj 183 215 t f b;
+#X obj 183 194 clip 0 31;
+#X floatatom 183 170 5 0 31 0 - - -;
+#X obj 208 274 tab_const src9;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 4 1 6 0;
+#X connect 10 0 11 0;
+#X connect 11 0 12 0;
+#X connect 11 1 15 1;
+#X connect 12 0 13 0;
+#X connect 13 0 18 0;
+#X connect 14 0 28 0;
+#X connect 17 0 10 0;
+#X connect 18 0 14 0;
+#X connect 20 0 21 0;
+#X connect 21 0 22 0;
+#X connect 21 1 24 1;
+#X connect 22 0 23 0;
+#X connect 23 0 27 0;
+#X connect 25 0 20 0;
+#X connect 26 0 24 0;
+#X connect 27 0 26 0;
+#X connect 28 0 15 0;
+#X connect 29 0 33 0;
+#X connect 30 0 29 0;
+#X connect 30 1 33 0;
+#X connect 31 0 30 0;
+#X connect 32 0 31 0;
+#X restore 293 433 pd fft~;
+#X obj 124 139 for++ 0 63 1;
+#X obj 124 162 t f f;
+#X obj 124 197 / 32;
+#X obj 124 218 * 3.14159;
+#X obj 124 269 sin;
+#X obj 124 119 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 124 243 * 5;
+#X msg 122 349 \; src const 0;
+#X obj 124 323 tabwrite src;
+#X msg 244 355 \; src const 1;
+#X obj 242 127 for++ 0 63 1;
+#X obj 242 150 t f f;
+#X obj 242 185 / 32;
+#X obj 242 206 * 3.14159;
+#X obj 242 107 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 242 257 cos;
+#X obj 242 305 tabwrite src;
+#X text 392 528 2.arg: <symbol> real_destination-name;
+#X text 393 542 3.arg: <symbol> imag_destination-name;
+#X text 394 557 4.arg: <float> fft-size;
+#X text 47 407 dst_re-onset;
+#X text 47 417 dst_im-onset;
+#X msg 111 494 dst_re dst_re;
+#X msg 152 517 dst_im dst_im;
+#X msg 242 527 fftsize 64;
+#X msg 372 106 \$1 1 1;
+#X obj 372 83 t f b;
+#X obj 372 62 clip 0 31;
+#X floatatom 372 38 5 0 31 0 - - -;
+#X obj 124 293 / 32;
+#X obj 242 231 * 8;
+#X obj 242 282 / 32;
+#X msg 362 281 \; src const \$1;
+#X obj 362 253 /;
+#X msg 362 221 1 32;
+#X msg 194 449 \; dst_re const 0 \; dst_im const 0;
+#X msg 63 445 20 30 30;
+#X obj 62 560 tab_rfft src dst_re dst_im 64;
+#X obj 61 78 tab_rfft src dst_re dst_im 64;
+#X connect 2 0 52 0;
+#X connect 10 0 51 0;
+#X connect 14 0 15 0;
+#X connect 15 0 16 0;
+#X connect 15 1 22 1;
+#X connect 16 0 17 0;
+#X connect 17 0 20 0;
+#X connect 18 0 43 0;
+#X connect 19 0 14 0;
+#X connect 20 0 18 0;
+#X connect 24 0 25 0;
+#X connect 25 0 26 0;
+#X connect 25 1 30 1;
+#X connect 26 0 27 0;
+#X connect 27 0 44 0;
+#X connect 28 0 24 0;
+#X connect 29 0 45 0;
+#X connect 36 0 51 0;
+#X connect 37 0 51 0;
+#X connect 38 0 51 0;
+#X connect 39 0 12 0;
+#X connect 40 0 39 0;
+#X connect 40 1 12 0;
+#X connect 41 0 40 0;
+#X connect 42 0 41 0;
+#X connect 43 0 22 0;
+#X connect 44 0 29 0;
+#X connect 45 0 30 0;
+#X connect 47 0 46 0;
+#X connect 48 0 47 0;
+#X connect 50 0 51 0;
+#X connect 51 0 4 0;
+#X connect 52 0 3 0;
diff --git a/help/tab_rifft-help.pd b/help/tab_rifft-help.pd
new file mode 100644
index 0000000..2068e9f
--- /dev/null
+++ b/help/tab_rifft-help.pd
@@ -0,0 +1,152 @@
+#N canvas 9 14 951 630 10;
+#N canvas 0 0 452 302 graph1 0;
+#X array spec_real 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 85 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array spec_imag 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 188 graph;
+#X obj 38 115 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 38 165 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 62 583 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 35 387 list of 3 floats:;
+#X text 47 398 src-onset;
+#X text 288 499 1.arg: <symbol> source-name;
+#X text 90 29 <bang> copy from zero-onset to zero-onset;
+#X text 130 40 the minimum-size of arrays;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 291 graph;
+#X obj 397 142 tab_const src;
+#X msg 122 349 \; src const 0;
+#X msg 244 355 \; src const 1;
+#X text 289 512 2.arg: <symbol> real_destination-name;
+#X text 290 526 3.arg: <symbol> imag_destination-name;
+#X text 291 541 4.arg: <float> fft-size;
+#X text 47 407 dst_re-onset;
+#X text 47 417 dst_im-onset;
+#X msg 189 527 fftsize 64;
+#X msg 372 106 \$1 1 1;
+#X obj 372 83 t f b;
+#X obj 372 62 clip 0 31;
+#X floatatom 372 38 5 0 31 0 - - -;
+#X msg 362 281 \; src const \$1;
+#X obj 362 253 /;
+#X msg 362 221 1 32;
+#X msg 63 445 20 30 30;
+#X msg 99 470 src_re src_re;
+#X msg 111 493 src_im src_im;
+#X msg 131 517 dst dst;
+#X msg 393 353 \; src_im const 0;
+#X msg 384 413 \; dst const 0;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 -18 graph;
+#X msg 169 162 \; spec_real const 0 \; spec_imag const 0 \; dst const
+0;
+#X obj 38 43 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 38 93 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 0 0 450 300 graph1 0;
+#X array mul 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 394 graph;
+#X obj 128 301 tab_const mul;
+#X msg 128 281 0 64 \$1;
+#X obj 128 260 /;
+#X msg 128 239 1 64;
+#X msg 53 305 0 0 0 64;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst2 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 591 497 graph;
+#X obj 53 326 tab_mul dst mul dst2;
+#N canvas 98 77 893 554 fft_ifft~ 0;
+#N canvas 0 0 450 300 graph1 0;
+#X array src9 100 float 1;
+#A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 505 -29 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array spec_real9 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 505 73 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array spec_imag9 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 505 176 graph;
+#X obj 56 35 tabreceive~ src9;
+#X obj 56 61 rfft~;
+#X msg 260 29 \$1 1 1;
+#X obj 260 6 t f b;
+#X obj 260 -15 clip 0 31;
+#X floatatom 260 -39 5 0 31 0 - - -;
+#X obj 285 65 tab_const src9;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst9 100 float 0;
+#X coords 0 1 99 -1 300 100 1;
+#X restore 505 278 graph;
+#X obj 47 144 rifft~;
+#X obj 47 188 tabsend~ dst9;
+#X obj 64 121 tabsend~ spec_real9;
+#X obj 87 95 tabsend~ spec_imag9;
+#X obj 47 166 /~ 64;
+#X obj 25 -84 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 25 -59 dsp;
+#X floatatom 25 -18 5 0 0 0 - - -;
+#X floatatom 38 -36 5 0 0 0 - - -;
+#X connect 3 0 4 0;
+#X connect 4 0 11 0;
+#X connect 4 0 13 0;
+#X connect 4 1 11 1;
+#X connect 4 1 14 0;
+#X connect 5 0 9 0;
+#X connect 6 0 5 0;
+#X connect 6 1 9 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 0;
+#X connect 11 0 15 0;
+#X connect 15 0 12 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 0;
+#X connect 17 1 19 0;
+#X restore 293 433 pd fft_ifft~;
+#X obj 38 137 tab_rifft spec_real spec_imag dst 64;
+#X obj 38 65 tab_rfft src spec_real spec_imag 64;
+#X obj 61 559 tab_rfft src_re src_im dst 64;
+#X connect 2 0 46 0;
+#X connect 19 0 48 0;
+#X connect 20 0 11 0;
+#X connect 21 0 20 0;
+#X connect 21 1 11 0;
+#X connect 22 0 21 0;
+#X connect 23 0 22 0;
+#X connect 25 0 24 0;
+#X connect 26 0 25 0;
+#X connect 27 0 48 0;
+#X connect 28 0 48 0;
+#X connect 29 0 48 0;
+#X connect 30 0 48 0;
+#X connect 35 0 47 0;
+#X connect 39 0 38 0;
+#X connect 40 0 39 0;
+#X connect 41 0 40 0;
+#X connect 42 0 44 0;
+#X connect 46 0 3 0;
+#X connect 47 0 36 0;
+#X connect 48 0 4 0;
diff --git a/help/tab_sqrt-help.pd b/help/tab_sqrt-help.pd
new file mode 100644
index 0000000..a51188e
--- /dev/null
+++ b/help/tab_sqrt-help.pd
@@ -0,0 +1,49 @@
+#N canvas 116 92 782 409 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 0.916135 0.888992 0.83593 0.810011 0.784501 0.759399 0.734704
+0.710418 0.663071 0.640009 0.595111 0.573274 0.551845 0.510212 0.490007
+0.450823 0.413271 0.395108 0.377353 0.326536 0.310413 0.279392 0.264494
+0.250004 0.222248 0.196126 0.171635 0.160003 0.148778 0.127553 0.0987772
+0.0900016 0.0736748 0.0661237 0.0522459 0.0459193 0.0344905 0.0246944
+0.0204086 0.0130616 0.0100003 0.00326543 0.00183682 0.000816378 5.03628e-013
+0.000204064 0.0018367 0.00510201 0.00510201 0.00999999 0.0165306 0.0204082
+0.0293879 0.0400002 0.0459187 0.05898 0.0661229 0.0816333 0.0816333
+0.0987763 0.10796 0.127552 0.13796 0.148777 0.160001 0.183675 0.196124
+0.208982 0.235921 0.250002 0.279391 0.294697 0.310411 0.343065 0.360004
+0.377351 0.395106 0.431841 0.470209 0.490005 0.510209 0.530822 0.551843
+0.573271 0.595108 0.617354 0.640007 0.663068 0.686538 0.710416 0.734702
+0.734702 0.759396 0.784498 0.810009 0.835928 0.862254 0.862254 0.88899
+0.916133;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 156 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 301 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 59 211 50 20 50;
+#X text 44 154 list of 3 floats:;
+#X text 56 165 src-onset;
+#X text 56 175 dst-onset;
+#X text 139 299 1.arg: <symbol> source-name;
+#X text 139 312 2.arg: <symbol> destination-name;
+#X text 130 40 the minimum-size of arrays;
+#X msg 142 217 src src;
+#X msg 202 226 dst dst;
+#X obj 61 78 tab_sqrt src dst;
+#X obj 59 264 tab_sqrt src dst;
+#X text 90 29 <bang> calc square root from zero-onset to zero-onset
+;
+#X text 58 184 n samples to copy square root;
+#X connect 2 0 14 0;
+#X connect 5 0 15 0;
+#X connect 12 0 15 0;
+#X connect 13 0 15 0;
+#X connect 14 0 3 0;
+#X connect 15 0 4 0;
diff --git a/help/tab_sub-help.pd b/help/tab_sub-help.pd
new file mode 100644
index 0000000..f847aeb
--- /dev/null
+++ b/help/tab_sub-help.pd
@@ -0,0 +1,70 @@
+#N canvas 116 92 847 552 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src1 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#N canvas 0 0 450 300 graph1 0;
+#X array dst 100 float 0;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 358 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 310 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 57 173 dst-onset;
+#X msg 286 234 dst dst;
+#N canvas 0 0 450 300 graph1 0;
+#X array src2 100 float 1;
+#A 0 0.557135 0.57142 0.557135 0.528564 0.499992 0.428564 0.357136
+0.299994 0.0999951 -0.0571467 -0.157146 -0.228574 -0.300002 -0.328573
+-0.357145 -0.385716 -0.400001 -0.400001 -0.385716 -0.385716 -0.37143
+-0.364287 -0.357145 -0.328573 -0.300002 -0.271431 -0.24286 -0.214288
+-0.14286 -0.085718 -0.0428611 -4.28595e-006 0.0428526 0.099995 0.171423
+0.21428 0.257137 0.328565 0.371422 0.428564 0.457135 0.485707 0.499992
+0.514278 0.499992 0.471421 0.44285 0.414279 0.357136 0.285708 0.171423
+0.0999952 0.0142815 -0.100003 -0.214288 -0.314288 -0.385716 -0.457144
+-0.471429 -0.514286 -0.500001 -0.47143 -0.442858 -0.414287 -0.37143
+-0.300002 -0.228574 -0.157146 -0.0714324 0.0571381 0.128566 0.199994
+0.271422 0.34285 0.414278 0.457135 0.485707 0.499992 0.528563 0.542849
+0.499992 0.457135 0.428564 0.371422 0.314279 0.242851 0.0857095 -0.0857178
+-0.271431 -0.400001 -0.514286 -0.542858 -0.557143 -0.585714 -0.585714
+-0.6 -0.6 -0.614286 -0.614286 -0.614286;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 535 161 graph;
+#X msg 142 217 src1 src1;
+#X msg 218 223 src2 src2;
+#X msg 59 211 50 50 20 50;
+#X text 45 139 list of 4 floats:;
+#X text 57 153 src1-onset;
+#X text 56 163 src2-onset;
+#X text 212 333 3.arg: <symbol> destination-name;
+#X text 126 42 with the minimum-size of arrays;
+#X text 90 29 <bang> subtract the 2 src-arrays to dst-array;
+#X obj 61 78 tab_sub src1 src2 dst;
+#X obj 59 271 tab_sub src1 src2 dst;
+#X text 57 183 n samples to subtract;
+#X text 211 306 1.arg: <symbol> source1-name;
+#X text 211 319 2.arg: <symbol> source2-name;
+#X connect 2 0 17 0;
+#X connect 6 0 18 0;
+#X connect 8 0 18 0;
+#X connect 9 0 18 0;
+#X connect 10 0 18 0;
+#X connect 17 0 3 0;
+#X connect 18 0 4 0;
diff --git a/help/tab_sum-help.pd b/help/tab_sum-help.pd
new file mode 100644
index 0000000..2d64162
--- /dev/null
+++ b/help/tab_sum-help.pd
@@ -0,0 +1,43 @@
+#N canvas 116 92 782 409 10;
+#N canvas 0 0 450 300 graph1 0;
+#X array src 100 float 1;
+#A 0 -0.442858 -0.414287 -0.385715 -0.342858 -0.314287 -0.257144 -0.128572
+-0.0428573 0.128572 0.228572 0.285715 0.328572 0.400001 0.414287 0.457144
+0.457144 0.442858 0.385715 0.314287 0.257144 0.214286 0.1 0.0428572
+-0.0142858 -0.0428573 -0.114286 -0.142858 -0.200001 -0.242858 -0.285715
+-0.328572 -0.342858 -0.37143 -0.385715 -0.414287 -0.414287 -0.414287
+-0.414287 -0.400001 -0.357144 -0.314287 -0.257144 -0.185715 -0.0714288
+0.0142857 0.0571429 0.171429 0.328572 0.400001 0.442858 0.47143 0.485715
+0.485715 0.485715 0.485715 0.485715 0.442858 0.357144 0.242858 0.185715
+0.114286 0.0714285 -0.071429 -0.242858 -0.300001 -0.328573 -0.357144
+-0.37143 -0.385715 -0.400001 -0.442858 -0.457144 -0.47143 -0.457144
+-0.428573 -0.400001 -0.378573 -0.328572 -0.271429 -0.242858 -0.200001
+-0.128572 -0.0428574 -0.0285717 0.0142858 0.114286 0.128572 0.185715
+0.214286 0.257144 0.285715 0.314287 0.342858 0.357144 0.357144 0.357144
+0.357144 0.357144 0.342858 0.328572;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 534 10 graph;
+#X obj 61 31 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 61 106 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 59 301 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 56 165 src-onset;
+#X text 143 263 1.arg: <symbol> source-name;
+#X msg 142 217 src src;
+#X obj 61 78 tab_sum src;
+#X floatatom 122 104 5 0 0 0 - - -;
+#X text 59 175 n samples to calc sum;
+#X text 44 154 list of 2 floats:;
+#X text 90 29 <bang> calc sum of array-elements;
+#X obj 59 264 tab_sum src;
+#X msg 59 211 50 20;
+#X floatatom 120 295 5 0 0 0 - - -;
+#X connect 1 0 7 0;
+#X connect 6 0 12 0;
+#X connect 7 0 2 0;
+#X connect 7 1 8 0;
+#X connect 12 0 3 0;
+#X connect 12 1 14 0;
+#X connect 13 0 12 0;
diff --git a/src/iem_tab.c b/src/iem_tab.c
new file mode 100644
index 0000000..37ece70
--- /dev/null
+++ b/src/iem_tab.c
@@ -0,0 +1,134 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+
+static t_class *iem_tab_class;
+
+int iem_tab_check_arrays(t_symbol *obj_name, t_symbol *array_name, t_float **beg_mem, int *array_size, int max_index)
+{
+ int ok=1;
+ t_garray *a;
+
+ if(!(a = (t_garray *)pd_findbyclass(array_name, garray_class)))
+ {
+ error("%s: no such array", array_name->s_name);
+ ok = 0;
+ }
+ else if(!garray_getfloatarray(a, array_size, beg_mem))
+ {
+ error("%s: bad template for %s", array_name->s_name, obj_name->s_name);
+ ok = 0;
+ }
+ else if(*array_size < max_index)
+ {
+ error("%s: bad array-size: %d", array_name->s_name, *array_size);
+ ok = 0;
+ }
+ return(ok);
+}
+
+static void *iem_tab_new(void)
+{
+ t_object *x = (t_object *)pd_new(iem_tab_class);
+
+ return (x);
+}
+
+void tab_copy_setup(void);
+void tab_reverse_setup(void);
+void tab_min_max_setup(void);
+void tab_min_index_setup(void);
+void tab_max_index_setup(void);
+void tab_find_peaks_setup(void);
+void tab_abs_setup(void);
+void tab_sqrt_setup(void);
+void tab_sum_setup(void);
+void tab_add_setup(void);
+void tab_sub_setup(void);
+void tab_mul_setup(void);
+void tab_div_setup(void);
+void tab_complex_mul_setup(void);
+void tab_complex_inv_setup(void);
+void tab_mul_scalar_setup(void);
+void tab_add_scalar_setup(void);
+void tab_const_setup(void);
+void tab_fft_setup(void);
+void tab_ifft_setup(void);
+void tab_rfft_setup(void);
+void tab_rifft_setup(void);
+void tab_cross_corr_setup(void);
+void tab_conv_setup(void);
+void tab_gt_scalar_setup(void);
+void tab_ge_scalar_setup(void);
+void tab_lt_scalar_setup(void);
+void tab_le_scalar_setup(void);
+void tab_ne_scalar_setup(void);
+void tab_eq_scalar_setup(void);
+void tab_gt_setup(void);
+void tab_ge_setup(void);
+void tab_lt_setup(void);
+void tab_le_setup(void);
+void tab_ne_setup(void);
+void tab_eq_setup(void);
+void tab_counter_setup(void);
+//void tab_mls_setup(void);
+
+/* ------------------------ setup routine ------------------------- */
+
+void iem_tab_setup(void)
+{
+ iem_tab_class = class_new(gensym("iem_tab"), iem_tab_new, 0,
+ sizeof(t_object), CLASS_NOINLET, 0);
+
+ tab_copy_setup();
+ tab_reverse_setup();
+ tab_min_max_setup();
+ tab_min_index_setup();
+ tab_max_index_setup();
+ tab_find_peaks_setup();
+ tab_abs_setup();
+ tab_sqrt_setup();
+ tab_sum_setup();
+ tab_add_setup();
+ tab_sub_setup();
+ tab_mul_setup();
+ tab_div_setup();
+ tab_complex_mul_setup();
+ tab_complex_inv_setup();
+ tab_mul_scalar_setup();
+ tab_add_scalar_setup();
+ tab_const_setup();
+ tab_fft_setup();
+ tab_ifft_setup();
+ tab_rfft_setup();
+ tab_rifft_setup();
+ tab_cross_corr_setup();
+ tab_conv_setup();
+ tab_gt_scalar_setup();
+ tab_ge_scalar_setup();
+ tab_lt_scalar_setup();
+ tab_le_scalar_setup();
+ tab_ne_scalar_setup();
+ tab_eq_scalar_setup();
+ tab_gt_setup();
+ tab_ge_setup();
+ tab_lt_setup();
+ tab_le_setup();
+ tab_ne_setup();
+ tab_eq_setup();
+ tab_counter_setup();
+// tab_mls_setup();
+
+ post("iem_tab (R-1.16) library loaded! (c) Thomas Musil 05.2005");
+ post(" musil%ciem.at iem KUG Graz Austria", '@');
+}
diff --git a/src/iem_tab.dsp b/src/iem_tab.dsp
new file mode 100644
index 0000000..a4eb853
--- /dev/null
+++ b/src/iem_tab.dsp
@@ -0,0 +1,85 @@
+# Microsoft Developer Studio Project File - Name="iem_tab" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) External Target" 0x0106
+
+CFG=iem_tab - Win32 Debug
+!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "iem_tab.mak".
+!MESSAGE
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "iem_tab.mak" CFG="iem_tab - Win32 Debug"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "iem_tab - Win32 Release" (basierend auf "Win32 (x86) External Target")
+!MESSAGE "iem_tab - Win32 Debug" (basierend auf "Win32 (x86) External Target")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "iem_tab - Win32 Release"
+
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Cmd_Line "NMAKE /f makefile_win"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "makefile_win.exe"
+# PROP BASE Bsc_Name "makefile_win.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Cmd_Line "NMAKE /f makefile_win"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "iem_tab.exe"
+# PROP Bsc_Name "iem_tab.bsc"
+# PROP Target_Dir ""
+
+!ELSEIF "$(CFG)" == "iem_tab - Win32 Debug"
+
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Cmd_Line "NMAKE /f makefile_win"
+# PROP BASE Rebuild_Opt "/a"
+# PROP BASE Target_File "makefile_win.exe"
+# PROP BASE Bsc_Name "makefile_win.bsc"
+# PROP BASE Target_Dir ""
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Cmd_Line "NMAKE /f makefile_win"
+# PROP Rebuild_Opt "/a"
+# PROP Target_File "iem_tab.exe"
+# PROP Bsc_Name "iem_tab.bsc"
+# PROP Target_Dir ""
+
+!ENDIF
+
+# Begin Target
+
+# Name "iem_tab - Win32 Release"
+# Name "iem_tab - Win32 Debug"
+
+!IF "$(CFG)" == "iem_tab - Win32 Release"
+
+!ELSEIF "$(CFG)" == "iem_tab - Win32 Debug"
+
+!ENDIF
+
+# Begin Source File
+
+SOURCE=.\makefile_win
+# End Source File
+# End Target
+# End Project
diff --git a/src/iem_tab.dsw b/src/iem_tab.dsw
new file mode 100644
index 0000000..2a182ba
--- /dev/null
+++ b/src/iem_tab.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
+
+###############################################################################
+
+Project: "iem_tab"=.\iem_tab.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/iem_tab.h b/src/iem_tab.h
new file mode 100644
index 0000000..cdd39eb
--- /dev/null
+++ b/src/iem_tab.h
@@ -0,0 +1,18 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifndef __IEMTAB_H__
+#define __IEMTAB_H__
+
+typedef struct
+{
+ float real;
+ float imag;
+}
+TAB_COMPLEX;
+
+int iem_tab_check_arrays(t_symbol *obj_name, t_symbol *array_name, t_float **beg_mem, int *array_size, int max_index);
+
+#endif
diff --git a/src/iemlib.h b/src/iemlib.h
new file mode 100644
index 0000000..c71b0ed
--- /dev/null
+++ b/src/iemlib.h
@@ -0,0 +1,102 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iemlib.h written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifndef __IEMLIB_H__
+#define __IEMLIB_H__
+
+
+#define IS_A_POINTER(atom,index) ((atom+index)->a_type == A_POINTER)
+#define IS_A_FLOAT(atom,index) ((atom+index)->a_type == A_FLOAT)
+#define IS_A_SYMBOL(atom,index) ((atom+index)->a_type == A_SYMBOL)
+#define IS_A_DOLLAR(atom,index) ((atom+index)->a_type == A_DOLLAR)
+#define IS_A_DOLLSYM(atom,index) ((atom+index)->a_type == A_DOLLSYM)
+#define IS_A_SEMI(atom,index) ((atom+index)->a_type == A_SEMI)
+#define IS_A_COMMA(atom,index) ((atom+index)->a_type == A_COMMA)
+
+
+#ifdef NT
+int sys_noloadbang;
+//t_symbol *iemgui_key_sym=0;
+#include <io.h>
+#else
+extern int sys_noloadbang;
+//extern t_symbol *iemgui_key_sym;
+#include <unistd.h>
+#endif
+
+#define DEFDELVS 64
+#define XTRASAMPS 4
+#define SAMPBLK 4
+
+
+#define UNITBIT32 1572864. /* 3*2^19; bit 32 has place value 1 */
+
+/* machine-dependent definitions. These ifdefs really
+should have been by CPU type and not by operating system! */
+#ifdef IRIX
+/* big-endian. Most significant byte is at low address in memory */
+#define HIOFFSET 0 /* word offset to find MSB */
+#define LOWOFFSET 1 /* word offset to find LSB */
+#define int32 long /* a data type that has 32 bits */
+#else
+#ifdef MSW
+/* little-endian; most significant byte is at highest address */
+#define HIOFFSET 1
+#define LOWOFFSET 0
+#define int32 long
+#else
+#ifdef __FreeBSD__
+#include <machine/endian.h>
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define HIOFFSET 1
+#define LOWOFFSET 0
+#else
+#define HIOFFSET 0 /* word offset to find MSB */
+#define LOWOFFSET 1 /* word offset to find LSB */
+#endif /* BYTE_ORDER */
+#include <sys/types.h>
+#define int32 int32_t
+#endif
+#ifdef __linux__
+
+#include <endian.h>
+
+#if !defined(__BYTE_ORDER) || !defined(__LITTLE_ENDIAN)
+#error No byte order defined
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define HIOFFSET 1
+#define LOWOFFSET 0
+#else
+#define HIOFFSET 0 /* word offset to find MSB */
+#define LOWOFFSET 1 /* word offset to find LSB */
+#endif /* __BYTE_ORDER */
+
+#include <sys/types.h>
+#define int32 int32_t
+
+#else
+#ifdef __APPLE__
+#define HIOFFSET 0 /* word offset to find MSB */
+#define LOWOFFSET 1 /* word offset to find LSB */
+#define int32 int /* a data type that has 32 bits */
+
+#endif /* __APPLE__ */
+#endif /* __linux__ */
+#endif /* MSW */
+#endif /* SGI */
+
+union tabfudge
+{
+ double tf_d;
+ int32 tf_i[2];
+};
+
+#define IEM_DENORMAL(f) ((((*(unsigned int*)&(f))&0x60000000)==0) || \
+(((*(unsigned int*)&(f))&0x60000000)==0x60000000))
+/* more stringent test: anything not between 1e-19 and 1e19 in absolute val */
+
+#endif
diff --git a/src/makefile b/src/makefile
new file mode 100644
index 0000000..2f297e4
--- /dev/null
+++ b/src/makefile
@@ -0,0 +1,83 @@
+current: all
+
+.SUFFIXES: .pd_linux
+
+INCLUDE = -I. -I/usr/local/src/pd/src
+
+LDFLAGS = -export-dynamic -shared
+LIB = -ldl -lm -lpthread
+
+#select either the DBG and OPT compiler flags below:
+
+CFLAGS = -DPD -DUNIX -W -Werror -Wno-unused \
+ -Wno-parentheses -Wno-switch -O6 -funroll-loops -fomit-frame-pointer \
+ -DDL_OPEN
+
+SYSTEM = $(shell uname -m)
+
+# the sources
+
+SRC = tab_copy.c \
+ tab_reverse.c \
+ tab_min_max.c \
+ tab_min_index.c \
+ tab_max_index.c \
+ tab_find_peaks.c \
+ tab_abs.c \
+ tab_sqrt.c \
+ tab_sum.c \
+ tab_add.c \
+ tab_sub.c \
+ tab_mul.c \
+ tab_div.c \
+ tab_complex_mul.c \
+ tab_complex_inv.c \
+ tab_add_scalar.c \
+ tab_mul_scalar.c \
+ tab_const.c \
+ tab_fft.c \
+ tab_ifft.c \
+ tab_rfft.c \
+ tab_rifft.c \
+ tab_cross_corr.c \
+ tab_conv.c \
+ tab_gt_scalar.c \
+ tab_ge_scalar.c \
+ tab_lt_scalar.c \
+ tab_le_scalar.c \
+ tab_ne_scalar.c \
+ tab_eq_scalar.c \
+ tab_gt.c \
+ tab_ge.c \
+ tab_lt.c \
+ tab_le.c \
+ tab_ne.c \
+ tab_eq.c \
+ tab_counter.c \
+ iem_tab.c
+
+TARGET = iem_tab.pd_linux
+
+
+OBJ = $(SRC:.c=.o)
+
+#
+# ------------------ targets ------------------------------------
+#
+
+clean:
+ rm $(TARGET)
+ rm *.o
+
+all: $(OBJ)
+ @echo :: $(OBJ)
+ ld $(LDFLAGS) -o $(TARGET) *.o $(LIB)
+ strip --strip-unneeded $(TARGET)
+
+$(OBJ) : %.o : %.c
+ touch $*.c
+ cc $(CFLAGS) $(INCLUDE) -c -o $*.o $*.c
+
+
+
+
diff --git a/src/makefile_win b/src/makefile_win
new file mode 100644
index 0000000..22a9fe1
--- /dev/null
+++ b/src/makefile_win
@@ -0,0 +1,73 @@
+
+all: iem_tab.dll
+
+VIS_CPP_PATH = "C:\Programme\Microsoft Visual Studio\Vc98"
+
+PD_INST_PATH = "C:\Programme\pd"
+
+PD_WIN_INCLUDE_PATH = /I. /I$(PD_INST_PATH)\src /I$(VIS_CPP_PATH)\include
+
+PD_WIN_C_FLAGS = /nologo /W3 /WX /DMSW /DNT /DPD /DWIN32 /DWINDOWS /Ox -DPA_LITTLE_ENDIAN
+
+PD_WIN_L_FLAGS = /nologo
+
+PD_WIN_LIB = /NODEFAULTLIB:libc /NODEFAULTLIB:oldnames /NODEFAULTLIB:kernel /NODEFAULTLIB:uuid \
+ $(VIS_CPP_PATH)\lib\libc.lib \
+ $(VIS_CPP_PATH)\lib\oldnames.lib \
+ $(VIS_CPP_PATH)\lib\kernel32.lib \
+ $(VIS_CPP_PATH)\lib\wsock32.lib \
+ $(VIS_CPP_PATH)\lib\winmm.lib \
+ $(PD_INST_PATH)\bin\pd.lib
+
+
+SRC = tab_copy.c \
+ tab_reverse.c \
+ tab_min_max.c \
+ tab_min_index.c \
+ tab_max_index.c \
+ tab_find_peaks.c \
+ tab_abs.c \
+ tab_sqrt.c \
+ tab_sum.c \
+ tab_add.c \
+ tab_sub.c \
+ tab_mul.c \
+ tab_div.c \
+ tab_complex_mul.c \
+ tab_complex_inv.c \
+ tab_add_scalar.c \
+ tab_mul_scalar.c \
+ tab_const.c \
+ tab_fft.c \
+ tab_ifft.c \
+ tab_rfft.c \
+ tab_rifft.c \
+ tab_cross_corr.c \
+ tab_conv.c \
+ tab_gt_scalar.c \
+ tab_ge_scalar.c \
+ tab_lt_scalar.c \
+ tab_le_scalar.c \
+ tab_ne_scalar.c \
+ tab_eq_scalar.c \
+ tab_gt.c \
+ tab_ge.c \
+ tab_lt.c \
+ tab_le.c \
+ tab_ne.c \
+ tab_eq.c \
+ tab_counter.c \
+ iem_tab.c
+
+
+OBJ = $(SRC:.c=.obj)
+
+.c.obj:
+ cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c
+
+iem_tab.dll: $(OBJ)
+ link $(PD_WIN_L_FLAGS) /dll /export:iem_tab_setup \
+ /out:iem_tab.dll $(OBJ) $(PD_WIN_LIB)
+
+clean:
+ del *.obj
diff --git a/src/tab_abs.c b/src/tab_abs.c
new file mode 100644
index 0000000..71042e6
--- /dev/null
+++ b/src/tab_abs.c
@@ -0,0 +1,170 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_abs ------------------------------ */
+
+typedef struct _tab_abs
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_abs;
+
+static t_class *tab_abs_class;
+
+static void tab_abs_src(t_tab_abs *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_abs_dst(t_tab_abs *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_abs_bang(t_tab_abs *x)
+{
+ int i, n;
+ int ok_src, ok_dst;
+ t_float *vec_src, *vec_dst;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_abs"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_abs"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ vec_src = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = fabs(vec_src[i]);
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_abs_list(t_tab_abs *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src, beg_dst;
+ int i, n;
+ int ok_src, ok_dst;
+ t_float *vec_src, *vec_dst;
+
+ if((argc >= 3) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_abs"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_abs"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src && ok_dst)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = fabs(vec_src[i]);
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_abs-ERROR: list need 3 float arguments:");
+ post(" source_offset + destination_offset + number_of_samples_to_abs");
+ }
+}
+
+static void tab_abs_free(t_tab_abs *x)
+{
+}
+
+static void *tab_abs_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_abs *x = (t_tab_abs *)pd_new(tab_abs_class);
+ t_symbol *src, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src;
+ }
+ else
+ {
+ post("tab_abs-ERROR: need 2 symbols arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_abs_setup(void)
+{
+ tab_abs_class = class_new(gensym("tab_abs"), (t_newmethod)tab_abs_new, (t_method)tab_abs_free,
+ sizeof(t_tab_abs), 0, A_GIMME, 0);
+ class_addbang(tab_abs_class, (t_method)tab_abs_bang);
+ class_addlist(tab_abs_class, (t_method)tab_abs_list);
+ class_addmethod(tab_abs_class, (t_method)tab_abs_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_abs_class, (t_method)tab_abs_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_abs_class, (t_method)tab_abs_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_abs_class, gensym("iemhelp2/tab_abs-help"));
+}
diff --git a/src/tab_add.c b/src/tab_add.c
new file mode 100644
index 0000000..48e469b
--- /dev/null
+++ b/src/tab_add.c
@@ -0,0 +1,196 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_add ------------------------------ */
+
+typedef struct _tab_add
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_add;
+
+static t_class *tab_add_class;
+
+static void tab_add_src1(t_tab_add *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_add_src2(t_tab_add *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_add_dst(t_tab_add *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_add_bang(t_tab_add *x)
+{
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_add"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_add"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_add"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ n = x->x_size_src2;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src1[i] + vec_src2[i];
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_add_list(t_tab_add *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n = (int)atom_getintarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_add"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_add"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_add"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src1[i] + vec_src2[i];
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_add-ERROR: list need 4 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_add");
+ }
+}
+
+static void tab_add_free(t_tab_add *x)
+{
+}
+
+static void *tab_add_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_add *x = (t_tab_add *)pd_new(tab_add_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_add-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_add_setup(void)
+{
+ tab_add_class = class_new(gensym("tab_add"), (t_newmethod)tab_add_new, (t_method)tab_add_free,
+ sizeof(t_tab_add), 0, A_GIMME, 0);
+ class_addbang(tab_add_class, (t_method)tab_add_bang);
+ class_addlist(tab_add_class, (t_method)tab_add_list);
+ class_addmethod(tab_add_class, (t_method)tab_add_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_add_class, (t_method)tab_add_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_add_class, (t_method)tab_add_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_add_class, gensym("iemhelp2/tab_add-help"));
+}
diff --git a/src/tab_add_scalar.c b/src/tab_add_scalar.c
new file mode 100644
index 0000000..a325117
--- /dev/null
+++ b/src/tab_add_scalar.c
@@ -0,0 +1,173 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_add_scalar ------------------------------ */
+
+typedef struct _tab_add_scalar
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_add_scalar;
+
+static t_class *tab_add_scalar_class;
+
+static void tab_add_scalar_src(t_tab_add_scalar *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_add_scalar_float(t_tab_add_scalar *x, t_floatarg add)
+{
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_add_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_add_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src1[i] + add;
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_add_scalar_dst(t_tab_add_scalar *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_add_scalar_list(t_tab_add_scalar *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_dst;
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst, add;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ add = (t_float)atom_getfloatarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_add_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_add_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src1[i] + add;
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_add_scalar-ERROR: list need 4 float arguments:");
+ post(" source1_offset + destination_offset + number_of_samples_to_add + add_scalar");
+ }
+}
+
+static void tab_add_scalar_free(t_tab_add_scalar *x)
+{
+}
+
+static void *tab_add_scalar_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_add_scalar *x = (t_tab_add_scalar *)pd_new(tab_add_scalar_class);
+ t_symbol *src1, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ }
+ else
+ {
+ post("tab_add_scalar-ERROR: need 2 symbol arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_add_scalar_setup(void)
+{
+ tab_add_scalar_class = class_new(gensym("tab_add_scalar"), (t_newmethod)tab_add_scalar_new, (t_method)tab_add_scalar_free,
+ sizeof(t_tab_add_scalar), 0, A_GIMME, 0);
+ class_addfloat(tab_add_scalar_class, (t_method)tab_add_scalar_float);
+ class_addlist(tab_add_scalar_class, (t_method)tab_add_scalar_list);
+ class_addmethod(tab_add_scalar_class, (t_method)tab_add_scalar_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_add_scalar_class, (t_method)tab_add_scalar_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_add_scalar_class, (t_method)tab_add_scalar_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_add_scalar_class, gensym("iemhelp2/tab_add_scalar-help"));
+}
diff --git a/src/tab_complex_inv.c b/src/tab_complex_inv.c
new file mode 100644
index 0000000..a0264b9
--- /dev/null
+++ b/src/tab_complex_inv.c
@@ -0,0 +1,246 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_complex_inv ------------------------------ */
+
+typedef struct _tab_complex_inv
+{
+ t_object x_obj;
+ int x_size_src1_re;
+ int x_size_dst_re;
+ int x_size_src1_im;
+ int x_size_dst_im;
+ int x_offset_src1_re;
+ int x_offset_dst_re;
+ int x_offset_src1_im;
+ int x_offset_dst_im;
+ float *x_beg_mem_src1_re;
+ float *x_beg_mem_dst_re;
+ float *x_beg_mem_src1_im;
+ float *x_beg_mem_dst_im;
+ t_symbol *x_sym_scr1_re;
+ t_symbol *x_sym_dst_re;
+ t_symbol *x_sym_scr1_im;
+ t_symbol *x_sym_dst_im;
+} t_tab_complex_inv;
+
+static t_class *tab_complex_inv_class;
+
+static void tab_complex_inv_src1_re(t_tab_complex_inv *x, t_symbol *s)
+{
+ x->x_sym_scr1_re = s;
+}
+
+static void tab_complex_inv_src1_im(t_tab_complex_inv *x, t_symbol *s)
+{
+ x->x_sym_scr1_im = s;
+}
+
+static void tab_complex_inv_dst_re(t_tab_complex_inv *x, t_symbol *s)
+{
+ x->x_sym_dst_re = s;
+}
+
+static void tab_complex_inv_dst_im(t_tab_complex_inv *x, t_symbol *s)
+{
+ x->x_sym_dst_im = s;
+}
+
+static void tab_complex_inv_bang(t_tab_complex_inv *x)
+{
+ int i, n;
+ int ok_src1_re, ok_dst_re;
+ int ok_src1_im, ok_dst_im;
+ t_float *vec_src1_re, *vec_dst_re;
+ t_float *vec_src1_im, *vec_dst_im;
+
+ ok_src1_re = iem_tab_check_arrays(gensym("tab_complex_inv"), x->x_sym_scr1_re, &x->x_beg_mem_src1_re, &x->x_size_src1_re, 0);
+ ok_dst_re = iem_tab_check_arrays(gensym("tab_complex_inv"), x->x_sym_dst_re, &x->x_beg_mem_dst_re, &x->x_size_dst_re, 0);
+ ok_src1_im = iem_tab_check_arrays(gensym("tab_complex_inv"), x->x_sym_scr1_im, &x->x_beg_mem_src1_im, &x->x_size_src1_im, 0);
+ ok_dst_im = iem_tab_check_arrays(gensym("tab_complex_inv"), x->x_sym_dst_im, &x->x_beg_mem_dst_im, &x->x_size_dst_im, 0);
+
+ if(ok_src1_re && ok_dst_re && ok_src1_im && ok_dst_im)
+ {
+ if(x->x_size_src1_re < x->x_size_dst_re)
+ n = x->x_size_src1_re;
+ else
+ n = x->x_size_dst_re;
+ if(x->x_size_src1_im < n)
+ n = x->x_size_src1_im;
+ if(x->x_size_dst_im < n)
+ n = x->x_size_dst_im;
+
+ vec_src1_re = x->x_beg_mem_src1_re;
+ vec_dst_re = x->x_beg_mem_dst_re;
+ vec_src1_im = x->x_beg_mem_src1_im;
+ vec_dst_im = x->x_beg_mem_dst_im;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ t_float re, im, abs;
+
+ re = vec_src1_re[i];
+ im = vec_src1_im[i];
+ abs = 1.0f / (re*re + im*im);
+ vec_dst_re[i] = re*abs;
+ vec_dst_im[i] = -im*abs;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_re, garray_class);
+ garray_redraw(a);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_im, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_complex_inv_list(t_tab_complex_inv *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i, n;
+ int beg_src1_re, beg_dst_re;
+ int beg_src1_im, beg_dst_im;
+ int ok_src1_re, ok_dst_re;
+ int ok_src1_im, ok_dst_im;
+ t_float *vec_src1_re, *vec_dst_re;
+ t_float *vec_src1_im, *vec_dst_im;
+
+ if((argc >= 5) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3) &&
+ IS_A_FLOAT(argv,4))
+ {
+ beg_src1_re = (int)atom_getintarg(0, argc, argv);
+ beg_src1_im = (int)atom_getintarg(1, argc, argv);
+ beg_dst_re = (int)atom_getintarg(2, argc, argv);
+ beg_dst_im = (int)atom_getintarg(3, argc, argv);
+ n = (int)atom_getintarg(4, argc, argv);
+ if(beg_src1_re < 0)
+ beg_src1_re = 0;
+ if(beg_dst_re < 0)
+ beg_dst_re = 0;
+ if(beg_src1_im < 0)
+ beg_src1_im = 0;
+ if(beg_dst_im < 0)
+ beg_dst_im = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1_re = iem_tab_check_arrays(gensym("tab_complex_inv"), x->x_sym_scr1_re, &x->x_beg_mem_src1_re, &x->x_size_src1_re, beg_src1_re+n);
+ ok_dst_re = iem_tab_check_arrays(gensym("tab_complex_inv"), x->x_sym_dst_re, &x->x_beg_mem_dst_re, &x->x_size_dst_re, beg_dst_re+n);
+ ok_src1_im = iem_tab_check_arrays(gensym("tab_complex_inv"), x->x_sym_scr1_im, &x->x_beg_mem_src1_im, &x->x_size_src1_im, beg_src1_im+n);
+ ok_dst_im = iem_tab_check_arrays(gensym("tab_complex_inv"), x->x_sym_dst_im, &x->x_beg_mem_dst_im, &x->x_size_dst_im, beg_dst_im+n);
+
+ if(ok_src1_re && ok_dst_re && ok_src1_im && ok_dst_im)
+ {
+ vec_src1_re = x->x_beg_mem_src1_re + beg_src1_re;
+ vec_dst_re = x->x_beg_mem_dst_re + beg_dst_re;
+ vec_src1_im = x->x_beg_mem_src1_im + beg_src1_im;
+ vec_dst_im = x->x_beg_mem_dst_im + beg_dst_im;
+
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ t_float re, im, abs;
+
+ re = vec_src1_re[i];
+ im = vec_src1_im[i];
+ abs = 1.0f / (re*re + im*im);
+ vec_dst_re[i] = re*abs;
+ vec_dst_im[i] = -im*abs;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_re, garray_class);
+ garray_redraw(a);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_im, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_complex_inv-ERROR: list need 5 float arguments:");
+ post(" source1_real_offset + source1_imag_offset + destination_real_offset + destination_imag_offset + number_of_samples_to_complex_mul");
+ }
+}
+
+static void tab_complex_inv_free(t_tab_complex_inv *x)
+{
+}
+
+static void *tab_complex_inv_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_complex_inv *x = (t_tab_complex_inv *)pd_new(tab_complex_inv_class);
+ t_symbol *src1_re, *src2_re, *dst_re, *src1_im, *src2_im, *dst_im;
+ t_float time;
+
+ if((argc >= 4) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2) &&
+ IS_A_SYMBOL(argv,3))
+ {
+ src1_re = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src1_im = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst_re = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ dst_im = (t_symbol *)atom_getsymbolarg(3, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1_re = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src1_im = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst_re = src1_re;
+ dst_im = src1_im;
+ }
+ else
+ {
+ post("tab_complex_inv-ERROR: need 4 symbols arguments:");
+ post(" source1_real_array_name + source1_imag_array_name + destination_real_array_name + destination_imag_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1_re = src1_re;
+ x->x_sym_scr1_im = src1_im;
+ x->x_sym_dst_re = dst_re;
+ x->x_sym_dst_im = dst_im;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_complex_inv_setup(void)
+{
+ tab_complex_inv_class = class_new(gensym("tab_complex_inv"), (t_newmethod)tab_complex_inv_new, (t_method)tab_complex_inv_free,
+ sizeof(t_tab_complex_inv), 0, A_GIMME, 0);
+ class_addbang(tab_complex_inv_class, (t_method)tab_complex_inv_bang);
+ class_addlist(tab_complex_inv_class, (t_method)tab_complex_inv_list);
+ class_addmethod(tab_complex_inv_class, (t_method)tab_complex_inv_src1_re, gensym("src1_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_complex_inv_class, (t_method)tab_complex_inv_dst_re, gensym("dst_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_complex_inv_class, (t_method)tab_complex_inv_src1_im, gensym("src1_im"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_complex_inv_class, (t_method)tab_complex_inv_dst_im, gensym("dst_im"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_complex_inv_class, gensym("iemhelp2/tab_complex_inv-help"));
+}
diff --git a/src/tab_complex_mul.c b/src/tab_complex_mul.c
new file mode 100644
index 0000000..95a9080
--- /dev/null
+++ b/src/tab_complex_mul.c
@@ -0,0 +1,298 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_complex_mul ------------------------------ */
+
+typedef struct _tab_complex_mul
+{
+ t_object x_obj;
+ int x_size_src1_re;
+ int x_size_src2_re;
+ int x_size_dst_re;
+ int x_size_src1_im;
+ int x_size_src2_im;
+ int x_size_dst_im;
+ int x_offset_src1_re;
+ int x_offset_src2_re;
+ int x_offset_dst_re;
+ int x_offset_src1_im;
+ int x_offset_src2_im;
+ int x_offset_dst_im;
+ float *x_beg_mem_src1_re;
+ float *x_beg_mem_src2_re;
+ float *x_beg_mem_dst_re;
+ float *x_beg_mem_src1_im;
+ float *x_beg_mem_src2_im;
+ float *x_beg_mem_dst_im;
+ t_symbol *x_sym_scr1_re;
+ t_symbol *x_sym_scr2_re;
+ t_symbol *x_sym_dst_re;
+ t_symbol *x_sym_scr1_im;
+ t_symbol *x_sym_scr2_im;
+ t_symbol *x_sym_dst_im;
+} t_tab_complex_mul;
+
+static t_class *tab_complex_mul_class;
+
+static void tab_complex_mul_src1_re(t_tab_complex_mul *x, t_symbol *s)
+{
+ x->x_sym_scr1_re = s;
+}
+
+static void tab_complex_mul_src1_im(t_tab_complex_mul *x, t_symbol *s)
+{
+ x->x_sym_scr1_im = s;
+}
+
+static void tab_complex_mul_src2_re(t_tab_complex_mul *x, t_symbol *s)
+{
+ x->x_sym_scr2_re = s;
+}
+
+static void tab_complex_mul_src2_im(t_tab_complex_mul *x, t_symbol *s)
+{
+ x->x_sym_scr2_im = s;
+}
+
+static void tab_complex_mul_dst_re(t_tab_complex_mul *x, t_symbol *s)
+{
+ x->x_sym_dst_re = s;
+}
+
+static void tab_complex_mul_dst_im(t_tab_complex_mul *x, t_symbol *s)
+{
+ x->x_sym_dst_im = s;
+}
+
+static void tab_complex_mul_bang(t_tab_complex_mul *x)
+{
+ int i, n;
+ int ok_src1_re, ok_src2_re, ok_dst_re;
+ int ok_src1_im, ok_src2_im, ok_dst_im;
+ t_float *vec_src1_re, *vec_src2_re, *vec_dst_re;
+ t_float *vec_src1_im, *vec_src2_im, *vec_dst_im;
+
+ ok_src1_re = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_scr1_re, &x->x_beg_mem_src1_re, &x->x_size_src1_re, 0);
+ ok_src2_re = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_scr2_re, &x->x_beg_mem_src2_re, &x->x_size_src2_re, 0);
+ ok_dst_re = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_dst_re, &x->x_beg_mem_dst_re, &x->x_size_dst_re, 0);
+ ok_src1_im = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_scr1_im, &x->x_beg_mem_src1_im, &x->x_size_src1_im, 0);
+ ok_src2_im = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_scr2_im, &x->x_beg_mem_src2_im, &x->x_size_src2_im, 0);
+ ok_dst_im = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_dst_im, &x->x_beg_mem_dst_im, &x->x_size_dst_im, 0);
+
+ if(ok_src1_re && ok_src2_re && ok_dst_re && ok_src1_im && ok_src2_im && ok_dst_im)
+ {
+ if(x->x_size_src1_re < x->x_size_dst_re)
+ n = x->x_size_src1_re;
+ else
+ n = x->x_size_dst_re;
+ if(x->x_size_src2_re < n)
+ n = x->x_size_src2_re;
+ if(x->x_size_src1_im < n)
+ n = x->x_size_src1_im;
+ if(x->x_size_src2_im < n)
+ n = x->x_size_src2_im;
+ if(x->x_size_dst_im < n)
+ n = x->x_size_dst_im;
+
+ vec_src1_re = x->x_beg_mem_src1_re;
+ vec_src2_re = x->x_beg_mem_src2_re;
+ vec_dst_re = x->x_beg_mem_dst_re;
+ vec_src1_im = x->x_beg_mem_src1_im;
+ vec_src2_im = x->x_beg_mem_src2_im;
+ vec_dst_im = x->x_beg_mem_dst_im;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ t_float re1, re2, im1, im2;
+
+ re1 = vec_src1_re[i];
+ re2 = vec_src2_re[i];
+ im1 = vec_src1_im[i];
+ im2 = vec_src2_im[i];
+ vec_dst_re[i] = re1*re2 - im1*im2;
+ vec_dst_im[i] = re1*im2 + im1*re2;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_re, garray_class);
+ garray_redraw(a);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_im, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_complex_mul_list(t_tab_complex_mul *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int i, n;
+ int beg_src1_re, beg_src2_re, beg_dst_re;
+ int beg_src1_im, beg_src2_im, beg_dst_im;
+ int ok_src1_re, ok_src2_re, ok_dst_re;
+ int ok_src1_im, ok_src2_im, ok_dst_im;
+ t_float *vec_src1_re, *vec_src2_re, *vec_dst_re;
+ t_float *vec_src1_im, *vec_src2_im, *vec_dst_im;
+
+ if((argc >= 7) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3) &&
+ IS_A_FLOAT(argv,4) &&
+ IS_A_FLOAT(argv,5) &&
+ IS_A_FLOAT(argv,6))
+ {
+ beg_src1_re = (int)atom_getintarg(0, argc, argv);
+ beg_src1_im = (int)atom_getintarg(1, argc, argv);
+ beg_src2_re = (int)atom_getintarg(2, argc, argv);
+ beg_src2_im = (int)atom_getintarg(3, argc, argv);
+ beg_dst_re = (int)atom_getintarg(4, argc, argv);
+ beg_dst_im = (int)atom_getintarg(5, argc, argv);
+ n = (int)atom_getintarg(6, argc, argv);
+ if(beg_src1_re < 0)
+ beg_src1_re = 0;
+ if(beg_src2_re < 0)
+ beg_src2_re = 0;
+ if(beg_dst_re < 0)
+ beg_dst_re = 0;
+ if(beg_src1_im < 0)
+ beg_src1_im = 0;
+ if(beg_src2_im < 0)
+ beg_src2_im = 0;
+ if(beg_dst_im < 0)
+ beg_dst_im = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1_re = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_scr1_re, &x->x_beg_mem_src1_re, &x->x_size_src1_re, beg_src1_re+n);
+ ok_src2_re = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_scr2_re, &x->x_beg_mem_src2_re, &x->x_size_src2_re, beg_src2_re+n);
+ ok_dst_re = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_dst_re, &x->x_beg_mem_dst_re, &x->x_size_dst_re, beg_dst_re+n);
+ ok_src1_im = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_scr1_im, &x->x_beg_mem_src1_im, &x->x_size_src1_im, beg_src1_im+n);
+ ok_src2_im = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_scr2_im, &x->x_beg_mem_src2_im, &x->x_size_src2_im, beg_src2_im+n);
+ ok_dst_im = iem_tab_check_arrays(gensym("tab_complex_mul"), x->x_sym_dst_im, &x->x_beg_mem_dst_im, &x->x_size_dst_im, beg_dst_im+n);
+
+ if(ok_src1_re && ok_src2_re && ok_dst_re && ok_src1_im && ok_src2_im && ok_dst_im)
+ {
+ vec_src1_re = x->x_beg_mem_src1_re + beg_src1_re;
+ vec_src2_re = x->x_beg_mem_src2_re + beg_src2_re;
+ vec_dst_re = x->x_beg_mem_dst_re + beg_dst_re;
+ vec_src1_im = x->x_beg_mem_src1_im + beg_src1_im;
+ vec_src2_im = x->x_beg_mem_src2_im + beg_src2_im;
+ vec_dst_im = x->x_beg_mem_dst_im + beg_dst_im;
+
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ t_float re1, re2, im1, im2;
+
+ re1 = vec_src1_re[i];
+ re2 = vec_src2_re[i];
+ im1 = vec_src1_im[i];
+ im2 = vec_src2_im[i];
+ vec_dst_re[i] = re1*re2 - im1*im2;
+ vec_dst_im[i] = re1*im2 + im1*re2;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_re, garray_class);
+ garray_redraw(a);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_im, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_complex_mul-ERROR: list need 7 float arguments:");
+ post(" source1_real_offset + source1_imag_offset + source2_real_offset + source2_imag_offset + destination_real_offset + destination_imag_offset + number_of_samples_to_complex_mul");
+ }
+}
+
+static void tab_complex_mul_free(t_tab_complex_mul *x)
+{
+}
+
+static void *tab_complex_mul_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_complex_mul *x = (t_tab_complex_mul *)pd_new(tab_complex_mul_class);
+ t_symbol *src1_re, *src2_re, *dst_re, *src1_im, *src2_im, *dst_im;
+ t_float time;
+
+ if((argc >= 6) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2) &&
+ IS_A_SYMBOL(argv,3) &&
+ IS_A_SYMBOL(argv,4) &&
+ IS_A_SYMBOL(argv,5))
+ {
+ src1_re = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src1_im = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ src2_re = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ src2_im = (t_symbol *)atom_getsymbolarg(3, argc, argv);
+ dst_re = (t_symbol *)atom_getsymbolarg(4, argc, argv);
+ dst_im = (t_symbol *)atom_getsymbolarg(5, argc, argv);
+ }
+ else if((argc >= 4) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2) &&
+ IS_A_SYMBOL(argv,4))
+ {
+ src1_re = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src1_im = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ src2_re = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ src2_im = (t_symbol *)atom_getsymbolarg(3, argc, argv);
+ dst_re = src1_re;
+ dst_im = src1_im;
+ }
+ else
+ {
+ post("tab_complex_mul-ERROR: need 6 symbols arguments:");
+ post(" source1_real_array_name + source1_imag_array_name + source2_real_array_name + source2_imag_array_name + destination_real_array_name + destination_imag_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1_re = src1_re;
+ x->x_sym_scr1_im = src1_im;
+ x->x_sym_scr2_re = src2_re;
+ x->x_sym_scr2_im = src2_im;
+ x->x_sym_dst_re = dst_re;
+ x->x_sym_dst_im = dst_im;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_complex_mul_setup(void)
+{
+ tab_complex_mul_class = class_new(gensym("tab_complex_mul"), (t_newmethod)tab_complex_mul_new, (t_method)tab_complex_mul_free,
+ sizeof(t_tab_complex_mul), 0, A_GIMME, 0);
+ class_addbang(tab_complex_mul_class, (t_method)tab_complex_mul_bang);
+ class_addlist(tab_complex_mul_class, (t_method)tab_complex_mul_list);
+ class_addmethod(tab_complex_mul_class, (t_method)tab_complex_mul_src1_re, gensym("src1_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_complex_mul_class, (t_method)tab_complex_mul_src2_re, gensym("src2_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_complex_mul_class, (t_method)tab_complex_mul_dst_re, gensym("dst_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_complex_mul_class, (t_method)tab_complex_mul_src1_im, gensym("src1_im"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_complex_mul_class, (t_method)tab_complex_mul_src2_im, gensym("src2_im"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_complex_mul_class, (t_method)tab_complex_mul_dst_im, gensym("dst_im"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_complex_mul_class, gensym("iemhelp2/tab_complex_mul-help"));
+}
diff --git a/src/tab_const.c b/src/tab_const.c
new file mode 100644
index 0000000..9199829
--- /dev/null
+++ b/src/tab_const.c
@@ -0,0 +1,169 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_const ------------------------------ */
+
+typedef struct _tab_const
+{
+ t_object x_obj;
+ int x_size_dst;
+ int x_offset_dst;
+ t_float x_const;
+ t_float *x_beg_mem_dst;
+ t_symbol *x_sym_dst;
+} t_tab_const;
+
+static t_class *tab_const_class;
+
+static void tab_const_dst(t_tab_const *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_const_bang(t_tab_const *x)
+{
+ int i, n;
+ int ok_dst;
+ t_float *vec_dst;
+
+ ok_dst = iem_tab_check_arrays(gensym("tab_const"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_dst)
+ {
+ n = x->x_size_dst;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = 0.0f;
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_const_float(t_tab_const *x, t_floatarg c)
+{
+ int i, n;
+ int ok_dst;
+ t_float *vec_dst;
+
+ ok_dst = iem_tab_check_arrays(gensym("tab_const"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_dst)
+ {
+ n = x->x_size_dst;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = c;
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_const_list(t_tab_const *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_dst;
+ int i, n;
+ int ok_dst;
+ t_float *vec_dst, c;
+
+ if((argc >= 3) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2))
+ {
+ beg_dst = (int)atom_getintarg(0, argc, argv);
+ n = (int)atom_getintarg(1, argc, argv);
+ c = (t_float)atom_getfloatarg(2, argc, argv);
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_dst = iem_tab_check_arrays(gensym("tab_const"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_dst)
+ {
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = c;
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_const-ERROR: list need 3 float arguments:");
+ post(" destination_offset + number_of_samples_to_copy + constant-value");
+ }
+}
+
+static void tab_const_free(t_tab_const *x)
+{
+}
+
+static void *tab_const_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_const *x = (t_tab_const *)pd_new(tab_const_class);
+ t_symbol *dst;
+ t_float time;
+
+ if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ dst = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ }
+ else
+ {
+ post("tab_const-ERROR: need 1 symbol argument:");
+ post(" destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_const_setup(void)
+{
+ tab_const_class = class_new(gensym("tab_const"), (t_newmethod)tab_const_new, (t_method)tab_const_free,
+ sizeof(t_tab_const), 0, A_GIMME, 0);
+ class_addbang(tab_const_class, (t_method)tab_const_bang);
+ class_addfloat(tab_const_class, (t_method)tab_const_float);
+ class_addlist(tab_const_class, (t_method)tab_const_list);
+ class_addmethod(tab_const_class, (t_method)tab_const_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_const_class, gensym("iemhelp2/tab_const-help"));
+}
diff --git a/src/tab_conv.c b/src/tab_conv.c
new file mode 100644
index 0000000..aa80069
--- /dev/null
+++ b/src/tab_conv.c
@@ -0,0 +1,228 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_conv ------------------------------ */
+
+typedef struct _tab_conv
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_conv;
+
+static t_class *tab_conv_class;
+
+static void tab_conv_src1(t_tab_conv *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_conv_src2(t_tab_conv *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_conv_dst(t_tab_conv *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_conv_bang(t_tab_conv *x)
+{
+ int i, j, k, l, min_s2, plu_s2, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+ t_float sum=0.0f;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_conv"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_conv"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_conv"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ {
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ min_s2 = -x->x_size_src2 / 2;
+ plu_s2 = min_s2 + x->x_size_src2;
+ for(i=0; i<n; i++)
+ {
+ sum = 0.0f;
+ for(j=min_s2, l=0; j<plu_s2; j++, l++)
+ {
+ k = j + i;
+ if((k >= 0) && (k < n))
+ sum += vec_src1[k] * vec_src2[l];
+ }
+ vec_dst[i] = sum;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+}
+
+static void tab_conv_list(t_tab_conv *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int n_src1, n_src2;
+ int i, j, k, l, min_s2, plu_s2;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+ t_float sum=0.0f;
+
+ if((argc >= 5) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3) &&
+ IS_A_FLOAT(argv,4))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n_src1 = (int)atom_getintarg(3, argc, argv);
+ n_src2 = (int)atom_getintarg(4, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n_src1 < 0)
+ n_src1 = 0;
+ if(n_src2 < 0)
+ n_src2 = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_conv"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n_src1);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_conv"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n_src2);
+ ok_dst = iem_tab_check_arrays(gensym("tab_conv"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n_src1);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(n_src2 < n_src1)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n_src1)
+ {
+ t_garray *a;
+
+ min_s2 = -n_src2 / 2;
+ plu_s2 = min_s2 + n_src2;
+ for(i=0; i<n_src1; i++)
+ {
+ sum = 0.0f;
+ for(j=min_s2, l=0; j<plu_s2; j++, l++)
+ {
+ k = j + i;
+ if((k >= 0) && (k < n_src1))
+ sum += vec_src1[k] * vec_src2[l];
+ }
+ vec_dst[i] = sum;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ }
+ else
+ {
+ post("tab_conv-ERROR: list need 5 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_convolute + convolution_window_width");
+ }
+}
+
+static void tab_conv_free(t_tab_conv *x)
+{
+}
+
+static void *tab_conv_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_conv *x = (t_tab_conv *)pd_new(tab_conv_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_conv-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_conv_setup(void)
+{
+ tab_conv_class = class_new(gensym("tab_conv"), (t_newmethod)tab_conv_new, (t_method)tab_conv_free,
+ sizeof(t_tab_conv), 0, A_GIMME, 0);
+ class_addbang(tab_conv_class, (t_method)tab_conv_bang);
+ class_addlist(tab_conv_class, (t_method)tab_conv_list);
+ class_addmethod(tab_conv_class, (t_method)tab_conv_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_conv_class, (t_method)tab_conv_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_conv_class, (t_method)tab_conv_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_conv_class, gensym("iemhelp2/tab_conv-help"));
+}
diff --git a/src/tab_copy.c b/src/tab_copy.c
new file mode 100644
index 0000000..14755cc
--- /dev/null
+++ b/src/tab_copy.c
@@ -0,0 +1,170 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_copy ------------------------------ */
+
+typedef struct _tab_copy
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_copy;
+
+static t_class *tab_copy_class;
+
+static void tab_copy_src(t_tab_copy *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_copy_dst(t_tab_copy *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_copy_bang(t_tab_copy *x)
+{
+ int i, n;
+ int ok_src, ok_dst;
+ t_float *vec_src, *vec_dst;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_copy"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_copy"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ vec_src = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src[i];
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_copy_list(t_tab_copy *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src, beg_dst;
+ int i, n;
+ int ok_src, ok_dst;
+ t_float *vec_src, *vec_dst;
+
+ if((argc >= 3) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_copy"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_copy"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src && ok_dst)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src[i];
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_copy-ERROR: list need 3 float arguments:");
+ post(" source_offset + destination_offset + number_of_samples_to_copy");
+ }
+}
+
+static void tab_copy_free(t_tab_copy *x)
+{
+}
+
+static void *tab_copy_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_copy *x = (t_tab_copy *)pd_new(tab_copy_class);
+ t_symbol *src, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src;
+ }
+ else
+ {
+ post("tab_copy-ERROR: need 2 symbols arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_copy_setup(void)
+{
+ tab_copy_class = class_new(gensym("tab_copy"), (t_newmethod)tab_copy_new, (t_method)tab_copy_free,
+ sizeof(t_tab_copy), 0, A_GIMME, 0);
+ class_addbang(tab_copy_class, (t_method)tab_copy_bang);
+ class_addlist(tab_copy_class, (t_method)tab_copy_list);
+ class_addmethod(tab_copy_class, (t_method)tab_copy_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_copy_class, (t_method)tab_copy_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_copy_class, (t_method)tab_copy_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_copy_class, gensym("iemhelp2/tab_copy-help"));
+}
diff --git a/src/tab_counter.c b/src/tab_counter.c
new file mode 100644
index 0000000..9014a0c
--- /dev/null
+++ b/src/tab_counter.c
@@ -0,0 +1,208 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_counter ------------------------------ */
+
+typedef struct _tab_counter
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_counter;
+
+static t_class *tab_counter_class;
+
+static void tab_counter_src(t_tab_counter *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_counter_bang(t_tab_counter *x)
+{
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_counter"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_counter"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] == 0.0f)
+ vec_dst[i] = 0.0f;
+ else
+ vec_dst[i] += 1.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_counter_dst(t_tab_counter *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_counter_list(t_tab_counter *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_dst;
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst;
+
+ if((argc >= 3) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_counter"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_counter"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] == 0.0f)
+ vec_dst[i] = 0.0f;
+ else
+ vec_dst[i] += 1.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_counter-ERROR: list need 4 float arguments:");
+ post(" source1_offset + destination_offset + number_of_samples_to_add + add_scalar");
+ }
+}
+
+static void tab_counter_reset(t_tab_counter *x)
+{
+ int beg_dst;
+ int i, n;
+ int ok_dst;
+ t_float *vec_dst;
+
+ ok_dst = iem_tab_check_arrays(gensym("tab_counter"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_dst)
+ {
+ n = x->x_size_dst;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = 0.0f;
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_counter_free(t_tab_counter *x)
+{
+}
+
+static void *tab_counter_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_counter *x = (t_tab_counter *)pd_new(tab_counter_class);
+ t_symbol *src1, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ }
+ else
+ {
+ post("tab_counter-ERROR: need 2 symbol arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_counter_setup(void)
+{
+ tab_counter_class = class_new(gensym("tab_counter"), (t_newmethod)tab_counter_new, (t_method)tab_counter_free,
+ sizeof(t_tab_counter), 0, A_GIMME, 0);
+ class_addbang(tab_counter_class, (t_method)tab_counter_bang);
+ class_addlist(tab_counter_class, (t_method)tab_counter_list);
+ class_addmethod(tab_counter_class, (t_method)tab_counter_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_counter_class, (t_method)tab_counter_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_counter_class, (t_method)tab_counter_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_counter_class, (t_method)tab_counter_reset, gensym("reset"), 0);
+ class_sethelpsymbol(tab_counter_class, gensym("iemhelp2/tab_counter-help"));
+}
diff --git a/src/tab_cross_corr.c b/src/tab_cross_corr.c
new file mode 100644
index 0000000..7c19c99
--- /dev/null
+++ b/src/tab_cross_corr.c
@@ -0,0 +1,222 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_cross_corr ------------------------------ */
+
+typedef struct _tab_cross_corr
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_n;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ float x_factor;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+ float x_delay;
+ int x_counter;
+ void *x_clock;
+} t_tab_cross_corr;
+
+static t_class *tab_cross_corr_class;
+
+static void tab_cross_corr_tick(t_tab_cross_corr *x)
+{
+ x->x_counter++;
+ if(x->x_counter < x->x_n)
+ {
+ t_float *vec_src1, *vec_src2, *vec_dst, sum;
+ int j, m;
+
+ vec_src1 = x->x_beg_mem_src1 + x->x_counter;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst + x->x_counter;
+ m = x->x_size_src2;
+ sum = 0.0f;
+ for(j=0; j<m; j++)
+ {
+ sum += vec_src1[j]*vec_src2[j];
+ }
+ vec_dst[0] = sum*x->x_factor;
+ clock_delay(x->x_clock, x->x_delay);
+ }
+ else
+ {
+ t_garray *a;
+
+ clock_unset(x->x_clock);
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+}
+
+static void tab_cross_corr_time(t_tab_cross_corr *x, t_floatarg time)
+{
+ if(time < 0.0f)
+ time = 0.0f;
+
+ x->x_delay = time;
+}
+
+static void tab_cross_corr_factor(t_tab_cross_corr *x, t_floatarg factor)
+{
+ x->x_factor = factor;
+}
+
+static void tab_cross_corr_src1(t_tab_cross_corr *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_cross_corr_src2(t_tab_cross_corr *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_cross_corr_dst(t_tab_cross_corr *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_cross_corr_bang(t_tab_cross_corr *x)
+{
+ int i, j, m, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+ t_float sum, f;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_cross_corr"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_cross_corr"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_cross_corr"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 > x->x_size_src2)
+ n = x->x_size_src1 - x->x_size_src2;
+ else
+ n = 0;
+ if(n > x->x_size_dst)
+ x->x_n = x->x_size_dst;
+ else
+ x->x_n = n;
+ f = x->x_factor;
+ if(n)
+ {
+ if(x->x_delay == 0.0f)
+ {
+ t_garray *a;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ m = x->x_size_src2;
+ for(i=0; i<n; i++)
+ {
+ sum = 0.0f;
+ for(j=0; j<m; j++)
+ {
+ sum += vec_src1[i+j]*vec_src2[j];
+ }
+ vec_dst[i] = sum*f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ else
+ {
+ x->x_counter = 0;
+ vec_src1 = x->x_beg_mem_src1 + x->x_counter;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst + x->x_counter;
+ m = x->x_size_src2;
+ sum = 0.0f;
+ for(j=0; j<m; j++)
+ {
+ sum += vec_src1[j]*vec_src2[j];
+ }
+ vec_dst[0] = sum*f;
+
+ clock_delay(x->x_clock, x->x_delay);
+ }
+ }
+ }
+}
+
+static void tab_cross_corr_free(t_tab_cross_corr *x)
+{
+ clock_free(x->x_clock);
+}
+
+static void *tab_cross_corr_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_cross_corr *x = (t_tab_cross_corr *)pd_new(tab_cross_corr_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time, factor;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2) &&
+ IS_A_FLOAT(argv,3) &&
+ IS_A_FLOAT(argv,4))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ factor = (t_float)atom_getfloatarg(3, argc, argv);
+ time = (t_float)atom_getfloatarg(4, argc, argv);
+ }
+ else
+ {
+ post("tab_cross_corr-ERROR: need 3 symbol + 2 float arguments:");
+ post(" source_reference_array_name + source_measure_array_name + destination_array_name + norm_factor + calculation-time-per-sample_ms");
+ return(0);
+ }
+
+ if(time < 0.0f)
+ time = 0.0f;
+
+ x->x_delay = time;
+ x->x_factor = factor;
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ x->x_clock = clock_new(x, (t_method)tab_cross_corr_tick);
+ return(x);
+}
+
+void tab_cross_corr_setup(void)
+{
+ tab_cross_corr_class = class_new(gensym("tab_cross_corr"), (t_newmethod)tab_cross_corr_new, (t_method)tab_cross_corr_free,
+ sizeof(t_tab_cross_corr), 0, A_GIMME, 0);
+ class_addbang(tab_cross_corr_class, (t_method)tab_cross_corr_bang);
+ class_addmethod(tab_cross_corr_class, (t_method)tab_cross_corr_time, gensym("time"), A_DEFFLOAT, 0);
+ class_addmethod(tab_cross_corr_class, (t_method)tab_cross_corr_factor, gensym("factor"), A_DEFFLOAT, 0);
+ class_addmethod(tab_cross_corr_class, (t_method)tab_cross_corr_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_cross_corr_class, (t_method)tab_cross_corr_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_cross_corr_class, (t_method)tab_cross_corr_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_cross_corr_class, gensym("iemhelp2/tab_cross_corr-help"));
+}
diff --git a/src/tab_div.c b/src/tab_div.c
new file mode 100644
index 0000000..a159ac3
--- /dev/null
+++ b/src/tab_div.c
@@ -0,0 +1,206 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_div ------------------------------ */
+
+typedef struct _tab_div
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_div;
+
+static t_class *tab_div_class;
+
+static void tab_div_src1(t_tab_div *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_div_src2(t_tab_div *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_div_dst(t_tab_div *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_div_bang(t_tab_div *x)
+{
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_div"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_div"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_div"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ n = x->x_size_src2;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src2[i] == 0.0f)
+ vec_dst[i] = 0.0f;
+ else
+ vec_dst[i] = vec_src1[i] / vec_src2[i];
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_div_list(t_tab_div *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n = (int)atom_getintarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_div"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_div"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_div"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src2[i] == 0.0f)
+ vec_dst[i] = 0.0f;
+ else
+ vec_dst[i] = vec_src1[i] / vec_src2[i];
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_div-ERROR: list need 4 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_div");
+ }
+}
+
+static void tab_div_free(t_tab_div *x)
+{
+}
+
+static void *tab_div_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_div *x = (t_tab_div *)pd_new(tab_div_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_div-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_div_setup(void)
+{
+ tab_div_class = class_new(gensym("tab_div"), (t_newmethod)tab_div_new, (t_method)tab_div_free,
+ sizeof(t_tab_div), 0, A_GIMME, 0);
+ class_addbang(tab_div_class, (t_method)tab_div_bang);
+ class_addlist(tab_div_class, (t_method)tab_div_list);
+ class_addmethod(tab_div_class, (t_method)tab_div_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_div_class, (t_method)tab_div_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_div_class, (t_method)tab_div_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_div_class, gensym("iemhelp2/tab_div-help"));
+}
diff --git a/src/tab_eq.c b/src/tab_eq.c
new file mode 100644
index 0000000..cbfe216
--- /dev/null
+++ b/src/tab_eq.c
@@ -0,0 +1,206 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_eq ------------------------------ */
+
+typedef struct _tab_eq
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_eq;
+
+static t_class *tab_eq_class;
+
+static void tab_eq_src1(t_tab_eq *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_eq_src2(t_tab_eq *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_eq_dst(t_tab_eq *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_eq_bang(t_tab_eq *x)
+{
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_eq"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_eq"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_eq"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ n = x->x_size_src2;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] == vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_eq_list(t_tab_eq *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n = (int)atom_getintarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_eq"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_eq"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_eq"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] == vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_eq-ERROR: list need 4 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_compare");
+ }
+}
+
+static void tab_eq_free(t_tab_eq *x)
+{
+}
+
+static void *tab_eq_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_eq *x = (t_tab_eq *)pd_new(tab_eq_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_eq-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_eq_setup(void)
+{
+ tab_eq_class = class_new(gensym("tab_eq"), (t_newmethod)tab_eq_new, (t_method)tab_eq_free,
+ sizeof(t_tab_eq), 0, A_GIMME, 0);
+ class_addbang(tab_eq_class, (t_method)tab_eq_bang);
+ class_addlist(tab_eq_class, (t_method)tab_eq_list);
+ class_addmethod(tab_eq_class, (t_method)tab_eq_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_eq_class, (t_method)tab_eq_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_eq_class, (t_method)tab_eq_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_eq_class, gensym("iemhelp2/tab_eq-help"));
+}
diff --git a/src/tab_eq_scalar.c b/src/tab_eq_scalar.c
new file mode 100644
index 0000000..cd00e7a
--- /dev/null
+++ b/src/tab_eq_scalar.c
@@ -0,0 +1,183 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_eq_scalar ------------------------------ */
+
+typedef struct _tab_eq_scalar
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_eq_scalar;
+
+static t_class *tab_eq_scalar_class;
+
+static void tab_eq_scalar_src(t_tab_eq_scalar *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_eq_scalar_float(t_tab_eq_scalar *x, t_floatarg compare)
+{
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_eq_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_eq_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] == compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_eq_scalar_dst(t_tab_eq_scalar *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_eq_scalar_list(t_tab_eq_scalar *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_dst;
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst, compare;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ compare = (t_float)atom_getfloatarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_eq_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_eq_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] == compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_eq_scalar-ERROR: list need 4 float arguments:");
+ post(" source1_offset + destination_offset + number_of_samples_to_compare + compare_scalar");
+ }
+}
+
+static void tab_eq_scalar_free(t_tab_eq_scalar *x)
+{
+}
+
+static void *tab_eq_scalar_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_eq_scalar *x = (t_tab_eq_scalar *)pd_new(tab_eq_scalar_class);
+ t_symbol *src1, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ }
+ else
+ {
+ post("tab_eq_scalar-ERROR: need 2 symbol arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_eq_scalar_setup(void)
+{
+ tab_eq_scalar_class = class_new(gensym("tab_eq_scalar"), (t_newmethod)tab_eq_scalar_new, (t_method)tab_eq_scalar_free,
+ sizeof(t_tab_eq_scalar), 0, A_GIMME, 0);
+ class_addfloat(tab_eq_scalar_class, (t_method)tab_eq_scalar_float);
+ class_addlist(tab_eq_scalar_class, (t_method)tab_eq_scalar_list);
+ class_addmethod(tab_eq_scalar_class, (t_method)tab_eq_scalar_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_eq_scalar_class, (t_method)tab_eq_scalar_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_eq_scalar_class, (t_method)tab_eq_scalar_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_eq_scalar_class, gensym("iemhelp2/tab_eq_scalar-help"));
+}
diff --git a/src/tab_fft.c b/src/tab_fft.c
new file mode 100644
index 0000000..0948821
--- /dev/null
+++ b/src/tab_fft.c
@@ -0,0 +1,400 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_fft ------------------------------ */
+
+typedef struct _tab_fft
+{
+ t_object x_obj;
+ int x_size_src_re;
+ int x_size_src_im;
+ int x_size_dst_re;
+ int x_size_dst_im;
+ int x_offset_src_re;
+ int x_offset_src_im;
+ int x_offset_dst_re;
+ int x_offset_dst_im;
+ int x_fftsize;
+ float *x_beg_mem_src_re;
+ float *x_beg_mem_src_im;
+ float *x_beg_mem_dst_re;
+ float *x_beg_mem_dst_im;
+ TAB_COMPLEX *x_sin_cos;
+ t_symbol *x_sym_src_re;
+ t_symbol *x_sym_src_im;
+ t_symbol *x_sym_dst_re;
+ t_symbol *x_sym_dst_im;
+} t_tab_fft;
+
+static t_class *tab_fft_class;
+
+static void tab_fft_init(t_tab_fft *x)
+{
+ int i, fftsize = x->x_fftsize;
+ float f, g;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+
+ g = 2.0f * 3.1415926538f / (float)fftsize;
+ for(i=0; i<fftsize; i++)
+ {
+ f = g * (float)i;
+ (*sincos).real = cos(f);
+ (*sincos).imag = -sin(f);/*FFT*/
+ sincos++;
+ }
+}
+
+static void tab_fft_fftsize(t_tab_fft *x, t_floatarg f)
+{
+ int i=1, fftsize = (int)f;
+
+ if(fftsize < 8)
+ fftsize = 8;
+
+ while(i <= fftsize)
+ i *= 2;
+ i /= 2;
+
+ if(i != x->x_fftsize)
+ {
+ x->x_sin_cos = (TAB_COMPLEX *)resizebytes(x->x_sin_cos, x->x_fftsize*sizeof(TAB_COMPLEX), i*sizeof(TAB_COMPLEX));
+ x->x_fftsize = i;
+ }
+ tab_fft_init(x);
+}
+
+static void tab_fft_src_re(t_tab_fft *x, t_symbol *s)
+{
+ x->x_sym_src_re = s;
+}
+
+static void tab_fft_src_im(t_tab_fft *x, t_symbol *s)
+{
+ x->x_sym_src_im = s;
+}
+
+static void tab_fft_dst_re(t_tab_fft *x, t_symbol *s)
+{
+ x->x_sym_dst_re = s;
+}
+
+static void tab_fft_dst_im(t_tab_fft *x, t_symbol *s)
+{
+ x->x_sym_dst_im = s;
+}
+
+static void tab_fft_bang(t_tab_fft *x)
+{
+ int i, j, k;
+ int ok_src_re, ok_src_im, ok_dst_re, ok_dst_im;
+ int w_index, w_inc, i_inc, v_index;
+ int fftsize = x->x_fftsize;
+ int fs1 = fftsize - 1;
+ int fs2 = fftsize / 2;
+ TAB_COMPLEX w;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+ t_float *vec_src_re, *vec_src_im, *vec_dst_re, *vec_dst_im;
+ t_float old1_re, old1_im, old2_re, old2_im;
+
+ ok_src_re = iem_tab_check_arrays(gensym("tab_fft"), x->x_sym_src_re, &x->x_beg_mem_src_re, &x->x_size_src_re, fftsize);
+ ok_src_im = iem_tab_check_arrays(gensym("tab_fft"), x->x_sym_src_im, &x->x_beg_mem_src_im, &x->x_size_src_im, fftsize);
+ ok_dst_re = iem_tab_check_arrays(gensym("tab_fft"), x->x_sym_dst_re, &x->x_beg_mem_dst_re, &x->x_size_dst_re, fftsize);
+ ok_dst_im = iem_tab_check_arrays(gensym("tab_fft"), x->x_sym_dst_im, &x->x_beg_mem_dst_im, &x->x_size_dst_im, fftsize);
+ if(ok_src_re && ok_src_im && ok_dst_re && ok_dst_im)
+ {
+ t_garray *a;
+
+ vec_src_re=x->x_beg_mem_src_re;
+ vec_src_im=x->x_beg_mem_src_im;
+ vec_dst_re=x->x_beg_mem_dst_re;
+ vec_dst_im=x->x_beg_mem_dst_im;
+
+ for(k=0; k<fftsize; k++)
+ {
+ vec_dst_re[k] = vec_src_re[k];
+ vec_dst_im[k] = vec_src_im[k];
+ }
+
+ i_inc = fs2;
+ w_inc = 1;
+ for(i=1; i<fftsize; i<<=1)
+ {
+ v_index = 0;
+ for(j=0; j<i; j++)
+ {
+ w_index = 0;
+ for(k=0; k<i_inc; k++)
+ {
+ old1_re = vec_dst_re[v_index];
+ old1_im = vec_dst_im[v_index];
+ old2_re = vec_dst_re[v_index+i_inc];
+ old2_im = vec_dst_im[v_index+i_inc];
+ w = sincos[w_index];
+ vec_dst_re[v_index+i_inc] = (old1_re - old2_re)*w.real - (old1_im - old2_im)*w.imag;
+ vec_dst_im[v_index+i_inc] = (old1_im - old2_im)*w.real + (old1_re - old2_re)*w.imag;
+ vec_dst_re[v_index] = old1_re + old2_re;
+ vec_dst_im[v_index] = old1_im + old2_im;
+ w_index += w_inc;
+ v_index++;
+ }
+ v_index += i_inc;
+ }
+ w_inc <<= 1;
+ i_inc >>= 1;
+ }
+
+ j = 0;
+ for(i=1;i<fs1;i++)
+ {
+ k = fs2;
+ while(k <= j)
+ {
+ j = j - k;
+ k >>= 1;
+ }
+ j = j + k;
+ if(i < j)
+ {
+ old1_re = vec_dst_re[j];
+ old1_im = vec_dst_im[j];
+ vec_dst_re[j] = vec_dst_re[i];
+ vec_dst_im[j] = vec_dst_im[i];
+ vec_dst_re[i] = old1_re;
+ vec_dst_im[i] = old1_im;
+ }
+ }
+
+// g = 2.0f / (float)fftsize;
+/*
+ ein fehler tritt auf beim 0.sample, hier sollte nur mal 1.0 multipliziert werden
+ wenn gelten soll : Energie im zeitfenster == Energie im Frequenz-dichte-fenster
+
+ g = 1.0f;
+ for(i = 0; i < fs2; i++)
+ {
+ vec_dst_re[i] *= g;
+ vec_dst_im[i] *= g;
+ }
+ */
+
+
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_re, garray_class);
+ garray_redraw(a);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_im, garray_class);
+ garray_redraw(a);
+ }
+}
+
+static void tab_fft_list(t_tab_fft *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src_re, beg_src_im, beg_dst_re, beg_dst_im;
+ int i, j, k;
+ int ok_src_re, ok_src_im, ok_dst_re, ok_dst_im;
+ int w_index, w_inc, i_inc, v_index;
+ int fftsize = x->x_fftsize;
+ int fs1 = fftsize - 1;
+ int fs2 = fftsize / 2;
+ TAB_COMPLEX w;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+ t_float *vec_src_re, *vec_src_im, *vec_dst_re, *vec_dst_im;
+ t_float old1_re, old1_im, old2_re, old2_im;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src_re = (int)atom_getintarg(0, argc, argv);
+ beg_src_im = (int)atom_getintarg(1, argc, argv);
+ beg_dst_re = (int)atom_getintarg(2, argc, argv);
+ beg_dst_im = (int)atom_getintarg(3, argc, argv);
+ if(beg_src_re < 0)
+ beg_src_re = 0;
+ if(beg_src_im < 0)
+ beg_src_im = 0;
+ if(beg_dst_re < 0)
+ beg_dst_re = 0;
+ if(beg_dst_im < 0)
+ beg_dst_im = 0;
+
+ ok_src_re = iem_tab_check_arrays(gensym("tab_fft"), x->x_sym_src_re, &x->x_beg_mem_src_re, &x->x_size_src_re, beg_src_re+fftsize);
+ ok_src_im = iem_tab_check_arrays(gensym("tab_fft"), x->x_sym_src_im, &x->x_beg_mem_src_im, &x->x_size_src_im, beg_src_im+fftsize);
+ ok_dst_re = iem_tab_check_arrays(gensym("tab_fft"), x->x_sym_dst_re, &x->x_beg_mem_dst_re, &x->x_size_dst_re, beg_dst_re+fftsize);
+ ok_dst_im = iem_tab_check_arrays(gensym("tab_fft"), x->x_sym_dst_im, &x->x_beg_mem_dst_im, &x->x_size_dst_im, beg_dst_im+fftsize);
+
+ if(ok_src_re && ok_src_im && ok_dst_re && ok_dst_im)
+ {
+ t_garray *a;
+
+ vec_src_re=x->x_beg_mem_src_re + beg_src_re;
+ vec_src_im=x->x_beg_mem_src_im + beg_src_im;
+ vec_dst_re=x->x_beg_mem_dst_re + beg_dst_re;
+ vec_dst_im=x->x_beg_mem_dst_im + beg_dst_im;
+
+ for(k=0; k<fftsize; k++)
+ {
+ vec_dst_re[k] = vec_src_re[k];
+ vec_dst_im[k] = vec_src_im[k];
+ }
+
+ i_inc = fs2;
+ w_inc = 1;
+ for(i=1; i<fftsize; i<<=1)
+ {
+ v_index = 0;
+ for(j=0; j<i; j++)
+ {
+ w_index = 0;
+ for(k=0; k<i_inc; k++)
+ {
+ old1_re = vec_dst_re[v_index];
+ old1_im = vec_dst_im[v_index];
+ old2_re = vec_dst_re[v_index+i_inc];
+ old2_im = vec_dst_im[v_index+i_inc];
+ w = sincos[w_index];
+ vec_dst_re[v_index+i_inc] = (old1_re - old2_re)*w.real - (old1_im - old2_im)*w.imag;
+ vec_dst_im[v_index+i_inc] = (old1_im - old2_im)*w.real + (old1_re - old2_re)*w.imag;
+ vec_dst_re[v_index] = old1_re + old2_re;
+ vec_dst_im[v_index] = old1_im + old2_im;
+ w_index += w_inc;
+ v_index++;
+ }
+ v_index += i_inc;
+ }
+ w_inc <<= 1;
+ i_inc >>= 1;
+ }
+
+ j = 0;
+ for(i=1;i<fs1;i++)
+ {
+ k = fs2;
+ while(k <= j)
+ {
+ j = j - k;
+ k >>= 1;
+ }
+ j = j + k;
+ if(i < j)
+ {
+ old1_re = vec_dst_re[j];
+ old1_im = vec_dst_im[j];
+ vec_dst_re[j] = vec_dst_re[i];
+ vec_dst_im[j] = vec_dst_im[i];
+ vec_dst_re[i] = old1_re;
+ vec_dst_im[i] = old1_im;
+ }
+ }
+
+// g = 2.0f / (float)fftsize;
+/*
+ ein fehler tritt auf beim 0.sample, hier sollte nur mal 1.0 multipliziert werden
+ wenn gelten soll : Energie im zeitfenster == Energie im Frequenz-dichte-fenster
+
+ g = 1.0f;
+ for(i = 0; i < fs2; i++)
+ {
+ vec_dst_re[i] *= g;
+ vec_dst_im[i] *= g;
+ }
+ */
+
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_re, garray_class);
+ garray_redraw(a);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_im, garray_class);
+ garray_redraw(a);
+ }
+ }
+ else
+ {
+ post("tab_fft-ERROR: list need 4 float arguments:");
+ post(" source_real_offset + source_imag_offset + destination_real_offset + destination_imag_offset");
+ }
+}
+
+static void tab_fft_free(t_tab_fft *x)
+{
+ freebytes(x->x_sin_cos, x->x_fftsize * sizeof(TAB_COMPLEX));
+}
+
+static void *tab_fft_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_fft *x = (t_tab_fft *)pd_new(tab_fft_class);
+ t_symbol *src_re, *src_im, *dst_re, *dst_im;
+ int fftsize, i=1;
+
+ if((argc >= 5) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2) &&
+ IS_A_SYMBOL(argv,3) &&
+ IS_A_FLOAT(argv,4))
+ {
+ src_re = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src_im = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst_re = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ dst_im = (t_symbol *)atom_getsymbolarg(3, argc, argv);
+ fftsize = (int)atom_getintarg(4, argc, argv);
+ }
+ else
+ {
+ post("tab_fft-ERROR: need 4 symbols + 1 float arguments:");
+ post(" source_real_array_name + source_imag_array_name + destination_real_array_name + destination_imag_array_name + FFT-size");
+ return(0);
+ }
+
+ if(fftsize < 8)
+ fftsize = 8;
+
+ while(i <= fftsize)
+ i *= 2;
+ i /= 2;
+ fftsize = i;
+
+ x->x_fftsize = fftsize;
+ x->x_sym_src_re = src_re;
+ x->x_sym_src_im = src_im;
+ x->x_sym_dst_re = dst_re;
+ x->x_sym_dst_im = dst_im;
+ x->x_sin_cos = (TAB_COMPLEX *)getbytes(x->x_fftsize * sizeof(TAB_COMPLEX));
+ tab_fft_init(x);
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_fft_setup(void)
+{
+ tab_fft_class = class_new(gensym("tab_fft"), (t_newmethod)tab_fft_new, (t_method)tab_fft_free,
+ sizeof(t_tab_fft), 0, A_GIMME, 0);
+ class_addbang(tab_fft_class, (t_method)tab_fft_bang);
+ class_addlist(tab_fft_class, (t_method)tab_fft_list);
+ class_addmethod(tab_fft_class, (t_method)tab_fft_fftsize, gensym("fftsize"), A_DEFFLOAT, 0);
+ class_addmethod(tab_fft_class, (t_method)tab_fft_src_re, gensym("src_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_fft_class, (t_method)tab_fft_src_im, gensym("src_im"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_fft_class, (t_method)tab_fft_src_re, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_fft_class, (t_method)tab_fft_src_im, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_fft_class, (t_method)tab_fft_dst_re, gensym("dst_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_fft_class, (t_method)tab_fft_dst_im, gensym("dst_im"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_fft_class, (t_method)tab_fft_dst_re, gensym("dst1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_fft_class, (t_method)tab_fft_dst_im, gensym("dst2"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_fft_class, gensym("iemhelp2/tab_fft-help"));
+}
diff --git a/src/tab_find_peaks.c b/src/tab_find_peaks.c
new file mode 100644
index 0000000..5b6cc61
--- /dev/null
+++ b/src/tab_find_peaks.c
@@ -0,0 +1,389 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_find_peaks ------------------------------ */
+
+#define IEMLIB_TAB_FIND_PEAKS_SORT_MODE_AMP 0
+#define IEMLIB_TAB_FIND_PEAKS_SORT_MODE_FREQ 1
+
+typedef struct _tab_find_peaks
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_offset_src1;
+ float *x_beg_mem_src1;
+ int x_work_alloc;
+ int *x_beg_mem_work1;
+ float *x_beg_mem_work2;
+ int x_sort_mode;
+ float x_hdiff;
+ int x_min_width;
+ int x_max_width;
+ int x_n_peaks;
+ t_symbol *x_sym_scr1;
+ t_outlet *x_bang_out;
+ t_outlet *x_sort_index_out;
+ t_outlet *x_peak_value_out;
+ t_outlet *x_peak_index_out;
+} t_tab_find_peaks;
+
+static t_class *tab_find_peaks_class;
+
+static void tab_find_peaks_max_peaks(t_tab_find_peaks *x, t_floatarg fmax_peaks)
+{
+ int max_peaks = (int)fmax_peaks;
+
+ if(max_peaks <= 0)
+ max_peaks = 1;
+ x->x_n_peaks = max_peaks;
+}
+
+static void tab_find_peaks_width_range(t_tab_find_peaks *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int minw, maxw, h;
+
+ if((argc >= 2) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1))
+ {
+ minw = (int)atom_getintarg(0, argc, argv);
+ maxw = (int)atom_getintarg(1, argc, argv);
+ if(minw <= 0)
+ minw = 1;
+ if(maxw <= 0)
+ maxw = 1;
+ if(minw > maxw)
+ {
+ h = minw;
+ minw = maxw;
+ maxw = h;
+ }
+ x->x_min_width = minw;
+ x->x_max_width = maxw;
+ }
+}
+
+static void tab_find_peaks_abs_min_height_diff(t_tab_find_peaks *x, t_floatarg height_diff)
+{
+ if(height_diff < 0.0f)
+ height_diff *= -1.0f;
+ x->x_hdiff = height_diff;
+}
+
+static void tab_find_peaks_amp_sort(t_tab_find_peaks *x)
+{
+ x->x_sort_mode = IEMLIB_TAB_FIND_PEAKS_SORT_MODE_AMP;
+}
+
+static void tab_find_peaks_freq_sort(t_tab_find_peaks *x)
+{
+ x->x_sort_mode = IEMLIB_TAB_FIND_PEAKS_SORT_MODE_FREQ;
+}
+
+static void tab_find_peaks_src(t_tab_find_peaks *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_find_peaks_bang(t_tab_find_peaks *x)
+{
+ int i, n, w, ww;
+ int ok_src, peak_index=0, sort_index=0;
+ t_float *vec_src, *vec_work2;
+ int *vec_work1;
+ t_float max=-1.0e37;
+ int max_peaks=x->x_n_peaks;
+ int min_width=x->x_min_width;
+ int max_width=x->x_max_width;
+ t_float abs_min_height_diff=x->x_hdiff;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_find_peaks"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+
+ if(ok_src)
+ {
+ n = x->x_size_src1;
+ if(n)
+ {
+ if(!x->x_work_alloc)
+ {
+ x->x_beg_mem_work1 = (int *)getbytes(n * sizeof(int));
+ x->x_beg_mem_work2 = (float *)getbytes(n * sizeof(float));
+ x->x_work_alloc = n;
+ }
+ else if(n != x->x_work_alloc)
+ {
+ x->x_beg_mem_work1 = (int *)resizebytes(x->x_beg_mem_work1, x->x_work_alloc*sizeof(int), n*sizeof(int));
+ x->x_beg_mem_work2 = (float *)resizebytes(x->x_beg_mem_work2, x->x_work_alloc*sizeof(float), n*sizeof(float));
+ x->x_work_alloc = n;
+ }
+ vec_src = x->x_beg_mem_src1;
+ vec_work1 = x->x_beg_mem_work1;
+ vec_work2 = x->x_beg_mem_work2;
+ if(x->x_sort_mode == IEMLIB_TAB_FIND_PEAKS_SORT_MODE_FREQ) // FREQ_SORT BEGIN
+ {
+ int sort_index=1,old=0,j;
+
+ for(i=0; i<n; i++)
+ {
+ vec_work1[i] = 0;
+ }
+ for(w=min_width; w<=max_width; w++) // w variiert zw. min u. max
+ {
+ for(ww=0; ww<w; ww++)
+ {
+ int beg=w-ww;
+ int end=n-1-ww;
+ int low_bord=beg-1;
+ int high_bord=n-end-1;
+ t_float diff_low,diff_high;
+
+ for(i=beg; i<end; i++)
+ {
+ diff_low = vec_src[i-low_bord] - abs_min_height_diff;
+ diff_high = vec_src[i+high_bord] - abs_min_height_diff;
+ if((vec_src[i-low_bord-1] < diff_low) && !vec_work1[i-low_bord] &&
+ (vec_src[i+high_bord+1] < diff_high) && !vec_work1[i+high_bord])
+ {
+ for(j=i-low_bord; j<=i+high_bord; j++)
+ vec_work1[j] = 1;
+ //post("f[%d]=%g, f[%d]=%g",i-low_bord,vec_src[i-low_bord],i+high_bord,vec_src[i+high_bord]);
+ }
+ }
+ }
+ }
+ old = vec_work1[0];
+ sort_index=1;
+ for(i=1; i<n; i++)
+ {
+ if(!old && vec_work1[i])
+ {
+ vec_work1[i] = 0;
+ j=i+1;
+ while(vec_work1[j])
+ {
+ vec_work1[j] = 0;
+ j++;
+ }
+ j--;
+ peak_index = (i + j) / 2;
+ if(sort_index <= max_peaks)
+ {
+ outlet_float(x->x_peak_value_out, vec_src[i]);
+ outlet_float(x->x_peak_index_out, (float)peak_index);
+ outlet_float(x->x_sort_index_out, sort_index);
+ sort_index++;
+ }
+ else
+ i = n+1;
+ }
+ old = vec_work1[i];
+ }
+ outlet_bang(x->x_bang_out);
+ } // FREQ_SORT END
+ else if(x->x_sort_mode == IEMLIB_TAB_FIND_PEAKS_SORT_MODE_AMP) // AMP_SORT BEGIN
+ {
+ int sort_index=1,old=0,j;
+
+ for(i=0; i<n; i++)
+ {
+ vec_work1[i] = 0;
+ vec_work2[i] = 0.0f;
+ }
+ for(w=min_width; w<=max_width; w++) // w variiert zw. min u. max
+ {
+ for(ww=0; ww<w; ww++)
+ {
+ int beg=w-ww;
+ int end=n-1-ww;
+ int low_bord=beg-1;
+ int high_bord=n-end-1;
+ t_float diff_low,diff_high;
+
+ for(i=beg; i<end; i++)
+ {
+ diff_low = vec_src[i-low_bord] - abs_min_height_diff;
+ diff_high = vec_src[i+high_bord] - abs_min_height_diff;
+ if((vec_src[i-low_bord-1] < diff_low) && !vec_work1[i-low_bord] &&
+ (vec_src[i+high_bord+1] < diff_high) && !vec_work1[i+high_bord])
+ {
+ for(j=i-low_bord; j<=i+high_bord; j++)
+ {
+ vec_work1[j] = 1;
+ vec_work2[j] = vec_src[j];
+ }
+ //post("a[%d]=%g, a[%d]=%g",i-low_bord,vec_src[i-low_bord],i+high_bord,vec_src[i+high_bord]);
+ }
+ }
+ }
+ }
+ old = vec_work1[0];
+ for(sort_index=1; sort_index<=max_peaks; sort_index++)
+ {
+ max = -1.0e37;
+ peak_index = -1;
+ for(i=0; i<n; i++)
+ {
+ if(vec_work1[i])
+ {
+ if(vec_work2[i] > max)
+ {
+ max = vec_work2[i];
+ peak_index = i;
+ }
+ }
+ }
+
+ if(peak_index >= 0)
+ {
+ outlet_float(x->x_peak_value_out, max);
+ outlet_float(x->x_peak_index_out, (float)peak_index);
+ outlet_float(x->x_sort_index_out, sort_index);
+ vec_work1[peak_index] = 0;
+ vec_work2[peak_index] = 0.0f;
+ j=peak_index+1;
+ while(vec_work1[j])
+ {
+ vec_work1[j] = 0;
+ j++;
+ }
+ j=peak_index-1;
+ while(vec_work1[j])
+ {
+ vec_work1[j] = 0;
+ j--;
+ }
+ }
+ else
+ sort_index = max_peaks+1;
+ }
+ outlet_bang(x->x_bang_out);
+ }
+ } // AMP_SORT END
+ }
+ /*
+ [n] zu [n-1] u. [n+1] (ww=0)(w=1)(beg=1)(end=n-1)
+ [n-1] u. [n] zu [n-2] u. [n+1] (ww=0)(w=2)(beg=2)(end=n-1)
+ [n] u. [n+1] zu [n-1] u. [n+2] (ww=1)(w=2)(beg=1)(end=n-2)
+ [n-2] u. [n-1] u. [n] zu [n-3] u. [n+1] (ww=0)(w=3)(beg=3)(end=n-1)
+ [n-1] u. [n] u. [n+1] zu [n-2] u. [n+2] (ww=1)(w=3)(beg=2)(end=n-2)
+ [n] u. [n+1] u. [n+2] zu [n-1] u. [n+3] (ww=2)(w=3)(beg=1)(end=n-3)
+ */
+}
+
+/*static void tab_find_peaks_list(t_tab_find_peaks *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src;
+ int i, n;
+ int ok_src, max_index=0;
+ t_float *vec_src;
+ t_float max=-1.0e37;
+
+ if((argc >= 2) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ n = (int)atom_getintarg(1, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_find_peaks"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+
+ if(ok_src)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ if(vec_src[i] > max)
+ {
+ max = vec_src[i];
+ max_index = i + beg_src;
+ }
+ }
+ outlet_float(x->x_peak_value_out, max);
+ outlet_float(x->x_peak_index_out, (float)max_index);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+ }
+ else
+ {
+ post("tab_find_peaks-ERROR: list need 2 float arguments:");
+ post(" source_offset + number_of_samples_to_calc_max_index");
+ }
+}*/
+
+static void tab_find_peaks_free(t_tab_find_peaks *x)
+{
+ if(x->x_work_alloc)
+ {
+ freebytes(x->x_beg_mem_work1, x->x_work_alloc * sizeof(int));
+ freebytes(x->x_beg_mem_work2, x->x_work_alloc * sizeof(float));
+ }
+}
+
+static void *tab_find_peaks_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_find_peaks *x = (t_tab_find_peaks *)pd_new(tab_find_peaks_class);
+ t_symbol *src;
+
+ if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ }
+ else
+ {
+ post("tab_find_peaks-ERROR: need 1 symbol argument:");
+ post(" source_array_name");
+ return(0);
+ }
+
+ x->x_work_alloc = 0;
+ x->x_beg_mem_work1 = (int *)0;
+ x->x_beg_mem_work2 = (float *)0;
+
+ x->x_sym_scr1 = src;
+ x->x_bang_out = (t_outlet *)outlet_new(&x->x_obj, &s_bang); // ready
+ x->x_sort_index_out = (t_outlet *)outlet_new(&x->x_obj, &s_float); // sort index
+ x->x_peak_index_out = (t_outlet *)outlet_new(&x->x_obj, &s_float); // freq
+ x->x_peak_value_out = (t_outlet *)outlet_new(&x->x_obj, &s_float); // value
+
+ return(x);
+}
+
+void tab_find_peaks_setup(void)
+{
+ tab_find_peaks_class = class_new(gensym("tab_find_peaks"), (t_newmethod)tab_find_peaks_new, (t_method)tab_find_peaks_free,
+ sizeof(t_tab_find_peaks), 0, A_GIMME, 0);
+ class_addbang(tab_find_peaks_class, (t_method)tab_find_peaks_bang);
+ /*class_addlist(tab_find_peaks_class, (t_method)tab_find_peaks_list);*/
+ class_addmethod(tab_find_peaks_class, (t_method)tab_find_peaks_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_find_peaks_class, (t_method)tab_find_peaks_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_find_peaks_class, (t_method)tab_find_peaks_max_peaks, gensym("max_peaks"), A_DEFFLOAT, 0);
+ class_addmethod(tab_find_peaks_class, (t_method)tab_find_peaks_width_range, gensym("width_range"), A_GIMME, 0);
+ class_addmethod(tab_find_peaks_class, (t_method)tab_find_peaks_abs_min_height_diff, gensym("abs_min_height_diff"), A_DEFFLOAT, 0);
+ class_addmethod(tab_find_peaks_class, (t_method)tab_find_peaks_amp_sort, gensym("amp_sort"), 0);
+ class_addmethod(tab_find_peaks_class, (t_method)tab_find_peaks_freq_sort, gensym("freq_sort"), 0);
+ class_sethelpsymbol(tab_find_peaks_class, gensym("iemhelp2/tab_find_peaks-help"));
+}
diff --git a/src/tab_ge.c b/src/tab_ge.c
new file mode 100644
index 0000000..41cb6a8
--- /dev/null
+++ b/src/tab_ge.c
@@ -0,0 +1,206 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_ge ------------------------------ */
+
+typedef struct _tab_ge
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_ge;
+
+static t_class *tab_ge_class;
+
+static void tab_ge_src1(t_tab_ge *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_ge_src2(t_tab_ge *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_ge_dst(t_tab_ge *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_ge_bang(t_tab_ge *x)
+{
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_ge"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_ge"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_ge"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ n = x->x_size_src2;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] >= vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_ge_list(t_tab_ge *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n = (int)atom_getintarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_ge"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_ge"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_ge"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] >= vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_ge-ERROR: list need 4 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_compare");
+ }
+}
+
+static void tab_ge_free(t_tab_ge *x)
+{
+}
+
+static void *tab_ge_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_ge *x = (t_tab_ge *)pd_new(tab_ge_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_ge-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_ge_setup(void)
+{
+ tab_ge_class = class_new(gensym("tab_ge"), (t_newmethod)tab_ge_new, (t_method)tab_ge_free,
+ sizeof(t_tab_ge), 0, A_GIMME, 0);
+ class_addbang(tab_ge_class, (t_method)tab_ge_bang);
+ class_addlist(tab_ge_class, (t_method)tab_ge_list);
+ class_addmethod(tab_ge_class, (t_method)tab_ge_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ge_class, (t_method)tab_ge_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ge_class, (t_method)tab_ge_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_ge_class, gensym("iemhelp2/tab_ge-help"));
+}
diff --git a/src/tab_ge_scalar.c b/src/tab_ge_scalar.c
new file mode 100644
index 0000000..3e42b03
--- /dev/null
+++ b/src/tab_ge_scalar.c
@@ -0,0 +1,183 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_ge_scalar ------------------------------ */
+
+typedef struct _tab_ge_scalar
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_ge_scalar;
+
+static t_class *tab_ge_scalar_class;
+
+static void tab_ge_scalar_src(t_tab_ge_scalar *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_ge_scalar_float(t_tab_ge_scalar *x, t_floatarg compare)
+{
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_ge_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_ge_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] >= compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_ge_scalar_dst(t_tab_ge_scalar *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_ge_scalar_list(t_tab_ge_scalar *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_dst;
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst, compare;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ compare = (t_float)atom_getfloatarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_ge_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_ge_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] >= compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_ge_scalar-ERROR: list need 4 float arguments:");
+ post(" source1_offset + destination_offset + number_of_samples_to_compare + compare_scalar");
+ }
+}
+
+static void tab_ge_scalar_free(t_tab_ge_scalar *x)
+{
+}
+
+static void *tab_ge_scalar_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_ge_scalar *x = (t_tab_ge_scalar *)pd_new(tab_ge_scalar_class);
+ t_symbol *src1, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ }
+ else
+ {
+ post("tab_ge_scalar-ERROR: need 2 symbol arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_ge_scalar_setup(void)
+{
+ tab_ge_scalar_class = class_new(gensym("tab_ge_scalar"), (t_newmethod)tab_ge_scalar_new, (t_method)tab_ge_scalar_free,
+ sizeof(t_tab_ge_scalar), 0, A_GIMME, 0);
+ class_addfloat(tab_ge_scalar_class, (t_method)tab_ge_scalar_float);
+ class_addlist(tab_ge_scalar_class, (t_method)tab_ge_scalar_list);
+ class_addmethod(tab_ge_scalar_class, (t_method)tab_ge_scalar_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ge_scalar_class, (t_method)tab_ge_scalar_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ge_scalar_class, (t_method)tab_ge_scalar_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_ge_scalar_class, gensym("iemhelp2/tab_ge_scalar-help"));
+}
diff --git a/src/tab_gt.c b/src/tab_gt.c
new file mode 100644
index 0000000..b1ddbb5
--- /dev/null
+++ b/src/tab_gt.c
@@ -0,0 +1,206 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_gt ------------------------------ */
+
+typedef struct _tab_gt
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_gt;
+
+static t_class *tab_gt_class;
+
+static void tab_gt_src1(t_tab_gt *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_gt_src2(t_tab_gt *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_gt_dst(t_tab_gt *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_gt_bang(t_tab_gt *x)
+{
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_gt"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_gt"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_gt"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ n = x->x_size_src2;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] > vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_gt_list(t_tab_gt *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n = (int)atom_getintarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_gt"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_gt"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_gt"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] > vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_gt-ERROR: list need 4 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_compare");
+ }
+}
+
+static void tab_gt_free(t_tab_gt *x)
+{
+}
+
+static void *tab_gt_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_gt *x = (t_tab_gt *)pd_new(tab_gt_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_gt-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_gt_setup(void)
+{
+ tab_gt_class = class_new(gensym("tab_gt"), (t_newmethod)tab_gt_new, (t_method)tab_gt_free,
+ sizeof(t_tab_gt), 0, A_GIMME, 0);
+ class_addbang(tab_gt_class, (t_method)tab_gt_bang);
+ class_addlist(tab_gt_class, (t_method)tab_gt_list);
+ class_addmethod(tab_gt_class, (t_method)tab_gt_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_gt_class, (t_method)tab_gt_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_gt_class, (t_method)tab_gt_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_gt_class, gensym("iemhelp2/tab_gt-help"));
+}
diff --git a/src/tab_gt_scalar.c b/src/tab_gt_scalar.c
new file mode 100644
index 0000000..f779ba6
--- /dev/null
+++ b/src/tab_gt_scalar.c
@@ -0,0 +1,183 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_gt_scalar ------------------------------ */
+
+typedef struct _tab_gt_scalar
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_gt_scalar;
+
+static t_class *tab_gt_scalar_class;
+
+static void tab_gt_scalar_src(t_tab_gt_scalar *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_gt_scalar_float(t_tab_gt_scalar *x, t_floatarg compare)
+{
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_gt_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_gt_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] > compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_gt_scalar_dst(t_tab_gt_scalar *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_gt_scalar_list(t_tab_gt_scalar *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_dst;
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst, compare;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ compare = (t_float)atom_getfloatarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_gt_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_gt_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] > compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_gt_scalar-ERROR: list need 4 float arguments:");
+ post(" source1_offset + destination_offset + number_of_samples_to_compare + compare_scalar");
+ }
+}
+
+static void tab_gt_scalar_free(t_tab_gt_scalar *x)
+{
+}
+
+static void *tab_gt_scalar_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_gt_scalar *x = (t_tab_gt_scalar *)pd_new(tab_gt_scalar_class);
+ t_symbol *src1, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ }
+ else
+ {
+ post("tab_gt_scalar-ERROR: need 2 symbol arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_gt_scalar_setup(void)
+{
+ tab_gt_scalar_class = class_new(gensym("tab_gt_scalar"), (t_newmethod)tab_gt_scalar_new, (t_method)tab_gt_scalar_free,
+ sizeof(t_tab_gt_scalar), 0, A_GIMME, 0);
+ class_addfloat(tab_gt_scalar_class, (t_method)tab_gt_scalar_float);
+ class_addlist(tab_gt_scalar_class, (t_method)tab_gt_scalar_list);
+ class_addmethod(tab_gt_scalar_class, (t_method)tab_gt_scalar_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_gt_scalar_class, (t_method)tab_gt_scalar_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_gt_scalar_class, (t_method)tab_gt_scalar_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_gt_scalar_class, gensym("iemhelp2/tab_gt_scalar-help"));
+}
diff --git a/src/tab_ifft.c b/src/tab_ifft.c
new file mode 100644
index 0000000..e92fb0d
--- /dev/null
+++ b/src/tab_ifft.c
@@ -0,0 +1,414 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_ifft ------------------------------ */
+
+typedef struct _tab_ifft
+{
+ t_object x_obj;
+ int x_size_src_re;
+ int x_size_src_im;
+ int x_size_dst_re;
+ int x_size_dst_im;
+ int x_offset_src_re;
+ int x_offset_src_im;
+ int x_offset_dst_re;
+ int x_offset_dst_im;
+ int x_fftsize;
+ float *x_beg_mem_src_re;
+ float *x_beg_mem_src_im;
+ float *x_beg_mem_dst_re;
+ float *x_beg_mem_dst_im;
+ TAB_COMPLEX *x_sin_cos;
+ t_symbol *x_sym_src_re;
+ t_symbol *x_sym_src_im;
+ t_symbol *x_sym_dst_re;
+ t_symbol *x_sym_dst_im;
+} t_tab_ifft;
+
+static t_class *tab_ifft_class;
+
+static void tab_ifft_init(t_tab_ifft *x)
+{
+ int i, fftsize = x->x_fftsize;
+ float f, g;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+
+ g = 2.0f * 3.1415926538f / (float)fftsize;
+ for(i=0; i<fftsize; i++)
+ {
+ f = g * (float)i;
+ (*sincos).real = cos(f);
+ (*sincos).imag = sin(f);/*IFFT*/
+ sincos++;
+ }
+}
+
+static void tab_ifft_ifftsize(t_tab_ifft *x, t_floatarg f)
+{
+ int i=1, fftsize = (int)f;
+
+ if(fftsize < 8)
+ fftsize = 8;
+
+ while(i <= fftsize)
+ i *= 2;
+ i /= 2;
+
+ if(i != x->x_fftsize)
+ {
+ x->x_sin_cos = (TAB_COMPLEX *)resizebytes(x->x_sin_cos, x->x_fftsize*sizeof(TAB_COMPLEX), i*sizeof(TAB_COMPLEX));
+ x->x_fftsize = i;
+ }
+ tab_ifft_init(x);
+}
+
+static void tab_ifft_dst_re(t_tab_ifft *x, t_symbol *s)
+{
+ x->x_sym_dst_re = s;
+}
+
+static void tab_ifft_dst_im(t_tab_ifft *x, t_symbol *s)
+{
+ x->x_sym_dst_im = s;
+}
+
+static void tab_ifft_src_re(t_tab_ifft *x, t_symbol *s)
+{
+ x->x_sym_src_re = s;
+}
+
+static void tab_ifft_src_im(t_tab_ifft *x, t_symbol *s)
+{
+ x->x_sym_src_im = s;
+}
+
+static void tab_ifft_bang(t_tab_ifft *x)
+{
+ int i, j, k;
+ int ok_src_re, ok_src_im, ok_dst_re, ok_dst_im;
+ int w_index, w_inc, i_inc, v_index;
+ int fftsize = x->x_fftsize;
+ int fs1 = fftsize - 1;
+ int fs2 = fftsize / 2;
+ TAB_COMPLEX w;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+ t_float *vec_src_re, *vec_src_im, *vec_dst_re, *vec_dst_im;
+ t_float old1_re, old1_im, old2_re, old2_im, g;
+
+ ok_src_re = iem_tab_check_arrays(gensym("tab_ifft"), x->x_sym_src_re, &x->x_beg_mem_src_re, &x->x_size_src_re, fftsize);
+ ok_src_im = iem_tab_check_arrays(gensym("tab_ifft"), x->x_sym_src_im, &x->x_beg_mem_src_im, &x->x_size_src_im, fftsize);
+ ok_dst_re = iem_tab_check_arrays(gensym("tab_ifft"), x->x_sym_dst_re, &x->x_beg_mem_dst_re, &x->x_size_dst_re, fftsize);
+ ok_dst_im = iem_tab_check_arrays(gensym("tab_ifft"), x->x_sym_dst_im, &x->x_beg_mem_dst_im, &x->x_size_dst_im, fftsize);
+
+ if(ok_src_re && ok_src_im && ok_dst_re && ok_dst_im)
+ {
+ t_garray *a;
+
+ vec_src_re=x->x_beg_mem_src_re;
+ vec_src_im=x->x_beg_mem_src_im;
+ vec_dst_re=x->x_beg_mem_dst_re;
+ vec_dst_im=x->x_beg_mem_dst_im;
+
+ for(j=0; j<fftsize; j++)
+ {
+ vec_dst_re[j] = vec_src_re[j];
+ vec_dst_im[j] = vec_src_im[j];
+ }
+
+ i_inc = fs2;
+ w_inc = 1;
+ for(i=1; i<fftsize; i<<=1)
+ {
+ v_index = 0;
+ for(j=0; j<i; j++)
+ {
+ w_index = 0;
+ for(k=0; k<i_inc; k++)
+ {
+ old1_re = vec_dst_re[v_index];
+ old1_im = vec_dst_im[v_index];
+ old2_re = vec_dst_re[v_index+i_inc];
+ old2_im = vec_dst_im[v_index+i_inc];
+ w = sincos[w_index];
+ vec_dst_re[v_index+i_inc] = (old1_re - old2_re)*w.real - (old1_im - old2_im)*w.imag;
+ vec_dst_im[v_index+i_inc] = (old1_im - old2_im)*w.real + (old1_re - old2_re)*w.imag;
+ vec_dst_re[v_index] = old1_re + old2_re;
+ vec_dst_im[v_index] = old1_im + old2_im;
+ w_index += w_inc;
+ v_index++;
+ }
+ v_index += i_inc;
+ }
+ w_inc <<= 1;
+ i_inc >>= 1;
+ }
+
+ j = 0;
+ for(i=1;i<fs1;i++)
+ {
+ k = fs2;
+ while(k <= j)
+ {
+ j = j - k;
+ k >>= 1;
+ }
+ j = j + k;
+ if(i < j)
+ {
+ old1_re = vec_dst_re[j];
+ old1_im = vec_dst_im[j];
+ vec_dst_re[j] = vec_dst_re[i];
+ vec_dst_im[j] = vec_dst_im[i];
+ vec_dst_re[i] = old1_re;
+ vec_dst_im[i] = old1_im;
+ }
+ }
+
+// g = 2.0f / (float)fftsize;
+/*
+ ein fehler tritt auf beim 0.sample, hier sollte nur mal 1.0 multipliziert werden
+ wenn gelten soll : Energie im zeitfenster == Energie im Frequenz-dichte-fenster
+
+ g = 1.0f;
+ for(i = 0; i < fs2; i++)
+ {
+ vec_dst_re[i] *= g;
+ vec_dst_im[i] *= g;
+ }
+ */
+
+ g = 1.0f / (float)fftsize;
+ for(i = 0; i < fftsize; i++)
+ {
+ vec_dst_re[i] *= g;
+ vec_dst_im[i] *= g;
+ }
+
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_re, garray_class);
+ garray_redraw(a);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_im, garray_class);
+ garray_redraw(a);
+ }
+}
+
+static void tab_ifft_list(t_tab_ifft *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src_re, beg_src_im, beg_dst_re, beg_dst_im;
+ int i, j, k;
+ int ok_src_re, ok_src_im, ok_dst_re, ok_dst_im;
+ int w_index, w_inc, i_inc, v_index;
+ int fftsize = x->x_fftsize;
+ int fs1 = fftsize - 1;
+ int fs2 = fftsize / 2;
+ TAB_COMPLEX w;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+ t_float *vec_src_re, *vec_src_im, *vec_dst_re, *vec_dst_im;
+ t_float old1_re, old1_im, old2_re, old2_im, g;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src_re = (int)atom_getintarg(0, argc, argv);
+ beg_src_im = (int)atom_getintarg(1, argc, argv);
+ beg_dst_re = (int)atom_getintarg(2, argc, argv);
+ beg_dst_im = (int)atom_getintarg(3, argc, argv);
+ if(beg_src_re < 0)
+ beg_src_re = 0;
+ if(beg_src_im < 0)
+ beg_src_im = 0;
+ if(beg_dst_re < 0)
+ beg_dst_re = 0;
+ if(beg_dst_im < 0)
+ beg_dst_im = 0;
+
+ ok_src_re = iem_tab_check_arrays(gensym("tab_ifft"), x->x_sym_src_re, &x->x_beg_mem_src_re, &x->x_size_src_re, fftsize);
+ ok_src_im = iem_tab_check_arrays(gensym("tab_ifft"), x->x_sym_src_im, &x->x_beg_mem_src_im, &x->x_size_src_im, fftsize);
+ ok_dst_re = iem_tab_check_arrays(gensym("tab_ifft"), x->x_sym_dst_re, &x->x_beg_mem_dst_re, &x->x_size_dst_re, fftsize);
+ ok_dst_im = iem_tab_check_arrays(gensym("tab_ifft"), x->x_sym_dst_im, &x->x_beg_mem_dst_im, &x->x_size_dst_im, fftsize);
+
+ if(ok_src_re && ok_src_im && ok_dst_re && ok_dst_im)
+ {
+ t_garray *a;
+
+ vec_src_re=x->x_beg_mem_src_re + beg_src_re;
+ vec_src_im=x->x_beg_mem_src_im + beg_src_im;
+ vec_dst_re=x->x_beg_mem_dst_re + beg_dst_re;
+ vec_dst_im=x->x_beg_mem_dst_im + beg_dst_im;
+
+ for(j=0; j<fftsize; j++)
+ {
+ vec_dst_re[j] = vec_src_re[j];
+ vec_dst_im[j] = vec_src_im[j];
+ }
+
+ i_inc = fs2;
+ w_inc = 1;
+ for(i=1; i<fftsize; i<<=1)
+ {
+ v_index = 0;
+ for(j=0; j<i; j++)
+ {
+ w_index = 0;
+ for(k=0; k<i_inc; k++)
+ {
+ old1_re = vec_dst_re[v_index];
+ old1_im = vec_dst_im[v_index];
+ old2_re = vec_dst_re[v_index+i_inc];
+ old2_im = vec_dst_im[v_index+i_inc];
+ w = sincos[w_index];
+ vec_dst_re[v_index+i_inc] = (old1_re - old2_re)*w.real - (old1_im - old2_im)*w.imag;
+ vec_dst_im[v_index+i_inc] = (old1_im - old2_im)*w.real + (old1_re - old2_re)*w.imag;
+ vec_dst_re[v_index] = old1_re + old2_re;
+ vec_dst_im[v_index] = old1_im + old2_im;
+ w_index += w_inc;
+ v_index++;
+ }
+ v_index += i_inc;
+ }
+ w_inc <<= 1;
+ i_inc >>= 1;
+ }
+
+ j = 0;
+ for(i=1;i<fs1;i++)
+ {
+ k = fs2;
+ while(k <= j)
+ {
+ j = j - k;
+ k >>= 1;
+ }
+ j = j + k;
+ if(i < j)
+ {
+ old1_re = vec_dst_re[j];
+ old1_im = vec_dst_im[j];
+ vec_dst_re[j] = vec_dst_re[i];
+ vec_dst_im[j] = vec_dst_im[i];
+ vec_dst_re[i] = old1_re;
+ vec_dst_im[i] = old1_im;
+ }
+ }
+
+// g = 2.0f / (float)fftsize;
+/*
+ ein fehler tritt auf beim 0.sample, hier sollte nur mal 1.0 multipliziert werden
+ wenn gelten soll : Energie im zeitfenster == Energie im Frequenz-dichte-fenster
+
+ g = 1.0f;
+ for(i = 0; i < fs2; i++)
+ {
+ vec_dst_re[i] *= g;
+ vec_dst_im[i] *= g;
+ }
+ */
+
+ g = 1.0f / (float)fftsize;
+ for(i = 0; i < fftsize; i++)
+ {
+ vec_dst_re[i] *= g;
+ vec_dst_im[i] *= g;
+ }
+
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_re, garray_class);
+ garray_redraw(a);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_im, garray_class);
+ garray_redraw(a);
+ }
+ }
+ else
+ {
+ post("tab_ifft-ERROR: list need 4 float arguments:");
+ post(" source_real_offset + source_imag_offset + destination_real_offset + destination_imag_offset");
+ }
+}
+
+static void tab_ifft_free(t_tab_ifft *x)
+{
+ freebytes(x->x_sin_cos, x->x_fftsize * sizeof(TAB_COMPLEX));
+}
+
+static void *tab_ifft_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_ifft *x = (t_tab_ifft *)pd_new(tab_ifft_class);
+ t_symbol *src_re, *src_im, *dst_re, *dst_im;
+ int fftsize, i=1;
+
+ if((argc >= 5) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2) &&
+ IS_A_SYMBOL(argv,3) &&
+ IS_A_FLOAT(argv,4))
+ {
+ src_re = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src_im = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst_re = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ dst_im = (t_symbol *)atom_getsymbolarg(3, argc, argv);
+ fftsize = (int)atom_getintarg(4, argc, argv);
+ }
+ else
+ {
+ post("tab_ifft-ERROR: need 4 symbols + 1 float arguments:");
+ post(" source_real_array_name + source_imag_array_name + destination_real_array_name + destination_imag_array_name + IFFT-size");
+ return(0);
+ }
+
+ if(fftsize < 8)
+ fftsize = 8;
+
+ while(i <= fftsize)
+ i *= 2;
+ i /= 2;
+ fftsize = i;
+
+ x->x_fftsize = fftsize;
+ x->x_sym_src_re = src_re;
+ x->x_sym_src_im = src_im;
+ x->x_sym_dst_re = dst_re;
+ x->x_sym_dst_im = dst_im;
+ x->x_sin_cos = (TAB_COMPLEX *)getbytes(x->x_fftsize * sizeof(TAB_COMPLEX));
+ tab_ifft_init(x);
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_ifft_setup(void)
+{
+ tab_ifft_class = class_new(gensym("tab_ifft"), (t_newmethod)tab_ifft_new, (t_method)tab_ifft_free,
+ sizeof(t_tab_ifft), 0, A_GIMME, 0);
+ class_addbang(tab_ifft_class, (t_method)tab_ifft_bang);
+ class_addlist(tab_ifft_class, (t_method)tab_ifft_list);
+ class_addmethod(tab_ifft_class, (t_method)tab_ifft_ifftsize, gensym("ifftsize"), A_DEFFLOAT, 0);
+ class_addmethod(tab_ifft_class, (t_method)tab_ifft_src_re, gensym("src_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ifft_class, (t_method)tab_ifft_src_im, gensym("src_im"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ifft_class, (t_method)tab_ifft_src_re, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ifft_class, (t_method)tab_ifft_src_im, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ifft_class, (t_method)tab_ifft_dst_re, gensym("dst_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ifft_class, (t_method)tab_ifft_dst_im, gensym("dst_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ifft_class, (t_method)tab_ifft_dst_re, gensym("dst1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ifft_class, (t_method)tab_ifft_dst_im, gensym("dst2"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_ifft_class, gensym("iemhelp2/tab_ifft-help"));
+}
diff --git a/src/tab_le.c b/src/tab_le.c
new file mode 100644
index 0000000..c919412
--- /dev/null
+++ b/src/tab_le.c
@@ -0,0 +1,206 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_le ------------------------------ */
+
+typedef struct _tab_le
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_le;
+
+static t_class *tab_le_class;
+
+static void tab_le_src1(t_tab_le *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_le_src2(t_tab_le *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_le_dst(t_tab_le *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_le_bang(t_tab_le *x)
+{
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_le"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_le"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_le"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ n = x->x_size_src2;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] <= vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_le_list(t_tab_le *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n = (int)atom_getintarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_le"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_le"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_le"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] <= vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_le-ERROR: list need 4 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_compare");
+ }
+}
+
+static void tab_le_free(t_tab_le *x)
+{
+}
+
+static void *tab_le_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_le *x = (t_tab_le *)pd_new(tab_le_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_le-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_le_setup(void)
+{
+ tab_le_class = class_new(gensym("tab_le"), (t_newmethod)tab_le_new, (t_method)tab_le_free,
+ sizeof(t_tab_le), 0, A_GIMME, 0);
+ class_addbang(tab_le_class, (t_method)tab_le_bang);
+ class_addlist(tab_le_class, (t_method)tab_le_list);
+ class_addmethod(tab_le_class, (t_method)tab_le_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_le_class, (t_method)tab_le_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_le_class, (t_method)tab_le_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_le_class, gensym("iemhelp2/tab_le-help"));
+}
diff --git a/src/tab_le_scalar.c b/src/tab_le_scalar.c
new file mode 100644
index 0000000..2226dbf
--- /dev/null
+++ b/src/tab_le_scalar.c
@@ -0,0 +1,183 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_le_scalar ------------------------------ */
+
+typedef struct _tab_le_scalar
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_le_scalar;
+
+static t_class *tab_le_scalar_class;
+
+static void tab_le_scalar_src(t_tab_le_scalar *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_le_scalar_float(t_tab_le_scalar *x, t_floatarg compare)
+{
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_le_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_le_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] <= compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_le_scalar_dst(t_tab_le_scalar *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_le_scalar_list(t_tab_le_scalar *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_dst;
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst, compare;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ compare = (t_float)atom_getfloatarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_le_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_le_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] <= compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_le_scalar-ERROR: list need 4 float arguments:");
+ post(" source1_offset + destination_offset + number_of_samples_to_compare + compare_scalar");
+ }
+}
+
+static void tab_le_scalar_free(t_tab_le_scalar *x)
+{
+}
+
+static void *tab_le_scalar_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_le_scalar *x = (t_tab_le_scalar *)pd_new(tab_le_scalar_class);
+ t_symbol *src1, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ }
+ else
+ {
+ post("tab_le_scalar-ERROR: need 2 symbol arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_le_scalar_setup(void)
+{
+ tab_le_scalar_class = class_new(gensym("tab_le_scalar"), (t_newmethod)tab_le_scalar_new, (t_method)tab_le_scalar_free,
+ sizeof(t_tab_le_scalar), 0, A_GIMME, 0);
+ class_addfloat(tab_le_scalar_class, (t_method)tab_le_scalar_float);
+ class_addlist(tab_le_scalar_class, (t_method)tab_le_scalar_list);
+ class_addmethod(tab_le_scalar_class, (t_method)tab_le_scalar_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_le_scalar_class, (t_method)tab_le_scalar_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_le_scalar_class, (t_method)tab_le_scalar_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_le_scalar_class, gensym("iemhelp2/tab_le_scalar-help"));
+}
diff --git a/src/tab_lt.c b/src/tab_lt.c
new file mode 100644
index 0000000..f3a4e6c
--- /dev/null
+++ b/src/tab_lt.c
@@ -0,0 +1,206 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_lt ------------------------------ */
+
+typedef struct _tab_lt
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_lt;
+
+static t_class *tab_lt_class;
+
+static void tab_lt_src1(t_tab_lt *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_lt_src2(t_tab_lt *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_lt_dst(t_tab_lt *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_lt_bang(t_tab_lt *x)
+{
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_lt"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_lt"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_lt"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ n = x->x_size_src2;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] < vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_lt_list(t_tab_lt *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n = (int)atom_getintarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_lt"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_lt"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_lt"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] < vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_lt-ERROR: list need 4 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_compare");
+ }
+}
+
+static void tab_lt_free(t_tab_lt *x)
+{
+}
+
+static void *tab_lt_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_lt *x = (t_tab_lt *)pd_new(tab_lt_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_lt-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_lt_setup(void)
+{
+ tab_lt_class = class_new(gensym("tab_lt"), (t_newmethod)tab_lt_new, (t_method)tab_lt_free,
+ sizeof(t_tab_lt), 0, A_GIMME, 0);
+ class_addbang(tab_lt_class, (t_method)tab_lt_bang);
+ class_addlist(tab_lt_class, (t_method)tab_lt_list);
+ class_addmethod(tab_lt_class, (t_method)tab_lt_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_lt_class, (t_method)tab_lt_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_lt_class, (t_method)tab_lt_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_lt_class, gensym("iemhelp2/tab_lt-help"));
+}
diff --git a/src/tab_lt_scalar.c b/src/tab_lt_scalar.c
new file mode 100644
index 0000000..e65b427
--- /dev/null
+++ b/src/tab_lt_scalar.c
@@ -0,0 +1,183 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_lt_scalar ------------------------------ */
+
+typedef struct _tab_lt_scalar
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_lt_scalar;
+
+static t_class *tab_lt_scalar_class;
+
+static void tab_lt_scalar_src(t_tab_lt_scalar *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_lt_scalar_float(t_tab_lt_scalar *x, t_floatarg compare)
+{
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_lt_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_lt_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] < compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_lt_scalar_dst(t_tab_lt_scalar *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_lt_scalar_list(t_tab_lt_scalar *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_dst;
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst, compare;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ compare = (t_float)atom_getfloatarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_lt_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_lt_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] < compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_lt_scalar-ERROR: list need 4 float arguments:");
+ post(" source1_offset + destination_offset + number_of_samples_to_compare + compare_scalar");
+ }
+}
+
+static void tab_lt_scalar_free(t_tab_lt_scalar *x)
+{
+}
+
+static void *tab_lt_scalar_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_lt_scalar *x = (t_tab_lt_scalar *)pd_new(tab_lt_scalar_class);
+ t_symbol *src1, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ }
+ else
+ {
+ post("tab_lt_scalar-ERROR: need 2 symbol arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_lt_scalar_setup(void)
+{
+ tab_lt_scalar_class = class_new(gensym("tab_lt_scalar"), (t_newmethod)tab_lt_scalar_new, (t_method)tab_lt_scalar_free,
+ sizeof(t_tab_lt_scalar), 0, A_GIMME, 0);
+ class_addfloat(tab_lt_scalar_class, (t_method)tab_lt_scalar_float);
+ class_addlist(tab_lt_scalar_class, (t_method)tab_lt_scalar_list);
+ class_addmethod(tab_lt_scalar_class, (t_method)tab_lt_scalar_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_lt_scalar_class, (t_method)tab_lt_scalar_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_lt_scalar_class, (t_method)tab_lt_scalar_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_lt_scalar_class, gensym("iemhelp2/tab_lt_scalar-help"));
+}
diff --git a/src/tab_max_index.c b/src/tab_max_index.c
new file mode 100644
index 0000000..d8e9bd9
--- /dev/null
+++ b/src/tab_max_index.c
@@ -0,0 +1,155 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_max_index ------------------------------ */
+
+typedef struct _tab_max_index
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_offset_src1;
+ float *x_beg_mem_src1;
+ t_symbol *x_sym_scr1;
+ void *x_bang_out;
+ void *x_max_out;
+ void *x_max_index_out;
+} t_tab_max_index;
+
+static t_class *tab_max_index_class;
+
+static void tab_max_index_src(t_tab_max_index *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_max_index_bang(t_tab_max_index *x)
+{
+ int i, n;
+ int ok_src, max_index=0;
+ t_float *vec_src;
+ t_float max=-1.0e37;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_max_index"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+
+ if(ok_src)
+ {
+ n = x->x_size_src1;
+ vec_src = x->x_beg_mem_src1;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ if(vec_src[i] > max)
+ {
+ max = vec_src[i];
+ max_index = i;
+ }
+ }
+ outlet_float(x->x_max_out, max);
+ outlet_float(x->x_max_index_out, (float)max_index);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+}
+
+static void tab_max_index_list(t_tab_max_index *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src;
+ int i, n;
+ int ok_src, max_index=0;
+ t_float *vec_src;
+ t_float max=-1.0e37;
+
+ if((argc >= 2) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ n = (int)atom_getintarg(1, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_max_index"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+
+ if(ok_src)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ if(vec_src[i] > max)
+ {
+ max = vec_src[i];
+ max_index = i + beg_src;
+ }
+ }
+ outlet_float(x->x_max_out, max);
+ outlet_float(x->x_max_index_out, (float)max_index);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+ }
+ else
+ {
+ post("tab_max_index-ERROR: list need 2 float arguments:");
+ post(" source_offset + number_of_samples_to_calc_max_index");
+ }
+}
+
+static void tab_max_index_free(t_tab_max_index *x)
+{
+}
+
+static void *tab_max_index_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_max_index *x = (t_tab_max_index *)pd_new(tab_max_index_class);
+ t_symbol *src;
+
+ if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ }
+ else
+ {
+ post("tab_max_index-ERROR: need 1 symbol argument:");
+ post(" source_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src;
+ x->x_bang_out = outlet_new(&x->x_obj, &s_bang);
+ x->x_max_index_out = outlet_new(&x->x_obj, &s_float);
+ x->x_max_out = outlet_new(&x->x_obj, &s_float);
+ return(x);
+}
+
+void tab_max_index_setup(void)
+{
+ tab_max_index_class = class_new(gensym("tab_max_index"), (t_newmethod)tab_max_index_new, (t_method)tab_max_index_free,
+ sizeof(t_tab_max_index), 0, A_GIMME, 0);
+ class_addbang(tab_max_index_class, (t_method)tab_max_index_bang);
+ class_addlist(tab_max_index_class, (t_method)tab_max_index_list);
+ class_addmethod(tab_max_index_class, (t_method)tab_max_index_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_max_index_class, (t_method)tab_max_index_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_max_index_class, gensym("iemhelp2/tab_max_index-help"));
+}
diff --git a/src/tab_mean.c b/src/tab_mean.c
new file mode 100644
index 0000000..9cb8b66
--- /dev/null
+++ b/src/tab_mean.c
@@ -0,0 +1,143 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_mean ------------------------------ */
+
+typedef struct _tab_mean
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_offset_src1;
+ float *x_beg_mem_src1;
+ t_symbol *x_sym_scr1;
+ void *x_bang_out;
+ void *x_mean_out;
+} t_tab_mean;
+
+static t_class *tab_mean_class;
+
+static void tab_mean_src(t_tab_mean *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_mean_bang(t_tab_mean *x)
+{
+ int i, n;
+ int ok_src;
+ t_float *vec_src;
+ t_float mean=0.0f;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_mean"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+
+ if(ok_src)
+ {
+ n = x->x_size_src1;
+ vec_src = x->x_beg_mem_src1;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ mean += vec_src[i];
+ }
+ outlet_float(x->x_mean_out, mean);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+}
+
+static void tab_mean_list(t_tab_mean *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src;
+ int i, n;
+ int ok_src;
+ t_float *vec_src;
+ t_float mean=0.0f;
+
+ if((argc >= 2) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ n = (int)atom_getintarg(1, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_mean"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+
+ if(ok_src)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ mean += vec_src[i];
+ }
+ outlet_float(x->x_mean_out, mean);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+ }
+ else
+ {
+ post("tab_mean-ERROR: list need 2 float arguments:");
+ post(" source_offset + number_of_samples_to_calc_mean-value");
+ }
+}
+
+static void tab_mean_free(t_tab_mean *x)
+{
+}
+
+static void *tab_mean_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_mean *x = (t_tab_mean *)pd_new(tab_mean_class);
+ t_symbol *src;
+
+ if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ }
+ else
+ {
+ post("tab_mean-ERROR: need 1 symbol argument:");
+ post(" source_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src;
+ x->x_bang_out = outlet_new(&x->x_obj, &s_bang);
+ x->x_mean_out = outlet_new(&x->x_obj, &s_float);
+ return(x);
+}
+
+void tab_mean_setup(void)
+{
+ tab_mean_class = class_new(gensym("tab_mean"), (t_newmethod)tab_mean_new, (t_method)tab_mean_free,
+ sizeof(t_tab_mean), 0, A_GIMME, 0);
+ class_addbang(tab_mean_class, (t_method)tab_mean_bang);
+ class_addlist(tab_mean_class, (t_method)tab_mean_list);
+ class_addmethod(tab_mean_class, (t_method)tab_mean_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_mean_class, (t_method)tab_mean_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_mean_class, gensym("iemhelp2/tab_mean-help"));
+}
diff --git a/src/tab_min_index.c b/src/tab_min_index.c
new file mode 100644
index 0000000..eeb47e5
--- /dev/null
+++ b/src/tab_min_index.c
@@ -0,0 +1,155 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_min_index ------------------------------ */
+
+typedef struct _tab_min_index
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_offset_src1;
+ float *x_beg_mem_src1;
+ t_symbol *x_sym_scr1;
+ void *x_bang_out;
+ void *x_min_out;
+ void *x_min_index_out;
+} t_tab_min_index;
+
+static t_class *tab_min_index_class;
+
+static void tab_min_index_src(t_tab_min_index *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_min_index_bang(t_tab_min_index *x)
+{
+ int i, n;
+ int ok_src, min_index=0;
+ t_float *vec_src;
+ t_float min=1.0e37;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_min_index"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+
+ if(ok_src)
+ {
+ n = x->x_size_src1;
+ vec_src = x->x_beg_mem_src1;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ if(vec_src[i] < min)
+ {
+ min = vec_src[i];
+ min_index = i;
+ }
+ }
+ outlet_float(x->x_min_out, min);
+ outlet_float(x->x_min_index_out, (float)min_index);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+}
+
+static void tab_min_index_list(t_tab_min_index *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src;
+ int i, n;
+ int ok_src, min_index=0;
+ t_float *vec_src;
+ t_float min=1.0e37;
+
+ if((argc >= 2) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ n = (int)atom_getintarg(1, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_min_index"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+
+ if(ok_src)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ if(vec_src[i] < min)
+ {
+ min = vec_src[i];
+ min_index = i + beg_src;
+ }
+ }
+ outlet_float(x->x_min_out, min);
+ outlet_float(x->x_min_index_out, (float)min_index);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+ }
+ else
+ {
+ post("tab_min_index-ERROR: list need 2 float arguments:");
+ post(" source_offset + number_of_samples_to_calc_min_index");
+ }
+}
+
+static void tab_min_index_free(t_tab_min_index *x)
+{
+}
+
+static void *tab_min_index_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_min_index *x = (t_tab_min_index *)pd_new(tab_min_index_class);
+ t_symbol *src;
+
+ if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ }
+ else
+ {
+ post("tab_min_index-ERROR: need 1 symbol argument:");
+ post(" source_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src;
+ x->x_bang_out = outlet_new(&x->x_obj, &s_bang);
+ x->x_min_index_out = outlet_new(&x->x_obj, &s_float);
+ x->x_min_out = outlet_new(&x->x_obj, &s_float);
+ return(x);
+}
+
+void tab_min_index_setup(void)
+{
+ tab_min_index_class = class_new(gensym("tab_min_index"), (t_newmethod)tab_min_index_new, (t_method)tab_min_index_free,
+ sizeof(t_tab_min_index), 0, A_GIMME, 0);
+ class_addbang(tab_min_index_class, (t_method)tab_min_index_bang);
+ class_addlist(tab_min_index_class, (t_method)tab_min_index_list);
+ class_addmethod(tab_min_index_class, (t_method)tab_min_index_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_min_index_class, (t_method)tab_min_index_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_min_index_class, gensym("iemhelp2/tab_min_index-help"));
+}
diff --git a/src/tab_min_max.c b/src/tab_min_max.c
new file mode 100644
index 0000000..38657d6
--- /dev/null
+++ b/src/tab_min_max.c
@@ -0,0 +1,153 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_min_max ------------------------------ */
+
+typedef struct _tab_min_max
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_offset_src1;
+ float *x_beg_mem_src1;
+ t_symbol *x_sym_scr1;
+ void *x_bang_out;
+ void *x_min_out;
+ void *x_max_out;
+} t_tab_min_max;
+
+static t_class *tab_min_max_class;
+
+static void tab_min_max_src(t_tab_min_max *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_min_max_bang(t_tab_min_max *x)
+{
+ int i, n;
+ int ok_src;
+ t_float *vec_src;
+ t_float min=1.0e37, max=-1.0e37;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_min_max"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+
+ if(ok_src)
+ {
+ n = x->x_size_src1;
+ vec_src = x->x_beg_mem_src1;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ if(vec_src[i] > max)
+ max = vec_src[i];
+ if(vec_src[i] < min)
+ min = vec_src[i];
+ }
+ outlet_float(x->x_max_out, max);
+ outlet_float(x->x_min_out, min);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+}
+
+static void tab_min_max_list(t_tab_min_max *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src;
+ int i, n;
+ int ok_src;
+ t_float *vec_src;
+ t_float min=1.0e37, max=-1.0e37;
+
+ if((argc >= 2) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ n = (int)atom_getintarg(1, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_min_max"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+
+ if(ok_src)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ if(vec_src[i] > max)
+ max = vec_src[i];
+ if(vec_src[i] < min)
+ min = vec_src[i];
+ }
+ outlet_float(x->x_max_out, max);
+ outlet_float(x->x_min_out, min);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+ }
+ else
+ {
+ post("tab_min_max-ERROR: list need 2 float arguments:");
+ post(" source_offset + number_of_samples_to_calc_min_max");
+ }
+}
+
+static void tab_min_max_free(t_tab_min_max *x)
+{
+}
+
+static void *tab_min_max_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_min_max *x = (t_tab_min_max *)pd_new(tab_min_max_class);
+ t_symbol *src;
+
+ if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ }
+ else
+ {
+ post("tab_min_max-ERROR: need 1 symbol argument:");
+ post(" source_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src;
+ x->x_bang_out = outlet_new(&x->x_obj, &s_bang);
+ x->x_min_out = outlet_new(&x->x_obj, &s_float);
+ x->x_max_out = outlet_new(&x->x_obj, &s_float);
+ return(x);
+}
+
+void tab_min_max_setup(void)
+{
+ tab_min_max_class = class_new(gensym("tab_min_max"), (t_newmethod)tab_min_max_new, (t_method)tab_min_max_free,
+ sizeof(t_tab_min_max), 0, A_GIMME, 0);
+ class_addbang(tab_min_max_class, (t_method)tab_min_max_bang);
+ class_addlist(tab_min_max_class, (t_method)tab_min_max_list);
+ class_addmethod(tab_min_max_class, (t_method)tab_min_max_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_min_max_class, (t_method)tab_min_max_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_min_max_class, gensym("iemhelp2/tab_min_max-help"));
+}
diff --git a/src/tab_mls.c b/src/tab_mls.c
new file mode 100644
index 0000000..308cc6c
--- /dev/null
+++ b/src/tab_mls.c
@@ -0,0 +1,256 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_mls ------------------------------ */
+
+typedef struct _tab_mls
+{
+ t_object x_obj;
+ int x_size_dst;
+ int x_offset_dst;
+ t_float *x_beg_mem_dst;
+ t_symbol *x_sym_dst;
+} t_tab_mls;
+
+static t_class *tab_mls_class;
+
+static int tab_mls_exp2(int mls_order)
+{
+ int i, j=1;
+
+ for(i=0; i<mls_order; i++)
+ j *= 2;
+ return(j);
+}
+
+static void tab_mls_calc(t_float *vec, int mls_order)
+{
+ int i, j;
+ int work1=1, work2, exor;
+ int mask, source, mls_size;
+
+ switch(mls_order)
+ {
+ case 3:
+ mask = 2+1;
+ source = 4;
+ break;
+ case 4:
+ mask = 2+1;
+ source = 8;
+ break;
+ case 5:
+ mask = 4+1;
+ source = 16;
+ break;
+ case 6:
+ mask = 2+1;
+ source = 32;
+ break;
+ case 7:
+ mask = 8+1;
+ source = 64;
+ break;
+ case 8:
+ mask = 32+8+2+1;
+ source = 128;
+ break;
+ case 9:
+ mask = 16+1;
+ source = 256;
+ break;
+ case 10:
+ mask = 8+1;
+ source = 512;
+ break;
+ case 11:
+ mask = 4+1;
+ source = 1024;
+ break;
+ case 12:
+ mask = 64+16+2+1;
+ source = 2048;
+ break;
+ case 13:
+ mask = 256+128+8+1;
+ source = 4096;
+ break;
+ case 14:
+ mask = 1024+64+2+1;
+ source = 8192;
+ break;
+ case 15:
+ mask = 2+1;
+ source = 16384;
+ break;
+ case 16:
+ mask = 32+8+4+1;
+ source = 32768;
+ break;
+ case 17:
+ mask = 8+1;
+ source = 65536;
+ break;
+ case 18:
+ mask = 128+1;
+ source = 131072;
+ break;
+ case 19:
+ mask = 32+4+2+1;
+ source = 262144;
+ break;
+ case 20:
+ mask = 8+1;
+ source = 524288;
+ break;
+ }
+
+ mls_size = 2*source - 1;
+
+ for(i=0; i<mls_size; i++)
+ {
+ i = work1 & mask;
+ work2 = work1 >> 1;
+ exor = 0;
+ for(j=0; j<lms_order; j++)
+ {
+ exor += & 1;
+ work1 >>= 1;
+ }
+ if(exor & 1)
+ {
+ vec[i] = 1.0f;
+ work1 = work2 | source;
+ }
+ else
+ {
+ vec[i] = -1.0f;
+ work1 = work2;
+ }
+ }
+ return;
+}
+
+static void tab_mls_dst(t_tab_mls *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_mls_float(t_tab_mls *x, t_floatarg fmls_order)
+{
+ int mls_order=(int)fmls_order;
+ int ok_dst, mls_size;
+
+ mls_size = tab_mls_exp2(mls_order) - 1;
+ ok_dst = iem_tab_check_arrays(gensym("tab_mls"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, mls_size);
+
+ if(ok_dst)
+ {
+ if((mls_order >= 3) && (mls_order <= 20))
+ {
+ t_garray *a;
+
+ tab_mls_calc(x->x_beg_mem_dst, mls_order);
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_mls_list(t_tab_mls *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_dst;
+ int i, n;
+ int ok_dst;
+ t_float *vec_dst, c;
+
+ if((argc >= 3) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2))
+ {
+ beg_dst = (int)atom_getintarg(0, argc, argv);
+ n = (int)atom_getintarg(1, argc, argv);
+ c = (t_float)atom_getfloatarg(2, argc, argv);
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_dst = iem_tab_check_arrays(gensym("tab_mls"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_dst)
+ {
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = c;
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_mls-ERROR: list need 3 float arguments:");
+ post(" destination_offset + number_of_samples_to_copy + constant-value");
+ }
+}
+
+static void tab_mls_free(t_tab_mls *x)
+{
+}
+
+static void *tab_mls_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_mls *x = (t_tab_mls *)pd_new(tab_mls_class);
+ t_symbol *dst;
+ t_float time;
+
+ if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ dst = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ }
+ else
+ {
+ post("tab_mls-ERROR: need 1 symbol argument:");
+ post(" destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_mls_setup(void)
+{
+ tab_mls_class = class_new(gensym("tab_mls"), (t_newmethod)tab_mls_new, (t_method)tab_mls_free,
+ sizeof(t_tab_mls), 0, A_GIMME, 0);
+ class_addfloat(tab_mls_class, (t_method)tab_mls_float);
+ class_addlist(tab_mls_class, (t_method)tab_mls_list);
+ class_addmethod(tab_mls_class, (t_method)tab_mls_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_mls_class, gensym("iemhelp2/tab_mls-help"));
+}
diff --git a/src/tab_mul.c b/src/tab_mul.c
new file mode 100644
index 0000000..8f24b08
--- /dev/null
+++ b/src/tab_mul.c
@@ -0,0 +1,196 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_mul ------------------------------ */
+
+typedef struct _tab_mul
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_mul;
+
+static t_class *tab_mul_class;
+
+static void tab_mul_src1(t_tab_mul *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_mul_src2(t_tab_mul *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_mul_dst(t_tab_mul *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_mul_bang(t_tab_mul *x)
+{
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_mul"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_mul"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_mul"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ n = x->x_size_src2;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src1[i]*vec_src2[i];
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_mul_list(t_tab_mul *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n = (int)atom_getintarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_mul"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_mul"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_mul"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src1[i]*vec_src2[i];
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_mul-ERROR: list need 4 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_mul");
+ }
+}
+
+static void tab_mul_free(t_tab_mul *x)
+{
+}
+
+static void *tab_mul_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_mul *x = (t_tab_mul *)pd_new(tab_mul_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_mul-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_mul_setup(void)
+{
+ tab_mul_class = class_new(gensym("tab_mul"), (t_newmethod)tab_mul_new, (t_method)tab_mul_free,
+ sizeof(t_tab_mul), 0, A_GIMME, 0);
+ class_addbang(tab_mul_class, (t_method)tab_mul_bang);
+ class_addlist(tab_mul_class, (t_method)tab_mul_list);
+ class_addmethod(tab_mul_class, (t_method)tab_mul_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_mul_class, (t_method)tab_mul_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_mul_class, (t_method)tab_mul_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_mul_class, gensym("iemhelp2/tab_mul-help"));
+}
diff --git a/src/tab_mul_scalar.c b/src/tab_mul_scalar.c
new file mode 100644
index 0000000..01f6a39
--- /dev/null
+++ b/src/tab_mul_scalar.c
@@ -0,0 +1,173 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_mul_scalar ------------------------------ */
+
+typedef struct _tab_mul_scalar
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_mul_scalar;
+
+static t_class *tab_mul_scalar_class;
+
+static void tab_mul_scalar_src(t_tab_mul_scalar *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_mul_scalar_float(t_tab_mul_scalar *x, t_floatarg m)
+{
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_mul_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_mul_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src1[i]*m;
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_mul_scalar_dst(t_tab_mul_scalar *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_mul_scalar_list(t_tab_mul_scalar *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_dst;
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst, m;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ m = (t_float)atom_getfloatarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_mul_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_mul_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src1[i]*m;
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_mul_scalar-ERROR: list need 4 float arguments:");
+ post(" source1_offset + destination_offset + number_of_samples_to_mul + mul_scalar");
+ }
+}
+
+static void tab_mul_scalar_free(t_tab_mul_scalar *x)
+{
+}
+
+static void *tab_mul_scalar_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_mul_scalar *x = (t_tab_mul_scalar *)pd_new(tab_mul_scalar_class);
+ t_symbol *src1, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ }
+ else
+ {
+ post("tab_mul_scalar-ERROR: need 2 symbol arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_mul_scalar_setup(void)
+{
+ tab_mul_scalar_class = class_new(gensym("tab_mul_scalar"), (t_newmethod)tab_mul_scalar_new, (t_method)tab_mul_scalar_free,
+ sizeof(t_tab_mul_scalar), 0, A_GIMME, 0);
+ class_addfloat(tab_mul_scalar_class, (t_method)tab_mul_scalar_float);
+ class_addlist(tab_mul_scalar_class, (t_method)tab_mul_scalar_list);
+ class_addmethod(tab_mul_scalar_class, (t_method)tab_mul_scalar_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_mul_scalar_class, (t_method)tab_mul_scalar_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_mul_scalar_class, (t_method)tab_mul_scalar_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_mul_scalar_class, gensym("iemhelp2/tab_mul_scalar-help"));
+}
diff --git a/src/tab_ne.c b/src/tab_ne.c
new file mode 100644
index 0000000..e90519f
--- /dev/null
+++ b/src/tab_ne.c
@@ -0,0 +1,206 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_ne ------------------------------ */
+
+typedef struct _tab_ne
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_ne;
+
+static t_class *tab_ne_class;
+
+static void tab_ne_src1(t_tab_ne *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_ne_src2(t_tab_ne *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_ne_dst(t_tab_ne *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_ne_bang(t_tab_ne *x)
+{
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_ne"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_ne"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_ne"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ n = x->x_size_src2;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] != vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_ne_list(t_tab_ne *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n = (int)atom_getintarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_ne"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_ne"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_ne"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] != vec_src2[i])
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_ne-ERROR: list need 4 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_compare");
+ }
+}
+
+static void tab_ne_free(t_tab_ne *x)
+{
+}
+
+static void *tab_ne_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_ne *x = (t_tab_ne *)pd_new(tab_ne_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_ne-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_ne_setup(void)
+{
+ tab_ne_class = class_new(gensym("tab_ne"), (t_newmethod)tab_ne_new, (t_method)tab_ne_free,
+ sizeof(t_tab_ne), 0, A_GIMME, 0);
+ class_addbang(tab_ne_class, (t_method)tab_ne_bang);
+ class_addlist(tab_ne_class, (t_method)tab_ne_list);
+ class_addmethod(tab_ne_class, (t_method)tab_ne_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ne_class, (t_method)tab_ne_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ne_class, (t_method)tab_ne_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_ne_class, gensym("iemhelp2/tab_ne-help"));
+}
diff --git a/src/tab_ne_scalar.c b/src/tab_ne_scalar.c
new file mode 100644
index 0000000..f2f0dca
--- /dev/null
+++ b/src/tab_ne_scalar.c
@@ -0,0 +1,183 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_ne_scalar ------------------------------ */
+
+typedef struct _tab_ne_scalar
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_ne_scalar;
+
+static t_class *tab_ne_scalar_class;
+
+static void tab_ne_scalar_src(t_tab_ne_scalar *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_ne_scalar_float(t_tab_ne_scalar *x, t_floatarg compare)
+{
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_ne_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_ne_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] != compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_ne_scalar_dst(t_tab_ne_scalar *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_ne_scalar_list(t_tab_ne_scalar *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_dst;
+ int i, n;
+ int ok_src1, ok_dst;
+ t_float *vec_src1, *vec_dst, compare;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ compare = (t_float)atom_getfloatarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_ne_scalar"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_ne_scalar"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ {
+ if(vec_src1[i] != compare)
+ vec_dst[i] = 1.0f;
+ else
+ vec_dst[i] = 0.0f;
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_ne_scalar-ERROR: list need 4 float arguments:");
+ post(" source1_offset + destination_offset + number_of_samples_to_compare + compare_scalar");
+ }
+}
+
+static void tab_ne_scalar_free(t_tab_ne_scalar *x)
+{
+}
+
+static void *tab_ne_scalar_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_ne_scalar *x = (t_tab_ne_scalar *)pd_new(tab_ne_scalar_class);
+ t_symbol *src1, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ }
+ else
+ {
+ post("tab_ne_scalar-ERROR: need 2 symbol arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_ne_scalar_setup(void)
+{
+ tab_ne_scalar_class = class_new(gensym("tab_ne_scalar"), (t_newmethod)tab_ne_scalar_new, (t_method)tab_ne_scalar_free,
+ sizeof(t_tab_ne_scalar), 0, A_GIMME, 0);
+ class_addfloat(tab_ne_scalar_class, (t_method)tab_ne_scalar_float);
+ class_addlist(tab_ne_scalar_class, (t_method)tab_ne_scalar_list);
+ class_addmethod(tab_ne_scalar_class, (t_method)tab_ne_scalar_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ne_scalar_class, (t_method)tab_ne_scalar_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_ne_scalar_class, (t_method)tab_ne_scalar_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_ne_scalar_class, gensym("iemhelp2/tab_ne_scalar-help"));
+}
diff --git a/src/tab_reverse.c b/src/tab_reverse.c
new file mode 100644
index 0000000..bd4769b
--- /dev/null
+++ b/src/tab_reverse.c
@@ -0,0 +1,170 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_reverse ------------------------------ */
+
+typedef struct _tab_reverse
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_reverse;
+
+static t_class *tab_reverse_class;
+
+static void tab_reverse_src(t_tab_reverse *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_reverse_dst(t_tab_reverse *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_reverse_bang(t_tab_reverse *x)
+{
+ int i, j, n;
+ int ok_src, ok_dst;
+ t_float *vec_src, *vec_dst;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_reverse"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_reverse"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src && ok_dst)
+ {
+ if(x->x_size_src1 > x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ vec_src = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0, j=n-1; i<n; i++, j--)
+ vec_dst[i] = vec_src[j];
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_reverse_list(t_tab_reverse *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src, beg_dst;
+ int i, j, n;
+ int ok_src, ok_dst;
+ t_float *vec_src, *vec_dst;
+
+ if((argc >= 3) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_reverse"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_reverse"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src && ok_dst)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0, j=n-1; i<n; i++, j--)
+ vec_dst[i] = vec_src[j];
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_reverse-ERROR: list need 3 float arguments:");
+ post(" source_offset + destination_offset + number_of_samples_to_copy");
+ }
+}
+
+static void tab_reverse_free(t_tab_reverse *x)
+{
+}
+
+static void *tab_reverse_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_reverse *x = (t_tab_reverse *)pd_new(tab_reverse_class);
+ t_symbol *src, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src;
+ }
+ else
+ {
+ post("tab_reverse-ERROR: need 2 symbols arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_reverse_setup(void)
+{
+ tab_reverse_class = class_new(gensym("tab_reverse"), (t_newmethod)tab_reverse_new, (t_method)tab_reverse_free,
+ sizeof(t_tab_reverse), 0, A_GIMME, 0);
+ class_addbang(tab_reverse_class, (t_method)tab_reverse_bang);
+ class_addlist(tab_reverse_class, (t_method)tab_reverse_list);
+ class_addmethod(tab_reverse_class, (t_method)tab_reverse_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_reverse_class, (t_method)tab_reverse_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_reverse_class, (t_method)tab_reverse_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_reverse_class, gensym("iemhelp2/tab_reverse-help"));
+}
diff --git a/src/tab_rfft.c b/src/tab_rfft.c
new file mode 100644
index 0000000..7e42623
--- /dev/null
+++ b/src/tab_rfft.c
@@ -0,0 +1,391 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_rfft ------------------------------ */
+
+typedef struct _tab_rfft
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst_re;
+ int x_size_dst_im;
+ int x_offset_src1;
+ int x_offset_dst_re;
+ int x_offset_dst_im;
+ int x_fftsize;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst_re;
+ float *x_beg_mem_dst_im;
+ TAB_COMPLEX *x_sin_cos;
+ t_symbol *x_sym_src1;
+ t_symbol *x_sym_dst_re;
+ t_symbol *x_sym_dst_im;
+} t_tab_rfft;
+
+static t_class *tab_rfft_class;
+
+static void tab_rfft_init(t_tab_rfft *x)
+{
+ int i, fftsize = x->x_fftsize;
+ float f, g;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+
+ g = 2.0f * 3.1415926538f / (float)fftsize;
+ for(i=0; i<fftsize; i++)
+ {
+ f = g * (float)i;
+ (*sincos).real = cos(f);
+ (*sincos).imag = -sin(f);/*FFT*/
+ sincos++;
+ }
+}
+
+static void tab_rfft_fftsize(t_tab_rfft *x, t_floatarg f)
+{
+ int i=1, fftsize = (int)f;
+
+ if(fftsize < 8)
+ fftsize = 8;
+
+ while(i <= fftsize)
+ i *= 2;
+ i /= 2;
+
+ if(i != x->x_fftsize)
+ {
+ x->x_sin_cos = (TAB_COMPLEX *)resizebytes(x->x_sin_cos, x->x_fftsize*sizeof(TAB_COMPLEX), i*sizeof(TAB_COMPLEX));
+ x->x_fftsize = i;
+ }
+ tab_rfft_init(x);
+}
+
+static void tab_rfft_src(t_tab_rfft *x, t_symbol *s)
+{
+ x->x_sym_src1 = s;
+}
+
+static void tab_rfft_dst_re(t_tab_rfft *x, t_symbol *s)
+{
+ x->x_sym_dst_re = s;
+}
+
+static void tab_rfft_dst_im(t_tab_rfft *x, t_symbol *s)
+{
+ x->x_sym_dst_im = s;
+}
+
+static void tab_rfft_bang(t_tab_rfft *x)
+{
+ int i, j, k;
+ int ok_src, ok_dst_re, ok_dst_im;
+ int w_index, w_inc, i_inc, v_index;
+ int fftsize = x->x_fftsize;
+ int fs1 = fftsize - 1;
+ int fs2 = fftsize / 2;
+ TAB_COMPLEX w;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+ t_float *vec_src, *vec_dst_re, *vec_dst_im;
+ t_float old1_re, old1_im, old2_re, old2_im;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_rfft"), x->x_sym_src1, &x->x_beg_mem_src1, &x->x_size_src1, fftsize);
+ ok_dst_re = iem_tab_check_arrays(gensym("tab_rfft"), x->x_sym_dst_re, &x->x_beg_mem_dst_re, &x->x_size_dst_re, fftsize);
+ ok_dst_im = iem_tab_check_arrays(gensym("tab_rfft"), x->x_sym_dst_im, &x->x_beg_mem_dst_im, &x->x_size_dst_im, fftsize);
+ if(ok_src && ok_dst_re && ok_dst_im)
+ {
+ t_garray *a;
+
+ vec_src=x->x_beg_mem_src1;
+ vec_dst_re=x->x_beg_mem_dst_re;
+ vec_dst_im=x->x_beg_mem_dst_im;
+
+ for(k=0; k<fftsize; k++)
+ {
+ vec_dst_re[k] = vec_src[k];
+ vec_dst_im[k] = 0.0f;
+ }
+
+ i_inc = fs2;
+ w_inc = 1;
+ for(i=1; i<fftsize; i<<=1)
+ {
+ v_index = 0;
+ for(j=0; j<i; j++)
+ {
+ w_index = 0;
+ for(k=0; k<i_inc; k++)
+ {
+ old1_re = vec_dst_re[v_index];
+ old1_im = vec_dst_im[v_index];
+ old2_re = vec_dst_re[v_index+i_inc];
+ old2_im = vec_dst_im[v_index+i_inc];
+ w = sincos[w_index];
+ vec_dst_re[v_index+i_inc] = (old1_re - old2_re)*w.real - (old1_im - old2_im)*w.imag;
+ vec_dst_im[v_index+i_inc] = (old1_im - old2_im)*w.real + (old1_re - old2_re)*w.imag;
+ vec_dst_re[v_index] = old1_re + old2_re;
+ vec_dst_im[v_index] = old1_im + old2_im;
+ w_index += w_inc;
+ v_index++;
+ }
+ v_index += i_inc;
+ }
+ w_inc <<= 1;
+ i_inc >>= 1;
+ }
+
+ j = 0;
+ for(i=1;i<fs1;i++)
+ {
+ k = fs2;
+ while(k <= j)
+ {
+ j = j - k;
+ k >>= 1;
+ }
+ j = j + k;
+ if(i < j)
+ {
+ old1_re = vec_dst_re[j];
+ old1_im = vec_dst_im[j];
+ vec_dst_re[j] = vec_dst_re[i];
+ vec_dst_im[j] = vec_dst_im[i];
+ vec_dst_re[i] = old1_re;
+ vec_dst_im[i] = old1_im;
+ }
+ }
+
+// g = 2.0f / (float)fftsize;
+/*
+ ein fehler tritt auf beim 0.sample, hier sollte nur mal 1.0 multipliziert werden
+ wenn gelten soll : Energie im zeitfenster == Energie im Frequenz-dichte-fenster
+
+ g = 1.0f;
+ for(i = 0; i < fs2; i++)
+ {
+ vec_dst_re[i] *= g;
+ vec_dst_im[i] *= g;
+ }
+ */
+
+ vec_dst_im[fs2] = 0.0f;
+ for(i = fs2+1; i < fftsize; i++)
+ {
+ vec_dst_re[i] = 0.0f;
+ vec_dst_im[i] = 0.0f;
+ }
+
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_re, garray_class);
+ garray_redraw(a);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_im, garray_class);
+ garray_redraw(a);
+ }
+}
+
+static void tab_rfft_list(t_tab_rfft *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src, beg_dst_re, beg_dst_im;
+ int i, j, k;
+ int ok_src, ok_dst_re, ok_dst_im;
+ int w_index, w_inc, i_inc, v_index;
+ int fftsize = x->x_fftsize;
+ int fs1 = fftsize - 1;
+ int fs2 = fftsize / 2;
+ TAB_COMPLEX w;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+ t_float *vec_src, *vec_dst_re, *vec_dst_im;
+ t_float old1_re, old1_im, old2_re, old2_im;
+
+ if((argc >= 3) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ beg_dst_re = (int)atom_getintarg(1, argc, argv);
+ beg_dst_im = (int)atom_getintarg(2, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(beg_dst_re < 0)
+ beg_dst_re = 0;
+ if(beg_dst_im < 0)
+ beg_dst_im = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_rfft"), x->x_sym_src1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+fftsize);
+ ok_dst_re = iem_tab_check_arrays(gensym("tab_rfft"), x->x_sym_dst_re, &x->x_beg_mem_dst_re, &x->x_size_dst_re, beg_dst_re+fftsize);
+ ok_dst_im = iem_tab_check_arrays(gensym("tab_rfft"), x->x_sym_dst_im, &x->x_beg_mem_dst_im, &x->x_size_dst_im, beg_dst_im+fftsize);
+
+ if(ok_src && ok_dst_re && ok_dst_im)
+ {
+ t_garray *a;
+
+ vec_src=x->x_beg_mem_src1 + beg_src;
+ vec_dst_re=x->x_beg_mem_dst_re + beg_dst_re;
+ vec_dst_im=x->x_beg_mem_dst_im + beg_dst_im;
+
+ for(k=0; k<fftsize; k++)
+ {
+ vec_dst_re[k] = vec_src[k];
+ vec_dst_im[k] = 0.0f;
+ }
+
+ i_inc = fs2;
+ w_inc = 1;
+ for(i=1; i<fftsize; i<<=1)
+ {
+ v_index = 0;
+ for(j=0; j<i; j++)
+ {
+ w_index = 0;
+ for(k=0; k<i_inc; k++)
+ {
+ old1_re = vec_dst_re[v_index];
+ old1_im = vec_dst_im[v_index];
+ old2_re = vec_dst_re[v_index+i_inc];
+ old2_im = vec_dst_im[v_index+i_inc];
+ w = sincos[w_index];
+ vec_dst_re[v_index+i_inc] = (old1_re - old2_re)*w.real - (old1_im - old2_im)*w.imag;
+ vec_dst_im[v_index+i_inc] = (old1_im - old2_im)*w.real + (old1_re - old2_re)*w.imag;
+ vec_dst_re[v_index] = old1_re + old2_re;
+ vec_dst_im[v_index] = old1_im + old2_im;
+ w_index += w_inc;
+ v_index++;
+ }
+ v_index += i_inc;
+ }
+ w_inc <<= 1;
+ i_inc >>= 1;
+ }
+
+ j = 0;
+ for(i=1;i<fs1;i++)
+ {
+ k = fs2;
+ while(k <= j)
+ {
+ j = j - k;
+ k >>= 1;
+ }
+ j = j + k;
+ if(i < j)
+ {
+ old1_re = vec_dst_re[j];
+ old1_im = vec_dst_im[j];
+ vec_dst_re[j] = vec_dst_re[i];
+ vec_dst_im[j] = vec_dst_im[i];
+ vec_dst_re[i] = old1_re;
+ vec_dst_im[i] = old1_im;
+ }
+ }
+
+// g = 2.0f / (float)fftsize;
+/*
+ ein fehler tritt auf beim 0.sample, hier sollte nur mal 1.0 multipliziert werden
+ wenn gelten soll : Energie im zeitfenster == Energie im Frequenz-dichte-fenster
+
+ g = 1.0f;
+ for(i = 0; i < fs2; i++)
+ {
+ vec_dst_re[i] *= g;
+ vec_dst_im[i] *= g;
+ }
+ */
+
+ vec_dst_im[fs2] = 0.0f;
+ for(i = fs2+1; i < fftsize; i++)
+ {
+ vec_dst_re[i] = 0.0f;
+ vec_dst_im[i] = 0.0f;
+ }
+
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_re, garray_class);
+ garray_redraw(a);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst_im, garray_class);
+ garray_redraw(a);
+ }
+ }
+ else
+ {
+ post("tab_rfft-ERROR: list need 3 float arguments:");
+ post(" source_offset + destination_real_offset + destination_imag_offset");
+ }
+}
+
+static void tab_rfft_free(t_tab_rfft *x)
+{
+ freebytes(x->x_sin_cos, x->x_fftsize * sizeof(TAB_COMPLEX));
+}
+
+static void *tab_rfft_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_rfft *x = (t_tab_rfft *)pd_new(tab_rfft_class);
+ t_symbol *src, *dst_re, *dst_im;
+ int fftsize, i=1;
+
+ if((argc >= 4) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst_re = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst_im = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ fftsize = (int)atom_getintarg(3, argc, argv);
+ }
+ else
+ {
+ post("tab_rfft-ERROR: need 3 symbols + 1 float arguments:");
+ post(" source_array_name + destination_real_array_name + destination_imag_array_name + FFT-size");
+ return(0);
+ }
+
+ if(fftsize < 8)
+ fftsize = 8;
+
+ while(i <= fftsize)
+ i *= 2;
+ i /= 2;
+ fftsize = i;
+
+ x->x_fftsize = fftsize;
+ x->x_sym_src1 = src;
+ x->x_sym_dst_re = dst_re;
+ x->x_sym_dst_im = dst_im;
+ x->x_sin_cos = (TAB_COMPLEX *)getbytes(x->x_fftsize * sizeof(TAB_COMPLEX));
+ tab_rfft_init(x);
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_rfft_setup(void)
+{
+ tab_rfft_class = class_new(gensym("tab_rfft"), (t_newmethod)tab_rfft_new, (t_method)tab_rfft_free,
+ sizeof(t_tab_rfft), 0, A_GIMME, 0);
+ class_addbang(tab_rfft_class, (t_method)tab_rfft_bang);
+ class_addlist(tab_rfft_class, (t_method)tab_rfft_list);
+ class_addmethod(tab_rfft_class, (t_method)tab_rfft_fftsize, gensym("fftsize"), A_DEFFLOAT, 0);
+ class_addmethod(tab_rfft_class, (t_method)tab_rfft_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_rfft_class, (t_method)tab_rfft_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_rfft_class, (t_method)tab_rfft_dst_re, gensym("dst_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_rfft_class, (t_method)tab_rfft_dst_im, gensym("dst_im"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_rfft_class, (t_method)tab_rfft_dst_re, gensym("dst1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_rfft_class, (t_method)tab_rfft_dst_im, gensym("dst2"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_rfft_class, gensym("iemhelp2/tab_rfft-help"));
+}
diff --git a/src/tab_rifft.c b/src/tab_rifft.c
new file mode 100644
index 0000000..1b92a05
--- /dev/null
+++ b/src/tab_rifft.c
@@ -0,0 +1,406 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_rifft ------------------------------ */
+
+typedef struct _tab_rifft
+{
+ t_object x_obj;
+ int x_size_src_re;
+ int x_size_src_im;
+ int x_size_dst;
+ int x_offset_src_re;
+ int x_offset_src_im;
+ int x_offset_dst;
+ int x_fftsize;
+ float *x_beg_mem_src_re;
+ float *x_beg_mem_src_im;
+ float *x_beg_mem_dst_re;
+ float *x_beg_mem_dst_im;
+ TAB_COMPLEX *x_sin_cos;
+ t_symbol *x_sym_src_re;
+ t_symbol *x_sym_src_im;
+ t_symbol *x_sym_dst;
+} t_tab_rifft;
+
+static t_class *tab_rifft_class;
+
+static void tab_rifft_init(t_tab_rifft *x)
+{
+ int i, fftsize = x->x_fftsize;
+ float f, g;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+
+ g = 2.0f * 3.1415926538f / (float)fftsize;
+ for(i=0; i<fftsize; i++)
+ {
+ f = g * (float)i;
+ (*sincos).real = cos(f);
+ (*sincos).imag = sin(f);/*IFFT*/
+ sincos++;
+ }
+}
+
+static void tab_rifft_ifftsize(t_tab_rifft *x, t_floatarg f)
+{
+ int i=1, fftsize = (int)f;
+
+ if(fftsize < 8)
+ fftsize = 8;
+
+ while(i <= fftsize)
+ i *= 2;
+ i /= 2;
+
+ if(i != x->x_fftsize)
+ {
+ x->x_sin_cos = (TAB_COMPLEX *)resizebytes(x->x_sin_cos, x->x_fftsize*sizeof(TAB_COMPLEX), i*sizeof(TAB_COMPLEX));
+ x->x_beg_mem_dst_im = (float *)resizebytes(x->x_beg_mem_dst_im, x->x_fftsize*sizeof(float), i*sizeof(float));
+ x->x_fftsize = i;
+ }
+ tab_rifft_init(x);
+}
+
+static void tab_rifft_dst(t_tab_rifft *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_rifft_src_re(t_tab_rifft *x, t_symbol *s)
+{
+ x->x_sym_src_re = s;
+}
+
+static void tab_rifft_src_im(t_tab_rifft *x, t_symbol *s)
+{
+ x->x_sym_src_im = s;
+}
+
+static void tab_rifft_bang(t_tab_rifft *x)
+{
+ int i, j, k;
+ int ok_src_re, ok_src_im, ok_dst;
+ int w_index, w_inc, i_inc, v_index;
+ int fftsize = x->x_fftsize;
+ int fs1 = fftsize - 1;
+ int fs2 = fftsize / 2;
+ TAB_COMPLEX w;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+ t_float *vec_src_re, *vec_src_im, *vec_dst_re, *vec_dst_im;
+ t_float old1_re, old1_im, old2_re, old2_im, g;
+
+ ok_src_re = iem_tab_check_arrays(gensym("tab_rifft"), x->x_sym_src_re, &x->x_beg_mem_src_re, &x->x_size_src_re, fftsize);
+ ok_src_im = iem_tab_check_arrays(gensym("tab_rifft"), x->x_sym_src_im, &x->x_beg_mem_src_im, &x->x_size_src_im, fftsize);
+ ok_dst = iem_tab_check_arrays(gensym("tab_rifft"), x->x_sym_dst, &x->x_beg_mem_dst_re, &x->x_size_dst, fftsize);
+
+ if(ok_src_re && ok_src_im && ok_dst)
+ {
+ t_garray *a;
+
+ vec_src_re=x->x_beg_mem_src_re;
+ vec_src_im=x->x_beg_mem_src_im;
+ vec_dst_re=x->x_beg_mem_dst_re;
+ vec_dst_im=x->x_beg_mem_dst_im;
+
+ for(j=0; j<fs2; j++)
+ {
+ vec_dst_re[j] = vec_src_re[j];
+ vec_dst_im[j] = vec_src_im[j];
+ }
+ vec_dst_re[fs2] = vec_src_re[fs2];
+ vec_dst_im[fs2] = 0.0f;
+ for(k=1, j=fftsize-1; k<fs2; k++, j--)
+ {
+ vec_dst_re[j] = vec_src_re[k];
+ vec_dst_im[j] = -vec_src_im[k];
+ }
+
+ i_inc = fs2;
+ w_inc = 1;
+ for(i=1; i<fftsize; i<<=1)
+ {
+ v_index = 0;
+ for(j=0; j<i; j++)
+ {
+ w_index = 0;
+ for(k=0; k<i_inc; k++)
+ {
+ old1_re = vec_dst_re[v_index];
+ old1_im = vec_dst_im[v_index];
+ old2_re = vec_dst_re[v_index+i_inc];
+ old2_im = vec_dst_im[v_index+i_inc];
+ w = sincos[w_index];
+ vec_dst_re[v_index+i_inc] = (old1_re - old2_re)*w.real - (old1_im - old2_im)*w.imag;
+ vec_dst_im[v_index+i_inc] = (old1_im - old2_im)*w.real + (old1_re - old2_re)*w.imag;
+ vec_dst_re[v_index] = old1_re + old2_re;
+ vec_dst_im[v_index] = old1_im + old2_im;
+ w_index += w_inc;
+ v_index++;
+ }
+ v_index += i_inc;
+ }
+ w_inc <<= 1;
+ i_inc >>= 1;
+ }
+
+ j = 0;
+ for(i=1;i<fs1;i++)
+ {
+ k = fs2;
+ while(k <= j)
+ {
+ j = j - k;
+ k >>= 1;
+ }
+ j = j + k;
+ if(i < j)
+ {
+ old1_re = vec_dst_re[j];
+ old1_im = vec_dst_im[j];
+ vec_dst_re[j] = vec_dst_re[i];
+ vec_dst_im[j] = vec_dst_im[i];
+ vec_dst_re[i] = old1_re;
+ vec_dst_im[i] = old1_im;
+ }
+ }
+
+// g = 2.0f / (float)fftsize;
+/*
+ ein fehler tritt auf beim 0.sample, hier sollte nur mal 1.0 multipliziert werden
+ wenn gelten soll : Energie im zeitfenster == Energie im Frequenz-dichte-fenster
+
+ g = 1.0f;
+ for(i = 0; i < fs2; i++)
+ {
+ vec_dst_re[i] *= g;
+ vec_dst_im[i] *= g;
+ }
+ */
+
+ g = 1.0f / (float)fftsize;
+ for(i = 0; i < fftsize; i++)
+ {
+ vec_dst_re[i] *= g;
+ }
+
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+}
+
+static void tab_rifft_list(t_tab_rifft *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src_re, beg_src_im, beg_dst;
+ int i, j, k;
+ int ok_src_re, ok_src_im, ok_dst;
+ int w_index, w_inc, i_inc, v_index;
+ int fftsize = x->x_fftsize;
+ int fs1 = fftsize - 1;
+ int fs2 = fftsize / 2;
+ TAB_COMPLEX w;
+ TAB_COMPLEX *sincos = x->x_sin_cos;
+ t_float *vec_src_re, *vec_src_im, *vec_dst_re, *vec_dst_im;
+ t_float old1_re, old1_im, old2_re, old2_im, g;
+
+ if((argc >= 3) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2))
+ {
+ beg_src_re = (int)atom_getintarg(0, argc, argv);
+ beg_src_im = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ if(beg_src_re < 0)
+ beg_src_re = 0;
+ if(beg_src_im < 0)
+ beg_src_im = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+
+ ok_src_re = iem_tab_check_arrays(gensym("tab_rifft"), x->x_sym_src_re, &x->x_beg_mem_src_re, &x->x_size_src_re, beg_src_re+fftsize);
+ ok_src_im = iem_tab_check_arrays(gensym("tab_rifft"), x->x_sym_src_im, &x->x_beg_mem_src_im, &x->x_size_src_im, beg_src_im+fftsize);
+ ok_dst = iem_tab_check_arrays(gensym("tab_rifft"), x->x_sym_dst, &x->x_beg_mem_dst_re, &x->x_size_dst, beg_dst+fftsize);
+
+ if(ok_src_re && ok_src_im && ok_dst)
+ {
+ t_garray *a;
+
+ vec_src_re=x->x_beg_mem_src_re + beg_src_re;
+ vec_src_im=x->x_beg_mem_src_im + beg_src_im;
+ vec_dst_re=x->x_beg_mem_dst_re + beg_dst;
+ vec_dst_im=x->x_beg_mem_dst_im;
+
+ for(j=0; j<fs2; j++)
+ {
+ vec_dst_re[j] = vec_src_re[j];
+ vec_dst_im[j] = vec_src_im[j];
+ }
+ vec_dst_re[fs2] = vec_src_re[fs2];
+ vec_dst_im[fs2] = 0.0f;
+ for(k=1, j=fftsize-1; k<fs2; k++, j--)
+ {
+ vec_dst_re[j] = vec_src_re[k];
+ vec_dst_im[j] = -vec_src_im[k];
+ }
+
+ i_inc = fs2;
+ w_inc = 1;
+ for(i=1; i<fftsize; i<<=1)
+ {
+ v_index = 0;
+ for(j=0; j<i; j++)
+ {
+ w_index = 0;
+ for(k=0; k<i_inc; k++)
+ {
+ old1_re = vec_dst_re[v_index];
+ old1_im = vec_dst_im[v_index];
+ old2_re = vec_dst_re[v_index+i_inc];
+ old2_im = vec_dst_im[v_index+i_inc];
+ w = sincos[w_index];
+ vec_dst_re[v_index+i_inc] = (old1_re - old2_re)*w.real - (old1_im - old2_im)*w.imag;
+ vec_dst_im[v_index+i_inc] = (old1_im - old2_im)*w.real + (old1_re - old2_re)*w.imag;
+ vec_dst_re[v_index] = old1_re + old2_re;
+ vec_dst_im[v_index] = old1_im + old2_im;
+ w_index += w_inc;
+ v_index++;
+ }
+ v_index += i_inc;
+ }
+ w_inc <<= 1;
+ i_inc >>= 1;
+ }
+
+ j = 0;
+ for(i=1;i<fs1;i++)
+ {
+ k = fs2;
+ while(k <= j)
+ {
+ j = j - k;
+ k >>= 1;
+ }
+ j = j + k;
+ if(i < j)
+ {
+ old1_re = vec_dst_re[j];
+ old1_im = vec_dst_im[j];
+ vec_dst_re[j] = vec_dst_re[i];
+ vec_dst_im[j] = vec_dst_im[i];
+ vec_dst_re[i] = old1_re;
+ vec_dst_im[i] = old1_im;
+ }
+ }
+
+// g = 2.0f / (float)fftsize;
+/*
+ ein fehler tritt auf beim 0.sample, hier sollte nur mal 1.0 multipliziert werden
+ wenn gelten soll : Energie im zeitfenster == Energie im Frequenz-dichte-fenster
+
+ g = 1.0f;
+ for(i = 0; i < fs2; i++)
+ {
+ vec_src_re[i] *= g;
+ vec_src_im[i] *= g;
+ }
+ */
+
+ g = 1.0f / (float)fftsize;
+ for(i = 0; i < fftsize; i++)
+ {
+ vec_dst_re[i] *= g;
+ }
+
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ else
+ {
+ post("tab_rifft-ERROR: list need 3 float arguments:");
+ post(" source_real_offset + source_imag_offset + destination_offset");
+ }
+}
+
+static void tab_rifft_free(t_tab_rifft *x)
+{
+ freebytes(x->x_sin_cos, x->x_fftsize * sizeof(TAB_COMPLEX));
+ freebytes(x->x_beg_mem_dst_im, x->x_fftsize * sizeof(float));
+}
+
+static void *tab_rifft_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_rifft *x = (t_tab_rifft *)pd_new(tab_rifft_class);
+ t_symbol *src_re, *src_im, *dst;
+ int fftsize, i=1;
+
+ if((argc >= 4) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ src_re = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src_im = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ fftsize = (int)atom_getintarg(3, argc, argv);
+ }
+ else
+ {
+ post("tab_rifft-ERROR: need 3 symbols + 1 float arguments:");
+ post(" source_real_array_name + source_imag_array_name + destination_array_name + IFFT-size");
+ return(0);
+ }
+
+ if(fftsize < 8)
+ fftsize = 8;
+
+ while(i <= fftsize)
+ i *= 2;
+ i /= 2;
+ fftsize = i;
+
+ x->x_fftsize = fftsize;
+ x->x_sym_src_re = src_re;
+ x->x_sym_src_im = src_im;
+ x->x_sym_dst = dst;
+ x->x_sin_cos = (TAB_COMPLEX *)getbytes(x->x_fftsize * sizeof(TAB_COMPLEX));
+ x->x_beg_mem_dst_im = (float *)getbytes(x->x_fftsize * sizeof(float));
+ tab_rifft_init(x);
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_rifft_setup(void)
+{
+ tab_rifft_class = class_new(gensym("tab_rifft"), (t_newmethod)tab_rifft_new, (t_method)tab_rifft_free,
+ sizeof(t_tab_rifft), 0, A_GIMME, 0);
+ class_addbang(tab_rifft_class, (t_method)tab_rifft_bang);
+ class_addlist(tab_rifft_class, (t_method)tab_rifft_list);
+ class_addmethod(tab_rifft_class, (t_method)tab_rifft_ifftsize, gensym("ifftsize"), A_DEFFLOAT, 0);
+ class_addmethod(tab_rifft_class, (t_method)tab_rifft_src_re, gensym("src_re"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_rifft_class, (t_method)tab_rifft_src_im, gensym("src_im"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_rifft_class, (t_method)tab_rifft_src_re, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_rifft_class, (t_method)tab_rifft_src_im, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_rifft_class, (t_method)tab_rifft_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_rifft_class, (t_method)tab_rifft_dst, gensym("dst1"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_rifft_class, gensym("iemhelp2/tab_rifft-help"));
+}
diff --git a/src/tab_sin.c b/src/tab_sin.c
new file mode 100644
index 0000000..308d575
--- /dev/null
+++ b/src/tab_sin.c
@@ -0,0 +1,221 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#define TABDUMTAB1SIZE 256
+#define TABDUMTAB2SIZE 1024
+
+static t_float tab_sin_exptab[TABDUMTAB1SIZE], tab_sin_mantissatab[TABDUMTAB2SIZE];
+
+static void init_tab_sin(void)
+{
+ int i;
+
+ for (i=0; i<TABDUMTAB1SIZE; i++)
+ {
+ t_float f;
+ long l = (i ? (i == TABDUMTAB1SIZE-1 ? TABDUMTAB1SIZE-2 : i) : 1)<< 23;
+
+ *(long *)(&f) = l;
+ tab_sin_exptab[i] = 1.0f/sqrt(f);
+ }
+
+ for (i=0; i<TABDUMTAB2SIZE; i++)
+ {
+ t_float f = 1.0f + (1.0f / (t_float)TABDUMTAB2SIZE) * (t_float)i;
+
+ tab_sin_mantissatab[i] = 1.0f / sqrt(f);
+ }
+}
+
+
+/* -------------------------- tab_sin ------------------------------ */
+
+typedef struct _tab_sin
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_sin;
+
+static t_class *tab_sin_class;
+
+static void tab_sin_src(t_tab_sin *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_sin_dst(t_tab_sin *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_sin_bang(t_tab_sin *x)
+{
+ int i, n;
+ int ok_src, ok_dst;
+ t_float *vec_src, *vec_dst;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_sin"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_sin"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ vec_src = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ while(n--)
+ {
+ t_float f = *vec_src;
+ long l = *(long *)(vec_src++);
+
+ if(f < 0.0f)
+ *vec_dst++ = 0.0f;
+ else
+ {
+ t_float g = tab_sin_exptab[(l >> 23) & 0xff] * tab_sin_mantissatab[(l >> 13) & 0x3ff];
+
+ *vec_dst++ = f*g*(1.5f - 0.5f * g * g * f);
+ }
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_sin_list(t_tab_sin *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src, beg_dst;
+ int i, n;
+ int ok_src, ok_dst;
+ t_float *vec_src, *vec_dst;
+
+ if((argc >= 3) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_sin"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_sin"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src && ok_dst)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ while(n--)
+ {
+ t_float f = *vec_src;
+ long l = *(long *)(vec_src++);
+
+ if(f < 0.0f)
+ *vec_dst++ = 0.0f;
+ else
+ {
+ t_float g = tab_sin_exptab[(l >> 23) & 0xff] * tab_sin_mantissatab[(l >> 13) & 0x3ff];
+
+ *vec_dst++ = f*g*(1.5f - 0.5f * g * g * f);
+ }
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_sin-ERROR: list need 3 float arguments:");
+ post(" source_offset + destination_offset + number_of_samples_to_sqrt");
+ }
+}
+
+static void tab_sin_free(t_tab_sin *x)
+{
+}
+
+static void *tab_sin_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_sin *x = (t_tab_sin *)pd_new(tab_sin_class);
+ t_symbol *src, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src;
+ }
+ else
+ {
+ post("tab_sin-ERROR: need 2 symbols arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_sin_setup(void)
+{
+ init_tab_sin();
+ tab_sin_class = class_new(gensym("tab_sin"), (t_newmethod)tab_sin_new, (t_method)tab_sin_free,
+ sizeof(t_tab_sin), 0, A_GIMME, 0);
+ class_addbang(tab_sin_class, (t_method)tab_sin_bang);
+ class_addlist(tab_sin_class, (t_method)tab_sin_list);
+ class_addmethod(tab_sin_class, (t_method)tab_sin_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_sin_class, (t_method)tab_sin_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_sin_class, (t_method)tab_sin_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_sin_class, gensym("iemhelp2/tab_sin-help"));
+}
diff --git a/src/tab_sqrt.c b/src/tab_sqrt.c
new file mode 100644
index 0000000..f67fee2
--- /dev/null
+++ b/src/tab_sqrt.c
@@ -0,0 +1,221 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#define TABDUMTAB1SIZE 256
+#define TABDUMTAB2SIZE 1024
+
+static t_float tab_rsqrt_exptab[TABDUMTAB1SIZE], tab_rsqrt_mantissatab[TABDUMTAB2SIZE];
+
+static void init_tab_rsqrt(void)
+{
+ int i;
+
+ for (i=0; i<TABDUMTAB1SIZE; i++)
+ {
+ t_float f;
+ long l = (i ? (i == TABDUMTAB1SIZE-1 ? TABDUMTAB1SIZE-2 : i) : 1)<< 23;
+
+ *(long *)(&f) = l;
+ tab_rsqrt_exptab[i] = 1.0f/sqrt(f);
+ }
+
+ for (i=0; i<TABDUMTAB2SIZE; i++)
+ {
+ t_float f = 1.0f + (1.0f / (t_float)TABDUMTAB2SIZE) * (t_float)i;
+
+ tab_rsqrt_mantissatab[i] = 1.0f / sqrt(f);
+ }
+}
+
+
+/* -------------------------- tab_sqrt ------------------------------ */
+
+typedef struct _tab_sqrt
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_dst;
+} t_tab_sqrt;
+
+static t_class *tab_sqrt_class;
+
+static void tab_sqrt_src(t_tab_sqrt *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_sqrt_dst(t_tab_sqrt *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_sqrt_bang(t_tab_sqrt *x)
+{
+ int i, n;
+ int ok_src, ok_dst;
+ t_float *vec_src, *vec_dst;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_sqrt"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_sqrt"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ vec_src = x->x_beg_mem_src1;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ while(n--)
+ {
+ t_float f = *vec_src;
+ long l = *(long *)(vec_src++);
+
+ if(f < 0.0f)
+ *vec_dst++ = 0.0f;
+ else
+ {
+ t_float g = tab_rsqrt_exptab[(l >> 23) & 0xff] * tab_rsqrt_mantissatab[(l >> 13) & 0x3ff];
+
+ *vec_dst++ = f*g*(1.5f - 0.5f * g * g * f);
+ }
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_sqrt_list(t_tab_sqrt *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src, beg_dst;
+ int i, n;
+ int ok_src, ok_dst;
+ t_float *vec_src, *vec_dst;
+
+ if((argc >= 3) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ beg_dst = (int)atom_getintarg(1, argc, argv);
+ n = (int)atom_getintarg(2, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_sqrt"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_sqrt"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src && ok_dst)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ while(n--)
+ {
+ t_float f = *vec_src;
+ long l = *(long *)(vec_src++);
+
+ if(f < 0.0f)
+ *vec_dst++ = 0.0f;
+ else
+ {
+ t_float g = tab_rsqrt_exptab[(l >> 23) & 0xff] * tab_rsqrt_mantissatab[(l >> 13) & 0x3ff];
+
+ *vec_dst++ = f*g*(1.5f - 0.5f * g * g * f);
+ }
+ }
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_sqrt-ERROR: list need 3 float arguments:");
+ post(" source_offset + destination_offset + number_of_samples_to_sqrt");
+ }
+}
+
+static void tab_sqrt_free(t_tab_sqrt *x)
+{
+}
+
+static void *tab_sqrt_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_sqrt *x = (t_tab_sqrt *)pd_new(tab_sqrt_class);
+ t_symbol *src, *dst;
+
+ if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src;
+ }
+ else
+ {
+ post("tab_sqrt-ERROR: need 2 symbols arguments:");
+ post(" source_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_sqrt_setup(void)
+{
+ init_tab_rsqrt();
+ tab_sqrt_class = class_new(gensym("tab_sqrt"), (t_newmethod)tab_sqrt_new, (t_method)tab_sqrt_free,
+ sizeof(t_tab_sqrt), 0, A_GIMME, 0);
+ class_addbang(tab_sqrt_class, (t_method)tab_sqrt_bang);
+ class_addlist(tab_sqrt_class, (t_method)tab_sqrt_list);
+ class_addmethod(tab_sqrt_class, (t_method)tab_sqrt_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_sqrt_class, (t_method)tab_sqrt_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_sqrt_class, (t_method)tab_sqrt_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_sqrt_class, gensym("iemhelp2/tab_sqrt-help"));
+}
diff --git a/src/tab_sub.c b/src/tab_sub.c
new file mode 100644
index 0000000..bda6955
--- /dev/null
+++ b/src/tab_sub.c
@@ -0,0 +1,196 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_sub ------------------------------ */
+
+typedef struct _tab_sub
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_size_src2;
+ int x_size_dst;
+ int x_offset_src1;
+ int x_offset_src2;
+ int x_offset_dst;
+ float *x_beg_mem_src1;
+ float *x_beg_mem_src2;
+ float *x_beg_mem_dst;
+ t_symbol *x_sym_scr1;
+ t_symbol *x_sym_scr2;
+ t_symbol *x_sym_dst;
+} t_tab_sub;
+
+static t_class *tab_sub_class;
+
+static void tab_sub_src1(t_tab_sub *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_sub_src2(t_tab_sub *x, t_symbol *s)
+{
+ x->x_sym_scr2 = s;
+}
+
+static void tab_sub_dst(t_tab_sub *x, t_symbol *s)
+{
+ x->x_sym_dst = s;
+}
+
+static void tab_sub_bang(t_tab_sub *x)
+{
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_sub"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_sub"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, 0);
+ ok_dst = iem_tab_check_arrays(gensym("tab_sub"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, 0);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ if(x->x_size_src1 < x->x_size_dst)
+ n = x->x_size_src1;
+ else
+ n = x->x_size_dst;
+ if(x->x_size_src2 < n)
+ n = x->x_size_src2;
+
+ vec_src1 = x->x_beg_mem_src1;
+ vec_src2 = x->x_beg_mem_src2;
+ vec_dst = x->x_beg_mem_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src1[i] - vec_src2[i];
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+}
+
+static void tab_sub_list(t_tab_sub *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src1, beg_src2, beg_dst;
+ int i, n;
+ int ok_src1, ok_src2, ok_dst;
+ t_float *vec_src1, *vec_src2, *vec_dst;
+
+ if((argc >= 4) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1) &&
+ IS_A_FLOAT(argv,2) &&
+ IS_A_FLOAT(argv,3))
+ {
+ beg_src1 = (int)atom_getintarg(0, argc, argv);
+ beg_src2 = (int)atom_getintarg(1, argc, argv);
+ beg_dst = (int)atom_getintarg(2, argc, argv);
+ n = (int)atom_getintarg(3, argc, argv);
+ if(beg_src1 < 0)
+ beg_src1 = 0;
+ if(beg_src2 < 0)
+ beg_src2 = 0;
+ if(beg_dst < 0)
+ beg_dst = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src1 = iem_tab_check_arrays(gensym("tab_sub"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src1+n);
+ ok_src2 = iem_tab_check_arrays(gensym("tab_sub"), x->x_sym_scr2, &x->x_beg_mem_src2, &x->x_size_src2, beg_src2+n);
+ ok_dst = iem_tab_check_arrays(gensym("tab_sub"), x->x_sym_dst, &x->x_beg_mem_dst, &x->x_size_dst, beg_dst+n);
+
+ if(ok_src1 && ok_src2 && ok_dst)
+ {
+ vec_src1 = x->x_beg_mem_src1 + beg_src1;
+ vec_src2 = x->x_beg_mem_src2 + beg_src2;
+ vec_dst = x->x_beg_mem_dst + beg_dst;
+ if(n)
+ {
+ t_garray *a;
+
+ for(i=0; i<n; i++)
+ vec_dst[i] = vec_src1[i] - vec_src2[i];
+ outlet_bang(x->x_obj.ob_outlet);
+ a = (t_garray *)pd_findbyclass(x->x_sym_dst, garray_class);
+ garray_redraw(a);
+ }
+ }
+ }
+ else
+ {
+ post("tab_sub-ERROR: list need 4 float arguments:");
+ post(" source1_offset + source2_offset + destination_offset + number_of_samples_to_sub");
+ }
+}
+
+static void tab_sub_free(t_tab_sub *x)
+{
+}
+
+static void *tab_sub_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_sub *x = (t_tab_sub *)pd_new(tab_sub_class);
+ t_symbol *src1, *src2, *dst;
+ t_float time;
+
+ if((argc >= 3) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1) &&
+ IS_A_SYMBOL(argv,2))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ dst = (t_symbol *)atom_getsymbolarg(2, argc, argv);
+ }
+ else if((argc >= 2) &&
+ IS_A_SYMBOL(argv,0) &&
+ IS_A_SYMBOL(argv,1))
+ {
+ src1 = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ dst = src1;
+ src2 = (t_symbol *)atom_getsymbolarg(1, argc, argv);
+ }
+ else
+ {
+ post("tab_sub-ERROR: need 3 symbols arguments:");
+ post(" source1_array_name + source2_array_name + destination_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src1;
+ x->x_sym_scr2 = src2;
+ x->x_sym_dst = dst;
+ outlet_new(&x->x_obj, &s_bang);
+ return(x);
+}
+
+void tab_sub_setup(void)
+{
+ tab_sub_class = class_new(gensym("tab_sub"), (t_newmethod)tab_sub_new, (t_method)tab_sub_free,
+ sizeof(t_tab_sub), 0, A_GIMME, 0);
+ class_addbang(tab_sub_class, (t_method)tab_sub_bang);
+ class_addlist(tab_sub_class, (t_method)tab_sub_list);
+ class_addmethod(tab_sub_class, (t_method)tab_sub_src1, gensym("src1"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_sub_class, (t_method)tab_sub_src2, gensym("src2"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_sub_class, (t_method)tab_sub_dst, gensym("dst"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_sub_class, gensym("iemhelp2/tab_sub-help"));
+}
diff --git a/src/tab_sum.c b/src/tab_sum.c
new file mode 100644
index 0000000..e27e17a
--- /dev/null
+++ b/src/tab_sum.c
@@ -0,0 +1,143 @@
+/* For information on usage and redistribution, and for a DISCLAIMER OF ALL
+* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
+
+iem_tab written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */
+
+#ifdef NT
+#pragma warning( disable : 4244 )
+#pragma warning( disable : 4305 )
+#endif
+
+
+#include "m_pd.h"
+#include "iemlib.h"
+#include "iem_tab.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+
+/* -------------------------- tab_sum ------------------------------ */
+
+typedef struct _tab_sum
+{
+ t_object x_obj;
+ int x_size_src1;
+ int x_offset_src1;
+ float *x_beg_mem_src1;
+ t_symbol *x_sym_scr1;
+ void *x_bang_out;
+ void *x_sum_out;
+} t_tab_sum;
+
+static t_class *tab_sum_class;
+
+static void tab_sum_src(t_tab_sum *x, t_symbol *s)
+{
+ x->x_sym_scr1 = s;
+}
+
+static void tab_sum_bang(t_tab_sum *x)
+{
+ int i, n;
+ int ok_src;
+ t_float *vec_src;
+ t_float sum=0.0f;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_sum"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, 0);
+
+ if(ok_src)
+ {
+ n = x->x_size_src1;
+ vec_src = x->x_beg_mem_src1;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ sum += vec_src[i];
+ }
+ outlet_float(x->x_sum_out, sum);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+}
+
+static void tab_sum_list(t_tab_sum *x, t_symbol *s, int argc, t_atom *argv)
+{
+ int beg_src;
+ int i, n;
+ int ok_src;
+ t_float *vec_src;
+ t_float sum=0.0f;
+
+ if((argc >= 2) &&
+ IS_A_FLOAT(argv,0) &&
+ IS_A_FLOAT(argv,1))
+ {
+ beg_src = (int)atom_getintarg(0, argc, argv);
+ n = (int)atom_getintarg(1, argc, argv);
+ if(beg_src < 0)
+ beg_src = 0;
+ if(n < 0)
+ n = 0;
+
+ ok_src = iem_tab_check_arrays(gensym("tab_sum"), x->x_sym_scr1, &x->x_beg_mem_src1, &x->x_size_src1, beg_src+n);
+
+ if(ok_src)
+ {
+ vec_src = x->x_beg_mem_src1 + beg_src;
+ if(n)
+ {
+ for(i=0; i<n; i++)
+ {
+ sum += vec_src[i];
+ }
+ outlet_float(x->x_sum_out, sum);
+ outlet_bang(x->x_bang_out);
+ }
+ }
+ }
+ else
+ {
+ post("tab_sum-ERROR: list need 2 float arguments:");
+ post(" source_offset + number_of_samples_to_calc_sum-value");
+ }
+}
+
+static void tab_sum_free(t_tab_sum *x)
+{
+}
+
+static void *tab_sum_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_tab_sum *x = (t_tab_sum *)pd_new(tab_sum_class);
+ t_symbol *src;
+
+ if((argc >= 1) &&
+ IS_A_SYMBOL(argv,0))
+ {
+ src = (t_symbol *)atom_getsymbolarg(0, argc, argv);
+ }
+ else
+ {
+ post("tab_sum-ERROR: need 1 symbol argument:");
+ post(" source_array_name");
+ return(0);
+ }
+
+ x->x_sym_scr1 = src;
+ x->x_bang_out = outlet_new(&x->x_obj, &s_bang);
+ x->x_sum_out = outlet_new(&x->x_obj, &s_float);
+ return(x);
+}
+
+void tab_sum_setup(void)
+{
+ tab_sum_class = class_new(gensym("tab_sum"), (t_newmethod)tab_sum_new, (t_method)tab_sum_free,
+ sizeof(t_tab_sum), 0, A_GIMME, 0);
+ class_addbang(tab_sum_class, (t_method)tab_sum_bang);
+ class_addlist(tab_sum_class, (t_method)tab_sum_list);
+ class_addmethod(tab_sum_class, (t_method)tab_sum_src, gensym("src"), A_DEFSYMBOL, 0);
+ class_addmethod(tab_sum_class, (t_method)tab_sum_src, gensym("src1"), A_DEFSYMBOL, 0);
+ class_sethelpsymbol(tab_sum_class, gensym("iemhelp2/tab_sum-help"));
+}