BangAround
From YoungMusic
My first external. Full explanation and demo patch will follow.
#include "m_pd.h"
/* This object can alternate bangs over 4 outputs. The counter has 16 steps,
and using an incoming integer from 0 to 5 (handy for radio buttons in pd)
you can make it bang on:
0: never
1: every 16 steps
2: every 8 steps
3: every 4 steps
4: every 2 steps
5: every step
I made this to trigger samples in a very steady rhythm. More specificly I try
to make an electronic version of Riley's in C with this.
The alternation between 4 outputs exists because a sample can be longer than a
period. This way it can keep playing 4 times longer.
A metro object can best be used as an input to get a steady pulse. You can
send a "reset" message to get the counter back to zero, which is handy to syncronise
several objects.
The output frequency can be changed with the message "setstep x" in which x is a
number between 0 and 5.
There is one creation argument, which is the initial output frequency ( = setstep).
*/
static t_class *cBangAround;
typedef struct _BangAround {
t_object x_obj;
t_int counter; // this counter is incremented with each bang
t_int output; // circulate between four outputs
t_int steps; // how often a bang i sent to the output
t_int incSteps; // temporary save incoming step format until we ended the current cycle
t_outlet *out1, *out2, *out3, *out4; // four outlets for bangs
} typeBangAround;
void incoming(typeBangAround *x) {
if (x->counter == 16) {
x->counter = 0;
x->steps = x->incSteps; // only change the steps after a whole cycle
}
if (x->steps > 0) { // 0 means don't output anything
if ((x->counter % x->steps) == 0) {
// generate output
if(x->output == 1) outlet_bang(x->out1);
if(x->output == 2) outlet_bang(x->out2);
if(x->output == 3) outlet_bang(x->out3);
if(x->output == 4) outlet_bang(x->out4);
// next time take the next output
if (x->output == 4) {
x->output = 1;
} else {
x->output++;
}
}
}
x->counter++;
}
void setStep(typeBangAround *x, t_floatarg f) {
t_int i = f;
switch (i) {
case 0: x->incSteps = 0;
break;
case 1: x->incSteps = 16;
break;
case 2: x->incSteps = 8;
break;
case 3: x->incSteps = 4;
break;
case 4: x->incSteps = 2;
break;
case 5: x->incSteps = 1;
}
}
void reset(typeBangAround *x) {
x->counter = 0;
}
void *New(t_floatarg f) {
typeBangAround *x = (typeBangAround *)pd_new(cBangAround);
x->counter = 0; // variables get an initial value in this function
x->output = 1;
x->steps = f;
x->incSteps = f;
x->out1 = outlet_new(&x->x_obj, gensym("bang"));
x->out2 = outlet_new(&x->x_obj, gensym("bang"));
x->out3 = outlet_new(&x->x_obj, gensym("bang"));
x->out4 = outlet_new(&x->x_obj, gensym("bang"));
return (void *)x;
}
__declspec(dllexport) void BangAround_setup(void) {
cBangAround = class_new(gensym("BangAround"),
(t_newmethod)New,
0, sizeof(typeBangAround),
CLASS_DEFAULT,
A_DEFFLOAT, 0); // one creation argument to set how many step
// go in each roun d
// a function is setup to intercept incoming bangs
class_addbang(cBangAround, incoming);
// another function for the incoming message setstep, which changes the interval
class_addmethod(cBangAround,
(t_method)setStep,
gensym("setstep"),
A_DEFFLOAT, 0);
class_addmethod(cBangAround,
(t_method)reset,
gensym("reset"),
0);
}

