Jamoma API  0.6.0.a19
Max/source/j.map/j.map.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternals
4  *
5  * @brief j.map - map input to output: y=f(x)
6  *
7  * @details
8  *
9  * @authors Théo de la Hogue, Trond Lossius
10  *
11  * @copyright Copyright © 2010 by Théo de la Hogue @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
18 
19 #define data_out 0
20 #define dump_out 1
21 
22 // This is used to store extra data
23 typedef struct extra {
24  TTValuePtr arguments; // keep creation arguments to reset the mapper to the initial state
25 } t_extra;
26 #define EXTRA ((t_extra*)x->extra)
27 
28 // Definitions
29 void WrapTTMapperClass(WrappedClassPtr c);
30 void WrappedMapperClass_new(TTPtr self, long argc, t_atom *argv);
31 void WrappedMapperClass_free(TTPtr self);
32 
33 void map_assist(TTPtr self, void *b, long msg, long arg, char *dst);
34 
35 void map_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
36 void map_return_input_going_down(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
37 void map_return_input_going_up(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
38 void map_return_output_going_down(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
39 void map_return_output_going_up(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
40 
41 void map_int(TTPtr self, long value);
42 void map_float(TTPtr self, double value);
43 void map_list(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
44 
45 void map_reset(TTPtr self);
46 
47 void map_subscribe(TTPtr self);
48 
49 int C74_EXPORT main(void)
50 {
51  ModularSpec *spec = new ModularSpec;
52  spec->_wrap = &WrapTTMapperClass;
53  spec->_new = &WrappedMapperClass_new;
54  spec->_free = &WrappedMapperClass_free;
55  spec->_any = NULL;
56 
57  return wrapTTModularClassAsMaxClass(kTTSym_Mapper, "j.map", NULL, spec);
58 }
59 
60 void WrapTTMapperClass(WrappedClassPtr c)
61 {
62  class_addmethod(c->maxClass, (method)map_assist, "assist", A_CANT, 0L);
63 
64  class_addmethod(c->maxClass, (method)map_return_value, "return_value", A_CANT, 0);
65  class_addmethod(c->maxClass, (method)map_return_input_going_down, "return_input_going_down", A_CANT, 0);
66  class_addmethod(c->maxClass, (method)map_return_input_going_up, "return_input_going_up", A_CANT, 0);
67  class_addmethod(c->maxClass, (method)map_return_output_going_down, "return_output_going_down", A_CANT, 0);
68  class_addmethod(c->maxClass, (method)map_return_output_going_up, "return_output_going_up", A_CANT, 0);
69 
70  class_addmethod(c->maxClass, (method)map_int, "int", A_LONG, 0L);
71  class_addmethod(c->maxClass, (method)map_float, "float", A_FLOAT, 0L);
72  class_addmethod(c->maxClass, (method)map_list, "list", A_GIMME, 0L);
73 
74  class_addmethod(c->maxClass, (method)map_reset, "reset", 0L);
75 }
76 
77 void WrappedMapperClass_new(TTPtr self, long argc, t_atom *argv)
78 {
80  t_symbol *relativeAddress;
81  long attrstart = attr_args_offset(argc, argv); // support normal arguments
82 
83  // possible relativeAddress
84  if (attrstart && argv)
85  relativeAddress = atom_getsym(argv);
86  else
87  relativeAddress = _sym_nothing;
88 
89  x->address = TTAddress(jamoma_parse_dieze((t_object*)x, relativeAddress)->s_name);
90 
91  jamoma_mapper_create((t_object*)x, x->wrappedObject);
92 
93  // Make two outlets
94  x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr) * 1);
95  x->outlets[data_out] = outlet_new(x, NULL); // anything outlet to output data
96 
97  // handle attribute args
98  attr_args_process(x, argc, argv);
99 
100  // Prepare extra data
101  x->extra = (t_extra*)malloc(sizeof(t_extra));
102  EXTRA->arguments = new TTValue();
103  jamoma_ttvalue_from_Atom(*EXTRA->arguments, _sym_nothing, argc, argv);
104 
105  // The following must be deferred because we have to interrogate our box,
106  // and our box is not yet valid until we have finished instantiating the object.
107  // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6)
108  defer_low((t_object*)x, (method)map_subscribe, NULL, 0, 0);
109 }
110 
111 void WrappedMapperClass_free(TTPtr self)
112 {
114  delete EXTRA->arguments;
115 
116  x->wrappedObject.set("input", kTTAdrsEmpty);
117  x->wrappedObject.set("output", kTTAdrsEmpty);
118 
119  free(EXTRA);
120 }
121 
122 // Method for Assistance Messages
123 void map_assist(TTPtr self, void *b, long msg, long arg, char *dst)
124 {
125  if (msg==1) // Inlets
126  strcpy(dst, "");
127  else { // Outlets
128  switch(arg) {
129  case data_out:
130  strcpy(dst, "mapping output");
131  break;
132  case dump_out:
133  strcpy(dst, "dumpout");
134  break;
135  }
136  }
137 }
138 
139 void map_subscribe(TTPtr self)
140 {
141  /* TODO : fix exposeAttribute as parameter because for now
142  it crash due to a locked mutex during the notification
143  of observers when the attribute is updated from a Max message.
144 
145  WrappedModularInstancePtr x = (WrappedModularInstancePtr)self;
146  TTValue v, n, args;
147  TTDataPtr aData;
148 
149  // add 'cue' after the address
150  if (x->address == kTTAdrsEmpty)
151  x->address = TADRS("mapper");
152  // if the subscription is successful
153  if (!jamoma_subscriber_create((ObjectPtr)x, x->wrappedObject, x->address, &x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode)) {
154  // expose attributes of TTMapper as TTData in the tree structure
155  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("input"), kTTSym_parameter, &aData);
156  aData->setAttributeValue(kTTSym_type, kTTSym_string);
157  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
158  aData->setAttributeValue(kTTSym_description, TTSymbol("The input address to map"));
159  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("output"), kTTSym_parameter, &aData);
160  aData->setAttributeValue(kTTSym_type, kTTSym_string);
161  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
162  aData->setAttributeValue(kTTSym_description, TTSymbol("The output address to map"));
163  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("inputMin"), kTTSym_parameter, &aData);
164  aData->setAttributeValue(kTTSym_type, kTTSym_decimal);
165  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
166  aData->setAttributeValue(kTTSym_description, TTSymbol("The low bound input value"));
167  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("inputMax"), kTTSym_parameter, &aData);
168  aData->setAttributeValue(kTTSym_type, kTTSym_decimal);
169  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
170  aData->setAttributeValue(kTTSym_description, TTSymbol("The high bound input value"));
171  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("outputMin"), kTTSym_parameter, &aData);
172  aData->setAttributeValue(kTTSym_type, kTTSym_decimal);
173  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
174  aData->setAttributeValue(kTTSym_description, TTSymbol("The low bound output value"));
175  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("outputMax"), kTTSym_parameter, &aData);
176  aData->setAttributeValue(kTTSym_type, kTTSym_decimal);
177  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
178  aData->setAttributeValue(kTTSym_description, TTSymbol("The high bound output value"));
179  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("enable"), kTTSym_parameter, &aData);
180  aData->setAttributeValue(kTTSym_type, kTTSym_boolean);
181  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
182  aData->setAttributeValue(kTTSym_description, TTSymbol("Turn on and off the mapping"));
183  }
184  */
185 }
186 
187 void map_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
188 {
190  outlet_atoms(x->outlets[data_out], argc, argv);
191 }
192 
193 void map_return_input_going_down(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
194 {
195  object_obex_dumpout(self, gensym("input/going/down"), argc, argv);
196 }
197 
198 void map_return_input_going_up(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
199 {
200  object_obex_dumpout(self, gensym("input/going/up"), argc, argv);
201 }
202 
203 void map_return_output_going_down(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
204 {
205  object_obex_dumpout(self, gensym("output/going/down"), argc, argv);
206 }
207 
208 void map_return_output_going_up(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
209 {
210  object_obex_dumpout(self, gensym("output/going/up"), argc, argv);
211 }
212 
213 void map_bang(TTPtr self)
214 {
215  map_list(self, _sym_bang, 0, NULL);
216 }
217 
218 void map_int(TTPtr self, long value)
219 {
220  t_atom a;
221 
222  atom_setlong(&a, value);
223  map_list(self, _sym_int, 1, &a);
224 }
225 
226 void map_float(TTPtr self, double value)
227 {
228  t_atom a;
229 
230  atom_setfloat(&a, value);
231  map_list(self, _sym_float, 1, &a);
232 }
233 
234 void map_list(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
235 {
237  TTValue inputValue, outputValue;
238 
239  jamoma_ttvalue_from_Atom(inputValue, msg, argc, argv);
240 
241  x->wrappedObject.send(kTTSym_Map, inputValue, outputValue);
242 
243  // we don't send the output value here because there is callback for this
244 }
245 
246 void map_reset(TTPtr self)
247 {
249  long argc = 0;
250  t_atom *argv = NULL;
251 
252  jamoma_ttvalue_to_Atom(*EXTRA->arguments, &argc, &argv);
253 
254  // handle attribute args to reset to creation state
255  attr_args_process(x, argc, argv);
256 }
TTErr send(const TTSymbol aName)
Send a message to this object with no arguments.
Definition: TTObject.cpp:135
TTHandle outlets
an array of outlet
TTErr wrapTTModularClassAsMaxClass(TTSymbol &ttblueClassName, const char *maxClassName, WrappedClassPtr *c, ModularSpec *specificities)
Wrap a Jamoma class as a Max class.
t_symbol JAMOMA_EXPORT * jamoma_parse_dieze(t_object *x, t_symbol *address)
Parse #N inside address and replace them by parent patcher arguments if there are.
TTAddress address
sometime external needs to store an address (e.g. send, receive, view, ...)
TTErr JAMOMA_EXPORT jamoma_mapper_create(t_object *x, TTObject &returnedMapper)
Create a TTMapper object.
int C74_EXPORT main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
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
void * TTPtr
A generic pointer.
Definition: TTBase.h:248
void JAMOMA_EXPORT jamoma_ttvalue_to_Atom(const TTValue &v, long *argc, t_atom **argv)
Make an Atom array from a TTValue.
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
TTObject wrappedObject
The instance of the Jamoma object we are wrapping.
void JAMOMA_EXPORT jamoma_ttvalue_from_Atom(TTValue &v, t_symbol *msg, long argc, const t_atom *argv)
Make a TTValue from Atom array.
Data Structure for this object.
Wraps Jamoma Core classes as objects for Max/MSP.
WrappedModularInstance * WrappedModularInstancePtr
Pointer to a wrapped instance of our object.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34