Skip to content

Commit

Permalink
wrap2~
Browse files Browse the repository at this point in the history
  • Loading branch information
porres committed Dec 11, 2023
1 parent 8f5f65a commit 277051d
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 118 deletions.
190 changes: 103 additions & 87 deletions Code_source/Compiled/audio/wrap2~.c
Original file line number Diff line number Diff line change
@@ -1,117 +1,133 @@
// Porres 2017
// Porres

#include "m_pd.h"
#include "math.h"

static t_class *wrap2_class;

typedef struct _wrap2{
t_object x_obj;
t_float x_low;
t_float x_high;
t_outlet *x_outlet;
typedef struct _wrap2 {
t_object x_obj;
t_inlet *x_inlet_min;
t_inlet *x_inlet_max;
int x_nchans;
t_int x_n;
t_int x_ch2;
t_int x_ch3;
}t_wrap2;

static t_int *wrap2_perform(t_int *w){
t_wrap2 *x = (t_wrap2 *)(w[1]);
t_sample *in = (t_sample *)(w[2]);
t_sample *out = (t_sample *)(w[3]);
int n = (int)(w[4]);
while(n--){
t_float output;
float input = *in++;
float low = x->x_low;
float high = x->x_high;
if(low > high){
low = x->x_high;
high = x->x_low;
}
float range = high - low;
if(low == high)
output = low;
else{
if(input < low){
output = input;
while(output < low)
output += range;
t_sample *in1 = (t_sample *)(w[2]);
t_sample *in2 = (t_sample *)(w[3]);
t_sample *in3 = (t_sample *)(w[4]);
t_sample *out = (t_sample *)(w[5]);
int n = x->x_n;
for(int j = 0; j < x->x_nchans; j++){
for(int i = 0; i < n; i++){
float input = in1[j*n + i];
float low = x->x_ch2 == 1 ? in2[i] : in2[j*n + i];
float high = x->x_ch3 == 1 ? in3[i] : in3[j*n + i];
float output;
if(low > high){ // swap values
float temp = high;
high = low;
low = temp;
};
float range = high - low;
if(low == high)
output = low;
else{
if(input < low){
output = input;
while(output < low)
output += range;
}
else
output = fmod(input - low, range) + low;
}
else
output = fmod(input - low, range) + low;
out[j*n + i] = output;
}
*out++ = output;
}
return(w+5);
return(w+6);
}


static void wrap2_dsp(t_wrap2 *x, t_signal **sp){
signal_setmultiout(&sp[1], sp[0]->s_nchans);
dsp_add(wrap2_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec,
((t_int)((sp[0])->s_length * (sp[0])->s_nchans)));
x->x_n = sp[0]->s_n;
x->x_nchans = sp[0]->s_nchans;
x->x_ch2 = sp[1]->s_nchans, x->x_ch3 = sp[2]->s_nchans;
signal_setmultiout(&sp[3], x->x_nchans);
if((x->x_ch2 > 1 && x->x_ch2 != x->x_nchans)
|| (x->x_ch3 > 1 && x->x_ch3 != x->x_nchans)){
dsp_add_zero(sp[3]->s_vec, x->x_nchans*x->x_n);
pd_error(x, "[wrap2~]: channel sizes mismatch");
return;
}
dsp_add(wrap2_perform, 5, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec);
}

static void *wrap2_free(t_wrap2 *x){
inlet_free(x->x_inlet_min);
inlet_free(x->x_inlet_max);
return(void *)x;
}

static void *wrap2_new(t_symbol *s, int ac, t_atom *av){
s = NULL;
t_wrap2 *x = (t_wrap2 *)pd_new(wrap2_class);
t_symbol *dummy = s;
dummy = NULL;
/////////////////////////////////////////////////////////////////////////////////////
float init_low, low, init_high, high;
if(ac){
if(ac == 1){
if(av -> a_type == A_FLOAT){
low = init_low = 0;
high = init_high = atom_getfloat(av);
}
else
goto errstate;
///////////////////////////
float min = -1.;
float max = 1.;
if(ac == 1){
if(av -> a_type == A_FLOAT){
min = 0;
max = atom_getfloat(av);
}
else if(ac == 2){
int argnum = 0;
while(ac){
if(av->a_type != A_FLOAT)
goto errstate;
else{
t_float curf = atom_getfloatarg(0, ac, av);
switch(argnum){
case 0:
low = init_low = curf;
break;
case 1:
high = init_high = curf;
break;
default:
break;
};
};
argnum++;
ac--;
av++;
};
}
else goto errstate;
}
else{
low = init_low = -1;
high = init_high = 1;
else
goto errstate;
}
if(low > high){
low = init_high;
high = init_low;
else if(ac == 2){
int numargs = 0;
while(ac > 0 ){
if(av -> a_type == A_FLOAT){ // if nullpointer, should be float or int
switch(numargs){
case 0: min = atom_getfloat(av);
numargs++;
ac--;
av++;
break;
case 1: max = atom_getfloat(av);
numargs++;
ac--;
av++;
break;
default:
ac--;
av++;
break;
};
}
else // not a float
goto errstate;
};
}
/////////////////////////////////////////////////////////////////////////////////////
x->x_low = low;
x->x_high = high;
floatinlet_new(&x->x_obj, &x->x_low);
floatinlet_new(&x->x_obj, &x->x_high);
outlet_new(&x->x_obj, &s_signal);
else if(ac > 2)
goto errstate;
///////////////////////////
x->x_inlet_min = inlet_new((t_object *)x, (t_pd *)x, &s_signal, &s_signal);
pd_float((t_pd *)x->x_inlet_min, min);
x->x_inlet_max = inlet_new((t_object *)x, (t_pd *)x, &s_signal, &s_signal);
pd_float((t_pd *)x->x_inlet_max, max);
outlet_new(&x->x_obj, gensym("signal"));
return(x);
errstate:
pd_error(x, "[wrap2~]: improper args");
return NULL;
errstate:
pd_error(x, "[wrap2~]: improper args");
return(NULL);
}

void wrap2_tilde_setup(void){
wrap2_class = class_new(gensym("wrap2~"), (t_newmethod)wrap2_new,
0, sizeof(t_wrap2), CLASS_MULTICHANNEL, A_GIMME, 0);
wrap2_class = class_new(gensym("wrap2~"), (t_newmethod)wrap2_new,
(t_method)wrap2_free, sizeof(t_wrap2), CLASS_MULTICHANNEL, A_GIMME, 0);
class_addmethod(wrap2_class, nullfn, gensym("signal"), 0);
class_addmethod(wrap2_class, (t_method)wrap2_dsp, gensym("dsp"), A_CANT, 0);
}
14 changes: 7 additions & 7 deletions Documentation/Help-files/fold~-help.pd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#N canvas 417 37 560 497 10;
#N canvas 484 44 560 497 10;
#X obj 2 2 cnv 15 301 42 empty empty fold~ 20 20 2 37 #e0e0e0 #000000 0;
#N canvas 0 22 450 278 (subpatch) 0;
#X coords 0 1 100 -1 302 42 1 0 0;
Expand Down Expand Up @@ -267,21 +267,21 @@
#X obj 90 178 else/fold~ -1 1;
#X obj 90 210 else/s2f~;
#X obj 90 143 else/sigs~ 1.1 1.2 1.3 1.4;
#X text 42 27 If the object has a multichannel left input \, it outputs the same number of channels. If the secondary inlets have a signal with a single channel \, the single value is applied to all channels. If a secondary inlet is also a multichhanel signal \, then each channel gets its min or max deviation value. Note \, however \, that the number of multichannels in secondary inlets need to match the same number of channels from the left input., f 76;
#X listbox 162 432 21 0 0 0 - - - 12;
#X obj 162 401 else/s2f~;
#X obj 162 294 else/sigs~ 1.1 1.2 1.3 1.4;
#X obj 162 369 else/fold~;
#X obj 190 319 else/sigs~ -1 -0.5 -0.75 -0.25;
#X obj 219 343 else/sigs~ 1 0.5 0.75 0.25;
#X text 42 27 If the object has a multichannel left input \, it outputs the same number of channels. If the secondary inlets have a signal with a single channel \, the single value is applied to all channels. If a secondary inlet is also a multichhanel signal \, then each channel gets its min or max value. Note \, however \, that the number of multichannels in secondary inlets need to match the same number of channels from the left input., f 76;
#X connect 2 0 3 0;
#X connect 3 0 0 0;
#X connect 4 0 2 0;
#X connect 7 0 6 0;
#X connect 8 0 9 0;
#X connect 9 0 7 0;
#X connect 10 0 9 1;
#X connect 11 0 9 2;
#X connect 6 0 5 0;
#X connect 7 0 8 0;
#X connect 8 0 6 0;
#X connect 9 0 8 1;
#X connect 10 0 8 2;
#X restore 449 241 pd multichannel;
#X text 74 90 [fold~] folds between a low and high value. This is like a mirroring function \, where an out of bounds value folds back until it is in the given range. It has multichannel support.;
#X text 171 291 signal(s);
Expand Down
59 changes: 35 additions & 24 deletions Documentation/Help-files/wrap2~-help.pd
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@
#X obj 4 356 cnv 3 550 3 empty empty outlets 8 12 0 13 #dcdcdc #000000 0;
#X obj 4 393 cnv 3 550 3 empty empty arguments 8 12 0 13 #dcdcdc #000000 0;
#X obj 111 366 cnv 17 3 17 empty empty 0 5 9 0 16 #dcdcdc #9c9c9c 0;
#X text 181 367 signal;
#X text 181 290 signal;
#X obj 111 290 cnv 17 3 17 empty empty 0 5 9 0 16 #dcdcdc #9c9c9c 0;
#X obj 4 280 cnv 3 550 3 empty empty inlets 8 12 0 13 #dcdcdc #000000 0;
#X obj 163 252 nbx 8 14 -1e+37 1e+37 0 0 empty empty empty 0 -8 0 10 #dcdcdc #000000 #000000 0 256;
#X obj 163 221 else/sig2float~;
#N canvas 207 34 366 264 (subpatch) 0;
#X obj 51 101 tgl 42 0 \$0-tgl-s \$0-tgl-r empty 1 8 1 9 #dcdcdc #7c7c7c #fcfcfc 0 1;
#X obj 51 101 tgl 42 0 \$0-tgl-s \$0-tgl-r empty 1 8 1 9 #4a4f51 #cde5c3 #fcfcfc 0 1;
#X obj 215 68 route dsp;
#X obj 215 37 receive pd;
#N canvas 977 77 379 291 set_color 0;
Expand Down Expand Up @@ -94,7 +92,7 @@
#X restore 215 165 pd set_color;
#X obj 135 122 r \$0-tgl-s;
#N canvas 121 482 450 300 (subpatch) 0;
#X obj 101 101 cnv 25 40 25 empty \$0-cnv DSP 3 13 0 20 #dcdcdc #7c7c7c 0;
#X obj 101 101 cnv 25 40 25 empty \$0-cnv DSP 3 13 0 20 #4a4f51 #cde5c3 0;
#X coords 0 -1 1 1 42 27 1 100 100;
#X restore 51 144 pd;
#X obj 226 139 s \$0-tgl-r;
Expand Down Expand Up @@ -160,12 +158,10 @@
#X connect 6 0 7 0;
#X connect 8 0 1 1;
#X restore 443 221 pd waveshape;
#X text 187 313 float;
#X text 187 334 float;
#N canvas 660 215 484 320 multichannel 0;
#X listbox 103 209 41 0 0 0 - - - 12;
#N canvas 575 141 548 496 multichannel 0;
#X listbox 90 241 41 0 0 0 - - - 12;
#N canvas 207 34 366 264 (subpatch) 0;
#X obj 51 101 tgl 42 0 \$0-tgl-s \$0-tgl-r empty 1 8 1 9 #dcdcdc #7c7c7c #fcfcfc 0 1;
#X obj 51 101 tgl 42 0 \$0-tgl-s \$0-tgl-r empty 1 8 1 9 #4a4f51 #cde5c3 #fcfcfc 0 1;
#X obj 215 68 route dsp;
#X obj 215 37 receive pd;
#N canvas 977 77 379 291 set_color 0;
Expand Down Expand Up @@ -234,7 +230,7 @@
#X restore 215 165 pd set_color;
#X obj 135 122 r \$0-tgl-s;
#N canvas 121 482 450 300 (subpatch) 0;
#X obj 101 101 cnv 25 40 25 empty \$0-cnv DSP 3 13 0 20 #dcdcdc #7c7c7c 0;
#X obj 101 101 cnv 25 40 25 empty \$0-cnv DSP 3 13 0 20 #4a4f51 #cde5c3 0;
#X coords 0 -1 1 1 42 27 1 100 100;
#X restore 51 144 pd;
#X obj 226 139 s \$0-tgl-r;
Expand Down Expand Up @@ -264,19 +260,34 @@
#X connect 7 0 6 0;
#X connect 9 0 0 0;
#X coords 0 -1 1 1 44 72 2 50 100;
#X restore 316 110 pd;
#X text 102 47 Example with multichannel signals.;
#X obj 103 178 else/s2f~;
#X obj 103 111 else/sigs~ 1.1 1.2 1.3 1.4;
#X obj 103 146 else/wrap2~ -1 1;
#X connect 3 0 0 0;
#X connect 4 0 5 0;
#X connect 5 0 3 0;
#X restore 303 142 pd;
#X obj 90 210 else/s2f~;
#X obj 90 143 else/sigs~ 1.1 1.2 1.3 1.4;
#X listbox 162 432 21 0 0 0 - - - 12;
#X obj 162 401 else/s2f~;
#X obj 162 294 else/sigs~ 1.1 1.2 1.3 1.4;
#X obj 193 319 else/sigs~ -1 -0.5 -0.75 -0.25;
#X obj 225 343 else/sigs~ 1 0.5 0.75 0.25;
#X obj 90 178 else/wrap2~ -1 1;
#X obj 162 369 else/wrap2~;
#X text 42 27 If the object has a multichannel left input \, it outputs the same number of channels. If the secondary inlets have a signal with a single channel \, the single value is applied to all channels. If a secondary inlet is also a multichhanel signal \, then each channel gets its min or max value. Note \, however \, that the number of multichannels in secondary inlets need to match the same number of channels from the left input., f 76;
#X connect 2 0 0 0;
#X connect 3 0 9 0;
#X connect 5 0 4 0;
#X connect 6 0 10 0;
#X connect 7 0 10 1;
#X connect 8 0 10 2;
#X connect 9 0 2 0;
#X connect 10 0 5 0;
#X restore 424 246 pd multichannel;
#X text 74 91 [wrap2~] wraps between a low and high value. It has multichannel support.;
#X connect 20 0 19 0;
#X connect 25 0 37 1;
#X connect 26 0 37 2;
#X connect 29 0 30 0;
#X connect 30 0 37 0;
#X connect 37 0 20 0;
#X text 171 291 signal(s);
#X text 171 313 signal(s);
#X text 171 334 signal(s);
#X text 171 368 signal(s);
#X connect 18 0 17 0;
#X connect 23 0 35 1;
#X connect 24 0 35 2;
#X connect 27 0 28 0;
#X connect 28 0 35 0;
#X connect 35 0 18 0;

0 comments on commit 277051d

Please sign in to comment.