00001
00002
00003
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"
00020 #include "ext_obex.h"
00021 #include "jpatcher_api.h"
00022 #include "jgraphics.h"
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
00048
00049
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
00055 void OMax_learn_add(t_OMax_learn *x, t_symbol *s, short ac, t_atom * av);
00056
00057
00058 t_symbol * OMax_learn_dataname(t_symbol * oname);
00059 bool OMax_learn_bind(t_OMax_learn *x);
00060
00061
00062 t_class *OMax_learn_class;
00063
00065
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 , A_GIMME, 0);
00074
00075
00076 class_addmethod(c, (method)OMax_learn_assist,"assist",A_CANT, 0);
00077
00078
00079 class_addmethod(c, (method)OMax_learn_add, "add", A_GIMME, 0);
00080
00081 class_register(CLASS_BOX, c);
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
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
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:
00139 switch (index)
00140 {
00141 case 0:
00142 sprintf(s, "messages (add ...)");
00143 break;
00144 }
00145 break;
00146 case 2:
00147 switch (index)
00148 {
00149 case 0:
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
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