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