18 #include "ext_hashtab.h"
22 #define MAX_NUM_INLETS 32
23 #define MAX_NUM_OUTLETS 32
26 typedef struct _wrappedInstance {
29 TTPtr audioGraphOutlets[MAX_NUM_OUTLETS];
30 TTPtr inlets[MAX_NUM_INLETS];
40 static t_hashtab* wrappedMaxClasses = NULL;
43 t_object* MaxAudioGraphWrappedClass_new(t_symbol* name,
long argc, t_atom* argv)
50 long attrstart = attr_args_offset(argc, argv);
53 hashtab_lookup(wrappedMaxClasses, name, (t_object**)&wrappedMaxClass);
57 if (wrappedMaxClass) {
72 int argumentOffsetToDefineTheNumberOfInlets = v;
73 if ((attrstart-argumentOffsetToDefineTheNumberOfInlets > 0) && argv+argumentOffsetToDefineTheNumberOfInlets)
74 self->numInputs = atom_getlong(argv+argumentOffsetToDefineTheNumberOfInlets);
77 int wrapperDefinedNumberOfInlets = v;
78 if (wrapperDefinedNumberOfInlets > 0)
79 self->numInputs = wrapperDefinedNumberOfInlets;
82 self->numInputs = min(self->numInputs, (
TTUInt8)MAX_NUM_INLETS);
84 for (
TTUInt16 i=self->numInputs-1; i>0; i--)
85 self->inlets[i-1] = proxy_new(
self, i, NULL);
87 object_obex_store((
void*)
self, _sym_dumpout, (
object*)outlet_new(
self, NULL));
89 int argumentOffsetToDefineTheNumberOfOutlets = v;
90 if ((attrstart-argumentOffsetToDefineTheNumberOfOutlets > 0) && argv+argumentOffsetToDefineTheNumberOfOutlets)
91 self->numOutputs = atom_getlong(argv+argumentOffsetToDefineTheNumberOfOutlets);
94 int wrapperDefinedNumberOfOutlets = v;
95 if (wrapperDefinedNumberOfOutlets > 0)
96 self->numOutputs = wrapperDefinedNumberOfOutlets;
99 self->numOutputs = min(self->numOutputs, (
TTUInt8)MAX_NUM_OUTLETS);
101 for (
TTInt16 i=self->numOutputs-1; i>=0; i--)
102 self->audioGraphOutlets[i] = outlet_new(
self,
"audio.connect");
105 self->wrappedClassDefinition = wrappedMaxClass;
108 v[1] =
self->numInputs;
109 v[2] =
self->numOutputs;
115 attr_args_process(
self, argc, argv);
117 return (t_object*)
self;
123 if (self->audioGraphObject)
126 for (
int i=0; i<MAX_NUM_INLETS; i++) {
128 object_free(self->inlets[i]);
139 return self->audioGraphObject->resetAudio();
149 atom_setobj(a+0, (t_object*)self->audioGraphObject);
150 while (self->audioGraphOutlets[i]) {
151 atom_setlong(a+1, i);
152 outlet_anything(self->audioGraphOutlets[i], gensym(
"audio.connect"), 2, a);
163 long inletNumber = proxy_getinlet(SELF);
165 return self->audioGraphObject->connectAudio(audioSourceObject, sourceOutletNumber, inletNumber);
176 err = (
TTErr)
long(object_method(sourceMaxObject, gensym(
"audio.object"), &sourceObject));
177 if (self->audioGraphObject && sourceObject && !err)
178 err =
self->audioGraphObject->dropAudio(sourceObject, sourceOutletNumber, inletNumber);
187 *returnedAudioGraphObject =
self->audioGraphObject;
193 t_max_err MaxAudioGraphWrappedClass_attrGet(
WrappedInstancePtr self, t_object* attr,
long* argc, t_atom** argv)
195 t_symbol* attrName = (t_symbol*)object_method(attr, _sym_getname);
199 TTSymbol ttAttrName(attrName->s_name);
201 self->audioGraphObject->getUnitGenerator().get(ttAttrName, v);
205 *argv = (t_atom *)sysmem_newptr(
sizeof(t_atom) * v.
size());
207 for (i=0; i<v.
size(); i++) {
210 atom_setfloat(*argv+i, value);
214 atom_setsym(*argv+i, gensym((
char*)value.
c_str()));
218 atom_setlong(*argv+i, value);
226 t_max_err MaxAudioGraphWrappedClass_attrSet(
WrappedInstancePtr self, t_object* attr,
long argc, t_atom* argv)
229 t_symbol* attrName = (t_symbol*)object_method(attr, _sym_getname);
233 TTSymbol ttAttrName(attrName->s_name);
236 for (i=0; i<argc; i++) {
237 if (atom_gettype(argv+i) == A_LONG)
238 v[i] = (
TTInt32)atom_getlong(argv+i);
239 else if (atom_gettype(argv+i) == A_FLOAT)
240 v[i] = atom_getfloat(argv+i);
241 else if (atom_gettype(argv+i) == A_SYM)
242 v[i] =
TT(atom_getsym(argv+i)->s_name);
244 object_error(SELF,
"bad type for attribute setter");
246 self->audioGraphObject->getUnitGenerator().set(ttAttrName, v);
249 return MAX_ERR_GENERIC;
254 t_max_err MaxAudioGraphWrappedClass_attrGetNumChannels(
WrappedInstancePtr self, t_object* attr,
long* argc, t_atom** argv)
258 *argv = (t_atom*)sysmem_newptr(
sizeof(t_atom));
260 atom_setlong(*argv, self->audioGraphObject->getOutputNumChannels(0));
266 t_max_err MaxAudioGraphWrappedClass_attrSetNumChannels(
WrappedInstancePtr self, t_object* attr,
long argc, t_atom* argv)
269 self->audioGraphObject->setOutputNumChannels(0, atom_getlong(argv));
275 void MaxAudioGraphWrappedClass_anything(
WrappedInstancePtr self, t_symbol* s,
long argc, t_atom* argv)
285 for (
long i=0; i<argc; i++) {
286 if (atom_gettype(argv+i) == A_LONG)
287 v_in[i] = (
TTInt32)atom_getlong(argv+i);
288 else if (atom_gettype(argv+i) == A_FLOAT)
289 v_in[i] = atom_getfloat(argv+i);
290 else if (atom_gettype(argv+i) == A_SYM)
291 v_in[i] =
TT(atom_getsym(argv+i)->s_name);
293 object_error(SELF,
"bad type for message arg");
297 self->audioGraphObject->getUnitGenerator().send(ttName, v_in, v_out);
301 long ac = v_out.
size();
304 t_atom* av = (t_atom*)malloc(
sizeof(t_atom) * ac);
306 for (
long i=0; i<ac; i++) {
309 atom_setsym(av+i, gensym((
char*)ttSym.
c_str()));
314 atom_setfloat(av+i, f);
318 atom_setfloat(av+i, l);
321 object_obex_dumpout(
self, s, ac, av);
329 void MaxAudioGraphWrappedClass_assist(
WrappedInstancePtr self,
void *b,
long msg,
long arg,
char *dst)
333 strcpy(dst,
"multichannel input and control messages");
335 snprintf(dst, 256,
"multichannel input %ld", arg+1);
339 if (arg == self->numOutputs)
340 strcpy(dst,
"dumpout");
342 snprintf(dst, 256,
"multichannel output %ld", arg+1);
363 TTCString nameCString = NULL;
364 t_symbol* nameMaxSymbol = NULL;
367 common_symbols_init();
370 if (!wrappedMaxClasses)
371 wrappedMaxClasses = hashtab_new(0);
375 wrappedMaxClass->
maxClass = class_new( maxClassName,
376 (method)MaxAudioGraphWrappedClass_new,
377 (method)MaxAudioGraphWrappedClass_free,
378 sizeof(WrappedInstance),
385 wrappedMaxClass->
options = options;
393 nameSize = strlen(name.
c_str());
394 nameCString =
new char[nameSize+1];
395 strncpy_zero(nameCString, name.
c_str(), nameSize+1);
397 nameMaxSymbol = gensym(nameCString);
398 class_addmethod(wrappedMaxClass->
maxClass, (method)MaxAudioGraphWrappedClass_anything, nameCString, A_GIMME, 0);
407 t_symbol* maxType = _sym_long;
411 nameSize = strlen(name.
c_str());
412 nameCString =
new char[nameSize+1];
413 strncpy_zero(nameCString, name.
c_str(), nameSize+1);
414 nameMaxSymbol = gensym(nameCString);
416 if (name ==
TT(
"maxNumChannels"))
418 if (name ==
TT(
"bypass")) {
426 maxType = _sym_float32;
428 maxType = _sym_float64;
430 maxType = _sym_symbol;
432 class_addattr(wrappedMaxClass->
maxClass, attr_offset_new(nameCString, maxType, 0, (method)MaxAudioGraphWrappedClass_attrGet, (method)MaxAudioGraphWrappedClass_attrSet, 0));
436 CLASS_ATTR_STYLE(wrappedMaxClass->
maxClass, (
char*)name.
c_str(), 0, (
char*)
"onoff");
437 if (name ==
TT(
"fontFace"))
438 CLASS_ATTR_STYLE(wrappedMaxClass->
maxClass, (
char*)
"fontFace", 0, (
char*)
"font");
451 class_addmethod(wrappedMaxClass->
maxClass, (method)MaxGraphConnect,
"graph.connect", A_OBJ, A_LONG, 0);
452 class_addmethod(wrappedMaxClass->
maxClass, (method)MaxGraphDrop,
"graph.drop", A_CANT, 0);
453 class_addmethod(wrappedMaxClass->
maxClass, (method)MaxGraphObject,
"graph.object", A_CANT, 0);
454 class_addmethod(wrappedMaxClass->
maxClass, (method)object_obex_dumpout,
"dumpout", A_CANT, 0);
455 class_addmethod(wrappedMaxClass->
maxClass, (method)MaxAudioGraphWrappedClass_assist,
"assist", A_CANT, 0L);
456 class_addmethod(wrappedMaxClass->
maxClass, (method)stdinletinfo,
"inletinfo", A_CANT, 0);
459 if (wrappedMaxClass->
options) {
460 TTValue userCanSetNumChannels = NO;
461 TTErr err = wrappedMaxClass->
options->
lookup(
TT(
"userCanSetNumChannels"), userCanSetNumChannels);
463 if (!err && userCanSetNumChannels ==
TTValue(YES))
464 class_addattr(wrappedMaxClass->
maxClass, attr_offset_new(
"numChannels", _sym_long, 0,
465 (method)MaxAudioGraphWrappedClass_attrGetNumChannels,
466 (method)MaxAudioGraphWrappedClass_attrSetNumChannels,
470 class_register(_sym_box, wrappedMaxClass->
maxClass);
472 *c = wrappedMaxClass;
474 hashtab_store(wrappedMaxClasses, wrappedMaxClass->
maxClassName, (t_object*)wrappedMaxClass);
484 (*c)->validityCheck = validityCheck;
485 (*c)->validityCheckArgument = (*c)->maxClass;
495 (*c)->validityCheck = validityCheck;
496 (*c)->validityCheckArgument = (*c)->maxClass;
507 (*c)->validityCheck = validityCheck;
508 (*c)->validityCheckArgument = validityCheckArgument;
518 (*c)->validityCheck = validityCheck;
519 (*c)->validityCheckArgument = validityCheckArgument;
std::uint16_t TTUInt16
16 bit unsigned integer
TTErr MaxAudioGraphDrop(t_object *x, long inletNumber, t_object *sourceMaxObject, long sourceOutletNumber)
Method called when a connection from an upstream node is dropped.
TTErr TTObjectBaseRelease(TTObjectBasePtr *anObject)
DEPRECATED.
TTErr lookup(const TTSymbol &optionName, TTValue &optionValue)
Loopup the value of an option.
TTDataType type
The data type of the attribute value.
TTErr MaxAudioGraphConnect(t_object *x, TTAudioGraphObjectBasePtr audioSourceObject, TTUInt16 sourceOutletNumber)
Method called when an upstream node is connected to this node.
TTErr wrapAsMaxAudioGraph(TTSymbol ttClassName, char *maxClassName, MaxAudioGraphWrappedClassPtr *c)
Wrap an AudioGraph class as a Max class.
WrappedInstance * WrappedInstancePtr
Pointer to a wrapped instance of our object.
size_type size() const noexcept
Return the number of elements.
TTErr MaxAudioGraphObject(t_object *x, TTAudioGraphObjectBasePtr *returnedAudioGraphObject)
Returns a pointer to the Jamoma Audio Graph object that is wrapped by this Max object.
This class represents a single attribute, as used by the TTObjectBase class.
Base class for all first-class Jamoma objects.
This object is an audio generator, and do not expect audio input.
t_symbol * maxClassName
The name to give the Max class.
double TTFloat64
64 bit floating point number
MaxAudioGraphWrappedClassOptions * options
Additional configuration options specified for the class.
#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
A class representing the options of a MaxAudioGraphWrappedClass.
t_class * maxClass
The Max class pointer.
Type definition for an AudioGraph class wrapped as a Max external.
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.
This object does not adapt its number of output channels to the number of input channels.
TTErr TTObjectBaseInstantiate(const TTSymbol className, TTObjectBasePtr *returnedObjectPtr, const TTValue arguments)
DEPRECATED.
TTErr MaxAudioGraphReset(t_object *x, long vectorSize)
Clear the list of source objects from which this object will try to pull audio.
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
A thin wrapper of Jamoma AudioGraph for use in the Cycling '74 Max/MSP environment.
TTErr MaxAudioGraphSetup(t_object *x)
Set up fresh connections from this object to nodes that are connected downstream. ...
TTPtr validityCheckArgument
An argument to pass to the validityCheck function when it is called.
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...
The TTAudioGraphObjectBase wraps a TTDSP object such that it is possible to build a dynamic graph of ...
std::uint32_t TTUInt32
32 bit unsigned integer
TTValidityCheckFunction validityCheck
A function to call to validate the context for an object before it is instantiated.
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.
TTSymbol ttClassName
The name of the class as registered with the Jamoma framework.
TTErr findAttribute(const TTSymbol name, TTAttribute **attr)
Find an attribute.
unsigned char TTUInt8
8 bit unsigned integer (char)