aboutsummaryrefslogtreecommitdiff
path: root/prob.c
diff options
context:
space:
mode:
Diffstat (limited to 'prob.c')
-rw-r--r--prob.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/prob.c b/prob.c
new file mode 100644
index 0000000..b94719d
--- /dev/null
+++ b/prob.c
@@ -0,0 +1,143 @@
+#ifdef NT
+#include "stdafx.h"
+#include <io.h>
+#endif
+#include "m_pd.h"
+#include <stdlib.h>
+#include<time.h>
+#include "prob.h"
+
+/**
+* The prob object is designed to generate random events
+* with a given probability - essentially every clock tick
+* it looks to see if it should generate an event or not
+*/
+
+static t_class *prob_class;
+
+/**
+* clock tick - do a bang and wait the next
+* time delay in the list
+*/
+
+static void prob_tick(t_prob *x)
+{
+ if ( x->x_running )
+ {
+ if ( prob_event( x) )
+ {
+ outlet_bang(x->x_obj.ob_outlet);
+ }
+ clock_delay(x->x_clock, x->x_time );
+ }
+}
+
+/**
+* prob event looks to see if we should generate and event or not
+*/
+
+static int prob_event( t_prob* x )
+{
+ int ret = 0;
+ if ( rand() < x->x_probability * RAND_MAX)
+ {
+ ret = 1;
+ }
+ return ret;
+}
+
+/**
+* a bang causes a reset to the start of the bar - used to
+* synchronize multiple prob's. If the rhythm is not
+* running it is started
+*/
+
+static void prob_bang(t_prob *x)
+{
+ x->x_running = 1;
+ clock_delay(x->x_clock, x->x_time );
+}
+
+/**
+* a stop message turns us off
+*/
+
+static void prob_stop(t_prob *x)
+{
+ x->x_running = 0;
+}
+
+/**
+* free our clock and our timer array
+*/
+
+static void prob_free(t_prob *x)
+{
+ clock_free(x->x_clock);
+}
+
+/*
+* make a new prob - we can provide a list of times
+* so read these in too
+*/
+
+static void *prob_new(t_float t , t_float probability )
+{
+ t_prob *x = (t_prob *)pd_new(prob_class);
+ prob_set_time( x , t );
+ prob_set_probability( x , probability );
+ x->x_running=0;
+ // make us some ins and outs
+ x->x_clock = clock_new(x, (t_method)prob_tick);
+ outlet_new(&x->x_obj, gensym("bang"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("time"));
+ inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("probability"));
+ return (x);
+}
+
+/**
+* set the probability
+*/
+
+static void prob_set_probability( t_prob *x, t_float f )
+{
+ if ( f < 0 )
+ {
+ post("probability must be between 0 and 1 ");
+ f = 0;
+ }
+ else if( f > 1 )
+ {
+ post("probability must be between 0 and 1 ");
+ f = 1;
+ }
+ x->x_probability = f;
+}
+
+
+/**
+* set the time
+*/
+
+static void prob_set_time( t_prob *x, t_float f )
+{
+ x->x_time = f;
+}
+
+/**
+* make a new one and setup all of our messages
+*/
+
+ void prob_setup(void)
+{
+ srand( (unsigned) time( NULL ) );
+ prob_class = class_new(gensym("prob"), (t_newmethod)prob_new,
+ (t_method)prob_free, sizeof(t_prob), 0, A_DEFFLOAT , A_DEFFLOAT, 0);
+ class_addbang(prob_class, prob_bang);
+ class_addmethod(prob_class, (t_method)prob_stop, gensym("stop"), 0);
+ class_addmethod(prob_class, (t_method)prob_bang, gensym("start"), 0);
+ class_addmethod(prob_class, (t_method)prob_set_probability, gensym("probability" ), A_FLOAT, 0);
+ class_addmethod(prob_class, (t_method)prob_set_time, gensym("time" ), A_FLOAT, 0);
+ class_sethelpsymbol(prob_class, gensym("mjLib/prob"));
+}
+