Jamoma API  0.6.0.a19
j.op~.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternalsDSP
4  *
5  * @brief j.op~ : wraps the #TTOperator class as a Jamoma external for MSP
6  *
7  * @details
8  *
9  * @authors Tim Place, 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 "TTClassWrapperMax.h"
18 #include "ext.h" // Max Header
19 #include "z_dsp.h" // MSP Header
20 #include "ext_strings.h" // String Functions
21 #include "commonsyms.h" // Common symbols used by the Max 4.5 API
22 #include "ext_obex.h" // Max Object Extensions (attributes) Header
23 
24 #include "TTDSP.h" // Jamoma DSP Interfaces...
25 
26 
27 // Data Structure for this object
28 typedef struct _op {
29  t_pxobject obj;
31  TTAudioSignalPtr audioIn;
32  TTAudioSignalPtr audioOut;
33  float attrOperand;
34  t_symbol* attrOperator;
35  TTUInt16 maxNumChannels;
36  TTUInt16 numChannels;
37  TTUInt16 vs;
38 } t_op;
39 
40 
41 // Prototypes for methods: need a method for each incoming message type
42 void* op_new(t_symbol *msg, short argc, t_atom *argv); // New Object Creation Method
43 void op_free(t_op *x);
44 void op_assist(t_op *x, void *b, long msg, long arg, char *dst); // Assistance Method
45 t_int* op_perform(t_int *w); // An MSP Perform (signal) Method
46 void op_dsp(t_op *x, t_signal **sp, short *count); // DSP Method
47 void op_dsp64(t_op *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags); // DSP64 Method
48 t_max_err op_setOperator(t_op *x, void *attr, long argc, t_atom *argv);
49 t_max_err op_setOperand(t_op *x, void *attr, long argc, t_atom *argv);
50 
51 
52 // Globals
53 t_class *s_op_class;
54 
55 
56 /************************************************************************************/
57 // Main() Function
58 
59 int C74_EXPORT main(void)
60 {
61  t_class *c;
62 
63  TTDSPInit();
64  common_symbols_init();
65 
66  c = class_new("j.op~",(method)op_new, (method)op_free, sizeof(t_op), (method)0L, A_GIMME, 0);
67 
68  class_addmethod(c, (method)op_dsp, "dsp", A_CANT, 0);
69  class_addmethod(c, (method)op_dsp64, "dsp64", A_CANT, 0);
70  class_addmethod(c, (method)op_assist, "assist", A_CANT, 0);
71  class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
72 
73  CLASS_ATTR_SYM(c, "operator", 0, t_op, attrOperator);
74  CLASS_ATTR_ACCESSORS(c, "operator", NULL, op_setOperator);
75  CLASS_ATTR_ENUM(c, "operator", 0, "+ - * / % > >= == != <= < abs acos asin atan ceil cos cosh exp floor log log10 sin sinh sqrt tan tanh");
76 
77  CLASS_ATTR_FLOAT(c, "operand", 0, t_op, attrOperand);
78  CLASS_ATTR_ACCESSORS(c, "operand", NULL, op_setOperand);
79 
80  class_dspinit(c); // Setup object's class to work with MSP
81  class_register(CLASS_BOX, c);
82  s_op_class = c;
83  return 0;
84 }
85 
86 
87 /************************************************************************************/
88 // Object Creation Method
89 
90 void* op_new(t_symbol *msg, short argc, t_atom *argv)
91 {
92  t_op *x;
93  TTValue sr(sys_getsr());
94  long attrstart = attr_args_offset(argc, argv); // support normal arguments
95  short i;
96 
97  x = (t_op *)object_alloc(s_op_class);
98  if (x) {
99  x->maxNumChannels = 2; // An initial argument to this object will set the maximum number of channels
100  if (attrstart && argv)
101  x->maxNumChannels = atom_getlong(argv);
102 
103  ttEnvironment->setAttributeValue(kTTSym_sampleRate, sr);
104  TTObjectBaseInstantiate(TT("operator"), &x->op, x->maxNumChannels);
105  TTObjectBaseInstantiate(TT("audiosignal"), &x->audioIn, x->maxNumChannels);
106  TTObjectBaseInstantiate(TT("audiosignal"), &x->audioOut, x->maxNumChannels);
107 
108  attr_args_process(x,argc,argv); // handle attribute args
109 
110  object_obex_store((void *)x, _sym_dumpout, (object *)outlet_new(x,NULL)); // dumpout
111  dsp_setup((t_pxobject *)x, x->maxNumChannels); // inlets
112  for (i=0; i < x->maxNumChannels; i++)
113  outlet_new((t_pxobject *)x, "signal"); // outlets
114 
115  x->obj.z_misc = Z_NO_INPLACE;
116  }
117  return (x); // Return the pointer
118 }
119 
120 // Memory Deallocation
121 void op_free(t_op *x)
122 {
123  dsp_free((t_pxobject *)x);
124  TTObjectBaseRelease(&x->op);
125  TTObjectBaseRelease(&x->audioIn);
126  TTObjectBaseRelease(&x->audioOut);
127 }
128 
129 
130 /************************************************************************************/
131 // Methods bound to input/inlets
132 
133 // Method for Assistance Messages
134 void op_assist(t_op *x, void *b, long msg, long arg, char *dst)
135 {
136  if (msg==1) { // Inlets
137  if (arg == 0)
138  snprintf(dst, 256, "(signal) input %ld, control messages", arg+1);
139  else
140  snprintf(dst, 256, "(signal) input %ld", arg+1);
141  }
142  else if (msg==2) // Outlets
143  if (arg == x->maxNumChannels)
144  strcpy(dst, "dumpout");
145  else
146  snprintf(dst, 256, "(signal) processed audio (ch. %ld)", arg+1);
147 
148 }
149 
150 
151 
152 
153 
154 // Perform (signal) Method
155 t_int *op_perform(t_int *w)
156 {
157  t_op *x = (t_op *)(w[1]);
158  short i, j;
159  TTUInt16 vs = x->audioIn->getVectorSizeAsInt();
160 
161  for (i=0; i<x->numChannels; i++) {
162  j = (i*2) + 1;
163  x->audioIn->setVector(i, vs, (t_float *)w[j+1]);
164  }
165 
166  if (!x->obj.z_disabled)
167  x->op->process(x->audioIn, x->audioOut);
168 
169  for (i=0; i<x->numChannels; i++) {
170  j = (i*2) + 1;
171  x->audioOut->getVector(i, vs, (t_float *)w[j+2]);
172  }
173 
174  return w + ((x->numChannels*2)+2);
175 }
176 
177 
178 // DSP Method
179 void op_dsp(t_op *x, t_signal **sp, short *count)
180 {
181  short i, j, k=0;
182  void **audioVectors = NULL;
183 
184  audioVectors = (void**)sysmem_newptr(sizeof(void*) * ((x->maxNumChannels * 2) + 1));
185  audioVectors[k] = x;
186  k++;
187 
188  x->numChannels = 0;
189  x->vs = 0;
190  for (i=0; i < x->maxNumChannels; i++) {
191  j = x->maxNumChannels + i;
192  if (count[i] && count[j]) {
193  x->numChannels++;
194  if (sp[i]->s_n > x->vs)
195  x->vs = sp[i]->s_n;
196 
197  audioVectors[k] = sp[i]->s_vec;
198  k++;
199  audioVectors[k] = sp[j]->s_vec;
200  k++;
201  }
202  }
203 
204  x->audioIn->setAttributeValue(kTTSym_numChannels, x->maxNumChannels);
205  x->audioOut->setAttributeValue(kTTSym_numChannels, x->maxNumChannels);
206  x->audioIn->setAttributeValue(kTTSym_vectorSize, x->vs);
207  x->audioOut->setAttributeValue(kTTSym_vectorSize, x->vs);
208  //audioIn will be set in the perform method
209  x->audioOut->sendMessage(TT("alloc"));
210 
211  x->op->setAttributeValue(kTTSym_sampleRate, sp[0]->s_sr);
212 
213  dsp_addv(op_perform, k, audioVectors);
214  sysmem_freeptr(audioVectors);
215 }
216 
217 
218 t_max_err op_setOperator(t_op *x, void *attr, long argc, t_atom *argv)
219 {
220  if (argc) {
221  x->attrOperator = atom_getsym(argv);
222  x->op->setAttributeValue(TT("operator"), TT(x->attrOperator->s_name));
223  }
224  return MAX_ERR_NONE;
225 }
226 
227 
228 t_max_err op_setOperand(t_op *x, void *attr, long argc, t_atom *argv)
229 {
230  if (argc) {
231  x->attrOperand = atom_getfloat(argv);
232  x->op->setAttributeValue(TT("operand"), x->attrOperand);
233  }
234  return MAX_ERR_NONE;
235 }
236 
237 
238 void op_perform64(t_op *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam)
239 {
240  short i;
241  TTUInt16 vs = x->audioIn->getVectorSizeAsInt();
242 
243  for (i=0; i<x->numChannels; i++)
244  x->audioIn->setVector(i, vs, ins[i]);
245 
246 
247  x->op->process(x->audioIn, x->audioOut);
248 
249  for (i=0; i<x->numChannels; i++)
250  x->audioOut->getVectorCopy(i, vs, outs[i]);
251 }
252 
253 
254 void op_perform_zero(t_op *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam)
255 {
256  int i;
257 
258  for (i=0; i<numouts; i++)
259  memset(outs[i], 0, sizeof(double) * sampleframes);
260 }
261 
262 
263 void op_dsp64(t_op *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags)
264 {
265 
266  short i, j;
267 
268  x->numChannels = 0;
269  x->vs = (TTUInt16)maxvectorsize;
270 
271  for (i=0; i < x->maxNumChannels; i++) {
272  j = x->maxNumChannels + i;
273  if (count[i] && count[j])
274  x->numChannels = i+1;
275  }
276 
277  if (x->numChannels > 0) {
278  x->audioIn->setAttributeValue(kTTSym_numChannels, x->numChannels);
279  x->audioOut->setAttributeValue(kTTSym_numChannels, x->numChannels);
280  x->audioIn->setAttributeValue(kTTSym_vectorSize, (TTUInt16)maxvectorsize);
281  x->audioOut->setAttributeValue(kTTSym_vectorSize, (TTUInt16)maxvectorsize);
282  //audioIn will be set in the perform method
283  x->audioOut->sendMessage(TT("alloc"));
284 
285  x->op->setAttributeValue(kTTSym_sampleRate, samplerate);
286  object_method(dsp64, gensym("dsp_add64"), x, op_perform64, 0, NULL);
287  }
288  else
289  object_method(dsp64, gensym("dsp_add64"), x, op_perform_zero, 0, NULL);
290 }
291 
std::uint16_t TTUInt16
16 bit unsigned integer
Definition: TTBase.h:176
TTErr TTObjectBaseRelease(TTObjectBasePtr *anObject)
DEPRECATED.
TTFOUNDATION_EXPORT TTEnvironment * ttEnvironment
The environment object has one instance, which is global in scope.
TTAudioObjectBase is the base class for all audio generating and processing objects in Jamoma DSP...
int C74_EXPORT main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
Definition: j.op~.cpp:59
Jamoma DSP Library.
TTErr setAttributeValue(const TTSymbol name, TTValue &value)
Set an attribute value for an object.
#define TT
This macro is defined as a shortcut for doing a lookup in the symbol table.
Definition: TTSymbol.h:155
TTErr TTObjectBaseInstantiate(const TTSymbol className, TTObjectBasePtr *returnedObjectPtr, const TTValue arguments)
DEPRECATED.
The TTAudioSignal class represents N vectors of audio samples for M channels.
Definition: TTAudioSignal.h:57
void TTDSP_EXPORT TTDSPInit(const char *pathToBinaries=NULL)
Initialise the Jamoma DSP library, as well as Jamoma Foundation foundation if needed.
Definition: TTDSP.cpp:30
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34