aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2004-11-23 15:29:47 +0000
committerIOhannes m zmölnig <zmoelnig@users.sourceforge.net>2004-11-23 15:29:47 +0000
commit9340768f6c7dea7cb7fe348f6fdf52db75ce9d82 (patch)
tree92af89757cb802aee5b088ce5a5c9ce5b29ebc37
This commit was generated by cvs2svn to compensate for changes in r2300,svn2git-root
which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/iem16/; revision=2301
-rw-r--r--GnuGPL.LICENSE290
-rw-r--r--examples/del16read~.pd41
-rw-r--r--examples/del16write~.pd25
-rw-r--r--examples/tab16play~.pd56
-rw-r--r--examples/tab16read.pd27
-rw-r--r--examples/tab16read4~.pd39
-rw-r--r--examples/tab16receive~.pd18
-rw-r--r--examples/tab16send~.pd20
-rw-r--r--examples/tab16write.pd28
-rw-r--r--examples/tab16write~.pd32
-rw-r--r--examples/table16.pd60
-rw-r--r--examples/vd16~.pd32
-rw-r--r--src/iem16.c52
-rwxr-xr-xsrc/iem16.dsp99
-rwxr-xr-xsrc/iem16.dsw29
-rw-r--r--src/iem16.h42
-rw-r--r--src/iem16_array.c173
-rw-r--r--src/iem16_array_tilde.c502
-rwxr-xr-xsrc/iem16_delay.c285
-rw-r--r--src/iem16_table.c141
-rw-r--r--src/iem16_table.h27
-rw-r--r--src/makefile79
22 files changed, 2097 insertions, 0 deletions
diff --git a/GnuGPL.LICENSE b/GnuGPL.LICENSE
new file mode 100644
index 0000000..fa0bef4
--- /dev/null
+++ b/GnuGPL.LICENSE
@@ -0,0 +1,290 @@
+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.
+
+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
diff --git a/examples/del16read~.pd b/examples/del16read~.pd
new file mode 100644
index 0000000..6d4d511
--- /dev/null
+++ b/examples/del16read~.pd
@@ -0,0 +1,41 @@
+#N canvas 24 20 800 531 12;
+#X text 372 274 1st argument: name of delay line;
+#X floatatom 116 253 0 0 0 0 - - -;
+#X text 151 255 float input (delay time in ms);
+#X text 127 310 signal output (delayed signal);
+#X floatatom 383 177 0 0 0 0 - - -;
+#X obj 116 375 snapshot~;
+#X floatatom 116 399 0 0 0 0 - - -;
+#X obj 24 246 loadbang;
+#X obj 24 313 metro 200;
+#X msg 32 273 \; pd dsp 1;
+#X text 424 176 input to delay line;
+#X obj 383 201 sig~;
+#X text 372 290 2nd argument: (initial) delay time in ms;
+#X text 36 443 see also:;
+#X obj 116 286 del16read~ del_example 1000;
+#X obj 383 226 del16write~ del_example 1000;
+#X obj 24 16 del16read~;
+#X obj 126 444 del16write~;
+#X obj 239 444 vd16~;
+#X text 133 14 - read a 16bit signal from a 16bit-delay line;
+#X obj 368 52 delread~;
+#X text 21 52 This is very similar to the pd-object;
+#X text 49 82 It uses only 16bit to store the samples \, which will
+need only half of the memory of pd's floatingpoint-based object.;
+#X text 50 120 However \, there are 2 drawbacks: there will be some
+additional noise (because floats are more precise than 16bit) \, and
+you cannot have values>1 stored in the delay-line;
+#X text 38 490 similar pd-objects:;
+#X obj 223 489 delread~;
+#X obj 307 489 delwrite~;
+#X obj 400 489 vd~;
+#X text 433 443 updated for iem16 version1.0;
+#X connect 1 0 14 0;
+#X connect 4 0 11 0;
+#X connect 5 0 6 0;
+#X connect 7 0 8 0;
+#X connect 7 0 9 0;
+#X connect 8 0 5 0;
+#X connect 11 0 15 0;
+#X connect 14 0 5 0;
diff --git a/examples/del16write~.pd b/examples/del16write~.pd
new file mode 100644
index 0000000..5aa280a
--- /dev/null
+++ b/examples/del16write~.pd
@@ -0,0 +1,25 @@
+#N canvas 83 192 678 431 12;
+#X text 88 202 signal input;
+#X text 136 16 writes a signal in a delay line;
+#X text 281 235 1st argument: name of delay line;
+#X obj 24 203 sig~ 0;
+#X text 304 265 (= max. delay time);
+#X text 281 251 2nd argument: length of delay line in msec;
+#X text 24 292 see also:;
+#X obj 24 16 del16write~;
+#X obj 112 294 delread16~;
+#X obj 209 294 vd16~;
+#X text 16 353 similar pd-objects:;
+#X obj 201 352 delread~;
+#X obj 285 352 delwrite~;
+#X obj 378 352 vd~;
+#X obj 24 237 del16write~ del_line_xxx 500;
+#X text 21 51 This is very similar to the pd-object;
+#X text 49 81 It uses only 16bit to store the samples \, which will
+need only half of the memory of pd's floatingpoint-based object.;
+#X text 50 119 However \, there are 2 drawbacks: there will be some
+additional noise (because floats are more precise than 16bit) \, and
+you cannot have values>1 stored in the delay-line;
+#X obj 368 51 delwrite~;
+#X text 411 306 updated for iem16 version1.0;
+#X connect 3 0 14 0;
diff --git a/examples/tab16play~.pd b/examples/tab16play~.pd
new file mode 100644
index 0000000..8c53199
--- /dev/null
+++ b/examples/tab16play~.pd
@@ -0,0 +1,56 @@
+#N canvas 159 54 804 495 10;
+#X msg 639 93 \; pd dsp 0;
+#X floatatom 11 342 0 0 0 0 - - -;
+#X msg 11 109 set array99;
+#X text 93 109 "set" message permits you to switch between arrays;
+#X text 138 228 creation argument initializes array name;
+#X obj 11 316 env~ 16384;
+#X obj 87 360 dac~ 1;
+#X obj 87 323 *~;
+#X obj 100 304 line~;
+#X msg 100 263 0.1 100;
+#X msg 116 284 0 100;
+#X text 162 264 on;
+#X text 157 283 off;
+#X text 148 301 envelope;
+#X text 148 312 generator;
+#X text 101 248 amplitude controls:;
+#X text 131 362 audio output;
+#X obj 87 342 hip~ 5;
+#X msg 26 179 0 44100;
+#X msg 27 158 44100;
+#X msg 26 138 bang;
+#X text 80 136 "bang" or 0 plays whole sample;
+#X text 82 157 play starting at 44100th sample;
+#X text 93 177 play starting at beginning for 44100 samples;
+#X msg 25 199 44100 1000;
+#X text 103 198 play from 44100 through 45099 (1000 samples);
+#X obj 11 228 tab16play~ array99;
+#X obj 589 205 table16 array99;
+#X text 389 444 updated for iem16 version1.0;
+#X obj 5 439 tab16write~;
+#X obj 5 458 tab16read4~;
+#X obj 89 458 tab16read;
+#X obj 89 439 tab16write;
+#X obj 166 439 tab16send~;
+#X obj 166 458 tab16receive~;
+#X obj 32 13 tab16play~;
+#X text 29 43 The [tab16play~] object is the same as the [tabplay~]
+object \, but it refers to 16bit-arrays stored in [table16] instead
+of floating-point arrays (stored in normal pd-tables/arrays);
+#X obj 328 444 table16;
+#X text 11 417 see also:;
+#X text 108 14 play a 16bit-table as a sample (non-transposing);
+#X connect 2 0 26 0;
+#X connect 5 0 1 0;
+#X connect 7 0 17 0;
+#X connect 8 0 7 1;
+#X connect 9 0 8 0;
+#X connect 10 0 8 0;
+#X connect 17 0 6 0;
+#X connect 18 0 26 0;
+#X connect 19 0 26 0;
+#X connect 20 0 26 0;
+#X connect 24 0 26 0;
+#X connect 26 0 5 0;
+#X connect 26 0 7 0;
diff --git a/examples/tab16read.pd b/examples/tab16read.pd
new file mode 100644
index 0000000..fd34feb
--- /dev/null
+++ b/examples/tab16read.pd
@@ -0,0 +1,27 @@
+#N canvas 245 143 703 316 12;
+#X text 62 102 index;
+#X floatatom 25 103 0 0 0 0 - - -;
+#X floatatom 25 199 0 0 0 0 - - -;
+#X text 70 197 output = array99[index];
+#X text 189 157 creation argument;
+#X text 185 175 gives array name;
+#X msg 35 125 set array99;
+#X text 147 125 change array name;
+#X obj 25 165 tab16read array99;
+#X obj 422 131 table16 array99;
+#X obj 17 13 tab16read;
+#X text 412 257 updated for iem16 version1.0;
+#X obj 16 252 tab16write~;
+#X obj 16 271 tab16read4~;
+#X obj 120 271 tab16read;
+#X obj 120 252 tab16write;
+#X obj 217 252 tab16send~;
+#X obj 217 271 tab16receive~;
+#X obj 339 257 table16;
+#X text 108 15 - read numbers from a 16bit-table;
+#X text 21 42 since [table16] can only hold 16bit values \, the output
+of [tab16read] is limited to integer-values between -32768..+32767
+;
+#X connect 1 0 8 0;
+#X connect 6 0 8 0;
+#X connect 8 0 2 0;
diff --git a/examples/tab16read4~.pd b/examples/tab16read4~.pd
new file mode 100644
index 0000000..6757552
--- /dev/null
+++ b/examples/tab16read4~.pd
@@ -0,0 +1,39 @@
+#N canvas 59 33 741 466 10;
+#X text 21 207 signal input x(n);
+#X text 127 21 4-point-interpolating table lookup;
+#X obj 11 316 snapshot~;
+#X obj 30 290 metro 200;
+#X obj 11 124 sig~;
+#X floatatom 11 98 0 0 0 0 - - -;
+#X obj 30 264 r readout;
+#X floatatom 11 342 0 0 0 0 - - -;
+#X text 49 94 incoming signal is index. Indices should range from 1
+to (size-2) so that the 4-point interpolation is meaningful. You can
+shift-drag the number box to see the effect of interpolation.;
+#X msg 34 158 set array99;
+#X text 116 158 "set" message permits you to switch between arrays
+;
+#X text 149 228 creation argument initializes array name;
+#X obj 10 228 tab16read4~ array99;
+#X obj 460 301 table16 array99;
+#X text 395 400 updated for iem16 version1.0;
+#X obj 11 395 tab16write~;
+#X obj 11 414 tab16read4~;
+#X obj 95 414 tab16read;
+#X obj 95 395 tab16write;
+#X obj 172 395 tab16send~;
+#X obj 172 414 tab16receive~;
+#X obj 334 400 table16;
+#X obj 47 21 tab16read4~;
+#X text 7 51 tab16read4~ is used to build samplers and other table
+lookup algorithms. The interpolation scheme is 4-point polynomial.
+;
+#X text 185 266 since [table16] can only hold 16bit-values \, the stored
+integer values -32768..+32767 are converted to floats -1.0..+1.0;
+#X connect 2 0 7 0;
+#X connect 3 0 2 0;
+#X connect 4 0 12 0;
+#X connect 5 0 4 0;
+#X connect 6 0 3 0;
+#X connect 9 0 12 0;
+#X connect 12 0 2 0;
diff --git a/examples/tab16receive~.pd b/examples/tab16receive~.pd
new file mode 100644
index 0000000..292ec2b
--- /dev/null
+++ b/examples/tab16receive~.pd
@@ -0,0 +1,18 @@
+#N canvas 109 83 646 239 12;
+#X text 17 53 creation argument: name of array;
+#X text 16 83 By default a block is 64 samples \; this can be reset
+using the block~ object.;
+#X obj 21 18 tab16receive~;
+#X text 376 199 updated for iem16 version1.0;
+#X obj 5 176 tab16write~;
+#X obj 5 195 tab16read4~;
+#X obj 109 195 tab16read;
+#X obj 109 176 tab16write;
+#X obj 204 176 tab16send~;
+#X obj 204 195 tab16receive~;
+#X obj 328 181 table16;
+#X text 17 155 see also:;
+#X text 129 18 - read a block of a 16bit-signal from an array continuously
+;
+#X text 10 129 16bit-signals are limited to 65536 values between -1.0..+1.0
+;
diff --git a/examples/tab16send~.pd b/examples/tab16send~.pd
new file mode 100644
index 0000000..918d75a
--- /dev/null
+++ b/examples/tab16send~.pd
@@ -0,0 +1,20 @@
+#N canvas 151 91 705 277 12;
+#X text 113 26 writes one block of a signal continuously to an array
+;
+#X text 41 60 creation argument: name of array;
+#X text 29 96 By default a block is 64 samples \; this can be reset
+using the block~ object.;
+#X text 376 239 updated for iem16 version1.0;
+#X obj 5 216 tab16write~;
+#X obj 5 235 tab16read4~;
+#X obj 109 235 tab16read;
+#X obj 109 216 tab16write;
+#X obj 204 216 tab16send~;
+#X obj 204 235 tab16receive~;
+#X obj 328 221 table16;
+#X text 17 195 see also:;
+#X text 14 137 16bit-signals are limited to 65536 values between -1.0..+1.0
+;
+#X text 16 157 if your signal has absolute values >1.0 \, these are
+wrapped around...;
+#X obj 11 27 tab16send~;
diff --git a/examples/tab16write.pd b/examples/tab16write.pd
new file mode 100644
index 0000000..209df02
--- /dev/null
+++ b/examples/tab16write.pd
@@ -0,0 +1,28 @@
+#N canvas 44 17 653 456 12;
+#X floatatom 39 96 0 0 0 0 - - -;
+#X floatatom 176 170 0 0 0 0 - - -;
+#X text 208 192 creation argument;
+#X text 210 210 is array name;
+#X text 76 87 set y value;
+#X text 74 152 right inlet selects x value;
+#X msg 55 117 set array99;
+#X text 163 116 change array name;
+#X obj 39 195 tab16write array99;
+#X obj 31 27 tab16write;
+#X text 388 378 updated for iem16 version1.0;
+#X obj 17 355 tab16write~;
+#X obj 17 374 tab16read4~;
+#X obj 121 374 tab16read;
+#X obj 121 355 tab16write;
+#X obj 216 355 tab16send~;
+#X obj 216 374 tab16receive~;
+#X obj 340 360 table16;
+#X text 29 334 see also:;
+#X obj 438 156 table16 array99;
+#X text 133 28 write numbers to a 16bit-table;
+#X text 20 256 since [table16] can only hold 16bit-values \, the stored
+numbers have to be integer (ok \, we take care of this!) values between
+-32768..+32767.;
+#X connect 0 0 8 0;
+#X connect 1 0 8 1;
+#X connect 6 0 8 0;
diff --git a/examples/tab16write~.pd b/examples/tab16write~.pd
new file mode 100644
index 0000000..0904d65
--- /dev/null
+++ b/examples/tab16write~.pd
@@ -0,0 +1,32 @@
+#N canvas 119 134 697 433 10;
+#X msg 43 131 bang;
+#X obj 23 82 sig~ 3000;
+#X obj 23 110 phasor~;
+#X text 158 213 creation argument initializes array name;
+#X msg 40 181 set array99;
+#X msg 445 35 \; pd dsp 1;
+#X msg 524 37 \; pd dsp 0;
+#X text 85 133 bang to start recording;
+#X text 126 180 set the destination array;
+#X msg 43 153 stop;
+#X text 85 154 stop recording;
+#X text 385 366 updated for iem16 version1.0;
+#X obj 14 343 tab16write~;
+#X obj 14 362 tab16read4~;
+#X obj 118 362 tab16read;
+#X obj 118 343 tab16write;
+#X obj 213 343 tab16send~;
+#X obj 213 362 tab16receive~;
+#X obj 337 348 table16;
+#X text 26 322 see also:;
+#X obj 22 211 tab16write~ array99;
+#X obj 492 160 table16 array99;
+#X obj 31 27 tab16write~;
+#X text 120 27 object to write a 16bit-signal in an array;
+#X text 261 261 since [table16] can only hold 16bit-values \, the incoming
+signal (-1.0..+1.0) is stored as integer values -32768..+32767;
+#X connect 0 0 20 0;
+#X connect 1 0 2 0;
+#X connect 2 0 20 0;
+#X connect 4 0 20 0;
+#X connect 9 0 20 0;
diff --git a/examples/table16.pd b/examples/table16.pd
new file mode 100644
index 0000000..50e6ccb
--- /dev/null
+++ b/examples/table16.pd
@@ -0,0 +1,60 @@
+#N canvas 37 0 856 640 10;
+#X obj 30 21 table16;
+#X text 97 22 16bit-table;
+#X text 32 51 [table16] stores 16bit values. The normal pd-tables ([table]
+\, array) store the values as floating-points. While floating points
+are (often) more precise (this is of course not really true... \, esp.
+when comparing integer(4byte) to floating-point.) they use a lot of
+memory (4byte).;
+#X text 32 121 [table16] uses only 16bit (2bytes) to store the values
+\, which is half of the memory.;
+#X text 32 155 However there are 2 major drawbacks;
+#X text 53 172 a) less precision means less SNR - you can only store
+65536 different values \, but this is what CD-quality is (should be
+good enough for most musical applications);
+#X text 55 221 b) the 65536 values (-32678..+32767) are mapped to -1.0..+1.0!
+This means you cannot store signals that exceed this magical limit.
+Please make sure \, that the signal has correct values (use [clip~])
+or the unclipped values will get wrapped!;
+#X text 20 323 There are several objects to access the data of [table16]:
+;
+#X obj 55 344 tab16write~;
+#X obj 55 363 tab16read4~;
+#X obj 279 363 tab16read;
+#X obj 279 344 tab16write;
+#X obj 164 344 tab16send~;
+#X obj 164 363 tab16receive~;
+#X obj 55 382 tab16read~;
+#X text 19 410 The message-objects [tab16read]/[tab16write] store the
+values directly (-32767..+32768) \, while the signal-objects convert
+the floats -1.0..+1.0 to the correct values or vice-versa.;
+#X text 270 21 updated for iem16 version1.0;
+#X msg 496 53 resize 100;
+#X obj 496 308 table16 array16 99;
+#N canvas 0 0 450 300 graph6 0;
+#X array array100 10 float 1;
+#A 0 1 2 3 4 5 6 7 8 9 0;
+#X coords 0 10 9 0 200 140 1;
+#X restore 477 452 graph;
+#X msg 478 409 \; array100 0 1 2 3 4 5 6 7 8 9;
+#X text 481 389 click to init float-array;
+#X msg 502 114 from array100;
+#X text 21 497 There is no beautiful graphical representation as with
+pd's arrays.;
+#X msg 508 139 from array100 resize;
+#X msg 516 190 from array100 20 30;
+#X msg 517 213 from array100 20 30 resize;
+#X msg 527 259 from array100 20 30 95;
+#X msg 527 279 from array100 20 30 95 resize;
+#X text 502 95 copy the data from a float-array;
+#X text 603 117 and resize the 16bit-array;
+#X text 513 173 copy floats (index20..30);
+#X text 653 192 and resize to 30-20;
+#X text 526 241 copy indexed values and insert at index95;
+#X connect 17 0 18 0;
+#X connect 22 0 18 0;
+#X connect 24 0 18 0;
+#X connect 25 0 18 0;
+#X connect 26 0 18 0;
+#X connect 27 0 18 0;
+#X connect 28 0 18 0;
diff --git a/examples/vd16~.pd b/examples/vd16~.pd
new file mode 100644
index 0000000..cf59065
--- /dev/null
+++ b/examples/vd16~.pd
@@ -0,0 +1,32 @@
+#N canvas 88 40 717 480 12;
+#X floatatom 50 254 0 0 0 0 - - -;
+#X obj 50 347 outlet~;
+#X text 130 346 signal output (delayed signal);
+#X obj 50 282 sig~;
+#X text 99 279 signal input (delay time in ms);
+#X text 218 310 creation argument: name of delay line;
+#X text 35 400 see also:;
+#X obj 24 16 vd16~;
+#X text 77 10 reads a signal from a 16bit delay line at a variable
+delay time (4-point-interpolation);
+#X text 31 51 vd16~ implements a 4-point interpolating delay tap from
+a corresponding delwrite~ object. The delay in milliseconds of the
+tap is specified by the incoming signal.;
+#X obj 50 314 vd16~ del_example;
+#X text 16 433 similar pd-objects:;
+#X obj 201 432 delread~;
+#X obj 285 432 delwrite~;
+#X obj 378 432 vd~;
+#X obj 123 403 del16write~;
+#X obj 242 403 del16read~;
+#X text 411 386 updated for iem16 version1.0;
+#X text 28 116 This is very similar to the pd-object;
+#X text 56 137 It uses only 16bit to store the samples \, which will
+need only half of the memory of pd's floatingpoint-based object.;
+#X text 57 175 However \, there are 2 drawbacks: there will be some
+additional noise (because floats are more precise than 16bit) \, and
+you cannot have values>1 stored in the delay-line;
+#X obj 375 112 vd~;
+#X connect 0 0 3 0;
+#X connect 3 0 10 0;
+#X connect 10 0 1 0;
diff --git a/src/iem16.c b/src/iem16.c
new file mode 100644
index 0000000..d916ddc
--- /dev/null
+++ b/src/iem16.c
@@ -0,0 +1,52 @@
+/* ...this is a very IEM16 external ...
+ it allows for 16bit-constructs where float would eat too much memory
+
+ forum::für::umläute@IEM:2003
+*/
+
+#include "iem16.h"
+
+/* do a little help thing */
+
+typedef struct iem16 {
+ t_object t_ob;
+} t_iem16;
+
+t_class *iem16_class;
+
+void *iem16_new(void){
+ t_iem16 *x = (t_iem16 *)pd_new(iem16_class);
+ post("iem16: 16bit objects for low memory usage");
+ return (void *)x;
+}
+
+/* include some externals */
+void iem16_table_setup();
+void iem16_array_setup();
+void iem16_array_tilde_setup();
+void iem16_delay_setup();
+
+void iem16_setup(void) {
+ iem16_table_setup();
+ iem16_array_setup();
+ iem16_array_tilde_setup();
+ iem16_delay_setup();
+
+ /* ************************************** */
+ post("iem16:\t16bit-objects for low memory usage");
+ post("iem16:\t(l) forum::für::umläute\t\tIOhannes m zmölnig");
+ post("iem16:\tInstitute of Electronic Music and Acoustics, Graz - iem");
+ post("iem16:\tcompiled: "__DATE__);
+
+
+ iem16_class = class_new(gensym("iem16"),
+ iem16_new,
+ 0,
+ sizeof(t_iem16), CLASS_NOINLET, A_NULL);
+ class_addcreator((t_newmethod)iem16_new,
+ gensym("IEM16"), A_NULL);
+}
+
+void IEM16_setup(void){
+ iem16_setup();
+}
diff --git a/src/iem16.dsp b/src/iem16.dsp
new file mode 100755
index 0000000..1c2f7fc
--- /dev/null
+++ b/src/iem16.dsp
@@ -0,0 +1,99 @@
+# Microsoft Developer Studio Project File - Name="iem16" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=IEM16 - WIN32 RELEASE
+!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 "iem16.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 "iem16.mak" CFG="IEM16 - WIN32 RELEASE"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "iem16 - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 1
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "obj\"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IEM16_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /I "..\..\pd\src" /D "WIN32" /D "NT" /D "_WINDOWS" /D "IEM16" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /win32
+# SUBTRACT MTL /mktyplib203
+# ADD BASE RSC /l 0xc07 /d "NDEBUG"
+# ADD RSC /l 0xc07
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib wsock32.lib uuid.lib libc.lib oldnames.lib pd.lib /nologo /dll /machine:I386 /nodefaultlib /out:"..\iem16.dll" /libpath:"../../pd/bin" /export:iem16_setup
+# SUBTRACT LINK32 /pdb:none
+# Begin Target
+
+# Name "iem16 - Win32 Release"
+# Begin Group "Quellcodedateien"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\iem16.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\iem16_array.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\iem16_array_tilde.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\iem16_delay.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\iem16_table.c
+# End Source File
+# End Group
+# Begin Group "Header-Dateien"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\iem16.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\iem16_table.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pd\src\m_pd.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/src/iem16.dsw b/src/iem16.dsw
new file mode 100755
index 0000000..0e01cda
--- /dev/null
+++ b/src/iem16.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: "iem16"=.\iem16.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/src/iem16.h b/src/iem16.h
new file mode 100644
index 0000000..f9649cd
--- /dev/null
+++ b/src/iem16.h
@@ -0,0 +1,42 @@
+/* ********************************************** */
+/* the IEM16 external */
+/* ********************************************** */
+/* forum::für::umläute */
+/* ********************************************** */
+
+/* the IEM16 external is a runtime-library for miller s. puckette's realtime-computermusic-software "pure data"
+ * therefore you NEED "pure data" to make any use of the IEM16 external
+ * (except if you want to use the code for other things)
+ * download "pure data" at
+
+ http://pd.iem.at
+ ftp://iem.at/pd
+
+ *
+ * if you are looking for the latest release of the IEM16-external you should have another look at
+
+ ftp://iem.at/pd/Externals/IEM16
+
+ *
+ * IEM16 is published under the GNU GeneralPublicLicense, that must be shipped with IEM16.
+ * if you are using Debian GNU/linux, the GNU-GPL can be found under /usr/share/common-licenses/GPL
+ * if you still haven't found a copy of the GNU-GPL, have a look at http://www.gnu.org
+ *
+ * "pure data" has it's own license, that comes shipped with "pure data".
+ *
+ * there are ABSOLUTELY NO WARRANTIES for anything
+ */
+
+#ifndef INCLUDE_IEM16_H__
+#define INCLUDE_IEM16_H__
+
+#include "m_pd.h"
+
+typedef short t_iem16_16bit;
+
+#define IEM16_SCALE_UP (32767)
+#define IEM16_SCALE_DOWN (1./32767)
+
+#define VERSION "0.1"
+
+#endif
diff --git a/src/iem16_array.c b/src/iem16_array.c
new file mode 100644
index 0000000..22ee35d
--- /dev/null
+++ b/src/iem16_array.c
@@ -0,0 +1,173 @@
+/* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
+ * based on d_array.c from pd:
+ * Copyright (c) 1997-1999 Miller Puckette and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* tab16read, tab16read4, tab16write */
+
+#include "iem16_table.h"
+
+/* ---------- tab16read: control, non-interpolating ------------------------ */
+
+static t_class *tab16read_class;
+
+typedef struct _tab16read{
+ t_object x_obj;
+ t_symbol *x_arrayname;
+} t_tab16read;
+
+static void tab16read_float(t_tab16read *x, t_float f){
+ t_table16 *a;
+ int npoints;
+ t_iem16_16bit *vec;
+
+ if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class)))
+ error("%s: no such array", x->x_arrayname->s_name);
+ else if (!table16_getarray16(a, &npoints, &vec))
+ error("%s: bad template for tab16read", x->x_arrayname->s_name);
+ else {
+ int n = f;
+ if (n < 0) n = 0;
+ else if (n >= npoints) n = npoints - 1;
+ outlet_float(x->x_obj.ob_outlet, (npoints ? vec[n] : 0));
+ }
+}
+
+static void tab16read_set(t_tab16read *x, t_symbol *s){
+ x->x_arrayname = s;
+}
+
+static void *tab16read_new(t_symbol *s){
+ t_tab16read *x = (t_tab16read *)pd_new(tab16read_class);
+ x->x_arrayname = s;
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void tab16read_setup(void){
+ tab16read_class = class_new(gensym("tab16read"), (t_newmethod)tab16read_new,
+ 0, sizeof(t_tab16read), 0, A_DEFSYM, 0);
+ class_addfloat(tab16read_class, (t_method)tab16read_float);
+ class_addmethod(tab16read_class, (t_method)tab16read_set, gensym("set"),
+ A_SYMBOL, 0);
+}
+
+/* ---------- tab16read4: control, non-interpolating ------------------------ */
+
+static t_class *tab16read4_class;
+
+typedef struct _tab16read4{
+ t_object x_obj;
+ t_symbol *x_arrayname;
+} t_tab16read4;
+
+static void tab16read4_float(t_tab16read4 *x, t_float f){
+ t_table16 *a;
+ int npoints;
+ t_iem16_16bit *vec;
+
+ if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class)))
+ error("%s: no such array", x->x_arrayname->s_name);
+ else if (!table16_getarray16(a, &npoints, &vec))
+ error("%s: bad template for tab16read4", x->x_arrayname->s_name);
+ else if (npoints < 4)
+ outlet_float(x->x_obj.ob_outlet, 0);
+ else if (f <= 1)
+ outlet_float(x->x_obj.ob_outlet, vec[1]);
+ else if (f >= npoints - 2)
+ outlet_float(x->x_obj.ob_outlet, vec[npoints - 2]);
+ else {
+ int n = f;
+ float a, b, c, d, cminusb, frac;
+ t_iem16_16bit *fp;
+ if (n >= npoints - 2) n = npoints - 3;
+ fp = vec + n;
+ frac = f - n;
+ a = fp[-1];
+ b = fp[0];
+ c = fp[1];
+ d = fp[2];
+ cminusb = c-b;
+ outlet_float(x->x_obj.ob_outlet, b + frac * (
+ cminusb - 0.5f * (frac-1.) * (
+ (a - d + 3.0f * cminusb) * frac + (b - a - cminusb))));
+ }
+}
+
+static void tab16read4_set(t_tab16read4 *x, t_symbol *s){
+ x->x_arrayname = s;
+}
+
+static void *tab16read4_new(t_symbol *s){
+ t_tab16read4 *x = (t_tab16read4 *)pd_new(tab16read4_class);
+ x->x_arrayname = s;
+ outlet_new(&x->x_obj, &s_float);
+ return (x);
+}
+
+static void tab16read4_setup(void){
+ tab16read4_class = class_new(gensym("tab16read4"), (t_newmethod)tab16read4_new,
+ 0, sizeof(t_tab16read4), 0, A_DEFSYM, 0);
+ class_addfloat(tab16read4_class, (t_method)tab16read4_float);
+ class_addmethod(tab16read4_class, (t_method)tab16read4_set, gensym("set"),
+ A_SYMBOL, 0);
+}
+
+/* ------------------ tab16write: control ------------------------ */
+
+static t_class *tab16write_class;
+
+typedef struct _tab16write {
+ t_object x_obj;
+ t_symbol *x_arrayname;
+ float x_ft1;
+ int x_set;
+} t_tab16write;
+
+static void tab16write_float(t_tab16write *x, t_float f) {
+ int vecsize;
+ t_table16 *a;
+ t_iem16_16bit *vec;
+
+ if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class)))
+ error("%s: no such array", x->x_arrayname->s_name);
+ else if (!table16_getarray16(a, &vecsize, &vec))
+ error("%s: bad template for tab16write", x->x_arrayname->s_name);
+ else {
+ int n = x->x_ft1;
+ if (n < 0) n = 0;
+ else if (n >= vecsize) n = vecsize-1;
+ vec[n] = f;
+ }
+}
+
+static void tab16write_set(t_tab16write *x, t_symbol *s){
+ x->x_arrayname = s;
+}
+
+static void tab16write_free(t_tab16write *x){}
+
+static void *tab16write_new(t_symbol *s){
+ t_tab16write *x = (t_tab16write *)pd_new(tab16write_class);
+ x->x_ft1 = 0;
+ x->x_arrayname = s;
+ floatinlet_new(&x->x_obj, &x->x_ft1);
+ return (x);
+}
+
+void tab16write_setup(void){
+ tab16write_class = class_new(gensym("tab16write"), (t_newmethod)tab16write_new,
+ (t_method)tab16write_free, sizeof(t_tab16write), 0, A_DEFSYM, 0);
+ class_addfloat(tab16write_class, (t_method)tab16write_float);
+ class_addmethod(tab16write_class, (t_method)tab16write_set, gensym("set"), A_SYMBOL, 0);
+}
+
+/* ------------------------ global setup routine ------------------------- */
+
+void iem16_array_setup(void){
+ tab16read_setup();
+ tab16read4_setup();
+ tab16write_setup();
+}
+
diff --git a/src/iem16_array_tilde.c b/src/iem16_array_tilde.c
new file mode 100644
index 0000000..2cda11f
--- /dev/null
+++ b/src/iem16_array_tilde.c
@@ -0,0 +1,502 @@
+/* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
+ * based on d_array.c from pd:
+ * Copyright (c) 1997-1999 Miller Puckette and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* tab16write~, tab16play~, tab16read~, tab16read4~, tab16send~, tab16receive~ */
+
+#include "iem16_table.h"
+
+/* ------------------------- tab16write~ -------------------------- */
+
+static t_class *tab16write_tilde_class;
+
+typedef struct _tab16write_tilde {
+ t_object x_obj;
+ int x_phase;
+ int x_nsampsintab;
+ short *x_vec;
+ t_symbol *x_arrayname;
+ float x_f;
+} t_tab16write_tilde;
+
+static void *tab16write_tilde_new(t_symbol *s) {
+ t_tab16write_tilde *x = (t_tab16write_tilde *)pd_new(tab16write_tilde_class);
+ x->x_phase = 0x7fffffff;
+ x->x_arrayname = s;
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *tab16write_tilde_perform(t_int *w) {
+ t_tab16write_tilde *x = (t_tab16write_tilde *)(w[1]);
+ t_float *in = (t_float *)(w[2]);
+ int n = (int)(w[3]), phase = x->x_phase, endphase = x->x_nsampsintab;
+ if (!x->x_vec) goto bad;
+
+ if (endphase > phase) {
+ int nxfer = endphase - phase;
+ t_iem16_16bit *fp = x->x_vec + phase;
+ if (nxfer > n) nxfer = n;
+ phase += nxfer;
+ while (nxfer--)*fp++ = *in++*IEM16_SCALE_UP;
+ x->x_phase = phase;
+ }
+ bad:
+ return (w+4);
+}
+
+void tab16write_tilde_set(t_tab16write_tilde *x, t_symbol *s){
+ t_table16 *a;
+
+ x->x_arrayname = s;
+ if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
+ if (*s->s_name) pd_error(x, "tab16write~: %s: no such array",
+ x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else if (!table16_getarray16(a, &x->x_nsampsintab, &x->x_vec)) {
+ error("%s: bad template for tab16write~", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else table16_usedindsp(a);
+}
+
+static void tab16write_tilde_dsp(t_tab16write_tilde *x, t_signal **sp){
+ tab16write_tilde_set(x, x->x_arrayname);
+ dsp_add(tab16write_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
+}
+
+static void tab16write_tilde_bang(t_tab16write_tilde *x){
+ x->x_phase = 0;
+}
+
+static void tab16write_tilde_stop(t_tab16write_tilde *x){}
+
+static void tab16write_tilde_free(t_tab16write_tilde *x){}
+
+static void tab16write_tilde_setup(void){
+ tab16write_tilde_class = class_new(gensym("tab16write~"),
+ (t_newmethod)tab16write_tilde_new, (t_method)tab16write_tilde_free,
+ sizeof(t_tab16write_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(tab16write_tilde_class, t_tab16write_tilde, x_f);
+ class_addmethod(tab16write_tilde_class, (t_method)tab16write_tilde_dsp,
+ gensym("dsp"), 0);
+ class_addmethod(tab16write_tilde_class, (t_method)tab16write_tilde_set,
+ gensym("set"), A_SYMBOL, 0);
+ class_addmethod(tab16write_tilde_class, (t_method)tab16write_tilde_stop,
+ gensym("stop"), 0);
+ class_addbang(tab16write_tilde_class, tab16write_tilde_bang);
+}
+
+/* ------------ tab16play~ - non-transposing sample playback --------------- */
+
+static t_class *tab16play_tilde_class;
+
+typedef struct _tab16play_tilde{
+ t_object x_obj;
+ t_outlet *x_bangout;
+ int x_phase;
+ int x_nsampsintab;
+ int x_limit;
+ t_iem16_16bit *x_vec;
+ t_symbol *x_arrayname;
+} t_tab16play_tilde;
+
+static void *tab16play_tilde_new(t_symbol *s){
+ t_tab16play_tilde *x = (t_tab16play_tilde *)pd_new(tab16play_tilde_class);
+ x->x_phase = 0x7fffffff;
+ x->x_limit = 0;
+ x->x_arrayname = s;
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_bangout = outlet_new(&x->x_obj, &s_bang);
+ return (x);
+}
+
+static t_int *tab16play_tilde_perform(t_int *w){
+ t_tab16play_tilde *x = (t_tab16play_tilde *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_iem16_16bit *fp;
+ int n = (int)(w[3]), phase = x->x_phase,
+ endphase = (x->x_nsampsintab < x->x_limit ?
+ x->x_nsampsintab : x->x_limit), nxfer, n3;
+ if (!x->x_vec || phase >= endphase) goto zero;
+
+ nxfer = endphase - phase;
+ fp = x->x_vec + phase;
+ if (nxfer > n)
+ nxfer = n;
+ n3 = n - nxfer;
+ phase += nxfer;
+ while (nxfer--) *out++ = *fp++*IEM16_SCALE_DOWN;
+ if (phase >= endphase) {
+ x->x_phase = 0x7fffffff;
+ while (n3--) *out++ = 0;
+ }
+ else x->x_phase = phase;
+
+ return (w+4);
+ zero:
+ while (n--) *out++ = 0;
+ return (w+4);
+}
+
+void tab16play_tilde_set(t_tab16play_tilde *x, t_symbol *s){
+ t_table16 *a;
+
+ x->x_arrayname = s;
+ if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
+ if (*s->s_name) pd_error(x, "tab16play~: %s: no such array",
+ x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else if (!table16_getarray16(a, &x->x_nsampsintab, &x->x_vec)) {
+ error("%s: bad template for tab16play~", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else table16_usedindsp(a);
+}
+
+static void tab16play_tilde_dsp(t_tab16play_tilde *x, t_signal **sp){
+ tab16play_tilde_set(x, x->x_arrayname);
+ dsp_add(tab16play_tilde_perform, 3, x, sp[0]->s_vec, sp[0]->s_n);
+}
+
+static void tab16play_tilde_list(t_tab16play_tilde *x, t_symbol *s,
+ int argc, t_atom *argv){
+ long start = atom_getfloatarg(0, argc, argv);
+ long length = atom_getfloatarg(1, argc, argv);
+ if (start < 0) start = 0;
+ if (length <= 0)x->x_limit = 0x7fffffff;
+ else x->x_limit = start + length;
+ x->x_phase = start;
+}
+
+static void tab16play_tilde_stop(t_tab16play_tilde *x){
+ x->x_phase = 0x7fffffff;
+}
+
+static void tab16play_tilde_free(t_tab16play_tilde *x){}
+
+static void tab16play_tilde_setup(void){
+ tab16play_tilde_class = class_new(gensym("tab16play~"),
+ (t_newmethod)tab16play_tilde_new, (t_method)tab16play_tilde_free,
+ sizeof(t_tab16play_tilde), 0, A_DEFSYM, 0);
+ class_addmethod(tab16play_tilde_class, (t_method)tab16play_tilde_dsp,
+ gensym("dsp"), 0);
+ class_addmethod(tab16play_tilde_class, (t_method)tab16play_tilde_stop,
+ gensym("stop"), 0);
+ class_addmethod(tab16play_tilde_class, (t_method)tab16play_tilde_set,
+ gensym("set"), A_DEFSYM, 0);
+ class_addlist(tab16play_tilde_class, tab16play_tilde_list);
+}
+
+/* ------------------------ tab16send~ ------------------------- */
+
+static t_class *tab16send_class;
+
+typedef struct _tab16send{
+ t_object x_obj;
+ t_iem16_16bit *x_vec;
+ int x_graphperiod;
+ int x_graphcount;
+ t_symbol *x_arrayname;
+ float x_f;
+} t_tab16send;
+
+static void *tab16send_new(t_symbol *s){
+ t_tab16send *x = (t_tab16send *)pd_new(tab16send_class);
+ x->x_graphcount = 0;
+ x->x_arrayname = s;
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *tab16send_perform(t_int *w){
+ t_tab16send *x = (t_tab16send *)(w[1]);
+ t_float *in = (t_float *)(w[2]);
+ int n = w[3];
+ t_iem16_16bit *dest = x->x_vec;
+ int i = x->x_graphcount;
+ if (!x->x_vec) goto bad;
+
+ while (n--) *dest = *in++*IEM16_SCALE_UP;
+ if (!i--)i = x->x_graphperiod;
+ x->x_graphcount = i;
+ bad:
+ return (w+4);
+}
+
+static void tab16send_dsp(t_tab16send *x, t_signal **sp){
+ int vecsize;
+ t_table16 *a;
+
+ if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
+ if (*x->x_arrayname->s_name)
+ error("tab16send~: %s: no such array", x->x_arrayname->s_name);
+ }
+ else if (!table16_getarray16(a, &vecsize, &x->x_vec))
+ error("%s: bad template for tab16send~", x->x_arrayname->s_name);
+ else {
+ int n = sp[0]->s_n;
+ int ticksper = sp[0]->s_sr/n;
+ if (ticksper < 1) ticksper = 1;
+ x->x_graphperiod = ticksper;
+ if (x->x_graphcount > ticksper) x->x_graphcount = ticksper;
+ if (n < vecsize) vecsize = n;
+ table16_usedindsp(a);
+ dsp_add(tab16send_perform, 3, x, sp[0]->s_vec, vecsize);
+ }
+}
+
+static void tab16send_free(t_tab16send *x){}
+
+static void tab16send_setup(void){
+ tab16send_class = class_new(gensym("tab16send~"), (t_newmethod)tab16send_new,
+ (t_method)tab16send_free, sizeof(t_tab16send), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(tab16send_class, t_tab16send, x_f);
+ class_addmethod(tab16send_class, (t_method)tab16send_dsp, gensym("dsp"), 0);
+}
+
+/* ------------------------ tab16receive~ ------------------------- */
+
+static t_class *tab16receive_class;
+
+typedef struct _tab16receive{
+ t_object x_obj;
+ t_iem16_16bit *x_vec;
+ t_symbol *x_arrayname;
+} t_tab16receive;
+
+static t_int *tab16receive_perform(t_int *w){
+ t_tab16receive *x = (t_tab16receive *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ int n = w[3];
+ t_iem16_16bit *from = x->x_vec;
+ if (from) while (n--) *out++ = *from++*IEM16_SCALE_DOWN;
+ else while (n--) *out++ = 0;
+ return (w+4);
+}
+
+static void tab16receive_dsp(t_tab16receive *x, t_signal **sp){
+ t_table16 *a;
+ int vecsize;
+
+ if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
+ if (*x->x_arrayname->s_name)
+ error("tab16send~: %s: no such array", x->x_arrayname->s_name);
+ }
+ else if (!table16_getarray16(a, &vecsize, &x->x_vec))
+ error("%s: bad template for tab16receive~", x->x_arrayname->s_name);
+ else {
+ int n = sp[0]->s_n;
+ if (n < vecsize) vecsize = n;
+ table16_usedindsp(a);
+ dsp_add(tab16receive_perform, 3, x, sp[0]->s_vec, vecsize);
+ }
+}
+
+static void *tab16receive_new(t_symbol *s){
+ t_tab16receive *x = (t_tab16receive *)pd_new(tab16receive_class);
+ x->x_arrayname = s;
+ outlet_new(&x->x_obj, &s_signal);
+ return (x);
+}
+
+static void tab16receive_setup(void){
+ tab16receive_class = class_new(gensym("tab16receive~"),
+ (t_newmethod)tab16receive_new, 0,
+ sizeof(t_tab16receive), 0, A_DEFSYM, 0);
+ class_addmethod(tab16receive_class, (t_method)tab16receive_dsp,
+ gensym("dsp"), 0);
+}
+
+/******************** tab16read~ ***********************/
+
+static t_class *tab16read_tilde_class;
+
+typedef struct _tab16read_tilde{
+ t_object x_obj;
+ int x_npoints;
+ t_iem16_16bit *x_vec;
+ t_symbol *x_arrayname;
+ float x_f;
+} t_tab16read_tilde;
+
+static void *tab16read_tilde_new(t_symbol *s){
+ t_tab16read_tilde *x = (t_tab16read_tilde *)pd_new(tab16read_tilde_class);
+ x->x_arrayname = s;
+ x->x_vec = 0;
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *tab16read_tilde_perform(t_int *w){
+ t_tab16read_tilde *x = (t_tab16read_tilde *)(w[1]);
+ t_float *in = (t_float *)(w[2]);
+ t_float *out = (t_float *)(w[3]);
+ int n = (int)(w[4]);
+ int maxindex;
+ t_iem16_16bit *buf = x->x_vec;
+ int i;
+
+ maxindex = x->x_npoints - 1;
+ if (!buf) goto zero;
+
+ for (i = 0; i < n; i++) {
+ int index = *in++;
+ if (index < 0) index = 0;
+ else if (index > maxindex) index = maxindex;
+ *out++ = buf[index]*IEM16_SCALE_DOWN;
+ }
+ return (w+5);
+ zero:
+ while (n--) *out++ = 0;
+
+ return (w+5);
+}
+
+void tab16read_tilde_set(t_tab16read_tilde *x, t_symbol *s){
+ t_table16 *a;
+
+ x->x_arrayname = s;
+ if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
+ if (*s->s_name)
+ error("tab16read~: %s: no such array", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else if (!table16_getarray16(a, &x->x_npoints, &x->x_vec)) {
+ error("%s: bad template for tab16read~", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else table16_usedindsp(a);
+}
+
+static void tab16read_tilde_dsp(t_tab16read_tilde *x, t_signal **sp){
+ tab16read_tilde_set(x, x->x_arrayname);
+
+ dsp_add(tab16read_tilde_perform, 4, x,
+ sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+
+}
+
+static void tab16read_tilde_free(t_tab16read_tilde *x){}
+
+static void tab16read_tilde_setup(void){
+ tab16read_tilde_class = class_new(gensym("tab16read~"),
+ (t_newmethod)tab16read_tilde_new, (t_method)tab16read_tilde_free,
+ sizeof(t_tab16read_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(tab16read_tilde_class, t_tab16read_tilde, x_f);
+ class_addmethod(tab16read_tilde_class, (t_method)tab16read_tilde_dsp,
+ gensym("dsp"), 0);
+ class_addmethod(tab16read_tilde_class, (t_method)tab16read_tilde_set,
+ gensym("set"), A_SYMBOL, 0);
+}
+
+/******************** tab16read4~ ***********************/
+
+static t_class *tab16read4_tilde_class;
+
+typedef struct _tab16read4_tilde{
+ t_object x_obj;
+ int x_npoints;
+ t_iem16_16bit *x_vec;
+ t_symbol *x_arrayname;
+ float x_f;
+} t_tab16read4_tilde;
+
+static void *tab16read4_tilde_new(t_symbol *s){
+ t_tab16read4_tilde *x = (t_tab16read4_tilde *)pd_new(tab16read4_tilde_class);
+ x->x_arrayname = s;
+ x->x_vec = 0;
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *tab16read4_tilde_perform(t_int *w){
+ t_tab16read4_tilde *x = (t_tab16read4_tilde *)(w[1]);
+ t_float *in = (t_float *)(w[2]);
+ t_float *out = (t_float *)(w[3]);
+ int n = (int)(w[4]);
+ int maxindex;
+ t_iem16_16bit *buf = x->x_vec;
+ t_iem16_16bit *fp;
+ int i;
+
+ maxindex = x->x_npoints - 3;
+
+ if (!buf) goto zero;
+
+ for (i = 0; i < n; i++) {
+ float findex = *in++;
+ int index = findex;
+ float frac, a, b, c, d, cminusb;
+ if (index < 1) index = 1, frac = 0;
+ else if (index > maxindex) index = maxindex, frac = 1;
+ else frac = findex - index;
+ fp = buf + index;
+ a = fp[-1]*IEM16_SCALE_DOWN;
+ b = fp[0]*IEM16_SCALE_DOWN;
+ c = fp[1]*IEM16_SCALE_DOWN;
+ d = fp[2]*IEM16_SCALE_DOWN;
+ cminusb = c-b;
+ *out++ = b + frac * (
+ cminusb - 0.5f * (frac-1.) * (
+ (a - d + 3.0f * cminusb) * frac + (b - a - cminusb)
+ )
+ );
+ }
+ return (w+5);
+ zero:
+ while (n--) *out++ = 0;
+
+ return (w+5);
+}
+
+void tab16read4_tilde_set(t_tab16read4_tilde *x, t_symbol *s){
+ t_table16 *a;
+
+ x->x_arrayname = s;
+ if (!(a = (t_table16 *)pd_findbyclass(x->x_arrayname, table16_class))) {
+ if (*s->s_name)
+ error("tab16read4~: %s: no such array", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else if (!table16_getarray16(a, &x->x_npoints, &x->x_vec)) {
+ error("%s: bad template for tab16read4~", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else table16_usedindsp(a);
+}
+
+static void tab16read4_tilde_dsp(t_tab16read4_tilde *x, t_signal **sp){
+ tab16read4_tilde_set(x, x->x_arrayname);
+
+ dsp_add(tab16read4_tilde_perform, 4, x,
+ sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+static void tab16read4_tilde_setup(void){
+ tab16read4_tilde_class = class_new(gensym("tab16read4~"),
+ (t_newmethod)tab16read4_tilde_new, 0,
+ sizeof(t_tab16read4_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(tab16read4_tilde_class, t_tab16read4_tilde, x_f);
+ class_addmethod(tab16read4_tilde_class, (t_method)tab16read4_tilde_dsp,
+ gensym("dsp"), 0);
+ class_addmethod(tab16read4_tilde_class, (t_method)tab16read4_tilde_set,
+ gensym("set"), A_SYMBOL, 0);
+}
+/* ------------------------ global setup routine ------------------------- */
+
+void iem16_array_tilde_setup(void){
+ tab16write_tilde_setup();
+ tab16play_tilde_setup();
+ tab16read_tilde_setup();
+ tab16read4_tilde_setup();
+ tab16send_setup();
+ tab16receive_setup();
+}
+
diff --git a/src/iem16_delay.c b/src/iem16_delay.c
new file mode 100755
index 0000000..24a45d3
--- /dev/null
+++ b/src/iem16_delay.c
@@ -0,0 +1,285 @@
+/* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
+ * based on d_delay.c from pd:
+ * Copyright (c) 1997-1999 Miller Puckette.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* del16read~, del16write~, vd16~ */
+
+#include "iem16_table.h"
+#ifdef NT
+static int ugen_getsortno(void){return 0;}
+#else
+extern int ugen_getsortno(void);
+#endif
+
+#define DEFDELVS 64 /* LATER get this from canvas at DSP time */
+
+/* ----------------------------- del16write~ ----------------------------- */
+static t_class *sigdel16write_class;
+
+typedef struct del16writectl{
+ int c_n;
+ t_iem16_16bit *c_vec;
+ int c_phase;
+} t_del16writectl;
+
+typedef struct _sigdel16write{
+ t_object x_obj;
+ t_symbol *x_sym;
+ t_del16writectl x_cspace;
+ int x_sortno; /* DSP sort number at which this was last put on chain */
+ int x_rsortno; /* DSP sort # for first del16read or write in chain */
+ int x_vecsize; /* vector size for del16read~ to use */
+ float x_f;
+} t_sigdel16write;
+
+#define XTRASAMPS 4
+#define SAMPBLK 4
+
+/* routine to check that all del16writes/del16reads/vds have same vecsize */
+static void sigdel16write_checkvecsize(t_sigdel16write *x, int vecsize){
+ if (x->x_rsortno != ugen_getsortno()) {
+ x->x_vecsize = vecsize;
+ x->x_rsortno = ugen_getsortno();
+ }
+ else if (vecsize != x->x_vecsize)
+ pd_error(x, "del16read/del16write/vd vector size mismatch");
+}
+
+static void *sigdel16write_new(t_symbol *s, t_floatarg msec){
+ int nsamps;
+ t_sigdel16write *x = (t_sigdel16write *)pd_new(sigdel16write_class);
+ if (!*s->s_name) s = gensym("del16write~");
+ pd_bind(&x->x_obj.ob_pd, s);
+ x->x_sym = s;
+ nsamps = msec * sys_getsr() * (float)(0.001f);
+ if (nsamps < 1) nsamps = 1;
+ nsamps += ((- nsamps) & (SAMPBLK - 1));
+ nsamps += DEFDELVS;
+ x->x_cspace.c_n = nsamps;
+ x->x_cspace.c_vec =
+ (t_iem16_16bit *)getbytes((nsamps + XTRASAMPS) * sizeof(t_iem16_16bit));
+ x->x_cspace.c_phase = XTRASAMPS;
+ x->x_sortno = 0;
+ x->x_vecsize = 0;
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *sigdel16write_perform(t_int *w){
+ t_float *in = (t_float *)(w[1]);
+ t_del16writectl *c = (t_del16writectl *)(w[2]);
+ int n = (int)(w[3]);
+ int phase = c->c_phase, nsamps = c->c_n;
+ t_iem16_16bit *vp = c->c_vec, *bp = vp + phase, *ep = vp + (c->c_n + XTRASAMPS);
+ phase += n;
+ while (n--) {
+ *bp++ = (*in++*IEM16_SCALE_UP);
+ if (bp == ep) {
+ vp[0] = ep[-4];
+ vp[1] = ep[-3];
+ vp[2] = ep[-2];
+ vp[3] = ep[-1];
+ bp = vp + XTRASAMPS;
+ phase -= nsamps;
+ }
+ }
+ c->c_phase = phase;
+ return (w+4);
+}
+
+static void sigdel16write_dsp(t_sigdel16write *x, t_signal **sp){
+ dsp_add(sigdel16write_perform, 3, sp[0]->s_vec, &x->x_cspace, sp[0]->s_n);
+ x->x_sortno = ugen_getsortno();
+ sigdel16write_checkvecsize(x, sp[0]->s_n);
+}
+
+static void sigdel16write_free(t_sigdel16write *x){
+ pd_unbind(&x->x_obj.ob_pd, x->x_sym);
+ freebytes(x->x_cspace.c_vec,
+ (x->x_cspace.c_n + XTRASAMPS) * sizeof(t_iem16_16bit));
+}
+
+static void sigdel16write_setup(void){
+ sigdel16write_class = class_new(gensym("del16write~"),
+ (t_newmethod)sigdel16write_new, (t_method)sigdel16write_free,
+ sizeof(t_sigdel16write), 0, A_DEFSYM, A_DEFFLOAT, 0);
+ CLASS_MAINSIGNALIN(sigdel16write_class, t_sigdel16write, x_f);
+ class_addmethod(sigdel16write_class, (t_method)sigdel16write_dsp,
+ gensym("dsp"), 0);
+}
+
+/* ----------------------------- del16read~ ----------------------------- */
+static t_class *sigdel16read_class;
+
+typedef struct _sigdel16read{
+ t_object x_obj;
+ t_symbol *x_sym;
+ t_float x_deltime; /* delay in msec */
+ int x_delsamps; /* delay in samples */
+ t_float x_sr; /* samples per msec */
+ t_float x_n; /* vector size */
+ int x_zerodel; /* 0 or vecsize depending on read/write order */
+} t_sigdel16read;
+
+static void sigdel16read_16bit(t_sigdel16read *x, t_float f);
+
+static void *sigdel16read_new(t_symbol *s, t_floatarg f){
+ t_sigdel16read *x = (t_sigdel16read *)pd_new(sigdel16read_class);
+ x->x_sym = s;
+ x->x_sr = 1;
+ x->x_n = 1;
+ x->x_zerodel = 0;
+ sigdel16read_16bit(x, f);
+ outlet_new(&x->x_obj, &s_signal);
+ return (x);
+}
+
+static void sigdel16read_16bit(t_sigdel16read *x, t_float f){
+ t_sigdel16write *delwriter =
+ (t_sigdel16write *)pd_findbyclass(x->x_sym, sigdel16write_class);
+ x->x_deltime = f;
+ if (delwriter) {
+ x->x_delsamps = (int)(0.5 + x->x_sr * x->x_deltime)
+ + x->x_n - x->x_zerodel;
+ if (x->x_delsamps < x->x_n) x->x_delsamps = x->x_n;
+ else if (x->x_delsamps > delwriter->x_cspace.c_n - DEFDELVS)
+ x->x_delsamps = delwriter->x_cspace.c_n - DEFDELVS;
+ }
+}
+
+static t_int *sigdel16read_perform(t_int *w){
+ t_float *out = (t_float *)(w[1]);
+ t_del16writectl *c = (t_del16writectl *)(w[2]);
+ int delsamps = *(int *)(w[3]);
+ int n = (int)(w[4]);
+ int phase = c->c_phase - delsamps, nsamps = c->c_n;
+ t_iem16_16bit *vp = c->c_vec, *bp, *ep = vp + (c->c_n + XTRASAMPS);
+
+ if (phase < 0) phase += nsamps;
+ bp = vp + phase;
+ while (n--) {
+ *out++ = *bp++*IEM16_SCALE_DOWN;
+ if (bp == ep) bp -= nsamps;
+ }
+ return (w+5);
+}
+
+static void sigdel16read_dsp(t_sigdel16read *x, t_signal **sp){
+ t_sigdel16write *delwriter =
+ (t_sigdel16write *)pd_findbyclass(x->x_sym, sigdel16write_class);
+ x->x_sr = sp[0]->s_sr * 0.001;
+ x->x_n = sp[0]->s_n;
+ if (delwriter) {
+ sigdel16write_checkvecsize(delwriter, sp[0]->s_n);
+ x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
+ 0 : delwriter->x_vecsize);
+ sigdel16read_16bit(x, x->x_deltime);
+ dsp_add(sigdel16read_perform, 4,
+ sp[0]->s_vec, &delwriter->x_cspace, &x->x_delsamps, sp[0]->s_n);
+ }
+ else if (*x->x_sym->s_name)
+ error("delread~: %s: no such delwrite~",x->x_sym->s_name);
+}
+
+static void sigdel16read_setup(void){
+ sigdel16read_class = class_new(gensym("del16read~"),
+ (t_newmethod)sigdel16read_new, 0,
+ sizeof(t_sigdel16read), 0, A_DEFSYM, A_DEFFLOAT, 0);
+ class_addmethod(sigdel16read_class, (t_method)sigdel16read_dsp,
+ gensym("dsp"), 0);
+ class_addfloat(sigdel16read_class, (t_method)sigdel16read_16bit);
+}
+
+
+/* ----------------------------- vd~ ----------------------------- */
+static t_class *sig16vd_class;
+
+typedef struct _sig16vd{
+ t_object x_obj;
+ t_symbol *x_sym;
+ t_float x_sr; /* samples per msec */
+ int x_zerodel; /* 0 or vecsize depending on read/write order */
+ float x_f;
+} t_sig16vd;
+
+static void *sig16vd_new(t_symbol *s){
+ t_sig16vd *x = (t_sig16vd *)pd_new(sig16vd_class);
+ if (!*s->s_name) s = gensym("vd~");
+ x->x_sym = s;
+ x->x_sr = 1;
+ x->x_zerodel = 0;
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *sig16vd_perform(t_int *w){
+ t_float *in = (t_float *)(w[1]);
+ t_float *out = (t_float *)(w[2]);
+ t_del16writectl *ctl = (t_del16writectl *)(w[3]);
+ t_sig16vd *x = (t_sig16vd *)(w[4]);
+ int n = (int)(w[5]);
+
+ int nsamps = ctl->c_n;
+ float limit = nsamps - n - 1;
+ float fn = n-4;
+ t_iem16_16bit *vp = ctl->c_vec, *bp, *wp = vp + ctl->c_phase;
+ float zerodel = x->x_zerodel;
+ while (n--) {
+ float delsamps = x->x_sr * *in++ - zerodel, frac;
+ int idelsamps;
+ float a, b, c, d, cminusb;
+ if (delsamps < 1.00001f) delsamps = 1.00001f;
+ if (delsamps > limit) delsamps = limit;
+ delsamps += fn;
+ fn = fn - 1.0f;
+ idelsamps = delsamps;
+ frac = delsamps - (float)idelsamps;
+ bp = wp - (idelsamps + 3);
+ if (bp < vp + 4) bp += nsamps;
+ d = bp[-3]*IEM16_SCALE_DOWN;
+ c = bp[-2]*IEM16_SCALE_DOWN;
+ b = bp[-1]*IEM16_SCALE_DOWN;
+ a = bp[00]*IEM16_SCALE_DOWN;
+ cminusb = c-b;
+ *out++ = b + frac * (
+ cminusb - 0.5f * (frac-1.) * (
+ (a - d + 3.0f * cminusb) * frac + (b - a - cminusb)
+ )
+ );
+ }
+ return (w+6);
+}
+
+static void sig16vd_dsp(t_sig16vd *x, t_signal **sp){
+ t_sigdel16write *delwriter =
+ (t_sigdel16write *)pd_findbyclass(x->x_sym, sigdel16write_class);
+ x->x_sr = sp[0]->s_sr * 0.001;
+ if (delwriter) {
+ sigdel16write_checkvecsize(delwriter, sp[0]->s_n);
+ x->x_zerodel = (delwriter->x_sortno == ugen_getsortno() ?
+ 0 : delwriter->x_vecsize);
+ dsp_add(sig16vd_perform, 5,
+ sp[0]->s_vec, sp[1]->s_vec,
+ &delwriter->x_cspace, x, sp[0]->s_n);
+ }
+ else error("vd~: %s: no such delwrite~",x->x_sym->s_name);
+}
+
+static void sig16vd_setup(void){
+ sig16vd_class = class_new(gensym("vd16~"), (t_newmethod)sig16vd_new, 0,
+ sizeof(t_sig16vd), 0, A_DEFSYM, 0);
+ class_addmethod(sig16vd_class, (t_method)sig16vd_dsp, gensym("dsp"), 0);
+ CLASS_MAINSIGNALIN(sig16vd_class, t_sig16vd, x_f);
+}
+
+/* ----------------------- global setup routine ---------------- */
+
+void iem16_delay_setup(void){
+ sigdel16write_setup();
+ sigdel16read_setup();
+ sig16vd_setup();
+}
+
diff --git a/src/iem16_table.c b/src/iem16_table.c
new file mode 100644
index 0000000..f43e2bb
--- /dev/null
+++ b/src/iem16_table.c
@@ -0,0 +1,141 @@
+/* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
+ * based on d_array.c from pd:
+ * Copyright (c) 1997-1999 Miller Puckette and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* sampling */
+
+#include "iem16_table.h"
+static void table16_const(t_table16*x, t_float f);
+
+static void *table16_new(t_symbol *s, t_float f){
+ t_table16 *x = (t_table16*)pd_new(table16_class);
+ int i=f;
+ if(i<1)i=100;
+ x->x_tablename=s;
+ x->x_size=i;
+ x->x_table=getbytes(x->x_size*sizeof(t_iem16_16bit));
+ x->x_usedindsp=0;
+ pd_bind(&x->x_obj.ob_pd, x->x_tablename);
+
+ table16_const(x, 0);
+ return(x);
+}
+
+static void table16_free(t_table16 *x){
+ if(x->x_table)freebytes(x->x_table, x->x_size*sizeof(t_iem16_16bit));
+ pd_unbind(&x->x_obj.ob_pd, x->x_tablename);
+}
+
+int table16_getarray16(t_table16*x, int*size,t_iem16_16bit**vec){
+ *size=x->x_size;
+ *vec =x->x_table;
+ return 1;
+}
+void table16_usedindsp(t_table16*x){
+ x->x_usedindsp=1;
+}
+static void table16_resize(t_table16*x, t_float f){
+ int i=f;
+ int was=x->x_size;
+ if (i<1){
+ error("can only resize to sizes >0");
+ return;
+ }
+ x->x_table=resizebytes(x->x_table, was*sizeof(t_iem16_16bit), i*sizeof(t_iem16_16bit));
+ if(i>was)memset(x->x_table+was, 0, (i-was)*sizeof(t_iem16_16bit));
+ x->x_size =i;
+ if (x->x_usedindsp) canvas_update_dsp();
+}
+
+static void table16_const(t_table16*x, t_float f){
+ t_iem16_16bit s = (t_iem16_16bit)f;
+ int i = x->x_size;
+ t_iem16_16bit*buf=x->x_table;
+ while(i--)*buf++=s;
+}
+
+
+static void table16_from(t_table16*x, t_symbol*s, int argc, t_atom*argv){
+ float scale=IEM16_SCALE_UP;
+ int resize=0;
+ int startfrom=0, startto=0, endfrom=0, endto=x->x_size;
+ t_garray *a=0;
+ int npoints;
+ t_float *vec, *src;
+ t_iem16_16bit *dest;
+
+ int i,length=0;
+
+ if(argc<1 || argv->a_type!=A_SYMBOL){
+ error("you have to specify the from-table !");
+ return;
+ }
+ s=atom_getsymbol(argv); argc--;argv++;
+ if (!(a = (t_garray *)pd_findbyclass(s, garray_class))){
+ error("%s: no such array", s->s_name);
+ return;
+ } else if (!garray_getfloatarray(a, &npoints, &vec)){
+ error("%s: bad template for tabread4", s->s_name);
+ return;
+ }
+
+ if(argc>0 && atom_getsymbol(argv+argc-1)==gensym("resize")){
+ resize=1;
+ argc--;
+ }
+ endfrom=npoints;
+
+ switch(argc){
+ case 0:break;
+ case 4:
+ endto =atom_getfloat(argv+3);
+ case 3:
+ startto =atom_getfloat(argv+2);
+ case 2:
+ endfrom =atom_getfloat(argv+1);
+ case 1:
+ startfrom=atom_getfloat(argv);
+ break;
+ default:
+ error("table16: from <tablename> [<startfrom> [<endfrom> [<startto> [<endto>]]]] [resize]");
+ return;
+ }
+ if(startfrom<0)startfrom=0;
+ if (startto<0)startto=0;
+ if(endfrom<=startfrom)return;
+ if(endto <=startto) return;
+
+ length=endfrom-startfrom;
+ if(resize){
+ if(x->x_size < (startto+length))table16_resize(x, startto+length);
+ } else{
+ if(x->x_size < (startto+length))length=x->x_size-startto;
+ }
+ endfrom=startfrom+length;
+ endto =startto+length;
+
+ dest=x->x_table+startto;
+ src =vec+startfrom;
+ i=length;
+ while(i--)*dest++=(*src++)*scale;
+ post("from %s (%d, %d) --> (%d, %d)\tresize=%s", s->s_name, startfrom, endfrom, startto, endto, (resize)?"yes":"no");
+}
+
+
+static void table16_setup(void){
+ table16_class = class_new(gensym("table16"),
+ (t_newmethod)table16_new, (t_method)table16_free,
+ sizeof(t_table16), 0, A_DEFSYM, A_DEFFLOAT, 0);
+ class_addmethod(table16_class, (t_method)table16_resize, gensym("resize"), A_DEFFLOAT);
+ class_addmethod(table16_class, (t_method)table16_const, gensym("const"), A_DEFFLOAT);
+ class_addmethod(table16_class, (t_method)table16_from, gensym("from"), A_GIMME);
+}
+
+
+void iem16_table_setup(void)
+{
+ table16_setup();
+}
+
diff --git a/src/iem16_table.h b/src/iem16_table.h
new file mode 100644
index 0000000..4810312
--- /dev/null
+++ b/src/iem16_table.h
@@ -0,0 +1,27 @@
+/* copyleft (c) 2003 forum::für::umläute -- IOhannes m zmölnig @ IEM
+ * based on d_array.c from pd:
+ * Copyright (c) 1997-1999 Miller Puckette and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* sampling */
+
+#include "iem16.h"
+#include <string.h>
+/* ------------------------- table16 -------------------------- */
+/* a 16bit table */
+
+t_class *table16_class;
+typedef struct _table16 {
+ t_object x_obj;
+
+ t_symbol *x_tablename;
+ long x_size;
+ t_iem16_16bit *x_table; // hold the data
+
+ int x_usedindsp;
+} t_table16;
+
+
+EXTERN int table16_getarray16(t_table16*x, int*size,t_iem16_16bit**vec);
+EXTERN void table16_usedindsp(t_table16*x);
diff --git a/src/makefile b/src/makefile
new file mode 100644
index 0000000..d8e6685
--- /dev/null
+++ b/src/makefile
@@ -0,0 +1,79 @@
+current: all
+
+# the IEM16-EXTERNAL-makefile
+# everything is GnuGPL that should come with the iem16.tgz
+# NO WARRANTIES FOR ANYTHING
+# et cetera
+# forum::für::umläute@IEM:2003
+
+# make sure that the "m_pd.h" is somehow available either by putting it into this
+# directory, by adding it's path to the INCLUDE-path or by putting it into an
+# already included path, e.g. "/usr/local/include/"
+
+#these are the user adjustables : adjust them to fit into your system
+# PD will install to $(DESTDIR)$(INSTALLL_PREFIX)$(PDLIBDIR), which is /usr/local/lib/pd
+# by default
+DESTDIR =
+INSTALL_PREFIX = /usr
+PDLIBDIR = /lib/pd
+#these were the user adjustables
+
+
+TARGETS = iem16 \
+ iem16_table \
+ iem16_array iem16_array_tilde \
+ iem16_delay
+
+# ----------------------- LINUX ----------------------------
+.SUFFIXES: .pd_linux
+
+
+LINUXOBJECTS = $(TARGETS:%=%.o)
+ARCH = $(shell uname --machine)
+
+PD_DIR = $(DESTDIR)$(INSTALL_PREFIX)$(PDLIBDIR)
+
+ifeq (${ARCH},alpha)
+AFLAGS = -mieee -mcpu=ev56
+endif
+
+LINCLUDE =
+
+$(LINUXOBJECTS): *.h
+
+#CFLAGS = -O2 -g -Wall $(LINCLUDE) $(UCFLAGS) $(AFLAGS)
+CFLAGS = -O3 -g -Wall $(LINCLUDE) $(UCFLAGS) $(AFLAGS)
+
+
+everything: clean all install distclean
+
+distclean:
+ touch dummy.o
+ touch dummy.pd_linux
+ touch dummy~
+ touch _dummy
+ rm *.o *.pd_linux *~ _*
+
+clean:
+ touch dummy.o
+ touch dummy.pd_linux
+ rm *.o *.pd_linux
+
+all: $(LINUXOBJECTS)
+
+ @echo :: $(LINUXOBJECTS)
+
+ ld -export_dynamic -shared -o iem16.pd_linux *.o -lc -lm
+ strip --strip-unneeded iem16.pd_linux
+
+.c.pd_linux:
+ cc $(CFLAGS) -O2 -DPD -fPIC $(INCLUDE) -c -o $*.o $*.c
+
+
+install: installdocs
+ install -d $(PD_DIR)/extra
+ install -m 644 iem16.pd_linux $(PD_DIR)/extra
+
+installdocs:
+ install -d $(PD_DIR)/doc/5.reference/iem16
+ install -m644 ../examples/*.pd $(PD_DIR)/doc/5.reference/iem16