Jamoma API  0.6.0.a19
j.pack_equal/j.pack.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternalsAudioGraph
4  *
5  * @brief j.pack= : Max external packing several MSP audio signals onto one AudioGraph multichannel audio signal.
6  *
7  * @details This object functions as a source (generator) for #TTAudioSignal usable by a Jamoma AudioGraph dsp chain.
8  *
9  * @authors Tim Place, Trond Lossius, Nils Peters
10  *
11  * @copyright 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 "j.pack.h"
18 
19 
20 
21 /************************************************************************************/
22 // Main() Function
23 
24 int C74_EXPORT main(void)
25 {
26  t_class* c;
27 
28  TTAudioGraphInit();
29  common_symbols_init();
30 
31  c = class_new("j.pack=", (method)PackNew, (method)PackFree, sizeof(Pack), (method)0L, A_GIMME, 0);
32 
33  class_addmethod(c, (method)PackReset, "audio.reset", A_CANT, 0);
34  class_addmethod(c, (method)PackSetup, "audio.setup", A_CANT, 0);
35  class_addmethod(c, (method)MaxAudioGraphDrop, "audio.drop", A_CANT, 0);
36  class_addmethod(c, (method)MaxAudioGraphObject, "audio.object", A_CANT, 0);
37  class_addmethod(c, (method)PackDsp64, "dsp64", A_CANT, 0);
38  class_addmethod(c, (method)PackAssist, "assist", A_CANT, 0);
39  class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
40 
41  class_dspinit(c);
42  class_register(_sym_box, c);
43  sInClass = c;
44  return 0;
45 }
46 
47 
48 /************************************************************************************/
49 // Object Creation Method
50 
51 PackPtr PackNew(t_symbol* msg, long argc, t_atom* argv)
52 {
53  PackPtr self;
54  TTValue sr(sys_getsr());
55  long attrstart = attr_args_offset(argc, argv);
56  TTValue v;
57  TTErr err;
58 
59  self =PackPtr(object_alloc(sInClass));
60  if (self) {
61  self->maxNumChannels = 2;
62  if (attrstart && argv)
63  self->maxNumChannels = atom_getlong(argv);
64 
65  // Set the sample rate of the Jamoma AudioGraph environment
66  ttEnvironment->setAttributeValue(kTTSym_sampleRate, sr);
67 
68  // Create an embedded Jamoma AudioGraph object functioning as a signal generator.
69  v.resize(3);
70  v[0] = "audio.generator";
71  v[1] = 0; // no audio graph inlets (only msp inlets)
72  v[2] = 1; // one audio graph outlet
73  err = TTObjectBaseInstantiate(TT("audio.object"), (TTObjectBasePtr*)&self->audioGraphObject, v);
74  self->audioGraphObject->addAudioFlag(kTTAudioGraphGenerator);
75  // Self check and return error if this did not work out.
76  if (!self->audioGraphObject->getUnitGenerator().valid()) {
77  object_error(SELF, "cannot load audio.generator");
78  return NULL;
79  }
80 
81  attr_args_process(self, argc, argv);
82 
83  // Create rightmost outlet for dumping attributes etc.
84  object_obex_store((void*)self, _sym_dumpout, (object*)outlet_new(self,NULL));
85 
86  // Create AudioGraph outlet
87  self->audioGraphObjectOutlet = outlet_new((t_pxobject*)self, "audio.connect");
88 
89  // Register this object as a DSP object with MSP
90  dsp_setup((t_pxobject*)self, self->maxNumChannels);
91 
92  // Set flags necsessary to ensure correct interaction with the MSP processing chain.
93  self->obj.z_misc = Z_NO_INPLACE | Z_PUT_FIRST;
94  }
95  return self;
96 }
97 
98 // Memory Deallocation
99 void PackFree(PackPtr self)
100 {
101  dsp_free((t_pxobject*)self);
102  // Release the AudioGraph object.
103  TTObjectBaseRelease((TTObjectBasePtr*)&self->audioGraphObject);
104 }
105 
106 
107 /************************************************************************************/
108 // Methods bound to input/inlets
109 
110 // Method for Assistance Messages
111 void PackAssist(PackPtr self, void* b, long msg, long arg, char* dst)
112 {
113  if (msg==1) //Packlets
114  if (arg > 0) { snprintf(dst, 256, "(signal) single-channel input Nr. %ld", arg + 1); }
115  else { strcpy(dst, "control messages and (signal) single-channel input Nr. 1");}
116  else if (msg==2) { // Outlets
117  if (arg == 0)
118  strcpy(dst, "multichannel output");
119  else
120  strcpy(dst, "dumpout");
121  }
122 }
123 
124 
125 TTErr PackReset(PackPtr self, long vectorSize)
126 {
127  return self->audioGraphObject->resetAudio();
128 }
129 
130 
132 {
133  t_atom a[2];
134 
135  atom_setobj(a+0, (t_object*)(self->audioGraphObject));
136  atom_setlong(a+1, 0);
137  outlet_anything(self->audioGraphObjectOutlet, gensym("audio.connect"), 2, a);
138  return kTTErrNone;
139 }
140 
141 
142 void PackPerform64(PackPtr self, t_object* dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam)
143 {
144  for (TTUInt32 i=0; i < self->numChannels; i++)
145  TTAudioGraphGeneratorPtr(self->audioGraphObject->getUnitGenerator().instance())->mBuffer->setVector64Copy(i, self->vectorSize, ins[i]);
146 }
147 
148 
149 void PackDsp64(PackPtr self, t_object* dsp64, short *count, double samplerate, long maxvectorsize, long flags)
150 {
151  self->vectorSize = maxvectorsize;
152 
153  // COMMENT: In the following commented out code we attempted to reduce the number of channels of the generated AudioGraph signal in the case that the rightmost inlets of j.pack= did not have any audio signals connected. This would save us some CPU. However it also introduced a bug logged as issue #16 at github.com/jamoma/JamomaCore. It might be that instead of considering this a bug in j.pack=, we rather should consider it a bug when combining several AudioGraph signals, to be resolved elsewhere. But this fixes the issue for now. [TL-2013-08-04]
154  /*
155  // Find the rightmost inlet that an audio signal is connected to.
156  TTUInt16 highestIndexForConnectedSignal = 0;
157 
158  self->numChannels = 0;
159  for (TTUInt16 i=0; i < self->maxNumChannels; i++) {
160  self->numChannels++;
161  if (count[i])
162  highestIndexForConnectedSignal = i;
163  }
164 
165  self->audioGraphObject->setOutputNumChannels(0, highestIndexForConnectedSignal+1);
166  */
167 
168  // We always set j.pack= to process all channels:
169  self->numChannels = self->maxNumChannels;
170  self->audioGraphObject->setOutputNumChannels(0, self->numChannels);
171 
172  self->audioGraphObject->getUnitGenerator().set(kTTSym_vectorSize, self->vectorSize);
173  self->audioGraphObject->getUnitGenerator().set(kTTSym_maxNumChannels, self->maxNumChannels);
174  self->audioGraphObject->getUnitGenerator().set(kTTSym_sampleRate, samplerate);
175 
176  object_method(dsp64, gensym("dsp_add64"), self,PackPerform64, 0, NULL);
177  //dsp_add64(dsp64, (t_object*)self, (t_perfroutine64)PackPerform64, 0, NULL);
178 }
TTErr TTObjectBaseRelease(TTObjectBasePtr *anObject)
DEPRECATED.
TTFOUNDATION_EXPORT TTEnvironment * ttEnvironment
The environment object has one instance, which is global in scope.
Base class for all first-class Jamoma objects.
Definition: TTObjectBase.h:109
This object is an audio generator, and do not expect audio input.
Definition: TTAudioGraph.h:73
Pack * PackPtr
Pointer to a j.pack= instance.
Definition: j.pack.h:30
TTErr setAttributeValue(const TTSymbol name, TTValue &value)
Set an attribute value for an object.
pack= : Max external packing several MSP audio signals onto one AudioGraph multichannel audio signal...
#define TT
This macro is defined as a shortcut for doing a lookup in the symbol table.
Definition: TTSymbol.h:155
void PackAssist(PackPtr self, void *b, long msg, long arg, char *dst)
Provides assist strings in Max for object inlets and outlets.
TTErr PackReset(PackPtr self, long vectorSize)
Reset audio for this object.
TTAudioGraphGenerator * TTAudioGraphGeneratorPtr
Pointer to a TTAudioGraphGenerator.
PackPtr PackNew(t_symbol *msg, long argc, t_atom *argv)
Create a new instance of the j.in= object.
TTErr TTObjectBaseInstantiate(const TTSymbol className, TTObjectBasePtr *returnedObjectPtr, const TTValue arguments)
DEPRECATED.
void PackDsp64(PackPtr self, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags)
Called when MSP is compiling the DSP chain, used to set up audio processing.
TTErr MaxAudioGraphObject(t_object *x, TTAudioGraphObjectBasePtr *returnedAudioGraphObject)
Returns a pointer to the Jamoma Audio Graph object that is wrapped by this Max object.
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
TTErr PackSetup(PackPtr self)
This method is used internally by AudioGraph when configuring itself.
std::uint32_t TTUInt32
32 bit unsigned integer
Definition: TTBase.h:178
Data Structure for the j.pack= Max object.
TTErr MaxAudioGraphDrop(t_object *x, long inletNumber, t_object *sourceMaxObject, long sourceOutletNumber)
Method called when a connection from an upstream node is dropped.
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 PackFree(PackPtr self)
Called when the object is freed (destroyed), ensuring that memory is properly freed up...
void resize(size_type n)
Change the number of elements.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34