obex and DSP objects - is it possible?


    Jun 26 2006 | 11:35 pm

    • Jun 27 2006 | 4:38 am
    • Jun 27 2006 | 9:46 am
      Jeremy Bernstein wrote: > Olaf, > > Happy to look at this, but I need source code. I have successfully > obex-ified MSP objects, though, so I know it's possible.
      Hi Jeremy,
      example code is attached (I hope attachmewnt will get through). It's basically the myregob example code extended in order to be a DSP object. While hacking this together I noticed that in case I create one signal inlet, my object shows up with 1 inlet and I can't connect a signal to it. In case I create the object to have 2 signal inlets, it has two inlets, I stil can't connect a signal to the first, but I can connect a signal to the second inlet...
      The crashes when I set up the signal inlet too early in the mydspob_new() don't happen with this code, so something else must be wrong with my orignal code.
      Olaf
      /* mydspob Copyright 2004 - Cycling '74 jeremy bernstein - jeremy@bootsquad.com
      Modified into DSP object by Olaf Matthes in order to demonstrate inability to connect a signal cord to the object's signal inlet. */
      #include "ext.h" #include "ext_common.h" #include "ext_obex.h" #include "z_dsp.h"
      typedef struct _mydspob { t_pxobject ob; void *obex; void *mmo; // minimetro objects void *out[4]; // 4 outlets long count; long inlet_no; } t_mydspob;
      void mydspob_dsp(t_mydspob *x, t_mydspob **sp); void *mydspob_new(t_symbol *s, long argc, t_atom *argv); void mydspob_free(t_mydspob *x); void mydspob_assist(t_mydspob *x, void *b, long m, long a, char *s); void mydspob_notify(t_mydspob *x, t_symbol *s, t_symbol *msg, void *sender, void *data);
      void mydspob_int(t_mydspob *x, long c); void mydspob_speed(t_mydspob *x, double speed); // pattr support function prototypes t_max_err mydspob_getvalueof(t_mydspob *x, long *ac, t_atom **av); t_max_err mydspob_setvalueof(t_mydspob *x, long ac, t_atom *av);
      void minimetro_init(void);
      void *mydspob_class;
      void main(void) { t_class *c; void *attr; long attrflags = 0;
      c = class_new("mydspob", (method)mydspob_new, (method)mydspob_free, (short)sizeof(t_mydspob), 0L, A_GIMME, 0);
      // initialize the common symbols, since we want to use them common_symbols_init(); dsp_initclass(); // we are a DSP object
      // initialize the minimetro class minimetro_init();
      // register the byte offset of obex with the class class_obexoffset_set(c, calcoffset(t_mydspob, obex));
      // add some attributes
      // add method for signals class_addmethod(c, (method)mydspob_dsp, "dsp", A_CANT, 0);
      // add methods to the class class_addmethod(c, (method)mydspob_int, "int", A_LONG,0); class_addmethod(c, (method)mydspob_speed, "speed", A_FLOAT,0); class_addmethod(c, (method)mydspob_assist, "assist", A_CANT,0);
      // these methods support the pattr set of objects class_addmethod(c, (method)mydspob_getvalueof, "getvalueof", A_CANT,0); class_addmethod(c, (method)mydspob_setvalueof, "setvalueof", A_CANT,0);
      // add a notify method, so we get notifications from child objects class_addmethod(c, (method)mydspob_notify, "notify", A_CANT, 0); // add methods for dumpout and quickref class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0); class_addmethod(c, (method)object_obex_quickref, "quickref", A_CANT, 0);
      // we want this class to instantiate inside of the Max UI; ergo CLASS_BOX class_register(CLASS_BOX, c); mydspob_class = c; }
      t_max_err mydspob_getvalueof(t_mydspob *x, long *ac, t_atom **av) { // not implemented return MAX_ERR_NONE; }
      t_max_err mydspob_setvalueof(t_mydspob *x, long ac, t_atom *av) { // not implemented return MAX_ERR_NONE; }
      void mydspob_assist(t_mydspob *x, void *b, long m, long a, char *s) { if (m == 1) { //input sprintf(s, "0 / 1, speed"); } else { //output if (a == x->count) sprintf(s, "dumpout"); else sprintf(s, "bang out"); } }
      void mydspob_int(t_mydspob *x, long c) { }
      void mydspob_speed(t_mydspob *x, double speed) { }
      void mydspob_notify(t_mydspob *x, t_symbol *s, t_symbol *msg, void *sender, void *data) { if (msg == _sym_bang) { // bang the outlet sent as data // outlet_bang(x->out[(long)data]); } else if (msg == _sym_free) { // this message is sent when the object is freeing object_detach(gensym("_regob_test"), s, x); object_unregister(sender); } }
      void mydspob_dsp(t_mydspob *x, t_mydspob **sp) { ; // just a fake for now }
      void mydspob_free(t_mydspob *x) { dsp_free((t_pxobject *)x);
      if (x->mmo) object_free(x->mmo); }
      void *mydspob_new(t_symbol *s, long ac, t_atom *av) { t_mydspob *x; t_symbol *name; long i;
      // we use object_alloc here, rather than newobject if (x = (t_mydspob *)object_alloc(mydspob_class)) { //only max object, no jit object // add a dumpout outlet object_obex_store(x, _sym_dumpout, outlet_new(x, NULL));
      /* register us with the DSP chain */ dsp_setup((t_pxobject *)x, 1); /* 1 signal input */
      /* create outlets (right to left) */ x->out[3] = floatout((t_object *)x); x->out[2] = floatout((t_object *)x); x->out[1] = bangout((t_object *)x); x->out[0] = floatout((t_object *)x);
      x->count = 1;
      x->mmo = object_new(CLASS_NOBOX, gensym("minimetro"), 0, 10); object_register(gensym("_regob_test"), name = symbol_unique(), x->mmo); object_attach(gensym("_regob_test"), name, x);
      attr_args_process(x, ac, av); } return (x); }
    • Jun 27 2006 | 9:57 am
      Try the following in main() - I think it's just the one thing: you need class_dspinit() instead of dsp_initclass()
      jb
      void main(void) { t_class *c; void *attr; long attrflags = 0;
      c = class_new("mydspob", (method)mydspob_new, (method)mydspob_free, (short)sizeof(t_mydspob), 0L, A_GIMME, 0);
      // initialize the common symbols, since we want to use them common_symbols_init(); // NO! THIS IS FOR NORMAL MAX CLASSES - see below // dsp_initclass(); // we are a DSP object
      // initialize the minimetro class minimetro_init();
      // register the byte offset of obex with the class class_obexoffset_set(c, calcoffset(t_mydspob, obex));
      // add some attributes
      // add method for signals class_addmethod(c, (method)mydspob_dsp, "dsp", A_CANT, 0);
      // add methods to the class class_addmethod(c, (method)mydspob_int, "int", A_LONG,0); class_addmethod(c, (method)mydspob_speed, "speed", A_FLOAT,0); class_addmethod(c, (method)mydspob_assist, "assist", A_CANT,0);
      // these methods support the pattr set of objects class_addmethod(c, (method)mydspob_getvalueof, "getvalueof", A_CANT,0); class_addmethod(c, (method)mydspob_setvalueof, "setvalueof", A_CANT,0);
      // add a notify method, so we get notifications from child objects class_addmethod(c, (method)mydspob_notify, "notify", A_CANT, 0); // add methods for dumpout and quickref class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0); class_addmethod(c, (method)object_obex_quickref, "quickref", A_CANT, 0);
      // THIS IS THE OBEX CALL FOR DSPINIT class_dspinit(c); // we want this class to instantiate inside of the Max UI; ergo CLASS_BOX class_register(CLASS_BOX, c); mydspob_class = c; }
      Am 27.06.2006 um 11:46 schrieb Olaf Matthes:
      > void main(void) > { > t_class *c; > void *attr; > long attrflags = 0; > > c = class_new("mydspob", (method)mydspob_new, (method) > mydspob_free, (short)sizeof(t_mydspob), > 0L, A_GIMME, 0); > > // initialize the common symbols, since we want to use them > common_symbols_init(); > dsp_initclass(); // we are a DSP object > > // initialize the minimetro class > minimetro_init(); > > // register the byte offset of obex with the class > class_obexoffset_set(c, calcoffset(t_mydspob, obex)); > > // add some attributes > > // add method for signals > class_addmethod(c, (method)mydspob_dsp, "dsp", A_CANT, 0); > > // add methods to the class > class_addmethod(c, (method)mydspob_int, "int", A_LONG,0); > class_addmethod(c, (method)mydspob_speed, "speed", A_FLOAT,0); > class_addmethod(c, (method)mydspob_assist, "assist", A_CANT,0); > > // these methods support the pattr set of objects > class_addmethod(c, (method)mydspob_getvalueof, "getvalueof", > A_CANT,0); > class_addmethod(c, (method)mydspob_setvalueof, "setvalueof", > A_CANT,0); > > // add a notify method, so we get notifications from child objects > class_addmethod(c, (method)mydspob_notify, "notify", A_CANT, 0); > // add methods for dumpout and quickref > class_addmethod(c, (method)object_obex_dumpout, "dumpout", > A_CANT, 0); > class_addmethod(c, (method)object_obex_quickref, "quickref", > A_CANT, 0); > > // we want this class to instantiate inside of the Max UI; ergo > CLASS_BOX > class_register(CLASS_BOX, c); > mydspob_class = c;
    • Jun 27 2006 | 10:07 am
      Jeremy Bernstein wrote:
      > Try the following in main() - I think it's just the one thing: you need > class_dspinit() instead of dsp_initclass()
      Thanks, that did the trick! :-)
      Olaf