From 625cfe29a61431181bc453e4454d9eb40da80cf9 Mon Sep 17 00:00:00 2001
From: Miller Puckette <msp@ucsd.edu>
Date: Thu, 22 May 2008 09:58:37 -0700
Subject: [PATCH] new pow~, log~, exp~, abs~, and wrap

---
 doc/5.reference/exp~-help.pd  |  23 +++++
 doc/5.reference/help-intro.pd |  55 +++++-----
 doc/5.reference/log~-help.pd  |  26 +++++
 doc/5.reference/pow~-help.pd  |  30 ++++++
 src/d_math.c                  | 187 ++++++++++++++++++++++++++++++++++
 src/g_graph.c                 |   2 -
 src/m_class.c                 |  15 ++-
 src/notes.txt                 |   1 +
 src/x_arithmetic.c            |  20 +++-
 9 files changed, 331 insertions(+), 28 deletions(-)
 create mode 100644 doc/5.reference/exp~-help.pd
 create mode 100644 doc/5.reference/log~-help.pd
 create mode 100644 doc/5.reference/pow~-help.pd

diff --git a/doc/5.reference/exp~-help.pd b/doc/5.reference/exp~-help.pd
new file mode 100644
index 000000000..fc9089af9
--- /dev/null
+++ b/doc/5.reference/exp~-help.pd
@@ -0,0 +1,23 @@
+#N canvas 35 5 531 296 10;
+#X obj 19 107 sig~;
+#X obj 50 167 loadbang;
+#X obj 50 191 metro 100;
+#X obj 50 215 snapshot~;
+#X floatatom 19 88 5 0 0 0 - - -;
+#X floatatom 50 240 7 0 0 0 - - -;
+#X text 314 271 updated for Pd version 0.42.;
+#X text 83 131 <-- optional creation argument initializes right inlet
+(the base of the logarithm).;
+#X obj 21 14 exp~;
+#X text 60 14 - exponential function;
+#X text 76 31 raises the Euler number 'e' (about 2.718) \, to the power
+of the input signal.;
+#X text 18 272 See also:;
+#X obj 92 271 pow~;
+#X obj 20 132 exp~;
+#X connect 0 0 13 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 3 0 5 0;
+#X connect 4 0 0 0;
+#X connect 13 0 3 0;
diff --git a/doc/5.reference/help-intro.pd b/doc/5.reference/help-intro.pd
index 10ae3502f..1315f27c5 100644
--- a/doc/5.reference/help-intro.pd
+++ b/doc/5.reference/help-intro.pd
@@ -81,15 +81,15 @@
 #X text 119 1178 - greater or lesser of 2 numbers;
 #X obj 19 1201 clip;
 #X text 119 1201 - force a number into a range;
-#X obj 16 1251 notein;
-#X obj 75 1251 ctlin;
-#X obj 126 1251 pgmin;
-#X obj 176 1251 bendin;
-#X obj 235 1251 touchin;
-#X obj 16 1274 polytouchin;
-#X obj 120 1274 midiin;
-#X obj 179 1274 sysexin;
-#X text 318 1263 - MIDI input;
+#X obj 16 1261 notein;
+#X obj 75 1261 ctlin;
+#X obj 126 1261 pgmin;
+#X obj 176 1261 bendin;
+#X obj 235 1261 touchin;
+#X obj 16 1284 polytouchin;
+#X obj 120 1284 midiin;
+#X obj 179 1284 sysexin;
+#X text 318 1273 - MIDI input;
 #X obj 19 1317 noteout;
 #X obj 87 1317 ctlout;
 #X obj 147 1317 pgmout;
@@ -99,8 +99,6 @@
 #X obj 210 1338 midiout;
 #X text 318 1327 - MIDI output;
 #X obj 20 1370 makenote;
-#X text 109 1368 - schedule a delayed "note off" message corresponding
-to a note-on;
 #X obj 19 1402 stripnote;
 #X text 112 1403 - strip "note off" messages;
 #X obj 17 1441 tabread;
@@ -143,18 +141,17 @@ to a note-on;
 #X obj 16 2052 q8_rsqrt~;
 #X text 116 2052 - cheap reciprocal square root (beware -- 8 bits!)
 ;
