Forums > Dev

obex and DSP objects – is it possible?

June 26, 2006 | 11:35 pm


June 27, 2006 | 4:38 am


June 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);
}


June 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;


June 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


Viewing 5 posts - 1 through 5 (of 5 total)