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