-#X obj 16 2082 q8_sqrt~;
-#X text 116 2082 - cheap square root (beware -- 8 bits!);
-#X obj 16 2112 wrap~;
-#X text 116 2112 - wraparound (fractional part;
-#X obj 16 2142 fft~;
-#X text 116 2142 - complex forward discrete Fourier transform;
-#X obj 16 2172 ifft~;
-#X text 116 2172 - complex inverse discrete Fourier transform;
-#X obj 16 2202 rfft~;
-#X text 116 2202 - real forward discrete Fourier transform;
-#X obj 16 2232 rifft~;
-#X text 116 2232 - real inverse discrete Fourier transform;
+#X obj 16 2074 q8_sqrt~;
+#X text 116 2074 - cheap square root (beware -- 8 bits!);
+#X obj 16 2104 wrap~;
+#X obj 16 2134 fft~;
+#X text 116 2134 - complex forward discrete Fourier transform;
+#X obj 16 2156 ifft~;
+#X text 116 2156 - complex inverse discrete Fourier transform;
+#X obj 16 2186 rfft~;
+#X text 116 2186 - real forward discrete Fourier transform;
+#X obj 16 2208 rifft~;
+#X text 116 2208 - real inverse discrete Fourier transform;
 #X obj 16 2262 framp~;
 #X text 116 2262 - output a ramp for each block;
 #X obj 16 2292 mtof~;
@@ -314,7 +311,7 @@ to a note-on;
 #X text 20 961 ------------------------- MATH -----------------;
 #X text 19 721 ------------------------- TIME --------------------------
 ;
-#X text 17 1232 ------------------------ MIDI -------------------------
+#X text 17 1242 ------------------------ MIDI -------------------------
 ;
 #X text 24 120 --------------- GLUE ----------------;
 #X text 18 3768 ------------------------ SUBWINDOWS ------------------------
@@ -358,3 +355,13 @@ aren't typed into object boxes but come straight off the "add" menu.)
 Right-click (or double-click on a Macintosh) on any object to get its
 "help window".;
 #X text 118 4368 - get a pointer into a list within a scalar;
+#X obj 19 1224 wrap;
+#X text 118 1224 - wrap a number to range [0 \, 1);
+#X text 116 2104 - wraparound (fractional part);
+#X obj 15 2236 pow~;
+#X obj 59 2236 log~;
+#X obj 103 2236 exp~;
+#X text 197 2238 - math;
+#X obj 149 2237 abs~;
+#X text 109 1368 - schedule delayed "note off" message corresponding
+to a note-on;
diff --git a/doc/5.reference/log~-help.pd b/doc/5.reference/log~-help.pd
new file mode 100644
index 000000000..fdad98d2a
--- /dev/null
+++ b/doc/5.reference/log~-help.pd
@@ -0,0 +1,26 @@
+#N canvas 299 273 531 296 10;
+#X obj 19 103 sig~;
+#X obj 50 167 loadbang;
+#X obj 50 191 metro 100;
+#X obj 50 215 snapshot~;
+#X floatatom 19 79 5 0 0 0 - - -;
+#X obj 60 103 sig~;
+#X floatatom 60 79 5 0 0 0 - - -;
+#X floatatom 50 240 7 0 0 0 - - -;
+#X text 316 257 updated for Pd version 0.42.;
+#X obj 21 14 log~;
+#X text 60 14 - logarithms;
+#X text 76 31 computes the logarithm of the left inlet \, to the base
+'e' (about 2.718) \, or to another base specified by the inlet or a
+cration argument.;
+#X obj 20 132 log~ 2;
+#X text 83 131 <-- optional creation argument initializes right inlet
+(the base of the logarithm).;
+#X connect 0 0 12 0;
+#X connect 1 0 2 0;
+#X connect 2 0 3 0;
+#X connect 3 0 7 0;
+#X connect 4 0 0 0;
+#X connect 5 0 12 1;
+#X connect 6 0 5 0;
+#X connect 12 0 3 0;
diff --git a/doc/5.reference/pow~-help.pd b/doc/5.reference/pow~-help.pd
new file mode 100644
index 000000000..049e8ba94
--- /dev/null
+++ b/doc/5.reference/pow~-help.pd
@@ -0,0 +1,30 @@
+#N canvas 191 0 534 413 10;
+#X obj 21 14 pow~;
+#X obj 67 109 sig~;
+#X obj 98 173 loadbang;
+#X obj 98 197 metro 100;
+#X obj 98 221 snapshot~;
+#X floatatom 67 73 5 0 0 0 - - -;
+#X obj 108 109 sig~;
+#X floatatom 108 73 5 0 0 0 - - -;
+#X obj 68 138 pow~ 2;
+#X floatatom 98 246 7 0 0 0 - - -;
+#X obj 413 268 pow~ 2;
+#X text 20 271 An optional creation argument initializes right inlet:
+;
+#X text 319 384 updated for Pd version 0.42.;
+#X text 23 303 WARNING: it's easy to generate "infinity" by accident
+\, and if you do \, the DSP chain may dramatically slow down if you're
+using an i386 or ia64 processor. Out-of-range floating point values
+are thousands of times slower to compute with than in-range ones.;
+#X text 68 12 - raise a signal to a numeric power (given by another
+signal). The left inlet must be a positive number. The right inlet
+my be positive \, zero \, or negative.;
+#X connect 1 0 8 0;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 4 0 9 0;
+#X connect 5 0 1 0;
+#X connect 6 0 8 1;
+#X connect 7 0 6 0;
+#X connect 8 0 4 0;
diff --git a/src/d_math.c b/src/d_math.c
index 8c480e37e..738f2d6cd 100644
--- a/src/d_math.c
+++ b/src/d_math.c
@@ -555,6 +555,189 @@ void powtodb_tilde_setup(void)
     class_addmethod(powtodb_tilde_class, (t_method)powtodb_tilde_dsp, gensym("dsp"), 0);
 }
 
