Jamoma API  0.6.0.a19
j.op_equal/j.op.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternalsAudioGraph
4  *
5  * @brief j.op= : wraps the #TTOperator class as an external for AudioGraph performing basic mathematical operations on multichannel signals
6  *
7  * @details
8  *
9  * @authors Timothy Place, Nils Peters, Trond Lossius
10  *
11  * @copyright © 2008 by Timothy Place @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
17 #include "maxAudioGraph.h"
18 #include "maxGraph.h"
19 
20 
21 // Data Structure for this object
22 struct Op {
23  t_object obj;
24  TTAudioGraphObjectBasePtr audioGraphObject;
25  TTPtr outlet;
26  TTPtr unused; // NULL pointer to signal end of JAG outlets to the class wrapper functions
27  TTPtr inlet; // proxy for the right inlet
28  long inletnum; // proxy input inlet number
29  t_symbol* attrOperator;
30  TTFloat32 attrOperand;
31 };
32 typedef Op* OpPtr;
33 
34 
35 // Prototypes for methods
36 OpPtr OpNew (t_symbol* msg, long argc, t_atom* argv);
37 void OpFree (OpPtr self);
38 void OpAssist (OpPtr self, void* b, long msg, long arg, char* dst);
39 TTErr OpResetAudio (OpPtr self, long vectorSize);
40 TTErr OpSetupAudio (OpPtr self);
41 //TTErr OpSetup (OpPtr self);
42 TTErr OpConnectAudio (OpPtr self, TTAudioGraphObjectBasePtr audioSourceObject, long sourceOutletNumber);
43 TTErr OpDropAudio (OpPtr self, long inletNumber, t_object* sourceMaxObject, long sourceOutletNumber);
44 t_max_err OpSetOperator (OpPtr self, void* attr, long argc, t_atom* argv);
45 t_max_err OpGetOperator (OpPtr self, t_object* attr, long* argc, t_atom** argv);
46 t_max_err OpSetOperand (OpPtr self, void* attr, long argc, t_atom* argv);
47 t_max_err OpGetOperand (OpPtr self, t_object* attr, long* argc, t_atom** argv);
48 
49 
50 // Globals
51 static t_class* sOpClass;
52 
53 
54 /************************************************************************************/
55 // Main() Function
56 
57 int C74_EXPORT main(void)
58 {
59  t_class* c;
60 
61  TTAudioGraphInit();
62  common_symbols_init();
63 
64  c = class_new("j.op=", (method)OpNew, (method)OpFree, sizeof(Op), (method)0L, A_GIMME, 0);
65 
66  class_addmethod(c, (method)OpResetAudio, "audio.reset", A_CANT, 0);
67  class_addmethod(c, (method)OpSetupAudio, "audio.setup", A_CANT, 0);
68  class_addmethod(c, (method)OpConnectAudio, "audio.connect", A_OBJ, A_LONG, 0);
69  class_addmethod(c, (method)OpDropAudio, "audio.drop", A_CANT, 0);
70  class_addmethod(c, (method)MaxAudioGraphObject, "audio.object", A_CANT, 0);
71  class_addmethod(c, (method)MaxAudioGraphReset, "graph.reset", A_CANT, 0);
72  //class_addmethod(c, (method)OpSetup, "graph.setup", A_CANT, 0); // no setup -- no graph outlets
73  class_addmethod(c, (method)MaxGraphConnect, "graph.connect", A_OBJ, A_LONG, 0);
74  class_addmethod(c, (method)MaxGraphDrop, "graph.drop", A_CANT, 0);
75  class_addmethod(c, (method)MaxGraphObject, "graph.object", A_CANT, 0);
76  class_addmethod(c, (method)OpAssist, "assist", A_CANT, 0);
77  class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
78 
79  CLASS_ATTR_SYM(c, "operator", 0, Op, attrOperator);
80  CLASS_ATTR_ACCESSORS(c, "operator", OpGetOperator, OpSetOperator);
81  CLASS_ATTR_ENUM(c, "operator", 0, "+ - * / % > >= == != <= < abs acos asin atan ceil cos cosh exp floor log log10 sin sinh sqrt tan tanh");
82 
83  CLASS_ATTR_FLOAT(c, "operand", 0, Op, attrOperand);
84  CLASS_ATTR_ACCESSORS(c, "operand", OpGetOperand, OpSetOperand);
85 
86  class_register(_sym_box, c);
87  sOpClass = c;
88  return 0;
89 }
90 
91 
92 /************************************************************************************/
93 // Object Creation Method
94 
95 OpPtr OpNew(t_symbol* msg, long argc, t_atom* argv)
96 {
97  OpPtr self;
98  TTValue v;
99  TTErr err;
100 
101  self = OpPtr(object_alloc(sOpClass));
102  if (self) {
103  object_obex_store((void*)self, _sym_dumpout, (t_object*)outlet_new(self, NULL)); // dumpout
104  self->outlet = outlet_new(self, "audio.connect");
105  self->inlet = proxy_new(self, 1, &self->inletnum);
106 
107  v.resize(2);
108  v[0] = "operator";
109  v[1] = 1; // we set it up with 1 inlet, and later modify to 2 inlets if the connection is made
110  err = TTObjectBaseInstantiate(TT("audio.object"), (TTObjectBasePtr*)&self->audioGraphObject, v);
111 
112  if (!self->audioGraphObject->getUnitGenerator().valid()) {
113  object_error(SELF, "cannot load Jamoma DSP object");
114  return NULL;
115  }
116 
117  attr_args_process(self, argc, argv);
118  }
119  return self;
120 }
121 
122 
123 // Memory Deallocation
124 void OpFree(OpPtr self)
125 {
126  TTObjectBaseRelease((TTObjectBasePtr*)&self->audioGraphObject);
127  object_free(self->inlet);
128 }
129 
130 
131 /************************************************************************************/
132 // Methods bound to input/inlets
133 
134 // Method for Assistance Messages
135 void OpAssist(OpPtr self, void* b, long msg, long arg, char* dst)
136 {
137  if (msg==1) // Inlets
138  strcpy (dst, "multichannel input and control messages");
139  else if (msg==2) { // Outlets
140  if (arg == 0)
141  strcpy(dst, "multichannel output");
142  else
143  strcpy(dst, "dumpout");
144  }
145 }
146 
147 
148 // METHODS SPECIFIC TO AUDIO GRAPH EXTERNALS
149 
150 TTErr OpResetAudio(OpPtr self, long vectorSize)
151 {
152  self->audioGraphObject->setAttributeValue(TT("numAudioInlets"), 1);
153  return self->audioGraphObject->resetAudio();
154 }
155 
156 
157 TTErr OpSetupAudio(OpPtr self)
158 {
159  t_atom a[2];
160 
161  atom_setobj(a+0, (t_object*)(self->audioGraphObject));
162  atom_setlong(a+1, 0);
163  outlet_anything(self->outlet, gensym("audio.connect"), 2, a);
164  return kTTErrNone;
165 }
166 
167 
168 /*
169 TTErr OpSetup(OpPtr self)
170 {
171  t_atom a[2];
172  TTUInt16 i=0;
173 
174  atom_setobj(a+0, (t_object*)(self->graphObject));
175  while (self->graphOutlets[i]) {
176  atom_setlong(a+1, i);
177  outlet_anything(self->graphOutlets[i], gensym("graph.connect"), 2, a);
178  i++;
179  }
180  return kTTErrNone;
181 }
182  */
183 
184 
185 TTErr OpConnectAudio(OpPtr self, TTAudioGraphObjectBasePtr audioSourceObject, long sourceOutletNumber)
186 {
187  long inletNumber = proxy_getinlet(SELF);
188 
189  if (inletNumber == 1)
190  self->audioGraphObject->setAttributeValue(TT("numAudioInlets"), 2);
191  return self->audioGraphObject->connectAudio(audioSourceObject, sourceOutletNumber, inletNumber);
192 }
193 
194 
195 TTErr OpDropAudio(OpPtr self, long inletNumber, t_object* sourceMaxObject, long sourceOutletNumber)
196 {
197  TTAudioGraphObjectBasePtr sourceObject = NULL;
198  TTErr err;
199 
200  if (inletNumber == 1)
201  self->audioGraphObject->setAttributeValue(TT("numAudioInlets"), 1);
202  err = (TTErr)TTPtrSizedInt(object_method(sourceMaxObject, gensym("audio.object"), &sourceObject));
203  if (self->audioGraphObject && sourceObject && !err)
204  err = self->audioGraphObject->dropAudio(sourceObject, sourceOutletNumber, inletNumber);
205  return err;
206 }
207 
208 
209 // ATTRIBUTE SETTERS
210 
211 t_max_err OpSetOperator(OpPtr self, void* attr, long argc, t_atom* argv)
212 {
213  if (argc) {
214  self->attrOperator = atom_getsym(argv);
215  self->audioGraphObject->getUnitGenerator().set(TT("operator"), TT(self->attrOperator->s_name));
216  }
217  return MAX_ERR_NONE;
218 }
219 
220 
221 t_max_err OpGetOperator(OpPtr self, t_object* attr, long* argc, t_atom** argv)
222 {
223  TTValue v;
224 
225  self->audioGraphObject->getUnitGenerator().get(TT("operator"), v);
226 
227  *argc = v.size();
228  if (!(*argv)) // otherwise use memory passed in
229  *argv = (t_atom *)sysmem_newptr(sizeof(t_atom) * v.size());
230 
231  for (int i=0; i < (TTInt32) v.size(); i++) {
232  if (v[i].type() == kTypeFloat32 || v[i].type() == kTypeFloat64) {
233  TTFloat64 value;
234  value = v[i];
235  atom_setfloat(*argv+i, value);
236  }
237  else if (v[i].type() == kTypeSymbol) {
238  TTSymbol value;
239  value = v[i];
240  atom_setsym(*argv+i, gensym((char*)value.c_str()));
241  }
242  else { // assume int
243  TTInt32 value;
244  value = v[i];
245  atom_setlong(*argv+i, value);
246  }
247  }
248  return MAX_ERR_NONE;
249 }
250 
251 t_max_err OpSetOperand(OpPtr self, void* attr, long argc, t_atom* argv)
252 {
253  if (argc) {
254  self->attrOperand = atom_getfloat(argv);
255  self->audioGraphObject->getUnitGenerator().set(TT("operand"), self->attrOperand);
256  }
257  return MAX_ERR_NONE;
258 }
259 
260 
261 t_max_err OpGetOperand(OpPtr self, t_object* attr, long* argc, t_atom** argv)
262 {
263  TTValue v;
264 
265  self->audioGraphObject->getUnitGenerator().get(TT("operand"), v);
266 
267  *argc = v.size();
268  if (!(*argv)) // otherwise use memory passed in
269  *argv = (t_atom *)sysmem_newptr(sizeof(t_atom) * v.size());
270 
271  for (TTUInt32 i=0; i < v.size(); i++) {
272  if (v[i].type() == kTypeFloat32 || v[i].type() == kTypeFloat64) {
273  TTFloat64 value;
274  value = v[i];
275  atom_setfloat(*argv+i, value);
276  }
277  else if (v[i].type() == kTypeSymbol) {
278  TTSymbol value;
279  value = v[i];
280  atom_setsym(*argv+i, gensym((char*)value.c_str()));
281  }
282  else { // assume int
283  TTInt32 value;
284  value = v[i];
285  atom_setlong(*argv+i, value);
286  }
287  }
288  return MAX_ERR_NONE;
289 }
TTErr TTObjectBaseRelease(TTObjectBasePtr *anObject)
DEPRECATED.
TTErr MaxAudioGraphReset(t_object *x, long vectorSize)
Clear the list of source objects from which this object will try to pull audio.
size_type size() const noexcept
Return the number of elements.
Base class for all first-class Jamoma objects.
Definition: TTObjectBase.h:109
TTErr setAttributeValue(const TTSymbol name, TTValue &value)
Set an attribute value for an object.
Symbol type.
Definition: TTBase.h:282
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
#define TT
This macro is defined as a shortcut for doing a lookup in the symbol table.
Definition: TTSymbol.h:155
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
64-bit floating point
Definition: TTBase.h:272
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
float TTFloat32
32 bit floating point number
Definition: TTBase.h:187
TTErr TTObjectBaseInstantiate(const TTSymbol className, TTObjectBasePtr *returnedObjectPtr, const TTValue arguments)
DEPRECATED.
void get(const TTUInt16 index, T &returnedElementValue) const
DEPRECATED.
Definition: TTValue.h:591
const char * c_str() const
Return a pointer to the internal string as a C-string.
Definition: TTSymbol.h:77
std::int32_t TTInt32
32 bit signed integer
Definition: TTBase.h:177
A thin wrapper of Jamoma AudioGraph for use in the Cycling '74 Max/MSP environment.
TTErr MaxAudioGraphObject(t_object *x, TTAudioGraphObjectBasePtr *returnedAudioGraphObject)
Returns a pointer to the Jamoma Audio Graph object that is wrapped by this Max object.
32-bit floating point
Definition: TTBase.h:271
long TTPtrSizedInt
An integer that is the same size as a pointer.
Definition: TTBase.h:240
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
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
Definition: TTBase.h:178
No Error.
Definition: TTBase.h:343
int C74_EXPORT main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
void resize(size_type n)
Change the number of elements.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34