1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
#include "defines.h"
/*--------------- hist ---------------*/
static t_class *hist_class;
typedef struct _hist
{
t_object x_obj;
t_float m_lo;
t_float m_hi;
t_float m_scale;
int m_nbins;
int m_n_observations;
t_float *m_hist;
} t_hist;
static void hist_perform_float(t_hist *x, t_float f)
{
int j;
j=(int)(.5+(f-x->m_lo)*x->m_scale);
j=(j>0)?(j<x->m_nbins?j:x->m_nbins-1):0; // limit without IF
x->m_hist[j]++;
x->m_n_observations++;
}
static void hist_perform_list(t_hist *x, t_symbol *s, int argc, t_atom *argv)
{
int i,j;
for (i = 0; i < argc; i++)
{
j=(int)(.5f+(atom_getfloat(&argv[i])-x->m_lo)*x->m_scale);
j=(j>0)?(j<x->m_nbins?j:x->m_nbins-1):0; // limit without IF
x->m_hist[j]++;
}
x->m_n_observations+=argc;
}
static void hist_bang(t_hist *x)
{
int i,n;
t_float *f;
t_atom *ap,*app;
n=x->m_nbins;
ap = (t_atom *)getbytes(sizeof(t_atom)*n);
app=ap;
i=x->m_nbins;
f=x->m_hist;
while(i--){
SETFLOAT(app, *f);
f++;
app++;
}
outlet_list(x->x_obj.ob_outlet,gensym("list"),n,ap);
freebytes(ap, sizeof(t_atom)*n);
}
static void hist_relative(t_hist *x)
{
int i,n;
t_float *f;
t_float invn;
t_atom *ap,*app;
n=x->m_nbins;
ap = (t_atom *)getbytes(sizeof(t_atom)*n);
app=ap;
invn=1.0f/(1e-10f+x->m_n_observations);
i=n;
f=x->m_hist;
while(i--){
SETFLOAT(app, (*f*invn));
f++;
app++;
}
outlet_list(x->x_obj.ob_outlet,gensym("list"),n,ap);
freebytes(ap, sizeof(t_atom)*n);
}
static void hist_clear(t_hist *x)
{
int i;
t_float *f;
f=x->m_hist;
for (i=0;i<x->m_nbins;i++)
*f++=0.0f;
x->m_n_observations=0;
}
static void hist_set(t_hist *x, t_float lo, t_float hi, t_float nbins)
{
if (nbins<1)
{
nbins=1;
logpost(x, 2, "[hist] minimum number of bins is 1");
}
if (hi<=lo)
{
logpost(x, 2, "[hist] higher bound (%g) must be greater than lower bound (%g)",
hi, lo);
hi=lo+1.0f;
}
freebytes(x->m_hist, x->m_nbins);
x->m_hi=hi;
x->m_lo=lo;
x->m_nbins=(int)nbins;
x->m_scale=(t_float)x->m_nbins/(hi-lo);
x->m_hist = (t_float*)getbytes(sizeof(t_float)*x->m_nbins);
hist_clear(x);
}
static void *hist_new(t_float lo, t_float hi, t_float nbins)
{
t_hist *x=(t_hist *)pd_new(hist_class);
outlet_new(&x->x_obj, gensym("list"));
x->m_hist=0;
x->m_nbins=0;
hist_set(x, lo, hi, nbins);
return (void *)x;
}
static void hist_free(t_hist *x)
{
freebytes(x->m_hist, x->m_nbins);
}
void hist_setup(void)
{
hist_class = class_new(gensym("hist"),
(t_newmethod)hist_new, (t_method)hist_free,
sizeof(t_hist),
CLASS_DEFAULT,
A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT,0);
class_addmethod(hist_class, (t_method)hist_clear, gensym("clear"),0);
class_addmethod(hist_class, (t_method)hist_bang, gensym("absolute"),0);
class_addmethod(hist_class, (t_method)hist_relative, gensym("relative"),0);
class_addmethod(hist_class, (t_method)hist_set, gensym("set"),A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT,0);
class_addlist(hist_class, (t_method)hist_perform_list);
class_addfloat(hist_class, (t_method)hist_perform_float);
class_addbang(hist_class, (t_method)hist_bang);
}
|