+/* ----------------------------- pow ----------------------------- */
+static t_class *pow_tilde_class;
+
+typedef struct _pow_tilde
+{
+    t_object x_obj;
+    t_float x_f;
+} t_pow_tilde;
+
+static void *pow_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+    t_pow_tilde *x = (t_pow_tilde *)pd_new(pow_tilde_class);
+    inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+    outlet_new(&x->x_obj, &s_signal);
+    x->x_f = 0;
+    return (x);
+}
+
+t_int *pow_tilde_perform(t_int *w)
+{
+    t_sample *in1 = (t_sample *)(w[1]);
+    t_sample *in2 = (t_sample *)(w[2]);
+    t_sample *out = (t_sample *)(w[3]);
+    int n = (int)(w[4]);
+    while (n--)
+    {
+        float f = *in1++;
+        if (f > 0)
+            *out = pow(f, *in2);
+        else *out = 0;
+        out++;
+        in2++;
+    }
+    return (w+5);
+}
+
+static void pow_tilde_dsp(t_pow_tilde *x, t_signal **sp)
+{
+    dsp_add(pow_tilde_perform, 4,
+        sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
+}
+
+static void pow_tilde_setup(void)
+{
+    pow_tilde_class = class_new(gensym("pow~"), (t_newmethod)pow_tilde_new, 0,
+        sizeof(t_pow_tilde), 0, A_DEFFLOAT, 0);
+    CLASS_MAINSIGNALIN(pow_tilde_class, t_pow_tilde, x_f);
+    class_addmethod(pow_tilde_class, (t_method)pow_tilde_dsp, gensym("dsp"), 0);
+}
+
+/* ----------------------------- exp ----------------------------- */
+static t_class *exp_tilde_class;
+
+typedef struct _exp_tilde
+{
+    t_object x_obj;
+    t_float x_f;
+} t_exp_tilde;
+
+static void *exp_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+    t_exp_tilde *x = (t_exp_tilde *)pd_new(exp_tilde_class);
+    outlet_new(&x->x_obj, &s_signal);
+    return (x);
+}
+
+t_int *exp_tilde_perform(t_int *w)
+{
+    t_sample *in1 = (t_sample *)(w[1]);
+    t_sample *out = (t_sample *)(w[2]);
+    int n = (int)(w[3]);
+    while (n--)
+        *out = exp(*in1);
+    return (w+4);
+}
+
+static void exp_tilde_dsp(t_exp_tilde *x, t_signal **sp)
+{
+    dsp_add(exp_tilde_perform, 3,
+        sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+static void exp_tilde_setup(void)
+{
+    exp_tilde_class = class_new(gensym("exp~"), (t_newmethod)exp_tilde_new, 0,
+        sizeof(t_exp_tilde), 0, 0);
+    CLASS_MAINSIGNALIN(exp_tilde_class, t_exp_tilde, x_f);
+    class_addmethod(exp_tilde_class, (t_method)exp_tilde_dsp, gensym("dsp"), 0);
+}
+
+/* ----------------------------- log ----------------------------- */
+static t_class *log_tilde_class;
+
+typedef struct _log_tilde
+{
+    t_object x_obj;
+    t_float x_f;
+} t_log_tilde;
+
+static void *log_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+    t_log_tilde *x = (t_log_tilde *)pd_new(log_tilde_class);
+    inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal);
+    outlet_new(&x->x_obj, &s_signal);
+    x->x_f = 0;
+    return (x);
+}
+
+t_int *log_tilde_perform(t_int *w)
+{
+    t_sample *in1 = (t_sample *)(w[1]);
+    t_sample *in2 = (t_sample *)(w[2]);
+    t_sample *out = (t_sample *)(w[3]);
+    int n = (int)(w[4]);
+    while (n--)
+    {
+        float f = *in1++, g = *in2++;
+        if (f <= 0)
+            *out = -1000;   /* rather than blow up, output a number << 0 */
+        else if (g <= 0)
+            *out = log(f);
+        else *out = log(f)/log(g);
+        out++;
+    }
+    return (w+5);
+}
+
+static void log_tilde_dsp(t_log_tilde *x, t_signal **sp)
+{
+    dsp_add(log_tilde_perform, 4,
+        sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n);
+}
+
+static void log_tilde_setup(void)
+{
+    log_tilde_class = class_new(gensym("log~"), (t_newmethod)log_tilde_new, 0,
+        sizeof(t_log_tilde), 0, A_DEFFLOAT, 0);
+    CLASS_MAINSIGNALIN(log_tilde_class, t_log_tilde, x_f);
+    class_addmethod(log_tilde_class, (t_method)log_tilde_dsp, gensym("dsp"), 0);
+}
+
+/* ----------------------------- abs ----------------------------- */
+static t_class *abs_tilde_class;
+
+typedef struct _abs_tilde
+{
+    t_object x_obj;
+    t_float x_f;
+} t_abs_tilde;
+
+static void *abs_tilde_new(t_symbol *s, int argc, t_atom *argv)
+{
+    t_abs_tilde *x = (t_abs_tilde *)pd_new(abs_tilde_class);
+    outlet_new(&x->x_obj, &s_signal);
+    return (x);
+}
+
+t_int *abs_tilde_perform(t_int *w)
+{
+    t_sample *in1 = (t_sample *)(w[1]);
+    t_sample *out = (t_sample *)(w[2]);
+    int n = (int)(w[3]);
+    while (n--)
+    {
+        float f = *in1++;
+        *out = (f >= 0 ? f : -f);
+    }
+    return (w+4);
+}
+
+static void abs_tilde_dsp(t_abs_tilde *x, t_signal **sp)
+{
+    dsp_add(abs_tilde_perform, 3,
+        sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
+}
+
+static void abs_tilde_setup(void)
+{
+    abs_tilde_class = class_new(gensym("abs~"), (t_newmethod)abs_tilde_new, 0,
+        sizeof(t_abs_tilde), 0, 0);
+    CLASS_MAINSIGNALIN(abs_tilde_class, t_abs_tilde, x_f);
+    class_addmethod(abs_tilde_class, (t_method)abs_tilde_dsp, gensym("dsp"), 0);
+}
 
 /* ------------------------ global setup routine ------------------------- */
 
@@ -571,6 +754,10 @@ void d_math_setup(void)
     rmstodb_tilde_setup();
     dbtopow_tilde_setup();
     powtodb_tilde_setup();
+    pow_tilde_setup();
+    exp_tilde_setup();
+    log_tilde_setup();
+    abs_tilde_setup();
 
     class_sethelpsymbol(mtof_tilde_class, s);
     class_sethelpsymbol(ftom_tilde_class, s);
diff --git a/src/g_graph.c b/src/g_graph.c
index 7af4213fc..cfda6c2ca 100644
--- a/src/g_graph.c
+++ b/src/g_graph.c
@@ -1107,8 +1107,6 @@ void g_graph_setup(void)
         A_SYMBOL, A_FLOAT, A_SYMBOL, A_DEFFLOAT, A_NULL);
     class_addmethod(canvas_class, (t_method)canvas_menuarray,
         gensym("menuarray"), A_NULL);
