WoMax Documentation

# OMax.render.c

Go to the documentation of this file.

    00001 /*--------------------------------------
    00002  * OMax.render - OMax.render.c
    00003  * Created on 20/03/09 by BenCello
    00004  *--------------------------------------*/
    00005
    00007
    00009
    00010
    00011 #ifndef __OMax_render_MAX_API_
    00012 #define __OMax_render_MAX_API_
    00013
    00014 #include <stdlib.h>
    00015 #include <list>
    00016 using namespace std;
    00017 #include "Oracle_data.hpp"
    00018
    00019 extern "C"
    00020 {
    00021
    00022 #include "ext.h"                                // standard Max include, always required
    00023 #include "ext_obex.h"                   // required for new style Max object
    00024 #include "jpatcher_api.h"               // required for the color
    00025 #include "jgraphics.h"                  // required for the color
    00026
    00027 #include "OMax.data.h"
    00028
    00033         typedef struct _OMax_render
    00034         {
    00035                 t_object        ob;
    00036                 t_symbol*       oname;
    00037                 t_symbol*       dataname;
    00038                 bool            obound;
    00039                 O_DataType      datatype;
    00040                 int                     nbcoeffs;
    00041                 O_data*         data;
    00042                 t_atom*         twout;
    00043                 t_atom*         coefout;
    00044                 list<float>*coeflist;
    00045                 float*          coeftab;
    00046                 void*           out_statenb;
    00047                 void*           out_buf;
    00048                 void*           out_sectphr;
    00049                 void*           out_data;
    00050                 void*           out_bang;
    00051         } t_OMax_render;
    00052
    00054
    00056         // Prototypes //
    00058
    00059         // Standard Max5 methodes
    00060         void *OMax_render_new(t_symbol *s, long argc, t_atom *argv);
    00061         void OMax_render_free(t_OMax_render *x);
    00062         void OMax_render_assist(t_OMax_render *x, void *b, long io, long index, char *s);
    00063
    00064         // Input/ouput routines
    00065         void OMax_render_read(t_OMax_render *x, long statnb);
    00066         void OMax_render_setname(t_OMax_render *x, t_symbol *newname);
    00067
    00068         // Internal routines
    00069         t_symbol * OMax_render_name(t_symbol * oname);
    00070         bool OMax_render_bind(t_OMax_render *x);
    00071
    00072         // Global class pointer variable
    00073         t_class *OMax_render_class;
    00074
    00076         // Functions //
    00078
    00079         int main(void)
    00080         {
    00081                 t_class *c;
    00082
    00083                 c = class_new("OMax.render", (method)OMax_render_new, (method)OMax_render_free, (long)sizeof(t_OMax_render),
    00084                                           0L /* leave NULL!! */, A_GIMME, 0);
    00085
    00086                 // assistance
    00087                 class_addmethod(c, (method)OMax_render_assist,"assist",A_CANT, 0);
    00088
    00089                 // input methods
    00090                 class_addmethod(c, (method)OMax_render_read,"int", A_LONG, 0);
    00091                 class_addmethod(c, (method)OMax_render_setname, "set", A_DEFSYM, 0);
    00092
    00093                 class_register(CLASS_BOX, c); /* CLASS_NOBOX */
    00094                 OMax_render_class = c;
    00095
    00096                 return 0;
    00097         }
    00098
    00100
    00101
    00104         void *OMax_render_new(t_symbol *s, long argc, t_atom *argv)
    00105         {
    00106                 t_OMax_render *x = NULL;
    00107
    00108                 if (x = (t_OMax_render *)object_alloc(OMax_render_class))
    00109                 {
    00110                         // allocation
    00111                         char err;
    00112                         long i = 0;
    00113                         atom_alloc_array(2, &i, &x->twout, &err);
    00114                         if (!err || i!=2)
    00115                                 object_error((t_object*)x, "Allocation error");
    00116
    00117                         // outlet init
    00118                         x->out_statenb = intout(x); // rightmost
    00119                         x->out_buf = listout(x);
    00120                         x->out_sectphr = listout(x);
    00121                         x->out_data = outlet_new(x,NULL);
    00122                         x->out_bang= bangout(x);
    00123
    00125                         x->obound = FALSE;
    00126                         if (argc == 0)
    00127                                 object_error((t_object *)x,"Missing name of the Oracle data to read");
    00128                         else
    00129                         {
    00130                                 if (argv->a_type != A_SYM)
    00131                                         object_error((t_object *)x,"First argument must be a symbol (name of an existing Oracle)");
    00132                                 else
    00133                                         x->oname = atom_getsym(argv);
    00134                         }
    00135
    00136                         // color
    00137                         t_object *box;
    00138                         t_jrgba colorvals;
    00139                         jrgba_set(&colorvals, 0.30, 1.0, 0.15, 1.0);
    00140                         object_obex_lookup((t_object *)x, gensym("#B"), &box);
    00141                         jbox_set_color(box, &colorvals);
    00142                 }
    00143                 return (x);
    00144         }
    00145
    00148         void OMax_render_free(t_OMax_render *x)
    00149         {
    00150                 ;
    00151         }
    00152
    00155         void OMax_render_assist(t_OMax_render *x, void *b, long io, long index, char *s)
    00156         {
    00157                 switch (io)
    00158                 {
    00159             case 1: // inlets
    00160                                 switch (index)
    00161                         {
    00162                                 case 0: // leftmost
    00163                                         sprintf(s, "state to read, set [symbol] changes sequence to read");
    00164                                         break;
    00165                         }
    00166                 break;
    00167             case 2: // outlets
    00168                                 switch (index)
    00169                         {
    00170                                 case 0:
    00171                                         sprintf(s, "bang when done");
    00172                                         break;
    00173                                 case 1: // leftmost
    00174                                         sprintf(s, "data");
    00175                                         break;
    00176                                 case 2:
    00177                                         sprintf(s, "section & phrase");
    00178                                         break;
    00179                                 case 3:
    00180                                         sprintf(s, "buffer date & duration");
    00181                                         break;
    00182                                 case 4:
    00183                                         sprintf(s, "state number");
    00184                                         break;
    00185                         }
    00186                                 break;
    00187                 }
    00188         }
    00189
    00191
    00193
    00194
    00197         t_symbol * OMax_render_name(t_symbol * oname)
    00198         {
    00199                 char dataname[128];
    00200                 strcpy(dataname,oname->s_name);
    00202                 strcat(dataname,"_data");
    00203                 return gensym(dataname);
    00204         }
    00205
    00208         bool OMax_render_bind(t_OMax_render *x)
    00209         {
    00211                 if (x->obound == FALSE)
    00212                 {
    00214                         x->dataname = OMax_render_name(x->oname);
    00215                         if ((x->dataname->s_thing) && (ob_sym(x->dataname->s_thing) == gensym("OMax.data")))
    00216                         {
    00217                                 x->data = &(((t_OMax_data*)(x->dataname->s_thing))->data);
    00218                                 // If binding is ok, then don't do it next time.
    00219                                 x->obound = TRUE;
    00221                                 x->datatype = ((t_OMax_data*)(x->dataname->s_thing))->datatype;
    00222                                 if (x->datatype == SPECTRAL)
    00223                                 {
    00224                                         x->nbcoeffs = ((t_OMax_data*)(x->dataname->s_thing))->nbcoeffs;
    00225                                         // allocation for coeff output
    00226                                         x->coeflist = new list<float>(x->nbcoeffs);
    00227                                         x->coeftab = (float*)malloc((x->nbcoeffs)*sizeof(float));
    00228                                         char err;
    00229                                         long i = 0;
    00230                                         atom_alloc_array(x->nbcoeffs, &i, &x->coefout, &err);
    00231                                         if (!err || i!=x->nbcoeffs)
    00232                                                 object_error((t_object*)x, "Allocation error");
    00233                                 }
    00234                         }
    00235                         else
    00236                         {
    00237                                 object_error((t_object *)x,"No data for Oracle %s declared", x->oname->s_name);
    00238                         }
    00239                 }
    00240                 return x->obound;
    00241         }
    00242
    00244
    00246
    00247
    00251         void OMax_render_setname(t_OMax_render *x, t_symbol *s)
    00252         {
    00253                 x->oname = s;
    00254                 x->obound = FALSE;
    00255                 OMax_render_bind(x);
    00256         }
    00257
    00261         void OMax_render_read(t_OMax_render *x, long statnb)
    00262         {
    00263                 if (OMax_render_bind(x))
    00264                 {
    00265                         ATOMIC_INCREMENT(&(((t_OMax_data *)(x->dataname->s_thing))->readcount));
    00266                         if(!(((t_OMax_data *)(x->dataname->s_thing))->wflag))
    00267                         {
    00268                                 if ((statnb>=0) && (statnb<(long)(x->data->get_size())))
    00269                                 {
    00270                                         O_label * labL = (*x->data)[statnb];
    00271
    00272                                         // state number
    00273                                         outlet_int(x->out_statenb, labL->get_statenb()); // output
    00274
    00275                                         // date & duration
    00276                                         atom_setlong(x->twout, labL->get_bufferef());
    00277                                         atom_setlong(x->twout+1, labL->get_duration());
    00278                                         outlet_list(x->out_buf, NULL, 2, x->twout); // output
    00279
    00280                                         // section & phrase
    00281                                         atom_setlong(x->twout, labL->get_section());
    00282                                         atom_setlong(x->twout+1, labL->get_phrase());
    00283                                         outlet_list(x->out_sectphr, NULL, 2, x->twout); // output
    00284
    00285                                         // data
    00286                                         switch(x->datatype)
    00287                                         {
    00288                                                 case LETTERS:
    00289                                                 {
    00290                                                         t_symbol * symout;
    00291                                                         char carout[2];
    00292                                                         *carout = ((O_char*)labL)->get_letter();
    00293                                                         *(carout+1) = '\0';
    00294                                                         symout = gensym(carout);
    00295                                                         outlet_anything(x->out_data, symout,0,NULL); // output
    00296                                                         break;
    00297                                                 }
    00298                                                 case MIDI_MONO:
    00299                                                 {
    00300                                                         atom_setlong(x->twout, ((O_MIDI_mono*)labL)->get_pitch());
    00301                                                         atom_setlong(x->twout+1, ((O_MIDI_mono*)labL)->get_velocity());
    00302                                                         outlet_list(x->out_data, NULL, 2, x->twout); // output
    00303                                                         break;
    00304                                                 }
    00305                                                 case SPECTRAL:
    00306                                                 {
    00307                                                         outlet_int(x->out_data, ((O_spectral*)labL)->get_pitch()); // output pitch first
    00308                                                         *x->coeflist = ((O_spectral*)labL)->get_coeffs();
    00309                                                         list<float>::iterator it = x->coeflist->begin();
    00310                                                         int coefi;
    00311                                                         for (coefi = 0; coefi< x->nbcoeffs; coefi++)
    00312                                                         {
    00313                                                                 x->coeftab[coefi] = (*it);
    00314                                                                 it ++;
    00315                                                         }
    00316                                                         atom_setfloat_array(x->nbcoeffs, x->coefout, x->nbcoeffs, x->coeftab);
    00317                                                         outlet_list(x->out_data, NULL,x->nbcoeffs, x->coefout); // then output coeffs
    00318                                                         break;
    00319                                                 }
    00320
    00321                                         }
    00322
    00323                                         outlet_bang(x->out_bang);
    00324
    00325                                 }
    00326                                 //else
    00327                                 //object_post((t_object *)x,"State %ld outside Oracles bounds", statnb, x->oname->s_name);
    00328                         }
    00329                         else
    00330                                 object_error((t_object *)x,"Data of Oracle %s busy",x->oname->s_name);
    00331                         ATOMIC_DECREMENT(&(((t_OMax_data *)(x->dataname->s_thing))->readcount));
    00332                 }
    00333         }
    00334
    00336 }
    00337
    00338 #endif