00001
00002
00003
00004
00005
00008
00009
00010 #include "ext.h"
00011 #include "ext_obex.h"
00012 #include "ext_time.h"
00013 #include "ext_itm.h"
00014
00016 typedef struct _statelem
00017 {
00018 bool enable;
00019 long pitch;
00020 double nbOcc;
00021 double nbtot;
00022 double ampacc;
00023 double proba;
00024 void* clock;
00025 void* object;
00026 } bc_statelem;
00027
00032 typedef struct _bc_yinstats
00033 {
00034 t_object ob;
00035 long nbstats;
00036 bc_statelem* stats;
00037 double minproba;
00038 long window;
00039 double lastpitch;
00040 double lastamp;
00041 long laststat;
00042 void* out_pitch;
00043 void* out_amp;
00044 void* out_proba;
00045 } t_bc_yinstats;
00046
00048
00050
00052
00053
00054 void *bc_yinstats_new(t_symbol *s, long argc, t_atom *argv);
00055 void bc_yinstats_free(t_bc_yinstats *x);
00056 void bc_yinstats_assist(t_bc_yinstats *x, void *b, long m, long a, char *s);
00057
00058
00059 void bc_yinstats_amp(t_bc_yinstats *x, double ampin);
00060 void bc_yinstats_pitch(t_bc_yinstats *x, long pitchin);
00061 void bc_yinstats_out(bc_statelem *stat);
00062 void bc_yinstats_stop(t_bc_yinstats *x);
00063
00064
00065 bool bc_yinstats_addocc(t_bc_yinstats *x, long pitchin, double ampin);
00066 long bc_yinstats_addstat(t_bc_yinstats *x, long pitchin, double ampin);
00067 void bc_yinstats_reset(t_bc_yinstats *x, bc_statelem *stat);
00068
00069
00070 void *bc_yinstats_class;
00071
00072
00073 int main(void)
00074 {
00075 t_class *c;
00076
00077 c = class_new("bc.yinstats", (method)bc_yinstats_new, (method)bc_yinstats_free, (long)sizeof(t_bc_yinstats), 0L, A_GIMME, 0);
00078
00079
00080 class_addmethod(c, (method)bc_yinstats_assist,"assist",A_CANT, 0);
00081
00082
00083 class_addmethod(c, (method)bc_yinstats_pitch, "int", A_LONG, 0);
00084 class_addmethod(c, (method)bc_yinstats_amp, "ft1", A_FLOAT, 0);
00085 class_addmethod(c, (method)bc_yinstats_stop, "stop", 0);
00086
00087 CLASS_ATTR_LONG(c, "window", 0, t_bc_yinstats, window);
00088 CLASS_ATTR_LABEL(c, "window", 0, "Window (ms)");
00089 CLASS_ATTR_SAVE(c, "window", 0);
00090 CLASS_ATTR_MIN(c, "window", 0, 0);
00091
00092 CLASS_ATTR_DOUBLE(c, "minproba", 0, t_bc_yinstats, minproba);
00093 CLASS_ATTR_LABEL(c, "minproba", 0, "Probability Threshold");
00094 CLASS_ATTR_SAVE(c, "minproba", 0);
00095 CLASS_ATTR_FILTER_CLIP(c, "minproba", 0., 1.);
00096
00097 class_register(CLASS_BOX, c);
00098 bc_yinstats_class = c;
00099
00100 return 0;
00101 }
00102
00104
00105
00108 void *bc_yinstats_new(t_symbol *s, long argc, t_atom *argv)
00109 {
00110 t_bc_yinstats *x = NULL;
00111
00112 if (x = (t_bc_yinstats *)object_alloc(bc_yinstats_class))
00113 {
00114
00115 floatin(x, 1);
00116
00117
00118 x->out_proba = floatout(x);
00119 x->out_amp = floatout(x);
00120 x->out_pitch = intout(x);
00121
00122 x->nbstats = 100;
00123 x->minproba = 0.;
00124
00125
00126 switch (argc)
00127 {
00128
00129
00130
00131
00132
00133
00134
00135
00136 case 1:
00137 if (argv->a_type == A_LONG)
00138 x->nbstats = atom_getlong(argv);
00139 break;
00140 default:
00141 object_error((t_object *)x, "Number of stat agents needed");
00142 }
00143
00144
00145
00146 attr_args_process(x, argc, argv);
00147
00149 x->stats = (bc_statelem*)sysmem_newptr(x->nbstats * sizeof(bc_statelem));
00150 long i;
00151 for (i = 0; i< x->nbstats; i++)
00152 bc_yinstats_reset(x, x->stats + i);
00153 x->laststat = 0;
00154 }
00155 return (x);
00156 }
00157
00160 void bc_yinstats_free(t_bc_yinstats *x)
00161 {
00162 long i;
00163 for (i = 0; i< x->nbstats; i++)
00164 {
00166 freeobject(x->stats[i].clock);
00167 }
00168 sysmem_freeptr(x->stats);
00169 }
00170
00173 void bc_yinstats_assist(t_bc_yinstats *x, void *b, long io, long index, char *s)
00174 {
00175 switch (io)
00176 {
00177 case 1:
00178 switch (index)
00179 {
00180 case 0:
00181 sprintf(s, "pitch");
00182 break;
00183 case 1:
00184 sprintf(s, "amplitude");
00185 break;
00186 }
00187 break;
00188 case 2:
00189 switch (index)
00190 {
00191 case 0:
00192 sprintf(s, "coocked pitch");
00193 break;
00194 case 1:
00195 sprintf(s, "average amplitude");
00196 break;
00197 case 2:
00198 sprintf(s,"probability");
00199 break;
00200 }
00201 }
00202 }
00204
00206
00207
00210 void bc_yinstats_amp(t_bc_yinstats *x, double ampin)
00211 {
00212 x->lastamp = ampin;
00213 }
00214
00217 void bc_yinstats_pitch(t_bc_yinstats *x, long pitchin)
00218 {
00219 x->lastpitch = pitchin;
00220 bc_yinstats_addocc(x, pitchin, x->lastamp);
00221 bc_yinstats_addstat(x, pitchin, x->lastamp);
00222 }
00223
00226 void bc_yinstats_stop(t_bc_yinstats *x)
00227 {
00228 long i;
00229 for (i = 0; i< x->laststat; i++)
00230 {
00231 x->stats[i].enable = FALSE;
00232 clock_unset(x->stats[i].clock);
00233 }
00234 x->laststat = 0;
00236 }
00237
00239
00241
00242
00245 bool bc_yinstats_addocc(t_bc_yinstats *x, long pitchin, double ampin)
00246 {
00247 long i;
00248 bool found = FALSE;
00249 for (i = 0; i<=(x->laststat); i++)
00250 {
00251 if (x->stats[i].enable)
00252 {
00253 x->stats[i].nbtot++;
00254 if (x->stats[i].pitch == pitchin)
00255 {
00257 found = TRUE;
00258 x->stats[i].nbOcc++;
00259 x->stats[i].ampacc += ampin;
00260 }
00261 }
00262 }
00263 return found;
00264 }
00265
00268 long bc_yinstats_addstat(t_bc_yinstats *x, long pitchin, double ampin)
00269 {
00270 long i = 0;
00271 while (x->stats[i].enable && i<x->nbstats)
00272 i++;
00273 if (i == x->nbstats)
00274 {
00275 i = 0;
00276 object_error((t_object *)x, "too many events");
00277 }
00278 x->stats[i].enable = TRUE;
00279 x->stats[i].pitch = pitchin;
00280 x->stats[i].ampacc = ampin;
00281 x->stats[i].nbOcc = 1;
00282 x->stats[i].nbtot = 1;
00284 clock_delay(x->stats[i].clock, x->window);
00285 if (i > (x->laststat))
00286 x->laststat = i;
00287 return i;
00288 }
00289
00292 void bc_yinstats_reset(t_bc_yinstats *x, bc_statelem *stat)
00293 {
00295 stat->enable = FALSE;
00296 stat->pitch = 0;
00297 stat->ampacc = 0.;
00298 stat->nbOcc = 0;
00299 stat->nbtot = 0;
00300 stat->proba = 0.;
00301 stat->object = x;
00302 stat->clock = clock_new(stat , (method)bc_yinstats_out);
00303 }
00304
00306
00308
00309
00312 void bc_yinstats_out(bc_statelem *stat)
00313 {
00314 t_bc_yinstats * x = stat->object;
00315 stat->proba = stat->nbOcc / stat->nbtot;
00316 if (stat->proba >= x->minproba)
00317 {
00318 outlet_float(x->out_proba, stat->proba);
00319 outlet_float(x->out_amp, stat->ampacc / stat->nbOcc);
00320 outlet_int(x->out_pitch, stat->pitch);
00321 }
00322 stat->enable = FALSE;
00323 }
00324