aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runningmean/runningmean.c59
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);