From 1baf1d957e195290cfd59089767ca63a547a9917 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 7 Apr 2004 14:32:29 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r1560, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/mjlib/; revision=1561 --- prob.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 prob.c (limited to 'prob.c') 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 +#endif +#include "m_pd.h" +#include +#include +#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")); +} + -- cgit v1.2.1