aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--distortion-help.pd35
-rw-r--r--distortion.pd22
-rw-r--r--lfo-help.pd26
-rw-r--r--lfo.pd116
-rw-r--r--msd/README.txt61
-rw-r--r--msd/editor/README14
-rw-r--r--msd/editor/arial.ttfbin0 -> 143300 bytes
-rw-r--r--msd/editor/cone.obj70
-rw-r--r--msd/editor/countto.pd19
-rw-r--r--msd/editor/curve2.pd18
-rw-r--r--msd/editor/ds-next.pd10
-rw-r--r--msd/editor/ds-vnext.pd10
-rw-r--r--msd/editor/expr_scale.pd53
-rw-r--r--msd/editor/gem_links.pd66
-rw-r--r--msd/editor/gem_masses.pd77
-rw-r--r--msd/editor/gem_strings.pd40
-rw-r--r--msd/editor/link-set.pd74
-rw-r--r--msd/editor/link2masses.pd35
-rw-r--r--msd/editor/make_circ.pd89
-rw-r--r--msd/editor/make_rect.pd117
-rw-r--r--msd/editor/mass-set.pd68
-rw-r--r--msd/editor/morelinks.pd234
-rw-r--r--msd/editor/msd-editor.pd1864
-rw-r--r--msd/editor/msd_append.pd248
-rw-r--r--msd/editor/mytri.pd45
-rw-r--r--msd/editor/obj-render.pd141
-rw-r--r--msd/editor/scale-ds2msd.pd42
-rw-r--r--msd/editor/scale-msd2ds.pd42
-rw-r--r--msd/editor/sixpack.pd31
-rw-r--r--msd/editor/structures.pd20
-rw-r--r--msd/msd/01_msdtest.pd92
-rw-r--r--msd/msd/02_msdstring.pd328
-rw-r--r--msd/msd/03_msdwave.pd230
-rw-r--r--msd/msd/Makefile.am51
-rw-r--r--msd/msd/license.txt504
-rw-r--r--msd/msd/main.cpp3
-rw-r--r--msd/msd/msd-help.pd438
-rw-r--r--msd/msd/package.txt4
-rw-r--r--msd/msd2D/01_msd2Dtest.pd168
-rw-r--r--msd/msd2D/02_msd2Dadd.pd463
-rw-r--r--msd/msd2D/03_imsd2Dtest.pd156
-rw-r--r--msd/msd2D/04_msd2Dperf.pd213
-rw-r--r--msd/msd2D/05_msd2DDataStruct.pd117
-rw-r--r--msd/msd2D/06_msd2Dgravit.pd212
-rw-r--r--msd/msd2D/07_sable.pd505
-rw-r--r--msd/msd2D/Makefile.am51
-rw-r--r--msd/msd2D/editor/MOVED1
-rw-r--r--msd/msd2D/lb.pd13
-rw-r--r--msd/msd2D/license.txt504
-rw-r--r--msd/msd2D/main.cpp3
-rw-r--r--msd/msd2D/make_anim.pd204
-rw-r--r--msd/msd2D/msd2D-help.pd582
-rw-r--r--msd/msd2D/package.txt4
-rw-r--r--msd/msd2D/sound_sable.pd67
-rw-r--r--msd/msd2D/structures.pd27
-rw-r--r--msd/msd3D/01_msd3Dtest.pd192
-rw-r--r--msd/msd3D/02_msd3Dperf.pd214
-rw-r--r--msd/msd3D/03_msd3Dmemb.pd207
-rw-r--r--msd/msd3D/04_msd3Dfilet.pd188
-rw-r--r--msd/msd3D/05_msd3Dvline.pd312
-rw-r--r--msd/msd3D/Makefile.am51
-rw-r--r--msd/msd3D/curve16.pd133
-rw-r--r--msd/msd3D/curve2.pd23
-rw-r--r--msd/msd3D/filet.pd106
-rw-r--r--msd/msd3D/license.txt504
-rw-r--r--msd/msd3D/main.cpp3
-rw-r--r--msd/msd3D/msd3D-help.pd567
-rw-r--r--msd/msd3D/package.txt4
-rw-r--r--msd/msd3D/partiel.pd29
-rw-r--r--msd/msdND/build.txt19
-rw-r--r--msd/msdND/license.txt504
-rw-r--r--msd/msdND/main.cpp4
-rw-r--r--msd/msdND/package.txt4
-rwxr-xr-xmsd/src/build.sh32
-rw-r--r--msd/src/msd.h2111
-rw-r--r--msd/utils/draw_link_force.pd94
-rw-r--r--nusmuk-audio/LICENSE.txt290
-rw-r--r--nusmuk-audio/Makefile303
-rw-r--r--nusmuk-audio/README.txt8
-rw-r--r--nusmuk-audio/additive~-help.pd (renamed from additive-help.pd)60
-rw-r--r--nusmuk-audio/additive~.pd (renamed from additive.pd)0
-rw-r--r--nusmuk-audio/bq_coef_bp-help.pd113
-rw-r--r--nusmuk-audio/bq_coef_bp.pd84
-rw-r--r--nusmuk-audio/bq_coef_highshelf-help.pd113
-rw-r--r--nusmuk-audio/bq_coef_highshelf.pd100
-rw-r--r--nusmuk-audio/bq_coef_hip-help.pd113
-rw-r--r--nusmuk-audio/bq_coef_hip.pd104
-rw-r--r--nusmuk-audio/bq_coef_lop-help.pd113
-rw-r--r--nusmuk-audio/bq_coef_lop.pd104
-rw-r--r--nusmuk-audio/bq_coef_lowshelf-help.pd113
-rw-r--r--nusmuk-audio/bq_coef_lowshelf.pd105
-rw-r--r--nusmuk-audio/bq_coef_notch-help.pd113
-rw-r--r--nusmuk-audio/bq_coef_notch.pd86
-rw-r--r--nusmuk-audio/bq_coef_peak-help.pd116
-rw-r--r--nusmuk-audio/bq_coef_peak.pd113
-rw-r--r--nusmuk-audio/bq~-help.pd926
-rw-r--r--nusmuk-audio/bq~.c112
-rw-r--r--nusmuk-audio/compress_limit~-help.pd51
-rw-r--r--nusmuk-audio/compress_limit~.pd45
-rw-r--r--nusmuk-audio/debian/changelog5
-rw-r--r--nusmuk-audio/debian/compat1
-rw-r--r--nusmuk-audio/debian/control26
-rw-r--r--nusmuk-audio/debian/copyright23
-rw-r--r--nusmuk-audio/debian/gbp.conf7
-rw-r--r--nusmuk-audio/debian/links3
-rwxr-xr-xnusmuk-audio/debian/rules17
-rw-r--r--nusmuk-audio/debian/source/format1
-rw-r--r--nusmuk-audio/debian/watch2
-rw-r--r--nusmuk-audio/distortion~-help.pd27
-rw-r--r--nusmuk-audio/distortion~.pd203
-rw-r--r--nusmuk-audio/echo~-help.pd17
-rw-r--r--nusmuk-audio/echo~.pd14
-rw-r--r--nusmuk-audio/examples/analog_synth_emulation.pd237
-rw-r--r--nusmuk-audio/examples/hanning.wav (renamed from hanning.wav)bin2092 -> 2092 bytes
-rw-r--r--nusmuk-audio/granulator~-help.pd (renamed from granulator-help.pd)36
-rw-r--r--nusmuk-audio/granulator~.pd (renamed from granulator.pd)0
-rw-r--r--nusmuk-audio/nusmuk-audio-meta.pd10
-rw-r--r--nusmuk-audio/oscillo~-help.pd (renamed from oscillo~-help.pd)0
-rw-r--r--nusmuk-audio/oscillo~.pd (renamed from oscillo~.pd)0
-rw-r--r--nusmuk-audio/pwm~-help.pd29
-rw-r--r--nusmuk-audio/pwm~.pd176
-rw-r--r--nusmuk-audio/saw~-help.pd16
-rw-r--r--nusmuk-audio/saw~.pd79
-rw-r--r--nusmuk-audio/spatialisation~-help.pd (renamed from spatialisation-help.pd)24
-rw-r--r--nusmuk-audio/spatialisation~.pd (renamed from spatialisation.pd)37
-rw-r--r--nusmuk-audio/tabosc4c~-help.pd104
-rw-r--r--nusmuk-audio/tabosc4c~.c244
-rw-r--r--nusmuk-audio/tabosci~-help.pd258
-rw-r--r--nusmuk-audio/tabosci~.c320
-rw-r--r--nusmuk-audio/tabread4c~-help.pd44
-rw-r--r--nusmuk-audio/tabread4c~.c176
-rw-r--r--nusmuk-utils/LICENSE.txt290
-rw-r--r--nusmuk-utils/Makefile303
-rw-r--r--nusmuk-utils/README.txt8
-rw-r--r--nusmuk-utils/between-help.pd (renamed from between-help.pd)0
-rw-r--r--nusmuk-utils/between.pd (renamed from between.pd)0
-rw-r--r--nusmuk-utils/common.h17
-rw-r--r--nusmuk-utils/debian/changelog5
-rw-r--r--nusmuk-utils/debian/compat1
-rw-r--r--nusmuk-utils/debian/control33
-rw-r--r--nusmuk-utils/debian/copyright23
-rw-r--r--nusmuk-utils/debian/gbp.conf7
-rw-r--r--nusmuk-utils/debian/links3
-rwxr-xr-xnusmuk-utils/debian/rules17
-rw-r--r--nusmuk-utils/debian/source/format1
-rw-r--r--nusmuk-utils/debian/watch2
-rw-r--r--nusmuk-utils/examples/bushmeat.pbank19
-rw-r--r--nusmuk-utils/filtered_random-help.pd47
-rw-r--r--nusmuk-utils/filtered_random.pd63
-rw-r--r--nusmuk-utils/fmod-help.pd9
-rw-r--r--nusmuk-utils/fmod.pd23
-rw-r--r--nusmuk-utils/lb-help.pd19
-rwxr-xr-xnusmuk-utils/lb.pd10
-rw-r--r--nusmuk-utils/lfo-help.pd21
-rw-r--r--nusmuk-utils/lfo.pd61
-rw-r--r--nusmuk-utils/line3-help.pd61
-rw-r--r--nusmuk-utils/line3.c177
-rw-r--r--nusmuk-utils/many_bang-help.pd (renamed from many_bang-help.pd)0
-rw-r--r--nusmuk-utils/many_bang.pd (renamed from many_bang.pd)0
-rw-r--r--nusmuk-utils/nusmuk-utils-meta.pd7
-rw-r--r--nusmuk-utils/once-help.pd13
-rw-r--r--nusmuk-utils/once.pd15
-rw-r--r--nusmuk-utils/p-help.pd8
-rwxr-xr-xnusmuk-utils/p.pd4
-rwxr-xr-xnusmuk-utils/pbank-help.pd562
-rwxr-xr-xnusmuk-utils/pbank.c1368
-rw-r--r--nusmuk-utils/pbank.h14
-rw-r--r--nusmuk-utils/pps-help.pd13
-rw-r--r--nusmuk-utils/pps.pd8
-rwxr-xr-xnusmuk-utils/rand_diff-help.pd18
-rw-r--r--nusmuk-utils/rand_diff.pd34
-rwxr-xr-xnusmuk-utils/randn-help.pd20
-rwxr-xr-xnusmuk-utils/randn.pd49
-rw-r--r--nusmuk-utils/rnd_flow-help.pd27
-rw-r--r--nusmuk-utils/rnd_flow.pd70
-rw-r--r--nusmuk-utils/rnd_metro-help.pd (renamed from rnd_metro-help.pd)0
-rw-r--r--nusmuk-utils/rnd_metro.pd (renamed from rnd_metro.pd)0
-rw-r--r--puremapping/speedlimit-help.pd15
-rw-r--r--puremapping/speedlimit.pd40
179 files changed, 22576 insertions, 278 deletions
diff --git a/distortion-help.pd b/distortion-help.pd
deleted file mode 100644
index c3e8a62..0000000
--- a/distortion-help.pd
+++ /dev/null
@@ -1,35 +0,0 @@
-#N canvas 468 234 684 571 10;
-#X obj 78 262 distortion;
-#X obj 77 302 dac~;
-#X msg 143 133 \$1 20;
-#X obj 143 155 line~;
-#X floatatom 143 109 5 0 0 0 - - -;
-#X obj 77 194 osc~ 80;
-#X obj 198 132 osc~ 30;
-#X floatatom 77 164 5 0 0 0 - - -;
-#X floatatom 198 111 5 0 0 0 - - -;
-#X floatatom 222 157 5 0 0 0 - - -;
-#X obj 199 178 *~ 0;
-#X text 134 24 simple distortion with audio input for the distortion
-ratio;
-#X text 169 51 Left inlet : audio in;
-#X text 168 71 Right inlet : distortion (0 to 1). gives oposit result
-with (-1 to 0);
-#X obj 143 235 min~ 1;
-#X obj 142 211 max~ -1;
-#X text 338 141 dependency : abs~ and pow~;
-#X obj 158 315 oscillo~;
-#X connect 0 0 1 0;
-#X connect 0 0 1 1;
-#X connect 0 0 17 0;
-#X connect 2 0 3 0;
-#X connect 3 0 15 0;
-#X connect 4 0 2 0;
-#X connect 5 0 0 0;
-#X connect 6 0 10 0;
-#X connect 7 0 5 0;
-#X connect 8 0 6 0;
-#X connect 9 0 10 1;
-#X connect 10 0 15 0;
-#X connect 14 0 0 1;
-#X connect 15 0 14 0;
diff --git a/distortion.pd b/distortion.pd
deleted file mode 100644
index 623edf7..0000000
--- a/distortion.pd
+++ /dev/null
@@ -1,22 +0,0 @@
-#N canvas 500 108 372 321 10;
-#X obj 29 217 outlet~;
-#X obj 29 132 /~;
-#X obj 46 104 abs~;
-#X obj 29 181 *~;
-#X obj 46 156 pow~ 2;
-#X obj 30 20 inlet~;
-#X obj 123 52 inlet~;
-#X text 87 20 audio in;
-#X obj 123 97 +~ 1;
-#X text 179 53 distortion (0 to 1);
-#X obj 122 73 *~ -1;
-#X connect 1 0 3 0;
-#X connect 2 0 1 1;
-#X connect 2 0 4 1;
-#X connect 3 0 0 0;
-#X connect 4 0 3 1;
-#X connect 5 0 1 0;
-#X connect 5 0 2 0;
-#X connect 6 0 10 0;
-#X connect 8 0 4 0;
-#X connect 10 0 8 0;
diff --git a/lfo-help.pd b/lfo-help.pd
deleted file mode 100644
index fcadd7f..0000000
--- a/lfo-help.pd
+++ /dev/null
@@ -1,26 +0,0 @@
-#N canvas 77 355 426 472 10;
-#X floatatom 54 100 5 0 0 0 - - -;
-#X obj 54 281 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144
--1 -1 12519 1;
-#X obj 54 252 * 127;
-#X msg 93 128 sin;
-#X msg 100 153 saw;
-#X msg 110 177 tri;
-#X text 114 254 creation arguments:;
-#X text 146 294 2 time grain in milliseconds;
-#X text 144 274 1 period time (ms);
-#X text 152 25 Low Frequency Modulator;
-#X text 105 100 <- time (ms);
-#X text 162 152 <- wave shape;
-#X text 192 173 (default = sin);
-#X msg 175 200 0;
-#X text 208 199 phase;
-#X obj 54 222 lfo 2000 20 ______;
-#X text 144 386 no audio on is neaded !;
-#X connect 0 0 15 0;
-#X connect 2 0 1 0;
-#X connect 3 0 15 0;
-#X connect 4 0 15 0;
-#X connect 5 0 15 0;
-#X connect 13 0 15 1;
-#X connect 15 0 2 0;
diff --git a/lfo.pd b/lfo.pd
deleted file mode 100644
index cc5de83..0000000
--- a/lfo.pd
+++ /dev/null
@@ -1,116 +0,0 @@
-#N canvas 396 93 485 798 10;
-#X obj 13 13 inlet;
-#X obj 285 174 t b b;
-#X obj 204 67 loadbang;
-#X msg 285 218 1;
-#X obj 230 402 table \$0-sin 1024;
-#X obj 230 440 loadbang;
-#X obj 230 467 \$0;
-#X obj 34 556 * 1024;
-#X obj 34 584 tabread \$0-sin;
-#X obj 315 195 \$2;
-#X obj 315 217 moses 1;
-#X msg 315 240 20;
-#X obj 285 315 metro;
-#X obj 15 765 outlet;
-#X obj 127 165 \$1;
-#X msg 219 87 bang;
-#X msg 230 495 \; \$1-sin cosinesum 1024 0.5 -0.5 \;;
-#X obj 158 585 moses 1;
-#X obj 202 609 * -1;
-#X obj 202 633 + 2;
-#X obj 158 560 * 2;
-#N canvas 0 0 804 690 gate 0;
-#X obj 199 96 == 1;
-#X obj 35 39 inlet;
-#X obj 148 39 inlet;
-#X obj 223 142 spigot;
-#X obj 300 143 spigot;
-#X obj 148 189 outlet;
-#X obj 223 39 inlet;
-#X obj 148 141 spigot 1;
-#X obj 300 39 inlet;
-#X obj 260 97 == 2;
-#X obj 337 98 == 3;
-#X connect 0 0 7 1;
-#X connect 1 0 0 0;
-#X connect 1 0 9 0;
-#X connect 1 0 10 0;
-#X connect 2 0 7 0;
-#X connect 3 0 5 0;
-#X connect 4 0 5 0;
-#X connect 6 0 3 0;
-#X connect 7 0 5 0;
-#X connect 8 0 4 0;
-#X connect 9 0 3 1;
-#X connect 10 0 4 1;
-#X restore 15 735 pd gate 3;
-#X msg 13 75 1;
-#X msg 51 75 2;
-#X msg 89 74 3;
-#X obj 13 42 route sin tri saw;
-#X obj 315 282 f;
-#X obj 127 369 /;
-#X obj 127 323 pack f f;
-#X msg 127 347 \$2 \$1;
-#X obj 110 430 +;
-#X obj 110 408 f;
-#X obj 110 464 moses 1;
-#X obj 154 486 - 1;
-#X obj 204 113 t b b;
-#X obj 73 495 f;
-#X obj 336 20 inlet;
-#X obj 336 78 t b f;
-#X msg 353 48 0;
-#X floatatom 152 517 5 0 0 0 - - -;
-#X obj 127 199 max 1;
-#X connect 0 0 25 0;
-#X connect 1 0 3 0;
-#X connect 1 1 9 0;
-#X connect 2 0 34 0;
-#X connect 3 0 12 0;
-#X connect 5 0 6 0;
-#X connect 6 0 16 0;
-#X connect 7 0 8 0;
-#X connect 8 0 21 1;
-#X connect 9 0 10 0;
-#X connect 10 0 11 0;
-#X connect 10 1 26 0;
-#X connect 11 0 26 0;
-#X connect 12 0 31 0;
-#X connect 14 0 40 0;
-#X connect 15 0 34 0;
-#X connect 17 0 21 2;
-#X connect 17 1 18 0;
-#X connect 18 0 19 0;
-#X connect 19 0 21 2;
-#X connect 20 0 17 0;
-#X connect 21 0 13 0;
-#X connect 22 0 21 0;
-#X connect 23 0 21 0;
-#X connect 24 0 21 0;
-#X connect 25 0 22 0;
-#X connect 25 1 23 0;
-#X connect 25 2 24 0;
-#X connect 25 3 14 0;
-#X connect 26 0 12 1;
-#X connect 26 0 28 1;
-#X connect 27 0 30 1;
-#X connect 28 0 29 0;
-#X connect 29 0 27 0;
-#X connect 30 0 32 0;
-#X connect 31 0 30 0;
-#X connect 32 0 31 1;
-#X connect 32 0 35 0;
-#X connect 32 1 33 0;
-#X connect 33 0 32 0;
-#X connect 34 0 14 0;
-#X connect 34 1 1 0;
-#X connect 35 0 7 0;
-#X connect 35 0 20 0;
-#X connect 35 0 21 3;
-#X connect 36 0 37 0;
-#X connect 37 0 34 0;
-#X connect 37 1 31 1;
-#X connect 38 0 37 0;
-#X connect 40 0 28 0;
diff --git a/msd/README.txt b/msd/README.txt
new file mode 100644
index 0000000..4603160
--- /dev/null
+++ b/msd/README.txt
@@ -0,0 +1,61 @@
+--------------------------
+msd - Mass Spring Damper modeling for Pd - Max/MSP
+--------------------------
+--------------------------
+07.06.2006
+
+Copyright (C) 2006 Nicolas Montgermont
+Written by Nicolas Montgermont for a Master's train in Acoustic,
+Signal processing and Computing Applied to Music (ATIAM, Paris 6)
+at La Kitchen supervised by Cyrille Henry.
+
+Optimized by Thomas Grill for Flext
+Based on Pure Data by Miller Puckette and others
+Based on pmpd by Cyrille Henry
+
+Contact : Nicolas Montgermont, nicolas_montgermont@yahoo.fr
+ Cyrille Henry, Cyrille.Henry@la-kitchen.fr
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+--------------------------
+# Version 0.07 -- 17.05.2005
+initial final vertion
+
+Version 0.08 -- 20070517
+add somes get messages
+--------------------------
+BUILD -- msd, msd2D, msd3D
+
+To build any of the predefined msd objects you need flext from Thomas Grill. You must compile and install flext following the instructions, and then compile and install msd.
+
+For example to build the msd2D object in pd with gcc on Linux, you must compile and install flext first, and then do
+
+cd EXTERNALSDIR/nusmuk/msd2D
+sudo bash ../../grill/flext/build.sh pd gcc
+sudo bash ../../grill/flext/build.sh pd gcc install
+
+It will compile and install the msd external in the directory you previously defined in flext.
+
+------------------
+BUILD -- msdND
+
+msd can virtually be build for any number of dimension. To do that you must edit the main.cpp and package.txt files in the msdND subfolder. Follow the instructions of the build.txt file also in the msdND folder.
+
+--------------------------
+USE -- msd, msd2D, msd3D
+
+To start open the 01_msdtest.pd file under pd or look at the help-msd.pd patch.
+
diff --git a/msd/editor/README b/msd/editor/README
new file mode 100644
index 0000000..e6253db
--- /dev/null
+++ b/msd/editor/README
@@ -0,0 +1,14 @@
+msd-editor
+------------
+
+patched by Frank Barknecht <fbar@footils.org> with a big hand from Nicolas
+Montgermont <montgermont@la-kitchen.fr> who wrote the msd2D and msd3D externals
+required for using this patch. GEM is used to provide an alternative
+visualization, but it is not required for the patch to work.
+
+If you want to export the messages to msd2d, that are created, you also need a
+[prepend] external, preferably the one from the Cyclone library.
+
+Thanks Nicolas for a great external colletion.
+
+msd-editor.pd is the patch to open, further documentation is inside.
diff --git a/msd/editor/arial.ttf b/msd/editor/arial.ttf
new file mode 100644
index 0000000..fc0a41b
--- /dev/null
+++ b/msd/editor/arial.ttf
Binary files differ
diff --git a/msd/editor/cone.obj b/msd/editor/cone.obj
new file mode 100644
index 0000000..7ff7446
--- /dev/null
+++ b/msd/editor/cone.obj
@@ -0,0 +1,70 @@
+# Exported from Wings 3D 0.98.29b
+mtllib cone.mtl
+o cone1
+#17 vertices, 30 faces
+v 1.00000000 -1.00000000 0.0000000e+0
+v 0.92387953 -1.00000000 0.38268343
+v 0.70710678 -1.00000000 0.70710678
+v 0.38268343 -1.00000000 0.92387953
+v 6.1230318e-17 -1.00000000 1.00000000
+v -0.38268343 -1.00000000 0.92387953
+v -0.70710678 -1.00000000 0.70710678
+v -0.92387953 -1.00000000 0.38268343
+v -1.00000000 -1.00000000 1.2246064e-16
+v -0.92387953 -1.00000000 -0.38268343
+v -0.70710678 -1.00000000 -0.70710678
+v -0.38268343 -1.00000000 -0.92387953
+v -1.8369095e-16 -1.00000000 -1.00000000
+v 0.38268343 -1.00000000 -0.92387953
+v 0.70710678 -1.00000000 -0.70710678
+v 0.92387953 -1.00000000 -0.38268343
+v 0.0000000e+0 1.00000000 0.0000000e+0
+vn 0.99770979 -6.7640061e-2 -1.2578715e-16
+vn 0.59046943 -0.76910745 0.24458044
+vn 0.45192573 -0.76910745 0.45192573
+vn 0.24458044 -0.76910745 0.59046943
+vn 0.0000000e+0 -0.76910745 0.63911950
+vn -0.24458044 -0.76910745 0.59046943
+vn -0.45192573 -0.76910745 0.45192573
+vn -0.77971445 -0.53641108 0.32296830
+vn -0.99770979 -6.7640061e-2 1.4151054e-16
+vn -0.59046943 -0.76910745 -0.24458044
+vn -0.45192573 -0.76910745 -0.45192573
+vn -0.24458044 -0.76910745 -0.59046943
+vn -8.0577559e-17 -0.76910745 -0.63911950
+vn 0.24458044 -0.76910745 -0.59046943
+vn 0.45192573 -0.76910745 -0.45192573
+vn 0.77971445 -0.53641108 -0.32296830
+vn -3.1518972e-17 1.00000000 9.0617045e-17
+g cone1_default
+usemtl default
+f 1//1 17//17 2//2
+f 2//2 16//16 1//1
+f 2//2 17//17 3//3
+f 3//3 15//15 2//2
+f 3//3 17//17 4//4
+f 4//4 14//14 3//3
+f 4//4 17//17 5//5
+f 5//5 13//13 4//4
+f 5//5 17//17 6//6
+f 6//6 12//12 5//5
+f 6//6 17//17 7//7
+f 7//7 11//11 6//6
+f 7//7 17//17 8//8
+f 8//8 10//10 7//7
+f 8//8 17//17 9//9
+f 9//9 10//10 8//8
+f 9//9 17//17 10//10
+f 10//10 17//17 11//11
+f 11//11 7//7 10//10
+f 11//11 17//17 12//12
+f 12//12 6//6 11//11
+f 12//12 17//17 13//13
+f 13//13 5//5 12//12
+f 13//13 17//17 14//14
+f 14//14 4//4 13//13
+f 14//14 17//17 15//15
+f 15//15 3//3 14//14
+f 15//15 17//17 16//16
+f 16//16 2//2 15//15
+f 16//16 17//17 1//1
diff --git a/msd/editor/countto.pd b/msd/editor/countto.pd
new file mode 100644
index 0000000..dd621e9
--- /dev/null
+++ b/msd/editor/countto.pd
@@ -0,0 +1,19 @@
+#N canvas 0 0 450 300 10;
+#X obj 110 106 until;
+#X obj 108 141 f 0;
+#X obj 140 141 + 1;
+#X obj 110 193 outlet;
+#X text 207 35 from \, to;
+#X obj 113 34 inlet;
+#X obj 112 59 t a a;
+#X msg 111 80 \$2;
+#X msg 177 110 \$1;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 1 0 3 0;
+#X connect 2 0 1 1;
+#X connect 5 0 6 0;
+#X connect 6 0 7 0;
+#X connect 6 1 8 0;
+#X connect 7 0 0 0;
+#X connect 8 0 1 1;
diff --git a/msd/editor/curve2.pd b/msd/editor/curve2.pd
new file mode 100644
index 0000000..0d7da1b
--- /dev/null
+++ b/msd/editor/curve2.pd
@@ -0,0 +1,18 @@
+#N canvas 409 354 379 280 10;
+#X obj 31 123 GEMglBegin;
+#X obj 86 100 GLdefine GL_LINE_STRIP;
+#X obj 31 13 inlet;
+#X obj 86 77 loadbang;
+#X obj 159 13 inlet;
+#X obj 221 12 inlet;
+#X obj 31 200 GEMglEnd;
+#X obj 31 151 GEMglVertex3fv;
+#X obj 31 175 GEMglVertex3fv;
+#X connect 0 0 7 0;
+#X connect 1 0 0 1;
+#X connect 2 0 0 0;
+#X connect 3 0 1 0;
+#X connect 4 0 7 1;
+#X connect 5 0 8 1;
+#X connect 7 0 8 0;
+#X connect 8 0 6 0;
diff --git a/msd/editor/ds-next.pd b/msd/editor/ds-next.pd
new file mode 100644
index 0000000..14f9653
--- /dev/null
+++ b/msd/editor/ds-next.pd
@@ -0,0 +1,10 @@
+#N canvas 0 0 450 300 10;
+#X obj 138 76 inlet;
+#X obj 138 214 outlet;
+#X obj 138 111 t b;
+#X msg 138 168 next;
+#X obj 138 140 del 0;
+#X connect 0 0 2 0;
+#X connect 2 0 4 0;
+#X connect 3 0 1 0;
+#X connect 4 0 3 0;
diff --git a/msd/editor/ds-vnext.pd b/msd/editor/ds-vnext.pd
new file mode 100644
index 0000000..93a9d81
--- /dev/null
+++ b/msd/editor/ds-vnext.pd
@@ -0,0 +1,10 @@
+#N canvas 0 0 450 300 10;
+#X obj 138 76 inlet;
+#X obj 138 214 outlet;
+#X obj 138 111 t b;
+#X msg 138 168 vnext 1;
+#X obj 138 140 del 1;
+#X connect 0 0 2 0;
+#X connect 2 0 4 0;
+#X connect 3 0 1 0;
+#X connect 4 0 3 0;
diff --git a/msd/editor/expr_scale.pd b/msd/editor/expr_scale.pd
new file mode 100644
index 0000000..fe55fa5
--- /dev/null
+++ b/msd/editor/expr_scale.pd
@@ -0,0 +1,53 @@
+#N canvas 236 224 1026 642 10;
+#X obj 166 328 expr ($f1-$f2)*($f4-$f5)/($f2-$f3)+$f4;
+#X obj 252 286 f \$1;
+#X obj 402 288 f \$4;
+#X obj 352 284 f \$3;
+#X obj 302 284 f \$2;
+#X obj 252 197 inlet;
+#X obj 302 197 inlet;
+#X obj 352 197 inlet;
+#X obj 402 197 inlet;
+#X obj 166 129 inlet;
+#X obj 166 369 outlet;
+#X text 510 173 ARGS;
+#X text 520 197 1: input_low_border;
+#X text 520 219 2: input_high_border;
+#X text 520 245 3: output_low_border;
+#X text 520 267 4: output_high_border;
+#X text 229 149 scale [from_low \, from_hi] to [to_low \, to_hi];
+#X obj 273 243 t b;
+#X obj 298 171 loadbang;
+#X obj 166 156 t f b;
+#N canvas 0 0 1090 810 once 0;
+#X obj 86 53 inlet;
+#X obj 92 185 outlet;
+#X obj 81 146 spigot 1;
+#X obj 112 91 t b a;
+#X msg 131 123 0;
+#X connect 0 0 3 0;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 3 1 2 0;
+#X connect 4 0 2 1;
+#X restore 196 186 pd once;
+#X text 174 391 [pc once] is only used \, because autogenerated objects
+don't receive loadbangs;
+#X connect 0 0 10 0;
+#X connect 1 0 0 1;
+#X connect 2 0 0 4;
+#X connect 3 0 0 3;
+#X connect 4 0 0 2;
+#X connect 5 0 1 0;
+#X connect 6 0 4 0;
+#X connect 7 0 3 0;
+#X connect 8 0 2 0;
+#X connect 9 0 19 0;
+#X connect 17 0 1 0;
+#X connect 17 0 3 0;
+#X connect 17 0 4 0;
+#X connect 17 0 2 0;
+#X connect 18 0 17 0;
+#X connect 19 0 0 0;
+#X connect 19 1 20 0;
+#X connect 20 0 17 0;
diff --git a/msd/editor/gem_links.pd b/msd/editor/gem_links.pd
new file mode 100644
index 0000000..3bff241
--- /dev/null
+++ b/msd/editor/gem_links.pd
@@ -0,0 +1,66 @@
+#N canvas 375 164 720 697 10;
+#X obj 141 31 inlet;
+#X obj 109 389 separator;
+#X obj 147 166 t b f;
+#X obj 178 210 pack 0 0 0;
+#X obj 269 213 pack 0 0 0;
+#X obj 141 97 unpack 0 0 0 0 0;
+#X obj 282 324 inlet;
+#X obj 109 364 spigot;
+#X msg 281 302 1;
+#X obj 281 277 loadbang;
+#N canvas 0 0 450 300 demux 0;
+#X obj 91 69 inlet;
+#X obj 255 73 inlet;
+#X obj 223 106 select 0;
+#X obj 73 213 spigot 1;
+#X obj 165 219 spigot 0;
+#X obj 141 188 unpack 1 0;
+#X obj 96 255 outlet;
+#X obj 173 257 outlet;
+#X msg 174 140 1 0;
+#X msg 216 140 0 1;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 2 0 8 0;
+#X connect 2 1 9 0;
+#X connect 3 0 6 0;
+#X connect 4 0 7 0;
+#X connect 5 0 3 1;
+#X connect 5 1 4 1;
+#X connect 8 0 5 0;
+#X connect 9 0 5 0;
+#X restore 141 64 pd demux;
+#X obj 192 37 r MSD-TYPE;
+#X obj 280 97 unpack 0 0 0 0 0 0 0;
+#X obj 156 432 curve2;
+#X obj 125 308 gemhead 40;
+#X obj 70 257 loadbang;
+#X msg 70 282 0;
+#X connect 0 0 10 0;
+#X connect 1 0 13 0;
+#X connect 2 0 14 0;
+#X connect 2 1 3 0;
+#X connect 3 0 13 1;
+#X connect 4 0 13 2;
+#X connect 5 1 2 0;
+#X connect 5 2 3 1;
+#X connect 5 3 4 0;
+#X connect 5 4 4 1;
+#X connect 6 0 7 1;
+#X connect 7 0 1 0;
+#X connect 8 0 7 1;
+#X connect 9 0 8 0;
+#X connect 10 0 5 0;
+#X connect 10 1 12 0;
+#X connect 11 0 10 1;
+#X connect 12 1 2 0;
+#X connect 12 2 3 1;
+#X connect 12 3 3 2;
+#X connect 12 4 4 0;
+#X connect 12 5 4 1;
+#X connect 12 6 4 2;
+#X connect 14 0 7 0;
+#X connect 15 0 16 0;
+#X connect 16 0 14 0;
diff --git a/msd/editor/gem_masses.pd b/msd/editor/gem_masses.pd
new file mode 100644
index 0000000..08a0827
--- /dev/null
+++ b/msd/editor/gem_masses.pd
@@ -0,0 +1,77 @@
+#N canvas 28 301 667 612 10;
+#X obj 141 31 inlet;
+#X obj 150 424 translateXYZ;
+#X obj 150 393 separator;
+#X obj 166 162 t b f;
+#X msg 47 325 draw line;
+#X obj 48 300 loadbang;
+#X obj 141 104 unpack 0 0 0;
+#X obj 338 297 inlet;
+#X obj 150 362 spigot;
+#X msg 337 275 1;
+#N canvas 0 0 450 300 demux 0;
+#X obj 91 69 inlet;
+#X obj 255 73 inlet;
+#X obj 223 106 select 0;
+#X obj 73 213 spigot 1;
+#X obj 165 219 spigot 0;
+#X obj 141 188 unpack 1 0;
+#X obj 96 255 outlet;
+#X obj 173 257 outlet;
+#X msg 174 140 1 0;
+#X msg 216 140 0 1;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 2 0 8 0;
+#X connect 2 1 9 0;
+#X connect 3 0 6 0;
+#X connect 4 0 7 0;
+#X connect 5 0 3 1;
+#X connect 5 1 4 1;
+#X connect 8 0 5 0;
+#X connect 9 0 5 0;
+#X restore 141 71 pd demux;
+#X obj 192 44 r MSD-TYPE;
+#X obj 238 104 unpack 0 0 0 0;
+#X floatatom 308 400 5 0 0 0 - - -;
+#X obj 126 479 square 0.025;
+#X msg 259 469 text \$1;
+#X obj 279 561 text3d;
+#X obj 388 503 loadbang;
+#X msg 385 528 2;
+#X obj 391 395 inlet mass-id;
+#X obj 211 516 spigot;
+#X obj 150 295 gemhead 40;
+#X msg 107 258 0;
+#X obj 107 227 loadbang;
+#X connect 0 0 10 0;
+#X connect 1 0 14 0;
+#X connect 1 0 20 0;
+#X connect 2 0 1 0;
+#X connect 3 0 21 0;
+#X connect 3 1 1 1;
+#X connect 5 0 4 0;
+#X connect 6 0 15 0;
+#X connect 6 1 3 0;
+#X connect 6 2 1 2;
+#X connect 7 0 8 1;
+#X connect 8 0 2 0;
+#X connect 9 0 8 1;
+#X connect 10 0 6 0;
+#X connect 10 1 12 0;
+#X connect 11 0 10 1;
+#X connect 12 0 15 0;
+#X connect 12 1 3 0;
+#X connect 12 2 1 2;
+#X connect 12 3 1 3;
+#X connect 13 0 14 1;
+#X connect 15 0 16 0;
+#X connect 17 0 18 0;
+#X connect 18 0 16 1;
+#X connect 19 0 20 1;
+#X connect 19 0 16 1;
+#X connect 20 0 16 0;
+#X connect 21 0 8 0;
+#X connect 22 0 21 0;
+#X connect 23 0 22 0;
diff --git a/msd/editor/gem_strings.pd b/msd/editor/gem_strings.pd
new file mode 100644
index 0000000..c84aaba
--- /dev/null
+++ b/msd/editor/gem_strings.pd
@@ -0,0 +1,40 @@
+#N canvas 76 70 906 731 10;
+#X obj 141 31 inlet;
+#X obj 109 369 separator;
+#X obj 147 166 t b f;
+#X obj 229 116 - 250;
+#X obj 147 110 - 250;
+#X obj 147 140 / 100;
+#X obj 229 143 / -100;
+#X obj 352 114 - 250;
+#X obj 287 116 - 250;
+#X obj 287 151 / 100;
+#X obj 352 143 / -100;
+#X obj 156 432 curve 2;
+#X obj 178 210 pack 0 0 0;
+#X obj 255 189 pack 0 0 0;
+#X obj 141 62 unpack 0 0 0 0 0;
+#X msg 65 279 0;
+#X obj 65 248 loadbang;
+#X obj 125 308 gemhead 40;
+#X connect 0 0 14 0;
+#X connect 1 0 11 0;
+#X connect 2 0 17 0;
+#X connect 2 1 12 0;
+#X connect 3 0 6 0;
+#X connect 4 0 5 0;
+#X connect 5 0 2 0;
+#X connect 6 0 12 1;
+#X connect 7 0 10 0;
+#X connect 8 0 9 0;
+#X connect 9 0 13 0;
+#X connect 10 0 13 1;
+#X connect 12 0 11 1;
+#X connect 13 0 11 2;
+#X connect 14 1 4 0;
+#X connect 14 2 3 0;
+#X connect 14 3 8 0;
+#X connect 14 4 7 0;
+#X connect 15 0 17 0;
+#X connect 16 0 15 0;
+#X connect 17 0 1 0;
diff --git a/msd/editor/link-set.pd b/msd/editor/link-set.pd
new file mode 100644
index 0000000..ec9edda
--- /dev/null
+++ b/msd/editor/link-set.pd
@@ -0,0 +1,74 @@
+#N canvas 449 81 747 726 10;
+#X obj 251 159 pack 0 p;
+#X obj 251 187 route \$1;
+#X obj 251 100 t p p;
+#X obj 90 229 spigot;
+#X msg 132 203 1;
+#X obj 216 212 t b p;
+#X obj 90 257 route \$1;
+#X obj 147 227 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X obj 90 165 r linkspositions;
+#X text 81 137 lid \, x1 \, y1 \, x2 \, y2;
+#X obj 251 131 get liaison lid;
+#X text 261 220 Select pointer with lid matching \$1;
+#X obj 90 526 set liaison x1 y1 x2 y2;
+#X obj 251 73 r myliapointer;
+#X obj 90 337 unpack 0 0 0 0;
+#X obj 90 497 scale-msd2ds;
+#X obj 181 496 scale-msd2ds;
+#N canvas 0 0 450 300 demux 0;
+#X obj 91 69 inlet;
+#X obj 255 73 inlet;
+#X obj 223 106 select 0;
+#X obj 73 213 spigot 1;
+#X obj 165 219 spigot 0;
+#X obj 141 188 unpack 1 0;
+#X obj 96 255 outlet;
+#X obj 173 257 outlet;
+#X msg 174 140 1 0;
+#X msg 216 140 0 1;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 2 0 8 0;
+#X connect 2 1 9 0;
+#X connect 3 0 6 0;
+#X connect 4 0 7 0;
+#X connect 5 0 3 1;
+#X connect 5 1 4 1;
+#X connect 8 0 5 0;
+#X connect 9 0 5 0;
+#X restore 90 292 pd demux;
+#X obj 272 340 unpack 0 0 0 0 0 0;
+#X text 198 336 msd2D;
+#X text 410 338 msd3D: skip Z;
+#X obj 157 255 r MSD-TYPE;
+#X connect 0 0 1 0;
+#X connect 1 0 5 0;
+#X connect 2 0 10 0;
+#X connect 2 1 0 1;
+#X connect 3 0 6 0;
+#X connect 4 0 3 1;
+#X connect 4 0 7 0;
+#X connect 5 0 4 0;
+#X connect 5 1 12 4;
+#X connect 6 0 17 0;
+#X connect 8 0 3 0;
+#X connect 10 0 0 0;
+#X connect 13 0 2 0;
+#X connect 14 0 15 0;
+#X connect 14 1 15 1;
+#X connect 14 2 16 0;
+#X connect 14 3 16 1;
+#X connect 15 0 12 0;
+#X connect 15 1 12 1;
+#X connect 16 0 12 2;
+#X connect 16 1 12 3;
+#X connect 17 0 14 0;
+#X connect 17 1 18 0;
+#X connect 18 0 15 0;
+#X connect 18 1 15 1;
+#X connect 18 3 16 0;
+#X connect 18 4 16 1;
+#X connect 21 0 17 1;
diff --git a/msd/editor/link2masses.pd b/msd/editor/link2masses.pd
new file mode 100644
index 0000000..b685745
--- /dev/null
+++ b/msd/editor/link2masses.pd
@@ -0,0 +1,35 @@
+#N canvas 567 387 697 434 10;
+#X obj 42 51 inlet;
+#X obj 42 83 t a b;
+#X obj 360 209 append liaison mid1 x1 y1;
+#X obj 530 186 pointer;
+#X msg 530 157 traverse pd-data \, bang;
+#X obj 42 118 unpack p p;
+#X obj 360 158 get mass mid x y;
+#X obj 42 177 get mass mid x y;
+#X text 199 24 Link two masses with a link in [pd data];
+#X obj 178 55 inlet;
+#X text 227 54 List: K \, D \, sid \, P \, Lmin \, Lmax;
+#X obj 42 249 set liaison mid2 x2 y2 K D sid P Lmin Lmax;
+#X obj 178 89 unpack 0 0 0 0 0 0;
+#X connect 0 0 1 0;
+#X connect 1 0 5 0;
+#X connect 1 1 4 0;
+#X connect 2 0 11 9;
+#X connect 3 0 2 3;
+#X connect 4 0 3 0;
+#X connect 5 0 7 0;
+#X connect 5 1 6 0;
+#X connect 6 0 2 0;
+#X connect 6 1 2 1;
+#X connect 6 2 2 2;
+#X connect 7 0 11 0;
+#X connect 7 1 11 1;
+#X connect 7 2 11 2;
+#X connect 9 0 12 0;
+#X connect 12 0 11 3;
+#X connect 12 1 11 4;
+#X connect 12 2 11 5;
+#X connect 12 3 11 6;
+#X connect 12 4 11 7;
+#X connect 12 5 11 8;
diff --git a/msd/editor/make_circ.pd b/msd/editor/make_circ.pd
new file mode 100644
index 0000000..839f493
--- /dev/null
+++ b/msd/editor/make_circ.pd
@@ -0,0 +1,89 @@
+#N canvas 496 414 573 483 10;
+#X obj 79 355 pack 0 0;
+#X obj 79 388 outlet;
+#X obj 235 67 unpack 0 0 0 0;
+#X obj 235 233 s \$0-x0;
+#X obj 274 205 s \$0-y0;
+#X obj 312 173 s \$0-radius;
+#X obj 352 150 s \$0-masses;
+#X obj 235 43 inlet;
+#X obj 79 34 inlet;
+#X obj 130 332 + 0;
+#X obj 149 304 r \$0-y0;
+#X obj 79 330 + 0;
+#X obj 95 304 r \$0-x0;
+#N canvas 484 634 450 300 1028-turnme 0;
+#X obj 119 48 inlet;
+#X obj 119 243 outlet;
+#X obj 135 77 r \$0-masses;
+#X obj 254 169 r \$0-radius;
+#X obj 119 195 expr $f2 * sin($f1) \; $f2 * cos($f1);
+#X obj 119 102 / 1;
+#X obj 254 242 outlet;
+#X obj 119 134 * 6.28319;
+#X text 192 132 2 * M_PI;
+#X connect 0 0 5 0;
+#X connect 2 0 5 1;
+#X connect 3 0 4 1;
+#X connect 4 0 1 0;
+#X connect 4 1 6 0;
+#X connect 5 0 7 0;
+#X connect 7 0 4 0;
+#X restore 79 122 pd \$0-turnme;
+#N canvas 0 0 723 519 1028-count 0;
+#X text 294 126 count y;
+#N canvas 0 0 450 300 1028-count 0;
+#X obj 112 28 inlet;
+#X obj 116 96 f 0;
+#X obj 156 98 + 1;
+#X obj 178 52 inlet;
+#X msg 175 73 0;
+#X obj 118 122 outlet;
+#X obj 112 66 until;
+#X connect 0 0 6 0;
+#X connect 1 0 2 0;
+#X connect 1 0 5 0;
+#X connect 2 0 1 1;
+#X connect 3 0 4 0;
+#X connect 4 0 1 1;
+#X connect 6 0 1 0;
+#X restore 237 228 pd \$0-count;
+#X obj 237 103 inlet;
+#X obj 237 371 outlet;
+#X obj 237 130 t b b;
+#X obj 262 176 r \$0-masses;
+#X obj 237 197 f 1;
+#X connect 1 0 3 0;
+#X connect 2 0 4 0;
+#X connect 4 0 6 0;
+#X connect 4 1 1 1;
+#X connect 5 0 6 1;
+#X connect 6 0 1 0;
+#X restore 79 80 pd \$0-count;
+#X obj 235 125 f \$1;
+#X obj 274 124 f \$2;
+#X obj 312 124 f \$3;
+#X obj 352 124 f \$4;
+#X obj 352 67 loadbang;
+#X connect 0 0 1 0;
+#X connect 2 0 15 0;
+#X connect 2 1 16 0;
+#X connect 2 2 17 0;
+#X connect 2 3 18 0;
+#X connect 7 0 2 0;
+#X connect 8 0 14 0;
+#X connect 9 0 0 1;
+#X connect 10 0 9 1;
+#X connect 11 0 0 0;
+#X connect 12 0 11 1;
+#X connect 13 0 11 0;
+#X connect 13 1 9 0;
+#X connect 14 0 13 0;
+#X connect 15 0 3 0;
+#X connect 16 0 4 0;
+#X connect 17 0 5 0;
+#X connect 18 0 6 0;
+#X connect 19 0 18 0;
+#X connect 19 0 17 0;
+#X connect 19 0 16 0;
+#X connect 19 0 15 0;
diff --git a/msd/editor/make_rect.pd b/msd/editor/make_rect.pd
new file mode 100644
index 0000000..57bc285
--- /dev/null
+++ b/msd/editor/make_rect.pd
@@ -0,0 +1,117 @@
+#N canvas 253 193 699 400 10;
+#X obj 77 53 inlet;
+#X obj 298 50 inlet;
+#X obj 298 77 unpack 0 0 0 0 0 0;
+#X obj 259 123 f \$1;
+#X obj 298 122 f \$2;
+#X obj 336 122 f \$3;
+#X obj 376 122 f \$4;
+#X obj 412 122 f \$5;
+#X obj 259 260 s \$0-x0;
+#X obj 448 122 f \$6;
+#X obj 298 239 s \$0-y0;
+#X obj 336 206 s \$0-xgap;
+#X obj 412 164 s \$0-xsteps;
+#X obj 448 143 s \$0-ysteps;
+#X obj 376 185 s \$0-ygap;
+#X obj 77 226 pack 0 0;
+#X obj 77 260 outlet;
+#X obj 77 129 t b f;
+#N canvas 0 0 490 471 1002-countx 0;
+#X obj 149 231 r \$0-x0;
+#X obj 126 258 + \$1;
+#X obj 126 200 * \$3;
+#X obj 149 171 r \$0-xgap;
+#X obj 126 115 f \$5;
+#X obj 149 92 r \$0-xsteps;
+#X text 194 49 count x;
+#X obj 126 23 inlet;
+#N canvas 0 0 450 300 1002-count 0;
+#X obj 112 28 inlet;
+#X obj 116 96 f 0;
+#X obj 156 98 + 1;
+#X obj 178 52 inlet;
+#X msg 175 73 0;
+#X obj 118 122 outlet;
+#X obj 112 66 until;
+#X connect 0 0 6 0;
+#X connect 1 0 2 0;
+#X connect 1 0 5 0;
+#X connect 2 0 1 1;
+#X connect 3 0 4 0;
+#X connect 4 0 1 1;
+#X connect 6 0 1 0;
+#X restore 126 146 pd \$0-count;
+#X obj 126 284 outlet;
+#X obj 126 48 t b b;
+#X connect 0 0 1 1;
+#X connect 1 0 9 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 1;
+#X connect 4 0 8 0;
+#X connect 5 0 4 1;
+#X connect 7 0 10 0;
+#X connect 8 0 2 0;
+#X connect 10 0 4 0;
+#X connect 10 1 8 1;
+#X restore 77 172 pd \$0-countx;
+#N canvas 0 0 723 519 1002-county 0;
+#X obj 260 174 r \$0-ysteps;
+#X obj 260 253 r \$0-ygap;
+#X obj 260 313 r \$0-y0;
+#X obj 237 340 + \$2;
+#X obj 237 282 * \$4;
+#X obj 237 197 f \$6;
+#X text 294 126 count y;
+#N canvas 0 0 450 300 1002-count 0;
+#X obj 112 28 inlet;
+#X obj 116 96 f 0;
+#X obj 156 98 + 1;
+#X obj 178 52 inlet;
+#X msg 175 73 0;
+#X obj 118 122 outlet;
+#X obj 112 66 until;
+#X connect 0 0 6 0;
+#X connect 1 0 2 0;
+#X connect 1 0 5 0;
+#X connect 2 0 1 1;
+#X connect 3 0 4 0;
+#X connect 4 0 1 1;
+#X connect 6 0 1 0;
+#X restore 237 228 pd \$0-count;
+#X obj 237 103 inlet;
+#X obj 237 371 outlet;
+#X obj 237 130 t b b;
+#X connect 0 0 5 1;
+#X connect 1 0 4 1;
+#X connect 2 0 3 1;
+#X connect 3 0 9 0;
+#X connect 4 0 3 0;
+#X connect 5 0 7 0;
+#X connect 7 0 4 0;
+#X connect 8 0 10 0;
+#X connect 10 0 5 0;
+#X connect 10 1 7 1;
+#X restore 77 100 pd \$0-county;
+#X obj 77 76 t b;
+#X text 452 208 Args;
+#X connect 0 0 20 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 2 1 4 0;
+#X connect 2 2 5 0;
+#X connect 2 3 6 0;
+#X connect 2 4 7 0;
+#X connect 2 5 9 0;
+#X connect 3 0 8 0;
+#X connect 4 0 10 0;
+#X connect 5 0 11 0;
+#X connect 6 0 14 0;
+#X connect 7 0 12 0;
+#X connect 9 0 13 0;
+#X connect 15 0 16 0;
+#X connect 17 0 18 0;
+#X connect 17 1 15 1;
+#X connect 18 0 15 0;
+#X connect 19 0 17 0;
+#X connect 20 0 19 0;
diff --git a/msd/editor/mass-set.pd b/msd/editor/mass-set.pd
new file mode 100644
index 0000000..1c53605
--- /dev/null
+++ b/msd/editor/mass-set.pd
@@ -0,0 +1,68 @@
+#N canvas 471 153 686 707 10;
+#X obj 251 159 pack 0 p;
+#X obj 251 187 route \$1;
+#X obj 118 383 set mass x y;
+#X obj 251 100 t p p;
+#X obj 251 131 get mass mid;
+#X text 261 220 Select pointer with mid matching \$1;
+#X obj 91 229 spigot;
+#X msg 133 203 1;
+#X obj 216 212 t b p;
+#X obj 91 165 r masspositions;
+#X text 94 145 mid \, x \, y;
+#X obj 91 291 route \$1;
+#X obj 148 227 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X obj 251 73 r mypointer;
+#X obj 263 348 pointer;
+#X obj 307 651 s pointer2msd;
+#X obj 91 261 t b a;
+#X obj 263 320 spigot;
+#X msg 305 294 1;
+#X obj 320 318 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X obj 263 274 r pollpos;
+#X obj 263 453 pack 0 0 0 0;
+#X obj 263 397 get mass mob mid x y;
+#X obj 263 478 route 0;
+#X text 320 478 = is a mobile mass \, don't set positions for these
+;
+#X msg 307 536 posX \$2 \$3;
+#X msg 327 562 posY \$2 \$4;
+#X obj 39 355 scale-msd2ds;
+#X obj 337 422 scale-ds2msd;
+#X msg 95 323 \$1 \$2;
+#X connect 0 0 1 0;
+#X connect 1 0 8 0;
+#X connect 3 0 4 0;
+#X connect 3 1 0 1;
+#X connect 4 0 0 0;
+#X connect 6 0 16 0;
+#X connect 7 0 6 1;
+#X connect 7 0 12 0;
+#X connect 8 0 7 0;
+#X connect 8 0 18 0;
+#X connect 8 1 2 2;
+#X connect 8 1 14 1;
+#X connect 9 0 6 0;
+#X connect 11 0 29 0;
+#X connect 13 0 3 0;
+#X connect 14 0 22 0;
+#X connect 16 1 11 0;
+#X connect 17 0 14 0;
+#X connect 18 0 17 1;
+#X connect 18 0 19 0;
+#X connect 20 0 17 0;
+#X connect 21 0 23 0;
+#X connect 22 0 21 0;
+#X connect 22 1 21 1;
+#X connect 22 2 28 0;
+#X connect 22 3 28 1;
+#X connect 23 1 25 0;
+#X connect 23 1 26 0;
+#X connect 25 0 15 0;
+#X connect 26 0 15 0;
+#X connect 27 2 2 0;
+#X connect 28 0 21 2;
+#X connect 28 1 21 3;
+#X connect 29 0 27 2;
diff --git a/msd/editor/morelinks.pd b/msd/editor/morelinks.pd
new file mode 100644
index 0000000..60d7624
--- /dev/null
+++ b/msd/editor/morelinks.pd
@@ -0,0 +1,234 @@
+#N canvas 225 469 146 202 10;
+#N canvas 375 417 614 523 left-right-links 0;
+#X obj 192 225 pointer mass;
+#X obj 184 423 pack p p;
+#X msg 192 193 traverse pd-data \, vnext 1;
+#X obj 191 150 inlet;
+#X text 115 56 m1 ---> m2 ---> m3 ---> m4;
+#X obj 393 207 s pd-data;
+#X msg 393 186 sort;
+#X text 111 18 This will walk through the selected masses from left
+to right and create links between two neighbor masses like:;
+#X text 113 90 Great for connecting "strings".;
+#X text 427 186 first sort left to right;
+#X obj 192 169 t b b b;
+#X obj 192 248 t b b p;
+#X obj 239 148 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 236 320 t p p;
+#X msg 294 320 0;
+#X obj 184 385 spigot;
+#X msg 206 321 1;
+#X text 258 384 Skip the first mass;
+#X obj 256 416 r \$0-link-param;
+#X obj 113 225 ds-vnext;
+#X obj 184 454 link2masses;
+#X connect 0 0 11 0;
+#X connect 0 1 19 0;
+#X connect 1 0 20 0;
+#X connect 2 0 0 0;
+#X connect 3 0 10 0;
+#X connect 6 0 5 0;
+#X connect 10 0 2 0;
+#X connect 10 1 14 0;
+#X connect 10 2 6 0;
+#X connect 11 0 19 0;
+#X connect 11 1 16 0;
+#X connect 11 2 13 0;
+#X connect 12 0 10 0;
+#X connect 13 0 1 1;
+#X connect 13 1 15 0;
+#X connect 14 0 15 1;
+#X connect 15 0 1 0;
+#X connect 16 0 15 1;
+#X connect 18 0 20 1;
+#X connect 19 0 0 0;
+#X restore 141 67 pd left-right-links;
+#X obj 2 18 cnv 15 140 80 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 10 52 bng 15 250 50 0 empty empty left-to-right 20 8 0 8 -241291
+-1 -1;
+#N canvas 487 247 771 749 one-to-many 0;
+#X obj 203 173 pointer mass;
+#X obj 182 442 pack p p;
+#X msg 203 141 traverse pd-data \, vnext 1;
+#X obj 132 337 t b p;
+#X obj 69 120 inlet;
+#X obj 135 310 pointer mass;
+#X obj 203 196 t b p;
+#X obj 69 178 t b b;
+#X msg 135 242 traverse pd-data;
+#X obj 274 378 outlet;
+#X msg 274 325 label one2many-Start;
+#X msg 281 351 label one2many-Ends;
+#X obj 69 146 select 0 1;
+#X obj 254 440 r \$0-link-param;
+#X obj 69 281 ds-vnext;
+#X obj 182 473 link2masses;
+#X connect 0 0 6 0;
+#X connect 1 0 15 0;
+#X connect 2 0 0 0;
+#X connect 3 0 14 0;
+#X connect 3 1 1 0;
+#X connect 4 0 12 0;
+#X connect 5 0 3 0;
+#X connect 5 1 14 0;
+#X connect 5 2 10 0;
+#X connect 6 0 11 0;
+#X connect 6 1 1 1;
+#X connect 7 0 14 0;
+#X connect 7 1 8 0;
+#X connect 8 0 5 0;
+#X connect 10 0 9 0;
+#X connect 11 0 9 0;
+#X connect 12 0 7 0;
+#X connect 12 1 2 0;
+#X connect 13 0 15 1;
+#X connect 14 0 5 0;
+#X restore 143 94 pd one-to-many;
+#X obj 10 75 tgl 15 0 empty empty one2many-Start 20 8 0 8 -262131 -1
+-1 0 1;
+#X obj 10 30 bng 15 250 50 0 empty empty all_selected 20 8 0 8 -241291
+-1 -1;
+#X obj 115 31 tgl 15 0 empty empty Keys -3 -6 0 8 -24198 -1 -1 0 1
+;
+#X obj 211 5 keyup;
+#X obj 211 26 spigot;
+#X obj 2 100 cnv 15 140 100 empty empty Link_Params 10 10 0 10 -195568
+-1 0;
+#X obj 20 120 nbx 4 14 -1e+37 1e+37 0 0 \$0-K \$0-K K -12 8 0 10 -225271
+-1 -1 10 256;
+#X obj 46 181 nbx 5 14 -1e+37 1e+37 0 0 \$0-lsid \$0-lsid SID -30 8
+0 10 -261681 -1 -1 0 256;
+#X obj 20 142 nbx 4 14 -1e+37 1e+37 0 0 \$0-D \$0-D D -12 8 0 10 -225271
+-1 -1 2.5 256;
+#N canvas 374 319 746 411 linkparam 0;
+#X obj 34 229 s \$0-link-param;
+#X obj 38 104 t b f;
+#X obj 81 106 t b f;
+#X obj 28 27 r \$0-K;
+#X obj 38 56 r \$0-D;
+#X obj 240 240 s \$0-K;
+#X obj 320 233 s \$0-D;
+#X obj 402 236 s \$0-D2;
+#X obj 240 147 f \$1;
+#X obj 320 157 f \$2;
+#X obj 402 156 f \$3;
+#X obj 240 178 select 0;
+#X msg 240 204 10;
+#X obj 320 181 select 0;
+#X obj 402 177 select 0;
+#X msg 320 207 2.5;
+#X msg 402 203 1.5;
+#X obj 443 50 loadbang;
+#X text 438 28 Init;
+#X obj 485 236 s \$0-lsid;
+#X msg 485 159 0;
+#X obj 81 80 r \$0-lsid;
+#X msg 515 131 1;
+#X obj 515 208 s \$0-P;
+#X obj 151 104 t b f;
+#X obj 151 78 r \$0-P;
+#X msg 563 129 0;
+#X obj 563 166 s \$0-Lmin;
+#X obj 632 202 s \$0-Lmax;
+#X msg 632 132 1e+10;
+#X obj 34 196 pack 0 0 0 0 0 0;
+#X obj 195 106 t b f;
+#X obj 235 106 t b f;
+#X obj 195 53 r \$0-Lmin;
+#X obj 235 78 r \$0-Lmax;
+#X obj 49 315 outlet;
+#X obj 49 287 r \$0-link-param;
+#X connect 1 0 30 0;
+#X connect 1 1 30 1;
+#X connect 2 0 30 0;
+#X connect 2 1 30 2;
+#X connect 3 0 30 0;
+#X connect 4 0 1 0;
+#X connect 8 0 11 0;
+#X connect 9 0 13 0;
+#X connect 10 0 14 0;
+#X connect 11 0 12 0;
+#X connect 11 1 5 0;
+#X connect 12 0 5 0;
+#X connect 13 0 15 0;
+#X connect 13 1 6 0;
+#X connect 14 0 16 0;
+#X connect 14 1 7 0;
+#X connect 15 0 6 0;
+#X connect 16 0 7 0;
+#X connect 17 0 8 0;
+#X connect 17 0 9 0;
+#X connect 17 0 10 0;
+#X connect 17 0 20 0;
+#X connect 17 0 22 0;
+#X connect 17 0 26 0;
+#X connect 17 0 29 0;
+#X connect 20 0 19 0;
+#X connect 21 0 2 0;
+#X connect 22 0 23 0;
+#X connect 24 0 30 0;
+#X connect 24 1 30 3;
+#X connect 25 0 24 0;
+#X connect 26 0 27 0;
+#X connect 29 0 28 0;
+#X connect 30 0 0 0;
+#X connect 31 0 30 0;
+#X connect 31 1 30 4;
+#X connect 32 0 30 0;
+#X connect 32 1 30 5;
+#X connect 33 0 31 0;
+#X connect 34 0 32 0;
+#X connect 36 0 35 0;
+#X restore 145 126 pd linkparam;
+#N canvas 0 0 483 507 ilinker 0;
+#X obj 195 306 pointer mass;
+#X obj 197 167 pointer mass;
+#X obj 197 190 t b p;
+#X obj 177 387 pack p p;
+#X msg 197 135 traverse pd-data \, vnext 1;
+#X obj 147 330 t b p;
+#X obj 197 106 inlet;
+#X text 111 48 This will create all possible links between all selected
+masses like iLink.;
+#X obj 249 386 r \$0-link-param;
+#X obj 274 214 ds-vnext;
+#X obj 147 257 ds-vnext;
+#X obj 177 418 link2masses;
+#X connect 0 0 5 0;
+#X connect 0 1 10 0;
+#X connect 0 2 9 0;
+#X connect 1 0 2 0;
+#X connect 1 1 9 0;
+#X connect 2 0 10 0;
+#X connect 2 1 3 1;
+#X connect 2 1 0 1;
+#X connect 3 0 11 0;
+#X connect 4 0 1 0;
+#X connect 5 0 10 0;
+#X connect 5 1 3 0;
+#X connect 6 0 4 0;
+#X connect 8 0 11 1;
+#X connect 9 0 1 0;
+#X connect 10 0 0 0;
+#X restore 137 45 pd ilinker;
+#X obj 210 46 select 108 114;
+#X obj 77 132 nbx 3 14 0 1e+37 0 0 \$0-Lmin \$0-Lmin Lmin 0 -8 0 10
+-225271 -1 -1 0 256;
+#X obj 20 161 nbx 3 14 -1e+37 1e+37 0 0 \$0-P \$0-P P -12 8 0 10 -225271
+-1 -1 1 256;
+#X obj 76 162 nbx 6 14 0 1e+37 0 0 \$0-Lmax \$0-Lmax Lmax 0 -8 0 10
+-225271 -1 -1 1e+10 256;
+#X obj 145 156 outlet;
+#X connect 2 0 0 0;
+#X connect 3 0 4 0;
+#X connect 4 0 3 0;
+#X connect 5 0 14 0;
+#X connect 6 0 8 1;
+#X connect 7 0 8 0;
+#X connect 8 0 15 0;
+#X connect 13 0 19 0;
+#X connect 15 0 14 0;
+#X connect 15 1 0 0;
+#X coords 0 0 1 1 142 200 1;
diff --git a/msd/editor/msd-editor.pd b/msd/editor/msd-editor.pd
new file mode 100644
index 0000000..eb6b9ce
--- /dev/null
+++ b/msd/editor/msd-editor.pd
@@ -0,0 +1,1864 @@
+#N struct liaison float x1 float y1 float x2 float y2 float mid1 float
+mid2 float lid float K float D float P float Lmin float Lmax float
+sid;
+#N struct mass float x float y float mid float mob float M float sid
+;
+#N canvas 249 108 419 631 10;
+#X obj 9 50 cnv 15 400 220 empty empty EDIT 20 12 1 14 -233017 -66577
+0;
+#X obj 9 275 cnv 15 400 60 empty empty CREATE 20 12 1 14 -195568 -66577
+0;
+#X obj 10 340 cnv 15 400 140 empty empty CONTROL 20 12 1 14 -233017
+-66577 0;
+#X obj 211 295 bng 24 250 50 0 \$0-generate \$0-generate generate 0
+-6 0 8 -24198 -1 -1;
+#N canvas 392 0 718 819 activate 0;
+#X obj 233 238 r \$0-msd;
+#X obj 233 453 gem_masses;
+#X obj 313 445 gem_links;
+#X obj 177 113 gemhead;
+#X obj 233 396 route massesPos linksPos;
+#X obj 97 710 gemwin;
+#X msg 97 683 0 \, destroy;
+#X obj 249 354 s \$0-msd-out;
+#X obj 97 597 select 1 0;
+#X obj 97 569 tgl 24 0 empty empty GEM 0 -6 0 8 -262144 -1 -1 0 1;
+#X obj 275 330 s \$0-msd-attr;
+#X obj 211 541 s masspositions;
+#X obj 313 515 s linkspositions;
+#X obj 167 69 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 233 421 spigot;
+#X obj 313 421 spigot;
+#X text 238 559 sent to the data struct pointers;
+#X obj 279 192 s pollpos;
+#X obj 165 22 inlet data_only;
+#X obj 39 488 inlet GEM;
+#X obj 341 40 inlet speed;
+#X obj 20 550 select 1;
+#X msg 20 575 0;
+#X obj 38 512 t f f;
+#X obj 54 90 select 1;
+#X msg 54 115 0;
+#X obj 72 52 t f f;
+#X msg 135 283 set \$1;
+#X msg 14 639 set \$1;
+#X obj 141 309 outlet;
+#X obj 15 665 outlet;
+#X obj 167 92 metro 20;
+#X obj 413 395 r \$0-gem-masses-on;
+#X obj 415 439 r \$0-gem-links-on;
+#X obj 279 171 spigot 1;
+#X obj 330 145 r \$0-poll-ds;
+#X obj 346 469 r \$0-set-ds;
+#X obj 233 516 spigot 1;
+#X obj 313 496 spigot 1;
+#X obj 297 238 r \$0-save-msd;
+#X obj 257 286 s \$0-msd2save;
+#X obj 255 261 spigot 0;
+#N canvas 0 0 788 568 msd 0;
+#N canvas 0 0 450 300 demux 0;
+#X obj 91 69 inlet;
+#X obj 255 73 inlet;
+#X obj 223 106 select 0;
+#X obj 73 213 spigot 1;
+#X obj 165 219 spigot 0;
+#X obj 141 188 unpack 1 0;
+#X obj 96 255 outlet;
+#X obj 173 257 outlet;
+#X msg 174 140 1 0;
+#X msg 216 140 0 1;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 2 0 8 0;
+#X connect 2 1 9 0;
+#X connect 3 0 6 0;
+#X connect 4 0 7 0;
+#X connect 5 0 3 1;
+#X connect 5 1 4 1;
+#X connect 8 0 5 0;
+#X connect 9 0 5 0;
+#X restore 195 170 pd demux;
+#X obj 262 133 r MSD-TYPE;
+#N canvas 0 0 450 300 demux 0;
+#X obj 91 69 inlet;
+#X obj 255 73 inlet;
+#X obj 223 106 select 0;
+#X obj 73 213 spigot 1;
+#X obj 165 219 spigot 0;
+#X obj 141 188 unpack 1 0;
+#X obj 96 255 outlet;
+#X obj 173 257 outlet;
+#X msg 174 140 1 0;
+#X msg 216 140 0 1;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 2 0 8 0;
+#X connect 2 1 9 0;
+#X connect 3 0 6 0;
+#X connect 4 0 7 0;
+#X connect 5 0 3 1;
+#X connect 5 1 4 1;
+#X connect 8 0 5 0;
+#X connect 9 0 5 0;
+#X restore 198 305 pd demux;
+#X obj 261 282 r MSD-TYPE;
+#X obj 195 136 inlet;
+#X obj 198 366 outlet;
+#N canvas 0 0 450 300 demux 0;
+#X obj 91 69 inlet;
+#X obj 255 73 inlet;
+#X obj 223 106 select 0;
+#X obj 73 213 spigot 1;
+#X obj 165 219 spigot 0;
+#X obj 141 188 unpack 1 0;
+#X obj 96 255 outlet;
+#X obj 173 257 outlet;
+#X msg 174 140 1 0;
+#X msg 216 140 0 1;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 2 0 8 0;
+#X connect 2 1 9 0;
+#X connect 3 0 6 0;
+#X connect 4 0 7 0;
+#X connect 5 0 3 1;
+#X connect 5 1 4 1;
+#X connect 8 0 5 0;
+#X connect 9 0 5 0;
+#X restore 377 303 pd demux;
+#X obj 442 280 r MSD-TYPE;
+#X obj 377 371 outlet;
+#X obj 200 233 msd2D;
+#X obj 350 233 msd3D;
+#X connect 0 0 9 0;
+#X connect 0 1 10 0;
+#X connect 1 0 0 1;
+#X connect 2 0 5 0;
+#X connect 2 1 5 0;
+#X connect 3 0 2 1;
+#X connect 4 0 0 0;
+#X connect 6 0 8 0;
+#X connect 6 1 8 0;
+#X connect 7 0 6 1;
+#X connect 9 0 2 0;
+#X connect 9 1 6 0;
+#X connect 10 0 2 0;
+#X connect 10 1 6 0;
+#X restore 233 308 pd msd;
+#X obj 357 676 gemhead;
+#X obj 357 699 world_light;
+#X obj 147 617 r \$0-fullscreen;
+#X obj 97 634 f 0;
+#X msg 97 659 reset \, lighting 1 \, fullscreen \$1 \, create \, 1
+;
+#X obj 535 568 pack 0 0 0;
+#X obj 540 699 s \$0-msd;
+#X msg 537 594 grabMass \$1 \$2 \$3;
+#X obj 602 540 t b f;
+#X obj 535 540 - 4;
+#X obj 572 539 + 4;
+#X obj 538 506 gemmouse 8 -8;
+#X obj 537 652 spigot 1;
+#X obj 591 630 r \$0-gemgrab;
+#X obj 353 175 s GEMBANG-GLOBAL;
+#X msg 432 671 0.6 0.8 0.4;
+#X obj 167 137 t b b b b;
+#X msg 167 216 get massesPos \, get linksPos \, get massesSpeeds;
+#X floatatom 265 121 5 0 0 0 - - -;
+#X msg 293 85 frame \$1;
+#X floatatom 331 67 5 0 0 0 - - -;
+#X obj 547 394 r \$0-show-mids;
+#X connect 0 0 41 0;
+#X connect 0 0 42 0;
+#X connect 3 0 59 0;
+#X connect 4 0 14 0;
+#X connect 4 0 37 0;
+#X connect 4 1 15 0;
+#X connect 4 1 38 0;
+#X connect 6 0 5 0;
+#X connect 8 0 46 0;
+#X connect 8 1 6 0;
+#X connect 9 0 8 0;
+#X connect 9 0 14 1;
+#X connect 9 0 15 1;
+#X connect 9 0 28 0;
+#X connect 13 0 27 0;
+#X connect 13 0 31 0;
+#X connect 14 0 1 0;
+#X connect 15 0 2 0;
+#X connect 18 0 26 0;
+#X connect 19 0 23 0;
+#X connect 20 0 31 1;
+#X connect 21 0 22 0;
+#X connect 22 0 13 0;
+#X connect 23 0 9 0;
+#X connect 23 1 21 0;
+#X connect 24 0 25 0;
+#X connect 25 0 9 0;
+#X connect 26 0 13 0;
+#X connect 26 1 24 0;
+#X connect 27 0 29 0;
+#X connect 28 0 30 0;
+#X connect 31 0 59 0;
+#X connect 32 0 1 1;
+#X connect 33 0 2 1;
+#X connect 34 0 17 0;
+#X connect 35 0 34 1;
+#X connect 36 0 38 1;
+#X connect 36 0 37 1;
+#X connect 37 0 11 0;
+#X connect 38 0 12 0;
+#X connect 39 0 41 1;
+#X connect 41 0 40 0;
+#X connect 42 0 7 0;
+#X connect 42 0 4 0;
+#X connect 42 1 10 0;
+#X connect 43 0 44 0;
+#X connect 45 0 46 1;
+#X connect 46 0 47 0;
+#X connect 47 0 5 0;
+#X connect 48 0 50 0;
+#X connect 50 0 55 0;
+#X connect 51 0 48 0;
+#X connect 51 1 48 2;
+#X connect 52 0 48 0;
+#X connect 53 0 48 1;
+#X connect 54 0 52 0;
+#X connect 54 1 53 0;
+#X connect 54 2 51 0;
+#X connect 55 0 49 0;
+#X connect 56 0 55 1;
+#X connect 58 0 44 1;
+#X connect 59 0 60 0;
+#X connect 59 1 42 0;
+#X connect 59 2 34 0;
+#X connect 59 3 57 0;
+#X connect 60 0 42 0;
+#X connect 62 0 3 0;
+#X connect 63 0 62 0;
+#X connect 64 0 1 2;
+#X restore 31 416 pd activate;
+#X obj 31 381 tgl 24 0 empty empty GEM 0 -6 0 8 -195568 -1 -1 0 1;
+#X obj 67 381 tgl 24 0 empty empty Datastructures 0 -6 0 8 -1 -262144
+-1 0 1;
+#X floatatom 103 396 5 10 1000 2 frequency - -;
+#N canvas 602 189 584 687 forces 0;
+#X obj 295 415 s \$0-msd;
+#X obj 394 355 hsl 128 24 -5 5 0 1 empty empty empty -2 -6 0 8 -262144
+-1 -1 4000 1;
+#X obj 295 230 vsl 24 128 -5 5 0 1 empty empty empty 0 -8 0 8 -262144
+-1 -1 8496 1;
+#X obj 295 174 tgl 24 0 empty empty constant? 0 -6 0 8 -262144 -1 -1
+0 1;
+#X obj 391 295 tgl 24 0 empty empty constant? 0 -6 0 8 -262144 -1 -1
+0 1;
+#X obj 295 205 metro 10;
+#X obj 391 326 metro 10;
+#X msg 455 325 0;
+#X msg 263 204 0;
+#X text 230 127 Add some forces to the system.;
+#X msg 63 158 forceX \$2 \$1;
+#X msg 63 272 forceY \$2 \$1;
+#X obj 63 137 pack 0 0;
+#X floatatom 114 114 5 0 0 2 Mass_ID - -;
+#X obj 63 249 pack 0 0;
+#X floatatom 63 115 5 0 0 0 forceX - -;
+#X floatatom 63 204 5 0 0 0 forceY - -;
+#X obj 63 299 s \$0-msd;
+#X obj 63 181 s \$0-msd;
+#X obj 63 224 * -1;
+#X obj 63 461 pack 0 0;
+#X floatatom 63 437 5 0 0 0 posY - -;
+#X obj 63 511 s \$0-msd;
+#X msg 63 484 posY \$2 \$1;
+#X obj 63 358 pack 0 0;
+#X floatatom 63 334 5 0 0 0 posX - -;
+#X obj 63 408 s \$0-msd;
+#X msg 63 381 posX \$2 \$1;
+#X text 31 74 Modify one mass:;
+#X obj 63 560 pack 0 0;
+#X floatatom 63 536 5 0 0 0 posZ - -;
+#X obj 63 610 s \$0-msd;
+#X msg 63 583 posZ \$2 \$1;
+#X msg 295 388 forceY 0-m \$1;
+#X msg 391 388 forceX 0-m \$1;
+#X obj 324 600 s \$0-msd;
+#X obj 327 530 hsl 128 24 -5 5 0 0 empty empty empty -2 -6 0 8 -233017
+-1 -1 0 1;
+#X obj 324 470 tgl 24 0 empty empty constant? 0 -6 0 8 -262144 -1 -1
+0 1;
+#X obj 324 501 metro 10;
+#X msg 324 563 forceZ 0-m \$1;
+#X msg 393 501 0;
+#X connect 1 0 34 0;
+#X connect 2 0 33 0;
+#X connect 3 0 5 0;
+#X connect 4 0 6 0;
+#X connect 5 0 2 0;
+#X connect 6 0 1 0;
+#X connect 7 0 1 0;
+#X connect 8 0 2 0;
+#X connect 10 0 18 0;
+#X connect 11 0 17 0;
+#X connect 12 0 10 0;
+#X connect 13 0 12 1;
+#X connect 13 0 14 1;
+#X connect 13 0 20 1;
+#X connect 13 0 24 1;
+#X connect 13 0 29 1;
+#X connect 14 0 11 0;
+#X connect 15 0 12 0;
+#X connect 16 0 19 0;
+#X connect 19 0 14 0;
+#X connect 20 0 23 0;
+#X connect 21 0 20 0;
+#X connect 23 0 22 0;
+#X connect 24 0 27 0;
+#X connect 25 0 24 0;
+#X connect 27 0 26 0;
+#X connect 29 0 32 0;
+#X connect 30 0 29 0;
+#X connect 32 0 31 0;
+#X connect 33 0 0 0;
+#X connect 34 0 0 0;
+#X connect 36 0 39 0;
+#X connect 37 0 38 0;
+#X connect 38 0 36 0;
+#X connect 39 0 35 0;
+#X connect 40 0 36 0;
+#X restore 176 450 pd forces;
+#N canvas 113 581 450 300 props 0;
+#X obj 121 232 s \$0-msd;
+#X text 244 59 Edit properties of Links.;
+#X obj 77 36 inlet;
+#X obj 123 36 inlet;
+#X obj 169 36 inlet;
+#X obj 152 101 pack 0 0;
+#X obj 239 33 inlet lsid;
+#X msg 121 179 setD \$2-l \$1;
+#X msg 94 203 setK \$2-l \$1;
+#X obj 122 123 pack 0 0;
+#X obj 76 99 pack 0 0;
+#X msg 145 150 setL \$2-l \$1;
+#X connect 2 0 10 0;
+#X connect 3 0 9 0;
+#X connect 4 0 5 0;
+#X connect 5 0 11 0;
+#X connect 6 0 5 1;
+#X connect 6 0 10 1;
+#X connect 6 0 9 1;
+#X connect 7 0 0 0;
+#X connect 8 0 0 0;
+#X connect 9 0 7 0;
+#X connect 10 0 8 0;
+#X connect 11 0 0 0;
+#X restore 268 452 pd props;
+#X obj 342 218 s pd-data;
+#X msg 342 194 clear;
+#N canvas 702 626 136 139 minmax 0;
+#X obj 2 15 cnv 15 130 120 empty empty Min/Max 10 10 0 10 -195568 -1
+0;
+#X obj 6 37 nbx 5 14 -1e+37 1e+37 0 0 \$0-min-DS \$0-min-DS Min-DS
+60 8 0 10 -225271 -1 -1 0 256;
+#X obj 6 57 nbx 5 14 -1e+37 1e+37 0 0 \$0-max-DS \$0-max-DS Max-DS
+60 8 0 10 -225271 -1 -1 800 256;
+#X obj 6 85 nbx 5 14 -1e+37 1e+37 0 0 \$0-min-MSD \$0-min-MSD Min-MSD
+60 8 0 10 -262131 -1 -1 -4 256;
+#X obj 6 105 nbx 5 14 -1e+37 1e+37 0 0 \$0-max-MSD \$0-max-MSD Max-MSD
+60 8 0 10 -262131 -1 -1 4 256;
+#N canvas 0 0 450 300 l 0;
+#X msg 35 78 0;
+#X obj 35 41 loadbang;
+#X obj 36 136 loadbang;
+#X obj 35 100 s \$0-min-DS;
+#X obj 128 101 s \$0-max-DS;
+#X obj 36 195 s \$0-min-MSD;
+#X obj 129 196 s \$0-max-MSD;
+#X msg 128 75 800;
+#X msg 36 173 -4;
+#X msg 129 170 4;
+#X connect 0 0 3 0;
+#X connect 1 0 0 0;
+#X connect 1 0 7 0;
+#X connect 2 0 8 0;
+#X connect 2 0 9 0;
+#X connect 7 0 4 0;
+#X connect 8 0 5 0;
+#X connect 9 0 6 0;
+#X restore 82 19 pd l;
+#X coords 0 0 1 1 132 135 1;
+#X restore 252 50 pd minmax;
+#X obj 177 295 tgl 24 0 MSD-TYPE \$0-MSD-TYPE 3-D 0 -6 0 8 -233017
+-1 -1 1 1;
+#X obj 28 96 msd_append;
+#X obj 10 566 cnv 15 400 60 empty empty DOC 20 12 1 14 -233017 -66577
+0;
+#X obj 182 381 tgl 15 0 \$0-gem-masses-on empty gem_m 0 -6 0 8 -225280
+-1 -1 0 1;
+#X obj 218 381 tgl 15 0 \$0-gem-links-on empty gem_l 0 -6 0 8 -225271
+-1 -1 0 1;
+#X obj 182 416 tgl 15 0 \$0-poll-ds \$0-poll-ds poll-ds -10 -6 0 8
+-225280 -1 -1 0 1;
+#X obj 218 416 tgl 15 0 \$0-set-ds \$0-set-ds set-ds 0 -6 0 8 -225271
+-1 -1 0 1;
+#X text 28 305 MSD-TYPE (2D or 3D):;
+#X obj 9 9 cnv 15 400 30 empty empty MSD-EDITOR 20 14 1 14 -128992
+-262144 0;
+#X obj 10 485 cnv 15 400 75 empty empty PERSIST 20 12 1 14 -195568
+-66577 0;
+#N canvas 460 399 104 45 save 0;
+#X obj 2 3 cnv 15 100 40 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 17 bng 20 250 50 0 empty empty load 0 -6 0 8 -258699 -1 -1
+;
+#X obj 34 17 bng 20 250 50 0 empty empty saveas 0 -6 0 8 -24198 -1
+-1;
+#X obj 101 60 savepanel;
+#X obj 50 168 s pd-data;
+#X msg 101 115 write \$1;
+#X obj 20 91 openpanel;
+#X msg 20 115 read \$1;
+#X obj 20 138 t b a;
+#X obj 20 195 s \$0-generate;
+#X obj 79 17 bng 20 250 50 0 empty empty save 0 -6 0 8 -241291 -1 -1
+;
+#X obj 100 91 symbol;
+#X connect 1 0 6 0;
+#X connect 2 0 3 0;
+#X connect 3 0 11 0;
+#X connect 5 0 4 0;
+#X connect 6 0 7 0;
+#X connect 6 0 11 1;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 8 1 4 0;
+#X connect 10 0 11 0;
+#X connect 11 0 5 0;
+#X coords 0 0 1 1 102 44 1;
+#X restore 116 489 pd save;
+#N canvas 0 0 84 49 save 0;
+#X obj 2 3 cnv 15 75 40 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 37 18 bng 20 250 50 0 empty empty saveas 0 -6 0 8 -24198 -1
+-1;
+#X obj 285 129 textfile;
+#X obj 285 64 r \$0-msd2save;
+#X obj 183 157 s \$0-generate;
+#X obj 166 270 s \$0-save-msd;
+#X msg 203 187 1;
+#X msg 138 193 0;
+#X obj 145 33 t b b b b;
+#X msg 213 55 clear;
+#X obj 285 88 prepend add;
+#X obj 138 126 del 500;
+#X obj 35 168 savepanel;
+#X msg 37 193 write \$1;
+#X obj 58 148 t b b;
+#X obj 292 202 s \$0-msd;
+#X msg 427 125 rewind;
+#X obj 7 18 bng 20 250 50 0 empty empty load 0 -6 0 8 -258699 -1 -1
+;
+#X obj 392 156 until;
+#X obj 396 102 t b b;
+#X obj 521 95 openpanel;
+#X msg 523 120 read \$1;
+#X obj 526 145 t b a;
+#X connect 1 0 8 0;
+#X connect 2 0 15 0;
+#X connect 2 1 18 1;
+#X connect 3 0 10 0;
+#X connect 6 0 5 0;
+#X connect 7 0 5 0;
+#X connect 8 1 11 0;
+#X connect 8 2 4 0;
+#X connect 8 3 6 0;
+#X connect 8 3 9 0;
+#X connect 9 0 2 0;
+#X connect 10 0 2 0;
+#X connect 11 0 14 0;
+#X connect 12 0 13 0;
+#X connect 13 0 2 0;
+#X connect 14 0 12 0;
+#X connect 14 1 7 0;
+#X connect 16 0 2 0;
+#X connect 17 0 20 0;
+#X connect 18 0 2 0;
+#X connect 19 0 18 0;
+#X connect 19 1 16 0;
+#X connect 20 0 21 0;
+#X connect 21 0 22 0;
+#X connect 22 0 19 0;
+#X connect 22 1 2 0;
+#X coords 0 0 1 1 77 44 1;
+#X restore 222 489 pd save;
+#X obj 285 374 vsl 15 64 0 10 0 0 empty empty D 0 -8 0 8 -195568 -1
+-1 0 1;
+#X obj 302 374 vsl 15 64 0 1 0 0 empty empty L 0 -8 0 8 -195568 -1
+-1 0 1;
+#X obj 268 374 vsl 15 64 0 100 0 0 empty empty K 0 -8 0 8 -195568 -1
+-1 0 1;
+#N canvas 504 489 531 315 TODO 0;
+#X text 146 11 TODO :: IDEAS;
+#X text 41 56 Oriented Links. It's best to create new data structures
+for this \, as the old link DS is quite loaded already.;
+#X restore 197 573 pd TODO;
+#N canvas 307 452 509 305 NEWS 0;
+#X text 32 24 RecentChanges;
+#X text 43 67 Links: D2 was killed \, L was born.;
+#X text 43 100 SID for Links and masses: Symbolic ids can now be set.
+You supply a number \, which will get transformed into a symbol id
+(sid) #-m for masses and #-l for standard Links.;
+#X restore 146 573 pd NEWS;
+#N canvas 387 277 751 433 ignore 0;
+#X obj 46 264 print ToMSD;
+#X obj 46 234 spigot;
+#X obj 83 181 tgl 15 0 empty empty debug_ToMSD 0 -6 0 8 -262144 -1
+-1 0 1;
+#X obj 46 207 r \$0-msd;
+#X obj 147 237 spigot;
+#X obj 184 184 tgl 15 0 empty empty debug_FromMSD 0 -6 0 8 -262144
+-1 -1 0 1;
+#X obj 147 265 print FromMSD;
+#X obj 147 210 r \$0-msd-out;
+#N canvas 0 0 578 686 setter 0;
+#X obj 73 654 mass-set 0;
+#X obj 109 596 mass-set 1;
+#X obj 130 639 mass-set 2;
+#X obj 188 434 mass-set 3;
+#X restore 523 45 pd setter;
+#N canvas 0 0 1257 922 lsetter 0;
+#X obj 130 639 link-set 0;
+#X obj 109 596 link-set 1;
+#X obj 109 596 link-set 2;
+#X obj 73 654 link-set 3;
+#X obj 73 654 link-set 4;
+#X obj 73 654 link-set 5;
+#X restore 522 68 pd lsetter;
+#X text 506 21 Automatic scripting targets;
+#X text 23 46 You can ignore this stuff here \, unless something goes
+wrong.;
+#X obj 269 233 spigot;
+#X obj 306 180 tgl 15 0 empty empty debug_AttrMSD 0 -6 0 8 -262144
+-1 -1 0 1;
+#X obj 269 206 r \$0-msd-attr;
+#X obj 269 264 print AttrMSD;
+#X obj 532 270 s \$0-msd;
+#X msg 544 247 infosL;
+#X obj 143 363 spigot;
+#X obj 180 310 tgl 15 0 empty empty global-send 0 -6 0 8 -262144 -1
+-1 0 1;
+#X obj 143 336 r \$0-msd-out;
+#X obj 143 391 s MSD-OUT-GLOBAL;
+#X msg 532 223 massesPosL;
+#X obj 532 199 metro 40;
+#X obj 532 177 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X floatatom 585 178 5 0 0 0 - - -;
+#X obj 280 365 spigot;
+#X obj 317 312 tgl 15 0 empty empty global-receive 0 -6 0 8 -262144
+-1 -1 0 1;
+#X obj 280 338 r MSD-IN-GLOBAL;
+#X obj 280 393 s \$0-msd;
+#X obj 630 201 metro 40;
+#X obj 630 179 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X floatatom 683 180 5 0 0 0 - - -;
+#X obj 630 273 s \$0-msd;
+#X obj 531 322 metro 40;
+#X obj 531 300 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X floatatom 584 301 5 0 0 0 - - -;
+#X obj 531 394 s \$0-msd;
+#X msg 627 48 clear;
+#X obj 627 75 s pd-setter;
+#X obj 627 95 s pd-lsetter;
+#X msg 531 346 massesForcesL;
+#X msg 630 225 massesPosYL;
+#N canvas 0 0 450 300 msd-type 0;
+#X obj 94 78 r MSD-TYPE;
+#X obj 89 201 s \$0-MSD-TYPE;
+#X obj 98 136 select 0;
+#X msg 89 168 label 2-D;
+#X msg 185 170 label 3-D;
+#X connect 0 0 2 0;
+#X connect 2 0 3 0;
+#X connect 2 1 4 0;
+#X connect 3 0 1 0;
+#X connect 4 0 1 0;
+#X restore 415 123 pd msd-type;
+#N canvas 6 378 553 343 camera 0;
+#X obj 161 31 gemhead;
+#X obj 162 82 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 185 63 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 234 108 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 260 86 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X msg 234 124 left \$1;
+#X msg 260 102 right \$1;
+#X obj 75 120 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 101 98 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X msg 101 114 up \$1;
+#X msg 75 136 down \$1;
+#X msg 267 58 reset;
+#X msg 185 80 forward \$1;
+#X msg 162 98 reverse \$1;
+#X msg 66 252 speed \$1;
+#X floatatom 66 232 5 0 0 0 - - -;
+#X floatatom 67 195 5 0 0 0 - - -;
+#X msg 379 150 lookX \$1;
+#X msg 379 187 lookY \$1;
+#X msg 379 223 lookZ \$1;
+#X floatatom 379 134 5 0 0 0 - - -;
+#X floatatom 379 207 5 0 0 0 - - -;
+#X floatatom 379 170 5 0 0 0 - - -;
+#X msg 67 213 distance \$1;
+#X obj 114 182 f 4;
+#X obj 181 237 +;
+#X obj 183 185 camera;
+#X connect 0 0 26 0;
+#X connect 1 0 13 0;
+#X connect 2 0 12 0;
+#X connect 3 0 5 0;
+#X connect 4 0 6 0;
+#X connect 5 0 26 0;
+#X connect 6 0 26 0;
+#X connect 7 0 10 0;
+#X connect 8 0 9 0;
+#X connect 9 0 26 0;
+#X connect 10 0 26 0;
+#X connect 11 0 26 0;
+#X connect 12 0 26 0;
+#X connect 13 0 26 0;
+#X connect 14 0 26 0;
+#X connect 15 0 14 0;
+#X connect 16 0 23 0;
+#X connect 17 0 26 0;
+#X connect 18 0 26 0;
+#X connect 19 0 26 0;
+#X connect 20 0 17 0;
+#X connect 21 0 19 0;
+#X connect 22 0 18 0;
+#X connect 23 0 26 0;
+#X connect 24 0 23 0;
+#X restore 416 83 pd camera;
+#N canvas 0 0 450 300 msynth 0;
+#X restore 522 89 pd msynth;
+#N canvas 0 0 1257 922 lsynth 0;
+#X restore 521 109 pd lsynth;
+#X obj 627 117 s pd-msynt;
+#X obj 627 137 s pd-lsynth;
+#X obj 63 101 tgl 16 0 \$0-gensynth \$0-gensynth l-synthesis 0 -6 0
+8 -262144 -1 -1 0 1;
+#X symbolatom 96 105 10 0 0 1 link-synth - #0-lsynth-name;
+#X symbolatom 99 138 10 0 0 1 masses-synth - #0-msynth-name;
+#X obj 62 137 tgl 16 0 \$0-gensynth-m \$0-gensynth-m m-synthesis 0
+-6 0 8 -262144 -1 -1 0 1;
+#X obj 420 381 netsend;
+#X obj 420 354 prepend send;
+#X msg 419 407 connect localhost 7777;
+#N canvas 0 0 582 592 save-trans 0;
+#X obj 28 53 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 28 72 savepanel;
+#X obj 28 121 s \$0-mid2msdid;
+#X msg 28 95 write \$1;
+#X text 118 84 Save mis2msdid table to disk.;
+#X obj 76 42 inlet;
+#X connect 0 0 1 0;
+#X connect 1 0 3 0;
+#X connect 3 0 2 0;
+#X connect 5 0 1 0;
+#X restore 413 180 pd save-trans;
+#X msg 413 157 bang;
+#X connect 1 0 0 0;
+#X connect 2 0 1 1;
+#X connect 3 0 1 0;
+#X connect 4 0 6 0;
+#X connect 5 0 4 1;
+#X connect 7 0 4 0;
+#X connect 12 0 15 0;
+#X connect 13 0 12 1;
+#X connect 14 0 12 0;
+#X connect 17 0 16 0;
+#X connect 18 0 21 0;
+#X connect 19 0 18 1;
+#X connect 20 0 18 0;
+#X connect 22 0 16 0;
+#X connect 23 0 22 0;
+#X connect 24 0 23 0;
+#X connect 25 0 23 1;
+#X connect 26 0 29 0;
+#X connect 27 0 26 1;
+#X connect 28 0 26 0;
+#X connect 30 0 42 0;
+#X connect 31 0 30 0;
+#X connect 32 0 30 1;
+#X connect 34 0 41 0;
+#X connect 35 0 34 0;
+#X connect 36 0 34 1;
+#X connect 38 0 39 0;
+#X connect 38 0 40 0;
+#X connect 38 0 47 0;
+#X connect 38 0 48 0;
+#X connect 41 0 37 0;
+#X connect 42 0 33 0;
+#X connect 54 0 53 0;
+#X connect 55 0 53 0;
+#X connect 57 0 56 0;
+#X restore 248 573 pd ignore this;
+#N canvas 0 0 489 250 help 0;
+#N canvas 0 0 450 300 visualize? 0;
+#X text 18 91 Visualization is done using either a GEM OpenGL window
+\, or just animate the data structure alone. Better don't use both
+at the same time. In GDS-mode you can set the frequency of the internal
+metro \, to accelerate or slow down the simulation.;
+#X text 19 172 In edit mode and while visualization is active \, you
+can move around the masses. The red masses will not receive any other
+forces from the model. Use the "forces" and "props" subpatches to change
+parameters of links and send forces.;
+#X text 56 39 Help on Visualization;
+#X restore 301 169 pd visualize?;
+#N canvas 0 0 450 300 append? 0;
+#X text 36 72 First create structure inside [pd data] using msd_append.
+Add mobile masses with black bang \, add fixed masses with the red
+bang. Set weight of mass with the "M" number box.;
+#X text 29 29 Help on Mass creation;
+#X text 34 122 Use the greenish "geos" bang to open a subwindow for
+creating masses in geometric formations: circles and rectangles.;
+#X restore 303 70 pd append?;
+#N canvas 0 0 537 336 links? 0;
+#X text 47 77 Links are created by selecting at least two masses in
+edit mode \, then press "L" to connect those with a link. If you select
+more than two masses \, then all possible links between those masses
+will get created. Use this to mass-connect masses. :);
+#X text 32 26 Help on Link Creation;
+#X text 44 148 The keyboard shortcut "L" is only active \, if the green
+toggle "Keys" is set to on. Otherwise use the yellow "link" bang.;
+#X text 45 196 More ways to create links: left-to-right connects masses
+from left to right. The keyboard shortcut for this is "R" (for "Right"
+\, as "L" is for "Links"). one2many will connect one mass to many others
+and has no shortcuts. First select the first mass \, then set the toggle
+to 1 \, after that select the other masses and set toggle to 0;
+#X restore 302 94 pd links?;
+#N canvas 0 0 450 300 generate? 0;
+#X text 19 98 Press "generate" to generate messages to the msd object
+and create the physical model inside. You can select which type of
+msd* to use as well: msd2D or msd3D. With 3-D \, the Z-coordinate will
+default to a value of zero.;
+#X text 31 38 Help on MSD generation;
+#X restore 302 144 pd generate?;
+#N canvas 0 0 215 157 minmax? 0;
+#X text 38 35 Data structs and;
+#X text 38 49 GEM like different;
+#X text 38 63 coordinate systems.;
+#X text 38 87 Set the mapping;
+#X text 38 101 between both here.;
+#X restore 302 118 pd minmax?;
+#X text 39 18 HELP / USAGE;
+#X text 143 71 How to create masses:;
+#X text 143 94 How to create links:;
+#X text 102 118 Coordinates in MSD-Editor:;
+#X text 109 146 Generate the MSD-Network:;
+#X text 17 170 Visualize the network using GEM or DS:;
+#X restore 95 573 pd help;
+#X obj 32 450 tgl 16 0 \$0-fullscreen \$0-fullscreen fullscreen 0 -6
+0 8 -195568 -1 -1 0 1;
+#X obj 319 427 nbx 5 14 -1e+37 1e+37 0 0 empty empty link-sid 0 -6
+0 10 -195568 -1 -1 0 256;
+#X obj 95 601 structures;
+#X obj 252 194 cnv 15 84 42 empty empty empty 2 8 1 10 -1 -66577 0
+;
+#X obj 253 195 cnv 15 82 40 empty empty EDIT_AREA 2 8 1 10 -225271
+-66577 0;
+#N canvas 0 35 1022 952 data 0;
+#X scalar liaison 130.917 639.836 188 434 2 3 0 10 2.5 1 0 1e+10 0
+\;;
+#X scalar liaison 109.715 596.152 188 434 1 3 1 10 2.5 1 0 1e+10 0
+\;;
+#X scalar liaison 109.715 596.152 130.917 639.836 1 2 2 10 2.5 1 0
+1e+10 0 \;;
+#X scalar liaison 73.418 654.69 188 434 0 3 3 10 2.5 1 0 1e+10 0 \;
+;
+#X scalar liaison 73.418 654.69 130.917 639.836 0 2 4 10 2.5 1 0 1e+10
+0 \;;
+#X scalar liaison 73.418 654.69 109.715 596.152 0 1 5 10 2.5 1 0 1e+10
+0 \;;
+#X scalar mass 73.418 654.69 0 0 100 0 \;;
+#X scalar mass 109.715 596.152 1 0 100 0 \;;
+#X scalar mass 130.917 639.836 2 0 100 0 \;;
+#X scalar mass 188 434 3 900 100 0 \;;
+#X restore 269 214 pd data;
+#X obj 265 295 bng 24 250 50 0 \$0-set-from-ds \$0-set-from-ds set-from-ds
+0 -6 0 8 -225271 -1 -1;
+#N canvas 0 0 450 300 testing 0;
+#N canvas 39 482 450 300 mass-lines 0;
+#X text 26 19 Paint a line of masses between two masses. First select
+two masses \, then press this bang:;
+#X obj 41 86 bng 20 250 50 0 \$0-massline \$0-massline massline 0 -6
+0 8 -262144 -1 -1;
+#N canvas 65 73 818 854 make-ml 0;
+#X obj 254 188 pointer mass;
+#X msg 254 156 traverse pd-data \, vnext 1;
+#X obj 455 170 s pd-data;
+#X msg 455 149 sort;
+#X text 489 149 first sort left to right;
+#X obj 254 132 t b b b;
+#X obj 301 111 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 141 186 ds-vnext;
+#X obj 380 390 get mass x y;
+#X obj 252 394 get mass x y;
+#X obj 341 531 -;
+#X obj 265 529 -;
+#X obj 344 585 / 5;
+#X obj 263 588 / 5;
+#X obj 48 368 - 1;
+#X obj 33 271 inlet;
+#X obj 28 393 f 4;
+#X obj 185 722 pack 0 0 0;
+#X obj 91 275 inlet;
+#X obj 87 296 select 0 1;
+#X msg 90 322 0;
+#X msg 123 321 900;
+#X obj 214 98 t b b;
+#X obj 219 68 r \$0-massline;
+#X obj 185 777 s \$0-newmass;
+#X obj 276 271 f 0;
+#X obj 306 271 + 1;
+#X msg 289 244 0;
+#X obj 280 332 route 1 0;
+#X obj 254 211 t b b p;
+#X obj 280 300 pack 0 p;
+#X obj 322 70 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 31 483 countto;
+#X obj 33 456 pack 1 0;
+#X obj 30 420 t b f;
+#X obj 91 572 f 0;
+#X obj 147 591 *;
+#X obj 109 621 +;
+#X obj 193 641 f 0;
+#X obj 243 646 *;
+#X obj 211 674 +;
+#X obj 107 647 t b f;
+#X obj 124 693 f;
+#X obj 30 751 print countto;
+#X obj 607 632 inlet linkit;
+#X obj 543 727 link2masses;
+#X obj 615 677 r \$0-link-param;
+#X obj 622 479 pointer;
+#X obj 495 477 pointer;
+#X text 548 479 first;
+#X text 686 477 last mass;
+#X obj 69 514 t f b b f;
+#X obj 536 617 pack p p;
+#X obj 526 513 r \$0-lastmass;
+#X obj 482 545 pointer;
+#X obj 413 488 t b b;
+#X obj 225 355 t b a a;
+#X obj 415 458 select 1;
+#X obj 577 366 select 1;
+#X obj 476 511 t b;
+#X obj 525 592 t p p;
+#X obj 610 426 t b b b;
+#X obj 557 671 spigot;
+#X connect 0 0 29 0;
+#X connect 0 1 7 0;
+#X connect 1 0 0 0;
+#X connect 3 0 2 0;
+#X connect 5 0 1 0;
+#X connect 5 2 3 0;
+#X connect 5 2 27 0;
+#X connect 6 0 5 0;
+#X connect 7 0 0 0;
+#X connect 8 0 11 1;
+#X connect 8 0 35 1;
+#X connect 8 1 10 1;
+#X connect 8 1 38 1;
+#X connect 9 0 11 0;
+#X connect 9 1 10 0;
+#X connect 10 0 12 0;
+#X connect 11 0 13 0;
+#X connect 12 0 39 1;
+#X connect 13 0 36 1;
+#X connect 14 0 16 1;
+#X connect 15 0 13 1;
+#X connect 15 0 12 1;
+#X connect 15 0 14 0;
+#X connect 16 0 34 0;
+#X connect 17 0 24 0;
+#X connect 18 0 19 0;
+#X connect 19 0 20 0;
+#X connect 19 1 21 0;
+#X connect 20 0 42 1;
+#X connect 21 0 42 1;
+#X connect 22 1 5 0;
+#X connect 23 0 22 0;
+#X connect 25 0 26 0;
+#X connect 25 0 30 0;
+#X connect 26 0 25 1;
+#X connect 27 0 25 1;
+#X connect 28 0 56 0;
+#X connect 28 1 8 0;
+#X connect 28 1 48 1;
+#X connect 29 0 7 0;
+#X connect 29 1 25 0;
+#X connect 29 2 30 1;
+#X connect 30 0 28 0;
+#X connect 31 0 22 0;
+#X connect 32 0 43 0;
+#X connect 32 0 51 0;
+#X connect 33 0 32 0;
+#X connect 34 0 33 0;
+#X connect 34 1 33 1;
+#X connect 34 1 58 1;
+#X connect 35 0 37 0;
+#X connect 36 0 37 1;
+#X connect 37 0 41 0;
+#X connect 38 0 40 0;
+#X connect 39 0 40 1;
+#X connect 40 0 17 2;
+#X connect 41 0 42 0;
+#X connect 41 1 17 1;
+#X connect 42 0 17 0;
+#X connect 44 0 62 1;
+#X connect 46 0 45 1;
+#X connect 47 0 52 1;
+#X connect 48 0 52 1;
+#X connect 51 0 57 0;
+#X connect 51 1 35 0;
+#X connect 51 2 38 0;
+#X connect 51 3 39 0;
+#X connect 51 3 36 0;
+#X connect 52 0 62 0;
+#X connect 53 0 54 1;
+#X connect 54 0 60 0;
+#X connect 55 0 54 0;
+#X connect 55 1 48 0;
+#X connect 56 0 16 0;
+#X connect 56 1 9 0;
+#X connect 56 2 47 1;
+#X connect 57 0 55 0;
+#X connect 57 1 58 0;
+#X connect 58 0 61 0;
+#X connect 58 1 59 0;
+#X connect 59 0 54 0;
+#X connect 60 0 52 1;
+#X connect 60 1 52 0;
+#X connect 61 0 54 0;
+#X connect 61 1 47 0;
+#X connect 61 2 59 0;
+#X connect 62 0 45 0;
+#X restore 108 92 pd make-ml;
+#X obj 173 69 tgl 15 0 empty empty fix/mob 0 -6 0 8 -262144 -1 -1 0
+1;
+#X floatatom 108 71 5 0 0 2 howmany - -;
+#X obj 73 89 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X connect 3 0 2 1;
+#X connect 4 0 2 0;
+#X connect 5 0 2 2;
+#X restore 40 32 pd mass-lines;
+#N canvas 14 85 865 862 mousepaint 0;
+#X obj 45 97 tot data;
+#X obj 99 136 route motion mouseup mouse key;
+#X msg 45 69 capture \$1;
+#X obj 45 46 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 106 258 pack 0 0 0;
+#X obj 106 293 s \$0-newmass;
+#X obj 455 410 link2masses;
+#X obj 527 360 r \$0-link-param;
+#X obj 457 192 r \$0-lastmass;
+#X obj 407 190 t b;
+#X obj 456 271 t p p;
+#X obj 204 194 print mouse;
+#X obj 592 194 r \$0-lastmass;
+#X obj 548 226 pointer;
+#X msg 134 232 \$1;
+#X msg 160 232 \$2;
+#X obj 455 318 pack p p;
+#X obj 413 224 pointer;
+#X msg 96 228 900;
+#X obj 134 166 t b a a;
+#X msg 49 183 \$3;
+#X obj 51 205 select 1 2;
+#X msg 41 229 0;
+#X obj 100 33 inlet;
+#X connect 0 2 1 0;
+#X connect 1 2 11 0;
+#X connect 1 2 19 0;
+#X connect 2 0 0 0;
+#X connect 3 0 2 0;
+#X connect 4 0 5 0;
+#X connect 7 0 6 1;
+#X connect 8 0 17 1;
+#X connect 9 0 17 0;
+#X connect 10 0 16 1;
+#X connect 10 1 16 0;
+#X connect 12 0 13 1;
+#X connect 14 0 4 1;
+#X connect 15 0 4 2;
+#X connect 16 0 6 0;
+#X connect 17 0 10 0;
+#X connect 18 0 4 0;
+#X connect 19 0 17 0;
+#X connect 19 1 20 0;
+#X connect 19 2 14 0;
+#X connect 19 2 15 0;
+#X connect 20 0 21 0;
+#X connect 21 0 22 0;
+#X connect 21 1 18 0;
+#X connect 22 0 4 0;
+#X connect 23 0 2 0;
+#X restore 31 97 pd mousepaint;
+#X obj 31 74 tgl 15 0 empty empty capture 0 -6 0 8 -262144 -1 -1 0
+1;
+#X connect 2 0 1 0;
+#X restore 175 601 pd testing;
+#X obj 24 79 r \$0-newmass;
+#X obj 17 226 s \$0-lastmass;
+#X obj 110 250 s \$0-link-param;
+#X obj 110 50 morelinks;
+#N canvas 0 0 450 300 guts 0;
+#N canvas 366 103 781 748 generator 0;
+#N canvas 311 93 877 551 getter 0;
+#X obj 244 89 inlet;
+#X obj 330 145 outlet;
+#X text 91 57 First build masses \, then links!!;
+#X obj 234 285 outlet;
+#N canvas 629 18 551 784 fix-mass-ids 0;
+#X obj 43 72 t b b b b b b b;
+#X msg 79 168 traverse pd-data \, next;
+#X obj 79 200 pointer mass;
+#X obj 143 103 s \$0-reset-counter;
+#N canvas 331 520 708 349 counter 0;
+#X obj 156 125 f 0;
+#X msg 172 102 0;
+#X obj 172 74 r \$0-reset-counter;
+#X obj 188 125 + 1;
+#X obj 156 179 outlet;
+#X obj 156 50 inlet;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 1 0 0 1;
+#X connect 2 0 1 0;
+#X connect 3 0 0 1;
+#X connect 5 0 0 0;
+#X restore 96 298 pd counter;
+#X obj 96 396 set mass mid;
+#X text 176 200 At end: fix links!;
+#X obj 186 300 get mass mid;
+#X obj 79 247 t b b b b p p;
+#X obj 211 375 pack 0 0;
+#X obj 211 404 tabwrite \$0-mid2msdid;
+#X text 125 434 Store a mapping mid => msdid for fixing links later
+;
+#X obj 43 24 inlet;
+#X obj 158 221 outlet;
+#X text 96 52 Avoid stack overflow lops;
+#X obj 85 23 r \$0-stack-delay;
+#X obj 16 228 ds-next;
+#X obj 43 51 del 0;
+#X text 122 470 This still is not prepared to handle symbolic IDs!!!
+;
+#X connect 0 5 1 0;
+#X connect 0 6 3 0;
+#X connect 1 0 2 0;
+#X connect 2 0 8 0;
+#X connect 2 1 16 0;
+#X connect 2 2 13 0;
+#X connect 4 0 9 0;
+#X connect 4 0 5 0;
+#X connect 7 0 9 1;
+#X connect 8 0 16 0;
+#X connect 8 1 4 0;
+#X connect 8 4 7 0;
+#X connect 8 5 5 1;
+#X connect 9 0 10 0;
+#X connect 12 0 17 0;
+#X connect 15 0 17 1;
+#X connect 16 0 2 0;
+#X connect 17 0 0 0;
+#X restore 244 173 pd fix-mass-ids;
+#N canvas 403 15 685 826 fix-links 0;
+#X obj 139 158 t b b b b b b b;
+#X msg 175 254 traverse pd-data \, next;
+#X obj 239 189 s \$0-reset-counter;
+#X obj 175 284 pointer liaison;
+#X text 293 285 At end: make links in msd*!;
+#X obj 192 420 tabread \$0-mid2msdid;
+#X obj 192 482 set liaison mid1 mid2;
+#X obj 343 418 tabread \$0-mid2msdid;
+#X obj 192 389 get liaison mid1 mid2;
+#X obj 175 333 t b b b b p p;
+#X obj 139 70 inlet;
+#X obj 275 312 outlet;
+#X text 192 106 Avoid stack overflow lops;
+#X obj 188 68 r \$0-stack-delay;
+#X obj 113 282 ds-next;
+#X obj 139 105 del 0;
+#X connect 0 5 1 0;
+#X connect 1 0 3 0;
+#X connect 3 0 9 0;
+#X connect 3 1 14 0;
+#X connect 3 2 11 0;
+#X connect 5 0 6 0;
+#X connect 7 0 6 1;
+#X connect 8 0 5 0;
+#X connect 8 1 7 0;
+#X connect 9 0 14 0;
+#X connect 9 4 8 0;
+#X connect 9 5 6 2;
+#X connect 10 0 15 0;
+#X connect 13 0 15 1;
+#X connect 14 0 3 0;
+#X connect 15 0 0 0;
+#X restore 244 196 pd fix-links;
+#N canvas 236 8 602 856 get-masses 0;
+#X obj 148 80 t b b b b b b b;
+#X msg 184 176 traverse pd-data \, next;
+#X obj 184 206 pointer mass;
+#X obj 325 385 select 0;
+#X msg 365 410 0;
+#X msg 324 409 1;
+#X obj 248 111 s \$0-reset-counter;
+#X msg 248 131 const 0;
+#X obj 248 152 s \$0-mid;
+#X obj 310 152 s \$0-msdid;
+#X text 44 397 At end: start 2nd pass;
+#X obj 148 31 inlet;
+#X obj 214 494 outlet;
+#X obj 81 435 outlet;
+#X obj 184 255 t b p;
+#X obj 214 402 scale-ds2msd;
+#X obj 120 251 ds-next;
+#X obj 214 362 get mass x y mid mob M sid;
+#X obj 214 444 pack 0 0 0 0 0 0;
+#X connect 0 5 1 0;
+#X connect 0 6 6 0;
+#X connect 0 6 7 0;
+#X connect 1 0 2 0;
+#X connect 2 0 14 0;
+#X connect 2 1 16 0;
+#X connect 2 2 13 0;
+#X connect 3 0 5 0;
+#X connect 3 1 4 0;
+#X connect 4 0 18 3;
+#X connect 5 0 18 3;
+#X connect 7 0 8 0;
+#X connect 7 0 9 0;
+#X connect 11 0 0 0;
+#X connect 14 0 16 0;
+#X connect 14 1 17 0;
+#X connect 15 0 18 0;
+#X connect 15 1 18 1;
+#X connect 16 0 2 0;
+#X connect 17 0 15 0;
+#X connect 17 1 15 1;
+#X connect 17 2 18 2;
+#X connect 17 3 3 0;
+#X connect 17 4 18 4;
+#X connect 17 5 18 5;
+#X connect 18 0 12 0;
+#X restore 244 115 pd get-masses;
+#N canvas 0 0 768 708 make-links 0;
+#X obj 316 252 pointer liaison;
+#X msg 354 227 traverse pd-data \, bang;
+#X obj 286 274 t b p;
+#X obj 364 418 outlet;
+#X obj 354 170 inlet;
+#X obj 192 389 outlet;
+#X text 142 412 Now set lid field of links.;
+#X text 407 200 Avoid stack overflow lops;
+#X obj 399 167 r \$0-stack-delay;
+#X obj 286 226 ds-next;
+#X obj 354 201 del 0;
+#X obj 316 298 get liaison sid mid1 mid2 K D P Lmin Lmax;
+#X obj 364 385 pack 0 0 0 0 0 0 0 0;
+#X connect 0 0 2 0;
+#X connect 0 1 9 0;
+#X connect 0 2 5 0;
+#X connect 1 0 0 0;
+#X connect 2 0 9 0;
+#X connect 2 1 11 0;
+#X connect 4 0 10 0;
+#X connect 8 0 10 1;
+#X connect 9 0 0 0;
+#X connect 10 0 1 0;
+#X connect 11 0 12 0;
+#X connect 11 1 12 1;
+#X connect 11 2 12 2;
+#X connect 11 3 12 3;
+#X connect 11 4 12 4;
+#X connect 11 5 12 5;
+#X connect 11 6 12 6;
+#X connect 11 7 12 7;
+#X connect 12 0 3 0;
+#X restore 148 257 pd make-links;
+#X text 284 418 TABLES USED:;
+#X text 364 174 Change DS mass ids to match msdIds \, store mid2msdid
+mapping;
+#X text 366 196 Fix mid1 and mid2 in links to match what msd2D thinks
+is right.;
+#X text 257 258 Create messages to msd2D to create links;
+#X text 317 325 Correct lids to match what msd2D tells us;
+#X obj 146 446 table \$0-mid2msdid 4000;
+#X text 354 111 First get masses positions \, send to msd2D;
+#X text 324 446 mass id as index \, msdid as value. Size 4000 taken
+from the #define in msd sources.;
+#N canvas 283 271 635 631 set-lid-alternative 0;
+#X obj 43 72 t b b b b b b b;
+#X msg 79 168 traverse pd-data \, next;
+#N canvas 331 520 708 349 counter 0;
+#X obj 156 125 f 0;
+#X msg 172 102 0;
+#X obj 172 74 r \$0-reset-counter;
+#X obj 188 125 + 1;
+#X obj 156 179 outlet;
+#X obj 156 50 inlet;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 1 0 0 1;
+#X connect 2 0 1 0;
+#X connect 3 0 0 1;
+#X connect 5 0 0 0;
+#X restore 96 298 pd counter;
+#X obj 79 247 t b b b b p p;
+#X obj 43 24 inlet;
+#X text 96 52 Avoid stack overflow lops;
+#X obj 85 23 r \$0-stack-delay;
+#X obj 16 228 ds-next;
+#X obj 43 51 del 0;
+#X obj 79 200 pointer liaison;
+#X obj 96 396 set liaison lid;
+#X connect 0 5 1 0;
+#X connect 1 0 9 0;
+#X connect 2 0 10 0;
+#X connect 3 0 7 0;
+#X connect 3 1 2 0;
+#X connect 3 5 10 1;
+#X connect 4 0 8 0;
+#X connect 6 0 8 1;
+#X connect 7 0 9 0;
+#X connect 8 0 0 0;
+#X connect 9 0 3 0;
+#X connect 9 1 7 0;
+#X restore 148 329 pd set-lid-alternative;
+#X text 319 346 This is simpler and may work as well. It depends on
+sorted data structures.;
+#X connect 0 0 6 0;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 4 0;
+#X connect 6 1 1 0;
+#X connect 7 0 16 0;
+#X connect 7 1 3 0;
+#X restore 131 221 pd getter;
+#X obj 131 369 s \$0-msd;
+#X msg 170 107 reset;
+#X obj 170 132 s \$0-msd;
+#X obj 112 80 t b b b b;
+#N canvas 338 182 781 563 make-setters 0;
+#X obj 262 451 s pd-setter;
+#X obj 136 109 t b b b b;
+#X obj 262 337 get mass x y mid;
+#X msg 262 404 obj \$1 \$2 mass-set \$3;
+#X obj 262 360 pack 0 0 0;
+#X obj 171 335 s mypointer;
+#X msg 194 135 clear;
+#X obj 194 160 s pd-setter;
+#X obj 136 68 inlet;
+#X obj 174 240 pointer mass liaison;
+#X obj 506 373 pack 0 0 0;
+#X obj 506 350 get liaison x1 y1 lid;
+#X msg 506 417 obj \$1 \$2 link-set \$3;
+#X obj 506 462 s pd-lsetter;
+#X obj 194 186 s pd-lsetter;
+#X obj 399 350 s myliapointer;
+#X obj 136 487 outlet;
+#X text 196 487 Post-Actions;
+#X obj 401 270 t b p p;
+#X obj 174 272 t b p p;
+#N canvas 0 0 450 300 next 0;
+#X obj 140 92 inlet;
+#X obj 140 215 outlet;
+#X msg 140 169 next;
+#X obj 140 134 del 0;
+#X connect 0 0 3 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X restore 37 267 pd next;
+#X msg 174 213 traverse pd-data;
+#X obj 136 443 del 1;
+#N canvas 0 0 859 632 1002-make-lsynth 0;
+#X obj 190 186 pack 0 0 0 s;
+#X obj 190 121 spigot;
+#X obj 283 149 r \$0-lsynth-name;
+#X msg 190 209 obj \$1 \$2 \$4 \$3;
+#X obj 190 77 inlet;
+#X obj 190 153 unpack 0 0 0;
+#X obj 234 66 r \$0-gensynth;
+#X obj 190 234 s pd-lsynth;
+#X connect 0 0 3 0;
+#X connect 1 0 5 0;
+#X connect 2 0 0 3;
+#X connect 3 0 7 0;
+#X connect 4 0 1 0;
+#X connect 5 0 0 0;
+#X connect 5 1 0 1;
+#X connect 5 2 0 2;
+#X connect 6 0 1 1;
+#X restore 590 397 pd \$0-make-lsynth;
+#N canvas 0 0 859 632 1002-make-msynth 0;
+#X obj 190 186 pack 0 0 0 s;
+#X msg 190 209 obj \$1 \$2 \$4 \$3;
+#X obj 190 77 inlet;
+#X obj 190 153 unpack 0 0 0;
+#X obj 192 232 s pd-msynth;
+#X obj 285 149 r \$0-msynth-name;
+#X obj 236 66 r \$0-gensynth-m;
+#X obj 190 121 spigot;
+#X connect 0 0 1 0;
+#X connect 1 0 4 0;
+#X connect 2 0 7 0;
+#X connect 3 0 0 0;
+#X connect 3 1 0 1;
+#X connect 3 2 0 2;
+#X connect 5 0 0 3;
+#X connect 6 0 7 1;
+#X connect 7 0 3 0;
+#X restore 290 383 pd \$0-make-msynth;
+#X obj 328 126 spigot 0;
+#X obj 329 167 s pd-msynth;
+#X obj 419 167 s pd-lsynth;
+#X msg 329 144 clear;
+#X obj 418 126 spigot 0;
+#X msg 419 144 clear;
+#X obj 469 99 r \$0-gensynth;
+#X obj 379 76 r \$0-gensynth-m;
+#X connect 1 0 22 0;
+#X connect 1 1 20 0;
+#X connect 1 2 21 0;
+#X connect 1 3 6 0;
+#X connect 1 3 25 0;
+#X connect 1 3 29 0;
+#X connect 2 0 4 0;
+#X connect 2 1 4 1;
+#X connect 2 2 4 2;
+#X connect 3 0 0 0;
+#X connect 4 0 3 0;
+#X connect 4 0 24 0;
+#X connect 6 0 7 0;
+#X connect 6 0 14 0;
+#X connect 8 0 1 0;
+#X connect 9 0 19 0;
+#X connect 9 1 18 0;
+#X connect 10 0 12 0;
+#X connect 10 0 23 0;
+#X connect 11 0 10 0;
+#X connect 11 1 10 1;
+#X connect 11 2 10 2;
+#X connect 12 0 13 0;
+#X connect 18 0 20 0;
+#X connect 18 1 15 0;
+#X connect 18 2 11 0;
+#X connect 19 0 20 0;
+#X connect 19 1 5 0;
+#X connect 19 2 2 0;
+#X connect 20 0 9 0;
+#X connect 21 0 9 0;
+#X connect 22 0 16 0;
+#X connect 25 0 28 0;
+#X connect 28 0 26 0;
+#X connect 29 0 30 0;
+#X connect 30 0 27 0;
+#X connect 31 0 29 1;
+#X connect 32 0 25 1;
+#X restore 112 428 pd make-setters;
+#X obj 181 344 r pointer2msd;
+#N canvas 382 305 870 520 set-min-max 0;
+#X obj 98 80 r \$0-min-DS;
+#X obj 240 84 r \$0-max-DS;
+#X obj 468 80 r \$0-min-MSD;
+#X obj 605 108 r \$0-max-MSD;
+#X obj 98 131 s DS-xmin;
+#X obj 240 145 s DS-xmax;
+#X obj 98 111 f;
+#X obj 240 113 f;
+#X obj 468 109 f;
+#X obj 605 143 f;
+#X obj 340 13 inlet;
+#X obj 339 41 t b b;
+#X text 252 195 reverse!;
+#X text 95 177 reverse!;
+#X obj 241 176 s DS-ymin;
+#X obj 98 158 s DS-ymax;
+#X obj 468 135 s MSD-xmin;
+#X obj 605 174 s MSD-xmax;
+#X obj 469 157 s MSD-ymin;
+#X obj 605 198 s MSD-ymax;
+#X obj 339 207 t b b;
+#X obj 339 344 s \$0-msd;
+#X obj 339 280 pack 0 0;
+#X obj 339 239 f -3;
+#X obj 376 245 f 3;
+#X obj 745 82 f 0;
+#X obj 761 54 r MSD-TYPE;
+#X obj 746 109 s MSD-TYPE;
+#X msg 339 306 Xmin \$1 \, Xmax \$2 \, Ymin \$1 \, Ymax \$2 \, Zmin
+\$1 \, Zmax \$2;
+#X connect 0 0 6 0;
+#X connect 1 0 7 0;
+#X connect 2 0 8 0;
+#X connect 3 0 9 0;
+#X connect 6 0 4 0;
+#X connect 6 0 15 0;
+#X connect 7 0 5 0;
+#X connect 7 0 14 0;
+#X connect 8 0 16 0;
+#X connect 8 0 18 0;
+#X connect 8 0 23 1;
+#X connect 9 0 17 0;
+#X connect 9 0 19 0;
+#X connect 9 0 24 1;
+#X connect 10 0 11 0;
+#X connect 11 0 20 0;
+#X connect 11 1 6 0;
+#X connect 11 1 7 0;
+#X connect 11 1 8 0;
+#X connect 11 1 9 0;
+#X connect 11 1 25 0;
+#X connect 20 0 23 0;
+#X connect 20 1 24 0;
+#X connect 22 0 28 0;
+#X connect 23 0 22 0;
+#X connect 24 0 22 1;
+#X connect 25 0 27 0;
+#X connect 26 0 25 1;
+#X connect 28 0 21 0;
+#X restore 112 468 pd set-min-max;
+#X text 283 344 <== messages coming from the data structure setters
+;
+#X obj 112 399 del 200;
+#X obj 172 399 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 0 0 450 300 demux 0;
+#X obj 91 69 inlet;
+#X obj 255 73 inlet;
+#X obj 223 106 select 0;
+#X obj 73 213 spigot 1;
+#X obj 165 219 spigot 0;
+#X obj 141 188 unpack 1 0;
+#X obj 96 255 outlet;
+#X obj 173 257 outlet;
+#X msg 174 140 1 0;
+#X msg 216 140 0 1;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 2 0 8 0;
+#X connect 2 1 9 0;
+#X connect 3 0 6 0;
+#X connect 4 0 7 0;
+#X connect 5 0 3 1;
+#X connect 5 1 4 1;
+#X connect 8 0 5 0;
+#X connect 9 0 5 0;
+#X restore 189 246 pd demux;
+#X obj 240 219 r MSD-TYPE;
+#X obj 112 41 r \$0-generate;
+#X msg 189 275 mass \$6-m \$4 \$5 \$1 \$2;
+#X msg 341 275 mass \$6-m \$4 \$5 \$1 \$2 0;
+#X obj 150 187 s pd-data;
+#X msg 150 159 sort;
+#X msg 131 324 link \$1-l \$2 \$3 \$4 \$5 \$6 \$7 \$8;
+#X connect 0 0 18 0;
+#X connect 0 1 11 0;
+#X connect 2 0 3 0;
+#X connect 4 0 9 0;
+#X connect 4 1 0 0;
+#X connect 4 2 17 0;
+#X connect 4 3 2 0;
+#X connect 5 0 7 0;
+#X connect 6 0 1 0;
+#X connect 9 0 5 0;
+#X connect 10 0 5 0;
+#X connect 11 0 14 0;
+#X connect 11 1 15 0;
+#X connect 12 0 11 1;
+#X connect 13 0 4 0;
+#X connect 14 0 1 0;
+#X connect 15 0 1 0;
+#X connect 17 0 16 0;
+#X connect 18 0 1 0;
+#X restore 106 127 pd generator;
+#N canvas 444 101 836 641 set 0;
+#N canvas 311 93 877 551 getter 0;
+#X obj 148 80 t b b b b b b b;
+#X msg 184 176 traverse pd-data \, next;
+#X obj 184 206 pointer mass;
+#X obj 148 31 inlet;
+#X obj 214 494 outlet;
+#X obj 184 255 t b p;
+#X obj 214 402 scale-ds2msd;
+#X obj 120 251 ds-next;
+#X obj 214 362 get mass x y mid;
+#X obj 214 444 pack 0 0 0;
+#X connect 0 5 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 5 0;
+#X connect 2 1 7 0;
+#X connect 3 0 0 0;
+#X connect 5 0 7 0;
+#X connect 5 1 8 0;
+#X connect 6 0 9 0;
+#X connect 6 1 9 1;
+#X connect 7 0 2 0;
+#X connect 8 0 6 0;
+#X connect 8 1 6 1;
+#X connect 8 2 9 2;
+#X connect 9 0 4 0;
+#X restore 228 102 pd getter;
+#X obj 228 179 s \$0-msd;
+#X msg 213 140 posX \$3 \$1;
+#X msg 309 137 posY \$3 \$2;
+#X obj 227 80 r \$0-set-from-ds;
+#X connect 0 0 2 0;
+#X connect 0 0 3 0;
+#X connect 2 0 1 0;
+#X connect 3 0 1 0;
+#X connect 4 0 0 0;
+#X restore 148 105 pd set;
+#N canvas 410 39 529 725 edits 0;
+#N canvas 203 212 450 300 1002-show 0;
+#X obj 101 125 makefilename pd-%s;
+#X obj 50 153 pack 0 s;
+#X obj 50 63 t f b;
+#X msg 50 202 \; \$2 vis \$1;
+#X obj 50 33 inlet;
+#X obj 101 95 symbol \$0-edit-mass;
+#X connect 0 0 1 1;
+#X connect 1 0 3 0;
+#X connect 2 0 1 0;
+#X connect 2 1 5 0;
+#X connect 4 0 2 0;
+#X connect 5 0 0 0;
+#X restore 234 58 pd \$0-show;
+#X obj 234 34 tgl 20 0 empty \$0-show-masseditor edit_mass 0 -6 0 8
+-262144 -1 -1 0 1;
+#N canvas 786 268 360 441 1002-edit-mass 0;
+#X obj 48 68 nbx 5 14 -1e+37 1e+37 0 0 \$0-mob-set \$0-mob-get mob_(900=fixed)
+0 -8 1 10 -262144 -1 -1 0 256;
+#X obj 48 31 nbx 5 15 -1e+37 1e+37 0 0 \$0-mid-set \$0-mid-get mass-id
+0 -6 1 10 -1 -233017 -1 0 256;
+#X obj 48 106 nbx 5 14 -1e+37 1e+37 0 0 \$0-M-set \$0-M-get Mass 0
+-6 1 10 -262144 -1 -1 0 256;
+#X obj 48 146 nbx 5 14 -1e+37 1e+37 0 0 \$0-sid-set \$0-sid-get SymbolicID
+0 -6 1 10 -262144 -1 -1 0 256;
+#X obj 39 403 s \$0-edit-mass;
+#X msg 39 379 vnext 1;
+#X obj 48 174 nbx 5 14 -1e+37 1e+37 0 0 \$0-mx-set \$0-mx-get x 0 -6
+1 10 -262144 -1 -1 0 256;
+#X obj 48 202 nbx 5 14 -1e+37 1e+37 0 0 \$0-my-set \$0-my-get y 0 -6
+1 10 -262144 -1 -1 0 256;
+#X msg 40 356 traverse pd-data;
+#X obj 218 29 nbx 5 15 -1e+37 1e+37 0 0 \$0-set-l-lid \$0-get-l-lid
+link-id 0 -6 1 10 -1 -233017 -1 0 256;
+#X msg 215 378 vnext 1;
+#X obj 215 401 s \$0-edit-link;
+#X obj 218 63 nbx 5 15 -1e+37 1e+37 0 0 \$0-set-l-mid1 \$0-get-l-mid1
+mass1 0 -6 1 10 -262144 -1 -1 0 256;
+#X obj 218 95 nbx 5 15 -1e+37 1e+37 0 0 \$0-set-l-mid2 \$0-get-l-mid2
+mass2 0 -6 1 10 -262144 -1 -1 0 256;
+#X obj 218 131 nbx 5 15 -1e+37 1e+37 0 0 \$0-set-l-sid \$0-get-l-sid
+SymbolicID 0 -6 1 10 -262144 -1 -1 0 256;
+#X obj 218 171 nbx 5 15 -1e+37 1e+37 0 0 \$0-set-l-K \$0-get-l-K K
+0 -6 1 10 -262144 -1 -1 0 256;
+#X obj 218 201 nbx 5 15 -1e+37 1e+37 0 0 \$0-set-l-D \$0-get-l-D D
+0 -6 1 10 -262144 -1 -1 0 256;
+#X obj 218 233 nbx 5 15 -1e+37 1e+37 0 0 \$0-set-l-P \$0-get-l-P P
+0 -6 1 10 -262144 -1 -1 0 256;
+#X obj 218 265 nbx 5 15 -1e+37 1e+37 0 0 \$0-set-l-Lmin \$0-get-l-Lmin
+Lmin 0 -6 1 10 -262144 -1 -1 0 256;
+#X obj 218 301 nbx 5 15 -1e+37 1e+37 0 0 \$0-set-l-Lmax \$0-get-l-Lmax
+Lmax 0 -6 1 10 -262144 -1 -1 0 256;
+#X msg 216 354 traverse pd-data;
+#X text 39 331 Next mass:;
+#X text 215 326 Next link:;
+#X connect 5 0 4 0;
+#X connect 8 0 4 0;
+#X connect 10 0 11 0;
+#X connect 20 0 11 0;
+#X restore 42 33 pd \$0-edit-mass;
+#N canvas 0 0 589 777 1002-editmass-guts 0;
+#X obj 80 289 s \$0-mob-get;
+#X obj 45 318 s \$0-mid-get;
+#X obj 115 258 s \$0-M-get;
+#X obj 151 230 s \$0-sid-get;
+#X msg 84 175 vnext 1;
+#X obj 20 63 r \$0-edit-mass;
+#X obj 45 83 loadbang;
+#X obj 45 148 pointer mass;
+#X obj 79 382 r \$0-mob-set;
+#X obj 41 411 r \$0-mid-set;
+#X obj 153 323 r \$0-sid-set;
+#X obj 115 351 r \$0-M-set;
+#X obj 14 175 t p p;
+#X obj 267 435 set mass M;
+#X obj 350 435 set mass sid;
+#X obj 170 436 set mass mob;
+#X obj 41 439 set mass mid;
+#X obj 252 322 pointer mass;
+#X msg 45 110 traverse pd-data;
+#X obj 45 201 get mass mid mob M sid x y;
+#X obj 193 258 s \$0-mx-get;
+#X obj 244 234 s \$0-my-get;
+#X obj 99 515 set mass x;
+#X obj 253 519 set mass y;
+#X obj 99 487 r \$0-mx-set;
+#X obj 252 495 r \$0-my-set;
+#X connect 4 0 7 0;
+#X connect 5 0 7 0;
+#X connect 6 0 18 0;
+#X connect 7 0 12 0;
+#X connect 7 1 4 0;
+#X connect 7 2 18 0;
+#X connect 8 0 15 0;
+#X connect 9 0 16 0;
+#X connect 10 0 14 0;
+#X connect 11 0 13 0;
+#X connect 12 0 19 0;
+#X connect 12 1 17 0;
+#X connect 17 0 16 1;
+#X connect 17 0 15 1;
+#X connect 17 0 13 1;
+#X connect 17 0 14 1;
+#X connect 17 0 23 1;
+#X connect 17 0 22 1;
+#X connect 18 0 7 0;
+#X connect 19 0 1 0;
+#X connect 19 1 0 0;
+#X connect 19 2 2 0;
+#X connect 19 3 3 0;
+#X connect 19 4 20 0;
+#X connect 19 5 21 0;
+#X connect 24 0 22 0;
+#X connect 25 0 23 0;
+#X restore 43 59 pd \$0-editmass-guts;
+#N canvas 599 247 589 777 1002-editlinks-guts 0;
+#X msg 84 175 vnext 1;
+#X obj 45 83 loadbang;
+#X obj 14 175 t p p;
+#X msg 45 110 traverse pd-data;
+#X obj 20 63 r \$0-edit-link;
+#X obj 45 148 pointer liaison;
+#X obj 325 279 s \$0-get-l-sid;
+#X obj 289 308 s \$0-get-l-Lmax;
+#X obj 249 338 s \$0-get-l-Lmin;
+#X obj 211 370 s \$0-get-l-P;
+#X obj 178 398 s \$0-get-l-D;
+#X obj 130 419 s \$0-get-l-K;
+#X obj 10 226 get liaison mid1 mid2 lid K D P Lmin Lmax sid;
+#X obj 17 544 s \$0-get-l-mid1;
+#X obj 52 493 s \$0-get-l-mid2;
+#X obj 92 469 s \$0-get-l-lid;
+#N canvas 266 70 710 834 1002-lset 0;
+#X obj 31 44 inlet;
+#X obj 41 65 s \$0-current-set-link;
+#X obj 483 69 r \$0-current-set-link;
+#X obj 372 38 r \$0-set-l-mid2;
+#X obj 379 98 set liaison mid2;
+#X obj 169 547 r \$0-current-set-link;
+#X obj 64 550 r \$0-set-l-lid;
+#X obj 65 576 set liaison lid;
+#X obj 170 493 r \$0-current-set-link;
+#X obj 65 496 r \$0-set-l-K;
+#X obj 66 522 set liaison K;
+#X obj 164 443 r \$0-current-set-link;
+#X obj 67 440 r \$0-set-l-D;
+#X obj 158 371 r \$0-current-set-link;
+#X obj 68 468 set liaison D;
+#X obj 64 398 set liaison P;
+#X obj 61 368 r \$0-set-l-P;
+#X obj 169 316 r \$0-current-set-link;
+#X obj 56 311 r \$0-set-l-Lmin;
+#X obj 59 339 set liaison Lmin;
+#X obj 171 248 r \$0-current-set-link;
+#X obj 59 271 set liaison Lmax;
+#X obj 56 243 r \$0-set-l-Lmax;
+#X obj 174 178 r \$0-current-set-link;
+#X obj 69 181 r \$0-set-l-sid;
+#X obj 70 207 set liaison sid;
+#X obj 408 179 pointer mass;
+#X msg 409 142 traverse pd-data \, next;
+#X msg 362 180 next;
+#X obj 408 226 get mass mid;
+#X obj 399 273 select;
+#X obj 406 202 t p p;
+#X obj 402 298 pointer;
+#X obj 402 337 get mass x y;
+#X obj 374 67 t f b f;
+#X obj 503 360 r \$0-current-set-link;
+#X obj 397 386 set liaison x2 y2;
+#X obj 504 449 r \$0-current-set-link;
+#X obj 429 559 pointer mass;
+#X msg 438 528 traverse pd-data \, next;
+#X msg 383 560 next;
+#X obj 429 606 get mass mid;
+#X obj 420 653 select;
+#X obj 427 582 t p p;
+#X obj 423 678 pointer;
+#X obj 423 717 get mass x y;
+#X obj 395 447 t f b f;
+#X obj 524 740 r \$0-current-set-link;
+#X obj 391 418 r \$0-set-l-mid1;
+#X obj 400 478 set liaison mid1;
+#X obj 418 766 set liaison x1 y1;
+#X obj 401 501 t b b;
+#X obj 396 529 until;
+#X obj 363 117 t b b;
+#X obj 358 145 until;
+#X connect 0 0 1 0;
+#X connect 2 0 4 1;
+#X connect 3 0 34 0;
+#X connect 5 0 7 1;
+#X connect 6 0 7 0;
+#X connect 8 0 10 1;
+#X connect 9 0 10 0;
+#X connect 11 0 14 1;
+#X connect 12 0 14 0;
+#X connect 13 0 15 1;
+#X connect 16 0 15 0;
+#X connect 17 0 19 1;
+#X connect 18 0 19 0;
+#X connect 20 0 21 1;
+#X connect 22 0 21 0;
+#X connect 23 0 25 1;
+#X connect 24 0 25 0;
+#X connect 26 0 31 0;
+#X connect 26 1 28 0;
+#X connect 26 2 54 1;
+#X connect 27 0 26 0;
+#X connect 28 0 26 0;
+#X connect 29 0 30 0;
+#X connect 30 0 32 0;
+#X connect 31 0 29 0;
+#X connect 31 1 32 1;
+#X connect 32 0 33 0;
+#X connect 33 0 36 0;
+#X connect 33 1 36 1;
+#X connect 34 0 4 0;
+#X connect 34 1 53 0;
+#X connect 34 2 30 1;
+#X connect 35 0 36 2;
+#X connect 37 0 49 1;
+#X connect 38 0 43 0;
+#X connect 38 1 40 0;
+#X connect 38 2 52 1;
+#X connect 39 0 38 0;
+#X connect 40 0 38 0;
+#X connect 41 0 42 0;
+#X connect 42 0 44 0;
+#X connect 43 0 41 0;
+#X connect 43 1 44 1;
+#X connect 44 0 45 0;
+#X connect 45 0 50 0;
+#X connect 45 1 50 1;
+#X connect 46 0 49 0;
+#X connect 46 1 51 0;
+#X connect 46 2 42 1;
+#X connect 47 0 50 2;
+#X connect 48 0 46 0;
+#X connect 51 0 52 0;
+#X connect 51 1 39 0;
+#X connect 52 0 40 0;
+#X connect 53 0 54 0;
+#X connect 53 1 27 0;
+#X connect 54 0 28 0;
+#X restore 46 201 pd \$0-lset;
+#X msg 19 521 set \$1;
+#X msg 50 286 set \$1;
+#X msg 84 314 set \$1;
+#X msg 124 288 set \$1;
+#X msg 168 320 set \$1;
+#X msg 202 278 set \$1;
+#X msg 242 302 set \$1;
+#X msg 278 272 set \$1;
+#X msg 321 251 set \$1;
+#X connect 0 0 5 0;
+#X connect 1 0 3 0;
+#X connect 2 0 12 0;
+#X connect 2 1 16 0;
+#X connect 3 0 5 0;
+#X connect 4 0 5 0;
+#X connect 5 0 2 0;
+#X connect 5 1 0 0;
+#X connect 5 2 3 0;
+#X connect 12 0 17 0;
+#X connect 12 1 18 0;
+#X connect 12 2 19 0;
+#X connect 12 3 20 0;
+#X connect 12 4 21 0;
+#X connect 12 5 22 0;
+#X connect 12 6 23 0;
+#X connect 12 7 24 0;
+#X connect 12 8 25 0;
+#X connect 17 0 13 0;
+#X connect 18 0 14 0;
+#X connect 19 0 15 0;
+#X connect 20 0 11 0;
+#X connect 21 0 10 0;
+#X connect 22 0 9 0;
+#X connect 23 0 8 0;
+#X connect 24 0 7 0;
+#X connect 25 0 6 0;
+#X restore 43 87 pd \$0-editlinks-guts;
+#X connect 1 0 0 0;
+#X restore 118 156 pd edits;
+#X restore 348 573 pd guts;
+#X obj 29 249 tgl 18 0 \$0-show-masseditor empty EditParam 22 9 0 8
+-1 -233017 -1 0 1;
+#X obj 181 355 nbx 2 14 0 99 0 0 \$0-show-mids \$0-show-mids show-mids
+0 -6 0 8 -225280 -1 -1 0 256;
+#N canvas 0 0 106 49 obj 0;
+#X obj 2 3 cnv 15 100 40 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 7 18 bng 20 250 50 0 empty empty load 0 -6 0 8 -258699 -1 -1
+;
+#X obj 38 17 tgl 15 0 RENDER-PRIMTRI RENDER-PRIMTRI TRI 0 -6 0 8 -262131
+-1 -1 0 1;
+#X obj 110 6 obj-render;
+#X obj 62 17 tgl 15 0 \$0-gen-tri \$0-gen-tri Gen-TRI 0 -6 0 8 -261681
+-1 -1 0 1;
+#X obj 111 26 s \$0-msd;
+#X connect 1 0 3 0;
+#X connect 3 0 5 0;
+#X connect 4 0 3 1;
+#X coords 0 0 1 1 102 44 1;
+#X restore 304 489 pd obj;
+#X text 229 537 Save MSD;
+#X text 314 538 Load *.obj;
+#X text 112 537 Save or Load DS;
+#X connect 4 0 5 0;
+#X connect 4 1 6 0;
+#X connect 5 0 4 0;
+#X connect 6 0 4 1;
+#X connect 7 0 4 2;
+#X connect 11 0 10 0;
+#X connect 14 0 41 0;
+#X connect 25 0 9 1;
+#X connect 26 0 9 2;
+#X connect 27 0 9 0;
+#X connect 33 0 9 3;
+#X connect 40 0 14 2;
+#X connect 43 0 42 0;
diff --git a/msd/editor/msd_append.pd b/msd/editor/msd_append.pd
new file mode 100644
index 0000000..7c5a13e
--- /dev/null
+++ b/msd/editor/msd_append.pd
@@ -0,0 +1,248 @@
+#N canvas 862 152 89 147 10;
+#X obj 2 16 cnv 15 80 60 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 6 29 bng 15 250 50 0 empty empty mass 0 -6 0 8 -1 -262144 -1
+;
+#X obj 34 29 bng 15 250 50 0 empty empty fix 0 -6 0 8 -258699 -1 -1
+;
+#N canvas 355 305 863 719 guts 0;
+#X obj 289 340 pointer;
+#X msg 289 303 traverse pd-data \, bang;
+#X obj 107 89 inlet;
+#X obj 214 89 inlet;
+#X obj 679 378 + 1;
+#X obj 649 318 r \$0-counter-bng;
+#X obj 649 420 s \$0-nextmass;
+#X obj 182 354 r \$0-nextmass;
+#X obj 107 298 s \$0-counter-bng;
+#X msg 107 112 0;
+#X text 148 89 mobile;
+#X text 260 89 fixed mass;
+#X msg 214 111 900;
+#X obj 649 378 f 0;
+#X obj 685 343 loadbang;
+#X obj 549 321 r \$0-counter;
+#X msg 590 411 set \$1;
+#X obj 590 452 s \$0-counter-in;
+#X obj 245 334 r \$0-M;
+#X obj 553 175 f \$1;
+#X obj 553 199 select 0;
+#X obj 553 254 s \$0-M;
+#X msg 552 224 100;
+#X obj 558 152 loadbang;
+#X obj 40 316 r \$0-geos;
+#X obj 289 278 r \$0-start-traverse;
+#X obj 216 405 f 0;
+#X obj 40 339 t a b;
+#X obj 232 374 r \$0-mfds;
+#X obj 270 399 r \$0-msid;
+#X obj 105 432 append mass x y mid mob M sid;
+#X obj 678 195 loadbang;
+#X obj 678 249 s \$0-msid;
+#X msg 678 221 0;
+#X msg 197 376 \$1;
+#X obj 141 172 random 100;
+#X obj 227 172 random 100;
+#X obj 141 196 + 20;
+#X obj 227 194 + 20;
+#X obj 107 272 t b a b b b a b;
+#X msg 123 356 \$2 \$3;
+#X obj 128 150 t f b;
+#X obj 107 230 pack 0 0 0;
+#X obj 363 90 inlet;
+#X text 410 91 another mass: list of "mob \, x \, y";
+#X obj 105 477 outlet;
+#X text 159 480 last mass created;
+#X obj 338 531 append hole x y;
+#X obj 438 505 pointer;
+#X msg 438 468 traverse pd-data \, bang;
+#X obj 438 443 r \$0-start-traverse;
+#X msg 338 479 10 10;
+#X connect 0 0 30 6;
+#X connect 1 0 0 0;
+#X connect 2 0 9 0;
+#X connect 3 0 12 0;
+#X connect 4 0 13 1;
+#X connect 5 0 13 0;
+#X connect 7 0 30 2;
+#X connect 9 0 41 0;
+#X connect 12 0 41 0;
+#X connect 13 0 4 0;
+#X connect 13 0 6 0;
+#X connect 13 0 16 0;
+#X connect 14 0 13 0;
+#X connect 15 0 13 0;
+#X connect 16 0 17 0;
+#X connect 18 0 30 4;
+#X connect 19 0 20 0;
+#X connect 20 0 22 0;
+#X connect 20 1 21 0;
+#X connect 22 0 21 0;
+#X connect 23 0 19 0;
+#X connect 24 0 27 0;
+#X connect 25 0 1 0;
+#X connect 26 0 30 3;
+#X connect 27 0 30 0;
+#X connect 27 1 26 0;
+#X connect 28 0 26 1;
+#X connect 29 0 30 5;
+#X connect 30 0 45 0;
+#X connect 31 0 33 0;
+#X connect 33 0 32 0;
+#X connect 34 0 30 3;
+#X connect 35 0 37 0;
+#X connect 36 0 38 0;
+#X connect 37 0 42 1;
+#X connect 38 0 42 2;
+#X connect 39 0 8 0;
+#X connect 39 1 40 0;
+#X connect 39 5 34 0;
+#X connect 39 6 1 0;
+#X connect 40 0 30 0;
+#X connect 41 0 42 0;
+#X connect 41 1 35 0;
+#X connect 41 1 36 0;
+#X connect 42 0 39 0;
+#X connect 43 0 42 0;
+#X connect 48 0 47 2;
+#X connect 49 0 48 0;
+#X connect 50 0 49 0;
+#X connect 51 0 47 0;
+#X restore 105 79 pd guts;
+#X obj 105 6 inlet;
+#X obj 148 5 inlet;
+#X obj 25 59 nbx 5 14 -1e+37 1e+37 0 0 \$0-counter \$0-counter-in id
+-22 8 0 10 -262144 -1 -1 0 256;
+#X obj 2 79 cnv 15 80 60 empty empty empty 10 10 0 10 -195568 -1 0
+;
+#X obj 26 85 nbx 5 14 -1e+37 1e+37 0 0 \$0-M \$0-M M -12 8 0 10 -225271
+-1 -1 100 256;
+#N canvas 379 246 663 624 geos 0;
+#X obj 93 96 make_rect 100 100 30 30 10 10;
+#X obj 123 162 s \$0-geos;
+#X obj 93 188 s \$0-counter-bng;
+#X obj 48 33 r \$0-make-rect;
+#X msg 93 67 bang;
+#N canvas 449 480 450 300 1015-geos 0;
+#X obj 48 82 bng 24 250 50 0 \$0-make-rect empty make-rect 0 -6 0 8
+-24198 -1 -1;
+#X floatatom 151 76 5 0 0 0 x0 - #0-x0;
+#X floatatom 151 92 5 0 0 0 y0 - #0-y0;
+#X floatatom 227 75 5 0 0 0 xgap - #0-xgap;
+#X floatatom 227 91 5 0 0 0 ygap - #0-ygap;
+#X floatatom 322 74 5 0 0 0 xsteps - #0-xsteps;
+#X floatatom 322 90 5 0 0 0 ysteps - #0-ysteps;
+#X text 46 18 Add various geometric forms;
+#X text 38 46 Rectangle Networks:;
+#X text 37 137 Circles:;
+#X obj 52 172 bng 24 250 50 0 \$0-make-circ empty make-circ 0 -6 0
+8 -24198 -1 -1;
+#X floatatom 145 166 5 0 0 0 x0 - #0-x0-circ;
+#X floatatom 145 182 5 0 0 0 y0 - #0-y0-circ;
+#X floatatom 251 166 5 0 0 0 radius - #0-radius;
+#X floatatom 251 184 5 0 0 0 masses_# - #0-masses-circ;
+#X text 107 266 All coords as used by data structs.;
+#X obj 54 233 hradio 15 1 0 2 \$0-mf \$0-mf Mobile/Fix 0 -6 0 8 -262144
+-1 -1 0;
+#X obj 91 234 cnv 15 60 15 \$0-mobfix \$0-mobfix mobile 2 6 0 10 -233017
+-66577 0;
+#X restore 518 165 pd \$0-geos;
+#X msg 519 125 \; \$1 vis 1;
+#X obj 518 96 makefilename pd-%s;
+#X obj 520 68 symbol \$0-geos;
+#X msg 516 22 bang;
+#X obj 48 66 t b b;
+#X obj 78 226 s \$0-start-traverse;
+#N canvas 0 0 930 534 1015-sixpack 0;
+#X obj 250 282 r \$0-x0;
+#X text 452 208 Args;
+#X obj 320 310 sixpack --------------------;
+#X obj 296 237 r \$0-y0;
+#X obj 336 206 r \$0-xgap;
+#X obj 376 185 r \$0-ygap;
+#X obj 412 164 r \$0-xsteps;
+#X obj 448 143 r \$0-ysteps;
+#X obj 326 342 outlet;
+#X connect 0 0 2 0;
+#X connect 2 0 8 0;
+#X connect 3 0 2 1;
+#X connect 4 0 2 2;
+#X connect 5 0 2 3;
+#X connect 6 0 2 4;
+#X connect 7 0 2 5;
+#X restore 291 40 pd \$0-sixpack;
+#X obj 93 128 t b a;
+#X obj 524 45 r \$0-show-geos;
+#X obj 63 322 r \$0-make-circ;
+#N canvas 0 0 930 534 1015-fourpack 0;
+#X text 452 208 Args;
+#X obj 320 310 sixpack --------------------;
+#X obj 319 390 outlet;
+#X msg 319 349 \$1 \$2 \$3 \$4;
+#X obj 252 282 r \$0-x0-circ;
+#X obj 296 237 r \$0-y0-circ;
+#X obj 376 185 r \$0-masses-circ;
+#X obj 336 206 r \$0-radius;
+#X connect 1 0 3 0;
+#X connect 3 0 2 0;
+#X connect 4 0 1 0;
+#X connect 5 0 1 1;
+#X connect 6 0 1 3;
+#X connect 7 0 1 2;
+#X restore 219 327 pd \$0-fourpack;
+#X obj 136 441 s \$0-geos;
+#X obj 106 467 s \$0-counter-bng;
+#X obj 63 345 t b b;
+#X obj 93 505 s \$0-start-traverse;
+#X obj 106 407 t b a;
+#X obj 63 370 make_circ 300 300 100 8;
+#X obj 368 266 select 0;
+#X msg 368 306 label mobile;
+#X obj 368 329 s \$0-mobfix;
+#X msg 420 288 label fix;
+#X obj 368 236 r \$0-mf;
+#X obj 507 332 s \$0-mfds;
+#X msg 508 301 0;
+#X msg 544 299 900;
+#X connect 0 0 13 0;
+#X connect 3 0 10 0;
+#X connect 4 0 0 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 0;
+#X connect 9 0 8 0;
+#X connect 10 0 0 0;
+#X connect 10 1 11 0;
+#X connect 12 0 0 1;
+#X connect 13 0 2 0;
+#X connect 13 1 1 0;
+#X connect 14 0 8 0;
+#X connect 15 0 19 0;
+#X connect 16 0 22 1;
+#X connect 19 0 22 0;
+#X connect 19 1 20 0;
+#X connect 21 0 18 0;
+#X connect 21 1 17 0;
+#X connect 22 0 21 0;
+#X connect 23 0 24 0;
+#X connect 23 0 29 0;
+#X connect 23 1 26 0;
+#X connect 23 1 30 0;
+#X connect 24 0 25 0;
+#X connect 26 0 25 0;
+#X connect 27 0 23 0;
+#X connect 29 0 28 0;
+#X connect 30 0 28 0;
+#X restore 106 122 pd geos;
+#X obj 59 29 bng 15 250 50 0 \$0-show-geos \$0-show-geos geos 0 -6
+0 8 -225271 -1 -1;
+#X obj 35 111 nbx 4 14 -1e+37 1e+37 0 0 \$0-msid \$0-msid SID -30 8
+0 10 -261681 -1 -1 0 256;
+#X obj 200 1 inlet;
+#X obj 105 103 outlet;
+#X connect 1 0 3 0;
+#X connect 2 0 3 1;
+#X connect 3 0 13 0;
+#X connect 4 0 3 0;
+#X connect 5 0 3 1;
+#X connect 12 0 3 2;
+#X coords 0 0 1 1 82 130 1;
diff --git a/msd/editor/mytri.pd b/msd/editor/mytri.pd
new file mode 100644
index 0000000..8049938
--- /dev/null
+++ b/msd/editor/mytri.pd
@@ -0,0 +1,45 @@
+#N canvas 0 0 773 622 10;
+#X obj 271 316 cnv 15 100 30 empty empty empty 20 12 0 14 -24198 -66577
+0;
+#X msg 222 209 draw line;
+#X msg 222 230 draw fill;
+#X msg 222 252 draw point;
+#X msg 309 242 0 0 1;
+#X msg 302 223 0 1 0;
+#X msg 294 204 1 0 0;
+#X text 335 204 (XYZ)1;
+#X text 347 222 (XYZ)2;
+#X text 357 242 (XYZ)3;
+#X msg 334 302 0 0 1;
+#X msg 327 283 0 1 0;
+#X msg 319 264 1 0 0;
+#X text 362 264 (XYZ)1;
+#X text 372 282 (XYZ)2;
+#X text 382 302 (XYZ)3;
+#X obj 280 323 primTri;
+#X obj 327 75 r MSD-OUT-GLOBAL;
+#X obj 314 148 route massesPos;
+#X obj 383 187 route \$1 \$2 \$3;
+#X obj 113 170 gemhead;
+#X obj 173 169 r RENDER-PRIMTRI;
+#X obj 113 215 spigot 0;
+#X obj 322 115 spigot 0;
+#X connect 1 0 16 0;
+#X connect 2 0 16 0;
+#X connect 3 0 16 0;
+#X connect 4 0 16 3;
+#X connect 5 0 16 2;
+#X connect 6 0 16 1;
+#X connect 10 0 16 6;
+#X connect 11 0 16 5;
+#X connect 12 0 16 4;
+#X connect 17 0 23 0;
+#X connect 18 0 19 0;
+#X connect 19 0 16 1;
+#X connect 19 1 16 3;
+#X connect 19 2 16 2;
+#X connect 20 0 22 0;
+#X connect 21 0 22 1;
+#X connect 21 0 23 1;
+#X connect 22 0 16 0;
+#X connect 23 0 18 0;
diff --git a/msd/editor/obj-render.pd b/msd/editor/obj-render.pd
new file mode 100644
index 0000000..3f2430b
--- /dev/null
+++ b/msd/editor/obj-render.pd
@@ -0,0 +1,141 @@
+#N canvas 226 31 720 648 10;
+#X obj 175 139 textfile;
+#N canvas 550 94 450 300 tri 0;
+#X restore 175 616 pd tri;
+#X msg 551 125 rewind;
+#X obj 175 99 until;
+#X obj 175 585 s pd-tri;
+#X msg 12 531 clear;
+#X msg 115 445 \$1;
+#X msg 219 447 \$1;
+#X msg 323 446 \$1;
+#X obj 175 517 pack 0 0 0;
+#X obj 115 481 - 1;
+#X obj 219 479 - 1;
+#X obj 323 481 - 1;
+#X obj 175 218 route f v;
+#X msg 472 357 mass 0-m 1 100 \$1 \$2 \$3;
+#X msg 482 430 link 0-l \$1 \$2 10 2.5 1.5;
+#X msg 482 401 \$1 \$2 \, \$2 \$3 \, \$3 \$1;
+#X msg 495 477 reset;
+#X obj 175 67 t b b;
+#N canvas 282 359 730 665 find-min-max 0;
+#X obj 166 448 outlet;
+#X obj 100 66 inlet;
+#X obj 182 26 inlet;
+#X obj 235 133 inlet;
+#X obj 182 124 abs;
+#X obj 182 223 spigot;
+#X obj 182 158 t f f;
+#X obj 166 388 pack 0 0;
+#X msg 166 414 Xmin \$1 \, Xmax \$2 \, Ymin \$1 \, Ymax \$2 \, Zmin
+\$1 \, Zmax \$2;
+#X obj 166 347 * -1;
+#X obj 166 323 t f f;
+#X obj 166 265 f 4;
+#X obj 219 197 > 4;
+#X msg 235 168 4;
+#X text 251 221 find maximum of all x \, y \, z;
+#X text 293 134 rest;
+#X text 216 326 at end \, send max to msd3D;
+#X obj 166 291 + 1;
+#X obj 182 52 t a a a;
+#X msg 251 80 \$1;
+#X msg 217 80 \$2;
+#X msg 182 82 \$3;
+#X connect 1 0 11 0;
+#X connect 2 0 18 0;
+#X connect 3 0 13 0;
+#X connect 4 0 6 0;
+#X connect 5 0 11 1;
+#X connect 6 0 5 0;
+#X connect 6 1 12 0;
+#X connect 7 0 8 0;
+#X connect 8 0 0 0;
+#X connect 9 0 7 0;
+#X connect 10 0 9 0;
+#X connect 10 1 7 1;
+#X connect 11 0 17 0;
+#X connect 12 0 5 1;
+#X connect 13 0 12 1;
+#X connect 17 0 10 0;
+#X connect 18 0 21 0;
+#X connect 18 1 20 0;
+#X connect 18 2 19 0;
+#X connect 19 0 4 0;
+#X connect 20 0 4 0;
+#X connect 21 0 4 0;
+#X restore 285 266 pd find-min-max;
+#X obj 233 100 s \$0-obj-import-init;
+#X obj 385 236 r \$0-obj-import-init;
+#X obj 495 456 r \$0-obj-import-init;
+#X obj 12 506 r \$0-obj-import-init;
+#X obj 24 99 r \$0-ob-import-file;
+#X obj 409 157 s \$0-ob-import-file;
+#X obj 409 59 openpanel;
+#X obj 409 37 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 428 124 print;
+#X msg 409 102 read \$1 cr \, rewind;
+#X msg 495 126 bang;
+#X msg 175 32 bang;
+#X obj 551 99 r \$0-obj-import-init;
+#X msg 281 181 \; pd-tri loadbang;
+#X msg 175 542 obj 0 0 mytri \$1 \$2 \$3;
+#X obj 383 81 t b a;
+#X obj 409 12 inlet;
+#X obj 572 546 inlet;
+#X obj 175 563 spigot;
+#X obj 472 509 outlet;
+#X obj 115 414 symbol2list /;
+#X obj 219 414 symbol2list /;
+#X obj 323 413 symbol2list /;
+#X obj 175 376 unpack s s s;
+#X connect 0 0 13 0;
+#X connect 0 1 3 1;
+#X connect 0 1 19 0;
+#X connect 0 1 33 0;
+#X connect 2 0 25 0;
+#X connect 3 0 0 0;
+#X connect 5 0 4 0;
+#X connect 6 0 10 0;
+#X connect 7 0 11 0;
+#X connect 8 0 12 0;
+#X connect 9 0 34 0;
+#X connect 9 0 16 0;
+#X connect 10 0 9 0;
+#X connect 11 0 9 1;
+#X connect 12 0 9 2;
+#X connect 13 0 43 0;
+#X connect 13 1 14 0;
+#X connect 13 1 19 1;
+#X connect 14 0 39 0;
+#X connect 15 0 39 0;
+#X connect 16 0 15 0;
+#X connect 17 0 39 0;
+#X connect 18 0 3 0;
+#X connect 18 1 20 0;
+#X connect 19 0 39 0;
+#X connect 21 0 19 2;
+#X connect 22 0 17 0;
+#X connect 23 0 5 0;
+#X connect 24 0 0 0;
+#X connect 26 0 35 0;
+#X connect 27 0 26 0;
+#X connect 28 0 25 0;
+#X connect 29 0 25 0;
+#X connect 30 0 25 0;
+#X connect 31 0 18 0;
+#X connect 32 0 2 0;
+#X connect 34 0 38 0;
+#X connect 35 0 31 0;
+#X connect 35 1 29 0;
+#X connect 36 0 27 0;
+#X connect 37 0 38 1;
+#X connect 38 0 4 0;
+#X connect 40 0 6 0;
+#X connect 41 0 7 0;
+#X connect 42 0 8 0;
+#X connect 43 0 40 0;
+#X connect 43 1 41 0;
+#X connect 43 2 42 0;
diff --git a/msd/editor/scale-ds2msd.pd b/msd/editor/scale-ds2msd.pd
new file mode 100644
index 0000000..df103aa
--- /dev/null
+++ b/msd/editor/scale-ds2msd.pd
@@ -0,0 +1,42 @@
+#N canvas 257 161 999 516 10;
+#X obj 43 52 inlet;
+#X text 87 52 X-coord. as in DS;
+#X obj 43 255 outlet;
+#X obj 338 50 inlet;
+#X obj 338 253 outlet;
+#X text 382 50 Y-coord. as in DS;
+#X text 99 255 X-coord. as in MSD;
+#X text 398 253 Y-coord. as in MSD;
+#X obj 688 336 pack 0 0;
+#X obj 688 367 outlet;
+#X obj 689 55 unpack 0 0;
+#X obj 689 30 inlet;
+#X text 725 148 Or use lists: (x \, y);
+#X obj 78 101 r DS-xmin;
+#X obj 149 166 r MSD-xmin;
+#X obj 373 99 r DS-ymin;
+#X obj 444 164 r MSD-ymin;
+#X obj 114 128 r DS-xmax;
+#X obj 185 191 r MSD-xmax;
+#X obj 409 126 r DS-ymax;
+#X obj 480 189 r MSD-ymax;
+#X obj 43 218 expr_scale 0 600 -2 2;
+#X obj 338 216 expr_scale 600 0 -2 2;
+#X connect 0 0 21 0;
+#X connect 3 0 22 0;
+#X connect 8 0 9 0;
+#X connect 10 0 21 0;
+#X connect 10 1 22 1;
+#X connect 11 0 10 0;
+#X connect 13 0 21 1;
+#X connect 14 0 21 3;
+#X connect 15 0 22 1;
+#X connect 16 0 22 3;
+#X connect 17 0 21 2;
+#X connect 18 0 21 4;
+#X connect 19 0 22 2;
+#X connect 20 0 22 4;
+#X connect 21 0 2 0;
+#X connect 21 0 8 0;
+#X connect 22 0 4 0;
+#X connect 22 0 8 1;
diff --git a/msd/editor/scale-msd2ds.pd b/msd/editor/scale-msd2ds.pd
new file mode 100644
index 0000000..d90c3c2
--- /dev/null
+++ b/msd/editor/scale-msd2ds.pd
@@ -0,0 +1,42 @@
+#N canvas 9 170 970 485 10;
+#X obj 43 52 inlet;
+#X obj 43 255 outlet;
+#X obj 338 50 inlet;
+#X obj 338 253 outlet;
+#X text 382 50 Y-coord. as in MSD;
+#X text 87 52 X-coord. as in MSD;
+#X text 99 255 X-coord. as in DS;
+#X text 398 253 Y-coord. as in DS;
+#X obj 688 336 pack 0 0;
+#X obj 688 367 outlet;
+#X obj 689 55 unpack 0 0;
+#X obj 689 30 inlet;
+#X text 725 148 Or use lists: (x \, y);
+#X obj 78 164 r MSD-xmin;
+#X obj 114 189 r MSD-xmax;
+#X obj 149 111 r DS-xmin;
+#X obj 185 138 r DS-xmax;
+#X obj 444 99 r DS-ymin;
+#X obj 480 126 r DS-ymax;
+#X obj 373 164 r MSD-ymin;
+#X obj 409 189 r MSD-ymax;
+#X obj 338 216 expr_scale -2 2 600 0;
+#X obj 43 218 expr_scale -2 2 0 600;
+#X connect 0 0 22 0;
+#X connect 2 0 21 0;
+#X connect 8 0 9 0;
+#X connect 10 0 22 0;
+#X connect 10 1 21 0;
+#X connect 11 0 10 0;
+#X connect 13 0 22 1;
+#X connect 14 0 22 2;
+#X connect 15 0 22 3;
+#X connect 16 0 22 4;
+#X connect 17 0 21 3;
+#X connect 18 0 21 4;
+#X connect 19 0 21 1;
+#X connect 20 0 21 2;
+#X connect 21 0 3 0;
+#X connect 21 0 8 1;
+#X connect 22 0 1 0;
+#X connect 22 0 8 0;
diff --git a/msd/editor/sixpack.pd b/msd/editor/sixpack.pd
new file mode 100644
index 0000000..fd97eee
--- /dev/null
+++ b/msd/editor/sixpack.pd
@@ -0,0 +1,31 @@
+#N canvas 519 499 450 300 10;
+#X obj 143 51 inlet;
+#X obj 91 51 inlet;
+#X obj 141 72 t b f;
+#X obj 191 51 inlet;
+#X obj 189 72 t b f;
+#X obj 238 50 inlet;
+#X obj 236 71 t b f;
+#X obj 148 222 outlet;
+#X obj 287 49 inlet;
+#X obj 285 70 t b f;
+#X obj 334 48 inlet;
+#X obj 332 69 t b f;
+#X obj 148 179 pack 0 0 0 0 0 0;
+#X connect 0 0 2 0;
+#X connect 1 0 12 0;
+#X connect 2 0 12 0;
+#X connect 2 1 12 1;
+#X connect 3 0 4 0;
+#X connect 4 0 12 0;
+#X connect 4 1 12 2;
+#X connect 5 0 6 0;
+#X connect 6 0 12 0;
+#X connect 6 1 12 3;
+#X connect 8 0 9 0;
+#X connect 9 0 12 0;
+#X connect 9 1 12 4;
+#X connect 10 0 11 0;
+#X connect 11 0 12 0;
+#X connect 11 1 12 5;
+#X connect 12 0 7 0;
diff --git a/msd/editor/structures.pd b/msd/editor/structures.pd
new file mode 100644
index 0000000..80ca36c
--- /dev/null
+++ b/msd/editor/structures.pd
@@ -0,0 +1,20 @@
+#N canvas 752 10 450 300 10;
+#N canvas 470 500 664 321 mass 0;
+#X obj 62 182 drawnumber mid 0 -18 0 m;
+#X obj 61 136 filledpolygon mob mob 1 -5 0 -4 4 0 5 4 4 5 0 4 -4 0
+-5 -4 -4;
+#X obj 64 72 struct mass float x float y float mid float mob float
+M float sid;
+#X restore 132 125 pd mass;
+#N canvas 73 302 487 201 liaison 0;
+#X obj 23 73 drawpolygon sid 2 x1 y1 x2 y2;
+#X obj 19 25 struct liaison float x1 float y1 float x2 float y2 float
+mid1 float mid2 float lid float K float D float P float Lmin float
+Lmax float sid;
+#X restore 132 147 pd liaison;
+#N canvas 749 676 450 300 hole 0;
+#X obj 79 73 struct hole float x float y;
+#X text 93 162 Green cross;
+#X obj 79 97 drawpolygon 50 2 -5 -5 5 5;
+#X obj 79 122 drawpolygon 50 2 -5 5 5 -5;
+#X restore 132 170 pd hole;
diff --git a/msd/msd/01_msdtest.pd b/msd/msd/01_msdtest.pd
new file mode 100644
index 0000000..49922e9
--- /dev/null
+++ b/msd/msd/01_msdtest.pd
@@ -0,0 +1,92 @@
+#N canvas 392 22 616 594 10;
+#X obj 20 33 loadbang;
+#X obj 382 197 print msd;
+#X obj 309 58 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X text 329 56 ON / OFF;
+#X obj 309 80 metro 50;
+#X obj 33 55 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 83 113 reset;
+#X msg 35 229 Xmax 100 \, Xmin 0;
+#X msg 128 372 setD souple 0.01;
+#X msg 18 371 setK souple 1;
+#X msg 128 394 setD souple 1;
+#X msg 18 393 setK souple 2;
+#X obj 331 392 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 7025 1;
+#X obj 354 392 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 7484 1;
+#X obj 308 392 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 6450 1;
+#X msg 308 538 posX fix \$1;
+#X obj 401 392 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 7901 1;
+#X obj 377 392 vsl 15 128 0 100 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 7771 1;
+#X msg 20 256 0 1 \, 1 2 \, 2 3 \, 3 4;
+#X obj 308 347 unpack f f f f f;
+#X obj 308 325 route massesPosL;
+#X msg 309 103 bang \, massesPosL;
+#X msg 20 278 link souple \$1 \$2 10 10;
+#X obj 309 167 msd;
+#X obj 309 31 loadbang;
+#X obj 20 77 t b b b b b;
+#X text 50 55 reset;
+#X text 18 10 creation : 5 masses and 4 links;
+#X text 308 10 compute and get masses positions;
+#X text 16 349 set rigidity and viscosity of links;
+#X text 17 452 add force on all mobile masses;
+#X text 443 440 move first slider;
+#X text 429 453 to move the fixed mass;
+#X msg 19 503 forceX mob 300;
+#X msg 19 479 forceX mob -300;
+#X text 307 279 display and interaction;
+#X msg 51 201 mass mob 1 100 50;
+#X msg 51 159 4;
+#X obj 51 180 until;
+#X msg 67 139 mass fix 0 100 50;
+#X obj 83 314 s \$0-msdin;
+#X obj 18 421 s \$0-msdin;
+#X obj 19 530 s \$0-msdin;
+#X obj 319 138 r \$0-msdin;
+#X obj 309 197 s \$0-msdout;
+#X obj 308 302 r \$0-msdout;
+#X obj 308 560 s \$0-msdin;
+#X connect 0 0 25 0;
+#X connect 2 0 4 0;
+#X connect 4 0 21 0;
+#X connect 5 0 25 0;
+#X connect 6 0 40 0;
+#X connect 7 0 40 0;
+#X connect 8 0 41 0;
+#X connect 9 0 41 0;
+#X connect 10 0 41 0;
+#X connect 11 0 41 0;
+#X connect 14 0 15 0;
+#X connect 15 0 46 0;
+#X connect 18 0 22 0;
+#X connect 19 0 14 0;
+#X connect 19 1 12 0;
+#X connect 19 2 13 0;
+#X connect 19 3 17 0;
+#X connect 19 4 16 0;
+#X connect 20 0 19 0;
+#X connect 21 0 23 0;
+#X connect 22 0 40 0;
+#X connect 23 0 44 0;
+#X connect 23 1 1 0;
+#X connect 24 0 2 0;
+#X connect 25 0 18 0;
+#X connect 25 1 7 0;
+#X connect 25 2 37 0;
+#X connect 25 3 39 0;
+#X connect 25 4 6 0;
+#X connect 33 0 42 0;
+#X connect 34 0 42 0;
+#X connect 36 0 40 0;
+#X connect 37 0 38 0;
+#X connect 38 0 36 0;
+#X connect 39 0 40 0;
+#X connect 43 0 23 0;
+#X connect 45 0 20 0;
diff --git a/msd/msd/02_msdstring.pd b/msd/msd/02_msdstring.pd
new file mode 100644
index 0000000..8eebc38
--- /dev/null
+++ b/msd/msd/02_msdstring.pd
@@ -0,0 +1,328 @@
+#N canvas 518 31 480 222 10;
+#X obj 24 54 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262131 -1
+-1;
+#X text 49 54 reset;
+#N canvas 0 22 610 333 creation_structure 0;
+#X obj 52 15 loadbang;
+#X obj 135 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262131 -1
+-1;
+#X msg 193 65 reset;
+#X text 173 21 reset;
+#N canvas 77 152 608 525 masses 0;
+#X obj 109 15 inlet;
+#X obj 112 338 outlet;
+#X obj 200 343 print;
+#X obj 112 64 t b b b b;
+#X obj 150 158 until 17;
+#X msg 150 184 mass corde 1 50 0;
+#X msg 112 276 mass zero 0 1 0;
+#X msg 150 134 80;
+#X text 232 275 masse nulle pour l'amortissement general;
+#X text 302 90 extremite gauche no 0;
+#X text 283 184 masses mobiles no 1->80;
+#X text 278 220 extremite droite no 81;
+#X msg 170 89 mass corde 0 100 0;
+#X msg 131 218 mass corde 0 100 0;
+#X connect 0 0 3 0;
+#X connect 3 0 6 0;
+#X connect 3 1 13 0;
+#X connect 3 2 7 0;
+#X connect 3 3 12 0;
+#X connect 4 0 5 0;
+#X connect 5 0 1 0;
+#X connect 6 0 1 0;
+#X connect 7 0 4 0;
+#X connect 12 0 1 0;
+#X connect 13 0 1 0;
+#X restore 173 87 pd masses;
+#N canvas 579 114 813 597 link 0;
+#X obj 157 35 inlet;
+#X obj 185 490 outlet;
+#X msg 176 320 link souple \$1 \$2 10 10;
+#X obj 236 210 + 1;
+#X obj 176 293 pack f f;
+#X obj 253 493 print;
+#X obj 176 241 t f f f;
+#X obj 176 212 f 0;
+#X obj 157 64 t b b b b;
+#X text 305 254 liens entre les masses mobiles;
+#X text 384 406 tlink qui fait un amortissement vertical general;
+#X obj 386 323 s rigidite;
+#X msg 386 300 10;
+#X msg 157 403 link D2 zero corde 0 0;
+#X msg 266 169 0;
+#X obj 203 269 + 1;
+#X obj 176 188 until;
+#X floatatom 267 251 5 0 0 0 - - -;
+#X msg 176 165 81;
+#X obj 467 324 s amort;
+#X connect 0 0 8 0;
+#X connect 2 0 1 0;
+#X connect 3 0 7 1;
+#X connect 4 0 2 0;
+#X connect 6 0 4 0;
+#X connect 6 1 15 0;
+#X connect 6 2 3 0;
+#X connect 7 0 6 0;
+#X connect 7 0 17 0;
+#X connect 8 0 12 0;
+#X connect 8 0 13 0;
+#X connect 8 1 18 0;
+#X connect 8 2 14 0;
+#X connect 12 0 11 0;
+#X connect 12 0 19 0;
+#X connect 13 0 1 0;
+#X connect 14 0 7 1;
+#X connect 15 0 4 1;
+#X connect 16 0 7 0;
+#X connect 18 0 16 0;
+#X restore 154 111 pd link;
+#X obj 135 42 t b b b b;
+#X text 252 82 CREATION : 2 masses fixes (fix) \, 80 mobiles (corde)
+\, 80 liens (souple) \, 78 tLink (D2);
+#X msg 135 132 Xmax 100 \, Xmin -100;
+#X obj 247 23 inlet;
+#X obj 121 213 loadbang;
+#X obj 121 237 s load;
+#X obj 135 160 s \$0-msdin;
+#X connect 0 0 6 0;
+#X connect 1 0 6 0;
+#X connect 2 0 12 0;
+#X connect 4 0 12 0;
+#X connect 5 0 12 0;
+#X connect 6 0 8 0;
+#X connect 6 1 5 0;
+#X connect 6 2 4 0;
+#X connect 6 3 2 0;
+#X connect 8 0 12 0;
+#X connect 9 0 6 0;
+#X connect 10 0 11 0;
+#X restore 24 76 pd creation_structure;
+#N canvas 508 227 516 328 compute 0;
+#X obj 27 30 gemhead;
+#N canvas 735 244 537 479 corde 0;
+#X obj 139 41 inlet;
+#X obj 81 333 translateXYZ;
+#X obj 139 167 / 12.5;
+#X obj 139 190 - 4;
+#X obj 81 307 separator;
+#X obj 139 238 t b f;
+#X obj 81 273 gemhead 45;
+#X obj 204 188 / 0.2;
+#X obj 139 106 unpack f f;
+#X msg 81 238 0;
+#X obj 81 213 loadbang;
+#X obj 81 369 color 1 1 1;
+#X obj 139 139 + 10;
+#X obj 81 398 cube 0.02;
+#X obj 139 80 route 82;
+#X connect 0 0 14 0;
+#X connect 1 0 11 0;
+#X connect 2 0 3 0;
+#X connect 3 0 5 0;
+#X connect 4 0 1 0;
+#X connect 5 0 6 0;
+#X connect 5 1 1 1;
+#X connect 6 0 4 0;
+#X connect 7 0 1 2;
+#X connect 8 0 12 0;
+#X connect 8 1 7 0;
+#X connect 9 0 6 0;
+#X connect 10 0 9 0;
+#X connect 11 0 13 0;
+#X connect 12 0 2 0;
+#X connect 14 1 8 0;
+#X restore 27 252 pd corde;
+#N canvas 643 123 605 590 vitesse 0;
+#X obj 127 22 inlet;
+#X obj 62 333 translateXYZ;
+#X obj 129 200 / 12.5;
+#X obj 129 223 - 4;
+#X obj 62 307 separator;
+#X obj 129 250 t b f;
+#X obj 62 280 gemhead 45;
+#X obj 62 398 cube 0.01;
+#X obj 431 25 inlet;
+#X obj 236 46 spigot;
+#X obj 195 216 + 2;
+#X obj 78 81 route 82;
+#X obj 129 107 unpack f f;
+#X obj 62 232 loadbang;
+#X msg 62 256 0;
+#X obj 129 172 + 10;
+#X obj 195 193 * 200;
+#X obj 62 369 color 1 0 0;
+#X connect 0 0 9 0;
+#X connect 1 0 17 0;
+#X connect 2 0 3 0;
+#X connect 3 0 5 0;
+#X connect 4 0 1 0;
+#X connect 5 0 6 0;
+#X connect 5 1 1 1;
+#X connect 6 0 4 0;
+#X connect 8 0 9 1;
+#X connect 9 0 11 0;
+#X connect 10 0 1 2;
+#X connect 11 1 12 0;
+#X connect 12 0 15 0;
+#X connect 12 1 16 0;
+#X connect 13 0 14 0;
+#X connect 14 0 6 0;
+#X connect 15 0 2 0;
+#X connect 16 0 10 0;
+#X connect 17 0 7 0;
+#X restore 121 239 pd vitesse;
+#X obj 186 219 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 27 136 msd --------------------------------;
+#X obj 27 53 t b b b b b b b;
+#X obj 27 195 route massesPos massesSpeeds massesForces;
+#X text 208 240 Afficher les vitesses en haut;
+#X text 310 279 Afficher les forces en bas;
+#X obj 379 185 inlet;
+#X obj 355 119 gemhead;
+#X obj 355 142 world_light;
+#N canvas 643 123 605 590 forces 0;
+#X obj 53 99 inlet;
+#X obj 60 377 translateXYZ;
+#X obj 139 260 / 12.5;
+#X obj 139 283 - 4;
+#X obj 204 261 / 12.5;
+#X obj 60 351 separator;
+#X obj 137 310 t b f;
+#X obj 60 325 gemhead 45;
+#X obj 60 434 cube 0.02;
+#X obj 111 99 inlet;
+#X obj 53 129 spigot;
+#X obj 60 284 loadbang;
+#X msg 60 306 0;
+#X obj 139 207 unpack f f;
+#X obj 139 232 + 10;
+#X obj 204 284 - 2;
+#X obj 53 180 route 0 81 82;
+#X obj 204 239 * 400;
+#X obj 60 405 color 0 1 0;
+#X connect 0 0 10 0;
+#X connect 1 0 18 0;
+#X connect 2 0 3 0;
+#X connect 3 0 6 0;
+#X connect 4 0 15 0;
+#X connect 5 0 1 0;
+#X connect 6 0 7 0;
+#X connect 6 1 1 1;
+#X connect 7 0 5 0;
+#X connect 9 0 10 1;
+#X connect 10 0 16 0;
+#X connect 11 0 12 0;
+#X connect 12 0 7 0;
+#X connect 13 0 14 0;
+#X connect 13 1 17 0;
+#X connect 14 0 2 0;
+#X connect 15 0 1 2;
+#X connect 16 3 13 0;
+#X connect 17 0 4 0;
+#X connect 18 0 8 0;
+#X restore 215 278 pd forces;
+#X msg 27 75 bang \, get massesPos \, get massesSpeeds \, get massesForces
+;
+#X obj 95 100 r \$0-msdin;
+#X connect 0 0 5 0;
+#X connect 3 0 2 1;
+#X connect 4 0 6 0;
+#X connect 5 0 13 0;
+#X connect 5 1 4 0;
+#X connect 5 2 4 0;
+#X connect 5 3 4 0;
+#X connect 5 4 4 0;
+#X connect 5 5 4 0;
+#X connect 5 6 4 0;
+#X connect 6 0 1 0;
+#X connect 6 1 2 0;
+#X connect 6 2 12 0;
+#X connect 9 0 12 1;
+#X connect 9 0 2 1;
+#X connect 10 0 11 0;
+#X connect 13 0 4 0;
+#X connect 14 0 4 0;
+#X restore 24 165 pd compute;
+#X obj 24 143 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
+1;
+#X obj 307 151 hsl 128 15 0 30 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 6500 1;
+#X text 303 134 Amortissement general;
+#X obj 307 93 hsl 128 15 0 127 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 0 1;
+#N canvas 0 22 611 439 milieu 0;
+#X obj 174 147 / 120;
+#X obj 174 84 inlet;
+#X msg 173 298 forceX \$1 \$2;
+#X msg 174 175 41 \$1 \, 42 \$1;
+#X obj 191 201 / 1.5;
+#X msg 191 225 39 \$1 \, 40 \$1 \, 43 \$1 \, 44 \$1;
+#X msg 206 271 36 \$1 \, 37 \$1 \, 38 \$1 \, 45 \$1 \, 46 \$1 \, 47
+\$1;
+#X obj 206 247 / 3;
+#X obj 173 326 s \$0-msdin;
+#X obj 398 76 t f f;
+#X obj 401 107 -;
+#X obj 400 131 * 10;
+#X connect 0 0 3 0;
+#X connect 0 0 4 0;
+#X connect 0 0 7 0;
+#X connect 1 0 9 0;
+#X connect 2 0 8 0;
+#X connect 3 0 2 0;
+#X connect 4 0 5 0;
+#X connect 5 0 2 0;
+#X connect 6 0 2 0;
+#X connect 7 0 6 0;
+#X connect 9 0 10 1;
+#X connect 9 1 10 0;
+#X connect 10 0 11 0;
+#X connect 11 0 0 0;
+#X restore 304 116 pd milieu;
+#N canvas 0 22 450 300 gem 0;
+#X obj 179 135 gemwin;
+#X msg 198 113 0 \, destroy;
+#X msg 179 90 reset \, create \, lighting 1 \, 1;
+#X obj 179 39 inlet;
+#X obj 179 68 sel 1 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
+#X connect 4 1 1 0;
+#X restore 24 118 pd gem;
+#X obj 24 99 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1
+;
+#X text 44 142 display forces (green) and speeds (red);
+#N canvas 0 22 450 300 forces 0;
+#X msg 167 134 forceX corde \$1;
+#X obj 167 89 inlet;
+#X obj 167 112 / 300;
+#X obj 167 157 s \$0-msdin;
+#X connect 0 0 3 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 0;
+#X restore 304 56 pd forces;
+#X obj 307 34 hsl 128 15 0 127 0 0 empty empty empty -2 -6 0 8 -262144
+-1 -1 2300 1;
+#N canvas 0 22 450 300 general_damping 0;
+#X msg 172 143 setD D2 \$1;
+#X obj 172 121 / 5;
+#X obj 173 100 inlet;
+#X obj 172 166 s \$0-msdin;
+#X connect 0 0 3 0;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X restore 304 171 pd general_damping;
+#X text 302 74 Send forces in the middle;
+#X text 302 16 Send forces;
+#X text 45 98 gem on/off;
+#X text 24 20 1D string model;
+#X connect 0 0 2 0;
+#X connect 4 0 3 0;
+#X connect 5 0 14 0;
+#X connect 7 0 8 0;
+#X connect 10 0 9 0;
+#X connect 13 0 12 0;
diff --git a/msd/msd/03_msdwave.pd b/msd/msd/03_msdwave.pd
new file mode 100644
index 0000000..816840a
--- /dev/null
+++ b/msd/msd/03_msdwave.pd
@@ -0,0 +1,230 @@
+#N canvas 617 175 594 188 10;
+#X obj 29 20 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X text 49 19 Reset;
+#X obj 202 27 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#N canvas 0 22 981 585 structure_creation 0;
+#X msg 681 243 mass filet 1 100 0;
+#X msg 663 64 reset;
+#X obj 418 25 t b b b b b b b b b b b b;
+#X obj 681 201 until;
+#X msg 681 170 400;
+#X msg 561 378 link fil \$1 \$2 10 1;
+#X msg 561 174 380;
+#X obj 561 206 until;
+#X obj 561 245 f 0;
+#X obj 609 261 + 1;
+#X msg 618 226 0;
+#X obj 636 312 + 20;
+#X obj 561 339 pack f f;
+#X obj 561 288 t f f;
+#X msg 397 151 400;
+#X obj 397 189 until;
+#X obj 397 231 f 0;
+#X obj 445 247 + 1;
+#X msg 454 212 0;
+#X obj 397 292 t f f;
+#X obj 452 325 mod 20;
+#X obj 452 355 != 19;
+#X obj 397 393 spigot;
+#X obj 397 475 pack f f;
+#X obj 397 424 t f f;
+#X obj 472 448 + 1;
+#X msg 397 505 link fil \$1 \$2 10 1;
+#X msg 403 107 setFixed 0 \, setFixed 19 \, setFixed 380 \, setFixed
+399;
+#X obj 418 -8 inlet;
+#X obj 326 61 loadbang;
+#X obj 690 527 s \$0-msdin;
+#X connect 0 0 30 0;
+#X connect 1 0 30 0;
+#X connect 2 5 27 0;
+#X connect 2 6 14 0;
+#X connect 2 7 18 0;
+#X connect 2 8 6 0;
+#X connect 2 9 10 0;
+#X connect 2 10 4 0;
+#X connect 2 11 1 0;
+#X connect 3 0 0 0;
+#X connect 4 0 3 0;
+#X connect 5 0 30 0;
+#X connect 6 0 7 0;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 8 0 13 0;
+#X connect 9 0 8 1;
+#X connect 10 0 8 1;
+#X connect 11 0 12 1;
+#X connect 12 0 5 0;
+#X connect 13 0 12 0;
+#X connect 13 1 11 0;
+#X connect 14 0 15 0;
+#X connect 15 0 16 0;
+#X connect 16 0 17 0;
+#X connect 16 0 19 0;
+#X connect 17 0 16 1;
+#X connect 18 0 16 1;
+#X connect 19 0 22 0;
+#X connect 19 1 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 22 1;
+#X connect 22 0 24 0;
+#X connect 23 0 26 0;
+#X connect 24 0 23 0;
+#X connect 24 1 25 0;
+#X connect 25 0 23 1;
+#X connect 26 0 30 0;
+#X connect 27 0 30 0;
+#X connect 28 0 2 0;
+#X connect 29 0 2 0;
+#X restore 29 39 pd structure_creation;
+#N canvas 813 63 450 300 gem 0;
+#X obj 114 171 gemwin;
+#X msg 134 149 0 \, destroy;
+#X msg 114 125 reset \, create \, 1 \, lighting 1;
+#X obj 114 71 inlet;
+#X obj 114 97 sel 1 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
+#X connect 4 1 1 0;
+#X restore 30 85 pd gem;
+#X obj 30 63 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1
+;
+#X text 200 -6 send forces;
+#X text 200 7 on a row;
+#N canvas 0 22 450 300 damping 0;
+#X msg 151 90 setD fil \$1;
+#X obj 151 70 / 8;
+#X obj 151 47 inlet;
+#X obj 151 113 s \$0-msdin;
+#X connect 0 0 3 0;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X restore 301 119 pd damping;
+#X obj 304 100 hsl 128 15 0 127 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 12700 1;
+#X text 300 79 change viscosity;
+#N canvas 0 22 450 300 row 0;
+#X msg 149 87 20;
+#X obj 149 132 f 6;
+#X obj 149 112 until;
+#X obj 192 133 + 20;
+#X msg 208 113 6;
+#X obj 149 63 t b b;
+#X msg 149 153 forceX \$1 30;
+#X obj 149 38 inlet;
+#X obj 149 183 s \$0-msdin;
+#X connect 0 0 2 0;
+#X connect 1 0 3 0;
+#X connect 1 0 6 0;
+#X connect 2 0 1 0;
+#X connect 3 0 1 1;
+#X connect 4 0 1 1;
+#X connect 5 0 0 0;
+#X connect 5 1 4 0;
+#X connect 6 0 8 0;
+#X connect 7 0 5 0;
+#X restore 202 51 pd row;
+#X obj 201 105 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X text 199 70 send forces;
+#X text 50 63 Gem on/off;
+#X obj 305 38 hsl 128 15 0 127 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 1300 1;
+#X text 300 17 change rigidity;
+#N canvas 0 22 450 300 rigi 0;
+#X obj 151 47 inlet;
+#X obj 151 70 / 4;
+#X msg 151 90 setK fil \$1;
+#X obj 151 113 s \$0-msdin;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X restore 302 57 pd rigi;
+#X text 199 83 on a point;
+#N canvas 0 22 450 300 point 0;
+#X msg 192 123 forceX 10 100;
+#X obj 193 95 inlet;
+#X obj 192 156 s \$0-msdin;
+#X connect 0 0 2 0;
+#X connect 1 0 0 0;
+#X restore 201 126 pd point;
+#X text 469 -2 move a corner;
+#N canvas 0 22 450 300 corner 0;
+#X msg 222 89 posX 0 \$1;
+#X obj 222 65 / 30;
+#X obj 223 32 inlet;
+#X obj 222 115 s \$0-msdin;
+#X connect 0 0 3 0;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X restore 471 155 pd corner;
+#X obj 471 17 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 0 1;
+#N canvas 696 124 709 588 compute 0;
+#X msg 126 130 bang \, get massesPos;
+#X obj 126 27 gemhead;
+#X obj 126 224 route massesPos;
+#X obj 34 306 gemhead;
+#X msg 34 268 0;
+#X obj 126 290 unpack f f;
+#X obj 34 539 translateXYZ;
+#X obj 126 334 mod 20;
+#X obj 126 389 - 3;
+#X obj 126 363 * 0.3;
+#X obj 126 257 t b a;
+#X obj 197 326 / 20;
+#X obj 197 356 int;
+#X obj 197 383 * -0.3;
+#X obj 197 410 + 3;
+#X obj 34 238 loadbang;
+#X obj 126 184 msd --------------;
+#X obj 439 286 gemhead;
+#X obj 439 349 light;
+#X obj 439 318 translateXYZ 0 0 1;
+#X obj 33 572 cube 0.08;
+#X obj 126 58 t b b;
+#X msg 171 97 bang \, bang \, bang \, bang \, bang \, bang \, bang
+;
+#X obj 34 443 translateXYZ 0 0 -2;
+#X obj 34 477 rotateXYZ 0 20 0;
+#X obj 141 153 r \$0-msdin;
+#X connect 0 0 16 0;
+#X connect 1 0 21 0;
+#X connect 2 0 10 0;
+#X connect 3 0 23 0;
+#X connect 4 0 3 0;
+#X connect 5 0 7 0;
+#X connect 5 0 11 0;
+#X connect 5 1 6 3;
+#X connect 6 0 20 0;
+#X connect 7 0 9 0;
+#X connect 8 0 6 1;
+#X connect 9 0 8 0;
+#X connect 10 0 3 0;
+#X connect 10 1 5 0;
+#X connect 11 0 12 0;
+#X connect 12 0 13 0;
+#X connect 13 0 14 0;
+#X connect 14 0 6 2;
+#X connect 15 0 4 0;
+#X connect 16 0 2 0;
+#X connect 17 0 19 0;
+#X connect 19 0 18 0;
+#X connect 21 0 0 0;
+#X connect 21 1 22 0;
+#X connect 22 0 16 0;
+#X connect 23 0 24 0;
+#X connect 24 0 6 0;
+#X connect 25 0 16 0;
+#X restore 30 109 pd compute;
+#X connect 0 0 3 0;
+#X connect 2 0 11 0;
+#X connect 5 0 4 0;
+#X connect 9 0 8 0;
+#X connect 12 0 19 0;
+#X connect 15 0 17 0;
+#X connect 22 0 21 0;
diff --git a/msd/msd/Makefile.am b/msd/msd/Makefile.am
new file mode 100644
index 0000000..59a3dff
--- /dev/null
+++ b/msd/msd/Makefile.am
@@ -0,0 +1,51 @@
+#
+# automake template
+# added by tim blechmann
+#
+
+NAME = msd2
+
+BUILT_SOURCES = main.cpp
+
+EXTRA_DIST = main.cpp \
+ $(NAME).mcp \
+ $(NAME).vcproj
+
+CXXFLAGS = @CXXFLAGS@ \
+ @OPT_FLAGS@ \
+ @INCLUDEDIR@ \
+ -I../../source \
+ $(DEFS) \
+ -DFLEXT_SHARED
+
+LDFLAGS = @DYNAMIC_LDFLAGS@ @LDFLAGS@ \
+ $(patsubst %,-framework %,$(FRAMEWORKS))
+
+LIBS = @LIBS@ -lflext-pd
+
+FRAMEWORKS = @FRAMEWORKS@
+
+TARGETDIR = @TARGETDIR@
+
+TARGET =$(NAME).@EXTENSION@
+
+OBJECTS = $(patsubst %.cpp,./%.@OBJEXT@,$(BUILT_SOURCES))
+
+SYSDIR = @SYSDIR@
+
+
+# ----------------------------- targets --------------------------------
+
+all-local: $(OBJECTS)
+ $(CXX) $(LDFLAGS) ./*.@OBJEXT@ $(LIBS) -o ../$(TARGETDIR)/$(TARGET)
+ strip --strip-unneeded ../$(TARGETDIR)/$(TARGET)
+
+./%.@OBJEXT@ : %.cpp
+ $(CXX) -c $(CXXFLAGS) $< -o $@
+
+clean-local:
+ rm -f ../$(TARGETDIR)/$(TARGET)
+ rm -f ./$(OBJECTS)
+
+install-exec-local:
+ install ../$(TARGET) $(SYSDIR)extra
diff --git a/msd/msd/license.txt b/msd/msd/license.txt
new file mode 100644
index 0000000..b1e3f5a
--- /dev/null
+++ b/msd/msd/license.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; 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.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/msd/msd/main.cpp b/msd/msd/main.cpp
new file mode 100644
index 0000000..7e6f013
--- /dev/null
+++ b/msd/msd/main.cpp
@@ -0,0 +1,3 @@
+#include "../src/msd.h"
+
+MSD("msd",msd,1)
diff --git a/msd/msd/msd-help.pd b/msd/msd/msd-help.pd
new file mode 100644
index 0000000..784d081
--- /dev/null
+++ b/msd/msd/msd-help.pd
@@ -0,0 +1,438 @@
+#N canvas 244 22 563 764 10;
+#X obj 4 369 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 729 cnv 15 550 30 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 8 6 cnv 15 550 30 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 14 389 cnv 15 75 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 14 584 cnv 15 75 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 527 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 4 562 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 7 76 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 679 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 699 cnv 15 550 30 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#N canvas 76 31 777 741 More_Info 0;
+#X text 94 17 MSD : mass - spring - damper model;
+#X text 26 46 MSD is the 1D object of the msd objects collection.;
+#X text 25 160 Be careful : if masses are deleted \, lists messages
+won't work;
+#X text 25 65 It is designed to implement particules physical model
+in PD.The model is based on two elements type : mass and link. The
+msd masses are the principals objects of the model. They got only one
+physical parameter \, the value of their mass. They can be mobile or
+fixed \, in this case forces applied on them automatically \, by links
+\, or manually \, by messages \, don't do anything.;
+#X text 25 262 Links can be created between mutiples masses \, instead
+of creation number \, the masses linked are defined with their Id.
+;
+#X obj 449 23 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 449 277 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity1 4 float 1;
+#A 0 -1 0 1 2;
+#X array zero 4 float 1;
+#A 0 0 0 0 0;
+#X coords 0 3 3 -3 200 150 1;
+#X restore 117 339 graph;
+#X text 175 496 L0;
+#N canvas 331 182 956 727 figure 0;
+#X obj 182 108 loadbang;
+#X msg 191 180 \; rigidity1 resize 1 \; rigidity1 resize 4 \; rigidity1
+bounds 0 3 3 -3 \; rigidity1 0 -1 0 1 2 \; rigidity1 ylabel -0.5 \;
+rigidity1 xlabel -3.5 \; rigidity1 xticks 0 1 1 \; rigidity1 yticks
+0 0.1 5;
+#X obj 399 574 sqrt;
+#X obj 316 651 tabwrite rigidity3;
+#X obj 343 464 - 20;
+#X obj 316 609 f;
+#X obj 316 579 t b f;
+#X obj 343 494 moses 0;
+#X obj 343 517 * -1;
+#X obj 343 538 sqrt;
+#X obj 343 559 * -1;
+#X obj 481 479 - 20;
+#X obj 453 662 f;
+#X obj 453 632 t b f;
+#X obj 481 509 moses 0;
+#X obj 481 532 * -1;
+#X obj 480 612 * -1;
+#X obj 536 627 *;
+#X obj 480 591 *;
+#X obj 533 595 t f f;
+#X obj 480 564 t f f;
+#X obj 453 704 tabwrite rigidity4;
+#X msg 55 419 \; rigidity3 resize 51 \; rigidity3 xticks 0 1 5 \; rigidity3
+yticks 0 1 5 \; rigidity4 resize 51 \; rigidity4 xticks 0 1 5 \; rigidity4
+yticks 0 100 5;
+#X obj 255 350 t b b;
+#X msg 404 183 \; rigidity2 resize 1 \; rigidity2 resize 23 \; rigidity2
+bounds 0 3 22 -3 \; rigidity2 0 0 0 -2.5 -2.34 -2.167 -2 -1.833 -1.667
+-1.5 0 0 0 0 0 1.5 1.667 1.833 2 2.167 2.34 2.5 0 0 0 \; rigidity2
+ylabel -0.5 \; rigidity2 xlabel -3.5 \; rigidity2 xticks 1 1 5 \; rigidity2
+yticks 0 0.2 5;
+#X obj 402 359 f;
+#X obj 418 409 + 1;
+#X obj 402 382 moses 50.5;
+#X obj 384 417 f;
+#X obj 395 328 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X connect 0 0 1 0;
+#X connect 0 0 24 0;
+#X connect 0 0 23 0;
+#X connect 2 0 5 1;
+#X connect 4 0 7 0;
+#X connect 5 0 3 0;
+#X connect 6 0 5 0;
+#X connect 6 1 3 1;
+#X connect 7 0 8 0;
+#X connect 7 1 2 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 5 1;
+#X connect 11 0 14 0;
+#X connect 12 0 21 0;
+#X connect 13 0 12 0;
+#X connect 13 1 21 1;
+#X connect 14 0 15 0;
+#X connect 14 1 19 0;
+#X connect 15 0 20 0;
+#X connect 16 0 12 1;
+#X connect 17 0 12 1;
+#X connect 18 0 16 0;
+#X connect 19 0 17 0;
+#X connect 19 1 17 1;
+#X connect 20 0 18 0;
+#X connect 20 1 18 1;
+#X connect 23 0 25 0;
+#X connect 23 1 22 0;
+#X connect 25 0 27 0;
+#X connect 26 0 25 0;
+#X connect 27 0 26 0;
+#X connect 27 0 28 0;
+#X connect 28 0 4 0;
+#X connect 28 0 6 0;
+#X connect 28 0 11 0;
+#X connect 28 0 13 0;
+#X connect 29 0 25 0;
+#X restore 430 703 pd figure;
+#X text 121 318 Rigidity;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity2 23 float 1;
+#A 0 0 0 -2.5 -2.34 -2.167 -2 -1.833 -1.667 -1.5 0 0 0 0 0 1.5 1.667
+1.833 2 2.167 2.34 2.5 0 0;
+#X array zero 23 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;
+#X coords 0 3 22 -3 200 150 1;
+#X restore 112 555 graph;
+#X text 204 710 L0;
+#X text 117 532 Rigidity with Lmin and Lmax;
+#X text 220 710 Lmin;
+#X text 282 711 Lmax;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity3 51 float 1;
+#A 0 -4.47214 -4.3589 -4.24264 -4.12311 -4 -3.87298 -3.74166 -3.60555
+-3.4641 -3.31662 -3.16228 -3 -2.82843 -2.64575 -2.44949 -2.23607 -2
+-1.73205 -1.41421 -1 0 1 1.41421 1.73205 2 2.23607 2.44949 2.64575
+2.82843 3 3.16228 3.31662 3.4641 3.60555 3.74166 3.87298 4 4.12311
+4.24264 4.3589 4.47214 4.58258 4.69042 4.79583 4.89898 5 5.09902 5.19615
+5.2915 5.38516 5.47723;
+#X array zero 51 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
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
+#X coords 0 6 50 -6 200 150 1;
+#X restore 557 346 graph;
+#X text 630 499 L0;
+#X text 562 325 Rigidity with power = 1/2;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity4 51 float 1;
+#A 0 -400 -361 -324 -289 -256 -225 -196 -169 -144 -121 -100 -81 -64
+-49 -36 -25 -16 -9 -4 -1 0 1 4 9 16 25 36 49 64 81 100 121 144 169
+196 225 256 289 324 361 400 441 484 529 576 625 676 729 784 841 900
+;
+#X array zero 51 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
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
+#X coords 0 1000 50 -1000 200 150 1;
+#X restore 554 561 graph;
+#X text 627 715 L0;
+#X text 557 539 Rigidity with power = 2;
+#X text 548 21 The equations are :;
+#X text 474 45 if Lmin<|L[n]-L[0]|<Lmax;
+#X text 473 84 else;
+#X text 473 104 F[n] = D(L[n]-L[n-1]);
+#X text 473 63 F[n] = K(L[n] - L[0])^P + D(L[n] - L[n-1]);
+#X text 25 192 Links connect masses two by two. They got 4 physicals
+parameters : length \, rigidity \, damping and power.;
+#X text 25 221 Rigidity \, damping and power are defined by the creation
+message. The lenght is initialised to the distance between the two
+masses at the creation.;
+#X connect 5 0 6 0;
+#X restore 16 735 pd More_Info;
+#X text 12 76 Examples:;
+#X text 9 369 Inlets:;
+#X text 19 388 - Left:;
+#X text 10 526 Arguments:;
+#X text 11 562 Outlets:;
+#X text 19 679 See Also:;
+#X text 74 48 Full Name:;
+#N canvas 58 22 262 70 Related_Objects 0;
+#X obj 3 10 cnv 15 250 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 3 30 cnv 15 250 30 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X text 5 10 Externals and libraries;
+#X obj 44 37 msd2D;
+#X obj 140 37 msd3D;
+#X restore 122 735 pd Related_Objects;
+#X text 12 8 HELP: msd;
+#X obj 157 48 msd;
+#X text 12 18 DESCRIPTION: Mass spring damper physical modeling in
+1D.;
+#X obj 17 319 msd;
+#N canvas 541 387 524 302 init 0;
+#X msg 89 187 Xmax 127 \, Xmin 0;
+#X obj 89 215 t a;
+#X obj 89 33 loadbang;
+#X msg 143 100 mass fix 0 10 0;
+#X obj 89 241 s \$0-in;
+#X obj 89 59 t b b b b b;
+#X msg 161 80 reset;
+#X obj 44 13 inlet;
+#X msg 125 120 mass mob 1 10 0 \, mass mob 1 10 0 \, mass mob 1 10
+0;
+#X msg 107 143 link souple 1 0 1 0.5 \, link souple 1 2 1 0.5 \, link
+souple 3 2 1 0.5;
+#X connect 0 0 1 0;
+#X connect 1 0 4 0;
+#X connect 2 0 5 0;
+#X connect 3 0 1 0;
+#X connect 5 0 0 0;
+#X connect 5 1 9 0;
+#X connect 5 2 8 0;
+#X connect 5 3 3 0;
+#X connect 5 4 6 0;
+#X connect 6 0 1 0;
+#X connect 7 0 5 0;
+#X connect 8 0 1 0;
+#X connect 9 0 1 0;
+#X restore 17 156 pd init;
+#X obj 17 344 s \$0-out;
+#X obj 17 295 r \$0-in;
+#X obj 261 184 vsl 15 127 0 127 0 0 empty empty Drag-----> -70 60 1
+10 -262144 -1 -1 0 1;
+#X obj 292 184 vsl 15 127 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X obj 261 345 s \$0-in;
+#X msg 261 322 posX fix \$1;
+#N canvas 565 515 355 193 compute 0;
+#X obj 159 37 inlet;
+#X obj 159 74 metro 20;
+#X obj 159 135 s \$0-in;
+#X msg 159 104 bang \, massesPosL;
+#X connect 0 0 1 0;
+#X connect 1 0 3 0;
+#X connect 3 0 2 0;
+#X restore 17 194 pd compute;
+#X obj 17 177 tgl 15 0 empty empty ON/OFF 25 10 1 10 -262144 -1 -1
+0 1;
+#X obj 261 107 r \$0-out;
+#X obj 17 139 bng 15 250 50 0 empty empty reset 25 10 1 10 -262144
+-1 -1;
+#X obj 261 131 route massesPosL;
+#X obj 311 184 vsl 15 127 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X obj 330 184 vsl 15 127 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X obj 261 152 unpack f f f f;
+#X text 101 388 Bang - A bang at the left inlet compute the new model
+state based on previous instant.;
+#X text 158 478 To set the model parameters after creation.;
+#X text 158 456 To create the model masses and links.;
+#X text 158 501 To get the model parameters;
+#N canvas 33 254 559 560 creation________ 0;
+#X obj 11 95 cnv 15 100 35 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 5 75 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 3 cnv 15 550 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X text 7 2 CREATION Messages;
+#X obj 10 156 cnv 15 150 140 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 137 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 10 332 cnv 15 240 220 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 3 308 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X msg 32 104 reset;
+#X text 202 167 Add a mass;
+#X text 288 168 \$1 : Id (symbol);
+#X text 287 188 \$2 : fixed or mobile (0/1);
+#X text 287 206 \$3 : mass;
+#X msg 32 167 mass \$1 \$2 \$3 \$4;
+#X msg 32 243 deleteMass \$1;
+#X text 201 245 Delete a mass and associated links;
+#X text 285 262 \$1 : Creation No of mass;
+#X text 287 224 \$4 : initial position;
+#X text 7 137 Masses :;
+#X text 7 74 Reset :;
+#X text 129 105 Delete all masses \, links and internal variables;
+#X text 6 308 Links :;
+#X text 271 360 \$1 : Id (symbol);
+#X text 271 413 \$4 : rigidity;
+#X msg 30 505 deleteLink \$1;
+#X text 264 507 Delete a link;
+#X text 268 525 \$1 : Creation No of link;
+#X text 271 360 \$1 : Id (symbol);
+#X text 271 413 \$4 : rigidity;
+#X text 271 378 \$2 : creation No/Id of mass1;
+#X text 271 396 \$3 : creation No/Id of mass2;
+#X text 266 341 Add link(s);
+#X text 268 468 (\$6) : minimum lenght of link;
+#X text 268 485 (\$7) : maximum lenght of link;
+#X text 271 431 \$5 : damping;
+#X text 10 28 Creation messages are used to define the structure of
+the model. Messages create links and masses or destroy them.;
+#X msg 30 341 link \$1 \$2 \$3 \$4 \$5 (\$6 \$7 \$8);
+#X text 271 449 \$6 : Power of the rigidity distance;
+#X restore 12 457 pd creation________;
+#X text 103 542 None;
+#X text 18 583 - Left:;
+#X text 101 584 Outputs the model parameters asked with the attributes
+messages.;
+#X obj 13 629 cnv 15 75 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X text 17 628 - Right:;
+#X text 100 629 Outputs information on model when creation messages
+are send or with the special message [infosL( which dump the complete
+state of the model.;
+#X text 101 420 Messages - Different messages are used to control the
+msd object. They are of three types :;
+#X text 9 701 CATEGORY: control;
+#N canvas 475 181 557 516 dynamic 0;
+#X obj 5 3 cnv 15 550 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 10 85 cnv 15 130 210 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 62 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 10 330 cnv 15 130 180 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 3 306 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X text 7 62 Masses :;
+#X text 6 306 Links :;
+#X text 7 2 DYNAMIC SETTINGS Messages;
+#X msg 31 96 posX \$1 \$2;
+#X text 190 144 Add force on mass(es);
+#X msg 30 152 forceX \$1 \$2;
+#X text 192 212 \$1 : Value;
+#X text 193 107 \$1 : Id (symbol) or No;
+#X text 193 161 \$1 : Id (symbol) or No;
+#X msg 30 195 Xmin \$1;
+#X msg 30 217 Xmax \$1;
+#X msg 29 244 setMobile \$1;
+#X msg 29 265 setFixed \$1;
+#X text 193 89 Set position of fixed mass(es);
+#X text 193 125 \$2 : Value;
+#X text 193 179 \$2 : Value;
+#X text 189 196 Set minimimum and maximum position of all masses;
+#X text 188 244 Set mass to mobile or fixed;
+#X msg 29 394 setD \$1 \$2;
+#X text 184 380 \$2 : New value;
+#X msg 29 343 setK \$1 \$2;
+#X text 184 436 \$2 : New value;
+#X text 184 489 \$2 : New value;
+#X text 178 344 Set rigidity of link(s);
+#X text 178 400 Set damping of link(s);
+#X msg 29 449 setL \$1 \$2;
+#X text 178 453 Set initial lenght of link(s);
+#X text 184 362 \$1 : Id (symbol) or No;
+#X text 184 418 \$1 : Id (symbol) or No;
+#X text 184 471 \$1 : Id (symbol) or No;
+#X text 191 261 \$1 : Id (symbol) or No;
+#X text 10 25 Dynamic settings messages allows the user to redefine
+internal parameters of links and masses.;
+#X restore 12 478 pd dynamic settings;
+#N canvas 191 75 634 669 attributes______ 0;
+#X obj 11 95 cnv 15 100 35 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 5 75 cnv 15 590 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 3 cnv 15 590 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 10 158 cnv 15 150 75 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 137 cnv 15 590 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 10 264 cnv 15 110 330 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 240 cnv 15 590 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X text 7 74 General :;
+#X text 7 2 ATTRIBUTES Messages;
+#X text 7 137 Lists :;
+#X msg 33 104 infosL;
+#X text 136 104 Get infos on all masses and links on right outlet;
+#X msg 32 170 massesPosL;
+#X msg 32 198 massesForcesL;
+#X text 170 170 Output all masses positions in a list on outlet No
+1;
+#X text 140 280 Get specific attribute on specific element;
+#X msg 20 278 get \$1 (\$2);
+#X text 7 240 Specific :;
+#X text 140 381 The get message return the asked attribute preceded
+by an identifier and the creation No of the element. The identifier
+is made of the asked parameter and the way you asked for it.;
+#X text 141 457 message;
+#X text 381 457 response;
+#X text 140 438 Examples with 3 masses numbered 0 \, 1 and 2 and named
+mas:;
+#X text 146 547 [get massesPos mas( -----> [massesPosId 0 x0(;
+#X text 335 562 [massesPosId 2 x2(;
+#X text 335 577 [massesPosId 1 x1(;
+#X text 174 476 [get massesPos( -----> [massesPos 0 x0(;
+#X text 335 490 [massesPos 2 x2(;
+#X text 335 504 [massesPos 1 x1(;
+#X text 160 526 [get massesPos 1( -----> [massesPosNo 1 x1(;
+#X text 15 30 The attributes messages ask the object to output some
+of his internal parameters. They can be output by lists for positions
+and forces of masses.;
+#X text 170 199 Output all forces applied on masses in a list on outlet
+No 1;
+#X text 140 348 (\$2) : - If not defined all the attributes are send
+for all the elements. - Ids or/and creations No;
+#X text 140 305 \$1 : Attribute type ( massesPos / massesPosName /
+massesSpeeds / massesSpeedsName / massesForces / massesForces / linksPos
+/ linksPos );
+#X text 146 596 [get massesPosName( -----> [massesPosName name_0 x0(
+;
+#X text 336 626 [massesPosName name_1 x1(;
+#X text 336 611 [massesPosName name_2 x2(;
+#X restore 12 499 pd attributes______;
+#X text 9 711 KEYWORDS: physical model mass spring damper link;
+#X text 267 736 - Nicolas Montgermont \, May 12 \, 2005;
+#X text 111 679 01_msdtest.pd;
+#X connect 22 0 24 0;
+#X connect 25 0 22 0;
+#X connect 26 0 29 0;
+#X connect 29 0 28 0;
+#X connect 31 0 30 0;
+#X connect 32 0 34 0;
+#X connect 33 0 23 0;
+#X connect 34 0 37 0;
+#X connect 37 0 26 0;
+#X connect 37 1 27 0;
+#X connect 37 2 35 0;
+#X connect 37 3 36 0;
diff --git a/msd/msd/package.txt b/msd/msd/package.txt
new file mode 100644
index 0000000..04abc69
--- /dev/null
+++ b/msd/msd/package.txt
@@ -0,0 +1,4 @@
+NAME=msd
+SRCS=main.cpp
+HDRS=../src/msd.h
+
diff --git a/msd/msd2D/01_msd2Dtest.pd b/msd/msd2D/01_msd2Dtest.pd
new file mode 100644
index 0000000..fe68b84
--- /dev/null
+++ b/msd/msd2D/01_msd2Dtest.pd
@@ -0,0 +1,168 @@
+#N canvas 520 22 626 507 10;
+#X obj 27 26 loadbang;
+#X obj 127 419 print msd;
+#X obj 369 155 gemwin;
+#X msg 384 132 0 \, destroy;
+#X text 260 26 2 DRAG THE STRUCTURE WITH THE MOUSE;
+#X obj 87 27 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 90 76 reset;
+#X obj 27 47 t b b b b b;
+#X msg 42 186 Xmax 100 \, Xmin 0 \, Ymax 100 \, Ymin 0;
+#X obj 53 300 gemhead;
+#X obj 53 323 t b;
+#X msg 53 345 bang \, get massesPos \, get linksPos;
+#N canvas 643 123 609 594 massrender 0;
+#X obj 127 22 inlet;
+#X obj 48 203 translateXYZ;
+#X obj 127 86 / 12.5;
+#X obj 127 109 - 4;
+#X obj 192 87 / 12.5;
+#X obj 192 110 - 4;
+#X obj 48 177 separator;
+#X obj 125 136 t b f;
+#X obj 127 57 unpack f f f;
+#X obj 48 141 gemhead 45;
+#X msg 48 104 0;
+#X obj 47 58 loadbang;
+#X obj 48 229 circle 0.1;
+#X connect 0 0 8 0;
+#X connect 1 0 12 0;
+#X connect 2 0 3 0;
+#X connect 3 0 7 0;
+#X connect 4 0 5 0;
+#X connect 5 0 1 2;
+#X connect 6 0 1 0;
+#X connect 7 0 9 0;
+#X connect 7 1 1 1;
+#X connect 8 1 2 0;
+#X connect 8 2 4 0;
+#X connect 9 0 6 0;
+#X connect 10 0 9 0;
+#X connect 11 0 10 0;
+#X restore 436 267 pd massrender;
+#X obj 366 244 route linksPos massesPos;
+#N canvas 731 296 458 308 gemmouse 0;
+#X obj 189 77 gemmouse;
+#X obj 189 184 pack f f;
+#X obj 189 218 spigot;
+#X obj 103 244 outlet;
+#X obj 189 131 - 0;
+#X obj 216 131 + 100;
+#X obj 189 108 / 5;
+#X obj 216 108 / -5;
+#X obj 79 51 inlet;
+#X obj 109 98 t b;
+#X obj 141 120 list;
+#X obj 141 41 r mouse_init;
+#X connect 0 0 6 0;
+#X connect 0 1 7 0;
+#X connect 0 2 2 1;
+#X connect 1 0 2 0;
+#X connect 2 0 10 1;
+#X connect 4 0 1 0;
+#X connect 5 0 1 1;
+#X connect 6 0 4 0;
+#X connect 7 0 5 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 3 0;
+#X connect 11 0 10 1;
+#X restore 366 356 pd gemmouse;
+#X obj 366 335 gemhead;
+#X msg 366 377 posX fix \$1;
+#X msg 366 398 posY fix \$2;
+#N canvas 0 22 454 304 linkrender 0;
+#X obj 127 22 inlet;
+#X obj 127 86 / 12.5;
+#X obj 127 109 - 4;
+#X obj 187 87 / 12.5;
+#X obj 187 110 - 4;
+#X obj 48 177 separator;
+#X obj 125 136 t b f;
+#X obj 241 86 / 12.5;
+#X obj 241 109 - 4;
+#X obj 308 87 / 12.5;
+#X obj 308 110 - 4;
+#X obj 48 222 curve 2;
+#X obj 155 189 pack f f 0;
+#X obj 241 190 pack f f 0;
+#X obj 127 57 unpack f f f f f;
+#X obj 46 130 gemhead 45;
+#X obj 45 44 loadbang;
+#X msg 45 68 0;
+#X connect 0 0 14 0;
+#X connect 1 0 2 0;
+#X connect 2 0 6 0;
+#X connect 3 0 4 0;
+#X connect 4 0 12 1;
+#X connect 5 0 11 0;
+#X connect 6 0 15 0;
+#X connect 6 1 12 0;
+#X connect 7 0 8 0;
+#X connect 8 0 13 0;
+#X connect 9 0 10 0;
+#X connect 10 0 13 1;
+#X connect 12 0 11 1;
+#X connect 13 0 11 2;
+#X connect 14 1 1 0;
+#X connect 14 2 3 0;
+#X connect 14 3 7 0;
+#X connect 14 4 9 0;
+#X connect 15 0 5 0;
+#X connect 16 0 17 0;
+#X connect 17 0 15 0;
+#X restore 366 289 pd linkrender;
+#X msg 194 139 50 50;
+#X msg 74 96 mass fix 0 100 50 50;
+#X msg 58 139 mass mob 1 100 \$1 \$2;
+#X msg 58 118 40 60 \, 60 60 \, 60 40 \, 40 40;
+#X obj 194 162 s mouse_init;
+#X msg 27 207 link souple mob mob 10 5;
+#X msg 27 230 link souple fix mob 10 5;
+#X text 25 1 creation : 5 masses and 20 links;
+#X text 52 281 compute and get masses and links positions;
+#X obj 53 397 msd2D;
+#X text 364 315 move mass to mouse position;
+#X text 365 197 display masses with gem;
+#X msg 369 109 reset \, create \, 1;
+#X text 261 6 1 CREATE WINDOW;
+#X text 108 26 reset struct;
+#X obj 90 259 s \$0-msdin;
+#X obj 84 373 r \$0-msdin;
+#X obj 52 419 s \$0-msdout;
+#X obj 365 423 s \$0-msdin;
+#X obj 366 218 r \$0-msdout;
+#X connect 0 0 7 0;
+#X connect 3 0 2 0;
+#X connect 5 0 7 0;
+#X connect 6 0 34 0;
+#X connect 7 0 24 0;
+#X connect 7 1 19 0;
+#X connect 7 1 8 0;
+#X connect 7 2 22 0;
+#X connect 7 3 20 0;
+#X connect 7 4 6 0;
+#X connect 8 0 34 0;
+#X connect 9 0 10 0;
+#X connect 10 0 11 0;
+#X connect 11 0 28 0;
+#X connect 13 0 18 0;
+#X connect 13 1 12 0;
+#X connect 14 0 16 0;
+#X connect 14 0 17 0;
+#X connect 15 0 14 0;
+#X connect 16 0 37 0;
+#X connect 17 0 37 0;
+#X connect 19 0 23 0;
+#X connect 20 0 34 0;
+#X connect 21 0 34 0;
+#X connect 22 0 21 0;
+#X connect 24 0 25 0;
+#X connect 24 0 34 0;
+#X connect 25 0 34 0;
+#X connect 28 0 36 0;
+#X connect 28 1 1 0;
+#X connect 31 0 2 0;
+#X connect 35 0 28 0;
+#X connect 38 0 13 0;
diff --git a/msd/msd2D/02_msd2Dadd.pd b/msd/msd2D/02_msd2Dadd.pd
new file mode 100644
index 0000000..8dbc071
--- /dev/null
+++ b/msd/msd2D/02_msd2Dadd.pd
@@ -0,0 +1,463 @@
+#N canvas 572 22 686 162 10;
+#X obj 22 16 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 177 95 954 737 synthese 0;
+#X msg -35 254 \$1 50;
+#X obj -35 276 line~;
+#X obj -75 280 *~;
+#X msg 60 254 \$1 50;
+#X obj 60 276 line~;
+#X obj 20 280 *~;
+#X msg 153 256 \$1 50;
+#X obj 153 278 line~;
+#X obj 113 282 *~;
+#X msg 245 254 \$1 50;
+#X obj 245 276 line~;
+#X obj 205 280 *~;
+#X obj 62 328 dac~;
+#X msg 346 257 \$1 50;
+#X obj 346 279 line~;
+#X obj 306 283 *~;
+#X msg 441 257 \$1 50;
+#X obj 441 279 line~;
+#X obj 401 283 *~;
+#X msg 534 259 \$1 50;
+#X obj 534 281 line~;
+#X obj 494 285 *~;
+#X msg 626 257 \$1 50;
+#X obj 626 279 line~;
+#X obj 586 283 *~;
+#X obj 443 331 dac~;
+#X obj -77 224 osc~ 55;
+#X obj 19 224 osc~ 110;
+#X obj 204 225 osc~ 222;
+#X obj -13 158 unpack f f;
+#X obj 176 164 unpack f f;
+#X obj 362 161 unpack f f;
+#X obj 553 168 unpack f f;
+#X msg -45 458 \$1 50;
+#X obj -45 480 line~;
+#X obj -85 484 *~;
+#X msg 50 458 \$1 50;
+#X obj 50 480 line~;
+#X obj 10 484 *~;
+#X msg 143 460 \$1 50;
+#X obj 143 482 line~;
+#X obj 103 486 *~;
+#X msg 235 458 \$1 50;
+#X obj 235 480 line~;
+#X obj 195 484 *~;
+#X obj 52 532 dac~;
+#X msg 336 461 \$1 50;
+#X obj 336 483 line~;
+#X obj 296 487 *~;
+#X msg 431 461 \$1 50;
+#X obj 431 483 line~;
+#X obj 391 487 *~;
+#X msg 524 463 \$1 50;
+#X obj 524 485 line~;
+#X obj 484 489 *~;
+#X msg 616 461 \$1 50;
+#X obj 616 483 line~;
+#X obj 576 487 *~;
+#X obj 433 535 dac~;
+#X obj 483 433 osc~ 1113;
+#X obj 575 431 osc~ 2229;
+#X obj -15 373 unpack f f;
+#X obj 166 368 unpack f f;
+#X obj 352 365 unpack f f;
+#X obj 543 372 unpack f f;
+#X obj 112 226 osc~ 165;
+#X obj 305 227 osc~ 267;
+#X obj 400 227 osc~ 311;
+#X obj 268 74 route 1 5 9 13 17 21 25 29;
+#X obj 493 229 osc~ 366;
+#X obj 585 227 osc~ 421;
+#X obj -87 428 osc~ 444;
+#X obj 9 428 osc~ 554;
+#X obj 102 430 osc~ 664;
+#X obj 194 428 osc~ 776;
+#X obj 295 431 osc~ 888;
+#X obj 390 431 osc~ 1000;
+#X obj -75 398 / 20;
+#X obj 52 404 / 20;
+#X obj 144 406 / 20;
+#X obj 240 404 / 50;
+#X obj 307 401 / 50;
+#X obj 434 407 / 50;
+#X obj 524 409 / 100;
+#X obj 621 407 / 100;
+#X obj 631 203 / 100;
+#X obj 532 206 / 100;
+#X obj 444 204 / 50;
+#X obj 317 197 / 50;
+#X obj 250 200 / 50;
+#X obj 153 202 / 20;
+#X obj 61 201 / 20;
+#X obj -64 194 / 20;
+#X obj 268 49 route massesSpeedsNo;
+#X obj 268 27 r \$0-msdout;
+#X connect 0 0 1 0;
+#X connect 1 0 2 1;
+#X connect 2 0 12 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 1;
+#X connect 5 0 12 0;
+#X connect 5 0 12 1;
+#X connect 6 0 7 0;
+#X connect 7 0 8 1;
+#X connect 8 0 12 0;
+#X connect 8 0 12 1;
+#X connect 9 0 10 0;
+#X connect 10 0 11 1;
+#X connect 11 0 12 1;
+#X connect 13 0 14 0;
+#X connect 14 0 15 1;
+#X connect 15 0 25 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 1;
+#X connect 18 0 25 0;
+#X connect 18 0 25 1;
+#X connect 19 0 20 0;
+#X connect 20 0 21 1;
+#X connect 21 0 25 0;
+#X connect 21 0 25 1;
+#X connect 22 0 23 0;
+#X connect 23 0 24 1;
+#X connect 24 0 25 1;
+#X connect 26 0 2 0;
+#X connect 27 0 5 0;
+#X connect 28 0 11 0;
+#X connect 29 0 92 0;
+#X connect 29 1 91 0;
+#X connect 30 0 90 0;
+#X connect 30 1 89 0;
+#X connect 31 0 88 0;
+#X connect 31 1 87 0;
+#X connect 32 0 86 0;
+#X connect 32 1 85 0;
+#X connect 33 0 34 0;
+#X connect 34 0 35 1;
+#X connect 35 0 45 0;
+#X connect 36 0 37 0;
+#X connect 37 0 38 1;
+#X connect 38 0 45 0;
+#X connect 38 0 45 1;
+#X connect 39 0 40 0;
+#X connect 40 0 41 1;
+#X connect 41 0 45 0;
+#X connect 41 0 45 1;
+#X connect 42 0 43 0;
+#X connect 43 0 44 1;
+#X connect 44 0 45 1;
+#X connect 46 0 47 0;
+#X connect 47 0 48 1;
+#X connect 48 0 58 0;
+#X connect 49 0 50 0;
+#X connect 50 0 51 1;
+#X connect 51 0 58 0;
+#X connect 51 0 58 1;
+#X connect 52 0 53 0;
+#X connect 53 0 54 1;
+#X connect 54 0 58 0;
+#X connect 54 0 58 1;
+#X connect 55 0 56 0;
+#X connect 56 0 57 1;
+#X connect 57 0 58 1;
+#X connect 59 0 54 0;
+#X connect 60 0 57 0;
+#X connect 61 0 77 0;
+#X connect 61 1 78 0;
+#X connect 62 0 79 0;
+#X connect 62 1 80 0;
+#X connect 63 0 81 0;
+#X connect 63 1 82 0;
+#X connect 64 0 83 0;
+#X connect 64 1 84 0;
+#X connect 65 0 8 0;
+#X connect 66 0 15 0;
+#X connect 67 0 18 0;
+#X connect 68 0 29 0;
+#X connect 68 1 30 0;
+#X connect 68 2 31 0;
+#X connect 68 3 32 0;
+#X connect 68 4 61 0;
+#X connect 68 5 62 0;
+#X connect 68 6 63 0;
+#X connect 68 7 64 0;
+#X connect 69 0 21 0;
+#X connect 70 0 24 0;
+#X connect 71 0 35 0;
+#X connect 72 0 38 0;
+#X connect 73 0 41 0;
+#X connect 74 0 44 0;
+#X connect 75 0 48 0;
+#X connect 76 0 51 0;
+#X connect 77 0 33 0;
+#X connect 78 0 36 0;
+#X connect 79 0 39 0;
+#X connect 80 0 42 0;
+#X connect 81 0 46 0;
+#X connect 82 0 49 0;
+#X connect 83 0 52 0;
+#X connect 84 0 55 0;
+#X connect 85 0 22 0;
+#X connect 86 0 19 0;
+#X connect 87 0 16 0;
+#X connect 88 0 13 0;
+#X connect 89 0 9 0;
+#X connect 90 0 6 0;
+#X connect 91 0 3 0;
+#X connect 92 0 0 0;
+#X connect 93 0 68 0;
+#X connect 94 0 93 0;
+#X restore 23 107 pd synthese;
+#X text 40 16 Reset;
+#N canvas 0 22 450 300 structure_creation 0;
+#X msg 195 86 reset;
+#X obj 52 15 loadbang;
+#X msg 156 145 Xmax 100 \, Xmin 0 \, Ymax 100 \, Ymin 0;
+#X text 238 112 Random positions and masses;
+#N canvas 557 309 487 357 masses 0;
+#X msg 245 215 mass mob 1 \$1 \$2 \$3;
+#X obj 417 165 random 100;
+#X msg 417 145 seed 1;
+#X obj 342 165 random 100;
+#X obj 239 146 random 100;
+#X msg 342 144 seed 2;
+#X msg 239 126 seed 3;
+#X obj 239 166 + 100;
+#X obj 245 194 pack f f f;
+#X obj 42 14 inlet;
+#X obj 246 283 outlet;
+#X obj 268 47 loadbang;
+#X text 284 101 M;
+#X text 356 106 X;
+#X text 437 106 Y;
+#X obj 223 68 t b b;
+#X obj 42 45 until;
+#X obj 42 78 f;
+#X obj 72 78 + 1;
+#X obj 72 100 mod 30;
+#X obj 90 45 sel 0;
+#X connect 0 0 10 0;
+#X connect 1 0 8 2;
+#X connect 2 0 1 0;
+#X connect 3 0 8 1;
+#X connect 4 0 7 0;
+#X connect 5 0 3 0;
+#X connect 6 0 4 0;
+#X connect 7 0 8 0;
+#X connect 8 0 0 0;
+#X connect 9 0 16 0;
+#X connect 11 0 6 0;
+#X connect 11 0 5 0;
+#X connect 11 0 2 0;
+#X connect 15 0 4 0;
+#X connect 15 1 3 0;
+#X connect 15 1 1 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 0;
+#X connect 17 0 15 0;
+#X connect 18 0 19 0;
+#X connect 19 0 17 1;
+#X connect 19 0 20 0;
+#X connect 20 0 16 1;
+#X restore 175 113 pd masses;
+#N canvas 0 22 450 300 links 0;
+#X obj 136 72 t b;
+#X obj 136 116 + 1;
+#X obj 130 191 f;
+#X obj 92 171 t f b;
+#X obj 91 211 pack f f;
+#X msg 91 233 link souple \$1 \$2 10 0.5;
+#X obj 136 23 inlet;
+#X obj 91 260 outlet;
+#X obj 136 48 until;
+#X obj 202 112 sel 0;
+#X obj 184 154 mod 29;
+#X obj 136 93 f 0;
+#X connect 0 0 11 0;
+#X connect 1 0 10 0;
+#X connect 1 0 2 1;
+#X connect 2 0 4 1;
+#X connect 3 0 4 0;
+#X connect 3 1 2 0;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 8 0;
+#X connect 8 0 0 0;
+#X connect 9 0 8 1;
+#X connect 10 0 9 0;
+#X connect 10 0 11 1;
+#X connect 11 0 1 0;
+#X connect 11 0 3 0;
+#X restore 137 176 pd links;
+#X obj 137 62 t b b b b;
+#X obj 137 15 inlet;
+#X obj 137 211 s \$0-msdin;
+#X connect 0 0 8 0;
+#X connect 1 0 6 0;
+#X connect 2 0 8 0;
+#X connect 4 0 8 0;
+#X connect 5 0 8 0;
+#X connect 6 0 5 0;
+#X connect 6 1 2 0;
+#X connect 6 2 4 0;
+#X connect 6 3 0 0;
+#X connect 7 0 6 0;
+#X restore 22 39 pd structure_creation;
+#N canvas 0 22 763 327 gem_stuff 0;
+#X msg 137 179 0 \, destroy;
+#X obj 118 200 gemwin;
+#X obj 118 104 inlet;
+#X obj 118 129 sel 1 0;
+#X msg 118 156 reset \, create \, 1;
+#X obj 274 105 gemhead;
+#N canvas 311 224 413 534 gemmouse2 0;
+#X obj 114 29 gemmouse;
+#X obj 96 266 outlet;
+#X obj 114 83 - 0;
+#X obj 165 97 + 100;
+#X obj 114 60 / 5;
+#X obj 165 74 / -5;
+#X obj 32 81 t b;
+#X obj 32 37 inlet;
+#X obj 96 177 f;
+#X obj 96 206 pack 0 0 0;
+#X connect 0 0 4 0;
+#X connect 0 1 5 0;
+#X connect 0 2 9 2;
+#X connect 2 0 8 1;
+#X connect 3 0 9 1;
+#X connect 4 0 2 0;
+#X connect 5 0 3 0;
+#X connect 6 0 8 0;
+#X connect 7 0 6 0;
+#X connect 8 0 9 0;
+#X connect 9 0 1 0;
+#X restore 274 127 pd gemmouse2;
+#X msg 274 150 grabMass \$1 \$2 \$3;
+#N canvas 643 123 617 602 massrender 0;
+#X obj 127 22 inlet;
+#X obj 62 267 translateXYZ;
+#X obj 166 123 / 12.5;
+#X obj 166 146 - 4;
+#X obj 231 124 / 12.5;
+#X obj 231 147 - 4;
+#X obj 62 241 separator;
+#X obj 127 57 unpack f f f;
+#X msg 128 194 \$1;
+#X obj 62 219 colorRGB 1 1 1;
+#X obj 128 174 / 29;
+#X obj 127 85 t b f;
+#X obj 62 135 gemhead 45;
+#X obj 62 63 loadbang;
+#X msg 62 93 0;
+#X obj 62 314 circle 0.1;
+#X connect 0 0 7 0;
+#X connect 1 0 15 0;
+#X connect 2 0 3 0;
+#X connect 3 0 1 1;
+#X connect 4 0 5 0;
+#X connect 5 0 1 2;
+#X connect 6 0 1 0;
+#X connect 7 0 11 0;
+#X connect 7 1 2 0;
+#X connect 7 2 4 0;
+#X connect 8 0 9 2;
+#X connect 8 0 9 3;
+#X connect 9 0 6 0;
+#X connect 10 0 8 0;
+#X connect 11 0 12 0;
+#X connect 11 1 10 0;
+#X connect 12 0 9 0;
+#X connect 13 0 14 0;
+#X connect 14 0 12 0;
+#X restore 502 153 pd massrender;
+#N canvas 284 227 595 566 linkrender 0;
+#X obj 261 87 inlet;
+#X obj 261 179 / 12.5;
+#X obj 261 202 - 4;
+#X obj 315 180 / 12.5;
+#X obj 315 203 - 4;
+#X obj 189 288 separator;
+#X obj 261 226 t b f;
+#X obj 189 331 curve 2;
+#X obj 375 183 / 12.5;
+#X obj 375 206 - 4;
+#X obj 429 184 / 12.5;
+#X obj 429 207 - 4;
+#X obj 291 256 pack f f;
+#X msg 291 279 \$1 \$2 0;
+#X obj 375 255 pack f f;
+#X msg 375 278 \$1 \$2 0;
+#X obj 261 131 unpack f f f f f;
+#X obj 189 310 colorRGB 1 1 1;
+#X obj 189 262 gemhead 45;
+#X obj 189 180 loadbang;
+#X msg 189 229 0;
+#X connect 0 0 16 0;
+#X connect 1 0 2 0;
+#X connect 2 0 6 0;
+#X connect 3 0 4 0;
+#X connect 4 0 12 1;
+#X connect 5 0 17 0;
+#X connect 6 0 18 0;
+#X connect 6 1 12 0;
+#X connect 8 0 9 0;
+#X connect 9 0 14 0;
+#X connect 10 0 11 0;
+#X connect 11 0 14 1;
+#X connect 12 0 13 0;
+#X connect 13 0 7 1;
+#X connect 14 0 15 0;
+#X connect 15 0 7 2;
+#X connect 16 1 1 0;
+#X connect 16 2 3 0;
+#X connect 16 3 8 0;
+#X connect 16 4 10 0;
+#X connect 17 0 7 0;
+#X connect 18 0 5 0;
+#X connect 19 0 20 0;
+#X connect 20 0 18 0;
+#X restore 432 174 pd linkrender;
+#X obj 432 124 route linksPos massesPos;
+#X obj 273 174 s \$0-msdin;
+#X obj 432 101 r \$0-msdout;
+#X connect 0 0 1 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 3 1 0 0;
+#X connect 4 0 1 0;
+#X connect 5 0 6 0;
+#X connect 6 0 7 0;
+#X connect 7 0 11 0;
+#X connect 10 0 9 0;
+#X connect 10 1 8 0;
+#X connect 12 0 10 0;
+#X restore 23 86 pd gem_stuff;
+#X obj 23 64 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1
+;
+#X text 43 63 gem on/off;
+#X text 196 54 1 Create window;
+#X text 196 74 2 Set dsp on;
+#N canvas 0 22 450 300 compute 0;
+#X obj 110 186 print msd;
+#X obj 52 69 gemhead;
+#X msg 52 96 bang \, get massesPos \, get linksPos \, get massesSpeeds
+1 5 9 13 17 21 25 29;
+#X obj 52 162 msd2D;
+#X obj 67 133 r \$0-msdin;
+#X obj 52 186 s \$0-msdout;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 3 0 5 0;
+#X connect 3 1 0 0;
+#X connect 4 0 3 0;
+#X restore 23 129 pd compute;
+#X text 196 94 Drag red masses for bass and white ones for high tones...
+;
+#X text 196 17 Additive synthesis example;
+#X connect 0 0 3 0;
+#X connect 5 0 4 0;
diff --git a/msd/msd2D/03_imsd2Dtest.pd b/msd/msd2D/03_imsd2Dtest.pd
new file mode 100644
index 0000000..a5ec27f
--- /dev/null
+++ b/msd/msd2D/03_imsd2Dtest.pd
@@ -0,0 +1,156 @@
+#N canvas 568 230 687 149 10;
+#X obj 23 17 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 43 16 reset;
+#N canvas 0 22 763 327 gem_stuff 0;
+#X msg 137 179 0 \, destroy;
+#X obj 118 200 gemwin;
+#X obj 118 104 inlet;
+#X obj 118 129 sel 1 0;
+#X msg 118 156 reset \, create \, 1;
+#N canvas 284 227 591 562 linkrender 0;
+#X obj 150 9 inlet;
+#X obj 150 101 / 12.5;
+#X obj 150 124 - 4;
+#X obj 204 102 / 12.5;
+#X obj 204 125 - 4;
+#X obj 67 265 separator;
+#X obj 150 148 t b f;
+#X obj 67 308 curve 2;
+#X obj 264 105 / 12.5;
+#X obj 264 128 - 4;
+#X obj 318 106 / 12.5;
+#X obj 318 129 - 4;
+#X obj 180 178 pack f f;
+#X msg 180 201 \$1 \$2 0;
+#X obj 264 177 pack f f;
+#X msg 264 200 \$1 \$2 0;
+#X obj 150 53 unpack f f f f f;
+#X obj 67 224 gemhead 45;
+#X obj 67 116 loadbang;
+#X msg 67 174 0;
+#X connect 0 0 16 0;
+#X connect 1 0 2 0;
+#X connect 2 0 6 0;
+#X connect 3 0 4 0;
+#X connect 4 0 12 1;
+#X connect 5 0 7 0;
+#X connect 6 0 17 0;
+#X connect 6 1 12 0;
+#X connect 8 0 9 0;
+#X connect 9 0 14 0;
+#X connect 10 0 11 0;
+#X connect 11 0 14 1;
+#X connect 12 0 13 0;
+#X connect 13 0 7 1;
+#X connect 14 0 15 0;
+#X connect 15 0 7 2;
+#X connect 16 1 1 0;
+#X connect 16 2 3 0;
+#X connect 16 3 8 0;
+#X connect 16 4 10 0;
+#X connect 17 0 5 0;
+#X connect 18 0 19 0;
+#X connect 19 0 17 0;
+#X restore 262 171 pd linkrender;
+#X obj 262 133 route linksPos;
+#X obj 262 110 r \$0-msdout;
+#N canvas 731 296 454 304 gemmouse 0;
+#X obj 189 77 gemmouse;
+#X obj 189 184 pack f f;
+#X obj 189 218 spigot;
+#X obj 103 244 outlet;
+#X obj 189 131 - 0;
+#X obj 216 131 + 100;
+#X obj 189 108 / 5;
+#X obj 216 108 / -5;
+#X obj 79 51 inlet;
+#X obj 109 98 t b;
+#X obj 108 139 list;
+#X obj 141 42 r mouse_init;
+#X connect 0 0 6 0;
+#X connect 0 1 7 0;
+#X connect 0 2 2 1;
+#X connect 1 0 2 0;
+#X connect 2 0 10 1;
+#X connect 4 0 1 0;
+#X connect 5 0 1 1;
+#X connect 6 0 4 0;
+#X connect 7 0 5 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 3 0;
+#X connect 11 0 10 1;
+#X restore 404 127 pd gemmouse;
+#X obj 404 106 gemhead;
+#X msg 405 147 posX fix \$1;
+#X msg 406 168 posY fix \$2;
+#X obj 405 194 s \$0-msdin;
+#X connect 0 0 1 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 3 1 0 0;
+#X connect 4 0 1 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 0;
+#X connect 8 0 10 0;
+#X connect 8 0 11 0;
+#X connect 9 0 8 0;
+#X connect 10 0 12 0;
+#X connect 11 0 12 0;
+#X restore 23 86 pd gem_stuff;
+#X obj 23 64 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1
+;
+#X text 43 63 gem on/off;
+#N canvas 487 334 635 333 creation 0;
+#X obj 52 15 loadbang;
+#X msg 221 71 reset;
+#X msg 153 170 50 50;
+#X msg 203 91 mass fix 0 100 50 50;
+#X msg 169 192 Xmax 100 \, Xmin 0 \, Ymax 100 \, Ymin 0;
+#X msg 186 150 mass mob 1 100 \$1 \$2;
+#X obj 135 42 t b b b b b b;
+#X msg 186 116 20 50 \, 23 61 \, 29 71 \, 39 77 \, 50 80 \, 61 77 \,
+71 71 \, 77 61 \, 80 50 \, 77 39 \, 71 29 \, 61 23 \, 50 20 \, 39 23
+\, 29 29 \, 23 39;
+#X msg 144 211 link intf mob 0 10 2.5;
+#X msg 135 234 link inter mob mob 1 2.5;
+#X obj 192 270 s mouse_init;
+#X obj 135 261 s \$0-msdin;
+#X obj 239 25 inlet;
+#X text 303 226 all links are created with these two messages;
+#X connect 0 0 6 0;
+#X connect 1 0 11 0;
+#X connect 2 0 10 0;
+#X connect 3 0 11 0;
+#X connect 4 0 11 0;
+#X connect 5 0 11 0;
+#X connect 6 0 9 0;
+#X connect 6 1 8 0;
+#X connect 6 2 2 0;
+#X connect 6 2 4 0;
+#X connect 6 3 7 0;
+#X connect 6 4 3 0;
+#X connect 6 5 1 0;
+#X connect 7 0 5 0;
+#X connect 8 0 11 0;
+#X connect 9 0 11 0;
+#X connect 12 0 6 0;
+#X restore 23 40 pd creation;
+#N canvas 0 22 450 300 compute 0;
+#X obj 53 100 gemhead;
+#X obj 53 123 t b;
+#X msg 53 145 bang \, get linksPos;
+#X obj 53 224 s \$0-msdout;
+#X obj 63 174 r \$0-msdin;
+#X obj 53 198 msd2D;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 5 0;
+#X connect 4 0 5 0;
+#X connect 5 0 3 0;
+#X restore 23 111 pd compute;
+#X text 164 54 create window;
+#X text 164 69 and drag the structure with the mouse;
+#X connect 0 0 5 0;
+#X connect 3 0 2 0;
diff --git a/msd/msd2D/04_msd2Dperf.pd b/msd/msd2D/04_msd2Dperf.pd
new file mode 100644
index 0000000..d264d8f
--- /dev/null
+++ b/msd/msd2D/04_msd2Dperf.pd
@@ -0,0 +1,213 @@
+#N canvas 521 54 428 182 10;
+#X msg 144 71 forceX mob 100;
+#X msg 144 94 forceX mob -100;
+#X text 141 13 change number of mass to test performance;
+#X text 141 26 (and reset afterwards);
+#X obj 81 19 nbx 5 14 1 20000 1 1 empty empty empty 0 -6 0 10 -262144
+-1 -1 125.925 256;
+#X obj 18 18 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 38 16 reset;
+#N canvas 487 334 635 333 creation 0;
+#X msg 239 84 reset;
+#X obj 167 55 t b b b b b;
+#X obj 441 55 f;
+#X msg 221 104 mass fix 0 100 0 0;
+#N canvas 0 22 450 300 links 0;
+#X obj 136 72 t b;
+#X obj 136 116 + 1;
+#X obj 130 191 f;
+#X obj 92 171 t f b;
+#X obj 91 211 pack f f;
+#X msg 91 233 link souple \$1 \$2 10 0.5;
+#X obj 136 23 inlet;
+#X obj 91 260 outlet;
+#X obj 136 48 until;
+#X obj 202 112 sel 0;
+#X obj 184 154 mod 29;
+#X obj 136 93 f 0;
+#X obj 311 32 inlet;
+#X connect 0 0 11 0;
+#X connect 1 0 10 0;
+#X connect 1 0 2 1;
+#X connect 2 0 4 1;
+#X connect 3 0 4 0;
+#X connect 3 1 2 0;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 8 0;
+#X connect 8 0 0 0;
+#X connect 9 0 8 1;
+#X connect 10 0 9 0;
+#X connect 10 0 11 1;
+#X connect 11 0 1 0;
+#X connect 11 0 3 0;
+#X connect 12 0 10 1;
+#X restore 167 194 pd links;
+#N canvas 557 309 487 357 masses 0;
+#X msg 211 239 mass mob 1 \$1 \$2 \$3;
+#X msg 417 145 seed 1;
+#X msg 342 144 seed 2;
+#X msg 239 126 seed 3;
+#X obj 211 218 pack f f f;
+#X obj 42 14 inlet;
+#X obj 212 307 outlet;
+#X obj 268 47 loadbang;
+#X text 284 101 M;
+#X text 356 106 X;
+#X text 437 106 Y;
+#X obj 223 68 t b b;
+#X obj 42 45 until;
+#X obj 42 78 f;
+#X obj 72 78 + 1;
+#X obj 72 100 mod 30;
+#X obj 90 45 sel 0;
+#X obj 164 15 inlet;
+#X obj 342 165 random 800;
+#X obj 418 165 random 800;
+#X obj 239 146 random 800;
+#X obj 342 186 / 100;
+#X obj 339 206 - 4;
+#X obj 407 193 / 100;
+#X obj 404 213 - 4;
+#X obj 239 166 + 800;
+#X obj 235 186 / 8;
+#X connect 0 0 6 0;
+#X connect 1 0 19 0;
+#X connect 2 0 18 0;
+#X connect 3 0 20 0;
+#X connect 4 0 0 0;
+#X connect 5 0 12 0;
+#X connect 7 0 3 0;
+#X connect 7 0 2 0;
+#X connect 7 0 1 0;
+#X connect 11 0 20 0;
+#X connect 11 1 18 0;
+#X connect 11 1 19 0;
+#X connect 12 0 13 0;
+#X connect 13 0 14 0;
+#X connect 13 0 11 0;
+#X connect 14 0 15 0;
+#X connect 15 0 13 1;
+#X connect 15 0 16 0;
+#X connect 16 0 12 1;
+#X connect 17 0 15 1;
+#X connect 18 0 21 0;
+#X connect 19 0 23 0;
+#X connect 20 0 25 0;
+#X connect 21 0 22 0;
+#X connect 22 0 4 1;
+#X connect 23 0 24 0;
+#X connect 24 0 4 2;
+#X connect 25 0 26 0;
+#X connect 26 0 4 0;
+#X restore 203 129 pd masses;
+#X msg 185 155 Xmax 4 \, Xmin -4 \, Ymax 4 \, Ymin -4;
+#X obj 166 29 inlet;
+#X obj 205 30 loadbang;
+#X obj 441 33 inlet;
+#X obj 167 221 s \$0-msdin;
+#X connect 0 0 10 0;
+#X connect 1 0 4 0;
+#X connect 1 1 6 0;
+#X connect 1 2 5 0;
+#X connect 1 3 3 0;
+#X connect 1 4 0 0;
+#X connect 2 0 4 1;
+#X connect 2 0 5 1;
+#X connect 3 0 10 0;
+#X connect 4 0 10 0;
+#X connect 5 0 10 0;
+#X connect 6 0 10 0;
+#X connect 7 0 1 0;
+#X connect 8 0 1 0;
+#X connect 9 0 2 0;
+#X restore 18 41 pd creation;
+#N canvas 0 22 450 300 gem 0;
+#X msg 30 99 0 \, destroy;
+#X msg 30 76 reset \, create \, lighting 1 \, 1;
+#X obj 30 148 gemwin;
+#X obj 32 25 inlet;
+#X obj 32 53 sel 1 0;
+#X obj 241 50 gemhead;
+#X obj 241 73 world_light;
+#X connect 0 0 2 0;
+#X connect 1 0 2 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 4 1 0 0;
+#X connect 5 0 6 0;
+#X restore 18 91 pd gem;
+#X obj 18 68 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1
+;
+#X text 38 66 gem on/off;
+#N canvas 0 22 450 300 compute 0;
+#N canvas 643 123 311 308 massrender 0;
+#X obj 24 196 translateXYZ;
+#X obj 24 170 separator;
+#X obj 24 144 gemhead 45;
+#X obj 103 17 inlet;
+#X obj 103 55 unpack f f f;
+#X obj 109 83 t b f;
+#X obj 24 56 loadbang;
+#X msg 24 80 0;
+#X obj 24 222 sphere 0.1;
+#X connect 0 0 8 0;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 1 5 0;
+#X connect 4 2 0 2;
+#X connect 5 0 2 0;
+#X connect 5 1 0 1;
+#X connect 6 0 7 0;
+#X connect 7 0 2 0;
+#X restore 133 205 pd massrender;
+#N canvas 284 227 394 269 linkrender 0;
+#X obj 121 20 inlet;
+#X obj 57 175 separator;
+#X obj 57 220 curve 2;
+#X obj 43 130 gemhead 45;
+#X msg 213 69 \$4 \$5 0;
+#X msg 141 65 \$2 \$3 0;
+#X obj 140 94 t b a;
+#X obj 44 46 loadbang;
+#X msg 44 75 0;
+#X connect 0 0 4 0;
+#X connect 0 0 5 0;
+#X connect 1 0 2 0;
+#X connect 3 0 1 0;
+#X connect 4 0 2 2;
+#X connect 5 0 6 0;
+#X connect 6 0 3 0;
+#X connect 6 1 2 1;
+#X connect 7 0 8 0;
+#X connect 8 0 3 0;
+#X restore 52 256 pd linkrender;
+#X obj 52 28 gemhead;
+#X msg 52 85 bang \, get massesPos \, get linksPos;
+#X obj 52 176 route linksPos massesPos;
+#X obj 82 127 r \$0-msdin;
+#X obj 52 153 msd2D;
+#X obj 85 198 inlet;
+#X obj 52 227 spigot;
+#X connect 2 0 3 0;
+#X connect 3 0 6 0;
+#X connect 4 0 8 0;
+#X connect 4 1 0 0;
+#X connect 5 0 6 0;
+#X connect 6 0 4 0;
+#X connect 7 0 8 1;
+#X connect 8 0 1 0;
+#X restore 19 137 pd compute;
+#X obj 144 118 s \$0-msdin;
+#X text 260 80 click to move;
+#X obj 19 115 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X text 39 114 display links;
+#X connect 0 0 12 0;
+#X connect 1 0 12 0;
+#X connect 4 0 7 1;
+#X connect 5 0 7 0;
+#X connect 9 0 8 0;
+#X connect 14 0 11 0;
diff --git a/msd/msd2D/05_msd2DDataStruct.pd b/msd/msd2D/05_msd2DDataStruct.pd
new file mode 100644
index 0000000..9f74841
--- /dev/null
+++ b/msd/msd2D/05_msd2DDataStruct.pd
@@ -0,0 +1,117 @@
+#N struct liaison float x1 float y1 float x2 float y2 float mid1 float
+mid2 float lid;
+#N struct mass float x float y float mid float mob;
+#N struct fixmass float x float y float mid;
+#N canvas 241 22 630 524 10;
+#X obj 15 58 structures;
+#X obj 16 96 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X msg 16 153 forceY mob 8;
+#X obj 16 125 metro 10;
+#N canvas 0 22 307 306 \$0-anim 0;
+#X scalar liaison 90.3805 300 139.692 181.359 0 0 0 \;;
+#X scalar liaison 89.4172 189.783 104.878 200.197 0 0 0 \;;
+#X scalar liaison 89.4172 189.783 139.692 181.359 0 0 0 \;;
+#X scalar liaison 145.861 231.953 90.3805 300 0 0 0 \;;
+#X scalar liaison 81.2748 184.111 102.254 162.589 0 0 0 \;;
+#X scalar liaison 89.4172 189.783 52.423 226.527 0 0 0 \;;
+#X scalar liaison 156.503 300 89.4172 189.783 0 0 0 \;;
+#X scalar liaison 104.878 200.197 121.885 186.762 0 0 0 \;;
+#X scalar liaison 145.861 231.953 89.4172 189.783 0 0 0 \;;
+#X scalar liaison 156.503 300 145.861 231.953 0 0 0 \;;
+#X scalar liaison 121.885 186.762 81.2748 184.111 0 0 0 \;;
+#X scalar liaison 52.423 226.527 139.692 181.359 0 0 0 \;;
+#X scalar liaison 156.503 300 97.1881 236.113 0 0 0 \;;
+#X scalar liaison 139.692 181.359 121.885 186.762 0 0 0 \;;
+#X scalar liaison 139.692 181.359 145.861 231.953 0 0 0 \;;
+#X scalar liaison 90.3805 300 97.1881 236.113 0 0 0 \;;
+#X scalar liaison 102.254 162.589 121.885 186.762 0 0 0 \;;
+#X scalar liaison 139.692 181.359 187.622 200.002 0 0 0 \;;
+#X scalar liaison 97.1881 236.113 145.861 231.953 0 0 0 \;;
+#X scalar liaison 104.878 200.197 81.2748 184.111 0 0 0 \;;
+#X scalar liaison 97.1881 236.113 139.692 181.359 0 0 0 \;;
+#X scalar liaison 97.1881 236.113 89.4172 189.783 0 0 0 \;;
+#X scalar liaison 104.878 200.197 102.254 162.589 0 0 0 \;;
+#X scalar liaison 89.4172 189.783 187.622 200.002 0 0 0 \;;
+#X scalar mass 90.3805 300 0 0 \;;
+#X scalar mass 104.878 200.197 8 0 \;;
+#X scalar mass 89.4172 189.783 4 0 \;;
+#X scalar mass 97.1881 236.113 2 0 \;;
+#X scalar mass 81.2748 184.111 10 0 \;;
+#X scalar mass 52.423 226.527 6 0 \;;
+#X scalar mass 156.503 300 1 0 \;;
+#X scalar mass 121.885 186.762 9 0 \;;
+#X scalar mass 139.692 181.359 5 0 \;;
+#X scalar mass 145.861 231.953 3 0 \;;
+#X scalar mass 102.254 162.589 11 0 \;;
+#X scalar mass 187.622 200.002 7 0 \;;
+#X coords 0 0 300 300 300 300 1;
+#X restore 255 92 pd \$0-anim;
+#X obj 16 212 make_anim \$0-anim;
+#X msg 15 358 forceY mob -200;
+#X msg 15 380 forceY mob 200;
+#X msg 15 316 forceX mob 200;
+#X msg 15 337 forceX mob -200;
+#X msg 15 400 forceX 0 -200 \, forceX 1 200;
+#X msg 15 442 forceY 0 -200 \, forceY 1 -200 \, forceX 0 -200 \, forceX
+1 200;
+#X msg 15 421 forceY 6 -200 \, forceY 7 -200;
+#X obj 15 182 r \$0-msdin;
+#N canvas 0 22 450 300 creation 0;
+#X obj 45 20 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262131 -1
+-1;
+#X msg 117 71 reset;
+#X text 83 21 reset;
+#X obj 45 42 t b b b b b;
+#X msg 63 181 Xmax 300 \, Xmin 0 \, Ymax 300 \, Ymin 0;
+#X msg 81 113 100 300 \, 150 300 \, 100 230 \, 150 230 \, 100 180 \,
+150 180 \, 50 180 \, 200 180 \, 115 180 \, 135 180 \, 110 150 \, 140
+150;
+#X msg 45 205 0 5 \, 1 2 \, 1 4 \, 2 3 \, 3 0 \, 0 2 \, 1 3 \, 2 4
+\, 4 5 \, 5 3 \, 3 4 \, 2 5 \, 4 6 \, 5 7 \, 6 5 \, 4 7 \, 4 8 \, 5
+9 \, 8 9 \, 8 10 \, 10 11 \, 11 9 \, 9 10 \, 8 11;
+#X msg 45 252 link souple \$1 \$2 12 20;
+#X msg 81 146 mass mob 1 100 \$1 \$2;
+#X obj 45 274 s \$0-msdin;
+#X obj 69 6 inlet;
+#X obj 141 26 loadbang;
+#X connect 0 0 3 0;
+#X connect 1 0 9 0;
+#X connect 3 0 6 0;
+#X connect 3 1 4 0;
+#X connect 3 2 5 0;
+#X connect 3 4 1 0;
+#X connect 4 0 9 0;
+#X connect 5 0 8 0;
+#X connect 6 0 7 0;
+#X connect 7 0 9 0;
+#X connect 8 0 9 0;
+#X connect 10 0 3 0;
+#X connect 11 0 3 0;
+#X restore 15 37 pd creation;
+#X obj 15 14 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X text 36 14 reset;
+#X obj 15 467 s \$0-msdin;
+#X obj 15 286 msd2D;
+#X text 38 95 compute;
+#X text 252 28 1 - notch the "poll" case to set DS to actual model
+state;
+#X text 252 47 2 - compute ON;
+#X text 252 64 3 - "force" the dancer to move;
+#X connect 1 0 3 0;
+#X connect 2 0 18 0;
+#X connect 3 0 2 0;
+#X connect 3 0 18 0;
+#X connect 5 0 18 0;
+#X connect 6 0 17 0;
+#X connect 7 0 17 0;
+#X connect 8 0 17 0;
+#X connect 9 0 17 0;
+#X connect 10 0 17 0;
+#X connect 11 0 17 0;
+#X connect 12 0 17 0;
+#X connect 13 0 18 0;
+#X connect 15 0 14 0;
+#X connect 18 0 5 0;
+#X connect 18 1 5 0;
diff --git a/msd/msd2D/06_msd2Dgravit.pd b/msd/msd2D/06_msd2Dgravit.pd
new file mode 100644
index 0000000..0213fe5
--- /dev/null
+++ b/msd/msd2D/06_msd2Dgravit.pd
@@ -0,0 +1,212 @@
+#N canvas 386 22 491 156 10;
+#X obj 18 21 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 39 18 reset;
+#N canvas 0 22 450 300 gem_stuff 0;
+#X msg 30 89 0 \, destroy;
+#X obj 30 185 gemhead;
+#X obj 30 238 world_light;
+#X obj 30 148 gemwin;
+#X msg 30 66 reset \, dimen 800 800 \, create \, lighting 1 \, 1;
+#X obj 30 212 rotateXYZ 30 20 0;
+#X obj 32 10 inlet;
+#X obj 32 37 sel 1 0;
+#X connect 0 0 3 0;
+#X connect 1 0 5 0;
+#X connect 4 0 3 0;
+#X connect 5 0 2 0;
+#X connect 6 0 7 0;
+#X connect 7 0 4 0;
+#X connect 7 1 0 0;
+#X restore 18 87 pd gem_stuff;
+#X obj 18 69 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1
+;
+#N canvas 0 22 804 395 creation 0;
+#X obj 42 28 bng 20 250 50 0 empty empty empty 0 -6 0 8 -258699 -1
+-1;
+#X msg 239 84 reset;
+#X obj 245 32 loadbang;
+#X text 68 30 reset;
+#X obj 167 55 t b b b b b;
+#X text 501 28 change number of mass to test performance;
+#X text 501 41 (and reset afterwards);
+#X obj 441 34 nbx 5 14 1 20000 1 1 empty empty empty 0 -6 0 10 -262144
+-1 -1 1681.79 256;
+#X msg 185 241 Xmax 4 \, Xmin -4 \, Ymax 4 \, Ymin -4;
+#X msg 167 215 setL sun 0;
+#X msg 221 107 mass fix 0 100 0 0;
+#X text 409 270 0.2 : rigidity \, 0 : damping \, -2 : power \, 0.4
+: Lmin;
+#X text 363 109 Sun;
+#X text 288 181 Initial speed;
+#N canvas 309 104 769 663 masses 0;
+#X obj 151 16 inlet;
+#X obj 232 28 inlet;
+#X obj 151 616 outlet;
+#X msg 151 551 mass mob 1 \$1 \$2 \$3;
+#X msg 151 307 seed 3;
+#X obj 151 519 pack f f f;
+#X obj 151 228 t b b b;
+#X msg 243 306 seed 20;
+#X msg 331 308 seed 10;
+#X obj 151 327 random 10000;
+#X obj 243 371 - 1;
+#X obj 331 370 - 1;
+#X obj 151 47 t b;
+#X obj 333 52 loadbang;
+#X text 263 277 X;
+#X text 166 276 M;
+#X text 372 278 Y;
+#X obj 151 67 until;
+#X obj 151 86 f;
+#X obj 177 87 + 1;
+#X obj 177 118 mod 1000;
+#X obj 206 87 sel 0;
+#X obj 243 327 random 1000;
+#X obj 331 328 random 1000;
+#X obj 243 348 / 50000;
+#X obj 331 349 / 50000;
+#X obj 151 349 / 250;
+#X obj 151 371 + 185;
+#X connect 0 0 12 0;
+#X connect 1 0 20 1;
+#X connect 3 0 2 0;
+#X connect 4 0 9 0;
+#X connect 5 0 3 0;
+#X connect 6 0 9 0;
+#X connect 6 1 22 0;
+#X connect 6 2 23 0;
+#X connect 7 0 22 0;
+#X connect 8 0 23 0;
+#X connect 9 0 26 0;
+#X connect 10 0 5 1;
+#X connect 11 0 5 2;
+#X connect 12 0 17 0;
+#X connect 13 0 7 0;
+#X connect 13 0 8 0;
+#X connect 13 0 4 0;
+#X connect 17 0 18 0;
+#X connect 18 0 19 0;
+#X connect 18 0 6 0;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 20 0 18 1;
+#X connect 21 0 17 1;
+#X connect 22 0 24 0;
+#X connect 23 0 25 0;
+#X connect 24 0 10 0;
+#X connect 25 0 11 0;
+#X connect 26 0 27 0;
+#X connect 27 0 5 0;
+#X restore 203 144 pd masses;
+#X text 410 289 The power of the link is -2 to simulate a gravity field
+in 1/R^2;
+#X text 292 146 Particules;
+#X msg 185 268 link sun fix mob 0.2 0 -2 0.4;
+#X msg 167 178 forceX mob 5.9;
+#X obj 167 310 s \$0-msdin;
+#X obj 166 25 inlet;
+#X connect 0 0 4 0;
+#X connect 1 0 19 0;
+#X connect 2 0 4 0;
+#X connect 4 0 9 0;
+#X connect 4 0 18 0;
+#X connect 4 1 8 0;
+#X connect 4 1 17 0;
+#X connect 4 2 14 0;
+#X connect 4 3 10 0;
+#X connect 4 4 1 0;
+#X connect 7 0 14 1;
+#X connect 8 0 19 0;
+#X connect 9 0 19 0;
+#X connect 10 0 19 0;
+#X connect 14 0 19 0;
+#X connect 17 0 19 0;
+#X connect 18 0 19 0;
+#X connect 20 0 4 0;
+#X restore 18 43 pd creation;
+#X text 116 58 gravity field simulation;
+#X text 115 72 if you have cpu problem \, you can reduce the mass number
+in "creation";
+#N canvas 0 22 450 300 compute 0;
+#X obj 52 182 msd2D --------------------------------;
+#X obj 52 64 t b;
+#X obj 52 41 gemhead;
+#X msg 197 123 forceX mob 0.051;
+#X msg 197 149 forceY mob 0.1;
+#X msg 52 98 bang \, bang \, get massesPos;
+#N canvas 637 205 609 594 massrender 0;
+#X obj 124 5 inlet;
+#X obj 291 245 translateXYZ;
+#X obj 291 186 gemhead;
+#X obj 291 219 separator;
+#X obj 292 63 unpack f f f;
+#X obj 57 257 translateXYZ;
+#X obj 57 198 gemhead;
+#X obj 57 231 separator;
+#X obj 123 31 route 0 1;
+#X obj 296 118 t b;
+#X obj 64 71 unpack f f;
+#X obj 57 151 t b f;
+#X obj 168 262 translateXYZ;
+#X obj 168 197 gemhead;
+#X obj 168 236 separator;
+#X obj 175 76 unpack f f;
+#X obj 168 154 t b f;
+#X obj 169 290 color 1 0 0;
+#X obj 292 319 square 0.015;
+#X obj 168 320 square 0.04;
+#X text 61 351 Sun;
+#X text 169 355 Red particule;
+#X text 307 355 Particule;
+#X obj 56 315 sphere 0.3 30;
+#X obj 57 289 color 0.3 0.3 0.3;
+#X obj 292 291 color 0.3 0.3 0.3;
+#X obj 9 49 loadbang;
+#X msg 9 80 0;
+#X connect 0 0 8 0;
+#X connect 1 0 25 0;
+#X connect 2 0 3 0;
+#X connect 3 0 1 0;
+#X connect 4 0 9 0;
+#X connect 4 1 1 1;
+#X connect 4 2 1 2;
+#X connect 5 0 24 0;
+#X connect 6 0 7 0;
+#X connect 7 0 5 0;
+#X connect 8 0 10 0;
+#X connect 8 1 15 0;
+#X connect 8 2 4 0;
+#X connect 9 0 2 0;
+#X connect 10 0 11 0;
+#X connect 10 1 5 2;
+#X connect 11 0 6 0;
+#X connect 11 1 5 1;
+#X connect 12 0 17 0;
+#X connect 13 0 14 0;
+#X connect 14 0 12 0;
+#X connect 15 0 16 0;
+#X connect 15 1 12 2;
+#X connect 16 0 13 0;
+#X connect 16 1 12 1;
+#X connect 17 0 19 0;
+#X connect 24 0 23 0;
+#X connect 25 0 18 0;
+#X connect 26 0 27 0;
+#X connect 27 0 2 0;
+#X connect 27 0 13 0;
+#X connect 27 0 6 0;
+#X restore 52 239 pd massrender;
+#X obj 52 212 route massesPos;
+#X obj 63 147 r \$0-msdin;
+#X connect 0 0 7 0;
+#X connect 1 0 5 0;
+#X connect 2 0 1 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X connect 7 0 6 0;
+#X connect 8 0 0 0;
+#X restore 18 107 pd compute;
+#X connect 0 0 4 0;
+#X connect 3 0 2 0;
diff --git a/msd/msd2D/07_sable.pd b/msd/msd2D/07_sable.pd
new file mode 100644
index 0000000..6dd44fe
--- /dev/null
+++ b/msd/msd2D/07_sable.pd
@@ -0,0 +1,505 @@
+#N canvas 649 116 636 696 10;
+#X obj 363 187 gemhead;
+#X obj 363 234 world_light;
+#X msg 364 141 \; pd dsp 1;
+#X msg 136 184 FSAA 4;
+#N canvas 451 61 454 540 toaster 0;
+#X obj 36 198 r T01;
+#N canvas 0 22 376 479 filtre 0;
+#X obj 59 42 inlet;
+#X obj 59 314 outlet;
+#X obj 59 247 +;
+#X obj 130 240 + 1;
+#X obj 130 42 inlet;
+#X obj 130 183 1;
+#X obj 130 160 /;
+#X obj 59 285 / 2;
+#X obj 59 223 * 1;
+#X msg 130 139 1 \$1;
+#X obj 142 92 loadbang;
+#X msg 141 117 1000;
+#X connect 0 0 8 0;
+#X connect 2 0 7 0;
+#X connect 3 0 7 1;
+#X connect 4 0 9 0;
+#X connect 5 0 3 0;
+#X connect 5 0 8 1;
+#X connect 6 0 5 0;
+#X connect 7 0 2 1;
+#X connect 7 0 1 0;
+#X connect 8 0 2 0;
+#X connect 9 0 6 0;
+#X connect 10 0 11 0;
+#X connect 11 0 9 0;
+#X restore 78 246 pd filtre;
+#X obj 33 226 t f f;
+#X obj 54 278 f;
+#X obj 51 255 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 32 399 outlet;
+#N canvas 0 22 376 479 filtre 0;
+#X obj 59 42 inlet;
+#X obj 59 314 outlet;
+#X obj 59 247 +;
+#X obj 130 240 + 1;
+#X obj 130 42 inlet;
+#X obj 130 183 1;
+#X obj 130 160 /;
+#X obj 59 285 / 2;
+#X obj 59 223 * 1;
+#X msg 130 139 1 \$1;
+#X obj 142 92 loadbang;
+#X msg 141 117 1000;
+#X connect 0 0 8 0;
+#X connect 2 0 7 0;
+#X connect 3 0 7 1;
+#X connect 4 0 9 0;
+#X connect 5 0 3 0;
+#X connect 5 0 8 1;
+#X connect 6 0 5 0;
+#X connect 7 0 2 1;
+#X connect 7 0 1 0;
+#X connect 8 0 2 0;
+#X connect 9 0 6 0;
+#X connect 10 0 11 0;
+#X connect 11 0 9 0;
+#X restore 243 256 pd filtre;
+#X obj 198 236 t f f;
+#X obj 219 288 f;
+#X obj 216 265 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 195 413 outlet;
+#X obj 201 208 r T02;
+#X floatatom 101 303 9 0 0 0 - - -;
+#X floatatom 260 322 9 0 0 0 - - -;
+#X obj 27 310 - 37286;
+#X obj 32 333 / 30;
+#X obj 195 342 / 30;
+#N canvas 0 22 376 479 filtre 0;
+#X obj 59 42 inlet;
+#X obj 59 314 outlet;
+#X obj 59 247 +;
+#X obj 130 240 + 1;
+#X obj 130 42 inlet;
+#X obj 130 183 1;
+#X obj 130 160 /;
+#X obj 59 285 / 2;
+#X obj 59 223 * 1;
+#X msg 130 139 1 \$1;
+#X obj 142 92 loadbang;
+#X msg 141 117 10;
+#X connect 0 0 8 0;
+#X connect 2 0 7 0;
+#X connect 3 0 7 1;
+#X connect 4 0 9 0;
+#X connect 5 0 3 0;
+#X connect 5 0 8 1;
+#X connect 6 0 5 0;
+#X connect 7 0 2 1;
+#X connect 7 0 1 0;
+#X connect 8 0 2 0;
+#X connect 9 0 6 0;
+#X connect 10 0 11 0;
+#X connect 11 0 9 0;
+#X restore 195 373 pd filtre;
+#N canvas 0 22 376 479 filtre 0;
+#X obj 59 42 inlet;
+#X obj 59 314 outlet;
+#X obj 59 247 +;
+#X obj 130 240 + 1;
+#X obj 130 42 inlet;
+#X obj 130 183 1;
+#X obj 130 160 /;
+#X obj 59 285 / 2;
+#X obj 59 223 * 1;
+#X msg 130 139 1 \$1;
+#X obj 142 92 loadbang;
+#X msg 141 117 10;
+#X connect 0 0 8 0;
+#X connect 2 0 7 0;
+#X connect 3 0 7 1;
+#X connect 4 0 9 0;
+#X connect 5 0 3 0;
+#X connect 5 0 8 1;
+#X connect 6 0 5 0;
+#X connect 7 0 2 1;
+#X connect 7 0 1 0;
+#X connect 8 0 2 0;
+#X connect 9 0 6 0;
+#X connect 10 0 11 0;
+#X connect 11 0 9 0;
+#X restore 31 362 pd filtre;
+#X obj 192 317 - 32797;
+#N canvas 0 22 450 300 receive 0;
+#X obj 17 103 send T01;
+#X obj 176 102 send T09;
+#X obj 195 134 send T10;
+#X obj 35 134 send T02;
+#X obj 56 166 send T03;
+#X obj 216 169 send T11;
+#X obj 236 201 send T12;
+#X obj 76 200 send T04;
+#X obj 96 103 send T05;
+#X obj 256 101 send T13;
+#X obj 274 135 send T14;
+#X obj 116 135 send T06;
+#X obj 296 168 send T15;
+#X obj 135 168 send T07;
+#X obj 316 201 send T16;
+#X obj 155 201 send T08;
+#X obj 17 20 dumpOSC 5679;
+#X obj 17 45 route /toaster;
+#X obj 17 70 unpack f f f f f f f f f f f f f f f f;
+#X obj 168 9 dumpOSC 5555;
+#X obj 166 40 route /toaster/sensors;
+#X obj 263 20 route /warhol/sensors;
+#X connect 16 0 17 0;
+#X connect 16 0 20 0;
+#X connect 17 0 18 0;
+#X connect 18 0 0 0;
+#X connect 18 1 3 0;
+#X connect 18 2 4 0;
+#X connect 18 3 7 0;
+#X connect 18 4 8 0;
+#X connect 18 5 11 0;
+#X connect 18 6 13 0;
+#X connect 18 7 15 0;
+#X connect 18 8 1 0;
+#X connect 18 9 2 0;
+#X connect 18 10 5 0;
+#X connect 18 11 6 0;
+#X connect 18 12 9 0;
+#X connect 18 13 10 0;
+#X connect 18 14 12 0;
+#X connect 18 15 14 0;
+#X connect 19 0 20 0;
+#X connect 19 0 17 0;
+#X connect 19 0 21 0;
+#X connect 20 0 18 0;
+#X connect 21 0 18 0;
+#X restore 56 48 pd receive;
+#X connect 0 0 2 0;
+#X connect 1 0 3 1;
+#X connect 2 0 14 0;
+#X connect 2 1 1 0;
+#X connect 3 0 12 0;
+#X connect 3 0 14 1;
+#X connect 4 0 3 0;
+#X connect 6 0 8 1;
+#X connect 7 0 19 0;
+#X connect 7 1 6 0;
+#X connect 8 0 13 0;
+#X connect 8 0 19 1;
+#X connect 9 0 8 0;
+#X connect 11 0 7 0;
+#X connect 14 0 15 0;
+#X connect 15 0 18 0;
+#X connect 16 0 17 0;
+#X connect 17 0 10 0;
+#X connect 18 0 5 0;
+#X connect 19 0 16 0;
+#X restore 306 474 pd toaster;
+#X obj 51 575 msd2D --------------------------------;
+#N canvas 1144 74 300 425 massrender 0;
+#X obj 112 80 inlet;
+#X obj 62 311 translateXYZ;
+#X obj 62 285 separator;
+#X obj 62 244 gemhead 45;
+#X obj 112 115 unpack s f f;
+#X obj 62 337 sphere 0.2 20;
+#X obj 109 156 t b b;
+#X obj 64 364 color;
+#X msg 207 229 1 1 1;
+#X obj 232 61 inlet;
+#X msg 231 255 1 0 0;
+#X obj 62 54 loadbang;
+#X msg 62 194 0;
+#X connect 0 0 4 0;
+#X connect 1 0 5 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X connect 4 0 6 0;
+#X connect 4 1 1 1;
+#X connect 4 2 1 2;
+#X connect 5 0 7 0;
+#X connect 6 0 8 0;
+#X connect 6 1 3 0;
+#X connect 8 0 7 1;
+#X connect 9 0 10 0;
+#X connect 10 0 7 1;
+#X connect 11 0 12 0;
+#X connect 12 0 3 0;
+#X restore 51 627 pd massrender;
+#X obj 51 350 gemhead;
+#X obj 212 397 gcanvas 80 80;
+#X obj 51 328 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X msg 51 373 get massesPos sable;
+#N canvas 754 153 608 476 creation 0;
+#X obj 198 405 t a;
+#X obj 196 30 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 207 72 reset;
+#X obj 128 28 loadbang;
+#X text 234 32 Reset;
+#X text 263 89 Random positions and masses;
+#N canvas 826 356 716 390 masses 0;
+#X msg 417 145 seed 1;
+#X msg 342 144 seed 2;
+#X obj 43 15 inlet;
+#X obj 238 362 outlet;
+#X obj 419 97 loadbang;
+#X obj 223 68 t b b;
+#X obj 43 78 f;
+#X obj 73 78 + 1;
+#X msg 43 41 0;
+#X msg 237 294 mass sable 1 1 \$1 \$2;
+#X obj 237 274 pack f f;
+#X obj 254 218 - 3;
+#X obj 336 223 - 3;
+#X obj 253 170 random 30;
+#X obj 339 172 random 30;
+#X obj 336 201 / 5;
+#X obj 254 196 / 5;
+#X obj 74 101 moses 32.5;
+#X connect 0 0 14 0;
+#X connect 1 0 13 0;
+#X connect 2 0 8 0;
+#X connect 4 0 1 0;
+#X connect 4 0 0 0;
+#X connect 5 0 13 0;
+#X connect 5 1 14 0;
+#X connect 6 0 7 0;
+#X connect 6 0 5 0;
+#X connect 7 0 17 0;
+#X connect 8 0 6 0;
+#X connect 9 0 3 0;
+#X connect 10 0 9 0;
+#X connect 11 0 10 0;
+#X connect 12 0 10 1;
+#X connect 13 0 16 0;
+#X connect 14 0 15 0;
+#X connect 15 0 12 0;
+#X connect 16 0 11 0;
+#X connect 17 0 6 0;
+#X restore 185 93 pd masses;
+#X obj 128 49 t b b b b;
+#X obj 40 149 t b b b b;
+#X msg 155 133 mass fixe 0 1 0 0;
+#X msg 138 176 tLink dampX fixe sable 0 0.001 0 1 1 0 1000;
+#X msg 131 198 tLink dampY fixe sable 0 0.001 1 0 1 0 1000;
+#X obj 197 434 outlet;
+#X obj 94 7 inlet;
+#X msg 36 375 Xmax 1111 \, Xmin -1111 \, Ymax 1111 \, Ymin -1111;
+#X msg 48 338 setL linkD 1000 \, setL linkG 1000 \, setL linkH 1000
+\, setL linkB 1000;
+#X msg 108 256 link linkD MlinkD sable 0.01 0 1 1000 100000;
+#X msg 103 276 link linkG MlinkG sable 0.01 0 1 1000 100000;
+#X msg 90 295 link linkH MlinkH sable 0.01 0 1 1000 100000;
+#X msg 78 315 link linkB MlinkB sable 0.01 0 1 1000 100000;
+#X msg 167 113 link rebond sable sable 0.003 0.005 1 0 0.4;
+#X msg 146 153 setL rebond 0.4;
+#X msg 120 221 mass MlinkD 0 1 -993.8 0 \, mass MlinkG 0 1 993.8 0
+\, mass MlinkH 0 1 0 996.2 \, mass MlinkB 0 1 0 -996.2;
+#X connect 0 0 12 0;
+#X connect 1 0 7 0;
+#X connect 2 0 0 0;
+#X connect 3 0 7 0;
+#X connect 6 0 0 0;
+#X connect 7 0 8 0;
+#X connect 7 0 21 0;
+#X connect 7 1 20 0;
+#X connect 7 1 9 0;
+#X connect 7 2 6 0;
+#X connect 7 3 2 0;
+#X connect 8 1 15 0;
+#X connect 8 2 16 0;
+#X connect 8 2 18 0;
+#X connect 8 2 19 0;
+#X connect 8 2 17 0;
+#X connect 8 3 10 0;
+#X connect 8 3 11 0;
+#X connect 8 3 22 0;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X connect 11 0 0 0;
+#X connect 13 0 7 0;
+#X connect 14 0 0 0;
+#X connect 15 0 0 0;
+#X connect 16 0 0 0;
+#X connect 17 0 0 0;
+#X connect 18 0 0 0;
+#X connect 19 0 0 0;
+#X connect 20 0 0 0;
+#X connect 21 0 0 0;
+#X connect 22 0 0 0;
+#X restore 68 494 pd creation;
+#X obj 89 515 bang~;
+#X msg 89 539 get massesForces;
+#N canvas 0 22 450 300 simulation_gravite 0;
+#X msg 28 224 forceX sable \$1;
+#X msg 142 224 forceY sable \$1;
+#X obj 29 60 min 80;
+#X obj 28 82 max 0;
+#X obj 28 107 - 40;
+#X obj 142 60 min 80;
+#X obj 141 82 max 0;
+#X obj 143 151 - 40;
+#X obj 142 102 * -1;
+#X obj 143 126 + 80;
+#X obj 48 132 bang~;
+#X obj 30 39 inlet;
+#X obj 140 38 inlet;
+#X obj 25 257 outlet;
+#X obj 125 179 f;
+#X obj 36 178 f;
+#X obj 31 201 / 2e+06;
+#X obj 145 200 / 2e+06;
+#X obj 291 45 inlet;
+#X obj 401 44 inlet;
+#X connect 0 0 13 0;
+#X connect 1 0 13 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 4 0 15 1;
+#X connect 5 0 6 0;
+#X connect 6 0 8 0;
+#X connect 7 0 14 1;
+#X connect 8 0 9 0;
+#X connect 9 0 7 0;
+#X connect 10 0 14 0;
+#X connect 10 0 15 0;
+#X connect 11 0 2 0;
+#X connect 12 0 5 0;
+#X connect 14 0 17 0;
+#X connect 15 0 16 0;
+#X connect 16 0 0 0;
+#X connect 17 0 1 0;
+#X connect 18 0 15 1;
+#X connect 19 0 14 1;
+#X restore 212 496 pd simulation_gravite;
+#X obj 68 475 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 65 417 metro 1;
+#X obj 65 396 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X msg 109 145 view 0 0 40 0 0 0 0 1 0;
+#X msg 119 165 perspec -0.1 0.1 -0.1 0.1 1 100;
+#X obj 116 119 b;
+#X obj 135 96 loadbang;
+#X obj 116 95 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 363 212 rotateXYZ -30 -20 0;
+#X obj 65 444 t b b;
+#X msg 209 242 destroy;
+#X obj 209 197 key;
+#X obj 209 218 sel 27;
+#X obj 364 67 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 364 90 s lb;
+#X obj 364 120 lb;
+#X obj 126 396 lb;
+#X msg 90 396 1;
+#X msg 88 61 dimen 1680 1050 \, cursor 0;
+#X text 390 475 <- sensors;
+#X text 321 450 <- sensors simulation;
+#X obj 52 282 gemwin 58;
+#X msg 51 13 dimen 672 420;
+#X msg 69 38 create \, lighting 1 \, 1;
+#N canvas 0 22 450 300 sound 0;
+#X obj 19 279 dac~;
+#X obj 202 220 *~ 1;
+#X obj 10 40 sound_sable 0 1;
+#X obj 268 191 sound_sable 28 29;
+#X obj 43 101 sound_sable 12 13;
+#X obj 20 61 sound_sable 4 5;
+#X obj 79 164 sound_sable 24 25;
+#X obj 33 80 sound_sable 8 9;
+#X obj 56 123 sound_sable 16 17;
+#X obj 66 144 sound_sable 20 21;
+#X obj 191 43 sound_sable 2 3;
+#X obj 201 64 sound_sable 6 7;
+#X obj 214 83 sound_sable 10 11;
+#X obj 224 104 sound_sable 14 15;
+#X obj 237 126 sound_sable 18 19;
+#X obj 247 148 sound_sable 22 23;
+#X obj 260 167 sound_sable 26 27;
+#X obj 277 212 sound_sable 30 31;
+#X obj 19 246 *~ 0.2;
+#X obj 13 11 inlet;
+#X connect 1 0 18 0;
+#X connect 2 0 18 0;
+#X connect 2 1 5 0;
+#X connect 3 0 1 0;
+#X connect 3 1 17 0;
+#X connect 4 0 18 0;
+#X connect 4 1 8 0;
+#X connect 5 0 18 0;
+#X connect 5 1 7 0;
+#X connect 6 0 18 0;
+#X connect 6 1 10 0;
+#X connect 7 0 18 0;
+#X connect 7 1 4 0;
+#X connect 8 0 18 0;
+#X connect 8 1 9 0;
+#X connect 9 0 18 0;
+#X connect 9 1 6 0;
+#X connect 10 0 1 0;
+#X connect 10 1 11 0;
+#X connect 11 0 1 0;
+#X connect 11 1 12 0;
+#X connect 12 0 1 0;
+#X connect 12 1 13 0;
+#X connect 13 0 1 0;
+#X connect 13 1 14 0;
+#X connect 14 0 1 0;
+#X connect 14 1 15 0;
+#X connect 15 0 1 0;
+#X connect 15 1 16 0;
+#X connect 16 0 1 0;
+#X connect 16 1 3 0;
+#X connect 17 0 1 0;
+#X connect 18 0 0 0;
+#X connect 18 0 0 1;
+#X connect 19 0 2 0;
+#X restore 153 626 pd sound;
+#X obj 51 596 route massesPosId massesForces;
+#X connect 0 0 23 0;
+#X connect 3 0 36 0;
+#X connect 4 0 14 2;
+#X connect 4 1 14 3;
+#X connect 5 0 40 0;
+#X connect 7 0 10 0;
+#X connect 8 0 14 0;
+#X connect 8 1 14 1;
+#X connect 9 0 7 0;
+#X connect 10 0 5 0;
+#X connect 11 0 5 0;
+#X connect 12 0 13 0;
+#X connect 13 0 5 0;
+#X connect 14 0 5 0;
+#X connect 15 0 11 0;
+#X connect 16 0 24 0;
+#X connect 17 0 16 0;
+#X connect 18 0 36 0;
+#X connect 19 0 36 0;
+#X connect 20 0 18 0;
+#X connect 20 0 19 0;
+#X connect 20 0 3 0;
+#X connect 21 0 20 0;
+#X connect 22 0 20 0;
+#X connect 23 0 1 0;
+#X connect 24 0 5 0;
+#X connect 24 1 6 1;
+#X connect 25 0 36 0;
+#X connect 26 0 27 0;
+#X connect 27 0 25 0;
+#X connect 28 0 29 0;
+#X connect 30 0 2 0;
+#X connect 31 0 32 0;
+#X connect 32 0 17 0;
+#X connect 33 0 36 0;
+#X connect 37 0 36 0;
+#X connect 38 0 36 0;
+#X connect 40 0 6 0;
+#X connect 40 1 39 0;
diff --git a/msd/msd2D/Makefile.am b/msd/msd2D/Makefile.am
new file mode 100644
index 0000000..59a3dff
--- /dev/null
+++ b/msd/msd2D/Makefile.am
@@ -0,0 +1,51 @@
+#
+# automake template
+# added by tim blechmann
+#
+
+NAME = msd2
+
+BUILT_SOURCES = main.cpp
+
+EXTRA_DIST = main.cpp \
+ $(NAME).mcp \
+ $(NAME).vcproj
+
+CXXFLAGS = @CXXFLAGS@ \
+ @OPT_FLAGS@ \
+ @INCLUDEDIR@ \
+ -I../../source \
+ $(DEFS) \
+ -DFLEXT_SHARED
+
+LDFLAGS = @DYNAMIC_LDFLAGS@ @LDFLAGS@ \
+ $(patsubst %,-framework %,$(FRAMEWORKS))
+
+LIBS = @LIBS@ -lflext-pd
+
+FRAMEWORKS = @FRAMEWORKS@
+
+TARGETDIR = @TARGETDIR@
+
+TARGET =$(NAME).@EXTENSION@
+
+OBJECTS = $(patsubst %.cpp,./%.@OBJEXT@,$(BUILT_SOURCES))
+
+SYSDIR = @SYSDIR@
+
+
+# ----------------------------- targets --------------------------------
+
+all-local: $(OBJECTS)
+ $(CXX) $(LDFLAGS) ./*.@OBJEXT@ $(LIBS) -o ../$(TARGETDIR)/$(TARGET)
+ strip --strip-unneeded ../$(TARGETDIR)/$(TARGET)
+
+./%.@OBJEXT@ : %.cpp
+ $(CXX) -c $(CXXFLAGS) $< -o $@
+
+clean-local:
+ rm -f ../$(TARGETDIR)/$(TARGET)
+ rm -f ./$(OBJECTS)
+
+install-exec-local:
+ install ../$(TARGET) $(SYSDIR)extra
diff --git a/msd/msd2D/editor/MOVED b/msd/msd2D/editor/MOVED
new file mode 100644
index 0000000..f7d2e2f
--- /dev/null
+++ b/msd/msd2D/editor/MOVED
@@ -0,0 +1 @@
+msd-editor has moved to /externals/nusmuk/editor.
diff --git a/msd/msd2D/lb.pd b/msd/msd2D/lb.pd
new file mode 100644
index 0000000..1433464
--- /dev/null
+++ b/msd/msd2D/lb.pd
@@ -0,0 +1,13 @@
+#N canvas 0 0 450 300 10;
+#X obj 18 86 loadbang;
+#X obj 18 63 universal;
+#X msg 18 41 loadbang loadbang;
+#X obj 18 17 inlet;
+#X obj 18 108 outlet;
+#X obj 104 84 r lb;
+#X obj 104 105 t b;
+#X connect 0 0 4 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X connect 5 0 6 0;
+#X connect 6 0 4 0;
diff --git a/msd/msd2D/license.txt b/msd/msd2D/license.txt
new file mode 100644
index 0000000..b1e3f5a
--- /dev/null
+++ b/msd/msd2D/license.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; 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.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/msd/msd2D/main.cpp b/msd/msd2D/main.cpp
new file mode 100644
index 0000000..46eb6c8
--- /dev/null
+++ b/msd/msd2D/main.cpp
@@ -0,0 +1,3 @@
+#include "../src/msd.h"
+
+MSD("msd2D",msd2D,2)
diff --git a/msd/msd2D/make_anim.pd b/msd/msd2D/make_anim.pd
new file mode 100644
index 0000000..c29fc3f
--- /dev/null
+++ b/msd/msd2D/make_anim.pd
@@ -0,0 +1,204 @@
+#N struct mass float x float y float mid float mob;
+#N struct fixmass float x float y float mid;
+#N canvas 445 254 669 506 10;
+#X obj 352 260 pointer;
+#X obj 86 83 spigot;
+#X obj 400 20 bng 15 250 50 0 \$0-create empty Create 22 6 0 10 -258113
+-1 -1;
+#X obj 316 76 r \$0-create;
+#X obj 123 50 r \$0-listen;
+#X obj 533 184 s \$0-listen;
+#X msg 533 159 1;
+#X obj 316 98 t b b b b b;
+#X obj 199 217 s \$0-listen;
+#X msg 199 191 0;
+#N canvas 0 22 870 770 \$0-anim 0;
+#X scalar mass 501.859 143.462 2 0 \;;
+#X scalar mass 385.528 207.845 3 0 \;;
+#X scalar mass 563.885 96.7994 4 0 \;;
+#X scalar mass 436.681 183.23 5 0 \;;
+#X scalar mass 677.97 25.7242 6 0 \;;
+#X scalar mass 635.854 51.7641 7 0 \;;
+#X scalar fixmass 287 68 0 \;;
+#X scalar fixmass 56 223 1 \;;
+#X restore 220 25 pd \$0-anim;
+#X obj 446 329 makefilename pd-%s;
+#X obj 446 283 loadbang;
+#X msg 446 261 bang;
+#X obj 446 353 s \$0-cnv;
+#X obj 400 137 symbol;
+#X obj 407 98 r \$0-cnv;
+#X obj 352 137 symbol;
+#X msg 352 228 traverse \$1 \, bang;
+#X obj 86 27 inlet;
+#X obj 400 35 tgl 15 0 empty empty poll 22 6 0 10 -262144 -1 -1 1 1
+;
+#X msg 400 160 \; \$1 clear \;;
+#X obj 464 376 r \$0-cnv;
+#X obj 413 403 pack 0 s;
+#X msg 413 434 \; \$2 vis \$1;
+#X obj 59 376 metro 40;
+#X obj 59 401 s \$0-create;
+#X obj 284 221 outlet;
+#X obj 446 305 symbol \$1;
+#N canvas 683 281 568 586 make_link 0;
+#X obj 165 35 inlet;
+#X obj 367 438 inlet;
+#X obj 236 135 s \$0-mass2;
+#X obj 334 305 r \$0-mass2;
+#X obj 293 283 r \$0-mass1;
+#X obj 203 159 s \$0-mass1;
+#N canvas 0 22 591 644 look4mass2 0;
+#X msg 228 199 next;
+#X obj 228 463 spigot;
+#X obj 228 386 pack 0 0;
+#X obj 228 508 unpack 0 0;
+#X obj 295 411 r \$0-mass2;
+#X obj 228 562 outlet;
+#X obj 293 564 outlet;
+#X obj 228 68 inlet;
+#X obj 228 90 t b b;
+#X obj 437 327 select 0;
+#X obj 137 319 get mass x y mid;
+#X obj 281 317 get fixmass x y mid;
+#X obj 265 437 == -1;
+#X obj 367 247 print lookmass1;
+#X msg 404 136 traverse pd-data \, next;
+#X obj 228 229 pointer;
+#X connect 0 0 15 0;
+#X connect 1 0 3 0;
+#X connect 2 0 1 0;
+#X connect 3 0 5 0;
+#X connect 3 1 6 0;
+#X connect 4 0 12 1;
+#X connect 7 0 8 0;
+#X connect 8 0 0 0;
+#X connect 8 1 14 0;
+#X connect 9 0 0 0;
+#X connect 10 0 2 0;
+#X connect 10 1 2 1;
+#X connect 10 2 12 0;
+#X connect 11 0 2 0;
+#X connect 11 1 2 1;
+#X connect 11 2 12 0;
+#X connect 12 0 1 1;
+#X connect 12 0 9 0;
+#X connect 14 0 15 0;
+#X connect 15 0 10 0;
+#X connect 15 0 11 0;
+#X connect 15 1 13 0;
+#X restore 184 267 pd look4mass2;
+#X obj 165 67 t b b a a;
+#X msg 203 113 \$3;
+#X msg 236 113 \$4;
+#N canvas 0 22 591 644 look4mass1 0;
+#X msg 228 199 next;
+#X obj 228 463 spigot;
+#X obj 228 386 pack 0 0;
+#X obj 228 508 unpack 0 0;
+#X obj 228 562 outlet;
+#X obj 293 564 outlet;
+#X obj 228 68 inlet;
+#X obj 228 90 t b b;
+#X obj 437 327 select 0;
+#X obj 228 229 pointer mass fixmass;
+#X obj 137 319 get mass x y mid;
+#X obj 281 317 get fixmass x y mid;
+#X obj 295 384 r \$0-mass1;
+#X obj 265 437 == -1;
+#X msg 404 136 traverse pd-data \, bang;
+#X connect 0 0 9 0;
+#X connect 1 0 3 0;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 3 1 5 0;
+#X connect 6 0 7 0;
+#X connect 7 0 0 0;
+#X connect 7 1 14 0;
+#X connect 8 0 0 0;
+#X connect 9 0 10 0;
+#X connect 9 1 11 0;
+#X connect 10 0 2 0;
+#X connect 10 1 2 1;
+#X connect 10 2 13 0;
+#X connect 11 0 2 0;
+#X connect 11 1 2 1;
+#X connect 11 2 13 0;
+#X connect 12 0 13 1;
+#X connect 13 0 1 1;
+#X connect 13 0 8 0;
+#X connect 14 0 9 0;
+#X restore 160 241 pd look4mass1;
+#X obj 121 463 append liaison x1 y1 x2 y2 mid1 mid2;
+#X obj 159 358 pack 0 0 0 0 0 0;
+#X obj 167 417 print linklist;
+#X connect 0 0 7 0;
+#X connect 1 0 11 6;
+#X connect 3 0 12 5;
+#X connect 4 0 12 4;
+#X connect 6 0 12 2;
+#X connect 6 1 12 3;
+#X connect 7 0 10 0;
+#X connect 7 1 6 0;
+#X connect 7 2 8 0;
+#X connect 7 3 9 0;
+#X connect 8 0 5 0;
+#X connect 9 0 2 0;
+#X connect 10 0 12 0;
+#X connect 10 1 12 1;
+#X connect 12 0 11 0;
+#X connect 12 0 13 0;
+#X restore 273 411 pd make_link;
+#X text 216 384 LATER:;
+#X obj 86 113 route Mass linksPos;
+#X msg 284 198 infosL \, get linksPos;
+#X obj 192 345 append liaison x1 y1 x2 y2;
+#X msg 195 325 \$2 \$3 \$4 \$5;
+#X obj 141 257 append mass mid x y;
+#X msg 141 168 \$1 \$5 \$6;
+#X obj 86 142 t a a;
+#X msg 62 166 \$3;
+#X obj 62 283 set mass mob;
+#X obj 62 229 * 0;
+#X obj 400 50 tgl 15 0 empty empty view 22 6 0 10 -262144 -1 -1 0 1
+;
+#X connect 0 0 29 1;
+#X connect 0 0 33 4;
+#X connect 0 0 35 3;
+#X connect 1 0 31 0;
+#X connect 3 0 7 0;
+#X connect 4 0 1 1;
+#X connect 6 0 5 0;
+#X connect 7 0 9 0;
+#X connect 7 1 32 0;
+#X connect 7 2 17 0;
+#X connect 7 3 15 0;
+#X connect 7 4 6 0;
+#X connect 7 4 13 0;
+#X connect 9 0 8 0;
+#X connect 11 0 14 0;
+#X connect 12 0 28 0;
+#X connect 13 0 28 0;
+#X connect 15 0 21 0;
+#X connect 16 0 15 1;
+#X connect 16 0 17 1;
+#X connect 17 0 18 0;
+#X connect 18 0 0 0;
+#X connect 19 0 1 0;
+#X connect 20 0 25 0;
+#X connect 22 0 23 1;
+#X connect 23 0 24 0;
+#X connect 25 0 26 0;
+#X connect 28 0 11 0;
+#X connect 31 0 37 0;
+#X connect 31 1 34 0;
+#X connect 32 0 27 0;
+#X connect 34 0 33 0;
+#X connect 35 0 39 1;
+#X connect 36 0 35 0;
+#X connect 37 0 38 0;
+#X connect 37 1 36 0;
+#X connect 38 0 40 0;
+#X connect 40 0 39 0;
+#X connect 41 0 23 0;
+#X coords 0 -1 1 1 120 65 1 400 0;
diff --git a/msd/msd2D/msd2D-help.pd b/msd/msd2D/msd2D-help.pd
new file mode 100644
index 0000000..9433767
--- /dev/null
+++ b/msd/msd2D/msd2D-help.pd
@@ -0,0 +1,582 @@
+#N canvas 335 73 553 632 10;
+#X obj 4 369 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 723 cnv 15 550 30 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 8 6 cnv 15 550 30 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 14 389 cnv 15 75 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 14 584 cnv 15 75 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 527 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 4 562 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 7 76 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 673 cnv 15 550 20 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 693 cnv 15 550 30 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#N canvas 76 31 921 714 More_Info 0;
+#X text 96 12 MSD : mass - spring - damper model;
+#X text 27 155 Be careful : if masses are deleted \, lists messages
+won't work;
+#X text 27 60 It is designed to implement particules physical model
+in PD.The model is based on two elements type : mass and link. The
+msd masses are the principals objects of the model. They got only one
+physical parameter \, the value of their mass. They can be mobile or
+fixed \, in this case forces applied on them automatically \, by links
+\, or manually \, by messages \, don't do anything.;
+#X obj 456 -5 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 456 294 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity1 4 float 1;
+#A 0 -1 0 1 2;
+#X array zero 4 float 1;
+#A 0 0 0 0 0;
+#X coords 0 3 3 -3 200 150 1;
+#X restore 121 328 graph;
+#X text 179 485 L0;
+#N canvas 438 87 956 727 figure 0;
+#X obj 284 53 loadbang;
+#X msg 293 125 \; rigidity1 resize 1 \; rigidity1 resize 4 \; rigidity1
+bounds 0 3 3 -3 \; rigidity1 0 -1 0 1 2 \; rigidity1 ylabel -0.5 \;
+rigidity1 xlabel -3.5 \; rigidity1 xticks 0 1 1 \; rigidity1 yticks
+0 0.1 5;
+#X obj 388 574 sqrt;
+#X obj 316 651 tabwrite rigidity3;
+#X obj 343 464 - 20;
+#X obj 316 609 f;
+#X obj 316 579 t b f;
+#X obj 343 494 moses 0;
+#X obj 343 517 * -1;
+#X obj 343 538 sqrt;
+#X obj 343 559 * -1;
+#X obj 481 479 - 20;
+#X obj 453 662 f;
+#X obj 453 632 t b f;
+#X obj 481 509 moses 0;
+#X obj 481 532 * -1;
+#X obj 480 612 * -1;
+#X obj 528 622 *;
+#X obj 480 591 *;
+#X obj 525 590 t f f;
+#X obj 480 564 t f f;
+#X obj 453 683 tabwrite rigidity4;
+#X obj 181 235 t b b;
+#X obj 620 552 f;
+#X obj 620 522 t b f;
+#X obj 620 623 tabwrite rigidity2;
+#X msg 763 574 0;
+#X obj 679 437 - 50;
+#X obj 751 491 moses 40;
+#X obj 681 510 moses -40;
+#X obj 620 586 * 1.5;
+#X obj 680 462 moses 10;
+#X obj 680 488 moses -10;
+#X msg 55 419 \; rigidity2 resize 101 \; rigidity2 xticks 1 10 5 \;
+rigidity2 yticks 0 5 5 \; rigidity3 resize 51 \; rigidity3 xticks 0
+1 5 \; rigidity3 yticks 0 1 5 \; rigidity4 resize 51 \; rigidity4 xticks
+0 1 5 \; rigidity4 yticks 0 100 5;
+#X obj 631 315 f;
+#X obj 648 394 + 1;
+#X obj 632 367 t f f;
+#X obj 375 333 f;
+#X obj 375 360 moses 50.5;
+#X obj 392 411 + 1;
+#X obj 376 384 t f f;
+#X obj 176 141 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X msg 371 310 0;
+#X msg 627 286 0;
+#X obj 631 343 moses 100.5;
+#X connect 0 0 1 0;
+#X connect 0 0 22 0;
+#X connect 2 0 5 1;
+#X connect 4 0 7 0;
+#X connect 5 0 3 0;
+#X connect 6 0 5 0;
+#X connect 6 1 3 1;
+#X connect 7 0 8 0;
+#X connect 7 1 2 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 5 1;
+#X connect 11 0 14 0;
+#X connect 12 0 21 0;
+#X connect 13 0 12 0;
+#X connect 13 1 21 1;
+#X connect 14 0 15 0;
+#X connect 14 1 19 0;
+#X connect 15 0 20 0;
+#X connect 16 0 12 1;
+#X connect 17 0 12 1;
+#X connect 18 0 16 0;
+#X connect 19 0 17 0;
+#X connect 19 1 17 1;
+#X connect 20 0 18 0;
+#X connect 20 1 18 1;
+#X connect 22 0 42 0;
+#X connect 22 1 33 0;
+#X connect 22 1 43 0;
+#X connect 23 0 30 0;
+#X connect 24 0 23 0;
+#X connect 24 1 25 1;
+#X connect 26 0 23 1;
+#X connect 27 0 31 0;
+#X connect 28 0 23 1;
+#X connect 28 1 26 0;
+#X connect 29 0 26 0;
+#X connect 29 1 23 1;
+#X connect 30 0 25 0;
+#X connect 31 0 32 0;
+#X connect 31 1 28 0;
+#X connect 32 0 29 0;
+#X connect 32 1 26 0;
+#X connect 34 0 44 0;
+#X connect 35 0 34 0;
+#X connect 36 0 35 0;
+#X connect 36 1 27 0;
+#X connect 36 1 24 0;
+#X connect 37 0 38 0;
+#X connect 38 0 40 0;
+#X connect 39 0 37 0;
+#X connect 40 0 39 0;
+#X connect 40 1 4 0;
+#X connect 40 1 6 0;
+#X connect 40 1 13 0;
+#X connect 40 1 11 0;
+#X connect 41 0 22 0;
+#X connect 42 0 37 0;
+#X connect 43 0 34 0;
+#X connect 44 0 36 0;
+#X restore 403 659 pd figure;
+#X text 125 307 Rigidity;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity2 101 float 1;
+#A 0 0 0 0 0 0 0 0 0 0 0 -60 -58.5 -57 -55.5 -54 -52.5 -51 -49.5 -48
+-46.5 -45 -43.5 -42 -40.5 -39 -37.5 -36 -34.5 -33 -31.5 -30 -28.5 -27
+-25.5 -24 -22.5 -21 -19.5 -18 -16.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 15 16.5 18 19.5 21 22.5 24 25.5 27 28.5 30 31.5 33 34.5 36
+37.5 39 40.5 42 43.5 45 46.5 48 49.5 51 52.5 54 55.5 57 58.5 0 0 0
+0 0 0 0 0 0 0 0;
+#X array zero 101 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
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 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 60 100 -60 200 150 1;
+#X restore 565 327 graph;
+#X text 657 482 L0;
+#X text 569 304 Rigidity with Lmin and Lmax;
+#X text 673 482 Lmin;
+#X text 735 481 Lmax;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity3 51 float 1;
+#A 0 -4.47214 -4.3589 -4.24264 -4.12311 -4 -3.87298 -3.74166 -3.60555
+-3.4641 -3.31662 -3.16228 -3 -2.82843 -2.64575 -2.44949 -2.23607 -2
+-1.73205 -1.41421 -1 0 1 1.41421 1.73205 2 2.23607 2.44949 2.64575
+2.82843 3 3.16228 3.31662 3.4641 3.60555 3.74166 3.87298 4 4.12311
+4.24264 4.3589 4.47214 4.58258 4.69042 4.79583 4.89898 5 5.09902 5.19615
+5.2915 5.38516 5.47723;
+#X array zero 51 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
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
+#X coords 0 6 50 -6 200 150 1;
+#X restore 119 526 graph;
+#X text 192 679 L0;
+#X text 126 505 Rigidity with power = 1/2;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity4 51 float 1;
+#A 0 0 -400 -361 -324 -289 -256 -225 -196 -169 -144 -121 -100 -81 -64
+-49 -36 -25 -16 -9 -4 -1 0 1 4 9 16 25 36 49 64 81 100 121 144 169
+196 225 256 289 324 361 400 441 484 529 576 625 676 729 784 841;
+#X array zero 51 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
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
+#X coords 0 1000 50 -1000 200 150 1;
+#X restore 566 530 graph;
+#X text 639 684 L0;
+#X text 571 508 Rigidity with power = 2;
+#X text 571 12 The equations are :;
+#X text 497 36 if Lmin<|L[n]-L[0]|<Lmax;
+#X text 496 75 else;
+#X text 496 95 F[n] = D(L[n]-L[n-1]);
+#X text 496 54 F[n] = K(L[n] - L[0])^P + D(L[n] - L[n-1]);
+#X text 28 187 Links connect masses two by two. They got 4 physicals
+parameters : length \, rigidity \, damping and power.;
+#X text 27 216 Rigidity \, damping and power are defined by the creation
+message. The lenght is initialised to the distance between the two
+masses at the creation.;
+#X text 495 124 For oriented links \, the force F[n] is projected onto
+a vector which is given during the creation of the link using x1y1
+coordinates.;
+#X text 495 169 For normal vector \, the direction is calculated using
+the scalar product :;
+#X text 495 248 You can build specific links using different links
+messages defining the characteristic step by step.;
+#X text 496 206 x1x2 + y1y2 = 0;
+#X text 27 257 Links can be created in one shot between mutiples masses
+\, instead of creation number \, the masses linked are defined with
+their Id.;
+#X text 28 41 MSD is the 2D object of the msd objects collection.;
+#X connect 3 0 4 0;
+#X restore 16 731 pd More_Info;
+#X text 12 76 Examples:;
+#X text 9 369 Inlets:;
+#X text 19 388 - Left:;
+#X text 10 526 Arguments:;
+#X text 11 562 Outlets:;
+#X text 19 675 See Also:;
+#X text 74 48 Full Name:;
+#N canvas 58 22 262 70 Related_Objects 0;
+#X obj 3 10 cnv 15 250 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 3 30 cnv 15 250 30 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X text 5 10 Externals and libraries;
+#X obj 141 38 msd3D;
+#X obj 44 37 msd;
+#X restore 122 731 pd Related_Objects;
+#N canvas 257 262 759 345 init 0;
+#X obj 89 215 t a;
+#X obj 89 33 loadbang;
+#X obj 89 241 s \$0-in;
+#X obj 89 59 t b b b b b;
+#X msg 161 80 reset;
+#X obj 44 13 inlet;
+#X msg 143 100 mass fix 0 10 0 0;
+#X msg 89 187 Xmax 4 \, Xmin -4 \, Ymax 4 \, Ymin -4;
+#X msg 125 120 mass mob 1 100 0 -2 \, mass mob 1 100 2 0 \, mass mob
+1 100 0 2 \, mass mob 1 100 -2 0;
+#X msg 107 161 link souple fix mob 10 10 \, link souple mob mob 10
+10;
+#X connect 0 0 2 0;
+#X connect 1 0 3 0;
+#X connect 3 0 7 0;
+#X connect 3 1 9 0;
+#X connect 3 2 8 0;
+#X connect 3 3 6 0;
+#X connect 3 4 4 0;
+#X connect 4 0 0 0;
+#X connect 5 0 3 0;
+#X connect 6 0 0 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 0;
+#X connect 9 0 0 0;
+#X restore 17 156 pd init;
+#X obj 18 321 s \$0-out;
+#X obj 18 272 r \$0-in;
+#X obj 393 317 s \$0-in;
+#N canvas 565 515 355 193 compute 0;
+#X obj 27 29 inlet;
+#X obj 27 127 s \$0-in;
+#X msg 27 96 bang \, get massesPos \, get linksPos;
+#X obj 27 66 gemhead;
+#X obj 160 36 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X connect 0 0 3 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X connect 4 0 2 0;
+#X restore 17 209 pd compute;
+#X obj 17 181 tgl 15 0 empty empty ON/OFF 25 10 1 10 -262144 -1 -1
+0 1;
+#X obj 172 270 r \$0-out;
+#X obj 17 126 bng 15 250 50 0 empty empty reset 25 10 1 10 -262144
+-1 -1;
+#X text 101 388 Bang - A bang at the left inlet compute the new model
+state based on previous instant.;
+#X text 158 478 To set the model parameters after creation.;
+#X text 158 456 To create the model masses and links.;
+#X text 158 501 To get the model parameters;
+#N canvas 8 28 967 626 creation________ 0;
+#X obj 5 75 cnv 15 450 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 3 cnv 15 450 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X text 7 2 CREATION Messages;
+#X obj 4 137 cnv 15 450 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 3 351 cnv 15 450 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X msg 32 104 reset;
+#X text 202 167 Add a mass;
+#X text 57 191 \$1 : Id (symbol);
+#X text 57 211 \$2 : fixed or mobile (0/1);
+#X text 57 229 \$3 : mass;
+#X msg 32 286 deleteMass \$1;
+#X text 194 288 Delete a mass and associated links;
+#X text 54 309 \$1 : Creation No of mass;
+#X text 7 137 Masses :;
+#X text 7 74 Reset :;
+#X text 129 105 Delete all masses \, links and internal variables;
+#X text 6 351 Links :;
+#X text 49 406 \$1 : Id (symbol);
+#X text 49 459 \$4 : rigidity;
+#X msg 30 555 deleteLink \$1;
+#X text 166 557 Delete a link;
+#X text 47 578 \$1 : Creation No of link;
+#X text 49 406 \$1 : Id (symbol);
+#X text 49 459 \$4 : rigidity;
+#X text 49 424 \$2 : creation No/Id of mass1;
+#X text 49 442 \$3 : creation No/Id of mass2;
+#X text 266 384 Add link(s);
+#X text 49 477 \$5 : damping;
+#X text 10 28 Creation messages are used to define the structure of
+the model. Messages create links and masses or destroy them.;
+#X msg 30 384 link \$1 \$2 \$3 \$4 \$5 (\$6 \$7 \$8);
+#X msg 32 167 mass \$1 \$2 \$3 \$4 \$5;
+#X text 57 247 \$4 \, \$5 : initial position;
+#X text 46 495 (\$6) : Power of the rigidity distance;
+#X text 46 514 (\$7) : minimum lenght of link;
+#X text 46 531 (\$8) : maximum lenght of link;
+#X obj 471 75 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 501 75 cnv 15 450 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 471 578 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 527 180 \$1 : Id (symbol);
+#X text 527 233 \$4 : rigidity;
+#X text 527 180 \$1 : Id (symbol);
+#X text 527 233 \$4 : rigidity;
+#X text 527 198 \$2 : creation No/Id of mass1;
+#X text 527 216 \$3 : creation No/Id of mass2;
+#X text 527 251 \$5 : damping;
+#X text 790 152 Add tangential link(s);
+#X text 524 289 (\$8) : Power of the rigidity distance;
+#X text 524 308 (\$9) : minimum lenght of link;
+#X text 524 325 (\$10) : maximum lenght of link;
+#X msg 508 153 tLink \$1 \$2 \$3 \$4 \$5 \$6 \$7 (\$8 \$9 \$10);
+#X text 504 75 Oriented links :;
+#X text 506 102 In 2D (and 3D) there are two specials links : oriented
+links. They works as general links excepts their calculation is made
+following a vector.;
+#X text 526 270 \$6 \, \$7 : tangential vector (x \, y);
+#X connect 35 0 37 0;
+#X restore 12 457 pd creation________;
+#X text 103 542 None;
+#X text 18 583 - Left:;
+#X text 101 584 Outputs the model parameters asked with the attributes
+messages.;
+#X obj 13 629 cnv 15 75 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X text 17 628 - Right:;
+#X text 100 629 Outputs information on model when creation messages
+are send or with the special message [infosL( which dump the complete
+state of the model.;
+#X text 101 420 Messages - Different messages are used to control the
+msd object. They are of three types :;
+#X text 9 697 CATEGORY: control;
+#N canvas 354 125 558 582 dynamic 0;
+#X obj 5 3 cnv 15 550 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 10 85 cnv 15 150 270 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 62 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 10 402 cnv 15 130 180 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 3 378 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X text 7 62 Masses :;
+#X text 6 378 Links :;
+#X text 7 2 DYNAMIC SETTINGS Messages;
+#X msg 31 96 posX \$1 \$2;
+#X text 190 144 Add force on mass(es);
+#X msg 30 143 forceX \$1 \$2;
+#X text 192 216 \$1 : Value;
+#X text 193 107 \$1 : Id (symbol) or No;
+#X text 193 161 \$1 : Id (symbol) or No;
+#X msg 30 195 Xmin \$1;
+#X msg 89 195 Xmax \$1;
+#X msg 29 244 setMobile \$1;
+#X msg 29 265 setFixed \$1;
+#X text 193 89 Set position of fixed mass(es);
+#X text 193 125 \$2 : Value;
+#X text 193 179 \$2 : Value;
+#X text 189 200 Set minimimum and maximum position of all masses;
+#X text 188 244 Set mass to mobile or fixed;
+#X msg 29 466 setD \$1 \$2;
+#X text 184 452 \$2 : New value;
+#X msg 29 415 setK \$1 \$2;
+#X text 184 508 \$2 : New value;
+#X text 184 561 \$2 : New value;
+#X text 178 416 Set rigidity of link(s);
+#X text 178 472 Set damping of link(s);
+#X msg 29 521 setL \$1 \$2;
+#X text 178 525 Set initial lenght of link(s);
+#X text 184 434 \$1 : Id (symbol) or No;
+#X text 184 490 \$1 : Id (symbol) or No;
+#X text 184 543 \$1 : Id (symbol) or No;
+#X text 191 261 \$1 : Id (symbol) or No;
+#X text 10 25 Dynamic settings messages allows the user to redefine
+internal parameters of links and masses.;
+#X msg 29 301 grabMass \$1 \$2 \$3;
+#X text 186 301 Grab nearest mass;
+#X text 191 317 \$1 \, \$2 : position;
+#X text 190 334 \$3 : grab or not (0/1);
+#X msg 31 117 posY \$1 \$2;
+#X msg 30 164 forceY \$1 \$2;
+#X msg 30 217 Ymin \$1;
+#X msg 89 217 Ymax \$1;
+#X restore 12 478 pd dynamic settings;
+#N canvas 382 95 601 681 attributes______ 0;
+#X obj 11 95 cnv 15 100 35 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 5 75 cnv 15 590 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 3 cnv 15 590 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 10 158 cnv 15 150 110 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 137 cnv 15 590 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 9 305 cnv 15 110 330 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 3 281 cnv 15 590 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X text 7 74 General :;
+#X text 7 2 ATTRIBUTES Messages;
+#X text 7 137 Lists :;
+#X msg 33 104 infosL;
+#X text 136 104 Get infos on all masses and links on right outlet;
+#X msg 32 170 massesPosL;
+#X msg 32 239 massesForcesL;
+#X text 170 170 Output all masses positions in a list on outlet No
+1;
+#X text 139 321 Get specific attribute on specific element;
+#X msg 19 319 get \$1 (\$2);
+#X text 6 281 Specific :;
+#X text 139 416 The get message return the asked attribute preceded
+by an identifier and the creation No of the element. The identifier
+is made of the asked parameter and the way you asked for it.;
+#X text 140 492 message;
+#X text 380 492 response;
+#X text 139 473 Examples with 3 masses numbered 0 \, 1 and 2 and named
+mas:;
+#X text 15 30 The attributes messages ask the object to output some
+of his internal parameters. They can be output by lists for positions
+and forces of masses.;
+#X text 169 240 Output all forces applied on masses in a list on outlet
+No 1;
+#X text 139 383 (\$2) : - If not defined all the attributes are send
+for all the elements. - Ids or/and creations No;
+#X msg 32 192 massesPosXL;
+#X text 170 202 Output all masses x or y in a list on outlet No 1;
+#X msg 32 213 massesPosYL;
+#X text 138 340 \$1 : Attribute type ( massesPos / massesPosName /
+massesSpeeds / massesSpeedsName / massesForces / massesForces / linksPos
+/ linksPos );
+#X text 173 511 [get massesPos( -----> [massesPos 0 x0 y0(;
+#X text 334 525 [massesPos 2 x2 y2(;
+#X text 334 539 [massesPos 1 x1 y1(;
+#X text 159 561 [get massesPos 1( -----> [massesPosNo 1 x1 y1(;
+#X text 145 582 [get massesPos mas( -----> [massesPosId 0 x0 y0(;
+#X text 334 597 [massesPosId 2 x2 y2(;
+#X text 334 612 [massesPosId 1 x1 y1(;
+#X text 145 633 [get massesPosName( -----> [massesPosName name_0 x0
+y0(;
+#X text 335 648 [massesPosName name_2 x2 y2(;
+#X text 335 663 [massesPosName name_1 x1 y1(;
+#X restore 12 499 pd attributes______;
+#X text 9 707 KEYWORDS: physical model mass spring damper link;
+#X text 267 732 - Nicolas Montgermont \, May 12 \, 2005;
+#X text 12 8 HELP: msd2D;
+#X text 12 18 DESCRIPTION: Mass spring damper physical modeling in
+2D.;
+#X obj 157 48 msd2D;
+#X text 257 676 editor/msd2d-editor.pd;
+#X text 112 676 01_msd2Dtest.pd;
+#X obj 18 296 msd2D;
+#X obj 172 294 route massesPos linksPos;
+#N canvas 731 296 450 300 gemmouse 0;
+#X obj 189 77 gemmouse;
+#X obj 189 184 pack f f;
+#X obj 189 218 spigot;
+#X obj 109 243 outlet;
+#X obj 109 36 inlet;
+#X obj 109 98 t b;
+#X obj 238 131 + 4;
+#X msg 57 182 posX fix \$1;
+#X msg 57 203 posY fix \$2;
+#X obj 189 108 / 62.5;
+#X obj 237 107 / -62.5;
+#X obj 189 131 - 4;
+#X obj 109 125 list 0 0;
+#X connect 0 0 9 0;
+#X connect 0 1 10 0;
+#X connect 0 2 2 1;
+#X connect 1 0 2 0;
+#X connect 2 0 12 1;
+#X connect 4 0 5 0;
+#X connect 5 0 12 0;
+#X connect 6 0 1 1;
+#X connect 7 0 3 0;
+#X connect 8 0 3 0;
+#X connect 9 0 11 0;
+#X connect 10 0 6 0;
+#X connect 11 0 1 0;
+#X connect 12 0 7 0;
+#X connect 12 0 8 0;
+#X restore 393 295 pd gemmouse;
+#X obj 393 274 gemhead;
+#X obj 336 216 gemwin;
+#X msg 336 194 0 \, destroy;
+#N canvas 472 258 550 319 gemrender 0;
+#X obj 48 203 translateXYZ;
+#X obj 48 229 sphere 0.1;
+#X obj 127 24 inlet;
+#X obj 360 32 inlet;
+#X obj 275 232 curve 2;
+#X msg 431 81 \$4 \$5 0;
+#X msg 359 77 \$2 \$3 0;
+#X obj 359 105 t b a;
+#X obj 127 62 unpack f f f;
+#X obj 166 88 t b f;
+#X msg 48 110 0;
+#X obj 48 77 loadbang;
+#X obj 48 137 gemhead;
+#X msg 275 160 0;
+#X obj 275 127 loadbang;
+#X obj 275 187 gemhead;
+#X connect 0 0 1 0;
+#X connect 2 0 8 0;
+#X connect 3 0 5 0;
+#X connect 3 0 6 0;
+#X connect 5 0 4 2;
+#X connect 6 0 7 0;
+#X connect 7 0 15 0;
+#X connect 7 1 4 1;
+#X connect 8 1 9 0;
+#X connect 8 2 0 2;
+#X connect 9 0 12 0;
+#X connect 9 1 0 1;
+#X connect 10 0 12 0;
+#X connect 11 0 10 0;
+#X connect 12 0 0 0;
+#X connect 13 0 15 0;
+#X connect 14 0 13 0;
+#X connect 15 0 4 0;
+#X restore 172 320 pd gemrender;
+#X msg 336 129 reset \, create \, 1;
+#X text 135 98 Sorry \, you need GEM for this example...;
+#X text 169 132 1 Create window -->;
+#X text 169 163 2 Drag the structure with the mouse;
+#X text 169 195 3 Destroy the window -->;
+#X connect 21 0 49 0;
+#X connect 24 0 23 0;
+#X connect 25 0 50 0;
+#X connect 26 0 19 0;
+#X connect 49 0 20 0;
+#X connect 50 0 55 0;
+#X connect 50 1 55 1;
+#X connect 51 0 22 0;
+#X connect 52 0 51 0;
+#X connect 54 0 53 0;
+#X connect 56 0 53 0;
diff --git a/msd/msd2D/package.txt b/msd/msd2D/package.txt
new file mode 100644
index 0000000..8e09583
--- /dev/null
+++ b/msd/msd2D/package.txt
@@ -0,0 +1,4 @@
+NAME=msd2D
+SRCS=main.cpp
+HDRS=../src/msd.h
+
diff --git a/msd/msd2D/sound_sable.pd b/msd/msd2D/sound_sable.pd
new file mode 100644
index 0000000..75f48a6
--- /dev/null
+++ b/msd/msd2D/sound_sable.pd
@@ -0,0 +1,67 @@
+#N canvas 420 100 846 647 10;
+#X obj 62 56 inlet;
+#X obj 179 112 outlet;
+#X obj 63 159 unpack f f;
+#X obj 63 231 +;
+#X obj 63 182 t f f;
+#X obj 63 205 *;
+#X obj 128 181 t f f;
+#X obj 128 204 *;
+#X obj 65 453 line~;
+#X obj 66 543 *~;
+#X obj 143 412 random 1000;
+#X obj 142 479 osc~;
+#X obj 66 571 outlet~;
+#X obj 65 404 min 0.1;
+#X obj 181 162 unpack f f;
+#X obj 181 234 +;
+#X obj 181 185 t f f;
+#X obj 181 208 *;
+#X obj 246 184 t f f;
+#X obj 246 207 *;
+#X obj 61 289 max;
+#X obj 143 434 / 3;
+#X obj 65 87 route \$1 \$2;
+#X obj 60 332 max 0;
+#X obj 63 252 * 1e+06;
+#X obj 180 255 * 1e+06;
+#X msg 64 430 \$1 0.5;
+#X obj 142 457 + 300;
+#X obj 143 390 lb;
+#X obj 60 312 - 0.009;
+#X connect 0 0 22 0;
+#X connect 2 0 4 0;
+#X connect 2 1 6 0;
+#X connect 3 0 24 0;
+#X connect 4 0 5 0;
+#X connect 4 1 5 1;
+#X connect 5 0 3 0;
+#X connect 6 0 7 0;
+#X connect 6 1 7 1;
+#X connect 7 0 3 1;
+#X connect 8 0 9 0;
+#X connect 9 0 12 0;
+#X connect 10 0 21 0;
+#X connect 11 0 9 1;
+#X connect 13 0 26 0;
+#X connect 14 0 16 0;
+#X connect 14 1 18 0;
+#X connect 15 0 25 0;
+#X connect 16 0 17 0;
+#X connect 16 1 17 1;
+#X connect 17 0 15 0;
+#X connect 18 0 19 0;
+#X connect 18 1 19 1;
+#X connect 19 0 15 1;
+#X connect 20 0 29 0;
+#X connect 21 0 27 0;
+#X connect 22 0 2 0;
+#X connect 22 1 14 0;
+#X connect 22 2 1 0;
+#X connect 23 0 13 0;
+#X connect 24 0 20 0;
+#X connect 25 0 20 1;
+#X connect 26 0 8 0;
+#X connect 27 0 11 0;
+#X connect 28 0 10 0;
+#X connect 29 0 23 0;
diff --git a/msd/msd2D/structures.pd b/msd/msd2D/structures.pd
new file mode 100644
index 0000000..c19074e
--- /dev/null
+++ b/msd/msd2D/structures.pd
@@ -0,0 +1,27 @@
+#N canvas 752 10 450 300 10;
+#N canvas 389 332 664 321 mass 0;
+#X obj 62 182 drawnumber mid 0 -18 0 m;
+#X obj 64 72 struct mass float x float y float mid float mob;
+#X obj 61 136 filledpolygon mob mob 1 -5 0 -4 4 0 5 4 4 5 0 4 -4 0
+-5 -4 -4;
+#X restore 132 125 pd mass;
+#N canvas 73 302 487 201 liaison 0;
+#X obj 19 25 struct liaison float x1 float y1 float x2 float y2 float
+mid1 float mid2 float lid;
+#X obj 23 73 drawpolygon lid 2 x1 y1 x2 y2;
+#X restore 132 169 pd liaison;
+#N canvas 0 0 450 300 model 0;
+#X obj 50 102 plot m 0 0 0 0;
+#X obj 51 135 plot l 0 0 0 0;
+#X obj 45 72 struct model float x1 array m mass array l liaison;
+#X restore 132 147 pd model;
+#N canvas 389 332 664 321 fixmass 0;
+#X obj 64 72 struct fixmass float x float y float mid;
+#X obj 61 136 filledpolygon 900 900 1 -5 0 -4 4 0 5 4 4 5 0 4 -4 0
+-5 -4 -4;
+#X obj 51 203 drawnumber mid 0 -18 900 m;
+#X restore 132 191 pd fixmass;
+#N canvas 0 0 450 300 fixed 0;
+#X obj 50 97 plot f 0 0 0 0;
+#X obj 49 56 struct fixed float x float y array f fixmass;
+#X restore 132 213 pd fixed;
diff --git a/msd/msd3D/01_msd3Dtest.pd b/msd/msd3D/01_msd3Dtest.pd
new file mode 100644
index 0000000..744adf2
--- /dev/null
+++ b/msd/msd3D/01_msd3Dtest.pd
@@ -0,0 +1,192 @@
+#N canvas 499 22 653 522 10;
+#X obj 27 26 loadbang;
+#X obj 127 419 print msd;
+#X obj 263 104 gemwin;
+#X msg 278 81 0 \, destroy;
+#X text 260 26 2 DRAG THE STRUCTURE WITH THE MOUSE;
+#X obj 87 27 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 90 76 reset;
+#X obj 27 47 t b b b b b;
+#X msg 42 186 Xmax 100 \, Xmin 0 \, Ymax 100 \, Ymin 0;
+#X obj 53 300 gemhead;
+#X obj 53 323 t b;
+#X msg 53 345 bang \, get massesPos \, get linksPos;
+#N canvas 643 123 308 285 massrender 0;
+#X obj 127 22 inlet;
+#X obj 48 203 translateXYZ;
+#X obj 127 86 / 12.5;
+#X obj 127 109 - 4;
+#X obj 192 87 / 12.5;
+#X obj 192 110 - 4;
+#X obj 48 177 separator;
+#X obj 125 136 t b f;
+#X obj 48 141 gemhead 45;
+#X msg 48 104 0;
+#X obj 47 58 loadbang;
+#X obj 127 57 unpack f f f f;
+#X obj 238 88 / 12.5;
+#X obj 238 111 - 4;
+#X obj 48 229 sphere 0.1;
+#X connect 0 0 11 0;
+#X connect 1 0 14 0;
+#X connect 2 0 3 0;
+#X connect 3 0 7 0;
+#X connect 4 0 5 0;
+#X connect 5 0 1 2;
+#X connect 6 0 1 0;
+#X connect 7 0 8 0;
+#X connect 7 1 1 1;
+#X connect 8 0 6 0;
+#X connect 9 0 8 0;
+#X connect 10 0 9 0;
+#X connect 11 1 2 0;
+#X connect 11 2 4 0;
+#X connect 11 3 12 0;
+#X connect 12 0 13 0;
+#X connect 13 0 1 3;
+#X restore 436 267 pd massrender;
+#X obj 366 244 route linksPos massesPos;
+#N canvas 731 296 458 308 gemmouse 0;
+#X obj 189 77 gemmouse;
+#X obj 189 184 pack f f;
+#X obj 189 218 spigot;
+#X obj 103 244 outlet;
+#X obj 189 131 - 0;
+#X obj 216 131 + 100;
+#X obj 189 108 / 5;
+#X obj 216 108 / -5;
+#X obj 79 51 inlet;
+#X obj 109 98 t b;
+#X obj 141 120 list;
+#X obj 141 41 r mouse_init;
+#X connect 0 0 6 0;
+#X connect 0 1 7 0;
+#X connect 0 2 2 1;
+#X connect 1 0 2 0;
+#X connect 2 0 10 1;
+#X connect 4 0 1 0;
+#X connect 5 0 1 1;
+#X connect 6 0 4 0;
+#X connect 7 0 5 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 3 0;
+#X connect 11 0 10 1;
+#X restore 366 356 pd gemmouse;
+#X obj 366 335 gemhead;
+#X msg 366 377 posX fix \$1;
+#X msg 366 398 posY fix \$2;
+#N canvas 0 22 454 304 linkrender 0;
+#X obj 127 22 inlet;
+#X obj 128 86 / 12.5;
+#X obj 128 109 - 4;
+#X obj 183 87 / 12.5;
+#X obj 183 110 - 4;
+#X obj 48 177 separator;
+#X obj 128 136 t b f;
+#X obj 262 88 / 12.5;
+#X obj 262 111 - 4;
+#X obj 290 112 / 12.5;
+#X obj 290 135 - 4;
+#X obj 48 222 curve 2;
+#X obj 155 189 pack f f 0;
+#X obj 262 192 pack f f 0;
+#X obj 48 130 gemhead 45;
+#X obj 47 44 loadbang;
+#X msg 47 68 0;
+#X obj 127 57 unpack f f f f f f f;
+#X obj 212 112 / 12.5;
+#X obj 212 135 - 4;
+#X obj 319 135 / 12.5;
+#X obj 319 158 - 4;
+#X connect 0 0 17 0;
+#X connect 1 0 2 0;
+#X connect 2 0 6 0;
+#X connect 3 0 4 0;
+#X connect 4 0 12 1;
+#X connect 5 0 11 0;
+#X connect 6 0 14 0;
+#X connect 6 1 12 0;
+#X connect 7 0 8 0;
+#X connect 8 0 13 0;
+#X connect 9 0 10 0;
+#X connect 10 0 13 1;
+#X connect 12 0 11 1;
+#X connect 13 0 11 2;
+#X connect 14 0 5 0;
+#X connect 15 0 16 0;
+#X connect 16 0 14 0;
+#X connect 17 1 1 0;
+#X connect 17 2 3 0;
+#X connect 17 3 18 0;
+#X connect 17 4 7 0;
+#X connect 17 5 9 0;
+#X connect 17 6 20 0;
+#X connect 18 0 19 0;
+#X connect 19 0 12 2;
+#X connect 20 0 21 0;
+#X connect 21 0 13 2;
+#X restore 366 289 pd linkrender;
+#X msg 206 139 50 50;
+#X msg 58 118 40 60 \, 60 60 \, 60 40 \, 40 40;
+#X obj 206 162 s mouse_init;
+#X msg 27 207 link souple mob mob 10 5;
+#X msg 27 230 link souple fix mob 10 5;
+#X text 25 1 creation : 5 masses and 20 links;
+#X text 52 281 compute and get masses and links positions;
+#X text 364 315 move mass to mouse position;
+#X text 365 197 display masses with gem;
+#X text 261 6 1 CREATE WINDOW;
+#X text 108 26 reset struct;
+#X obj 90 259 s \$0-msdin;
+#X obj 84 373 r \$0-msdin;
+#X obj 52 419 s \$0-msdout;
+#X obj 365 423 s \$0-msdin;
+#X obj 366 218 r \$0-msdout;
+#X msg 74 96 mass fix 0 100 50 50 50;
+#X msg 58 139 mass mob 1 100 \$1 \$2 50;
+#X obj 53 397 msd3D;
+#X obj 368 177 s \$0-msdin;
+#X msg 369 129 forceZ mob 200;
+#X msg 368 153 forceZ mob 200;
+#X text 367 108 send vertical forces;
+#X msg 263 58 reset \, create \, lighting 1 \, 1;
+#X obj 51 454 gemhead;
+#X obj 51 476 world_light;
+#X connect 0 0 7 0;
+#X connect 3 0 2 0;
+#X connect 5 0 7 0;
+#X connect 6 0 30 0;
+#X connect 7 0 22 0;
+#X connect 7 1 19 0;
+#X connect 7 1 8 0;
+#X connect 7 2 20 0;
+#X connect 7 3 35 0;
+#X connect 7 4 6 0;
+#X connect 8 0 30 0;
+#X connect 9 0 10 0;
+#X connect 10 0 11 0;
+#X connect 11 0 37 0;
+#X connect 13 0 18 0;
+#X connect 13 1 12 0;
+#X connect 14 0 16 0;
+#X connect 14 0 17 0;
+#X connect 15 0 14 0;
+#X connect 16 0 33 0;
+#X connect 17 0 33 0;
+#X connect 19 0 21 0;
+#X connect 20 0 36 0;
+#X connect 22 0 23 0;
+#X connect 22 0 30 0;
+#X connect 23 0 30 0;
+#X connect 31 0 37 0;
+#X connect 34 0 13 0;
+#X connect 35 0 30 0;
+#X connect 36 0 30 0;
+#X connect 37 0 32 0;
+#X connect 37 1 1 0;
+#X connect 39 0 38 0;
+#X connect 40 0 38 0;
+#X connect 42 0 2 0;
+#X connect 43 0 44 0;
diff --git a/msd/msd3D/02_msd3Dperf.pd b/msd/msd3D/02_msd3Dperf.pd
new file mode 100644
index 0000000..0d87f9d
--- /dev/null
+++ b/msd/msd3D/02_msd3Dperf.pd
@@ -0,0 +1,214 @@
+#N canvas 652 25 483 246 10;
+#X obj 20 12 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 43 12 reset;
+#X text 323 102 <-- Move masses;
+#X obj 83 13 nbx 5 14 200 20000 1 0 empty empty empty 0 -6 0 10 -262144
+-1 -1 347.56 1000;
+#X msg 206 45 forceX mob 10;
+#X msg 206 69 forceX mob -10;
+#X msg 225 95 forceY mob 10;
+#X msg 224 119 forceY mob -10;
+#X msg 238 143 forceZ mob 10;
+#X msg 237 167 forceZ mob -10;
+#N canvas 0 22 659 390 creation 0;
+#X obj 159 5 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X msg 231 60 reset;
+#X obj 37 10 loadbang;
+#X text 182 5 reset;
+#X obj 159 27 t b b b b b;
+#X msg 213 116 mass fix 0 100 50 50 0;
+#N canvas 557 309 632 363 masses 0;
+#X msg 417 145 seed 1;
+#X msg 342 144 seed 2;
+#X msg 239 126 seed 3;
+#X obj 42 14 inlet;
+#X obj 212 307 outlet;
+#X obj 268 47 loadbang;
+#X text 284 101 M;
+#X text 356 106 X;
+#X text 437 106 Y;
+#X obj 223 68 t b b;
+#X obj 42 45 until;
+#X obj 42 78 f;
+#X obj 72 78 + 1;
+#X obj 72 100 mod 30;
+#X obj 90 45 sel 0;
+#X obj 164 15 inlet;
+#X obj 342 165 random 800;
+#X obj 418 165 random 800;
+#X obj 239 146 random 800;
+#X obj 342 186 / 100;
+#X obj 339 206 - 4;
+#X obj 407 193 / 100;
+#X obj 404 213 - 4;
+#X obj 239 166 + 800;
+#X obj 502 161 random 800;
+#X obj 491 189 / 100;
+#X obj 488 209 - 4;
+#X text 505 107 Z;
+#X msg 501 141 seed 10;
+#X obj 211 218 pack f f f f;
+#X msg 211 239 mass mob 1 \$1 \$2 \$3 \$4;
+#X obj 235 186 / 4;
+#X connect 0 0 17 0;
+#X connect 1 0 16 0;
+#X connect 2 0 18 0;
+#X connect 3 0 10 0;
+#X connect 5 0 2 0;
+#X connect 5 0 1 0;
+#X connect 5 0 0 0;
+#X connect 5 0 28 0;
+#X connect 9 0 18 0;
+#X connect 9 1 16 0;
+#X connect 9 1 17 0;
+#X connect 9 1 24 0;
+#X connect 10 0 11 0;
+#X connect 11 0 12 0;
+#X connect 11 0 9 0;
+#X connect 12 0 13 0;
+#X connect 13 0 11 1;
+#X connect 13 0 14 0;
+#X connect 14 0 10 1;
+#X connect 15 0 13 1;
+#X connect 16 0 19 0;
+#X connect 17 0 21 0;
+#X connect 18 0 23 0;
+#X connect 19 0 20 0;
+#X connect 20 0 29 1;
+#X connect 21 0 22 0;
+#X connect 22 0 29 2;
+#X connect 23 0 31 0;
+#X connect 24 0 25 0;
+#X connect 25 0 26 0;
+#X connect 26 0 29 3;
+#X connect 28 0 24 0;
+#X connect 29 0 30 0;
+#X connect 30 0 4 0;
+#X connect 31 0 29 0;
+#X restore 195 146 pd masses;
+#N canvas 0 22 450 300 links 0;
+#X obj 136 72 t b;
+#X obj 136 116 + 1;
+#X obj 130 191 f;
+#X obj 92 171 t f b;
+#X obj 91 211 pack f f;
+#X msg 91 233 link souple \$1 \$2 10 0.5;
+#X obj 136 23 inlet;
+#X obj 91 260 outlet;
+#X obj 136 48 until;
+#X obj 202 112 sel 0;
+#X obj 184 154 mod 29;
+#X obj 136 93 f 0;
+#X obj 311 32 inlet;
+#X connect 0 0 11 0;
+#X connect 1 0 10 0;
+#X connect 1 0 2 1;
+#X connect 2 0 4 1;
+#X connect 3 0 4 0;
+#X connect 3 1 2 0;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 8 0;
+#X connect 8 0 0 0;
+#X connect 9 0 8 1;
+#X connect 10 0 9 0;
+#X connect 10 0 11 1;
+#X connect 11 0 1 0;
+#X connect 11 0 3 0;
+#X connect 12 0 10 1;
+#X restore 159 191 pd links;
+#X msg 177 228 Xmax 4 \, Xmin -4 \, Ymax 4 \, Ymin -4 \, Zmax 4 \,
+Zmin -4;
+#X obj 386 54 inlet;
+#X obj 232 7 inlet;
+#X obj 159 280 s \$0-msdin;
+#X connect 0 0 4 0;
+#X connect 1 0 11 0;
+#X connect 2 0 4 0;
+#X connect 4 0 7 0;
+#X connect 4 1 8 0;
+#X connect 4 2 6 0;
+#X connect 4 3 5 0;
+#X connect 4 4 1 0;
+#X connect 5 0 11 0;
+#X connect 6 0 11 0;
+#X connect 7 0 11 0;
+#X connect 8 0 11 0;
+#X connect 9 0 6 1;
+#X connect 9 0 7 1;
+#X connect 10 0 4 0;
+#X restore 20 32 pd creation;
+#X text 148 11 <-- Number of masses (change and reset);
+#N canvas 0 22 450 300 compute 0;
+#X obj 52 50 t b;
+#N canvas 643 123 617 602 massrender 0;
+#X obj 127 22 inlet;
+#X obj 48 203 translateXYZ;
+#X obj 48 153 gemhead;
+#X obj 48 177 separator;
+#X obj 125 136 t b f;
+#X obj 127 57 unpack f f f f;
+#X obj 48 229 cube 0.03;
+#X obj 48 99 loadbang;
+#X msg 48 127 0;
+#X connect 0 0 5 0;
+#X connect 1 0 6 0;
+#X connect 2 0 3 0;
+#X connect 3 0 1 0;
+#X connect 4 0 2 0;
+#X connect 4 1 1 1;
+#X connect 5 1 4 0;
+#X connect 5 2 1 2;
+#X connect 5 3 1 3;
+#X connect 7 0 8 0;
+#X connect 8 0 2 0;
+#X restore 52 209 pd massrender;
+#X obj 52 27 gemhead;
+#X obj 52 188 route massesPos;
+#X msg 52 84 bang \, get massesPos;
+#X obj 52 165 msd3D;
+#X obj 79 132 r \$0-msdin;
+#X connect 0 0 4 0;
+#X connect 2 0 0 0;
+#X connect 3 0 1 0;
+#X connect 4 0 5 0;
+#X connect 5 0 3 0;
+#X connect 6 0 5 0;
+#X restore 20 53 pd compute;
+#X obj 206 196 s \$0-msdin;
+#N canvas 0 22 450 300 gem 0;
+#X msg 106 118 0 \, destroy;
+#X obj 86 173 gemhead;
+#X obj 86 218 world_light;
+#X msg 86 58 reset \, create \, lighting 1 \, 1;
+#X obj 86 138 gemwin;
+#X msg 86 98 view 8 0 0.5 0 0 0 0 0 1;
+#X obj 86 77 t b;
+#X obj 86 195 rotateXYZ 30 30 0;
+#X obj 83 10 inlet;
+#X obj 85 32 sel 1 0;
+#X connect 0 0 4 0;
+#X connect 1 0 7 0;
+#X connect 3 0 4 0;
+#X connect 3 0 6 0;
+#X connect 5 0 4 0;
+#X connect 6 0 5 0;
+#X connect 7 0 2 0;
+#X connect 8 0 9 0;
+#X connect 9 0 3 0;
+#X connect 9 1 0 0;
+#X restore 20 92 pd gem;
+#X obj 20 74 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1
+;
+#X text 41 73 gem on/off;
+#X connect 0 0 10 0;
+#X connect 3 0 10 1;
+#X connect 4 0 13 0;
+#X connect 5 0 13 0;
+#X connect 6 0 13 0;
+#X connect 7 0 13 0;
+#X connect 8 0 13 0;
+#X connect 9 0 13 0;
+#X connect 15 0 14 0;
diff --git a/msd/msd3D/03_msd3Dmemb.pd b/msd/msd3D/03_msd3Dmemb.pd
new file mode 100644
index 0000000..66309af
--- /dev/null
+++ b/msd/msd3D/03_msd3Dmemb.pd
@@ -0,0 +1,207 @@
+#N canvas 807 173 535 198 10;
+#X obj 26 16 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 50 15 reset;
+#X text 182 65 Add a constant force;
+#X msg 338 127 posZ fix \$1;
+#X text 337 86 Change altitude of corners;
+#N canvas 0 22 616 405 creation 0;
+#X obj 32 13 loadbang;
+#X obj 129 18 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262131 -1
+-1;
+#X msg 202 59 reset;
+#X text 167 19 reset;
+#X msg 148 229 Xmax 100 \, Xmin 0 \, Ymax 100 \, Ymin 0 \, Zmax 70
+\, Zmin 0;
+#X msg 130 255 0 4 \, 4 5 \, 5 6 \, 6 1 \, 7 8 \, 8 9 \, 9 10 \, 10
+11 \, 12 13 \, 13 14 \, 14 15 \, 15 16 \, 17 18 \, 18 19 \, 19 20 \,
+20 21 \, 2 22 \, 22 23 \, 23 24 \, 24 3 \, 0 7 \, 4 8 \, 5 9 \, 6 10
+\, 1 11 \, 7 12 \, 8 13 \, 9 14 \, 10 15 \, 11 16 \, 12 17 \, 13 18
+\, 14 19 \, 15 20 \, 16 21 \, 2 17 \, 18 22 \, 19 23 \, 20 24 \, 21
+3;
+#X msg 166 130 30 40 40 \, 30 50 40 \, 30 60 40 \, 40 30 40 \, 40 40
+40 \, 40 50 40 \, 40 60 40 \, 40 70 40 \, 50 30 40 \, 50 40 40 \, 50
+50 40 \, 50 60 40 \, 50 70 40 \, 60 30 40 \, 60 40 40 \, 60 50 40 \,
+60 60 40 \, 60 70 40 \, 70 40 40 \, 70 50 40 \, 70 60 40;
+#X msg 184 82 mass fix 0 100 30 30 40 \, mass fix 0 100 30 70 40 \,
+mass fix 0 100 70 30 40 \, mass fix 0 100 70 70 40;
+#X obj 130 38 t b b b b b;
+#X msg 166 193 mass mob 1 70 \$1 \$2 \$3;
+#X msg 130 335 link souple \$1 \$2 2 10;
+#X msg 71 72 posZ fix 70;
+#X obj 130 361 s \$0-msdin;
+#X obj 204 14 inlet;
+#X connect 0 0 8 0;
+#X connect 1 0 8 0;
+#X connect 2 0 12 0;
+#X connect 4 0 12 0;
+#X connect 5 0 10 0;
+#X connect 6 0 9 0;
+#X connect 7 0 12 0;
+#X connect 8 0 5 0;
+#X connect 8 0 11 0;
+#X connect 8 1 4 0;
+#X connect 8 2 6 0;
+#X connect 8 3 7 0;
+#X connect 8 4 2 0;
+#X connect 9 0 12 0;
+#X connect 10 0 12 0;
+#X connect 11 0 12 0;
+#X connect 13 0 8 0;
+#X restore 26 36 pd creation;
+#N canvas 0 22 450 300 compute 0;
+#N canvas 613 332 591 562 linkrender 0;
+#X obj 93 25 inlet;
+#X obj 93 117 / 12.5;
+#X obj 93 140 - 4;
+#X obj 147 118 / 12.5;
+#X obj 147 141 - 4;
+#X obj 42 266 separator;
+#X obj 63 163 t b f;
+#X obj 266 117 / 12.5;
+#X obj 266 140 - 4;
+#X obj 320 118 / 12.5;
+#X obj 320 141 - 4;
+#X obj 197 117 / 12.5;
+#X obj 197 142 - 4;
+#X obj 123 194 pack f f f;
+#X msg 123 217 \$1 \$2 \$3;
+#X obj 371 118 / 12.5;
+#X obj 371 141 - 4;
+#X obj 266 189 pack f f f;
+#X msg 266 212 \$1 \$2 \$3;
+#X obj 93 69 unpack f f f f f f f;
+#X obj 136 297 sel 0;
+#X obj 354 24 inlet;
+#X msg 132 418 \$1 \$1 \$1;
+#X obj 139 333 counter 0 2;
+#X obj 44 310 curve2;
+#X obj 133 363 / 2;
+#X msg 268 24 reset;
+#X obj 434 26 inlet;
+#X obj 437 52 t b;
+#X obj 31 196 gemhead 5;
+#X obj 31 222 color 1 1 1;
+#X obj 31 100 loadbang;
+#X msg 31 128 0;
+#X connect 0 0 19 0;
+#X connect 1 0 2 0;
+#X connect 2 0 13 0;
+#X connect 3 0 4 0;
+#X connect 4 0 13 1;
+#X connect 5 0 24 0;
+#X connect 6 0 29 0;
+#X connect 6 1 20 0;
+#X connect 7 0 8 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 10 0 17 1;
+#X connect 11 0 12 0;
+#X connect 12 0 13 2;
+#X connect 13 0 14 0;
+#X connect 14 0 24 1;
+#X connect 15 0 16 0;
+#X connect 16 0 17 2;
+#X connect 17 0 18 0;
+#X connect 18 0 24 2;
+#X connect 19 0 6 0;
+#X connect 19 1 1 0;
+#X connect 19 2 3 0;
+#X connect 19 3 11 0;
+#X connect 19 4 7 0;
+#X connect 19 5 9 0;
+#X connect 19 6 15 0;
+#X connect 20 0 23 0;
+#X connect 21 0 23 3;
+#X connect 21 0 25 1;
+#X connect 23 0 25 0;
+#X connect 25 0 22 0;
+#X connect 26 0 23 0;
+#X connect 27 0 28 0;
+#X connect 28 0 26 0;
+#X connect 29 0 30 0;
+#X connect 30 0 5 0;
+#X connect 31 0 32 0;
+#X connect 32 0 29 0;
+#X restore 33 225 pd linkrender;
+#X obj 33 200 route linksPos;
+#X text 98 93 Multiple draw;
+#X obj 33 64 gemhead 15;
+#X msg 33 127 bang \, get linksPos;
+#X obj 33 92 t b b b b;
+#X obj 33 175 msd3D;
+#X obj 75 148 r \$0-msdin;
+#X connect 1 0 0 0;
+#X connect 3 0 5 0;
+#X connect 4 0 6 0;
+#X connect 5 0 4 0;
+#X connect 5 1 4 0;
+#X connect 5 2 4 0;
+#X connect 5 3 4 0;
+#X connect 6 0 1 0;
+#X connect 7 0 6 0;
+#X restore 26 59 pd compute;
+#X text 182 23 membrane with a multiple drawing;
+#N canvas 0 22 450 300 constant 0;
+#X obj 122 129 f;
+#X msg 122 154 forceZ mob \$1;
+#X obj 122 73 metro 65;
+#X obj 122 25 inlet;
+#X obj 225 25 inlet;
+#X obj 122 180 s \$0-msdin;
+#X connect 0 0 1 0;
+#X connect 1 0 5 0;
+#X connect 2 0 0 0;
+#X connect 3 0 2 0;
+#X connect 4 0 0 1;
+#X restore 183 126 pd constant;
+#X obj 183 83 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X text 221 82 on/off;
+#X floatatom 183 104 5 0 0 0 - - -;
+#N canvas 583 304 450 300 gem 0;
+#X obj 101 220 gemwin;
+#X msg 120 102 0 \, destroy;
+#X obj 13 211 gemhead;
+#X obj 13 234 world_light;
+#X msg 219 198 view 0 4 0 0 0 0 0 0 1;
+#X msg 219 156 view 4 0 0.5 0 0 0 0 0 1;
+#X msg 219 177 view 0 0 4 0 0 0 0 1 0;
+#X text -3 77 Create window;
+#X text 9 126 Change view;
+#X msg 101 80 reset \, dimen 800 800 \, create \, lighting 1 \, 1;
+#X obj 101 17 inlet;
+#X obj 101 47 sel 1 0;
+#X obj 219 104 inlet;
+#X obj 219 134 sel 2 1 0;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 0 0;
+#X connect 9 0 0 0;
+#X connect 10 0 11 0;
+#X connect 11 0 9 0;
+#X connect 11 1 1 0;
+#X connect 12 0 13 0;
+#X connect 13 0 5 0;
+#X connect 13 1 6 0;
+#X connect 13 2 4 0;
+#X restore 26 135 pd gem;
+#X obj 26 87 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1
+;
+#X text 79 84 gem on/off;
+#X obj 26 111 hradio 15 1 0 3 empty empty empty 0 -8 0 10 -262144 -1
+-1 1;
+#X text 79 110 change view;
+#X obj 341 107 hsl 128 15 0 127 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 0 1;
+#X text 221 103 amplitude;
+#X obj 338 150 s \$0-msdin;
+#X connect 0 0 5 0;
+#X connect 3 0 19 0;
+#X connect 9 0 8 0;
+#X connect 11 0 8 1;
+#X connect 13 0 12 0;
+#X connect 15 0 12 1;
+#X connect 17 0 3 0;
diff --git a/msd/msd3D/04_msd3Dfilet.pd b/msd/msd3D/04_msd3Dfilet.pd
new file mode 100644
index 0000000..03c5b64
--- /dev/null
+++ b/msd/msd3D/04_msd3Dfilet.pd
@@ -0,0 +1,188 @@
+#N canvas 719 216 416 177 10;
+#X obj 26 32 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 47 31 reset;
+#N canvas 530 297 450 300 gem 0;
+#X obj 101 220 gemwin;
+#X msg 120 102 0 \, destroy;
+#X obj 13 211 gemhead;
+#X obj 13 234 world_light;
+#X msg 101 80 reset \, dimen 800 800 \, create \, lighting 1 \, 1;
+#X obj 101 17 inlet;
+#X obj 101 47 sel 1 0;
+#X obj 219 104 inlet;
+#X obj 219 134 sel 2 1 0;
+#X msg 219 177 view 0 0 2 0 0 0 0 1 0;
+#X msg 219 198 view 0 4 4 0 0 0 0 0 1;
+#X msg 219 156 view 2 0 3.5 0 0 0 0 0 1;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 4 0 0 0;
+#X connect 5 0 6 0;
+#X connect 6 0 4 0;
+#X connect 6 1 1 0;
+#X connect 7 0 8 0;
+#X connect 8 0 11 0;
+#X connect 8 1 9 0;
+#X connect 8 2 10 0;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X connect 11 0 0 0;
+#X restore 26 135 pd gem;
+#X obj 26 87 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1
+;
+#X text 79 84 gem on/off;
+#X obj 26 111 hradio 15 1 0 3 empty empty empty 0 -8 0 10 -262144 -1
+-1 0;
+#X text 79 110 change view;
+#N canvas 0 22 584 305 creation 0;
+#X msg 203 63 reset;
+#X msg 203 83 symbol reset;
+#X msg 145 173 Xmax 100 \, Xmin 0 \, Ymax 100 \, Ymin 0 \, Zmax 70
+\, Zmin -40;
+#X msg 164 140 setFixed 62 \, setFixed 87 \, setFixed 512 \, setFixed
+537;
+#X obj 183 113 filet 20 30 2 2 20 30;
+#X obj 145 38 t b b b b;
+#X text 383 114 Filet abstraction : x0 y0 stepx stepy ny nx;
+#X obj 94 15 loadbang;
+#X obj 150 14 inlet;
+#X obj 145 205 s \$0-msdin;
+#X connect 0 0 9 0;
+#X connect 1 0 4 1;
+#X connect 2 0 9 0;
+#X connect 3 0 9 0;
+#X connect 4 0 9 0;
+#X connect 5 0 2 0;
+#X connect 5 1 3 0;
+#X connect 5 2 4 0;
+#X connect 5 3 0 0;
+#X connect 5 3 1 0;
+#X connect 7 0 5 0;
+#X connect 8 0 5 0;
+#X restore 26 52 pd creation;
+#N canvas 0 22 563 472 compute 0;
+#X obj 33 28 gemhead;
+#X obj 33 51 t b;
+#X msg 33 73 bang \, get massesPos \, get linksPos;
+#N canvas 643 123 613 598 massrender 0;
+#X obj 130 9 inlet;
+#X obj 48 203 translateXYZ;
+#X obj 48 229 sphere 0.1;
+#X obj 130 73 / 12.5;
+#X obj 130 96 - 4;
+#X obj 195 74 / 12.5;
+#X obj 195 97 - 4;
+#X obj 48 156 gemhead;
+#X obj 48 177 separator;
+#X obj 128 123 t b f;
+#X obj 249 75 / 12.5;
+#X obj 249 98 - 4;
+#X obj 130 44 unpack f f f f;
+#X obj 48 90 loadbang;
+#X msg 48 118 0;
+#X connect 0 0 12 0;
+#X connect 1 0 2 0;
+#X connect 3 0 4 0;
+#X connect 4 0 9 0;
+#X connect 5 0 6 0;
+#X connect 6 0 1 2;
+#X connect 7 0 8 0;
+#X connect 8 0 1 0;
+#X connect 9 0 7 0;
+#X connect 9 1 1 1;
+#X connect 10 0 11 0;
+#X connect 11 0 1 3;
+#X connect 12 1 3 0;
+#X connect 12 2 5 0;
+#X connect 12 3 10 0;
+#X connect 13 0 14 0;
+#X connect 14 0 7 0;
+#X restore 114 359 pd massrender;
+#N canvas 284 227 595 566 linkrender 0;
+#X obj 93 25 inlet;
+#X obj 93 117 / 12.5;
+#X obj 93 140 - 4;
+#X obj 147 118 / 12.5;
+#X obj 147 141 - 4;
+#X obj 44 194 gemhead;
+#X obj 44 222 separator;
+#X obj 93 164 t b f;
+#X obj 266 117 / 12.5;
+#X obj 266 140 - 4;
+#X obj 320 118 / 12.5;
+#X obj 320 141 - 4;
+#X obj 197 117 / 12.5;
+#X obj 197 142 - 4;
+#X obj 123 194 pack f f f;
+#X msg 123 217 \$1 \$2 \$3;
+#X obj 371 118 / 12.5;
+#X obj 371 141 - 4;
+#X obj 266 189 pack f f f;
+#X msg 266 212 \$1 \$2 \$3;
+#X obj 44 265 curve 2;
+#X obj 93 69 unpack f f f f f f f;
+#X obj 44 90 loadbang;
+#X msg 44 118 0;
+#X connect 0 0 21 0;
+#X connect 1 0 2 0;
+#X connect 2 0 7 0;
+#X connect 3 0 4 0;
+#X connect 4 0 14 1;
+#X connect 5 0 6 0;
+#X connect 6 0 20 0;
+#X connect 7 0 5 0;
+#X connect 7 1 14 0;
+#X connect 8 0 9 0;
+#X connect 9 0 18 0;
+#X connect 10 0 11 0;
+#X connect 11 0 18 1;
+#X connect 12 0 13 0;
+#X connect 13 0 14 2;
+#X connect 14 0 15 0;
+#X connect 15 0 20 1;
+#X connect 16 0 17 0;
+#X connect 17 0 18 2;
+#X connect 18 0 19 0;
+#X connect 19 0 20 2;
+#X connect 21 1 1 0;
+#X connect 21 2 3 0;
+#X connect 21 3 12 0;
+#X connect 21 4 8 0;
+#X connect 21 5 10 0;
+#X connect 21 6 16 0;
+#X connect 22 0 23 0;
+#X connect 23 0 5 0;
+#X restore 33 380 pd linkrender;
+#X obj 33 269 route linksPos massesPos;
+#X msg 46 145 forceZ filet -0.2;
+#X text 61 122 Ambient force;
+#X obj 47 188 r \$0-msdin;
+#X obj 147 296 inlet;
+#X obj 114 337 spigot;
+#X obj 33 341 spigot 1;
+#X obj 78 318 == 0;
+#X obj 33 227 msd3D;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 6 0;
+#X connect 2 0 13 0;
+#X connect 5 0 11 0;
+#X connect 5 1 10 0;
+#X connect 6 0 13 0;
+#X connect 8 0 13 0;
+#X connect 9 0 10 1;
+#X connect 9 0 12 0;
+#X connect 10 0 3 0;
+#X connect 11 0 4 0;
+#X connect 12 0 11 1;
+#X connect 13 0 5 0;
+#X restore 204 131 pd compute;
+#X obj 204 106 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X text 225 105 display links or masses;
+#X text 201 27 grid in a gravity field;
+#X connect 0 0 7 0;
+#X connect 3 0 2 0;
+#X connect 5 0 2 1;
+#X connect 9 0 8 0;
diff --git a/msd/msd3D/05_msd3Dvline.pd b/msd/msd3D/05_msd3Dvline.pd
new file mode 100644
index 0000000..e500868
--- /dev/null
+++ b/msd/msd3D/05_msd3Dvline.pd
@@ -0,0 +1,312 @@
+#N canvas 600 228 703 389 10;
+#N canvas 530 297 450 300 gem 0;
+#X obj 101 220 gemwin;
+#X msg 120 102 0 \, destroy;
+#X obj 13 211 gemhead;
+#X obj 13 234 world_light;
+#X msg 101 80 reset \, dimen 800 800 \, create \, lighting 1 \, 1;
+#X obj 101 17 inlet;
+#X obj 101 47 sel 1 0;
+#X msg 219 156 view 0 0 11 0 0 0 1 0 0;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 4 0 0 0;
+#X connect 4 0 7 0;
+#X connect 5 0 6 0;
+#X connect 6 0 4 0;
+#X connect 6 1 1 0;
+#X connect 7 0 0 0;
+#X restore 14 85 pd gem;
+#X obj 14 62 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1
+;
+#X text 33 60 gem on/off;
+#N canvas 0 22 563 316 creation 0;
+#X obj 32 13 loadbang;
+#X msg 204 68 reset;
+#X msg 204 88 symbol reset;
+#X obj 146 42 t b b b b;
+#X msg 165 139 setFixed 0 \, setFixed 29 \, setFixed 420 \, setFixed
+449;
+#X obj 184 115 filet -3.2 -3.2 0.22068 0.45714 15 30;
+#X msg 146 173 Xmax 4 \, Xmin -4 \, Ymax 4 \, Ymin -4 \, Zmax 9 \,
+Zmin -6;
+#X obj 146 205 s \$0-msdin;
+#X obj 147 19 inlet;
+#X connect 0 0 3 0;
+#X connect 1 0 7 0;
+#X connect 2 0 5 1;
+#X connect 3 0 6 0;
+#X connect 3 1 4 0;
+#X connect 3 2 5 0;
+#X connect 3 3 1 0;
+#X connect 3 3 2 0;
+#X connect 4 0 7 0;
+#X connect 5 0 7 0;
+#X connect 6 0 7 0;
+#X connect 8 0 3 0;
+#X restore 14 38 pd creation;
+#X text 34 17 reset;
+#X obj 14 20 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#N canvas 0 22 450 300 compute 0;
+#X obj 33 23 gemhead;
+#X obj 33 201 msd3D --------------------------------;
+#N canvas 646 294 504 533 getmmasses 0;
+#X obj 154 13 inlet;
+#X obj 152 238 outlet;
+#X obj 154 45 t b b;
+#X obj 156 162 f 0;
+#X obj 156 186 + 1;
+#X msg 242 154 0;
+#X obj 154 129 repeat 450;
+#X connect 0 0 2 0;
+#X connect 2 0 6 0;
+#X connect 2 1 5 0;
+#X connect 3 0 4 0;
+#X connect 3 0 1 0;
+#X connect 4 0 3 1;
+#X connect 5 0 3 1;
+#X connect 6 0 3 0;
+#X restore 60 116 pd getmmasses;
+#N canvas 446 323 942 390 massrender 0;
+#X obj 286 2 inlet;
+#X obj 306 144 pack f f f f;
+#X obj 306 99 % 30;
+#X obj 56 247 route 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
+19 20 21 22 23 24 25 26 27 28 29;
+#X obj 44 288 curve16 ---------------------------------------------
+;
+#X obj 325 41 unpack f f f f;
+#X obj 261 125 sel 29;
+#X obj 559 210 pack f f f f;
+#X obj 430 147 moses 240;
+#X obj 432 177 moses 210;
+#X text 669 215 Get middle masses;
+#X obj 555 295 outlet;
+#X obj 44 197 gemhead 45;
+#X obj 44 128 loadbang;
+#X msg 44 156 0;
+#X connect 0 0 5 0;
+#X connect 1 0 3 0;
+#X connect 2 0 1 0;
+#X connect 2 0 6 0;
+#X connect 3 0 4 1;
+#X connect 3 1 4 2;
+#X connect 3 2 4 3;
+#X connect 3 3 4 4;
+#X connect 3 4 4 5;
+#X connect 3 5 4 6;
+#X connect 3 6 4 7;
+#X connect 3 7 4 8;
+#X connect 3 8 4 9;
+#X connect 3 9 4 10;
+#X connect 3 10 4 11;
+#X connect 3 11 4 12;
+#X connect 3 12 4 13;
+#X connect 3 13 4 14;
+#X connect 3 14 4 15;
+#X connect 3 15 4 16;
+#X connect 3 16 4 17;
+#X connect 3 17 4 18;
+#X connect 3 18 4 19;
+#X connect 3 19 4 20;
+#X connect 3 20 4 21;
+#X connect 3 21 4 22;
+#X connect 3 22 4 23;
+#X connect 3 23 4 24;
+#X connect 3 24 4 25;
+#X connect 3 25 4 26;
+#X connect 3 26 4 27;
+#X connect 3 27 4 28;
+#X connect 3 28 4 29;
+#X connect 3 29 4 30;
+#X connect 5 0 2 0;
+#X connect 5 0 8 0;
+#X connect 5 1 1 1;
+#X connect 5 1 7 1;
+#X connect 5 2 1 2;
+#X connect 5 2 7 2;
+#X connect 5 3 1 3;
+#X connect 5 3 7 3;
+#X connect 6 0 12 0;
+#X connect 7 0 11 0;
+#X connect 8 0 9 0;
+#X connect 9 1 7 0;
+#X connect 12 0 4 0;
+#X connect 13 0 14 0;
+#X connect 14 0 12 0;
+#X restore 33 253 pd massrender;
+#X msg 60 140 get massesPos \$1;
+#X obj 33 47 t b b;
+#X msg 33 75 bang;
+#X text 154 155 Get masses in order;
+#X obj 33 227 route massesPosNo;
+#X obj 60 162 r \$0-msdin;
+#X connect 0 0 5 0;
+#X connect 1 0 8 0;
+#X connect 2 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 2 0;
+#X connect 5 0 6 0;
+#X connect 5 1 2 0;
+#X connect 5 1 6 0;
+#X connect 6 0 1 0;
+#X connect 8 0 3 0;
+#X connect 9 0 1 0;
+#X restore 14 106 pd compute;
+#N canvas 0 22 450 300 sinus 0;
+#X msg 206 243 forceZ filet \$1;
+#X obj 116 165 sin;
+#X obj 116 185 *;
+#X obj 116 105 counter 0 360;
+#X obj 116 54 tgl 20 0 empty empty empty 0 -6 0 8 -262131 -1 -1 0 0.23622
+;
+#X obj 116 125 / 3.6;
+#X obj 116 145 * 6.28319;
+#X obj 116 82 metro 35;
+#X obj 93 69 vsl 15 128 0 30 0 0 empty empty empty 0 -8 0 8 -262131
+-1 -1 0 1;
+#X text 64 215 Get masses in order;
+#X obj 206 264 s \$0-msdin;
+#X obj 163 51 inlet;
+#X connect 0 0 10 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 0;
+#X connect 3 0 5 0;
+#X connect 4 0 7 0;
+#X connect 5 0 6 0;
+#X connect 6 0 1 0;
+#X connect 7 0 3 0;
+#X connect 8 0 4 0;
+#X connect 11 0 2 1;
+#X connect 11 0 4 0;
+#X restore 190 146 pd sinus;
+#X obj 193 125 hsl 128 15 0 127 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 0 1;
+#X text 189 106 add sinusoidal force;
+#X text 330 107 add constant force;
+#N canvas 0 22 450 300 constant 0;
+#X msg 176 111 forceZ filet \$1;
+#X obj 176 33 tgl 20 0 empty empty empty 0 -6 0 8 -262131 -1 -1 0 1
+;
+#X obj 176 84 f;
+#X obj 176 60 metro 65;
+#X obj 176 132 s \$0-msdin;
+#X obj 225 28 inlet;
+#X connect 0 0 4 0;
+#X connect 1 0 3 0;
+#X connect 2 0 0 0;
+#X connect 3 0 2 0;
+#X connect 5 0 1 0;
+#X connect 5 0 2 1;
+#X restore 332 145 pd constant;
+#X obj 335 125 hsl 128 15 0 127 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 0 1;
+#X text 151 26 vertical lines under various forces;
+#N canvas 0 22 450 300 sinus 0;
+#X obj 116 195 sin;
+#X obj 116 215 *;
+#X obj 116 135 counter 0 360;
+#X obj 116 54 tgl 20 0 empty empty empty 0 -6 0 8 -262131 -1 -1 0 8
+;
+#X obj 116 155 / 3.6;
+#X obj 116 175 * 6.28319;
+#X obj 116 112 metro 35;
+#X obj 116 264 s \$0-msdin;
+#X obj 163 51 inlet;
+#X msg 116 243 forceX filet \$1;
+#X obj 163 83 / 30;
+#X connect 0 0 1 0;
+#X connect 1 0 9 0;
+#X connect 2 0 4 0;
+#X connect 3 0 6 0;
+#X connect 4 0 5 0;
+#X connect 5 0 0 0;
+#X connect 6 0 2 0;
+#X connect 8 0 3 0;
+#X connect 8 0 10 0;
+#X connect 9 0 7 0;
+#X connect 10 0 1 1;
+#X restore 190 216 pd sinus;
+#X obj 193 195 hsl 128 15 0 127 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 0 1;
+#X text 189 176 add sinusoidal force;
+#X text 330 177 add constant force;
+#N canvas 0 22 450 300 constant 0;
+#X obj 176 33 tgl 20 0 empty empty empty 0 -6 0 8 -262131 -1 -1 0 10
+;
+#X obj 176 84 f;
+#X obj 176 60 metro 65;
+#X obj 176 152 s \$0-msdin;
+#X obj 225 28 inlet;
+#X msg 176 131 forceX filet \$1;
+#X obj 176 107 / 100;
+#X connect 0 0 2 0;
+#X connect 1 0 6 0;
+#X connect 2 0 1 0;
+#X connect 4 0 0 0;
+#X connect 4 0 1 1;
+#X connect 5 0 3 0;
+#X connect 6 0 5 0;
+#X restore 332 215 pd constant;
+#X obj 335 195 hsl 128 15 0 127 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 0 1;
+#X text 128 120 on Z;
+#X text 128 193 on Y;
+#N canvas 0 22 450 300 sinus 0;
+#X obj 116 205 sin;
+#X obj 116 225 *;
+#X obj 116 145 counter 0 360;
+#X obj 116 54 tgl 20 0 empty empty empty 0 -6 0 8 -262131 -1 -1 0 3
+;
+#X obj 116 165 / 3.6;
+#X obj 116 185 * 6.28319;
+#X obj 116 122 metro 35;
+#X obj 116 287 s \$0-msdin;
+#X obj 163 51 inlet;
+#X msg 116 266 forceY filet \$1;
+#X obj 163 78 / 30;
+#X connect 0 0 1 0;
+#X connect 1 0 9 0;
+#X connect 2 0 4 0;
+#X connect 3 0 6 0;
+#X connect 4 0 5 0;
+#X connect 5 0 0 0;
+#X connect 6 0 2 0;
+#X connect 8 0 3 0;
+#X connect 8 0 10 0;
+#X connect 9 0 7 0;
+#X connect 10 0 1 1;
+#X restore 190 276 pd sinus;
+#X obj 193 255 hsl 128 15 0 127 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 0 1;
+#X text 189 236 add sinusoidal force;
+#X text 330 237 add constant force;
+#N canvas 0 22 450 300 constant 0;
+#X obj 176 33 tgl 20 0 empty empty empty 0 -6 0 8 -262131 -1 -1 0 12
+;
+#X obj 176 84 f;
+#X obj 176 60 metro 65;
+#X obj 176 172 s \$0-msdin;
+#X obj 225 28 inlet;
+#X msg 176 151 forceY filet \$1;
+#X obj 176 113 / 127;
+#X connect 0 0 2 0;
+#X connect 1 0 6 0;
+#X connect 2 0 1 0;
+#X connect 4 0 0 0;
+#X connect 4 0 1 1;
+#X connect 5 0 3 0;
+#X connect 6 0 5 0;
+#X restore 332 275 pd constant;
+#X obj 335 255 hsl 128 15 0 127 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 0 1;
+#X text 128 253 on X;
+#X connect 1 0 0 0;
+#X connect 5 0 3 0;
+#X connect 8 0 7 0;
+#X connect 12 0 11 0;
+#X connect 15 0 14 0;
+#X connect 19 0 18 0;
+#X connect 23 0 22 0;
+#X connect 27 0 26 0;
diff --git a/msd/msd3D/Makefile.am b/msd/msd3D/Makefile.am
new file mode 100644
index 0000000..59a3dff
--- /dev/null
+++ b/msd/msd3D/Makefile.am
@@ -0,0 +1,51 @@
+#
+# automake template
+# added by tim blechmann
+#
+
+NAME = msd2
+
+BUILT_SOURCES = main.cpp
+
+EXTRA_DIST = main.cpp \
+ $(NAME).mcp \
+ $(NAME).vcproj
+
+CXXFLAGS = @CXXFLAGS@ \
+ @OPT_FLAGS@ \
+ @INCLUDEDIR@ \
+ -I../../source \
+ $(DEFS) \
+ -DFLEXT_SHARED
+
+LDFLAGS = @DYNAMIC_LDFLAGS@ @LDFLAGS@ \
+ $(patsubst %,-framework %,$(FRAMEWORKS))
+
+LIBS = @LIBS@ -lflext-pd
+
+FRAMEWORKS = @FRAMEWORKS@
+
+TARGETDIR = @TARGETDIR@
+
+TARGET =$(NAME).@EXTENSION@
+
+OBJECTS = $(patsubst %.cpp,./%.@OBJEXT@,$(BUILT_SOURCES))
+
+SYSDIR = @SYSDIR@
+
+
+# ----------------------------- targets --------------------------------
+
+all-local: $(OBJECTS)
+ $(CXX) $(LDFLAGS) ./*.@OBJEXT@ $(LIBS) -o ../$(TARGETDIR)/$(TARGET)
+ strip --strip-unneeded ../$(TARGETDIR)/$(TARGET)
+
+./%.@OBJEXT@ : %.cpp
+ $(CXX) -c $(CXXFLAGS) $< -o $@
+
+clean-local:
+ rm -f ../$(TARGETDIR)/$(TARGET)
+ rm -f ./$(OBJECTS)
+
+install-exec-local:
+ install ../$(TARGET) $(SYSDIR)extra
diff --git a/msd/msd3D/curve16.pd b/msd/msd3D/curve16.pd
new file mode 100644
index 0000000..cdf10c6
--- /dev/null
+++ b/msd/msd3D/curve16.pd
@@ -0,0 +1,133 @@
+#N canvas 8 35 1142 910 10;
+#X obj 31 123 GEMglBegin;
+#X obj 86 100 GLdefine GL_LINE_STRIP;
+#X obj 31 13 inlet;
+#X obj 86 77 loadbang;
+#X obj 159 13 inlet;
+#X obj 200 13 inlet;
+#X obj 25 865 GEMglEnd;
+#X obj 31 151 GEMglVertex3fv;
+#X obj 31 175 GEMglVertex3fv;
+#X obj 241 13 inlet;
+#X obj 280 12 inlet;
+#X obj 29 202 GEMglVertex3fv;
+#X obj 29 226 GEMglVertex3fv;
+#X obj 319 12 inlet;
+#X obj 359 12 inlet;
+#X obj 161 76 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 29 252 GEMglVertex3fv;
+#X obj 29 276 GEMglVertex3fv;
+#X obj 29 300 GEMglVertex3fv;
+#X obj 29 324 GEMglVertex3fv;
+#X obj 28 346 GEMglVertex3fv;
+#X obj 28 370 GEMglVertex3fv;
+#X obj 28 394 GEMglVertex3fv;
+#X obj 28 418 GEMglVertex3fv;
+#X obj 403 12 inlet;
+#X obj 444 12 inlet;
+#X obj 485 12 inlet;
+#X obj 524 11 inlet;
+#X obj 563 11 inlet;
+#X obj 603 11 inlet;
+#X obj 28 441 GEMglVertex3fv;
+#X obj 28 465 GEMglVertex3fv;
+#X obj 28 489 GEMglVertex3fv;
+#X obj 27 511 GEMglVertex3fv;
+#X obj 27 535 GEMglVertex3fv;
+#X obj 27 559 GEMglVertex3fv;
+#X obj 27 583 GEMglVertex3fv;
+#X obj 643 13 inlet;
+#X obj 683 13 inlet;
+#X obj 727 13 inlet;
+#X obj 768 13 inlet;
+#X obj 809 13 inlet;
+#X obj 848 12 inlet;
+#X obj 887 12 inlet;
+#X obj 927 12 inlet;
+#X obj 27 605 GEMglVertex3fv;
+#X obj 26 625 GEMglVertex3fv;
+#X obj 26 649 GEMglVertex3fv;
+#X obj 26 672 GEMglVertex3fv;
+#X obj 26 696 GEMglVertex3fv;
+#X obj 26 720 GEMglVertex3fv;
+#X obj 25 742 GEMglVertex3fv;
+#X obj 25 766 GEMglVertex3fv;
+#X obj 25 790 GEMglVertex3fv;
+#X obj 25 814 GEMglVertex3fv;
+#X obj 25 836 GEMglVertex3fv;
+#X obj 970 13 inlet;
+#X obj 1010 13 inlet;
+#X obj 1050 15 inlet;
+#X obj 1090 15 inlet;
+#X obj 1134 15 inlet;
+#X obj 1175 15 inlet;
+#X obj 1216 15 inlet;
+#X obj 1255 14 inlet;
+#X obj 1294 14 inlet;
+#X obj 1334 14 inlet;
+#X connect 0 0 7 0;
+#X connect 1 0 0 1;
+#X connect 2 0 0 0;
+#X connect 3 0 1 0;
+#X connect 4 0 7 1;
+#X connect 5 0 8 1;
+#X connect 7 0 8 0;
+#X connect 8 0 11 0;
+#X connect 9 0 11 1;
+#X connect 10 0 12 1;
+#X connect 11 0 12 0;
+#X connect 12 0 16 0;
+#X connect 13 0 16 1;
+#X connect 14 0 17 1;
+#X connect 15 0 1 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 0;
+#X connect 18 0 19 0;
+#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 30 0;
+#X connect 24 0 18 1;
+#X connect 25 0 19 1;
+#X connect 26 0 20 1;
+#X connect 27 0 21 1;
+#X connect 28 0 22 1;
+#X connect 29 0 23 1;
+#X connect 30 0 31 0;
+#X connect 31 0 32 0;
+#X connect 32 0 33 0;
+#X connect 33 0 34 0;
+#X connect 34 0 35 0;
+#X connect 35 0 36 0;
+#X connect 36 0 45 0;
+#X connect 37 0 30 1;
+#X connect 38 0 31 1;
+#X connect 39 0 32 1;
+#X connect 40 0 33 1;
+#X connect 41 0 34 1;
+#X connect 42 0 35 1;
+#X connect 43 0 36 1;
+#X connect 44 0 45 1;
+#X connect 45 0 46 0;
+#X connect 46 0 47 0;
+#X connect 47 0 48 0;
+#X connect 48 0 49 0;
+#X connect 49 0 50 0;
+#X connect 50 0 51 0;
+#X connect 51 0 52 0;
+#X connect 52 0 53 0;
+#X connect 53 0 54 0;
+#X connect 54 0 55 0;
+#X connect 55 0 6 0;
+#X connect 56 0 46 1;
+#X connect 57 0 47 1;
+#X connect 58 0 48 1;
+#X connect 59 0 49 1;
+#X connect 60 0 50 1;
+#X connect 61 0 51 1;
+#X connect 62 0 52 1;
+#X connect 63 0 53 1;
+#X connect 64 0 54 1;
+#X connect 65 0 55 1;
diff --git a/msd/msd3D/curve2.pd b/msd/msd3D/curve2.pd
new file mode 100644
index 0000000..7fb277b
--- /dev/null
+++ b/msd/msd3D/curve2.pd
@@ -0,0 +1,23 @@
+#N canvas 0 25 1255 894 10;
+#X obj 30 164 GEMglBegin;
+#X obj 86 100 GLdefine GL_LINE_STRIP;
+#X obj 31 13 inlet;
+#X obj 86 77 loadbang;
+#X obj 159 13 inlet;
+#X obj 200 13 inlet;
+#X obj 27 241 GEMglEnd;
+#X obj 30 188 GEMglVertex3fv;
+#X obj 30 212 GEMglVertex3fv;
+#X obj 161 76 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 30 138 GEMglNormal3fv 0 0 1;
+#X connect 0 0 7 0;
+#X connect 1 0 0 1;
+#X connect 2 0 10 0;
+#X connect 3 0 1 0;
+#X connect 4 0 7 1;
+#X connect 5 0 8 1;
+#X connect 7 0 8 0;
+#X connect 8 0 6 0;
+#X connect 9 0 1 0;
+#X connect 10 0 0 0;
diff --git a/msd/msd3D/filet.pd b/msd/msd3D/filet.pd
new file mode 100644
index 0000000..fb67b80
--- /dev/null
+++ b/msd/msd3D/filet.pd
@@ -0,0 +1,106 @@
+#N canvas 543 268 669 547 10;
+#X obj 54 407 outlet;
+#X obj 152 71 f \$5;
+#X obj 188 72 f \$6;
+#X obj 115 17 loadbang;
+#X obj 46 134 repeat 0;
+#X obj 172 101 *;
+#X obj 130 45 t b b b b;
+#X obj 46 164 f -1;
+#X obj 46 188 + 1;
+#X msg 297 77 -1;
+#X obj 46 211 t f f;
+#X obj 150 323 pack f f;
+#X obj 46 50 inlet;
+#X obj 297 28 select reset;
+#X obj 297 5 inlet;
+#X obj 46 89 t b b;
+#X obj 330 175 repeat 0;
+#X obj 330 197 f -1;
+#X obj 330 218 + 1;
+#X obj 381 153 - 1;
+#X obj 387 340 moses;
+#X obj 46 280 + \$1;
+#X obj 176 278 + \$2;
+#X obj 46 234 mod \$6;
+#X obj 176 234 div \$6;
+#X text 445 35 x0 y0 xstep ystep M N;
+#X obj 414 314 - 1;
+#X obj 357 297 mod \$6;
+#X obj 474 300 div \$6;
+#X obj 366 396 + 1;
+#X obj 336 432 pack f f;
+#X obj 344 59 t b b;
+#X obj 375 370 t b;
+#X obj 334 391 f;
+#X obj 330 253 t f f f f;
+#X obj 494 339 moses;
+#X obj 443 431 pack f f;
+#X obj 482 369 t b;
+#X obj 441 390 f;
+#X obj 473 395 + \$6;
+#X obj 521 313 - 1;
+#X obj 46 257 * \$3;
+#X obj 176 256 * \$4;
+#X msg 335 468 link fil \$1 \$2 10 25;
+#X msg 54 359 mass filet 1 180 \$1 \$2 0;
+#X connect 1 0 5 0;
+#X connect 1 0 40 0;
+#X connect 2 0 5 1;
+#X connect 2 0 26 0;
+#X connect 3 0 6 0;
+#X connect 4 0 7 0;
+#X connect 5 0 4 1;
+#X connect 5 0 19 0;
+#X connect 6 2 1 0;
+#X connect 6 3 2 0;
+#X connect 6 3 9 0;
+#X connect 7 0 8 0;
+#X connect 8 0 7 1;
+#X connect 8 0 10 0;
+#X connect 9 0 7 1;
+#X connect 9 0 17 1;
+#X connect 10 0 23 0;
+#X connect 10 1 24 0;
+#X connect 11 0 44 0;
+#X connect 12 0 15 0;
+#X connect 13 0 9 0;
+#X connect 13 0 31 0;
+#X connect 14 0 13 0;
+#X connect 15 0 16 0;
+#X connect 15 1 4 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 0;
+#X connect 18 0 17 1;
+#X connect 18 0 34 0;
+#X connect 19 0 16 1;
+#X connect 20 0 32 0;
+#X connect 21 0 11 0;
+#X connect 22 0 11 1;
+#X connect 23 0 41 0;
+#X connect 24 0 42 0;
+#X connect 26 0 20 1;
+#X connect 27 0 20 0;
+#X connect 28 0 35 0;
+#X connect 29 0 30 1;
+#X connect 30 0 43 0;
+#X connect 31 0 1 0;
+#X connect 31 1 2 0;
+#X connect 32 0 33 0;
+#X connect 33 0 30 0;
+#X connect 34 0 27 0;
+#X connect 34 1 29 0;
+#X connect 34 1 33 1;
+#X connect 34 2 28 0;
+#X connect 34 3 39 0;
+#X connect 34 3 38 1;
+#X connect 35 0 37 0;
+#X connect 36 0 43 0;
+#X connect 37 0 38 0;
+#X connect 38 0 36 0;
+#X connect 39 0 36 1;
+#X connect 40 0 35 1;
+#X connect 41 0 21 0;
+#X connect 42 0 22 0;
+#X connect 43 0 0 0;
+#X connect 44 0 0 0;
diff --git a/msd/msd3D/license.txt b/msd/msd3D/license.txt
new file mode 100644
index 0000000..b1e3f5a
--- /dev/null
+++ b/msd/msd3D/license.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; 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.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/msd/msd3D/main.cpp b/msd/msd3D/main.cpp
new file mode 100644
index 0000000..4eae6c1
--- /dev/null
+++ b/msd/msd3D/main.cpp
@@ -0,0 +1,3 @@
+#include "../src/msd.h"
+
+MSD("msd3D",msd3D,3)
diff --git a/msd/msd3D/msd3D-help.pd b/msd/msd3D/msd3D-help.pd
new file mode 100644
index 0000000..264828c
--- /dev/null
+++ b/msd/msd3D/msd3D-help.pd
@@ -0,0 +1,567 @@
+#N canvas 385 87 553 632 10;
+#X obj 4 369 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 729 cnv 15 550 30 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 8 6 cnv 15 550 30 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 14 389 cnv 15 75 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 14 584 cnv 15 75 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 527 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 4 562 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 7 76 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 679 cnv 15 550 20 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 699 cnv 15 550 30 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#N canvas 76 31 967 770 More_Info 0;
+#X text 123 27 MSD : mass - spring - damper model;
+#X text 53 170 Be careful : if masses are deleted \, lists messages
+won't work;
+#X text 54 75 It is designed to implement particules physical model
+in PD.The model is based on two elements type : mass and link. The
+msd masses are the principals objects of the model. They got only one
+physical parameter \, the value of their mass. They can be mobile or
+fixed \, in this case forces applied on them automatically \, by links
+\, or manually \, by messages \, don't do anything.;
+#X obj 476 19 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 476 318 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity1 4 float 1;
+#A 0 -1 0 1 2;
+#X array zero 4 float 1;
+#A 0 0 0 0 0;
+#X coords 0 3 3 -3 200 150 1;
+#X restore 163 345 graph;
+#X text 221 498 L0;
+#N canvas 127 141 956 727 figure 0;
+#X obj 182 108 loadbang;
+#X msg 191 180 \; rigidity1 resize 1 \; rigidity1 resize 4 \; rigidity1
+bounds 0 3 3 -3 \; rigidity1 0 -1 0 1 2 \; rigidity1 ylabel -0.5 \;
+rigidity1 xlabel -3.5 \; rigidity1 xticks 0 1 1 \; rigidity1 yticks
+0 0.1 5;
+#X obj 388 574 sqrt;
+#X obj 316 651 tabwrite rigidity3;
+#X obj 343 464 - 20;
+#X obj 316 609 f;
+#X obj 316 579 t b f;
+#X obj 343 494 moses 0;
+#X obj 343 517 * -1;
+#X obj 343 538 sqrt;
+#X obj 343 559 * -1;
+#X obj 481 479 - 20;
+#X obj 453 662 f;
+#X obj 453 632 t b f;
+#X obj 481 509 moses 0;
+#X obj 481 532 * -1;
+#X obj 480 612 * -1;
+#X obj 528 622 *;
+#X obj 480 591 *;
+#X obj 525 590 t f f;
+#X obj 480 564 t f f;
+#X obj 453 683 tabwrite rigidity4;
+#X obj 255 350 t b b;
+#X obj 620 552 f;
+#X obj 620 522 t b f;
+#X obj 620 623 tabwrite rigidity2;
+#X msg 763 574 0;
+#X obj 679 437 - 50;
+#X obj 751 491 moses 40;
+#X obj 681 510 moses -40;
+#X obj 620 586 * 1.5;
+#X obj 680 462 moses 10;
+#X obj 680 488 moses -10;
+#X msg 55 419 \; rigidity2 resize 101 \; rigidity2 xticks 1 10 5 \;
+rigidity2 yticks 0 5 5 \; rigidity3 resize 51 \; rigidity3 xticks 0
+1 5 \; rigidity3 yticks 0 1 5 \; rigidity4 resize 51 \; rigidity4 xticks
+0 1 5 \; rigidity4 yticks 0 100 5;
+#X msg 405 333 0;
+#X obj 405 361 f;
+#X obj 405 390 moses 50.5;
+#X obj 407 418 t f f;
+#X obj 408 446 + 1;
+#X msg 598 314 0;
+#X obj 598 342 f;
+#X obj 600 399 t f f;
+#X obj 601 427 + 1;
+#X obj 598 370 moses 100.5;
+#X obj 267 322 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X connect 0 0 1 0;
+#X connect 0 0 22 0;
+#X connect 2 0 5 1;
+#X connect 4 0 7 0;
+#X connect 5 0 3 0;
+#X connect 6 0 5 0;
+#X connect 6 1 3 1;
+#X connect 7 0 8 0;
+#X connect 7 1 2 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 5 1;
+#X connect 11 0 14 0;
+#X connect 12 0 21 0;
+#X connect 13 0 12 0;
+#X connect 13 1 21 1;
+#X connect 14 0 15 0;
+#X connect 14 1 19 0;
+#X connect 15 0 20 0;
+#X connect 16 0 12 1;
+#X connect 17 0 12 1;
+#X connect 18 0 16 0;
+#X connect 19 0 17 0;
+#X connect 19 1 17 1;
+#X connect 20 0 18 0;
+#X connect 20 1 18 1;
+#X connect 22 0 34 0;
+#X connect 22 1 33 0;
+#X connect 22 1 39 0;
+#X connect 23 0 30 0;
+#X connect 24 0 23 0;
+#X connect 24 1 25 1;
+#X connect 26 0 23 1;
+#X connect 27 0 31 0;
+#X connect 28 0 23 1;
+#X connect 28 1 26 0;
+#X connect 29 0 26 0;
+#X connect 29 1 23 1;
+#X connect 30 0 25 0;
+#X connect 31 0 32 0;
+#X connect 31 1 28 0;
+#X connect 32 0 29 0;
+#X connect 32 1 26 0;
+#X connect 34 0 35 0;
+#X connect 35 0 36 0;
+#X connect 36 0 37 0;
+#X connect 37 0 38 0;
+#X connect 37 1 4 0;
+#X connect 37 1 6 0;
+#X connect 37 1 13 0;
+#X connect 37 1 11 0;
+#X connect 38 0 35 0;
+#X connect 39 0 40 0;
+#X connect 40 0 43 0;
+#X connect 41 0 42 0;
+#X connect 41 1 27 0;
+#X connect 41 1 24 0;
+#X connect 42 0 40 0;
+#X connect 43 0 41 0;
+#X connect 44 0 22 0;
+#X restore 439 721 pd figure;
+#X text 167 322 Rigidity;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity2 101 float 1;
+#A 0 0 0 0 0 0 0 0 0 0 0 -60 -58.5 -57 -55.5 -54 -52.5 -51 -49.5 -48
+-46.5 -45 -43.5 -42 -40.5 -39 -37.5 -36 -34.5 -33 -31.5 -30 -28.5 -27
+-25.5 -24 -22.5 -21 -19.5 -18 -16.5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 15 16.5 18 19.5 21 22.5 24 25.5 27 28.5 30 31.5 33 34.5 36
+37.5 39 40.5 42 43.5 45 46.5 48 49.5 51 52.5 54 55.5 57 58.5 0 0 0
+0 0 0 0 0 0 0 0;
+#X array zero 101 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
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 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 60 100 -60 200 150 1;
+#X restore 578 341 graph;
+#X text 670 496 L0;
+#X text 583 318 Rigidity with Lmin and Lmax;
+#X text 686 496 Lmin;
+#X text 748 496 Lmax;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity3 51 float 1;
+#A 0 -4.47214 -4.3589 -4.24264 -4.12311 -4 -3.87298 -3.74166 -3.60555
+-3.4641 -3.31662 -3.16228 -3 -2.82843 -2.64575 -2.44949 -2.23607 -2
+-1.73205 -1.41421 -1 0 1 1.41421 1.73205 2 2.23607 2.44949 2.64575
+2.82843 3 3.16228 3.31662 3.4641 3.60555 3.74166 3.87298 4 4.12311
+4.24264 4.3589 4.47214 4.58258 4.69042 4.79583 4.89898 5 5.09902 5.19615
+5.2915 5.38516 5.47723;
+#X array zero 51 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
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
+#X coords 0 6 50 -6 200 150 1;
+#X restore 162 547 graph;
+#X text 235 700 L0;
+#X text 167 525 Rigidity with power = 1/2;
+#N canvas 0 22 450 300 (subpatch) 0;
+#X array rigidity4 51 float 1;
+#A 0 0 -400 -361 -324 -289 -256 -225 -196 -169 -144 -121 -100 -81 -64
+-49 -36 -25 -16 -9 -4 -1 0 1 4 9 16 25 36 49 64 81 100 121 144 169
+196 225 256 289 324 361 400 441 484 529 576 625 676 729 784 841;
+#X array zero 51 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
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
+#X coords 0 1000 50 -1000 200 150 1;
+#X restore 575 551 graph;
+#X text 648 705 L0;
+#X text 582 529 Rigidity with power = 2;
+#X text 601 26 The equations are :;
+#X text 525 50 if Lmin<|L[n]-L[0]|<Lmax;
+#X text 524 89 else;
+#X text 533 109 F[n] = D(L[n]-L[n-1]);
+#X text 533 69 F[n] = K(L[n] - L[0])^P + D(L[n] - L[n-1]);
+#X text 53 202 Links connect masses two by two. They got 4 physicals
+parameters : length \, rigidity \, damping and power.;
+#X text 52 231 Rigidity \, damping and power are defined by the creation
+message. The lenght is initialised to the distance between the two
+masses at the creation.;
+#X text 524 284 You can build specific links using different links
+messages defining the characteristic step by step.;
+#X text 51 272 Links can be created in one shot between mutiples masses
+\, instead of creation number \, the masses linked are defined with
+their Id.;
+#X text 533 250 x1x2 + y1y2 + z1z2 = 0;
+#X text 525 138 For oriented links \, the force F[n] is projected using
+a vector which is given during the creation of the link using x1y1z1
+coordinates.;
+#X text 524 179 For tangentials links \, the force is projected onto
+the given vector x1y1z1.;
+#X text 533 266 x1x3 + y1y3 + z1z3 = 0;
+#X text 524 209 For normals links \, the force is projected onto a
+plane define with x2y2z2 and x3y3z3 calculated with the scalar products
+:;
+#X text 55 56 MSD is the 3D object of the msd objects collection.;
+#X connect 3 0 4 0;
+#X restore 16 735 pd More_Info;
+#X text 12 76 Examples:;
+#X text 9 369 Inlets:;
+#X text 19 388 - Left:;
+#X text 10 526 Arguments:;
+#X text 11 562 Outlets:;
+#X text 19 679 See Also:;
+#X text 74 48 Full Name:;
+#N canvas 58 22 262 70 Related_Objects 0;
+#X obj 3 10 cnv 15 250 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 3 30 cnv 15 250 30 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X text 5 10 Externals and libraries;
+#X obj 44 37 msd;
+#X obj 141 38 msd2D;
+#X restore 122 735 pd Related_Objects;
+#N canvas 257 262 759 345 init 0;
+#X obj 89 215 t a;
+#X obj 89 33 loadbang;
+#X obj 89 241 s \$0-in;
+#X obj 89 59 t b b b b b;
+#X msg 161 80 reset;
+#X obj 44 13 inlet;
+#X msg 107 161 link souple fix mob 10 10 \, link souple mob mob 10
+10;
+#X msg 125 120 mass mob 1 100 0 -2 0 \, mass mob 1 100 2 0 0 \, mass
+mob 1 100 0 2 0 \, mass mob 1 100 -2 0 0;
+#X msg 89 187 Xmax 4 \, Xmin -4 \, Ymax 4 \, Ymin -4 \, Zmax 4 \, Zmin
+-4;
+#X msg 143 100 mass fix 0 10 0 0 0;
+#X connect 0 0 2 0;
+#X connect 1 0 3 0;
+#X connect 3 0 8 0;
+#X connect 3 1 6 0;
+#X connect 3 2 7 0;
+#X connect 3 3 9 0;
+#X connect 3 4 4 0;
+#X connect 4 0 0 0;
+#X connect 5 0 3 0;
+#X connect 6 0 0 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 0;
+#X connect 9 0 0 0;
+#X restore 17 156 pd init;
+#X obj 18 321 s \$0-out;
+#X obj 18 272 r \$0-in;
+#X obj 393 317 s \$0-in;
+#N canvas 565 515 355 193 compute 0;
+#X obj 27 29 inlet;
+#X obj 27 127 s \$0-in;
+#X msg 27 96 bang \, get massesPos \, get linksPos;
+#X obj 27 66 gemhead;
+#X obj 160 36 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X connect 0 0 3 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X connect 4 0 2 0;
+#X restore 17 209 pd compute;
+#X obj 17 181 tgl 15 0 empty empty ON/OFF 25 10 1 10 -262144 -1 -1
+0 1;
+#X obj 172 270 r \$0-out;
+#X obj 17 126 bng 15 250 50 0 empty empty reset 25 10 1 10 -262144
+-1 -1;
+#X text 101 388 Bang - A bang at the left inlet compute the new model
+state based on previous instant.;
+#X text 158 478 To set the model parameters after creation.;
+#X text 158 456 To create the model masses and links.;
+#X text 158 501 To get the model parameters;
+#N canvas 8 28 963 606 creation________ 0;
+#X obj 5 75 cnv 15 450 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 3 cnv 15 450 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X text 7 2 CREATION Messages;
+#X obj 4 137 cnv 15 450 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 3 329 cnv 15 450 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X msg 32 104 reset;
+#X text 245 168 Add a mass;
+#X text 70 191 \$1 : Id (symbol);
+#X text 69 211 \$2 : fixed or mobile (0/1);
+#X text 69 229 \$3 : mass;
+#X msg 32 277 deleteMass \$1;
+#X text 171 276 Delete a mass and associated links;
+#X text 66 302 \$1 : Creation No of mass;
+#X text 7 137 Masses :;
+#X text 7 74 Reset :;
+#X text 100 105 Delete all masses \, links and internal variables;
+#X text 6 329 Links :;
+#X text 62 388 \$1 : Id (symbol);
+#X text 62 441 \$4 : rigidity;
+#X msg 30 542 deleteLink \$1;
+#X text 164 542 Delete a link;
+#X text 57 570 \$1 : Creation No of link;
+#X text 62 388 \$1 : Id (symbol);
+#X text 62 441 \$4 : rigidity;
+#X text 62 406 \$2 : creation No/Id of mass1;
+#X text 62 424 \$3 : creation No/Id of mass2;
+#X text 281 363 Add link(s);
+#X text 62 459 \$5 : damping;
+#X text 10 28 Creation messages are used to define the structure of
+the model. Messages create links and masses or destroy them.;
+#X msg 30 362 link \$1 \$2 \$3 \$4 \$5 (\$6 \$7 \$8);
+#X text 59 477 (\$6) : Power of the rigidity distance;
+#X text 59 496 (\$7) : minimum lenght of link;
+#X text 59 513 (\$8) : maximum lenght of link;
+#X obj 461 3 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 482 75 cnv 15 450 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 461 572 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 519 197 \$1 : Id (symbol);
+#X text 519 250 \$4 : rigidity;
+#X text 519 197 \$1 : Id (symbol);
+#X text 519 250 \$4 : rigidity;
+#X text 519 215 \$2 : creation No/Id of mass1;
+#X text 519 233 \$3 : creation No/Id of mass2;
+#X text 519 268 \$5 : damping;
+#X text 799 169 Add tangential link(s);
+#X text 516 306 (\$8) : Power of the rigidity distance;
+#X text 516 325 (\$9) : minimum lenght of link;
+#X text 516 342 (\$10) : maximum lenght of link;
+#X text 485 75 Oriented links :;
+#X msg 32 167 mass \$1 \$2 \$3 \$4 \$5 \$6;
+#X msg 489 168 tLink \$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 (\$9 \$10 \$11)
+;
+#X text 69 247 \$4 \, \$5 \, \$8 : initial position;
+#X text 487 102 In 2D (and 3D) there are two specials links : oriented
+links. They works as general links excepts their calculation is made
+following a vector for tangentials links or a plane for normals links.
+;
+#X text 518 287 \$6 \, \$7 \, \$8 : tangential vector (x \, y \, z)
+;
+#X connect 33 0 35 0;
+#X restore 12 457 pd creation________;
+#X text 103 542 None;
+#X text 18 583 - Left:;
+#X text 101 584 Outputs the model parameters asked with the attributes
+messages.;
+#X obj 13 629 cnv 15 75 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X text 17 628 - Right:;
+#X text 100 629 Outputs information on model when creation messages
+are send or with the special message [infosL( which dump the complete
+state of the model.;
+#X text 101 420 Messages - Different messages are used to control the
+msd object. They are of three types :;
+#X text 9 701 CATEGORY: control;
+#N canvas 354 125 579 668 dynamic 0;
+#X obj 5 3 cnv 15 550 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 10 85 cnv 15 150 300 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 62 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 10 420 cnv 15 130 180 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 3 396 cnv 15 550 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X text 7 62 Masses :;
+#X text 6 396 Links :;
+#X text 7 2 DYNAMIC SETTINGS Messages;
+#X msg 30 88 posX \$1 \$2;
+#X text 190 148 Add force on mass(es);
+#X msg 30 151 forceX \$1 \$2;
+#X text 192 232 \$1 : Value;
+#X text 193 107 \$1 : Id (symbol) or No;
+#X text 193 165 \$1 : Id (symbol) or No;
+#X msg 30 215 Xmin \$1;
+#X msg 88 215 Xmax \$1;
+#X msg 30 278 setMobile \$1;
+#X msg 30 299 setFixed \$1;
+#X text 193 89 Set position of fixed mass(es);
+#X text 193 125 \$2 : Value;
+#X text 193 183 \$2 : Value;
+#X text 189 216 Set minimimum and maximum position of all masses;
+#X text 189 278 Set mass to mobile or fixed;
+#X msg 29 484 setD \$1 \$2;
+#X text 184 470 \$2 : New value;
+#X msg 29 433 setK \$1 \$2;
+#X text 184 526 \$2 : New value;
+#X text 184 579 \$2 : New value;
+#X text 178 434 Set rigidity of link(s);
+#X text 178 490 Set damping of link(s);
+#X msg 29 539 setL \$1 \$2;
+#X text 178 543 Set initial lenght of link(s);
+#X text 184 452 \$1 : Id (symbol) or No;
+#X text 184 508 \$1 : Id (symbol) or No;
+#X text 184 561 \$1 : Id (symbol) or No;
+#X text 192 295 \$1 : Id (symbol) or No;
+#X text 10 25 Dynamic settings messages allows the user to redefine
+internal parameters of links and masses.;
+#X msg 30 329 grabMass \$1 \$2 \$3;
+#X text 187 329 Grab nearest mass;
+#X text 192 345 \$1 \, \$2 : position;
+#X text 191 362 \$3 : grab or not (0/1);
+#X msg 30 234 Ymin \$1;
+#X msg 89 234 Ymax \$1;
+#X msg 30 107 posY \$1 \$2;
+#X msg 30 171 forceY \$1 \$2;
+#X msg 30 126 posZ \$1 \$2;
+#X msg 30 191 forceZ \$1 \$2;
+#X msg 30 253 Zmin \$1;
+#X msg 89 253 Zmax \$1;
+#X restore 12 478 pd dynamic settings;
+#N canvas 675 41 600 721 attributes______ 0;
+#X obj 11 95 cnv 15 100 35 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 5 75 cnv 15 590 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 5 3 cnv 15 590 15 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 10 158 cnv 15 150 130 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 137 cnv 15 590 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X obj 10 314 cnv 15 110 330 empty empty empty 20 12 0 14 -233017 -66577
+0;
+#X obj 4 290 cnv 15 590 15 empty empty empty 20 12 0 14 -158509 -66577
+0;
+#X text 7 74 General :;
+#X text 7 2 ATTRIBUTES Messages;
+#X text 7 137 Lists :;
+#X msg 33 104 infosL;
+#X text 136 104 Get infos on all masses and links on right outlet;
+#X msg 32 170 massesPosL;
+#X msg 31 255 massesForcesL;
+#X text 171 170 Output all masses positions in a list on outlet No
+1;
+#X text 140 330 Get specific attribute on specific element;
+#X msg 20 328 get \$1 (\$2);
+#X text 7 290 Specific :;
+#X text 140 425 The get message return the asked attribute preceded
+by an identifier and the creation No of the element. The identifier
+is made of the asked parameter and the way you asked for it.;
+#X text 141 501 message;
+#X text 381 501 response;
+#X text 140 482 Examples with 3 masses numbered 0 \, 1 and 2 and named
+mas:;
+#X text 15 30 The attributes messages ask the object to output some
+of his internal parameters. They can be output by lists for positions
+and forces of masses.;
+#X text 171 256 Output all forces applied on masses in a list on outlet
+No 1;
+#X text 140 392 (\$2) : - If not defined all the attributes are send
+for all the elements. - Ids or/and creations No;
+#X text 174 520 [get massesPos( -----> [massesPos 0 x0 y0 z0(;
+#X text 335 534 [massesPos 2 x2 y2 z2(;
+#X text 335 548 [massesPos 1 x1 y1 z1(;
+#X text 160 570 [get massesPos 1( -----> [massesPosNo 1 x1 y1 z1(;
+#X text 146 591 [get massesPos mas( -----> [massesPosId 0 x0 y0 z0(
+;
+#X text 335 606 [massesPosId 2 x2 y2 z2(;
+#X text 335 621 [massesPosId 1 x1 y1 z1(;
+#X msg 32 194 massesPosXL;
+#X msg 32 215 massesPosYL;
+#X msg 32 234 massesPosZL;
+#X text 171 215 Output all masses x \, y or z in a list on outlet No
+1;
+#X text 141 349 \$1 : Attribute type ( massesPos / massesPosName /
+massesSpeeds / massesSpeedsName / massesForces / massesForces / linksPos
+/ linksPos );
+#X text 147 645 [get massesPosName( -----> [massesPosName name_0 x0
+y0 z0(;
+#X text 337 660 [massesPosName name_2 x2 y2 z2(;
+#X text 337 675 [massesPosName name_1 x1 y1 z1(;
+#X restore 12 499 pd attributes______;
+#X text 9 711 KEYWORDS: physical model mass spring damper link;
+#X text 267 736 - Nicolas Montgermont \, May 12 \, 2005;
+#X obj 172 294 route massesPos linksPos;
+#X obj 336 216 gemwin;
+#X msg 336 194 0 \, destroy;
+#N canvas 363 318 550 319 gemrender 0;
+#X obj 48 203 translateXYZ;
+#X obj 48 229 sphere 0.1;
+#X obj 127 24 inlet;
+#X obj 390 13 inlet;
+#X obj 303 213 curve 2;
+#X obj 125 136 t b f;
+#X obj 127 62 unpack f f f f;
+#X msg 390 58 \$2 \$3 \$4;
+#X msg 462 62 \$5 \$6 \$7;
+#X obj 48 167 gemhead;
+#X msg 48 143 0;
+#X obj 48 115 loadbang;
+#X obj 303 147 gemhead;
+#X msg 303 123 0;
+#X obj 303 95 loadbang;
+#X obj 390 86 t b l;
+#X connect 0 0 1 0;
+#X connect 2 0 6 0;
+#X connect 3 0 8 0;
+#X connect 3 0 7 0;
+#X connect 5 0 9 0;
+#X connect 5 1 0 1;
+#X connect 6 1 5 0;
+#X connect 6 2 0 2;
+#X connect 6 3 0 3;
+#X connect 7 0 15 0;
+#X connect 8 0 4 2;
+#X connect 9 0 0 0;
+#X connect 10 0 9 0;
+#X connect 11 0 10 0;
+#X connect 12 0 4 0;
+#X connect 13 0 12 0;
+#X connect 14 0 13 0;
+#X connect 15 0 12 0;
+#X connect 15 1 4 1;
+#X restore 172 321 pd gemrender;
+#X msg 336 129 reset \, create \, 1;
+#X text 12 8 HELP: msd3D;
+#X text 12 18 DESCRIPTION: Mass spring damper physical modeling in
+3D.;
+#X obj 157 48 msd3D;
+#X text 112 680 01_msd3Dtest.pd;
+#X obj 18 296 msd3D;
+#X msg 393 271 forceZ mob -10;
+#X msg 393 293 forceZ mob 10;
+#X text 392 246 2 Send forces;
+#X text 170 132 1 Create window -->;
+#X text 170 195 3 And destroy it -->;
+#X connect 21 0 53 0;
+#X connect 24 0 23 0;
+#X connect 25 0 44 0;
+#X connect 26 0 19 0;
+#X connect 44 0 47 0;
+#X connect 44 1 47 1;
+#X connect 46 0 45 0;
+#X connect 48 0 45 0;
+#X connect 53 0 20 0;
+#X connect 54 0 22 0;
+#X connect 55 0 22 0;
diff --git a/msd/msd3D/package.txt b/msd/msd3D/package.txt
new file mode 100644
index 0000000..929ff95
--- /dev/null
+++ b/msd/msd3D/package.txt
@@ -0,0 +1,4 @@
+NAME=msd3D
+SRCS=main.cpp
+HDRS=../src/msd.h
+
diff --git a/msd/msd3D/partiel.pd b/msd/msd3D/partiel.pd
new file mode 100644
index 0000000..f7d89a0
--- /dev/null
+++ b/msd/msd3D/partiel.pd
@@ -0,0 +1,29 @@
+#N canvas 0 0 508 377 10;
+#X obj 136 26 inlet;
+#X obj 133 281 outlet~;
+#X obj 174 189 line~;
+#X obj 134 193 *~;
+#X obj 133 148 osc~ 55;
+#X msg 172 61 \$3;
+#X obj 260 170 mtof;
+#X msg 174 167 \$1 50;
+#X msg 131 60 \$2;
+#X obj 131 119 / 2;
+#X obj 131 88 abs;
+#X obj 174 86 abs;
+#X obj 177 108 * 5;
+#X obj 187 136 + 10;
+#X connect 0 0 8 0;
+#X connect 0 0 5 0;
+#X connect 2 0 3 1;
+#X connect 3 0 1 0;
+#X connect 4 0 3 0;
+#X connect 5 0 11 0;
+#X connect 6 0 4 0;
+#X connect 7 0 2 0;
+#X connect 8 0 10 0;
+#X connect 9 0 7 0;
+#X connect 10 0 9 0;
+#X connect 11 0 12 0;
+#X connect 12 0 13 0;
+#X connect 13 0 6 0;
diff --git a/msd/msdND/build.txt b/msd/msdND/build.txt
new file mode 100644
index 0000000..8b45fcb
--- /dev/null
+++ b/msd/msdND/build.txt
@@ -0,0 +1,19 @@
+
+msd can be compiled in other dimension than 1D, 2D or 3D.
+
+To do that, edit the main.cpp and the package.txt files in the msdND folder and replace "N" with the dimension you want.
+
+For example, in 13D :
+
+main.cpp file:
+
+#include "../msd.h"
+MSD("msd13D",msd13D,13)
+
+package.txt file:
+
+NAME=msd13D
+SRCS=main.cpp
+HDRS=../msd.h
+
+And then compile using flext as usual. You call it in Max/PD using the name you entered, "msd13D" here.
diff --git a/msd/msdND/license.txt b/msd/msdND/license.txt
new file mode 100644
index 0000000..b1e3f5a
--- /dev/null
+++ b/msd/msdND/license.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; 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.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/msd/msdND/main.cpp b/msd/msdND/main.cpp
new file mode 100644
index 0000000..33b4e84
--- /dev/null
+++ b/msd/msdND/main.cpp
@@ -0,0 +1,4 @@
+#include "../src/msd.h"
+// replace N with the number of dimension
+// ex: MSD("msd13D",msd13D,13) for 13D
+MSD("msdND",msdND,N)
diff --git a/msd/msdND/package.txt b/msd/msdND/package.txt
new file mode 100644
index 0000000..bdc8838
--- /dev/null
+++ b/msd/msdND/package.txt
@@ -0,0 +1,4 @@
+NAME=msdND
+SRCS=main.cpp
+HDRS=../src/msd.h
+
diff --git a/msd/src/build.sh b/msd/src/build.sh
new file mode 100755
index 0000000..4f3b3d3
--- /dev/null
+++ b/msd/src/build.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# build the 3 msd objects using flext and its configuration
+
+
+# build
+cd ../msd
+../../../grill/flext/build.sh pd gcc
+cd ../msd2D
+../../../grill/flext/build.sh pd gcc
+cd ../msd3D
+../../../grill/flext/build.sh pd gcc
+cd ../src
+
+# move objects
+UNAME=`uname -s`
+if [ $UNAME = "Darwin" ]
+then
+ mv ../msd/pd-darwin/release-single/msd.pd_darwin ../msd/msd.pd_darwin
+ mv ../msd2D/pd-darwin/release-single/msd2D.pd_darwin ../msd2D/msd2D.pd_darwin
+ mv ../msd3D/pd-darwin/release-single/msd3D.pd_darwin ../msd3D/msd3D.pd_darwin
+fi
+
+if [ $UNAME = "Linux" ]
+then
+ cd ../msd
+ ../../../grill/flext/build.sh pd gcc install
+ cd ../msd2D
+ ../../../grill/flext/build.sh pd gcc install
+ cd ../msd3D
+ ../../../grill/flext/build.sh pd gcc install
+ cd ../src
+fi
diff --git a/msd/src/msd.h b/msd/src/msd.h
new file mode 100644
index 0000000..353002d
--- /dev/null
+++ b/msd/src/msd.h
@@ -0,0 +1,2111 @@
+
+
+/*
+ msd - mass spring damper model for Pure Data or Max/MSP
+
+ Copyright (C) 2005 Nicolas Montgermont
+ Written by Nicolas Montgermont
+ Optimized by Thomas Grill for Flext
+ Based on pmpd by Cyrille Henry
+ Based on Pure Data by Miller Puckette and others
+
+ Contact : Nicolas Montgermont, nicolas_montgermont @ yahoo dot fr
+ Cyrille Henry, Cyrille.Henry @ la-kitchen dot fr
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ Version 0.09 -- 12.09.2010
+*/
+
+// include flext header
+#include <flext.h>
+#include <flmap.h>
+#include <math.h>
+#include <string.h>
+#include <vector>
+
+// define constants
+#define MSD_VERSION 0.09
+#define PI 3.1415926535
+
+// check for appropriate flext version
+#if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500)
+#error You need at least flext version 0.5.0
+#endif
+
+#ifdef _MSC_VER
+#define NEWARR(type,var,size) type *var = new type[size]
+#define DELARR(var) delete[] var
+#else
+#define NEWARR(type,var,size) type var[size]
+#define DELARR(var) ((void)0)
+#endif
+
+// Maths functions
+inline t_float sqr(t_float x) { return x*x; }
+
+template<int N> class Link;
+
+class t_buffer {
+public:
+ t_int nbr;
+ const t_symbol *Id;
+ flext::buffer *buf;
+ bool tested;
+ t_int size;
+
+ t_buffer(t_int n,const t_symbol *id):nbr(n),Id(id) {
+ buf = new flext::buffer(Id);
+ tested=true;
+ if(!buf->Ok()) {
+ post("error : table %s not found!", *Id);
+ tested = false;
+ }
+ }
+
+ ~t_buffer() {
+ if(buf) {
+ delete buf;
+ buf=NULL;
+ Id=NULL;
+ }
+ }
+
+ inline void buffer_test() {
+ if(!buf || !buf->Ok() ) {
+ post("no %s table",*Id);
+ tested = false;
+ }
+ else if(!buf->Valid()) {
+ post("no valid %s table",*Id);
+ tested = false;
+ }
+ else {
+ if(!buf || buf->Update()) {
+ // buffer parameters have been updated
+ if(buf->Valid()) {
+ post("updated buffer %s reference", *Id);
+ tested = true;
+ }
+ else {
+ post("buffer %s has become invalid", *Id);
+ tested = false;
+ }
+ }
+ else
+ tested = true;
+ }
+ }
+
+ inline t_float interp_buf(t_float indexf, t_float factor) {
+ t_float size_buf=buf->Frames();
+ t_float index_factor = indexf*(size_buf-1)/factor;
+ if (index_factor > size_buf - 1)
+ return buf->Data()[(int)size_buf - 1];
+ else if (index_factor < 0)
+ return buf->Data()[0];
+ else {
+ t_int index = floor(index_factor);
+ t_float interp = index_factor - (float)index;
+ if (index==index_factor)
+ return buf->Data()[index];
+ else
+ return (1-interp) * buf->Data()[index] + interp * buf->Data()[index+1];
+ }
+ }
+};
+
+template<int N>
+class LinkList : public std::vector<Link<N> *> {
+public:
+ void insert(Link<N> *l)
+ {
+ for(typename LinkList<N>::iterator it = this->begin(); it != this->end(); ++it)
+ if(*it == l) return;
+ // not found -> add
+ push_back(l);
+ }
+
+ void erase(Link<N> *l)
+ {
+ for(typename LinkList<N>::iterator it = this->begin(); it != this->end(); ++it)
+ if(*it == l) {
+ // found
+ std::vector<Link<N> *>::erase(it);
+ return;
+ }
+ }
+};
+
+template<int N>
+class Mass {
+public:
+ t_int nbr;
+ const t_symbol *Id;
+ t_float M,invM;
+ t_float speed[N];
+ t_float pos[N];
+ t_float pos2[N];
+ t_float force[N];
+ t_float out_force[N];
+ LinkList<N> links;
+
+ Mass(t_int n,const t_symbol *id,bool mob,t_float m,t_float p[N])
+ : nbr(n),Id(id)
+ , M(m)
+ {
+ if(mob) setMobile(); else setFixed();
+
+ for(int i = 0; i < N; ++i) {
+ pos[i] = pos2[i] = p[i];
+ force[i] = speed[i] = 0;
+ }
+ }
+
+ inline void setForce(int n,t_float f) { force[n] += f; }
+
+ inline void setForce(t_float f[N])
+ {
+ for(int i = 0; i < N; ++i) setForce(i,f[i]);
+ }
+
+ inline void setPos(int n,t_float p) { pos[n] = pos2[n] = p; }
+
+ inline void setPos(t_float p[N])
+ {
+ for(int i = 0; i < N; ++i) setPos(i,p[i]);
+ }
+
+ inline bool getMobile() const { return invM != 0; }
+
+ inline void setMobile() { invM = M?1/M:0.; }
+ inline void setFixed() { invM = 0; }
+
+ inline void compute(t_float limit[N][2])
+ {
+ for(int i = 0; i < N; ++i) {
+ t_float pold = pos[i];
+ t_float pnew;
+ if(invM) // if mass is mobile
+ pnew = force[i] * invM + 2*pold - pos2[i]; // x[n] =Fx[n]/M+2x[n]-x[n-1]
+ else // if mass is fixed
+ pnew = pos[i];
+
+ // check limit
+ if(pnew < limit[i][0]) pnew = limit[i][0]; else if(pnew > limit[i][1]) pnew = limit[i][1];
+ speed[i] = (pos[i] = pnew) - (pos2[i] = pold); // x[n-2] = x[n-1], x[n-1] = x[n],vx[n] = x[n] - x[n-1]
+
+ // clear forces
+ out_force[i] = force[i];
+ force[i] = 0; // Fx[n] = 0
+ }
+ }
+
+ static inline t_float dist(const Mass &m1,const Mass &m2)
+ {
+ if(N == 1)
+ return fabs(m1.pos[0]-m2.pos[0]); // L[n] = |x1 - x2|
+ else {
+ t_float distance = 0;
+ for(int i = 0; i < N; ++i) distance += sqr(m1.pos[i]-m2.pos[i]);
+ return sqrt(distance);
+ }
+ }
+};
+
+template<int N>
+class Link {
+
+public:
+ t_int nbr;
+ const t_symbol *Id;
+ Mass<N> *mass1,*mass2;
+ t_float K1, D1, D2;
+ t_float longueur, long_min, long_max;
+ t_float distance_old;
+ t_float puissance;
+ t_int link_type; //0 : no, 1 : tangential, 2 : normal, 3 : table
+ t_float tdirection1[N], tdirection2[N];
+ t_float l_tab, l_tab2;
+ t_int buffer_tested;
+ t_buffer *k_buffer,*d_buffer;
+
+ Link(t_int n,const t_symbol *id,Mass<N> *m1,Mass<N> *m2,t_float k1,t_float d1, t_int o=0, t_float tangent[N]=NULL,t_float pow=1, t_float lmin = 0,t_float lmax = 1e10,t_buffer *ktab=NULL, t_float ltab=1, t_buffer *dtab=NULL, t_float ltab2=1)
+ : nbr(n),Id(id)
+ , mass1(m1),mass2(m2)
+ , K1(k1),D1(d1),D2(0),link_type(o),puissance(pow)
+ , long_min(lmin),long_max(lmax)
+ , l_tab(ltab), l_tab2(ltab2)
+ , buffer_tested(1)
+ , k_buffer(ktab),d_buffer(dtab)
+ {
+ for (int i=0; i<N; i++) {
+ tdirection1[i] = 0;
+ tdirection2[i] = 0;
+ }
+ if (link_type == 1) { // TANGENTIAL LINK
+ t_float norme = 0;
+ for(int i = 0; i < N; ++i)
+ norme += sqr(tangent[i]);
+ norme = sqrt(norme);
+ for(int i = 0; i < N; ++i)
+ tdirection1[i] = tangent[i]/norme;
+ distance_old = 0;
+ for(int i = 0; i < N; ++i)
+ distance_old += sqr((m1->pos[i]-m2->pos[i])*tdirection1[i]);
+ distance_old = sqrt(distance_old);
+ longueur = distance_old;
+ }
+ else
+ distance_old = longueur = Mass<N>::dist(*mass1,*mass2); // L[n-1]
+ mass1->links.insert(this);
+ mass2->links.insert(this);
+ }
+
+ ~Link() {
+ mass1->links.erase(this);
+ mass2->links.erase(this);
+ }
+
+ // compute link forces
+ inline void compute()
+ {
+ t_float distance=0;
+ t_float F;
+ Mass<N> *m1 = mass1,*m2 = mass2; // cache locally
+ if (m1->invM || m2->invM) {
+ if (link_type == 1) {
+ for(int i = 0; i < N; ++i)
+ distance += sqr((m1->pos[i]-m2->pos[i])*tdirection1[i]);
+ distance = sqrt(distance);
+ }
+ else if (link_type == 2) {
+ for(int i = 0; i < N; ++i)
+ distance += sqr((m1->pos[i]-m2->pos[i])*(tdirection1[i] +tdirection2[i]));
+ distance = sqrt(distance);
+ }
+ else
+ distance = Mass<N>::dist(*m1,*m2);
+
+ if (distance < long_min || distance > long_max || distance == 0) {
+ // pas de forces
+ }
+ else { // Lmin < L < Lmax
+ // F[n] = k1 (L[n] - L[0])/L[n] + D1 (L[n] - L[n-1])/L[n]
+ if (link_type == 3 ) {//&& buffer_tested) { // tabLink
+ t_float k_temp = distance-longueur;
+ if (k_buffer && k_buffer->tested) {
+ k_temp = k_buffer->interp_buf(distance,l_tab);
+ }
+ t_float d_temp = distance-distance_old;
+ if (d_buffer && d_buffer->tested) {
+ if (distance>distance_old)
+ d_temp = d_buffer->interp_buf(distance-distance_old,l_tab2);
+ else
+ d_temp = -d_buffer->interp_buf(distance_old - distance,l_tab2);
+ }
+ F = (K1*k_temp + D1*d_temp)/distance;
+ }
+ else {
+ if ((distance - longueur)>0)
+ F = (K1 * pow(distance - longueur,puissance) + D1 * (distance - distance_old))/distance ;
+ else
+ F = (-K1 * pow(longueur - distance,puissance) + D1 * (distance - distance_old))/distance ;
+ }
+ if (link_type == 1 || (link_type == 2 && N == 2)) // tangential
+ for(int i = 0; i < N; ++i) {
+ const t_float Fn = F * (m1->pos[i] - m2->pos[i])*tdirection1[i]; // Fx = F * Lx[n]/L[n]
+ m1->force[i] -= Fn + D2 * m1->speed[i]; // Fx1[n] = -Fx, Fx1[n] = Fx1[n] - D2 * vx1[n-1]
+ m2->force[i] += Fn - D2 * m2->speed[i]; // Fx2[n] = Fx, Fx2[n] = Fx2[n] - D2 * vx2[n-1]
+ }
+ else if (link_type == 2 && N == 3) // deprecated
+ for(int i = 0; i < N; ++i) {
+ const t_float Fn = F * (m1->pos[i] - m2->pos[i])*(tdirection1[i] +tdirection2[i]); // Fx = F * Lx[n]/L[n]
+ m1->force[i] -= Fn + D2 * m1->speed[i]; // Fx1[n] = -Fx, Fx1[n] = Fx1[n] - D2 * vx1[n-1]
+ m2->force[i] += Fn - D2 * m2->speed[i]; // Fx2[n] = Fx, Fx2[n] = Fx2[n] - D2 * vx2[n-1]
+ }
+ else // usual link
+ for(int i = 0; i < N; ++i) {
+ const t_float Fn = F * (m1->pos[i] - m2->pos[i]); // Fx = F * Lx[n]/L[n]
+ m1->force[i] -= Fn + D2 * m1->speed[i]; // Fx1[n] = -Fx, Fx1[n] = Fx1[n] - D2 * vx1[n-1]
+ m2->force[i] += Fn - D2 * m2->speed[i]; // Fx2[n] = Fx, Fx2[n] = Fx2[n] - D2 * vx2[n-1]
+ }
+
+ }
+
+ distance_old = distance; // L[n-1] = L[n]
+ }
+ }
+};
+
+
+
+template <typename T>
+inline T bitrev(T k) {
+ T r = 0;
+ for(int i = 0; i < sizeof(k)*8; ++i) r = (r<<1)|(k&1),k >>= 1;
+ return r;
+}
+
+// use bit-reversed key to pseudo-balance the map tree
+template <typename T>
+class IndexMap : TablePtrMap<unsigned int,T,64> {
+public:
+ typedef TablePtrMap<unsigned int,T,64> Parent;
+
+ virtual ~IndexMap() { reset(); }
+
+ void reset()
+ {
+ // delete all associated items
+ for(typename Parent::iterator it(*this); it; ++it) delete it.data();
+ Parent::clear();
+ }
+
+ inline int size() const { return Parent::size(); }
+
+ inline T insert(unsigned int k,T v) { return Parent::insert(bitrev(k),v); }
+
+ inline T find(unsigned int k) { return Parent::find(bitrev(k)); }
+
+ inline T remove(unsigned int k) { return Parent::remove(bitrev(k)); }
+
+ class iterator
+ : public Parent::iterator
+ {
+ public:
+ iterator() {}
+ iterator(IndexMap &m): Parent::iterator(m) {}
+ inline unsigned int key() const { return bitrev(Parent::key()); }
+ };
+};
+
+template <typename T>
+class IDMap : TablePtrMap<const t_symbol *,TablePtrMap<T,T,4> *,4> {
+public:
+ // that's the container holding the data items (masses, links) of one ID
+ typedef TablePtrMap<T,T,4> Container;
+ // that's the map for the key ID (symbol,int) relating to the data items
+ typedef TablePtrMap<const t_symbol *,Container *,4> Parent;
+
+ typedef typename Container::iterator iterator;
+
+ IDMap() {}
+
+ virtual ~IDMap() { reset(); }
+
+ void reset()
+ {
+ typename Parent::iterator it(*this);
+ for(; it; ++it) delete it.data();
+ Parent::clear();
+ }
+
+ void insert(T item)
+ {
+ Container *c = Parent::find(item->Id);
+ if(!c)
+ Parent::insert(item->Id,c = new Container);
+ c->insert(item,item);
+ }
+
+ iterator find(const t_symbol *key)
+ {
+ Container *c = Parent::find(key);
+ if(c)
+ return iterator(*c);
+ else
+ return iterator();
+ }
+
+ void erase(T item)
+ {
+ Container *c = Parent::find(item->Id);
+ if(c) c->remove(item);
+ }
+};
+
+
+template<int N>
+class msdN: public flext_base {
+ FLEXT_HEADER_S(msdN,flext_base,setup) //class with setup
+
+public:
+ // constructor with no arguments
+ msdN(int argc,t_atom *argv) : id_mass(0),id_link(0) {
+ for(int i = 0; i < N; ++i) limit[i][0] = -1.e10,limit[i][1] = 1.e10;
+
+ // --- define inlets and outlets ---
+ AddInAnything("bang, reset, etc."); // default inlet
+ AddOutAnything("infos on masses"); // outlet for integer count
+ AddOutAnything("control"); // outlet for bang
+ }
+
+ virtual ~msdN() { clear(); }
+
+protected:
+
+// -------------------------------------------------------------- PROTECTED VARIABLES
+// -----------------------------------------------------------------------------------
+
+ typedef Mass<N> t_mass;
+ typedef Link<N> t_link;
+
+ IndexMap<t_link *> link; // links
+ IDMap<t_link *> linkids; // links by name
+ IndexMap<t_mass *> mass; // masses
+ IDMap<t_mass *> massids; // masses by name
+ IndexMap<t_buffer *> buffers; // buffers
+ IDMap<t_buffer *> buffersids; // buffers by name
+
+ t_float limit[N][2]; // Limit values
+ unsigned int id_mass, id_link, id_buffer, mouse_grab, nearest_mass, link_deleted, mass_deleted;
+
+// --------------------------------------------------------------- RESET
+// ----------------------------------------------------------------------
+ void m_reset() {
+ clear();
+ ToOutAnything(1,S_Reset,0,NULL);
+ }
+
+// -------------------------------------------------------------- COMPUTE
+// -----------------------------------------------------------------------
+
+ void m_bang() {
+ // test all buffers
+ for (typename IndexMap<t_buffer *>::iterator bit(buffers); bit; ++bit) bit.data()->buffer_test();
+
+ // update all links
+ for (typename IndexMap<t_link *>::iterator lit(link); lit; ++lit) lit.data()->compute();
+
+ // update all masses
+ for (typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) mit.data()->compute(limit);
+ }
+
+// -------------------------------------------------------------- MASSES
+// ----------------------------------------------------------------------
+
+ // add a mass
+ // Id, nbr, mobile, invM, speedX, posX, forceX
+ void m_mass(int argc,t_atom *argv) {
+ if(argc != 3+N) {
+ error("mass : Id mobile mass X%s%s",N >= 2?" Y":"",N >= 3?" Z":"");
+ return;
+ }
+
+ t_float pos[N];
+ for(int i = 0; i < N; ++i) pos[i] = GetAFloat(argv[3+i]);
+
+ t_mass *m = new t_mass(
+ id_mass, // index
+ GetSymbol(argv[0]), // ID
+ GetABool(argv[1]), // mobile
+ GetAFloat(argv[2]), // mass
+ pos // pos
+ );
+
+ outmass(S_Mass,m);
+
+ massids.insert(m);
+ mass.insert(id_mass++,m);
+ }
+
+ // add a force to mass(es) named Id or No
+ void m_force(int argc,t_atom *argv,int n) {
+ if(argc != 2) {
+ error("%s - %s Syntax : Id/Nomass value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_float f = GetAFloat(argv[1]);
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_mass *>::iterator it;
+ for(it = massids.find(GetSymbol(argv[0])); it; ++it) {
+ t_mass *m = it.data();
+ m->setForce(n,f);
+ }
+ }
+ else {
+ t_mass *m = mass.find(GetAInt(argv[0]));
+ if(m)
+ m->setForce(n,f);
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ inline void m_forceX(int argc,t_atom *argv) { m_force(argc,argv,0); }
+ inline void m_forceY(int argc,t_atom *argv) { m_force(argc,argv,1); }
+ inline void m_forceZ(int argc,t_atom *argv) { m_force(argc,argv,2); }
+ inline void m_forceN(int argc,t_atom *argv) {
+ t_atom arglist[2];
+
+ if(argc != 3) {
+ error("%s - %s Syntax : N Id/Nomass value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ if (IsSymbol(argv[1]))
+ SetSymbol(arglist[0],GetSymbol(argv[1]));
+ else
+ SetInt(arglist[0],GetAInt(argv[1]));
+ SetFloat(arglist[1],GetFloat(argv[2]));
+ m_force(argc-1,arglist,GetAInt(argv[0])-1);
+ }
+
+ // displace mass(es) named Id or No to a certain position
+ void m_pos(int argc,t_atom *argv,int n) {
+ if(argc != 2) {
+ error("%s - %s Syntax : Id/Nomass value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_float p = GetAFloat(argv[1]);
+ if(p > limit[n][1] || p < limit[n][0]) return;
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_mass *>::iterator it;
+ for(it = massids.find(GetSymbol(argv[0])); it; ++it)
+ it.data()->setPos(n,p);
+ }
+ else {
+ t_mass *m = mass.find(GetAInt(argv[0]));
+ if(m)
+ m->setPos(n,p);
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ inline void m_posX(int argc,t_atom *argv) { m_pos(argc,argv,0); }
+ inline void m_posY(int argc,t_atom *argv) { m_pos(argc,argv,1); }
+ inline void m_posZ(int argc,t_atom *argv) { m_pos(argc,argv,2); }
+ inline void m_posN(int argc,t_atom *argv) {
+ t_atom arglist[2];
+
+ if(argc != 3) {
+ error("%s - %s Syntax : N Id/Nomass value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ if (IsSymbol(argv[1]))
+ SetSymbol(arglist[0],GetSymbol(argv[1]));
+ else
+ SetInt(arglist[0],GetAInt(argv[1]));
+ SetFloat(arglist[1],GetFloat(argv[2]));
+ m_pos(argc-1,arglist,GetAInt(argv[0])-1);
+ }
+
+ // set mass to mobile
+ void m_set_mobile(int argc,t_atom *argv,bool mob = true) {
+ if (argc != 1) {
+ error("%s - %s Syntax : Id/Nomass",thisName(),GetString(thisTag()));
+ return;
+ }
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_mass *>::iterator it;
+ if(mob)
+ for(it = massids.find(GetSymbol(argv[0])); it; ++it)
+ it.data()->setMobile();
+ else
+ for(it = massids.find(GetSymbol(argv[0])); it; ++it)
+ it.data()->setFixed();
+ }
+ else {
+ t_mass *m = mass.find(GetAInt(argv[0]));
+ if(m)
+ if(mob) m->setMobile();
+ else m->setFixed();
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ // set mass No to fixed
+ inline void m_set_fixe(int argc,t_atom *argv) { m_set_mobile(argc,argv,false); }
+
+ // Delete mass
+ void m_delete_mass(int argc,t_atom *argv) {
+ if (argc != 1) {
+ error("%s - %s Syntax : Nomass",thisName(),GetString(thisTag()));
+ return;
+ }
+
+
+ t_mass *m = mass.find(GetAInt(argv[0]));
+ if(m) {
+ // Delete all associated links
+
+ while(!m->links.empty())
+ deletelink(m->links.front());
+
+ outmass(S_Mass_deleted,m);
+ massids.erase(m);
+ mass.remove(m->nbr);
+
+ delete m;
+ mass_deleted = 1;
+ }
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+
+ // set X,Y,Z min/max
+ void m_limit(int argc,t_atom *argv,int n,int i) {
+ if (argc != 1)
+ error("%s - %s Syntax : Value",thisName(),GetString(thisTag()));
+ else
+ limit[n][i] = GetAFloat(argv[0]);
+ }
+
+ inline void m_Xmin(int argc,t_atom *argv) { m_limit(argc,argv,0,0); }
+ inline void m_Ymin(int argc,t_atom *argv) { m_limit(argc,argv,1,0); }
+ inline void m_Zmin(int argc,t_atom *argv) { m_limit(argc,argv,2,0); }
+ inline void m_Nmin(int argc,t_atom *argv) {
+ t_atom arglist[1];
+
+ if(argc != 2) {
+ error("%s - %s Syntax : N value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ SetFloat(arglist[0],GetFloat(argv[1]));
+ m_limit(argc-1,arglist,GetAInt(argv[0])-1,0);
+ }
+
+ inline void m_Xmax(int argc,t_atom *argv) { m_limit(argc,argv,0,1); }
+ inline void m_Ymax(int argc,t_atom *argv) { m_limit(argc,argv,1,1); }
+ inline void m_Zmax(int argc,t_atom *argv) { m_limit(argc,argv,2,1); }
+ inline void m_Nmax(int argc,t_atom *argv) {
+ t_atom arglist[1];
+
+ if(argc != 2) {
+ error("%s - %s Syntax : N value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ SetFloat(arglist[0],GetFloat(argv[1]));
+ m_limit(argc-1,arglist,GetAInt(argv[0])-1,1);
+ }
+
+ // set Id of mass(s) named Id or number No
+ void m_setMassId(int argc,t_atom *argv) {
+ if (argc != 2) {
+ error("%s - %s Syntax : OldId/NoMass NewId",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_symbol *id = GetSymbol(argv[1]);
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_mass *>::iterator it;
+ for(it = massids.find(GetSymbol(argv[0])); it; ++it)
+ it.data()->Id = id;
+ }
+ else {
+ t_mass *m = mass.find(GetAInt(argv[0]));
+ if(m)
+ m->Id = id;
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ // set mass of mass(s) named Id or number No
+ void m_setM(int argc,t_atom *argv) {
+ if (argc != 2) {
+ error("%s - %s Syntax : Id/NoLink Value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_float ma = GetAFloat(argv[1]);
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_mass *>::iterator it;
+ //typename IDMap<t_link *>::iterator it;
+ for(it = massids.find(GetSymbol(argv[0])); it; ++it) {
+ it.data()->M = ma;
+ it.data()->invM = ma?1/ma:0.;
+ }
+ }
+ else {
+ t_mass *m = mass.find(GetAInt(argv[0]));
+ if(m) {
+ m->M = ma;
+ m->invM = ma?1/ma:0.;
+ }
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ // grab nearest mass
+ void m_grab_mass(int argc,t_atom *argv) {
+ // grab nearest mass X Y
+ t_mass **mi;
+ t_float aux, distance;
+ t_atom aux2[2];
+ bool mobil;
+
+ // if click
+ if (GetInt(argv[2])==1 && mass.size()>0) {
+
+ if (argc != 3)
+ error("grabMass : X Y click");
+ // first time we grab this mass?Find nearest mass
+ if (mouse_grab == 0) {
+ t_mass *m = mass.find(0);
+ aux = sqr(m->pos[0]-GetFloat(argv[0])) + sqr(m->pos[1]-GetFloat(argv[1]));
+ nearest_mass = 0;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ distance = sqr(mit.data()->pos[0]-GetFloat(argv[0])) + sqr(mit.data()->pos[1]-GetFloat(argv[1]));
+ if (distance<aux) {
+ aux = distance;
+ nearest_mass = mit.data()->nbr;
+ }
+ }
+ }
+
+ // Set fixed if mobile
+ mobil = mass.find(nearest_mass)->invM;
+ SetInt(aux2[0],nearest_mass);
+ if (mobil != 0)
+ m_set_fixe(1,aux2);
+
+ // Set XY
+ SetFloat(aux2[1],GetFloat(argv[0]));
+ m_posX(2,aux2);
+ SetFloat(aux2[1],GetFloat(argv[1]));
+ m_posY(2,aux2);
+
+ // Set mobile
+ if(mobil != 0)
+ m_set_mobile(1,aux2);
+
+ // Current grabbing on
+ mouse_grab = 1;
+ }
+ else
+ // Grabing off
+ mouse_grab = 0;
+ }
+
+// -------------------------------------------------------------- LINKS
+// ---------------------------------------------------------------------
+
+ // add a link
+ // Id, *mass1, *mass2, K1, D1, D2, (Lmin,Lmax)
+ void m_link(int argc,t_atom *argv) {
+ if (argc < 5 || argc > 8) {
+ error("%s - %s Syntax : Id No/Idmass1 No/Idmass2 K D1 (pow Lmin Lmax)",thisName(),GetString(thisTag()));
+ return;
+ }
+ if (IsSymbol(argv[1]) && IsSymbol(argv[2])) { // ID & ID
+ typename IDMap<t_mass *>::iterator it1,it2,it;
+ it1 = massids.find(GetSymbol(argv[1]));
+ it2 = massids.find(GetSymbol(argv[2]));
+ for(; it1; ++it1) {
+ for(it = it2; it; ++it) {
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ it1.data(),it.data(), // pointer to mass1, mass2
+ GetAFloat(argv[3]), // K1
+ GetAFloat(argv[4]), // D1
+ 0,NULL,
+ argc >= 6?GetFloat(argv[5]):1, // power
+ argc >= 7?GetFloat(argv[6]):0,
+ argc >= 8?GetFloat(argv[7]):1e10
+ );
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_iLink,l);
+ }
+ }
+ }
+ else if (IsSymbol(argv[1])==0 && IsSymbol(argv[2])) { // No & ID
+ typename IDMap<t_mass *>::iterator it2,it;
+ t_mass *mass1 = mass.find(GetAInt(argv[1]));
+ it2 = massids.find(GetSymbol(argv[2]));
+ for(it = it2; it; ++it) {
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ mass1,it.data(), // pointer to mass1, mass2
+ GetAFloat(argv[3]), // K1
+ GetAFloat(argv[4]), // D1
+ 0,NULL,
+ argc >= 6?GetFloat(argv[5]):1, // power
+ argc >= 7?GetFloat(argv[6]):0,
+ argc >= 8?GetFloat(argv[7]):1e10
+ );
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_iLink,l);
+ }
+ }
+ else if (IsSymbol(argv[1]) && IsSymbol(argv[2])==0) { // ID & No
+ typename IDMap<t_mass *>::iterator it1,it;
+ it1 = massids.find(GetSymbol(argv[1]));
+ t_mass *mass2 = mass.find(GetAInt(argv[2]));
+ for(it = it1; it; ++it) {
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ it.data(),mass2, // pointer to mass1, mass2
+ GetAFloat(argv[3]), // K1
+ GetAFloat(argv[4]), // D1
+ 0,NULL,
+ argc >= 6?GetFloat(argv[5]):1, // power
+ argc >= 7?GetFloat(argv[6]):0,
+ argc >= 8?GetFloat(argv[7]):1e10
+ );
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_iLink,l);
+ }
+ }
+ else { // No & No
+ t_mass *mass1 = mass.find(GetAInt(argv[1]));
+ t_mass *mass2 = mass.find(GetAInt(argv[2]));
+
+ if(!mass1 || !mass2) {
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ mass1,mass2, // pointer to mass1, mass2
+ GetAFloat(argv[3]), // K1
+ GetAFloat(argv[4]), // D1
+ 0,NULL,
+ argc >= 6?GetFloat(argv[5]):1, // power
+ argc >= 7?GetFloat(argv[6]):0, // Lmin
+ argc >= 8?GetFloat(argv[7]):1e10// Lmax
+ );
+
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_Link,l);
+ }
+ }
+
+ // add interactor link (for compatibility)
+ // Id, Id masses1, Id masses2, K1, D1, D2, (Lmin, Lmax)
+ void m_ilink(int argc,t_atom *argv) {m_link(argc,argv); }
+
+ // add a tangential link
+ // Id, *mass1, *mass2, K1, D1, D2, (Lmin,Lmax)
+ void m_tlink(int argc,t_atom *argv) {
+ if (argc < 5+N || argc > 8+N) {
+ error("%s - %s Syntax : Id Nomass1 Nomass2 K D1 xa%s%s (pow Lmin Lmax)",thisName(),GetString(thisTag()),N >= 2?" ya":"",N >= 3?" za":"");
+ return;
+ }
+ t_float tangent[N];
+ for(int i = 0; i < N; ++i) tangent[i] = GetAFloat(argv[5+i]);
+
+ if (IsSymbol(argv[1]) && IsSymbol(argv[2])) { // ID & ID
+ typename IDMap<t_mass *>::iterator it1,it2,it;
+ it1 = massids.find(GetSymbol(argv[1]));
+ it2 = massids.find(GetSymbol(argv[2]));
+ for(; it1; ++it1) {
+ for(it = it2; it; ++it) {
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ it1.data(),it.data(), // pointer to mass1, mass2
+ GetAFloat(argv[3]), // K1
+ GetAFloat(argv[4]), // D1
+ 1, // tangential
+ tangent,
+ argc >= 6+N?GetFloat(argv[5+N]):1, // power
+ argc >= 7+N?GetFloat(argv[6+N]):0, // Lmin
+ argc >= 8+N?GetFloat(argv[7+N]):1e10 // Lmax
+ );
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_iLink,l);
+ }
+ }
+ }
+ else if (IsSymbol(argv[1])==0 && IsSymbol(argv[2])) { // No & ID
+ typename IDMap<t_mass *>::iterator it2,it;
+ t_mass *mass1 = mass.find(GetAInt(argv[1]));
+ it2 = massids.find(GetSymbol(argv[2]));
+ for(it = it2; it; ++it) {
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ mass1,it.data(), // pointer to mass1, mass2
+ GetAFloat(argv[3]), // K1
+ GetAFloat(argv[4]), // D1
+ 1, // tangential
+ tangent,
+ argc >= 6+N?GetFloat(argv[5+N]):1, // power
+ argc >= 7+N?GetFloat(argv[6+N]):0, // Lmin
+ argc >= 8+N?GetFloat(argv[7+N]):1e10 // Lmax
+ );
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_tLink,l);
+ }
+ }
+ else if (IsSymbol(argv[1]) && IsSymbol(argv[2])==0) { // ID & No
+ typename IDMap<t_mass *>::iterator it1,it;
+ it1 = massids.find(GetSymbol(argv[1]));
+ t_mass *mass2 = mass.find(GetAInt(argv[2]));
+ for(it = it1; it; ++it) {
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ it.data(),mass2, // pointer to mass1, mass2
+ GetAFloat(argv[3]), // K1
+ GetAFloat(argv[4]), // D1
+ 1,
+ tangent, // tangential
+ argc >= 6+N?GetFloat(argv[5+N]):1, // power
+ argc >= 7+N?GetFloat(argv[6+N]):0, // Lmin
+ argc >= 8+N?GetFloat(argv[7+N]):1e10 // Lmax
+ );
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_tLink,l);
+ }
+ }
+ else { // No & No
+ t_mass *mass1 = mass.find(GetAInt(argv[1]));
+ t_mass *mass2 = mass.find(GetAInt(argv[2]));
+
+ if(!mass1 || !mass2) {
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ return;
+ }
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ mass1,mass2, // pointer to mass1, mass2
+ GetAFloat(argv[3]), // K1
+ GetAFloat(argv[4]), // D1
+ 1, // tangential
+ tangent, // tangential
+ argc >= 6+N?GetFloat(argv[5+N]):1, // power
+ argc >= 7+N?GetFloat(argv[6+N]):0, // Lmin
+ argc >= 8+N?GetFloat(argv[7+N]):1e10 // Lmax
+ );
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_tLink,l);
+ }
+ }
+
+ // add a tab link
+ // Id, *mass1, *mass2, k_tabname/K1, d_tabname/D1, l_tab
+ void m_tablink(int argc,t_atom *argv) {
+ if (argc != 7) {
+ error("%s - %s Syntax : Id No/Idmass1 No/Idmass2 ktab lk dtab ld",thisName(),GetString(thisTag()));
+ return;
+ }
+ // Searching exisiting buffers or create one.
+ t_buffer *bk,*bd;
+
+ if (IsSymbol(argv[3])) { // K tab
+ typename IDMap<t_buffer *>::iterator itk;
+ itk = buffersids.find(GetSymbol(argv[3]));
+ if(!itk) {
+ bk = new t_buffer(id_buffer,GetSymbol(argv[3]));
+ buffersids.insert(bk);
+ buffers.insert(id_buffer++,bk);
+ }
+ else
+ bk = itk.data();
+ }
+ if (IsSymbol(argv[5])) { // D tab
+ typename IDMap<t_buffer *>::iterator itd;
+ itd = buffersids.find(GetSymbol(argv[5]));
+ if(!itd) {
+ bd = new t_buffer(id_buffer,GetSymbol(argv[5]));
+ buffersids.insert(bd);
+ buffers.insert(id_buffer++,bd);
+ }
+ else
+ bd = itd.data();
+ }
+
+ if (IsSymbol(argv[1]) && IsSymbol(argv[2])) { // ID & ID
+ typename IDMap<t_mass *>::iterator it1,it2,it;
+ it1 = massids.find(GetSymbol(argv[1]));
+ it2 = massids.find(GetSymbol(argv[2]));
+ for(; it1; ++it1) {
+ for(it = it2; it; ++it) {
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ it1.data(),it.data(), // pointer to mass1, mass2
+ IsSymbol(argv[3])?1:GetAFloat(argv[3]), // K1 = 1 if buffer
+ IsSymbol(argv[5])?1:GetAFloat(argv[5]), // D1
+ 3,NULL,
+ 1, // power
+ 0, // Lmin
+ 1e10, // Lmax
+ IsSymbol(argv[3])?bk:NULL, // k_tabname
+ GetAFloat(argv[4]), // l_tab
+ IsSymbol(argv[5])?bd:NULL, // d_tabname
+ GetAFloat(argv[6]) // l_tab2
+ );
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_tabLink,l);
+ }
+ }
+ }
+ else if (IsSymbol(argv[1])==0 && IsSymbol(argv[2])) { // No & ID
+ typename IDMap<t_mass *>::iterator it2,it;
+ t_mass *mass1 = mass.find(GetAInt(argv[1]));
+ it2 = massids.find(GetSymbol(argv[2]));
+ for(it = it2; it; ++it) {
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ mass1,it.data(), // pointer to mass1, mass2
+ IsSymbol(argv[3])?1:GetAFloat(argv[3]), // K1 = 1 if buffer
+ IsSymbol(argv[5])?1:GetAFloat(argv[5]), // D1
+ 3,NULL,
+ 1, // power
+ 0, // Lmin
+ 1e10, // Lmax
+ IsSymbol(argv[3])?bk:NULL, // k_tabname
+ GetAFloat(argv[4]), // l_tab
+ IsSymbol(argv[5])?bd:NULL, // d_tabname
+ GetAFloat(argv[6]) // l_tab2
+ );
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_tabLink,l);
+ }
+ }
+ else if (IsSymbol(argv[1]) && IsSymbol(argv[2])==0) { // ID & No
+ typename IDMap<t_mass *>::iterator it1,it;
+ it1 = massids.find(GetSymbol(argv[1]));
+ t_mass *mass2 = mass.find(GetAInt(argv[2]));
+ for(it = it1; it; ++it) {
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ it1.data(),mass2, // pointer to mass1, mass2
+ IsSymbol(argv[3])?1:GetAFloat(argv[3]), // K1 = 1 if buffer
+ IsSymbol(argv[5])?1:GetAFloat(argv[5]), // D1
+ 3,NULL,
+ 1, // power
+ 0, // Lmin
+ 1e10, // Lmax
+ IsSymbol(argv[3])?bk:NULL, // k_tabname
+ GetAFloat(argv[4]), // l_tab
+ IsSymbol(argv[5])?bd:NULL, // d_tabname
+ GetAFloat(argv[6]) // l_tab2
+ );
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_tabLink,l);
+ }
+ }
+ else { // No & No
+ t_mass *mass1 = mass.find(GetAInt(argv[1]));
+ t_mass *mass2 = mass.find(GetAInt(argv[2]));
+
+ if(!mass1 || !mass2) {
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ t_link *l = new t_link(
+ id_link,
+ GetSymbol(argv[0]), // ID
+ mass1,mass2, // pointer to mass1, mass2
+ IsSymbol(argv[3])?1:GetAFloat(argv[3]), // K1 = 1 if buffer
+ IsSymbol(argv[5])?1:GetAFloat(argv[5]), // D1
+ 3,NULL,
+ 1, // power
+ 0, // Lmin
+ 1e10, // Lmax
+ IsSymbol(argv[3])?bk:NULL, // k_tabname
+ GetAFloat(argv[4]), // l_tab
+ IsSymbol(argv[5])?bd:NULL, // d_tabname
+ GetAFloat(argv[6]) // l_tab2
+ );
+
+ linkids.insert(l);
+ link.insert(id_link++,l);
+ outlink(S_tabLink,l);
+ }
+ }
+
+ // add a normal link
+ // Id, *mass1, *mass2, K1, D1, D2, (Lmin,Lmax)
+ void m_nlink(int argc,t_atom *argv) {
+ // deprecated
+ }
+
+ // set Id of link(s) named Id or number No
+ void m_setLinkId(int argc,t_atom *argv) {
+ if (argc != 2) {
+ error("%s - %s Syntax : OldId/NoLink NewId",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_symbol *id = GetSymbol(argv[1]);
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_link *>::iterator it;
+ for(it = linkids.find(GetSymbol(argv[0])); it; ++it)
+ it.data()->Id = id;
+ }
+ else {
+ t_link *l = link.find(GetAInt(argv[0]));
+ if(l)
+ l->Id = id;
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ // set rigidity of link(s) named Id or number No
+ void m_setK(int argc,t_atom *argv) {
+ if (argc != 2) {
+ error("%s - %s Syntax : Id/NoLink Value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_float k1 = GetAFloat(argv[1]);
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_link *>::iterator it;
+ for(it = linkids.find(GetSymbol(argv[0])); it; ++it)
+ it.data()->K1 = k1;
+ }
+ else {
+ t_link *l = link.find(GetAInt(argv[0]));
+ if(l)
+ l->K1 = k1;
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ // set damping of link(s) named Id or number No
+ void m_setD(int argc,t_atom *argv) {
+ if (argc != 2) {
+ error("%s - %s Syntax : Id/NoLink Value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_float d1 = GetAFloat(argv[1]);
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_link *>::iterator it;
+ for(it = linkids.find(GetSymbol(argv[0])); it; ++it)
+ it.data()->D1 = d1;
+ }
+ else {
+ t_link *l = link.find(GetAInt(argv[0]));
+ if(l)
+ l->D1 = d1;
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ // set max lenght of link(s) named Id or number No
+ void m_setLmax(int argc,t_atom *argv) {
+ if (argc != 2) {
+ error("%s - %s Syntax : Id/NoLink Value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_float lon = GetAFloat(argv[1]);
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_link *>::iterator it;
+ for(it = linkids.find(GetSymbol(argv[0])); it; ++it) {
+ it.data()->long_max = lon;
+ }
+ }
+ else {
+ t_link *l = link.find(GetAInt(argv[0]));
+ if(l) {
+ l->long_max = lon;
+ }
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ // set min lenght of link(s) named Id or number No
+ void m_setLmin(int argc,t_atom *argv) {
+ if (argc != 2) {
+ error("%s - %s Syntax : Id/NoLink Value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_float lon = GetAFloat(argv[1]);
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_link *>::iterator it;
+ for(it = linkids.find(GetSymbol(argv[0])); it; ++it) {
+ it.data()->long_min = lon;
+ }
+ }
+ else {
+ t_link *l = link.find(GetAInt(argv[0]));
+ if(l) {
+ l->long_min = lon;
+ }
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ // set initial lenght of link(s) named Id or number No
+ void m_setL(int argc,t_atom *argv) {
+ if (argc != 2) {
+ error("%s - %s Syntax : Id/NoLink Value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_float lon = GetAFloat(argv[1]);
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_link *>::iterator it;
+ for(it = linkids.find(GetSymbol(argv[0])); it; ++it) {
+ it.data()->longueur = lon;
+ it.data()->distance_old = lon;
+ }
+ }
+ else {
+ t_link *l = link.find(GetAInt(argv[0]));
+ if(l) {
+ l->longueur = lon;
+ l->distance_old = lon;
+ }
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ // set l_tab of tablink(s) named Id or number No
+ void m_setLtab(int argc,t_atom *argv) {
+ if (argc != 2) {
+ error("%s - %s Syntax : Id/NoLink Value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ const t_float lon = GetAFloat(argv[1]);
+
+ if(IsSymbol(argv[0])) {
+ typename IDMap<t_link *>::iterator it;
+ for(it = linkids.find(GetSymbol(argv[0])); it; ++it) {
+ if(it.data()->link_type==3)
+ it.data()->l_tab = lon;
+ else
+ error("%s - %s : set Ltab is working only on tablink",thisName(),GetString(thisTag()));
+ }
+ }
+ else {
+ t_link *l = link.find(GetAInt(argv[0]));
+ if(l) {
+ if(l->link_type==3)
+ l->l_tab = lon;
+ else
+ error("%s - %s : set Ltab is working only on tablink",thisName(),GetString(thisTag()));
+
+ }
+ else
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+
+ // set damping of link(s) named Id
+ void m_setD2(int argc,t_atom *argv) {
+ if (argc != 2) {
+ error("%s - %s Syntax : IdLink Value",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ t_float d2 = GetAFloat(argv[1]);
+ typename IDMap<t_link *>::iterator it;
+ for(it = linkids.find(GetSymbol(argv[0])); it; ++it)
+ it.data()->D2 = d2;
+ }
+
+ // Delete link
+ void m_delete_link(int argc,t_atom *argv) {
+ if (argc != 1) {
+ error("%s - %s Syntax : NtLink",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ t_link *l = link.find(GetAInt(argv[0]));
+ if(l) {
+ deletelink(l);
+ link_deleted = 1;
+ }
+ else {
+ error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ return;
+ }
+ }
+
+
+// -------------------------------------------------------------- GET
+// -------------------------------------------------------------------
+
+ // get attributes
+ void m_get(int argc,t_atom *argv) {
+ if(argc == 0) {
+ return;
+ }
+
+ t_atom sortie[1+2*N];
+ t_float mean[N] ,std[N], nombre;
+ const t_symbol *auxtype = GetSymbol(argv[0]);
+
+
+ if (argc == 1) {
+ if (auxtype == S_massesPos) { // get all masses positions
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ SetInt(sortie[0],mit.data()->nbr);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],mit.data()->pos[i]);
+ ToOutAnything(0,S_massesPos,1+N,sortie);
+ }
+ }
+ else if (auxtype == S_massesPosName) { // get all masses positions output Id
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ SetSymbol(sortie[0],mit.data()->Id);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],mit.data()->pos[i]);
+ ToOutAnything(0,S_massesPosName,1+N,sortie);
+ }
+ }
+ else if (auxtype == S_massesPosMean) { // get all masses positions mean
+ for(int i = 0; i<N; ++i)
+ mean[i] = 0;
+ nombre = 0;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ ++nombre;
+ for(int i = 0; i < N; ++i)
+ mean[i] += mit.data()->pos[i];
+ }
+ for(int i = 0; i < N; ++i)
+ SetFloat(sortie[0+i],mean[i]/nombre);
+ ToOutAnything(0,S_massesPosMean,0+N,sortie);
+ }
+ else if (auxtype == S_massesPosStd) { // get all masses positions std
+ for(int i = 0; i<N; ++i) {
+ mean[i] = 0;
+ std[i] = 0;
+ }
+ nombre = 0;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ ++nombre;
+ for(int i = 0; i < N; ++i) {
+ mean[i] += mit.data()->pos[i];
+ std[i] += sqr(mit.data()->pos[i]) ;
+ }
+ }
+ for(int i = 0; i < N; ++i)
+ SetFloat(sortie[0+i],sqrt(std[i]/nombre-sqr(mean[i]/nombre)));
+ ToOutAnything(0,S_massesPosStd,0+N,sortie);
+ }
+ else if (auxtype == S_massesForces) { // get all masses forces
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ SetInt(sortie[0],mit.data()->nbr);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],mit.data()->out_force[i]);
+ ToOutAnything(0,S_massesForces,1+N,sortie);
+ }
+ }
+ else if (auxtype == S_massesForcesName) { // get all masses forces
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ SetSymbol(sortie[0],mit.data()->Id);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],mit.data()->out_force[i]);
+ ToOutAnything(0,S_massesForcesName,1+N,sortie);
+ }
+ }
+ else if (auxtype == S_massesForcesMean) { // get all masses forces mean
+ for(int i = 0; i<N; ++i)
+ mean[i] = 0;
+ nombre = 0;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ ++nombre;
+ for(int i = 0; i < N; ++i)
+ mean[i] += mit.data()->out_force[i];
+ }
+ for(int i = 0; i < N; ++i)
+ SetFloat(sortie[0+i],mean[i]/nombre);
+ ToOutAnything(0,S_massesForcesMean,0+N,sortie);
+ }
+ else if (auxtype == S_massesForcesStd) { // get all masses forces std
+ for(int i = 0; i<N; ++i) {
+ mean[i] = 0;
+ std[i] = 0;
+ }
+ nombre = 0;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ ++nombre;
+ for(int i = 0; i < N; ++i) {
+ mean[i] += mit.data()->out_force[i];
+ std[i] += sqr(mit.data()->out_force[i]) ;
+ }
+ }
+ for(int i = 0; i < N; ++i)
+ SetFloat(sortie[0+i],sqrt(std[i]/nombre-sqr(mean[i]/nombre)));
+ ToOutAnything(0,S_massesForcesStd,0+N,sortie);
+ }
+ else if (auxtype == S_linksPos) { // get all links positions
+ for(typename IndexMap<t_link *>::iterator lit(link); lit; ++lit) {
+ SetInt(sortie[0],lit.data()->nbr);
+ for(int i = 0; i < N; ++i) {
+ SetFloat(sortie[1+i],lit.data()->mass1->pos[i]);
+ SetFloat(sortie[1+N+i],lit.data()->mass2->pos[i]);
+ }
+ ToOutAnything(0,S_linksPos,1+2*N,sortie);
+ }
+ }
+ else if (auxtype == S_linksPosName) { // get all links positions
+ for(typename IndexMap<t_link *>::iterator lit(link); lit; ++lit) {
+ SetSymbol(sortie[0],lit.data()->Id);
+ for(int i = 0; i < N; ++i) {
+ SetFloat(sortie[1+i],lit.data()->mass1->pos[i]);
+ SetFloat(sortie[1+N+i],lit.data()->mass2->pos[i]);
+ }
+ ToOutAnything(0,S_linksPosName,1+2*N,sortie);
+ }
+ }
+ else if (auxtype == S_linksLenghts) { // get all links lenghts
+ for(typename IndexMap<t_link *>::iterator lit(link); lit; ++lit) {
+ SetInt(sortie[0],lit.data()->nbr);
+ SetFloat(sortie[1],lit.data()->distance_old);
+ ToOutAnything(0,S_linksLenghts,2,sortie);
+ }
+ }
+ else if (auxtype == S_linksLenghtsMean) { // get all links lenghts mean
+ for(int i = 0; i<N; ++i)
+ mean[i] = 0;
+ nombre = 0;
+ for(typename IndexMap<t_link *>::iterator lit(link); lit; ++lit) {
+ ++nombre;
+ mean[0] += lit.data()->distance_old;
+ }
+ for(int i = 0; i < N; ++i)
+ SetFloat(sortie[0],mean[0]/nombre);
+ ToOutAnything(0,S_linksLenghtsMean,1,sortie);
+ }
+ else if (auxtype == S_linksLenghtsStd) { // get all links lenghts std
+ for(int i = 0; i<N; ++i) {
+ mean[i] = 0;
+ std[i] = 0;
+ }
+ nombre = 0;
+ for(typename IndexMap<t_link *>::iterator lit(link); lit; ++lit) {
+ ++nombre;
+ mean[0] += lit.data()->distance_old;
+ std[0] += sqr(lit.data()->distance_old) ;
+ }
+ for(int i = 0; i < N; ++i)
+ SetFloat(sortie[0],sqrt(std[0]/nombre-sqr(mean[0]/nombre)));
+ ToOutAnything(0,S_linksLenghtsStd,1,sortie);
+ }
+ else if (auxtype == S_massesSpeeds) { // get all masses speeds
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ SetInt(sortie[0],mit.data()->nbr);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],mit.data()->speed[i]);
+ ToOutAnything(0,S_massesSpeeds,1+N,sortie);
+ }
+ }
+ else if (auxtype == S_massesSpeedsName) { // get all masses speeds
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ SetSymbol(sortie[0],mit.data()->Id);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],mit.data()->speed[i]);
+ ToOutAnything(0,S_massesSpeedsName,1+N,sortie);
+ }
+ }
+ else if (auxtype == S_massesSpeedsMean) { // get all masses forces mean
+ for(int i = 0; i<N; ++i)
+ mean[i] = 0;
+ nombre = 0;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ ++nombre;
+ for(int i = 0; i < N; ++i)
+ mean[i] += mit.data()->speed[i];
+ }
+ for(int i = 0; i < N; ++i)
+ SetFloat(sortie[0+i],mean[i]/nombre);
+ ToOutAnything(0,S_massesSpeedsMean,0+N,sortie);
+ }
+ else if (auxtype == S_massesSpeedsStd) { // get all masses forces std
+ for(int i = 0; i<N; ++i) {
+ mean[i] = 0;
+ std[i] = 0;
+ }
+ nombre = 0;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit) {
+ ++nombre;
+ for(int i = 0; i < N; ++i) {
+ mean[i] += mit.data()->speed[i];
+ std[i] += sqr(mit.data()->speed[i]) ;
+ }
+ }
+ for(int i = 0; i < N; ++i)
+ SetFloat(sortie[0+i],sqrt(std[i]/nombre-sqr(mean[i]/nombre)));
+ ToOutAnything(0,S_massesSpeedsStd,0+N,sortie);
+ }
+ else
+ error("%s - %s : Syntax error",thisName(),GetString(thisTag()));
+ return;
+ }
+
+ // more than 1 args
+ if (auxtype == S_massesPos) // get mass positions
+ {
+ for(int j = 1; j<argc; j++) {
+ if(IsSymbol(argv[j])) {
+ typename IDMap<t_mass *>::iterator mit;
+ for(mit = massids.find(GetSymbol(argv[j])); mit; ++mit) {
+ SetSymbol(sortie[0],mit.data()->Id);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],mit.data()->pos[i]);
+ ToOutAnything(0,S_massesPosId,1+N,sortie);
+ }
+ }
+ else {
+ t_mass *m = mass.find(GetAInt(argv[j]));
+ if(m) {
+ SetInt(sortie[0],m->nbr);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],m->pos[i]);
+ ToOutAnything(0,S_massesPosNo,1+N,sortie);
+ }
+// else
+// error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+ }
+ else if (auxtype == S_massesForces) // get mass forces
+ {
+ for(int j = 1; j<argc; j++) {
+ if(IsSymbol(argv[j])) {
+ typename IDMap<t_mass *>::iterator mit;
+ for(mit = massids.find(GetSymbol(argv[j])); mit; ++mit) {
+ SetSymbol(sortie[0],mit.data()->Id);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],mit.data()->out_force[i]);
+ ToOutAnything(0,S_massesForcesId,1+N,sortie);
+ }
+ }
+ else {
+ t_mass *m = mass.find(GetAInt(argv[j]));
+ if(m) {
+ SetInt(sortie[0],m->nbr);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],m->out_force[i]);
+ ToOutAnything(0,S_massesForcesNo,1+N,sortie);
+ }
+// else
+// error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+ }
+ else if (auxtype == S_linksPos) // get links positions
+ {
+ for(int j = 1; j<argc; j++) {
+ if(IsSymbol(argv[j])) {
+ typename IDMap<t_link *>::iterator lit;
+ for(lit = linkids.find(GetSymbol(argv[j])); lit; ++lit) {
+ SetSymbol(sortie[0],lit.data()->Id);
+ for(int i = 0; i < N; ++i) {
+ SetFloat(sortie[1+i],lit.data()->mass1->pos[i]);
+ SetFloat(sortie[1+N+i],lit.data()->mass2->pos[i]);
+ }
+ ToOutAnything(0,S_linksPosId,1+2*N,sortie);
+ }
+ }
+ else {
+ t_link *l = link.find(GetAInt(argv[j]));
+ if(l) {
+ SetInt(sortie[0],l->nbr);
+ for(int i = 0; i < N; ++i) {
+ SetFloat(sortie[1+i],l->mass1->pos[i]);
+ SetFloat(sortie[1+N+i],l->mass2->pos[i]);
+ }
+ ToOutAnything(0,S_linksPosNo,1+2*N,sortie);
+ }
+// else
+// error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+ }
+ else if (auxtype == S_linksLenghts) // get links lenghts
+ {
+ for(int j = 1; j<argc; j++) {
+ if(IsSymbol(argv[j])) {
+ typename IDMap<t_link *>::iterator lit;
+ for(lit = linkids.find(GetSymbol(argv[j])); lit; ++lit) {
+ SetSymbol(sortie[0],lit.data()->Id);
+ SetFloat(sortie[1],lit.data()->distance_old);
+ ToOutAnything(0,S_linksLenghtsId,2,sortie);
+ }
+ }
+ else {
+ t_link *l = link.find(GetAInt(argv[j]));
+ if(l) {
+ SetInt(sortie[0],l->nbr);
+ SetFloat(sortie[1],l->distance_old);
+ ToOutAnything(0,S_linksLenghtsNo,2,sortie);
+ }
+// else
+// error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+ }
+ else // get mass speeds
+ {
+ for(int j = 1; j<argc; j++) {
+ if(IsSymbol(argv[j])) {
+ typename IDMap<t_mass *>::iterator mit;
+ for(mit = massids.find(GetSymbol(argv[j])); mit; ++mit) {
+ SetSymbol(sortie[0],mit.data()->Id);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],mit.data()->speed[i]);
+ ToOutAnything(0,S_massesSpeedsId,1+N,sortie);
+ }
+ }
+ else {
+ t_mass *m = mass.find(GetAInt(argv[j]));
+ if(m) {
+ SetInt(sortie[0],m->nbr);
+ for(int i = 0; i < N; ++i) SetFloat(sortie[1+i],m->speed[i]);
+ ToOutAnything(0,S_massesSpeedsNo,1+N,sortie);
+ }
+// else
+// error("%s - %s : Index not found",thisName(),GetString(thisTag()));
+ }
+ }
+ }
+ }
+
+ // List of masses positions on first outlet
+ void m_mass_dumpl() {
+ if (mass_deleted ==0) {
+ int sz = mass.size();
+ NEWARR(t_atom,sortie,sz*N);
+ t_atom *s = sortie;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit)
+ for(int i = 0; i < N; ++i) SetFloat(s[mit.data()->nbr*N+i],mit.data()->pos[i]);
+ ToOutAnything(0, S_massesPosL, sz*N, sortie);
+ DELARR(sortie);
+ }
+ else
+ error("%s - %s : Message Forbidden when deletion is used",thisName(),GetString(thisTag()));
+ }
+
+ // List of masses x positions on first outlet
+ void m_mass_dump_xl() {
+ if (mass_deleted ==0) {
+ int sz = mass.size();
+ NEWARR(t_atom,sortie,sz);
+ t_atom *s = sortie;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit)
+ SetFloat(s[mit.data()->nbr],mit.data()->pos[0]);
+ ToOutAnything(0, S_massesPosXL, sz, sortie);
+ DELARR(sortie);
+ }
+ else
+ error("%s - %s : Message Forbidden when deletion is used",thisName(),GetString(thisTag()));
+ }
+
+ // List of masses y positions on first outlet
+ void m_mass_dump_yl() {
+ if (mass_deleted ==0) {
+ int sz = mass.size();
+ NEWARR(t_atom,sortie,sz);
+ t_atom *s = sortie;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit)
+ SetFloat(s[mit.data()->nbr],mit.data()->pos[1]);
+ ToOutAnything(0, S_massesPosYL, sz, sortie);
+ DELARR(sortie);
+ }
+ else
+ error("%s - %s : Message Forbidden when deletion is used",thisName(),GetString(thisTag()));
+ }
+
+ // List of masses z positions on first outlet
+ void m_mass_dump_zl() {
+ if (mass_deleted ==0) {
+ int sz = mass.size();
+ NEWARR(t_atom,sortie,sz);
+ t_atom *s = sortie;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit)
+ SetFloat(s[mit.data()->nbr],mit.data()->pos[2]);
+ ToOutAnything(0, S_massesPosZL, sz, sortie);
+ DELARR(sortie);
+ }
+ else
+ error("%s - %s : Message Forbidden when deletion is used",thisName(),GetString(thisTag()));
+ }
+
+ // List of masses forces on first outlet
+ void m_force_dumpl() {
+ if (mass_deleted ==0) {
+ int sz = mass.size();
+ NEWARR(t_atom,sortie,sz*N);
+ t_atom *s = sortie;
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit)
+ for(int i = 0; i < N; ++i) SetFloat(s[mit.data()->nbr*N+i],mit.data()->out_force[i]);
+ ToOutAnything(0, S_massesForcesL, sz*N, sortie);
+ DELARR(sortie);
+ }
+ else
+ error("%s - %s : Message Forbidden when deletion is used",thisName(),GetString(thisTag()));
+ }
+
+ // List of masses and links infos on second outlet
+ void m_info_dumpl() {
+ for(typename IndexMap<t_mass *>::iterator mit(mass); mit; ++mit)
+ outmass(S_Mass,mit.data());
+
+ for(typename IndexMap<t_link *>::iterator lit(link); lit; ++lit)
+ outlink(S_Link,lit.data());
+ }
+
+
+// -------------------------------------------------------------- SETUP
+// ---------------------------------------------------------------------
+
+private:
+
+ void clear() {
+ buffersids.reset();
+ buffers.reset();
+
+ linkids.reset();
+ link.reset();
+
+ massids.reset();
+ mass.reset();
+ // Reset state variables
+ id_mass = id_link = id_buffer = mouse_grab = mass_deleted = link_deleted = 0;
+ }
+
+ void deletelink(t_link *l) {
+ outlink(S_Link_deleted,l);
+ linkids.erase(l);
+ link.remove(l->nbr);
+ delete l;
+ }
+
+ void outmass(const t_symbol *s,const t_mass *m) {
+ t_atom sortie[4+N];
+ SetInt((sortie[0]),m->nbr);
+ SetSymbol((sortie[1]),m->Id);
+ SetBool((sortie[2]),m->getMobile());
+ SetFloat((sortie[3]),m->M);
+ for(int i = 0; i < N; ++i) SetFloat((sortie[4+i]),m->pos[i]);
+ ToOutAnything(1,s,4+N,sortie);
+ }
+
+ void outlink(const t_symbol *s,const t_link *l) {
+ t_atom sortie[15];
+ int size=6;
+ SetInt((sortie[0]),l->nbr);
+ SetSymbol((sortie[1]),l->Id);
+ SetInt((sortie[2]),l->mass1->nbr);
+ SetInt((sortie[3]),l->mass2->nbr);
+ l->k_buffer?SetSymbol(sortie[4],l->k_buffer->Id):SetFloat((sortie[4]),l->K1);
+ l->d_buffer?SetSymbol(sortie[5],l->d_buffer->Id):SetFloat((sortie[5]),l->D1);
+ if (l->link_type == 1 ||(l->link_type == 2 && N ==2)) {
+ for (int i=0; i<N; i++)
+ SetFloat((sortie[6+i]),l->tdirection1[i]);
+// ToOutAnything(1,s,6+N,sortie);
+ size = 6+N;
+ }
+ else if (l->link_type == 2 && N==3) {
+ for (int i=0; i<N; i++) {
+ SetFloat((sortie[6+i]),l->tdirection1[i]);
+ SetFloat((sortie[6+i+N]),l->tdirection2[i]);
+ }
+// ToOutAnything(1,s,6+2*N,sortie);
+ size = 6+2*N;
+ }
+
+ if(l->long_max != 1e10) {
+ SetFloat((sortie[size]),l->puissance);
+ size++;
+ SetFloat((sortie[size]),l->long_min);
+ size++;
+ SetFloat((sortie[size]),l->long_max);
+ size++;
+ }
+ else if(l->long_min != 0) {
+ SetFloat((sortie[size]),l->puissance);
+ size++;
+ SetFloat((sortie[size]),l->long_min);
+ size++;
+ }
+ else if(l->puissance != 1) {
+ SetFloat((sortie[size]),l->puissance);
+ size++;
+ }
+ ToOutAnything(1,s,size,sortie);
+ }
+
+
+ // Static symbols
+ const static t_symbol *S_Reset;
+ const static t_symbol *S_Mass;
+ const static t_symbol *S_Link;
+ const static t_symbol *S_iLink;
+ const static t_symbol *S_tLink;
+ const static t_symbol *S_nLink;
+ const static t_symbol *S_tabLink;
+ const static t_symbol *S_Mass_deleted;
+ const static t_symbol *S_Link_deleted;
+ const static t_symbol *S_massesPos;
+ const static t_symbol *S_massesPosName;
+ const static t_symbol *S_massesPosMean;
+ const static t_symbol *S_massesPosStd;
+ const static t_symbol *S_massesPosNo;
+ const static t_symbol *S_massesPosId;
+ const static t_symbol *S_linksPos;
+ const static t_symbol *S_linksPosName;
+ const static t_symbol *S_linksPosNo;
+ const static t_symbol *S_linksPosId;
+ const static t_symbol *S_linksLenghts;
+ const static t_symbol *S_linksLenghtsMean;
+ const static t_symbol *S_linksLenghtsStd;
+ const static t_symbol *S_linksLenghtsNo;
+ const static t_symbol *S_linksLenghtsId;
+ const static t_symbol *S_massesForces;
+ const static t_symbol *S_massesForcesName;
+ const static t_symbol *S_massesForcesMean;
+ const static t_symbol *S_massesForcesStd;
+ const static t_symbol *S_massesForcesNo;
+ const static t_symbol *S_massesForcesId;
+ const static t_symbol *S_massesSpeeds;
+ const static t_symbol *S_massesSpeedsName;
+ const static t_symbol *S_massesSpeedsMean;
+ const static t_symbol *S_massesSpeedsStd;
+ const static t_symbol *S_massesSpeedsNo;
+ const static t_symbol *S_massesSpeedsId;
+ const static t_symbol *S_massesPosL;
+ const static t_symbol *S_massesPosXL;
+ const static t_symbol *S_massesPosYL;
+ const static t_symbol *S_massesPosZL;
+ const static t_symbol *S_massesForcesL;
+
+ static void setup(t_classid c) {
+ S_Reset = MakeSymbol("Reset");
+ S_Mass = MakeSymbol("Mass");
+ S_Link = MakeSymbol("Link");
+ S_iLink = MakeSymbol("iLink");
+ S_tLink = MakeSymbol("tLink");
+ S_nLink = MakeSymbol("nLink");
+ S_tabLink = MakeSymbol("tabLink");
+ S_Mass_deleted = MakeSymbol("Mass deleted");
+ S_Link_deleted = MakeSymbol("Link deleted");
+ S_massesPos = MakeSymbol("massesPos");
+ S_massesPosName = MakeSymbol("massesPosName");
+ S_massesPosMean = MakeSymbol("massesPosMean");
+ S_massesPosStd = MakeSymbol("massesPosStd");
+ S_massesPosNo = MakeSymbol("massesPosNo");
+ S_massesPosId = MakeSymbol("massesPosId");
+ S_linksPos = MakeSymbol("linksPos");
+ S_linksPosName = MakeSymbol("linksPosName");
+ S_linksPosNo = MakeSymbol("linksPosNo");
+ S_linksPosId = MakeSymbol("linksPosId");
+ S_linksLenghts = MakeSymbol("linksLenghts");
+ S_linksLenghtsMean = MakeSymbol("linksLenghtsMean");
+ S_linksLenghtsStd = MakeSymbol("linksLenghtsStd");
+ S_linksLenghtsNo = MakeSymbol("linksLenghtsNo");
+ S_linksLenghtsId = MakeSymbol("linksLenghtsId");
+ S_massesForces = MakeSymbol("massesForces");
+ S_massesForcesName = MakeSymbol("massesForcesName");
+ S_massesForcesMean = MakeSymbol("massesForcesMean");
+ S_massesForcesStd = MakeSymbol("massesForcesStd");
+ S_massesForcesNo = MakeSymbol("massesForcesNo");
+ S_massesForcesId = MakeSymbol("massesForcesId");
+ S_massesSpeeds = MakeSymbol("massesSpeeds");
+ S_massesSpeedsName = MakeSymbol("massesSpeedsName");
+ S_massesSpeedsMean = MakeSymbol("massesSpeedsMean");
+ S_massesSpeedsStd = MakeSymbol("massesSpeedsStd");
+ S_massesSpeedsNo = MakeSymbol("massesSpeedsNo");
+ S_massesSpeedsId = MakeSymbol("massesSpeedsId");
+ S_massesPosL = MakeSymbol("massesPosL");
+ S_massesPosXL = MakeSymbol("massesPosXL");
+ S_massesPosYL = MakeSymbol("massesPosYL");
+ S_massesPosZL = MakeSymbol("massesPosZL");
+ S_massesForcesL = MakeSymbol("massesForcesL");
+
+ // --- set up methods (class scope) ---
+
+ // register a bang method to the default inlet (0)
+ FLEXT_CADDBANG(c,0,m_bang);
+
+ // set up tagged methods for the default inlet (0)
+ // the underscore _ after CADDMETHOD indicates that a message tag is used
+ // no, variable list or anything and all single arguments are recognized automatically, ...
+ FLEXT_CADDMETHOD_(c,0,"reset",m_reset);
+
+ FLEXT_CADDMETHOD_(c,0,"forceX",m_forceX);
+ FLEXT_CADDMETHOD_(c,0,"posX",m_posX);
+ FLEXT_CADDMETHOD_(c,0,"Xmax",m_Xmax);
+ FLEXT_CADDMETHOD_(c,0,"Xmin",m_Xmin);
+ FLEXT_CADDMETHOD_(c,0,"forceN",m_forceN);
+ FLEXT_CADDMETHOD_(c,0,"posN",m_posN);
+ FLEXT_CADDMETHOD_(c,0,"Nmax",m_Nmax);
+ FLEXT_CADDMETHOD_(c,0,"Nmin",m_Nmin);
+ FLEXT_CADDMETHOD_(c,0,"massesPosL",m_mass_dumpl);
+ FLEXT_CADDMETHOD_(c,0,"massesPosXL",m_mass_dump_xl);
+ if(N >= 2) {
+ FLEXT_CADDMETHOD_(c,0,"forceY",m_forceY);
+ FLEXT_CADDMETHOD_(c,0,"posY",m_posY);
+ FLEXT_CADDMETHOD_(c,0,"Ymax",m_Ymax);
+ FLEXT_CADDMETHOD_(c,0,"Ymin",m_Ymin);
+ FLEXT_CADDMETHOD_(c,0,"massesPosYL",m_mass_dump_yl);
+ FLEXT_CADDMETHOD_(c,0,"grabMass",m_grab_mass);
+ }
+ if(N >= 3) {
+ FLEXT_CADDMETHOD_(c,0,"forceZ",m_forceZ);
+ FLEXT_CADDMETHOD_(c,0,"posZ",m_posZ);
+ FLEXT_CADDMETHOD_(c,0,"Zmax",m_Zmax);
+ FLEXT_CADDMETHOD_(c,0,"Zmin",m_Zmin);
+ FLEXT_CADDMETHOD_(c,0,"massesPosZL",m_mass_dump_zl);
+ }
+
+ FLEXT_CADDMETHOD_(c,0,"setMobile",m_set_mobile);
+ FLEXT_CADDMETHOD_(c,0,"setFixed",m_set_fixe);
+ FLEXT_CADDMETHOD_(c,0,"setMassId",m_setMassId);
+ FLEXT_CADDMETHOD_(c,0,"setLinkId",m_setLinkId);
+ FLEXT_CADDMETHOD_(c,0,"setK",m_setK);
+ FLEXT_CADDMETHOD_(c,0,"setD",m_setD);
+ FLEXT_CADDMETHOD_(c,0,"setL",m_setL);
+ FLEXT_CADDMETHOD_(c,0,"setLtab",m_setLtab);
+ FLEXT_CADDMETHOD_(c,0,"setLMin",m_setLmin);
+ FLEXT_CADDMETHOD_(c,0,"setLMax",m_setLmax);
+ FLEXT_CADDMETHOD_(c,0,"setM",m_setM);
+ FLEXT_CADDMETHOD_(c,0,"setD2",m_setD2);
+ FLEXT_CADDMETHOD_(c,0,"mass",m_mass);
+ FLEXT_CADDMETHOD_(c,0,"link",m_link);
+ FLEXT_CADDMETHOD_(c,0,"iLink",m_ilink);
+ FLEXT_CADDMETHOD_(c,0,"tLink",m_tlink);
+ FLEXT_CADDMETHOD_(c,0,"nLink",m_nlink);
+ FLEXT_CADDMETHOD_(c,0,"tabLink",m_tablink);
+ FLEXT_CADDMETHOD_(c,0,"get",m_get);
+ FLEXT_CADDMETHOD_(c,0,"deleteLink",m_delete_link);
+ FLEXT_CADDMETHOD_(c,0,"deleteMass",m_delete_mass);
+ FLEXT_CADDMETHOD_(c,0,"infosL",m_info_dumpl);
+ FLEXT_CADDMETHOD_(c,0,"massesForcesL",m_force_dumpl);
+ }
+
+ // for every registered method a callback has to be declared
+ FLEXT_CALLBACK(m_bang)
+ FLEXT_CALLBACK(m_mass_dumpl)
+ FLEXT_CALLBACK(m_mass_dump_xl)
+ FLEXT_CALLBACK(m_mass_dump_yl)
+ FLEXT_CALLBACK(m_mass_dump_zl)
+ FLEXT_CALLBACK(m_info_dumpl)
+ FLEXT_CALLBACK(m_force_dumpl)
+ FLEXT_CALLBACK(m_reset)
+ FLEXT_CALLBACK_V(m_set_mobile)
+ FLEXT_CALLBACK_V(m_set_fixe)
+ FLEXT_CALLBACK_V(m_mass)
+ FLEXT_CALLBACK_V(m_link)
+ FLEXT_CALLBACK_V(m_ilink)
+ FLEXT_CALLBACK_V(m_tlink)
+ FLEXT_CALLBACK_V(m_nlink)
+ FLEXT_CALLBACK_V(m_tablink)
+ FLEXT_CALLBACK_V(m_Xmax)
+ FLEXT_CALLBACK_V(m_Xmin)
+ FLEXT_CALLBACK_V(m_forceX)
+ FLEXT_CALLBACK_V(m_posX)
+ FLEXT_CALLBACK_V(m_Ymax)
+ FLEXT_CALLBACK_V(m_Ymin)
+ FLEXT_CALLBACK_V(m_forceY)
+ FLEXT_CALLBACK_V(m_posY)
+ FLEXT_CALLBACK_V(m_Zmax)
+ FLEXT_CALLBACK_V(m_Zmin)
+ FLEXT_CALLBACK_V(m_forceZ)
+ FLEXT_CALLBACK_V(m_posZ)
+ FLEXT_CALLBACK_V(m_Nmax)
+ FLEXT_CALLBACK_V(m_Nmin)
+ FLEXT_CALLBACK_V(m_forceN)
+ FLEXT_CALLBACK_V(m_posN)
+ FLEXT_CALLBACK_V(m_setMassId)
+ FLEXT_CALLBACK_V(m_setLinkId)
+ FLEXT_CALLBACK_V(m_setK)
+ FLEXT_CALLBACK_V(m_setD)
+ FLEXT_CALLBACK_V(m_setL)
+ FLEXT_CALLBACK_V(m_setLtab)
+ FLEXT_CALLBACK_V(m_setLmin)
+ FLEXT_CALLBACK_V(m_setLmax)
+ FLEXT_CALLBACK_V(m_setM)
+ FLEXT_CALLBACK_V(m_setD2)
+ FLEXT_CALLBACK_V(m_get)
+ FLEXT_CALLBACK_V(m_delete_link)
+ FLEXT_CALLBACK_V(m_delete_mass)
+ FLEXT_CALLBACK_V(m_grab_mass)
+};
+// -------------------------------------------------------------- STATIC VARIABLES
+// -------------------------------------------------------------------------------
+
+template<int N> const t_symbol *msdN<N>::S_Reset;
+template<int N> const t_symbol *msdN<N>::S_Mass;
+template<int N> const t_symbol *msdN<N>::S_Link;
+template<int N> const t_symbol *msdN<N>::S_iLink;
+template<int N> const t_symbol *msdN<N>::S_tLink;
+template<int N> const t_symbol *msdN<N>::S_nLink;
+template<int N> const t_symbol *msdN<N>::S_tabLink;
+template<int N> const t_symbol *msdN<N>::S_Mass_deleted;
+template<int N> const t_symbol *msdN<N>::S_Link_deleted;
+template<int N> const t_symbol *msdN<N>::S_massesPos;
+template<int N> const t_symbol *msdN<N>::S_massesPosName;
+template<int N> const t_symbol *msdN<N>::S_massesPosNo;
+template<int N> const t_symbol *msdN<N>::S_massesPosId;
+template<int N> const t_symbol *msdN<N>::S_linksPos;
+template<int N> const t_symbol *msdN<N>::S_linksPosName;
+template<int N> const t_symbol *msdN<N>::S_linksPosNo;
+template<int N> const t_symbol *msdN<N>::S_linksPosId;
+template<int N> const t_symbol *msdN<N>::S_linksLenghts;
+template<int N> const t_symbol *msdN<N>::S_linksLenghtsMean;
+template<int N> const t_symbol *msdN<N>::S_linksLenghtsStd;
+template<int N> const t_symbol *msdN<N>::S_linksLenghtsNo;
+template<int N> const t_symbol *msdN<N>::S_linksLenghtsId;
+template<int N> const t_symbol *msdN<N>::S_massesForces;
+template<int N> const t_symbol *msdN<N>::S_massesForcesName;
+template<int N> const t_symbol *msdN<N>::S_massesForcesMean;
+template<int N> const t_symbol *msdN<N>::S_massesForcesStd;
+template<int N> const t_symbol *msdN<N>::S_massesForcesNo;
+template<int N> const t_symbol *msdN<N>::S_massesForcesId;
+template<int N> const t_symbol *msdN<N>::S_massesSpeeds;
+template<int N> const t_symbol *msdN<N>::S_massesSpeedsName;
+template<int N> const t_symbol *msdN<N>::S_massesSpeedsMean;
+template<int N> const t_symbol *msdN<N>::S_massesSpeedsStd;
+template<int N> const t_symbol *msdN<N>::S_massesSpeedsNo;
+template<int N> const t_symbol *msdN<N>::S_massesSpeedsId;
+template<int N> const t_symbol *msdN<N>::S_massesPosL;
+template<int N> const t_symbol *msdN<N>::S_massesPosXL;
+template<int N> const t_symbol *msdN<N>::S_massesPosYL;
+template<int N> const t_symbol *msdN<N>::S_massesPosZL;
+template<int N> const t_symbol *msdN<N>::S_massesPosStd;
+template<int N> const t_symbol *msdN<N>::S_massesPosMean;
+template<int N> const t_symbol *msdN<N>::S_massesForcesL;
+
+#define MSD(NAME,CLASS,N) \
+typedef msdN<N> CLASS; \
+template<> FLEXT_NEW_V(NAME,CLASS)
diff --git a/msd/utils/draw_link_force.pd b/msd/utils/draw_link_force.pd
new file mode 100644
index 0000000..514b8a8
--- /dev/null
+++ b/msd/utils/draw_link_force.pd
@@ -0,0 +1,94 @@
+#N canvas 520 143 684 479 10;
+#X obj 30 174 until;
+#X obj 30 244 - 100;
+#X obj 30 198 f;
+#X obj 58 198 + 1;
+#X obj 30 152 t f b;
+#X msg 74 174 0;
+#X msg 374 173 reset;
+#X obj 335 153 t b b b;
+#X obj 30 327 msd;
+#X obj 335 287 s \$0-msd;
+#X obj 150 277 r \$0-msd;
+#X obj 335 134 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 30 264 / 100;
+#X floatatom 128 152 5 0 0 0 - - -;
+#X obj 30 218 t f f;
+#X obj 30 390 tabwrite force;
+#X msg 354 199 mass M1 0 1 0;
+#X obj 30 348 route massesForcesId;
+#X obj 30 370 route M2;
+#N canvas 0 0 450 300 (subpatch) 0;
+#X array force 200 float 3;
+#A 0 0.123457 0.126247 0.129132 0.132118 0.135208 0.138408 0.141723
+0.145159 0.148721 0.152416 0.15625 0.160231 0.164366 0.168663 0.17313
+0.177778 0.182615 0.187652 0.192901 0.198373 0.204082 0.21004 0.216263
+0.222767 0.229568 0.236686 0.244141 0.251953 0.260146 0.268745 0.277778
+0.287274 0.297265 0.307787 0.318878 0.330579 0.342936 0.355999 0.369823
+0.384468 0.4 0.416493 0.434028 0.452694 0.47259 0.493827 0.516529 0.540833
+0.566893 0.594884 1.225 0.57 0.54 0.51 0.48 0.45 0.42 0.39 0.36 0.33
+0.3 0.27 0.24 0.21 0.18 0.15 0.12 0.09 0.0599999 0.03 0 -0.0300001
+-0.06 -0.09 -0.12 -0.15 -0.18 -0.21 -0.24 -0.27 -0.3 -0.33 -0.36 -0.39
+-0.42 -0.45 -0.48 -0.51 -0.54 -0.57 -0.6 -0.63 -0.66 -0.69 -0.72 -0.75
+-0.78 -0.81 -0.84 -0.87 0 0.87 0.84 0.81 0.78 0.75 0.72 0.69 0.66 0.63
+0.6 0.57 0.54 0.51 0.48 0.45 0.42 0.39 0.36 0.33 0.3 0.27 0.24 0.21
+0.18 0.15 0.12 0.09 0.06 0.0300001 0 -0.03 -0.0599999 -0.09 -0.12 -0.15
+-0.18 -0.21 -0.24 -0.27 -0.3 -0.33 -0.36 -0.39 -0.42 -0.45 -0.48 -0.51
+-0.54 -0.57 -1.225 -0.594884 -0.566893 -0.540833 -0.516529 -0.493827
+-0.47259 -0.452694 -0.434028 -0.416493 -0.4 -0.384468 -0.369823 -0.355999
+-0.342936 -0.330579 -0.318878 -0.307787 -0.297265 -0.287274 -0.277778
+-0.268745 -0.260146 -0.251953 -0.244141 -0.236686 -0.229568 -0.222767
+-0.216263 -0.21004 -0.204082 -0.198373 -0.192901 -0.187652 -0.182615
+-0.177778 -0.17313 -0.168663 -0.164366 -0.160231 -0.15625 -0.152416
+-0.148721 -0.145159 -0.141723 -0.138408 -0.135208 -0.132118 -0.129132
+-0.126247;
+#X coords 0 1 200 -1 200 140 1;
+#X restore 331 318 graph;
+#X msg 30 304 posX M2 \$1 \, bang \, get massesForces M2;
+#X obj 30 284 * 1;
+#X text 167 152 link length;
+#X text 360 132 reset;
+#X text 65 133 draw;
+#X msg 363 218 mass M2 1 1 0;
+#X obj 30 75 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 30 98 t b b;
+#X msg 337 243 link test M1 M2 0.1 0 -2 0.5 10 \, setL test 0.1;
+#X msg 354 262 link test2 M1 M2 3 0 1 0 0.5 \, setL test2 0.3;
+#X msg 30 132 200;
+#X text 31 9 This abstraction help to draw link forces regarding to
+it's elongation;
+#X connect 0 0 2 0;
+#X connect 1 0 12 0;
+#X connect 2 0 3 0;
+#X connect 2 0 14 0;
+#X connect 3 0 2 1;
+#X connect 4 0 0 0;
+#X connect 4 1 5 0;
+#X connect 5 0 2 1;
+#X connect 6 0 9 0;
+#X connect 7 0 28 0;
+#X connect 7 0 29 0;
+#X connect 7 1 16 0;
+#X connect 7 1 25 0;
+#X connect 7 2 6 0;
+#X connect 8 0 17 0;
+#X connect 10 0 8 0;
+#X connect 11 0 7 0;
+#X connect 12 0 21 0;
+#X connect 13 0 21 1;
+#X connect 14 0 1 0;
+#X connect 14 1 15 1;
+#X connect 16 0 9 0;
+#X connect 17 0 18 0;
+#X connect 18 0 15 0;
+#X connect 20 0 8 0;
+#X connect 21 0 20 0;
+#X connect 25 0 9 0;
+#X connect 26 0 27 0;
+#X connect 27 0 30 0;
+#X connect 27 1 11 0;
+#X connect 28 0 9 0;
+#X connect 29 0 9 0;
+#X connect 30 0 4 0;
diff --git a/nusmuk-audio/LICENSE.txt b/nusmuk-audio/LICENSE.txt
new file mode 100644
index 0000000..fa0bef4
--- /dev/null
+++ b/nusmuk-audio/LICENSE.txt
@@ -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/nusmuk-audio/Makefile b/nusmuk-audio/Makefile
new file mode 100644
index 0000000..e7c9281
--- /dev/null
+++ b/nusmuk-audio/Makefile
@@ -0,0 +1,303 @@
+## Pd library template version 1.0.5
+# For instructions on how to use this template, see:
+# http://puredata.info/docs/developer/MakefileTemplate
+LIBRARY_NAME = nusmuk-audio
+
+# add your .c source files, one object per file, to the SOURCES
+# variable, help files will be included automatically
+SOURCES = bq~.c tabosc4c~.c tabosci~.c tabread4c~.c
+
+# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
+# be included automatically
+PDOBJECTS = bq_coef_notch.pd additive~.pd oscillo~.pd bq_coef_peak.pd bq_coef_bp.pd pwm~.pd bq_coef_highshelf.pd compress_limit~.pd saw~.pd bq_coef_hip.pd distortion~.pd spatialisation~.pd bq_coef_lop.pd echo~.pd bq_coef_lowshelf.pd granulator~.pd
+
+# example patches and related files, in the 'examples' subfolder
+EXAMPLES = analog_synth_emulation.pd hanning.wav
+
+# manuals and related files, in the 'manual' subfolder
+MANUAL =
+
+# if you want to include any other files in the source and binary tarballs,
+# list them here. This can be anything from header files, test patches,
+# documentation, etc. README.txt and LICENSE.txt are required and therefore
+# automatically included
+EXTRA_DIST =
+
+
+
+#------------------------------------------------------------------------------#
+#
+# things you might need to edit if you are using other C libraries
+#
+#------------------------------------------------------------------------------#
+
+CFLAGS = -DPD -I"$(PD_INCLUDE)" -Wall -W -g
+LDFLAGS =
+LIBS =
+
+#------------------------------------------------------------------------------#
+#
+# you shouldn't need to edit anything below here, if we did it right :)
+#
+#------------------------------------------------------------------------------#
+
+# get library version from meta file
+LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd)
+
+CFLAGS += -DVERSION='"$(LIBRARY_VERSION)"'
+
+PD_INCLUDE = $(PD_PATH)/include
+# where to install the library, overridden below depending on platform
+prefix = /usr/local
+libdir = $(prefix)/lib
+pkglibdir = $(libdir)/pd-externals
+objectsdir = $(pkglibdir)
+
+INSTALL = install
+INSTALL_PROGRAM = $(INSTALL) -p -m 644
+INSTALL_DATA = $(INSTALL) -p -m 644
+INSTALL_DIR = $(INSTALL) -p -m 755 -d
+
+ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \
+ $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows)
+
+DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION)
+ORIGDIR=pd-$(LIBRARY_NAME:~=)_$(LIBRARY_VERSION)
+
+UNAME := $(shell uname -s)
+ifeq ($(UNAME),Darwin)
+ CPU := $(shell uname -p)
+ ifeq ($(CPU),arm) # iPhone/iPod Touch
+ SOURCES += $(SOURCES_iphoneos)
+ EXTENSION = pd_darwin
+ OS = iphoneos
+ PD_PATH = /Applications/Pd-extended.app/Contents/Resources
+ IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
+ CC=$(IPHONE_BASE)/gcc
+ CPP=$(IPHONE_BASE)/cpp
+ CXX=$(IPHONE_BASE)/g++
+ ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk
+ IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6
+ OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer
+ CFLAGS := $(IPHONE_CFLAGS) $(OPT_CFLAGS) $(CFLAGS)
+ LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT)
+ LIBS += -lc
+ STRIP = strip -x
+ DISTBINDIR=$(DISTDIR)-$(OS)
+ else # Mac OS X
+ SOURCES += $(SOURCES_macosx)
+ EXTENSION = pd_darwin
+ OS = macosx
+ PD_PATH = /Applications/Pd-extended.app/Contents/Resources
+ OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast
+# build universal 32-bit on 10.4 and 32/64 on newer
+ ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8)
+ FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4
+ else
+ FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
+ SOURCES += $(SOURCES_iphoneos)
+ endif
+ CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include
+ LDFLAGS += $(FAT_FLAGS) -bundle -undefined dynamic_lookup -L/sw/lib
+ # if the 'pd' binary exists, check the linking against it to aid with stripping
+ LDFLAGS += $(shell test -e $(PD_PATH)/bin/pd && echo -bundle_loader $(PD_PATH)/bin/pd)
+ LIBS += -lc
+ STRIP = strip -x
+ DISTBINDIR=$(DISTDIR)-$(OS)
+# install into ~/Library/Pd on Mac OS X since /usr/local isn't used much
+ pkglibdir=$(HOME)/Library/Pd
+ endif
+endif
+ifeq ($(UNAME),Linux)
+ CPU := $(shell uname -m)
+ SOURCES += $(SOURCES_linux)
+ EXTENSION = pd_linux
+ OS = linux
+ PD_PATH = /usr
+ OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+ CFLAGS += -fPIC
+ LDFLAGS += -Wl,--export-dynamic -shared -fPIC
+ LIBS += -lc
+ STRIP = strip --strip-unneeded -R .note -R .comment
+ DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
+endif
+ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME)))
+ CPU := $(shell uname -m)
+ SOURCES += $(SOURCES_cygwin)
+ EXTENSION = dll
+ OS = cygwin
+ PD_PATH = $(cygpath $(PROGRAMFILES))/pd
+ OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+ CFLAGS +=
+ LDFLAGS += -Wl,--export-dynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin"
+ LIBS += -lc -lpd
+ STRIP = strip --strip-unneeded -R .note -R .comment
+ DISTBINDIR=$(DISTDIR)-$(OS)
+endif
+ifeq (MINGW,$(findstring MINGW,$(UNAME)))
+ CPU := $(shell uname -m)
+ SOURCES += $(SOURCES_windows)
+ EXTENSION = dll
+ OS = windows
+ PD_PATH = $(shell cd "$(PROGRAMFILES)"/pd && pwd)
+ OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer
+ CFLAGS += -mms-bitfields
+ LDFLAGS += -s -shared -Wl,--enable-auto-import
+ LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" -lpd -lwsock32 -lkernel32 -luser32 -lgdi32
+ STRIP = strip --strip-unneeded -R .note -R .comment
+ DISTBINDIR=$(DISTDIR)-$(OS)
+endif
+
+# in case somebody manually set the HELPPATCHES above
+HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd)
+
+CFLAGS += $(OPT_CFLAGS)
+
+
+.PHONY = install libdir_install single_install install-doc install-exec install-examples install-manual clean dist etags $(LIBRARY_NAME)
+
+all: $(SOURCES:.c=.$(EXTENSION))
+
+%.o: %.c
+ $(CC) $(CFLAGS) -o "$*.o" -c "$*.c"
+
+%.$(EXTENSION): %.o
+ $(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(LIBS)
+ chmod a-x "$*.$(EXTENSION)"
+
+# this links everything into a single binary file
+$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o
+ $(CC) $(LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(LIBS)
+ chmod a-x $(LIBRARY_NAME).$(EXTENSION)
+
+install: libdir_install
+
+# The meta and help files are explicitly installed to make sure they are
+# actually there. Those files are not optional, then need to be there.
+libdir_install: $(SOURCES:.c=.$(EXTENSION)) install-doc install-examples install-manual
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \
+ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ test -z "$(strip $(SOURCES))" || (\
+ $(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \
+ $(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION))))
+ test -z "$(strip $(PDOBJECTS))" || \
+ $(INSTALL_DATA) $(PDOBJECTS) \
+ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+
+# install library linked as single binary
+single_install: $(LIBRARY_NAME) install-doc install-exec
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION)
+
+install-doc:
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ test -z "$(strip $(SOURCES) $(PDOBJECTS))" || \
+ $(INSTALL_DATA) $(HELPPATCHES) \
+ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(INSTALL_DATA) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt
+ $(INSTALL_DATA) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt
+
+install-examples:
+ test -z "$(strip $(EXAMPLES))" || \
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples && \
+ for file in $(EXAMPLES); do \
+ $(INSTALL_DATA) examples/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples; \
+ done
+
+install-manual:
+ test -z "$(strip $(MANUAL))" || \
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual && \
+ for file in $(MANUAL); do \
+ $(INSTALL_DATA) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \
+ done
+
+
+clean:
+ -rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o)
+ -rm -f -- $(SOURCES:.c=.$(EXTENSION))
+ -rm -f -- $(LIBRARY_NAME).o
+ -rm -f -- $(LIBRARY_NAME).$(EXTENSION)
+
+distclean: clean
+ -rm -f -- $(DISTBINDIR).tar.gz
+ -rm -rf -- $(DISTBINDIR)
+ -rm -f -- $(DISTDIR).tar.gz
+ -rm -rf -- $(DISTDIR)
+ -rm -f -- $(ORIGDIR).tar.gz
+ -rm -rf -- $(ORIGDIR)
+
+
+$(DISTBINDIR):
+ $(INSTALL_DIR) $(DISTBINDIR)
+
+libdir: all $(DISTBINDIR)
+ $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTBINDIR)
+ $(INSTALL_DATA) $(SOURCES) $(DISTBINDIR)
+ $(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR)
+ test -z "$(strip $(EXTRA_DIST))" || \
+ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTBINDIR)
+# tar --exclude-vcs -czpf $(DISTBINDIR).tar.gz $(DISTBINDIR)
+
+$(DISTDIR):
+ $(INSTALL_DIR) $(DISTDIR)
+
+$(ORIGDIR):
+ $(INSTALL_DIR) $(ORIGDIR)
+
+dist: $(DISTDIR)
+ $(INSTALL_DATA) Makefile $(DISTDIR)
+ $(INSTALL_DATA) README.txt $(DISTDIR)
+ $(INSTALL_DATA) LICENSE.txt $(DISTDIR)
+ $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTDIR)
+ test -z "$(strip $(ALLSOURCES))" || \
+ $(INSTALL_DATA) $(ALLSOURCES) $(DISTDIR)
+ test -z "$(strip $(PDOBJECTS))" || \
+ $(INSTALL_DATA) $(PDOBJECTS) $(DISTDIR)
+ test -z "$(strip $(HELPPATCHES))" || \
+ $(INSTALL_DATA) $(HELPPATCHES) $(DISTDIR)
+ test -z "$(strip $(EXTRA_DIST))" || \
+ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTDIR)
+ test -z "$(strip $(EXAMPLES))" || \
+ $(INSTALL_DIR) $(DISTDIR)/examples && \
+ for file in $(EXAMPLES); do \
+ $(INSTALL_DATA) examples/$$file $(DISTDIR)/examples; \
+ done
+ test -z "$(strip $(MANUAL))" || \
+ $(INSTALL_DIR) $(DISTDIR)/manual && \
+ for file in $(MANUAL); do \
+ $(INSTALL_DATA) manual/$$file $(DISTDIR)/manual; \
+ done
+ tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR)
+
+# make a Debian source package
+dpkg-source:
+ debclean
+ make distclean dist
+ mv $(DISTDIR) $(ORIGDIR)
+ tar --exclude-vcs -czpf ../$(ORIGDIR).orig.tar.gz $(ORIGDIR)
+ rm -f -- $(DISTDIR).tar.gz
+ rm -rf -- $(DISTDIR) $(ORIGDIR)
+ cd .. && dpkg-source -b $(LIBRARY_NAME)
+
+etags:
+ etags *.h $(SOURCES) ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h
+
+showsetup:
+ @echo "CFLAGS: $(CFLAGS)"
+ @echo "LDFLAGS: $(LDFLAGS)"
+ @echo "LIBS: $(LIBS)"
+ @echo "PD_INCLUDE: $(PD_INCLUDE)"
+ @echo "PD_PATH: $(PD_PATH)"
+ @echo "objectsdir: $(objectsdir)"
+ @echo "LIBRARY_NAME: $(LIBRARY_NAME)"
+ @echo "LIBRARY_VERSION: $(LIBRARY_VERSION)"
+ @echo "SOURCES: $(SOURCES)"
+ @echo "PDOBJECTS: $(PDOBJECTS)"
+ @echo "ALLSOURCES: $(ALLSOURCES)"
+ @echo "UNAME: $(UNAME)"
+ @echo "CPU: $(CPU)"
+ @echo "pkglibdir: $(pkglibdir)"
+ @echo "DISTDIR: $(DISTDIR)"
+ @echo "ORIGDIR: $(ORIGDIR)"
diff --git a/nusmuk-audio/README.txt b/nusmuk-audio/README.txt
new file mode 100644
index 0000000..7b4e0f1
--- /dev/null
+++ b/nusmuk-audio/README.txt
@@ -0,0 +1,8 @@
+This objects' collection is based on abstractions and externals. They aim at improving audio synthesis quality within Pure Data. This collection enholds band limited oscillator and objects that read tables in a more flexible way than the Pure Data native ones. Some filters and various objects are also available.
+
+This lib is made by Cyrille Henry, you can contact him throw his webpage :
+http://www.chnry.net/ch/?001-Cyrille-Henry
+
+This lib is realese under the GNU Public License.
+
+To build it, just type make.
diff --git a/additive-help.pd b/nusmuk-audio/additive~-help.pd
index 26d6e9f..a16853d 100644
--- a/additive-help.pd
+++ b/nusmuk-audio/additive~-help.pd
@@ -1,8 +1,7 @@
-#N canvas 120 75 697 786 10;
+#N canvas 120 75 697 667 10;
#X obj 85 91 hradio 15 1 0 6 empty empty empty 0 -6 0 8 -262144 -1
-1 0;
#X obj 34 748 dac~;
-#X obj 34 699 additive;
#X msg 34 171 waveform \$1 \$2;
#X floatatom 34 57 5 0 0 0 - - -;
#X obj 34 147 pack f f;
@@ -51,31 +50,32 @@
#X text 193 568 addresse each voice independently;
#X obj 111 405 pack f 54 90 300 500 1000 0.5 1800;
#X obj 148 527 pack f 69 90 100 500 1000 0.9 1800;
-#X connect 0 0 5 1;
-#X connect 2 0 35 0;
-#X connect 3 0 2 0;
-#X connect 4 0 5 0;
-#X connect 5 0 3 0;
-#X connect 8 0 14 0;
-#X connect 9 0 8 0;
-#X connect 10 0 8 1;
-#X connect 11 0 8 2;
-#X connect 12 0 8 3;
-#X connect 14 0 2 0;
-#X connect 17 0 49 1;
-#X connect 18 0 2 0;
-#X connect 19 0 20 0;
-#X connect 20 0 2 0;
-#X connect 22 0 5 0;
-#X connect 23 0 5 0;
-#X connect 25 0 2 0;
-#X connect 27 0 49 0;
-#X connect 29 0 5 0;
-#X connect 30 0 27 0;
-#X connect 31 0 48 1;
-#X connect 33 0 48 0;
-#X connect 34 0 33 0;
-#X connect 35 0 1 0;
-#X connect 35 0 1 1;
-#X connect 48 0 2 0;
-#X connect 49 0 2 0;
+#X obj 34 699 additive~;
+#X connect 0 0 4 1;
+#X connect 2 0 49 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
+#X connect 7 0 13 0;
+#X connect 8 0 7 0;
+#X connect 9 0 7 1;
+#X connect 10 0 7 2;
+#X connect 11 0 7 3;
+#X connect 13 0 49 0;
+#X connect 16 0 48 1;
+#X connect 17 0 49 0;
+#X connect 18 0 19 0;
+#X connect 19 0 49 0;
+#X connect 21 0 4 0;
+#X connect 22 0 4 0;
+#X connect 24 0 49 0;
+#X connect 26 0 48 0;
+#X connect 28 0 4 0;
+#X connect 29 0 26 0;
+#X connect 30 0 47 1;
+#X connect 32 0 47 0;
+#X connect 33 0 32 0;
+#X connect 34 0 1 0;
+#X connect 34 0 1 1;
+#X connect 47 0 49 0;
+#X connect 48 0 49 0;
+#X connect 49 0 34 0;
diff --git a/additive.pd b/nusmuk-audio/additive~.pd
index 2c6602f..2c6602f 100644
--- a/additive.pd
+++ b/nusmuk-audio/additive~.pd
diff --git a/nusmuk-audio/bq_coef_bp-help.pd b/nusmuk-audio/bq_coef_bp-help.pd
new file mode 100644
index 0000000..880781a
--- /dev/null
+++ b/nusmuk-audio/bq_coef_bp-help.pd
@@ -0,0 +1,113 @@
+#N canvas 544 74 484 505 10;
+#X obj 29 160 hip~ 2;
+#X msg 39 187 clear;
+#X obj 156 140 pack f f f f f;
+#X obj 156 94 mtof;
+#X floatatom 156 77 5 0 0 0 - - -;
+#X floatatom 219 98 5 0 0 0 - - -;
+#X obj 29 132 noise~;
+#N canvas 0 0 450 300 5_line~ 0;
+#X obj 80 123 line~;
+#X obj 79 147 outlet~;
+#X obj 80 73 inlet;
+#X obj 136 123 line~;
+#X obj 135 147 outlet~;
+#X obj 136 73 inlet;
+#X obj 193 123 line~;
+#X obj 192 147 outlet~;
+#X obj 193 73 inlet;
+#X obj 247 123 line~;
+#X obj 246 147 outlet~;
+#X obj 247 73 inlet;
+#X obj 304 123 line~;
+#X obj 303 147 outlet~;
+#X obj 304 73 inlet;
+#X msg 80 96 \$1 133;
+#X msg 136 96 \$1 133;
+#X msg 193 96 \$1 133;
+#X msg 247 96 \$1 133;
+#X msg 304 96 \$1 133;
+#X connect 0 0 1 0;
+#X connect 2 0 15 0;
+#X connect 3 0 4 0;
+#X connect 5 0 16 0;
+#X connect 6 0 7 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 11 0 18 0;
+#X connect 12 0 13 0;
+#X connect 14 0 19 0;
+#X connect 15 0 0 0;
+#X connect 16 0 3 0;
+#X connect 17 0 6 0;
+#X connect 18 0 9 0;
+#X connect 19 0 12 0;
+#X restore 45 258 pd 5_line~;
+#X obj 45 231 unpack f f f f f;
+#X obj 43 328 dac~;
+#X obj 156 166 t a;
+#X obj 44 301 *~ 0.1;
+#N canvas 0 0 444 301 oscillo 0;
+#X obj 41 25 loadbang;
+#X obj 26 223 metro 100;
+#X obj 8 -9 inlet~;
+#X msg 41 47 1;
+#X obj 42 81 tgl 20 0 empty empty Stop 0 -6 0 8 -258699 -1 -1 1 1;
+#X obj 118 -3 inlet;
+#X msg 147 48 1;
+#X msg 115 48 0;
+#X obj 118 21 moses 10;
+#X obj 19 263 tabwrite~ \$0-oscillo;
+#X obj 100 140 cnv 1 300 1 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 0 767 419 (subpatch) 0;
+#X array \$0-oscillo 300 float 0;
+#X coords 0 1 299 -1 300 80 1;
+#X restore 100 100 graph;
+#X obj 110 75 change;
+#X obj 234 62 block~ 640 1 0.25;
+#X connect 0 0 3 0;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 6 0 12 0;
+#X connect 7 0 12 0;
+#X connect 8 0 7 0;
+#X connect 8 1 6 0;
+#X connect 8 1 1 1;
+#X connect 12 0 1 0;
+#X coords 0 -1 1 1 300 80 1 100 100;
+#X restore 29 372 pd oscillo;
+#X text 260 95 Q;
+#X text 192 77 cutoff;
+#X obj 156 116 bq_coef_bp;
+#X text 153 8 band pass filter coeficient for a biquad;
+#X obj 29 280 bq~ --------;
+#X connect 0 0 17 0;
+#X connect 1 0 17 0;
+#X connect 2 0 10 0;
+#X connect 3 0 15 0;
+#X connect 4 0 3 0;
+#X connect 5 0 15 1;
+#X connect 6 0 0 0;
+#X connect 7 0 17 1;
+#X connect 7 1 17 2;
+#X connect 7 2 17 3;
+#X connect 7 3 17 4;
+#X connect 7 4 17 5;
+#X connect 8 0 7 0;
+#X connect 8 1 7 1;
+#X connect 8 2 7 2;
+#X connect 8 3 7 3;
+#X connect 8 4 7 4;
+#X connect 10 0 8 0;
+#X connect 11 0 9 0;
+#X connect 15 0 2 0;
+#X connect 15 1 2 1;
+#X connect 15 2 2 2;
+#X connect 15 3 2 3;
+#X connect 15 4 2 4;
+#X connect 17 0 11 0;
+#X connect 17 0 12 0;
diff --git a/nusmuk-audio/bq_coef_bp.pd b/nusmuk-audio/bq_coef_bp.pd
new file mode 100644
index 0000000..565d91e
--- /dev/null
+++ b/nusmuk-audio/bq_coef_bp.pd
@@ -0,0 +1,84 @@
+#N canvas 0 0 417 599 10;
+#X obj 50 32 inlet;
+#X obj 211 31 inlet;
+#X text 92 34 f;
+#X text 256 31 Q;
+#X obj 119 148 samplerate~;
+#X obj 119 125 loadbang;
+#X obj 176 126 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 180 /;
+#X obj 50 349 cos;
+#X obj 199 276 sin;
+#X obj 211 126 * 2;
+#X obj 50 544 outlet;
+#X obj 288 484 + 1;
+#X obj 50 467 * -2;
+#X obj 50 249 t f f;
+#X obj 50 519 /;
+#X obj 94 520 /;
+#X obj 139 520 /;
+#X obj 229 520 /;
+#X obj 139 544 outlet;
+#X obj 94 544 outlet;
+#X obj 184 544 outlet;
+#X obj 229 544 outlet;
+#X obj 50 226 f;
+#X obj 211 195 t b f;
+#X msg 94 438 1 \$1;
+#X obj 94 483 -;
+#X obj 229 481 * -1;
+#X msg 184 520 0;
+#X obj 199 330 t f b f;
+#X obj 211 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 122 * 3.14159;
+#X obj 211 105 + 0.7;
+#X msg 211 148 1 \$1;
+#X obj 211 170 /;
+#X obj 50 148 * 2;
+#X obj 50 99 min 21000;
+#X obj 199 303 * 0.767;
+#X obj 238 242 expr sinh($f1);
+#X connect 0 0 31 0;
+#X connect 1 0 30 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 23 0;
+#X connect 8 0 13 0;
+#X connect 9 0 38 0;
+#X connect 10 0 34 0;
+#X connect 12 0 15 1;
+#X connect 12 0 16 1;
+#X connect 12 0 17 1;
+#X connect 12 0 18 1;
+#X connect 13 0 15 0;
+#X connect 14 0 8 0;
+#X connect 14 1 9 0;
+#X connect 15 0 11 0;
+#X connect 16 0 20 0;
+#X connect 17 0 19 0;
+#X connect 18 0 22 0;
+#X connect 23 0 14 0;
+#X connect 24 0 23 0;
+#X connect 24 1 39 0;
+#X connect 25 0 26 0;
+#X connect 26 0 16 0;
+#X connect 27 0 18 0;
+#X connect 28 0 21 0;
+#X connect 29 0 25 0;
+#X connect 29 0 17 0;
+#X connect 29 0 27 0;
+#X connect 29 1 28 0;
+#X connect 29 2 12 0;
+#X connect 30 0 33 0;
+#X connect 31 0 37 0;
+#X connect 32 0 36 0;
+#X connect 33 0 10 0;
+#X connect 34 0 35 0;
+#X connect 35 0 24 0;
+#X connect 36 0 7 0;
+#X connect 37 0 32 0;
+#X connect 38 0 29 0;
+#X connect 39 0 38 1;
diff --git a/nusmuk-audio/bq_coef_highshelf-help.pd b/nusmuk-audio/bq_coef_highshelf-help.pd
new file mode 100644
index 0000000..e8286ad
--- /dev/null
+++ b/nusmuk-audio/bq_coef_highshelf-help.pd
@@ -0,0 +1,113 @@
+#N canvas 143 113 484 505 10;
+#X obj 29 160 hip~ 2;
+#X msg 39 189 clear;
+#X obj 156 140 pack f f f f f;
+#X obj 156 94 mtof;
+#X floatatom 156 77 5 0 0 0 - - -;
+#X floatatom 219 98 5 0 0 0 - - -;
+#X obj 29 132 noise~;
+#N canvas 0 0 450 300 5_line~ 0;
+#X obj 80 123 line~;
+#X obj 79 147 outlet~;
+#X obj 80 73 inlet;
+#X obj 136 123 line~;
+#X obj 135 147 outlet~;
+#X obj 136 73 inlet;
+#X obj 193 123 line~;
+#X obj 192 147 outlet~;
+#X obj 193 73 inlet;
+#X obj 247 123 line~;
+#X obj 246 147 outlet~;
+#X obj 247 73 inlet;
+#X obj 304 123 line~;
+#X obj 303 147 outlet~;
+#X obj 304 73 inlet;
+#X msg 80 96 \$1 133;
+#X msg 136 96 \$1 133;
+#X msg 193 96 \$1 133;
+#X msg 247 96 \$1 133;
+#X msg 304 96 \$1 133;
+#X connect 0 0 1 0;
+#X connect 2 0 15 0;
+#X connect 3 0 4 0;
+#X connect 5 0 16 0;
+#X connect 6 0 7 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 11 0 18 0;
+#X connect 12 0 13 0;
+#X connect 14 0 19 0;
+#X connect 15 0 0 0;
+#X connect 16 0 3 0;
+#X connect 17 0 6 0;
+#X connect 18 0 9 0;
+#X connect 19 0 12 0;
+#X restore 45 258 pd 5_line~;
+#X obj 45 231 unpack f f f f f;
+#X obj 43 328 dac~;
+#X obj 156 166 t a;
+#X obj 44 301 *~ 0.1;
+#N canvas 0 0 444 301 oscillo 0;
+#X obj 41 25 loadbang;
+#X obj 26 223 metro 100;
+#X obj 8 -9 inlet~;
+#X msg 41 47 1;
+#X obj 42 81 tgl 20 0 empty empty Stop 0 -6 0 8 -258699 -1 -1 1 1;
+#X obj 118 -3 inlet;
+#X msg 147 48 1;
+#X msg 115 48 0;
+#X obj 118 21 moses 10;
+#X obj 19 263 tabwrite~ \$0-oscillo;
+#X obj 100 140 cnv 1 300 1 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 0 767 419 (subpatch) 0;
+#X array \$0-oscillo 300 float 0;
+#X coords 0 1 299 -1 300 80 1;
+#X restore 100 100 graph;
+#X obj 110 75 change;
+#X obj 234 62 block~ 640 1 0.25;
+#X connect 0 0 3 0;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 6 0 12 0;
+#X connect 7 0 12 0;
+#X connect 8 0 7 0;
+#X connect 8 1 6 0;
+#X connect 8 1 1 1;
+#X connect 12 0 1 0;
+#X coords 0 -1 1 1 300 80 1 100 100;
+#X restore 29 372 pd oscillo;
+#X text 192 77 cutoff;
+#X text 153 8 high shelf filter coeficient for a biquad;
+#X obj 156 116 bq_coef_highshelf;
+#X text 260 95 gain;
+#X obj 29 280 bq~ --------;
+#X connect 0 0 17 0;
+#X connect 1 0 17 0;
+#X connect 2 0 10 0;
+#X connect 3 0 15 0;
+#X connect 4 0 3 0;
+#X connect 5 0 15 1;
+#X connect 6 0 0 0;
+#X connect 7 0 17 1;
+#X connect 7 1 17 2;
+#X connect 7 2 17 3;
+#X connect 7 3 17 4;
+#X connect 7 4 17 5;
+#X connect 8 0 7 0;
+#X connect 8 1 7 1;
+#X connect 8 2 7 2;
+#X connect 8 3 7 3;
+#X connect 8 4 7 4;
+#X connect 10 0 8 0;
+#X connect 11 0 9 0;
+#X connect 15 0 2 0;
+#X connect 15 1 2 1;
+#X connect 15 2 2 2;
+#X connect 15 3 2 3;
+#X connect 15 4 2 4;
+#X connect 17 0 11 0;
+#X connect 17 0 12 0;
diff --git a/nusmuk-audio/bq_coef_highshelf.pd b/nusmuk-audio/bq_coef_highshelf.pd
new file mode 100644
index 0000000..52e1132
--- /dev/null
+++ b/nusmuk-audio/bq_coef_highshelf.pd
@@ -0,0 +1,100 @@
+#N canvas 0 0 511 569 10;
+#X obj 50 32 inlet;
+#X text 92 34 f;
+#X obj 50 165 * 6.283;
+#X obj 106 188 samplerate~;
+#X obj 106 166 loadbang;
+#X obj 164 167 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 220 /;
+#X obj 96 272 cos;
+#X obj 69 271 sin;
+#X obj 319 36 inlet;
+#X text 387 146 A;
+#X obj 319 121 pow;
+#X msg 319 100 10;
+#X obj 319 81 t b f;
+#X obj 319 58 / 40;
+#X obj 319 182 t f f;
+#X obj 319 204 *;
+#X obj 319 224 + 1;
+#X obj 360 183 - 1;
+#X obj 360 204 t f f;
+#X obj 360 226 *;
+#X obj 319 254 -;
+#X text 360 279 beta;
+#X obj 319 278 sqrt;
+#X obj 319 143 t f f f;
+#X obj 50 243 t b f f;
+#X obj 50 493 /;
+#X obj 50 525 outlet;
+#X obj 99 527 outlet;
+#X obj 149 528 outlet;
+#X obj 199 528 outlet;
+#X obj 249 529 outlet;
+#X obj 99 493 /;
+#X obj 149 496 /;
+#X obj 199 494 /;
+#X obj 249 497 /;
+#X obj 50 392 expr 2 * ( ($f2-1) - ($f2+1)*$f4 ) \; ($f2+1) - ($f2-1)*$f4
+- $f1*$f3 \; $f2 * ( ($f2+1) + ($f2-1)*$f4 + $f1*$f3 ) \; -2 * $f2
+* ( ($f2-1) + ($f2+1)*$f4 ) \; $f2 * ( ($f2+1) + ($f2-1)*$f4 - $f1*$f3
+) \; ($f2+1) - ($f2-1)*$f4 + $f1*$f3 \;;
+#X obj 50 73 max 0;
+#X obj 50 99 min 21000;
+#X obj 50 357 f;
+#X msg 135 281 1;
+#X obj 135 302 sqrt;
+#X obj 135 257 loadbang;
+#X connect 0 0 37 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 1;
+#X connect 4 0 3 0;
+#X connect 5 0 3 0;
+#X connect 6 0 25 0;
+#X connect 7 0 36 3;
+#X connect 8 0 36 2;
+#X connect 9 0 14 0;
+#X connect 11 0 24 0;
+#X connect 12 0 11 0;
+#X connect 13 0 12 0;
+#X connect 13 1 11 1;
+#X connect 14 0 13 0;
+#X connect 15 0 16 0;
+#X connect 15 1 16 1;
+#X connect 16 0 17 0;
+#X connect 17 0 21 0;
+#X connect 18 0 19 0;
+#X connect 19 0 20 0;
+#X connect 19 1 20 1;
+#X connect 20 0 21 1;
+#X connect 21 0 23 0;
+#X connect 23 0 36 0;
+#X connect 24 0 15 0;
+#X connect 24 1 18 0;
+#X connect 24 2 36 1;
+#X connect 25 0 39 0;
+#X connect 25 1 8 0;
+#X connect 25 2 7 0;
+#X connect 26 0 27 0;
+#X connect 32 0 28 0;
+#X connect 33 0 29 0;
+#X connect 34 0 30 0;
+#X connect 35 0 31 0;
+#X connect 36 0 26 0;
+#X connect 36 1 32 0;
+#X connect 36 2 33 0;
+#X connect 36 3 34 0;
+#X connect 36 4 35 0;
+#X connect 36 5 26 1;
+#X connect 36 5 32 1;
+#X connect 36 5 33 1;
+#X connect 36 5 34 1;
+#X connect 36 5 35 1;
+#X connect 37 0 38 0;
+#X connect 38 0 2 0;
+#X connect 39 0 36 0;
+#X connect 40 0 41 0;
+#X connect 40 0 36 1;
+#X connect 41 0 39 1;
+#X connect 42 0 40 0;
diff --git a/nusmuk-audio/bq_coef_hip-help.pd b/nusmuk-audio/bq_coef_hip-help.pd
new file mode 100644
index 0000000..2e0ddb5
--- /dev/null
+++ b/nusmuk-audio/bq_coef_hip-help.pd
@@ -0,0 +1,113 @@
+#N canvas 544 74 484 505 10;
+#X obj 29 160 hip~ 2;
+#X msg 40 187 clear;
+#X obj 156 140 pack f f f f f;
+#X obj 156 94 mtof;
+#X floatatom 156 77 5 0 0 0 - - -;
+#X floatatom 219 98 5 0 0 0 - - -;
+#X obj 29 132 noise~;
+#N canvas 0 0 450 300 5_line~ 0;
+#X obj 80 123 line~;
+#X obj 79 147 outlet~;
+#X obj 80 73 inlet;
+#X obj 136 123 line~;
+#X obj 135 147 outlet~;
+#X obj 136 73 inlet;
+#X obj 193 123 line~;
+#X obj 192 147 outlet~;
+#X obj 193 73 inlet;
+#X obj 247 123 line~;
+#X obj 246 147 outlet~;
+#X obj 247 73 inlet;
+#X obj 304 123 line~;
+#X obj 303 147 outlet~;
+#X obj 304 73 inlet;
+#X msg 80 96 \$1 133;
+#X msg 136 96 \$1 133;
+#X msg 193 96 \$1 133;
+#X msg 247 96 \$1 133;
+#X msg 304 96 \$1 133;
+#X connect 0 0 1 0;
+#X connect 2 0 15 0;
+#X connect 3 0 4 0;
+#X connect 5 0 16 0;
+#X connect 6 0 7 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 11 0 18 0;
+#X connect 12 0 13 0;
+#X connect 14 0 19 0;
+#X connect 15 0 0 0;
+#X connect 16 0 3 0;
+#X connect 17 0 6 0;
+#X connect 18 0 9 0;
+#X connect 19 0 12 0;
+#X restore 45 258 pd 5_line~;
+#X obj 45 231 unpack f f f f f;
+#X obj 43 328 dac~;
+#X obj 156 166 t a;
+#X obj 44 301 *~ 0.1;
+#N canvas 0 0 444 301 oscillo 0;
+#X obj 41 25 loadbang;
+#X obj 26 223 metro 100;
+#X obj 8 -9 inlet~;
+#X msg 41 47 1;
+#X obj 42 81 tgl 20 0 empty empty Stop 0 -6 0 8 -258699 -1 -1 1 1;
+#X obj 118 -3 inlet;
+#X msg 147 48 1;
+#X msg 115 48 0;
+#X obj 118 21 moses 10;
+#X obj 19 263 tabwrite~ \$0-oscillo;
+#X obj 100 140 cnv 1 300 1 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 0 767 419 (subpatch) 0;
+#X array \$0-oscillo 300 float 0;
+#X coords 0 1 299 -1 300 80 1;
+#X restore 100 100 graph;
+#X obj 110 75 change;
+#X obj 234 62 block~ 640 1 0.25;
+#X connect 0 0 3 0;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 6 0 12 0;
+#X connect 7 0 12 0;
+#X connect 8 0 7 0;
+#X connect 8 1 6 0;
+#X connect 8 1 1 1;
+#X connect 12 0 1 0;
+#X coords 0 -1 1 1 300 80 1 100 100;
+#X restore 29 372 pd oscillo;
+#X text 260 95 Q;
+#X text 192 77 cutoff;
+#X obj 156 116 bq_coef_hip;
+#X text 153 8 high pass filter coeficient for a biquad;
+#X obj 29 280 bq~ --------;
+#X connect 0 0 17 0;
+#X connect 1 0 17 0;
+#X connect 2 0 10 0;
+#X connect 3 0 15 0;
+#X connect 4 0 3 0;
+#X connect 5 0 15 1;
+#X connect 6 0 0 0;
+#X connect 7 0 17 1;
+#X connect 7 1 17 2;
+#X connect 7 2 17 3;
+#X connect 7 3 17 4;
+#X connect 7 4 17 5;
+#X connect 8 0 7 0;
+#X connect 8 1 7 1;
+#X connect 8 2 7 2;
+#X connect 8 3 7 3;
+#X connect 8 4 7 4;
+#X connect 10 0 8 0;
+#X connect 11 0 9 0;
+#X connect 15 0 2 0;
+#X connect 15 1 2 1;
+#X connect 15 2 2 2;
+#X connect 15 3 2 3;
+#X connect 15 4 2 4;
+#X connect 17 0 11 0;
+#X connect 17 0 12 0;
diff --git a/nusmuk-audio/bq_coef_hip.pd b/nusmuk-audio/bq_coef_hip.pd
new file mode 100644
index 0000000..a3f578f
--- /dev/null
+++ b/nusmuk-audio/bq_coef_hip.pd
@@ -0,0 +1,104 @@
+#N canvas 0 0 360 583 10;
+#X obj 50 32 inlet;
+#X obj 211 31 inlet;
+#X text 92 34 f;
+#X text 256 31 Q;
+#X obj 116 138 samplerate~;
+#X obj 116 115 loadbang;
+#X obj 173 116 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 170 /;
+#X obj 50 339 cos;
+#X obj 199 266 sin;
+#X obj 211 116 * 2;
+#X obj 50 534 outlet;
+#X obj 288 474 + 1;
+#X obj 139 471 / 2;
+#X msg 139 428 1 \$1;
+#X obj 184 450 -;
+#X obj 229 471 / 2;
+#X msg 229 428 1 \$1;
+#X obj 50 457 * -2;
+#X obj 50 239 t f f;
+#X obj 50 509 /;
+#X obj 94 510 /;
+#X obj 139 510 /;
+#X obj 184 509 /;
+#X obj 229 510 /;
+#X obj 139 534 outlet;
+#X obj 94 534 outlet;
+#X obj 184 534 outlet;
+#X obj 229 534 outlet;
+#X obj 50 216 f;
+#X obj 211 185 t b f;
+#X obj 211 95 + 0.707;
+#X msg 94 428 1 \$1;
+#X obj 94 473 -;
+#X obj 199 320 t f f;
+#X obj 139 450 +;
+#X obj 229 451 +;
+#X msg 184 428 -1 \$1;
+#X obj 211 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 364 t f f b;
+#X obj 50 115 * 3.14159;
+#X obj 60 193 min 3.14;
+#X obj 199 294 * 0.767;
+#X obj 238 254 sinh;
+#X msg 211 140 1 \$1;
+#X obj 211 162 /;
+#X obj 50 144 * 2;
+#X obj 50 95 min 21000;
+#X connect 0 0 39 0;
+#X connect 1 0 38 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 29 0;
+#X connect 8 0 40 0;
+#X connect 9 0 43 0;
+#X connect 10 0 45 0;
+#X connect 12 0 20 1;
+#X connect 12 0 21 1;
+#X connect 12 0 22 1;
+#X connect 12 0 23 1;
+#X connect 12 0 24 1;
+#X connect 13 0 22 0;
+#X connect 14 0 35 0;
+#X connect 15 0 23 0;
+#X connect 16 0 24 0;
+#X connect 17 0 36 0;
+#X connect 18 0 20 0;
+#X connect 19 0 8 0;
+#X connect 19 1 9 0;
+#X connect 20 0 11 0;
+#X connect 21 0 26 0;
+#X connect 22 0 25 0;
+#X connect 23 0 27 0;
+#X connect 24 0 28 0;
+#X connect 29 0 19 0;
+#X connect 30 0 29 0;
+#X connect 30 1 44 0;
+#X connect 31 0 10 0;
+#X connect 32 0 33 0;
+#X connect 33 0 21 0;
+#X connect 34 0 32 0;
+#X connect 34 1 12 0;
+#X connect 35 0 13 0;
+#X connect 36 0 16 0;
+#X connect 37 0 15 0;
+#X connect 38 0 31 0;
+#X connect 39 0 48 0;
+#X connect 40 0 18 0;
+#X connect 40 1 14 0;
+#X connect 40 1 37 0;
+#X connect 40 1 17 0;
+#X connect 40 2 33 0;
+#X connect 41 0 47 0;
+#X connect 42 0 29 0;
+#X connect 43 0 34 0;
+#X connect 44 0 43 1;
+#X connect 45 0 46 0;
+#X connect 46 0 30 0;
+#X connect 47 0 7 0;
+#X connect 48 0 41 0;
diff --git a/nusmuk-audio/bq_coef_lop-help.pd b/nusmuk-audio/bq_coef_lop-help.pd
new file mode 100644
index 0000000..2e0fa85
--- /dev/null
+++ b/nusmuk-audio/bq_coef_lop-help.pd
@@ -0,0 +1,113 @@
+#N canvas 544 74 484 505 10;
+#X obj 29 160 hip~ 2;
+#X msg 42 190 clear;
+#X obj 156 140 pack f f f f f;
+#X obj 156 94 mtof;
+#X floatatom 156 77 5 0 0 0 - - -;
+#X floatatom 219 98 5 0 0 0 - - -;
+#X obj 29 132 noise~;
+#N canvas 0 0 450 300 5_line~ 0;
+#X obj 80 123 line~;
+#X obj 79 147 outlet~;
+#X obj 80 73 inlet;
+#X obj 136 123 line~;
+#X obj 135 147 outlet~;
+#X obj 136 73 inlet;
+#X obj 193 123 line~;
+#X obj 192 147 outlet~;
+#X obj 193 73 inlet;
+#X obj 247 123 line~;
+#X obj 246 147 outlet~;
+#X obj 247 73 inlet;
+#X obj 304 123 line~;
+#X obj 303 147 outlet~;
+#X obj 304 73 inlet;
+#X msg 80 96 \$1 133;
+#X msg 136 96 \$1 133;
+#X msg 193 96 \$1 133;
+#X msg 247 96 \$1 133;
+#X msg 304 96 \$1 133;
+#X connect 0 0 1 0;
+#X connect 2 0 15 0;
+#X connect 3 0 4 0;
+#X connect 5 0 16 0;
+#X connect 6 0 7 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 11 0 18 0;
+#X connect 12 0 13 0;
+#X connect 14 0 19 0;
+#X connect 15 0 0 0;
+#X connect 16 0 3 0;
+#X connect 17 0 6 0;
+#X connect 18 0 9 0;
+#X connect 19 0 12 0;
+#X restore 45 258 pd 5_line~;
+#X obj 45 231 unpack f f f f f;
+#X obj 43 328 dac~;
+#X obj 156 166 t a;
+#X obj 44 301 *~ 0.1;
+#X obj 156 116 bq_coef_lop;
+#N canvas 0 0 444 301 oscillo 0;
+#X obj 41 25 loadbang;
+#X obj 26 223 metro 100;
+#X obj 8 -9 inlet~;
+#X msg 41 47 1;
+#X obj 42 81 tgl 20 0 empty empty Stop 0 -6 0 8 -258699 -1 -1 1 1;
+#X obj 118 -3 inlet;
+#X msg 147 48 1;
+#X msg 115 48 0;
+#X obj 118 21 moses 10;
+#X obj 19 263 tabwrite~ \$0-oscillo;
+#X obj 100 140 cnv 1 300 1 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 0 767 419 (subpatch) 0;
+#X array \$0-oscillo 300 float 0;
+#X coords 0 1 299 -1 300 80 1;
+#X restore 100 100 graph;
+#X obj 110 75 change;
+#X obj 234 62 block~ 640 1 0.25;
+#X connect 0 0 3 0;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 6 0 12 0;
+#X connect 7 0 12 0;
+#X connect 8 0 7 0;
+#X connect 8 1 6 0;
+#X connect 8 1 1 1;
+#X connect 12 0 1 0;
+#X coords 0 -1 1 1 300 80 1 100 100;
+#X restore 29 372 pd oscillo;
+#X text 153 8 low pass filter coeficient for a biquad;
+#X text 260 95 Q;
+#X text 192 77 cutoff;
+#X obj 29 280 bq~ --------;
+#X connect 0 0 17 0;
+#X connect 1 0 17 0;
+#X connect 2 0 10 0;
+#X connect 3 0 12 0;
+#X connect 4 0 3 0;
+#X connect 5 0 12 1;
+#X connect 6 0 0 0;
+#X connect 7 0 17 1;
+#X connect 7 1 17 2;
+#X connect 7 2 17 3;
+#X connect 7 3 17 4;
+#X connect 7 4 17 5;
+#X connect 8 0 7 0;
+#X connect 8 1 7 1;
+#X connect 8 2 7 2;
+#X connect 8 3 7 3;
+#X connect 8 4 7 4;
+#X connect 10 0 8 0;
+#X connect 11 0 9 0;
+#X connect 12 0 2 0;
+#X connect 12 1 2 1;
+#X connect 12 2 2 2;
+#X connect 12 3 2 3;
+#X connect 12 4 2 4;
+#X connect 17 0 11 0;
+#X connect 17 0 13 0;
diff --git a/nusmuk-audio/bq_coef_lop.pd b/nusmuk-audio/bq_coef_lop.pd
new file mode 100644
index 0000000..5f25d20
--- /dev/null
+++ b/nusmuk-audio/bq_coef_lop.pd
@@ -0,0 +1,104 @@
+#N canvas 0 0 454 630 10;
+#X obj 50 32 inlet;
+#X obj 211 31 inlet;
+#X text 92 34 f;
+#X text 256 31 Q;
+#X obj 117 137 samplerate~;
+#X obj 117 114 loadbang;
+#X obj 174 115 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 170 /;
+#X obj 50 369 cos;
+#X obj 199 296 sin;
+#X obj 211 116 * 2;
+#X obj 50 564 outlet;
+#X obj 288 504 + 1;
+#X obj 139 501 / 2;
+#X obj 94 505 -;
+#X msg 99 463 1 \$1;
+#X msg 139 458 1 \$1;
+#X obj 184 480 -;
+#X obj 229 501 / 2;
+#X msg 229 460 1 \$1;
+#X obj 50 487 * -2;
+#X obj 139 480 -;
+#X msg 184 458 1 \$1;
+#X obj 229 481 -;
+#X obj 199 350 t f f;
+#X obj 50 269 t f f;
+#X obj 50 539 /;
+#X obj 94 540 /;
+#X obj 139 540 /;
+#X obj 184 539 /;
+#X obj 229 540 /;
+#X obj 139 564 outlet;
+#X obj 94 564 outlet;
+#X obj 184 564 outlet;
+#X obj 229 564 outlet;
+#X obj 50 246 f;
+#X obj 211 185 t b f;
+#X obj 211 95 + 0.707;
+#X obj 211 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 394 t f f b;
+#X obj 50 115 * 3.14159;
+#X obj 67 206 min 3.14;
+#X obj 238 295 sinh;
+#X obj 199 325 * 0.767;
+#X msg 211 140 1 \$1;
+#X obj 211 162 /;
+#X obj 50 143 * 2;
+#X obj 50 95 min 21000;
+#X connect 0 0 39 0;
+#X connect 1 0 38 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 35 0;
+#X connect 8 0 40 0;
+#X connect 9 0 44 0;
+#X connect 10 0 45 0;
+#X connect 12 0 26 1;
+#X connect 12 0 27 1;
+#X connect 12 0 28 1;
+#X connect 12 0 29 1;
+#X connect 12 0 30 1;
+#X connect 13 0 28 0;
+#X connect 14 0 27 0;
+#X connect 15 0 14 0;
+#X connect 16 0 21 0;
+#X connect 17 0 29 0;
+#X connect 18 0 30 0;
+#X connect 19 0 23 0;
+#X connect 20 0 26 0;
+#X connect 21 0 13 0;
+#X connect 22 0 17 0;
+#X connect 23 0 18 0;
+#X connect 24 0 15 0;
+#X connect 24 1 12 0;
+#X connect 25 0 8 0;
+#X connect 25 1 9 0;
+#X connect 26 0 11 0;
+#X connect 27 0 32 0;
+#X connect 28 0 31 0;
+#X connect 29 0 33 0;
+#X connect 30 0 34 0;
+#X connect 35 0 25 0;
+#X connect 36 0 35 0;
+#X connect 36 1 43 0;
+#X connect 37 0 10 0;
+#X connect 38 0 37 0;
+#X connect 39 0 48 0;
+#X connect 40 0 20 0;
+#X connect 40 1 16 0;
+#X connect 40 1 22 0;
+#X connect 40 1 19 0;
+#X connect 40 2 14 0;
+#X connect 41 0 47 0;
+#X connect 42 0 35 0;
+#X connect 43 0 44 1;
+#X connect 44 0 24 0;
+#X connect 45 0 46 0;
+#X connect 46 0 36 0;
+#X connect 47 0 7 0;
+#X connect 48 0 41 0;
diff --git a/nusmuk-audio/bq_coef_lowshelf-help.pd b/nusmuk-audio/bq_coef_lowshelf-help.pd
new file mode 100644
index 0000000..7ce08b6
--- /dev/null
+++ b/nusmuk-audio/bq_coef_lowshelf-help.pd
@@ -0,0 +1,113 @@
+#N canvas 143 113 484 505 10;
+#X obj 29 160 hip~ 2;
+#X msg 45 191 clear;
+#X obj 156 140 pack f f f f f;
+#X obj 156 94 mtof;
+#X floatatom 156 77 5 0 0 0 - - -;
+#X floatatom 219 98 5 0 0 0 - - -;
+#X obj 29 132 noise~;
+#N canvas 0 0 450 300 5_line~ 0;
+#X obj 80 123 line~;
+#X obj 79 147 outlet~;
+#X obj 80 73 inlet;
+#X obj 136 123 line~;
+#X obj 135 147 outlet~;
+#X obj 136 73 inlet;
+#X obj 193 123 line~;
+#X obj 192 147 outlet~;
+#X obj 193 73 inlet;
+#X obj 247 123 line~;
+#X obj 246 147 outlet~;
+#X obj 247 73 inlet;
+#X obj 304 123 line~;
+#X obj 303 147 outlet~;
+#X obj 304 73 inlet;
+#X msg 80 96 \$1 133;
+#X msg 136 96 \$1 133;
+#X msg 193 96 \$1 133;
+#X msg 247 96 \$1 133;
+#X msg 304 96 \$1 133;
+#X connect 0 0 1 0;
+#X connect 2 0 15 0;
+#X connect 3 0 4 0;
+#X connect 5 0 16 0;
+#X connect 6 0 7 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 11 0 18 0;
+#X connect 12 0 13 0;
+#X connect 14 0 19 0;
+#X connect 15 0 0 0;
+#X connect 16 0 3 0;
+#X connect 17 0 6 0;
+#X connect 18 0 9 0;
+#X connect 19 0 12 0;
+#X restore 45 258 pd 5_line~;
+#X obj 45 231 unpack f f f f f;
+#X obj 43 328 dac~;
+#X obj 156 166 t a;
+#X obj 44 301 *~ 0.1;
+#N canvas 0 0 444 301 oscillo 0;
+#X obj 41 25 loadbang;
+#X obj 26 223 metro 100;
+#X obj 8 -9 inlet~;
+#X msg 41 47 1;
+#X obj 42 81 tgl 20 0 empty empty Stop 0 -6 0 8 -258699 -1 -1 1 1;
+#X obj 118 -3 inlet;
+#X msg 147 48 1;
+#X msg 115 48 0;
+#X obj 118 21 moses 10;
+#X obj 19 263 tabwrite~ \$0-oscillo;
+#X obj 100 140 cnv 1 300 1 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 0 767 419 (subpatch) 0;
+#X array \$0-oscillo 300 float 0;
+#X coords 0 1 299 -1 300 80 1;
+#X restore 100 100 graph;
+#X obj 110 75 change;
+#X obj 234 62 block~ 640 1 0.25;
+#X connect 0 0 3 0;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 6 0 12 0;
+#X connect 7 0 12 0;
+#X connect 8 0 7 0;
+#X connect 8 1 6 0;
+#X connect 8 1 1 1;
+#X connect 12 0 1 0;
+#X coords 0 -1 1 1 300 80 1 100 100;
+#X restore 29 372 pd oscillo;
+#X text 192 77 cutoff;
+#X text 260 95 gain;
+#X obj 156 116 bq_coef_lowshelf;
+#X text 153 8 low shelf filter coeficient for a biquad;
+#X obj 29 280 bq~ --------;
+#X connect 0 0 17 0;
+#X connect 1 0 17 0;
+#X connect 2 0 10 0;
+#X connect 3 0 15 0;
+#X connect 4 0 3 0;
+#X connect 5 0 15 1;
+#X connect 6 0 0 0;
+#X connect 7 0 17 1;
+#X connect 7 1 17 2;
+#X connect 7 2 17 3;
+#X connect 7 3 17 4;
+#X connect 7 4 17 5;
+#X connect 8 0 7 0;
+#X connect 8 1 7 1;
+#X connect 8 2 7 2;
+#X connect 8 3 7 3;
+#X connect 8 4 7 4;
+#X connect 10 0 8 0;
+#X connect 11 0 9 0;
+#X connect 15 0 2 0;
+#X connect 15 1 2 1;
+#X connect 15 2 2 2;
+#X connect 15 3 2 3;
+#X connect 15 4 2 4;
+#X connect 17 0 11 0;
+#X connect 17 0 12 0;
diff --git a/nusmuk-audio/bq_coef_lowshelf.pd b/nusmuk-audio/bq_coef_lowshelf.pd
new file mode 100644
index 0000000..00969c9
--- /dev/null
+++ b/nusmuk-audio/bq_coef_lowshelf.pd
@@ -0,0 +1,105 @@
+#N canvas 0 0 551 580 10;
+#X obj 50 32 inlet;
+#X text 92 34 f;
+#X obj 50 185 * 6.283;
+#X obj 106 208 samplerate~;
+#X obj 106 186 loadbang;
+#X obj 164 187 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 240 /;
+#X obj 96 292 cos;
+#X obj 69 291 sin;
+#X obj 319 36 inlet;
+#X text 387 176 A;
+#X obj 319 121 pow;
+#X msg 319 100 10;
+#X obj 319 81 t b f;
+#X obj 319 58 / 40;
+#X obj 319 212 t f f;
+#X obj 319 234 *;
+#X obj 319 254 + 1;
+#X obj 360 213 - 1;
+#X obj 360 234 t f f;
+#X obj 360 256 *;
+#X obj 319 284 -;
+#X text 360 309 beta;
+#X obj 319 308 sqrt;
+#X obj 319 173 t f f f;
+#X obj 50 263 t b f f;
+#X obj 50 493 /;
+#X obj 50 391 expr -2 * ( ($f2-1) + ($f2+1)*$f4 ) \; ($f2+1) + ($f2-1)*$f4
+- $f1*$f3 \; $f2 * ( ($f2+1) - ($f2-1)*$f4 + $f1*$f3 ) \; 2 * $f2 *
+( ($f2-1) - ($f2+1)*$f4 ) \; $f2 * ( ($f2+1) - ($f2-1)*$f4 - $f1*$f3
+) \; ($f2+1) + ($f2-1)*$f4 + $f1*$f3 \;;
+#X obj 50 525 outlet;
+#X obj 99 527 outlet;
+#X obj 149 528 outlet;
+#X obj 199 528 outlet;
+#X obj 249 529 outlet;
+#X obj 99 493 /;
+#X obj 149 496 /;
+#X obj 199 494 /;
+#X obj 249 497 /;
+#X obj 50 73 max 0;
+#X obj 50 99 min 21000;
+#X obj 319 149 1;
+#X obj 353 125 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 357 f;
+#X msg 135 281 1;
+#X obj 135 302 sqrt;
+#X obj 135 257 loadbang;
+#X connect 0 0 37 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 1;
+#X connect 4 0 3 0;
+#X connect 5 0 3 0;
+#X connect 6 0 25 0;
+#X connect 7 0 27 3;
+#X connect 8 0 27 2;
+#X connect 9 0 14 0;
+#X connect 11 0 39 0;
+#X connect 12 0 11 0;
+#X connect 13 0 12 0;
+#X connect 13 1 11 1;
+#X connect 14 0 13 0;
+#X connect 15 0 16 0;
+#X connect 15 1 16 1;
+#X connect 16 0 17 0;
+#X connect 17 0 21 0;
+#X connect 18 0 19 0;
+#X connect 19 0 20 0;
+#X connect 19 1 20 1;
+#X connect 20 0 21 1;
+#X connect 21 0 23 0;
+#X connect 23 0 27 0;
+#X connect 24 0 15 0;
+#X connect 24 1 18 0;
+#X connect 24 2 27 1;
+#X connect 25 0 41 0;
+#X connect 25 1 8 0;
+#X connect 25 2 7 0;
+#X connect 26 0 28 0;
+#X connect 27 0 26 0;
+#X connect 27 1 33 0;
+#X connect 27 2 34 0;
+#X connect 27 3 35 0;
+#X connect 27 4 36 0;
+#X connect 27 5 26 1;
+#X connect 27 5 33 1;
+#X connect 27 5 34 1;
+#X connect 27 5 35 1;
+#X connect 27 5 36 1;
+#X connect 33 0 29 0;
+#X connect 34 0 30 0;
+#X connect 35 0 31 0;
+#X connect 36 0 32 0;
+#X connect 37 0 38 0;
+#X connect 38 0 2 0;
+#X connect 39 0 24 0;
+#X connect 40 0 39 0;
+#X connect 41 0 27 0;
+#X connect 42 0 43 0;
+#X connect 42 0 27 1;
+#X connect 43 0 41 1;
+#X connect 44 0 42 0;
diff --git a/nusmuk-audio/bq_coef_notch-help.pd b/nusmuk-audio/bq_coef_notch-help.pd
new file mode 100644
index 0000000..5c1d7f0
--- /dev/null
+++ b/nusmuk-audio/bq_coef_notch-help.pd
@@ -0,0 +1,113 @@
+#N canvas 143 113 484 505 10;
+#X obj 29 160 hip~ 2;
+#X msg 48 185 clear;
+#X obj 156 140 pack f f f f f;
+#X obj 156 94 mtof;
+#X floatatom 156 77 5 0 0 0 - - -;
+#X floatatom 231 98 5 0 0 0 - - -;
+#X obj 29 132 noise~;
+#N canvas 0 0 450 300 5_line~ 0;
+#X obj 80 123 line~;
+#X obj 79 147 outlet~;
+#X obj 80 73 inlet;
+#X obj 136 123 line~;
+#X obj 135 147 outlet~;
+#X obj 136 73 inlet;
+#X obj 193 123 line~;
+#X obj 192 147 outlet~;
+#X obj 193 73 inlet;
+#X obj 247 123 line~;
+#X obj 246 147 outlet~;
+#X obj 247 73 inlet;
+#X obj 304 123 line~;
+#X obj 303 147 outlet~;
+#X obj 304 73 inlet;
+#X msg 80 96 \$1 133;
+#X msg 136 96 \$1 133;
+#X msg 193 96 \$1 133;
+#X msg 247 96 \$1 133;
+#X msg 304 96 \$1 133;
+#X connect 0 0 1 0;
+#X connect 2 0 15 0;
+#X connect 3 0 4 0;
+#X connect 5 0 16 0;
+#X connect 6 0 7 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 11 0 18 0;
+#X connect 12 0 13 0;
+#X connect 14 0 19 0;
+#X connect 15 0 0 0;
+#X connect 16 0 3 0;
+#X connect 17 0 6 0;
+#X connect 18 0 9 0;
+#X connect 19 0 12 0;
+#X restore 45 258 pd 5_line~;
+#X obj 45 231 unpack f f f f f;
+#X obj 43 328 dac~;
+#X obj 156 166 t a;
+#X obj 44 301 *~ 0.1;
+#N canvas 0 0 444 301 oscillo 0;
+#X obj 41 25 loadbang;
+#X obj 26 223 metro 100;
+#X obj 8 -9 inlet~;
+#X msg 41 47 1;
+#X obj 42 81 tgl 20 0 empty empty Stop 0 -6 0 8 -258699 -1 -1 1 1;
+#X obj 118 -3 inlet;
+#X msg 147 48 1;
+#X msg 115 48 0;
+#X obj 118 21 moses 10;
+#X obj 19 263 tabwrite~ \$0-oscillo;
+#X obj 100 140 cnv 1 300 1 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 0 767 419 (subpatch) 0;
+#X array \$0-oscillo 300 float 0;
+#X coords 0 1 299 -1 300 80 1;
+#X restore 100 100 graph;
+#X obj 110 75 change;
+#X obj 234 62 block~ 640 1 0.25;
+#X connect 0 0 3 0;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 6 0 12 0;
+#X connect 7 0 12 0;
+#X connect 8 0 7 0;
+#X connect 8 1 6 0;
+#X connect 8 1 1 1;
+#X connect 12 0 1 0;
+#X coords 0 -1 1 1 300 80 1 100 100;
+#X restore 29 372 pd oscillo;
+#X text 192 77 cutoff;
+#X text 155 12 notch filter coeficient for a biquad;
+#X obj 156 116 bq_coef_notch;
+#X text 269 96 Q;
+#X obj 28 280 bq~ --------;
+#X connect 0 0 17 0;
+#X connect 1 0 17 0;
+#X connect 2 0 10 0;
+#X connect 3 0 15 0;
+#X connect 4 0 3 0;
+#X connect 5 0 15 1;
+#X connect 6 0 0 0;
+#X connect 7 0 17 1;
+#X connect 7 1 17 2;
+#X connect 7 2 17 3;
+#X connect 7 3 17 4;
+#X connect 7 4 17 5;
+#X connect 8 0 7 0;
+#X connect 8 1 7 1;
+#X connect 8 2 7 2;
+#X connect 8 3 7 3;
+#X connect 8 4 7 4;
+#X connect 10 0 8 0;
+#X connect 11 0 9 0;
+#X connect 15 0 2 0;
+#X connect 15 1 2 1;
+#X connect 15 2 2 2;
+#X connect 15 3 2 3;
+#X connect 15 4 2 4;
+#X connect 17 0 11 0;
+#X connect 17 0 12 0;
diff --git a/nusmuk-audio/bq_coef_notch.pd b/nusmuk-audio/bq_coef_notch.pd
new file mode 100644
index 0000000..abfc38e
--- /dev/null
+++ b/nusmuk-audio/bq_coef_notch.pd
@@ -0,0 +1,86 @@
+#N canvas 0 0 387 638 10;
+#X obj 50 32 inlet;
+#X obj 205 31 inlet;
+#X text 92 34 f;
+#X text 250 31 Q;
+#X obj 119 148 samplerate~;
+#X obj 119 125 loadbang;
+#X obj 176 126 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 180 /;
+#X obj 50 349 cos;
+#X obj 199 276 sin;
+#X obj 205 126 * 2;
+#X obj 50 574 outlet;
+#X obj 288 484 + 1;
+#X obj 50 467 * -2;
+#X obj 50 249 t f f;
+#X obj 50 519 /;
+#X obj 94 520 /;
+#X obj 139 520 /;
+#X obj 229 520 /;
+#X obj 139 574 outlet;
+#X obj 94 574 outlet;
+#X obj 184 574 outlet;
+#X obj 229 574 outlet;
+#X obj 50 226 f;
+#X obj 205 195 t b f;
+#X msg 94 438 1 \$1;
+#X obj 94 483 -;
+#X obj 199 330 t f b f;
+#X obj 205 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 122 * 3.14159;
+#X msg 205 148 1 \$1;
+#X obj 232 242 sinh;
+#X obj 205 170 /;
+#X obj 199 303 *;
+#X obj 50 148 * 2;
+#X msg 139 487 1;
+#X msg 231 481 1;
+#X obj 50 548 t f f;
+#X obj 205 104 + 0.1;
+#X obj 50 99 min 21000;
+#X connect 0 0 29 0;
+#X connect 1 0 28 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 23 0;
+#X connect 8 0 13 0;
+#X connect 9 0 34 0;
+#X connect 10 0 31 0;
+#X connect 12 0 15 1;
+#X connect 12 0 16 1;
+#X connect 12 0 17 1;
+#X connect 12 0 18 1;
+#X connect 13 0 15 0;
+#X connect 14 0 8 0;
+#X connect 14 1 9 0;
+#X connect 15 0 38 0;
+#X connect 16 0 20 0;
+#X connect 17 0 19 0;
+#X connect 18 0 22 0;
+#X connect 23 0 14 0;
+#X connect 24 0 23 0;
+#X connect 24 1 32 0;
+#X connect 25 0 26 0;
+#X connect 26 0 16 0;
+#X connect 27 0 25 0;
+#X connect 27 1 36 0;
+#X connect 27 1 37 0;
+#X connect 27 2 12 0;
+#X connect 28 0 39 0;
+#X connect 29 0 40 0;
+#X connect 30 0 35 0;
+#X connect 31 0 33 0;
+#X connect 32 0 34 1;
+#X connect 33 0 24 0;
+#X connect 34 0 27 0;
+#X connect 35 0 7 0;
+#X connect 36 0 17 0;
+#X connect 37 0 18 0;
+#X connect 38 0 11 0;
+#X connect 38 1 21 0;
+#X connect 39 0 10 0;
+#X connect 40 0 30 0;
diff --git a/nusmuk-audio/bq_coef_peak-help.pd b/nusmuk-audio/bq_coef_peak-help.pd
new file mode 100644
index 0000000..45e9eb2
--- /dev/null
+++ b/nusmuk-audio/bq_coef_peak-help.pd
@@ -0,0 +1,116 @@
+#N canvas 143 113 484 505 10;
+#X obj 29 160 hip~ 2;
+#X msg 43 188 clear;
+#X obj 156 140 pack f f f f f;
+#X obj 156 94 mtof;
+#X floatatom 156 77 5 0 0 0 - - -;
+#X floatatom 190 98 5 0 0 0 - - -;
+#X obj 29 132 noise~;
+#N canvas 0 0 450 300 5_line~ 0;
+#X obj 80 123 line~;
+#X obj 79 147 outlet~;
+#X obj 80 73 inlet;
+#X obj 136 123 line~;
+#X obj 135 147 outlet~;
+#X obj 136 73 inlet;
+#X obj 193 123 line~;
+#X obj 192 147 outlet~;
+#X obj 193 73 inlet;
+#X obj 247 123 line~;
+#X obj 246 147 outlet~;
+#X obj 247 73 inlet;
+#X obj 304 123 line~;
+#X obj 303 147 outlet~;
+#X obj 304 73 inlet;
+#X msg 80 96 \$1 133;
+#X msg 136 96 \$1 133;
+#X msg 193 96 \$1 133;
+#X msg 247 96 \$1 133;
+#X msg 304 96 \$1 133;
+#X connect 0 0 1 0;
+#X connect 2 0 15 0;
+#X connect 3 0 4 0;
+#X connect 5 0 16 0;
+#X connect 6 0 7 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 11 0 18 0;
+#X connect 12 0 13 0;
+#X connect 14 0 19 0;
+#X connect 15 0 0 0;
+#X connect 16 0 3 0;
+#X connect 17 0 6 0;
+#X connect 18 0 9 0;
+#X connect 19 0 12 0;
+#X restore 45 258 pd 5_line~;
+#X obj 45 231 unpack f f f f f;
+#X obj 43 328 dac~;
+#X obj 156 166 t a;
+#X obj 44 301 *~ 0.1;
+#N canvas 0 0 444 301 oscillo 0;
+#X obj 41 25 loadbang;
+#X obj 26 223 metro 100;
+#X obj 8 -9 inlet~;
+#X msg 41 47 1;
+#X obj 42 81 tgl 20 0 empty empty Stop 0 -6 0 8 -258699 -1 -1 1 1;
+#X obj 118 -3 inlet;
+#X msg 147 48 1;
+#X msg 115 48 0;
+#X obj 118 21 moses 10;
+#X obj 19 263 tabwrite~ \$0-oscillo;
+#X obj 100 140 cnv 1 300 1 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 0 767 419 (subpatch) 0;
+#X array \$0-oscillo 300 float 0;
+#X coords 0 1 299 -1 300 80 1;
+#X restore 100 100 graph;
+#X obj 110 75 change;
+#X obj 234 62 block~ 640 1 0.25;
+#X connect 0 0 3 0;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 6 0 12 0;
+#X connect 7 0 12 0;
+#X connect 8 0 7 0;
+#X connect 8 1 6 0;
+#X connect 8 1 1 1;
+#X connect 12 0 1 0;
+#X coords 0 -1 1 1 300 80 1 100 100;
+#X restore 29 372 pd oscillo;
+#X text 192 77 cutoff;
+#X text 155 12 notch filter coeficient for a biquad;
+#X text 228 96 Q;
+#X obj 156 116 bq_coef_peak;
+#X floatatom 244 98 5 0 0 0 - - -;
+#X text 282 96 Gain;
+#X obj 29 280 bq~ --------;
+#X connect 0 0 19 0;
+#X connect 1 0 19 0;
+#X connect 2 0 10 0;
+#X connect 3 0 16 0;
+#X connect 4 0 3 0;
+#X connect 5 0 16 1;
+#X connect 6 0 0 0;
+#X connect 7 0 19 1;
+#X connect 7 1 19 2;
+#X connect 7 2 19 3;
+#X connect 7 3 19 4;
+#X connect 7 4 19 5;
+#X connect 8 0 7 0;
+#X connect 8 1 7 1;
+#X connect 8 2 7 2;
+#X connect 8 3 7 3;
+#X connect 8 4 7 4;
+#X connect 10 0 8 0;
+#X connect 11 0 9 0;
+#X connect 16 0 2 0;
+#X connect 16 1 2 1;
+#X connect 16 2 2 2;
+#X connect 16 3 2 3;
+#X connect 16 4 2 4;
+#X connect 17 0 16 2;
+#X connect 19 0 11 0;
+#X connect 19 0 12 0;
diff --git a/nusmuk-audio/bq_coef_peak.pd b/nusmuk-audio/bq_coef_peak.pd
new file mode 100644
index 0000000..a3f2e2b
--- /dev/null
+++ b/nusmuk-audio/bq_coef_peak.pd
@@ -0,0 +1,113 @@
+#N canvas 0 0 433 621 10;
+#X obj 50 32 inlet;
+#X obj 206 31 inlet;
+#X text 92 34 f;
+#X text 251 31 Q;
+#X obj 119 148 samplerate~;
+#X obj 119 125 loadbang;
+#X obj 176 126 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 180 /;
+#X obj 50 349 cos;
+#X obj 200 276 sin;
+#X obj 206 126 * 2;
+#X obj 50 574 outlet;
+#X obj 283 485 + 1;
+#X obj 50 467 * -2;
+#X obj 50 249 t f f;
+#X obj 50 519 /;
+#X obj 94 520 /;
+#X obj 139 520 /;
+#X obj 229 520 /;
+#X obj 139 574 outlet;
+#X obj 94 574 outlet;
+#X obj 184 574 outlet;
+#X obj 229 574 outlet;
+#X obj 50 226 f;
+#X obj 206 195 t b f;
+#X msg 94 458 1 \$1;
+#X obj 206 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 128 * 3.14159;
+#X msg 206 148 1 \$1;
+#X obj 233 226 sinh;
+#X obj 206 170 /;
+#X obj 50 148 * 2;
+#X obj 50 548 t f f;
+#X obj 206 104 + 0.1;
+#X obj 302 32 inlet;
+#X text 344 198 A;
+#X obj 302 117 pow;
+#X msg 302 96 10;
+#X obj 302 77 t b f;
+#X obj 302 54 / 40;
+#X msg 140 460 1 \$1;
+#X msg 230 460 1 \$1;
+#X obj 230 485 -;
+#X obj 200 356 t f f;
+#X obj 302 202 t b f;
+#X obj 140 485 +;
+#X obj 94 483 -;
+#X obj 50 99 min 21000;
+#X obj 200 406 / 1;
+#X obj 230 407 * 1;
+#X obj 283 407 / 1;
+#X obj 200 303 * 74.2;
+#X connect 0 0 27 0;
+#X connect 1 0 26 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 23 0;
+#X connect 8 0 13 0;
+#X connect 9 0 52 0;
+#X connect 10 0 29 0;
+#X connect 12 0 15 1;
+#X connect 12 0 16 1;
+#X connect 12 0 17 1;
+#X connect 12 0 18 1;
+#X connect 13 0 15 0;
+#X connect 14 0 8 0;
+#X connect 14 1 9 0;
+#X connect 15 0 33 0;
+#X connect 16 0 20 0;
+#X connect 17 0 19 0;
+#X connect 18 0 22 0;
+#X connect 23 0 14 0;
+#X connect 24 0 23 0;
+#X connect 24 1 30 0;
+#X connect 25 0 47 0;
+#X connect 26 0 34 0;
+#X connect 27 0 48 0;
+#X connect 28 0 32 0;
+#X connect 29 0 31 0;
+#X connect 30 0 52 1;
+#X connect 31 0 24 0;
+#X connect 32 0 7 0;
+#X connect 33 0 11 0;
+#X connect 33 1 21 0;
+#X connect 34 0 10 0;
+#X connect 35 0 40 0;
+#X connect 37 0 45 0;
+#X connect 38 0 37 0;
+#X connect 39 0 38 0;
+#X connect 39 1 37 1;
+#X connect 40 0 39 0;
+#X connect 41 0 46 0;
+#X connect 42 0 43 0;
+#X connect 43 0 18 0;
+#X connect 44 0 49 0;
+#X connect 44 0 50 0;
+#X connect 44 1 51 0;
+#X connect 45 0 23 0;
+#X connect 45 1 49 1;
+#X connect 45 1 50 1;
+#X connect 45 1 51 1;
+#X connect 46 0 17 0;
+#X connect 47 0 16 0;
+#X connect 48 0 28 0;
+#X connect 49 0 25 0;
+#X connect 50 0 42 0;
+#X connect 50 0 41 0;
+#X connect 51 0 12 0;
+#X connect 52 0 44 0;
diff --git a/nusmuk-audio/bq~-help.pd b/nusmuk-audio/bq~-help.pd
new file mode 100644
index 0000000..3b6928a
--- /dev/null
+++ b/nusmuk-audio/bq~-help.pd
@@ -0,0 +1,926 @@
+#N canvas 425 30 746 628 10;
+#X obj 342 172 mtof;
+#X floatatom 342 156 5 0 127 0 - - -;
+#X floatatom 477 170 5 0 0 0 - - -;
+#N canvas 435 52 535 646 coef_lowShelf_biquad 0;
+#X obj 50 32 inlet;
+#X text 92 34 f;
+#X obj 50 185 * 6.283;
+#X obj 106 208 samplerate~;
+#X obj 106 186 loadbang;
+#X obj 164 187 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 240 /;
+#X obj 96 292 cos;
+#X obj 69 291 sin;
+#X obj 319 36 inlet;
+#X text 387 176 A;
+#X obj 319 121 pow;
+#X msg 319 100 10;
+#X obj 319 81 t b f;
+#X obj 319 58 / 40;
+#X obj 319 212 t f f;
+#X obj 319 234 *;
+#X obj 319 254 + 1;
+#X obj 360 213 - 1;
+#X obj 360 234 t f f;
+#X obj 360 256 *;
+#X obj 319 284 -;
+#X text 360 309 beta;
+#X obj 319 308 sqrt;
+#X obj 319 173 t f f f;
+#X obj 50 263 t b f f;
+#X obj 50 493 /;
+#X obj 50 391 expr -2 * ( ($f2-1) + ($f2+1)*$f4 ) \; ($f2+1) + ($f2-1)*$f4
+- $f1*$f3 \; $f2 * ( ($f2+1) - ($f2-1)*$f4 + $f1*$f3 ) \; 2 * $f2 *
+( ($f2-1) - ($f2+1)*$f4 ) \; $f2 * ( ($f2+1) - ($f2-1)*$f4 - $f1*$f3
+) \; ($f2+1) + ($f2-1)*$f4 + $f1*$f3 \;;
+#X obj 50 525 outlet;
+#X obj 99 527 outlet;
+#X obj 149 528 outlet;
+#X obj 199 528 outlet;
+#X obj 249 529 outlet;
+#X obj 99 493 /;
+#X obj 149 496 /;
+#X obj 199 494 /;
+#X obj 249 497 /;
+#X obj 50 73 max 0;
+#X obj 50 99 min 21000;
+#X obj 319 149 1;
+#X obj 353 125 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 357 f;
+#X msg 135 281 1;
+#X obj 135 302 sqrt;
+#X obj 135 257 loadbang;
+#X connect 0 0 37 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 1;
+#X connect 4 0 3 0;
+#X connect 5 0 3 0;
+#X connect 6 0 25 0;
+#X connect 7 0 27 3;
+#X connect 8 0 27 2;
+#X connect 9 0 14 0;
+#X connect 11 0 39 0;
+#X connect 12 0 11 0;
+#X connect 13 0 12 0;
+#X connect 13 1 11 1;
+#X connect 14 0 13 0;
+#X connect 15 0 16 0;
+#X connect 15 1 16 1;
+#X connect 16 0 17 0;
+#X connect 17 0 21 0;
+#X connect 18 0 19 0;
+#X connect 19 0 20 0;
+#X connect 19 1 20 1;
+#X connect 20 0 21 1;
+#X connect 21 0 23 0;
+#X connect 23 0 27 0;
+#X connect 24 0 15 0;
+#X connect 24 1 18 0;
+#X connect 24 2 27 1;
+#X connect 25 0 41 0;
+#X connect 25 1 8 0;
+#X connect 25 2 7 0;
+#X connect 26 0 28 0;
+#X connect 27 0 26 0;
+#X connect 27 1 33 0;
+#X connect 27 2 34 0;
+#X connect 27 3 35 0;
+#X connect 27 4 36 0;
+#X connect 27 5 26 1;
+#X connect 27 5 33 1;
+#X connect 27 5 34 1;
+#X connect 27 5 35 1;
+#X connect 27 5 36 1;
+#X connect 33 0 29 0;
+#X connect 34 0 30 0;
+#X connect 35 0 31 0;
+#X connect 36 0 32 0;
+#X connect 37 0 38 0;
+#X connect 38 0 2 0;
+#X connect 39 0 24 0;
+#X connect 40 0 39 0;
+#X connect 41 0 27 0;
+#X connect 42 0 43 0;
+#X connect 42 0 27 1;
+#X connect 43 0 41 1;
+#X connect 44 0 42 0;
+#X restore 342 192 pd coef_lowShelf_biquad;
+#X obj 28 425 hip~ 2;
+#N canvas 275 396 358 628 coef_hpf_biquad 0;
+#X obj 50 32 inlet;
+#X obj 211 31 inlet;
+#X text 92 34 f;
+#X text 256 31 Q;
+#X obj 116 138 samplerate~;
+#X obj 116 115 loadbang;
+#X obj 173 116 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 170 /;
+#X obj 50 339 cos;
+#X obj 199 266 sin;
+#X obj 211 116 * 2;
+#X obj 50 534 outlet;
+#X obj 288 474 + 1;
+#X obj 139 471 / 2;
+#X msg 139 428 1 \$1;
+#X obj 184 450 -;
+#X obj 229 471 / 2;
+#X msg 229 428 1 \$1;
+#X obj 50 457 * -2;
+#X obj 50 239 t f f;
+#X obj 50 509 /;
+#X obj 94 510 /;
+#X obj 139 510 /;
+#X obj 184 509 /;
+#X obj 229 510 /;
+#X obj 139 534 outlet;
+#X obj 94 534 outlet;
+#X obj 184 534 outlet;
+#X obj 229 534 outlet;
+#X obj 50 216 f;
+#X obj 211 185 t b f;
+#X obj 211 95 + 0.707;
+#X msg 94 428 1 \$1;
+#X obj 94 473 -;
+#X obj 199 320 t f f;
+#X obj 139 450 +;
+#X obj 229 451 +;
+#X msg 184 428 -1 \$1;
+#X obj 211 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 364 t f f b;
+#X obj 50 115 * 3.14159;
+#X obj 60 193 min 3.14;
+#X obj 199 294 * 0.767;
+#X obj 238 254 sinh;
+#X msg 211 140 1 \$1;
+#X obj 211 162 /;
+#X obj 50 144 * 2;
+#X obj 50 95 min 21000;
+#X connect 0 0 39 0;
+#X connect 1 0 38 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 29 0;
+#X connect 8 0 40 0;
+#X connect 9 0 43 0;
+#X connect 10 0 45 0;
+#X connect 12 0 20 1;
+#X connect 12 0 21 1;
+#X connect 12 0 22 1;
+#X connect 12 0 23 1;
+#X connect 12 0 24 1;
+#X connect 13 0 22 0;
+#X connect 14 0 35 0;
+#X connect 15 0 23 0;
+#X connect 16 0 24 0;
+#X connect 17 0 36 0;
+#X connect 18 0 20 0;
+#X connect 19 0 8 0;
+#X connect 19 1 9 0;
+#X connect 20 0 11 0;
+#X connect 21 0 26 0;
+#X connect 22 0 25 0;
+#X connect 23 0 27 0;
+#X connect 24 0 28 0;
+#X connect 29 0 19 0;
+#X connect 30 0 29 0;
+#X connect 30 1 44 0;
+#X connect 31 0 10 0;
+#X connect 32 0 33 0;
+#X connect 33 0 21 0;
+#X connect 34 0 32 0;
+#X connect 34 1 12 0;
+#X connect 35 0 13 0;
+#X connect 36 0 16 0;
+#X connect 37 0 15 0;
+#X connect 38 0 31 0;
+#X connect 39 0 48 0;
+#X connect 40 0 18 0;
+#X connect 40 1 14 0;
+#X connect 40 1 37 0;
+#X connect 40 1 17 0;
+#X connect 40 2 33 0;
+#X connect 41 0 47 0;
+#X connect 42 0 29 0;
+#X connect 43 0 34 0;
+#X connect 44 0 43 1;
+#X connect 45 0 46 0;
+#X connect 46 0 30 0;
+#X connect 47 0 7 0;
+#X connect 48 0 41 0;
+#X restore 147 201 pd coef_hpf_biquad;
+#N canvas 269 177 545 625 coef_bpf_biquad 0;
+#X obj 50 32 inlet;
+#X obj 211 31 inlet;
+#X text 92 34 f;
+#X text 256 31 Q;
+#X obj 119 148 samplerate~;
+#X obj 119 125 loadbang;
+#X obj 176 126 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 180 /;
+#X obj 50 349 cos;
+#X obj 199 276 sin;
+#X obj 211 126 * 2;
+#X obj 50 544 outlet;
+#X obj 288 484 + 1;
+#X obj 50 467 * -2;
+#X obj 50 249 t f f;
+#X obj 50 519 /;
+#X obj 94 520 /;
+#X obj 139 520 /;
+#X obj 229 520 /;
+#X obj 139 544 outlet;
+#X obj 94 544 outlet;
+#X obj 184 544 outlet;
+#X obj 229 544 outlet;
+#X obj 50 226 f;
+#X obj 211 195 t b f;
+#X msg 94 438 1 \$1;
+#X obj 94 483 -;
+#X obj 229 481 * -1;
+#X msg 184 520 0;
+#X obj 199 330 t f b f;
+#X obj 211 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 122 * 3.14159;
+#X obj 211 105 + 0.7;
+#X msg 211 148 1 \$1;
+#X obj 238 242 sinh;
+#X obj 211 170 /;
+#X obj 50 148 * 2;
+#X obj 50 99 min 21000;
+#X obj 199 303 * 0.767;
+#X connect 0 0 31 0;
+#X connect 1 0 30 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 23 0;
+#X connect 8 0 13 0;
+#X connect 9 0 39 0;
+#X connect 10 0 34 0;
+#X connect 12 0 15 1;
+#X connect 12 0 16 1;
+#X connect 12 0 17 1;
+#X connect 12 0 18 1;
+#X connect 13 0 15 0;
+#X connect 14 0 8 0;
+#X connect 14 1 9 0;
+#X connect 15 0 11 0;
+#X connect 16 0 20 0;
+#X connect 17 0 19 0;
+#X connect 18 0 22 0;
+#X connect 23 0 14 0;
+#X connect 24 0 23 0;
+#X connect 24 1 35 0;
+#X connect 25 0 26 0;
+#X connect 26 0 16 0;
+#X connect 27 0 18 0;
+#X connect 28 0 21 0;
+#X connect 29 0 25 0;
+#X connect 29 0 17 0;
+#X connect 29 0 27 0;
+#X connect 29 1 28 0;
+#X connect 29 2 12 0;
+#X connect 30 0 33 0;
+#X connect 31 0 38 0;
+#X connect 32 0 37 0;
+#X connect 33 0 10 0;
+#X connect 34 0 36 0;
+#X connect 35 0 39 1;
+#X connect 36 0 24 0;
+#X connect 37 0 7 0;
+#X connect 38 0 32 0;
+#X connect 39 0 29 0;
+#X restore 158 294 pd coef_bpf_biquad;
+#X msg 81 425 clear;
+#N canvas 520 123 368 628 coef_lpf_biquad 0;
+#X obj 50 32 inlet;
+#X obj 211 31 inlet;
+#X text 92 34 f;
+#X text 256 31 Q;
+#X obj 117 137 samplerate~;
+#X obj 117 114 loadbang;
+#X obj 174 115 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 170 /;
+#X obj 50 369 cos;
+#X obj 199 296 sin;
+#X obj 211 116 * 2;
+#X obj 50 564 outlet;
+#X obj 288 504 + 1;
+#X obj 139 501 / 2;
+#X obj 94 505 -;
+#X msg 99 463 1 \$1;
+#X msg 139 458 1 \$1;
+#X obj 184 480 -;
+#X obj 229 501 / 2;
+#X msg 229 460 1 \$1;
+#X obj 50 487 * -2;
+#X obj 139 480 -;
+#X msg 184 458 1 \$1;
+#X obj 229 481 -;
+#X obj 199 350 t f f;
+#X obj 50 269 t f f;
+#X obj 50 539 /;
+#X obj 94 540 /;
+#X obj 139 540 /;
+#X obj 184 539 /;
+#X obj 229 540 /;
+#X obj 139 564 outlet;
+#X obj 94 564 outlet;
+#X obj 184 564 outlet;
+#X obj 229 564 outlet;
+#X obj 50 246 f;
+#X obj 211 185 t b f;
+#X obj 211 95 + 0.707;
+#X obj 211 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 394 t f f b;
+#X obj 50 115 * 3.14159;
+#X obj 67 206 min 3.14;
+#X obj 238 295 sinh;
+#X obj 199 325 * 0.767;
+#X msg 211 140 1 \$1;
+#X obj 211 162 /;
+#X obj 50 143 * 2;
+#X obj 50 95 min 21000;
+#X connect 0 0 39 0;
+#X connect 1 0 38 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 35 0;
+#X connect 8 0 40 0;
+#X connect 9 0 44 0;
+#X connect 10 0 45 0;
+#X connect 12 0 26 1;
+#X connect 12 0 27 1;
+#X connect 12 0 28 1;
+#X connect 12 0 29 1;
+#X connect 12 0 30 1;
+#X connect 13 0 28 0;
+#X connect 14 0 27 0;
+#X connect 15 0 14 0;
+#X connect 16 0 21 0;
+#X connect 17 0 29 0;
+#X connect 18 0 30 0;
+#X connect 19 0 23 0;
+#X connect 20 0 26 0;
+#X connect 21 0 13 0;
+#X connect 22 0 17 0;
+#X connect 23 0 18 0;
+#X connect 24 0 15 0;
+#X connect 24 1 12 0;
+#X connect 25 0 8 0;
+#X connect 25 1 9 0;
+#X connect 26 0 11 0;
+#X connect 27 0 32 0;
+#X connect 28 0 31 0;
+#X connect 29 0 33 0;
+#X connect 30 0 34 0;
+#X connect 35 0 25 0;
+#X connect 36 0 35 0;
+#X connect 36 1 43 0;
+#X connect 37 0 10 0;
+#X connect 38 0 37 0;
+#X connect 39 0 48 0;
+#X connect 40 0 20 0;
+#X connect 40 1 16 0;
+#X connect 40 1 22 0;
+#X connect 40 1 19 0;
+#X connect 40 2 14 0;
+#X connect 41 0 47 0;
+#X connect 42 0 35 0;
+#X connect 43 0 44 1;
+#X connect 44 0 24 0;
+#X connect 45 0 46 0;
+#X connect 46 0 36 0;
+#X connect 47 0 7 0;
+#X connect 48 0 41 0;
+#X restore 135 113 pd coef_lpf_biquad;
+#X obj 135 137 pack f f f f f;
+#X obj 135 91 mtof;
+#X floatatom 135 74 5 0 0 0 - - -;
+#X floatatom 240 92 5 0 0 0 - - -;
+#X obj 147 225 pack f f f f f;
+#X obj 147 180 mtof;
+#X floatatom 147 162 5 0 0 0 - - -;
+#X floatatom 252 180 5 0 0 0 - - -;
+#X obj 158 315 pack f f f f f;
+#X obj 158 270 mtof;
+#X floatatom 158 250 5 0 0 0 - - -;
+#X floatatom 263 270 5 0 0 0 - - -;
+#X obj 555 135 pack f f f f f;
+#X obj 555 90 mtof;
+#X floatatom 555 72 5 0 0 0 - - -;
+#X floatatom 673 92 5 0 0 0 - - -;
+#N canvas 101 71 356 625 coef_notch_biquad 0;
+#X obj 50 32 inlet;
+#X obj 205 31 inlet;
+#X text 92 34 f;
+#X text 250 31 Q;
+#X obj 119 148 samplerate~;
+#X obj 119 125 loadbang;
+#X obj 176 126 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 180 /;
+#X obj 50 349 cos;
+#X obj 199 276 sin;
+#X obj 205 126 * 2;
+#X obj 50 574 outlet;
+#X obj 288 484 + 1;
+#X obj 50 467 * -2;
+#X obj 50 249 t f f;
+#X obj 50 519 /;
+#X obj 94 520 /;
+#X obj 139 520 /;
+#X obj 229 520 /;
+#X obj 139 574 outlet;
+#X obj 94 574 outlet;
+#X obj 184 574 outlet;
+#X obj 229 574 outlet;
+#X obj 50 226 f;
+#X obj 205 195 t b f;
+#X msg 94 438 1 \$1;
+#X obj 94 483 -;
+#X obj 199 330 t f b f;
+#X obj 205 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 122 * 3.14159;
+#X msg 205 148 1 \$1;
+#X obj 232 242 sinh;
+#X obj 205 170 /;
+#X obj 199 303 *;
+#X obj 50 148 * 2;
+#X msg 139 487 1;
+#X msg 231 481 1;
+#X obj 50 548 t f f;
+#X obj 205 104 + 0.1;
+#X obj 50 99 min 21000;
+#X connect 0 0 29 0;
+#X connect 1 0 28 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 23 0;
+#X connect 8 0 13 0;
+#X connect 9 0 34 0;
+#X connect 10 0 31 0;
+#X connect 12 0 15 1;
+#X connect 12 0 16 1;
+#X connect 12 0 17 1;
+#X connect 12 0 18 1;
+#X connect 13 0 15 0;
+#X connect 14 0 8 0;
+#X connect 14 1 9 0;
+#X connect 15 0 38 0;
+#X connect 16 0 20 0;
+#X connect 17 0 19 0;
+#X connect 18 0 22 0;
+#X connect 23 0 14 0;
+#X connect 24 0 23 0;
+#X connect 24 1 32 0;
+#X connect 25 0 26 0;
+#X connect 26 0 16 0;
+#X connect 27 0 25 0;
+#X connect 27 1 36 0;
+#X connect 27 1 37 0;
+#X connect 27 2 12 0;
+#X connect 28 0 39 0;
+#X connect 29 0 40 0;
+#X connect 30 0 35 0;
+#X connect 31 0 33 0;
+#X connect 32 0 34 1;
+#X connect 33 0 24 0;
+#X connect 34 0 27 0;
+#X connect 35 0 7 0;
+#X connect 36 0 17 0;
+#X connect 37 0 18 0;
+#X connect 38 0 11 0;
+#X connect 38 1 21 0;
+#X connect 39 0 10 0;
+#X connect 40 0 30 0;
+#X restore 555 113 pd coef_notch_biquad;
+#X obj 28 397 noise~;
+#X obj 27 520 dac~;
+#X obj 135 383 t a;
+#X obj 325 135 pack f f f f f;
+#X obj 325 90 mtof;
+#X floatatom 325 72 5 0 0 0 - - -;
+#X floatatom 386 90 5 0 0 0 - - -;
+#X obj 325 350 t a;
+#N canvas 101 71 356 625 coef_peak_biquad 0;
+#X obj 50 32 inlet;
+#X obj 206 31 inlet;
+#X text 92 34 f;
+#X text 251 31 Q;
+#X obj 119 148 samplerate~;
+#X obj 119 125 loadbang;
+#X obj 176 126 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 180 /;
+#X obj 50 349 cos;
+#X obj 200 276 sin;
+#X obj 206 126 * 2;
+#X obj 50 574 outlet;
+#X obj 283 485 + 1;
+#X obj 50 467 * -2;
+#X obj 50 249 t f f;
+#X obj 50 519 /;
+#X obj 94 520 /;
+#X obj 139 520 /;
+#X obj 229 520 /;
+#X obj 139 574 outlet;
+#X obj 94 574 outlet;
+#X obj 184 574 outlet;
+#X obj 229 574 outlet;
+#X obj 50 226 f;
+#X obj 206 195 t b f;
+#X msg 94 458 1 \$1;
+#X obj 206 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 128 * 3.14159;
+#X msg 206 148 1 \$1;
+#X obj 233 226 sinh;
+#X obj 206 170 /;
+#X obj 50 148 * 2;
+#X obj 50 548 t f f;
+#X obj 206 104 + 0.1;
+#X obj 302 32 inlet;
+#X text 344 198 A;
+#X obj 302 117 pow;
+#X msg 302 96 10;
+#X obj 302 77 t b f;
+#X obj 302 54 / 40;
+#X msg 140 460 1 \$1;
+#X msg 230 460 1 \$1;
+#X obj 230 485 -;
+#X obj 200 356 t f f;
+#X obj 302 202 t b f;
+#X obj 140 485 +;
+#X obj 94 483 -;
+#X obj 50 99 min 21000;
+#X obj 200 406 / 1;
+#X obj 230 407 * 1;
+#X obj 283 407 / 1;
+#X obj 200 303 * 74.2;
+#X connect 0 0 27 0;
+#X connect 1 0 26 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 23 0;
+#X connect 8 0 13 0;
+#X connect 9 0 52 0;
+#X connect 10 0 29 0;
+#X connect 12 0 15 1;
+#X connect 12 0 16 1;
+#X connect 12 0 17 1;
+#X connect 12 0 18 1;
+#X connect 13 0 15 0;
+#X connect 14 0 8 0;
+#X connect 14 1 9 0;
+#X connect 15 0 33 0;
+#X connect 16 0 20 0;
+#X connect 17 0 19 0;
+#X connect 18 0 22 0;
+#X connect 23 0 14 0;
+#X connect 24 0 23 0;
+#X connect 24 1 30 0;
+#X connect 25 0 47 0;
+#X connect 26 0 34 0;
+#X connect 27 0 48 0;
+#X connect 28 0 32 0;
+#X connect 29 0 31 0;
+#X connect 30 0 52 1;
+#X connect 31 0 24 0;
+#X connect 32 0 7 0;
+#X connect 33 0 11 0;
+#X connect 33 1 21 0;
+#X connect 34 0 10 0;
+#X connect 35 0 40 0;
+#X connect 37 0 45 0;
+#X connect 38 0 37 0;
+#X connect 39 0 38 0;
+#X connect 39 1 37 1;
+#X connect 40 0 39 0;
+#X connect 41 0 46 0;
+#X connect 42 0 43 0;
+#X connect 43 0 18 0;
+#X connect 44 0 49 0;
+#X connect 44 0 50 0;
+#X connect 44 1 51 0;
+#X connect 45 0 23 0;
+#X connect 45 1 49 1;
+#X connect 45 1 50 1;
+#X connect 45 1 51 1;
+#X connect 46 0 17 0;
+#X connect 47 0 16 0;
+#X connect 48 0 28 0;
+#X connect 49 0 25 0;
+#X connect 50 0 42 0;
+#X connect 50 0 41 0;
+#X connect 51 0 12 0;
+#X connect 52 0 44 0;
+#X restore 325 113 pd coef_peak_biquad;
+#X floatatom 447 93 5 0 0 0 - - -;
+#X obj 28 493 *~ 0.1;
+#X obj 342 215 pack f f f f f;
+#X obj 358 277 mtof;
+#X floatatom 358 261 5 0 127 0 - - -;
+#X floatatom 493 275 5 0 0 0 - - -;
+#X obj 358 320 pack f f f f f;
+#N canvas 435 52 535 646 coef_highShelf_biquad 0;
+#X obj 50 32 inlet;
+#X text 92 34 f;
+#X obj 50 165 * 6.283;
+#X obj 106 188 samplerate~;
+#X obj 106 166 loadbang;
+#X obj 164 167 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 220 /;
+#X obj 96 272 cos;
+#X obj 69 271 sin;
+#X obj 319 36 inlet;
+#X text 387 146 A;
+#X obj 319 121 pow;
+#X msg 319 100 10;
+#X obj 319 81 t b f;
+#X obj 319 58 / 40;
+#X obj 319 182 t f f;
+#X obj 319 204 *;
+#X obj 319 224 + 1;
+#X obj 360 183 - 1;
+#X obj 360 204 t f f;
+#X obj 360 226 *;
+#X obj 319 254 -;
+#X text 360 279 beta;
+#X obj 319 278 sqrt;
+#X obj 319 143 t f f f;
+#X obj 50 243 t b f f;
+#X obj 50 493 /;
+#X obj 50 525 outlet;
+#X obj 99 527 outlet;
+#X obj 149 528 outlet;
+#X obj 199 528 outlet;
+#X obj 249 529 outlet;
+#X obj 99 493 /;
+#X obj 149 496 /;
+#X obj 199 494 /;
+#X obj 249 497 /;
+#X obj 50 392 expr 2 * ( ($f2-1) - ($f2+1)*$f4 ) \; ($f2+1) - ($f2-1)*$f4
+- $f1*$f3 \; $f2 * ( ($f2+1) + ($f2-1)*$f4 + $f1*$f3 ) \; -2 * $f2
+* ( ($f2-1) + ($f2+1)*$f4 ) \; $f2 * ( ($f2+1) + ($f2-1)*$f4 - $f1*$f3
+) \; ($f2+1) - ($f2-1)*$f4 + $f1*$f3 \;;
+#X obj 50 73 max 0;
+#X obj 50 99 min 21000;
+#X obj 50 357 f;
+#X msg 135 281 1;
+#X obj 135 302 sqrt;
+#X obj 135 257 loadbang;
+#X connect 0 0 37 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 1;
+#X connect 4 0 3 0;
+#X connect 5 0 3 0;
+#X connect 6 0 25 0;
+#X connect 7 0 36 3;
+#X connect 8 0 36 2;
+#X connect 9 0 14 0;
+#X connect 11 0 24 0;
+#X connect 12 0 11 0;
+#X connect 13 0 12 0;
+#X connect 13 1 11 1;
+#X connect 14 0 13 0;
+#X connect 15 0 16 0;
+#X connect 15 1 16 1;
+#X connect 16 0 17 0;
+#X connect 17 0 21 0;
+#X connect 18 0 19 0;
+#X connect 19 0 20 0;
+#X connect 19 1 20 1;
+#X connect 20 0 21 1;
+#X connect 21 0 23 0;
+#X connect 23 0 36 0;
+#X connect 24 0 15 0;
+#X connect 24 1 18 0;
+#X connect 24 2 36 1;
+#X connect 25 0 39 0;
+#X connect 25 1 8 0;
+#X connect 25 2 7 0;
+#X connect 26 0 27 0;
+#X connect 32 0 28 0;
+#X connect 33 0 29 0;
+#X connect 34 0 30 0;
+#X connect 35 0 31 0;
+#X connect 36 0 26 0;
+#X connect 36 1 32 0;
+#X connect 36 2 33 0;
+#X connect 36 3 34 0;
+#X connect 36 4 35 0;
+#X connect 36 5 26 1;
+#X connect 36 5 32 1;
+#X connect 36 5 33 1;
+#X connect 36 5 34 1;
+#X connect 36 5 35 1;
+#X connect 37 0 38 0;
+#X connect 38 0 2 0;
+#X connect 39 0 36 0;
+#X connect 40 0 41 0;
+#X connect 40 0 36 1;
+#X connect 41 0 39 1;
+#X connect 42 0 40 0;
+#X restore 358 297 pd coef_highShelf_biquad;
+#X text 45 34 y(n) = b0 x(n) + b1 x(n-1) + b2 x(n-2) -a1 y(n-1) -a2
+y(n-2);
+#N canvas 0 0 450 300 5_line~ 0;
+#X obj 80 123 line~;
+#X obj 79 147 outlet~;
+#X obj 80 73 inlet;
+#X obj 136 123 line~;
+#X obj 135 147 outlet~;
+#X obj 136 73 inlet;
+#X obj 193 123 line~;
+#X obj 192 147 outlet~;
+#X obj 193 73 inlet;
+#X obj 247 123 line~;
+#X obj 246 147 outlet~;
+#X obj 247 73 inlet;
+#X obj 304 123 line~;
+#X obj 303 147 outlet~;
+#X obj 304 73 inlet;
+#X msg 80 96 \$1 133;
+#X msg 136 96 \$1 133;
+#X msg 193 96 \$1 133;
+#X msg 247 96 \$1 133;
+#X msg 304 96 \$1 133;
+#X connect 0 0 1 0;
+#X connect 2 0 15 0;
+#X connect 3 0 4 0;
+#X connect 5 0 16 0;
+#X connect 6 0 7 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 11 0 18 0;
+#X connect 12 0 13 0;
+#X connect 14 0 19 0;
+#X connect 15 0 0 0;
+#X connect 16 0 3 0;
+#X connect 17 0 6 0;
+#X connect 18 0 9 0;
+#X connect 19 0 12 0;
+#X restore 135 424 pd 5_line~;
+#X obj 135 403 unpack f f f f f;
+#N canvas 0 0 444 301 oscillo 0;
+#X obj 41 25 loadbang;
+#X obj 26 223 metro 100;
+#X obj 8 -9 inlet~;
+#X msg 41 47 1;
+#X obj 42 81 tgl 20 0 empty empty Stop 0 -6 0 8 -258699 -1 -1 1 1;
+#X obj 118 -3 inlet;
+#X msg 147 48 1;
+#X msg 115 48 0;
+#X obj 118 21 moses 10;
+#X obj 19 263 tabwrite~ \$0-oscillo;
+#X obj 100 140 cnv 1 300 1 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 0 767 419 (subpatch) 0;
+#X array \$0-oscillo 300 float 0;
+#X coords 0 1 299 -1 300 80 1;
+#X restore 100 100 graph;
+#X obj 110 75 change;
+#X obj 234 62 block~ 640 1 0.25;
+#X connect 0 0 3 0;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 8 0;
+#X connect 6 0 12 0;
+#X connect 7 0 12 0;
+#X connect 8 0 7 0;
+#X connect 8 1 6 0;
+#X connect 8 1 1 1;
+#X connect 12 0 1 0;
+#X coords 0 -1 1 1 300 80 1 100 100;
+#X restore 83 497 pd oscillo;
+#X obj 29 466 bq~ ---------;
+#X text 27 6 bq~ is a biquad \, but with audio input for the coeficients.
+Out out is :;
+#X text 43 52 (it's not the same structure than biquad~ ! );
+#N canvas 0 98 595 201 bq~ 0;
+#X obj 56 60 inlet~;
+#X obj 192 58 inlet~;
+#X obj 239 58 inlet~;
+#X obj 319 59 inlet~;
+#X obj 366 59 inlet~;
+#X obj 412 58 inlet~;
+#X text 323 37 b0;
+#X obj 56 156 outlet~;
+#X msg 67 84 clear;
+#X text 188 34 a1;
+#X obj 57 113 fexpr~ $x4[0]*$x1[0] + $x5[0]*$x1[-1] + $x6[0]*$x1[-2]
+- $x2[0]*$y1[-1] - $x3[0]*$y1[-2];
+#X connect 0 0 10 0;
+#X connect 1 0 10 1;
+#X connect 2 0 10 2;
+#X connect 3 0 10 3;
+#X connect 4 0 10 4;
+#X connect 5 0 10 5;
+#X connect 8 0 10 0;
+#X connect 10 0 7 0;
+#X restore 19 597 pd bq~ ---;
+#X text 101 597 <- drop in remplacement for bq~ \, using fexpr~ (lot's
+slower);
+#X obj 555 313 t a;
+#X connect 0 0 3 0;
+#X connect 1 0 0 0;
+#X connect 2 0 3 1;
+#X connect 3 0 37 0;
+#X connect 3 1 37 1;
+#X connect 3 2 37 2;
+#X connect 3 3 37 3;
+#X connect 3 4 37 4;
+#X connect 4 0 47 0;
+#X connect 5 0 13 0;
+#X connect 5 1 13 1;
+#X connect 5 2 13 2;
+#X connect 5 3 13 3;
+#X connect 5 4 13 4;
+#X connect 6 0 17 0;
+#X connect 6 1 17 1;
+#X connect 6 2 17 2;
+#X connect 6 3 17 3;
+#X connect 6 4 17 4;
+#X connect 7 0 47 0;
+#X connect 8 0 9 0;
+#X connect 8 1 9 1;
+#X connect 8 2 9 2;
+#X connect 8 3 9 3;
+#X connect 8 4 9 4;
+#X connect 9 0 28 0;
+#X connect 10 0 8 0;
+#X connect 11 0 10 0;
+#X connect 12 0 8 1;
+#X connect 13 0 28 0;
+#X connect 14 0 5 0;
+#X connect 15 0 14 0;
+#X connect 16 0 5 1;
+#X connect 17 0 28 0;
+#X connect 18 0 6 0;
+#X connect 19 0 18 0;
+#X connect 20 0 6 1;
+#X connect 21 0 52 0;
+#X connect 22 0 25 0;
+#X connect 23 0 22 0;
+#X connect 24 0 25 1;
+#X connect 25 0 21 0;
+#X connect 25 1 21 1;
+#X connect 25 2 21 2;
+#X connect 25 3 21 3;
+#X connect 25 4 21 4;
+#X connect 26 0 4 0;
+#X connect 28 0 45 0;
+#X connect 29 0 33 0;
+#X connect 30 0 34 0;
+#X connect 31 0 30 0;
+#X connect 32 0 34 1;
+#X connect 33 0 28 0;
+#X connect 34 0 29 0;
+#X connect 34 1 29 1;
+#X connect 34 2 29 2;
+#X connect 34 3 29 3;
+#X connect 34 4 29 4;
+#X connect 35 0 34 2;
+#X connect 36 0 27 0;
+#X connect 36 0 27 1;
+#X connect 37 0 33 0;
+#X connect 38 0 42 0;
+#X connect 39 0 38 0;
+#X connect 40 0 42 1;
+#X connect 41 0 33 0;
+#X connect 42 0 41 0;
+#X connect 42 1 41 1;
+#X connect 42 2 41 2;
+#X connect 42 3 41 3;
+#X connect 42 4 41 4;
+#X connect 44 0 47 1;
+#X connect 44 1 47 2;
+#X connect 44 2 47 3;
+#X connect 44 3 47 4;
+#X connect 44 4 47 5;
+#X connect 45 0 44 0;
+#X connect 45 1 44 1;
+#X connect 45 2 44 2;
+#X connect 45 3 44 3;
+#X connect 45 4 44 4;
+#X connect 47 0 46 0;
+#X connect 47 0 36 0;
+#X connect 52 0 33 0;
diff --git a/nusmuk-audio/bq~.c b/nusmuk-audio/bq~.c
new file mode 100644
index 0000000..d8a70b4
--- /dev/null
+++ b/nusmuk-audio/bq~.c
@@ -0,0 +1,112 @@
+/* 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. */
+
+// modification of this code by cyrille henry in order to change the biquad topology and add audio inlet for filter coefs
+
+#include "m_pd.h"
+#include <math.h>
+
+/* ---------------- bq~ - raw bq filter ----------------- */
+
+typedef struct bqctl
+{
+ t_sample c_x1;
+ t_sample c_x2;
+ t_sample c_y1;
+ t_sample c_y2;
+} t_bqctl;
+
+typedef struct bq_tilde
+{
+ t_object x_obj;
+ t_float x_f;
+ t_bqctl x_cspace;
+ t_bqctl *x_ctl;
+} t_bq_tilde;
+
+t_class *bq_tilde_class;
+
+static void *bq_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+ t_bq_tilde *x = (t_bq_tilde *)pd_new(bq_tilde_class);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+ outlet_new(&x->x_obj, &s_signal);
+ x->x_ctl = &x->x_cspace;
+ x->x_cspace.c_x1 = x->x_cspace.c_x2 = 0;
+ x->x_cspace.c_y1 = x->x_cspace.c_y2 = 0;
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *bq_tilde_perform(t_int *w)
+{
+ t_sample *in = (t_sample *)(w[1]);
+ t_sample *ina1 = (t_sample *)(w[2]);
+ t_sample *ina2 = (t_sample *)(w[3]);
+ t_sample *inb1 = (t_sample *)(w[4]);
+ t_sample *inb2 = (t_sample *)(w[5]);
+ t_sample *inb3 = (t_sample *)(w[6]);
+ t_sample *out = (t_sample *)(w[7]);
+ t_bqctl *c = (t_bqctl *)(w[8]);
+ int n = (t_int)(w[9]);
+ int i;
+ t_sample last_in = c->c_x1;
+ t_sample prev_in = c->c_x2;
+ t_sample last_out = c->c_y1;
+ t_sample prev_out = c->c_y2;
+
+ for (i = 0; i < n; i++)
+ {
+ t_sample output = *inb1++ * *in + *inb2++ * last_in + *inb3++ * prev_in - *ina1++ * last_out - *ina2++ * prev_out;
+// if (PD_BIGORSMALL(output))
+// output = 0; i don't understnd why it did not compile with this 2 lines.
+// should be fixed latter if denormal is a problem
+ *out++ = output;
+ prev_in = last_in;
+ prev_out = last_out;
+ last_out = output;
+ last_in = *in++;
+ }
+ c->c_x1 = last_in;
+ c->c_x2 = prev_in;
+ c->c_y1 = last_out;
+ c->c_y2 = prev_out;
+
+ return (w+10);
+}
+
+static void bq_tilde_set(t_bq_tilde *x, t_symbol *s, int argc, t_atom *argv)
+{
+ t_bqctl *c = x->x_ctl;
+ c->c_x1 = atom_getfloatarg(0, argc, argv);
+ c->c_x2 = atom_getfloatarg(1, argc, argv);
+ c->c_y1 = atom_getfloatarg(2, argc, argv);
+ c->c_y2 = atom_getfloatarg(3, argc, argv);
+}
+
+static void bq_tilde_dsp(t_bq_tilde *x, t_signal **sp)
+{
+ dsp_add(bq_tilde_perform, 9,
+ sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec, sp[4]->s_vec,
+ sp[5]->s_vec, sp[6]->s_vec, x->x_ctl, sp[0]->s_n);
+
+}
+
+void bq_tilde_setup(void)
+{
+ bq_tilde_class = class_new(gensym("bq~"), (t_newmethod)bq_tilde_new,
+ 0, sizeof(t_bq_tilde), 0, A_GIMME, 0);
+ CLASS_MAINSIGNALIN(bq_tilde_class, t_bq_tilde, x_f);
+ class_addmethod(bq_tilde_class, (t_method)bq_tilde_dsp, gensym("dsp"), 0);
+ class_addmethod(bq_tilde_class, (t_method)bq_tilde_set, gensym("set"),
+ A_GIMME, 0);
+ class_addmethod(bq_tilde_class, (t_method)bq_tilde_set, gensym("clear"),
+ A_GIMME, 0);
+}
+
+
diff --git a/nusmuk-audio/compress_limit~-help.pd b/nusmuk-audio/compress_limit~-help.pd
new file mode 100644
index 0000000..8fffdc4
--- /dev/null
+++ b/nusmuk-audio/compress_limit~-help.pd
@@ -0,0 +1,51 @@
+#N canvas 227 97 586 521 10;
+#X obj 62 144 *~;
+#X floatatom 82 126 5 0 0 0 - - -;
+#X obj 61 94 osc~ 33;
+#X floatatom 61 51 5 0 0 0 - - -;
+#X obj 61 69 mtof;
+#X obj 147 80 dirac~;
+#X obj 147 55 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 146 124 *~;
+#X floatatom 168 107 5 0 0 0 - - -;
+#X obj 250 157 vline~;
+#X obj 227 177 *~;
+#X obj 227 199 *~;
+#X floatatom 263 179 5 0 0 0 - - -;
+#X obj 243 53 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 63 361 dac~;
+#X obj 229 101 osc~ 222;
+#X obj 250 77 metro 33;
+#X obj 62 289 *~;
+#X msg 250 132 1 1 0 \, 0 1 10;
+#X floatatom 302 58 5 0 0 0 - - -;
+#X floatatom 121 269 5 0 0 0 - - -;
+#X obj 202 319 oscillo~;
+#X obj 189 420 oscillo~;
+#X obj 63 324 compress_limit~;
+#X connect 0 0 17 0;
+#X connect 1 0 0 1;
+#X connect 2 0 0 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
+#X connect 5 0 7 0;
+#X connect 6 0 5 0;
+#X connect 7 0 17 0;
+#X connect 8 0 7 1;
+#X connect 9 0 10 1;
+#X connect 10 0 11 0;
+#X connect 11 0 17 0;
+#X connect 12 0 11 1;
+#X connect 13 0 16 0;
+#X connect 15 0 10 0;
+#X connect 16 0 18 0;
+#X connect 17 0 21 0;
+#X connect 17 0 23 0;
+#X connect 18 0 9 0;
+#X connect 19 0 16 1;
+#X connect 20 0 17 1;
+#X connect 23 0 14 0;
+#X connect 23 0 14 1;
+#X connect 23 0 22 0;
diff --git a/nusmuk-audio/compress_limit~.pd b/nusmuk-audio/compress_limit~.pd
new file mode 100644
index 0000000..8db39c2
--- /dev/null
+++ b/nusmuk-audio/compress_limit~.pd
@@ -0,0 +1,45 @@
+#N canvas 227 97 586 521 10;
+#X obj 23 14 inlet~;
+#X obj 24 373 /~;
+#X obj 24 402 outlet~;
+#X obj 234 151 dbtorms;
+#X obj 234 130 + 3;
+#X obj 234 175 + 0.1;
+#X obj 234 222 moses 1;
+#X obj 234 292 f;
+#X obj 234 268 + 0.5;
+#X obj 234 245 * 0.5;
+#X obj 234 58 env~ 128 64;
+#X obj 234 197 env+ 11;
+#X obj 234 339 line~;
+#X obj 335 59 env~ 1024 128;
+#X obj 234 102 max;
+#X msg 234 316 \$1 4;
+#X obj 24 284 / 44100;
+#X msg 24 262 128;
+#X obj 24 242 loadbang;
+#X obj 23 79 delwrite~ \$0-delay 3;
+#X obj 24 307 delread~ \$0-delay 0.0029024;
+#X text 298 262 change this curve if you wish;
+#X connect 0 0 10 0;
+#X connect 0 0 13 0;
+#X connect 0 0 19 0;
+#X connect 1 0 2 0;
+#X connect 3 0 5 0;
+#X connect 4 0 3 0;
+#X connect 5 0 11 0;
+#X connect 6 0 9 0;
+#X connect 6 1 7 0;
+#X connect 7 0 15 0;
+#X connect 8 0 7 0;
+#X connect 9 0 8 0;
+#X connect 10 0 14 0;
+#X connect 11 0 6 0;
+#X connect 12 0 1 1;
+#X connect 13 0 14 1;
+#X connect 14 0 4 0;
+#X connect 15 0 12 0;
+#X connect 16 0 20 0;
+#X connect 17 0 16 0;
+#X connect 18 0 17 0;
+#X connect 20 0 1 0;
diff --git a/nusmuk-audio/debian/changelog b/nusmuk-audio/debian/changelog
new file mode 100644
index 0000000..d7dacbd
--- /dev/null
+++ b/nusmuk-audio/debian/changelog
@@ -0,0 +1,5 @@
+pd-nusmuk-audio (1.2-1) unstable; urgency=low
+
+ * Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>
+
+ -- Hans-Christoph Steiner <hans@eds.org> Thu, 21 Jan 2010 23:27:04 -0500
diff --git a/nusmuk-audio/debian/compat b/nusmuk-audio/debian/compat
new file mode 100644
index 0000000..7f8f011
--- /dev/null
+++ b/nusmuk-audio/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/nusmuk-audio/debian/control b/nusmuk-audio/debian/control
new file mode 100644
index 0000000..c920e46
--- /dev/null
+++ b/nusmuk-audio/debian/control
@@ -0,0 +1,26 @@
+Source: pd-nusmuk-audio
+Section: sound
+Priority: optional
+Maintainer: Debian Multimedia Maintainers <pkg-multimedia-maintainers@lists.alioth.debian.org>
+Uploaders: Hans-Christoph Steiner <hans@eds.org>
+Build-Depends: debhelper (>= 7.0.50~),
+ puredata
+Standards-Version: 3.9.1
+Homepage: http://puredata.info
+
+Package: pd-nusmuk-audio
+Architecture: any
+Depends: ${shlibs:Depends},
+ pd,
+ ${misc:Depends}
+Description: a random collection of Pd objects dedicated to audio synthesis by Cyrille Henry
+ This objects collection aim at improving audio synthesis quality
+ This collection enholds :
+ synthesis tools
+ band limited oscillator
+ better tables reader
+ filters
+ effects
+ visualisation tools
+
+
diff --git a/nusmuk-audio/debian/copyright b/nusmuk-audio/debian/copyright
new file mode 100644
index 0000000..1d3fe60
--- /dev/null
+++ b/nusmuk-audio/debian/copyright
@@ -0,0 +1,23 @@
+Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?rev=135
+Name: nusmuk-audio
+Maintainer: Cyrille Henry <ch@chnry.net>
+Source: http://sourceforge.net/projects/pure-data/files/libraries/nusmuk-audio/
+
+Files: *
+Copyright: 2002-2010, Cyrille Henry <ch@chnry.net>
+License: GPL-2+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this package; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+X-Comment: On Debian systems, the complete text of the GNU General
+ Public License can be found in `/usr/share/common-licenses/GPL-2'.
diff --git a/nusmuk-audio/debian/gbp.conf b/nusmuk-audio/debian/gbp.conf
new file mode 100644
index 0000000..ae1dc36
--- /dev/null
+++ b/nusmuk-audio/debian/gbp.conf
@@ -0,0 +1,7 @@
+[DEFAULT]
+upstream-branch = upstream
+debian-branch = master
+upstream-tag = upstream/%(version)s
+debian-tag = debian/%(version)s
+pristine-tar = True
+sign-tags = True
diff --git a/nusmuk-audio/debian/links b/nusmuk-audio/debian/links
new file mode 100644
index 0000000..5574cdb
--- /dev/null
+++ b/nusmuk-audio/debian/links
@@ -0,0 +1,3 @@
+usr/lib/pd/extra/nusmuk-audio/README.txt usr/share/doc/pd-nusmuk-audio/README
+usr/lib/pd/extra/nusmuk-audio/examples usr/share/doc/pd-nusmuk-audio/examples
+usr/share/common-licenses/GPL-2 usr/lib/pd/extra/nusmuk-audio/LICENSE.txt
diff --git a/nusmuk-audio/debian/rules b/nusmuk-audio/debian/rules
new file mode 100755
index 0000000..fdd5b9c
--- /dev/null
+++ b/nusmuk-audio/debian/rules
@@ -0,0 +1,17 @@
+#!/usr/bin/make -f
+
+LIBRARY_NAME = nusmuk-audio
+PACKAGE = pd-$(LIBRARY_NAME)
+pkglibdir = /usr/lib/pd/extra
+
+%:
+ dh $@ --buildsystem=makefile
+
+override_dh_auto_install:
+ dh_auto_install -- prefix=/usr pkglibdir=$(pkglibdir)
+# replace license file with link to the Debian license file
+ rm -f -- $(CURDIR)/debian/$(PACKAGE)/$(pkglibdir)/$(LIBRARY_NAME)/LICENSE.txt
+
+override_dh_shlibdeps:
+ dpkg-shlibdeps $(CURDIR)/debian/$(PACKAGE)$(pkglibdir)/$(LIBRARY_NAME)/*.pd_linux \
+ -T$(CURDIR)/debian/$(PACKAGE).substvars
diff --git a/nusmuk-audio/debian/source/format b/nusmuk-audio/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/nusmuk-audio/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/nusmuk-audio/debian/watch b/nusmuk-audio/debian/watch
new file mode 100644
index 0000000..20552f4
--- /dev/null
+++ b/nusmuk-audio/debian/watch
@@ -0,0 +1,2 @@
+version=3
+http://sf.net/pure-data/nusmuk-audio-(.*)\.tar\.gz
diff --git a/nusmuk-audio/distortion~-help.pd b/nusmuk-audio/distortion~-help.pd
new file mode 100644
index 0000000..281916b
--- /dev/null
+++ b/nusmuk-audio/distortion~-help.pd
@@ -0,0 +1,27 @@
+#N canvas 635 105 450 300 10;
+#X obj 38 206 oscillo~;
+#X obj 39 24 osc~ 222;
+#X obj 60 172 dac~;
+#X obj 60 148 *~ 0.1;
+#X floatatom 151 28 5 0 1 0 - - -;
+#X obj 151 64 line~;
+#X msg 151 44 \$1 100;
+#X obj 38 79 +~;
+#X floatatom 53 61 5 0 0 0 - - -;
+#X obj 151 96 hradio 15 1 0 4 empty empty empty 0 -8 0 10 -262144 -1
+-1 0;
+#X text 224 97 disto mode;
+#X text 199 28 distortion %;
+#X text 91 61 asym;
+#X obj 38 121 distortion~;
+#X connect 1 0 7 0;
+#X connect 3 0 2 1;
+#X connect 3 0 2 0;
+#X connect 4 0 6 0;
+#X connect 5 0 13 1;
+#X connect 6 0 5 0;
+#X connect 7 0 13 0;
+#X connect 8 0 7 1;
+#X connect 9 0 13 2;
+#X connect 13 0 3 0;
+#X connect 13 0 0 0;
diff --git a/nusmuk-audio/distortion~.pd b/nusmuk-audio/distortion~.pd
new file mode 100644
index 0000000..e5a7064
--- /dev/null
+++ b/nusmuk-audio/distortion~.pd
@@ -0,0 +1,203 @@
+#N canvas 188 64 622 419 10;
+#X obj 30 129 +~ 5000;
+#X obj 29 27 inlet~;
+#X obj 31 153 tabread4~ \$0-disto;
+#X obj 160 29 inlet~;
+#X obj 29 102 *~;
+#X obj 160 49 *~ 5000;
+#X obj 160 129 +~ 5000;
+#X obj 160 153 tabread4~ \$0-disto;
+#X obj 30 229 outlet~;
+#X obj 294 298 table \$0-disto 10000;
+#X obj 31 197 /~;
+#X obj 160 71 +~ 100;
+#N canvas 27 440 450 300 sqrt 0;
+#X obj 20 63 t b b;
+#X obj 20 159 f;
+#X obj 63 159 + 1;
+#X msg 47 136 0;
+#X obj 20 104 until;
+#X obj 20 44 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 20 219 - 0.5;
+#X obj 20 259 t f f f;
+#X obj 39 280 *;
+#X obj 39 300 + 1;
+#X obj 39 320 sqrt;
+#X obj 20 340 /;
+#X obj 20 239 * 20;
+#X obj 20 199 / 9999;
+#X msg 20 83 10000;
+#X obj 20 179 t f f;
+#X obj 20 360 tabwrite \$0-disto;
+#X obj 20 18 inlet;
+#X connect 0 0 14 0;
+#X connect 0 1 3 0;
+#X connect 1 0 2 0;
+#X connect 1 0 15 0;
+#X connect 2 0 1 1;
+#X connect 3 0 1 1;
+#X connect 4 0 1 0;
+#X connect 5 0 0 0;
+#X connect 6 0 12 0;
+#X connect 7 0 11 0;
+#X connect 7 1 8 0;
+#X connect 7 2 8 1;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 11 1;
+#X connect 11 0 16 0;
+#X connect 12 0 7 0;
+#X connect 13 0 6 0;
+#X connect 14 0 4 0;
+#X connect 15 0 13 0;
+#X connect 15 1 16 1;
+#X connect 17 0 5 0;
+#X restore 313 169 pd sqrt;
+#X obj 313 151 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#N canvas 0 0 640 460 sigmoid 0;
+#X obj 23 59 t b b;
+#X obj 23 148 f;
+#X obj 61 148 + 1;
+#X msg 50 125 0;
+#X obj 23 102 until;
+#X obj 23 40 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 23 213 - 0.5;
+#X obj 23 276 - 0.5;
+#X obj 23 298 * 2;
+#X obj 23 319 tabwrite \$0-disto;
+#X msg 23 81 10000;
+#X obj 23 192 / 9999;
+#X obj 23 234 * 30;
+#X obj 23 171 t f f;
+#X obj 23 255 expr ( exp($f1)) / ( 1 + exp($f1));
+#X obj 23 15 inlet;
+#X connect 0 0 10 0;
+#X connect 0 1 3 0;
+#X connect 1 0 2 0;
+#X connect 1 0 13 0;
+#X connect 2 0 1 1;
+#X connect 3 0 1 1;
+#X connect 4 0 1 0;
+#X connect 5 0 0 0;
+#X connect 6 0 12 0;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 10 0 4 0;
+#X connect 11 0 6 0;
+#X connect 12 0 14 0;
+#X connect 13 0 11 0;
+#X connect 13 1 9 1;
+#X connect 14 0 7 0;
+#X connect 15 0 5 0;
+#X restore 298 131 pd sigmoid;
+#X obj 298 112 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#N canvas 0 0 739 509 x_over_xplus 0;
+#X obj 17 58 t b b;
+#X obj 17 141 f;
+#X obj 55 141 + 1;
+#X msg 44 118 0;
+#X obj 17 96 until;
+#X obj 17 39 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 17 315 /;
+#X obj 44 269 abs;
+#X obj 44 248 * 2;
+#X obj 17 208 - 0.5;
+#X obj 44 290 + 0.1;
+#X msg 17 77 10000;
+#X obj 17 189 / 9999;
+#X obj 17 359 tabwrite \$0-disto;
+#X obj 17 337 * 2;
+#X obj 17 228 t f f;
+#X obj 17 167 t f f;
+#X obj 17 16 inlet;
+#X connect 0 0 11 0;
+#X connect 0 1 3 0;
+#X connect 1 0 2 0;
+#X connect 1 0 16 0;
+#X connect 2 0 1 1;
+#X connect 3 0 1 1;
+#X connect 4 0 1 0;
+#X connect 5 0 0 0;
+#X connect 6 0 14 0;
+#X connect 7 0 10 0;
+#X connect 8 0 7 0;
+#X connect 9 0 15 0;
+#X connect 10 0 6 1;
+#X connect 11 0 4 0;
+#X connect 12 0 9 0;
+#X connect 14 0 13 0;
+#X connect 15 0 6 0;
+#X connect 15 1 8 0;
+#X connect 16 0 12 0;
+#X connect 16 1 13 1;
+#X connect 17 0 5 0;
+#X restore 328 214 pd x_over_xplus;
+#X obj 328 194 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#N canvas 0 0 588 371 poly 0;
+#X obj 16 14 inlet;
+#X obj 16 55 t b b;
+#X obj 16 140 f;
+#X obj 54 140 + 1;
+#X msg 43 117 0;
+#X obj 16 98 until;
+#X obj 16 36 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 16 209 - 0.5;
+#X obj 16 253 expr exp(-$f1*$f1)*($f1+pow($f1 \, 3)*2/3 + pow($f1 \,
+5)*4/15);
+#X obj 16 275 tabwrite \$0-disto;
+#X obj 16 188 / 9999;
+#X msg 16 76 10000;
+#X obj 16 165 t f f;
+#X obj 16 231 * 2;
+#X connect 0 0 6 0;
+#X connect 1 0 11 0;
+#X connect 1 1 4 0;
+#X connect 2 0 3 0;
+#X connect 2 0 12 0;
+#X connect 3 0 2 1;
+#X connect 4 0 2 1;
+#X connect 5 0 2 0;
+#X connect 6 0 1 0;
+#X connect 7 0 13 0;
+#X connect 8 0 9 0;
+#X connect 10 0 7 0;
+#X connect 11 0 5 0;
+#X connect 12 0 10 0;
+#X connect 12 1 9 1;
+#X connect 13 0 8 0;
+#X restore 345 258 pd poly;
+#X obj 345 238 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 298 32 inlet;
+#X obj 298 84 sel 0 1 2 3;
+#X msg 337 54 0;
+#X obj 337 32 loadbang;
+#X connect 0 0 2 0;
+#X connect 1 0 4 0;
+#X connect 2 0 10 0;
+#X connect 3 0 5 0;
+#X connect 4 0 0 0;
+#X connect 5 0 11 0;
+#X connect 6 0 7 0;
+#X connect 7 0 10 1;
+#X connect 10 0 8 0;
+#X connect 11 0 4 1;
+#X connect 11 0 6 0;
+#X connect 13 0 12 0;
+#X connect 15 0 14 0;
+#X connect 17 0 16 0;
+#X connect 19 0 18 0;
+#X connect 20 0 21 0;
+#X connect 21 0 15 0;
+#X connect 21 1 13 0;
+#X connect 21 2 17 0;
+#X connect 21 3 19 0;
+#X connect 22 0 21 0;
+#X connect 23 0 22 0;
diff --git a/nusmuk-audio/echo~-help.pd b/nusmuk-audio/echo~-help.pd
new file mode 100644
index 0000000..6e0fd27
--- /dev/null
+++ b/nusmuk-audio/echo~-help.pd
@@ -0,0 +1,17 @@
+#N canvas 231 293 450 300 10;
+#X obj 43 53 osc~ 333;
+#X obj 118 55 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 42 87 *~;
+#X obj 42 150 *~ 0.1;
+#X obj 41 182 dac~;
+#X obj 58 117 echo~ 555 0.8;
+#X text 113 141 parametter 1: echo time (ms);
+#X text 113 160 parameter 2 : amplitude attenuation;
+#X connect 0 0 2 0;
+#X connect 1 0 2 1;
+#X connect 2 0 3 0;
+#X connect 2 0 5 0;
+#X connect 3 0 4 0;
+#X connect 3 0 4 1;
+#X connect 5 0 3 0;
diff --git a/nusmuk-audio/echo~.pd b/nusmuk-audio/echo~.pd
new file mode 100644
index 0000000..bb49a3f
--- /dev/null
+++ b/nusmuk-audio/echo~.pd
@@ -0,0 +1,14 @@
+#N canvas 712 336 450 300 10;
+#X obj 82 46 inlet~;
+#X obj 80 183 delwrite~ \$0-delay 10000;
+#X obj 47 115 delread~ \$0-delay \$1;
+#X obj 46 215 outlet~;
+#X obj 62 151 *~ \$2;
+#X obj 248 44 inlet;
+#X obj 154 48 inlet;
+#X connect 0 0 1 0;
+#X connect 2 0 3 0;
+#X connect 2 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 4 1;
+#X connect 6 0 2 0;
diff --git a/nusmuk-audio/examples/analog_synth_emulation.pd b/nusmuk-audio/examples/analog_synth_emulation.pd
new file mode 100644
index 0000000..eefd015
--- /dev/null
+++ b/nusmuk-audio/examples/analog_synth_emulation.pd
@@ -0,0 +1,237 @@
+#N canvas 333 22 523 667 10;
+#X obj 66 468 *~ 0.1;
+#X obj 67 496 dac~;
+#X obj 65 126 vsl 15 128 -20 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 5200 1;
+#X obj 65 283 line~;
+#X msg 65 261 \$1 20;
+#X obj 134 476 oscillo~;
+#X obj 66 324 ../saw~;
+#X obj 66 345 ../distortion~;
+#X obj 67 434 ../distortion~;
+#N canvas 520 123 368 628 coef_lpf_biquad 0;
+#X obj 50 32 inlet;
+#X obj 211 31 inlet;
+#X text 92 34 f;
+#X text 256 31 Q;
+#X obj 117 137 samplerate~;
+#X obj 117 114 loadbang;
+#X obj 174 115 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 50 170 /;
+#X obj 50 369 cos;
+#X obj 199 296 sin;
+#X obj 211 116 * 2;
+#X obj 50 564 outlet;
+#X obj 288 504 + 1;
+#X obj 139 501 / 2;
+#X obj 94 505 -;
+#X msg 99 463 1 \$1;
+#X msg 139 458 1 \$1;
+#X obj 184 480 -;
+#X obj 229 501 / 2;
+#X msg 229 460 1 \$1;
+#X obj 50 487 * -2;
+#X obj 139 480 -;
+#X msg 184 458 1 \$1;
+#X obj 229 481 -;
+#X obj 199 350 t f f;
+#X obj 50 269 t f f;
+#X obj 50 539 /;
+#X obj 94 540 /;
+#X obj 139 540 /;
+#X obj 184 539 /;
+#X obj 229 540 /;
+#X obj 139 564 outlet;
+#X obj 94 564 outlet;
+#X obj 184 564 outlet;
+#X obj 229 564 outlet;
+#X obj 50 246 f;
+#X obj 211 185 t b f;
+#X obj 211 95 + 0.707;
+#X obj 211 74 max 0;
+#X obj 50 73 max 0;
+#X obj 50 394 t f f b;
+#X obj 50 115 * 3.14159;
+#X obj 67 206 min 3.14;
+#X obj 238 295 sinh;
+#X obj 199 325 * 0.767;
+#X msg 211 140 1 \$1;
+#X obj 211 162 /;
+#X obj 50 143 * 2;
+#X obj 50 95 min 21000;
+#X connect 0 0 39 0;
+#X connect 1 0 38 0;
+#X connect 4 0 7 1;
+#X connect 5 0 4 0;
+#X connect 6 0 4 0;
+#X connect 7 0 35 0;
+#X connect 8 0 40 0;
+#X connect 9 0 44 0;
+#X connect 10 0 45 0;
+#X connect 12 0 26 1;
+#X connect 12 0 27 1;
+#X connect 12 0 28 1;
+#X connect 12 0 29 1;
+#X connect 12 0 30 1;
+#X connect 13 0 28 0;
+#X connect 14 0 27 0;
+#X connect 15 0 14 0;
+#X connect 16 0 21 0;
+#X connect 17 0 29 0;
+#X connect 18 0 30 0;
+#X connect 19 0 23 0;
+#X connect 20 0 26 0;
+#X connect 21 0 13 0;
+#X connect 22 0 17 0;
+#X connect 23 0 18 0;
+#X connect 24 0 15 0;
+#X connect 24 1 12 0;
+#X connect 25 0 8 0;
+#X connect 25 1 9 0;
+#X connect 26 0 11 0;
+#X connect 27 0 32 0;
+#X connect 28 0 31 0;
+#X connect 29 0 33 0;
+#X connect 30 0 34 0;
+#X connect 35 0 25 0;
+#X connect 36 0 35 0;
+#X connect 36 1 43 0;
+#X connect 37 0 10 0;
+#X connect 38 0 37 0;
+#X connect 39 0 48 0;
+#X connect 40 0 20 0;
+#X connect 40 1 16 0;
+#X connect 40 1 22 0;
+#X connect 40 1 19 0;
+#X connect 40 2 14 0;
+#X connect 41 0 47 0;
+#X connect 42 0 35 0;
+#X connect 43 0 44 1;
+#X connect 44 0 24 0;
+#X connect 45 0 46 0;
+#X connect 46 0 36 0;
+#X connect 47 0 7 0;
+#X connect 48 0 41 0;
+#X restore 244 253 pd coef_lpf_biquad;
+#X obj 244 277 pack f f f f f;
+#X obj 244 231 mtof;
+#X floatatom 369 229 5 0 0 0 - - -;
+#X obj 244 303 t a;
+#N canvas 0 0 450 300 5_line~ 0;
+#X obj 80 123 line~;
+#X obj 79 147 outlet~;
+#X obj 80 71 inlet;
+#X obj 136 123 line~;
+#X obj 135 147 outlet~;
+#X obj 136 73 inlet;
+#X obj 193 123 line~;
+#X obj 192 147 outlet~;
+#X obj 193 73 inlet;
+#X obj 247 123 line~;
+#X obj 246 147 outlet~;
+#X obj 247 73 inlet;
+#X obj 304 123 line~;
+#X obj 303 147 outlet~;
+#X obj 304 73 inlet;
+#X msg 80 97 \$1 5;
+#X msg 135 98 \$1 5;
+#X msg 193 96 \$1 5;
+#X msg 247 99 \$1 5;
+#X msg 303 99 \$1 5;
+#X connect 0 0 1 0;
+#X connect 2 0 15 0;
+#X connect 3 0 4 0;
+#X connect 5 0 16 0;
+#X connect 6 0 7 0;
+#X connect 8 0 17 0;
+#X connect 9 0 10 0;
+#X connect 11 0 18 0;
+#X connect 12 0 13 0;
+#X connect 14 0 19 0;
+#X connect 15 0 0 0;
+#X connect 16 0 3 0;
+#X connect 17 0 6 0;
+#X connect 18 0 9 0;
+#X connect 19 0 12 0;
+#X restore 244 344 pd 5_line~;
+#X obj 244 323 unpack f f f f f;
+#X obj 66 388 bq~ ---------;
+#X obj 244 96 vsl 15 128 -20 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 8200 1;
+#X obj 101 -39 metro 222;
+#X obj 101 93 pack f f;
+#X obj 101 -16 t b b;
+#X obj 154 25 random 222;
+#X obj 232 25 random 222;
+#X obj 101 -58 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1
+1;
+#X obj 179 71 pack f f;
+#X obj 179 93 line;
+#X obj 66 304 mtof~;
+#X floatatom 132 323 5 0 0 0 - - -;
+#X floatatom 114 415 5 0 0 0 - - -;
+#X obj 359 38 random 222;
+#X obj 306 104 pack f f;
+#X obj 306 126 line;
+#X obj 306 62 random 100;
+#X obj 306 83 / 10;
+#X obj 101 72 + 22;
+#X obj 179 49 random 99;
+#X obj 101 49 random 44;
+#X obj 135 455 *~ 0.5;
+#X connect 0 0 1 0;
+#X connect 0 0 1 1;
+#X connect 2 0 4 0;
+#X connect 3 0 26 0;
+#X connect 4 0 3 0;
+#X connect 6 0 7 0;
+#X connect 7 0 16 0;
+#X connect 8 0 0 0;
+#X connect 8 0 37 0;
+#X connect 9 0 10 0;
+#X connect 9 1 10 1;
+#X connect 9 2 10 2;
+#X connect 9 3 10 3;
+#X connect 9 4 10 4;
+#X connect 10 0 13 0;
+#X connect 11 0 9 0;
+#X connect 12 0 9 1;
+#X connect 13 0 15 0;
+#X connect 14 0 16 1;
+#X connect 14 1 16 2;
+#X connect 14 2 16 3;
+#X connect 14 3 16 4;
+#X connect 14 4 16 5;
+#X connect 15 0 14 0;
+#X connect 15 1 14 1;
+#X connect 15 2 14 2;
+#X connect 15 3 14 3;
+#X connect 15 4 14 4;
+#X connect 16 0 8 0;
+#X connect 17 0 11 0;
+#X connect 18 0 20 0;
+#X connect 19 0 3 0;
+#X connect 20 0 32 0;
+#X connect 20 0 35 0;
+#X connect 20 0 36 0;
+#X connect 20 1 21 0;
+#X connect 20 1 22 0;
+#X connect 20 1 29 0;
+#X connect 21 0 19 1;
+#X connect 22 0 24 1;
+#X connect 23 0 18 0;
+#X connect 24 0 25 0;
+#X connect 25 0 11 0;
+#X connect 26 0 6 0;
+#X connect 27 0 7 1;
+#X connect 28 0 8 1;
+#X connect 29 0 30 1;
+#X connect 30 0 31 0;
+#X connect 31 0 9 1;
+#X connect 32 0 33 0;
+#X connect 33 0 30 0;
+#X connect 34 0 19 0;
+#X connect 35 0 24 0;
+#X connect 36 0 34 0;
+#X connect 37 0 5 0;
diff --git a/hanning.wav b/nusmuk-audio/examples/hanning.wav
index b4f30fa..b4f30fa 100644
--- a/hanning.wav
+++ b/nusmuk-audio/examples/hanning.wav
Binary files differ
diff --git a/granulator-help.pd b/nusmuk-audio/granulator~-help.pd
index 52d509e..32daf2a 100644
--- a/granulator-help.pd
+++ b/nusmuk-audio/granulator~-help.pd
@@ -1,4 +1,4 @@
-#N canvas 145 74 1000 707 10;
+#N canvas 122 22 1000 667 10;
#X obj 115 575 soundfiler;
#X msg 34 171 open \$1 \$2;
#X obj 85 91 hradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1
@@ -26,8 +26,7 @@
#X floatatom 749 312 5 0 0 0 - - -;
#X floatatom 760 329 5 0 0 0 - - -;
#X text 286 24 ch 2005_04_10;
-#X msg 105 352 window cos;
-#X msg 105 374 window hanning.wav;
+#X msg 90 353 window cos;
#X msg 65 199 table foo 44100;
#X text 74 216 use a specific table for the audio source;
#X msg 84 257 table reset;
@@ -109,7 +108,6 @@ in the table);
#X connect 35 1 18 0;
#X connect 36 0 18 0;
#X restore 34 664 pd help RealTime Granulator;
-#X obj 34 552 granulator;
#X text 260 7 granular synthesys with pd;
#X text 65 46 open a sound file;
#X text 8 111 table number (8 diferents files can be open in the same
@@ -126,21 +124,23 @@ time);
#X text 539 383 Table number \, position \, Random \, size \, random
\, frequency \, random \, ampitude \, random;
#X text 224 353 default windowing for the grain;
-#X text 240 373 load a soundfile for the windowing;
+#X text 210 399 load a soundfile for the windowing;
#X text 196 572 always connect a soundfiler here : it help locating
the sound relatively to the patch folder \, and not to the abstraction
folder;
#X text 95 279 to get back to the internal tables;
#X text 74 232 (user has to fill it manually : used for live granulation)
;
-#X connect 0 0 31 1;
-#X connect 1 0 31 0;
+#X msg 102 374 window examples/hanning.wav;
+#X obj 34 552 granulator~;
+#X connect 0 0 49 1;
+#X connect 1 0 49 0;
#X connect 2 0 5 1;
#X connect 3 0 5 0;
#X connect 4 0 3 0;
#X connect 5 0 1 0;
-#X connect 6 0 28 0;
-#X connect 7 0 28 1;
+#X connect 6 0 27 0;
+#X connect 7 0 27 1;
#X connect 8 0 19 0;
#X connect 9 0 19 1;
#X connect 10 0 19 2;
@@ -152,14 +152,14 @@ folder;
#X connect 15 0 16 1;
#X connect 17 0 9 0;
#X connect 18 0 8 1;
-#X connect 19 0 31 0;
+#X connect 19 0 49 0;
#X connect 20 0 19 7;
#X connect 21 0 19 8;
-#X connect 23 0 31 0;
-#X connect 24 0 31 0;
-#X connect 25 0 31 0;
-#X connect 27 0 31 0;
-#X connect 28 0 8 0;
-#X connect 29 0 17 0;
-#X connect 31 0 15 0;
-#X connect 31 1 0 0;
+#X connect 23 0 49 0;
+#X connect 24 0 49 0;
+#X connect 26 0 49 0;
+#X connect 27 0 8 0;
+#X connect 28 0 17 0;
+#X connect 48 0 49 0;
+#X connect 49 0 15 0;
+#X connect 49 1 0 0;
diff --git a/granulator.pd b/nusmuk-audio/granulator~.pd
index a1963c8..a1963c8 100644
--- a/granulator.pd
+++ b/nusmuk-audio/granulator~.pd
diff --git a/nusmuk-audio/nusmuk-audio-meta.pd b/nusmuk-audio/nusmuk-audio-meta.pd
new file mode 100644
index 0000000..6b803b4
--- /dev/null
+++ b/nusmuk-audio/nusmuk-audio-meta.pd
@@ -0,0 +1,10 @@
+#N canvas 10 10 496 221 10;
+#X text 10 157 LICENSE GNU GPL;
+#X text 10 39 AUTHOR Cyrille Henry;
+#X text 10 19 NAME nusmuk_audio;
+#X text 10 58 DESCRIPTION This objects' collection is based on abstractions
+and externals. They aim at improving audio synthesis quality within
+Pure Data. This collection enholds band limited oscillator and objects
+that read tables in a more flexible way than the Pure Data native ones.
+Some filters and various objects are also available.;
+#X text 9 177 VERSION 1.2;
diff --git a/oscillo~-help.pd b/nusmuk-audio/oscillo~-help.pd
index 65513fb..65513fb 100644
--- a/oscillo~-help.pd
+++ b/nusmuk-audio/oscillo~-help.pd
diff --git a/oscillo~.pd b/nusmuk-audio/oscillo~.pd
index 48351ba..48351ba 100644
--- a/oscillo~.pd
+++ b/nusmuk-audio/oscillo~.pd
diff --git a/nusmuk-audio/pwm~-help.pd b/nusmuk-audio/pwm~-help.pd
new file mode 100644
index 0000000..747da2d
--- /dev/null
+++ b/nusmuk-audio/pwm~-help.pd
@@ -0,0 +1,29 @@
+#N canvas 492 122 521 323 10;
+#X obj 42 266 dac~;
+#X obj 42 76 mtof;
+#X obj 41 170 pwm~;
+#X obj 42 121 line~;
+#X msg 42 98 \$1 33;
+#X obj 146 122 line~;
+#X msg 146 99 \$1 33;
+#X text 40 17 pwm~ is a band-limited square oscillator.;
+#X msg 146 60 0.5;
+#X obj 149 80 hsl 70 15 0 1 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 3450 1;
+#X floatatom 42 52 5 0 0 0 - - -;
+#X obj 125 215 oscillo~;
+#X obj 41 231 *~ 0.1;
+#X obj 146 40 loadbang;
+#X connect 1 0 4 0;
+#X connect 2 0 11 0;
+#X connect 2 0 12 0;
+#X connect 3 0 2 0;
+#X connect 4 0 3 0;
+#X connect 5 0 2 1;
+#X connect 6 0 5 0;
+#X connect 8 0 9 0;
+#X connect 9 0 6 0;
+#X connect 10 0 1 0;
+#X connect 12 0 0 0;
+#X connect 12 0 0 1;
+#X connect 13 0 8 0;
diff --git a/nusmuk-audio/pwm~.pd b/nusmuk-audio/pwm~.pd
new file mode 100644
index 0000000..a593e5f
--- /dev/null
+++ b/nusmuk-audio/pwm~.pd
@@ -0,0 +1,176 @@
+#N canvas 268 49 728 663 10;
+#X obj 65 122 phasor~;
+#X obj 66 59 inlet~;
+#X obj 238 172 +~;
+#X obj 255 64 inlet~;
+#X obj 237 198 wrap~;
+#X obj 334 327 sig~ 22050;
+#X obj 334 284 samplerate~;
+#X obj 334 232 loadbang;
+#X obj 334 307 * 0.5;
+#X obj 67 475 -~;
+#X obj 67 503 outlet~;
+#X obj 475 432 loadbang;
+#X obj 475 495 table \$0-lookup 2;
+#X obj 475 474 s \$0-lookup;
+#X msg 475 453 0 0 1;
+#X msg 344 257 bang;
+#N canvas 315 401 852 607 sinc-phasor 0;
+#X obj 173 131 -~ 0.5;
+#X obj 421 192 *~ 2;
+#X obj 459 191 /~;
+#X obj 421 219 *~;
+#X obj 422 241 abs~;
+#X obj 421 263 +~ 1.8955;
+#X obj 174 427 +~;
+#N canvas 104 42 701 480 sin(x)/x 0;
+#X obj 220 229 cos~;
+#X obj 221 204 -~ 0.25;
+#X msg 288 90 1;
+#X floatatom 288 162 5 0 0 0 - - -;
+#X obj 288 116 atan;
+#X obj 288 137 * 8;
+#X obj 220 181 /~ 6.238;
+#X obj 288 67 loadbang;
+#X obj 221 148 inlet~;
+#X obj 219 291 outlet~;
+#X obj 220 255 /~;
+#X connect 0 0 10 0;
+#X connect 1 0 0 0;
+#X connect 2 0 4 0;
+#X connect 3 0 6 1;
+#X connect 4 0 5 0;
+#X connect 5 0 3 0;
+#X connect 6 0 1 0;
+#X connect 7 0 2 0;
+#X connect 8 0 6 0;
+#X connect 8 0 10 1;
+#X connect 10 0 9 0;
+#X restore 421 293 pd sin(x)/x;
+#X text 208 426 + v3;
+#X obj 175 333 tabread~ \$0-lookup;
+#X obj 174 311 +~ 1;
+#X obj 127 78 inlet~;
+#X text 123 53 phasor~;
+#X obj 433 71 inlet~;
+#X obj 510 72 inlet~;
+#X text 506 47 SR;
+#X text 429 46 freq;
+#X obj 109 486 outlet~;
+#X obj 328 217 wrap~;
+#X obj 329 243 *~ 2;
+#X obj 329 268 -~ 1;
+#X obj 330 392 *~;
+#X text 357 387 v2*sin(v4)/v4;
+#X obj 110 460 -~;
+#X connect 0 0 1 0;
+#X connect 0 0 10 0;
+#X connect 0 0 18 0;
+#X connect 1 0 3 0;
+#X connect 2 0 3 1;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 23 0;
+#X connect 7 0 21 1;
+#X connect 9 0 6 0;
+#X connect 10 0 9 0;
+#X connect 11 0 0 0;
+#X connect 11 0 23 1;
+#X connect 13 0 2 1;
+#X connect 14 0 2 0;
+#X connect 18 0 19 0;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 6 1;
+#X connect 23 0 17 0;
+#X restore 238 442 pd sinc-phasor;
+#N canvas 315 401 852 607 sinc-phasor 0;
+#X obj 173 131 -~ 0.5;
+#X obj 421 192 *~ 2;
+#X obj 459 191 /~;
+#X obj 421 219 *~;
+#X obj 422 241 abs~;
+#X obj 421 263 +~ 1.8955;
+#X obj 174 427 +~;
+#N canvas 104 42 701 480 sin(x)/x 0;
+#X obj 220 229 cos~;
+#X obj 221 204 -~ 0.25;
+#X msg 288 90 1;
+#X floatatom 288 162 5 0 0 0 - - -;
+#X obj 288 116 atan;
+#X obj 288 137 * 8;
+#X obj 220 181 /~ 6.238;
+#X obj 288 67 loadbang;
+#X obj 221 148 inlet~;
+#X obj 219 291 outlet~;
+#X obj 220 255 /~;
+#X connect 0 0 10 0;
+#X connect 1 0 0 0;
+#X connect 2 0 4 0;
+#X connect 3 0 6 1;
+#X connect 4 0 5 0;
+#X connect 5 0 3 0;
+#X connect 6 0 1 0;
+#X connect 7 0 2 0;
+#X connect 8 0 6 0;
+#X connect 8 0 10 1;
+#X connect 10 0 9 0;
+#X restore 421 293 pd sin(x)/x;
+#X text 208 426 + v3;
+#X obj 175 333 tabread~ \$0-lookup;
+#X obj 174 311 +~ 1;
+#X obj 127 78 inlet~;
+#X text 123 53 phasor~;
+#X obj 433 71 inlet~;
+#X obj 510 72 inlet~;
+#X text 506 47 SR;
+#X text 429 46 freq;
+#X obj 109 486 outlet~;
+#X obj 328 217 wrap~;
+#X obj 329 243 *~ 2;
+#X obj 329 268 -~ 1;
+#X obj 330 392 *~;
+#X text 357 387 v2*sin(v4)/v4;
+#X obj 110 460 -~;
+#X connect 0 0 1 0;
+#X connect 0 0 10 0;
+#X connect 0 0 18 0;
+#X connect 1 0 3 0;
+#X connect 2 0 3 1;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 23 0;
+#X connect 7 0 21 1;
+#X connect 9 0 6 0;
+#X connect 10 0 9 0;
+#X connect 11 0 0 0;
+#X connect 11 0 23 1;
+#X connect 13 0 2 1;
+#X connect 14 0 2 0;
+#X connect 18 0 19 0;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 6 1;
+#X connect 23 0 17 0;
+#X restore 66 443 pd sinc-phasor;
+#X connect 0 0 2 0;
+#X connect 0 0 17 0;
+#X connect 1 0 0 0;
+#X connect 1 0 16 1;
+#X connect 1 0 17 1;
+#X connect 2 0 4 0;
+#X connect 3 0 2 1;
+#X connect 4 0 16 0;
+#X connect 5 0 16 2;
+#X connect 5 0 17 2;
+#X connect 6 0 8 0;
+#X connect 7 0 6 0;
+#X connect 8 0 5 0;
+#X connect 9 0 10 0;
+#X connect 11 0 14 0;
+#X connect 14 0 13 0;
+#X connect 15 0 6 0;
+#X connect 16 0 9 1;
+#X connect 17 0 9 0;
diff --git a/nusmuk-audio/saw~-help.pd b/nusmuk-audio/saw~-help.pd
new file mode 100644
index 0000000..fbc3a11
--- /dev/null
+++ b/nusmuk-audio/saw~-help.pd
@@ -0,0 +1,16 @@
+#N canvas 340 204 450 293 10;
+#X obj 42 137 saw~;
+#X obj 43 110 sig~ 333;
+#X obj 43 194 dac~;
+#X floatatom 43 63 5 0 0 0 - - -;
+#X obj 43 86 mtof;
+#X text 30 17 saw~ is a band-limited sawtooth oscillator.;
+#X obj 137 197 oscillo~;
+#X obj 43 162 *~ 0.1;
+#X connect 0 0 7 0;
+#X connect 0 0 6 0;
+#X connect 1 0 0 0;
+#X connect 3 0 4 0;
+#X connect 4 0 1 0;
+#X connect 7 0 2 0;
+#X connect 7 0 2 1;
diff --git a/nusmuk-audio/saw~.pd b/nusmuk-audio/saw~.pd
new file mode 100644
index 0000000..f06316e
--- /dev/null
+++ b/nusmuk-audio/saw~.pd
@@ -0,0 +1,79 @@
+#N canvas 232 120 725 608 10;
+#X obj 105 96 phasor~;
+#X obj 173 131 -~ 0.5;
+#X obj 421 192 *~ 2;
+#X obj 328 217 wrap~;
+#X obj 329 243 *~ 2;
+#X obj 329 268 -~ 1;
+#X obj 459 191 /~;
+#X obj 458 146 sig~ 22050;
+#X obj 421 219 *~;
+#X obj 422 241 abs~;
+#X obj 421 263 +~ 1.8955;
+#X obj 106 49 inlet~;
+#X obj 87 542 outlet~;
+#X obj 458 97 samplerate~;
+#X obj 458 74 loadbang;
+#X obj 458 120 * 0.5;
+#X obj 174 427 +~;
+#N canvas 104 42 701 480 sin(x)/x 0;
+#X obj 220 229 cos~;
+#X obj 221 204 -~ 0.25;
+#X msg 288 90 1;
+#X floatatom 288 162 5 0 0 0 - - -;
+#X obj 288 116 atan;
+#X obj 288 137 * 8;
+#X obj 220 181 /~ 6.238;
+#X obj 288 67 loadbang;
+#X obj 221 148 inlet~;
+#X obj 219 291 outlet~;
+#X obj 220 255 /~;
+#X connect 0 0 10 0;
+#X connect 1 0 0 0;
+#X connect 2 0 4 0;
+#X connect 3 0 6 1;
+#X connect 4 0 5 0;
+#X connect 5 0 3 0;
+#X connect 6 0 1 0;
+#X connect 7 0 2 0;
+#X connect 8 0 6 0;
+#X connect 8 0 10 1;
+#X connect 10 0 9 0;
+#X restore 421 293 pd sin(x)/x;
+#X obj 330 392 *~;
+#X text 357 387 v2*sin(v4)/v4;
+#X text 208 426 + v3;
+#X obj 87 482 -~;
+#X obj 557 476 loadbang;
+#X obj 557 539 table \$0-lookup 2;
+#X obj 175 333 tabread~ \$0-lookup;
+#X obj 174 311 +~ 1;
+#X obj 557 518 s \$0-lookup;
+#X msg 557 497 0 0 1;
+#X connect 0 0 1 0;
+#X connect 0 0 21 1;
+#X connect 1 0 2 0;
+#X connect 1 0 3 0;
+#X connect 1 0 25 0;
+#X connect 2 0 8 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 5 0 18 0;
+#X connect 6 0 8 1;
+#X connect 7 0 6 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 17 0;
+#X connect 11 0 0 0;
+#X connect 11 0 6 1;
+#X connect 13 0 15 0;
+#X connect 14 0 13 0;
+#X connect 15 0 7 0;
+#X connect 16 0 21 0;
+#X connect 17 0 18 1;
+#X connect 18 0 16 1;
+#X connect 21 0 12 0;
+#X connect 22 0 27 0;
+#X connect 24 0 16 0;
+#X connect 25 0 24 0;
+#X connect 27 0 26 0;
diff --git a/spatialisation-help.pd b/nusmuk-audio/spatialisation~-help.pd
index 0355d11..1e371b6 100644
--- a/spatialisation-help.pd
+++ b/nusmuk-audio/spatialisation~-help.pd
@@ -1,14 +1,13 @@
#N canvas 589 189 682 476 10;
-#X obj 159 428 dac~;
-#X obj 103 104 gcanvas 256 128;
-#X text 226 223 o;
+#X obj 164 428 dac~;
+#X obj 108 104 gcanvas 256 128;
+#X text 231 223 o;
#X obj 24 315 noise~;
#X obj 23 344 bp~ 2444 10;
#X text 90 92 HP;
#X text 359 92 HP;
#X obj 24 371 *~ 3;
#X text 212 326 \$2 : doppler effect;
-#X obj 25 398 spatialisation 1 10 2 1;
#N canvas 590 401 804 649 carttopol 0;
#X obj 36 137 cartopol;
#X obj 36 20 inlet;
@@ -37,19 +36,20 @@
#X connect 9 0 10 0;
#X connect 12 0 13 0;
#X connect 13 0 5 0;
-#X restore 103 244 pd carttopol;
+#X restore 108 244 pd carttopol;
#X text 212 364 \$4 : ampitude pan (0 to 1);
#X text 212 345 \$3 : pan time shift;
#X text 212 309 \$1 : distance to amplitude;
#X text 153 38 with amplidute limitation / doepler effect on movement
/ delay line from left to right / pan;
#X text 292 7 Basic spacialisation (2 HP);
-#X connect 1 0 10 0;
-#X connect 1 1 10 1;
+#X obj 25 399 spatialisation~ 1 10 2 1;
+#X connect 1 0 9 0;
+#X connect 1 1 9 1;
#X connect 3 0 4 0;
#X connect 4 0 7 0;
-#X connect 7 0 9 0;
-#X connect 9 0 0 0;
-#X connect 9 1 0 1;
-#X connect 10 0 9 1;
-#X connect 10 1 9 2;
+#X connect 7 0 15 0;
+#X connect 9 0 15 1;
+#X connect 9 1 15 2;
+#X connect 15 0 0 0;
+#X connect 15 1 0 1;
diff --git a/spatialisation.pd b/nusmuk-audio/spatialisation~.pd
index 607a381..e80625b 100644
--- a/spatialisation.pd
+++ b/nusmuk-audio/spatialisation~.pd
@@ -48,9 +48,6 @@
#X connect 14 0 10 0;
#X connect 16 0 13 0;
#X restore 30 230 pd pan ______________________________;
-#X text 171 30 r (mettre);
-#X text 309 117 \$1 : attenuation de l'ampitude en fct de la distance
-;
#X text 307 28 theta (radian);
#N canvas 866 546 478 334 volume_distance 0;
#X obj 26 15 inlet~;
@@ -123,23 +120,25 @@
#X connect 15 0 6 0;
#X connect 16 0 5 0;
#X restore 30 190 pd decalage_temporel ________________;
-#X text 309 152 \$2 : effet de la distance sur l'effet doppler;
-#X text 310 230 \$4 : effet du panoramique;
-#X text 310 190 \$3 : distance entre les 2 ecouteurs;
-#X connect 0 0 11 0;
+#X text 309 117 \$1 : amplitude atenuation regarding the distance;
+#X text 309 152 \$2 : doepler effect;
+#X text 310 190 \$3 : distance beetween 2 speeker;
+#X text 310 230 \$4 : panoramic effect;
+#X text 171 30 r (metter);
+#X connect 0 0 9 0;
#X connect 1 0 4 0;
#X connect 2 0 4 1;
-#X connect 4 0 11 1;
-#X connect 4 1 11 2;
+#X connect 4 0 9 1;
+#X connect 4 1 9 2;
#X connect 7 0 5 0;
#X connect 7 1 6 0;
-#X connect 11 0 12 0;
-#X connect 11 1 12 1;
-#X connect 11 2 12 2;
-#X connect 12 0 13 0;
-#X connect 12 1 13 1;
-#X connect 12 2 13 2;
-#X connect 13 0 7 0;
-#X connect 13 1 7 1;
-#X connect 13 2 7 2;
-#X connect 13 3 7 3;
+#X connect 9 0 10 0;
+#X connect 9 1 10 1;
+#X connect 9 2 10 2;
+#X connect 10 0 11 0;
+#X connect 10 1 11 1;
+#X connect 10 2 11 2;
+#X connect 11 0 7 0;
+#X connect 11 1 7 1;
+#X connect 11 2 7 2;
+#X connect 11 3 7 3;
diff --git a/nusmuk-audio/tabosc4c~-help.pd b/nusmuk-audio/tabosc4c~-help.pd
new file mode 100644
index 0000000..e8a209a
--- /dev/null
+++ b/nusmuk-audio/tabosc4c~-help.pd
@@ -0,0 +1,104 @@
+#N canvas 298 40 774 479 12;
+#X floatatom 41 42 9 0 0 0 - - -;
+#X obj 41 63 sig~ 100;
+#N canvas 0 0 450 300 (subpatch) 0;
+#X array array99 11 float 0;
+#X coords 0 1 10 -1 250 200 1;
+#X restore 436 180 graph;
+#X obj 437 48 loadbang;
+#X floatatom 41 -1 5 0 0 0 - - -;
+#X obj 41 19 mtof;
+#X floatatom 77 307 0 0 0 0 - - -;
+#N canvas 159 26 706 447 output 0;
+#X obj 414 196 t b;
+#X obj 414 134 f;
+#X obj 414 73 inlet;
+#X text 421 36 mute;
+#X obj 414 227 f;
+#X msg 521 218 0;
+#X msg 414 104 bang;
+#X obj 414 166 moses 1;
+#X obj 521 187 t b f;
+#X obj 486 143 moses 1;
+#X obj 102 181 dbtorms;
+#X obj 486 113 r master-lvl;
+#X obj 102 52 r master-lvl;
+#X obj 414 257 s master-lvl;
+#X obj 26 222 inlet~;
+#X obj 244 50 inlet;
+#X text 244 22 level;
+#X obj 244 122 s master-lvl;
+#X msg 118 80 set \$1;
+#X obj 118 109 outlet;
+#X msg 262 78 \; pd dsp 1;
+#X obj 102 238 line~;
+#X obj 26 259 *~;
+#X obj 26 295 dac~;
+#X obj 102 210 pack 0 50;
+#X text 24 195 audio;
+#X text 114 135 show level;
+#X connect 0 0 4 0;
+#X connect 1 0 7 0;
+#X connect 2 0 6 0;
+#X connect 4 0 13 0;
+#X connect 5 0 13 0;
+#X connect 6 0 1 0;
+#X connect 7 0 0 0;
+#X connect 7 1 8 0;
+#X connect 8 0 5 0;
+#X connect 9 1 4 1;
+#X connect 10 0 24 0;
+#X connect 11 0 1 1;
+#X connect 11 0 9 0;
+#X connect 12 0 10 0;
+#X connect 12 0 18 0;
+#X connect 14 0 22 0;
+#X connect 15 0 17 0;
+#X connect 15 0 20 0;
+#X connect 18 0 19 0;
+#X connect 21 0 22 1;
+#X connect 22 0 23 0;
+#X connect 22 0 23 1;
+#X connect 24 0 21 0;
+#X restore 43 333 pd output;
+#X msg 113 307 MUTE;
+#X obj 42 123 tabosc4~ array99;
+#X obj 179 230 *~;
+#X msg 356 42 \$1 30;
+#X obj 359 19 hsl 128 15 0 1 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 0 1;
+#X obj 357 89 -~ 1;
+#X obj 356 113 *~ -1;
+#X obj 356 66 line~;
+#X obj 43 231 *~;
+#X text 498 18 tabosc4~;
+#X text 279 17 tabosc4c~;
+#X msg 294 67 0;
+#X obj 178 123 tabosc4c~ array99;
+#X msg 437 75 \; array99 resize 11 \; array99 0 0 0 -0.5 -0.5 1 -1
+0.5 -1 0 0 0 \; pd dsp 1 \;;
+#X text 40 395 tabosc4c~ is a drop in remplacement for tabosc4~ \,
+but offer a 4 points cubic interpolation with tengent continuity. So
+\, in some case \, quality is better than the standart interpolation
+;
+#X connect 0 0 1 0;
+#X connect 1 0 9 0;
+#X connect 1 0 20 0;
+#X connect 3 0 21 0;
+#X connect 4 0 5 0;
+#X connect 5 0 0 0;
+#X connect 6 0 7 1;
+#X connect 7 0 6 0;
+#X connect 8 0 7 2;
+#X connect 9 0 16 0;
+#X connect 10 0 7 0;
+#X connect 11 0 15 0;
+#X connect 12 0 11 0;
+#X connect 13 0 14 0;
+#X connect 14 0 10 1;
+#X connect 15 0 13 0;
+#X connect 15 0 16 1;
+#X connect 16 0 7 0;
+#X connect 19 0 9 1;
+#X connect 19 0 20 1;
+#X connect 20 0 10 0;
diff --git a/nusmuk-audio/tabosc4c~.c b/nusmuk-audio/tabosc4c~.c
new file mode 100644
index 0000000..ad4e7a2
--- /dev/null
+++ b/nusmuk-audio/tabosc4c~.c
@@ -0,0 +1,244 @@
+// tabosc4c~
+// can replace with tabosc4~
+// most of this code comes from pd. just the interpolation shematic is diferent.
+
+/*
+This software is copyrighted by Miller Puckette and others. The following
+terms (the "Standard Improved BSD License") apply to all files associated with
+the software unless explicitly disclaimed in individual files:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+3. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// Cyrille Henry 06 2008
+
+
+#include "m_pd.h"
+
+/******************** tabosc4c~ ***********************/
+
+/* this is all copied from d_osc.c... what include file could this go in? */
+#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 */
+#endif /* IRIX */
+
+#ifdef MSW
+ /* little-endian; most significant byte is at highest address */
+#define HIOFFSET 1
+#define LOWOFFSET 0
+#define int32 long
+#endif
+
+#if defined(__FreeBSD__) || defined(__APPLE__)
+#include <machine/endian.h>
+#endif
+
+#ifdef __linux__
+#include <endian.h>
+#endif
+
+#if defined(__unix__) || defined(__APPLE__)
+#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
+#endif /* __unix__ or __APPLE__*/
+
+union tabfudge
+{
+ double tf_d;
+ int32 tf_i[2];
+};
+
+static t_class *tabosc4c_tilde_class;
+
+typedef struct _tabosc4c_tilde
+{
+ t_object x_obj;
+ t_float x_fnpoints;
+ t_float x_finvnpoints;
+ t_word *x_vec;
+ t_symbol *x_arrayname;
+ t_float x_f;
+ double x_phase;
+ t_float x_conv;
+} t_tabosc4c_tilde;
+
+static void *tabosc4c_tilde_new(t_symbol *s)
+{
+ t_tabosc4c_tilde *x = (t_tabosc4c_tilde *)pd_new(tabosc4c_tilde_class);
+ x->x_arrayname = s;
+ x->x_vec = 0;
+ x->x_fnpoints = 512.;
+ x->x_finvnpoints = (1./512.);
+ outlet_new(&x->x_obj, gensym("signal"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ x->x_f = 0;
+ return (x);
+}
+
+static t_int *tabosc4c_tilde_perform(t_int *w)
+{
+ t_tabosc4c_tilde *x = (t_tabosc4c_tilde *)(w[1]);
+ t_sample *in = (t_sample *)(w[2]);
+ t_sample *out = (t_sample *)(w[3]);
+ int n = (int)(w[4]);
+ int normhipart;
+ union tabfudge tf;
+ double a3,a1,a2; // CH : for the interpolation
+ t_float fnpoints = x->x_fnpoints;
+ int mask = fnpoints - 1;
+ t_float conv = fnpoints * x->x_conv;
+ int maxindex;
+ t_word *tab = x->x_vec, *addr;
+ int i;
+ double dphase = fnpoints * x->x_phase + UNITBIT32;
+
+ if (!tab) goto zero;
+ tf.tf_d = UNITBIT32;
+ normhipart = tf.tf_i[HIOFFSET];
+
+ while (n--)
+ {
+ t_sample frac, a, b, c, d, cminusb;
+ tf.tf_d = dphase;
+ dphase += *in++ * conv;
+ addr = tab + (tf.tf_i[HIOFFSET] & mask);
+ tf.tf_i[HIOFFSET] = normhipart;
+ frac = tf.tf_d - UNITBIT32;
+ a = addr[0].w_float;
+ b = addr[1].w_float;
+ c = addr[2].w_float;
+ d = addr[3].w_float;
+// cminusb = c-b;
+// *out++ = b + frac * (
+// cminusb - 0.1666667f * (1.-frac) * (
+// (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b) ) );
+// CH
+// a0 = d - c - a + b;
+// a1 = a - b - a0;
+// a2 = c - a;
+// *out++ = ((a0*frac+a1)*frac+a2)*frac+b;
+
+ // 4-point, 3rd-order Hermite (x-form)
+ a1 = 0.5f * (c - a);
+ a2 = a - 2.5 * b + 2.f * c - 0.5f * d;
+ a3 = 0.5f * (d - a) + 1.5f * (b - c);
+
+ *out++ = ((a3 * frac + a2) * frac + a1) * frac + b;
+ }
+
+
+ tf.tf_d = UNITBIT32 * fnpoints;
+ normhipart = tf.tf_i[HIOFFSET];
+ tf.tf_d = dphase + (UNITBIT32 * fnpoints - UNITBIT32);
+ tf.tf_i[HIOFFSET] = normhipart;
+ x->x_phase = (tf.tf_d - UNITBIT32 * fnpoints) * x->x_finvnpoints;
+ return (w+5);
+ zero:
+ while (n--) *out++ = 0;
+
+ return (w+5);
+}
+
+void tabosc4c_tilde_set(t_tabosc4c_tilde *x, t_symbol *s)
+{
+ t_garray *a;
+ int npoints, pointsinarray;
+
+ x->x_arrayname = s;
+ if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+ {
+ if (*s->s_name)
+ pd_error(x, "tabosc4c~: %s: no such array", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else if (!garray_getfloatwords(a, &pointsinarray, &x->x_vec))
+ {
+ pd_error(x, "%s: bad template for tabosc4c~", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else if ((npoints = pointsinarray - 3) != (1 << ilog2(pointsinarray - 3)))
+ {
+ pd_error(x, "%s: number of points (%d) not a power of 2 plus three",
+ x->x_arrayname->s_name, pointsinarray);
+ x->x_vec = 0;
+ garray_usedindsp(a);
+ }
+ else
+ {
+ x->x_fnpoints = npoints;
+ x->x_finvnpoints = 1./npoints;
+ garray_usedindsp(a);
+ }
+}
+
+static void tabosc4c_tilde_ft1(t_tabosc4c_tilde *x, t_float f)
+{
+ x->x_phase = f;
+}
+
+static void tabosc4c_tilde_dsp(t_tabosc4c_tilde *x, t_signal **sp)
+{
+ x->x_conv = 1. / sp[0]->s_sr;
+ tabosc4c_tilde_set(x, x->x_arrayname);
+
+ dsp_add(tabosc4c_tilde_perform, 4, x,
+ sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+void tabosc4c_tilde_setup(void)
+{
+ tabosc4c_tilde_class = class_new(gensym("tabosc4c~"),
+ (t_newmethod)tabosc4c_tilde_new, 0,
+ sizeof(t_tabosc4c_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(tabosc4c_tilde_class, t_tabosc4c_tilde, x_f);
+ class_addmethod(tabosc4c_tilde_class, (t_method)tabosc4c_tilde_dsp,
+ gensym("dsp"), 0);
+ class_addmethod(tabosc4c_tilde_class, (t_method)tabosc4c_tilde_set,
+ gensym("set"), A_SYMBOL, 0);
+ class_addmethod(tabosc4c_tilde_class, (t_method)tabosc4c_tilde_ft1,
+ gensym("ft1"), A_FLOAT, 0);
+}
+
diff --git a/nusmuk-audio/tabosci~-help.pd b/nusmuk-audio/tabosci~-help.pd
new file mode 100644
index 0000000..5b2dad6
--- /dev/null
+++ b/nusmuk-audio/tabosci~-help.pd
@@ -0,0 +1,258 @@
+#N canvas 72 25 1011 661 12;
+#X floatatom 46 55 9 0 0 0 - - -;
+#N canvas 0 0 450 300 (subpatch) 0;
+#X array array99 11 float 0;
+#X coords 0 1 10 -1 250 200 1;
+#X restore 603 153 graph;
+#X obj 600 27 loadbang;
+#X floatatom 46 12 5 0 135 0 - - -;
+#X obj 46 32 mtof;
+#X floatatom 80 380 0 0 0 0 - - -;
+#N canvas 159 26 706 447 output 0;
+#X obj 414 196 t b;
+#X obj 414 134 f;
+#X obj 414 73 inlet;
+#X text 421 36 mute;
+#X obj 414 227 f;
+#X msg 521 218 0;
+#X msg 414 104 bang;
+#X obj 414 166 moses 1;
+#X obj 521 187 t b f;
+#X obj 486 143 moses 1;
+#X obj 102 181 dbtorms;
+#X obj 486 113 r master-lvl;
+#X obj 102 52 r master-lvl;
+#X obj 414 257 s master-lvl;
+#X obj 26 222 inlet~;
+#X obj 244 50 inlet;
+#X text 244 22 level;
+#X obj 244 122 s master-lvl;
+#X msg 118 80 set \$1;
+#X obj 118 109 outlet;
+#X msg 262 78 \; pd dsp 1;
+#X obj 102 238 line~;
+#X obj 26 259 *~;
+#X obj 26 295 dac~;
+#X obj 102 210 pack 0 50;
+#X text 24 195 audio;
+#X text 114 135 show level;
+#X connect 0 0 4 0;
+#X connect 1 0 7 0;
+#X connect 2 0 6 0;
+#X connect 4 0 13 0;
+#X connect 5 0 13 0;
+#X connect 6 0 1 0;
+#X connect 7 0 0 0;
+#X connect 7 1 8 0;
+#X connect 8 0 5 0;
+#X connect 9 1 4 1;
+#X connect 10 0 24 0;
+#X connect 11 0 1 1;
+#X connect 11 0 9 0;
+#X connect 12 0 10 0;
+#X connect 12 0 18 0;
+#X connect 14 0 22 0;
+#X connect 15 0 17 0;
+#X connect 15 0 20 0;
+#X connect 18 0 19 0;
+#X connect 21 0 22 1;
+#X connect 22 0 23 0;
+#X connect 22 0 23 1;
+#X connect 24 0 21 0;
+#X restore 46 406 pd output;
+#X msg 116 380 MUTE;
+#X obj 200 293 *~;
+#X msg 433 193 \$1 30;
+#X obj 436 170 hsl 128 15 0 1 0 0 empty empty empty -2 -8 0 10 -262144
+-1 -1 0 1;
+#X obj 434 240 -~ 1;
+#X obj 433 264 *~ -1;
+#X obj 433 217 line~;
+#X obj 46 294 *~;
+#X msg 341 214 0;
+#X msg 600 54 \; array99 resize 11 \; array99 0 0 0 -0.5 -0.5 1 -1
+0.5 -1 0 0 0 \; pd dsp 1 \;;
+#X obj 200 255 tabosc4~ array99;
+#X text 501 149 tabosc4~;
+#N canvas 371 25 645 661 osc~ 0;
+#X obj 12 133 pack~;
+#X obj 14 7 inlet~;
+#X text 230 14 change block size;
+#X msg 77 379 0;
+#X obj 47 403 f;
+#X obj 63 428 + 1;
+#X obj 17 379 t a b;
+#X obj 16 245 gemhead;
+#X text 72 7 audio input;
+#X obj 13 29 rfft~;
+#X obj 13 51 *~;
+#X obj 53 53 *~;
+#X obj 171 72 block~ 4096 4;
+#X obj 12 75 /~ 4096;
+#X obj 12 95 log~;
+#X obj 12 114 *~ 0.05;
+#X obj 12 152 list prepend 0;
+#X obj 12 173 s \$0-fft;
+#X obj 273 189 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 273 207 t b b;
+#X obj 272 251 until;
+#X msg 272 228 2048;
+#X msg 331 251 0;
+#X obj 272 276 f;
+#X obj 287 299 + 1;
+#X obj 272 349 tabread \$0-fft;
+#X obj 408 348 tabread \$0-fft-lop;
+#X obj 272 399 +;
+#X obj 272 443 tabwrite \$0-fft-lop;
+#X obj 272 324 t f f f;
+#X obj 296 183 bang~;
+#X obj 272 421 / 8;
+#X obj 409 376 * 7;
+#X obj 77 494 tabread \$0-fft-lop;
+#X obj 26 611 loadbang;
+#X obj 47 451 t f f;
+#X obj 72 578 l;
+#X obj 22 224 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 71 547 t l b;
+#X obj 18 659 curve 2;
+#X obj 46 519 pack f f f;
+#X floatatom 36 296 5 0 0 0 - - -;
+#X floatatom 78 297 5 0 0 0 - - -;
+#X obj 17 334 t a b;
+#X floatatom 72 250 5 0 0 0 - - -;
+#X floatatom 114 251 5 0 0 0 - - -;
+#X obj 17 358 repeat 2048;
+#X obj 14 277 translateXYZ -4 0 0;
+#X obj 47 471 log;
+#X obj 17 314 scaleXYZ 1.04 6 0;
+#X msg 26 633 res 2;
+#X obj 170 92 table \$0-fft 2048;
+#X obj 170 112 table \$0-fft-lop 2048;
+#X connect 0 0 16 0;
+#X connect 1 0 9 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 4 0 35 0;
+#X connect 5 0 4 1;
+#X connect 6 0 39 0;
+#X connect 6 1 4 0;
+#X connect 7 0 47 0;
+#X connect 9 0 10 0;
+#X connect 9 0 10 1;
+#X connect 9 1 11 0;
+#X connect 9 1 11 1;
+#X connect 10 0 13 0;
+#X connect 11 0 13 0;
+#X connect 13 0 14 0;
+#X connect 14 0 15 0;
+#X connect 15 0 0 0;
+#X connect 16 0 17 0;
+#X connect 18 0 19 0;
+#X connect 19 0 21 0;
+#X connect 19 1 22 0;
+#X connect 20 0 23 0;
+#X connect 21 0 20 0;
+#X connect 22 0 23 1;
+#X connect 23 0 24 0;
+#X connect 23 0 29 0;
+#X connect 24 0 23 1;
+#X connect 25 0 27 0;
+#X connect 26 0 32 0;
+#X connect 27 0 31 0;
+#X connect 29 0 25 0;
+#X connect 29 1 26 0;
+#X connect 29 2 28 1;
+#X connect 30 0 19 0;
+#X connect 31 0 28 0;
+#X connect 32 0 27 1;
+#X connect 33 0 40 1;
+#X connect 34 0 50 0;
+#X connect 35 0 48 0;
+#X connect 35 1 33 0;
+#X connect 36 0 39 2;
+#X connect 37 0 7 0;
+#X connect 38 0 36 1;
+#X connect 38 1 36 0;
+#X connect 40 0 38 0;
+#X connect 40 0 39 1;
+#X connect 41 0 49 1;
+#X connect 42 0 49 2;
+#X connect 43 0 46 0;
+#X connect 43 1 3 0;
+#X connect 44 0 47 1;
+#X connect 45 0 47 2;
+#X connect 46 0 6 0;
+#X connect 47 0 49 0;
+#X connect 48 0 40 0;
+#X connect 49 0 43 0;
+#X connect 50 0 39 0;
+#X restore 55 356 pd osc~;
+#X msg 605 385 reset \, create \, 1;
+#X msg 611 407 0 \, destroy;
+#X msg 46 73 \$1 100;
+#X obj 46 96 line~;
+#X obj 605 429 gemwin 20;
+#X msg 172 77 cutoff \$1;
+#X floatatom 172 14 5 0 0 0 - - -;
+#X obj 172 34 mtof;
+#X floatatom 185 58 9 0 0 0 - - -;
+#X text 396 149 tabosc4i~;
+#X obj 45 333 +~;
+#X floatatom 286 52 5 0 0 0 - - -;
+#X msg 286 75 upsample \$1;
+#X msg 325 23 4;
+#X msg 286 23 2;
+#X obj 47 254 tabosci~ array99;
+#X obj 214 353 oscillo~;
+#X msg 364 23 8;
+#X text 41 458 tabosc4c~ is a drop in remplacement for tabosc4~ \,
+but offer an other 4 points interpolation. So \, in some case \, quality
+is better than the standart interpolation. Moreover \, it can use table
+size 2^n (and not 2^n+3) \, so you dan't have to copy the 1st 3 point
+of the table at the end.;
+#X text 764 387 <- draw spectrum with Gem;
+#X text 43 543 You can also adjust an upsamplig factor \, and a cutoff
+freq of the internal biquad. Upsample by 4 is ok most of the time.
+To remove "all" spectrom folding \, main sampling rate should be 96000Hz
+\, but it already gives good result at 44.1 or 48KHz...;
+#X msg 171 110 cutoff 0;
+#X text 255 110 no filter;
+#X connect 0 0 22 0;
+#X connect 2 0 16 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 5 0 6 1;
+#X connect 6 0 5 0;
+#X connect 7 0 6 2;
+#X connect 8 0 30 0;
+#X connect 9 0 13 0;
+#X connect 10 0 9 0;
+#X connect 11 0 12 0;
+#X connect 12 0 14 1;
+#X connect 13 0 11 0;
+#X connect 13 0 8 1;
+#X connect 14 0 30 0;
+#X connect 15 0 17 1;
+#X connect 15 0 35 1;
+#X connect 17 0 8 0;
+#X connect 20 0 24 0;
+#X connect 21 0 24 0;
+#X connect 22 0 23 0;
+#X connect 23 0 17 0;
+#X connect 23 0 35 0;
+#X connect 25 0 35 0;
+#X connect 26 0 27 0;
+#X connect 27 0 28 0;
+#X connect 27 0 25 0;
+#X connect 30 0 6 0;
+#X connect 30 0 19 0;
+#X connect 30 0 36 0;
+#X connect 31 0 32 0;
+#X connect 32 0 35 0;
+#X connect 33 0 31 0;
+#X connect 34 0 31 0;
+#X connect 35 0 14 0;
+#X connect 37 0 31 0;
+#X connect 41 0 35 0;
diff --git a/nusmuk-audio/tabosci~.c b/nusmuk-audio/tabosci~.c
new file mode 100644
index 0000000..9936c77
--- /dev/null
+++ b/nusmuk-audio/tabosci~.c
@@ -0,0 +1,320 @@
+// tabosci~
+// tabosc interpolation
+// can replace tabosc4~
+// most of this code comes from pd. but with somes modifications
+
+/*
+This software is copyrighted by Miller Puckette and others. The following
+terms (the "Standard Improved BSD License") apply to all files associated with
+the software unless explicitly disclaimed in individual files:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+3. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// Cyrille Henry 02 2009
+
+
+#include "m_pd.h"
+#include <math.h>
+
+#define max(a,b) ( ((a) > (b)) ? (a) : (b) )
+#define min(a,b) ( ((a) < (b)) ? (a) : (b) )
+
+/******************** tabosci~ ***********************/
+
+/* this is all copied from d_osc.c... what include file could this go in? */
+#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 */
+#endif /* IRIX */
+
+#ifdef MSW
+ /* little-endian; most significant byte is at highest address */
+#define HIOFFSET 1
+#define LOWOFFSET 0
+#define int32 long
+#endif
+
+#if defined(__FreeBSD__) || defined(__APPLE__)
+#include <machine/endian.h>
+#endif
+
+#ifdef __linux__
+#include <endian.h>
+#endif
+
+#if defined(__unix__) || defined(__APPLE__)
+#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
+#endif /* __unix__ or __APPLE__*/
+
+union tabfudge
+{
+ double tf_d;
+ int32 tf_i[2];
+};
+
+static t_class *tabosci_tilde_class;
+
+typedef struct _tabosci_tilde
+{
+ t_object x_obj;
+ t_float x_fnpoints;
+ t_float x_finvnpoints;
+ t_word *x_vec;
+ t_symbol *x_arrayname;
+ t_float x_f;
+ double x_phase;
+ t_float x_conv;
+ t_sample x_prev_in, x_last_in, x_prev_out, x_last_out;
+ t_float x_fa1, x_fa2, x_fb1, x_fb2, x_fb3;
+ t_float cutoff;
+ t_int upsample;
+ t_float x_sr;
+} t_tabosci_tilde;
+
+void tabosci_tilde_cutoff(t_tabosci_tilde *x, t_float cut)
+{
+ x->cutoff = cut;
+
+ if (x->cutoff == 0)
+ {
+ x->x_fb1 = 1;
+ x->x_fb2 = 0;
+ x->x_fb3 = 0;
+ x->x_fa1 = 0;
+ x->x_fa2 = 0;
+
+ x->x_prev_in = 0;
+ x->x_last_in = 0;
+ x->x_prev_out = 0; // reset filter memory
+ }
+ else
+ {
+ // filter coef to cut all high freq.
+ t_float tmp1, tmp2;
+
+ tmp1 = sqrt(2)/2;
+ tmp1 = sinh(tmp1);
+
+ tmp2 = x->cutoff * 2 * 3.1415926 / (x->upsample * x->x_sr);
+ tmp2 = min(6.28,tmp2);
+
+ tmp1 *= sin(tmp2);
+ tmp2 = cos(tmp2);
+
+ x->x_fb1 = (1-tmp2 ) /2;
+ x->x_fb2 = (1-tmp2 );
+ x->x_fb3 = (1-tmp2 ) /2;
+ x->x_fa1 = -2 * tmp2;
+ x->x_fa2 = 1 - tmp1;
+
+ tmp1 +=1;
+
+ x->x_fb1 /= tmp1;
+ x->x_fb2 /= tmp1;
+ x->x_fb3 /= tmp1;
+ x->x_fa1 /= tmp1;
+ x->x_fa2 /= tmp1;
+ }
+}
+
+static void *tabosci_tilde_new(t_symbol *s)
+{
+ t_tabosci_tilde *x = (t_tabosci_tilde *)pd_new(tabosci_tilde_class);
+ x->x_arrayname = s;
+ x->x_vec = 0;
+ x->x_fnpoints = 512.;
+ x->x_finvnpoints = (1./512.);
+ outlet_new(&x->x_obj, gensym("signal"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
+ x->x_f = 0;
+ x->cutoff = 0;
+ x->upsample = 1;
+ x->x_sr = 0;
+ tabosci_tilde_cutoff(x,0); // comput filter coef
+ return (x);
+}
+
+static t_int *tabosci_tilde_perform(t_int *w)
+{
+ t_tabosci_tilde *x = (t_tabosci_tilde *)(w[1]);
+ t_sample *in = (t_sample *)(w[2]);
+ t_sample *out = (t_sample *)(w[3]);
+ int n = (int)(w[4]);
+ int normhipart;
+ union tabfudge tf;
+ double a1,a2,a3; // CH : for the interpolation
+ t_float fnpoints = x->x_fnpoints;
+ int mask = fnpoints - 1;
+ t_float conv = fnpoints * x->x_conv;
+ int maxindex;
+ t_word *tab = x->x_vec, *addr;
+ int i;
+ double dphase = fnpoints * x->x_phase + UNITBIT32;
+
+ if (!tab) goto zero;
+ tf.tf_d = UNITBIT32;
+ normhipart = tf.tf_i[HIOFFSET];
+
+ while (n--)
+ {
+ t_sample frac, a, b, c, d, cminusb, temp, filter_out;
+
+ for (i=0;i<x->upsample;i++)
+ {
+ tf.tf_d = dphase;
+ dphase += *in/x->upsample * conv;
+ addr = tab + (tf.tf_i[HIOFFSET] & mask);
+ a = addr[0].w_float;
+ addr = tab + ((1+tf.tf_i[HIOFFSET]) & mask);
+ b = addr[0].w_float;
+ addr = tab + ((2+tf.tf_i[HIOFFSET]) & mask);
+ c = addr[0].w_float;
+ addr = tab + ((3+tf.tf_i[HIOFFSET]) & mask);
+ d = addr[0].w_float;
+ tf.tf_i[HIOFFSET] = normhipart;
+ frac = tf.tf_d - UNITBIT32;
+
+ // 4-point, 3rd-order Hermite (x-form)
+ a1 = 0.5f * (c - a);
+ a2 = a - 2.5 * b + 2.f * c - 0.5f * d;
+ a3 = 0.5f * (d - a) + 1.5f * (b - c);
+
+ temp = ((a3 * frac + a2) * frac + a1) * frac + b;
+
+ filter_out = x->x_fb1* temp + x->x_fb2 * x->x_last_in + x->x_fb3 * x->x_prev_in - x->x_fa1 * x->x_last_out - x->x_fa2 * x->x_prev_out;
+ // low pass
+
+ x->x_prev_in = x->x_last_in;
+ x->x_last_in = temp;
+ x->x_prev_out = x->x_last_out;
+ x->x_last_out = filter_out;
+ }
+ *out++ = x->x_last_out;
+ *in++;
+ }
+
+ tf.tf_d = UNITBIT32 * fnpoints;
+ normhipart = tf.tf_i[HIOFFSET];
+ tf.tf_d = dphase + (UNITBIT32 * fnpoints - UNITBIT32);
+ tf.tf_i[HIOFFSET] = normhipart;
+ x->x_phase = (tf.tf_d - UNITBIT32 * fnpoints) * x->x_finvnpoints;
+ return (w+5);
+ zero:
+ while (n--) *out++ = 0;
+
+ return (w+5);
+}
+
+void tabosci_tilde_set(t_tabosci_tilde *x, t_symbol *s)
+{
+ t_garray *a;
+ int npoints, pointsinarray;
+
+ x->x_arrayname = s;
+ if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+ {
+ if (*s->s_name)
+ pd_error(x, "tabosci~: %s: no such array", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else if (!garray_getfloatwords(a, &pointsinarray, &x->x_vec))
+ {
+ pd_error(x, "%s: bad template for tabosci~", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else
+ {
+ npoints = 1 << ilog2(pointsinarray);
+// if ( npoints != pointsinarray) post("warning, tabosci~ is using only the first %d points of array %s",npoints, x->x_arrayname->s_name);
+ x->x_fnpoints = npoints;
+ x->x_finvnpoints = 1./npoints;
+ garray_usedindsp(a);
+ }
+}
+
+
+void tabosci_tilde_upsample(t_tabosci_tilde *x, t_float up)
+{
+ x->upsample = max(1,up);
+ tabosci_tilde_cutoff(x,x->cutoff);
+}
+
+static void tabosci_tilde_ft1(t_tabosci_tilde *x, t_float f)
+{
+ x->x_phase = f;
+}
+
+static void tabosci_tilde_dsp(t_tabosci_tilde *x, t_signal **sp)
+{
+ if (x->x_sr != sp[0]->s_sr)
+ {
+ x->x_sr = sp[0]->s_sr;
+ tabosci_tilde_cutoff(x,x->cutoff);
+ x->x_conv = 1. / sp[0]->s_sr;
+ }
+ tabosci_tilde_set(x, x->x_arrayname);
+ dsp_add(tabosci_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+void tabosci_tilde_setup(void)
+{
+ tabosci_tilde_class = class_new(gensym("tabosci~"),
+ (t_newmethod)tabosci_tilde_new, 0,
+ sizeof(t_tabosci_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(tabosci_tilde_class, t_tabosci_tilde, x_f);
+ class_addmethod(tabosci_tilde_class, (t_method)tabosci_tilde_dsp,
+ gensym("dsp"), 0);
+ class_addmethod(tabosci_tilde_class, (t_method)tabosci_tilde_set,
+ gensym("set"), A_SYMBOL, 0);
+ class_addmethod(tabosci_tilde_class, (t_method)tabosci_tilde_cutoff,
+ gensym("cutoff"), A_FLOAT, 0);
+ class_addmethod(tabosci_tilde_class, (t_method)tabosci_tilde_upsample,
+ gensym("upsample"), A_FLOAT, 0);
+ class_addmethod(tabosci_tilde_class, (t_method)tabosci_tilde_ft1,
+ gensym("ft1"), A_FLOAT, 0);
+}
+
diff --git a/nusmuk-audio/tabread4c~-help.pd b/nusmuk-audio/tabread4c~-help.pd
new file mode 100644
index 0000000..82acd94
--- /dev/null
+++ b/nusmuk-audio/tabread4c~-help.pd
@@ -0,0 +1,44 @@
+#N canvas 252 101 743 661 10;
+#N canvas 0 0 450 300 (subpatch) 0;
+#X array array99 11 float 0;
+#X coords 0 1 10 -1 250 200 1;
+#X restore 461 80 graph;
+#X obj 69 195 line~;
+#X obj 36 139 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X msg 69 172 0 \, 10 1000;
+#X obj 70 219 tabread4c~ array99;
+#X obj 36 32 loadbang;
+#X obj 296 195 line~;
+#X msg 296 172 0 \, 10 1000;
+#X obj 297 219 tabread4~ array99;
+#X obj 298 241 tabwrite~ test_miller;
+#X obj 70 241 tabwrite~ test_cubic;
+#X obj 36 55 t b b;
+#N canvas 0 0 450 300 (subpatch) 0;
+#X array test_miller 44100 float 0;
+#X coords 0 1 44099 -1 250 200 1;
+#X restore 295 312 graph;
+#N canvas 0 0 450 300 (subpatch) 0;
+#X array test_cubic 44100 float 0;
+#X coords 0 1 44099 -1 250 200 1;
+#X restore 34 312 graph;
+#X msg 63 77 \; array99 resize 10 \; array99 0 -0.5 -0.5 -0.5 0.5 0.5
+0.5 -0.5 0 0 \; pd dsp 1 \;;
+#X text 43 531 tabread4c~ is a drop in remplacement for tabrad4~ \,
+but offer a 4 points cubic interpolation with tengent continuity. So
+\, in some case \, quality is better than the standart interpolation
+;
+#X connect 1 0 4 0;
+#X connect 2 0 3 0;
+#X connect 2 0 7 0;
+#X connect 2 0 9 0;
+#X connect 2 0 10 0;
+#X connect 3 0 1 0;
+#X connect 4 0 10 0;
+#X connect 5 0 11 0;
+#X connect 6 0 8 0;
+#X connect 7 0 6 0;
+#X connect 8 0 9 0;
+#X connect 11 0 2 0;
+#X connect 11 1 14 0;
diff --git a/nusmuk-audio/tabread4c~.c b/nusmuk-audio/tabread4c~.c
new file mode 100644
index 0000000..c4a7804
--- /dev/null
+++ b/nusmuk-audio/tabread4c~.c
@@ -0,0 +1,176 @@
+// tabread4c~
+// can replace tabread4c~
+// most of this code comes from pd. just the interpolation shematic is diferent.
+
+
+/*
+This software is copyrighted by Miller Puckette and others. The following
+terms (the "Standard Improved BSD License") apply to all files associated with
+the software unless explicitly disclaimed in individual files:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+3. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// Cyrille Henry 06 2008
+
+#include "m_pd.h"
+
+/******************** tabread4c~ ***********************/
+
+static t_class *tabread4c_tilde_class;
+
+typedef struct _tabread4c_tilde
+{
+ t_object x_obj;
+ int x_npoints;
+ t_word *x_vec;
+ t_symbol *x_arrayname;
+ t_float x_f;
+} t_tabread4c_tilde;
+
+static void *tabread4c_tilde_new(t_symbol *s)
+{
+ t_tabread4c_tilde *x = (t_tabread4c_tilde *)pd_new(tabread4c_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 *tabread4c_tilde_perform(t_int *w)
+{
+ t_tabread4c_tilde *x = (t_tabread4c_tilde *)(w[1]);
+ t_sample *in = (t_sample *)(w[2]);
+ t_sample *out = (t_sample *)(w[3]);
+ int n = (int)(w[4]);
+ int maxindex;
+ t_word *buf = x->x_vec, *wp;
+ int i;
+ double a3,a1,a2; // CH
+
+ maxindex = x->x_npoints - 3;
+
+ if (!buf) goto zero;
+
+#if 0 /* test for spam -- I'm not ready to deal with this */
+ for (i = 0, xmax = 0, xmin = maxindex, fp = in1; i < n; i++, fp++)
+ {
+ t_sample f = *in1;
+ if (f < xmin) xmin = f;
+ else if (f > xmax) xmax = f;
+ }
+ if (xmax < xmin + x->c_maxextent) xmax = xmin + x->c_maxextent;
+ for (i = 0, splitlo = xmin+ x->c_maxextent, splithi = xmax - x->c_maxextent,
+ fp = in1; i < n; i++, fp++)
+ {
+ t_sample f = *in1;
+ if (f > splitlo && f < splithi) goto zero;
+ }
+#endif
+
+ for (i = 0; i < n; i++)
+ {
+ t_sample findex = *in++;
+ int index = findex;
+ t_sample frac, a, b, c, d, cminusb;
+ static int count;
+ if (index < 1)
+ index = 1, frac = 0;
+ else if (index > maxindex)
+ index = maxindex, frac = 1;
+ else frac = findex - index;
+ wp = buf + index;
+ a = wp[-1].w_float;
+ b = wp[0].w_float;
+ c = wp[1].w_float;
+ d = wp[2].w_float;
+ /* if (!i && !(count++ & 1023))
+ post("fp = %lx, shit = %lx, b = %f", fp, buf->b_shit, b); */
+// cminusb = c-b;
+// *out++ = b + frac * (
+// cminusb - 0.1666667f * (1.-frac) * (
+// (d - a - 3.0f * cminusb) * frac + (d + 2.0f*a - 3.0f*b)
+// CH
+ // 4-point, 3rd-order Hermite (x-form)
+ a1 = 0.5f * (c - a);
+ a2 = a - 2.5 * b + 2.f * c - 0.5f * d;
+ a3 = 0.5f * (d - a) + 1.5f * (b - c);
+
+ *out++ = ((a3 * frac + a2) * frac + a1) * frac + b;
+ }
+ return (w+5);
+ zero:
+ while (n--) *out++ = 0;
+
+ return (w+5);
+}
+
+void tabread4c_tilde_set(t_tabread4c_tilde *x, t_symbol *s)
+{
+ t_garray *a;
+
+ x->x_arrayname = s;
+ if (!(a = (t_garray *)pd_findbyclass(x->x_arrayname, garray_class)))
+ {
+ if (*s->s_name)
+ pd_error(x, "tabread4c~: %s: no such array", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else if (!garray_getfloatwords(a, &x->x_npoints, &x->x_vec))
+ {
+ pd_error(x, "%s: bad template for tabread4c~", x->x_arrayname->s_name);
+ x->x_vec = 0;
+ }
+ else garray_usedindsp(a);
+}
+
+static void tabread4c_tilde_dsp(t_tabread4c_tilde *x, t_signal **sp)
+{
+ tabread4c_tilde_set(x, x->x_arrayname);
+
+ dsp_add(tabread4c_tilde_perform, 4, x,
+ sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+
+}
+
+static void tabread4c_tilde_free(t_tabread4c_tilde *x)
+{
+}
+
+void tabread4c_tilde_setup(void)
+{
+ tabread4c_tilde_class = class_new(gensym("tabread4c~"),
+ (t_newmethod)tabread4c_tilde_new, (t_method)tabread4c_tilde_free,
+ sizeof(t_tabread4c_tilde), 0, A_DEFSYM, 0);
+ CLASS_MAINSIGNALIN(tabread4c_tilde_class, t_tabread4c_tilde, x_f);
+ class_addmethod(tabread4c_tilde_class, (t_method)tabread4c_tilde_dsp,
+ gensym("dsp"), 0);
+ class_addmethod(tabread4c_tilde_class, (t_method)tabread4c_tilde_set,
+ gensym("set"), A_SYMBOL, 0);
+}
diff --git a/nusmuk-utils/LICENSE.txt b/nusmuk-utils/LICENSE.txt
new file mode 100644
index 0000000..fa0bef4
--- /dev/null
+++ b/nusmuk-utils/LICENSE.txt
@@ -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/nusmuk-utils/Makefile b/nusmuk-utils/Makefile
new file mode 100644
index 0000000..aa5f728
--- /dev/null
+++ b/nusmuk-utils/Makefile
@@ -0,0 +1,303 @@
+## Pd library template version 1.0.5
+# For instructions on how to use this template, see:
+# http://puredata.info/docs/developer/MakefileTemplate
+LIBRARY_NAME = nusmuk-utils
+
+# add your .c source files, one object per file, to the SOURCES
+# variable, help files will be included automatically
+SOURCES = line3.c pbank.c
+
+# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
+# be included automatically
+PDOBJECTS = pps.pd between.pd many_bang.pd rand_diff.pd filtered_random.pd randn.pd fmod.pd once.pd rnd_flow.pd lb.pd p.pd rnd_metro.pd lfo.pd
+
+# example patches and related files, in the 'examples' subfolder
+EXAMPLES = bushmeat.pbank
+
+# manuals and related files, in the 'manual' subfolder
+MANUAL =
+
+# if you want to include any other files in the source and binary tarballs,
+# list them here. This can be anything from header files, test patches,
+# documentation, etc. README.txt and LICENSE.txt are required and therefore
+# automatically included
+EXTRA_DIST = common.h pbank.h
+
+
+
+#------------------------------------------------------------------------------#
+#
+# things you might need to edit if you are using other C libraries
+#
+#------------------------------------------------------------------------------#
+
+CFLAGS = -DPD -I"$(PD_INCLUDE)" -Wall -W -g
+LDFLAGS =
+LIBS =
+
+#------------------------------------------------------------------------------#
+#
+# you shouldn't need to edit anything below here, if we did it right :)
+#
+#------------------------------------------------------------------------------#
+
+# get library version from meta file
+LIBRARY_VERSION = $(shell sed -n 's|^\#X text [0-9][0-9]* [0-9][0-9]* VERSION \(.*\);|\1|p' $(LIBRARY_NAME)-meta.pd)
+
+CFLAGS += -DVERSION='"$(LIBRARY_VERSION)"'
+
+PD_INCLUDE = $(PD_PATH)/include
+# where to install the library, overridden below depending on platform
+prefix = /usr/local
+libdir = $(prefix)/lib
+pkglibdir = $(libdir)/pd-externals
+objectsdir = $(pkglibdir)
+
+INSTALL = install
+INSTALL_PROGRAM = $(INSTALL) -p -m 644
+INSTALL_DATA = $(INSTALL) -p -m 644
+INSTALL_DIR = $(INSTALL) -p -m 755 -d
+
+ALLSOURCES := $(SOURCES) $(SOURCES_android) $(SOURCES_cygwin) $(SOURCES_macosx) \
+ $(SOURCES_iphoneos) $(SOURCES_linux) $(SOURCES_windows)
+
+DISTDIR=$(LIBRARY_NAME)-$(LIBRARY_VERSION)
+ORIGDIR=pd-$(LIBRARY_NAME:~=)_$(LIBRARY_VERSION)
+
+UNAME := $(shell uname -s)
+ifeq ($(UNAME),Darwin)
+ CPU := $(shell uname -p)
+ ifeq ($(CPU),arm) # iPhone/iPod Touch
+ SOURCES += $(SOURCES_iphoneos)
+ EXTENSION = pd_darwin
+ OS = iphoneos
+ PD_PATH = /Applications/Pd-extended.app/Contents/Resources
+ IPHONE_BASE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin
+ CC=$(IPHONE_BASE)/gcc
+ CPP=$(IPHONE_BASE)/cpp
+ CXX=$(IPHONE_BASE)/g++
+ ISYSROOT = -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk
+ IPHONE_CFLAGS = -miphoneos-version-min=3.0 $(ISYSROOT) -arch armv6
+ OPT_CFLAGS = -fast -funroll-loops -fomit-frame-pointer
+ CFLAGS := $(IPHONE_CFLAGS) $(OPT_CFLAGS) $(CFLAGS)
+ LDFLAGS += -arch armv6 -bundle -undefined dynamic_lookup $(ISYSROOT)
+ LIBS += -lc
+ STRIP = strip -x
+ DISTBINDIR=$(DISTDIR)-$(OS)
+ else # Mac OS X
+ SOURCES += $(SOURCES_macosx)
+ EXTENSION = pd_darwin
+ OS = macosx
+ PD_PATH = /Applications/Pd-extended.app/Contents/Resources
+ OPT_CFLAGS = -ftree-vectorize -ftree-vectorizer-verbose=2 -fast
+# build universal 32-bit on 10.4 and 32/64 on newer
+ ifeq ($(shell uname -r | sed 's|\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*|\1|'), 8)
+ FAT_FLAGS = -arch ppc -arch i386 -mmacosx-version-min=10.4
+ else
+ FAT_FLAGS = -arch ppc -arch i386 -arch x86_64 -mmacosx-version-min=10.4
+ SOURCES += $(SOURCES_iphoneos)
+ endif
+ CFLAGS += $(FAT_FLAGS) -fPIC -I/sw/include
+ LDFLAGS += $(FAT_FLAGS) -bundle -undefined dynamic_lookup -L/sw/lib
+ # if the 'pd' binary exists, check the linking against it to aid with stripping
+ LDFLAGS += $(shell test -e $(PD_PATH)/bin/pd && echo -bundle_loader $(PD_PATH)/bin/pd)
+ LIBS += -lc
+ STRIP = strip -x
+ DISTBINDIR=$(DISTDIR)-$(OS)
+# install into ~/Library/Pd on Mac OS X since /usr/local isn't used much
+ pkglibdir=$(HOME)/Library/Pd
+ endif
+endif
+ifeq ($(UNAME),Linux)
+ CPU := $(shell uname -m)
+ SOURCES += $(SOURCES_linux)
+ EXTENSION = pd_linux
+ OS = linux
+ PD_PATH = /usr
+ OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+ CFLAGS += -fPIC
+ LDFLAGS += -Wl,--export-dynamic -shared -fPIC
+ LIBS += -lc
+ STRIP = strip --strip-unneeded -R .note -R .comment
+ DISTBINDIR=$(DISTDIR)-$(OS)-$(shell uname -m)
+endif
+ifeq (CYGWIN,$(findstring CYGWIN,$(UNAME)))
+ CPU := $(shell uname -m)
+ SOURCES += $(SOURCES_cygwin)
+ EXTENSION = dll
+ OS = cygwin
+ PD_PATH = $(cygpath $(PROGRAMFILES))/pd
+ OPT_CFLAGS = -O6 -funroll-loops -fomit-frame-pointer
+ CFLAGS +=
+ LDFLAGS += -Wl,--export-dynamic -shared -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin"
+ LIBS += -lc -lpd
+ STRIP = strip --strip-unneeded -R .note -R .comment
+ DISTBINDIR=$(DISTDIR)-$(OS)
+endif
+ifeq (MINGW,$(findstring MINGW,$(UNAME)))
+ CPU := $(shell uname -m)
+ SOURCES += $(SOURCES_windows)
+ EXTENSION = dll
+ OS = windows
+ PD_PATH = $(shell cd "$(PROGRAMFILES)"/pd && pwd)
+ OPT_CFLAGS = -O3 -funroll-loops -fomit-frame-pointer
+ CFLAGS += -mms-bitfields
+ LDFLAGS += -s -shared -Wl,--enable-auto-import
+ LIBS += -L"$(PD_PATH)/src" -L"$(PD_PATH)/bin" -L"$(PD_PATH)/obj" -lpd -lwsock32 -lkernel32 -luser32 -lgdi32
+ STRIP = strip --strip-unneeded -R .note -R .comment
+ DISTBINDIR=$(DISTDIR)-$(OS)
+endif
+
+# in case somebody manually set the HELPPATCHES above
+HELPPATCHES ?= $(SOURCES:.c=-help.pd) $(PDOBJECTS:.pd=-help.pd)
+
+CFLAGS += $(OPT_CFLAGS)
+
+
+.PHONY = install libdir_install single_install install-doc install-exec install-examples install-manual clean dist etags $(LIBRARY_NAME)
+
+all: $(SOURCES:.c=.$(EXTENSION))
+
+%.o: %.c
+ $(CC) $(CFLAGS) -o "$*.o" -c "$*.c"
+
+%.$(EXTENSION): %.o
+ $(CC) $(LDFLAGS) -o "$*.$(EXTENSION)" "$*.o" $(LIBS)
+ chmod a-x "$*.$(EXTENSION)"
+
+# this links everything into a single binary file
+$(LIBRARY_NAME): $(SOURCES:.c=.o) $(LIBRARY_NAME).o
+ $(CC) $(LDFLAGS) -o $(LIBRARY_NAME).$(EXTENSION) $(SOURCES:.c=.o) $(LIBRARY_NAME).o $(LIBS)
+ chmod a-x $(LIBRARY_NAME).$(EXTENSION)
+
+install: libdir_install
+
+# The meta and help files are explicitly installed to make sure they are
+# actually there. Those files are not optional, then need to be there.
+libdir_install: $(SOURCES:.c=.$(EXTENSION)) install-doc install-examples install-manual
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd \
+ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ test -z "$(strip $(SOURCES))" || (\
+ $(INSTALL_PROGRAM) $(SOURCES:.c=.$(EXTENSION)) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME) && \
+ $(STRIP) $(addprefix $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/,$(SOURCES:.c=.$(EXTENSION))))
+ test -z "$(strip $(PDOBJECTS))" || \
+ $(INSTALL_DATA) $(PDOBJECTS) \
+ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+
+# install library linked as single binary
+single_install: $(LIBRARY_NAME) install-doc install-exec
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(INSTALL_PROGRAM) $(LIBRARY_NAME).$(EXTENSION) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(STRIP) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/$(LIBRARY_NAME).$(EXTENSION)
+
+install-doc:
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ test -z "$(strip $(SOURCES) $(PDOBJECTS))" || \
+ $(INSTALL_DATA) $(HELPPATCHES) \
+ $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)
+ $(INSTALL_DATA) README.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/README.txt
+ $(INSTALL_DATA) LICENSE.txt $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/LICENSE.txt
+
+install-examples:
+ test -z "$(strip $(EXAMPLES))" || \
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples && \
+ for file in $(EXAMPLES); do \
+ $(INSTALL_DATA) examples/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/examples; \
+ done
+
+install-manual:
+ test -z "$(strip $(MANUAL))" || \
+ $(INSTALL_DIR) $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual && \
+ for file in $(MANUAL); do \
+ $(INSTALL_DATA) manual/$$file $(DESTDIR)$(objectsdir)/$(LIBRARY_NAME)/manual; \
+ done
+
+
+clean:
+ -rm -f -- $(SOURCES:.c=.o) $(SOURCES_LIB:.c=.o)
+ -rm -f -- $(SOURCES:.c=.$(EXTENSION))
+ -rm -f -- $(LIBRARY_NAME).o
+ -rm -f -- $(LIBRARY_NAME).$(EXTENSION)
+
+distclean: clean
+ -rm -f -- $(DISTBINDIR).tar.gz
+ -rm -rf -- $(DISTBINDIR)
+ -rm -f -- $(DISTDIR).tar.gz
+ -rm -rf -- $(DISTDIR)
+ -rm -f -- $(ORIGDIR).tar.gz
+ -rm -rf -- $(ORIGDIR)
+
+
+$(DISTBINDIR):
+ $(INSTALL_DIR) $(DISTBINDIR)
+
+libdir: all $(DISTBINDIR)
+ $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTBINDIR)
+ $(INSTALL_DATA) $(SOURCES) $(DISTBINDIR)
+ $(INSTALL_DATA) $(HELPPATCHES) $(DISTBINDIR)
+ test -z "$(strip $(EXTRA_DIST))" || \
+ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTBINDIR)
+# tar --exclude-vcs -czpf $(DISTBINDIR).tar.gz $(DISTBINDIR)
+
+$(DISTDIR):
+ $(INSTALL_DIR) $(DISTDIR)
+
+$(ORIGDIR):
+ $(INSTALL_DIR) $(ORIGDIR)
+
+dist: $(DISTDIR)
+ $(INSTALL_DATA) Makefile $(DISTDIR)
+ $(INSTALL_DATA) README.txt $(DISTDIR)
+ $(INSTALL_DATA) LICENSE.txt $(DISTDIR)
+ $(INSTALL_DATA) $(LIBRARY_NAME)-meta.pd $(DISTDIR)
+ test -z "$(strip $(ALLSOURCES))" || \
+ $(INSTALL_DATA) $(ALLSOURCES) $(DISTDIR)
+ test -z "$(strip $(PDOBJECTS))" || \
+ $(INSTALL_DATA) $(PDOBJECTS) $(DISTDIR)
+ test -z "$(strip $(HELPPATCHES))" || \
+ $(INSTALL_DATA) $(HELPPATCHES) $(DISTDIR)
+ test -z "$(strip $(EXTRA_DIST))" || \
+ $(INSTALL_DATA) $(EXTRA_DIST) $(DISTDIR)
+ test -z "$(strip $(EXAMPLES))" || \
+ $(INSTALL_DIR) $(DISTDIR)/examples && \
+ for file in $(EXAMPLES); do \
+ $(INSTALL_DATA) examples/$$file $(DISTDIR)/examples; \
+ done
+ test -z "$(strip $(MANUAL))" || \
+ $(INSTALL_DIR) $(DISTDIR)/manual && \
+ for file in $(MANUAL); do \
+ $(INSTALL_DATA) manual/$$file $(DISTDIR)/manual; \
+ done
+ tar --exclude-vcs -czpf $(DISTDIR).tar.gz $(DISTDIR)
+
+# make a Debian source package
+dpkg-source:
+ debclean
+ make distclean dist
+ mv $(DISTDIR) $(ORIGDIR)
+ tar --exclude-vcs -czpf ../$(ORIGDIR).orig.tar.gz $(ORIGDIR)
+ rm -f -- $(DISTDIR).tar.gz
+ rm -rf -- $(DISTDIR) $(ORIGDIR)
+ cd .. && dpkg-source -b $(LIBRARY_NAME)
+
+etags:
+ etags *.h $(SOURCES) ../../pd/src/*.[ch] /usr/include/*.h /usr/include/*/*.h
+
+showsetup:
+ @echo "CFLAGS: $(CFLAGS)"
+ @echo "LDFLAGS: $(LDFLAGS)"
+ @echo "LIBS: $(LIBS)"
+ @echo "PD_INCLUDE: $(PD_INCLUDE)"
+ @echo "PD_PATH: $(PD_PATH)"
+ @echo "objectsdir: $(objectsdir)"
+ @echo "LIBRARY_NAME: $(LIBRARY_NAME)"
+ @echo "LIBRARY_VERSION: $(LIBRARY_VERSION)"
+ @echo "SOURCES: $(SOURCES)"
+ @echo "PDOBJECTS: $(PDOBJECTS)"
+ @echo "ALLSOURCES: $(ALLSOURCES)"
+ @echo "UNAME: $(UNAME)"
+ @echo "CPU: $(CPU)"
+ @echo "pkglibdir: $(pkglibdir)"
+ @echo "DISTDIR: $(DISTDIR)"
+ @echo "ORIGDIR: $(ORIGDIR)"
diff --git a/nusmuk-utils/README.txt b/nusmuk-utils/README.txt
new file mode 100644
index 0000000..34b4486
--- /dev/null
+++ b/nusmuk-utils/README.txt
@@ -0,0 +1,8 @@
+This are a collection of usefull abstraction and that can be usefull.
+
+This lib is made by Cyrille Henry (exept pbank for zack settel), you can contact him on his webpage :
+http://www.chnry.net/ch/?001-Cyrille-Henry
+
+This lib is realese under the GNU Public License.
+
+To build it, just type make.
diff --git a/between-help.pd b/nusmuk-utils/between-help.pd
index f8dd77a..f8dd77a 100644
--- a/between-help.pd
+++ b/nusmuk-utils/between-help.pd
diff --git a/between.pd b/nusmuk-utils/between.pd
index 2ddfead..2ddfead 100644
--- a/between.pd
+++ b/nusmuk-utils/between.pd
diff --git a/nusmuk-utils/common.h b/nusmuk-utils/common.h
new file mode 100644
index 0000000..3f4a1c8
--- /dev/null
+++ b/nusmuk-utils/common.h
@@ -0,0 +1,17 @@
+/* common.h -- those things we define often */
+
+#define InRange(v,lo,hi) ((v)<=(hi)&&(v)>=(lo))
+#define MAXIUM(a,b) ((a)>(b)?(a):(b))
+#define MINIUM(a,b) ((a)<(b)?(a):(b))
+
+#define RetKey 13
+#define EnterKey 3
+#define SpaceBar 32
+#define BackSpace 8
+#define BackSlash 0x5C
+#define VertBar 0x7C
+#define Grave 0x60
+#define Tilde 0x7E
+#define TabKey 9
+#define ClearKey 27
+#define OptionSpace 202
diff --git a/nusmuk-utils/debian/changelog b/nusmuk-utils/debian/changelog
new file mode 100644
index 0000000..a533ffe
--- /dev/null
+++ b/nusmuk-utils/debian/changelog
@@ -0,0 +1,5 @@
+pd-nusmuk-utils (1-1) unstable; urgency=low
+
+ * Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>
+
+ -- Hans-Christoph Steiner <hans@eds.org> Thu, 21 Jan 2010 23:27:04 -0500
diff --git a/nusmuk-utils/debian/compat b/nusmuk-utils/debian/compat
new file mode 100644
index 0000000..7f8f011
--- /dev/null
+++ b/nusmuk-utils/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/nusmuk-utils/debian/control b/nusmuk-utils/debian/control
new file mode 100644
index 0000000..bb5aab4
--- /dev/null
+++ b/nusmuk-utils/debian/control
@@ -0,0 +1,33 @@
+Source: pd-nusmuk-utils
+Section: sound
+Priority: optional
+Maintainer: Debian Multimedia Maintainers <pkg-multimedia-maintainers@lists.alioth.debian.org>
+Uploaders: Hans-Christoph Steiner <hans@eds.org>
+Build-Depends: debhelper (>= 7.0.50~),
+ puredata
+Standards-Version: 3.9.1
+Homepage: http://puredata.info
+
+Package: pd-nusmuk-utils
+Architecture: any
+Depends: ${shlibs:Depends},
+ pd,
+ ${misc:Depends}
+Description: a random collection of usefull Pd objects by Cyrille Henry
+ This is my collection of abstraction that i always use.
+ the object included are :
+ between
+ line3
+ pps
+ filtered_random
+ many_bang
+ rand_diff
+ fmod
+ once
+ randn
+ lb
+ pbank
+ rnd_flow
+ lfo
+ p
+ rnd_metro
diff --git a/nusmuk-utils/debian/copyright b/nusmuk-utils/debian/copyright
new file mode 100644
index 0000000..6994051
--- /dev/null
+++ b/nusmuk-utils/debian/copyright
@@ -0,0 +1,23 @@
+Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?rev=135
+Name: nusmuk-utils
+Maintainer: Cyrille Henry <ch@chnry.net>
+Source: http://sourceforge.net/projects/pure-data/files/libraries/nusmuk-utils/
+
+Files: *
+Copyright: 2002-2010, Cyrille Henry <ch@chnry.net>
+License: GPL-2+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this package; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+X-Comment: On Debian systems, the complete text of the GNU General
+ Public License can be found in `/usr/share/common-licenses/GPL-2'.
diff --git a/nusmuk-utils/debian/gbp.conf b/nusmuk-utils/debian/gbp.conf
new file mode 100644
index 0000000..ae1dc36
--- /dev/null
+++ b/nusmuk-utils/debian/gbp.conf
@@ -0,0 +1,7 @@
+[DEFAULT]
+upstream-branch = upstream
+debian-branch = master
+upstream-tag = upstream/%(version)s
+debian-tag = debian/%(version)s
+pristine-tar = True
+sign-tags = True
diff --git a/nusmuk-utils/debian/links b/nusmuk-utils/debian/links
new file mode 100644
index 0000000..3d032a6
--- /dev/null
+++ b/nusmuk-utils/debian/links
@@ -0,0 +1,3 @@
+usr/lib/pd/extra/nusmuk-utils/README.txt usr/share/doc/pd-nusmuk-utils/README
+usr/lib/pd/extra/nusmuk-utils/examples usr/share/doc/pd-nusmuk-utils/examples
+usr/share/common-licenses/GPL-2 usr/lib/pd/extra/nusmuk-utils/LICENSE.txt
diff --git a/nusmuk-utils/debian/rules b/nusmuk-utils/debian/rules
new file mode 100755
index 0000000..b6061f3
--- /dev/null
+++ b/nusmuk-utils/debian/rules
@@ -0,0 +1,17 @@
+#!/usr/bin/make -f
+
+LIBRARY_NAME = nusmuk-utils
+PACKAGE = pd-$(LIBRARY_NAME)
+pkglibdir = /usr/lib/pd/extra
+
+%:
+ dh $@ --buildsystem=makefile
+
+override_dh_auto_install:
+ dh_auto_install -- prefix=/usr pkglibdir=$(pkglibdir)
+# replace license file with link to the Debian license file
+ rm -f -- $(CURDIR)/debian/$(PACKAGE)/$(pkglibdir)/$(LIBRARY_NAME)/LICENSE.txt
+
+override_dh_shlibdeps:
+ dpkg-shlibdeps $(CURDIR)/debian/$(PACKAGE)$(pkglibdir)/$(LIBRARY_NAME)/*.pd_linux \
+ -T$(CURDIR)/debian/$(PACKAGE).substvars
diff --git a/nusmuk-utils/debian/source/format b/nusmuk-utils/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/nusmuk-utils/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/nusmuk-utils/debian/watch b/nusmuk-utils/debian/watch
new file mode 100644
index 0000000..bc401ad
--- /dev/null
+++ b/nusmuk-utils/debian/watch
@@ -0,0 +1,2 @@
+version=3
+http://sf.net/pure-data/nusmuk-utils-(.*)\.tar\.gz
diff --git a/nusmuk-utils/examples/bushmeat.pbank b/nusmuk-utils/examples/bushmeat.pbank
new file mode 100644
index 0000000..1b83547
--- /dev/null
+++ b/nusmuk-utils/examples/bushmeat.pbank
@@ -0,0 +1,19 @@
+pbank 4 12,
+ 166 1.10236 236 94,
+ 874 0.629921 7086 85,
+ 2286
+0.629921 4251 85,
+ 285.433 1.43937 2792.13 71,
+ 585.61 1.48661
+2886.93 75,
+ 165.362 3.46457 7414.57 75,
+ 5935.83 0.209449 9764.96
+75,
+ 403 0.472441 9921 75,
+ 403 0.472441 6692 75,
+ 403 0.472441
+1811 75,
+ CarrierFQ ModulatorFQ FMindex Gain,
+ PARAM1 PARAM2 PARAM3
+PARAM4,
+ \ No newline at end of file
diff --git a/nusmuk-utils/filtered_random-help.pd b/nusmuk-utils/filtered_random-help.pd
new file mode 100644
index 0000000..19e726b
--- /dev/null
+++ b/nusmuk-utils/filtered_random-help.pd
@@ -0,0 +1,47 @@
+#N canvas 374 22 791 605 10;
+#X obj 84 102 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 240 1;
+#X obj 85 363 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 0 1;
+#X obj 111 362 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 12033 1;
+#X obj 187 362 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 5750 1;
+#X obj 214 362 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 6142 1;
+#X obj 283 362 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 126 1;
+#X obj 310 362 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 7655 1;
+#X obj 85 244 filtered_random 127 0 0.3 20 0;
+#X obj 84 79 filtered_random 127 0 0 20 0;
+#X obj 187 282 filtered_random 127 0 0 20 500;
+#X obj 310 339 filtered_random 127 0 0 20 100;
+#X obj 111 263 filtered_random 127 0 -0.3 20 0;
+#X obj 283 320 filtered_random 1000 0 0.5 20 100;
+#X floatatom 84 12 5 0 0 0 - - -;
+#X floatatom 220 12 5 0 0 0 - - -;
+#X floatatom 344 12 5 0 0 0 - - -;
+#X floatatom 470 12 5 0 0 0 - - -;
+#X floatatom 612 12 5 0 0 0 - - -;
+#X text 446 450 related to :;
+#X text 345 28 courbe (-1 1);
+#X text 470 26 metro (20 5000..);
+#X text 610 27 line (0 5000..);
+#X text 89 28 amplitude (0 1..);
+#X text 223 29 offset (0 1..);
+#X text 82 -36 generate stream of number \, based on random;
+#X obj 448 471 rnd_flow;
+#X obj 214 301 filtered_random 127 0 0 20 1500;
+#X connect 7 0 1 0;
+#X connect 8 0 0 0;
+#X connect 9 0 3 0;
+#X connect 10 0 6 0;
+#X connect 11 0 2 0;
+#X connect 12 0 5 0;
+#X connect 13 0 8 0;
+#X connect 14 0 8 1;
+#X connect 15 0 8 2;
+#X connect 16 0 8 3;
+#X connect 17 0 8 4;
+#X connect 26 0 4 0;
diff --git a/nusmuk-utils/filtered_random.pd b/nusmuk-utils/filtered_random.pd
new file mode 100644
index 0000000..028174d
--- /dev/null
+++ b/nusmuk-utils/filtered_random.pd
@@ -0,0 +1,63 @@
+#N canvas 144 268 750 421 10;
+#X obj 58 279 outlet;
+#X obj 58 259 line;
+#X obj 58 79 loadbang;
+#X msg 58 99 1;
+#X text 86 -52 amplitude (0-100);
+#X text 220 -51 offset (0-100);
+#X text 467 -54 metro (20-5000);
+#X obj 83 -71 inlet;
+#X obj 220 -71 inlet;
+#X obj 339 -71 inlet;
+#X obj 464 -71 inlet;
+#X obj 590 -71 inlet;
+#X obj 58 199 * \$1;
+#X obj 58 219 + \$2;
+#X obj 58 179 pow \$3;
+#X obj 58 239 pack f \$5;
+#X obj 464 19 moses 0;
+#X msg 464 40 20;
+#X obj 58 139 random 100000;
+#X obj 58 159 / 100000;
+#X obj 58 119 metro 20;
+#X obj 472 -21 loadbang;
+#X obj 464 -2 \$4;
+#X obj 339 112 exp;
+#X msg 371 55 2;
+#X obj 371 74 log;
+#X obj 339 93 *;
+#X obj 346 -21 loadbang;
+#X obj 339 36 t f b;
+#X obj 339 -2 \$3;
+#X text 342 -52 courbe (-1 1);
+#X text 587 -52 line (0-5000);
+#X obj 339 17 * 10;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 3 0 20 0;
+#X connect 7 0 12 1;
+#X connect 8 0 13 1;
+#X connect 9 0 29 0;
+#X connect 10 0 22 0;
+#X connect 11 0 15 1;
+#X connect 12 0 13 0;
+#X connect 13 0 15 0;
+#X connect 14 0 12 0;
+#X connect 15 0 1 0;
+#X connect 16 0 17 0;
+#X connect 16 1 20 1;
+#X connect 17 0 20 1;
+#X connect 18 0 19 0;
+#X connect 19 0 14 0;
+#X connect 20 0 18 0;
+#X connect 21 0 22 0;
+#X connect 22 0 16 0;
+#X connect 23 0 14 1;
+#X connect 24 0 25 0;
+#X connect 25 0 26 1;
+#X connect 26 0 23 0;
+#X connect 27 0 29 0;
+#X connect 28 0 26 0;
+#X connect 28 1 24 0;
+#X connect 29 0 32 0;
+#X connect 32 0 28 0;
diff --git a/nusmuk-utils/fmod-help.pd b/nusmuk-utils/fmod-help.pd
new file mode 100644
index 0000000..b1ebd3c
--- /dev/null
+++ b/nusmuk-utils/fmod-help.pd
@@ -0,0 +1,9 @@
+#N canvas 1 22 449 300 10;
+#X obj 58 100 fmod 2.34;
+#X text 97 13 float version for mod;
+#X floatatom 58 80 5 0 0 0 - - -;
+#X floatatom 109 81 5 0 0 0 - - -;
+#X floatatom 58 123 5 0 0 0 - - -;
+#X connect 0 0 4 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 1;
diff --git a/nusmuk-utils/fmod.pd b/nusmuk-utils/fmod.pd
new file mode 100644
index 0000000..b8b9dab
--- /dev/null
+++ b/nusmuk-utils/fmod.pd
@@ -0,0 +1,23 @@
+#N canvas 714 472 314 297 10;
+#X obj 52 36 inlet;
+#X obj 52 208 outlet;
+#X obj 110 36 inlet;
+#X obj 52 64 / \$1;
+#X obj 52 188 * \$1;
+#X obj 84 106 int;
+#X obj 52 84 t f f;
+#X obj 52 126 -;
+#X obj 52 146 moses 0;
+#X obj 52 167 + 1;
+#X connect 0 0 3 0;
+#X connect 2 0 3 1;
+#X connect 2 0 4 1;
+#X connect 3 0 6 0;
+#X connect 4 0 1 0;
+#X connect 5 0 7 1;
+#X connect 6 0 7 0;
+#X connect 6 1 5 0;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 8 1 4 0;
+#X connect 9 0 4 0;
diff --git a/nusmuk-utils/lb-help.pd b/nusmuk-utils/lb-help.pd
new file mode 100644
index 0000000..2469e6b
--- /dev/null
+++ b/nusmuk-utils/lb-help.pd
@@ -0,0 +1,19 @@
+#N canvas 198 102 450 300 10;
+#X obj 83 92 lb;
+#X obj 113 92 loadbang;
+#X obj 83 112 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 113 113 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 58 92 lb;
+#X obj 58 112 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 205 91 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 205 112 s lb;
+#X text 102 29 This is mostly a shortcut for loadbang;
+#X text 103 45 you can send bangs to lb;
+#X connect 0 0 2 0;
+#X connect 1 0 3 0;
+#X connect 4 0 5 0;
+#X connect 6 0 7 0;
diff --git a/nusmuk-utils/lb.pd b/nusmuk-utils/lb.pd
new file mode 100755
index 0000000..eb73036
--- /dev/null
+++ b/nusmuk-utils/lb.pd
@@ -0,0 +1,10 @@
+#N canvas 583 629 201 161 10;
+#X obj 36 86 loadbang;
+#X obj 18 17 inlet;
+#X obj 18 108 outlet;
+#X obj 33 41 r lb;
+#X obj 18 63 t b;
+#X connect 0 0 2 0;
+#X connect 1 0 4 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 0;
diff --git a/nusmuk-utils/lfo-help.pd b/nusmuk-utils/lfo-help.pd
new file mode 100644
index 0000000..658695f
--- /dev/null
+++ b/nusmuk-utils/lfo-help.pd
@@ -0,0 +1,21 @@
+#N canvas 77 355 426 472 10;
+#X floatatom 54 63 5 0 0 0 - - -;
+#X obj 54 237 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 3302 1;
+#X obj 54 188 * 127;
+#X text 93 85 creation arguments:;
+#X text 125 125 2 time grain in milliseconds;
+#X text 123 105 1 period time (ms);
+#X text 152 25 Low Frequency Modulator;
+#X text 105 63 <- time (ms);
+#X obj 54 165 lfo 2000 20 ______;
+#X obj 177 238 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 12700 1;
+#X obj 177 209 * 64;
+#X obj 177 188 + 1;
+#X connect 0 0 8 0;
+#X connect 2 0 1 0;
+#X connect 8 0 2 0;
+#X connect 8 1 11 0;
+#X connect 10 0 9 0;
+#X connect 11 0 10 0;
diff --git a/nusmuk-utils/lfo.pd b/nusmuk-utils/lfo.pd
new file mode 100644
index 0000000..2bb7330
--- /dev/null
+++ b/nusmuk-utils/lfo.pd
@@ -0,0 +1,61 @@
+#N canvas 193 96 408 667 10;
+#X obj 32 44 inlet;
+#X obj 200 41 loadbang;
+#X msg 200 95 1;
+#X obj 200 213 metro;
+#X obj 230 97 \$2;
+#X obj 230 125 sel 0;
+#X msg 230 152 20;
+#X obj 200 67 t b b;
+#X obj 200 636 outlet;
+#X obj 230 185 f;
+#X obj 58 258 /;
+#X obj 271 40 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 58 284 t b f;
+#X msg 58 232 1 \$1;
+#X obj 32 339 *;
+#X obj 32 317 \$1;
+#X obj 200 555 -;
+#X obj 230 532 i;
+#X obj 32 383 /;
+#X msg 32 362 1 \$1;
+#X obj 200 508 t f f;
+#X obj 276 634 outlet;
+#X obj 276 589 * 3.14159;
+#X obj 276 613 sin;
+#X obj 276 568 * 2;
+#X obj 200 451 f;
+#X obj 200 480 +;
+#X connect 0 0 15 0;
+#X connect 1 0 7 0;
+#X connect 2 0 3 0;
+#X connect 3 0 25 0;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 5 1 9 0;
+#X connect 6 0 9 0;
+#X connect 7 0 2 0;
+#X connect 7 1 4 0;
+#X connect 9 0 3 1;
+#X connect 9 0 13 0;
+#X connect 10 0 12 0;
+#X connect 11 0 7 0;
+#X connect 12 0 15 0;
+#X connect 12 1 14 1;
+#X connect 13 0 10 0;
+#X connect 14 0 19 0;
+#X connect 15 0 14 0;
+#X connect 16 0 8 0;
+#X connect 16 0 24 0;
+#X connect 16 0 25 1;
+#X connect 17 0 16 1;
+#X connect 18 0 26 1;
+#X connect 19 0 18 0;
+#X connect 20 0 16 0;
+#X connect 20 1 17 0;
+#X connect 22 0 23 0;
+#X connect 23 0 21 0;
+#X connect 24 0 22 0;
+#X connect 25 0 26 0;
+#X connect 26 0 20 0;
diff --git a/nusmuk-utils/line3-help.pd b/nusmuk-utils/line3-help.pd
new file mode 100644
index 0000000..77a9a5d
--- /dev/null
+++ b/nusmuk-utils/line3-help.pd
@@ -0,0 +1,61 @@
+#N canvas 256 172 683 616 10;
+#X obj 33 279 line3;
+#X msg 32 44 0 1000;
+#X msg 43 66 127 1000;
+#N canvas 0 0 450 300 graph3 0;
+#X array line3 100 float 2;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 306 174 graph;
+#X obj 33 394 t f b;
+#X obj 63 440 + 1;
+#X obj 63 418 f;
+#X obj 63 466 % 100;
+#X obj 62 163 random 127;
+#X obj 62 114 metro 300;
+#X msg 62 186 \$1 1000;
+#X obj 62 91 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 149 279 line;
+#N canvas 0 0 450 300 graph1 0;
+#X array line 100 float 2;
+#X coords 0 1 99 -1 200 140 1;
+#X restore 306 314 graph;
+#X obj 33 525 tabwrite line3;
+#X obj 149 526 tabwrite line;
+#X text 290 7 line3;
+#N canvas 0 0 450 300 nothing 0;
+#X obj 29 22 inlet;
+#X obj 29 52 outlet;
+#X connect 0 0 1 0;
+#X restore 33 218 pd nothing;
+#X obj 80 139 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X text 168 40 line3 is compatible with line \, but the transition
+is made with a 3d order polynome. coeficiant of this polynome are adjusted
+to have the continuity of the output variation speed.;
+#X obj 33 317 - 63.5;
+#X obj 149 318 - 63.5;
+#X obj 149 342 / 63.5;
+#X obj 33 340 / 63.5;
+#X connect 0 0 20 0;
+#X connect 1 0 17 0;
+#X connect 2 0 17 0;
+#X connect 4 0 14 0;
+#X connect 4 1 6 0;
+#X connect 5 0 7 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 7 0 14 1;
+#X connect 7 0 15 1;
+#X connect 8 0 10 0;
+#X connect 9 0 8 0;
+#X connect 10 0 17 0;
+#X connect 11 0 9 0;
+#X connect 12 0 21 0;
+#X connect 17 0 0 0;
+#X connect 17 0 12 0;
+#X connect 18 0 8 0;
+#X connect 20 0 23 0;
+#X connect 21 0 22 0;
+#X connect 22 0 15 0;
+#X connect 23 0 4 0;
diff --git a/nusmuk-utils/line3.c b/nusmuk-utils/line3.c
new file mode 100644
index 0000000..25dcd8e
--- /dev/null
+++ b/nusmuk-utils/line3.c
@@ -0,0 +1,177 @@
+// line3
+// based on miller puckette line object (so licence / copyright comes from pure data)
+// compatible with line, but with a 3d order polynome.
+// there is continuity of the variation speed
+
+/*
+This software is copyrighted by Miller Puckette and others. The following
+terms (the "Standard Improved BSD License") apply to all files associated with
+the software unless explicitly disclaimed in individual files:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+3. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// Cyrille Henry 01 2005
+
+
+#include "m_pd.h"
+
+static t_class *line3_class;
+
+typedef struct _line3
+{
+ t_object x_obj;
+ t_clock *x_clock;
+ double x_targettime;
+ t_float x_targetval,setderiv, a, b;
+ double x_prevtime;
+ t_float x_setval;
+ int x_gotinlet;
+ t_float x_grain;
+ double x_1overtimediff;
+ double x_in1val;
+} t_line3;
+
+void line3_tick(t_line3 *x)
+{
+ double tmp, t;
+ double timenow = clock_getsystime();
+ double msectogo = - clock_gettimesince(x->x_targettime);
+ if (msectogo < 1E-9)
+ {
+ outlet_float(x->x_obj.ob_outlet, x->x_targetval);
+ }
+ else
+ {
+ t = (timenow - x->x_prevtime);
+
+ tmp = x->a * t * t * t + x->b * t * t + x->setderiv * t + x->x_setval;
+
+ outlet_float(x->x_obj.ob_outlet, tmp);
+ clock_delay(x->x_clock, (x->x_grain > msectogo ? msectogo : x->x_grain));
+ }
+}
+
+void line3_float(t_line3 *x, t_float f)
+{
+ double timenow = clock_getsystime();
+ if (x->x_gotinlet && x->x_in1val > 0)
+ {
+ if (timenow >= x->x_targettime)
+ {
+ x->x_setval = x->x_targetval;
+ x->setderiv = 0;
+ }
+ else
+ {
+ x->x_setval = x->a * (timenow - x->x_prevtime) * (timenow - x->x_prevtime) * (timenow - x->x_prevtime) + x->b * (timenow - x->x_prevtime) * (timenow - x->x_prevtime) + x->setderiv * (timenow - x->x_prevtime) + x->x_setval;
+
+ x->setderiv = 3 * x->a * (timenow - x->x_prevtime) * (timenow - x->x_prevtime) + 2 * x->b * (timenow - x->x_prevtime) + x->setderiv;
+
+ }
+ x->x_prevtime = timenow;
+ x->x_targettime = clock_getsystimeafter(x->x_in1val);
+ x->x_targetval = f;
+ x->x_1overtimediff = 1./ (x->x_targettime - timenow);
+
+ x->a = -2 * (x->x_targetval - x->x_setval) * x->x_1overtimediff;
+ x->a += x->setderiv;
+ x->a *= x->x_1overtimediff;
+ x->a *= x->x_1overtimediff;
+
+ x->b = 3 * (x->x_targetval - x->x_setval) * x->x_1overtimediff;
+ x->b -= 2 * x->setderiv;
+ x->b *= x->x_1overtimediff;
+
+ line3_tick(x);
+ x->x_gotinlet = 0;
+
+ clock_delay(x->x_clock, (x->x_grain > x->x_in1val ? x->x_in1val : x->x_grain));
+ }
+ else
+ {
+ clock_unset(x->x_clock);
+ x->x_targetval = x->x_setval = f;
+ x->x_targettime = timenow;
+ outlet_float(x->x_obj.ob_outlet, f);
+ }
+ x->x_gotinlet = 0;
+}
+
+void line3_ft1(t_line3 *x, t_floatarg g)
+{
+ x->x_in1val = g;
+ x->x_gotinlet = 1;
+}
+
+void line3_stop(t_line3 *x)
+{
+ x->x_targetval = x->x_setval;
+ clock_unset(x->x_clock);
+}
+
+void line3_set(t_line3 *x, t_floatarg f)
+{
+ clock_unset(x->x_clock);
+ x->x_targetval = x->x_setval = f;
+ x->setderiv = 0;
+}
+
+void line3_free(t_line3 *x)
+{
+ clock_free(x->x_clock);
+}
+
+void *line3_new(t_floatarg f, t_floatarg grain)
+{
+ t_line3 *x = (t_line3 *)pd_new(line3_class);
+ x->x_targetval = x->x_setval = f;
+ x->x_gotinlet = 0;
+ x->setderiv = 0;
+ x->x_1overtimediff = 1;
+ x->x_clock = clock_new(x, (t_method)line3_tick);
+ x->x_targettime = x->x_prevtime = clock_getsystime();
+ if (grain <= 0) grain = 20;
+ x->x_grain = grain;
+ outlet_new(&x->x_obj, gensym("float"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
+ return (x);
+}
+
+void line3_setup(void)
+{
+ line3_class = class_new(gensym("line3"), (t_newmethod)line3_new,
+ (t_method)line3_free, sizeof(t_line3), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
+ class_addmethod(line3_class, (t_method)line3_ft1,
+ gensym("ft1"), A_FLOAT, 0);
+ class_addmethod(line3_class, (t_method)line3_stop,
+ gensym("stop"), 0);
+ class_addmethod(line3_class, (t_method)line3_set,
+ gensym("set"), A_FLOAT, 0);
+ class_addfloat(line3_class, (t_method)line3_float);
+}
diff --git a/many_bang-help.pd b/nusmuk-utils/many_bang-help.pd
index d296adb..d296adb 100644
--- a/many_bang-help.pd
+++ b/nusmuk-utils/many_bang-help.pd
diff --git a/many_bang.pd b/nusmuk-utils/many_bang.pd
index d2bf173..d2bf173 100644
--- a/many_bang.pd
+++ b/nusmuk-utils/many_bang.pd
diff --git a/nusmuk-utils/nusmuk-utils-meta.pd b/nusmuk-utils/nusmuk-utils-meta.pd
new file mode 100644
index 0000000..dc94aca
--- /dev/null
+++ b/nusmuk-utils/nusmuk-utils-meta.pd
@@ -0,0 +1,7 @@
+#N canvas 272 88 496 221 10;
+#X text 12 116 LICENSE GNU GPL;
+#X text 10 39 AUTHOR Cyrille Henry;
+#X text 10 19 NAME nusmuk-utils;
+#X text 11 136 VERSION 1;
+#X text 10 58 DESCRIPTION This objects' collection is based on abstractions
+and externals. they provide usfull stuff for pd.;
diff --git a/nusmuk-utils/once-help.pd b/nusmuk-utils/once-help.pd
new file mode 100644
index 0000000..8838878
--- /dev/null
+++ b/nusmuk-utils/once-help.pd
@@ -0,0 +1,13 @@
+#N canvas 153 103 450 300 10;
+#X obj 84 130 once;
+#X obj 84 61 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X obj 109 100 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 84 166 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1
+-1;
+#X text 129 100 reset;
+#X text 120 15 once pass only 1 bang;
+#X connect 0 0 3 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 1;
diff --git a/nusmuk-utils/once.pd b/nusmuk-utils/once.pd
new file mode 100644
index 0000000..7fe3c60
--- /dev/null
+++ b/nusmuk-utils/once.pd
@@ -0,0 +1,15 @@
+#N canvas 818 139 431 322 10;
+#X obj 24 26 inlet;
+#X obj 24 168 outlet;
+#X msg 92 49 1;
+#X msg 115 79 0;
+#X obj 24 86 spigot 1;
+#X obj 24 119 t a b;
+#X obj 92 26 inlet;
+#X connect 0 0 4 0;
+#X connect 2 0 4 1;
+#X connect 3 0 4 1;
+#X connect 4 0 5 0;
+#X connect 5 0 1 0;
+#X connect 5 1 3 0;
+#X connect 6 0 2 0;
diff --git a/nusmuk-utils/p-help.pd b/nusmuk-utils/p-help.pd
new file mode 100644
index 0000000..620f09e
--- /dev/null
+++ b/nusmuk-utils/p-help.pd
@@ -0,0 +1,8 @@
+#N canvas 0 0 450 300 10;
+#X obj 103 97 p;
+#X floatatom 103 76 5 0 0 0 - - -;
+#X floatatom 145 77 5 0 0 0 - - -;
+#X obj 145 98 p foo;
+#X text 100 20 p is a shortcut to print;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
diff --git a/nusmuk-utils/p.pd b/nusmuk-utils/p.pd
new file mode 100755
index 0000000..20b3fa9
--- /dev/null
+++ b/nusmuk-utils/p.pd
@@ -0,0 +1,4 @@
+#N canvas 0 0 108 111 12;
+#X obj 9 10 inlet;
+#X obj 9 38 print \$1;
+#X connect 0 0 1 0;
diff --git a/nusmuk-utils/pbank-help.pd b/nusmuk-utils/pbank-help.pd
new file mode 100755
index 0000000..21839ef
--- /dev/null
+++ b/nusmuk-utils/pbank-help.pd
@@ -0,0 +1,562 @@
+#N canvas 212 22 1013 667 10;
+#X msg 487 31 set 1 2 100 3.1415 shupsh;
+#X msg 500 59 0 1 1.234;
+#X text 573 59 write 1.234 to column 0 of row 1;
+#X text 672 31 set list of elements starting at column 1 in row 2;
+#X msg 513 87 0 1;
+#X text 542 87 read value at column 0 of row 1;
+#X msg 538 138 2 0 coptox;
+#X text 556 110 read value at column 2 of row 0;
+#X msg 526 110 2 0;
+#X msg 608 245 put 0 100 3.14159 shupsh;
+#X text 793 251 put list of elements starting at column 0 in edit buffer
+;
+#X text 41 -12 A 2-dimensional parameter bank for floats or symbols
+;
+#X text -19 42 args:;
+#X text -4 56 argument1 gives the number of columns (X axis): <int>
+\; argument2 gives the number of rows (Y axis): <int> \; argument3
+is the name of the pbank: <symbol>;
+#X text 66 95 The arg3 (pbank 'name') is used by pbank in two ways:
+when a patch using a pbank is loaded \, a pbank data file corresponding
+to arg3 will be searched for and loaded if found. The 'name' also allows
+other pbanks with the same name to share data -in the way that tables
+do. If these two features are not wanted \, Arg3 (the 'name') can be
+set to the empty string: "" (two quotes) - see example below-;
+#X text 616 138 write symbol "coptox" to column 2 of row 0;
+#X text 777 564 The left-hand outlet outputs lists of the form: columnNo
+<int> item <int \, float or symbol>;
+#X text 777 589 note: Do not forget that this outlet is only used by
+pbank if argument 4 undefined (omitted) -see arguments;
+#X text 40 0 note: The structure of pbank includes an additional row
+that serves as an edit buffer. - see Messages;
+#X msg 654 336 store 3;
+#X msg 625 273 recall 3;
+#X text -5 187 argument4;
+#X text 65 187 is the symbol that pbank uses when directing its output
+to receives based on this symbol: <optional symbol>;
+#X obj -7 315 pbank 4 12;
+#X text -8 330 Creates a parameter bank of 4 columns by 12 rows;
+#X text -10 378 Creates a parameter bank of 4 columns by 12 rows \,
+reading in the contents of the file name "bushmeat.pbank" \, and sharing
+data with any other pbanks with the same name;
+#X floatatom 776 777 5 0 0 0 - - -;
+#X floatatom 816 777 5 0 0 0 - - -;
+#X obj 883 742 print pbankOut;
+#X obj 776 742 route 0 1 2 3;
+#X floatatom 856 777 5 0 0 0 - - -;
+#X floatatom 896 777 5 0 0 0 - - -;
+#X obj 614 636 send toPbanks;
+#X obj 776 682 receive toPbanks;
+#X text 486 3 MESSAGES: read/write;
+#X text 587 221 MESSAGES: edit buffer;
+#X text 696 485 MESSAGES: file IO;
+#X obj 383 677 route 0 1 2 3;
+#X msg 383 707 set \$1;
+#X msg 384 768 untitled_10;
+#X msg 484 707 set \$1;
+#X msg 484 768 0;
+#X msg 577 707 set \$1;
+#X msg 577 768 0;
+#X msg 670 707 set \$1;
+#X msg 670 768 0;
+#X msg 419 623 recall 11;
+#X msg 420 602 recall 10;
+#X obj 510 388 vradio 18 1 0 10 empty empty empty 0 -6 0 8 -262144
+-1 -1 7;
+#X msg 510 574 recall \$1;
+#X obj -9 437 receive toPbanks;
+#X floatatom 397 752 5 0 0 0 - - -;
+#X floatatom 490 752 5 0 0 0 - - -;
+#X floatatom 583 752 5 0 0 0 - - -;
+#X floatatom 676 752 5 0 0 0 - - -;
+#X obj -9 573 pbank 4 12 "" wireless;
+#X obj 420 576 loadbang;
+#X obj 397 730 r wireless-0;
+#X obj 490 730 r wireless-1;
+#X obj 583 730 r wireless-2;
+#X obj 676 730 r wireless-3;
+#X text -11 592 Creates an unnamed parameter bank of 4 columns by 12
+rows \, whose output will be sent to 4 corresponding receives whose
+names are based on the symbol "wireless-n" \, where n is the corresponding
+column number. Note that the argument3 has been set to the empty string:
+"".;
+#N canvas 291 52 1062 794 An_EXAMPLE 0;
+#X obj 109 8 r synth-0;
+#X msg 87 32 set \$1;
+#X msg 109 79 set \$1;
+#X obj 109 174 vsl 15 128 50 15000 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X floatatom 87 336 7 0 0 1 hz - -;
+#X msg 87 357 put 0 \$1;
+#X obj 259 426 s toSynthPbank;
+#X obj 117 104 r name-0;
+#X msg 117 126 set \$1;
+#X msg 117 147 untitled_10;
+#N canvas 571 157 505 529 SYNTH 0;
+#X obj 80 43 inlet;
+#X obj 192 43 inlet;
+#X obj 300 43 inlet;
+#X obj 399 43 inlet;
+#X text 89 23 fq;
+#X text 178 24 modFQscaler;
+#X text 299 23 index;
+#X text 401 23 gain;
+#X floatatom 80 69 5 0 0 0 - - -;
+#X obj 123 110 float;
+#X obj 80 156 sig~;
+#X obj 192 71 t b f;
+#X obj 123 156 * 1;
+#X obj 123 178 sig~;
+#X obj 123 207 osc~;
+#X floatatom 222 110 5 0 0 0 - - -;
+#X obj 123 238 *~;
+#X obj 300 154 sig~;
+#X floatatom 300 110 5 0 0 0 - - -;
+#X obj 80 285 +~;
+#X obj 80 330 osc~;
+#X obj 399 72 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X obj 79 441 dac~;
+#X text 19 474 xjimmies lib. z. settel/jm dumas 2003-2007;
+#X obj 80 410 gain2~;
+#X obj 98 388 r \$0-gain;
+#X obj 80 364 gain1~;
+#X connect 0 0 8 0;
+#X connect 1 0 11 0;
+#X connect 2 0 18 0;
+#X connect 3 0 21 0;
+#X connect 8 0 10 0;
+#X connect 8 0 9 0;
+#X connect 9 0 12 0;
+#X connect 10 0 19 0;
+#X connect 11 0 9 0;
+#X connect 11 1 15 0;
+#X connect 12 0 13 0;
+#X connect 13 0 14 0;
+#X connect 14 0 16 0;
+#X connect 15 0 12 1;
+#X connect 16 0 19 1;
+#X connect 17 0 16 1;
+#X connect 18 0 17 0;
+#X connect 19 0 20 0;
+#X connect 20 0 26 0;
+#X connect 21 0 26 1;
+#X connect 24 0 22 0;
+#X connect 24 0 22 1;
+#X connect 25 0 24 1;
+#X connect 26 0 24 0;
+#X restore 623 425 pd SYNTH;
+#X msg 259 33 set \$1;
+#X msg 281 80 set \$1;
+#X obj 281 175 vsl 15 128 0 20 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X floatatom 259 337 7 0 0 1 hz - -;
+#X msg 289 127 set \$1;
+#X msg 289 148 0;
+#X msg 437 31 set \$1;
+#X msg 459 78 set \$1;
+#X obj 459 173 vsl 15 128 50 10000 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X floatatom 437 335 7 0 0 1 hz - -;
+#X msg 467 125 set \$1;
+#X msg 467 146 0;
+#X msg 608 34 set \$1;
+#X obj 630 176 vsl 15 128 0 127 0 0 empty empty empty 0 -8 0 8 -262144
+-1 -1 0 1;
+#X floatatom 608 338 7 0 0 1 hz - -;
+#X msg 634 126 set \$1;
+#X msg 634 147 0;
+#X obj 281 9 r synth-1;
+#X obj 459 7 r synth-2;
+#X obj 608 7 r synth-3;
+#X obj 634 104 r name-3;
+#X obj 467 103 r name-2;
+#X obj 289 105 r name-1;
+#X msg 259 358 put 1 \$1;
+#X msg 437 356 put 2 \$1;
+#X msg 608 359 put 3 \$1;
+#X obj 721 530 r toSynthPbank;
+#X obj 447 554 s toSynthPbank;
+#X msg 447 526 recall \$1;
+#X msg 810 480 recall 11;
+#X msg 723 480 recall 10;
+#X obj 723 460 loadbang;
+#X obj 723 506 pbank 4 12 bushmeat.pbank name;
+#X obj 449 501 i;
+#X obj 366 486 bng 15 250 50 0 empty empty empty 0 -6 0 8 -18753 -1
+-1;
+#X text 381 487 recall;
+#X obj 366 604 s toSynthPbank;
+#X obj 366 550 i;
+#X obj 366 466 bng 15 250 50 0 empty empty empty 0 -6 0 8 -258049 -1
+-1;
+#X text 388 465 store;
+#X msg 366 576 store \$1;
+#X floatatom 476 479 5 0 0 0 - - -;
+#X text 517 479 select memory;
+#X floatatom 476 502 5 0 0 0 - - -;
+#X text 518 500 current memory;
+#X obj 748 333 r synth-0;
+#X obj 748 353 r synth-1;
+#X obj 748 374 r synth-2;
+#X obj 748 395 r synth-3;
+#X obj 763 124 vsl 15 128 -99 18 0 1 \$0-gain empty Output -15 -14
+0 14 -260097 -1 -1 9300 1;
+#X floatatom 763 260 5 0 0 1 _db - -;
+#X obj 106 657 s toSynthPbank;
+#X obj 116 471 vradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1
+-1 0;
+#X obj 475 433 hradio 15 1 0 8 empty empty empty 0 -6 0 8 -262144 -1
+-1 0;
+#X floatatom 106 607 5 0 0 0 - - -;
+#X obj 723 629 pbank 4 12 bushmeat.pbank;
+#X msg 723 603 dump;
+#X msg 762 603 dump 2;
+#N canvas 675 151 189 317 interpol 0;
+#X obj 11 26 inlet;
+#X obj 72 98 min 127;
+#X obj 72 121 max 0;
+#X obj 11 98 min 127;
+#X obj 11 121 max 0;
+#N canvas 0 22 355 236 position 0;
+#X obj 49 121 pack f f;
+#X obj 49 17 inlet;
+#X obj 236 15 inlet;
+#X obj 49 152 outlet;
+#X obj 236 62 / 127;
+#X obj 49 93 / 127;
+#X obj 237 90 t b f;
+#X connect 0 0 3 0;
+#X connect 1 0 5 0;
+#X connect 2 0 4 0;
+#X connect 4 0 6 0;
+#X connect 5 0 0 0;
+#X connect 6 0 0 0;
+#X connect 6 1 0 1;
+#X restore 11 171 pd position;
+#N canvas 300 173 814 597 distance 0;
+#X obj 35 27 inlet;
+#X obj 37 538 outlet;
+#X obj 194 539 outlet;
+#X obj 37 144 unpack f f;
+#X obj 206 143 unpack f f;
+#X obj 341 142 unpack f f;
+#X obj 495 142 unpack f f;
+#X obj 634 140 unpack f f;
+#X obj 37 168 +;
+#X msg 37 192 1 \$1;
+#X obj 37 214 -;
+#X obj 206 171 - 1;
+#X obj 206 195 * -1;
+#X obj 205 224 +;
+#X msg 205 248 1 \$1;
+#X obj 205 270 -;
+#X obj 340 230 +;
+#X msg 340 254 1 \$1;
+#X obj 340 276 -;
+#X obj 492 223 +;
+#X msg 492 247 1 \$1;
+#X obj 492 269 -;
+#X obj 395 172 - 1;
+#X obj 395 196 * -1;
+#X obj 494 172 - 1;
+#X obj 494 196 * -1;
+#X obj 547 175 - 1;
+#X obj 547 199 * -1;
+#X obj 37 239 max 0;
+#X obj 206 292 max 0;
+#X obj 338 301 max 0;
+#X obj 493 298 max 0;
+#X obj 35 49 t a a a a a;
+#X obj 628 224 +;
+#X msg 628 248 1 \$1;
+#X obj 628 270 -;
+#X obj 629 299 max 0;
+#X obj 632 173 - 0.5;
+#X obj 683 176 - 0.5;
+#X obj 683 200 abs;
+#X obj 630 197 abs;
+#X obj 509 322 +;
+#X obj 379 349 +;
+#X obj 257 378 +;
+#X obj 62 413 +;
+#X obj 37 513 /;
+#X obj 37 264 t f f;
+#X obj 193 493 f;
+#X obj 193 517 /;
+#X obj 70 437 t b f;
+#X obj 325 487 f;
+#X obj 325 511 /;
+#X obj 480 481 f;
+#X obj 480 505 /;
+#X obj 616 480 f;
+#X obj 616 504 /;
+#X obj 480 531 outlet;
+#X obj 325 537 outlet;
+#X obj 616 532 outlet;
+#X connect 0 0 32 0;
+#X connect 3 0 8 0;
+#X connect 3 1 8 1;
+#X connect 4 0 11 0;
+#X connect 4 1 13 1;
+#X connect 5 0 16 0;
+#X connect 5 1 22 0;
+#X connect 6 0 24 0;
+#X connect 6 1 26 0;
+#X connect 7 0 37 0;
+#X connect 7 1 38 0;
+#X connect 8 0 9 0;
+#X connect 9 0 10 0;
+#X connect 10 0 28 0;
+#X connect 11 0 12 0;
+#X connect 12 0 13 0;
+#X connect 13 0 14 0;
+#X connect 14 0 15 0;
+#X connect 15 0 29 0;
+#X connect 16 0 17 0;
+#X connect 17 0 18 0;
+#X connect 18 0 30 0;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 31 0;
+#X connect 22 0 23 0;
+#X connect 23 0 16 1;
+#X connect 24 0 25 0;
+#X connect 25 0 19 0;
+#X connect 26 0 27 0;
+#X connect 27 0 19 1;
+#X connect 28 0 46 0;
+#X connect 29 0 43 0;
+#X connect 29 0 47 1;
+#X connect 30 0 42 0;
+#X connect 30 0 50 1;
+#X connect 31 0 41 0;
+#X connect 31 0 52 1;
+#X connect 32 0 3 0;
+#X connect 32 1 4 0;
+#X connect 32 2 5 0;
+#X connect 32 3 6 0;
+#X connect 32 4 7 0;
+#X connect 33 0 34 0;
+#X connect 34 0 35 0;
+#X connect 35 0 36 0;
+#X connect 36 0 41 1;
+#X connect 36 0 54 1;
+#X connect 37 0 40 0;
+#X connect 38 0 39 0;
+#X connect 39 0 33 1;
+#X connect 40 0 33 0;
+#X connect 41 0 42 1;
+#X connect 42 0 43 1;
+#X connect 43 0 44 1;
+#X connect 44 0 45 1;
+#X connect 44 0 49 0;
+#X connect 45 0 1 0;
+#X connect 46 0 45 0;
+#X connect 46 1 44 0;
+#X connect 47 0 48 0;
+#X connect 48 0 2 0;
+#X connect 49 0 47 0;
+#X connect 49 0 50 0;
+#X connect 49 0 52 0;
+#X connect 49 0 54 0;
+#X connect 49 1 48 1;
+#X connect 49 1 51 1;
+#X connect 49 1 53 1;
+#X connect 49 1 55 1;
+#X connect 50 0 51 0;
+#X connect 51 0 57 0;
+#X connect 52 0 53 0;
+#X connect 53 0 56 0;
+#X connect 54 0 55 0;
+#X connect 55 0 58 0;
+#X restore 11 194 pd distance;
+#X obj 11 217 pack f f f f f;
+#X obj 11 266 outlet;
+#X msg 11 242 interp \$1 \$2 \$3 \$4 \$5;
+#X obj 11 50 unpack f f;
+#X obj 11 73 / 2;
+#X obj 72 72 / 2;
+#X obj 11 144 change;
+#X obj 72 144 change;
+#X connect 0 0 10 0;
+#X connect 1 0 2 0;
+#X connect 2 0 14 0;
+#X connect 3 0 4 0;
+#X connect 4 0 13 0;
+#X connect 5 0 6 0;
+#X connect 6 0 7 0;
+#X connect 6 1 7 1;
+#X connect 6 2 7 2;
+#X connect 6 3 7 3;
+#X connect 6 4 7 4;
+#X connect 7 0 9 0;
+#X connect 9 0 8 0;
+#X connect 10 0 11 0;
+#X connect 10 1 12 0;
+#X connect 11 0 3 0;
+#X connect 12 0 1 0;
+#X connect 13 0 5 0;
+#X connect 14 0 5 1;
+#X restore 200 616 pd interpol;
+#X obj 96 474 vsl 15 115 7 0 0 1 empty empty empty 0 -8 0 8 -262144
+-1 -1 11400 1;
+#X obj 721 560 pbank 4 12 bushmeat.pbank synth;
+#X msg 106 627 recall \$1;
+#X text 47 455 interpolation beetween adjacent presets;
+#X text 171 563 complicated interpolation;
+#X obj 200 592 xy;
+#X text 229 590 <- click here;
+#X connect 0 0 1 0;
+#X connect 0 0 2 0;
+#X connect 1 0 4 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 4 0 10 0;
+#X connect 5 0 6 0;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 11 0 14 0;
+#X connect 12 0 13 0;
+#X connect 13 0 14 0;
+#X connect 14 0 34 0;
+#X connect 14 0 10 1;
+#X connect 15 0 16 0;
+#X connect 17 0 20 0;
+#X connect 18 0 19 0;
+#X connect 19 0 20 0;
+#X connect 20 0 35 0;
+#X connect 20 0 10 2;
+#X connect 21 0 22 0;
+#X connect 23 0 25 0;
+#X connect 23 0 24 0;
+#X connect 24 0 25 0;
+#X connect 25 0 36 0;
+#X connect 25 0 10 3;
+#X connect 26 0 27 0;
+#X connect 28 0 11 0;
+#X connect 28 0 12 0;
+#X connect 29 0 17 0;
+#X connect 29 0 18 0;
+#X connect 30 0 23 0;
+#X connect 31 0 26 0;
+#X connect 32 0 21 0;
+#X connect 33 0 15 0;
+#X connect 34 0 6 0;
+#X connect 35 0 6 0;
+#X connect 36 0 6 0;
+#X connect 37 0 71 0;
+#X connect 39 0 38 0;
+#X connect 40 0 43 0;
+#X connect 41 0 43 0;
+#X connect 42 0 41 0;
+#X connect 44 0 39 0;
+#X connect 44 0 54 0;
+#X connect 45 0 44 0;
+#X connect 48 0 51 0;
+#X connect 48 0 54 0;
+#X connect 49 0 48 0;
+#X connect 51 0 47 0;
+#X connect 56 0 10 0;
+#X connect 57 0 10 1;
+#X connect 58 0 10 2;
+#X connect 59 0 10 3;
+#X connect 60 0 61 0;
+#X connect 63 0 65 0;
+#X connect 64 0 44 1;
+#X connect 64 0 52 0;
+#X connect 64 0 48 1;
+#X connect 65 0 72 0;
+#X connect 67 0 66 0;
+#X connect 68 0 66 0;
+#X connect 69 0 62 0;
+#X connect 70 0 65 0;
+#X connect 72 0 62 0;
+#X connect 75 0 69 0;
+#X restore 1076 740 pd An_EXAMPLE;
+#X text -18 -12 pbank :;
+#X text 776 545 OUTLETS;
+#X text -15 691 "pdjimmies" lib. z. settel 2004;
+#X text 65 216 Arg4 is optional. If it is not specified \, Pbank's
+output will be sent out of its outlet. If arg4 is specified \, pbank's
+outlet will be inactive and output will be directed to a number of
+receive objects whose names are based on arg4 (receive symbol). For
+each column \, there is a corresponding receive whose name shitfuck
+includes the column number -see example below.;
+#X text 723 363 output edit buffer (share beetween diferents object
+with same pbank file);
+#X msg 705 429 interp 0 0.2 0.6 0.2;
+#X text 620 157 output row 2 (same as recall \, but does not compy
+to the edit buffer);
+#X text 712 336 copy edit buffer to row 3;
+#X text 692 273 recall (output) row 3 and copy it into edit buffer
+;
+#X text 746 401 read value from edit buffer (-1) at column 2;
+#X msg 696 399 2 -1;
+#X msg 640 299 recall 2.5;
+#X text 714 450 interpolation between presets : output = 0 * preset1
++ 0.2 * preset2 + 0.6* preset3 + 0.2 * preset4;
+#X text 721 299 recalls interpolated values between adjacent rows:
+;
+#X text 725 312 output = (row 2 + row 3) * 0.5;
+#X text -14 708 "interp" method contributed by Cyrille Henry;
+#X text 1079 722 LOOK IN HERE;
+#X obj 383 652 pbank 4 12 glen;
+#X text -10 481 Creates a named pbank whose output is sent to receives
+based on the symbol "wireless". Since there are 4 columns \, pbank
+will be sending its output to 4 receives each one corresponding to
+the column number included in its name. This provides an alterative
+(and faster) way of getting data from a pbank.;
+#X msg 680 363 dump;
+#X msg 555 166 dump 2;
+#X msg 572 191 dump 2;
+#X text 625 190 same as above but outputs row as list thru outlet;
+#X obj -8 361 pbank 4 12 examples/bushmeat.pbank;
+#X obj -9 461 pbank 4 12 examples/bushmeat.pbank wireless;
+#X msg 697 505 read examples/bushmeat.pbank;
+#X msg 697 529 write examples/bushmeat.pbank;
+#X obj 776 706 pbank 4 12 examples/bushmeat.pbank;
+#X connect 0 0 32 0;
+#X connect 1 0 32 0;
+#X connect 4 0 32 0;
+#X connect 6 0 32 0;
+#X connect 8 0 32 0;
+#X connect 9 0 32 0;
+#X connect 19 0 32 0;
+#X connect 20 0 32 0;
+#X connect 29 0 26 0;
+#X connect 29 1 27 0;
+#X connect 29 2 30 0;
+#X connect 29 3 31 0;
+#X connect 33 0 90 0;
+#X connect 37 0 38 0;
+#X connect 37 1 40 0;
+#X connect 37 2 42 0;
+#X connect 37 3 44 0;
+#X connect 38 0 39 0;
+#X connect 40 0 41 0;
+#X connect 42 0 43 0;
+#X connect 44 0 45 0;
+#X connect 46 0 80 0;
+#X connect 47 0 80 0;
+#X connect 48 0 49 0;
+#X connect 49 0 32 0;
+#X connect 50 0 87 0;
+#X connect 56 0 47 0;
+#X connect 57 0 51 0;
+#X connect 58 0 52 0;
+#X connect 59 0 53 0;
+#X connect 60 0 54 0;
+#X connect 68 0 32 0;
+#X connect 73 0 32 0;
+#X connect 74 0 32 0;
+#X connect 80 0 37 0;
+#X connect 82 0 32 0;
+#X connect 83 0 32 0;
+#X connect 84 0 32 0;
+#X connect 88 0 32 0;
+#X connect 89 0 32 0;
+#X connect 90 0 28 0;
+#X connect 90 0 29 0;
diff --git a/nusmuk-utils/pbank.c b/nusmuk-utils/pbank.c
new file mode 100755
index 0000000..d391a66
--- /dev/null
+++ b/nusmuk-utils/pbank.c
@@ -0,0 +1,1368 @@
+/* pbank - zack settel 1994 */
+// ported to PD - Zack Settel 2004 using the ISPW sources
+// note that the generated message receivers are of the format: "name-n" and not "n-name"(the way it was on the ISPW)
+/* features class-independent data structure see pbank.h */
+
+
+// Source code for this object derived from the original sources in the IRCAM Jimmies release (1994), with the authorization of IRCAM. This object is part of the nSLAM release, developed by La SAT. nSLAM is also available on the IRCAM Forum site (http://forum.ircam.fr), as an incentive to PD users to join and contribute to Forum IRCAM"
+
+
+// multi row interpolation method provided by cyrille.henry@la-kitchen.fr
+
+/*
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the
+Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Based on PureData by Miller Puckette and others.
+*/
+
+// Zack Maintenance: march 06
+// fixed recallf method: index bounded now.
+// fixed pbank_saveto: fixed bug when full path is specified.
+
+
+#include "m_pd.h"
+#include <stdio.h>
+#include <string.h>
+
+
+#include "pbank.h"
+#include "common.h"
+
+#define VERSION "pbank/pd v1.11 z.s. 2006"
+#define NIL 0L
+#define MAX_COLUMNS 2048
+#define DEFAULT_COLUMNS 10
+#define DEFAULT_ROWS 32
+#define MAX_ROWS 256 - EDBUFF
+#define PBANK_ID_STRING "theFucKinGPbanKIdeNtifacATioNStrinGGGG"
+
+#define EDBUFF 1 /* edbuffer at rows + 1 */
+#define DIRTFLAG 1 /* dirty flag kept at rows + 2 */
+
+#define GETROW(X,R)(((X)->p_data[(R)]))
+#define GET_EDBUFF(X)(((X)->p_data[((X)->p_rows)]))
+#define CR 13
+#define TAB 9
+
+
+
+typedef struct pbank
+{
+ t_object p_ob;
+ t_atom **p_data; /* param matrix : data[PATCH_COUNT] X *data+PARAMCOUNT */
+ t_symbol **p_receives; /* used for back door messaging */
+ t_symbol *p_name; /* pbank data/file name <optional> */
+ t_atom **p_dirty; /* points to extra cell in matrix used for dirty flag */
+ t_symbol *p_vol; /* default volume */
+ int p_curpatch;
+ int p_columns;
+ int p_rows;
+ t_canvas *x_canvas;
+
+} t_pbank;
+
+t_atom pbank_outlist[3]; /* used by list method for output */
+
+void *pbank_new(t_symbol *s, int argc, t_atom *argv);
+void pbank_bang(t_pbank *x);
+void pbank_dispose(t_pbank *x);
+void pbank_list(t_pbank *x, t_symbol *s, int argc, t_atom *argv);
+void pbank_recall(t_pbank *x,t_float row);
+void pbank_recallf(t_pbank *x,t_float row);
+void pbank_dump(t_pbank *x, t_symbol *s, int argc, t_atom *argv);
+void pbank_store(t_pbank *x,t_float row);
+void pbank_set(t_pbank *x, t_symbol *s, int argc, t_atom *argv);
+void pbank_put(t_pbank *x, t_symbol *s, int argc, t_atom *argv);
+void pbank_interp(t_pbank *x, t_symbol *s, int argc, t_atom *argv);
+void pbank_write(t_pbank *x, t_symbol *name);
+void pbank_tobinbuf(t_pbank *x,void *b);
+void pbank_read(t_pbank *x, t_symbol *fname);
+void pbank_saveto(t_pbank *x,char *fn);
+void pbank_db(t_pbank *x,t_float c,t_float r);
+void pbank_setup(void);
+int pbank_fromtext(t_pbank *x,void *b);
+
+t_atom **pbank_getmem(t_symbol *name,int columns,int rows);
+
+t_symbol *z_list, *z_float, *z_symbol, *z_receive; // *z_int,
+
+#define EMPTYSTRING ""
+
+/* class variables */
+
+t_shared *pbank_banks = NIL; /* linked list of shared data-matrixs */
+t_symbol *pbank_ID;
+
+t_atom *pbank_clipboard; /* NOT IMPLEMENTED points to edbuff of "copied" pbank */
+/* clipboard needed ???? */
+
+/* ************************************************************ */
+
+
+void pbank_db(t_pbank *x, t_float c_float, t_float r_float)
+{
+ t_atom *a;
+ long c = (long) c_float;
+ long r = (long) r_float;
+
+ *x->p_dirty = (c) ? (t_atom *)1:NIL;
+
+
+ post("p_dirty at %lx",x->p_dirty);
+ post("plus %ld addr = %lx",r,x->p_data+r);
+
+ a = GETROW(x,r);
+}
+
+
+
+void pbank_bang(t_pbank *x)
+{
+
+ t_shared *piss = NIL;
+
+ post(":DIRTY FLAS = %ld at %lx",*x->p_dirty,x->p_dirty);
+ return;
+
+ piss = pbank_banks; /* maintain list of instance memories */
+ while(piss)
+ {
+ post("->%s at %lx",piss->s_sym->s_name,piss);
+ post(" next->%lx",piss->s_next);
+ piss = piss->s_next;
+ }
+}
+ /* write item to matrix at given column,row address */
+ /* message: column row thing1......thingN */
+void pbank_set(t_pbank *x, t_symbol *s, int ac, t_atom *argv)
+{
+ t_atom *shit;
+ int column,row;
+
+ if (ac < 3)
+ {
+ post("ac=%d",ac);
+ error("pbank_set: takes at least 3 arguments: column row item(s)");
+ return;
+ }
+ if ((argv)->a_type != A_FLOAT || (argv+1)->a_type != A_FLOAT)
+ {
+ error("pbank_set: first arguments must of type float (columnNo. or rowNo.)");
+ return;
+ }
+
+ if ((column = (int)(argv)->a_w.w_float) < 0) column = 0;
+ else if (column >= x->p_columns) column = x->p_columns-1;
+
+ if ((row = (int)(argv+1)->a_w.w_float) < 0) row = 0;
+ else if (row >= x->p_rows) row = x->p_rows-1;
+
+ shit = GETROW(x,row);
+
+ ac -=2; /* get data */
+ argv +=2;
+ while (ac-- && (column < x->p_columns))
+ {
+ if ((argv)->a_type != A_FLOAT && (argv)->a_type != A_SYMBOL && (argv)->a_type != A_FLOAT)
+ {
+ error("pbank_set: argument no %d must be afloat or symbol",ac+1);
+ return;
+ }
+ *(shit+column++) = *argv++;
+ }
+ *x->p_dirty = (t_atom *)1; /* set dirty flag */
+
+}
+
+ /* same as set but writes to the edirt buffer: 'put' column thing1......thingN */
+void pbank_put(t_pbank *x, t_symbol *s, int ac, t_atom *argv)
+{
+ t_atom *shit;
+ int column;
+
+ if (ac < 2)
+ {
+ post("ac=%d",ac);
+ error("pbank_put: takes at least 2 arguments: column item(s)");
+ return;
+ }
+ if ((argv)->a_type != A_FLOAT)
+ {
+ error("pbank_put: first argument must a number (columnNo.)");
+ return;
+ }
+ if ((column = (int)(argv)->a_w.w_float) < 0) column = 0;
+ else if (column >= x->p_columns) column = x->p_columns-1;
+
+ shit = GET_EDBUFF(x);
+
+ ac --; /* get data */
+ argv ++;
+ while (ac-- && (column < x->p_columns))
+ {
+ if ((argv)->a_type != A_FLOAT && (argv)->a_type != A_SYMBOL && (argv)->a_type != A_FLOAT)
+ {
+ error("pbank_put: argument no %d must be a float or symbol",ac);
+ return;
+ }
+ *(shit+column++) = *argv++;
+ }
+}
+
+
+
+void pbank_recall(t_pbank *x, t_float row_float) /* dumps (outputs) and copies row to edbuffer */
+{
+
+ int z,ac;
+ t_atom *av,*ebuff;
+ long row = (long) row_float;
+ float indexf = (float) row_float;
+
+ if (row < 0) row = 0L;
+ else if (row > x->p_rows-1) row = (long)x->p_rows-1;
+
+ if (indexf < 0) indexf = 0L;
+ else if (indexf > x->p_rows-1) indexf = (float)x->p_rows-1;
+
+
+ if (indexf - row)
+ {
+ pbank_recallf(x, (t_float) indexf);
+ return;
+ }
+
+ av = GETROW(x,row);
+ ebuff = GET_EDBUFF(x);
+
+ if (x->p_receives) /* back-door sending??? */
+ {
+ t_symbol *type;
+ ebuff += x->p_columns-1;
+ av += x->p_columns-1;
+
+ for (z=x->p_columns-1;z>-1;z--,ebuff--,av--)
+ {
+ *ebuff = *av;
+ if (x->p_receives[z]->s_thing)
+ {
+ ac=1;
+ if (ebuff->a_type == A_FLOAT) type = z_float;
+ // else if (ebuff->a_type == A_LONG) type = z_int;
+ else if (ebuff->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[z]->s_thing, type,ac, ebuff);
+ }
+ }
+ }
+ else /* otherwise use outlet */
+ for (z=0;z<x->p_columns;z++,av++,ebuff++)
+ {
+ *ebuff = *av;
+ pbank_outlist->a_w.w_float = (float)z;
+ (pbank_outlist+1)->a_type = ebuff->a_type;
+ if (ebuff->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+ }
+exit:
+ return;
+}
+
+
+void pbank_recallf(t_pbank *x, t_float row_float) /* interpol, dumps (outputs) and copies row to edbuffer */
+{
+ int u, v, z, ac;
+ t_atom *av,*avplus1, *ebuff;
+
+
+ // no need to range check, since that's done by caller method
+
+ // float indexf = (float) row_float;
+ float interpfac;
+
+ u=(int)row_float;
+
+ interpfac = (float) (row_float - u);
+
+ av = GETROW(x,u);
+ av += x->p_columns-1;
+
+ avplus1 = GETROW(x,u+1);
+ avplus1 += x->p_columns-1;
+
+
+
+ ebuff = GET_EDBUFF(x);
+
+ ebuff += x->p_columns-1;
+
+
+ // for (v=x->p_columns-1;v>-1;v--,ebuff--)
+ // {
+ // SETFLOAT(ebuff, 0); //clear edit buffer
+ //}
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (v=x->p_columns-1;v>-1;v--,ebuff--,av--,avplus1--)
+ {
+ if (ebuff->a_type == A_FLOAT && av->a_type == A_FLOAT && avplus1->a_type == A_FLOAT)
+ SETFLOAT(ebuff, (t_float)(av->a_w.w_float * (1 - interpfac) + avplus1->a_w.w_float * interpfac));
+ else if (ebuff->a_type == A_SYMBOL)
+ {
+ if (interpfac <.5) SETSYMBOL(ebuff, av->a_w.w_symbol);
+ else SETSYMBOL(ebuff, avplus1->a_w.w_symbol);
+ }
+ else error("pbank: bug found in recallf method");
+ }
+
+#ifdef why_is_this_here_sheefa
+
+ if ((int)indexf!=indexf)
+ {
+ u++;
+
+ av = GETROW(x,u);
+ av += x->p_columns-1;
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (v=x->p_columns-1;v>-1;v--,ebuff--,av--)
+ {
+ if (ebuff->a_type == A_FLOAT && av->a_type == A_FLOAT)
+ SETFLOAT(ebuff, ebuff->a_w.w_float + av->a_w.w_float * (indexf - u +1)); else if (ebuff->a_type == A_SYMBOL)
+ SETSYMBOL(ebuff, av->a_w.w_symbol);
+ else error("pbank: bug found in recallf method");
+ }
+ }
+
+#endif
+
+ if (x->p_receives) /* back-door sending??? */
+ {
+ t_symbol *type;
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (z=x->p_columns-1;z>-1;z--,ebuff--,av--)
+ {
+
+ if (x->p_receives[z]->s_thing)
+ {
+ ac=1;
+ if (ebuff->a_type == A_FLOAT) type = z_float;
+ // else if (ebuff->a_type == A_LONG) type = z_int;
+ else
+ if (ebuff->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[z]->s_thing, type,ac, ebuff);
+ }
+ }
+ }
+ else /* otherwise use outlet */
+ {
+ ebuff = GET_EDBUFF(x);
+
+ for (z=0;z<x->p_columns;z++,ebuff++)
+ {
+ pbank_outlist->a_w.w_float = (float)z;
+ (pbank_outlist+1)->a_type = ebuff->a_type;
+ if (ebuff->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+ }
+ }
+exit:
+ return;
+
+}
+
+
+void pbank_interp(t_pbank *x, t_symbol *s, int argc, t_atom *argv)
+/* interpol, dumps (outputs) and copies row to edbuffer */
+{
+
+ int u, v, z, ac;
+ t_atom *av,*ebuff;
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (v=x->p_columns-1;v>-1;v--,ebuff--)
+ {
+ SETFLOAT(ebuff, 0); //clear edit buffer
+ }
+ for (u=argc-1;u>-1;u--)
+ {
+ av = GETROW(x,u);
+ av += x->p_columns-1;
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (v=x->p_columns-1;v>-1;v--,ebuff--,av--)
+ {
+ if (ebuff->a_type == A_FLOAT && av->a_type == A_FLOAT)
+ SETFLOAT(ebuff, ebuff->a_w.w_float + av->a_w.w_float * atom_getfloatarg(u, argc, argv) ); //add value of each columns and row
+ else
+ SETSYMBOL(ebuff, gensym("null"));
+ }
+ }
+
+ if (x->p_receives) /* back-door sending??? */
+ {
+ t_symbol *type;
+
+ ebuff = GET_EDBUFF(x);
+ ebuff += x->p_columns-1;
+
+ for (z=x->p_columns-1;z>-1;z--,ebuff--,av--)
+ {
+
+ if (x->p_receives[z]->s_thing)
+ {
+ ac=1;
+ if (ebuff->a_type == A_FLOAT) type = z_float;
+ // else if (ebuff->a_type == A_LONG) type = z_int;
+ else
+ if (ebuff->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[z]->s_thing, type,ac, ebuff);
+ }
+ }
+ }
+ else /* otherwise use outlet */
+ {
+ ebuff = GET_EDBUFF(x);
+
+ for (z=0;z<x->p_columns;z++,ebuff++)
+
+ {
+ pbank_outlist->a_w.w_float = (float)z;
+ (pbank_outlist+1)->a_type = ebuff->a_type;
+ if (ebuff->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+
+ }
+ }
+
+exit:
+ return;
+}
+
+// 'dump' dumps edit buff, 'dump n' dumps memory n, 'dump n l' dumps row n as one single list
+void pbank_dump(t_pbank *x, t_symbol *s, int argc, t_atom *argv) /* dumps (outputs) ediuffer or row */
+{
+
+ int z,ac, row;
+ t_atom *ebuff;
+
+ if (argc==0)
+ {
+ ebuff = GET_EDBUFF(x);
+ if (x->p_receives) /* back-door sending??? */
+ {
+ t_symbol *type;
+ ebuff += x->p_columns-1;
+
+ for (z=x->p_columns-1;z>-1;z--,ebuff--)
+ {
+ if (x->p_receives[z]->s_thing)
+ {
+ ac=1;
+ if (ebuff->a_type == A_FLOAT) type = z_float;
+ // else if (ebuff->a_type == A_LONG) type = z_int;
+ else if (ebuff->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[z]->s_thing, type,ac, ebuff);
+ }
+ }
+ }
+ else /* otherwise use outlet */
+ for (z=0;z<x->p_columns;z++,ebuff++)
+ {
+ pbank_outlist->a_w.w_float = (float)z;
+ (pbank_outlist+1)->a_type = ebuff->a_type;
+ if (ebuff->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+ }
+ }
+
+ else
+ {
+ if ((row = (int)(argv)->a_w.w_float) < 0) row = 0;
+ else if (row >= x->p_rows) row = x->p_rows-1;
+
+ ebuff = GETROW(x, row);
+
+ if (x->p_receives) /* back-door sending??? */
+ {
+ t_symbol *type;
+ ebuff += x->p_columns-1;
+
+ for (z=x->p_columns-1;z>-1;z--,ebuff--)
+ {
+ if (x->p_receives[z]->s_thing)
+ {
+ ac=1;
+ if (ebuff->a_type == A_FLOAT) type = z_float;
+ // else if (ebuff->a_type == A_LONG) type = z_int;
+ else if (ebuff->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[z]->s_thing, type,ac, ebuff);
+ }
+ }
+ }
+ else /* otherwise use outlet */
+ {
+ if(argc>1) // dump as single list
+ outlet_list(x->p_ob.ob_outlet,0L,x->p_columns, ebuff);
+ else
+ {
+ for (z=0;z<x->p_columns;z++,ebuff++)
+ {
+ pbank_outlist->a_w.w_float = (float)z;
+ (pbank_outlist+1)->a_type = ebuff->a_type;
+ if (ebuff->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = ebuff->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+ }
+ }
+ }
+ }
+exit:
+ return;
+}
+
+
+void pbank_store(t_pbank *x, t_float row_float) /* copies edbuffer to row */
+{
+ t_atom *av,*ebuff;
+ int z;
+ long row = (long) row_float;
+
+ if (row < 0) row = 0L;
+ else if (row >= x->p_rows) row = (long)x->p_rows-1;
+
+ av = GETROW(x,row);
+ ebuff = GET_EDBUFF(x);
+ for (z=0;z<x->p_columns;z++,av++,ebuff++)
+ {
+ *av = *ebuff;
+ }
+ *x->p_dirty = (t_atom *)1; /* set dirty flag */
+}
+
+
+/* eg 'list COLUMN ROW <optional> VALUE' - argc=2 is read, arg=3 is write */
+
+void pbank_list(t_pbank *x, t_symbol *s, int argc, t_atom *argv)
+{
+
+ t_atom *av;
+ int ac,column,row;
+
+ if ((argc != 2) && (argc != 3))
+ {
+ error("pbank_list: less than 2, or more than 3 elements in list");
+ goto exit;
+ }
+
+
+ if (((argv)->a_type != A_FLOAT) || ((argv+1)->a_type != A_FLOAT))
+ {
+ error("pbank_list: first two elements must be numbers");
+ goto exit;
+ }
+ if ((column = (int)(argv)->a_w.w_float) < 0) column = 0;
+ else if (column >= x->p_columns) column = x->p_columns-1;
+
+ if ((row = (int)(argv+1)->a_w.w_float) < -1) row = -1;
+ else if (row >= x->p_rows) row = x->p_rows-1;
+
+
+ if (row == -1)
+ {
+ av = GET_EDBUFF(x);
+ }
+ else
+ {
+ av = GETROW(x,row);
+ }
+
+ av += column;
+ ac = 1;
+
+ if (argc == 2) /* read */
+ {
+ if (x->p_receives)
+ {
+ if (x->p_receives[column]->s_thing)
+ {
+ t_symbol *type;
+ if (av->a_type == A_FLOAT) type = z_float;
+ // else if (av->a_type == A_LONG) type = z_int;
+ else if (av->a_type == A_SYMBOL) type = z_symbol;
+ else
+ {
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ typedmess(x->p_receives[column]->s_thing, type,ac, av);
+ }
+ }
+ else
+ {
+ pbank_outlist->a_w.w_float = (t_float)column;
+ (pbank_outlist+1)->a_type = av->a_type;
+ if (av->a_type == A_SYMBOL)
+ {
+ (pbank_outlist+1)->a_w.w_symbol = z_symbol;
+ (pbank_outlist+2)->a_type = A_SYMBOL;
+ (pbank_outlist+2)->a_w = av->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,3, pbank_outlist);
+ }
+ else
+ {
+ (pbank_outlist+1)->a_w = av->a_w;
+ outlet_list(x->p_ob.ob_outlet,0L,2, pbank_outlist);
+ }
+ }
+
+ }
+ else /* write */
+ {
+ switch ((argv+2)->a_type)
+ {
+
+ case A_FLOAT:
+ SETFLOAT(av,(argv+2)->a_w.w_float);
+ break;
+ /* case A_LONG:
+ SETLONG(av,(argv+2)->a_w.w_long);
+ break;
+ */
+ case A_SYMBOL:
+ SETSYMBOL(av,(argv+2)->a_w.w_symbol);
+ break;
+ default:
+ error("pbank_list: 3rd element must be a float or sym.");
+ goto exit;
+ }
+ *x->p_dirty = (t_atom *)1; /* set dirty flag */
+ }
+exit:
+ return;
+
+}
+
+int pbank_fromtext(t_pbank *x,void *b)
+{
+ t_atom *av;
+ int z,atype;
+ int columnpos = 0,columns = 0;
+ int rowpos = 0, rows = 0;
+ long items = 0;
+ int argc = binbuf_getnatom(b),count = 0;
+
+ t_atom *ap = binbuf_getvec(b);
+
+
+ /* get pbank symbol */
+ if (ap->a_type != A_SYMBOL || ap->a_w.w_symbol != gensym("pbank"))
+ {
+ error("pbank_fromtext: bad file format: item one must be the symbol 'pbank");
+ goto error;
+ }
+
+ for (z=0;z<2;z++)
+ {
+ ap++, count++;
+
+ // binbuf_getatom(b,&p1,&p2,&at); /* get columns and rows */
+ if (ap->a_type != A_FLOAT)
+ {
+ error("pbank_fromtext: bad file format: item two and three must be COLUMNcount and ROWcount");
+ goto error;
+ }
+ if (z==0) columns = (int)ap->a_w.w_float;
+ else rows = (int)ap->a_w.w_float;
+ }
+
+ if (columns < 1 || rows < 1)
+ {
+ error("pbank_fromtext: bad value(s) for item two and/or three (COLUMNcount and/or ROWcount)");
+ goto error;
+ }
+ if (columns != x->p_columns)
+ {
+ error("pbank_fromtext: bad file format: wrong no. of columns (%d) in file", columns);
+ goto error;
+ }
+
+ /* get comma */
+ ap++, count++;
+ if (ap->a_type != A_COMMA)
+ {
+ error("pbank_fromtext: bad file format: comma expected after third item");
+ goto error;
+ }
+
+
+
+ av = GETROW(x,rowpos);
+
+ // post("pbank_fromtext: columns %d rows %d",columns,rows);
+
+ while (count < argc)
+ {
+
+
+ if (rowpos > x->p_rows) // safety check- remove later
+ {
+ bug("pbank_fromtext: rowpos=%d x->p_rows=%d items=%d argc=%d",rowpos,x->p_rows,count,argc);
+ error("pbank_fromtext: rowpos greater than x->p_rows: aborting");
+ goto error;
+ }
+
+
+
+ ap++, count++; // get next atom
+ atype = ap->a_type;
+
+ if (atype == A_NULL)
+ {
+ if (count == argc) goto done;
+ else
+ {
+ error("pbank_fromtext: unexpected A_NULL type read at position %d: aborting", count);
+ goto error;
+ }
+ }
+
+
+ if (columnpos >= x->p_columns) goto skipit;
+
+
+
+ if (atype==A_FLOAT || atype==A_SYMBOL)
+ {
+ av[columnpos] = *ap; /* write atom to matrix */
+ items++;
+ }
+
+ else if (atype==A_COMMA) /* new line */
+ {
+ if (columnpos)
+ post("pbank_fromtext: warning: unexpected comma found in column %d row %d", columnpos,rowpos);
+ goto skipit;
+ }
+ else
+ {
+ // post("ATYPE = %d", atype);
+ post("pbank_fromtext: warning: strange token found in at column %d, row %d of file", columnpos,rowpos);
+ goto ignore;
+ }
+skipit: /* ignore any data that lies outside of X's dimensions */
+ if (atype!=A_COMMA)
+ columnpos++;
+ if (columnpos == columns)
+ {
+ columnpos = 0;
+ rowpos++;
+ av = GETROW(x,rowpos);
+ }
+ignore:;
+ }
+done:
+ return(items);
+error:
+ return(0);
+}
+
+
+void pbank_fromfile(t_pbank *x,char *name, int type, int silentFlag) // filename with or without path
+{
+ void *b;
+ int errorf, itemcount;
+ char nilbuf[1];
+
+ nilbuf[0] = 0;
+
+
+ b = binbuf_new();
+ // errorf = binbuf_read(b, name, vol, type);
+
+ if (*name != '/' && *name != '~') // file name is not an absolute path
+ errorf = binbuf_read(b, name, canvas_getdir(x->x_canvas)->s_name, type);
+ else
+ errorf = binbuf_read(b, name, nilbuf, type);
+
+
+ if (errorf)
+ {
+ if (!silentFlag) post("warning: pbank_fromfile:%s not found",name); // not error, since filename may be used only as symbol for pbanks sharing memory
+ }
+ else
+ {
+ itemcount = pbank_fromtext(x,b);
+ post("pbank_fromfile: %d items read from file %s",itemcount, name);
+ *x->p_dirty = NIL;
+ }
+ binbuf_free(b);
+}
+
+
+#define TEXT 0
+#define BINARY 1
+
+void pbank_read(t_pbank *x, t_symbol *fname)
+{
+ /* if (!open_dialog(name, &vol, &type, types, 1)) */
+ pbank_fromfile(x,fname->s_name,TEXT,0);
+}
+
+
+ /* format for file <float type> <symbol *pname> <float p1 p2 p3 p4..p10> A_COMMA.... */
+void pbank_tobinbuf(t_pbank *x,void *b)
+{
+ t_atom at,*av;
+ t_symbol *s;
+ char shit[256];
+ int z,i;
+
+ sprintf(shit,"\n");
+ s = gensym("");
+
+ SETSYMBOL(&at,gensym("pbank")); /* write class name */
+ binbuf_add(b,1,&at);
+
+ SETFLOAT(&at,(t_float) x->p_columns); /* write column count */
+ binbuf_add(b,1,&at);
+
+ SETFLOAT(&at,(t_float) x->p_rows); /* write row count */
+ binbuf_add(b,1,&at);
+
+ SETCOMMA(&at); /* write comma */
+ binbuf_add(b,1,&at);
+
+ SETSYMBOL(&at,gensym(shit)); /* write CR */
+ binbuf_add(b,1,&at);
+
+
+ for (z=0;z<x->p_rows;z++) /* write params to binbuf */
+ {
+ av = GETROW(x,z);
+ for (i=0;i<x->p_columns;i++,av++)
+ {
+
+/* if (av->a_type == A_FLOAT)
+ {
+ post("A_FLOAT"); postfloat(av->a_w.w_float);
+ }
+
+ // else if (av->a_type == A_LONG) post("A_LONG %ld", av->a_w.w_long);
+
+ else if (av->a_type == A_SYMBOL) post("A_SYMBOL %s", av->a_w.w_symbol->s_name);
+*/
+ binbuf_add(b,1,av); /* write atom */
+ }
+ SETCOMMA(&at); /* rows seperated by comma */
+ binbuf_add(b,1,&at);
+ SETSYMBOL(&at,gensym(shit)); /* write CR */
+ binbuf_add(b,1,&at);
+
+ }
+}
+
+void pbank_write(t_pbank *x, t_symbol *name)
+{
+ char fn[256];
+
+ sprintf(fn,"%s", name->s_name);
+
+ /* def volume shit here */
+
+ pbank_saveto(x,fn);
+}
+
+void pbank_saveto(t_pbank *x,char *fn)
+{
+ int errorf = 0;
+ char nilbuf[1];
+ void *b = binbuf_new();
+
+
+ pbank_tobinbuf(x,b);
+
+ nilbuf[0]= 0; // nilbuf[1]= 0; bug fixed: zk-03/06
+
+ if (*fn != '/' && *fn != '~') // file name is not an absolute path
+ errorf = binbuf_write(b, fn, canvas_getdir(x->x_canvas)->s_name, TEXT); /* save as TEXT */
+ else
+ errorf = binbuf_write(b, fn, nilbuf, TEXT); /* save as TEXT */
+
+ binbuf_free(b);
+
+ if (errorf)
+ error("pbank_saveto: couldn't write %s", fn);
+ else
+ {
+ *x->p_dirty = NIL;
+ post("pbank_write:wrote file %s",fn);
+ }
+}
+
+void pbank_dispose(t_pbank *x)
+{
+ int z;
+
+ t_shared *prePiss = NIL;
+ t_shared *piss = NIL;
+
+ if (*x->p_dirty)
+ {
+ /* need a save dialog here */
+ post("unsaved data");
+ }
+
+ prePiss = piss = pbank_banks; /* maintain list of instance memories */
+ if (x->p_name)
+ {
+ while(piss)
+ {
+
+ /* post("->%s at %lx",piss->s_sym->s_name,piss);
+ post(" next->%lx",piss->s_next); */
+
+ if ((t_symbol *)piss->s_sym == x->p_name) break;
+
+ prePiss = piss;
+ piss = piss->s_next;
+ }
+ if (!piss)
+ {
+ error("pbank_dispose: bug found- can't find symbol");
+ goto skip;
+ }
+ /* post("found %s", piss->s_sym->s_name); */
+
+ piss->s_refcount--;
+ if (piss->s_refcount)
+ {
+ /* post("%s refcount = %d",piss->s_sym->s_name, piss->s_refcount); */
+ goto skip; /* things still pointing to data- don't dispose */
+ }
+
+ piss->s_sym->s_thing = (void *) 0L; /* clear symbol to no longer point to this class */
+
+ if (!piss->s_next) /* last element in list */
+ {
+ if (piss == pbank_banks) /* first element in list of only one element*/
+ {
+ /* post("°°°°°° unique element in list"); */
+ freebytes(piss, (int)sizeof(t_shared));
+ pbank_banks = NIL;
+ }
+ else /* last element in list - snip it */
+ {
+ if (!prePiss)
+ {
+ error("bug found in pbank_dispose (prePiss)");
+ goto skip;
+ }
+ /* post("°°°°°° last element in list"); */
+ prePiss->s_next = NIL;
+ freebytes(piss, (int)sizeof(t_shared));
+ }
+ }
+ else if (piss == pbank_banks) /* first element in list of at least two elements */
+ {
+ /* post("°°°°°° first element in list"); */
+ pbank_banks = piss->s_next;
+ freebytes(piss, (int)sizeof(t_shared));
+ }
+ else /* element with adjacent elements */
+ {
+ if (!prePiss)
+ {
+ error("bug found in pbank_dispose (prePiss)");
+ goto skip;
+ }
+ /* post("°°°°°° embedded element in list"); */
+ prePiss->s_next = piss->s_next;
+ freebytes(piss, (int)sizeof(t_shared));
+ }
+
+ }
+
+ for (z=0;z<x->p_rows+EDBUFF;z++)
+ {
+ freebytes((void *)x->p_data[z], (int)sizeof(t_atom)*x->p_columns);
+ }
+
+ freebytes((void *)x->p_data,(int)sizeof(t_atom *)*(x->p_rows+EDBUFF+DIRTFLAG));
+
+skip:
+ if (x->p_receives)
+ freebytes((void *)x->p_receives, (int)sizeof(t_symbol *)*x->p_columns);
+
+}
+
+
+
+t_class *pbank_class;
+
+void pbank_setup(void)
+{
+ pbank_class = class_new(gensym("pbank"), (t_newmethod) pbank_new, (t_method) pbank_dispose, sizeof(t_pbank), 0, A_GIMME,0);
+ class_addbang(pbank_class, (t_method) pbank_bang);
+ class_addlist(pbank_class, (t_method) pbank_list);
+ class_addmethod(pbank_class, (t_method) pbank_put, gensym("put"),A_GIMME,0);
+ class_addmethod(pbank_class, (t_method) pbank_db, gensym("db"), A_FLOAT,A_FLOAT, 0);
+ class_addmethod(pbank_class, (t_method) pbank_recall, gensym("recall"), A_FLOAT,0);
+ // class_addmethod(pbank_class, (t_method) pbank_recallf, gensym("recallf"), A_FLOAT,0);
+ class_addmethod(pbank_class, (t_method) pbank_dump, gensym("dump"),A_GIMME,0);
+ class_addmethod(pbank_class, (t_method) pbank_store, gensym("store"), A_FLOAT,0);
+ class_addmethod(pbank_class, (t_method) pbank_write, gensym("write"), A_SYMBOL,0);
+ class_addmethod(pbank_class, (t_method) pbank_read, gensym("read"), A_SYMBOL,0);
+ class_addmethod(pbank_class, (t_method) pbank_interp, gensym("interp"), A_GIMME,0);
+ class_addmethod(pbank_class, (t_method) pbank_set, gensym("set"),A_GIMME,0);
+
+
+ pbank_outlist->a_type = A_FLOAT;
+
+ z_list = gensym("list");
+ z_float = gensym("float");
+ // z_int = gensym("int");
+ z_symbol = gensym("symbol");
+ z_receive = gensym("receive");
+ pbank_ID = gensym(PBANK_ID_STRING);
+ pbank_ID->s_thing = (void *)pbank_ID;
+
+ post("%s", VERSION);
+}
+
+
+/* columns rows memory-name receiveName<optional> */
+/* note: memory-name is optional when no receiveName argument is specified */
+void *pbank_new(t_symbol *s, int argc, t_atom *argv)
+{
+ int z=0;
+ char *shit;
+ char piss[256];
+
+ t_pbank *x = (t_pbank *)pd_new(pbank_class);
+
+ x->p_name = NIL;
+ x->p_receives = NIL;
+ x->x_canvas = canvas_getcurrent();
+
+ // x->p_vol = getdefvolume();
+
+ if (!InRange(argc,2,4))
+ {
+ error("pbank_new: bad arg count - takes: colums rows fname <opt symbol> sendname");
+ goto err;
+ }
+
+
+
+
+ if (((argv)->a_type != A_FLOAT) || ((argv+1)->a_type != A_FLOAT))
+ {
+ error("pbank_new: first two elements must be numbers");
+ goto err;
+ }
+
+
+// if ((argv)->a_w.w_float < 1 || (argv+1)->a_w.w_float < 1)
+// {
+// error("pbank_new: first or second argument less than 1, can't continue");
+// goto err;
+// }
+
+ if (!InRange((argv)->a_w.w_float, 1,MAX_COLUMNS-1))
+ {
+ x->p_columns = DEFAULT_COLUMNS;
+ post("pbank_new: warning: columns argument out of range, setting to %d",x->p_columns);
+ }
+ else x->p_columns = (int)(argv)->a_w.w_float;
+
+ if (!InRange((argv+1)->a_w.w_float, 1,MAX_ROWS-1))
+ {
+ x->p_rows = DEFAULT_ROWS;
+ post("pbank_new: warning: rows argument out of range, setting to %d",x->p_rows);
+ }
+ else x->p_rows = (int)(argv+1)->a_w.w_float;
+
+
+
+ if (argc == 2) x->p_name = NIL;
+ else
+ {
+ if ((argv+2)->a_type != A_SYMBOL)
+ {
+ error("pbank_new: bad third arg: needs to be a symbol (or empty string %s)",gensym("")->s_name);
+ goto err;
+ }
+ shit = (argv+2)->a_w.w_symbol->s_name;
+ /* is it a crosshatch or un-defined ("") ? */
+ x->p_name = ((shit[0] == '#') || (shit[0] == '"' && shit[1] == '"')) ? NIL:gensym(shit);
+ }
+
+
+ if (argc == 4) /* argc == 4: establish output pointers to receive objects */
+ {
+ if ((argv+3)->a_type != A_SYMBOL)
+ {
+ if ((argv+3)->a_type == A_FLOAT)
+ {
+ post("pbank_new: warning: 4th arg not symbol: ignoring (%f)", (argv+3)->a_w.w_float);
+ goto nosyms;
+ }
+ else
+ {
+ error("pbank_new: optional fourth arg. needs to be a symbol");
+ goto err;
+ }
+ }
+
+
+ shit = (argv+3)->a_w.w_symbol->s_name;
+ if (shit[0] == '#' || (shit[0] == '"' && shit[1] == '"')) goto nosyms; /* crosshatch here */;
+
+ x->p_receives = (t_symbol **)getbytes((int)sizeof(t_symbol *)*x->p_columns);
+
+ for (z=0;z<x->p_columns;z++)
+ {
+ sprintf(piss,"%s-%d",shit,z); // generate symbol of form: "name-columnNo"
+ x->p_receives[z] = gensym(piss);
+
+ if (x->p_receives[z]->s_thing)
+ { /* sends or receive obj */
+
+ // post("found us a %s",class_getname(pd_class(x->p_receives[z]->s_thing)));
+
+ // if ((void *)pd_class(x->p_receives[z]->s_thing)->c_sym != gensym("through"))
+ /*
+ NO TESTING FOR SHARED SYMBOLS
+
+ if (strcmp(class_getname(pd_class(x->p_receives[z]->s_thing)), "send") &&
+ strcmp(class_getname(pd_class(x->p_receives[z]->s_thing)), "receive") &&
+ strcmp(class_getname(pd_class(x->p_receives[z]->s_thing)), "bindlist"))
+ {
+ error("pbank_new: symbol %s already being used, can't use it",shit);
+ post("z=%d found a %s",z,class_getname(pd_class(x->p_receives[z]->s_thing)));
+ goto err;
+ }
+ */
+
+ }
+ }
+ }
+
+nosyms:
+ if (NIL == (x->p_data = pbank_getmem(x->p_name, x->p_columns,x->p_rows))) goto err; /* can't allocate data matrix */
+ x->p_dirty = x->p_data+x->p_rows-1+EDBUFF+DIRTFLAG; /* points to extra cell in matrix used for dirty flag */
+
+
+ if (x->p_name)
+ {
+ pbank_fromfile(x,x->p_name->s_name, TEXT,1);
+ }
+
+ outlet_new((t_object *) x, gensym("list"));
+
+ return(x);
+err:
+ if (x->p_receives) freebytes((void *)x->p_receives, (int)sizeof(t_symbol *)*x->p_columns);
+ return(NIL);
+}
+
+
+
+
+
+
+/* NOTE: light error checking --- allocates memory and manages allocation list */
+/* returns NIL (on error) or pointer to existing or new data matrix */
+/* note memory size is columns*(rows+1) + 1 - where the extra row is for the edit buffer */
+/* and the extra cell is for the DIRTY flag */
+/* class independent allocation - needs class independent dispose method */
+
+t_atom **pbank_getmem(t_symbol *name,int columns,int rows)
+{
+ int z,i;
+ t_shared *piss = NIL;
+ t_atom **matrix,*av;
+ char crap[256];
+
+ if (!InRange(columns, 1,MAX_COLUMNS-1)) columns = DEFAULT_COLUMNS;
+ if (!InRange(rows, 1,MAX_ROWS-1)) rows = DEFAULT_ROWS;
+
+ if (name)
+ {
+ if (name->s_thing)
+ {
+ if (name->s_thing == pbank_ID->s_thing) /* memory already exists - increment refcount */
+ {
+ piss = pbank_banks; /* maintain list of instance memories */
+ while(piss)
+ {
+ if (piss->s_sym == name) /* pbank instances sharing memory */
+ {
+ if (piss->s_columns != columns || piss->s_rows != rows)
+ {
+ error("pbank_getmem: pbank %s's dimensions must be (%d x %d)",name->s_name,
+ piss->s_columns,piss->s_rows);
+ return(NIL);
+ }
+ piss->s_refcount++;
+ /* post("%s refcount=%d",piss->s_sym->s_name,piss->s_refcount); */
+ return(piss->s_data);
+ }
+ piss = piss->s_next;
+ }
+ error("pbank_getmem: bug: name %s not found",name->s_name);
+ return(NIL);
+ }
+ else /* bad symbol - already taken - can't do anything */
+ {
+ error("pbank_getmem: symbol %s already being used by another object",name->s_name);
+ return(NIL);
+ }
+ }
+ else /* allocate entry for given name in shared memory list */
+ {
+
+ name->s_thing = pbank_ID->s_thing; /* associate symbol with pbank class */
+ piss = getbytes(sizeof(t_shared)); /* allocate new entry */
+ piss->s_sym = name;
+ piss->s_refcount = 1;
+ piss->s_next = (pbank_banks) ? pbank_banks:NIL;
+ pbank_banks = piss; /* link it in at head of list */
+ /* post("PISS alloc %lx",piss); */
+ }
+ }
+
+ /* allocate memory for data matrix */
+ /* allocate "rows" + 1 (edbuff) + 1 (dirty flag) ROWS */
+ matrix = (t_atom **)getbytes((int)sizeof(t_atom *)*(rows+EDBUFF+DIRTFLAG));
+ for (z=0;z<rows+EDBUFF;z++)
+ matrix[z] = (t_atom *)getbytes(sizeof(t_atom)*columns);
+
+
+ for (z=0;z<rows+EDBUFF;z++) /* data matrix - all 0's */
+ {
+
+ sprintf(crap,"untitled_%d", z);
+ av = matrix[z];
+ SETSYMBOL(av,gensym(crap));
+ for (i=1;i<columns;i++)
+ SETFLOAT(av+i,0L);
+ }
+
+ matrix[rows-1+EDBUFF+DIRTFLAG] = NIL; /* set dirty flag cell to 0 */
+ if (piss)
+ {
+ piss->s_data = matrix; /* keep pointer to memory with shared */
+ piss->s_columns = columns;
+ piss->s_rows = rows;
+ }
+ return(matrix); /* no errors - return pointer to data matrix */
+}
+
+
+
+
+
+
+
+
+
diff --git a/nusmuk-utils/pbank.h b/nusmuk-utils/pbank.h
new file mode 100644
index 0000000..7bd1f44
--- /dev/null
+++ b/nusmuk-utils/pbank.h
@@ -0,0 +1,14 @@
+
+
+
+typedef struct shared
+{
+ t_symbol *s_sym; /* shared memory name */
+ t_atom **s_data; /* memory pointer */
+ int s_rows; /* memory dimension */
+ int s_columns; /* memory dimension */
+ int s_refcount; /* number of objects pointing to "s_data" */
+ struct shared *s_next;
+} t_shared;
+
+
diff --git a/nusmuk-utils/pps-help.pd b/nusmuk-utils/pps-help.pd
new file mode 100644
index 0000000..2702e65
--- /dev/null
+++ b/nusmuk-utils/pps-help.pd
@@ -0,0 +1,13 @@
+#N canvas 0 0 450 300 10;
+#X obj 40 28 pps;
+#X text 85 27 shortcut for :;
+#X obj 209 29 list prepend set;
+#X obj 209 50 list trim;
+#X obj 45 163 pps;
+#X msg 45 190 41 0;
+#X obj 45 137 pack f foo;
+#X floatatom 45 118 5 0 0 0 - - -;
+#X connect 2 0 3 0;
+#X connect 4 0 5 0;
+#X connect 6 0 4 0;
+#X connect 7 0 6 0;
diff --git a/nusmuk-utils/pps.pd b/nusmuk-utils/pps.pd
new file mode 100644
index 0000000..3e4c023
--- /dev/null
+++ b/nusmuk-utils/pps.pd
@@ -0,0 +1,8 @@
+#N canvas 0 0 450 300 10;
+#X obj 55 24 inlet;
+#X obj 55 43 list prepend set;
+#X obj 55 65 list trim;
+#X obj 55 87 outlet;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
diff --git a/nusmuk-utils/rand_diff-help.pd b/nusmuk-utils/rand_diff-help.pd
new file mode 100755
index 0000000..bbda493
--- /dev/null
+++ b/nusmuk-utils/rand_diff-help.pd
@@ -0,0 +1,18 @@
+#N canvas 93 73 450 300 10;
+#X msg 53 132 bang;
+#X floatatom 53 232 0 0 0 0 - - -;
+#X msg 63 156 seed 123;
+#X text 105 130 bang for output;
+#X text 145 156 message to set the seed;
+#X floatatom 134 183 0 0 0 0 - - -;
+#X text 164 183 inlet to reset the range;
+#X text 144 206 argument to initialize the range;
+#X text 125 77 \$1 : range;
+#X obj 53 206 rand_diff 10;
+#X text 45 31 rand-diff - random number with very few redondancy from
+precedent output;
+#X text 45 60 output are mostly growing;
+#X connect 0 0 9 0;
+#X connect 2 0 9 0;
+#X connect 5 0 9 1;
+#X connect 9 0 1 0;
diff --git a/nusmuk-utils/rand_diff.pd b/nusmuk-utils/rand_diff.pd
new file mode 100644
index 0000000..3682090
--- /dev/null
+++ b/nusmuk-utils/rand_diff.pd
@@ -0,0 +1,34 @@
+#N canvas 90 260 450 300 10;
+#X obj 51 169 random;
+#X obj 81 207 %;
+#X obj 51 207 +;
+#X obj 51 188 + 1;
+#X obj 174 100 sqrt;
+#X obj 174 138 i;
+#X obj 174 119 * 1.5;
+#X obj 174 11 inlet;
+#X obj 51 30 route bang seed;
+#X obj 51 11 inlet;
+#X obj 51 49 t b b;
+#X msg 102 81 seed \$1;
+#X obj 81 227 outlet;
+#X obj 174 81 \$1;
+#X obj 187 55 loadbang;
+#X connect 0 0 3 0;
+#X connect 1 0 2 1;
+#X connect 1 0 12 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X connect 4 0 6 0;
+#X connect 5 0 0 1;
+#X connect 6 0 5 0;
+#X connect 7 0 13 0;
+#X connect 8 0 10 0;
+#X connect 8 1 11 0;
+#X connect 9 0 8 0;
+#X connect 10 0 0 0;
+#X connect 10 1 13 0;
+#X connect 11 0 0 0;
+#X connect 13 0 1 1;
+#X connect 13 0 4 0;
+#X connect 14 0 13 0;
diff --git a/nusmuk-utils/randn-help.pd b/nusmuk-utils/randn-help.pd
new file mode 100755
index 0000000..b0787d9
--- /dev/null
+++ b/nusmuk-utils/randn-help.pd
@@ -0,0 +1,20 @@
+#N canvas 460 231 523 310 10;
+#X text 49 31 _randn - random numbers in gaussian distribution;
+#X text 111 67 \$2 : mean;
+#X text 111 49 \$1 : standard deviation;
+#X msg 73 112 bang;
+#X floatatom 103 161 0 0 0 0 - - -;
+#X floatatom 73 242 0 0 0 0 - - -;
+#X msg 83 136 seed 123;
+#X text 125 110 bang for output;
+#X text 165 136 message to set the seed;
+#X text 136 160 inlet to reset the std;
+#X text 149 216 argument to initialize the std and mean;
+#X floatatom 133 189 0 0 0 0 - - -;
+#X text 163 189 inlet to reset the mean;
+#X obj 73 217 randn 5 0;
+#X connect 3 0 13 0;
+#X connect 4 0 13 1;
+#X connect 6 0 13 0;
+#X connect 11 0 13 2;
+#X connect 13 0 5 0;
diff --git a/nusmuk-utils/randn.pd b/nusmuk-utils/randn.pd
new file mode 100755
index 0000000..c38ae79
--- /dev/null
+++ b/nusmuk-utils/randn.pd
@@ -0,0 +1,49 @@
+#N canvas 146 129 994 651 10;
+#X text 273 329 u1;
+#X obj 310 376 log;
+#X obj 310 401 * -2;
+#X obj 310 430 sqrt;
+#X obj 419 435 cos;
+#X obj 419 405 * 6.283;
+#X obj 310 463 *;
+#X text 521 339 u2;
+#X text 370 512 sigma;
+#X text 373 557 mean;
+#X obj 375 258 t b b;
+#X obj 310 214 route seed;
+#X obj 419 259 * 65636;
+#X obj 310 156 inlet;
+#X msg 419 311 seed \$1;
+#X msg 310 298 seed \$1;
+#X obj 310 592 outlet;
+#X obj 310 514 * \$1;
+#X obj 310 552 + \$2;
+#X obj 384 482 inlet;
+#X obj 471 483 inlet;
+#X obj 310 328 random 6.5e+06;
+#X obj 310 355 / 6.5e+06;
+#X obj 419 337 random 6.5e+06;
+#X obj 419 364 / 6.5e+06;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 3 0 6 0;
+#X connect 4 0 6 1;
+#X connect 5 0 4 0;
+#X connect 6 0 17 0;
+#X connect 10 0 21 0;
+#X connect 10 1 23 0;
+#X connect 11 0 12 0;
+#X connect 11 0 15 0;
+#X connect 11 1 10 0;
+#X connect 12 0 14 0;
+#X connect 13 0 11 0;
+#X connect 14 0 23 0;
+#X connect 15 0 21 0;
+#X connect 17 0 18 0;
+#X connect 18 0 16 0;
+#X connect 19 0 17 1;
+#X connect 20 0 18 1;
+#X connect 21 0 22 0;
+#X connect 22 0 1 0;
+#X connect 23 0 24 0;
+#X connect 24 0 5 0;
diff --git a/nusmuk-utils/rnd_flow-help.pd b/nusmuk-utils/rnd_flow-help.pd
new file mode 100644
index 0000000..05adb21
--- /dev/null
+++ b/nusmuk-utils/rnd_flow-help.pd
@@ -0,0 +1,27 @@
+#N canvas 579 67 428 392 10;
+#X obj 27 70 metro 20;
+#X obj 27 53 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 1 1
+;
+#X floatatom 68 92 5 0 0 0 - - -;
+#X floatatom 109 108 5 0 0 0 - - -;
+#X floatatom 150 124 5 0 0 0 - - -;
+#X obj 27 211 vsl 15 128 0 127 0 0 empty empty empty 0 -9 0 10 -262144
+-1 -1 6171 1;
+#X obj 27 171 + 1;
+#X obj 27 190 * 64;
+#X obj 27 33 loadbang;
+#X obj 242 308 filtered_random;
+#X text 241 287 related to :;
+#X text 113 90 amplitude max of each step;
+#X text 155 107 low pass filter of the output;
+#X text 195 124 high pass filter of the output;
+#X obj 27 152 rnd_flow 0.1 20 20;
+#X connect 0 0 14 0;
+#X connect 1 0 0 0;
+#X connect 2 0 14 1;
+#X connect 3 0 14 2;
+#X connect 4 0 14 3;
+#X connect 6 0 7 0;
+#X connect 7 0 5 0;
+#X connect 8 0 1 0;
+#X connect 14 0 6 0;
diff --git a/nusmuk-utils/rnd_flow.pd b/nusmuk-utils/rnd_flow.pd
new file mode 100644
index 0000000..70791e3
--- /dev/null
+++ b/nusmuk-utils/rnd_flow.pd
@@ -0,0 +1,70 @@
+#N canvas 596 195 579 445 10;
+#X obj 77 151 random 10001;
+#X obj 77 170 - 5000;
+#X obj 77 189 / 5000;
+#X obj 77 339 +;
+#X msg 131 74 0;
+#X obj 77 54 route bang reset;
+#X obj 77 246 +;
+#X obj 332 218 + 1;
+#X obj 332 181 1;
+#X obj 332 161 /;
+#X msg 332 141 1 \$1;
+#X obj 77 265 / 2;
+#X obj 77 227 * 1;
+#X obj 77 34 inlet;
+#X obj 77 365 outlet;
+#X obj 220 34 inlet;
+#X obj 332 34 inlet;
+#X obj 471 34 inlet;
+#X obj 77 208 * \$1;
+#X obj 109 338 * 1;
+#X obj 342 53 loadbang;
+#X obj 332 72 \$2;
+#X obj 332 91 max 0.0001;
+#X text 225 92 amplitude;
+#X text 342 109 filter (lop);
+#X text 345 124 0 .. 100;
+#X obj 471 91 / 1000;
+#X msg 471 110 1 \$1;
+#X obj 471 129 -;
+#X obj 480 53 loadbang;
+#X obj 471 72 \$3;
+#X text 474 153 filter (hip);
+#X text 476 168 0 .. 100;
+#X obj 230 53 loadbang;
+#X obj 220 72 \$1;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 18 0;
+#X connect 3 0 14 0;
+#X connect 3 0 19 0;
+#X connect 4 0 3 1;
+#X connect 4 0 6 1;
+#X connect 5 0 0 0;
+#X connect 5 1 4 0;
+#X connect 6 0 11 0;
+#X connect 7 0 11 1;
+#X connect 8 0 7 0;
+#X connect 8 0 12 1;
+#X connect 9 0 8 0;
+#X connect 10 0 9 0;
+#X connect 11 0 6 1;
+#X connect 11 0 3 0;
+#X connect 12 0 6 0;
+#X connect 13 0 5 0;
+#X connect 15 0 34 0;
+#X connect 16 0 21 0;
+#X connect 17 0 30 0;
+#X connect 18 0 12 0;
+#X connect 19 0 3 1;
+#X connect 20 0 21 0;
+#X connect 21 0 22 0;
+#X connect 22 0 10 0;
+#X connect 26 0 27 0;
+#X connect 27 0 28 0;
+#X connect 28 0 19 1;
+#X connect 29 0 30 0;
+#X connect 30 0 26 0;
+#X connect 33 0 34 0;
+#X connect 34 0 18 1;
diff --git a/rnd_metro-help.pd b/nusmuk-utils/rnd_metro-help.pd
index 0d40928..0d40928 100644
--- a/rnd_metro-help.pd
+++ b/nusmuk-utils/rnd_metro-help.pd
diff --git a/rnd_metro.pd b/nusmuk-utils/rnd_metro.pd
index d16905a..d16905a 100644
--- a/rnd_metro.pd
+++ b/nusmuk-utils/rnd_metro.pd
diff --git a/puremapping/speedlimit-help.pd b/puremapping/speedlimit-help.pd
new file mode 100644
index 0000000..49020db
--- /dev/null
+++ b/puremapping/speedlimit-help.pd
@@ -0,0 +1,15 @@
+#N canvas 630 215 450 300 10;
+#X floatatom 96 112 5 0 0 0 - - -;
+#X floatatom 96 153 5 0 0 0 - - -;
+#X text 55 31 limit data flow to the specific time;
+#X obj 139 179 t b b;
+#X obj 139 202 timer;
+#X floatatom 139 226 5 0 0 0 - - -;
+#X obj 96 131 speedlimit 500;
+#X text 54 47 (same than speedlim \, but as an abstraction);
+#X connect 0 0 6 0;
+#X connect 3 0 4 0;
+#X connect 3 1 4 1;
+#X connect 4 0 5 0;
+#X connect 6 0 1 0;
+#X connect 6 0 3 0;
diff --git a/puremapping/speedlimit.pd b/puremapping/speedlimit.pd
new file mode 100644
index 0000000..8b732f3
--- /dev/null
+++ b/puremapping/speedlimit.pd
@@ -0,0 +1,40 @@
+#N canvas 0 0 440 550 10;
+#X obj 45 33 inlet;
+#X obj 44 448 outlet;
+#X obj 68 124 list;
+#X msg 122 272 1;
+#X msg 111 102 1;
+#X msg 70 273 0;
+#X obj 44 214 t a b b;
+#X obj 90 350 sel 1;
+#X obj 89 378 f;
+#X obj 59 402 sel 1;
+#X obj 45 68 t a a b;
+#X obj 44 162 spigot 1;
+#X obj 177 339 f;
+#X obj 121 297 t f f;
+#X obj 71 298 t f f;
+#X obj 265 24 inlet;
+#X obj 121 248 delay \$1;
+#X connect 0 0 10 0;
+#X connect 2 0 11 0;
+#X connect 3 0 13 0;
+#X connect 4 0 8 1;
+#X connect 5 0 14 0;
+#X connect 6 0 1 0;
+#X connect 6 1 5 0;
+#X connect 6 2 16 0;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 9 0 2 0;
+#X connect 10 0 11 0;
+#X connect 10 1 2 1;
+#X connect 10 2 4 0;
+#X connect 11 0 6 0;
+#X connect 12 0 11 1;
+#X connect 13 0 7 0;
+#X connect 13 1 12 0;
+#X connect 14 0 8 1;
+#X connect 14 1 12 0;
+#X connect 15 0 16 1;
+#X connect 16 0 3 0;