12 #include "ext_hashtab.h"
14 #define MAX_NUM_INLETS 16
17 typedef struct _wrappedInstance {
20 TTPtr graphOutlets[MAX_NUM_INLETS];
21 TTPtr inlets[MAX_NUM_INLETS];
22 WrappedClassPtr wrappedClassDefinition;
29 static t_hashtab* wrappedMaxClasses = NULL;
32 t_object* wrappedClass_new(t_symbol* name,
long argc, t_atom* argv)
34 WrappedClass* wrappedMaxClass = NULL;
40 long attrstart = attr_args_offset(argc, argv);
43 hashtab_lookup(wrappedMaxClasses, name, (t_object**)&wrappedMaxClass);
47 if (wrappedMaxClass) {
48 if (wrappedMaxClass->validityCheck)
49 err = wrappedMaxClass->validityCheck(wrappedMaxClass->validityCheckArgument);
60 if (wrappedMaxClass->options && !wrappedMaxClass->options->lookup(
TT(
"argumentDefinesNumInlets"), v)) {
61 int argumentOffsetToDefineTheNumberOfInlets = v;
62 if ((attrstart-argumentOffsetToDefineTheNumberOfInlets > 0) && argv+argumentOffsetToDefineTheNumberOfInlets)
63 numInputs = atom_getlong(argv+argumentOffsetToDefineTheNumberOfInlets);
65 for (
TTUInt16 i=numInputs-1; i>0; i--)
66 self->inlets[i-1] = proxy_new(
self, i, NULL);
68 object_obex_store((
void*)
self, _sym_dumpout, (
object*)outlet_new(
self, NULL));
69 if (wrappedMaxClass->options && !wrappedMaxClass->options->lookup(
TT(
"argumentDefinesNumOutlets"), v)) {
70 int argumentOffsetToDefineTheNumberOfOutlets = v;
71 if ((attrstart-argumentOffsetToDefineTheNumberOfOutlets > 0) && argv+argumentOffsetToDefineTheNumberOfOutlets)
72 numOutputs = atom_getlong(argv+argumentOffsetToDefineTheNumberOfOutlets);
74 for (
TTInt16 i=numOutputs-1; i>=0; i--)
75 self->graphOutlets[i] = outlet_new(
self,
"audio.connect");
77 self->wrappedClassDefinition = wrappedMaxClass;
79 v[0] = wrappedMaxClass->ttClassName;
84 attr_args_process(
self, argc, argv);
86 return (t_object*)
self;
92 if (self->graphObject)
95 for (
int i=0; i<MAX_NUM_INLETS; i++) {
97 object_free(self->inlets[i]);
106 TTErr MaxGraphReset(t_object* x)
109 return self->graphObject->reset();
113 TTErr MaxGraphSetup(t_object* x)
119 atom_setobj(a+0, (t_object*)self->graphObject);
120 while (self->graphOutlets[i]) {
121 atom_setlong(a+1, i);
122 outlet_anything(self->graphOutlets[i], gensym(
"graph.connect"), 2, a);
132 long inletNumber = proxy_getinlet(SELF);
134 return self->graphObject->connect(audioSourceObject, sourceOutletNumber, inletNumber);
138 TTErr MaxGraphDrop(t_object* x,
long inletNumber, t_object* sourceMaxObject,
long sourceOutletNumber)
144 err = (
TTErr)
long(object_method(sourceMaxObject, gensym(
"graph.object"), &sourceObject));
145 if (self->graphObject && sourceObject && !err)
146 err =
self->graphObject->
drop(sourceObject, sourceOutletNumber, inletNumber);
155 *returnedGraphObject =
self->graphObject;
160 t_max_err wrappedClass_attrGet(
WrappedInstancePtr self, t_object* attr,
long* argc, t_atom** argv)
162 t_symbol* attrName = (t_symbol*)object_method(attr, _sym_getname);
168 err = hashtab_lookup(self->wrappedClassDefinition->maxNamesToTTNames, attrName, (t_object**)&rawpointer);
174 self->graphObject->mKernel.get(ttAttrName, v);
178 *argv = (t_atom *)sysmem_newptr(
sizeof(t_atom) * v.
size());
180 for (i=0; i<v.
size(); i++) {
183 atom_setfloat(*argv+i, value);
187 atom_setsym(*argv+i, gensym((
char*)value.
c_str()));
191 atom_setlong(*argv+i, value);
198 t_max_err wrappedClass_attrSet(
WrappedInstancePtr self, t_object* attr,
long argc, t_atom* argv)
201 t_symbol* attrName = (t_symbol*)object_method(attr, _sym_getname);
207 err = hashtab_lookup(self->wrappedClassDefinition->maxNamesToTTNames, attrName, (t_object**)&ptr);
214 for (i=0; i<argc; i++) {
215 if (atom_gettype(argv+i) == A_LONG)
216 v[i] = (
TTInt32)atom_getlong(argv+i);
217 else if (atom_gettype(argv+i) == A_FLOAT)
218 v[i] = atom_getfloat(argv+i);
219 else if (atom_gettype(argv+i) == A_SYM)
220 v[i] =
TT(atom_getsym(argv+i)->s_name);
222 object_error(SELF,
"bad type for attribute setter");
224 self->graphObject->mKernel.set(ttAttrName, v);
227 return MAX_ERR_GENERIC;
231 void wrappedClass_anything(
WrappedInstancePtr self, t_symbol* s,
long argc, t_atom* argv)
237 err = hashtab_lookup(self->wrappedClassDefinition->maxNamesToTTNames, s, (t_object**)&ttName);
239 object_post(SELF,
"no method found for %s", s->s_name);
247 for (
long i=0; i<argc; i++) {
248 if (atom_gettype(argv+i) == A_LONG)
249 v[i] = (
TTInt32)atom_getlong(argv+i);
250 else if (atom_gettype(argv+i) == A_FLOAT)
251 v[i] = atom_getfloat(argv+i);
252 else if (atom_gettype(argv+i) == A_SYM)
253 v[i] =
TT(atom_getsym(argv+i)->s_name);
255 object_error(SELF,
"bad type for message arg");
257 self->graphObject->mKernel.send(ttName, v, v);
264 t_atom* av = (t_atom*)malloc(
sizeof(t_atom) * ac);
266 for (
long i=0; i<ac; i++) {
269 atom_setsym(av+i, gensym((
char*)ttSym.
c_str()));
273 atom_setfloat(av+i, f);
277 atom_setfloat(av+i, l);
280 object_obex_dumpout(
self, s, ac, av);
286 self->graphObject->mKernel.send(ttName);
291 void wrappedClass_assist(
WrappedInstancePtr self,
void *b,
long msg,
long arg,
char *dst)
294 strcpy(dst,
"multichannel input and control messages");
297 strcpy(dst,
"multichannel output");
299 strcpy(dst,
"dumpout");
308 TTErr wrapAsMaxGraph(
TTSymbol& ttClassName,
char* maxClassName, WrappedClassPtr* c)
310 return wrapAsMaxGraph(ttClassName, maxClassName, c, (WrappedClassOptionsPtr)NULL);
313 TTErr wrapAsMaxGraph(
TTSymbol& ttClassName,
char* maxClassName, WrappedClassPtr* c, WrappedClassOptionsPtr options)
318 WrappedClass* wrappedMaxClass = NULL;
320 TTCString nameCString = NULL;
321 t_symbol* nameMaxSymbol = NULL;
324 common_symbols_init();
327 if (!wrappedMaxClasses)
328 wrappedMaxClasses = hashtab_new(0);
330 wrappedMaxClass =
new WrappedClass;
331 wrappedMaxClass->maxClassName = gensym(maxClassName);
332 wrappedMaxClass->maxClass = class_new( maxClassName,
333 (method)wrappedClass_new,
334 (method)wrappedClass_free,
335 sizeof(WrappedInstance),
339 wrappedMaxClass->ttClassName = ttClassName;
340 wrappedMaxClass->validityCheck = NULL;
341 wrappedMaxClass->validityCheckArgument = NULL;
342 wrappedMaxClass->options = options;
343 wrappedMaxClass->maxNamesToTTNames = hashtab_new(0);
351 nameSize = strlen(name.
c_str());
352 nameCString =
new char[nameSize+1];
353 strncpy_zero(nameCString, name.
c_str(), nameSize+1);
355 nameMaxSymbol = gensym(nameCString);
356 hashtab_store(wrappedMaxClass->maxNamesToTTNames, nameMaxSymbol, (t_object*)name.
rawpointer());
357 class_addmethod(wrappedMaxClass->maxClass, (method)wrappedClass_anything, nameCString, A_GIMME, 0);
366 t_symbol* maxType = _sym_long;
369 nameSize = strlen(name.
c_str());
370 nameCString =
new char[nameSize+1];
371 strncpy_zero(nameCString, name.
c_str(), nameSize+1);
372 nameMaxSymbol = gensym(nameCString);
374 if (name ==
TT(
"MaxNumChannels"))
376 if (name ==
TT(
"Bypass")) {
377 if (wrappedMaxClass->options && !wrappedMaxClass->options->lookup(
TT(
"generator"), v))
384 maxType = _sym_float32;
386 maxType = _sym_float64;
388 maxType = _sym_symbol;
390 hashtab_store(wrappedMaxClass->maxNamesToTTNames, nameMaxSymbol, (t_object*)name.
rawpointer());
391 class_addattr(wrappedMaxClass->maxClass, attr_offset_new(nameCString, maxType, 0, (method)wrappedClass_attrGet, (method)wrappedClass_attrSet, 0));
395 CLASS_ATTR_STYLE(wrappedMaxClass->maxClass, (
char*)name.
c_str(), 0,
"onoff");
396 if (name ==
TT(
"fontFace"))
397 CLASS_ATTR_STYLE(wrappedMaxClass->maxClass,
"fontFace", 0,
"font");
405 class_addmethod(wrappedMaxClass->maxClass, (method)MaxGraphReset,
"graph.reset", A_CANT, 0);
406 class_addmethod(wrappedMaxClass->maxClass, (method)MaxGraphSetup,
"graph.setup", A_CANT, 0);
407 class_addmethod(wrappedMaxClass->maxClass, (method)MaxGraphConnect,
"graph.connect", A_OBJ, A_LONG, 0);
408 class_addmethod(wrappedMaxClass->maxClass, (method)object_obex_dumpout,
"dumpout", A_CANT, 0);
409 class_addmethod(wrappedMaxClass->maxClass, (method)wrappedClass_assist,
"assist", A_CANT, 0L);
410 class_addmethod(wrappedMaxClass->maxClass, (method)stdinletinfo,
"inletinfo", A_CANT, 0);
412 class_register(_sym_box, wrappedMaxClass->maxClass);
414 *c = wrappedMaxClass;
416 hashtab_store(wrappedMaxClasses, wrappedMaxClass->maxClassName, (t_object*)wrappedMaxClass);
423 TTErr err = wrapAsMaxGraph(ttClassName, maxClassName, c);
426 (*c)->validityCheck = validityCheck;
427 (*c)->validityCheckArgument = (*c)->maxClass;
434 TTErr err = wrapAsMaxGraph(ttClassName, maxClassName, c, options);
437 (*c)->validityCheck = validityCheck;
438 (*c)->validityCheckArgument = (*c)->maxClass;
446 TTErr err = wrapAsMaxGraph(ttClassName, maxClassName, c);
449 (*c)->validityCheck = validityCheck;
450 (*c)->validityCheckArgument = validityCheckArgument;
457 TTErr err = wrapAsMaxGraph(ttClassName, maxClassName, c, options);
460 (*c)->validityCheck = validityCheck;
461 (*c)->validityCheckArgument = validityCheckArgument;
The TTGraphObjectBase wraps a TTDSP object such that it is possible to build a dynamic graph of audio...
std::uint16_t TTUInt16
16 bit unsigned integer
TTErr TTObjectBaseRelease(TTObjectBasePtr *anObject)
DEPRECATED.
TTDataType type
The data type of the attribute value.
size_type size() const noexcept
Return the number of elements.
This class represents a single attribute, as used by the TTObjectBase class.
Base class for all first-class Jamoma objects.
double TTFloat64
64 bit floating point number
#define TT
This macro is defined as a shortcut for doing a lookup in the symbol table.
WrappedInstance * WrappedInstancePtr
Pointer to a wrapped instance of our object.
void * TTPtr
A generic pointer.
std::int16_t TTInt16
16 bit signed integer
TTPtr rawpointer() const
Get the value of the raw pointer into the symbol table.
TTErr(* TTValidityCheckFunction)(const TTPtr data)
A type that can be used to store a pointer to a validity checking function.
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
void getMessageNames(TTValue &messageNameList)
Return a list of names of the available messages.
TTErr TTObjectBaseInstantiate(const TTSymbol className, TTObjectBasePtr *returnedObjectPtr, const TTValue arguments)
DEPRECATED.
Boolean (1/0) or (true/false) flag.
const char * c_str() const
Return a pointer to the internal string as a C-string.
std::int32_t TTInt32
32 bit signed integer
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
std::uint32_t TTUInt32
32 bit unsigned integer
TTErr drop(TTGraphObjectBasePtr anObject, TTUInt16 fromOutletNumber=0, TTUInt16 toInletNumber=0)
Drop a source from the list of objects from which to request audio.
void resize(size_type n)
Change the number of elements.
[doxygenAppendixC_copyExample]
void getAttributeNames(TTValue &attributeNameList)
Return a list of names of the available attributes.
TTErr findAttribute(const TTSymbol name, TTAttribute **attr)
Find an attribute.
unsigned char TTUInt8
8 bit unsigned integer (char)