testobex example in pattrsdk.pdf
hello,
I tried compiling the testobex external in the pattrsdk.pdf and found a few errors. I corrected the errors but still the example does not work correctly.
firstly, void *class_testobex was declared but then was used as testobex_class twice. so i changed it to class_testobex.
secondly, the attribute 'operand' was registered but then 'data' was used in place of 'operand' . I changed all instances of 'data' to 'operand' and it compiled fine.
When i set up a test in max however, the output value was always 0. I did put a value for operand in the object 'command line' ie
@operand 34
any idea on how to correct this?
chuck
I decided to post the source. It is the same as in pattrsdk.pdf with the changes i mentioned.
I have it working when i manually set operand to the value (which i commented out here), so maybe i am confused by the point of
//handle attribute arguments (e.g. @operand 0.5)
attr_args_process(x, ac, av);
does it not set the values of the attributes to the variable you create and register with class_addattr(c, attr); ?
chuck
#include "ext.h"
#include "ext_obex.h"
typedef struct _testobex
{ t_object ob;
void *obex;
float operand;
void *out;
} t_testobex;
void *class_testobex;
void *testobex_new(t_symbol *s, long ac, t_atom *av);
void testobex_free(t_testobex *x);
void testobex_int(t_testobex *x, long d);
void testobex_float(t_testobex *x, double f);
void main(void)
{ t_class *c;
t_object *attr;
long attrflags = 0;
// define the class – A_GIMME required for attributes
c = class_new("testobex", (method)testobex_new, (method)testobex_free, sizeof(t_testobex), (method)0L, A_GIMME, 0);
// register the obex object's offset
class_obexoffset_set(c, calcoffset(t_testobex, obex));
// create and register an attribute (attr_offset)
attr = attr_offset_new("operand", _sym_float32, attrflags, (method)0L, (method)0L, calcoffset(t_testobex, operand));
class_addattr(c, attr);
// create and register some methods
class_addmethod(c, (method)testobex_int, "int", A_LONG, 0);
class_addmethod(c, (method)testobex_float, "float", A_FLOAT, 0);
// add dumpout and quickref methods
class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
class_addmethod(c, (method)object_obex_quickref, "quickref", A_CANT, 0);
// register the class as an instantiable box
class_register(CLASS_BOX, c);
// set the global class variable
class_testobex = c;
}
void *testobex_new(t_symbol *s, long ac, t_atom *av)
{ t_testobex *x = NULL;
// allocate a new object
if (x = (t_testobex *)object_alloc(class_testobex))
{ // important: initialize class members before processing
// attribute args. otherwise, you might replace data.
x->operand = 0;
//handle attribute arguments (e.g. @operand 0.5)
attr_args_process(x, ac, av);
// if (ac > 1) x->operand = atom_getlong(av+1);
// create a dumpout outlet, used by attributes
object_obex_store(x, _sym_dumpout, outlet_new(x, NULL));
// create another outlet
x->out = outlet_new(x, NULL);
}
return x;
}
void testobex_free(t_testobex *x)
{ ; // nix
}
void testobex_int(t_testobex *x, long d)
{ // int in, int out
outlet_int(x->out, (long)((float)d * x->operand));
}
void testobex_float(t_testobex *x, double f)
{
// float in, float out
outlet_float(x->out, f * x->operand);
}