aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Christoph Steiner <eighthave@users.sourceforge.net>2012-10-04 22:24:37 +0000
committerHans-Christoph Steiner <eighthave@users.sourceforge.net>2012-10-04 22:24:37 +0000
commit84231a000a4f06e34efa0d3700377dd3cc447e0b (patch)
tree9cec4db39062de619d61c9197fa7dfc5708bc059
parentb418fb91e7bb45d7b5f1eb8b19703441ae94eb13 (diff)
took FFTease2.5_Pd_OSX.zip and unpacked it into a Library Template layout
original source: http://www.somasa.qub.ac.uk/~elyon/LyonSoftware/MaxMSP/FFTease/FFTease2.5_Pd_OSX.zip svn path=/trunk/externals/fftease/; revision=16331
-rw-r--r--LICENSE.txt15
-rw-r--r--MSPd.h38
-rw-r--r--PenroseOscil.c40
-rw-r--r--PenroseOscil.h8
-rw-r--r--PenroseRand.c13
-rw-r--r--PenroseRand.h3
-rw-r--r--README5
-rw-r--r--README.txt19
-rw-r--r--ampdb.pd20
-rw-r--r--bloscbank.c1
-rw-r--r--bthresher~-help.pd193
-rw-r--r--bthresher~.c8
-rw-r--r--burrow~-help.pd129
-rw-r--r--burrow~.c8
-rw-r--r--cavoc27~-help.pd86
-rw-r--r--cavoc~-help.pd96
-rw-r--r--cavoc~.c8
-rw-r--r--centerring~-help.pd77
-rw-r--r--centerring~.c8
-rw-r--r--codepend~-help.pd140
-rw-r--r--codepend~.c8
-rw-r--r--convert.c1
-rw-r--r--crossx~-help.pd135
-rw-r--r--crossx~.c5
-rw-r--r--dentist~-help.pd112
-rw-r--r--dentist~.c8
-rw-r--r--disarrain~-help.pd109
-rw-r--r--disarrain~.c8
-rw-r--r--disarray~-help.pd67
-rw-r--r--disarray~.c12
-rw-r--r--drown~-help.pd64
-rw-r--r--drown~.c8
-rw-r--r--ether~.c8
-rw-r--r--fft.c1
-rw-r--r--fft4.c1
-rw-r--r--fftease-system.pd38
-rw-r--r--fftease.h61
-rw-r--r--fftease_setup.c5
-rw-r--r--fold.c1
-rw-r--r--help/burrow~-help.pd90
-rw-r--r--help/cross~-help.pd88
-rw-r--r--help/dentist~-help.pd65
-rw-r--r--help/disarray~-help.pd67
-rw-r--r--help/drown~-help.pd61
-rw-r--r--help/ether~-help.pd84
-rw-r--r--help/morphine~-help.pd77
-rw-r--r--help/residency~-help.pd33
-rw-r--r--help/scrape~-help.pd72
-rw-r--r--help/shapee~-help.pd62
-rw-r--r--help/swinger~-help.pd62
-rw-r--r--help/taint~-help.pd83
-rw-r--r--help/thresher~-help.pd46
-rw-r--r--help/vacancy~-help.pd97
-rw-r--r--help/xsyn~-help.pd61
-rw-r--r--leaker~-help.pd106
-rw-r--r--leaker~.c8
-rw-r--r--leanconvert.c1
-rw-r--r--leanunconvert.c1
-rw-r--r--limit_fftsize.c1
-rw-r--r--makewindows.c1
-rw-r--r--manual/code-notes.rtf51
-rw-r--r--mindwarp~-help.pd168
-rw-r--r--mindwarp~.c8
-rw-r--r--morphine~-help.pd120
-rw-r--r--morphine~.c8
-rw-r--r--multyq~-help.pd92
-rw-r--r--multyq~.c8
-rw-r--r--overlapadd.c1
-rw-r--r--power_of_two.c33
-rw-r--r--presidency~-help.pd250
-rw-r--r--presidency~.c8
-rw-r--r--pvcompand~-help.pd86
-rw-r--r--pvcompand~.c8
-rw-r--r--pvgrain~-help.pd361
-rw-r--r--pvgrain~.c4
-rw-r--r--pvharm~-help.pd87
-rw-r--r--pvharm~.c8
-rw-r--r--pvoc~-help.pd114
-rw-r--r--pvoc~.c12
-rw-r--r--pvtuner.h120
-rw-r--r--pvtuner~-help.pd139
-rw-r--r--pvtuner~.c8
-rw-r--r--pvwarp~-help.pd141
-rw-r--r--pvwarp~.c873
-rw-r--r--qsortE.c1
-rw-r--r--reanimator~-help.pd163
-rw-r--r--reanimator~.c4
-rw-r--r--resent~-help.pd143
-rw-r--r--resent~.c8
-rw-r--r--residency~-help.pd124
-rw-r--r--residency~.c4
-rw-r--r--scrape~-help.pd88
-rw-r--r--scrape~.c8
-rw-r--r--shapee~-help.pd109
-rw-r--r--shapee~.c4
-rw-r--r--swinger~-help.pd94
-rw-r--r--swinger~.c6
-rw-r--r--taint~-help.pd147
-rw-r--r--taint~.c8
-rw-r--r--thresher~-help.pd63
-rw-r--r--thresher~.c17
-rw-r--r--unconvert.c34
-rw-r--r--vacancy~-help.pd130
-rw-r--r--vacancy~.c8
-rw-r--r--xsyn~-help.pd79
-rw-r--r--xsyn~.c8
106 files changed, 5518 insertions, 1173 deletions
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..6d20b06
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,15 @@
+This software is released under the MIT License, as described here:
+http://www.opensource.org/licenses/mit-license.php
+and here: http://tinyurl.com/y6u53r
+
+-EL
+
+*******************************************************************
+
+FFTease is Copyright (c) 1999-2008 Eric Lyon and Christopher Penrose
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/MSPd.h b/MSPd.h
new file mode 100644
index 0000000..dbf689c
--- /dev/null
+++ b/MSPd.h
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+/* choose your poison */
+
+#define MSP (0)
+#define PD (!MSP)
+/* for compiling under XP */
+
+
+#ifndef PIOVERTWO
+#define PIOVERTWO 1.5707963268
+#define TWOPI 6.2831853072
+#endif
+
+#if MSP
+#include "ext.h"
+#include "z_dsp.h"
+#include "buffer.h"
+#include "ext_obex.h"
+#define t_floatarg double
+#endif
+
+#if PD
+#include "m_pd.h"
+#define t_floatarg float
+#endif
+
+/* because Max and Pd have different ideas of what A_FLOAT is, use t_floatarg
+to force consistency. Otherwise functions that look good will fail on some
+hardware. Also note that Pd messages cannot accept arguments of type A_LONG. */
+
+
+
+
+
diff --git a/PenroseOscil.c b/PenroseOscil.c
new file mode 100644
index 0000000..78cd7b6
--- /dev/null
+++ b/PenroseOscil.c
@@ -0,0 +1,40 @@
+#include <math.h>
+#include "PenroseOscil.h"
+
+
+float frequencyToIncrement( float samplingRate, float frequency, int bufferLength ) {
+
+ return (frequency / samplingRate) * (float) bufferLength;
+}
+
+void makeSineBuffer( float *buffer, int bufferLength ) {
+
+ int i;
+
+ float myTwoPi = 8. * atan(1.);
+
+ for ( i=0; i <= bufferLength; i++ )
+ *(buffer+i) = sin( myTwoPi * ((float) i / (float) bufferLength) );
+
+ return;
+}
+
+
+float bufferOscil( float *phase, float increment, float *buffer,
+ int bufferLength )
+{
+
+ float sample;
+
+ while ( *phase > bufferLength )
+ *phase -= bufferLength;
+
+ while ( *phase < 0. )
+ *phase += bufferLength;
+
+ sample = *( buffer + (int) (*phase) );
+
+ *phase += increment;
+
+ return sample;
+}
diff --git a/PenroseOscil.h b/PenroseOscil.h
new file mode 100644
index 0000000..a47414d
--- /dev/null
+++ b/PenroseOscil.h
@@ -0,0 +1,8 @@
+
+float frequencyToIncrement( float samplingRate, float frequency,
+ int bufferLength );
+
+void makeSineBuffer( float *buffer, int bufferLength );
+
+float bufferOscil( float *phase, float increment, float *buffer,
+ int bufferLength );
diff --git a/PenroseRand.c b/PenroseRand.c
new file mode 100644
index 0000000..98f396e
--- /dev/null
+++ b/PenroseRand.c
@@ -0,0 +1,13 @@
+#include "PenroseRand.h"
+
+float rrand(int *seed)
+{
+ int i = ((*seed = *seed * 1103515245 + 12345)>>16) & 077777;
+ return((float)i/16384. - 1.);
+}
+
+float prand(int *seed)
+{
+ int i = ((*seed = *seed * 1103515245 + 12345)>>16) & 077777;
+ return((float)i/32768.);
+}
diff --git a/PenroseRand.h b/PenroseRand.h
new file mode 100644
index 0000000..fb06588
--- /dev/null
+++ b/PenroseRand.h
@@ -0,0 +1,3 @@
+
+float rrand(int *seed);
+float prand(int *seed);
diff --git a/README b/README
deleted file mode 100644
index 20aeafc..0000000
--- a/README
+++ /dev/null
@@ -1,5 +0,0 @@
-This is source code for FFTease 2.5. It is up to you to link it into
-your favorite compiler system. You are welcome to study, modify or do
-anything else with it.
-
-FFTease is copyright 2000-2005 Eric Lyon and Christopher Penrose. \ No newline at end of file
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..39721b0
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,19 @@
+FFTease 2.5 by Eric Lyon and Christopher Penrose
+
+This is the third release of FFTease, a set of live spectral sound processors for Max/MSP and Pd. This Pd distribution is compiled for Linux, OS X, and Windows. Move the appropriate set of binaries from "bin" to the Pd "extra" folder. Move the contents of "help" to the Pd "doc/5.reference" directory. You are now ready to use FFTease.
+
+Caveat: these objects are CPU intensive. A few of these objects in a patch could push your computer to its limits. Be very careful with playback volume as some of the objects produce dramatically different (lower or higher) overall levels.
+
+The FFT size, which must be a power of 2, is calculated relative to the Pd block size. It is recommended to use FFTease externals in a sub-patch that contains a block~ object, granting you control of the local block size, and thus FFT size. A larger block size results in a larger FFT size. Don't expect a great savings in CPU usage with smaller block sizes. But do expect increased CPU load as you crank the block size up. A block size of 256, with a default overlap of 4 gives an FFT size of 1024 that works acceptably well in many cases. With some of these objects, an even smaller block size/FFT size can actually work better. See the abstraction "fftease-system.pd" for more information on how to control these parameters.
+
+Acknowledgements: This work draws heavily on the phase vocoder code presented by F. Richard Moore in his classic "Elements of Computer Music." Additional inspiration was derived from work on cross synthesis and noise reduction by Mark Dolson at CARL in the mid-1980s. We also wish to thank Miller Puckette and David Zicarelli for designing and implementing the framework under which FFTease is presented.
+
+The authors would like to warmly acknowledge the support of the following institutions: Brown University, Dartmouth College, IAMAS, Keio University, the University of Manchester, and Queen's University Belfast.
+
+FFTease is copyright 2000-2009 Eric Lyon and Christopher Penrose. FFTease is released under the MIT license.
+
+Eric Lyon
+e.lyon@qub.ac.uk
+
+Christopher Penrose
+penrose@silvertone.princeton.edu
diff --git a/ampdb.pd b/ampdb.pd
new file mode 100644
index 0000000..a49c656
--- /dev/null
+++ b/ampdb.pd
@@ -0,0 +1,20 @@
+#N canvas 945 219 212 299 10;
+#X obj 32 107 pow;
+#X obj 32 64 t b f;
+#X msg 32 83 10;
+#X obj 54 170 /;
+#X obj 32 127 t b f;
+#X msg 32 148 1;
+#X obj 32 41 * -0.05;
+#X obj 32 19 inlet;
+#X obj 54 193 outlet;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 1 1 0 1;
+#X connect 2 0 0 0;
+#X connect 3 0 8 0;
+#X connect 4 0 5 0;
+#X connect 4 1 3 1;
+#X connect 5 0 3 0;
+#X connect 6 0 1 0;
+#X connect 7 0 6 0;
diff --git a/bloscbank.c b/bloscbank.c
new file mode 100644
index 0000000..c35ab0d
--- /dev/null
+++ b/bloscbank.c
@@ -0,0 +1 @@
+ #include "fftease.h" void bloscbank( float *S, float *O, int D, float iD, float *lf, float *la, float *index, float *tab, int len, float synt, int lo, int hi ) { int amp,freq,chan, i; float a,ainc,f,finc,address; for ( chan = lo; chan < hi; chan++ ) { freq = ( amp = ( chan << 1 ) ) + 1; if ( S[amp] > synt ){ finc = ( S[freq] - ( f = lf[chan] ) )* iD; ainc = ( S[amp] - ( a = la[chan] ) )* iD; address = index[chan]; for ( i = 0; i < D ; i++ ) { O[i] += a*tab[ (int) address ]; address += f; while ( address >= len ) address -= len; while ( address < 0 ) address += len; a += ainc; f += finc; } lf[chan] = S[freq]; la[chan] = S[amp]; index[chan] = address; } } } \ No newline at end of file
diff --git a/bthresher~-help.pd b/bthresher~-help.pd
new file mode 100644
index 0000000..25bdfd1
--- /dev/null
+++ b/bthresher~-help.pd
@@ -0,0 +1,193 @@
+#N canvas 609 64 625 468 10;
+#N canvas 0 22 478 328 bthresher-block 0;
+#X obj 177 189 block~ 256;
+#X obj 188 161 outlet~;
+#X obj 344 173 outlet;
+#X obj 188 40 inlet~;
+#X obj 266 65 inlet;
+#X obj 344 69 inlet;
+#X obj 391 101 inlet;
+#X obj 188 117 bthresher~ 0.1 0.97 4 1;
+#X connect 3 0 7 0;
+#X connect 4 0 7 1;
+#X connect 5 0 7 2;
+#X connect 6 0 7 0;
+#X connect 7 0 1 0;
+#X connect 7 1 2 0;
+#X restore 154 133 pd bthresher-block;
+#X obj 154 206 dac~;
+#X obj 154 34 noise~;
+#N canvas 613 44 522 372 messages 0;
+#X obj 32 248 outlet;
+#N canvas 314 293 617 400 individual-bin-control 0;
+#X obj 23 363 outlet;
+#X obj 220 97 pack f f f;
+#X floatatom 220 48 5 0 0 1 bin_number - -;
+#X floatatom 252 62 5 0 0 1 damping_factor - -;
+#X floatatom 285 78 5 0 0 1 threshold - -;
+#X text 23 29 format:;
+#X msg 153 241 0 0.968693 0.124173 1 0.968693 0.124173 2 0.968693 0.124173
+3 0.968693 0.124173 4 0.968693 0.124173 5 0.93 0.01 6 0.93 0.01 7 0.93
+0.01 8 0.93 0.01 9 0.93 0.01 10 0.93 0.01 11 0.93 0.01 12 0.93 0.1
+13 0.93 0.1 14 0.93 0.1 15 0.93 0.1 16 0.93 0.1 17 0.968693 0.124173
+18 0.968693 0.124173 19 0.968693 0.124173 20 0.968693 0.124173;
+#X msg 23 56 bin 5 0.93 0.01;
+#X text 23 41 bin # \, damping \, threshold;
+#X msg 220 139 bin \$1 \$2 \$3;
+#X text 153 223 or send raw data controlling many bins from a list
+;
+#X text 23 17 affect a single bin;
+#X text 219 31 construct bin message from components;
+#X connect 1 0 9 0;
+#X connect 2 0 1 0;
+#X connect 3 0 1 1;
+#X connect 4 0 1 2;
+#X connect 6 0 0 0;
+#X connect 7 0 0 0;
+#X connect 9 0 0 0;
+#X restore 32 20 pd individual-bin-control;
+#N canvas 0 22 498 348 global-bin-control 0;
+#X msg 253 203 alldamp \$1;
+#X msg 221 105 allthresh \$1;
+#X floatatom 221 73 5 0 0 0 - allthresh -;
+#X floatatom 253 181 5 0 0 0 - alldamp -;
+#X obj 221 238 outlet;
+#X obj 62 90 vsl 15 128 0 0.2 0 0 allthresh allthresh-init allthresh
+0 -8 0 8 -117632 -1 -1 6985 1;
+#X obj 117 90 vsl 15 128 0 1.1 0 0 alldamp alldamp-init alldamp 0 -8
+0 8 -117632 -1 -1 11084 1;
+#X connect 0 0 4 0;
+#X connect 1 0 4 0;
+#X connect 2 0 1 0;
+#X connect 3 0 0 0;
+#X restore 69 113 pd global-bin-control;
+#N canvas 0 22 494 344 random-bin-control 0;
+#X obj 8 105 outlet;
+#X text 4 33 format: min max;
+#X msg 8 50 rthreshold 0.05 0.7;
+#X msg 149 49 rdamper 0.8 0.999;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X restore 60 78 pd random-bin-control;
+#X text 222 21 <- start here;
+#N canvas 444 60 502 352 system 0;
+#X obj 26 268 outlet;
+#X text 122 87 arg must be power of 2;
+#X obj 26 19 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X msg 26 43 mute \$1;
+#X msg 124 103 overlap 4;
+#X msg 124 122 overlap 2;
+#X text 193 124 <- cuts CPU demand in half;
+#X text 197 105 <- default;
+#X msg 134 252 fftinfo;
+#X msg 140 185 winfac 1;
+#X text 136 166 relative size of input window to FFT;
+#X msg 210 186 winfac 2;
+#X connect 2 0 3 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X connect 8 0 0 0;
+#X connect 9 0 0 0;
+#X connect 11 0 0 0;
+#X restore 83 158 pd system;
+#X msg 197 189 dump;
+#X text 195 172 with a list message;
+#X text 195 145 output current state;
+#X text 196 159 which can then be reloaded;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 0 0;
+#X restore 275 97 pd messages;
+#X msg 79 242 \; pd dsp \$1;
+#X obj 79 221 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj 154 163 *~ 0.2;
+#X floatatom 194 70 5 0 0 0 - scale-thresh -;
+#X floatatom 234 95 5 0 0 0 - scale-damping -;
+#X obj 191 268 hsl 128 15 0 2 0 0 scale-thresh slider-init scale-thresh
+-2 -6 0 8 -258369 -1 -1 6350 1;
+#X obj 191 302 hsl 128 15 0 2 0 0 scale-damping slider-init scale-damping
+-2 -6 0 8 -258369 -1 -1 6350 1;
+#N canvas 137 230 511 492 capture 0;
+#X obj 8 12 inlet;
+#X text 20 173 clear;
+#X msg 8 237 0 0.960032 0.11 1 0.960032 0.11 2 0.960032 0.11 3 0.960032
+0.11 4 0.960032 0.11 5 0.960032 0.11 6 0.960032 0.11 7 0.960032 0.11
+8 0.960032 0.11 9 0.960032 0.11 10 0.960032 0.11 11 0.960032 0.11 12
+0.960032 0.11 13 0.960032 0.11 14 0.960032 0.11 15 0.960032 0.11 16
+0.960032 0.11 17 0.960032 0.11 18 0.960032 0.11 19 0.960032 0.11 0
+0.838661 0.383391 1 0.85394 0.349312 2 0.963181 0.277742 3 0.863287
+0.111771 4 0.871333 0.331876 5 0.940383 0.510999 6 0.94973 0.125378
+7 0.992569 0.100742 8 0.80563 0.290001 9 0.943857 0.0718399 10 0.971641
+0.17489 11 0.928632 0.356374 12 0.871212 0.144183 13 0.933891 0.516592
+14 0.918071 0.480113 15 0.851894 0.330705 16 0.97568 0.339909 17 0.98587
+0.380415 18 0.859807 0.39325 19 0.839784 0.422369 0 0.838661 0.383391
+1 0.85394 0.349312 2 0.963181 0.277742 3 0.863287 0.111771 4 0.871333
+0.331876 5 0.940383 0.510999 6 0.94973 0.125378 7 0.992569 0.100742
+8 0.80563 0.290001 9 0.943857 0.0718399 10 0.971641 0.17489 11 0.928632
+0.356374 12 0.871212 0.144183 13 0.933891 0.516592 14 0.918071 0.480113
+15 0.851894 0.330705 16 0.97568 0.339909 17 0.98587 0.380415 18 0.859807
+0.39325 19 0.839784 0.422369;
+#X msg 23 191 set;
+#X text 82 15 capture (some) list output from 'dump' message;
+#X msg 8 59 add2 \$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 \$30 \$31 \$32 \$33 \$34 \$35 \$36 \$37 \$38 \$39 \$40
+\$41 \$42 \$43 \$44 \$45 \$46 \$47 \$48 \$49 \$50 \$51 \$52 \$53 \$54
+\$55 \$56 \$57 \$58 \$59 \$60;
+#X text 86 118 The "dump" message outputs the current state of bthresher~
+as a series of triplets [bin# \, damp factor \, threshold]. This data
+can be captured as a list and reloaded to itself or any other bthresher~
+unit. In this example we only show the first twenty triplets. Since
+there are potentially as many as N/2 triplets where N is the FFT size
+\, you would need to modify this subpatch to capture all the information
+of the current state of bthresher~. (A version of Pd with the "prepend"
+object would make your life easier here.);
+#X connect 0 0 5 0;
+#X connect 3 0 2 0;
+#X connect 5 0 2 0;
+#X restore 275 159 pd capture;
+#N canvas 0 22 470 320 initialize 0;
+#X obj 38 150 s slider-init;
+#X msg 38 85 1;
+#X obj 38 51 loadbang;
+#X obj 142 150 s allthresh-init;
+#X obj 265 150 s alldamp-init;
+#X msg 265 83 0.96;
+#X msg 142 83 0.11;
+#X obj 142 41 inlet;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 2 0 6 0;
+#X connect 2 0 5 0;
+#X connect 5 0 4 0;
+#X connect 6 0 3 0;
+#X connect 7 0 1 0;
+#X connect 7 0 6 0;
+#X connect 7 0 5 0;
+#X restore 399 270 pd initialize;
+#X text 364 97 <- click me to learn more;
+#X obj 399 245 loadbang;
+#X text 50 336 bthresher~ extends the thresher~ model to allow independent
+control over the parameters of each individual bin. You can also randomly
+set damping and threshold values \, and can dump the current values
+(to possibly send as input to another bthresher~ unit). It is recommended
+that you familiarize yourself with thresher~ before exploring the more
+complicated bthresher~.;
+#X text 182 52 threshold scale factor;
+#X text 237 80 damping scale factor;
+#X text 351 160 <- state captured here;
+#X connect 0 0 6 0;
+#X connect 0 1 11 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 3;
+#X connect 5 0 4 0;
+#X connect 6 0 1 0;
+#X connect 6 0 1 1;
+#X connect 7 0 0 1;
+#X connect 8 0 0 2;
+#X connect 14 0 12 0;
diff --git a/bthresher~.c b/bthresher~.c
index 050ca2a..5174f81 100644
--- a/bthresher~.c
+++ b/bthresher~.c
@@ -213,7 +213,7 @@ int i;
void bthresher_overlap(t_bthresher *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -225,7 +225,7 @@ void bthresher_winfac(t_bthresher *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -352,9 +352,9 @@ int i;
x->D = 256;
if(!x->R)
x->R = 44100;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 1;
x->N = x->D * x->overlap;
diff --git a/burrow~-help.pd b/burrow~-help.pd
new file mode 100644
index 0000000..41ee9ce
--- /dev/null
+++ b/burrow~-help.pd
@@ -0,0 +1,129 @@
+#N canvas 579 109 517 612 10;
+#N canvas 590 312 458 308 burrow-block 0;
+#X obj 160 154 burrow~;
+#X obj 160 39 inlet~;
+#X obj 174 72 inlet~;
+#X obj 189 99 inlet;
+#X obj 204 120 inlet;
+#X obj 160 209 outlet~;
+#X obj 270 186 block~ 256;
+#X obj 303 124 inlet;
+#X connect 0 0 5 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 1;
+#X connect 3 0 0 2;
+#X connect 4 0 0 3;
+#X connect 7 0 0 0;
+#X restore 93 227 pd burrow-block;
+#X obj 93 42 noise~;
+#X obj 118 82 noise~;
+#X obj 118 129 bp~ 500 50;
+#X text 90 25 sound to filter;
+#X text 115 66 sound to provide filter shape;
+#X obj 93 269 *~ 1;
+#X obj 93 304 dac~;
+#X msg 352 411 \; pd dsp \$1;
+#X obj 352 394 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X floatatom 116 251 5 0 0 0 - burrow-gain -;
+#X obj 151 313 hsl 128 15 0 0.2 0 0 burrow-gain empty output_gain -2
+-6 0 8 -182539 -1 -1 3175 1;
+#X floatatom 143 150 5 0 0 0 - burrow-threshold -;
+#X floatatom 168 170 5 0 0 0 - burrow-multiplier -;
+#N canvas 0 22 505 427 messages 0;
+#X obj 162 351 outlet;
+#X msg 162 253 invert \$1;
+#X obj 162 227 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 59 49 When invert is turned on \, the spectrum of the filter
+sound becomes the shape of the filter. Although this might seem more
+intuitive \, and thus a better candidate for default behavior \, recall
+that the external is called "burrow~" which is what it does.;
+#N canvas 380 158 454 304 system 0;
+#X obj 201 186 outlet;
+#X msg 93 128 overlap \$1;
+#X msg 84 96 2;
+#X msg 118 96 4;
+#X obj 298 44 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X msg 298 70 mute \$1;
+#X msg 302 132 fftinfo;
+#X msg 145 47 2;
+#X msg 179 47 4;
+#X msg 154 79 winfac \$1;
+#X msg 109 46 1;
+#X text 25 235 Try different combos of window factor and overlap. Lower
+overlap requires less CPU.;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 1 0;
+#X connect 4 0 5 0;
+#X connect 5 0 0 0;
+#X connect 6 0 0 0;
+#X connect 7 0 9 0;
+#X connect 8 0 9 0;
+#X connect 9 0 0 0;
+#X connect 10 0 9 0;
+#X restore 182 305 pd system;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 4 0 0 0;
+#X restore 193 197 pd messages;
+#X obj 153 348 hsl 128 15 0.0001 0.01 0 0 burrow-threshold empty threshold
+-2 -6 0 8 -182539 -1 -1 3720 1;
+#X obj 154 381 hsl 128 15 0.001 1 0 0 burrow-multiplier empty multiplier
+-2 -6 0 8 -182539 -1 -1 114 1;
+#X floatatom 150 103 5 0 0 0 - bp-center-freq -;
+#X obj 154 412 hsl 128 15 100 1500 0 0 bp-center-freq empty center-freq
+-2 -6 0 8 -182539 -1 -1 8164 1;
+#X floatatom 205 103 5 0 0 0 - bp-resonance -;
+#X obj 153 442 hsl 128 15 10 100 0 0 bp-resonance empty resonance -2
+-6 0 8 -182539 -1 -1 12700 1;
+#X text 12 476 The sound in the leftmost inlet gets filtered by the
+spectrum of the sound in the next inlet \, except that by default this
+spectrum is cut out from (or burrows into) the source sound. We use
+noise sources here to highlight the effect but it is recommended to
+use much more interesting sounds as one or both of the inputs. In this
+example \, with bandpassed noise as the filter sound \, the result
+is to create a notch in the source noise \, similar but inverse to
+the shape of the bandpass peak band.;
+#N canvas 0 22 462 312 init 0;
+#X obj 92 140 unpack f f f f f;
+#X obj 92 95 loadbang;
+#X obj 92 195 outlet;
+#X obj 110 234 outlet;
+#X obj 131 276 outlet;
+#X obj 165 256 outlet;
+#X obj 213 246 outlet;
+#X obj 197 71 inlet;
+#X msg 92 117 0.05 0.003 0.01 100 1000;
+#X connect 0 0 2 0;
+#X connect 0 1 3 0;
+#X connect 0 2 4 0;
+#X connect 0 3 5 0;
+#X connect 0 4 6 0;
+#X connect 1 0 8 0;
+#X connect 7 0 8 0;
+#X connect 8 0 0 0;
+#X restore 94 381 pd init;
+#X obj 94 364 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X connect 0 0 6 0;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 3 0 0 1;
+#X connect 6 0 7 0;
+#X connect 6 0 7 1;
+#X connect 9 0 8 0;
+#X connect 10 0 6 1;
+#X connect 12 0 0 2;
+#X connect 13 0 0 3;
+#X connect 14 0 0 4;
+#X connect 17 0 3 1;
+#X connect 19 0 3 2;
+#X connect 22 0 11 0;
+#X connect 22 1 15 0;
+#X connect 22 2 16 0;
+#X connect 22 3 20 0;
+#X connect 22 4 18 0;
+#X connect 23 0 22 0;
diff --git a/burrow~.c b/burrow~.c
index cf5be2d..f5d2acd 100644
--- a/burrow~.c
+++ b/burrow~.c
@@ -165,7 +165,7 @@ void burrow_mute(t_burrow *x, t_floatarg toggle)
void burrow_overlap(t_burrow *x, t_floatarg o)
{
- if(!power_of_two(o)){
+ if(!fftease_power_of_two(o)){
error("%f is not a power of two",o);
return;
}
@@ -175,7 +175,7 @@ void burrow_overlap(t_burrow *x, t_floatarg o)
void burrow_winfac(t_burrow *x, t_floatarg f)
{
- if(!power_of_two(f)){
+ if(!fftease_power_of_two(f)){
error("%f is not a power of two",f);
return;
}
@@ -275,10 +275,10 @@ void *burrow_new(t_symbol *s, int argc, t_atom *argv)
x->overlap = atom_getfloatarg(2,argc,argv);
x->winfac = atom_getfloatarg(3,argc,argv);
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 1;
}
if(x->threshold > 1.0 || x->threshold < 0.0){
diff --git a/cavoc27~-help.pd b/cavoc27~-help.pd
new file mode 100644
index 0000000..e36cb76
--- /dev/null
+++ b/cavoc27~-help.pd
@@ -0,0 +1,86 @@
+#N canvas 323 304 466 316 10;
+#N canvas 0 22 462 312 cavoc27-block 0;
+#X obj 141 110 cavoc27~ 0.05 200 4 1;
+#X obj 141 61 inlet~;
+#X obj 141 156 outlet~;
+#X obj 255 78 inlet;
+#X obj 142 212 block~ 256;
+#X text 89 187 args: density \, holdtime \, overlap \, winfac;
+#X connect 0 0 2 0;
+#X connect 1 0 0 0;
+#X connect 3 0 0 0;
+#X restore 146 109 pd cavoc27-block;
+#N canvas 0 22 478 328 messages 0;
+#X obj 111 220 outlet;
+#N canvas 0 22 466 316 rules 0;
+#X obj 15 181 outlet;
+#X msg 2 36 rule 1 0 1 0 0 0 1 0 0 1 2 1 0 2 0 2 0 0 1 0 2 0 2 1 2
+1 1;
+#X msg 9 58 rule 0 2 1 0 0 1 0 0 0 1 1 2 0 1 2 1 1 1 1 0 0 0 1 1 0
+1 1;
+#X msg 28 88 rule 2 2 0 1 0 2 1 1 0 2 1 2 0 1 1 2 0 2 2 1 2 1 1 2 0
+0 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X restore 111 134 pd rules;
+#N canvas 520 382 466 316 messages 0;
+#X obj 59 290 outlet;
+#X msg 308 110 interpolate \$1;
+#X obj 308 87 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X msg 199 241 hold_time \$1;
+#X floatatom 199 212 5 0 0 0 - - -;
+#X floatatom 305 211 5 0 0 0 - - -;
+#X msg 305 242 density \$1;
+#X msg 61 37 retune 0.5 2;
+#X obj 89 68 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X msg 89 92 capture_spectrum \$1;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 0 0;
+#X connect 4 0 3 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 7 0 0 0;
+#X connect 8 0 9 0;
+#X connect 9 0 0 0;
+#X restore 180 134 pd messages;
+#X obj 273 135 fftease-system;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X restore 253 81 pd messages;
+#X obj 146 208 dac~;
+#X msg 287 201 \; pd dsp \$1;
+#X obj 287 176 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 200 147 hsl 128 15 0 0.01 0 0 empty empty output_gain -2 -6
+0 10 -245150 -1 -1 0 1;
+#N canvas 0 22 462 312 example-input-spectrum 0;
+#X obj 114 228 outlet~;
+#X obj 62 124 phasor~ 100;
+#X obj 145 124 phasor~ 125;
+#X obj 231 125 phasor~ 150;
+#X obj 114 175 *~ 0.333;
+#X text 26 89 this gets sampled when "capture_spectrum" is on;
+#X connect 1 0 4 0;
+#X connect 2 0 4 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X restore 146 48 pd example-input-spectrum;
+#X text 341 82 <- info;
+#X floatatom 197 168 5 0 0 0 - - -;
+#X obj 146 185 *~ 0.001;
+#X text 21 256 27 rule cellular automata (CA). New rules lists have
+27 values (0 \, 1 \, or 2). Start with VERY low gain. See cavoc~ for
+a simpler implementation of CA-generated spectra.;
+#X connect 0 0 9 0;
+#X connect 1 0 0 1;
+#X connect 4 0 3 0;
+#X connect 5 0 8 0;
+#X connect 6 0 0 0;
+#X connect 8 0 9 1;
+#X connect 9 0 2 0;
+#X connect 9 0 2 1;
diff --git a/cavoc~-help.pd b/cavoc~-help.pd
new file mode 100644
index 0000000..6792f00
--- /dev/null
+++ b/cavoc~-help.pd
@@ -0,0 +1,96 @@
+#N canvas 674 329 486 336 10;
+#N canvas 172 264 478 328 cavoc-block 0;
+#X obj 161 176 block~ 256;
+#X obj 167 155 outlet~;
+#X obj 292 69 inlet;
+#X obj 167 111 cavoc~ 0.05 150 4 1;
+#X text 133 127 args: density holdtime \, overlap \, window factor
+;
+#X connect 2 0 3 0;
+#X connect 3 0 1 0;
+#X restore 29 72 pd cavoc-block;
+#X obj 29 143 dac~;
+#X msg 29 208 \; pd dsp \$1;
+#X obj 29 186 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X floatatom 80 96 5 0 0 0 - gain -;
+#X obj 32 261 hsl 128 15 0 1 0 0 gain gain-init gain -2 -6 0 8 -261127
+-1 -1 0 1;
+#N canvas 773 396 486 336 messages 0;
+#X obj 120 243 outlet;
+#N canvas 321 426 474 324 rules 0;
+#X obj 55 273 outlet;
+#X msg 59 71 rule 1 1 1 1 0 0 0 0;
+#X msg 213 72 rule 1 0 1 0 1 0 1 0;
+#X msg 203 122 rule 0 0 0 0 0 1 0 1;
+#X msg 203 149 rule 0 1 1 0 1 0 0 1;
+#X msg 203 194 rule 0 0 0 0 1 1 1 1;
+#X msg 90 34 rule 1 1 0 1 0 1 0 0;
+#X msg 265 23 rule 1 1 0 1 0 1 1 0;
+#X msg 300 51 rule 1 1 0 0 1 1 0 0;
+#X msg 294 94 rule 0 0 1 0 1 0 1 1;
+#X msg 204 234 rule 0 0 0 1 1 0 0 0;
+#X msg 244 265 rule 1 0 0 1 1 0 0 1;
+#X text 38 301 rules define CA evolution of spectrum;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 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 connect 10 0 0 0;
+#X connect 11 0 0 0;
+#X restore 250 227 pd rules;
+#N canvas 687 59 486 336 system 0;
+#X obj 209 277 outlet;
+#X msg 132 162 fftinfo;
+#X msg 64 181 mute \$1;
+#X obj 64 154 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X msg 215 121 overlap \$1;
+#X msg 249 161 winfac \$1;
+#X floatatom 215 91 5 0 0 0 - - -;
+#X floatatom 249 142 5 0 0 0 - - -;
+#X text 243 240 default: overlap=4 \, winfac=1;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 2 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 4 0;
+#X connect 7 0 5 0;
+#X restore 41 177 pd system;
+#X floatatom 292 77 5 0 0 0 - - -;
+#X msg 291 101 density \$1;
+#X msg 251 44 0.05;
+#X msg 105 126 retune 0.5 2;
+#X msg 303 42 0.2;
+#X floatatom 316 163 5 0 0 0 - - -;
+#X msg 316 181 hold_time \$1;
+#X text 311 228 <- CA rules;
+#X text 220 149 hold time (in ms) for each step of CA;
+#X text 109 21 density is percent of bins turned on at start of CA
+;
+#X text 96 102 reset phase "tunings";
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 5 0 4 0;
+#X connect 6 0 0 0;
+#X connect 7 0 3 0;
+#X connect 8 0 9 0;
+#X connect 9 0 0 0;
+#X restore 29 38 pd messages;
+#X obj 29 115 *~ 0.025;
+#X text 27 290 cavoc~ is an 8 rule cellular automaton that generates
+spectra. Start with very low gain.;
+#X connect 0 0 7 0;
+#X connect 3 0 2 0;
+#X connect 4 0 7 1;
+#X connect 6 0 0 0;
+#X connect 7 0 1 0;
+#X connect 7 0 1 1;
diff --git a/cavoc~.c b/cavoc~.c
index 7bfcedc..56d8c2a 100644
--- a/cavoc~.c
+++ b/cavoc~.c
@@ -140,7 +140,7 @@ void cavoc_fftinfo( t_cavoc *x )
void cavoc_overlap(t_cavoc *x, t_floatarg f)
{
- if(!power_of_two(f)){
+ if(!fftease_power_of_two(f)){
error("%f is not a power of two",f);
return;
}
@@ -150,7 +150,7 @@ void cavoc_overlap(t_cavoc *x, t_floatarg f)
void cavoc_winfac(t_cavoc *x, t_floatarg f)
{
- if(!power_of_two(f)){
+ if(!fftease_power_of_two(f)){
error("%f is not a power of two",f);
return;
}
@@ -304,9 +304,9 @@ int i;
x->D = 256;
if(!x->R)
x->R = 44100;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 1;
x->N = x->D * x->overlap;
x->Nw = x->N * x->winfac;
diff --git a/centerring~-help.pd b/centerring~-help.pd
new file mode 100644
index 0000000..2f6b9d4
--- /dev/null
+++ b/centerring~-help.pd
@@ -0,0 +1,77 @@
+#N canvas 281 24 648 434 10;
+#N canvas 376 316 462 312 centerring-block 0;
+#X obj 163 128 centerring~;
+#X obj 233 219 block~ 256;
+#X obj 152 180 outlet~;
+#X obj 141 63 inlet~;
+#X obj 337 89 inlet;
+#X obj 195 67 inlet;
+#X obj 242 66 inlet;
+#X obj 290 71 inlet;
+#X connect 0 0 2 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 1;
+#X connect 6 0 0 2;
+#X connect 7 0 0 3;
+#X restore 167 141 pd centerring-block;
+#X obj 167 195 *~ 1;
+#X obj 167 230 dac~;
+#X floatatom 190 176 5 0 0 0 - centerring-gain -;
+#X msg 333 242 \; pd dsp \$1;
+#X obj 333 225 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 18 207 hsl 128 15 0 0.1 0 0 centerring-gain empty output_gain
+-2 -6 0 8 -79789 -1 -1 800 1;
+#X obj 81 51 phasor~ 150;
+#N canvas 0 22 474 324 messages 0;
+#X obj 159 192 outlet;
+#X msg 154 138 zerophases;
+#X msg 263 138 randphases;
+#X msg 71 101 seed \$1;
+#X floatatom 70 71 5 0 0 0 - - -;
+#X msg 117 65 1974;
+#X obj 320 168 fftease-system;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 3 0;
+#X connect 5 0 3 0;
+#X connect 6 0 0 0;
+#X restore 319 108 pd messages;
+#X floatatom 193 54 5 0 0 0 - cr-base-frequency -;
+#X obj 18 240 hsl 128 15 0.1 20 0 0 cr-base-frequency empty base_frequency
+-2 -6 0 8 -79789 -1 -1 900 1;
+#X floatatom 251 59 5 0 0 0 - cr-bandwidth -;
+#X obj 16 271 hsl 128 15 0.1 20 0 0 cr-bandwidth empty bandwidth -2
+-6 0 8 -79789 -1 -1 7700 1;
+#X floatatom 329 42 5 0 0 0 - cr-freq-constant -;
+#X obj 15 305 hsl 128 15 0.1 20 0 0 cr-freq-constant empty frequency_constant
+-2 -6 0 8 -79789 -1 -1 6300 1;
+#X obj 9 99 loadbang;
+#X msg 9 125 0.1 1 0.15 1;
+#X obj 9 157 unpack f f f f;
+#X text 171 294 centerring~ performs frequency independent amplitude
+modulation upon the spectral magnitudes of input signals. The effect
+is somewhat akin to flanging. The base frequency is used to derive
+the frequency of an oscillator associated with each frequency band.
+The frequency bandwidth and constant control the deviation of a particular
+frequency band's modulation oscillator frequency.;
+#X floatatom 81 30 5 0 0 0 - - -;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 1 0 2 1;
+#X connect 3 0 1 1;
+#X connect 5 0 4 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 4;
+#X connect 9 0 0 1;
+#X connect 11 0 0 2;
+#X connect 13 0 0 3;
+#X connect 15 0 16 0;
+#X connect 16 0 17 0;
+#X connect 17 0 6 0;
+#X connect 17 1 10 0;
+#X connect 17 2 12 0;
+#X connect 17 3 14 0;
+#X connect 19 0 7 0;
diff --git a/centerring~.c b/centerring~.c
index 31e9483..4bd7ce2 100644
--- a/centerring~.c
+++ b/centerring~.c
@@ -217,10 +217,10 @@ void *centerring_new(t_symbol *s, int argc, t_atom *argv)
x->overlap = atom_getfloatarg(4,argc,argv);
x->winfac = atom_getfloatarg(5,argc,argv);
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 1;
}
@@ -538,7 +538,7 @@ void centerring_mute(t_centerring *x, t_floatarg toggle)
void centerring_overlap(t_centerring *x, t_floatarg o)
{
- if(!power_of_two((int)o)){
+ if(!fftease_power_of_two((int)o)){
error("%f is not a power of two",o);
return;
}
@@ -548,7 +548,7 @@ void centerring_overlap(t_centerring *x, t_floatarg o)
void centerring_winfac(t_centerring *x, t_floatarg f)
{
- if(!power_of_two((int)f)){
+ if(!fftease_power_of_two((int)f)){
error("%f is not a power of two",f);
return;
}
diff --git a/codepend~-help.pd b/codepend~-help.pd
new file mode 100644
index 0000000..eb542b4
--- /dev/null
+++ b/codepend~-help.pd
@@ -0,0 +1,140 @@
+#N canvas 281 24 668 454 10;
+#X obj 167 237 *~ 1;
+#X obj 167 289 dac~;
+#X floatatom 190 218 5 0 0 0 - centerring-gain -;
+#X msg 333 284 \; pd dsp \$1;
+#X obj 333 267 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 17 207 hsl 128 15 0 4 0 0 centerring-gain empty output_gain
+-2 -6 0 8 -79789 -1 -1 317 1;
+#N canvas 0 22 519 354 messages 0;
+#X obj 132 268 outlet;
+#X text 30 194 turn on invert;
+#X msg 132 175 pad \$1;
+#X obj 132 146 ampdb;
+#X floatatom 132 116 5 -200 -12 0 - - -;
+#X text 221 177 is turned on;
+#X obj 9 195 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X msg 9 217 invert \$1;
+#X text 221 163 pad affects the gain only when "invert";
+#X obj 184 233 fftease-system;
+#X connect 2 0 0 0;
+#X connect 3 0 2 0;
+#X connect 4 0 3 0;
+#X connect 6 0 7 0;
+#X connect 7 0 0 0;
+#X connect 9 0 0 0;
+#X restore 448 167 pd messages;
+#X obj 18 240 hsl 128 15 0.15 1 0 0 cod-scaling-exponent empty scaling_exponent
+-2 -6 0 8 -88868 -1 -1 2241 1;
+#N canvas 376 316 470 320 codepend-block 0;
+#X obj 233 219 block~ 256;
+#X obj 163 185 outlet~;
+#X obj 163 38 inlet~;
+#X obj 269 107 inlet;
+#X obj 201 81 inlet;
+#X obj 221 98 inlet;
+#X obj 163 128 codepend~;
+#X obj 182 65 inlet~;
+#X connect 2 0 6 0;
+#X connect 3 0 6 0;
+#X connect 4 0 6 2;
+#X connect 5 0 6 3;
+#X connect 6 0 1 0;
+#X connect 7 0 6 1;
+#X restore 167 183 pd codepend-block;
+#X obj 252 142 ampdb;
+#X floatatom 252 122 5 0 0 0 - cod-inverse-threshold -;
+#X floatatom 252 164 5 0 0 0 - - -;
+#N canvas 990 218 504 393 playsound1 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#X msg 31 177 read -resize \$1 codepend-sound1;
+#N canvas 0 22 450 300 graph1 0;
+#X array codepend-sound1 501762 float 2;
+#X coords 0 1 501761 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X obj 227 268 tabplay~ codepend-sound1;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X connect 1 0 2 0;
+#X connect 2 0 0 0;
+#X connect 4 0 1 0;
+#X connect 6 0 5 0;
+#X connect 6 1 8 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 0;
+#X connect 9 0 8 1;
+#X restore 167 22 pd playsound1;
+#N canvas 990 218 508 397 playsound2 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X text 316 205 comment;
+#X msg 31 177 read -resize \$1 codepend-sound2;
+#N canvas 0 22 450 300 graph2 0;
+#X array codepend-sound2 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 216 15 graph;
+#X obj 227 268 tabplay~ codepend-sound2;
+#X connect 1 0 11 0;
+#X connect 2 0 1 0;
+#X connect 4 0 13 0;
+#X connect 5 0 4 0;
+#X connect 6 0 5 1;
+#X connect 11 0 0 0;
+#X connect 13 0 3 0;
+#X connect 13 1 5 0;
+#X restore 195 40 pd playsound2;
+#X floatatom 224 90 5 0 0 0 - cod-scaling-exponent -;
+#X obj 19 278 hsl 128 15 -90 0 0 0 cod-inverse-threshold empty inverse_threshold
+-2 -6 0 8 -88868 -1 -1 7620 1;
+#X text 296 137 but only when "invert" is turned on);
+#X text 224 72 scaling exponent (lower values increase distortion)
+;
+#X text 294 31 <- load and loop two soundfiles to hear effect;
+#X msg 14 123 0.1 0.3 -36;
+#X obj 14 139 unpack f f f;
+#X obj 14 107 loadbang;
+#X text 293 121 inverse threshold (lower values intensify effect;
+#X text 31 316 codepend~ is a classic "block convolution" processor.
+It performs a complex multiply upon the spectra of two input signals.
+Multiplication of spectra can cause significant drops in the amplitude
+of the output signal. The invert message causes codepend~ to perform
+complex division of the input spectra rather than multiplication. This
+can cause huge amplitude gains. A "pad" message is provided to allow
+for empirical amplitude balancing between the normal and "invert" states.
+;
+#X connect 0 0 1 0;
+#X connect 0 0 1 1;
+#X connect 2 0 0 1;
+#X connect 4 0 3 0;
+#X connect 6 0 8 4;
+#X connect 8 0 0 0;
+#X connect 9 0 11 0;
+#X connect 10 0 9 0;
+#X connect 11 0 8 3;
+#X connect 12 0 8 0;
+#X connect 13 0 8 1;
+#X connect 14 0 8 2;
+#X connect 19 0 20 0;
+#X connect 20 0 5 0;
+#X connect 20 1 7 0;
+#X connect 20 2 15 0;
+#X connect 21 0 19 0;
diff --git a/codepend~.c b/codepend~.c
index cdc29ff..ec9a492 100644
--- a/codepend~.c
+++ b/codepend~.c
@@ -157,7 +157,7 @@ void codepend_mute(t_codepend *x, t_floatarg toggle)
void codepend_overlap(t_codepend *x, t_floatarg o)
{
- if(!power_of_two((int)o)){
+ if(!fftease_power_of_two((int)o)){
error("%f is not a power of two",o);
return;
}
@@ -167,7 +167,7 @@ void codepend_overlap(t_codepend *x, t_floatarg o)
void codepend_winfac(t_codepend *x, t_floatarg f)
{
- if(!power_of_two((int)f)){
+ if(!fftease_power_of_two((int)f)){
error("%f is not a power of two",f);
return;
}
@@ -277,10 +277,10 @@ void *codepend_new(t_symbol *s, int argc, t_atom *argv)
if(x->exponent < 0.25)
x->exponent = 0.25;
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 1;
}
diff --git a/convert.c b/convert.c
new file mode 100644
index 0000000..0131774
--- /dev/null
+++ b/convert.c
@@ -0,0 +1 @@
+#include "fftease.h" /* S is a spectrum in rfft format, i.e., it contains N real values arranged as real followed by imaginary values, except for first two values, which are real parts of 0 and Nyquist frequencies; convert first changes these into N/2+1 PAIRS of magnitude and phase values to be stored in output array C; the phases are then unwrapped and successive phase differences are used to compute estimates of the instantaneous frequencies for each phase vocoder analysis channel; decimation rate D and sampling rate R are used to render these frequency values directly in Hz. */ void convert(float *S, float *C, int N2, float *lastphase, float fundamental, float factor ) { float phase, phasediff; int real, imag, amp, freq; float a, b; int i; /* float myTWOPI, myPI; */ /* double sin(), cos(), atan(), hypot();*/ /* myTWOPI = 8.*atan(1.); myPI = 4.*atan(1.); */ for ( i = 0; i <= N2; i++ ) { imag = freq = ( real = amp = i<<1 ) + 1; a = ( i == N2 ? S[1] : S[real] ); b = ( i == 0 || i == N2 ? 0. : S[imag] ); C[amp] = hypot( a, b ); if ( C[amp] == 0. ) phasediff = 0.; else { phasediff = ( phase = -atan2( b, a ) ) - lastphase[i]; lastphase[i] = phase; while ( phasediff > PI ) phasediff -= TWOPI; while ( phasediff < -PI ) phasediff += TWOPI; } C[freq] = phasediff*factor + i*fundamental; } } \ No newline at end of file
diff --git a/crossx~-help.pd b/crossx~-help.pd
new file mode 100644
index 0000000..82ec6f7
--- /dev/null
+++ b/crossx~-help.pd
@@ -0,0 +1,135 @@
+#N canvas 684 407 470 320 10;
+#X obj 25 189 dac~;
+#N canvas 0 22 470 320 rich-harmonic-source 0;
+#X obj 127 232 outlet~;
+#X obj 127 125 phasor~ 100;
+#X obj 212 126 phasor~ 125;
+#X obj 296 125 phasor~ 150;
+#X obj 127 183 *~ 0.3;
+#X floatatom 127 67 5 0 0 0 - - -;
+#X obj 212 99 * 1.25;
+#X obj 296 100 * 1.5;
+#X obj 130 34 hsl 128 15 60 600 0 0 empty empty empty -2 -6 0 8 -154413
+-1 -1 8900 1;
+#X connect 1 0 4 0;
+#X connect 2 0 4 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 5 0 6 0;
+#X connect 5 0 1 0;
+#X connect 5 0 7 0;
+#X connect 6 0 2 0;
+#X connect 7 0 3 0;
+#X connect 8 0 5 0;
+#X restore 25 23 pd rich-harmonic-source;
+#X floatatom 91 66 5 0 0 0 - - -;
+#N canvas 179 221 657 470 vocal-source 0;
+#X text 13 300 try a vocal sound or other sound with strong formant
+structure;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array crossx-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X msg 31 177 read -resize \$1 crossx-sound1;
+#X obj 227 268 tabplay~ crossx-sound1;
+#X connect 2 0 12 0;
+#X connect 4 0 2 0;
+#X connect 6 0 13 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 1;
+#X connect 12 0 1 0;
+#X connect 13 0 5 0;
+#X connect 13 1 7 0;
+#X restore 58 45 pd vocal-source;
+#X msg 186 229 \; pd dsp \$1;
+#X obj 186 208 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 25 160 *~ 1;
+#X floatatom 48 141 5 0 0 0 - - -;
+#X text 90 143 <- might need large amplitude;
+#X text 96 155 but watch for sudden spikes!;
+#X text 133 70 <- synthesis advancement threshold;
+#N canvas 172 351 466 316 crossx-block 0;
+#X obj 161 178 outlet~;
+#X obj 161 49 inlet~;
+#X obj 219 100 inlet;
+#X obj 283 102 inlet;
+#X obj 161 213 block~ 256;
+#X obj 190 80 inlet~;
+#X obj 161 132 crossx~ 4;
+#X connect 1 0 6 0;
+#X connect 2 0 6 2;
+#X connect 3 0 6 0;
+#X connect 5 0 6 1;
+#X connect 6 0 0 0;
+#X restore 25 88 pd crossx-block;
+#N canvas 0 22 458 308 messages 0;
+#X obj 56 233 outlet;
+#X msg 56 175 autonorm \$1;
+#X text 56 66 frame normalization to tame amplitude spikes;
+#X obj 209 217 fftease-system;
+#N canvas 0 22 458 308 rescale-autonorm 0;
+#X obj 93 30 inlet;
+#X obj 61 92 t b b;
+#X msg 61 115 1;
+#X msg 108 118 0.05;
+#X obj 108 144 s output-gain;
+#X obj 96 221 outlet;
+#X obj 197 49 inlet;
+#X obj 226 102 t b b;
+#X obj 243 237 s output-gain;
+#X msg 313 130 0;
+#X msg 243 211 5;
+#X obj 261 174 pipe 100;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 1 1 3 0;
+#X connect 2 0 5 0;
+#X connect 3 0 4 0;
+#X connect 6 0 7 0;
+#X connect 7 0 11 0;
+#X connect 7 1 9 0;
+#X connect 9 0 5 0;
+#X connect 10 0 8 0;
+#X connect 11 0 10 0;
+#X restore 56 122 pd rescale-autonorm;
+#X obj 56 93 bng 15 250 50 0 empty empty on 0 -6 0 8 -262144 -1 -1
+;
+#X obj 184 94 bng 15 250 50 0 empty empty off 0 -6 0 8 -262144 -1 -1
+;
+#X connect 1 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 1 0;
+#X connect 5 0 4 0;
+#X connect 6 0 4 1;
+#X restore 143 88 pd messages;
+#X obj 48 118 r output-gain;
+#X text 96 170 a compressor could be useful here;
+#X obj 215 51 hsl 128 15 0 0.05 0 0 empty empty empty -2 -6 0 8 -191432
+-1 -1 700 1;
+#X text 26 262 crossx~ is related to xsyn~ but uses a threshold to
+determine whether to perform spectral multiplication or maintain the
+last calculated amplitude/phase pair. crossx~ is also somewhat less
+CPU intensive.;
+#X connect 1 0 11 0;
+#X connect 2 0 11 2;
+#X connect 3 0 11 1;
+#X connect 5 0 4 0;
+#X connect 6 0 0 0;
+#X connect 6 0 0 1;
+#X connect 7 0 6 1;
+#X connect 11 0 6 0;
+#X connect 12 0 11 3;
+#X connect 13 0 7 0;
+#X connect 15 0 2 0;
diff --git a/crossx~.c b/crossx~.c
index 70739f0..daea02b 100644
--- a/crossx~.c
+++ b/crossx~.c
@@ -110,7 +110,6 @@ void crossx_tilde_setup(void)
class_addmethod(crossx_class, (t_method)crossx_fftinfo, gensym("fftinfo"), 0);
class_addmethod(crossx_class, (t_method)crossx_autonorm, gensym("autonorm"), A_DEFFLOAT,0);
post("%s %s",OBJECT_NAME,FFTEASE_ANNOUNCEMENT);
-post("padded memory");
}
#endif
@@ -141,7 +140,7 @@ void crossx_assist (t_crossx *x, void *b, long msg, long arg, char *dst)
void crossx_overlap(t_crossx *x, t_floatarg o)
{
- if(!power_of_two((int)o)){
+ if(!fftease_power_of_two((int)o)){
error("%f is not a power of two",o);
return;
}
@@ -151,7 +150,7 @@ void crossx_overlap(t_crossx *x, t_floatarg o)
void crossx_winfac(t_crossx *x, t_floatarg f)
{
- if(!power_of_two((int)f)){
+ if(!fftease_power_of_two((int)f)){
error("%f is not a power of two",f);
return;
}
diff --git a/dentist~-help.pd b/dentist~-help.pd
new file mode 100644
index 0000000..e157285
--- /dev/null
+++ b/dentist~-help.pd
@@ -0,0 +1,112 @@
+#N canvas 71 582 526 376 10;
+#N canvas 0 22 482 332 dentist-block 0;
+#X obj 322 150 block~ 256;
+#X obj 185 65 inlet~;
+#X obj 257 67 inlet;
+#X obj 185 174 outlet~;
+#X obj 221 264 snapshot~;
+#X obj 199 229 metro 80;
+#X msg 201 204 1;
+#X obj 310 287 outlet;
+#X obj 84 188 loadbang;
+#X obj 185 112 dentist~ 8000;
+#X obj 271 218 s dentist-stored-teeth;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 4 0 7 0;
+#X connect 5 0 4 0;
+#X connect 6 0 5 0;
+#X connect 8 0 6 0;
+#X connect 9 0 3 0;
+#X connect 9 1 4 0;
+#X connect 9 2 10 0;
+#X restore 126 106 pd dentist-block;
+#X msg 263 173 \; pd dsp \$1;
+#X obj 263 147 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 126 180 dac~;
+#N canvas 639 41 688 619 messages 0;
+#X obj 70 447 outlet;
+#X msg 271 50 ramptime \$1;
+#X obj 271 26 nbx 5 14 -1e+37 1e+37 0 0 empty empty empty 0 -6 0 10
+-262144 -1 -1 1000 256;
+#X msg 271 4 1000;
+#X obj 271 -17 loadbang;
+#X msg 186 431 toothcount \$1;
+#X msg 95 234 topfreq \$1;
+#X floatatom 95 212 5 0 0 0 - - -;
+#X text 94 196 highest frequency for bin selection;
+#X text 330 26 interpolation time between distributions;
+#X text 89 57 set distribution;
+#X msg 330 330 interpolate_singles \$1;
+#X obj 330 303 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X msg 70 75 scramble;
+#X obj 299 430 hsl 128 15 0 127 0 0 toothcount empty toothcount -2
+-6 0 8 -85171 -1 -1 5300 1;
+#X text 220 448 this sets the number of bins within a fixed random
+distribution. must be greater than zero to hear sound.;
+#X obj 70 487 fftease-system;
+#X msg 186 389 10;
+#N canvas 643 146 878 628 data-storage 0;
+#X obj 260 105 outlet;
+#X msg 260 -66 setstate 30 31 32 33 34 35;
+#X msg 260 -49 setstate 7 9 11 13;
+#X text 250 -92 set a particular bin distribution;
+#X msg 260 -32 setstate 16 20 7 10 24 12 2 23 3;
+#X msg 260 64 showstate;
+#X text 337 64 list current bin selections;
+#X obj 80 140 r dentist-stored-teeth;
+#X obj 80 167 print;
+#X text 128 170 <- replace with [prepend set] -> [messagebox] if you
+have a "prepend" in your Pd distribution. Otherwise we just print to
+the Pd window.;
+#X text 241 141 <- from the dentist~ list outlet;
+#X connect 5 0 0 0;
+#X connect 7 0 8 0;
+#X restore 143 339 pd data-storage;
+#X obj 186 369 loadbang;
+#X obj 186 410 nbx 5 14 -1e+37 1e+37 0 0 empty toothcount empty 0 -6
+0 12 -262144 -1 -1 50 256;
+#X obj 70 17 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 70 36 metro 1000;
+#X text 89 15 do it repeatedly;
+#X text 286 275 turn OFF to make toothcount changes instantaneous;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 2 0;
+#X connect 4 0 3 0;
+#X connect 5 0 0 0;
+#X connect 6 0 0 0;
+#X connect 7 0 6 0;
+#X connect 11 0 0 0;
+#X connect 12 0 11 0;
+#X connect 13 0 0 0;
+#X connect 16 0 0 0;
+#X connect 17 0 20 0;
+#X connect 18 0 0 0;
+#X connect 19 0 17 0;
+#X connect 20 0 5 0;
+#X connect 21 0 22 0;
+#X connect 22 0 13 0;
+#X restore 233 80 pd messages;
+#X obj 126 150 *~ 2;
+#X obj 61 228 hsl 128 15 0 4 0 0 gain empty gain -2 -6 0 8 -208862
+-1 -1 12700 1;
+#X text 316 81 <- open me;
+#X obj 126 66 noise~;
+#X floatatom 233 131 5 0 0 0 - - -;
+#X text 279 131 sync;
+#X text 72 272 dentist~ punches out all but a select set of partials.
+The argument is the maximum frequency from which to select partials.
+;
+#X floatatom 149 130 5 0 0 0 - gain -;
+#X connect 0 0 5 0;
+#X connect 0 1 9 0;
+#X connect 2 0 1 0;
+#X connect 4 0 0 1;
+#X connect 5 0 3 0;
+#X connect 5 0 3 1;
+#X connect 8 0 0 0;
+#X connect 12 0 5 1;
diff --git a/dentist~.c b/dentist~.c
index e9cb8fe..50c5ec1 100644
--- a/dentist~.c
+++ b/dentist~.c
@@ -174,7 +174,7 @@ void dentist_free(t_dentist *x)
void dentist_overlap(t_dentist *x, t_floatarg f)
{
int o = (int)f;
- if(!power_of_two(o)){
+ if(!fftease_power_of_two(o)){
error("%d is not a power of two",o);
return;
}
@@ -185,7 +185,7 @@ int o = (int)f;
void dentist_winfac(t_dentist *x, t_floatarg f)
{
int w = (int)f;
- if(!power_of_two(w)){
+ if(!fftease_power_of_two(w)){
error("%d is not a power of two",w);
return;
}
@@ -254,9 +254,9 @@ void *dentist_new(t_symbol *msg, short argc, t_atom *argv)
x->topfreq = atom_getfloatarg(0,argc,argv);
x->overlap = atom_getfloatarg(1,argc,argv);
x->winfac = atom_getfloatarg(2,argc,argv);
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 1;
dentist_init(x,0);
diff --git a/disarrain~-help.pd b/disarrain~-help.pd
new file mode 100644
index 0000000..b761bae
--- /dev/null
+++ b/disarrain~-help.pd
@@ -0,0 +1,109 @@
+#N canvas 717 430 516 403 10;
+#N canvas 1009 566 462 312 disarrain-block 0;
+#X obj 137 111 disarrain~ 4000;
+#X obj 137 177 outlet~;
+#X obj 237 173 outlet;
+#X obj 137 66 inlet~;
+#X obj 53 247 block~ 256;
+#X obj 205 217 snapshot~;
+#X obj 324 189 metro 100;
+#X msg 325 162 1;
+#X obj 327 125 loadbang;
+#X obj 205 242 outlet;
+#X obj 316 74 inlet;
+#X connect 0 0 1 0;
+#X connect 0 1 5 0;
+#X connect 0 2 2 0;
+#X connect 3 0 0 0;
+#X connect 5 0 9 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 0;
+#X connect 10 0 0 0;
+#X restore 63 80 pd disarrain-block;
+#X obj 63 11 phasor~ 174;
+#X obj 63 241 *~ 0.05;
+#X floatatom 123 132 5 0 0 0 - - -;
+#X obj 63 286 dac~;
+#X obj 110 199 hsl 128 15 0 0.5 0 0 empty empty empty -2 -6 0 8 -258444
+-1 -1 3000 1;
+#X floatatom 107 220 5 0 0 0 - - -;
+#X msg 285 258 \; pd dsp \$1;
+#X obj 285 237 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 51 333 disarrain~ is a modified version of disarray~ that interpolates
+between different spectral reorderings.;
+#N canvas 476 454 458 308 messages 0;
+#X obj 209 234 outlet;
+#X obj 303 202 fftease-system;
+#N canvas 904 74 603 462 main-messages 0;
+#X obj 8 407 outlet;
+#X floatatom 38 65 5 0 0 0 - - -;
+#X msg 77 148 forcefade \$1;
+#X obj 78 122 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X floatatom 99 216 5 0 0 0 - - -;
+#X msg 99 242 fadetime \$1;
+#X floatatom 218 283 5 0 0 0 - - -;
+#X msg 218 309 topfreq \$1;
+#X msg 195 391 killfade;
+#X msg 38 91 switch_count \$1;
+#X msg 8 28 reset_shuffle;
+#X text 123 29 make new reordering;
+#X text 153 93 number of bins to reorder (at 0 there is no bin swapping)
+;
+#X text 167 151 permit override of current fade for instantaneous changes
+;
+#X text 297 312 top frequency to be shuffled;
+#X text 270 391 immediately end current crossfade;
+#X text 195 241 crossfade interpolation time;
+#X msg 99 194 3000;
+#X obj 99 172 loadbang;
+#X connect 1 0 9 0;
+#X connect 2 0 0 0;
+#X connect 3 0 2 0;
+#X connect 4 0 5 0;
+#X connect 5 0 0 0;
+#X connect 6 0 7 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 0;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X connect 17 0 4 0;
+#X connect 18 0 17 0;
+#X restore 31 31 pd main-messages;
+#N canvas 752 371 590 315 data 0;
+#X obj 89 237 outlet;
+#X msg 48 83 isetstate 73 109 187 113 3 2 1 30 96 4 7;
+#X msg 105 119 setstate 0 20 23 42 2 18 6 7 38 14 10 27 12 8 4 19 16
+5 36 9 15 40 39 45 24 25 28 17 33 13 43 29 34 21 32 35 22 37 46 1 26
+3 41 44 11 31 30 47 48 49;
+#X text 138 160 instant recall;
+#X text 51 67 recall a mapping you like;
+#X msg 194 188 showstate;
+#X text 269 189 output current remapping as a list;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 5 0 0 0;
+#X restore 5 145 pd data;
+#X text 151 32 <- now go here;
+#X text 58 144 <- if you find a setting you like and wish to store
+it;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X restore 184 53 pd messages;
+#X obj 184 111 print;
+#X text 229 113 prints current reordering;
+#X text 124 146 crossfade sync;
+#X text 277 56 <- start here;
+#X connect 0 0 2 0;
+#X connect 0 1 3 0;
+#X connect 0 2 11 0;
+#X connect 1 0 0 0;
+#X connect 2 0 4 0;
+#X connect 2 0 4 1;
+#X connect 5 0 6 0;
+#X connect 6 0 2 1;
+#X connect 8 0 7 0;
+#X connect 10 0 0 1;
diff --git a/disarrain~.c b/disarrain~.c
index d0a7ff7..ce680a5 100644
--- a/disarrain~.c
+++ b/disarrain~.c
@@ -199,10 +199,10 @@ void disarrain_init(t_disarrain *x, short initialized)
int i;
float curfreq;
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 1;
}
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
x->N = x->D * x->overlap;
@@ -395,7 +395,7 @@ void disarrain_bypass(t_disarrain *x, t_floatarg toggle)
void disarrain_overlap(t_disarrain *x, t_floatarg df)
{
int o = (int)df;
- if(!power_of_two(o)){
+ if(!fftease_power_of_two(o)){
error("%d is not a power of two",o);
return;
}
@@ -406,7 +406,7 @@ int o = (int)df;
void disarrain_winfac(t_disarrain *x, t_floatarg f)
{
int wf = (int)f;
- if(!power_of_two(wf)){
+ if(!fftease_power_of_two(wf)){
error("%f is not a power of two",wf);
return;
}
diff --git a/disarray~-help.pd b/disarray~-help.pd
new file mode 100644
index 0000000..ae241b0
--- /dev/null
+++ b/disarray~-help.pd
@@ -0,0 +1,67 @@
+#N canvas 863 421 559 421 10;
+#X obj 174 83 phasor~ 300;
+#N canvas 0 22 478 328 disarray_block 0;
+#X obj 107 116 disarray~ 3000 0 4 1;
+#X obj 107 59 inlet~;
+#X obj 186 65 inlet;
+#X obj 107 186 outlet~;
+#X obj 295 170 print;
+#X obj 188 206 block~ 256;
+#X connect 0 0 3 0;
+#X connect 0 1 4 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X restore 174 133 pd disarray_block;
+#X obj 174 179 *~ 0.2;
+#X obj 174 216 dac~;
+#N canvas 673 80 659 338 messages 0;
+#X obj 172 305 outlet;
+#X obj 136 33 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X floatatom 304 138 5 0 0 0 - - -;
+#X msg 304 163 topfreq \$1;
+#X msg 184 130 switch_count \$1;
+#X floatatom 184 104 5 0 0 0 - - -;
+#X msg 415 201 showstate;
+#X obj 421 277 fftease-system;
+#X msg 184 81 40;
+#X obj 184 54 loadbang;
+#X msg 304 112 4000;
+#X obj 304 88 loadbang;
+#X text 344 137 top frequency to scramble;
+#X text 222 73 number of bins to scramble;
+#X text 418 182 report current scramble;
+#X text 160 30 get new distribution;
+#N canvas 887 617 454 304 data 0;
+#X obj 8 226 outlet;
+#X msg 8 104 35 89 192 56 132 187 141 82 51 87 156 43 103 37 80 122
+107 1 109 209 81;
+#X text 11 80 load your own data as a list;
+#X text 62 139 use the data reported from "showstate" as a start;
+#X connect 1 0 0 0;
+#X restore 405 245 pd data;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 4 0;
+#X connect 6 0 0 0;
+#X connect 7 0 0 0;
+#X connect 8 0 5 0;
+#X connect 9 0 8 0;
+#X connect 10 0 2 0;
+#X connect 11 0 10 0;
+#X connect 16 0 0 0;
+#X restore 288 90 pd messages;
+#X msg 26 166 \; pd dsp \$1;
+#X obj 26 143 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X text 286 75 open for controls:;
+#X text 36 283 disarray~ reorders the weights of spectral components
+below a specified top frequency.;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 2 0 3 1;
+#X connect 4 0 1 1;
+#X connect 6 0 5 0;
diff --git a/disarray~.c b/disarray~.c
index c115857..30839fe 100644
--- a/disarray~.c
+++ b/disarray~.c
@@ -149,7 +149,7 @@ void disarray_free(t_disarray *x)
void disarray_overlap(t_disarray *x, t_floatarg o)
{
- if(!power_of_two(o)){
+ if(!fftease_power_of_two(o)){
error("%f is not a power of two",o);
return;
}
@@ -159,7 +159,7 @@ void disarray_overlap(t_disarray *x, t_floatarg o)
void disarray_winfac(t_disarray *x, t_floatarg f)
{
- if(!power_of_two(f)){
+ if(!fftease_power_of_two(f)){
error("%f is not a power of two",f);
return;
}
@@ -233,9 +233,9 @@ void *disarray_new(t_symbol *msg, short argc, t_atom *argv)
x->overlap = atom_getintarg(1,argc,argv);
x->winfac = atom_getintarg(2,argc,argv);
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 1;
disarray_init(x,0);
return (x);
@@ -248,10 +248,10 @@ void disarray_init(t_disarray *x, short initialized)
float curfreq;
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 1;
}
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
diff --git a/drown~-help.pd b/drown~-help.pd
new file mode 100644
index 0000000..bb4ee3f
--- /dev/null
+++ b/drown~-help.pd
@@ -0,0 +1,64 @@
+#N canvas 1012 277 466 316 10;
+#N canvas 0 22 470 320 drown-block 0;
+#X obj 178 165 drown~ 0.001 0.1 4 1;
+#X obj 178 195 outlet~;
+#X obj 178 124 inlet~;
+#X obj 245 123 inlet;
+#X obj 313 125 inlet;
+#X obj 371 129 inlet;
+#X obj 178 232 block~ 256;
+#X connect 0 0 1 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 1;
+#X connect 4 0 0 2;
+#X connect 5 0 0 0;
+#X restore 18 93 pd drown-block;
+#X obj 18 140 dac~;
+#X msg 24 256 \; pd dsp \$1;
+#X obj 24 233 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X floatatom 49 49 5 0 0 0 - threshold -;
+#X floatatom 80 65 5 0 0 0 - noise-gain -;
+#N canvas 730 185 462 312 sound-source 0;
+#X obj 127 102 osc~ 350;
+#X obj 127 194 outlet~;
+#X obj 249 107 noise~;
+#X obj 127 155 *~ 0.1;
+#X obj 249 143 *~ 0.03;
+#X text 58 103 signal ->;
+#X text 298 110 <- add noise;
+#X connect 0 0 3 0;
+#X connect 2 0 4 0;
+#X connect 3 0 1 0;
+#X connect 4 0 1 0;
+#X restore 18 7 pd sound-source;
+#N canvas 928 509 470 320 messages 0;
+#X obj 231 210 outlet;
+#N canvas 0 22 458 308 init 0;
+#X obj 333 21 loadbang;
+#X obj 333 71 unpack f f;
+#X obj 333 103 s drown-s1;
+#X obj 362 129 s drown-s2;
+#X msg 333 48 0.01 1;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 1 1 3 0;
+#X connect 4 0 1 0;
+#X restore 89 104 pd init;
+#X obj 231 180 fftease-system;
+#X connect 2 0 0 0;
+#X restore 163 77 pd messages;
+#X obj 26 173 hsl 128 15 0 0.02 0 0 threshold drown-s1 threshold -2
+-6 0 8 -189148 -1 -1 6800 1;
+#X obj 26 211 hsl 128 15 0 1 0 0 noise-gain drown-s2 noise-gain -2
+-6 0 8 -189148 -1 -1 0 1;
+#X text 160 210 <- reduce noise here;
+#X text 160 172 <- threshold to block noise;
+#X text 103 265 threshold-based noise reduction;
+#X connect 0 0 1 0;
+#X connect 0 0 1 1;
+#X connect 3 0 2 0;
+#X connect 4 0 0 1;
+#X connect 5 0 0 2;
+#X connect 6 0 0 0;
+#X connect 7 0 0 3;
diff --git a/drown~.c b/drown~.c
index b7fe734..4d9b6b0 100644
--- a/drown~.c
+++ b/drown~.c
@@ -127,7 +127,7 @@ void drown_tilde_setup(void)
void drown_overlap(t_drown *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -139,7 +139,7 @@ void drown_winfac(t_drown *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -202,9 +202,9 @@ void *drown_new(t_symbol *s, int argc, t_atom *argv)
x->threshold = .0001;
if(x->drownmult <= 0)
x->drownmult = 0.1;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 1;
x->vs = sys_getblksize();
diff --git a/ether~.c b/ether~.c
index 4293676..124d8c5 100644
--- a/ether~.c
+++ b/ether~.c
@@ -160,7 +160,7 @@ void ether_free(t_ether *x)
void ether_overlap(t_ether *x, t_floatarg df)
{
int o = (int)df;
- if(!power_of_two(o)){
+ if(!fftease_power_of_two(o)){
error("%d is not a power of two",o);
return;
}
@@ -171,7 +171,7 @@ int o = (int)df;
void ether_winfac(t_ether *x, t_floatarg f)
{
int wf = (int)f;
- if(!power_of_two(wf)){
+ if(!fftease_power_of_two(wf)){
error("%f is not a power of two",f);
return;
}
@@ -209,10 +209,10 @@ void *ether_new(t_symbol *s, int argc, t_atom *argv)
x->overlap = atom_getfloatarg(0,argc,argv);
x->winfac = atom_getfloatarg(1,argc,argv);
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 1;
}
x->vs = sys_getblksize();
diff --git a/fft.c b/fft.c
new file mode 100644
index 0000000..d6bb1bc
--- /dev/null
+++ b/fft.c
@@ -0,0 +1 @@
+#include "fftease.h" /* If forward is true, rfft replaces 2*N real data points in x with N complex values representing the positive frequency half of their Fourier spectrum, with x[1] replaced with the real part of the Nyquist frequency value. If forward is false, rfft expects x to contain a positive frequency spectrum arranged as before, and replaces it with 2*N real values. N MUST be a power of 2. */ void rfft( float *x, int N, int forward ) { float c1,c2, h1r,h1i, h2r,h2i, wr,wi, wpr,wpi, temp, theta; float xr,xi; int i, i1,i2,i3,i4, N2p1; static int first = 1; /*float PI, TWOPI;*/ void cfft(); if ( first ) { first = 0; } theta = PI/N; wr = 1.; wi = 0.; c1 = 0.5; if ( forward ) { c2 = -0.5; cfft( x, N, forward ); xr = x[0]; xi = x[1]; } else { c2 = 0.5; theta = -theta; xr = x[1]; xi = 0.; x[1] = 0.; } wpr = -2.*pow( sin( 0.5*theta ), 2. ); wpi = sin( theta ); N2p1 = (N<<1) + 1; for ( i = 0; i <= N>>1; i++ ) { i1 = i<<1; i2 = i1 + 1; i3 = N2p1 - i2; i4 = i3 + 1; if ( i == 0 ) { h1r = c1*(x[i1] + xr ); h1i = c1*(x[i2] - xi ); h2r = -c2*(x[i2] + xi ); h2i = c2*(x[i1] - xr ); x[i1] = h1r + wr*h2r - wi*h2i; x[i2] = h1i + wr*h2i + wi*h2r; xr = h1r - wr*h2r + wi*h2i; xi = -h1i + wr*h2i + wi*h2r; } else { h1r = c1*(x[i1] + x[i3] ); h1i = c1*(x[i2] - x[i4] ); h2r = -c2*(x[i2] + x[i4] ); h2i = c2*(x[i1] - x[i3] ); x[i1] = h1r + wr*h2r - wi*h2i; x[i2] = h1i + wr*h2i + wi*h2r; x[i3] = h1r - wr*h2r + wi*h2i; x[i4] = -h1i + wr*h2i + wi*h2r; } wr = (temp = wr)*wpr - wi*wpi + wr; wi = wi*wpr + temp*wpi + wi; } if ( forward ) x[1] = xr; else cfft( x, N, forward ); } /* cfft replaces float array x containing NC complex values (2*NC float values alternating real, imagininary, etc.) by its Fourier transform if forward is true, or by its inverse Fourier transform if forward is false, using a recursive Fast Fourier transform method due to Danielson and Lanczos. NC MUST be a power of 2. */ void cfft( float *x, int NC, int forward ) { float wr,wi, wpr,wpi, theta, scale; int mmax, ND, m, i,j, delta; void bitreverse(); ND = NC<<1; bitreverse( x, ND ); for ( mmax = 2; mmax < ND; mmax = delta ) { delta = mmax<<1; theta = TWOPI/( forward? mmax : -mmax ); wpr = -2.*pow( sin( 0.5*theta ), 2. ); wpi = sin( theta ); wr = 1.; wi = 0.; for ( m = 0; m < mmax; m += 2 ) { register float rtemp, itemp; for ( i = m; i < ND; i += delta ) { j = i + mmax; rtemp = wr*x[j] - wi*x[j+1]; itemp = wr*x[j+1] + wi*x[j]; x[j] = x[i] - rtemp; x[j+1] = x[i+1] - itemp; x[i] += rtemp; x[i+1] += itemp; } wr = (rtemp = wr)*wpr - wi*wpi + wr; wi = wi*wpr + rtemp*wpi + wi; } } /* scale output */ scale = forward ? 1./ND : 2.; { register float *xi=x, *xe=x+ND; while ( xi < xe ) *xi++ *= scale; } } /* bitreverse places float array x containing N/2 complex values into bit-reversed order */ void bitreverse( float *x, int N ) { float rtemp,itemp; int i,j, m; for ( i = j = 0; i < N; i += 2, j += m ) { if ( j > i ) { rtemp = x[j]; itemp = x[j+1]; /* complex exchange */ x[j] = x[i]; x[j+1] = x[i+1]; x[i] = rtemp; x[i+1] = itemp; } for ( m = N>>1; m >= 2 && j >= m; m >>= 1 ) j -= m; } } \ No newline at end of file
diff --git a/fft4.c b/fft4.c
new file mode 100644
index 0000000..fb22118
--- /dev/null
+++ b/fft4.c
@@ -0,0 +1 @@
+#include <math.h> #include "fftease.h" void init_rdft(int n, int *ip, float *w) { int nw, nc; void makewt(int nw, int *ip, float *w); void makect(int nc, int *ip, float *c); nw = n >> 2; makewt(nw, ip, w); nc = n >> 2; makect(nc, ip, w + nw); return; } void rdft(int n, int isgn, float *a, int *ip, float *w) { int j, nw, nc; float xi; void bitrv2(int n, int *ip, float *a), cftsub(int n, float *a, float *w), rftsub(int n, float *a, int nc, float *c); nw = ip[0]; nc = ip[1]; if (isgn < 0) { a[1] = 0.5 * (a[1] - a[0]); a[0] += a[1]; for (j = 3; j <= n - 1; j += 2) { a[j] = -a[j]; } if (n > 4) { rftsub(n, a, nc, w + nw); bitrv2(n, ip + 2, a); } cftsub(n, a, w); for (j = 1; j <= n - 1; j += 2) { a[j] = -a[j]; } } else { if (n > 4) { bitrv2(n, ip + 2, a); } cftsub(n, a, w); if (n > 4) { rftsub(n, a, nc, w + nw); } xi = a[0] - a[1]; a[0] += a[1]; a[1] = xi; } } void bitrv2(int n, int *ip, float *a) { int j, j1, k, k1, l, m, m2; float xr, xi; ip[0] = 0; l = n; m = 1; while ((m << 2) < l) { l >>= 1; for (j = 0; j <= m - 1; j++) { ip[m + j] = ip[j] + l; } m <<= 1; } if ((m << 2) > l) { for (k = 1; k <= m - 1; k++) { for (j = 0; j <= k - 1; j++) { j1 = (j << 1) + ip[k]; k1 = (k << 1) + ip[j]; xr = a[j1]; xi = a[j1 + 1]; a[j1] = a[k1]; a[j1 + 1] = a[k1 + 1]; a[k1] = xr; a[k1 + 1] = xi; } } } else { m2 = m << 1; for (k = 1; k <= m - 1; k++) { for (j = 0; j <= k - 1; j++) { j1 = (j << 1) + ip[k]; k1 = (k << 1) + ip[j]; xr = a[j1]; xi = a[j1 + 1]; a[j1] = a[k1]; a[j1 + 1] = a[k1 + 1]; a[k1] = xr; a[k1 + 1] = xi; j1 += m2; k1 += m2; xr = a[j1]; xi = a[j1 + 1]; a[j1] = a[k1]; a[j1 + 1] = a[k1 + 1]; a[k1] = xr; a[k1 + 1] = xi; } } } } void cftsub(int n, float *a, float *w) { int j, j1, j2, j3, k, k1, ks, l, m; float wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; l = 2; while ((l << 1) < n) { m = l << 2; for (j = 0; j <= l - 2; j += 2) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; a[j2] = x0r - x2r; a[j2 + 1] = x0i - x2i; a[j1] = x1r - x3i; a[j1 + 1] = x1i + x3r; a[j3] = x1r + x3i; a[j3 + 1] = x1i - x3r; } if (m < n) { wk1r = w[2]; for (j = m; j <= l + m - 2; j += 2) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; a[j2] = x2i - x0i; a[j2 + 1] = x0r - x2r; x0r = x1r - x3i; x0i = x1i + x3r; a[j1] = wk1r * (x0r - x0i); a[j1 + 1] = wk1r * (x0r + x0i); x0r = x3i + x1r; x0i = x3r - x1i; a[j3] = wk1r * (x0i - x0r); a[j3 + 1] = wk1r * (x0i + x0r); } k1 = 1; ks = -1; for (k = (m << 1); k <= n - m; k += m) { k1++; ks = -ks; wk1r = w[k1 << 1]; wk1i = w[(k1 << 1) + 1]; wk2r = ks * w[k1]; wk2i = w[k1 + ks]; wk3r = wk1r - 2 * wk2i * wk1i; wk3i = 2 * wk2i * wk1r - wk1i; for (j = k; j <= l + k - 2; j += 2) { j1 = j + l; j2 = j1 + l; j3 = j2 + l; x0r = a[j] + a[j1]; x0i = a[j + 1] + a[j1 + 1]; x1r = a[j] - a[j1]; x1i = a[j + 1] - a[j1 + 1]; x2r = a[j2] + a[j3]; x2i = a[j2 + 1] + a[j3 + 1]; x3r = a[j2] - a[j3]; x3i = a[j2 + 1] - a[j3 + 1]; a[j] = x0r + x2r; a[j + 1] = x0i + x2i; x0r -= x2r; x0i -= x2i; a[j2] = wk2r * x0r - wk2i * x0i; a[j2 + 1] = wk2r * x0i + wk2i * x0r; x0r = x1r - x3i; x0i = x1i + x3r; a[j1] = wk1r * x0r - wk1i * x0i; a[j1 + 1] = wk1r * x0i + wk1i * x0r; x0r = x1r + x3i; x0i = x1i - x3r; a[j3] = wk3r * x0r - wk3i * x0i; a[j3 + 1] = wk3r * x0i + wk3i * x0r; } } } l = m; } if (l < n) { for (j = 0; j <= l - 2; j += 2) { j1 = j + l; x0r = a[j] - a[j1]; x0i = a[j + 1] - a[j1 + 1]; a[j] += a[j1]; a[j + 1] += a[j1 + 1]; a[j1] = x0r; a[j1 + 1] = x0i; } } } void rftsub(int n, float *a, int nc, float *c) { int j, k, kk, ks; float wkr, wki, xr, xi, yr, yi; ks = (nc << 2) / n; kk = 0; for (k = (n >> 1) - 2; k >= 2; k -= 2) { j = n - k; kk += ks; wkr = 0.5 - c[kk]; wki = c[nc - kk]; xr = a[k] - a[j]; xi = a[k + 1] + a[j + 1]; yr = wkr * xr - wki * xi; yi = wkr * xi + wki * xr; a[k] -= yr; a[k + 1] -= yi; a[j] += yr; a[j + 1] -= yi; } } void makewt(int nw, int *ip, float *w) { void bitrv2(int n, int *ip, float *a); int nwh, j; float delta, x, y; ip[0] = nw; ip[1] = 1; if (nw > 2) { nwh = nw >> 1; delta = atan(1.0) / nwh; w[0] = 1; w[1] = 0; w[nwh] = cos(delta * nwh); w[nwh + 1] = w[nwh]; for (j = 2; j <= nwh - 2; j += 2) { x = cos(delta * j); y = sin(delta * j); w[j] = x; w[j + 1] = y; w[nw - j] = y; w[nw - j + 1] = x; } bitrv2(nw, ip + 2, w); } } void makect(int nc, int *ip, float *c) { int nch, j; float delta; ip[1] = nc; if (nc > 1) { nch = nc >> 1; delta = atan(1.0) / nch; c[0] = 0.5; c[nch] = 0.5 * cos(delta * nch); for (j = 1; j <= nch - 1; j++) { c[j] = 0.5 * cos(delta * j); c[nc - j] = 0.5 * sin(delta * j); } } } \ No newline at end of file
diff --git a/fftease-system.pd b/fftease-system.pd
new file mode 100644
index 0000000..bccbc61
--- /dev/null
+++ b/fftease-system.pd
@@ -0,0 +1,38 @@
+#N canvas 724 87 493 474 10;
+#X obj 174 207 outlet;
+#X msg 174 167 overlap \$1;
+#X msg 161 122 2;
+#X msg 202 121 4;
+#X msg 235 120 8;
+#X msg 297 165 winfac \$1;
+#X msg 282 120 1;
+#X msg 323 119 2;
+#X msg 355 118 4;
+#X msg 36 175 fftinfo;
+#X msg 102 155 mute \$1;
+#X obj 102 120 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X text 45 27 FFT size is overlap times the fftease subpatch block
+size (256 in our examples). With a blocksize of 256 and overlap 4 your
+FFT size is 1024 Higher overlap generally gives higher quality \, but
+CPU load is proportional to overlap \, so if you double the overlap
+\, you double the CPU load.;
+#X text 33 245 winfac determines the ratio between the FFT size and
+an input window that funnels samples into the FFT. Roughly speaking
+\, smaller window sizes (minimum is 1) give tighter temporal response
+\, but higher sizes can improve frequency performance \, especially
+with lower FFT sizes.;
+#X text 29 337 It is recommended that overlap and winfac only be used
+when the DACs are off. They can potentially crash Pd when the DACs
+are active.;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 1 0;
+#X connect 4 0 1 0;
+#X connect 5 0 0 0;
+#X connect 6 0 5 0;
+#X connect 7 0 5 0;
+#X connect 8 0 5 0;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X connect 11 0 10 0;
diff --git a/fftease.h b/fftease.h
new file mode 100644
index 0000000..f858b52
--- /dev/null
+++ b/fftease.h
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/*
+The new improved fftease.h
+*/
+
+#define getbytes t_getbytes
+#define freebytes t_freebytes
+#define resizebytes t_resizebytes
+
+#define FFTEASE_ANNOUNCEMENT "- a member of FFTease 2.52"
+
+#ifndef PI
+#define PI 3.141592653589793115997963468544185161590576171875
+#endif
+
+#ifndef TWOPI
+#define TWOPI 6.28318530717958623199592693708837032318115234375
+#endif
+
+#define MAX_N (16384)
+#define MAX_N2 (MAX_N/2)
+#define MAX_Nw (MAX_N * 4)
+
+void convert(float *S, float *C, int N2, float *lastphase, float fundamental, float factor );
+void unconvert( float *C, float *S, int N2, float *lastphase, float fundamental, float factor );
+void rfft( float *x, int N, int forward );
+void cfft( float *x, int NC, int forward );
+void bitreverse( float *x, int N );
+void fold( float *I, float *W, int Nw, float *O, int N, int n );
+void init_rdft(int n, int *ip, float *w);
+void rdft(int n, int isgn, float *a, int *ip, float *w);
+void bitrv2(int n, int *ip, float *a);
+void cftsub(int n, float *a, float *w);
+void rftsub(int n, float *a, int nc, float *c);
+void makewt(int nw, int *ip, float *w);
+void makect(int nc, int *ip, float *c);
+void leanconvert( float *S, float *C, int N2 );
+void leanunconvert( float *C, float *S, int N2 );
+void makewindows( float *H, float *A, float *S, int Nw, int N, int I );
+void makehamming( float *H, float *A, float *S, int Nw, int N, int I,int odd );
+void makehanning( float *H, float *A, float *S, int Nw, int N, int I,int odd );
+void overlapadd( float *I, int N, float *W, float *O, int Nw, int n );
+void bloscbank( float *S, float *O, int D, float iD, float *lf, float *la,
+ float *bindex, float *tab, int len, float synt, int lo, int hi );
+
+float randf( float min, float max );
+int randi( int min, int max );
+int power_of_two(int test);
+
+
+void freebytes2(void *fatso, size_t nbytes);
+void *getbytes2(size_t nbytes);
+void *resizebytes2(void *old, size_t oldsize, size_t newsize);
+void limit_fftsize(int *N, int *Nw, char *OBJECT_NAME);
+
+/* THE FUNCTIONS */
diff --git a/fftease_setup.c b/fftease_setup.c
new file mode 100644
index 0000000..8c42f60
--- /dev/null
+++ b/fftease_setup.c
@@ -0,0 +1,5 @@
+void fftease_setup(void)
+{
+ post("Loaded FFTease Library");
+ printf("Loaded FFTease Library(2)");
+}
diff --git a/fold.c b/fold.c
new file mode 100644
index 0000000..0523d28
--- /dev/null
+++ b/fold.c
@@ -0,0 +1 @@
+#include "fftease.h" /* * multiply current input I by window W (both of length Nw); * using modulus arithmetic, fold and rotate windowed input * into output array O of (FFT) length N according to current * input time n */ void fold( float *I, float *W, int Nw, float *O, int N, int n ) { int i; for ( i = 0; i < N; i++ ) O[i] = 0.; while ( n < 0 ) n += N; n %= N; for ( i = 0; i < Nw; i++ ) { O[n] += I[i]*W[i]; if ( ++n == N ) n = 0; } } \ No newline at end of file
diff --git a/help/burrow~-help.pd b/help/burrow~-help.pd
deleted file mode 100644
index 5e50cb7..0000000
--- a/help/burrow~-help.pd
+++ /dev/null
@@ -1,90 +0,0 @@
-#N canvas 143 237 600 366 12;
-#X msg 17 161 getattributes;
-#X obj 391 278 print A;
-#X obj 161 210 burrow~ -30 -18 0;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 211 78 tgl 20 0 empty empty inverse_filtering 0 -6 0 10 -225271
--1 -1 0 1;
-#X msg 211 102 invert \$1;
-#X obj 373 78 nbx 5 18 -100 0 0 1 empty empty filtering_threshold(dB)
-0 -6 0 10 -225271 -1 -1 -30 256;
-#X msg 373 100 thresh \$1;
-#X obj 374 145 nbx 5 18 -100 0 0 1 empty empty filter_multiplier(dB)
-0 -6 0 10 -225271 -1 -1 -18 256;
-#X msg 374 167 mult \$1;
-#X obj 161 275 *~;
-#X obj 202 280 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 10000 1;
-#X obj 150 312 dac~;
-#X text 390 297 print attributes;
-#X text 15 143 list attributes;
-#X obj 16 8 cnv 15 550 40 empty empty burrow~ 10 22 0 24 -260818 -1
-0;
-#X text 188 8 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 188 28 Pd port;
-#X text 222 231 threshold \, multiplier \, invert;
-#X obj 138 80 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 233 172 pd schubert;
-#N canvas 35 47 460 310 nixon 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/nixon.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 161 172 pd nixon;
-#X msg 17 259 getthresh;
-#X msg 17 284 getmult;
-#X msg 17 234 getinvert;
-#X text 15 213 get attributes;
-#X connect 0 0 2 0;
-#X connect 2 0 11 0;
-#X connect 2 1 1 0;
-#X connect 3 0 4 0;
-#X connect 4 0 2 0;
-#X connect 5 0 6 0;
-#X connect 6 0 2 0;
-#X connect 7 0 8 0;
-#X connect 8 0 2 0;
-#X connect 9 0 10 0;
-#X connect 10 0 2 0;
-#X connect 11 0 13 0;
-#X connect 11 0 13 1;
-#X connect 12 0 11 1;
-#X connect 20 0 21 0;
-#X connect 20 0 22 0;
-#X connect 21 0 2 1;
-#X connect 22 0 2 0;
-#X connect 23 0 2 0;
-#X connect 24 0 2 0;
-#X connect 25 0 2 0;
diff --git a/help/cross~-help.pd b/help/cross~-help.pd
deleted file mode 100644
index 6d5523a..0000000
--- a/help/cross~-help.pd
+++ /dev/null
@@ -1,88 +0,0 @@
-#N canvas 275 53 604 370 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 312 84 nbx 5 18 -100 0 0 1 empty empty threshold(dB) 0 -6 0
-10 -225271 -1 -1 -86 256;
-#X obj 161 275 *~;
-#X obj 202 280 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 11800 1;
-#X obj 150 312 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty cross~ 10 22 0 24 -260818 -1
-0;
-#X text 188 8 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 188 28 Pd port;
-#X obj 161 210 cross~;
-#X obj 312 161 sig~;
-#X obj 311 113 + 100;
-#X obj 312 136 dbtorms;
-#X obj 161 80 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 162 175 pd schubert;
-#N canvas 35 47 460 310 nixon 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/nixon.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 183 142 pd nixon;
-#X msg 17 161 getattributes;
-#X text 15 143 list attributes;
-#X text 15 215 get attributes;
-#X obj 445 85 tgl 25 1 empty empty memorize 0 -6 0 10 -225271 -1 -1
-1 1;
-#X text 371 182 partials below the threshold;
-#X text 370 200 are taken from the previous;
-#X text 370 216 frame;
-#X obj 391 278 print A;
-#X text 390 297 print attributes;
-#X msg 17 234 getmemorize;
-#X text 373 165 memorize defaults to 1;
-#X msg 445 117 memorize \$1;
-#X connect 0 0 1 0;
-#X connect 1 0 9 0;
-#X connect 2 0 11 0;
-#X connect 3 0 5 0;
-#X connect 3 0 5 1;
-#X connect 4 0 3 1;
-#X connect 9 0 3 0;
-#X connect 9 1 23 0;
-#X connect 10 0 9 2;
-#X connect 11 0 12 0;
-#X connect 12 0 10 0;
-#X connect 13 0 14 0;
-#X connect 13 0 15 0;
-#X connect 14 0 9 0;
-#X connect 15 0 9 1;
-#X connect 16 0 9 0;
-#X connect 19 0 27 0;
-#X connect 25 0 9 0;
-#X connect 27 0 9 0;
diff --git a/help/dentist~-help.pd b/help/dentist~-help.pd
deleted file mode 100644
index 3ca8841..0000000
--- a/help/dentist~-help.pd
+++ /dev/null
@@ -1,65 +0,0 @@
-#N canvas 45 260 600 366 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 417 91 nbx 5 18 0 20000 0 0 empty empty knee_frq 0 -6 0 10 -225271
--1 -1 0 256;
-#X obj 211 272 *~;
-#X obj 252 277 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 10200 1;
-#X obj 200 309 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty dentist~ 10 22 0 24 -260818 -1
-0;
-#X text 198 8 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 198 28 Pd port;
-#X msg 14 181 getattributes;
-#X obj 432 255 print A;
-#X obj 337 90 bng 25 250 50 0 empty empty reshuffle 0 -6 0 8 -225271
--1 -1;
-#X msg 417 123 knee \$1;
-#X obj 495 91 nbx 5 18 0 1000 0 0 empty empty teeth 0 -6 0 10 -225271
--1 -1 0 256;
-#X msg 495 123 teeth \$1;
-#X text 348 209 knee frq. \, teeth;
-#X obj 211 208 dentist~ 1000 10;
-#X text 14 164 list attributes;
-#X obj 212 92 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 212 156 pd schubert;
-#X text 15 222 get attributes;
-#X msg 15 239 getknee;
-#X msg 15 267 getteeth;
-#X connect 0 0 1 0;
-#X connect 1 0 16 0;
-#X connect 2 0 12 0;
-#X connect 3 0 5 0;
-#X connect 3 0 5 1;
-#X connect 4 0 3 1;
-#X connect 9 0 16 0;
-#X connect 11 0 16 0;
-#X connect 12 0 16 0;
-#X connect 13 0 14 0;
-#X connect 14 0 16 0;
-#X connect 16 0 3 0;
-#X connect 16 1 10 0;
-#X connect 18 0 19 0;
-#X connect 19 0 16 0;
-#X connect 21 0 16 0;
-#X connect 22 0 16 0;
diff --git a/help/disarray~-help.pd b/help/disarray~-help.pd
deleted file mode 100644
index d3238a2..0000000
--- a/help/disarray~-help.pd
+++ /dev/null
@@ -1,67 +0,0 @@
-#N canvas 68 275 606 372 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 369 88 nbx 5 18 0 20000 0 1 empty empty knee_frq 0 -6 0 10 -225271
--1 -1 1300 256;
-#X obj 211 272 *~;
-#X obj 252 277 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 9600 1;
-#X obj 200 309 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty disarray~ 10 22 0 24 -260818
--1 0;
-#X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 206 27 Pd port;
-#X msg 14 181 getattributes;
-#X obj 427 281 print A;
-#X text 14 164 list attributes;
-#X obj 211 217 disarray~ 1300 0 20;
-#X obj 281 89 bng 25 250 50 0 empty empty reshuffle 0 -6 0 10 -225271
--1 -1;
-#X obj 454 88 nbx 5 18 0 1000 0 1 empty empty shuffle_count 0 -6 0
-10 -225271 -1 -1 20 256;
-#X text 424 300 attributes;
-#X text 15 219 get attributes;
-#X obj 207 89 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 212 154 pd schubert;
-#X msg 369 120 knee \$1;
-#X msg 454 120 partials \$1;
-#X msg 15 238 getknee;
-#X msg 16 263 getpartials;
-#X text 292 199 knee frq \, quality \, partials;
-#X text 367 218 (these are the defaults);
-#X connect 0 0 1 0;
-#X connect 1 0 12 0;
-#X connect 2 0 19 0;
-#X connect 3 0 5 0;
-#X connect 3 0 5 1;
-#X connect 4 0 3 1;
-#X connect 9 0 12 0;
-#X connect 12 0 3 0;
-#X connect 12 1 10 0;
-#X connect 13 0 12 0;
-#X connect 14 0 20 0;
-#X connect 17 0 18 0;
-#X connect 18 0 12 0;
-#X connect 19 0 12 0;
-#X connect 20 0 12 0;
-#X connect 21 0 12 0;
-#X connect 22 0 12 0;
diff --git a/help/drown~-help.pd b/help/drown~-help.pd
deleted file mode 100644
index 1a35b97..0000000
--- a/help/drown~-help.pd
+++ /dev/null
@@ -1,61 +0,0 @@
-#N canvas 140 138 612 378 12;
-#X obj 17 90 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 115 enable \$1;
-#X obj 166 272 *~;
-#X obj 207 277 hsl 128 15 0.001 1000 1 1 empty empty volume -2 -6 0
-10 -261681 -1 -1 9700 1;
-#X obj 155 309 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty drown~ 10 22 0 24 -260818 -1
-0;
-#X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 206 27 Pd port;
-#X obj 294 97 nbx 5 18 -100 0 0 1 empty empty threshold 0 -6 0 10 -225271
--1 -1 -75 256;
-#X obj 166 88 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 166 126 pd schubert;
-#X obj 166 217 drown~;
-#X obj 384 174 sig~ 1;
-#X obj 385 99 nbx 5 18 -100 10 0 1 empty empty multiplication_factor
-0 -6 0 10 -225271 -1 -1 -18 256;
-#X obj 292 175 sig~ 1;
-#X obj 294 125 + 100;
-#X obj 385 125 + 100;
-#X obj 385 148 dbtorms;
-#X obj 293 149 dbtorms;
-#X obj 405 324 denude~;
-#X text 403 345 alternative naming;
-#X connect 0 0 1 0;
-#X connect 1 0 11 0;
-#X connect 2 0 4 0;
-#X connect 2 0 4 1;
-#X connect 3 0 2 1;
-#X connect 8 0 15 0;
-#X connect 9 0 10 0;
-#X connect 10 0 11 0;
-#X connect 11 0 2 0;
-#X connect 12 0 11 2;
-#X connect 13 0 16 0;
-#X connect 14 0 11 1;
-#X connect 15 0 18 0;
-#X connect 16 0 17 0;
-#X connect 17 0 12 0;
-#X connect 18 0 14 0;
diff --git a/help/ether~-help.pd b/help/ether~-help.pd
deleted file mode 100644
index 5eed4e0..0000000
--- a/help/ether~-help.pd
+++ /dev/null
@@ -1,84 +0,0 @@
-#N canvas 140 138 602 368 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 211 272 *~;
-#X obj 252 277 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 8600 1;
-#X obj 200 309 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty ether~ 10 22 0 24 -260818 -1
-0;
-#X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 206 27 Pd port;
-#X msg 14 181 getattributes;
-#X obj 427 281 print A;
-#X text 14 164 list attributes;
-#X obj 499 84 nbx 5 18 0 1000 0 0 empty empty index 0 -6 0 10 -225271
--1 -1 22 256;
-#X text 424 300 attributes;
-#X msg 387 117 invert \$1;
-#X obj 387 83 tgl 25 0 empty empty invert 0 -6 0 8 -225271 -1 -1 0
-1;
-#X msg 499 116 index \$1;
-#X obj 211 217 ether~ 1;
-#X text 287 212 quality \, invert \, index;
-#X obj 211 88 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 271 172 pd schubert;
-#N canvas 35 47 460 310 nixon 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/nixon.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 212 148 pd nixon;
-#X text 15 213 get attributes;
-#X msg 15 230 getinvert;
-#X msg 16 259 getindex;
-#X text 287 228 (defaults are 0 \, 0 \, 0);
-#X connect 0 0 1 0;
-#X connect 1 0 16 0;
-#X connect 2 0 4 0;
-#X connect 2 0 4 1;
-#X connect 3 0 2 1;
-#X connect 8 0 16 0;
-#X connect 11 0 15 0;
-#X connect 13 0 16 0;
-#X connect 14 0 13 0;
-#X connect 15 0 16 0;
-#X connect 16 0 2 0;
-#X connect 16 1 9 0;
-#X connect 18 0 19 0;
-#X connect 18 0 20 0;
-#X connect 19 0 16 1;
-#X connect 20 0 16 0;
-#X connect 22 0 16 0;
-#X connect 23 0 16 0;
diff --git a/help/morphine~-help.pd b/help/morphine~-help.pd
deleted file mode 100644
index 6124b23..0000000
--- a/help/morphine~-help.pd
+++ /dev/null
@@ -1,77 +0,0 @@
-#N canvas 140 138 606 372 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 211 272 *~;
-#X obj 252 277 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 10000 1;
-#X obj 200 309 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty morphine~ 10 22 0 24 -260818
--1 0;
-#X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 206 27 Pd port;
-#X msg 14 181 getattributes;
-#X obj 427 281 print A;
-#X text 14 164 list attributes;
-#X obj 414 86 nbx 5 18 0.001 1 1 1 empty empty index 0 -6 0 10 -225271
--1 -1 0.001 256;
-#X text 424 300 attributes;
-#X msg 414 110 index \$1;
-#X obj 211 88 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 210 184 pd schubert;
-#N canvas 35 47 460 310 nixon 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/nixon.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 307 186 pd nixon;
-#X text 15 215 get attributes;
-#X msg 16 234 getindex;
-#X text 477 87 (0...1);
-#X obj 211 217 morphine~ 0.05;
-#X text 336 219 index (defaults to 0);
-#X connect 0 0 1 0;
-#X connect 1 0 20 0;
-#X connect 2 0 4 0;
-#X connect 2 0 4 1;
-#X connect 3 0 2 1;
-#X connect 8 0 20 0;
-#X connect 11 0 13 0;
-#X connect 13 0 20 0;
-#X connect 14 0 15 0;
-#X connect 14 0 16 0;
-#X connect 15 0 20 0;
-#X connect 16 0 20 1;
-#X connect 18 0 20 0;
-#X connect 20 0 2 0;
-#X connect 20 1 9 0;
diff --git a/help/residency~-help.pd b/help/residency~-help.pd
deleted file mode 100644
index f80a2b5..0000000
--- a/help/residency~-help.pd
+++ /dev/null
@@ -1,33 +0,0 @@
-#N canvas 37 209 558 409 10;
-#X floatatom 264 146 5 0 0 0 - - -;
-#X obj 207 190 residency~ 5000 1;
-#X floatatom 321 145 5 0 0 0 - - -;
-#X obj 198 278 dac~;
-#X obj 207 243 *~;
-#X obj 83 133 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
-;
-#X msg 83 156 playthrough \$1;
-#X obj 206 60 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
--1;
-#X obj 342 12 adc~;
-#X obj 414 69 prvu~;
-#X obj 415 94 vu 15 120 empty empty -1 -8 0 8 -66577 -1 1 0;
-#X obj 242 101 *~;
-#X obj 261 81 hsl 128 15 0.01 1 1 0 empty empty gain 12 8 1 12 -225271
--1 -1 0 1;
-#X obj 226 224 hsl 128 15 0.01 1 1 0 empty empty gain 12 8 1 12 -225271
--1 -1 0 1;
-#X connect 0 0 1 1;
-#X connect 1 0 4 0;
-#X connect 2 0 1 2;
-#X connect 4 0 3 0;
-#X connect 4 0 3 1;
-#X connect 5 0 6 0;
-#X connect 6 0 1 0;
-#X connect 7 0 1 0;
-#X connect 8 0 9 0;
-#X connect 8 0 11 0;
-#X connect 9 0 10 0;
-#X connect 11 0 1 0;
-#X connect 12 0 11 1;
-#X connect 13 0 4 1;
diff --git a/help/scrape~-help.pd b/help/scrape~-help.pd
deleted file mode 100644
index 72f2440..0000000
--- a/help/scrape~-help.pd
+++ /dev/null
@@ -1,72 +0,0 @@
-#N canvas 140 138 606 372 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 211 272 *~;
-#X obj 252 277 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 9800 1;
-#X obj 200 309 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty scrape~ 10 22 0 24 -260818 -1
-0;
-#X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 206 27 Pd port;
-#X msg 14 181 getattributes;
-#X obj 427 281 print A;
-#X text 14 164 list attributes;
-#X obj 423 90 nbx 5 18 10 20000 1 1 empty empty knee 0 -6 0 10 -225271
--1 -1 1000 256;
-#X text 424 300 attributes;
-#X obj 211 88 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 210 184 pd schubert;
-#X text 15 215 get attributes;
-#X obj 319 89 nbx 5 18 -100 0 0 1 empty empty multiplier 0 -6 0 10
--225271 -1 -1 -60 256;
-#X obj 318 183 sig~ 1;
-#X obj 318 116 + 100;
-#X obj 318 143 dbtorms;
-#X msg 16 234 getknee;
-#X msg 16 257 getcutoff;
-#X msg 423 114 knee \$1;
-#X obj 505 90 nbx 5 18 10 20000 1 1 empty empty cutoff 0 -6 0 10 -225271
--1 -1 2000 256;
-#X msg 505 114 cutoff \$1;
-#X obj 211 217 scrape~ 1000 2000;
-#X text 361 219 knee \, cutoff;
-#X connect 0 0 1 0;
-#X connect 1 0 25 0;
-#X connect 2 0 4 0;
-#X connect 2 0 4 1;
-#X connect 3 0 2 1;
-#X connect 8 0 25 0;
-#X connect 11 0 22 0;
-#X connect 13 0 14 0;
-#X connect 14 0 25 0;
-#X connect 16 0 18 0;
-#X connect 17 0 25 1;
-#X connect 18 0 19 0;
-#X connect 19 0 17 0;
-#X connect 20 0 25 0;
-#X connect 21 0 25 0;
-#X connect 22 0 25 0;
-#X connect 23 0 24 0;
-#X connect 24 0 25 0;
-#X connect 25 0 2 0;
-#X connect 25 1 9 0;
diff --git a/help/shapee~-help.pd b/help/shapee~-help.pd
deleted file mode 100644
index c0a06de..0000000
--- a/help/shapee~-help.pd
+++ /dev/null
@@ -1,62 +0,0 @@
-#N canvas 140 138 612 378 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 211 272 *~;
-#X obj 252 277 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 10700 1;
-#X obj 200 309 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty shapee~ 10 22 0 24 -260818 -1
-0;
-#X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 206 27 Pd port;
-#X obj 211 88 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 458 308 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 210 184 pd schubert;
-#N canvas 35 47 460 310 nixon 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/nixon.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 307 184 pd nixon;
-#X text 298 219 quality (defaults to 0);
-#X obj 211 217 shapee~ 1;
-#X connect 0 0 1 0;
-#X connect 1 0 12 0;
-#X connect 2 0 4 0;
-#X connect 2 0 4 1;
-#X connect 3 0 2 1;
-#X connect 8 0 9 0;
-#X connect 8 0 10 0;
-#X connect 9 0 12 0;
-#X connect 10 0 12 1;
-#X connect 12 0 2 0;
diff --git a/help/swinger~-help.pd b/help/swinger~-help.pd
deleted file mode 100644
index af12c5e..0000000
--- a/help/swinger~-help.pd
+++ /dev/null
@@ -1,62 +0,0 @@
-#N canvas 275 53 610 376 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 198 275 *~;
-#X obj 239 280 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 10300 1;
-#X obj 187 312 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty swinger~ 10 22 0 24 -260818 -1
-0;
-#X text 188 8 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 188 28 Pd port;
-#X obj 198 80 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 199 175 pd schubert;
-#N canvas 35 47 460 310 nixon 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/nixon.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 274 144 pd nixon;
-#X obj 198 210 swinger~ 1;
-#X text 284 210 quality (defaults to 0);
-#X connect 0 0 1 0;
-#X connect 1 0 11 0;
-#X connect 2 0 4 0;
-#X connect 2 0 4 1;
-#X connect 3 0 2 1;
-#X connect 8 0 9 0;
-#X connect 8 0 10 0;
-#X connect 9 0 11 0;
-#X connect 10 0 11 1;
-#X connect 11 0 2 0;
diff --git a/help/taint~-help.pd b/help/taint~-help.pd
deleted file mode 100644
index fa2b627..0000000
--- a/help/taint~-help.pd
+++ /dev/null
@@ -1,83 +0,0 @@
-#N canvas 140 138 614 380 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 211 272 *~;
-#X obj 252 277 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 10000 1;
-#X obj 200 309 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty taint~ 10 22 0 24 -260818 -1
-0;
-#X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 206 27 Pd port;
-#X msg 14 181 getattributes;
-#X obj 427 281 print A;
-#X text 14 164 list attributes;
-#X obj 480 89 nbx 5 18 -100 0 0 1 empty empty thresh 0 -6 0 10 -225271
--1 -1 -60 256;
-#X text 424 300 attributes;
-#X obj 211 88 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 210 184 pd schubert;
-#N canvas 35 47 460 310 nixon 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/nixon.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 302 185 pd nixon;
-#X text 15 215 get attributes;
-#X obj 211 217 taint~ -60 0;
-#X msg 481 125 thresh \$1;
-#X obj 391 89 tgl 25 1 empty empty invert 0 -6 0 10 -225271 -1 -1 0
-1;
-#X msg 391 125 invert \$1;
-#X msg 16 258 getthresh;
-#X msg 16 234 getinvert;
-#X text 319 217 threshold \, invert (default -10 \, 0);
-#X connect 0 0 1 0;
-#X connect 1 0 17 0;
-#X connect 2 0 4 0;
-#X connect 2 0 4 1;
-#X connect 3 0 2 1;
-#X connect 8 0 17 0;
-#X connect 11 0 18 0;
-#X connect 13 0 14 0;
-#X connect 13 0 15 0;
-#X connect 14 0 17 0;
-#X connect 15 0 17 1;
-#X connect 17 0 2 0;
-#X connect 17 1 9 0;
-#X connect 18 0 17 0;
-#X connect 19 0 20 0;
-#X connect 20 0 17 0;
-#X connect 21 0 17 0;
-#X connect 22 0 17 0;
diff --git a/help/thresher~-help.pd b/help/thresher~-help.pd
deleted file mode 100644
index fbfde9f..0000000
--- a/help/thresher~-help.pd
+++ /dev/null
@@ -1,46 +0,0 @@
-#N canvas 140 138 585 330 12;
-#X obj 17 86 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 111 enable \$1;
-#X obj 219 248 *~;
-#X obj 260 253 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 10300 1;
-#X obj 208 285 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty thresher~ 10 22 0 24 -260818
--1 0;
-#X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 206 27 Pd port;
-#X obj 327 217 print A;
-#X text 391 216 attributes;
-#X obj 219 92 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 460 310 nixon 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/nixon.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 219 144 pd nixon;
-#X obj 218 187 thresher~;
-#X obj 18 250 nacho~;
-#X text 17 274 alternative name;
-#X connect 0 0 1 0;
-#X connect 1 0 12 0;
-#X connect 2 0 4 0;
-#X connect 2 0 4 1;
-#X connect 3 0 2 1;
-#X connect 10 0 11 0;
-#X connect 11 0 12 0;
-#X connect 12 0 2 0;
-#X connect 12 1 8 0;
diff --git a/help/vacancy~-help.pd b/help/vacancy~-help.pd
deleted file mode 100644
index b6e01f6..0000000
--- a/help/vacancy~-help.pd
+++ /dev/null
@@ -1,97 +0,0 @@
-#N canvas 140 138 622 388 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 179 284 *~;
-#X obj 220 289 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 11000 1;
-#X obj 168 321 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty vacancy~ 10 22 0 24 -260818 -1
-0;
-#X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 206 27 Pd port;
-#X msg 14 181 getattributes;
-#X obj 427 293 print A;
-#X text 14 164 list attributes;
-#X obj 276 91 nbx 5 18 -100 0 0 1 empty empty threshold 0 -6 0 10 -225271
--1 -1 -31 256;
-#X text 424 312 attributes;
-#X obj 179 88 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 180 174 pd schubert;
-#N canvas 35 47 460 310 nixon 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/nixon.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 316 175 pd nixon;
-#X text 15 215 get attributes;
-#X msg 275 129 thresh \$1;
-#X obj 363 91 tgl 25 1 empty empty invert 0 -6 0 10 -225271 -1 -1 0
-1;
-#X msg 363 127 invert \$1;
-#X msg 16 235 getthresh;
-#X msg 16 259 getinvert;
-#X obj 179 203 vacancy~ -30 0 1 0;
-#X obj 451 91 tgl 25 1 empty empty use_rms 0 -6 0 10 -225271 -1 -1
-1 1;
-#X obj 520 91 tgl 25 1 empty empty swap_phase 0 -6 0 10 -225271 -1
--1 0 1;
-#X msg 451 127 rms \$1;
-#X msg 520 127 swap \$1;
-#X text 256 226 threshold \, invert \, rms \, swap;
-#X msg 16 283 getrms;
-#X msg 17 308 getswap;
-#X connect 0 0 1 0;
-#X connect 1 0 22 0;
-#X connect 2 0 4 0;
-#X connect 2 0 4 1;
-#X connect 3 0 2 1;
-#X connect 8 0 22 0;
-#X connect 11 0 17 0;
-#X connect 13 0 14 0;
-#X connect 13 0 15 0;
-#X connect 14 0 22 0;
-#X connect 15 0 22 1;
-#X connect 17 0 22 0;
-#X connect 18 0 19 0;
-#X connect 19 0 22 0;
-#X connect 20 0 22 0;
-#X connect 21 0 22 0;
-#X connect 22 0 2 0;
-#X connect 22 1 9 0;
-#X connect 23 0 25 0;
-#X connect 24 0 26 0;
-#X connect 25 0 22 0;
-#X connect 26 0 22 0;
-#X connect 28 0 22 0;
-#X connect 29 0 22 0;
diff --git a/help/xsyn~-help.pd b/help/xsyn~-help.pd
deleted file mode 100644
index 2416afb..0000000
--- a/help/xsyn~-help.pd
+++ /dev/null
@@ -1,61 +0,0 @@
-#N canvas 140 138 589 373 12;
-#X obj 17 78 tgl 20 1 empty empty enable_dsp 0 -6 0 10 -225271 -1 -1
-1 1;
-#X msg 17 103 enable \$1;
-#X obj 214 284 *~;
-#X obj 255 289 hsl 128 15 0.001 10 1 1 empty empty volume -2 -6 0 10
--261681 -1 -1 10500 1;
-#X obj 203 321 dac~;
-#X obj 16 8 cnv 15 550 40 empty empty xsyn~ 10 22 0 24 -260818 -1 0
-;
-#X text 206 7 FFTease (C)Lyon \, Penrose (for Max/MSP);
-#X text 206 27 Pd port;
-#X obj 214 88 bng 25 250 50 0 empty empty start 0 -6 0 8 -261689 -1
--1;
-#N canvas 35 47 456 306 schubert 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/schubert.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 215 174 pd schubert;
-#N canvas 35 47 460 310 nixon 0;
-#X obj 51 234 outlet~;
-#X obj 51 188 readsf~ 1;
-#X obj 51 19 inlet;
-#X msg 27 80 1;
-#X obj 52 115 t f b;
-#X obj 51 44 route bang 1 0;
-#X msg 86 149 open ../media/nixon.aiff;
-#X connect 1 0 0 0;
-#X connect 2 0 5 0;
-#X connect 3 0 4 0;
-#X connect 4 0 1 0;
-#X connect 4 1 6 0;
-#X connect 5 0 3 0;
-#X connect 5 1 4 0;
-#X connect 5 2 1 0;
-#X connect 6 0 1 0;
-#X restore 249 150 pd nixon;
-#X obj 214 203 xsyn~;
-#X connect 0 0 1 0;
-#X connect 1 0 11 0;
-#X connect 2 0 4 0;
-#X connect 2 0 4 1;
-#X connect 3 0 2 1;
-#X connect 8 0 9 0;
-#X connect 8 0 10 0;
-#X connect 9 0 11 0;
-#X connect 10 0 11 1;
-#X connect 11 0 2 0;
diff --git a/leaker~-help.pd b/leaker~-help.pd
new file mode 100644
index 0000000..bcdbd3b
--- /dev/null
+++ b/leaker~-help.pd
@@ -0,0 +1,106 @@
+#N canvas 718 386 500 440 10;
+#N canvas 0 22 462 312 leaker-block 0;
+#X obj 194 143 outlet~;
+#X obj 198 186 block~ 256;
+#X obj 194 112 leaker~ 4 1;
+#X obj 165 52 inlet~;
+#X obj 212 52 inlet~;
+#X obj 280 60 inlet;
+#X obj 329 97 inlet;
+#X connect 2 0 0 0;
+#X connect 3 0 2 0;
+#X connect 4 0 2 1;
+#X connect 5 0 2 2;
+#X connect 6 0 2 0;
+#X restore 96 168 pd leaker-block;
+#X msg 255 182 \; pd dsp \$1;
+#X obj 255 159 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 96 221 dac~;
+#X floatatom 162 113 5 0 1 0 - xfade -;
+#X obj 100 254 hsl 128 15 0 1 0 0 xfade empty xfade -2 -6 0 8 -260372
+-1 -1 10400 1;
+#N canvas 0 22 466 316 messages 1;
+#X msg 40 116 upsieve;
+#X msg 52 138 downsieve;
+#X msg 69 163 randsieve;
+#X obj 40 262 outlet;
+#X obj 105 220 fftease-system;
+#X text 43 90 select sieve characteristic:;
+#X connect 0 0 3 0;
+#X connect 1 0 3 0;
+#X connect 2 0 3 0;
+#X connect 4 0 3 0;
+#X restore 196 141 pd messages;
+#X text 237 254 <- spectral crossfade here;
+#X obj 16 215 loadbang;
+#X msg 16 238 0.5;
+#N canvas 990 218 520 409 playsound1 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array leaker-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X msg 31 177 read -resize \$1 leaker-sound1;
+#X obj 227 268 tabplay~ leaker-sound1;
+#X connect 1 0 11 0;
+#X connect 3 0 1 0;
+#X connect 5 0 12 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 11 0 0 0;
+#X connect 12 0 4 0;
+#X connect 12 1 6 0;
+#X restore 96 37 pd playsound1;
+#N canvas 990 218 516 405 playsound2 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#N canvas 0 22 450 300 graph2 0;
+#X array leaker-sound2 2.499e+06 float 2;
+#X coords 0 1 2.499e+06 -1 200 140 1;
+#X restore 216 15 graph;
+#X msg 31 177 read -resize \$1 leaker-sound2;
+#X obj 227 268 tabplay~ leaker-sound2;
+#X connect 1 0 11 0;
+#X connect 2 0 1 0;
+#X connect 4 0 12 0;
+#X connect 5 0 4 0;
+#X connect 6 0 5 1;
+#X connect 11 0 0 0;
+#X connect 12 0 3 0;
+#X connect 12 1 5 0;
+#X restore 129 55 pd playsound2;
+#X text 38 317 leaker~ combines two input sounds \, with the spectral
+contribution of each sound determined by an internally maintained sieve
+and a threshold selection value. At value 0 \, only sound 1 is heard
+and at value 1 \, only sound 2 is heard. At intermediate values \,
+parts of each spectrum are aggregated according to the sieve structure
+which may be specified as upsieve \, downsieve or randsieve.;
+#X connect 0 0 3 0;
+#X connect 0 0 3 1;
+#X connect 2 0 1 0;
+#X connect 4 0 0 2;
+#X connect 6 0 0 3;
+#X connect 8 0 9 0;
+#X connect 9 0 5 0;
+#X connect 10 0 0 0;
+#X connect 11 0 0 1;
diff --git a/leaker~.c b/leaker~.c
index ccdb6a0..7a77e6d 100644
--- a/leaker~.c
+++ b/leaker~.c
@@ -125,7 +125,7 @@ void leaker_tilde_setup(void)
void leaker_overlap(t_leaker *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -137,7 +137,7 @@ void leaker_winfac(t_leaker *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -270,9 +270,9 @@ void *leaker_new(t_symbol *msg, short argc, t_atom *argv)
void leaker_init(t_leaker *x, short initialized)
{
int i;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 2;
x->N = x->D * x->overlap;
x->Nw = x->N * x->winfac;
diff --git a/leanconvert.c b/leanconvert.c
new file mode 100644
index 0000000..617c665
--- /dev/null
+++ b/leanconvert.c
@@ -0,0 +1 @@
+#include "fftease.h" void leanconvert( float *S, float *C, int N2 ) { int real, imag, amp, phase; float a, b; int i; double hypot(), atan2(); for ( i = 0; i <= N2; i++ ) { imag = phase = ( real = amp = i<<1 ) + 1; a = ( i == N2 ? S[1] : S[real] ); b = ( i == 0 || i == N2 ? 0. : S[imag] ); C[amp] = hypot( a, b ); C[phase] = -atan2( b, a ); } } \ No newline at end of file
diff --git a/leanunconvert.c b/leanunconvert.c
new file mode 100644
index 0000000..4880729
--- /dev/null
+++ b/leanunconvert.c
@@ -0,0 +1 @@
+#include "fftease.h" /* unconvert essentially undoes what convert does, i.e., it turns N2+1 PAIRS of amplitude and frequency values in C into N2 PAIR of complex spectrum data (in rfft format) in output array S; sampling rate R and interpolation factor I are used to recompute phase values from frequencies */ void leanunconvert( float *C, float *S, int N2 ) { double cos(), sin(); int real, imag, amp, phase; register int i; for ( i = 0; i <= N2; i++ ) { imag = phase = ( real = amp = i<<1 ) + 1; S[real] = *(C+amp) * cos( *(C+phase) ); if ( i != N2 ) S[imag] = -*(C+amp) * sin( *(C+phase) ); } } \ No newline at end of file
diff --git a/limit_fftsize.c b/limit_fftsize.c
new file mode 100644
index 0000000..9071289
--- /dev/null
+++ b/limit_fftsize.c
@@ -0,0 +1 @@
+#include "fftease.h" extern void post(const char *fmt, ...); void limit_fftsize(int *N, int *Nw, char *OBJECT_NAME) { if(*N > MAX_N){ // post("%s: N set to maximum FFT size of %d",OBJECT_NAME,MAX_N); *N = MAX_N; } if(*Nw > MAX_Nw){ // post("%s: Nw set to maximum window size of %d",OBJECT_NAME,MAX_Nw); *Nw = MAX_Nw; } } \ No newline at end of file
diff --git a/makewindows.c b/makewindows.c
new file mode 100644
index 0000000..81a80f0
--- /dev/null
+++ b/makewindows.c
@@ -0,0 +1 @@
+#include "fftease.h" void makewindows( float *H, float *A, float *S, int Nw, int N, int I ) { int i ; float sum ; for ( i = 0 ; i < Nw ; i++ ) H[i] = A[i] = S[i] = 0.54 - 0.46*cos( TWOPI*i/(Nw - 1) ) ; if ( Nw > N ) { float x ; x = -(Nw - 1)/2. ; for ( i = 0 ; i < Nw ; i++, x += 1. ) if ( x != 0. ) { A[i] *= N*sin( PI*x/N )/(PI*x) ; if ( I ) S[i] *= I*sin( PI*x/I )/(PI*x) ; } } for ( sum = i = 0 ; i < Nw ; i++ ) sum += A[i] ; for ( i = 0 ; i < Nw ; i++ ) { float afac = 2./sum ; float sfac = Nw > N ? 1./afac : afac ; A[i] *= afac ; S[i] *= sfac ; } if ( Nw <= N && I ) { for ( sum = i = 0 ; i < Nw ; i += I ) sum += S[i]*S[i] ; for ( sum = 1./sum, i = 0 ; i < Nw ; i++ ) S[i] *= sum ; } } void makehamming( float *H, float *A, float *S, int Nw, int N, int I, int odd ) { int i; float sum ; if (odd) { for ( i = 0 ; i < Nw ; i++ ) H[i] = A[i] = S[i] = sqrt(0.54 - 0.46*cos( TWOPI*i/(Nw - 1) )); } else { for ( i = 0 ; i < Nw ; i++ ) H[i] = A[i] = S[i] = 0.54 - 0.46*cos( TWOPI*i/(Nw - 1) ); } if ( Nw > N ) { float x ; x = -(Nw - 1)/2. ; for ( i = 0 ; i < Nw ; i++, x += 1. ) if ( x != 0. ) { A[i] *= N*sin( PI*x/N )/(PI*x) ; if ( I ) S[i] *= I*sin( PI*x/I )/(PI*x) ; } } for ( sum = i = 0 ; i < Nw ; i++ ) sum += A[i] ; for ( i = 0 ; i < Nw ; i++ ) { float afac = 2./sum ; float sfac = Nw > N ? 1./afac : afac ; A[i] *= afac ; S[i] *= sfac ; } if ( Nw <= N && I ) { for ( sum = i = 0 ; i < Nw ; i += I ) sum += S[i]*S[i] ; for ( sum = 1./sum, i = 0 ; i < Nw ; i++ ) S[i] *= sum ; } } void makehanning( float *H, float *A, float *S, int Nw, int N, int I, int odd ) { int i; float sum ; if (odd) { for ( i = 0 ; i < Nw ; i++ ) H[i] = A[i] = S[i] = sqrt(0.5 * (1. + cos(PI + TWOPI * i / (Nw - 1)))); } else { for ( i = 0 ; i < Nw ; i++ ) H[i] = A[i] = S[i] = 0.5 * (1. + cos(PI + TWOPI * i / (Nw - 1))); } if ( Nw > N ) { float x ; x = -(Nw - 1)/2. ; for ( i = 0 ; i < Nw ; i++, x += 1. ) if ( x != 0. ) { A[i] *= N*sin( PI*x/N )/(PI*x) ; if ( I ) S[i] *= I*sin( PI*x/I )/(PI*x) ; } } for ( sum = i = 0 ; i < Nw ; i++ ) sum += A[i] ; for ( i = 0 ; i < Nw ; i++ ) { float afac = 2./sum ; float sfac = Nw > N ? 1./afac : afac ; A[i] *= afac ; S[i] *= sfac ; } if ( Nw <= N && I ) { for ( sum = i = 0 ; i < Nw ; i += I ) sum += S[i]*S[i] ; for ( sum = 1./sum, i = 0 ; i < Nw ; i++ ) S[i] *= sum ; } } \ No newline at end of file
diff --git a/manual/code-notes.rtf b/manual/code-notes.rtf
new file mode 100644
index 0000000..04742d4
--- /dev/null
+++ b/manual/code-notes.rtf
@@ -0,0 +1,51 @@
+{\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf230
+{\fonttbl\f0\fswiss\fcharset77 Helvetica;\f1\fnil\fcharset77 LucidaGrande;}
+{\colortbl;\red255\green255\blue255;}
+\margl1440\margr1440\vieww9000\viewh8400\viewkind0
+\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
+
+\f0\fs24 \cf0 notes:\
+\
+improved memory cleaning in resident\
+\
+disabled residency_buffer if no argument given\
+\
+fixed dentist factor of two bug for bin number\
+\
+30.11.05\
+\
+gave presidency an "int" function to avoid int error\
+\
+fixed potential memory bug in all objects and recompiled for OS X. Now must reinstall code for Pd and Windows FFTease.\
+\
+\
+removed FFTease Lite from helpfiles and
+\f1 FFTease-objectlist.txt\
+\
+31.11.05\
+\
+compiled stuff for windows:\
+removed "old memory" message from hacked miller code in reanimator\
+\
+fixed residency_buffer:\
+added overlap\
+fixed problem with initiating sampling\
+\
+added residency_buffer helpfile gain slider\
+residency_buffer: return 0 instead of return if no argument\
+\
+residency: modified helpfile\
+\
+resent:\
+fixed no sync out bug when mute is on\
+\
+scrape: fixed helpfile\
+\
+swinger: fixed helpfile\
+\
+dentist: fixed sync bug on mute\
+\
+disarray: fixed mute bug, helpfile\
+\
+drown: fixed mute bug\
+} \ No newline at end of file
diff --git a/mindwarp~-help.pd b/mindwarp~-help.pd
new file mode 100644
index 0000000..26bb364
--- /dev/null
+++ b/mindwarp~-help.pd
@@ -0,0 +1,168 @@
+#N canvas 61 22 766 791 10;
+#X obj 384 435 dac~;
+#X floatatom 124 121 5 0.1 3 2 transpose transpose -;
+#X msg 500 486 \; pd dsp \$1;
+#X obj 500 467 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 85 512 hsl 128 15 0.1 4 0 0 empty empty empty -2 -6 0 8 -261285
+-1 -1 1600 1;
+#N canvas 0 22 494 344 messages 0;
+#X obj 154 185 outlet;
+#X obj 154 136 fftease-system;
+#X connect 1 0 0 0;
+#X restore 210 338 pd messages;
+#X obj 227 512 hsl 128 15 0 0.01 0 0 empty empty empty -2 -6 0 8 -227712
+-1 -1 0 1;
+#X obj 224 538 s thresh;
+#X obj 82 538 s transpose;
+#X obj 82 460 loadbang;
+#X msg 82 491 1;
+#N canvas 0 22 550 400 mindwarp-block 0;
+#X obj 27 158 outlet~;
+#X obj 27 42 inlet~;
+#X obj 73 14 inlet;
+#X obj 120 49 inlet;
+#X obj 213 69 inlet;
+#X text 107 105 args: warp factor \, shape width \, overlap \, winfac
+;
+#X obj 27 85 mindwarp~ 1 16;
+#X obj 28 183 block~ 256;
+#X connect 1 0 6 0;
+#X connect 2 0 6 1;
+#X connect 3 0 6 2;
+#X connect 4 0 6 0;
+#X connect 6 0 0 0;
+#X restore 96 364 pd mindwarp-block;
+#N canvas 1171 182 470 320 pvoc-block 0;
+#X obj 102 141 pvoc~;
+#X obj 102 199 outlet~;
+#X obj 102 50 inlet~;
+#X obj 117 94 inlet;
+#X obj 233 94 inlet;
+#X obj 270 115 block~ 256;
+#X obj 164 95 inlet;
+#X connect 0 0 1 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 1;
+#X connect 4 0 0 0;
+#X connect 6 0 0 2;
+#X restore 96 194 pd pvoc-block;
+#X text 176 274 warp factor;
+#X floatatom 172 316 5 1 16 0 - - -;
+#N canvas 990 218 520 409 playsound 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X text 316 205 comment;
+#N canvas 0 22 450 300 graph3 0;
+#X array mindwarp-sound1 302338 float 2;
+#X coords 0 1 302337 -1 200 140 1;
+#X restore 231 21 graph;
+#X obj 227 268 tabplay~ mindwarp-sound1;
+#X msg 31 177 read -resize \$1 mindwarp-sound1;
+#X connect 1 0 13 0;
+#X connect 2 0 1 0;
+#X connect 4 0 12 0;
+#X connect 5 0 4 0;
+#X connect 6 0 5 1;
+#X connect 12 0 3 0;
+#X connect 12 1 5 0;
+#X connect 13 0 0 0;
+#X restore 96 38 pd playsound;
+#N canvas 0 22 494 344 messages 0;
+#X obj 154 185 outlet;
+#X obj 302 145 fftease-system;
+#X floatatom 65 105 5 0 0 0 - - -;
+#X msg 65 126 highfreq \$1;
+#X floatatom 201 94 5 0 0 0 - - -;
+#X msg 201 112 lowfreq \$1;
+#X msg 65 83 8000;
+#X obj 65 61 loadbang;
+#X msg 201 73 0;
+#X obj 201 51 loadbang;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 3 0 0 0;
+#X connect 4 0 5 0;
+#X connect 5 0 0 0;
+#X connect 6 0 2 0;
+#X connect 7 0 6 0;
+#X connect 8 0 4 0;
+#X connect 9 0 8 0;
+#X restore 182 174 pd messages;
+#X msg 384 314 set mindwarp-raw;
+#X obj 384 409 receive~ mindwarp-warped;
+#X msg 384 333 set mindwarp-pvoc;
+#X msg 384 352 set mindwarp-warped;
+#X obj 129 396 send~ mindwarp-warped;
+#X obj 119 228 send~ mindwarp-pvoc;
+#X obj 108 73 send~ mindwarp-raw;
+#X text 380 290 select listening point:;
+#X text 503 314 original sound;
+#X text 511 335 pvoc transposed;
+#X text 523 352 post-pvoc formant-adjusted;
+#X text 82 577 mindwarp~ performs spectral envelope warping. It can
+be used to correct for the formant shifting effects of pitch-scaling.
+The warp factor is tuned to warp spectra to compensate for directly
+corresponding pitch-scaling values. For example \, if you have pitch-scaled
+a signal by a factor of two \, increasing its frequency content by
+an octave \, by providing mindwarp~ with a warp factor of 2 and the
+pitch-scaled signal \, mindwarp~ will restore the spectral formant
+of the signal to an estimation of the shape present in the original
+unscaled signal. Currently \, warp factor values are restricted to
+the range [1/16 ... 16.]. mindwarp~ utilizes frequency shaping to perform
+its duty. It can be fun to decorrelate the warp factor from the transposition
+factor.;
+#X text 190 32 <- first load a soundfile here;
+#X floatatom 153 156 5 0 0 0 - - -;
+#X floatatom 134 275 5 0.1 20 0 - - -;
+#X obj 134 252 r transpose;
+#X text 214 316 shape width;
+#X obj 153 137 r thresh;
+#X msg 224 476 1e-05;
+#X obj 172 296 r shapewidth;
+#N canvas 0 22 454 304 init 0;
+#X obj 95 88 loadbang;
+#X msg 95 116 16;
+#X obj 95 155 s shapewidth;
+#X obj 198 155 s transpose;
+#X msg 198 120 1;
+#X connect 0 0 1 0;
+#X connect 0 0 4 0;
+#X connect 1 0 2 0;
+#X connect 4 0 3 0;
+#X restore 501 518 pd init;
+#X connect 1 0 12 1;
+#X connect 3 0 2 0;
+#X connect 4 0 8 0;
+#X connect 5 0 11 3;
+#X connect 6 0 7 0;
+#X connect 9 0 10 0;
+#X connect 9 0 35 0;
+#X connect 10 0 4 0;
+#X connect 11 0 21 0;
+#X connect 12 0 11 0;
+#X connect 12 0 22 0;
+#X connect 14 0 11 2;
+#X connect 15 0 12 0;
+#X connect 15 0 23 0;
+#X connect 16 0 12 3;
+#X connect 17 0 18 0;
+#X connect 18 0 0 0;
+#X connect 18 0 0 1;
+#X connect 19 0 18 0;
+#X connect 20 0 18 0;
+#X connect 30 0 12 2;
+#X connect 31 0 11 1;
+#X connect 32 0 31 0;
+#X connect 34 0 30 0;
+#X connect 35 0 6 0;
+#X connect 36 0 14 0;
diff --git a/mindwarp~.c b/mindwarp~.c
index d49769e..293a6b3 100644
--- a/mindwarp~.c
+++ b/mindwarp~.c
@@ -192,10 +192,10 @@ void *mindwarp_new(t_symbol *s, int argc, t_atom *argv)
x->overlap = atom_getfloatarg(2,argc,argv);
x->winfac = atom_getfloatarg(3,argc,argv);
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 1;
}
@@ -584,7 +584,7 @@ void mindwarp_mute(t_mindwarp *x, t_floatarg toggle)
void mindwarp_overlap(t_mindwarp *x, t_floatarg o)
{
- if(!power_of_two((int)o)){
+ if(!fftease_power_of_two((int)o)){
error("%f is not a power of two",o);
return;
}
@@ -594,7 +594,7 @@ void mindwarp_overlap(t_mindwarp *x, t_floatarg o)
void mindwarp_winfac(t_mindwarp *x, t_floatarg f)
{
- if(!power_of_two((int)f)){
+ if(!fftease_power_of_two((int)f)){
error("%f is not a power of two",f);
return;
}
diff --git a/morphine~-help.pd b/morphine~-help.pd
new file mode 100644
index 0000000..13af0d6
--- /dev/null
+++ b/morphine~-help.pd
@@ -0,0 +1,120 @@
+#N canvas 831 409 575 413 10;
+#N canvas 0 22 454 304 morphine-block 0;
+#X obj 48 204 block~ 512;
+#X obj 152 114 morphine~;
+#X obj 152 69 inlet~;
+#X obj 201 71 inlet~;
+#X obj 260 73 inlet;
+#X obj 314 81 inlet;
+#X obj 152 202 outlet~;
+#X connect 1 0 6 0;
+#X connect 2 0 1 0;
+#X connect 3 0 1 1;
+#X connect 4 0 1 2;
+#X connect 5 0 1 0;
+#X restore 149 150 pd morphine-block;
+#N canvas 990 218 520 409 playsound1 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array morphine-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X msg 31 177 read -resize \$1 morphine-sound1;
+#X obj 227 268 tabplay~ morphine-sound1;
+#X text 316 205 comment;
+#X text 63 132 1 open the sound;
+#X text 109 245 2 then play it;
+#X text 304 190 3 loop if you like;
+#X connect 1 0 8 0;
+#X connect 3 0 1 0;
+#X connect 5 0 9 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 8 0 0 0;
+#X connect 9 0 4 0;
+#X connect 9 1 6 0;
+#X restore 149 18 pd playsound1;
+#N canvas 990 218 520 409 playsound2 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array morphine-sound2 2.5137e+06 float 2;
+#X coords 0 1 2.5137e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 316 205 comment;
+#X text 63 132 1 open the sound;
+#X text 109 245 2 then play it;
+#X text 304 190 3 loop if you like;
+#X obj 227 268 tabplay~ morphine-sound2;
+#X msg 31 177 read -resize \$1 morphine-sound2;
+#X connect 1 0 13 0;
+#X connect 3 0 1 0;
+#X connect 5 0 12 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 12 0 4 0;
+#X connect 12 1 6 0;
+#X connect 13 0 0 0;
+#X restore 187 42 pd playsound2;
+#X floatatom 225 119 5 0 0 0 - - -;
+#X text 223 81 morph index;
+#N canvas 643 138 458 308 messages 0;
+#X obj 100 164 outlet;
+#X msg 100 126 transition \$1;
+#X obj 103 78 hsl 128 15 -30 0 0 0 empty empty empty -2 -6 0 8 -110787
+-1 -1 10900 1;
+#X text 61 49 exponential transition scalar;
+#X floatatom 100 106 5 0 0 0 - - -;
+#X obj 35 26 loadbang;
+#X msg 35 49 -5;
+#X obj 177 148 fftease-system;
+#X connect 1 0 0 0;
+#X connect 2 0 4 0;
+#X connect 4 0 1 0;
+#X connect 5 0 6 0;
+#X connect 6 0 2 0;
+#X connect 7 0 0 0;
+#X restore 295 134 pd messages;
+#X msg 27 233 \; pd dsp \$1;
+#X obj 27 216 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 149 209 *~ 1;
+#X obj 149 261 dac~;
+#X obj 175 170 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -110787
+-1 -1 6700 1;
+#X floatatom 172 190 5 0 0 0 - - -;
+#X obj 228 97 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -110787
+-1 -1 9400 1;
+#X text 251 18 <- load sounds here;
+#X text 289 41 <- and here;
+#X text 23 291 morphine~ performs spectral morphing \, creating a new
+spectrum from its two inputs. Values between 0 and 1 are the useful
+range for the morph index. The progression depends upon the exponential
+transition scaling value. Progressively smaller negative values will
+widen the transition space between the two sounds. Larger FFT sizes
+\, such as 4096 \, produce smoother results.;
+#X text 310 170 gain;
+#X connect 0 0 8 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 1;
+#X connect 3 0 0 2;
+#X connect 5 0 0 3;
+#X connect 7 0 6 0;
+#X connect 8 0 9 0;
+#X connect 8 0 9 1;
+#X connect 10 0 11 0;
+#X connect 11 0 8 1;
+#X connect 12 0 3 0;
diff --git a/morphine~.c b/morphine~.c
index c57c4a5..de2c53c 100644
--- a/morphine~.c
+++ b/morphine~.c
@@ -201,10 +201,10 @@ void *morphine_new(t_symbol *s, int argc, t_atom *argv)
x->overlap = atom_getfloatarg(1,argc,argv);
x->winfac = atom_getfloatarg(2,argc,argv);
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 1;
}
@@ -529,7 +529,7 @@ void morphine_overlap(t_morphine *x, t_floatarg df)
{
int o = (int)df;
- if(!power_of_two(o)){
+ if(!fftease_power_of_two(o)){
error("%d is not a power of two",o);
return;
}
@@ -540,7 +540,7 @@ int o = (int)df;
void morphine_winfac(t_morphine *x, t_floatarg df)
{
int wf = (int) df;
- if(!power_of_two(wf)){
+ if(!fftease_power_of_two(wf)){
error("%d is not a power of two",wf);
return;
}
diff --git a/multyq~-help.pd b/multyq~-help.pd
new file mode 100644
index 0000000..fca5483
--- /dev/null
+++ b/multyq~-help.pd
@@ -0,0 +1,92 @@
+#N canvas 224 36 657 848 10;
+#X msg 360 574 \; pd dsp \$1;
+#X obj 360 548 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 136 366 dac~;
+#X obj 180 295 nbx 5 14 -1e+37 1e+37 0 0 empty out-gain empty 0 -6
+0 10 -262144 -1 -1 0.0551181 256;
+#X obj 29 394 hsl 128 15 60 600 0 0 cf1 empty cf1 -2 -6 0 8 -235882
+-1 -1 5400 1;
+#X obj 49 151 noise~;
+#N canvas 0 22 502 352 multyq-block 0;
+#X obj 71 352 block~ 256;
+#X obj 28 95 inlet~;
+#X obj 193 169 inlet;
+#X obj 72 299 outlet~;
+#X obj 72 256 multyq~ 4 1;
+#X obj 249 239 inlet;
+#X obj 66 143 inlet;
+#X obj 72 182 inlet;
+#X obj 78 217 inlet;
+#X obj 110 142 inlet;
+#X obj 116 181 inlet;
+#X obj 122 216 inlet;
+#X text 67 105 [cf \, bw \, gain] triplets;
+#X obj 182 141 inlet~;
+#X obj 199 189 inlet;
+#X connect 1 0 4 0;
+#X connect 2 0 4 8;
+#X connect 4 0 3 0;
+#X connect 5 0 4 0;
+#X connect 6 0 4 1;
+#X connect 7 0 4 2;
+#X connect 8 0 4 3;
+#X connect 9 0 4 4;
+#X connect 10 0 4 5;
+#X connect 11 0 4 6;
+#X connect 13 0 4 7;
+#X connect 14 0 4 9;
+#X restore 136 261 pd multyq-block;
+#X floatatom 146 7 5 0 0 2 - cf1 -;
+#X floatatom 156 22 5 0 0 2 - bw1 -;
+#X floatatom 166 37 5 0 0 2 - gain1 -;
+#X obj 30 433 hsl 128 15 0.01 0.5 0 0 bw1 empty bw1 -2 -6 0 8 -235882
+-1 -1 7000 1;
+#X obj 30 471 hsl 128 15 0 20 0 0 gain1 empty gain1 -2 -6 0 8 -235882
+-1 -1 7900 1;
+#X obj 136 314 *~ 0.05;
+#X obj 190 595 hsl 128 15 0 1 0 0 out-gain empty out-gain -2 -6 0 8
+-44646 -1 -1 700 1;
+#X obj 31 518 hsl 128 15 600 2000 0 0 cf2 empty cf2 -2 -6 0 8 -235882
+-1 -1 2300 1;
+#X obj 31 557 hsl 128 15 0.01 0.5 0 0 bw2 empty bw2 -2 -6 0 8 -235882
+-1 -1 8100 1;
+#X obj 31 595 hsl 128 15 -1 20 0 0 gain2 empty gain2 -2 -6 0 8 -235882
+-1 -1 6600 1;
+#X floatatom 176 56 5 0 0 2 - cf2 -;
+#X floatatom 186 73 5 0 0 2 - bw2 -;
+#X floatatom 196 92 5 0 0 2 - gain2 -;
+#X obj 206 111 phasor~ 2;
+#X obj 206 134 *~ 2000;
+#X obj 206 157 +~ 1500;
+#X obj 246 452 hsl 128 15 0.01 0.5 0 0 bw3 empty bw3 -2 -6 0 8 -125810
+-1 -1 3900 1;
+#X obj 247 485 hsl 128 15 -1 20 0 0 gain3 empty gain3 -2 -6 0 8 -125810
+-1 -1 5400 1;
+#X floatatom 216 185 5 0 0 0 - bw3 -;
+#X floatatom 226 213 5 0 0 0 - gain3 -;
+#X obj 236 238 fftease-system;
+#X text 29 643 multyq~ is a four band equalizer. Gain values below
+0 create notches rather than peaks \, but only go as far as -1.0. Bandwidth
+is from 0 to 1.0. Only three bands are used in this example \, but
+cpu usage is the same regardless of how many are used. As the filter
+is FFT-based \, its performance is spotty in the low frequency range.
+;
+#X connect 1 0 0 0;
+#X connect 3 0 12 1;
+#X connect 5 0 6 0;
+#X connect 6 0 12 0;
+#X connect 7 0 6 1;
+#X connect 8 0 6 2;
+#X connect 9 0 6 3;
+#X connect 12 0 2 0;
+#X connect 12 0 2 1;
+#X connect 17 0 6 4;
+#X connect 18 0 6 5;
+#X connect 19 0 6 6;
+#X connect 20 0 21 0;
+#X connect 21 0 22 0;
+#X connect 22 0 6 7;
+#X connect 25 0 6 8;
+#X connect 26 0 6 9;
+#X connect 27 0 6 10;
diff --git a/multyq~.c b/multyq~.c
index fee3228..d79d5ec 100644
--- a/multyq~.c
+++ b/multyq~.c
@@ -152,7 +152,7 @@ void multyq_free(t_multyq *x)
void multyq_overlap(t_multyq *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -164,7 +164,7 @@ void multyq_winfac(t_multyq *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -201,9 +201,9 @@ int i;
x->overlap = atom_getfloatarg(0,argc,argv);
x->winfac = atom_getfloatarg(1,argc,argv);
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 2;
x->D = sys_getblksize();
diff --git a/overlapadd.c b/overlapadd.c
new file mode 100644
index 0000000..beab0e0
--- /dev/null
+++ b/overlapadd.c
@@ -0,0 +1 @@
+/* * input I is a folded spectrum of length N; output O and * synthesis window W are of length Nw--overlap-add windowed, * unrotated, unfolded input data into output O */ #include "fftease.h" void overlapadd( float *I, int N, float *W, float *O, int Nw, int n ) { int i ; while ( n < 0 ) n += N ; n %= N ; for ( i = 0 ; i < Nw ; i++ ) { O[i] += I[n]*W[i] ; if ( ++n == N ) n = 0 ; } } \ No newline at end of file
diff --git a/power_of_two.c b/power_of_two.c
new file mode 100644
index 0000000..54bd4d2
--- /dev/null
+++ b/power_of_two.c
@@ -0,0 +1,33 @@
+
+int power_of_two(int test)
+{
+ int limit = 8192;
+ int compare = 1;
+ // post("testing what we thing is an int:%d",test);
+ do {
+ if(test == compare){
+ // post("good power of 2 found!");
+ return 1;
+ }
+ compare *= 2;
+ } while (compare <= limit);
+
+ return 0;
+}
+// we think the above function is shadowed somewhere else
+
+int fftease_power_of_two(int test)
+{
+ int limit = 8192;
+ int compare = 1;
+ // post("testing what we thing is an int:%d",test);
+ do {
+ if(test == compare){
+ // post("good power of 2 found!");
+ return 1;
+ }
+ compare *= 2;
+ } while (compare <= limit);
+
+ return 0;
+}
diff --git a/presidency~-help.pd b/presidency~-help.pd
new file mode 100644
index 0000000..6256347
--- /dev/null
+++ b/presidency~-help.pd
@@ -0,0 +1,250 @@
+#N canvas 58 237 555 452 10;
+#N canvas 431 336 551 457 messages 0;
+#X obj 34 383 outlet;
+#X floatatom 42 228 5 0 0 2 - size -;
+#X msg 42 259 size \$1;
+#X obj 34 87 bng 15 250 50 0 empty trigger trigger_sampling 0 -6 0
+8 -262144 -1 -1;
+#X obj 64 139 s playsound;
+#X obj 34 115 t b b;
+#X msg 34 166 acquire_sample;
+#X msg 85 230 10000;
+#X obj 280 367 fftease-system;
+#X text 45 210 resize memory (but with DACs off to be safe);
+#X obj 291 266 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 320 265 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 349 265 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X obj 291 239 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#N canvas 0 22 462 312 init 0;
+#X msg 33 61 playthrough 1;
+#X obj 33 34 loadbang;
+#X obj 33 103 outlet;
+#X obj 233 93 loadbang;
+#X msg 233 114 1;
+#X obj 233 136 s speed-slider;
+#X msg 137 61 verbose 0;
+#X msg 169 142 1;
+#X obj 169 164 s transpose-slider;
+#X connect 0 0 2 0;
+#X connect 1 0 0 0;
+#X connect 1 0 6 0;
+#X connect 3 0 4 0;
+#X connect 3 0 7 0;
+#X connect 4 0 5 0;
+#X connect 6 0 2 0;
+#X connect 7 0 8 0;
+#X restore 111 335 pd init;
+#N canvas 260 69 789 579 frequency-boundaries 0;
+#X msg 283 158 high_freq \$1;
+#X obj 286 120 hsl 128 15 500 8000 0 0 empty empty empty -2 -6 0 8
+-155632 -1 -1 0 1;
+#X floatatom 283 140 5 0 0 0 - - -;
+#X text 280 102 highest frequency to resynthesize;
+#X text 9 364 note: these relate to frequencies in the original sound.
+If you transpose the resynthesis \, you will go outside these ranges.
+;
+#X obj 4 318 outlet;
+#X obj 7 117 hsl 128 15 0 1000 0 0 empty empty empty -2 -6 0 8 -155632
+-1 -1 0 1;
+#X floatatom 4 138 5 0 0 0 - - -;
+#X msg 4 167 low_freq \$1;
+#X obj 7 117 hsl 128 15 0 1000 0 0 empty empty empty -2 -6 0 8 -155632
+-1 -1 0 1;
+#X text -1 98 lowest frequency to resynthesize;
+#X connect 0 0 5 0;
+#X connect 1 0 2 0;
+#X connect 2 0 0 0;
+#X connect 6 0 7 0;
+#X connect 7 0 8 0;
+#X connect 8 0 5 0;
+#X restore 64 287 pd frequency-boundaries;
+#N canvas 24 525 634 358 random-behavior 0;
+#X obj 46 95 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 46 149 random 1000;
+#X obj 46 187 * 0.001;
+#X obj 190 101 random 1000;
+#X obj 190 139 * 0.001;
+#X obj 190 169 * 3;
+#X obj 190 196 + 0.05;
+#X obj 190 46 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 190 73 metro 233;
+#X obj 46 57 inlet;
+#X obj 46 243 spigot;
+#X obj 83 221 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj 190 243 spigot;
+#X obj 227 221 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X obj 344 101 random 1000;
+#X obj 344 139 * 0.001;
+#X obj 344 73 metro 233;
+#X obj 344 243 spigot;
+#X obj 381 221 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X obj 344 169 * 2;
+#X obj 344 196 - 1;
+#X obj 344 50 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 190 19 inlet;
+#X obj 344 18 inlet;
+#X obj 344 268 s speed-slider;
+#X obj 190 268 s transpose-slider;
+#X obj 46 268 s position-slider;
+#X obj 479 183 loadbang;
+#X msg 479 205 1;
+#X obj 46 121 metro 650;
+#X connect 0 0 29 0;
+#X connect 1 0 2 0;
+#X connect 2 0 10 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 12 0;
+#X connect 7 0 8 0;
+#X connect 8 0 3 0;
+#X connect 9 0 0 0;
+#X connect 10 0 26 0;
+#X connect 11 0 10 1;
+#X connect 12 0 25 0;
+#X connect 13 0 12 1;
+#X connect 14 0 15 0;
+#X connect 15 0 19 0;
+#X connect 16 0 14 0;
+#X connect 17 0 24 0;
+#X connect 18 0 17 1;
+#X connect 19 0 20 0;
+#X connect 20 0 17 0;
+#X connect 21 0 16 0;
+#X connect 22 0 7 0;
+#X connect 23 0 21 0;
+#X connect 27 0 28 0;
+#X connect 28 0 18 0;
+#X connect 28 0 13 0;
+#X connect 28 0 11 0;
+#X connect 29 0 1 0;
+#X restore 291 288 pd random-behavior;
+#X text 36 10 Load a valid soundfile in sound-source \, then hit the
+sampling trigger below. The resulting recording is stored as a series
+of FFT frames inside presidency~ available for arbitrary time-access.
+;
+#X connect 1 0 2 0;
+#X connect 2 0 0 0;
+#X connect 3 0 5 0;
+#X connect 5 0 6 0;
+#X connect 5 1 4 0;
+#X connect 6 0 0 0;
+#X connect 7 0 2 0;
+#X connect 8 0 0 0;
+#X connect 10 0 16 0;
+#X connect 11 0 16 1;
+#X connect 12 0 16 2;
+#X connect 13 0 10 0;
+#X connect 13 0 11 0;
+#X connect 13 0 12 0;
+#X connect 14 0 0 0;
+#X connect 15 0 0 0;
+#X restore 252 214 pd messages;
+#X floatatom 156 134 5 0 0 2 speed speed -;
+#N canvas 0 22 530 380 sound-source 0;
+#X text 13 300 try a vocal sound or other sound with strong formant
+structure;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array presidency-sound1 441202 float 2;
+#X coords 0 1 441201 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X obj 227 268 tabplay~ presidency-sound1;
+#X msg 31 177 read -resize \$1 presidency-sound1;
+#X obj 227 219 r playsound;
+#X connect 2 0 13 0;
+#X connect 4 0 2 0;
+#X connect 6 0 12 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 1;
+#X connect 12 0 5 0;
+#X connect 12 1 7 0;
+#X connect 13 0 1 0;
+#X connect 14 0 6 0;
+#X restore 124 95 pd sound-source;
+#X msg 301 272 \; pd dsp \$1;
+#X obj 301 246 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X floatatom 188 163 5 0 1 2 position position -;
+#X obj 28 47 vsl 15 128 -2 2 0 0 speed speed-slider speed 0 -8 0 8
+-253906 -1 -1 9525 1;
+#X obj 60 47 vsl 15 128 0 1 0 0 position position-slider position 0
+-8 0 8 -4094 -1 -1 0 1;
+#X text 333 214 <- ask me what I can do;
+#X floatatom 220 194 5 0 1 2 transpose transpose -;
+#X obj 35 216 vsl 15 128 0.1 2 0 0 transpose transpose-slider transpose
+0 -8 0 8 -231210 -1 -1 6016 1;
+#X msg 29 13 0;
+#N canvas 81 500 498 348 presidency-block 0;
+#X obj 28 42 inlet~;
+#X obj 89 42 inlet~;
+#X obj 150 42 inlet~;
+#X obj 313 66 inlet;
+#X obj 28 140 outlet~;
+#X obj 28 169 block~ 256;
+#X text 103 171 FFT size is block~ size times overlap;
+#X obj 28 99 presidency~ 5000 0 4000 4 1;
+#X obj 212 42 inlet~;
+#X text 39 120 args: size \, minfreq \, maxfreq \, overlap \, window
+factor;
+#X obj 323 279 outlet;
+#X obj 323 251 snapshot~;
+#X obj 378 213 metro 50;
+#X msg 378 192 1;
+#X obj 378 156 loadbang;
+#X connect 0 0 7 0;
+#X connect 1 0 7 1;
+#X connect 2 0 7 2;
+#X connect 3 0 7 0;
+#X connect 7 0 4 0;
+#X connect 7 1 11 0;
+#X connect 8 0 7 3;
+#X connect 11 0 10 0;
+#X connect 12 0 11 0;
+#X connect 13 0 12 0;
+#X connect 14 0 13 0;
+#X restore 124 246 pd presidency-block;
+#X text 128 372 presidency~ follows the residency~ model but uses an
+oscillator bank for resynthesis and offers independent control of speed
+\, location and transposition of playback.;
+#X text 237 94 <- first load a sound here;
+#X floatatom 252 271 5 0 0 0 - - -;
+#X text 212 272 sync;
+#X obj 214 31 hsl 128 15 0 1 0 0 presidency-gain empty gain -2 -6 0
+8 -67648 -1 -1 0 1;
+#X obj 124 322 dac~;
+#X obj 124 284 *~ 0.25;
+#X floatatom 168 268 5 0 0 3 - presidency-gain -;
+#X text 59 14 freeze frame;
+#X connect 0 0 12 4;
+#X connect 1 0 12 1;
+#X connect 2 0 12 0;
+#X connect 4 0 3 0;
+#X connect 5 0 12 2;
+#X connect 9 0 12 3;
+#X connect 11 0 6 0;
+#X connect 12 0 19 0;
+#X connect 12 1 15 0;
+#X connect 19 0 18 1;
+#X connect 19 0 18 0;
+#X connect 20 0 19 1;
diff --git a/presidency~.c b/presidency~.c
index 3e78243..6cc5ea8 100644
--- a/presidency~.c
+++ b/presidency~.c
@@ -224,7 +224,7 @@ void presidency_calc_bins_from_freqs(t_presidency *x)
void presidency_overlap(t_presidency *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -236,7 +236,7 @@ void presidency_winfac(t_presidency *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -309,9 +309,9 @@ void presidency_init(t_presidency *x, short initialized)
x->lock = 1;
x->virgin = 1;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 1;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
if(!x->R)
x->R = 44100;
diff --git a/pvcompand~-help.pd b/pvcompand~-help.pd
new file mode 100644
index 0000000..a275d4a
--- /dev/null
+++ b/pvcompand~-help.pd
@@ -0,0 +1,86 @@
+#N canvas 854 454 487 362 10;
+#N canvas 0 22 458 308 pvcompand-block 0;
+#X obj 231 190 block~ 256;
+#X obj 231 133 pvcompand~;
+#X obj 231 86 inlet~;
+#X obj 296 94 inlet;
+#X obj 362 117 inlet;
+#X obj 231 159 outlet~;
+#X connect 1 0 5 0;
+#X connect 2 0 1 0;
+#X connect 3 0 1 1;
+#X connect 4 0 1 0;
+#X restore 121 99 pd pvcompand-block;
+#X obj 121 139 dac~;
+#N canvas 0 22 466 316 messages 0;
+#X obj 203 227 outlet;
+#X obj 281 174 fftease-system;
+#N canvas 181 394 454 304 init 0;
+#X obj 97 48 loadbang;
+#X obj 97 182 outlet;
+#X obj 262 124 s compandslider;
+#X msg 262 97 -6;
+#X text 105 152 attempt to preserve overall amplitude;
+#X msg 97 130 normalize \$1;
+#X obj 97 103 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X msg 97 83 1;
+#X connect 0 0 3 0;
+#X connect 0 0 7 0;
+#X connect 3 0 2 0;
+#X connect 5 0 1 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 0;
+#X restore 203 153 pd init;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X restore 242 69 pd messages;
+#X msg 211 165 \; pd dsp \$1;
+#X obj 211 143 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X floatatom 181 78 5 0 0 0 - compand-factor -;
+#X obj 123 229 hsl 128 15 -60 60 0 0 compand-factor compandslider compand-factor
+-2 -6 0 8 -258842 -1 -1 5115 1;
+#X text 256 230 -> expansion;
+#X text 17 230 compression <-;
+#X text 23 258 pvcompand~ either expands or compresses the differences
+between the amplitudes of the spectral frames. The threshold is interpreted
+as dB and useful ranges are from about -60 to +60. Positive values
+increase the "peakiness" of the sound and negative values tend to whiten
+the spectrum.;
+#N canvas 179 221 661 474 sound-source 0;
+#X text 13 300 try a vocal sound or other sound with strong formant
+structure;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array pvcompand-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X obj 227 268 tabplay~ pvcompand-sound1;
+#X msg 31 177 read -resize \$1 pvcompand-sound1;
+#X connect 2 0 13 0;
+#X connect 4 0 2 0;
+#X connect 6 0 12 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 1;
+#X connect 12 0 5 0;
+#X connect 12 1 7 0;
+#X connect 13 0 1 0;
+#X restore 121 38 pd sound-source;
+#X text 232 39 <- first load sound here;
+#X connect 0 0 1 0;
+#X connect 0 0 1 1;
+#X connect 2 0 0 2;
+#X connect 4 0 3 0;
+#X connect 5 0 0 1;
+#X connect 10 0 0 0;
diff --git a/pvcompand~.c b/pvcompand~.c
index 92035f3..a2fc22d 100644
--- a/pvcompand~.c
+++ b/pvcompand~.c
@@ -211,9 +211,9 @@ void pvcompand_init(t_pvcompand *x,short initialized)
{
int i;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 1;
x->N = x->D * x->overlap;
@@ -461,7 +461,7 @@ float pvcompand_ampdb(float db)
void pvcompand_overlap(t_pvcompand *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -473,7 +473,7 @@ void pvcompand_winfac(t_pvcompand *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
diff --git a/pvgrain~-help.pd b/pvgrain~-help.pd
new file mode 100644
index 0000000..25b844b
--- /dev/null
+++ b/pvgrain~-help.pd
@@ -0,0 +1,361 @@
+#N canvas 772 607 490 340 10;
+#N canvas 0 22 482 332 pvgrain-block 0;
+#X obj 9 110 outlet;
+#X obj 9 15 inlet~;
+#X obj 94 15 inlet;
+#X obj 8 140 block~ 256;
+#X text 12 90 args: grains/frame \, odds \, topfreq \, overlap \, window-factor
+;
+#X obj 9 68 pvgrain~ 4 0.01 2000 4 2;
+#X connect 1 0 5 0;
+#X connect 2 0 5 0;
+#X connect 5 0 0 0;
+#X restore 13 103 pd pvgrain-block;
+#X obj 220 158 dac~;
+#X obj 13 172 print;
+#X msg 110 242 \; pd dsp \$1;
+#X obj 110 221 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#N canvas 368 141 902 629 messages 0;
+#X obj 111 523 outlet;
+#X msg 105 115 probability \$1;
+#X obj 108 68 hsl 128 15 0 0.1 0 0 empty empty empty -2 -6 0 8 -43542
+-1 -1 1270 1;
+#X floatatom 105 94 5 0 0 0 - - -;
+#X obj 198 179 hsl 128 15 200 10000 0 0 empty empty empty -2 -6 0 8
+-43542 -1 -1 2333 1;
+#X floatatom 195 205 5 0 0 0 - - -;
+#X msg 195 226 topfreq \$1;
+#X obj 439 388 hsl 128 15 0 20 0 0 empty empty empty -2 -6 0 8 -43542
+-1 -1 5080 1;
+#X floatatom 436 414 5 0 0 0 - - -;
+#X msg 436 435 framegrains \$1;
+#X obj 105 1 loadbang;
+#X obj 283 284 hsl 128 15 0 1500 0 0 empty empty empty -2 -6 0 8 -43542
+-1 -1 423 1;
+#X floatatom 280 310 5 0 0 0 - - -;
+#X msg 280 331 bottomfreq \$1;
+#X obj 105 40 unpack f f f f;
+#X msg 105 21 0.01 2000 50 8;
+#X obj 300 492 fftease-system;
+#X text 436 363 maximum data grains per FFT frame;
+#X text 197 157 top frequency to listen to in source sound;
+#X text 283 263 ditto for bottom frequency;
+#X text 221 48 odds for a grain appearing from an active bin;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 3 0 1 0;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 9 0 0 0;
+#X connect 10 0 15 0;
+#X connect 11 0 12 0;
+#X connect 12 0 13 0;
+#X connect 13 0 0 0;
+#X connect 14 0 2 0;
+#X connect 14 1 4 0;
+#X connect 14 2 11 0;
+#X connect 14 3 7 0;
+#X connect 15 0 14 0;
+#X connect 16 0 0 0;
+#X restore 120 62 pd messages;
+#X obj 50 129 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 13 149 spigot;
+#X text 69 131 see amp/freq info;
+#X text 42 277 spectral granular (re)synthesis;
+#N canvas 0 22 478 328 resynth-engine 0;
+#X obj 12 28 inlet;
+#N canvas 0 22 450 300 graph1 0;
+#X array piano-sample 46383 float 2;
+#X coords 0 1 46382 -1 200 140 1;
+#X restore 215 4 graph;
+#X obj 17 242 soundfiler;
+#X msg 17 205 read -resize Piano.aif piano-sample;
+#X obj 17 169 loadbang;
+#N canvas 578 40 566 745 choir 0;
+#X obj 79 103 inlet;
+#X obj 79 141 t l b;
+#X obj 25 199 float;
+#X obj 25 228 + 1;
+#X obj 25 252 % 8;
+#X floatatom 25 276 5 0 0 0 - - -;
+#X obj 47 367 pack f f f;
+#X obj 79 315 unpack f f;
+#X obj 47 395 route 0 1 2 3 4 5 6 7;
+#X obj 112 343 / 261;
+#X text 156 345 <- piano sample base frequency;
+#N canvas 74 88 1066 749 playit 0;
+#X obj 21 47 unpack f f;
+#X obj 21 222 outlet~;
+#X floatatom 131 120 5 0 0 0 - - -;
+#X floatatom 88 118 5 0 0 0 - - -;
+#X obj 21 119 impulse~;
+#X obj 21 146 *~;
+#X obj 21 80 t b f;
+#X obj 21 182 player~ piano-sample;
+#X obj 21 8 inlet;
+#X connect 0 0 6 0;
+#X connect 0 1 2 0;
+#X connect 2 0 7 1;
+#X connect 3 0 5 1;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 4 0;
+#X connect 6 1 3 0;
+#X connect 7 0 1 0;
+#X connect 8 0 0 0;
+#X restore 47 430 pd playit;
+#X obj 123 595 outlet~;
+#X obj 123 572 *~ 0.25;
+#N canvas 74 88 1062 745 playit 0;
+#X obj 21 47 unpack f f;
+#X obj 21 222 outlet~;
+#X floatatom 131 120 5 0 0 0 - - -;
+#X floatatom 88 118 5 0 0 0 - - -;
+#X obj 21 119 impulse~;
+#X obj 21 146 *~;
+#X obj 21 80 t b f;
+#X obj 21 182 player~ piano-sample;
+#X obj 21 8 inlet;
+#X connect 0 0 6 0;
+#X connect 0 1 2 0;
+#X connect 2 0 7 1;
+#X connect 3 0 5 1;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 4 0;
+#X connect 6 1 3 0;
+#X connect 7 0 1 0;
+#X connect 8 0 0 0;
+#X restore 64 451 pd playit;
+#N canvas 74 88 1062 745 playit 0;
+#X obj 21 47 unpack f f;
+#X obj 21 222 outlet~;
+#X floatatom 131 120 5 0 0 0 - - -;
+#X floatatom 88 118 5 0 0 0 - - -;
+#X obj 21 119 impulse~;
+#X obj 21 146 *~;
+#X obj 21 80 t b f;
+#X obj 21 182 player~ piano-sample;
+#X obj 21 8 inlet;
+#X connect 0 0 6 0;
+#X connect 0 1 2 0;
+#X connect 2 0 7 1;
+#X connect 3 0 5 1;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 4 0;
+#X connect 6 1 3 0;
+#X connect 7 0 1 0;
+#X connect 8 0 0 0;
+#X restore 83 472 pd playit;
+#N canvas 74 88 1062 745 playit 0;
+#X obj 21 47 unpack f f;
+#X obj 21 222 outlet~;
+#X floatatom 131 120 5 0 0 0 - - -;
+#X floatatom 88 118 5 0 0 0 - - -;
+#X obj 21 119 impulse~;
+#X obj 21 146 *~;
+#X obj 21 80 t b f;
+#X obj 21 182 player~ piano-sample;
+#X obj 21 8 inlet;
+#X connect 0 0 6 0;
+#X connect 0 1 2 0;
+#X connect 2 0 7 1;
+#X connect 3 0 5 1;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 4 0;
+#X connect 6 1 3 0;
+#X connect 7 0 1 0;
+#X connect 8 0 0 0;
+#X restore 101 493 pd playit;
+#N canvas 74 88 1062 745 playit 0;
+#X obj 21 47 unpack f f;
+#X obj 21 222 outlet~;
+#X floatatom 131 120 5 0 0 0 - - -;
+#X floatatom 88 118 5 0 0 0 - - -;
+#X obj 21 119 impulse~;
+#X obj 21 146 *~;
+#X obj 21 80 t b f;
+#X obj 21 182 player~ piano-sample;
+#X obj 21 8 inlet;
+#X connect 0 0 6 0;
+#X connect 0 1 2 0;
+#X connect 2 0 7 1;
+#X connect 3 0 5 1;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 4 0;
+#X connect 6 1 3 0;
+#X connect 7 0 1 0;
+#X connect 8 0 0 0;
+#X restore 118 421 pd playit;
+#N canvas 74 88 1062 745 playit 0;
+#X obj 21 47 unpack f f;
+#X obj 21 222 outlet~;
+#X floatatom 131 120 5 0 0 0 - - -;
+#X floatatom 88 118 5 0 0 0 - - -;
+#X obj 21 119 impulse~;
+#X obj 21 146 *~;
+#X obj 21 80 t b f;
+#X obj 21 182 player~ piano-sample;
+#X obj 21 8 inlet;
+#X connect 0 0 6 0;
+#X connect 0 1 2 0;
+#X connect 2 0 7 1;
+#X connect 3 0 5 1;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 4 0;
+#X connect 6 1 3 0;
+#X connect 7 0 1 0;
+#X connect 8 0 0 0;
+#X restore 135 442 pd playit;
+#N canvas 74 88 1062 745 playit 0;
+#X obj 21 47 unpack f f;
+#X obj 21 222 outlet~;
+#X floatatom 131 120 5 0 0 0 - - -;
+#X floatatom 88 118 5 0 0 0 - - -;
+#X obj 21 119 impulse~;
+#X obj 21 146 *~;
+#X obj 21 80 t b f;
+#X obj 21 182 player~ piano-sample;
+#X obj 21 8 inlet;
+#X connect 0 0 6 0;
+#X connect 0 1 2 0;
+#X connect 2 0 7 1;
+#X connect 3 0 5 1;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 4 0;
+#X connect 6 1 3 0;
+#X connect 7 0 1 0;
+#X connect 8 0 0 0;
+#X restore 154 463 pd playit;
+#N canvas 74 88 1062 745 playit 0;
+#X obj 21 47 unpack f f;
+#X obj 21 222 outlet~;
+#X floatatom 131 120 5 0 0 0 - - -;
+#X floatatom 88 118 5 0 0 0 - - -;
+#X obj 21 119 impulse~;
+#X obj 21 146 *~;
+#X obj 21 80 t b f;
+#X obj 21 182 player~ piano-sample;
+#X obj 21 8 inlet;
+#X connect 0 0 6 0;
+#X connect 0 1 2 0;
+#X connect 2 0 7 1;
+#X connect 3 0 5 1;
+#X connect 4 0 5 0;
+#X connect 5 0 7 0;
+#X connect 6 0 4 0;
+#X connect 6 1 3 0;
+#X connect 7 0 1 0;
+#X connect 8 0 0 0;
+#X restore 172 484 pd playit;
+#X connect 0 0 1 0;
+#X connect 1 0 7 0;
+#X connect 1 1 2 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 4 0 2 1;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 8 0;
+#X connect 7 0 6 1;
+#X connect 7 1 9 0;
+#X connect 8 0 11 0;
+#X connect 8 1 14 0;
+#X connect 8 2 15 0;
+#X connect 8 3 16 0;
+#X connect 8 4 17 0;
+#X connect 8 5 18 0;
+#X connect 8 6 19 0;
+#X connect 8 7 20 0;
+#X connect 9 0 6 2;
+#X connect 11 0 13 0;
+#X connect 13 0 12 0;
+#X connect 14 0 13 0;
+#X connect 15 0 13 0;
+#X connect 16 0 13 0;
+#X connect 17 0 13 0;
+#X connect 18 0 13 0;
+#X connect 19 0 13 0;
+#X connect 20 0 13 0;
+#X restore 12 97 pd choir;
+#X obj 12 121 outlet~;
+#X text 13 269 this is one example of what you can do with the analysis
+data;
+#X obj 12 63 spigot;
+#X obj 49 44 inlet;
+#X obj 113 27 loadbang;
+#X msg 113 47 0;
+#X connect 0 0 8 0;
+#X connect 3 0 2 0;
+#X connect 4 0 3 0;
+#X connect 5 0 6 0;
+#X connect 8 0 5 0;
+#X connect 9 0 8 1;
+#X connect 10 0 11 0;
+#X connect 11 0 8 1;
+#X restore 220 119 pd resynth-engine;
+#N canvas 408 408 482 332 sound-source 0;
+#X obj -34 240 outlet~;
+#X obj -34 215 *~ 0.3;
+#X floatatom -34 72 5 0 0 0 - - -;
+#X obj 149 119 * 1.5;
+#X floatatom 51 142 5 0 0 0 - - -;
+#X floatatom 149 143 5 0 0 0 - - -;
+#X obj 51 161 phasor~ 586.6;
+#X obj 149 161 phasor~ 660;
+#X obj -34 161 phasor~ 440;
+#X obj 51 119 * 1.25;
+#X msg -34 41 440;
+#X obj -34 15 loadbang;
+#X text -18 262 a soundfile or live mic would be more interesting here
+;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 2 0 8 0;
+#X connect 2 0 9 0;
+#X connect 3 0 5 0;
+#X connect 4 0 6 0;
+#X connect 5 0 7 0;
+#X connect 6 0 1 0;
+#X connect 7 0 1 0;
+#X connect 8 0 1 0;
+#X connect 9 0 4 0;
+#X connect 10 0 2 0;
+#X connect 11 0 10 0;
+#X restore 13 41 pd sound-source;
+#N canvas 180 51 470 320 what's-going-on-here? 0;
+#X text 18 26 Input sound is analyzed and a certain number of bin snapshots
+are taken \, based on the probability and framegrains parameters. Each
+bin grain snapshot is sent out as a list with two members: [amplitude
+\, frequency]. In this example the grain data is used to drive a sample
+player. One could easily replace this with a synth or even drive an
+external MIDI synth. This is something like a pitch-follower except
+that it follows the entire spectrum (limited by the topfreq parameter)
+rather than just looking for the fundamental. Since this is based on
+FFT analysis the resolution is worse for lower frequencies. Frequency
+resolution can be improved by upping the FFT size.;
+#X restore 269 203 pd what's-going-on-here?;
+#X obj 334 96 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X text 356 98 <- turn me on;
+#X text 204 64 <- check me out;
+#X connect 0 0 7 0;
+#X connect 0 0 10 0;
+#X connect 4 0 3 0;
+#X connect 5 0 0 1;
+#X connect 6 0 7 1;
+#X connect 7 0 2 0;
+#X connect 10 0 1 0;
+#X connect 10 0 1 1;
+#X connect 11 0 0 0;
+#X connect 13 0 10 1;
diff --git a/pvgrain~.c b/pvgrain~.c
index e3eee1d..cfcbeba 100644
--- a/pvgrain~.c
+++ b/pvgrain~.c
@@ -344,7 +344,7 @@ void pvgrain_init(t_pvgrain *x, short initialized)
void pvgrain_overlap(t_pvgrain *x, t_floatarg o)
{
- if(!power_of_two((int)o)){
+ if(!fftease_power_of_two((int)o)){
error("%f is not a power of two",o);
return;
}
@@ -354,7 +354,7 @@ void pvgrain_overlap(t_pvgrain *x, t_floatarg o)
void pvgrain_winfac(t_pvgrain *x, t_floatarg f)
{
- if(!power_of_two((int)f)){
+ if(!fftease_power_of_two((int)f)){
error("%f is not a power of two",f);
return;
}
diff --git a/pvharm~-help.pd b/pvharm~-help.pd
new file mode 100644
index 0000000..e22266f
--- /dev/null
+++ b/pvharm~-help.pd
@@ -0,0 +1,87 @@
+#N canvas 768 40 466 316 10;
+#N canvas 0 22 466 316 pvharm-block 0;
+#X obj 22 81 pvharm~ 0 3000 4 1;
+#X obj 22 130 outlet~;
+#X obj 22 20 inlet~;
+#X obj 22 156 block~ 256;
+#X obj 62 41 inlet;
+#X obj 102 41 inlet;
+#X obj 143 41 inlet;
+#X obj 216 65 inlet;
+#X text 32 106 args: lowfreq \, highfreq \, overlap \, window-factor
+;
+#X connect 0 0 1 0;
+#X connect 2 0 0 0;
+#X connect 4 0 0 1;
+#X connect 5 0 0 2;
+#X connect 6 0 0 3;
+#X connect 7 0 0 0;
+#X restore 70 134 pd pvharm-block;
+#X obj 70 200 dac~;
+#X obj 70 177 *~ 0.1;
+#X obj 70 53 phasor~ 300;
+#X floatatom 95 80 5 0 0 1 transpose1 - -;
+#X floatatom 120 97 5 0 0 1 transpose2 - -;
+#X floatatom 145 114 5 0 0 1 synth-threshold - -;
+#N canvas 587 239 474 324 messages 0;
+#X obj 61 259 outlet;
+#X msg 61 121 highfreq \$1;
+#X floatatom 61 100 5 0 0 0 - - -;
+#X floatatom 118 168 5 0 0 0 - - -;
+#X msg 118 189 lowfreq \$1;
+#X obj 165 228 fftease-system;
+#X obj 64 72 hsl 128 15 500 5000 0 0 empty empty empty -2 -6 0 8 -184257
+-1 -1 3500 1;
+#X obj 121 144 hsl 128 15 0 450 0 0 empty empty empty -2 -6 0 8 -184257
+-1 -1 5700 1;
+#X text 29 37 synthesis frequency boundaries;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 2 0;
+#X connect 7 0 3 0;
+#X restore 292 118 pd messages;
+#X obj 13 136 *~ 0.3;
+#X msg 163 206 \; pd dsp \$1;
+#X obj 110 155 hsl 128 15 0 0.2 0 0 empty empty empty -2 -6 0 8 -184257
+-1 -1 3500 1;
+#X obj 163 180 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X floatatom 70 30 5 0 0 0 - - -;
+#X text 18 254 pvharm~ provides basic harmonizing with two transpositions
+of the input internally calculated and mixed to the output;
+#N canvas 578 326 1043 702 init 0;
+#X obj 56 175 outlet;
+#X obj 104 171 outlet;
+#X obj 157 173 outlet;
+#X obj 230 177 outlet;
+#X obj 179 21 loadbang;
+#X msg 179 43 165 1.25 1.5 0.01;
+#X obj 179 64 unpack f f f f;
+#X connect 4 0 5 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 6 1 1 0;
+#X connect 6 2 2 0;
+#X connect 6 3 3 0;
+#X restore 369 -6 pd init;
+#X text 244 156 gain;
+#X connect 0 0 2 0;
+#X connect 2 0 1 0;
+#X connect 2 0 1 1;
+#X connect 3 0 0 0;
+#X connect 3 0 8 0;
+#X connect 4 0 0 1;
+#X connect 5 0 0 2;
+#X connect 6 0 0 3;
+#X connect 7 0 0 4;
+#X connect 8 0 2 0;
+#X connect 10 0 2 1;
+#X connect 11 0 9 0;
+#X connect 12 0 3 0;
+#X connect 14 0 12 0;
+#X connect 14 1 4 0;
+#X connect 14 2 5 0;
+#X connect 14 3 6 0;
diff --git a/pvharm~.c b/pvharm~.c
index 6952960..8231b3b 100644
--- a/pvharm~.c
+++ b/pvharm~.c
@@ -182,7 +182,7 @@ void pvharm_assist (t_pvharm *x, void *b, long msg, long arg, char *dst)
void pvharm_overlap(t_pvharm *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -194,7 +194,7 @@ void pvharm_winfac(t_pvharm *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -281,9 +281,9 @@ void *pvharm_new(t_symbol *s, int argc, t_atom *argv)
if(x->hifreq <50 || x->hifreq> 22050)
x->hifreq = 4000;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 2;
pvharm_init(x,0);
diff --git a/pvoc~-help.pd b/pvoc~-help.pd
new file mode 100644
index 0000000..91f3c69
--- /dev/null
+++ b/pvoc~-help.pd
@@ -0,0 +1,114 @@
+#N canvas -2 462 686 439 10;
+#N canvas 0 22 502 352 pvocblock 0;
+#X obj 27 158 outlet~;
+#X obj 27 42 inlet~;
+#X obj 80 13 inlet;
+#X obj 134 46 inlet;
+#X obj 213 69 inlet;
+#X text 145 87 args: lo-freq \, hi-freq \, overlap \, window-factor
+;
+#X obj 27 85 pvoc~ 0 8000 4 4;
+#X obj 27 182 block~ 256;
+#X connect 1 0 6 0;
+#X connect 2 0 6 1;
+#X connect 3 0 6 2;
+#X connect 4 0 6 0;
+#X connect 6 0 0 0;
+#X restore 203 144 pd pvocblock;
+#X obj 203 203 dac~;
+#X floatatom 229 68 5 0.1 3 2 transpose transpose -;
+#X floatatom 255 99 5 0 0 2 thresh thresh -;
+#X msg 44 193 \; pd dsp \$1;
+#X obj 44 174 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 80 285 hsl 128 15 0.1 4 0 0 empty empty empty -2 -6 0 8 -261285
+-1 -1 1931 1;
+#N canvas 242 216 504 402 messages 1;
+#X obj 70 293 outlet;
+#X floatatom 70 82 5 0 0 0 - - -;
+#X msg 70 112 highfreq \$1;
+#X floatatom 182 175 5 0 0 0 - - -;
+#X msg 182 204 lowfreq \$1;
+#X msg 70 53 8000;
+#X obj 70 27 loadbang;
+#X msg 182 154 0;
+#X obj 182 132 loadbang;
+#X obj 212 267 fftease-system;
+#X obj 161 48 hsl 128 15 500 8000 0 0 empty empty empty -2 -6 0 8 -68760
+-1 -1 6900 1;
+#X obj 256 148 hsl 128 15 0 1000 0 0 empty empty empty -2 -6 0 8 -68760
+-1 -1 0 1;
+#X text 149 22 maximum frequency to synthesize;
+#X text 252 124 minimum;
+#X connect 1 0 2 0;
+#X connect 2 0 0 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 5 0 1 0;
+#X connect 6 0 5 0;
+#X connect 7 0 3 0;
+#X connect 8 0 7 0;
+#X connect 9 0 0 0;
+#X connect 10 0 1 0;
+#X connect 11 0 3 0;
+#X restore 282 116 pd messages;
+#X obj 222 285 hsl 128 15 0 0.05 0 0 empty empty empty -2 -6 0 8 -227712
+-1 -1 300 1;
+#X obj 219 311 s thresh;
+#X obj 77 311 s transpose;
+#X obj 77 233 loadbang;
+#X msg 77 264 1;
+#X obj 311 144 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -43049
+-1 -1 5400 1;
+#X obj 203 170 *~ 0.01;
+#X text 444 143 gain;
+#N canvas 639 439 639 490 sndfile 0;
+#X text 13 300 try a vocal sound or other sound with strong formant
+structure;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array pvoc-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X obj 227 268 tabplay~ pvoc-sound1;
+#X msg 31 177 read -resize \$1 pvoc-sound1;
+#X connect 2 0 13 0;
+#X connect 4 0 2 0;
+#X connect 6 0 12 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 1;
+#X connect 12 0 5 0;
+#X connect 12 1 7 0;
+#X connect 13 0 1 0;
+#X restore 203 31 pd sndfile;
+#X msg 219 249 0.001;
+#X text 286 27 <- load a soundfile here;
+#X text 75 345 pvoc~ allows you to change the pitch of the input sound
+without changing its speed. Optional arguments: low frequency to synthesize
+\, high frequency to synthesize. These parameters \, together with
+the pvoc~ block size will determine CPU load.;
+#X connect 0 0 14 0;
+#X connect 2 0 0 1;
+#X connect 3 0 0 2;
+#X connect 5 0 4 0;
+#X connect 6 0 10 0;
+#X connect 7 0 0 3;
+#X connect 8 0 9 0;
+#X connect 11 0 12 0;
+#X connect 11 0 17 0;
+#X connect 12 0 6 0;
+#X connect 13 0 14 1;
+#X connect 14 0 1 0;
+#X connect 14 0 1 1;
+#X connect 16 0 0 0;
+#X connect 17 0 8 0;
diff --git a/pvoc~.c b/pvoc~.c
index 2b806d9..a8f658c 100644
--- a/pvoc~.c
+++ b/pvoc~.c
@@ -137,7 +137,7 @@ void pvoc_mute(t_pvoc *x, t_floatarg tog)
void pvoc_overlap(t_pvoc *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -149,7 +149,7 @@ void pvoc_winfac(t_pvoc *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -255,9 +255,9 @@ void pvoc_init(t_pvoc *x, short initialized)
x->D = 256;
if(x->P <= 0)
x->P = 1.0;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 2;
x->N = x->D * x->overlap;
x->Nw = x->N * x->winfac;
@@ -357,10 +357,10 @@ void *pvoc_new(t_symbol *s, int argc, t_atom *argv)
x->hifreq = 4000;
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 2;
}
x->R = sys_getsr();
diff --git a/pvtuner.h b/pvtuner.h
new file mode 100644
index 0000000..6f51fc8
--- /dev/null
+++ b/pvtuner.h
@@ -0,0 +1,120 @@
+#define MAXTONES (1024)
+#define BASE_FREQ (27.5) /* low A */
+#define DIATONIC 0
+#define EASTERN 1
+#define MINOR 2
+#define EQ12 3
+#define PENTATONIC 4
+#define MAJOR_ADDED_SIXTH 5
+#define MINOR_ADDED_SIXTH 6
+#define MAJOR_SEVENTH_CHORD 7
+#define MINOR_SEVENTH_CHORD 8
+#define DOMINANT_SEVENTH_CHORD 9
+#define EQ8 10
+#define PENTACLUST 11
+#define QUARTERCLUST 12
+#define EQ5 13
+#define SLENDRO 14
+#define PELOG 15
+#define IMPORTED_SCALE 16
+
+#define DEFAULT_VECTOR_SIZE 512
+static t_class *pvtuner_class;
+
+typedef struct _pvtuner
+{
+ t_object x_obj;
+ t_float x_f;
+ int R;
+ int N;
+ int N2;
+ int Nw;
+ int Nw2;
+ int D;
+ int i;
+ int inCount;
+ float *Wanal;
+ float *Wsyn;
+ float *input;
+ float *Hwin;
+ float *buffer;
+ float *channel;
+ float *output;
+ // for convert
+ float *c_lastphase_in;
+ float *c_lastphase_out;
+ float c_fundamental;
+ float c_factor_in;
+ float c_factor_out;
+
+ // for oscbank
+ int NP;
+ float P;
+ int L;
+ int first;
+ float Iinv;
+ float *lastamp;
+ float *lastfreq;
+ float *bindex;
+ float *table;
+ float myPInc;
+ float ffac;
+ //
+ int lo_bin;
+ int hi_bin;
+ float topfreq;
+ float synt;
+ float myPI;
+ float TWOmyPI;
+ // for fast fft
+ float mult;
+ float *trigland;
+ int *bitshuffle;
+ //
+ float *prebuffer;
+ float *postbuffer;
+ //
+ int bypass_state;
+ int pitch_connected;
+ int synt_connected;
+ // TUNING
+ float *pitchgrid ;
+ float pbase ;
+ int scale_steps;
+ short current_scale;
+ short mute;
+ //
+ float TWOPIoL;
+ float user_lofreq;
+ float user_hifreq;
+ int vector_size;
+ float funda;
+ float curfreq;
+ int overlap;
+ int window_factor;
+ float tabscale;
+ int quality;
+ int scale_len;
+} t_pvtuner;
+
+
+float closestf(float test, float *arr) ;
+void pvtuner_diatonic( t_pvtuner *x );
+void pvtuner_eastern( t_pvtuner *x );
+void pvtuner_minor( t_pvtuner *x );
+void pvtuner_eq12( t_pvtuner *x );
+void pvtuner_pentatonic( t_pvtuner *x );
+void pvtuner_major_added_sixth( t_pvtuner *x );
+void pvtuner_minor_added_sixth( t_pvtuner *x );
+void pvtuner_major_seventh_chord( t_pvtuner *x );
+void pvtuner_minor_seventh_chord( t_pvtuner *x );
+void pvtuner_dominant_seventh_chord( t_pvtuner *x );
+void pvtuner_eq8( t_pvtuner *x );
+void pvtuner_pentaclust( t_pvtuner *x );
+void pvtuner_quarterclust( t_pvtuner *x );
+void pvtuner_eq5( t_pvtuner *x );
+void pvtuner_slendro( t_pvtuner *x );
+void pvtuner_pelog( t_pvtuner *x );
+void pvtuner_update_imported( t_pvtuner *x );
+
+
diff --git a/pvtuner~-help.pd b/pvtuner~-help.pd
new file mode 100644
index 0000000..51a6b25
--- /dev/null
+++ b/pvtuner~-help.pd
@@ -0,0 +1,139 @@
+#N canvas 688 343 449 413 10;
+#N canvas 0 22 502 352 tuneblock 0;
+#X obj 33 21 inlet~;
+#X obj 97 20 inlet;
+#X obj 161 25 inlet;
+#X obj 242 56 inlet;
+#X obj 33 203 outlet~;
+#X obj 33 102 pvtuner~ 0 5000;
+#X obj 147 208 block~ 256;
+#X connect 0 0 5 0;
+#X connect 1 0 5 1;
+#X connect 2 0 5 2;
+#X connect 3 0 5 0;
+#X connect 5 0 4 0;
+#X restore 24 141 pd tuneblock;
+#X obj 24 3 noise~;
+#X floatatom 50 71 5 0.1 2 1 transpose - -;
+#X obj 24 242 dac~;
+#X msg 81 239 \; pd dsp \$1;
+#X obj 81 216 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#N canvas 968 733 654 290 messages 0;
+#X obj 21 216 outlet;
+#N canvas 0 22 536 459 built-in-scales 0;
+#X msg 11 30 major_seventh_chord;
+#X msg 41 49 minor_seventh_chord;
+#X msg 113 88 minor_added_sixth;
+#X msg 84 68 major_added_sixth;
+#X msg 320 8 pelog;
+#X msg 324 36 slendro;
+#X obj 46 312 outlet;
+#X msg 296 97 eq5;
+#X msg 302 117 eq8;
+#X msg 309 138 eq12;
+#X msg -1 11 dominant_seventh_chord;
+#X msg 276 181 minor;
+#X msg 284 208 pentatonic;
+#X msg 282 233 eastern;
+#X msg 255 261 pentaclust;
+#X msg 270 282 quarterclust;
+#X connect 0 0 6 0;
+#X connect 1 0 6 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 0;
+#X connect 4 0 6 0;
+#X connect 5 0 6 0;
+#X connect 7 0 6 0;
+#X connect 8 0 6 0;
+#X connect 9 0 6 0;
+#X connect 10 0 6 0;
+#X connect 11 0 6 0;
+#X connect 12 0 6 0;
+#X connect 13 0 6 0;
+#X connect 14 0 6 0;
+#X connect 15 0 6 0;
+#X restore 21 27 pd built-in-scales;
+#N canvas 519 357 742 434 more-scales 0;
+#X msg 77 94 27.5 41.25 55 82.5 110 165 220 330 440 660 880 1320 1760
+2640 3520 5280 7040 10560 14080 21120;
+#X text 80 78 define scale as ordered list of numbers;
+#X obj 77 223 outlet;
+#X msg 165 148 import_scale /Applications/Pd/Pd-0.38-3.app/Contents/Resources/extra/blue3.scale
+;
+#X text 161 130 you can even load a file \, but be sure to use a full
+pathname;
+#X connect 0 0 2 0;
+#X connect 3 0 2 0;
+#X restore 48 48 pd more-scales;
+#X obj 130 154 fftease-system;
+#N canvas 968 224 694 704 frequency-management 0;
+#X obj 37 509 outlet;
+#X msg 37 122 toptune \$1;
+#X msg 187 129 topfreq \$1;
+#X floatatom 37 93 5 0 0 0 - - -;
+#X floatatom 187 98 5 0 0 0 - - -;
+#X obj 160 31 hsl 200 15 500 9000 0 0 empty empty empty -2 -6 0 8 -126035
+-1 -1 9500 1;
+#X obj 157 57 t f f;
+#X msg 258 181 frequency_range 500 2000;
+#X msg 258 207 frequency_range 0 6000;
+#X text 45 106 highest tuned freq;
+#X text 191 114 highest synthesized freq;
+#X text 256 166 set synthesize range;
+#X msg 155 471 basefreq \$1;
+#X floatatom 155 454 5 0 0 0 - - -;
+#X obj 158 433 hsl 128 15 27.5 500 0 0 empty empty empty -2 -6 0 8
+-261681 -1 -1 0 1;
+#X msg 155 406 27.5;
+#X obj 155 381 loadbang;
+#X text 190 409 set base frequency for scale;
+#X obj 40 12 hsl 200 15 500 9000 0 0 empty empty empty -2 -6 0 8 -126035
+-1 -1 9700 1;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 1 0;
+#X connect 4 0 2 0;
+#X connect 5 0 6 0;
+#X connect 6 0 3 0;
+#X connect 6 1 4 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 0;
+#X connect 12 0 0 0;
+#X connect 13 0 12 0;
+#X connect 14 0 13 0;
+#X connect 15 0 14 0;
+#X connect 16 0 15 0;
+#X connect 18 0 3 0;
+#X restore 56 73 pd frequency-management;
+#X msg 109 116 binfo;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X restore 103 115 pd messages;
+#X obj 167 26 loadbang;
+#X msg 50 42 1;
+#X obj 71 163 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -123336
+-1 -1 600 1;
+#X floatatom 68 181 5 0 0 0 - - -;
+#X floatatom 76 91 5 0 0 1 synth-threshold - -;
+#X msg 167 47 0.001;
+#X text 188 116 <- check it;
+#X obj 24 199 *~ 0.01;
+#X text 27 295 pvtuner~ tunes sounds to scales.;
+#X connect 0 0 14 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 1;
+#X connect 5 0 4 0;
+#X connect 6 0 0 3;
+#X connect 7 0 8 0;
+#X connect 7 0 12 0;
+#X connect 8 0 2 0;
+#X connect 9 0 10 0;
+#X connect 10 0 14 1;
+#X connect 11 0 0 2;
+#X connect 12 0 11 0;
+#X connect 14 0 3 0;
+#X connect 14 0 3 1;
diff --git a/pvtuner~.c b/pvtuner~.c
index a142680..84cdd58 100644
--- a/pvtuner~.c
+++ b/pvtuner~.c
@@ -200,9 +200,9 @@ void pvtuner_init(t_pvtuner *x,short initialized)
if(!x->D)
x->D = 256;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 2;
x->Iinv = 1./x->D;
@@ -1091,7 +1091,7 @@ void pvtuner_mute(t_pvtuner *x, t_floatarg state)
void pvtuner_overlap(t_pvtuner *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -1103,7 +1103,7 @@ void pvtuner_winfac(t_pvtuner *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
diff --git a/pvwarp~-help.pd b/pvwarp~-help.pd
new file mode 100644
index 0000000..a26d2c8
--- /dev/null
+++ b/pvwarp~-help.pd
@@ -0,0 +1,141 @@
+#N canvas 36 232 566 392 10;
+#N canvas 0 22 462 312 pvwarp-block 0;
+#X obj 185 146 pvwarp~ 0 4000 4 2;
+#X obj 185 187 outlet~;
+#X obj 158 250 block~ 256;
+#X obj 185 88 inlet~;
+#X obj 339 83 inlet;
+#X obj 265 47 inlet;
+#X obj 283 70 inlet;
+#X obj 321 52 inlet;
+#X connect 0 0 1 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 7;
+#X connect 6 0 0 8;
+#X connect 7 0 0 9;
+#X restore 121 125 pd pvwarp-block;
+#N canvas 595 467 629 326 messages 0;
+#X obj 182 294 outlet;
+#X msg 99 77 bottomfreq \$1;
+#X floatatom 99 54 5 0 0 0 - - -;
+#X floatatom 253 68 5 0 0 0 - - -;
+#X msg 253 87 topfreq \$1;
+#X msg 301 178 autofunc 0.1 2;
+#X obj 301 158 loadbang;
+#X text 254 50 highest freq to synthesize;
+#X text 98 38 lowest freq;
+#N canvas 430 531 673 333 init 0;
+#X msg 66 47 automate 1;
+#X obj 66 17 loadbang;
+#X text 159 28 this tells Pd to ignore its control inlets and take
+the warp function exclusively from its internally generated states.
+This is because otherwise we'd have to deal with sending lots of data
+to the inlets.;
+#X text 78 125 FYI - the inlets are as follows: signal in \, CF1 \,
+BW1 \, warpfac1 \, CF2 \, BW2 \, warpfac2 \, transposition \, synthesis
+threshold.;
+#X obj 22 268 outlet;
+#X obj 196 265 s warp-offset;
+#X obj 305 262 s warp-transpose;
+#X obj 429 262 s warp-threshold;
+#X obj 207 221 unpack f f f;
+#X msg 207 197 0 1 1e-05;
+#X obj 207 174 loadbang;
+#X connect 0 0 4 0;
+#X connect 1 0 0 0;
+#X connect 8 0 5 0;
+#X connect 8 1 6 0;
+#X connect 8 2 7 0;
+#X connect 9 0 8 0;
+#X connect 10 0 9 0;
+#X restore 290 231 pd init;
+#X obj 256 26 hsl 128 15 500 5000 0 0 empty empty empty -2 -6 0 8 -260204
+-1 -1 8700 1;
+#X obj 102 17 hsl 128 15 0 1000 0 0 empty empty empty -2 -6 0 8 -260204
+-1 -1 0 1;
+#X text 407 177 punch for a new warp function.;
+#X text 295 201 parameters are minimum warp and maximum warp.;
+#X obj 370 259 fftease-system;
+#X connect 1 0 0 0;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 5 0;
+#X connect 9 0 0 0;
+#X connect 10 0 3 0;
+#X connect 11 0 2 0;
+#X connect 14 0 0 0;
+#X restore 258 109 pd messages;
+#X msg 44 193 \; pd dsp \$1;
+#X obj 44 174 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj 121 160 dac~;
+#X floatatom 171 89 5 0 0 0 - transpose -;
+#X floatatom 146 72 5 0 0 0 - offset -;
+#X obj 201 196 hsl 128 15 0 1 0 0 offset empty offset -2 -6 0 8 -260204
+-1 -1 4200 1;
+#X obj 202 231 hsl 128 15 0.25 1.5 0 0 transpose empty transpose -2
+-6 0 8 -260204 -1 -1 7720 1;
+#X obj 201 264 hsl 128 15 0 0.05 0 0 threshold empty threshold -2 -6
+0 8 -260204 -1 -1 0 1;
+#X floatatom 196 106 5 0 0 0 - threshold -;
+#X text 231 41 load a sound \, then warp away;
+#X text 339 262 synthesis threshold;
+#X text 334 196 offset for warping function;
+#X text 343 107 <- more info here;
+#N canvas 639 439 647 498 sound-source 0;
+#X text 13 300 try a vocal sound or other sound with strong formant
+structure;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array pvwarp-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X obj 227 268 tabplay~ pvwarp-sound1;
+#X msg 31 177 read -resize \$1 pvwarp-sound1;
+#X connect 2 0 13 0;
+#X connect 4 0 2 0;
+#X connect 6 0 12 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 1;
+#X connect 12 0 5 0;
+#X connect 12 1 7 0;
+#X connect 13 0 1 0;
+#X restore 121 41 pd sound-source;
+#X text 80 304 Experimental spectrum warper. An internal frequency
+warping function is created either according to specification or with
+the autofunc message. Try it on vocal sounds.;
+#N canvas 0 22 454 304 rinit 0;
+#X obj 26 83 r warp-offset;
+#X obj 135 80 r warp-transpose;
+#X obj 256 79 r warp-threshold;
+#X obj 48 160 outlet;
+#X obj 109 171 outlet;
+#X obj 244 174 outlet;
+#X connect 0 0 3 0;
+#X connect 1 0 4 0;
+#X connect 2 0 5 0;
+#X restore 131 231 pd rinit;
+#X connect 0 0 4 0;
+#X connect 0 0 4 1;
+#X connect 1 0 0 4;
+#X connect 3 0 2 0;
+#X connect 5 0 0 2;
+#X connect 6 0 0 1;
+#X connect 10 0 0 3;
+#X connect 15 0 0 0;
+#X connect 17 0 7 0;
+#X connect 17 1 8 0;
+#X connect 17 2 9 0;
diff --git a/pvwarp~.c b/pvwarp~.c
index 63a97db..3aa4209 100644
--- a/pvwarp~.c
+++ b/pvwarp~.c
@@ -1 +1,872 @@
-#include "MSPd.h" #include "fftease.h" #if MSP void *pvwarp_class; #endif #if PD static t_class *pvwarp_class; #endif #define OBJECT_NAME "pvwarp~" typedef struct _pvwarp { #if MSP t_pxobject x_obj; #endif #if PD t_object x_obj; float x_f; #endif int R; int N; int N2; int Nw; int Nw2; int D; int i; int inCount; float *Wanal; float *Wsyn; float *input; float *Hwin; float *buffer; float *channel; float *output; // for convert float *c_lastphase_in; float *c_lastphase_out; float c_fundamental; float c_factor_in; float c_factor_out; float P; int L; int first; float Iinv; float *lastamp; float *lastfreq; float *windex; float *table; float myPInc; float ffac; // int lo_bin; int hi_bin; float lofreq;//user speficied lowest synthfreq float hifreq;// user specified highest synthfreq float topfreq; float synt; float myPI; float TWOmyPI; // for fast fft float mult; float *trigland; int *bitshuffle; // short *connections; short mute; short bypass; int pitch_connected; int synt_connected; float *warpfunc ; short please_update; short always_update; float cf1; float bw1; float warpfac1; float cf2; float bw2; float warpfac2; int funcoff; short verbose; short automate; int overlap;//overlap factor int winfac;// window factor int vs;//last measurement of vector size } t_pvwarp; void *pvwarp_new(t_symbol *s, int argc, t_atom *argv); //t_int *offset_perform(t_int *w); t_int *pvwarp_perform(t_int *w); void pvwarp_dsp(t_pvwarp *x, t_signal **sp, short *count); void pvwarp_assist(t_pvwarp *x, void *b, long m, long a, char *s); void pvwarp_bypass(t_pvwarp *x, t_floatarg state); void pvwarp_mute(t_pvwarp *x, t_floatarg state); void pvwarp_verbose(t_pvwarp *x, t_floatarg state); void pvwarp_overlap(t_pvwarp *x, t_floatarg o); void pvwarp_automate(t_pvwarp *x, t_floatarg state); void pvwarp_autofunc(t_pvwarp *x, t_floatarg minval, t_floatarg maxval); void pvwarp_float(t_pvwarp *x, t_float f); void pvwarp_dsp_free( t_pvwarp *x ); void pvwarp_fftinfo( t_pvwarp *x ); float myrand( float min, float max ); float closestf(float test, float *arr) ; int freq_to_bin( float target, float fundamental ); void update_warp_function( t_pvwarp *x ) ; void pvwarp_init(t_pvwarp *x, short initialized); void pvwarp_bottomfreq(t_pvwarp *x, t_floatarg f); void pvwarp_topfreq(t_pvwarp *x, t_floatarg f); void pvwarp_fftinfo(t_pvwarp *x); void pvwarp_overlap(t_pvwarp *x, t_floatarg f); void pvwarp_winfac(t_pvwarp *x, t_floatarg f);; #if MSP void main(void) { setup((t_messlist **)&pvwarp_class, (method)pvwarp_new, (method)pvwarp_dsp_free, (short)sizeof(t_pvwarp), 0, A_GIMME, 0); addmess((method)pvwarp_dsp, "dsp", A_CANT, 0); addmess((method)pvwarp_assist,"assist",A_CANT,0); addmess((method)pvwarp_bypass,"bypass",A_DEFFLOAT,0); addmess((method)pvwarp_mute,"mute",A_DEFFLOAT,0); addmess((method)pvwarp_verbose,"verbose",A_DEFFLOAT,0); addmess((method)pvwarp_overlap,"overlap",A_FLOAT,0); addmess((method)pvwarp_bottomfreq,"bottomfreq",A_FLOAT,0); addmess((method)pvwarp_topfreq,"topfreq",A_FLOAT,0); addmess((method)pvwarp_fftinfo,"fftinfo",0); addmess((method)pvwarp_autofunc,"autofunc",A_DEFFLOAT, A_DEFFLOAT,0); addmess((method)pvwarp_overlap,"overlap",A_DEFFLOAT,0); addmess((method)pvwarp_winfac,"winfac",A_DEFFLOAT,0); addmess((method)pvwarp_fftinfo,"fftinfo",0); addfloat((method)pvwarp_float); dsp_initclass(); post("%s %s",OBJECT_NAME,FFTEASE_ANNOUNCEMENT); } #endif #if PD /* Pd Initialization */ void pvwarp_tilde_setup(void) { pvwarp_class = class_new(gensym("pvwarp~"), (t_newmethod)pvwarp_new, (t_method)pvwarp_dsp_free ,sizeof(t_pvwarp), 0,A_GIMME,0); CLASS_MAINSIGNALIN(pvwarp_class, t_pvwarp, x_f); class_addmethod(pvwarp_class, (t_method)pvwarp_dsp, gensym("dsp"), 0); class_addmethod(pvwarp_class, (t_method)pvwarp_mute, gensym("mute"), A_DEFFLOAT,0); class_addmethod(pvwarp_class, (t_method)pvwarp_bypass, gensym("bypass"), A_DEFFLOAT,0); class_addmethod(pvwarp_class, (t_method)pvwarp_overlap, gensym("overlap"), A_DEFFLOAT,0); class_addmethod(pvwarp_class, (t_method)pvwarp_bottomfreq, gensym("bottomfreq"), A_DEFFLOAT,0); class_addmethod(pvwarp_class, (t_method)pvwarp_topfreq, gensym("topfreq"), A_DEFFLOAT, 0); class_addmethod(pvwarp_class, (t_method)pvwarp_automate, gensym("automate"), A_DEFFLOAT, 0); class_addmethod(pvwarp_class, (t_method)pvwarp_autofunc, gensym("autofunc"), A_DEFFLOAT,A_DEFFLOAT,0); class_addmethod(pvwarp_class,(t_method)pvwarp_overlap,gensym("overlap"),A_FLOAT,0); class_addmethod(pvwarp_class,(t_method)pvwarp_winfac,gensym("winfac"),A_FLOAT,0); class_addmethod(pvwarp_class,(t_method)pvwarp_fftinfo,gensym("fftinfo"),0); // addfloat((method)pvwarp_float); post("%s %s",OBJECT_NAME,FFTEASE_ANNOUNCEMENT); } #endif void pvwarp_automate(t_pvwarp *x, t_floatarg state) { x->automate = state; } void pvwarp_overlap(t_pvwarp *x, t_floatarg f) { int i = (int) f; if(!power_of_two(i)){ error("%f is not a power of two",f); return; } x->overlap = i; pvwarp_init(x,1); } void pvwarp_winfac(t_pvwarp *x, t_floatarg f) { int i = (int)f; if(!power_of_two(i)){ error("%f is not a power of two",f); return; } x->winfac = i; pvwarp_init(x,2); } void pvwarp_fftinfo(t_pvwarp *x) { if( ! x->overlap ){ post("zero overlap!"); return; } post("%s: FFT size %d, hopsize %d, windowsize %d", OBJECT_NAME, x->N, x->N/x->overlap, x->Nw); } float myrand ( float min, float max ) { return (min + (max-min) * ((float) (rand() % 32768) / (float) 32768.0)); } void update_warp_function( t_pvwarp *x ) { int i,j; int N2 = x->N2; float *warpfunc = x->warpfunc; float warpfac1 = x->warpfac1; float warpfac2 = x->warpfac2; float cf1 = x->cf1; float cf2 = x->cf2; float bw1 = x->bw1; float bw2 = x->bw2; float c_fundamental = x->c_fundamental; float deviation; float diff; int midbin, lobin, hibin ; float hif, lof; int bin_extent; short verbose = x->verbose; for( i = 0; i < N2; i++ ){ warpfunc[i] = 1.0; } hif = cf1 * (1. + bw1); lof = cf1 * (1. - bw1); midbin = freq_to_bin( cf1, c_fundamental ); hibin = freq_to_bin( hif, c_fundamental ); lobin = freq_to_bin( lof, c_fundamental ); if( hibin >= N2 - 1 ){ hibin = N2 - 1; } if( lobin < 0 ){ lobin = 0; } if( verbose ) post("bump1: hi %d mid %d lo %d",hibin,midbin,lobin); warpfunc[midbin] = warpfac1; diff = warpfac1 - 1.0 ; bin_extent = hibin - midbin ; for( i = midbin, j = 0; i < hibin; i++, j++ ){ deviation = diff * ((float)(bin_extent - j) / (float) bin_extent ); warpfunc[ i ] += deviation ; } bin_extent = midbin - lobin ; for( i = midbin, j = 0; i > lobin; i--, j++ ){ deviation = diff * ((float)(bin_extent - j) / (float) bin_extent ); warpfunc[ i ] += deviation ; } // NOW DO SECOND BUMP hif = cf2 * (1. + bw2); lof = cf2 * (1. - bw2); midbin = freq_to_bin( cf2, c_fundamental ); hibin = freq_to_bin( hif, c_fundamental ); lobin = freq_to_bin( lof, c_fundamental ); if( hibin >= N2 - 1 ){ hibin = N2 - 1; } if( lobin < 0 ){ lobin = 0; } if( verbose ) post("bump2: hi %d mid %d lo %d",hibin,midbin,lobin); warpfunc[midbin] = warpfac2; diff = warpfac2 - 1.0 ; bin_extent = hibin - midbin ; for( i = midbin, j = 0; i < hibin; i++, j++ ){ deviation = diff * ((float)(bin_extent - j) / (float) bin_extent ); warpfunc[ i ] += deviation ; } bin_extent = midbin - lobin ; for( i = midbin, j = 0; i > lobin; i--, j++ ){ deviation = diff * ((float)(bin_extent - j) / (float) bin_extent ); warpfunc[ i ] += deviation ; } x->please_update = 0; // return( x ); } void pvwarp_verbose(t_pvwarp *x, t_floatarg state) { x->verbose = state; } void pvwarp_autofunc(t_pvwarp *x, t_floatarg minval, t_floatarg maxval) { int minpoints, maxpoints, segpoints, i; int pointcount = 0; float target, lastval; float m1, m2; int N2 = x->N2; float *warpfunc = x->warpfunc; ///// minpoints = 0.05 * (float) N2; maxpoints = 0.25 * (float) N2; if( minval > 1000.0 || minval < .001 ){ minval = 0.5; } if( maxval < 0.01 || maxval > 1000.0 ){ minval = 2.0; } lastval = myrand(minval, maxval); // post("automate: min %d max %d",minpoints, maxpoints); while( pointcount < N2 ){ target = myrand(minval, maxval); segpoints = minpoints + (rand() % (maxpoints-minpoints)); if( pointcount + segpoints > N2 ){ segpoints = N2 - pointcount; } for( i = 0; i < segpoints; i++ ){ m2 = (float)i / (float) segpoints ; m1 = 1.0 - m2; warpfunc[ pointcount + i ] = m1 * lastval + m2 * target; } lastval = target; pointcount += segpoints; } } void pvwarp_bypass(t_pvwarp *x, t_floatarg state) { x->bypass = state; } void pvwarp_mute(t_pvwarp *x, t_floatarg state) { x->mute = state; } void pvwarp_dsp_free( t_pvwarp *x ){ #if MSP dsp_free( (t_pxobject *) x); #endif free(x->c_lastphase_in); free(x->c_lastphase_out); free(x->trigland); free(x->bitshuffle); free(x->Wanal); free(x->Wsyn); free(x->input); free(x->Hwin); free(x->buffer); free(x->channel); free(x->output); free(x->lastamp); free(x->lastfreq); free(x->windex); free(x->table); free(x->warpfunc); free(x->connections); } void pvwarp_assist (t_pvwarp *x, void *b, long msg, long arg, char *dst) { if (msg==1) { switch (arg) { case 0: sprintf(dst,"(signal) Input "); break; case 1: sprintf(dst,"(signal/float) Center Frequency 1"); break; case 2: sprintf(dst,"(signal/float) Bandwidth Factor 1"); break; case 3: sprintf(dst,"(signal/float) Warp Factor 1"); break; case 4: sprintf(dst,"(signal/float) Center Frequency 2"); break; case 5: sprintf(dst,"(signal/float) Bandwidth Factor 2"); break; case 6: sprintf(dst,"(signal/float) Warp Factor 2"); break; case 7: sprintf(dst,"(signal/float) Function Offset (0.0-1.0) "); break; case 8: sprintf(dst,"(signal/float) Pitch Factor"); break; case 9: sprintf(dst,"(signal/float) Synthesis Gate Value"); break; } } else if (msg==2) { sprintf(dst,"(signal) Output"); } } void *pvwarp_new(t_symbol *s, int argc, t_atom *argv) { #if MSP t_pvwarp *x = (t_pvwarp *)newobject(pvwarp_class); dsp_setup((t_pxobject *)x,10); outlet_new((t_pxobject *)x, "signal"); #endif #if PD int i; t_pvwarp *x = (t_pvwarp *)pd_new(pvwarp_class); for(i=0;i<9;i++) inlet_new(&x->x_obj, &x->x_obj.ob_pd,gensym("signal"), gensym("signal")); outlet_new(&x->x_obj, gensym("signal")); #endif x->lofreq = atom_getfloatarg(0,argc,argv); x->hifreq = atom_getfloatarg(1,argc,argv); x->overlap = atom_getfloatarg(2,argc,argv); x->winfac = atom_getfloatarg(3,argc,argv); if(!x->overlap) x->overlap = 4; if(!x->winfac) x->winfac = 2; x->D = sys_getblksize(); x->R = sys_getsr(); pvwarp_init(x,0); return (x); } void pvwarp_init(t_pvwarp *x, short initialized) { int i, j; float funda, curfreq; x->N = x->D * x->overlap; x->Nw = x->N * x->winfac; limit_fftsize(&x->N,&x->Nw,OBJECT_NAME); x->N2 = (x->N)>>1; x->Nw2 = (x->Nw)>>1; x->c_fundamental = (float) x->R/(float)( (x->N2)<<1 ); x->c_factor_in = (float) x->R/((float)x->D * TWOPI); x->c_factor_out = TWOPI * (float) x->D / (float) x->R; x->inCount = -(x->Nw); x->mult = 1. / (float) x->N; x->Iinv = 1./x->D; x->myPInc = x->P*x->L/x->R;// really needed x->ffac = x->P * PI/x->N; if(!initialized){ srand(clock()); x->L = 8192; x->P = 1.0 ; //initialization only x->please_update = 0; x->verbose = 0; x->bypass = 0; x->mute = 0; x->topfreq = 3000. ; x->always_update = 0; x->automate = 0; x->warpfac1 = 1.0; x->warpfac2 = 1.0; x->funcoff = 0; x->cf1 = 500.; x->cf2 = 3000.; x->bw1 = 0.2; x->bw2 = 0.2; x->synt = .000001; x->connections = (short *) calloc(16, sizeof(short)); x->Wanal = (float *) calloc(MAX_Nw, sizeof(float)); x->Wsyn = (float *) calloc(MAX_Nw, sizeof(float)); x->input = (float *) calloc(MAX_Nw, sizeof(float)); x->Hwin = (float *) calloc(MAX_Nw, sizeof(float)); x->buffer = (float *) calloc(MAX_N, sizeof(float)); x->channel = (float *) calloc(MAX_N+2, sizeof(float)); x->output = (float *) calloc(MAX_Nw, sizeof(float)); x->bitshuffle = (int *) calloc(MAX_N * 2, sizeof(int)); x->trigland = (float *) calloc(MAX_N * 2, sizeof(float)); x->warpfunc = (float *) calloc(MAX_N2, sizeof(float)); x->lastamp = (float *) calloc(MAX_N+1, sizeof(float)); x->lastfreq = (float *) calloc(MAX_N+1, sizeof(float)); x->windex = (float *) calloc(MAX_N+1, sizeof(float)); x->table = (float *) calloc(x->L, sizeof(float)); x->c_lastphase_in = (float *) calloc(MAX_N2+1, sizeof(float)); x->c_lastphase_out = (float *) calloc(MAX_N2+1, sizeof(float)); } for (i = 0; i < x->L; i++) { x->table[i] = (float) x->N * cos((float)i * TWOPI / (float)x->L); } memset((char *)x->input,0,x->Nw * sizeof(float)); memset((char *)x->output,0,x->Nw * sizeof(float)); memset((char *)x->buffer,0,x->N * sizeof(float)); memset((char *)x->channel,0,(x->N+2) * sizeof(float)); memset((char *)x->lastfreq,0,(x->N+1) * sizeof(float)); memset((char *)x->lastamp,0,(x->N+1) * sizeof(float)); // added memset((char *)x->c_lastphase_in,0,(x->N2+1) * sizeof(float)); memset((char *)x->c_lastphase_out,0,(x->N2+1) * sizeof(float)); memset((char *)x->windex,0,(x->N+1) * sizeof(float)); if( x->hifreq < x->c_fundamental ) { x->hifreq = 1000.0;// arbitrary } x->hi_bin = 1; curfreq = 0; while( curfreq < x->hifreq ) { ++(x->hi_bin); curfreq += x->c_fundamental ; } if( x->hi_bin >= x->N2 ) x->hi_bin = x->N2 - 1; x->lo_bin = 0; curfreq = 0; while( curfreq < x->lofreq ) { ++(x->lo_bin); curfreq += x->c_fundamental ; } update_warp_function(x); init_rdft(x->N, x->bitshuffle, x->trigland); makehanning(x->Hwin, x->Wanal, x->Wsyn, x->Nw, x->N, x->D, 0); // post("FFT size: %d",x->N); } void pvwarp_bottomfreq(t_pvwarp *x, t_floatarg f) { int tbin; float curfreq; float fundamental = x->c_fundamental; tbin = 1; curfreq = 0; if( f < 0 || f > x->R / 2.0 ){ error("frequency %f out of range", f); return; } while( curfreq < f ) { ++tbin; curfreq += fundamental ; } if( tbin < x->hi_bin && tbin >= 0 ){ x->lo_bin = tbin; x->lofreq = f; } else { error("bin %d out of range", tbin); } } void pvwarp_topfreq(t_pvwarp *x, t_floatarg f) { int tbin; float curfreq; float fundamental = x->c_fundamental; tbin = 1; curfreq = 0; if( f < 0 || f > x->R / 2.0 ){ error("frequency %f out of range", f); return; } while( curfreq < f ) { ++tbin; curfreq += fundamental ; } if( tbin > x->lo_bin && tbin < x->N2 - 1 ){ x->hi_bin = tbin; x->hifreq = f; } else { error("bin %d out of range", tbin); } } t_int *pvwarp_perform(t_int *w) { int i,j, in,on; int amp,freq,chan,NP,L = 8192; float a,ainc,f,finc,address; int breaker = 0; t_pvwarp *x = (t_pvwarp *) (w[1]); t_float *inbuf = (t_float *)(w[2]); t_float *in1 = (t_float *)(w[3]); t_float *in2 = (t_float *)(w[4]); t_float *in3 = (t_float *)(w[5]); t_float *in4 = (t_float *)(w[6]); t_float *in5 = (t_float *)(w[7]); t_float *in6 = (t_float *)(w[8]); t_float *in7 = (t_float *)(w[9]); t_float *in8 = (t_float *)(w[10]); t_float *in9 = (t_float *)(w[11]); t_float *outbuf = (t_float *)(w[12]); t_int n = w[13]; int D = x->D; int I = D; int R = x->R; int Nw = x->Nw; int N = x->N ; int N2 = x-> N2; int Nw2 = x->Nw2; float fundamental = x->c_fundamental; float factor_in = x->c_factor_in; float factor_out = x->c_factor_out; int *bitshuffle = x->bitshuffle; float *trigland = x->trigland; float mult = x->mult; float warpfac1 = x->warpfac1; float warpfac2 = x->warpfac2; int funcoff; float P; float synt; float Iinv = 1./x->D; float myPInc = x->myPInc; /* assign pointers */ float *table = x->table; float *lastamp = x->lastamp ; float *lastfreq = x->lastfreq ; float *windex = x->windex; float *lastphase_in = x->c_lastphase_in; float *lastphase_out = x->c_lastphase_out; float *Wanal = x->Wanal; float *Wsyn = x->Wsyn; float *input = x->input; float *Hwin = x->Hwin; float *buffer = x->buffer; float *channel = x->channel; float *output = x->output; short *connections = x->connections; float *warpfunc; int hi_bin = x->hi_bin; int lo_bin = x->lo_bin; if(!x->automate) { if( connections[0] ) { x->cf1 = *in1 ; } if ( connections[1] ) { x->bw1 = *in2 ; } if ( connections[2] ) { x->warpfac1 = *in3 ; } if( connections[3] ) { x->cf2 = *in4 ; } if ( connections[4] ) { x->bw2 = *in5 ; } if ( connections[5] ) { x->warpfac2 = *in6 ; } } if( connections[6] ) { f = *in7 ; if( f < 0 ) { f = 0.0; } else if (f > 1.0 ){ f = 1.0; } x->funcoff = f * (float) (N2 - 1); } if ( connections[7] ) { x->P = *in8 ; x->myPInc = x->P*x->L/x->R; } if ( connections[8] ) { x->synt = *in9 ; } P= x->P; synt = x->synt; funcoff = x->funcoff; if( (x->please_update || x->always_update) && ! x->automate){ update_warp_function(x); } warpfunc = x->warpfunc; in = on = x->inCount ; if( x->mute) { for ( j = 0; j < n; j++ ){ outbuf[j] = 0.; } return (w+14); } else if( x->bypass ) { for ( j = 0; j < n; j++ ){ outbuf[j] = *inbuf++; } return (w+14); } else { in = on = x->inCount ; in += D; on += I; for ( j = 0 ; j < (Nw - D) ; j++ ){ input[j] = input[j+D]; } for ( j = (Nw-D), i = 0 ; j < Nw; j++, i++ ) { input[j] = *inbuf++; } fold( input, Wanal, Nw, buffer, N, in ); rdft( N, 1, buffer, bitshuffle, trigland ); convert( buffer, channel, N2, lastphase_in, fundamental, factor_in ); // start osc bank for ( chan = lo_bin; chan < hi_bin; chan++ ) { freq = ( amp = ( chan << 1 ) ) + 1; if ( channel[amp] < synt ){ breaker = 1; } if( breaker ) { breaker = 0 ; } else { /* HERE IS WHERE WE WARP THE SPECTRUM */ channel[freq] *= myPInc * warpfunc[(chan + funcoff) % N2]; finc = ( channel[freq] - ( f = lastfreq[chan] ) )*Iinv; ainc = ( channel[amp] - ( a = lastamp[chan] ) )*Iinv; address = windex[chan]; for ( n = 0; n < I; n++ ) { output[n] += a*table[ (int) address ]; address += f; while ( address >= L ) address -= L; while ( address < 0 ) address += L; a += ainc; f += finc; } lastfreq[chan] = channel[freq]; lastamp[chan] = channel[amp]; windex[chan] = address; } } for ( j = 0; j < D; j++ ){ *outbuf++ = output[j] * mult; } for ( j = 0; j < Nw - D; j++ ){ output[j] = output[j+D]; } for ( j = Nw - D; j < Nw; j++ ){ output[j] = 0.; } /* restore state variables */ x->inCount = in % Nw; return (w+14); } } int freq_to_bin( float target, float fundamental ){ float lastf = 0.0; float testf = 0.0; int thebin = 0; while( testf < target ){ ++thebin; lastf = testf; testf += fundamental; } if(fabs(target - testf) < fabs(target - lastf) ){ return thebin; } else { return (thebin - 1); } } #if MSP void pvwarp_float(t_pvwarp *x, t_float f) // Look at floats at inlets { int inlet = ((t_pxobject*)x)->z_in; int N2 = x->N2; if (inlet == 1){ x->cf1 = f; x->please_update = 1; } else if (inlet == 2) { x->bw1 = f; x->please_update = 1; } else if (inlet == 3) { x->warpfac1 = f; x->please_update = 1; } else if (inlet == 4) { x->cf2 = f; x->please_update = 1; } else if (inlet == 5) { x->bw2 = f; x->please_update = 1; } else if (inlet == 6) { x->warpfac2 = f; x->please_update = 1; } else if (inlet == 7) { if( f < 0 ) { f = 0.0; } else if (f > 1.0 ){ f = 1.0; } x->funcoff = f * (float) (x->N2 - 1); } else if (inlet == 8) { x->P = f; x->myPInc = x->P*x->L/x->R; } else if (inlet == 9) { x->synt = f; } } #endif void pvwarp_dsp(t_pvwarp *x, t_signal **sp, short *count) { long i; x->always_update = 0; #if MSP for( i = 1; i < 10; i++ ){ // only the first 6 inlets alter warp function if( i < 6 ){ x->always_update += count[i]; } x->connections[i-1] = count[i]; // post("connection %d: %d", i-1, count[i]); } #endif #if PD x->always_update = 1; for(i=0;i<10;i++){ x->connections[i] = 1; } #endif if(x->D != sp[0]->s_n || x->R != sp[0]->s_sr){ x->D = sp[0]->s_n; x->R = sp[0]->s_sr; pvwarp_init(x,1); } dsp_add(pvwarp_perform, 13, x, 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, sp[7]->s_vec, sp[8]->s_vec, sp[9]->s_vec, sp[10]->s_vec, sp[0]->s_n); } \ No newline at end of file
+#include "MSPd.h"
+#include "fftease.h"
+
+#if MSP
+void *pvwarp_class;
+#endif
+
+#if PD
+static t_class *pvwarp_class;
+#endif
+
+#define OBJECT_NAME "pvwarp~"
+
+typedef struct _pvwarp
+{
+#if MSP
+ t_pxobject x_obj;
+#endif
+#if PD
+ t_object x_obj;
+ float x_f;
+#endif
+ int R;
+ int N;
+ int N2;
+ int Nw;
+ int Nw2;
+ int D;
+ int i;
+ int inCount;
+ float *Wanal;
+ float *Wsyn;
+ float *input;
+ float *Hwin;
+ float *buffer;
+ float *channel;
+ float *output;
+ // for convert
+ float *c_lastphase_in;
+ float *c_lastphase_out;
+ float c_fundamental;
+ float c_factor_in;
+ float c_factor_out;
+ float P;
+ int L;
+ int first;
+ float Iinv;
+ float *lastamp;
+ float *lastfreq;
+ float *windex;
+ float *table;
+ float myPInc;
+ float ffac;
+ //
+ int lo_bin;
+ int hi_bin;
+ float lofreq;//user speficied lowest synthfreq
+ float hifreq;// user specified highest synthfreq
+ float topfreq;
+ float synt;
+ float myPI;
+ float TWOmyPI;
+ // for fast fft
+ float mult;
+ float *trigland;
+ int *bitshuffle;
+ //
+ short *connections;
+ short mute;
+ short bypass;
+ int pitch_connected;
+ int synt_connected;
+ float *warpfunc ;
+ short please_update;
+ short always_update;
+ float cf1;
+ float bw1;
+ float warpfac1;
+ float cf2;
+ float bw2;
+ float warpfac2;
+ int funcoff;
+ short verbose;
+ short automate;
+ int overlap;//overlap factor
+ int winfac;// window factor
+ int vs;//last measurement of vector size
+} t_pvwarp;
+
+void *pvwarp_new(t_symbol *s, int argc, t_atom *argv);
+//t_int *offset_perform(t_int *w);
+t_int *pvwarp_perform(t_int *w);
+void pvwarp_dsp(t_pvwarp *x, t_signal **sp, short *count);
+void pvwarp_assist(t_pvwarp *x, void *b, long m, long a, char *s);
+void pvwarp_bypass(t_pvwarp *x, t_floatarg state);
+void pvwarp_mute(t_pvwarp *x, t_floatarg state);
+void pvwarp_verbose(t_pvwarp *x, t_floatarg state);
+void pvwarp_overlap(t_pvwarp *x, t_floatarg o);
+void pvwarp_automate(t_pvwarp *x, t_floatarg state);
+void pvwarp_autofunc(t_pvwarp *x, t_floatarg minval, t_floatarg maxval);
+void pvwarp_float(t_pvwarp *x, t_float f);
+void pvwarp_dsp_free( t_pvwarp *x );
+void pvwarp_fftinfo( t_pvwarp *x );
+float myrand( float min, float max );
+float closestf(float test, float *arr) ;
+int freq_to_bin( float target, float fundamental );
+void update_warp_function( t_pvwarp *x ) ;
+void pvwarp_init(t_pvwarp *x, short initialized);
+void pvwarp_bottomfreq(t_pvwarp *x, t_floatarg f);
+void pvwarp_topfreq(t_pvwarp *x, t_floatarg f);
+void pvwarp_fftinfo(t_pvwarp *x);
+void pvwarp_overlap(t_pvwarp *x, t_floatarg f);
+void pvwarp_winfac(t_pvwarp *x, t_floatarg f);;
+
+#if MSP
+void main(void)
+{
+ setup((t_messlist **)&pvwarp_class, (method)pvwarp_new, (method)pvwarp_dsp_free, (short)sizeof(t_pvwarp),
+ 0, A_GIMME, 0);
+ addmess((method)pvwarp_dsp, "dsp", A_CANT, 0);
+ addmess((method)pvwarp_assist,"assist",A_CANT,0);
+ addmess((method)pvwarp_bypass,"bypass",A_DEFFLOAT,0);
+ addmess((method)pvwarp_mute,"mute",A_DEFFLOAT,0);
+ addmess((method)pvwarp_verbose,"verbose",A_DEFFLOAT,0);
+ addmess((method)pvwarp_overlap,"overlap",A_FLOAT,0);
+ addmess((method)pvwarp_bottomfreq,"bottomfreq",A_FLOAT,0);
+ addmess((method)pvwarp_topfreq,"topfreq",A_FLOAT,0);
+ addmess((method)pvwarp_fftinfo,"fftinfo",0);
+ addmess((method)pvwarp_autofunc,"autofunc",A_DEFFLOAT, A_DEFFLOAT,0);
+ addmess((method)pvwarp_overlap,"overlap",A_DEFFLOAT,0);
+ addmess((method)pvwarp_winfac,"winfac",A_DEFFLOAT,0);
+ addmess((method)pvwarp_fftinfo,"fftinfo",0);
+ addfloat((method)pvwarp_float);
+ dsp_initclass();
+ post("%s %s",OBJECT_NAME,FFTEASE_ANNOUNCEMENT);
+}
+#endif
+
+#if PD
+/* Pd Initialization */
+void pvwarp_tilde_setup(void)
+{
+ pvwarp_class = class_new(gensym("pvwarp~"), (t_newmethod)pvwarp_new,
+ (t_method)pvwarp_dsp_free ,sizeof(t_pvwarp), 0,A_GIMME,0);
+ CLASS_MAINSIGNALIN(pvwarp_class, t_pvwarp, x_f);
+ class_addmethod(pvwarp_class, (t_method)pvwarp_dsp, gensym("dsp"), 0);
+ class_addmethod(pvwarp_class, (t_method)pvwarp_mute, gensym("mute"), A_DEFFLOAT,0);
+ class_addmethod(pvwarp_class, (t_method)pvwarp_bypass, gensym("bypass"), A_DEFFLOAT,0);
+ class_addmethod(pvwarp_class, (t_method)pvwarp_overlap, gensym("overlap"), A_DEFFLOAT,0);
+ class_addmethod(pvwarp_class, (t_method)pvwarp_bottomfreq, gensym("bottomfreq"), A_DEFFLOAT,0);
+ class_addmethod(pvwarp_class, (t_method)pvwarp_topfreq, gensym("topfreq"), A_DEFFLOAT, 0);
+ class_addmethod(pvwarp_class, (t_method)pvwarp_automate, gensym("automate"), A_DEFFLOAT, 0);
+ class_addmethod(pvwarp_class, (t_method)pvwarp_autofunc, gensym("autofunc"), A_DEFFLOAT,A_DEFFLOAT,0);
+ class_addmethod(pvwarp_class,(t_method)pvwarp_overlap,gensym("overlap"),A_FLOAT,0);
+ class_addmethod(pvwarp_class,(t_method)pvwarp_winfac,gensym("winfac"),A_FLOAT,0);
+ class_addmethod(pvwarp_class,(t_method)pvwarp_fftinfo,gensym("fftinfo"),0);
+ // addfloat((method)pvwarp_float);
+ post("%s %s",OBJECT_NAME,FFTEASE_ANNOUNCEMENT);
+}
+#endif
+
+void pvwarp_automate(t_pvwarp *x, t_floatarg state)
+{
+ x->automate = state;
+}
+void pvwarp_overlap(t_pvwarp *x, t_floatarg f)
+{
+ int i = (int) f;
+ if(!fftease_power_of_two(i)){
+ error("%f is not a power of two",f);
+ return;
+ }
+ x->overlap = i;
+ pvwarp_init(x,1);
+}
+
+void pvwarp_winfac(t_pvwarp *x, t_floatarg f)
+{
+ int i = (int)f;
+
+ if(!fftease_power_of_two(i)){
+ error("%f is not a power of two",f);
+ return;
+ }
+ x->winfac = i;
+ pvwarp_init(x,2);
+}
+
+void pvwarp_fftinfo(t_pvwarp *x)
+{
+ if( ! x->overlap ){
+ post("zero overlap!");
+ return;
+ }
+ post("%s: FFT size %d, hopsize %d, windowsize %d", OBJECT_NAME, x->N, x->N/x->overlap, x->Nw);
+}
+
+float myrand ( float min, float max )
+{
+ return (min + (max-min) * ((float) (rand() % 32768) / (float) 32768.0));
+}
+void update_warp_function( t_pvwarp *x )
+{
+ int i,j;
+ int N2 = x->N2;
+ float *warpfunc = x->warpfunc;
+ float warpfac1 = x->warpfac1;
+ float warpfac2 = x->warpfac2;
+
+ float cf1 = x->cf1;
+ float cf2 = x->cf2;
+ float bw1 = x->bw1;
+ float bw2 = x->bw2;
+ float c_fundamental = x->c_fundamental;
+ float deviation;
+ float diff;
+ int midbin, lobin, hibin ;
+ float hif, lof;
+ int bin_extent;
+ short verbose = x->verbose;
+
+ for( i = 0; i < N2; i++ ){
+ warpfunc[i] = 1.0;
+ }
+ hif = cf1 * (1. + bw1);
+ lof = cf1 * (1. - bw1);
+ midbin = freq_to_bin( cf1, c_fundamental );
+ hibin = freq_to_bin( hif, c_fundamental );
+ lobin = freq_to_bin( lof, c_fundamental );
+ if( hibin >= N2 - 1 ){
+ hibin = N2 - 1;
+ }
+ if( lobin < 0 ){
+ lobin = 0;
+ }
+ if( verbose )
+ post("bump1: hi %d mid %d lo %d",hibin,midbin,lobin);
+
+ warpfunc[midbin] = warpfac1;
+ diff = warpfac1 - 1.0 ;
+ bin_extent = hibin - midbin ;
+ for( i = midbin, j = 0; i < hibin; i++, j++ ){
+ deviation = diff * ((float)(bin_extent - j) / (float) bin_extent );
+ warpfunc[ i ] += deviation ;
+ }
+ bin_extent = midbin - lobin ;
+ for( i = midbin, j = 0; i > lobin; i--, j++ ){
+ deviation = diff * ((float)(bin_extent - j) / (float) bin_extent );
+ warpfunc[ i ] += deviation ;
+ }
+
+ // NOW DO SECOND BUMP
+ hif = cf2 * (1. + bw2);
+ lof = cf2 * (1. - bw2);
+ midbin = freq_to_bin( cf2, c_fundamental );
+ hibin = freq_to_bin( hif, c_fundamental );
+ lobin = freq_to_bin( lof, c_fundamental );
+ if( hibin >= N2 - 1 ){
+ hibin = N2 - 1;
+ }
+ if( lobin < 0 ){
+ lobin = 0;
+ }
+ if( verbose )
+ post("bump2: hi %d mid %d lo %d",hibin,midbin,lobin);
+ warpfunc[midbin] = warpfac2;
+ diff = warpfac2 - 1.0 ;
+ bin_extent = hibin - midbin ;
+ for( i = midbin, j = 0; i < hibin; i++, j++ ){
+ deviation = diff * ((float)(bin_extent - j) / (float) bin_extent );
+ warpfunc[ i ] += deviation ;
+ }
+ bin_extent = midbin - lobin ;
+ for( i = midbin, j = 0; i > lobin; i--, j++ ){
+ deviation = diff * ((float)(bin_extent - j) / (float) bin_extent );
+ warpfunc[ i ] += deviation ;
+ }
+
+ x->please_update = 0;
+ // return( x );
+
+}
+void pvwarp_verbose(t_pvwarp *x, t_floatarg state)
+{
+ x->verbose = state;
+}
+
+void pvwarp_autofunc(t_pvwarp *x, t_floatarg minval, t_floatarg maxval)
+{
+ int minpoints, maxpoints, segpoints, i;
+ int pointcount = 0;
+ float target, lastval;
+ float m1, m2;
+ int N2 = x->N2;
+ float *warpfunc = x->warpfunc;
+ /////
+
+ minpoints = 0.05 * (float) N2;
+ maxpoints = 0.25 * (float) N2;
+ if( minval > 1000.0 || minval < .001 ){
+ minval = 0.5;
+ }
+ if( maxval < 0.01 || maxval > 1000.0 ){
+ minval = 2.0;
+ }
+
+ lastval = myrand(minval, maxval);
+ // post("automate: min %d max %d",minpoints, maxpoints);
+ while( pointcount < N2 ){
+ target = myrand(minval, maxval);
+ segpoints = minpoints + (rand() % (maxpoints-minpoints));
+ if( pointcount + segpoints > N2 ){
+ segpoints = N2 - pointcount;
+ }
+ for( i = 0; i < segpoints; i++ ){
+ m2 = (float)i / (float) segpoints ;
+ m1 = 1.0 - m2;
+ warpfunc[ pointcount + i ] = m1 * lastval + m2 * target;
+ }
+ lastval = target;
+ pointcount += segpoints;
+ }
+}
+
+void pvwarp_bypass(t_pvwarp *x, t_floatarg state)
+{
+ x->bypass = state;
+}
+void pvwarp_mute(t_pvwarp *x, t_floatarg state)
+{
+ x->mute = state;
+}
+
+void pvwarp_dsp_free( t_pvwarp *x ){
+#if MSP
+ dsp_free( (t_pxobject *) x);
+#endif
+ free(x->c_lastphase_in);
+ free(x->c_lastphase_out);
+ free(x->trigland);
+ free(x->bitshuffle);
+ free(x->Wanal);
+ free(x->Wsyn);
+ free(x->input);
+ free(x->Hwin);
+ free(x->buffer);
+ free(x->channel);
+ free(x->output);
+ free(x->lastamp);
+ free(x->lastfreq);
+ free(x->windex);
+ free(x->table);
+ free(x->warpfunc);
+ free(x->connections);
+}
+
+void pvwarp_assist (t_pvwarp *x, void *b, long msg, long arg, char *dst)
+{
+ if (msg==1) {
+ switch (arg) {
+ case 0:
+ sprintf(dst,"(signal) Input ");
+ break;
+ case 1:
+ sprintf(dst,"(signal/float) Center Frequency 1");
+ break;
+ case 2:
+ sprintf(dst,"(signal/float) Bandwidth Factor 1");
+ break;
+ case 3:
+ sprintf(dst,"(signal/float) Warp Factor 1");
+ break;
+ case 4:
+ sprintf(dst,"(signal/float) Center Frequency 2");
+ break;
+ case 5:
+ sprintf(dst,"(signal/float) Bandwidth Factor 2");
+ break;
+ case 6:
+ sprintf(dst,"(signal/float) Warp Factor 2");
+ break;
+ case 7:
+ sprintf(dst,"(signal/float) Function Offset (0.0-1.0) ");
+ break;
+ case 8:
+ sprintf(dst,"(signal/float) Pitch Factor");
+ break;
+ case 9:
+ sprintf(dst,"(signal/float) Synthesis Gate Value");
+ break;
+
+ }
+ } else if (msg==2) {
+ sprintf(dst,"(signal) Output");
+ }
+}
+
+void *pvwarp_new(t_symbol *s, int argc, t_atom *argv)
+{
+#if MSP
+ t_pvwarp *x = (t_pvwarp *)newobject(pvwarp_class);
+ dsp_setup((t_pxobject *)x,10);
+ outlet_new((t_pxobject *)x, "signal");
+#endif
+#if PD
+ int i;
+ t_pvwarp *x = (t_pvwarp *)pd_new(pvwarp_class);
+ for(i=0;i<9;i++)
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd,gensym("signal"), gensym("signal"));
+ outlet_new(&x->x_obj, gensym("signal"));
+#endif
+
+ x->lofreq = atom_getfloatarg(0,argc,argv);
+ x->hifreq = atom_getfloatarg(1,argc,argv);
+ x->overlap = atom_getfloatarg(2,argc,argv);
+ x->winfac = atom_getfloatarg(3,argc,argv);
+ if(!x->overlap)
+ x->overlap = 4;
+ if(!x->winfac)
+ x->winfac = 2;
+ x->D = sys_getblksize();
+ x->R = sys_getsr();
+ pvwarp_init(x,0);
+
+ return (x);
+}
+
+void pvwarp_init(t_pvwarp *x, short initialized)
+{
+ int i, j;
+ float funda, curfreq;
+ x->N = x->D * x->overlap;
+ x->Nw = x->N * x->winfac;
+ limit_fftsize(&x->N,&x->Nw,OBJECT_NAME);
+ x->N2 = (x->N)>>1;
+ x->Nw2 = (x->Nw)>>1;
+ x->c_fundamental = (float) x->R/(float)( (x->N2)<<1 );
+ x->c_factor_in = (float) x->R/((float)x->D * TWOPI);
+ x->c_factor_out = TWOPI * (float) x->D / (float) x->R;
+ x->inCount = -(x->Nw);
+ x->mult = 1. / (float) x->N;
+ x->Iinv = 1./x->D;
+ x->myPInc = x->P*x->L/x->R;// really needed
+ x->ffac = x->P * PI/x->N;
+
+ if(!initialized){
+ srand(clock());
+ x->L = 8192;
+ x->P = 1.0 ; //initialization only
+
+ x->please_update = 0;
+ x->verbose = 0;
+ x->bypass = 0;
+ x->mute = 0;
+ x->topfreq = 3000. ;
+ x->always_update = 0;
+ x->automate = 0;
+ x->warpfac1 = 1.0;
+ x->warpfac2 = 1.0;
+ x->funcoff = 0;
+ x->cf1 = 500.;
+ x->cf2 = 3000.;
+ x->bw1 = 0.2;
+ x->bw2 = 0.2;
+ x->synt = .000001;
+
+ x->connections = (short *) calloc(16, sizeof(short));
+ x->Wanal = (float *) calloc(MAX_Nw, sizeof(float));
+ x->Wsyn = (float *) calloc(MAX_Nw, sizeof(float));
+ x->input = (float *) calloc(MAX_Nw, sizeof(float));
+ x->Hwin = (float *) calloc(MAX_Nw, sizeof(float));
+ x->buffer = (float *) calloc(MAX_N, sizeof(float));
+ x->channel = (float *) calloc(MAX_N+2, sizeof(float));
+ x->output = (float *) calloc(MAX_Nw, sizeof(float));
+ x->bitshuffle = (int *) calloc(MAX_N * 2, sizeof(int));
+ x->trigland = (float *) calloc(MAX_N * 2, sizeof(float));
+ x->warpfunc = (float *) calloc(MAX_N2, sizeof(float));
+ x->lastamp = (float *) calloc(MAX_N+1, sizeof(float));
+ x->lastfreq = (float *) calloc(MAX_N+1, sizeof(float));
+ x->windex = (float *) calloc(MAX_N+1, sizeof(float));
+ x->table = (float *) calloc(x->L, sizeof(float));
+ x->c_lastphase_in = (float *) calloc(MAX_N2+1, sizeof(float));
+ x->c_lastphase_out = (float *) calloc(MAX_N2+1, sizeof(float));
+
+ }
+ for (i = 0; i < x->L; i++) {
+ x->table[i] = (float) x->N * cos((float)i * TWOPI / (float)x->L);
+ }
+
+ memset((char *)x->input,0,x->Nw * sizeof(float));
+ memset((char *)x->output,0,x->Nw * sizeof(float));
+ memset((char *)x->buffer,0,x->N * sizeof(float));
+ memset((char *)x->channel,0,(x->N+2) * sizeof(float));
+ memset((char *)x->lastfreq,0,(x->N+1) * sizeof(float));
+ memset((char *)x->lastamp,0,(x->N+1) * sizeof(float));
+ // added
+ memset((char *)x->c_lastphase_in,0,(x->N2+1) * sizeof(float));
+ memset((char *)x->c_lastphase_out,0,(x->N2+1) * sizeof(float));
+ memset((char *)x->windex,0,(x->N+1) * sizeof(float));
+
+ if( x->hifreq < x->c_fundamental ) {
+ x->hifreq = 1000.0;// arbitrary
+ }
+ x->hi_bin = 1;
+ curfreq = 0;
+ while( curfreq < x->hifreq ) {
+ ++(x->hi_bin);
+ curfreq += x->c_fundamental ;
+ }
+ if( x->hi_bin >= x->N2 )
+ x->hi_bin = x->N2 - 1;
+ x->lo_bin = 0;
+ curfreq = 0;
+ while( curfreq < x->lofreq ) {
+ ++(x->lo_bin);
+ curfreq += x->c_fundamental ;
+ }
+ update_warp_function(x);
+ init_rdft(x->N, x->bitshuffle, x->trigland);
+ makehanning(x->Hwin, x->Wanal, x->Wsyn, x->Nw, x->N, x->D, 0);
+ // post("FFT size: %d",x->N);
+}
+
+
+
+void pvwarp_bottomfreq(t_pvwarp *x, t_floatarg f)
+{
+ int tbin;
+ float curfreq;
+ float fundamental = x->c_fundamental;
+ tbin = 1;
+ curfreq = 0;
+
+ if( f < 0 || f > x->R / 2.0 ){
+ error("frequency %f out of range", f);
+ return;
+ }
+
+ while( curfreq < f ) {
+ ++tbin;
+ curfreq += fundamental ;
+ }
+
+ if( tbin < x->hi_bin && tbin >= 0 ){
+ x->lo_bin = tbin;
+ x->lofreq = f;
+ } else {
+ error("bin %d out of range", tbin);
+ }
+
+}
+
+void pvwarp_topfreq(t_pvwarp *x, t_floatarg f)
+{
+ int tbin;
+ float curfreq;
+ float fundamental = x->c_fundamental;
+ tbin = 1;
+ curfreq = 0;
+
+ if( f < 0 || f > x->R / 2.0 ){
+ error("frequency %f out of range", f);
+ return;
+ }
+
+ while( curfreq < f ) {
+ ++tbin;
+ curfreq += fundamental ;
+ }
+
+ if( tbin > x->lo_bin && tbin < x->N2 - 1 ){
+ x->hi_bin = tbin;
+ x->hifreq = f;
+ } else {
+ error("bin %d out of range", tbin);
+ }
+
+}
+
+t_int *pvwarp_perform(t_int *w)
+{
+ int i,j, in,on;
+ int amp,freq,chan,NP,L = 8192;
+
+ float a,ainc,f,finc,address;
+ int breaker = 0;
+ t_pvwarp *x = (t_pvwarp *) (w[1]);
+
+ t_float *inbuf = (t_float *)(w[2]);
+ t_float *in1 = (t_float *)(w[3]);
+ t_float *in2 = (t_float *)(w[4]);
+ t_float *in3 = (t_float *)(w[5]);
+ t_float *in4 = (t_float *)(w[6]);
+ t_float *in5 = (t_float *)(w[7]);
+ t_float *in6 = (t_float *)(w[8]);
+ t_float *in7 = (t_float *)(w[9]);
+ t_float *in8 = (t_float *)(w[10]);
+ t_float *in9 = (t_float *)(w[11]);
+ t_float *outbuf = (t_float *)(w[12]);
+ t_int n = w[13];
+
+ int D = x->D;
+ int I = D;
+ int R = x->R;
+ int Nw = x->Nw;
+ int N = x->N ;
+ int N2 = x-> N2;
+ int Nw2 = x->Nw2;
+ float fundamental = x->c_fundamental;
+ float factor_in = x->c_factor_in;
+ float factor_out = x->c_factor_out;
+ int *bitshuffle = x->bitshuffle;
+ float *trigland = x->trigland;
+ float mult = x->mult;
+ float warpfac1 = x->warpfac1;
+ float warpfac2 = x->warpfac2;
+ int funcoff;
+ float P;
+ float synt;
+
+ float Iinv = 1./x->D;
+ float myPInc = x->myPInc;
+
+ /* assign pointers */
+
+ float *table = x->table;
+ float *lastamp = x->lastamp ;
+ float *lastfreq = x->lastfreq ;
+ float *windex = x->windex;
+ float *lastphase_in = x->c_lastphase_in;
+ float *lastphase_out = x->c_lastphase_out;
+
+ float *Wanal = x->Wanal;
+ float *Wsyn = x->Wsyn;
+ float *input = x->input;
+ float *Hwin = x->Hwin;
+ float *buffer = x->buffer;
+ float *channel = x->channel;
+ float *output = x->output;
+ short *connections = x->connections;
+ float *warpfunc;
+
+ int hi_bin = x->hi_bin;
+ int lo_bin = x->lo_bin;
+
+ if(!x->automate) {
+ if( connections[0] ) {
+ x->cf1 = *in1 ;
+ }
+ if ( connections[1] ) {
+ x->bw1 = *in2 ;
+ }
+ if ( connections[2] ) {
+ x->warpfac1 = *in3 ;
+ }
+ if( connections[3] ) {
+ x->cf2 = *in4 ;
+ }
+ if ( connections[4] ) {
+ x->bw2 = *in5 ;
+ }
+ if ( connections[5] ) {
+ x->warpfac2 = *in6 ;
+ }
+ }
+
+ if( connections[6] ) {
+ f = *in7 ;
+ if( f < 0 ) {
+ f = 0.0;
+ } else if (f > 1.0 ){
+ f = 1.0;
+ }
+ x->funcoff = f * (float) (N2 - 1);
+ }
+ if ( connections[7] ) {
+ x->P = *in8 ;
+ x->myPInc = x->P*x->L/x->R;
+ }
+ if ( connections[8] ) {
+ x->synt = *in9 ;
+ }
+ P= x->P;
+ synt = x->synt;
+ funcoff = x->funcoff;
+
+
+ if( (x->please_update || x->always_update) && ! x->automate){
+ update_warp_function(x);
+ }
+ warpfunc = x->warpfunc;
+
+ in = on = x->inCount ;
+ if( x->mute) {
+ for ( j = 0; j < n; j++ ){
+ outbuf[j] = 0.;
+ }
+ return (w+14);
+ }
+ else if( x->bypass ) {
+ for ( j = 0; j < n; j++ ){
+ outbuf[j] = *inbuf++;
+ }
+ return (w+14);
+ } else {
+
+ in = on = x->inCount ;
+
+
+ in += D;
+ on += I;
+
+ for ( j = 0 ; j < (Nw - D) ; j++ ){
+ input[j] = input[j+D];
+ }
+ for ( j = (Nw-D), i = 0 ; j < Nw; j++, i++ ) {
+ input[j] = *inbuf++;
+ }
+
+ fold( input, Wanal, Nw, buffer, N, in );
+ rdft( N, 1, buffer, bitshuffle, trigland );
+ convert( buffer, channel, N2, lastphase_in, fundamental, factor_in );
+
+
+ // start osc bank
+
+ for ( chan = lo_bin; chan < hi_bin; chan++ ) {
+
+ freq = ( amp = ( chan << 1 ) ) + 1;
+ if ( channel[amp] < synt ){
+ breaker = 1;
+ }
+ if( breaker ) {
+ breaker = 0 ;
+ } else {
+
+ /* HERE IS WHERE WE WARP THE SPECTRUM */
+ channel[freq] *= myPInc * warpfunc[(chan + funcoff) % N2];
+ finc = ( channel[freq] - ( f = lastfreq[chan] ) )*Iinv;
+ ainc = ( channel[amp] - ( a = lastamp[chan] ) )*Iinv;
+ address = windex[chan];
+ for ( n = 0; n < I; n++ ) {
+ output[n] += a*table[ (int) address ];
+
+ address += f;
+ while ( address >= L )
+ address -= L;
+ while ( address < 0 )
+ address += L;
+ a += ainc;
+ f += finc;
+ }
+ lastfreq[chan] = channel[freq];
+ lastamp[chan] = channel[amp];
+ windex[chan] = address;
+ }
+ }
+
+
+ for ( j = 0; j < D; j++ ){
+ *outbuf++ = output[j] * mult;
+ }
+ for ( j = 0; j < Nw - D; j++ ){
+ output[j] = output[j+D];
+ }
+
+ for ( j = Nw - D; j < Nw; j++ ){
+ output[j] = 0.;
+ }
+
+
+
+ /* restore state variables */
+ x->inCount = in % Nw;
+ return (w+14);
+ }
+
+}
+
+
+int freq_to_bin( float target, float fundamental ){
+ float lastf = 0.0;
+ float testf = 0.0;
+ int thebin = 0;
+ while( testf < target ){
+ ++thebin;
+ lastf = testf;
+ testf += fundamental;
+ }
+
+ if(fabs(target - testf) < fabs(target - lastf) ){
+ return thebin;
+ } else {
+ return (thebin - 1);
+ }
+}
+#if MSP
+void pvwarp_float(t_pvwarp *x, t_float f) // Look at floats at inlets
+{
+ int inlet = ((t_pxobject*)x)->z_in;
+ int N2 = x->N2;
+ if (inlet == 1){
+ x->cf1 = f;
+ x->please_update = 1;
+ } else if (inlet == 2) {
+ x->bw1 = f;
+ x->please_update = 1;
+ } else if (inlet == 3) {
+ x->warpfac1 = f;
+ x->please_update = 1;
+ } else if (inlet == 4) {
+ x->cf2 = f;
+ x->please_update = 1;
+
+ } else if (inlet == 5) {
+ x->bw2 = f;
+ x->please_update = 1;
+
+ } else if (inlet == 6) {
+ x->warpfac2 = f;
+ x->please_update = 1;
+ } else if (inlet == 7) {
+ if( f < 0 ) {
+ f = 0.0;
+ } else if (f > 1.0 ){
+ f = 1.0;
+ }
+ x->funcoff = f * (float) (x->N2 - 1);
+ } else if (inlet == 8) {
+ x->P = f;
+ x->myPInc = x->P*x->L/x->R;
+
+ } else if (inlet == 9)
+ {
+ x->synt = f;
+ }
+}
+#endif
+
+void pvwarp_dsp(t_pvwarp *x, t_signal **sp, short *count)
+{
+ long i;
+ x->always_update = 0;
+#if MSP
+ for( i = 1; i < 10; i++ ){
+ // only the first 6 inlets alter warp function
+ if( i < 6 ){
+ x->always_update += count[i];
+ }
+ x->connections[i-1] = count[i];
+ // post("connection %d: %d", i-1, count[i]);
+ }
+#endif
+#if PD
+ x->always_update = 1;
+ for(i=0;i<10;i++){
+ x->connections[i] = 1;
+ }
+#endif
+
+ if(x->D != sp[0]->s_n || x->R != sp[0]->s_sr){
+ x->D = sp[0]->s_n;
+ x->R = sp[0]->s_sr;
+ pvwarp_init(x,1);
+ }
+ dsp_add(pvwarp_perform, 13, x,
+ 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, sp[7]->s_vec,
+ sp[8]->s_vec, sp[9]->s_vec, sp[10]->s_vec,
+ sp[0]->s_n);
+}
+
diff --git a/qsortE.c b/qsortE.c
new file mode 100644
index 0000000..0fa7e50
--- /dev/null
+++ b/qsortE.c
@@ -0,0 +1 @@
+/* Plug-compatible replacement for UNIX qsort. Copyright (C) 1989 Free Software Foundation, Inc. Written by Douglas C. Schmidt (schmidt@ics.uci.edu) This file is part of GNU CC. GNU QSORT 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, or (at your option) any later version. GNU QSORT 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 GNU QSORT; see the file COPYING. If not, write to the Free the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Synched up with: FSF 19.28. */ #ifdef sparc #include <alloca.h> #endif #include <stdlib.h> /* Invoke the comparison function, returns either 0, < 0, or > 0. */ #define CMP(A,B) ((*cmp)((A),(B))) /* Byte-wise swap two items of size SIZE. */ #define SWAP(A,B,SIZE) do {int sz = (SIZE); char *a = (A); char *b = (B); \ do { char _temp = *a;*a++ = *b;*b++ = _temp;} while (--sz);} while (0) /* Copy SIZE bytes from item B to item A. */ #define COPY(A,B,SIZE) {int sz = (SIZE); do { *(A)++ = *(B)++; } while (--sz); } /* This should be replaced by a standard ANSI macro. */ #define BYTES_PER_WORD 8 /* The next 4 #defines implement a very fast in-line stack abstraction. */ #define STACK_SIZE (BYTES_PER_WORD * sizeof (long)) #define PUSH(LOW,HIGH) do {top->lo = LOW;top++->hi = HIGH;} while (0) #define POP(LOW,HIGH) do {LOW = (--top)->lo;HIGH = top->hi;} while (0) #define STACK_NOT_EMPTY (stack < top) /* Discontinue quicksort algorithm when partition gets below this size. This particular magic number was chosen to work best on a Sun 4/260. */ #define MAX_THRESH 4 /* requisite prototype */ int qsortE (char *base_ptr, int total_elems, int size, int (*cmp)()); /* Stack node declarations used to store unfulfilled partition obligations. */ typedef struct { char *lo; char *hi; } stack_node; /* Order size using quicksort. This implementation incorporates four optimizations discussed in Sedgewick: 1. Non-recursive, using an explicit stack of pointer that store the next array partition to sort. To save time, this maximum amount of space required to store an array of MAX_INT is allocated on the stack. Assuming a 32-bit integer, this needs only 32 * sizeof (stack_node) == 136 bits. Pretty cheap, actually. 2. Choose the pivot element using a median-of-three decision tree. This reduces the probability of selecting a bad pivot value and eliminates certain extraneous comparisons. 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving insertion sort to order the MAX_THRESH items within each partition. This is a big win, since insertion sort is faster for small, mostly sorted array segments. 4. The larger of the two sub-partitions is always pushed onto the stack first, with the algorithm then concentrating on the smaller partition. This *guarantees* no more than log (n) stack size is needed (actually O(1) in this case)! */ int qsortE (char *base_ptr, int total_elems, int size, int (*cmp)()) { /* Allocating SIZE bytes for a pivot buffer facilitates a better algorithm below since we can do comparisons directly on the pivot. */ char *pivot_buffer = (char *) malloc(size); int max_thresh = MAX_THRESH * size; if (total_elems > MAX_THRESH) { char *lo = base_ptr; char *hi = lo + size * (total_elems - 1); stack_node stack[STACK_SIZE]; /* Largest size needed for 32-bit int!!! */ stack_node *top = stack + 1; while (STACK_NOT_EMPTY) { char *left_ptr; char *right_ptr; { char *pivot = pivot_buffer; { /* Select median value from among LO, MID, and HI. Rearrange LO and HI so the three values are sorted. This lowers the probability of picking a pathological pivot value and skips a comparison for both the LEFT_PTR and RIGHT_PTR. */ char *mid = lo + size * ((hi - lo) / size >> 1); if (CMP (mid, lo) < 0) SWAP (mid, lo, size); if (CMP (hi, mid) < 0) SWAP (mid, hi, size); else goto jump_over; if (CMP (mid, lo) < 0) SWAP (mid, lo, size); jump_over: COPY (pivot, mid, size); pivot = pivot_buffer; } left_ptr = lo + size; right_ptr = hi - size; /* Here's the famous ``collapse the walls'' section of quicksort. Gotta like those tight inner loops! They are the main reason that this algorithm runs much faster than others. */ do { while (CMP (left_ptr, pivot) < 0) left_ptr += size; while (CMP (pivot, right_ptr) < 0) right_ptr -= size; if (left_ptr < right_ptr) { SWAP (left_ptr, right_ptr, size); left_ptr += size; right_ptr -= size; } else if (left_ptr == right_ptr) { left_ptr += size; right_ptr -= size; break; } } while (left_ptr <= right_ptr); } /* Set up pointers for next iteration. First determine whether left and right partitions are below the threshold size. If so, ignore one or both. Otherwise, push the larger partition's bounds on the stack and continue sorting the smaller one. */ if ((right_ptr - lo) <= max_thresh) { if ((hi - left_ptr) <= max_thresh) /* Ignore both small partitions. */ POP (lo, hi); else /* Ignore small left partition. */ lo = left_ptr; } else if ((hi - left_ptr) <= max_thresh) /* Ignore small right partition. */ hi = right_ptr; else if ((right_ptr - lo) > (hi - left_ptr)) /* Push larger left partition indices. */ { PUSH (lo, right_ptr); lo = left_ptr; } else /* Push larger right partition indices. */ { PUSH (left_ptr, hi); hi = right_ptr; } } } /* Once the BASE_PTR array is partially sorted by quicksort the rest is completely sorted using insertion sort, since this is efficient for partitions below MAX_THRESH size. BASE_PTR points to the beginning of the array to sort, and END_PTR points at the very last element in the array (*not* one beyond it!). */ #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) { char *end_ptr = base_ptr + size * (total_elems - 1); char *run_ptr; char *tmp_ptr = base_ptr; char *thresh = MIN (end_ptr, base_ptr + max_thresh); /* Find smallest element in first threshold and place it at the array's beginning. This is the smallest array element, and the operation speeds up insertion sort's inner loop. */ for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) if (CMP (run_ptr, tmp_ptr) < 0) tmp_ptr = run_ptr; if (tmp_ptr != base_ptr) SWAP (tmp_ptr, base_ptr, size); /* Insertion sort, running from left-hand-side up to `right-hand-side.' Pretty much straight out of the original GNU qsort routine. */ for (run_ptr = base_ptr + size; (tmp_ptr = run_ptr += size) <= end_ptr; ) { while (CMP (run_ptr, tmp_ptr -= size) < 0) ; if ((tmp_ptr += size) != run_ptr) { char *trav; for (trav = run_ptr + size; --trav >= run_ptr;) { char c = *trav; char *hi, *lo; for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) *hi = *lo; *hi = c; } } } } return 1; } \ No newline at end of file
diff --git a/reanimator~-help.pd b/reanimator~-help.pd
new file mode 100644
index 0000000..3e67bf0
--- /dev/null
+++ b/reanimator~-help.pd
@@ -0,0 +1,163 @@
+#N canvas 17 365 720 517 10;
+#N canvas 132 212 480 321 reanimator-block 0;
+#X obj 15 170 block~ 256;
+#X obj 19 30 inlet~;
+#X obj 154 33 inlet~;
+#X obj 217 34 inlet;
+#X obj 19 105 outlet~;
+#X obj 86 105 outlet~;
+#X obj 154 106 outlet~;
+#X text 17 128 args: size of texture analysis(ms.) \, overlap factor
+\, window factor;
+#X obj 19 78 reanimator~ 5000 4 1;
+#X connect 1 0 8 0;
+#X connect 2 0 8 1;
+#X connect 3 0 8 0;
+#X connect 8 0 4 0;
+#X connect 8 1 5 0;
+#X connect 8 2 6 0;
+#X restore 96 87 pd reanimator-block;
+#N canvas 536 186 752 534 driver-sound 0;
+#X text 13 300 try a vocal sound or other sound with strong formant
+structure;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array reanimator-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X msg 31 177 read -resize \$1 reanimator-sound1;
+#X obj 227 268 tabplay~ reanimator-sound1;
+#X text 63 132 open the driver sound;
+#X connect 2 0 11 0;
+#X connect 4 0 2 0;
+#X connect 6 0 12 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 1;
+#X connect 11 0 1 0;
+#X connect 12 0 5 0;
+#X connect 12 1 7 0;
+#X restore 96 30 pd driver-sound;
+#N canvas 349 43 518 368 texture-sound 0;
+#X text 13 300 try a vocal sound or other sound with strong formant
+structure;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array reanimator-sound2 1.25363e+06 float 2;
+#X coords 0 1 1.25363e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X msg 31 177 read -resize \$1 reanimator-sound2;
+#X obj 227 268 tabplay~ reanimator-sound2;
+#X text 63 132 open the texture sound;
+#X connect 2 0 11 0;
+#X connect 4 0 2 0;
+#X connect 6 0 12 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 1;
+#X connect 11 0 1 0;
+#X connect 12 0 5 0;
+#X connect 12 1 7 0;
+#X restore 160 49 pd texture-sound;
+#X msg 499 356 \; pd dsp \$1;
+#X obj 499 337 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X obj 96 269 dac~;
+#X obj 160 150 snapshot~;
+#X floatatom 160 172 5 0 0 0 - - -;
+#X obj 324 167 snapshot~;
+#X floatatom 324 189 5 0 0 0 - - -;
+#X obj 324 134 metro 50;
+#X obj 324 113 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 324 201 analysis sync;
+#X text 158 184 matched frame;
+#N canvas 913 441 569 496 messages 0;
+#X obj 128 229 outlet;
+#X msg 24 181 analyze;
+#X msg 128 117 topbin \$1;
+#X floatatom 128 81 5 0 0 0 - - -;
+#X msg 206 117 inverse \$1;
+#X obj 206 84 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X text 189 163 texture sound must be playing during analysis;
+#X text 194 183 otherwise: crash!!!;
+#X text 223 84 matches with *least* good frame;
+#X text 128 39 top bin to match: lower means less CPU;
+#X text 128 54 different (perhaps worse) matching;
+#X obj 36 39 loadbang;
+#X msg 36 65 20;
+#X obj 231 213 fftease-system;
+#N canvas 0 22 454 304 more-info 0;
+#X text 18 60 How does this work? First load up a texture sound and
+play it into the right inlet of reanimator~. While the texture sound
+is playing \, send an "analyze" message and the texture sound will
+be captured (5 seconds worth in this example patch). Once you see the
+message "data acquisition completed" in the Pd window \, play any sound
+into the left inlet and reanimator~ will output the best match from
+the texture sound. If the input and output are the same sound \, the
+match should be identical. Otherwise the result is "texture mapping"
+the texture sound onto the driver sound. The key to effective use of
+reanimator~ is in smart selections of driver and texture sounds.;
+#X restore 382 225 pd more-info;
+#X text 5 163 get texture sample;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 3 0 2 0;
+#X connect 4 0 0 0;
+#X connect 5 0 4 0;
+#X connect 11 0 12 0;
+#X connect 12 0 3 0;
+#X connect 13 0 0 0;
+#X restore 255 71 pd messages;
+#X text 51 287 reanimator performs spectral reanimation \, AKA audio
+texture mapping. An online paper descripts this process in greater
+detail. Essentially reanimator~ captures input from its rightmost inlet
+and uses this as material to reconstitute sound coming in on the left.
+Since this is done by searching all stored spectra \, there are limits
+to how much sound may be recorded before overloading your computer's
+CPU. Start with a small amount of sound \, say 5 seconds \, and gradually
+increase until you find your practical limit. Once the texture sound
+has been recorded \, it may be driven by unlimited amounts of material
+in the leftmost inlet. Your driver should have a clear rhythmic profile.
+A drum loop would be a good place to start.;
+#X text 80 470 http://tinyurl.com/9324v;
+#X text 57 450 more info below or google "spectral reanimation";
+#X text 261 31 <- load sounds into both buffers;
+#X obj 122 202 hsl 128 15 0 4 0 0 empty empty empty -2 -6 0 8 -176298
+-1 -1 11100 1;
+#X floatatom 119 225 5 0 0 0 - - -;
+#X obj 96 246 *~ 1;
+#X text 165 223 gain;
+#X connect 0 0 21 0;
+#X connect 0 1 6 0;
+#X connect 0 2 8 0;
+#X connect 1 0 0 0;
+#X connect 2 0 0 1;
+#X connect 4 0 3 0;
+#X connect 6 0 7 0;
+#X connect 8 0 9 0;
+#X connect 10 0 8 0;
+#X connect 10 0 6 0;
+#X connect 11 0 10 0;
+#X connect 14 0 0 2;
+#X connect 19 0 20 0;
+#X connect 20 0 21 1;
+#X connect 21 0 5 0;
+#X connect 21 0 5 1;
diff --git a/reanimator~.c b/reanimator~.c
index 8afec93..1e4aceb 100644
--- a/reanimator~.c
+++ b/reanimator~.c
@@ -154,7 +154,7 @@ void reanimator_tilde_setup(void)
void reanimator_overlap(t_reanimator *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -166,7 +166,7 @@ void reanimator_winfac(t_reanimator *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
diff --git a/resent~-help.pd b/resent~-help.pd
new file mode 100644
index 0000000..fc3be61
--- /dev/null
+++ b/resent~-help.pd
@@ -0,0 +1,143 @@
+#N canvas 309 443 478 328 10;
+#N canvas 0 22 522 372 sound-source 0;
+#X text 13 300 try a vocal sound or other sound with strong formant
+structure;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array resent-sound1 1.25363e+06 float 2;
+#X coords 0 1 1.25363e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X obj 227 268 tabplay~ resent-sound1;
+#X msg 31 177 read -resize \$1 resent-sound1;
+#X connect 2 0 13 0;
+#X connect 4 0 2 0;
+#X connect 6 0 12 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 1;
+#X connect 12 0 5 0;
+#X connect 12 1 7 0;
+#X connect 13 0 1 0;
+#X restore 35 68 pd sound-source;
+#X msg 231 143 \; pd dsp \$1;
+#X obj 231 117 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#N canvas 0 22 474 324 resent-block 1;
+#X obj 164 51 inlet~;
+#X obj 164 143 outlet~;
+#X obj 271 203 outlet;
+#X obj 162 183 block~ 256;
+#X obj 264 54 inlet;
+#X obj 164 98 resent~ 5000 4 1;
+#X obj 271 175 snapshot~;
+#X obj 326 137 metro 50;
+#X msg 326 116 1;
+#X obj 326 80 loadbang;
+#X connect 0 0 5 0;
+#X connect 4 0 5 0;
+#X connect 5 0 1 0;
+#X connect 5 1 6 0;
+#X connect 6 0 2 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 0;
+#X connect 9 0 8 0;
+#X restore 35 114 pd resent-block;
+#X obj 35 158 dac~;
+#N canvas 921 180 636 397 messages 0;
+#X obj 171 295 outlet;
+#X msg 171 112 acquire_sample;
+#N canvas 260 436 657 449 global-control 0;
+#X obj 82 351 outlet;
+#X msg 257 259 1 0;
+#X msg 299 259 -1 0;
+#X text 254 347 set speed and phase;
+#X msg 82 166 setspeed \$1;
+#X floatatom 82 140 5 0 0 0 - a -;
+#X msg 337 259 0 0;
+#X floatatom 206 66 5 0 0 0 - b -;
+#X msg 206 92 setphase \$1;
+#X obj 439 235 vsl 15 128 -2 2 0 0 a empty empty 0 -8 0 8 -236160 -1
+-1 0 1;
+#X obj 461 235 vsl 15 128 0 1 0 0 b empty empty 0 -8 0 8 -236160 -1
+-1 0 1;
+#X msg 257 327 ssap \$1 \$1;
+#X text 421 209 speed;
+#X text 460 373 phase;
+#X connect 1 0 11 0;
+#X connect 2 0 11 0;
+#X connect 4 0 0 0;
+#X connect 5 0 4 0;
+#X connect 6 0 11 0;
+#X connect 7 0 8 0;
+#X connect 8 0 0 0;
+#X connect 11 0 0 0;
+#X restore 197 151 pd global-control;
+#X text 281 112 record sample to FFT buffer;
+#X obj 320 255 fftease-system;
+#N canvas 0 22 454 304 init 0;
+#X msg 158 101 verbose 1;
+#X obj 158 76 loadbang;
+#X msg 235 148 playthrough 1;
+#X obj 235 125 loadbang;
+#X obj 178 210 outlet;
+#X connect 0 0 4 0;
+#X connect 1 0 0 0;
+#X connect 2 0 4 0;
+#X connect 3 0 2 0;
+#X restore 252 245 pd init;
+#N canvas 786 85 508 405 separate-bin-control 0;
+#X obj 50 296 outlet;
+#X obj 50 129 pack f f;
+#X floatatom 50 95 5 0 0 0 - - -;
+#X floatatom 101 96 5 0 0 0 - - -;
+#X text 48 79 bin #;
+#X text 99 81 bin speed;
+#X msg 187 122 linespeed 0 -1 511 1;
+#X text 164 105 startbin startspeed endbin endspeed;
+#X text 164 222 minspeed maxspeed;
+#X msg 162 265 randphase 0 1;
+#X msg 188 163 linephase 0 0 511 1;
+#X msg 165 237 randspeed 0.95 1.05;
+#X text 47 53 phase is bounded by 0-1;
+#X text 47 39 bin numbers are bounded by 0-(FFT_size/2 - 1);
+#X msg 50 168 bin \$1 \$2;
+#X text 45 327 The cool thing here is that each FFT bin can be set
+to a different speed.;
+#X connect 1 0 14 0;
+#X connect 2 0 1 0;
+#X connect 3 0 1 1;
+#X connect 6 0 0 0;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X connect 11 0 0 0;
+#X connect 14 0 0 0;
+#X restore 210 176 pd separate-bin-control;
+#X text 334 157 then control it;
+#X connect 1 0 0 0;
+#X connect 2 0 0 0;
+#X connect 4 0 0 0;
+#X connect 5 0 0 0;
+#X connect 6 0 0 0;
+#X restore 135 92 pd messages;
+#X text 28 212 resent~ follows the model of residency~ but allows independent
+control over each bin. It is recommended that you familiarize yourself
+with residency~ before working with the more complicated resent~.;
+#X floatatom 135 150 5 0 0 0 - - -;
+#X text 117 167 record sync;
+#X text 155 71 <- first load a sound;
+#X text 228 93 <- then see what else you can do;
+#X connect 0 0 3 0;
+#X connect 2 0 1 0;
+#X connect 3 0 4 0;
+#X connect 3 0 4 1;
+#X connect 3 1 7 0;
+#X connect 5 0 3 1;
diff --git a/resent~.c b/resent~.c
index 704bb6a..d258506 100644
--- a/resent~.c
+++ b/resent~.c
@@ -182,7 +182,7 @@ void resent_verbose(t_resent *x, t_floatarg t)
void resent_overlap(t_resent *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -194,7 +194,7 @@ void resent_winfac(t_resent *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -382,9 +382,9 @@ void resent_init(t_resent *x,short initialized)
x->D = 256;
if(!x->R)
x->R = 44100;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 1;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 1;
x->verbose = 0; // testing only
diff --git a/residency~-help.pd b/residency~-help.pd
new file mode 100644
index 0000000..fc8eac9
--- /dev/null
+++ b/residency~-help.pd
@@ -0,0 +1,124 @@
+#N canvas 230 215 591 546 10;
+#N canvas 0 22 490 340 residency-block 0;
+#X obj 28 42 inlet~;
+#X obj 92 44 inlet~;
+#X obj 156 44 inlet~;
+#X obj 229 46 inlet;
+#X obj 28 140 outlet~;
+#X obj 28 99 residency~ 5000 4 1;
+#X obj 28 169 block~ 256;
+#X text 39 120 args: buffer size \, overlap \, window factor;
+#X text 103 171 FFT size is block~ size times overlap;
+#X obj 232 235 snapshot~;
+#X obj 393 187 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X obj 232 264 outlet;
+#X msg 393 142 loadbang;
+#X msg 393 165 1;
+#X obj 394 205 metro 100;
+#X connect 0 0 5 0;
+#X connect 1 0 5 1;
+#X connect 2 0 5 2;
+#X connect 3 0 5 0;
+#X connect 5 0 4 0;
+#X connect 5 1 9 0;
+#X connect 9 0 11 0;
+#X connect 10 0 14 0;
+#X connect 12 0 13 0;
+#X connect 13 0 10 0;
+#X connect 14 0 9 0;
+#X restore 124 220 pd residency-block;
+#N canvas 449 46 676 438 messages 0;
+#X obj 119 302 outlet;
+#X floatatom 289 121 5 0 0 2 resize_memory size -;
+#X msg 289 151 size \$1;
+#X obj 119 70 bng 15 250 50 0 empty trigger trigger_sampling 0 -6 0
+8 -262144 -1 -1;
+#X obj 149 122 s playsound;
+#X obj 119 98 t b b;
+#X msg 119 149 acquire_sample;
+#X text 36 10 Load a valid soundfile in sound-source \, then hit the
+sampling trigger below. The resulting recording is stored as a series
+of FFT frames inside residency~ available for arbitrary time-access.
+;
+#X text 254 134 first turn off DACs to be safe;
+#X obj 274 264 fftease-system;
+#N canvas 0 22 642 503 init 0;
+#X msg 241 126 verbose 1;
+#X msg 140 126 playthrough 1;
+#X obj 140 99 loadbang;
+#X obj 140 36 loadbang;
+#X msg 140 57 1;
+#X obj 140 79 s speed-slider;
+#X obj 130 194 outlet;
+#X connect 0 0 6 0;
+#X connect 1 0 6 0;
+#X connect 2 0 1 0;
+#X connect 2 0 0 0;
+#X connect 3 0 4 0;
+#X connect 4 0 5 0;
+#X restore 233 231 pd init;
+#X connect 1 0 2 0;
+#X connect 2 0 0 0;
+#X connect 3 0 5 0;
+#X connect 5 0 6 0;
+#X connect 5 1 4 0;
+#X connect 6 0 0 0;
+#X connect 9 0 0 0;
+#X connect 10 0 0 0;
+#X restore 245 185 pd messages;
+#X floatatom 164 196 5 0 0 0 - speed -;
+#N canvas 0 22 514 364 sound-source 0;
+#X obj 227 222 r playsound;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array residency-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X msg 31 177 read -resize \$1 residency-sound1;
+#X obj 227 268 tabplay~ residency-sound1;
+#X text 63 132 open the sound;
+#X connect 0 0 6 0;
+#X connect 2 0 11 0;
+#X connect 4 0 2 0;
+#X connect 6 0 12 0;
+#X connect 7 0 6 0;
+#X connect 8 0 7 1;
+#X connect 11 0 1 0;
+#X connect 12 0 5 0;
+#X connect 12 1 7 0;
+#X restore 124 125 pd sound-source;
+#X obj 124 263 dac~;
+#X text 161 181 speed;
+#X msg 284 257 \; pd dsp \$1;
+#X obj 284 231 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X floatatom 204 168 5 0 1 2 position position -;
+#X obj 28 47 vsl 15 128 -2 2 0 0 speed speed-slider speed 0 -8 0 8
+-253906 -1 -1 6325 1;
+#X obj 60 47 vsl 15 128 0 1 0 0 position empty position 0 -8 0 8 -4094
+-1 -1 8000 1;
+#X text 329 185 <- ask me what I can do;
+#X floatatom 245 291 5 0 0 0 - - -;
+#X text 245 307 recording sync;
+#X text 112 352 residency~ is a spectral sampler. The first argument
+specifies how many milliseconds of sampling memory to use. Start conservatively.
+If you request more memory than is available \, you may experience
+difficulty.;
+#X connect 0 0 4 0;
+#X connect 0 0 4 1;
+#X connect 0 1 12 0;
+#X connect 1 0 0 3;
+#X connect 2 0 0 1;
+#X connect 3 0 0 0;
+#X connect 7 0 6 0;
+#X connect 8 0 0 2;
diff --git a/residency~.c b/residency~.c
index 6e84938..00af6fe 100644
--- a/residency~.c
+++ b/residency~.c
@@ -143,7 +143,7 @@ void residency_meminfo( t_residency *x )
void residency_overlap(t_residency *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -155,7 +155,7 @@ void residency_winfac(t_residency *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
diff --git a/scrape~-help.pd b/scrape~-help.pd
new file mode 100644
index 0000000..2c1c4fc
--- /dev/null
+++ b/scrape~-help.pd
@@ -0,0 +1,88 @@
+#N canvas 153 350 531 534 10;
+#N canvas 0 22 462 312 scrape-block 0;
+#X obj 134 142 scrape~ 1000 4000 0.001 0.05 0.1 4 1;
+#X obj 126 237 block~ 256;
+#X obj 134 188 outlet~;
+#X obj 134 74 inlet~;
+#X obj 198 84 inlet;
+#X obj 239 84 inlet;
+#X obj 282 84 inlet;
+#X obj 324 85 inlet;
+#X obj 366 85 inlet;
+#X obj 421 94 inlet;
+#X connect 0 0 2 0;
+#X connect 3 0 0 0;
+#X connect 4 0 0 1;
+#X connect 5 0 0 2;
+#X connect 6 0 0 3;
+#X connect 7 0 0 4;
+#X connect 8 0 0 5;
+#X connect 9 0 0 0;
+#X restore 61 203 pd scrape-block;
+#N canvas 0 22 470 320 messages 0;
+#X obj 200 244 outlet;
+#X obj 200 212 fftease-system;
+#X connect 1 0 0 0;
+#X restore 161 182 pd messages;
+#N canvas 0 22 470 320 playsound 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array scrape-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X text 63 132 open the sound;
+#X msg 31 177 read -resize \$1 scrape-sound1;
+#X obj 227 268 tabplay~ scrape-sound1;
+#X connect 1 0 11 0;
+#X connect 3 0 1 0;
+#X connect 5 0 12 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 11 0 0 0;
+#X connect 12 0 4 0;
+#X connect 12 1 6 0;
+#X restore 61 22 pd playsound;
+#X floatatom 77 53 5 0 0 1 knee - -;
+#X floatatom 94 75 5 0 0 1 cutoff - -;
+#X floatatom 111 97 5 0 0 1 threshold1 - -;
+#X floatatom 127 115 5 0 0 1 threshold2 - -;
+#X floatatom 144 135 5 0 0 1 weak_bin_multiplier - -;
+#X obj 61 240 dac~;
+#X msg 223 235 \; pd dsp \$1;
+#X obj 223 215 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X msg 287 14 1000 4000 0.001 0.05 0.1;
+#X obj 287 37 unpack f f f f f;
+#X obj 287 -7 loadbang;
+#X text 54 284 scrape~ is like drown~ except that it only operates
+between the frequencies specified by knee and cutoff to the Nyquist.
+Between knee and cutoff is a transition range to gradually increase
+the noise reduction. This is good if you just want to scrape some noise
+off the upper frequency range without affecting lower parts of the
+spectrum (much).;
+#X connect 0 0 8 0;
+#X connect 0 0 8 1;
+#X connect 1 0 0 6;
+#X connect 2 0 0 0;
+#X connect 3 0 0 1;
+#X connect 4 0 0 2;
+#X connect 5 0 0 3;
+#X connect 6 0 0 4;
+#X connect 7 0 0 5;
+#X connect 10 0 9 0;
+#X connect 11 0 12 0;
+#X connect 12 0 3 0;
+#X connect 12 1 4 0;
+#X connect 12 2 5 0;
+#X connect 12 3 6 0;
+#X connect 12 4 7 0;
+#X connect 13 0 11 0;
diff --git a/scrape~.c b/scrape~.c
index bd435f7..9d8c962 100644
--- a/scrape~.c
+++ b/scrape~.c
@@ -174,9 +174,9 @@ void *scrape_new(t_symbol *msg, short argc, t_atom *argv)
if( x->scrape_mult < 0 || x->scrape_mult > 10 ){
x->scrape_mult = 0.1;
}
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 1;
x->vs = sys_getblksize();
@@ -223,7 +223,7 @@ void scrape_init(t_scrape *x, short initialized)
void scrape_overlap(t_scrape *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -235,7 +235,7 @@ void scrape_winfac(t_scrape *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
diff --git a/shapee~-help.pd b/shapee~-help.pd
new file mode 100644
index 0000000..fa1cfef
--- /dev/null
+++ b/shapee~-help.pd
@@ -0,0 +1,109 @@
+#N canvas 263 477 494 344 10;
+#N canvas 657 88 510 360 messages 0;
+#X obj 160 251 outlet;
+#X obj 160 215 fftease-system;
+#X obj 308 200 loadbang;
+#X msg 308 235 16;
+#X obj 308 264 outlet;
+#X connect 1 0 0 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X restore 248 126 pd messages;
+#X obj 148 221 dac~;
+#X msg 210 242 \; pd dsp \$1;
+#X obj 210 212 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X floatatom 212 175 5 0 1 0 - - -;
+#N canvas 638 45 502 352 shapee-block 0;
+#X obj 150 160 outlet~;
+#X obj 150 66 inlet~;
+#X obj 229 70 inlet~;
+#X obj 411 78 inlet;
+#X obj 150 115 shapee~ 4 1;
+#X floatatom 279 149 5 0 0 0 - - -;
+#X obj 329 72 inlet;
+#X obj 154 253 block~ 512;
+#X connect 1 0 4 0;
+#X connect 2 0 4 1;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 5 0 4 2;
+#X connect 6 0 4 2;
+#X restore 148 153 pd shapee-block;
+#X floatatom 214 98 5 0 0 0 - - -;
+#X text 258 99 shaping width;
+#N canvas 501 137 751 450 pitch-source 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array shapee-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X msg 31 177 read -resize \$1 shapee-sound1;
+#X obj 227 268 tabplay~ shapee-sound1;
+#X text 63 132 open the pitched sound;
+#X connect 1 0 10 0;
+#X connect 3 0 1 0;
+#X connect 5 0 11 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 10 0 0 0;
+#X connect 11 0 4 0;
+#X connect 11 1 6 0;
+#X restore 148 25 pd pitch-source;
+#N canvas 0 22 495 403 formant-source 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array shapee-sound2 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X obj 227 268 tabplay~ shapee-sound2;
+#X msg 31 177 read -resize \$1 shapee-sound2;
+#X text 36 337 try a vocal sound or other sound with strong formant
+structure;
+#X text 63 132 open the formant sound;
+#X connect 1 0 11 0;
+#X connect 3 0 1 0;
+#X connect 5 0 10 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 10 0 4 0;
+#X connect 10 1 6 0;
+#X connect 11 0 0 0;
+#X restore 181 49 pd formant-source;
+#X obj 320 160 hsl 128 15 0 2 0 0 empty empty empty -2 -6 0 8 -195520
+-1 -1 5200 1;
+#X text 321 146 gain;
+#X obj 148 188 *~ 0.1;
+#X text 40 287 shapee~ shapes the frequency evolution of one signal
+with that of another. The shape width controls the amount of the frequency
+shaping effect. Try to avoid sounds containing silence \, which can
+cause strong clicks.;
+#X connect 0 0 5 3;
+#X connect 0 1 6 0;
+#X connect 3 0 2 0;
+#X connect 4 0 12 1;
+#X connect 5 0 12 0;
+#X connect 6 0 5 2;
+#X connect 8 0 5 0;
+#X connect 9 0 5 1;
+#X connect 10 0 4 0;
+#X connect 12 0 1 0;
+#X connect 12 0 1 1;
diff --git a/shapee~.c b/shapee~.c
index 95a19d8..81b8f48 100644
--- a/shapee~.c
+++ b/shapee~.c
@@ -216,7 +216,7 @@ void shapee_mute(t_shapee *x, t_floatarg state)
void shapee_overlap(t_shapee *x, t_floatarg o)
{
int test = (int) o;
- if(!power_of_two(test)){
+ if(!fftease_power_of_two(test)){
post("%d is not a power of two",test);
return;
}
@@ -227,7 +227,7 @@ int test = (int) o;
void shapee_winfac(t_shapee *x, t_floatarg wf)
{
int test = (int) wf;
-if(!power_of_two(test)){
+if(!fftease_power_of_two(test)){
post("%d is not a power of two",test);
return;
}
diff --git a/swinger~-help.pd b/swinger~-help.pd
new file mode 100644
index 0000000..353bf91
--- /dev/null
+++ b/swinger~-help.pd
@@ -0,0 +1,94 @@
+#N canvas 263 477 470 320 10;
+#N canvas 0 22 478 328 swinger-block 0;
+#X obj 150 160 outlet~;
+#X obj 150 66 inlet~;
+#X obj 229 70 inlet~;
+#X obj 293 82 inlet;
+#X obj 179 224 block~ 512;
+#X obj 150 115 swinger~ 4 1;
+#X connect 1 0 5 0;
+#X connect 2 0 5 1;
+#X connect 3 0 5 0;
+#X connect 5 0 0 0;
+#X restore 148 121 pd swinger-block;
+#N canvas 0 22 478 328 messages 0;
+#X obj 160 251 outlet;
+#X obj 160 227 fftease-system;
+#X connect 1 0 0 0;
+#X restore 255 94 pd messages;
+#X obj 148 189 dac~;
+#X obj 148 156 *~ 1;
+#X msg 210 210 \; pd dsp \$1;
+#X obj 210 180 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X floatatom 212 143 5 0 0 0 - - -;
+#X text 41 255 swinger~ replaces the phases of one signal (left) with
+those from another (right). The result often sounds like victory. A
+swinging trick: Don't connect any signal to the right inlet and listen
+to the result.;
+#N canvas 538 45 558 447 sound1 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array swinger-sound1 1.5435e+06 float 2;
+#X coords 0 1 1.5435e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X msg 31 177 read -resize \$1 swinger-sound1;
+#X obj 227 268 tabplay~ swinger-sound1;
+#X text 64 132 open the sound;
+#X connect 1 0 10 0;
+#X connect 3 0 1 0;
+#X connect 5 0 11 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 10 0 0 0;
+#X connect 11 0 4 0;
+#X connect 11 1 6 0;
+#X restore 148 51 pd sound1;
+#N canvas 0 22 758 461 sound2 0;
+#X obj 161 265 soundfiler;
+#X obj 161 231 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array swinger-sound2 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 367 84 graph;
+#X msg 161 202 bang;
+#X obj 357 355 outlet~;
+#X msg 357 315 bang;
+#X obj 478 299 spigot;
+#X obj 515 276 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 263 315 then play it;
+#X text 434 261 loop if you like;
+#X text 193 203 open the sound;
+#X obj 357 339 tabplay~ swinger-sound2;
+#X msg 161 248 read -resize \$1 swinger-sound2;
+#X connect 1 0 12 0;
+#X connect 3 0 1 0;
+#X connect 5 0 11 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 11 0 4 0;
+#X connect 11 1 6 0;
+#X connect 12 0 0 0;
+#X restore 201 73 pd sound2;
+#X obj 314 128 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -131603
+-1 -1 11500 1;
+#X text 334 151 gain;
+#X connect 0 0 3 0;
+#X connect 1 0 0 2;
+#X connect 3 0 2 0;
+#X connect 3 0 2 1;
+#X connect 5 0 4 0;
+#X connect 6 0 3 1;
+#X connect 8 0 0 0;
+#X connect 9 0 0 1;
+#X connect 10 0 6 0;
diff --git a/swinger~.c b/swinger~.c
index b1c2b3d..5e95927 100644
--- a/swinger~.c
+++ b/swinger~.c
@@ -61,7 +61,7 @@ void swinger_init(t_swinger *x, short initialized);
void swinger_dsp_free(t_swinger *x);
void swinger_overlap(t_swinger *x, t_floatarg o);
void swinger_winfac(t_swinger *x, t_floatarg o);
-//int power_of_two(int p);
+//int fftease_power_of_two(int p);
void swinger_fftinfo(t_swinger *x);
#if MSP
@@ -167,7 +167,7 @@ void *swinger_new(t_symbol *s, int argc, t_atom *argv)
void swinger_overlap(t_swinger *x, t_floatarg o)
{
- if(!power_of_two(o)){
+ if(!fftease_power_of_two(o)){
post("%f is not a power of two",o);
return;
}
@@ -177,7 +177,7 @@ void swinger_overlap(t_swinger *x, t_floatarg o)
void swinger_winfac(t_swinger *x, t_floatarg f)
{
- if(!power_of_two(f)){
+ if(!fftease_power_of_two(f)){
error("%f is not a power of two",f);
return;
}
diff --git a/taint~-help.pd b/taint~-help.pd
new file mode 100644
index 0000000..81386d1
--- /dev/null
+++ b/taint~-help.pd
@@ -0,0 +1,147 @@
+#N canvas 417 69 677 443 10;
+#X obj 167 237 *~ 1;
+#X obj 167 289 dac~;
+#X floatatom 190 218 5 0 0 0 - centerring-gain -;
+#X msg 18 330 \; pd dsp \$1;
+#X obj 18 313 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 17 207 hsl 128 15 0 1.5 0 0 centerring-gain empty output_gain
+-2 -6 0 8 -79789 -1 -1 447 1;
+#N canvas 0 22 523 358 messages 0;
+#X obj 132 286 outlet;
+#X text 302 155 turn on invert;
+#X msg 132 223 pad \$1;
+#X floatatom 132 112 5 0 0 0 - - -;
+#X text 227 108 is turned on;
+#X obj 281 156 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X msg 281 178 invert \$1;
+#X text 227 94 pad affects the gain only when "invert";
+#X obj 132 142 ampdb;
+#X obj 132 67 loadbang;
+#X msg 132 90 -32;
+#X floatatom 132 167 5 0 0 0 - - -;
+#X obj 257 256 fftease-system;
+#X connect 2 0 0 0;
+#X connect 3 0 8 0;
+#X connect 5 0 6 0;
+#X connect 6 0 0 0;
+#X connect 8 0 11 0;
+#X connect 9 0 10 0;
+#X connect 10 0 3 0;
+#X connect 11 0 2 0;
+#X connect 12 0 0 0;
+#X restore 448 167 pd messages;
+#X obj 18 240 hsl 128 15 0.15 1 0 0 cod-scaling-exponent empty scaling_exponent
+-2 -6 0 8 -88868 -1 -1 800 1;
+#X floatatom 236 121 5 0 0 0 - cod-inverse-threshold -;
+#X floatatom 236 163 5 0 0 0 - - -;
+#N canvas 990 218 508 397 playsound1 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array taint-sound1 17642 float 2;
+#X coords 0 1 17641 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X text 316 205 comment;
+#X msg 31 177 read -resize \$1 taint-sound1;
+#X obj 227 268 tabplay~ taint-sound1;
+#X connect 1 0 12 0;
+#X connect 3 0 1 0;
+#X connect 5 0 13 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 12 0 0 0;
+#X connect 13 0 4 0;
+#X connect 13 1 6 0;
+#X restore 167 22 pd playsound1;
+#N canvas 990 218 512 401 playsound2 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X text 316 205 comment;
+#N canvas 0 22 450 300 graph2 0;
+#X array taint-sound2 133504 float 2;
+#X coords 0 1 133503 -1 200 140 1;
+#X restore 216 15 graph;
+#X msg 31 177 read -resize \$1 taint-sound2;
+#X obj 227 268 tabplay~ taint-sound2;
+#X connect 1 0 12 0;
+#X connect 2 0 1 0;
+#X connect 4 0 13 0;
+#X connect 5 0 4 0;
+#X connect 6 0 5 1;
+#X connect 12 0 0 0;
+#X connect 13 0 3 0;
+#X connect 13 1 5 0;
+#X restore 190 43 pd playsound2;
+#X floatatom 213 91 5 0.35 2 0 - cod-scaling-exponent -;
+#X obj 19 278 hsl 128 15 -90 0 0 0 cod-inverse-threshold empty inverse_threshold
+-2 -6 0 8 -88868 -1 -1 6100 1;
+#X text 280 136 but only when "invert" is turned on);
+#X text 213 73 scaling exponent (lower values increase distortion)
+;
+#X text 294 31 <- load and loop two soundfiles to hear effect;
+#X msg 14 123 0.1 0.3 -36;
+#X obj 14 139 unpack f f f;
+#X obj 14 107 loadbang;
+#X text 275 120 inverse threshold (lower values intensify effect;
+#N canvas 376 316 478 328 taint-block 0;
+#X obj 163 185 outlet~;
+#X obj 163 38 inlet~;
+#X obj 269 107 inlet;
+#X obj 201 81 inlet;
+#X obj 221 98 inlet;
+#X obj 182 65 inlet~;
+#X obj 163 128 taint~;
+#X obj 233 219 block~ 512;
+#X connect 1 0 6 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 2;
+#X connect 4 0 6 3;
+#X connect 5 0 6 1;
+#X connect 6 0 0 0;
+#X restore 167 183 pd taint-block;
+#X obj 236 141 ampdb;
+#X text 221 262 taint~ multiplies the spectra of two input signals.
+Multiplication of spectra can cause significant drops in the amplitude
+of the output signal. The inverse option allows division of the input
+spectra. Division requires the use of a threshold to avert division
+by zero. Also \, signal division will cause massive amplitude gains.
+Be careful of your ears and equipment. Start the amplitude very low
+(-100dB) and slowly work up to an acceptable level. A pad is provided
+to balance gain between normal and invert options.;
+#X connect 0 0 1 0;
+#X connect 0 0 1 1;
+#X connect 2 0 0 1;
+#X connect 4 0 3 0;
+#X connect 6 0 21 4;
+#X connect 8 0 22 0;
+#X connect 9 0 21 3;
+#X connect 10 0 21 0;
+#X connect 11 0 21 1;
+#X connect 12 0 21 2;
+#X connect 17 0 18 0;
+#X connect 18 0 5 0;
+#X connect 18 1 7 0;
+#X connect 18 2 13 0;
+#X connect 19 0 17 0;
+#X connect 21 0 0 0;
+#X connect 22 0 9 0;
diff --git a/taint~.c b/taint~.c
index e7f7c14..2207171 100644
--- a/taint~.c
+++ b/taint~.c
@@ -153,7 +153,7 @@ void taint_mute(t_taint *x, t_floatarg toggle)
void taint_overlap(t_taint *x, t_floatarg o)
{
- if(!power_of_two(o)){
+ if(!fftease_power_of_two(o)){
error("%f is not a power of two",o);
return;
}
@@ -163,7 +163,7 @@ void taint_overlap(t_taint *x, t_floatarg o)
void taint_winfac(t_taint *x, t_floatarg f)
{
- if(!power_of_two(f)){
+ if(!fftease_power_of_two(f)){
error("%f is not a power of two",f);
return;
}
@@ -274,10 +274,10 @@ void *taint_new(t_symbol *s, int argc, t_atom *argv)
if(x->exponent < 0.25)
x->exponent = 0.25;
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 1;
}
diff --git a/thresher~-help.pd b/thresher~-help.pd
new file mode 100644
index 0000000..72f9abc
--- /dev/null
+++ b/thresher~-help.pd
@@ -0,0 +1,63 @@
+#N canvas 112 22 564 566 10;
+#N canvas 0 22 470 320 threshblock 0;
+#X obj 197 47 inlet;
+#X obj 234 68 inlet;
+#X obj 161 29 inlet~;
+#X obj 161 111 outlet~;
+#X obj 161 87 thresher~ 4;
+#X obj 276 87 block~ 256;
+#X obj 313 47 inlet;
+#X connect 0 0 4 1;
+#X connect 1 0 4 2;
+#X connect 2 0 4 0;
+#X connect 4 0 3 0;
+#X connect 6 0 4 0;
+#X restore 64 79 pd threshblock;
+#X obj 66 223 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj 64 21 noise~;
+#X obj 249 206 vsl 15 128 1e-05 0.2 0 0 thresh b threshold 0 -8 0 8
+-73688 -1 -1 5050 1;
+#X obj 300 206 vsl 15 128 0.75 0.999 0 0 damp c damping_factor 0 -8
+0 8 -258462 -1 -1 10800 1;
+#X obj 64 187 dac~;
+#X obj 64 138 *~ 0.1;
+#X msg 66 246 \; pd dsp \$1;
+#X obj 205 206 vsl 15 128 0 4 0 0 amp a amp 0 -8 0 8 -150784 -1 -1
+11700 1;
+#N canvas 0 22 462 312 init 0;
+#X obj 31 29 loadbang;
+#X obj 32 71 unpack f f f;
+#X obj 33 99 s a;
+#X obj 43 108 s b;
+#X obj 53 118 s c;
+#X msg 31 51 0.8 0.1 0.95;
+#X connect 0 0 5 0;
+#X connect 1 0 2 0;
+#X connect 1 1 3 0;
+#X connect 1 2 4 0;
+#X connect 5 0 1 0;
+#X restore 67 286 pd init;
+#X obj 101 116 nbx 5 14 -1e+37 1e+37 0 0 empty amp empty 0 -6 0 10
+-262144 -1 -1 3.68504 256;
+#X obj 126 60 nbx 5 14 -1e+37 1e+37 0 0 empty damp empty 0 -6 0 10
+-262144 -1 -1 0.961748 256;
+#X obj 95 44 nbx 5 14 -1e+37 1e+37 0 0 empty thresh empty 0 -6 0 10
+-262144 -1 -1 0.0795336 256;
+#X text 113 20 <- something more interesting could go here.;
+#X obj 251 63 fftease-system;
+#X text 54 359 thresher~ sustains the amplitude and frequency in lower-energy
+FFT bins. The extent of this effect is controlled by the threshold
+parameter - at 0 all frames pass \, at higher values more frames are
+sustained. The damping factor controls the decay time - a value of
+1 gives an infinite freeze. See also the somewhat more interesting
+bthresher~.;
+#X connect 0 0 6 0;
+#X connect 1 0 7 0;
+#X connect 2 0 0 0;
+#X connect 6 0 5 0;
+#X connect 6 0 5 1;
+#X connect 10 0 6 1;
+#X connect 11 0 0 2;
+#X connect 12 0 0 1;
+#X connect 14 0 0 3;
diff --git a/thresher~.c b/thresher~.c
index 02c486c..5a6d1a8 100644
--- a/thresher~.c
+++ b/thresher~.c
@@ -121,7 +121,7 @@ void thresher_tilde_setup(void)
void thresher_overlap(t_thresher *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -133,7 +133,7 @@ void thresher_winfac(t_thresher *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -218,6 +218,10 @@ void *thresher_new(t_symbol *s, int argc, t_atom *argv)
x->overlap = atom_getfloatarg( 2, argc, argv );
x->winfac = atom_getfloatarg( 3, argc, argv );
+// post("thresh %f damper %f overlap %d winfac %d", x->move_threshold, x->damping_factor, x->overlap, x->winfac);
+
+ /* if overlap is zero we crash so should protect against bad input parameters*/
+
x->D = sys_getblksize();
x->R = sys_getsr();
@@ -233,9 +237,9 @@ void thresher_init(t_thresher *x, short initialized)
x->D = 256;
if(!x->R)
x->R = 44100;
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap) )
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac) )
x->winfac = 1;
x->N = x->D * x->overlap;
x->Nw = x->N * x->winfac;
@@ -254,8 +258,11 @@ void thresher_init(t_thresher *x, short initialized)
if(!x->damping_factor){
x->damping_factor = .95;
}
+ if(!x->move_threshold){
+ x->move_threshold = .00001 ;
+ }
x->first_frame = 1;
- x->move_threshold = .00001 ;
+
x->max_hold_time = DEFAULT_HOLD ;
x->max_hold_frames = x->max_hold_time / x->tadv;
x->c_fundamental = (float) x->R/( (x->N2)<<1 );
diff --git a/unconvert.c b/unconvert.c
new file mode 100644
index 0000000..85392dd
--- /dev/null
+++ b/unconvert.c
@@ -0,0 +1,34 @@
+#include "fftease.h"
+
+
+
+void unconvert( float *C, float *S, int N2, float *lastphase, float fundamental, float factor )
+
+{
+ int i,
+ real,
+ imag,
+ amp,
+ freq;
+ float mag,
+ phase;
+double sin(), cos();
+
+ for ( i = 0; i <= N2; i++ ) {
+
+ imag = freq = ( real = amp = i<<1 ) + 1;
+
+ if ( i == N2 )
+ real = 1;
+
+ mag = C[amp];
+ lastphase[i] += C[freq] - i*fundamental;
+ phase = lastphase[i]*factor;
+ S[real] = mag*cos( phase );
+
+ if ( i != N2 )
+ S[imag] = -mag*sin( phase );
+
+ }
+
+}
diff --git a/vacancy~-help.pd b/vacancy~-help.pd
new file mode 100644
index 0000000..b167fc7
--- /dev/null
+++ b/vacancy~-help.pd
@@ -0,0 +1,130 @@
+#N canvas 606 96 689 455 10;
+#X obj 167 237 *~ 1;
+#X obj 167 289 dac~;
+#X floatatom 190 218 5 0 0 0 - centerring-gain -;
+#X msg 18 330 \; pd dsp \$1;
+#X obj 18 313 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#X obj 17 207 hsl 128 15 0 1.5 0 0 centerring-gain empty output_gain
+-2 -6 0 8 -171124 -1 -1 847 1;
+#N canvas 785 535 531 366 messages 0;
+#X obj 132 268 outlet;
+#X text 291 182 turn on invert;
+#X obj 270 183 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X msg 270 205 invert \$1;
+#X obj 132 105 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X msg 132 127 swapphase \$1;
+#X obj 182 172 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X msg 182 194 rms \$1;
+#X obj 311 252 fftease-system;
+#X connect 2 0 3 0;
+#X connect 3 0 0 0;
+#X connect 4 0 5 0;
+#X connect 5 0 0 0;
+#X connect 6 0 7 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 0;
+#X restore 448 167 pd messages;
+#X floatatom 238 123 5 0 0 0 - vac-compositing-threshold -;
+#N canvas 990 218 520 409 playsound1 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array vacancy-sound1 1.09357e+06 float 2;
+#X coords 0 1 1.09357e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X text 316 205 comment;
+#X msg 31 177 read -resize \$1 vacancy-sound1;
+#X obj 227 268 tabplay~ vacancy-sound1;
+#X connect 1 0 12 0;
+#X connect 3 0 1 0;
+#X connect 5 0 13 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 12 0 0 0;
+#X connect 13 0 4 0;
+#X connect 13 1 6 0;
+#X restore 167 22 pd playsound1;
+#N canvas 990 218 524 413 playsound2 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X text 316 205 comment;
+#N canvas 0 22 450 300 graph2 0;
+#X array vacancy-sound2 1.764e+06 float 2;
+#X coords 0 1 1.764e+06 -1 200 140 1;
+#X restore 216 15 graph;
+#X msg 31 177 read -resize \$1 vacancy-sound2;
+#X obj 227 268 tabplay~ vacancy-sound2;
+#X connect 1 0 12 0;
+#X connect 2 0 1 0;
+#X connect 4 0 13 0;
+#X connect 5 0 4 0;
+#X connect 6 0 5 1;
+#X connect 12 0 0 0;
+#X connect 13 0 3 0;
+#X connect 13 1 5 0;
+#X restore 202 45 pd playsound2;
+#X text 294 31 <- load and loop two soundfiles to hear effect;
+#X obj 14 107 loadbang;
+#N canvas 376 316 482 332 vacancy-block 0;
+#X obj 163 185 outlet~;
+#X obj 163 38 inlet~;
+#X obj 269 107 inlet;
+#X obj 214 87 inlet;
+#X obj 188 64 inlet~;
+#X obj 233 219 block~ 512;
+#X obj 163 128 vacancy~;
+#X connect 1 0 6 0;
+#X connect 2 0 6 0;
+#X connect 3 0 6 2;
+#X connect 4 0 6 1;
+#X connect 6 0 0 0;
+#X restore 167 183 pd vacancy-block;
+#X text 280 124 compositing threshold;
+#X obj 16 242 hsl 128 15 -90 90 0 0 vac-compositing-threshold empty
+compositing_threshold -2 -6 0 8 -171124 -1 -1 3810 1;
+#X text 221 262 vacancy~ performs spectral compositing. The threshold
+controls the compositing and is specified in dB. Useful values lie
+in the range from -90 dB to 90 dB. Threshold inversion is available
+via the invert message. The threshold can also track the current RMS
+value of of the signal. In RMS tracking mode \, the useful threshold
+range will be somewhat different depending upon the character of the
+input signals. Phases will be derived from the left input unless phase
+swapping is specified. In this case phases will be taken from the right
+input signal when the threshold test is true.;
+#X msg 14 123 0.1 -36;
+#X obj 14 139 unpack f f;
+#X connect 0 0 1 0;
+#X connect 0 0 1 1;
+#X connect 2 0 0 1;
+#X connect 4 0 3 0;
+#X connect 6 0 12 3;
+#X connect 7 0 12 2;
+#X connect 8 0 12 0;
+#X connect 9 0 12 1;
+#X connect 11 0 16 0;
+#X connect 12 0 0 0;
+#X connect 16 0 17 0;
+#X connect 17 0 5 0;
+#X connect 17 1 14 0;
diff --git a/vacancy~.c b/vacancy~.c
index 0be6087..074274a 100644
--- a/vacancy~.c
+++ b/vacancy~.c
@@ -183,7 +183,7 @@ void vacancy_mute(t_vacancy *x, t_floatarg toggle)
void vacancy_overlap(t_vacancy *x, t_floatarg o)
{
- if(!power_of_two(o)){
+ if(!fftease_power_of_two(o)){
error("%f is not a power of two",o);
return;
}
@@ -193,7 +193,7 @@ void vacancy_overlap(t_vacancy *x, t_floatarg o)
void vacancy_winfac(t_vacancy *x, t_floatarg f)
{
- if(!power_of_two(f)){
+ if(!fftease_power_of_two(f)){
error("%f is not a power of two",f);
return;
}
@@ -223,10 +223,10 @@ void *vacancy_new(t_symbol *s, int argc, t_atom *argv)
x->overlap = atom_getfloatarg(0,argc,argv);
x->winfac = atom_getfloatarg(1,argc,argv);
- if(!power_of_two(x->overlap)){
+ if(!fftease_power_of_two(x->overlap)){
x->overlap = 4;
}
- if(!power_of_two(x->winfac)){
+ if(!fftease_power_of_two(x->winfac)){
x->winfac = 1;
}
diff --git a/xsyn~-help.pd b/xsyn~-help.pd
new file mode 100644
index 0000000..0d5f208
--- /dev/null
+++ b/xsyn~-help.pd
@@ -0,0 +1,79 @@
+#N canvas 236 558 603 436 10;
+#X obj 25 136 dac~;
+#N canvas 0 22 470 320 rich-harmonic-source 0;
+#X obj 127 232 outlet~;
+#X obj 127 125 phasor~ 100;
+#X obj 212 126 phasor~ 125;
+#X obj 296 125 phasor~ 150;
+#X obj 127 183 *~ 0.3;
+#X floatatom 127 67 5 0 0 0 - - -;
+#X obj 212 99 * 1.25;
+#X obj 296 100 * 1.5;
+#X obj 130 34 hsl 128 15 60 600 0 0 empty empty empty -2 -6 0 8 -154413
+-1 -1 6350 1;
+#X msg 127 11 330;
+#X obj 127 -18 loadbang;
+#X connect 1 0 4 0;
+#X connect 2 0 4 0;
+#X connect 3 0 4 0;
+#X connect 4 0 0 0;
+#X connect 5 0 6 0;
+#X connect 5 0 1 0;
+#X connect 5 0 7 0;
+#X connect 6 0 2 0;
+#X connect 7 0 3 0;
+#X connect 8 0 5 0;
+#X connect 9 0 8 0;
+#X connect 10 0 9 0;
+#X restore 25 23 pd rich-harmonic-source;
+#N canvas 473 320 623 326 vocal-source 0;
+#X obj 31 194 soundfiler;
+#X obj 31 160 openpanel;
+#N canvas 0 22 450 300 graph1 0;
+#X array xsyn-sound1 4e+06 float 2;
+#X coords 0 1 4e+06 -1 200 140 1;
+#X restore 237 13 graph;
+#X msg 31 131 bang;
+#X obj 227 284 outlet~;
+#X msg 227 244 bang;
+#X obj 348 228 spigot;
+#X obj 385 205 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1
+1;
+#X text 63 132 open the sound;
+#X text 133 244 then play it;
+#X text 304 190 loop if you like;
+#X obj 227 268 tabplay~ xsyn-sound1;
+#X msg 31 177 read -resize \$1 xsyn-sound1;
+#X connect 1 0 12 0;
+#X connect 3 0 1 0;
+#X connect 5 0 11 0;
+#X connect 6 0 5 0;
+#X connect 7 0 6 1;
+#X connect 11 0 4 0;
+#X connect 11 1 6 0;
+#X connect 12 0 0 0;
+#X restore 68 46 pd vocal-source;
+#X msg 34 242 \; pd dsp \$1;
+#X obj 34 221 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1
+;
+#N canvas 172 351 466 316 xsyn-block 0;
+#X obj 161 178 outlet~;
+#X obj 161 49 inlet~;
+#X obj 283 102 inlet;
+#X obj 161 213 block~ 256;
+#X obj 205 72 inlet~;
+#X obj 161 132 xsyn~ 4;
+#X connect 1 0 5 0;
+#X connect 2 0 5 0;
+#X connect 4 0 5 1;
+#X connect 5 0 0 0;
+#X restore 25 88 pd xsyn-block;
+#X obj 111 68 fftease-system;
+#X text 34 284 xsyn~ filters the first input with the second input
+\, creating a spectral cross synthesis effect.;
+#X connect 1 0 5 0;
+#X connect 2 0 5 1;
+#X connect 4 0 3 0;
+#X connect 5 0 0 0;
+#X connect 5 0 0 1;
+#X connect 6 0 5 2;
diff --git a/xsyn~.c b/xsyn~.c
index 2940935..a5c4ab0 100644
--- a/xsyn~.c
+++ b/xsyn~.c
@@ -136,7 +136,7 @@ void xsyn_mute(t_xsyn *x, t_floatarg toggle)
void xsyn_overlap(t_xsyn *x, t_floatarg f)
{
int i = (int) f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -148,7 +148,7 @@ void xsyn_winfac(t_xsyn *x, t_floatarg f)
{
int i = (int)f;
- if(!power_of_two(i)){
+ if(!fftease_power_of_two(i)){
error("%f is not a power of two",f);
return;
}
@@ -196,9 +196,9 @@ void *xsyn_new(t_symbol *s, int argc, t_atom *argv)
#endif
x->overlap = atom_getfloatarg(0,argc,argv);
x->winfac = atom_getfloatarg(1,argc,argv);
- if(!power_of_two(x->overlap))
+ if(!fftease_power_of_two(x->overlap))
x->overlap = 4;
- if(!power_of_two(x->winfac))
+ if(!fftease_power_of_two(x->winfac))
x->winfac = 1;
x->R = sys_getsr();