Jamoma API  0.6.0.a19
PureData/source/j.out/j.out.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationPdExternals
4  *
5  * @brief j.out & j.out~ & j.out= - Manage control and audio outputs for a Jamoma model
6  *
7  * @details
8  *
9  * @authors Timothy Place, Théo de la Hogue, Trond Lossius, Antoine Villeret
10  *
11  * @copyright © 2008 by Timothy Place and Théo de la Hogue @n
12  * Copyright © 2015, Antoine Villeret@n
13  * This code is licensed under the terms of the "New BSD License" @n
14  * http://creativecommons.org/licenses/BSD/
15  */
16 
17 
19 
20 #define signal_out 0
21 #define dump_out 1
22 
23 // This is used to store extra data
24 typedef struct extra {
25 
26  TTSymbol instance; ///< Output instance symbol
27 
28 } t_extra;
29 #define EXTRA ((t_extra*)x->extra)
30 
31 
32 // Definitions
33 
34 /** Wrap the j.out class as a Max object.
35  @param c The class to be wrapped
36  @see WrappedOutputClass_new, WrappedOutputClass_free
37  */
38 void WrapTTOutputClass(WrappedClassPtr c);
39 
40 /** Wrapper for the j.out constructor class, called when an instance is created.
41  @param self Pointer to this object.
42  @param argc The number of arguments passed to the object.
43  @param argv Pointer to an array of atoms passed to the object.
44  @see WrappedOutputClass_free, out_subscribe
45  */
46 void WrappedOutputClass_new(TTPtr self, long argc, t_atom* argv);
47 
48 /** Wrapper for the j.out deconstructor class, called when an instance is destroyed.
49  @param self Pointer to this object.
50  @see WrappedOutputClass_new
51  */
53 
54 /** Assistance Method.
55  @param self Pointer to this object.
56  @param b Pointer to (exactly what?)
57  @param msg The message passed to the object.
58  @param arg
59  @param dst Pointer to the destination that assistance strings are passed to for display.
60  */
61 void out_assist(TTPtr self, TTPtr b, long msg, long arg, char *dst);
62 
63 /** Associate j.out(~) with NodeLib. This is a prerequisit for communication with other Jamoma object in the module and beyond. */
64 void out_subscribe(TTPtr self);
65 
66 //TODO : void out_register_preview(t_out *x, void *preview_object) { x->preview_object = preview_object; }
67 
68 #ifdef J_OUT_TILDE
69 
70 /** j.out~ 64-bit MSP perform method (for Max 6). Only defined for j.out~. */
71 void out_perform64(TTPtr self, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam);
72 
73 /** j.out~ 64-bit DSP method (for Max 6). Only defined for j.out~. */
74 void out_dsp64(TTPtr self, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags);
75 
76 #endif
77 
78 #ifdef J_OUT_MULTI
79 
80 /** reset audiogrpaph setup of the wrapped object
81  @param self Pointer to this object.
82  */
83 void out_reset(TTPtr self);
84 
85 /** reset audiogrpaph setup of the wrapped object
86  @param self Pointer to this object.
87  */
88 void out_setup(TTPtr self);
89 
90 /** reset audiogrpaph setup of the wrapped audiograph object
91  @param self Pointer to this audiograph object.
92  @param audioSourceObject The audiograph object to connect with.
93  @param sourceOutletNumber The number of channel the source audiograph object have.
94  */
95 void out_connect(TTPtr self, TTAudioGraphObjectBasePtr audioSourceObject, long sourceOutletNumber);
96 #endif
97 
98 #ifndef J_OUT_TILDE
99 #ifndef J_OUT_MULTI
100 
101 /** bang handler for j.out
102  @param self Pointer to this object.
103  @see out_float, out_list, WrappedOutputClass_anything
104  */
105 void out_bang(TTPtr self);
106 
107 /** float handler for j.out
108  @param self Pointer to this object.
109  @param value The value sent to this object.
110  @see out_bang, out_list, WrappedOutputClass_anything
111  */
112 void out_float(TTPtr self, t_float value);
113 
114 /** list handler for j.out
115  @param self Pointer to this object.
116  @param msg The message sent to this object.
117  @param argc The number of arguments passed to the object.
118  @param argv Pointer to an array of atoms passed to the object.
119  @see out_bang, out_float, WrappedOutputClass_anything
120  */
121 void out_list(TTPtr self, t_symbol* msg, long argc, t_atom* argv);
122 
123 /** anything else handler for j.out
124  @param self Pointer to this object.
125  @param msg The message sent to this object.
126  @param argc The number of arguments passed to the object.
127  @param argv Pointer to an array of atoms passed to the object.
128  @see out_bang, out_float, out_list
129  */
130 void WrappedOutputClass_anything(TTPtr self, t_symbol* msg, long argc, t_atom* argv);
131 
132 /** Method used to pass message to the module outlet
133  @param self Pointer to this object.
134  @param msg The message sent to this object.
135  @param argc The number of arguments passed to the object.
136  @param argv Pointer to an array of atoms passed to the object.
137  */
138 void out_return_signal(TTPtr self, t_symbol* msg, long argc, t_atom* argv);
139 
140 #endif
141 #endif
142 
143 #pragma mark -
144 #pragma mark main
145 
146 extern "C" void JAMOMA_EXPORT_MAXOBJ setup_j0x2eout(void)
147 {
148  ModularSpec *spec = new ModularSpec;
149  spec->_wrap = &WrapTTOutputClass;
150  spec->_new = &WrappedOutputClass_new;
151  spec->_free = &WrappedOutputClass_free;
152 
153 #ifdef J_OUT_TILDE
154  spec->_any = NULL;
155  return (void)wrapTTModularClassAspdClass(kTTSym_OutputAudio, "j.out~", NULL, spec);
156 #endif
157 
158 #ifdef J_OUT_MULTI
159  spec->_any = NULL;
160  return (void)wrapTTModularClassAspdClass(kTTSym_OutputAudio, "j.out=", NULL, spec);
161 #endif
162 
163 #ifndef J_OUT_TILDE
164 #ifndef J_OUT_MULTI
165  spec->_any = &WrappedOutputClass_anything;
166  return (void)wrapTTModularClassAsPdClass(kTTSym_Output, "j.out", NULL, spec);
167 #endif
168 #endif
169 }
170 
171 void WrapTTOutputClass(WrappedClassPtr c)
172 {
173  eclass_addmethod(c->pdClass, (method)out_assist, "assist", A_CANT, 0L);
174 
175 #ifdef J_OUT_TILDE
176  eclass_addmethod(c->pdClass, (method)out_dsp64, "dsp64", A_CANT, 0);
177 #endif
178 
179 #ifdef J_OUT_MULTI
180  eclass_addmethod(c->pdClass, (method)out_reset, "audio.reset", A_CANT, 0);
181  eclass_addmethod(c->pdClass, (method)out_setup, "audio.setup", A_CANT, 0);
182  eclass_addmethod(c->pdClass, (method)out_connect, "audio.connect", A_OBJ, A_LONG, 0);
183 #endif
184 
185 #ifndef J_OUT_TILDE
186 #ifndef J_OUT_MULTI
187  eclass_addmethod(c->pdClass, (method)out_return_signal, "return_signal", A_CANT, 0);
188 
189  eclass_addmethod(c->pdClass, (method)out_bang, "bang", A_NULL, 0L);
190  eclass_addmethod(c->pdClass, (method)out_float, "float", A_FLOAT, 0L);
191  eclass_addmethod(c->pdClass, (method)out_list, "list", A_GIMME, 0L);
192 
193  // eclass_addmethod(c->pdClass, (method)out_subscribe, "loadbang", A_NULL, 0L);
194 #endif
195 #endif
196 
197  // no class_dspinit : it is done in wrapTTModularClassAspdClass for AUDIO_EXTERNAL
198 
199 }
200 
201 #pragma mark -
202 #pragma mark Object life
203 
204 void WrappedOutputClass_new(TTPtr self, long argc, t_atom* argv)
205 {
207  long attrstart = attr_args_offset(argc, argv); // support normal arguments
208  TTString sInstance;
209  TTValue v;
210 
211  // Prepare extra data
212  x->extra = (t_extra*)malloc(sizeof(t_extra));
213 
214  // Get input instance symbol
215  if (attrstart && argv) {
216 
217  jamoma_ttvalue_from_Atom(v, _sym_nothing, attrstart, argv);
218 
219  v.toString();
220  sInstance = TTString(v[0]);
221  EXTRA->instance = TTSymbol(sInstance.data());
222  }
223  else
224  EXTRA->instance = kTTSymEmpty;
225 
226  // Create Input Object and one outlet
227  x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr));
228 
229 #ifdef J_OUT_TILDE
230  jamoma_output_create_audio((t_object*)x, x->wrappedObject);
231 
232  dsp_setup((t_pxobject *)x, 1);
233  x->obj.z_misc = Z_NO_INPLACE | Z_PUT_FIRST;
234 
235  outlet_new((t_pxobject *)x, "signal");
236 
237 #endif
238 
239 #ifdef J_OUT_MULTI
240  jamoma_output_create_audio((t_object*)x, x->wrappedObject);
241 
242  x->outlets[0] = outlet_new(x, 0L);
243 #endif
244 
245 #ifndef J_OUT_TILDE
246 #ifndef J_OUT_MULTI
247  jamoma_output_create((t_object*)x, x->wrappedObject);
248 
249  x->outlets[0] = outlet_new((t_object*)x, 0L);
250 #endif
251 #endif
252 
253  // handle attribute args
254  attr_args_process(x, argc, argv);
255 
256  // The following must be deferred because we have to interrogate our box,
257  // and our box is not yet valid until we have finished instantiating the object.
258  // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6)
259  // out_subscribe(x);
260 // defer_low((t_object*)x, (method)out_subscribe, NULL, 0, NULL);
261 }
262 
264 {
266 
267 #ifdef J_OUT_TILDE
268  dsp_free((t_pxobject *)x); // Always call dsp_free first in this routine
269 #endif
270 
271  //x->wrappedObject.set("inputAddress", kTTAdrsEmpty);
272 }
273 
274 #pragma mark -
275 #pragma mark NodeLib association
276 
278 {
280  TTAddress signalAddress;
281  TTAddress outputAddress;
282  TTAddress inputAddress;
283  TTValue v, args;
284  TTNodePtr returnedNode = NULL;
285  TTNodePtr returnedContextNode = NULL;
286  TTAddress returnedAddress, parentAddress;
287  TTString formatDescription, sInstance;
288  t_object *modelOrView = NULL;
289 
290 #ifdef J_OUT_TILDE
291  signalAddress = TTAddress("audio");
292 #endif
293 
294 #ifdef J_OUT_MULTI
295  signalAddress = TTAddress("audio");
296 #endif
297 
298 #ifndef J_OUT_TILDE
299 #ifndef J_OUT_MULTI
300  signalAddress = TTAddress("data");
301 #endif
302 #endif
303 
304  // edit "signal/out.instance" address
305  outputAddress = signalAddress.appendAddress(TTAddress("out")).appendInstance(EXTRA->instance);
306 
307  // if the subscription is successful
308  if (!jamoma_subscriber_create((t_eobj*)x, x->wrappedObject, outputAddress, x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode)) {
309 
310  // get patcher
311  x->patcherPtr = ((t_eobj*)x)->o_canvas;
312 
313  // update instance symbol in case of duplicate instance
314  EXTRA->instance = returnedAddress.getInstance();
315 
316  // observe /parent/in address in order to link/unlink with an Input object below
317  returnedNode->getParent()->getAddress(parentAddress);
318  inputAddress = parentAddress.appendAddress(TTAddress("in")).appendInstance(EXTRA->instance);
319  x->wrappedObject.set("inputAddress", inputAddress);
320 
321  // get model or view object
323 
324  // notify the model there is something new concerning signal processing
325  if (modelOrView)
326  object_method_typed(modelOrView, gensym("output_created"), 0, NULL, NULL);
327  }
328 }
329 
330 #pragma mark -
331 #pragma mark Methods bound to input/inlets
332 
333 // Method for Assistance Messages
334 void out_assist(TTPtr self, TTPtr b, long msg, long arg, char *dst)
335 {
336  if (msg==1) // Inlets
337  strcpy(dst, "(signal) connect to the algorithm");
338  else if (msg==2) { // Outlets
339  if (arg == 0)
340  strcpy(dst, "(signal) output of the model");
341  else
342  strcpy(dst, "dumpout");
343  }
344 }
345 
346 #ifdef J_OUT_TILDE
347 #pragma mark -
348 #pragma mark Methods relating to audio processing
349 
350 // Perform Method 64 bit - just pass the whole vector straight through
351 // (the work is all done in the dsp 64 bit method)
352 void out_perform64(TTPtr self, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam)
353 {
356 
357  if (anOutput)
358  anOutput->process(ins[0], outs[0], sampleframes);
359 }
360 
361 
362 // DSP64 method
363 void out_dsp64(TTPtr self, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags)
364 {
367 
368  if (anOutput) {
369  anOutput->setupAudioSignals(maxvectorsize, samplerate);
370  object_method(dsp64, gensym("dsp_add64"), x, out_perform64, 0, NULL);
371  }
372 }
373 #endif
374 
375 #ifdef J_OUT_MULTI
376 #pragma mark -
377 #pragma mark Methods relating to audiograph processing
378 
379 void out_reset(TTPtr self)
380 {
383 
384  // NOTE FOR TIM : all the code below is a try and it's also a way to show you how to access to #TTOutputAudio members
385  // fell free to change everything if needed !
386 
387  // clear the internal signal in used to get signal from inside the model
388  TTAudioGraphObjectBasePtr(anOutput->mSignalIn.instance())->resetAudio();
389 
390  // clear the internal signal out used to forward signal outside the model
391  TTAudioGraphObjectBasePtr(anOutput->mSignalOut.instance())->resetAudio();
392 }
393 
394 void out_setup(TTPtr self)
395 {
398 
399  // NOTE FOR TIM : all the code below is a try and it's also a way to show you how to access to #TTOutputAudio members
400  // fell free to change everything if needed !
401 
402  t_atom a[2];
403 
404  // forward the internal signal out to connect it to any audiograph object below the j.out=
405  atom_setobj(a+0, (t_object*)anOutput->mSignalOut.instance());
406  atom_setlong(a+1, 0);
407  outlet_anything(x->outlets[signal_out], gensym("audio.connect"), 2, a);
408 }
409 
410 void out_connect(TTPtr self, TTAudioGraphObjectBasePtr audioSourceObject, long sourceOutletNumber)
411 {
414 
415  // NOTE FOR TIM : all the code below is a try and it's also a way to show you how to access to #TTOutputAudio members
416  // fell free to change everything if needed !
417 
418  // connect the source to the internal signal in
419  TTAudioGraphObjectBasePtr(anOutput->mSignalIn.instance())->connectAudio(audioSourceObject, sourceOutletNumber);
420 
421  // ??? : do we need to connect the internal signal in to the internal signal out
422  //TTAudioGraphObjectBasePtr(anOutput->mSignalOut.instance())->connectAudio(anOutput->mSignalIn, ?);
423 }
424 #endif
425 
426 #ifndef J_OUT_TILDE
427 #ifndef J_OUT_MULTI
428 #pragma mark -
429 #pragma mark Methods relating to any data processing
430 
431 void out_bang(TTPtr self)
432 {
433  out_list(self, _sym_bang, 0, NULL);
434 }
435 
436 void out_float(TTPtr self, t_float value)
437 {
438  t_atom a;
439 
440  atom_setfloat(&a, value);
441  out_list(self, _sym_float, 1, &a);
442 }
443 
444 void out_list(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
445 {
447 
448  jamoma_output_send(x->wrappedObject, msg, argc, argv);
449 }
450 
451 void WrappedOutputClass_anything(TTPtr self, t_symbol* msg, long argc, t_atom* argv)
452 {
454 
455  jamoma_output_send(x->wrappedObject, msg, argc, argv);
456 }
457 
458 void out_return_signal(TTPtr self, t_symbol* msg, long argc, t_atom* argv)
459 {
461 
462  // avoid blank before data
463  if (msg == _sym_nothing)
464  outlet_anything((t_outlet*)x->outlets[signal_out], NULL, argc, argv);
465  else
466  outlet_anything((t_outlet*)x->outlets[signal_out], msg, argc, argv);
467 }
468 #endif
469 #endif
TTAddress appendAddress(const TTAddress &toAppend)
Return a new TTAddress with the appended part.
Definition: TTAddress.h:167
TTObject subscriberObject
The instance of a TTSubscriber object used to register the wrapped object in the tree structure...
TTSymbol & getInstance()
Get the instance part.
Definition: TTAddress.h:124
TTHandle outlets
an array of outlet
TTString toString(TTBoolean quotes=YES) const
Return the content as a single string with spaces between elements.
Definition: TTValue.h:351
void WrapTTOutputClass(WrappedClassPtr c)
Wrap the j.out class as a Max object.
We build a directory of TTNodes, and you can request a pointer for any TTNode, or add an observer to ...
Definition: TTNode.h:59
TTErr JAMOMA_EXPORT jamoma_output_send(TTObject &anOutput, t_symbol *msg, long argc, const t_atom *argv)
Send any signal to a TTOutput object.
The TTAddress class is used to represent a string and efficiently pass and compare that string...
Definition: TTAddress.h:29
Data structure for storing extra data.
void * extra
used to keep very specific things
TTAddress appendInstance(const TTSymbol anInstance)
Return a new TTAddress with a instance part.
Definition: TTAddress.h:173
void out_assist(TTPtr self, TTPtr b, long msg, long arg, char *dst)
Assistance Method.
t_object * patcherPtr
the patcher in which the external is (ignoring subpatcher)
void out_return_signal(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
Method used to pass message to the module outlet.
void out_subscribe(TTPtr self)
Associate j.out(~) with NodeLib.
TTErr JAMOMA_EXPORT jamoma_output_create(t_object *x, TTObject &returnedOutput)
Create a TTOutput object for signal.
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
t_object obj
Max control object header.
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTObject wrappedObject
The instance of the Jamoma object we are wrapping.
void WrappedOutputClass_new(TTPtr self, long argc, t_atom *argv)
Wrapper for the j.out constructor class, called when an instance is created.
void JAMOMA_EXPORT jamoma_ttvalue_from_Atom(TTValue &v, t_symbol *msg, long argc, const t_atom *argv)
Make a TTValue from Atom array.
void WrappedOutputClass_anything(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
anything else handler for j.out
void WrappedOutputClass_free(TTPtr self)
Wrapper for the j.out deconstructor class, called when an instance is destroyed.
Wraps Jamoma Core classes as objects for PureData.
TTErr getAddress(TTAddress &returnedAddress, TTAddress from=kTTAdrsEmpty)
Get the address of the node.
Definition: TTNode.cpp:478
Data Structure for this object.
void out_float(TTPtr self, t_float value)
float handler for j.out
void out_bang(TTPtr self)
bang handler for j.out
The TTAudioGraphObjectBase wraps a TTDSP object such that it is possible to build a dynamic graph of ...
TTErr JAMOMA_EXPORT jamoma_output_create_audio(t_object *x, TTObject &returnedOutput)
Create an output object for audio signal.
TTObjectBase * instance() const
Return a direct pointer to the internal instance.
Definition: TTObject.cpp:105
TTErr JAMOMA_EXPORT jamoma_subscriber_create(t_object *x, TTObject &anObject, TTAddress relativeAddress, TTObject &returnedSubscriber, TTSymbol &returnedAddress, TTNodePtr *returnedNode, TTNodePtr *returnedContextNode)
Create a #TTSubscriber object and register a TTObject into the tree or, if aTTObject is NULL...
The TTString class is used to represent a string.
Definition: TTString.h:34
An audio output component for Jamoma models.
Definition: TTOutputAudio.h:23
void out_list(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
list handler for j.out
WrappedModularInstance * WrappedModularInstancePtr
Pointer to a wrapped instance of our object.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
TTNodePtr getParent()
Get a pointer to the parent node of the node.
Definition: TTNode.cpp:296
TTErr wrapTTModularClassAsPdClass(TTSymbol &ttblueClassName, const char *pdClassName, WrappedClassPtr *c, ModularSpec *specificities)
Wrap a Jamoma class as a Pd class.
void JAMOMA_EXPORT jamoma_patcher_get_model_or_view(t_object *patcher, t_object **returnedModelOrView)
Get j.model or j.view of a patcher.