diff options
-rw-r--r-- | runningmean/runningmean.c | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/runningmean/runningmean.c b/runningmean/runningmean.c index ef22b2f..96cc157 100644 --- a/runningmean/runningmean.c +++ b/runningmean/runningmean.c @@ -2,12 +2,11 @@ /* output the running mean of the input */ #include "m_pd.h" -/* We implement a circular buffer x_data of length x_n and */ -/* add all the values in it and divide by the */ -/* number of values to get the mean x_mean. */ +/* We implement a circular buffer x_data of length x_n */ +/* With each incoming value we sum the x_n values, then divide by */ +/* x_n to get the mean value, x_mean. */ -/* for simplicity and to avoid reallocation problems, we preallocate a longish array for the data */ -#define RUNNINGMEAN_MAX 1024 /* arbitrary maximum length of the data list*/ +#define RUNNINGMEAN_MAX 128 /* a default value when no valid argument is supplied */ typedef struct _runningmean { @@ -18,7 +17,8 @@ typedef struct _runningmean t_outlet *x_out; t_inlet *x_inlet2; t_int x_n; - t_float x_data[RUNNINGMEAN_MAX]; + t_int x_originalsize; + t_float *x_data; t_float x_mean; t_int x_pointer; } t_runningmean; @@ -26,7 +26,7 @@ typedef struct _runningmean static t_class *runningmean_class; void runningmean_setup(void); -static void *runningmean_new(t_symbol *s, t_floatarg f); +static void *runningmean_new(t_floatarg f); static void runningmean_free(t_runningmean *x); static void runningmean_bang(t_runningmean *x); static void runningmean_float(t_runningmean *x, t_float f); @@ -39,12 +39,15 @@ static void runningmean_float(t_runningmean *x, t_float f) float total = 0; int i; - /* add a float at the current location, overwriting the oldest data */ - x->x_data[x->x_pointer] = f; - if (++x->x_pointer >= x->x_n) x->x_pointer = 0; /* wrap pointer */ - for (i = 0; i < x->x_n; ++i) total += *p++; - x->x_mean = total/x->x_n; - outlet_float(x->x_out, x->x_mean); + if (x->x_n > 0) + { + /* add a float at the current location, overwriting the oldest data */ + x->x_data[x->x_pointer] = f; + if (++x->x_pointer >= x->x_n) x->x_pointer = 0; /* wrap pointer */ + for (i = 0; i < x->x_n; ++i) total += *p++; + x->x_mean = total/x->x_n; + outlet_float(x->x_out, x->x_mean); + } return; } @@ -57,12 +60,12 @@ static void runningmean_bang(t_runningmean *x) static void runningmean_length(t_runningmean *x, t_float f) { - if ((f >= 1) && ((int)f == f) && (f < RUNNINGMEAN_MAX)) + if ((f >= 1) && ((int)f == f) && (f <= x->x_originalsize)) { x->x_n = (int)f; runningmean_zero(x); } - else post("runningmean length must be an integer between 1 and %d.", RUNNINGMEAN_MAX); + else post("runningmean length must be an integer between 1 and %d.", x->x_originalsize); return; } @@ -72,7 +75,7 @@ static void runningmean_zero(t_runningmean *x) int i; /* zero the entire array */ - for (i = 0; i < RUNNINGMEAN_MAX; ++i) *p++ = 0; + for (i = 0; i < x->x_n; ++i) *p++ = 0; x->x_mean = 0; x->x_pointer = 0; return; @@ -81,26 +84,40 @@ static void runningmean_zero(t_runningmean *x) static void runningmean_free(t_runningmean *x) { + freebytes(x->x_data, x->x_originalsize); + x->x_originalsize = x->x_n = 0; + x->x_data = NULL; return; } -static void *runningmean_new(t_symbol *s, t_floatarg f) +static void *runningmean_new(t_floatarg f) { t_runningmean *x; - post("runningmean_new %f", f); - x = (t_runningmean *)pd_new(runningmean_class); if (x == NULL) return (x); x->x_out = outlet_new((t_object *)x, &s_float); x->x_inlet2 = inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("length")); - if (!((f >= 1) && ((int)f == f) && (f < RUNNINGMEAN_MAX))) + if (!((f >= 1) && ((int)f == f))) { - post("runningmean length %f must be an integer between 1 and %d, using %d", f, RUNNINGMEAN_MAX, RUNNINGMEAN_MAX); + post("runningmean length %0.2f must be an integer greater than 1, using %d", f, RUNNINGMEAN_MAX); f = RUNNINGMEAN_MAX; } { x->x_n = (int)f; + x->x_data = (t_float *)getbytes(sizeof(float)*x->x_n); + if (x->x_data == NULL) + { + post("runningmean unable to allocate %lu bytes of memory, using %d", sizeof(float)*x->x_n, RUNNINGMEAN_MAX); + x->x_n = RUNNINGMEAN_MAX; + //x->x_data = (t_float *)getbytes(x->x_n); + if (x->x_data == NULL) + { + post("runningmean unable to allocate %lu bytes of memory, using 0", x->x_n); + x->x_n = 0; + } + } + x->x_originalsize = x->x_n; runningmean_zero(x); } return (x); |