Jamoma API  0.6.0.a19
j.wavetable.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternalsAudioGraph
4  *
5  * @brief j.wavetable= : wraps the #TTWavetable class as oscillation generator for AudioGraph
6  *
7  * @details
8  *
9  * @authors Tim Place, Trond Lossius
10  *
11  * @copyright © 2008, Tim 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 
19 
20 // Data Structure for this object
21 typedef struct _oscil {
22  t_object obj;
23  TTAudioGraphObjectBasePtr audioGraphObject;
24  TTPtr audioGraphOutlet;
25  t_symbol *attrWaveform;
26  t_symbol *attrInterpolation;
27  float attrFrequency;
28  float attrGain;
29  long attrNumChannels;
30 } t_oscil;
31 
32 
33 // Prototypes for methods
34 t_oscil* OscilNew(t_symbol *msg, long argc, t_atom* argv);
35 void OscilFree(t_oscil* self);
36 void OscilAssist(t_oscil* self, void* b, long msg, long arg, char* dst);
37 TTErr OscilReset(t_oscil* self);
38 TTErr OscilSetup(t_oscil* self);
39 TTErr OscilConnectAudio(t_oscil* self, TTAudioGraphObjectBasePtr audioSourceObject, long sourceOutletNumber);
40 TTErr OscilDropAudio(t_oscil* self, long inletNumber, t_object* sourceMaxObject, long sourceOutletNumber);
41 t_max_err OscilSetMode(t_oscil* self, void* attr, long argc, t_atom* argv);
42 t_max_err OscilSetInterpolation(t_oscil* self, void* attr, long argc, t_atom* argv);
43 t_max_err OscilSetFrequency(t_oscil* self, void* attr, long argc, t_atom* argv);
44 t_max_err OscilSetGain(t_oscil* self, void* attr, long argc, t_atom* argv);
45 t_max_err OscilSetNumChannels(t_oscil* self, void* attr, long argc, t_atom* argv);
46 
47 
48 // Globals
49 static t_class* s_oscil_class;
50 
51 
52 /************************************************************************************/
53 // Main() Function
54 
55 int C74_EXPORT main(void)
56 {
57  t_class *c;
58 
59  TTAudioGraphInit();
60  common_symbols_init();
61 
62  c = class_new("j.wavetable=", (method)OscilNew, (method)OscilFree, sizeof(t_oscil), (method)0L, A_GIMME, 0);
63 
64  class_addmethod(c, (method)OscilReset, "audio.reset", A_CANT, 0);
65  class_addmethod(c, (method)OscilSetup, "audio.setup", A_CANT, 0);
66  class_addmethod(c, (method)OscilConnectAudio, "audio.connect", A_OBJ, A_LONG, 0);
67  class_addmethod(c, (method)OscilDropAudio, "audio.drop", A_CANT, 0);
68  class_addmethod(c, (method)MaxAudioGraphObject, "audio.object", A_CANT, 0);
69  class_addmethod(c, (method)OscilAssist, "assist", A_CANT, 0);
70  class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
71 
72  CLASS_ATTR_SYM(c, "waveform", 0, t_oscil, attrWaveform);
73  CLASS_ATTR_ACCESSORS(c, "waveform", NULL, OscilSetMode);
74  CLASS_ATTR_ENUM(c, "waveform", 0, "cosine ramp sawtooth sine square triangle");
75  CLASS_ATTR_DEFAULTNAME(c,"waveform", 0, "sine");
76 
77  CLASS_ATTR_SYM(c, "interpolation", 0, t_oscil, attrInterpolation);
78  CLASS_ATTR_ACCESSORS(c, "interpolation", NULL, OscilSetInterpolation);
79  CLASS_ATTR_ENUM(c, "interpolation", 0, "none linear lfo");
80  CLASS_ATTR_DEFAULTNAME(c,"interpolation", 0, "linear");
81 
82  CLASS_ATTR_FLOAT(c, "frequency", 0, t_oscil, attrFrequency);
83  CLASS_ATTR_ACCESSORS(c, "frequency", NULL, OscilSetFrequency);
84  CLASS_ATTR_DEFAULT(c, "frequency", 0, "1000");
85 
86  CLASS_ATTR_FLOAT(c, "gain", 0, t_oscil, attrGain);
87  CLASS_ATTR_DEFAULT(c, "gain", 0, "1.0");
88  CLASS_ATTR_ACCESSORS(c, "gain", NULL, OscilSetGain);
89 
90  CLASS_ATTR_LONG(c, "numChannels", 0, t_oscil, attrNumChannels);
91  CLASS_ATTR_ACCESSORS(c, "numChannels", NULL, OscilSetNumChannels);
92  CLASS_ATTR_DEFAULT(c, "numChannels", 0, "1");
93 
94  class_register(_sym_box, c);
95  s_oscil_class = c;
96  return 0;
97 }
98 
99 
100 /************************************************************************************/
101 // Object Creation Method
102 
103 t_oscil* OscilNew(t_symbol *msg, long argc, t_atom* argv)
104 {
105  t_oscil* self = (t_oscil*)object_alloc(s_oscil_class);
106  TTValue v;
107  TTErr err;
108 
109  if (self) {
110  v.resize(2);
111  v[0] = "wavetable";
112  v[1] = 0;
113  err = TTObjectBaseInstantiate(TT("audio.object"), (TTObjectBasePtr*)&self->audioGraphObject, v);
114 
115  self->audioGraphObject->addAudioFlag(kTTAudioGraphGenerator);
116 
117  attr_args_process(self, argc, argv);
118  object_obex_store((TTPtr)self, _sym_dumpout, (t_object*)outlet_new(self, NULL));
119  self->audioGraphOutlet = outlet_new((t_pxobject*)self, "audio.connect");
120  }
121  return self;
122 }
123 
124 // Memory Deallocation
125 void OscilFree(t_oscil* self)
126 {
127  TTObjectBaseRelease((TTObjectBasePtr*)&self->audioGraphObject);
128 }
129 
130 
131 /************************************************************************************/
132 // Methods bound to input/inlets
133 
134 // Method for Assistance Messages
135 void OscilAssist(t_oscil* self, void* b, long msg, long arg, char* dst)
136 {
137  if (msg==1) // Inlets
138  strcpy(dst, "multichannel audio connection and control messages");
139  else if (msg==2) { // Outlets
140  if (arg == 0)
141  strcpy(dst, "multichannel audio connection");
142  else
143  strcpy(dst, "dumpout");
144  }
145 }
146 
147 
148 TTErr OscilReset(t_oscil* self)
149 {
150  return self->audioGraphObject->resetAudio();
151 }
152 
153 
154 TTErr OscilSetup(t_oscil* self)
155 {
156  t_atom a[2];
157 
158  atom_setobj(a+0, (t_object*)(self->audioGraphObject));
159  atom_setlong(a+1, 0);
160  outlet_anything(self->audioGraphOutlet, gensym("audio.connect"), 2, a);
161  return kTTErrNone;
162 }
163 
164 
165 TTErr OscilConnectAudio(t_oscil* self, TTAudioGraphObjectBasePtr audioSourceObject, long sourceOutletNumber)
166 {
167  self->audioGraphObject->removeAudioFlag(kTTAudioGraphGenerator);
168  self->audioGraphObject->setAttributeValue(TT("numAudioInlets"), 1);
169  return self->audioGraphObject->connectAudio(audioSourceObject, sourceOutletNumber);
170 }
171 
172 
173 TTErr OscilDropAudio(t_oscil* self, long inletNumber, t_object* sourceMaxObject, long sourceOutletNumber)
174 {
175  TTAudioGraphObjectBasePtr sourceObject = NULL;
176  TTErr err;
177 
178  self->audioGraphObject->setAttributeValue(TT("numAudioInlets"), 0);
179  self->audioGraphObject->addAudioFlag(kTTAudioGraphGenerator);
180  err = (TTErr)(TTPtrSizedInt)(object_method(sourceMaxObject, gensym("audio.object"), &sourceObject));
181  if (self->audioGraphObject && sourceObject && !err)
182  err = self->audioGraphObject->dropAudio(sourceObject, sourceOutletNumber, inletNumber);
183  return err;
184 }
185 
186 
187 
188 t_max_err OscilSetMode(t_oscil* self, void* attr, long argc, t_atom* argv)
189 {
190 
191  if (argc) {
192  TTValue v;
193 
194  v.resize(argc);
195  for (int i=0; i<argc; i++)
196  v[i] = TT(atom_getsym(argv+i)->s_name);
197 
198  self->attrWaveform = atom_getsym(argv);
199  self->audioGraphObject->getUnitGenerator().set(TT("mode"), v);
200  }
201  return MAX_ERR_NONE;
202 }
203 
204 
205 t_max_err OscilSetInterpolation(t_oscil* self, void* attr, long argc, t_atom* argv)
206 {
207  if (argc) {
208  self->attrInterpolation = atom_getsym(argv);
209  self->audioGraphObject->getUnitGenerator().set(TT("interpolation"), TT(self->attrInterpolation->s_name));
210  }
211  return MAX_ERR_NONE;
212 }
213 
214 
215 t_max_err OscilSetFrequency(t_oscil* self, void* attr, long argc, t_atom* argv)
216 {
217  if (argc) {
218  self->attrFrequency = atom_getfloat(argv);
219  self->audioGraphObject->getUnitGenerator().set(TT("frequency"), self->attrFrequency);
220  }
221  return MAX_ERR_NONE;
222 }
223 
224 
225 t_max_err OscilSetGain(t_oscil* self, void* attr, long argc, t_atom* argv)
226 {
227  if (argc) {
228  self->attrGain = atom_getfloat(argv);
229  self->audioGraphObject->getUnitGenerator().set(TT("gain"), self->attrGain);
230  }
231  return MAX_ERR_NONE;
232 }
233 
234 
235 t_max_err OscilSetNumChannels(t_oscil* self, void* attr, long argc, t_atom* argv)
236 {
237  if (argc) {
238  self->attrNumChannels = atom_getlong(argv);
239  self->audioGraphObject->setOutputNumChannels(0, self->attrNumChannels);
240  }
241  return MAX_ERR_NONE;
242 }
243 
TTErr TTObjectBaseRelease(TTObjectBasePtr *anObject)
DEPRECATED.
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
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
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
TTErr TTObjectBaseInstantiate(const TTSymbol className, TTObjectBasePtr *returnedObjectPtr, const TTValue arguments)
DEPRECATED.
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.
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 ...
No Error.
Definition: TTBase.h:343
void resize(size_type n)
Change the number of elements.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
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.wavetable.cpp:55