WoMax Documentation OMax Logo

OMax.learn.c

Go to the documentation of this file.
00001 /*----------------------------------
00002  * OMax.learn - OMax.learn.c
00003  * Created on 13/03/09 by BenCello
00004  *----------------------------------*/
00005 
00007 
00009 
00010 
00011 #ifndef __OMAX_LEARN_MAX_API_
00012 #define __OMAX_LEARN_MAX_API_
00013 
00014 #include "Oracle_learn.hpp"
00015 
00016 extern "C"
00017 {
00018         
00019 #include "ext.h"                                // standard Max include, always required
00020 #include "ext_obex.h"                   // required for new style Max object
00021 #include "jpatcher_api.h"               // required for the color
00022 #include "jgraphics.h"                  // required for the color
00023         
00024 #include "OMax.oracle.h"
00025 #include "OMax.data.h"
00026         
00031         typedef struct _OMax_learn 
00032         {
00033                 t_object        ob;                     
00034                 t_symbol*       oname;          
00035                 O_DataType      datatype;       
00036                 int                     nbcoeffs;       
00037                 t_symbol*       dataname;       
00038                 bool            obound;         
00039                 O_learner       builder;        
00040                 void*           stateout;       
00041         } t_OMax_learn;
00042         
00044         
00046         // Prototypes //
00048         
00049         // Standard Max5 methodes
00050         void *OMax_learn_new(t_symbol *s, long argc, t_atom *argv);
00051         void OMax_learn_free(t_OMax_learn *x);
00052         void OMax_learn_assist(t_OMax_oracle *x, void *b, long io, long index, char *s);
00053         
00054         // Input/ouput routines
00055         void OMax_learn_add(t_OMax_learn *x, t_symbol *s, short ac, t_atom * av);
00056         
00057         // Internal routines
00058         t_symbol * OMax_learn_dataname(t_symbol * oname);
00059         bool OMax_learn_bind(t_OMax_learn *x);
00060         
00061         // Global class pointer variable
00062         t_class *OMax_learn_class;
00063         
00065         // Functions //
00067         
00068         int main(void)
00069         {       
00070                 t_class *c;
00071                 
00072                 c = class_new("OMax.learn", (method)OMax_learn_new, (method)OMax_learn_free, (long)sizeof(t_OMax_learn), 
00073                                           0L /* leave NULL!! */, A_GIMME, 0);
00074                 
00075                 // assistance
00076                 class_addmethod(c, (method)OMax_learn_assist,"assist",A_CANT, 0); 
00077                 
00078                 // input methods
00079                 class_addmethod(c, (method)OMax_learn_add, "add", A_GIMME, 0);
00080                 
00081                 class_register(CLASS_BOX, c); /* CLASS_NOBOX */
00082                 OMax_learn_class = c;
00083                 
00084                 return 0;
00085         }
00086         
00088 
00089         
00092         void *OMax_learn_new(t_symbol *s, long argc, t_atom *argv)
00093         {
00094                 t_OMax_learn *x = NULL;
00095                 
00096                 if (x = (t_OMax_learn *)object_alloc(OMax_learn_class))
00097                 {
00098                         // inlets & outlets
00099                         x->stateout = intout(x);
00100                         
00102                         x->obound = FALSE;
00103                         if (argc == 0)
00104                                 object_error((t_object *)x,"Missing name of the Oracle to build");
00105                         else
00106                         {
00107                                 if (argv->a_type != A_SYM)
00108                                         object_error((t_object *)x,"First argument must be a symbol (name of an existing Oracle)");
00109                                 else
00110                                         x->oname = atom_getsym(argv);
00111                                 x->dataname = OMax_learn_dataname(x->oname);
00112                         }
00113                         
00114                         // color
00115                         t_object *box;
00116                         t_jrgba colorvals;
00117                         jrgba_set(&colorvals, 0.30, 1.0, 0.15, 1.0);
00118                         object_obex_lookup((t_object *)x, gensym("#B"), &box);
00119                         jbox_set_color(box, &colorvals);
00120                 }
00121                 
00122                 return (x);
00123         }
00124         
00127         void OMax_learn_free(t_OMax_learn *x)
00128         {
00129                 ;
00130         }
00131         
00134         void OMax_learn_assist(t_OMax_oracle *x, void *b, long io, long index, char *s)
00135         {
00136                 switch (io)
00137                 {
00138             case 1: // inlets
00139                                 switch (index)
00140                         {
00141                                 case 0: // leftmost
00142                                         sprintf(s, "messages (add ...)");
00143                                         break;
00144                         }
00145                 break;
00146                         case 2: // outlets
00147                                 switch (index)
00148                         {
00149                                 case 0: // leftmost
00150                                         sprintf(s, "state just added");
00151                                         break;
00152                         }
00153                 }
00154         }
00155         
00157         
00159 
00160 
00163         t_symbol * OMax_learn_dataname(t_symbol * oname)
00164         {
00165                 char dataname[128];
00166                 strcpy(dataname,oname->s_name);
00168                 strcat(dataname,"_data");
00169                 return gensym(dataname);
00170         }
00171         
00174         bool OMax_learn_bind(t_OMax_learn *x)
00175         {
00177                 if (x->obound == FALSE)
00178                 {
00180                         if ((x->oname->s_thing) && (ob_sym(x->oname->s_thing) == gensym("OMax.oracle")))
00181                         {
00182                                 x->builder.set_oracle((((t_OMax_oracle*)(x->oname->s_thing))->oracle));
00183                                 object_post((t_object *)x,"Learner bound to Oracle %s", x->oname->s_name);
00184                         }
00185                         else
00186                         {
00187                                 object_error((t_object *)x,"No oracle %s declared", x->oname->s_name);
00188                         }
00189                         
00191                         if ((x->dataname->s_thing) && (ob_sym(x->dataname->s_thing) == gensym("OMax.data")))
00192                         {
00193                                 x->builder.set_data((((t_OMax_data*)(x->dataname->s_thing))->data));
00194                                 x->obound = TRUE;
00195                                 x->datatype = ((t_OMax_data*)(x->dataname->s_thing))->datatype;
00196                                 if (x->datatype == SPECTRAL)
00197                                         x->nbcoeffs = ((t_OMax_data*)(x->dataname->s_thing))->nbcoeffs;
00198                                 ((t_OMax_data*)(x->dataname->s_thing))->noDelete = FALSE;
00199                                 object_post((t_object *)x,"Learner bound to Data of Oracle %s", x->oname->s_name);
00200                         }
00201                         else
00202                         {
00203                                 object_error((t_object *)x,"No data for oracle %s declared", x->oname->s_name);
00204                         }
00205                 }
00206                 // If binding is ok, then don't do it next time.
00207                 return x->obound;
00208         }
00209         
00211         
00213 
00214         
00218         void OMax_learn_add(t_OMax_learn *x, t_symbol *s, short ac, t_atom * av)
00219         {
00221                 if (OMax_learn_bind(x))
00222                 {
00223                         int out;                                
00224                         if (ac>0)
00225                         {
00227                                 switch (x->datatype)
00228                                 {
00229                                         case LETTERS:
00230                                         {
00231                                                 if (av->a_type == A_SYM)
00232                                                 {
00233                                                         int statenb;
00234                                                         O_char newdata (*atom_getsym(av)->s_name);
00235                                                         statenb = x->builder.get_data()->get_size()-1;
00236                                                         if (statenb>0)
00237                                                                 newdata.set_bufferef(statenb);
00238                                                         else
00239                                                                 newdata.set_bufferef(0);
00240                                                         newdata.set_duration(1);
00241                                                         
00242                                                         ATOMIC_INCREMENT(&((t_OMax_oracle *)(x->oname->s_thing))->wflag);
00243                                                         ATOMIC_INCREMENT(&((t_OMax_data *)(x->dataname->s_thing))->wflag);
00244                                                         if (!(((t_OMax_oracle *)(x->oname->s_thing))->readcount)
00245                                                                 && !(((t_OMax_data *)(x->dataname->s_thing))->readcount))
00246                                                         {
00248                                                                 out = x->builder.add(newdata);
00249                                                         }
00250                                                         else
00251                                                                 object_error((t_object *)x,"Oracle %s being read (%d, %d)",x->oname->s_name, ((t_OMax_oracle *)(x->oname->s_thing))->readcount, ((t_OMax_data *)(x->dataname->s_thing))->readcount);
00252                                                         ATOMIC_DECREMENT(&((t_OMax_oracle *)(x->oname->s_thing))->wflag);
00253                                                         ATOMIC_DECREMENT(&((t_OMax_data *)(x->dataname->s_thing))->wflag);
00254                                                 }
00255                                                 else
00256                                                         object_error((t_object *)x,"Wrong type of data");
00257                                                 break;
00258                                                 
00259                                         }
00260                                         case MIDI_MONO:
00261                                         {
00262                                                 O_MIDI_mono * newdata = new O_MIDI_mono();
00263                                                 bool valid = TRUE;
00264                                                 switch(ac)
00265                                                 {
00266                                                         case 6:
00267                                                                 if ((av+5)->a_type == A_LONG)
00268                                                                         ((O_label*)newdata)->set_duration(atom_getlong(av+5));
00269                                                                 else
00270                                                                 {
00271                                                                         object_error((t_object *)x, "Error in input, duration must be int");
00272                                                                         valid = FALSE;
00273                                                                         break;
00274                                                                 }
00275                                                         case 5:
00276                                                                 if ((av+4)->a_type == A_LONG)
00277                                                                         ((O_label*)newdata)->set_bufferef(atom_getlong(av+4));
00278                                                                 else
00279                                                                 {
00280                                                                         object_error((t_object *)x, "Error in input, buffer reference must be int");
00281                                                                         valid = FALSE;
00282                                                                         break;
00283                                                                 }
00284                                                         case 4:
00285                                                                 if ((av+3)->a_type == A_LONG)
00286                                                                         ((O_label*)newdata)->set_section(atom_getlong(av+3));
00287                                                                 else
00288                                                                 {
00289                                                                         object_error((t_object *)x, "Error in input, section must be int");
00290                                                                         valid = FALSE;
00291                                                                         break;
00292                                                                 }
00293                                                         case 3:
00294                                                                 if ((av+2)->a_type == A_LONG)
00295                                                                         ((O_label*)newdata)->set_phrase(atom_getlong(av+2));
00296                                                                 else
00297                                                                 {
00298                                                                         object_error((t_object *)x, "Error in input, phrase must be int");
00299                                                                         valid = FALSE;
00300                                                                         break;
00301                                                                 }
00302                                                         case 2:
00303                                                                 if ((av+1)->a_type == A_LONG)
00304                                                                         newdata->set_velocity(atom_getlong(av+1));
00305                                                                 else
00306                                                                 {
00307                                                                         object_error((t_object *)x, "Error in input, velocity must be int");
00308                                                                         valid = FALSE;
00309                                                                         break;
00310                                                                 }
00311                                                         case 1:
00312                                                                 if (av->a_type == A_LONG)
00313                                                                         newdata->set_pitch(atom_getlong(av));
00314                                                                 else
00315                                                                 {
00316                                                                         object_error((t_object *)x, "Error in input, pitch must be int");
00317                                                                         valid = FALSE;
00318                                                                 }
00319                                                                 break;
00320                                                         default:
00321                                                                 object_error((t_object *)x, "Error in input, too many arguments");
00322                                                                 valid = FALSE;
00323                                                                 break;
00324                                                 }
00325                                                 ATOMIC_INCREMENT(&((t_OMax_oracle *)(x->oname->s_thing))->wflag);
00326                                                 ATOMIC_INCREMENT(&((t_OMax_data *)(x->dataname->s_thing))->wflag);
00327                                                 if (!(((t_OMax_oracle *)(x->oname->s_thing))->readcount)
00328                                                         && !(((t_OMax_data *)(x->dataname->s_thing))->readcount))
00329                                                 {
00331                                                         out = x->builder.add(*newdata);
00332                                                 }
00333                                                 else
00334                                                         object_error((t_object *)x,"Oracle %s being read (%d, %d)",x->oname->s_name, ((t_OMax_oracle *)(x->oname->s_thing))->readcount, ((t_OMax_data *)(x->dataname->s_thing))->readcount);
00335                                                 ATOMIC_DECREMENT(&((t_OMax_oracle *)(x->oname->s_thing))->wflag);
00336                                                 ATOMIC_DECREMENT(&((t_OMax_data *)(x->dataname->s_thing))->wflag);
00337                                                 break;
00338                                         }
00339                                         case SPECTRAL:
00340                                                 int pitchin;
00341                                                 int coeffcount;
00342                                                 bool valid = TRUE;
00343                                                 O_spectral * newdata;
00344                                                 if(ac < (x->nbcoeffs+1)) {
00345                                                         object_error((t_object *)x, "Missing coefficients");
00346                                                         valid = FALSE;
00347                                                 }
00348                                                 else
00349                                                 {
00350                                                         if ((av)->a_type == A_LONG)
00351                                                                 pitchin = atom_getlong(av);
00352                                                         else
00353                                                                 valid = FALSE;
00354                                                         list<float> coeffsin;
00355                                                         for (coeffcount = 0; coeffcount < x->nbcoeffs; coeffcount++)
00356                                                         {
00357                                                                 if((av+coeffcount+1)->a_type == A_FLOAT)
00358                                                                         coeffsin.push_back(atom_getfloat(av+coeffcount+1));
00359                                                                 else {
00360                                                                         object_error((t_object *)x, "Wrong types in coefficents");
00361                                                                         valid = FALSE;
00362                                                                 }
00363                                                         }
00364                                                         newdata = new O_spectral(pitchin, coeffsin);
00365                                                         if (ac >= x->nbcoeffs+2) {
00366                                                                 if ((av+x->nbcoeffs+1)->a_type == A_LONG)
00367                                                                         ((O_label*)newdata)->set_phrase(atom_getlong(av+x->nbcoeffs+1));
00368                                                                 else
00369                                                                 {
00370                                                                         object_error((t_object *)x, "Error in input, phrase must be int");
00371                                                                         valid = FALSE;
00372                                                                 }
00373                                                                 if (ac >= x->nbcoeffs+3) {
00374                                                                         if ((av+x->nbcoeffs+2)->a_type == A_LONG)
00375                                                                                 ((O_label*)newdata)->set_section(atom_getlong(av+x->nbcoeffs+2));
00376                                                                         else
00377                                                                         {
00378                                                                                 object_error((t_object *)x, "Error in input, section must be int");
00379                                                                                 valid = FALSE;
00380                                                                         }
00381                                                                         if (ac >= x->nbcoeffs+4) {
00382                                                                                 if ((av+x->nbcoeffs+3)->a_type == A_LONG)
00383                                                                                         ((O_label*)newdata)->set_bufferef(atom_getlong(av+x->nbcoeffs+3));
00384                                                                                 else
00385                                                                                 {
00386                                                                                         object_error((t_object *)x, "Error in input, buffer reference must be int");
00387                                                                                         valid = FALSE;
00388                                                                                 }
00389                                                                                 if (ac == x->nbcoeffs+5) {
00390                                                                                         if ((av+x->nbcoeffs+4)->a_type == A_LONG)
00391                                                                                                 ((O_label*)newdata)->set_duration(atom_getlong(av+x->nbcoeffs+4));
00392                                                                                         else
00393                                                                                         {
00394                                                                                                 object_error((t_object *)x, "Error in input, duration must be int");
00395                                                                                                 valid = FALSE;
00396                                                                                         }
00397                                                                                         
00398                                                                                 }
00399                                                                                 else {
00400                                                                                         object_error((t_object *)x, "Error in input, too many arguments");
00401                                                                                         valid = FALSE;
00402                                                                                 }
00403                                                                         }}}
00404                                                 }
00405                                                 ATOMIC_INCREMENT(&((t_OMax_oracle *)(x->oname->s_thing))->wflag);
00406                                                 ATOMIC_INCREMENT(&((t_OMax_data *)(x->dataname->s_thing))->wflag);
00407                                                 if (!(((t_OMax_oracle *)(x->oname->s_thing))->readcount)
00408                                                         && !(((t_OMax_data *)(x->dataname->s_thing))->readcount))
00409                                                 {
00411                                                         out = x->builder.add(*newdata);
00412                                                 }
00413                                                 else
00414                                                         object_error((t_object *)x,"Oracle %s being read (%d, %d)",x->oname->s_name, ((t_OMax_oracle *)(x->oname->s_thing))->readcount, ((t_OMax_data *)(x->dataname->s_thing))->readcount);
00415                                                 ATOMIC_DECREMENT(&((t_OMax_oracle *)(x->oname->s_thing))->wflag);
00416                                                 ATOMIC_DECREMENT(&((t_OMax_data *)(x->dataname->s_thing))->wflag);
00417                                                 break;          
00418                                 }
00420                                 outlet_int(x->stateout, out);
00421                         }
00422                         else
00423                                 object_error((t_object *)x,"Error in input, too few arguments");
00424                 }
00425         }
00426         
00428 }
00429 
00430 
00431 #endif

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