-    class_addmethod(canvas_class, (t_method)glist_arraydialog,
-        gensym("arraydialog"), A_SYMBOL, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);
     class_addmethod(canvas_class, (t_method)glist_sort,
         gensym("sort"), A_NULL);
 }
diff --git a/src/m_class.c b/src/m_class.c
index da8b0e4f4..e95926432 100644
--- a/src/m_class.c
+++ b/src/m_class.c
@@ -167,7 +167,7 @@ t_class *class_new(t_symbol *s, t_newmethod newmethod, t_method freemethod,
     {
         if (count == MAXPDARG)
         {
-            error("class %s: sorry: only %d creation args allowed",
+            error("class %s: sorry: only %d args typechecked; use A_GIMME",
                 s->s_name, MAXPDARG);
             break;
         }
@@ -299,6 +299,19 @@ void class_addmethod(t_class *c, t_method fn, t_symbol *sel,
     }
     else
     {
+        int i;
+        for (i = 0; i < c->c_nmethod; i++)
+            if (c->c_methods[i].me_name == sel)
+        {
+            char nbuf[80];
+            snprintf(nbuf, 80, "%s_aliased", sel->s_name);
+            c->c_methods[i].me_name = gensym(nbuf);
+            if (c == pd_objectmaker)
+                post("warning: class '%s' overwritten; old one renamed '%s'",
+                    sel->s_name, nbuf);
+            else post("warning: old method '%s' for class '%s' renamed '%s'",
+                sel->s_name, c->c_name->s_name, nbuf);
+        }
         c->c_methods = t_resizebytes(c->c_methods,
             c->c_nmethod * sizeof(*c->c_methods),
             (c->c_nmethod + 1) * sizeof(*c->c_methods));
diff --git a/src/notes.txt b/src/notes.txt
index 9d66d8eb4..8f94137fa 100644
--- a/src/notes.txt
+++ b/src/notes.txt
@@ -43,6 +43,7 @@ scofo reports error on reading score1.txt
 loading e-mailed patches without removing headers crashes pd
 check if _vsnprintf with zero argument in windows works any better...
 detect adc~ and dac~ reblocking
+wierd bug: help doesn't work if pd is started in 5.reference directory
 
 more demonstration patches:
 vibrato using variable delay
diff --git a/src/x_arithmetic.c b/src/x_arithmetic.c
index f64c8cbd4..0dd199372 100644
--- a/src/x_arithmetic.c
+++ b/src/x_arithmetic.c
@@ -623,7 +623,6 @@ static void log_float(t_object *x, t_float f)
     outlet_float(x->ob_outlet, r);
 }
 
-
 static t_class *exp_class;      /* ----------- exp --------------- */
 
 static void *exp_new(void)
@@ -659,6 +658,20 @@ static void abs_float(t_object *x, t_float f)
     outlet_float(x->ob_outlet, fabsf(f));
 }
 
+static t_class *wrap_class;      /* ----------- wrap --------------- */
+
+static void *wrap_new(void)
+{
+    t_object *x = (t_object *)pd_new(wrap_class);
+    outlet_new(x, &s_float);
+    return (x);
+}
+
+static void wrap_float(t_object *x, t_float f)
+{
+    outlet_float(x->ob_outlet, f - floor(f));
+}
+
 /* ------------------------  misc ------------------------ */
 
 static t_class *clip_class;
@@ -898,6 +911,11 @@ void x_arithmetic_setup(void)
     class_addfloat(abs_class, (t_method)abs_float);    
     class_sethelpsymbol(abs_class, math_sym);
 
+    wrap_class = class_new(gensym("wrap"), wrap_new, 0,
+        sizeof(t_object), 0, 0);
+    class_addfloat(wrap_class, (t_method)wrap_float);    
+    class_sethelpsymbol(wrap_class, math_sym);
+
 /* ------------------------  misc ------------------------ */
 
     clip_setup();
-- 
GitLab