WoMax Documentation OMax Logo

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 

Generated on 16 Mar 2010 for Benjamin Lévy by  doxygen 1.6.1