WoMax Documentation

# bc.yinstats.c

Go to the documentation of this file.

    00001 /*--------------------------------------
    00002  * bc.stat - bc.stat.c
    00003  * Created on 24/11/09 by Benjamin Levy
    00004  *--------------------------------------*/
    00005
    00008
    00009
    00010 #include "ext.h"                                // standard Max include, always required
    00011 #include "ext_obex.h"                   // required for new style Max object
    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 // prototypes //
    00052
    00053 // Standard Max5 methodes
    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 // Input/ouput routines
    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 // Internal routines
    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 // Global class pointer variable
    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         // assistance
    00080     class_addmethod(c, (method)bc_yinstats_assist,"assist",A_CANT, 0);
    00081
    00082         // input methods
    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); /* CLASS_NOBOX */
    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                 // inlets
    00115                 floatin(x, 1); // amplitude
    00116
    00117                 // outlets
    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                 // process arguments
    00126                 switch (argc)
    00127                 {
    00128                         /*
    00129                         case 3:
    00130                                 if ((argv + 2)->a_type == A_FLOAT);
    00131                                         x->minproba = atom_getfloat(argv + 2);
    00132                         case 2:
    00133                                 if ((argv + 1)->a_type == A_LONG);
    00134                                         x->window = atom_getlong(argv + 1);
    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                 // process attributes
    00145                 // override arguments if needed
    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: // inlets
    00178                         switch (index)
    00179                 {
    00180                         case 0: // leftmost
    00181                                 sprintf(s, "pitch");
    00182                                 break;
    00183                         case 1:
    00184                                 sprintf(s, "amplitude");
    00185                                 break;
    00186                 }
    00187                         break;
    00188                 case 2: // outlets
    00189                         switch (index)
    00190                 {
    00191                         case 0: // leftmost
    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