Jamoma API  0.6.0.a19
PureData/source/j.map/j.map.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationPdExternals
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, Antoine Villeret
10  *
11  * @copyright Copyright © 2010 by 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 data_out 0
21 #define dump_out 1
22 
23 // This is used to store extra data
24 typedef struct extra {
25  TTValuePtr arguments; // keep creation arguments to reset the mapper to the initial state
26 } t_extra;
27 #define EXTRA ((t_extra*)x->extra)
28 
29 // Definitions
30 void WrapTTMapperClass(WrappedClassPtr c);
31 void WrappedMapperClass_new(TTPtr self, long argc, t_atom *argv);
32 void WrappedMapperClass_free(TTPtr self);
33 
34 void map_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
35 void map_return_input_going_down(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
36 void map_return_input_going_up(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
37 void map_return_output_going_down(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
38 void map_return_output_going_up(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
39 
40 void map_float(TTPtr self, t_float value);
41 void map_list(TTPtr self, t_symbol *msg, long argc, t_atom *argv);
42 
43 void map_reset(TTPtr self);
44 
45 void map_subscribe(TTPtr self);
46 
47 extern "C" void JAMOMA_EXPORT_MAXOBJ setup_j0x2emap(void)
48 {
49  ModularSpec *spec = new ModularSpec;
50  spec->_wrap = &WrapTTMapperClass;
51  spec->_new = &WrappedMapperClass_new;
52  spec->_free = &WrappedMapperClass_free;
53  spec->_any = NULL;
54  spec->_notify = NULL;
55 
56  return (void)wrapTTModularClassAsPdClass(kTTSym_Mapper, "j.map", NULL, spec);
57 }
58 
59 void WrapTTMapperClass(WrappedClassPtr c)
60 {
61  eclass_addmethod(c->pdClass, (method)map_return_value, "return_value", A_CANT, 0);
62  eclass_addmethod(c->pdClass, (method)map_return_input_going_down, "return_input_going_down", A_CANT, 0);
63  eclass_addmethod(c->pdClass, (method)map_return_input_going_up, "return_input_going_up", A_CANT, 0);
64  eclass_addmethod(c->pdClass, (method)map_return_output_going_down, "return_output_going_down", A_CANT, 0);
65  eclass_addmethod(c->pdClass, (method)map_return_output_going_up, "return_output_going_up", A_CANT, 0);
66 
67  eclass_addmethod(c->pdClass, (method)map_float, "float", A_FLOAT, 0L);
68  eclass_addmethod(c->pdClass, (method)map_list, "list", A_GIMME, 0L);
69 
70  eclass_addmethod(c->pdClass, (method)map_reset, "reset", A_NULL, 0L);
71  eclass_addmethod(c->pdClass, (method)map_subscribe, "loadbang", A_NULL, 0L);
72 }
73 
74 void WrappedMapperClass_new(TTPtr self, long argc, t_atom *argv)
75 {
77  t_symbol *relativeAddress;
78  long attrstart = attr_args_offset(argc, argv); // support normal arguments
79 
80  // possible relativeAddress
81  if (attrstart && argv)
82  relativeAddress = atom_getsym(argv);
83  else
84  relativeAddress = _sym_nothing;
85 
86  if (relativeAddress) x->address = TTAddress(relativeAddress->s_name);
87 
88  jamoma_mapper_create((t_object*)x, x->wrappedObject);
89 
90  // Make two outlets
91  x->outlets = (TTHandle)sysmem_newptr(sizeof(TTPtr));
92  x->outlets[data_out] = outlet_new((t_object*)x, NULL); // anything outlet to output data
93  x->dumpOut = outlet_new((t_object*)x, NULL);
94 
95  // handle attribute args
96  attr_args_process(x, argc, argv);
97 
98  // Prepare extra data
99  x->extra = (t_extra*)malloc(sizeof(t_extra));
100  EXTRA->arguments = new TTValue();
101  jamoma_ttvalue_from_Atom(*EXTRA->arguments, _sym_nothing, argc, argv);
102 
103  // The following must be deferred because we have to interrogate our box,
104  // and our box is not yet valid until we have finished instantiating the object.
105  // Trying to use a loadbang method instead is also not fully successful (as of Max 5.0.6)
106 // map_subscribe(x);
107 // defer_low((t_object*)x, (method)map_subscribe, NULL, 0, 0);
108 }
109 
110 void WrappedMapperClass_free(TTPtr self)
111 {
113  delete EXTRA->arguments;
114 
115  x->wrappedObject.set("input", kTTAdrsEmpty);
116  x->wrappedObject.set("output", kTTAdrsEmpty);
117 
118  free(EXTRA);
119 }
120 
121 void map_subscribe(TTPtr self)
122 {
123  /* TODO : fix exposeAttribute as parameter because for now
124  it crash due to a locked mutex during the notification
125  of observers when the attribute is updated from a Max message.
126 
127  WrappedModularInstancePtr x = (WrappedModularInstancePtr)self;
128  TTValue v, n, args;
129  TTDataPtr aData;
130 
131  // add 'cue' after the address
132  if (x->address == kTTAdrsEmpty)
133  x->address = TADRS("mapper");
134  // if the subscription is successful
135  if (!jamoma_subscriber_create((ObjectPtr)x, x->wrappedObject, x->address, &x->subscriberObject, returnedAddress, &returnedNode, &returnedContextNode)) {
136  // expose attributes of TTMapper as TTData in the tree structure
137  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("input"), kTTSym_parameter, &aData);
138  aData->setAttributeValue(kTTSym_type, kTTSym_string);
139  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
140  aData->setAttributeValue(kTTSym_description, TTSymbol("The input address to map"));
141  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("output"), kTTSym_parameter, &aData);
142  aData->setAttributeValue(kTTSym_type, kTTSym_string);
143  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
144  aData->setAttributeValue(kTTSym_description, TTSymbol("The output address to map"));
145  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("inputMin"), kTTSym_parameter, &aData);
146  aData->setAttributeValue(kTTSym_type, kTTSym_decimal);
147  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
148  aData->setAttributeValue(kTTSym_description, TTSymbol("The low bound input value"));
149  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("inputMax"), kTTSym_parameter, &aData);
150  aData->setAttributeValue(kTTSym_type, kTTSym_decimal);
151  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
152  aData->setAttributeValue(kTTSym_description, TTSymbol("The high bound input value"));
153  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("outputMin"), kTTSym_parameter, &aData);
154  aData->setAttributeValue(kTTSym_type, kTTSym_decimal);
155  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
156  aData->setAttributeValue(kTTSym_description, TTSymbol("The low bound output value"));
157  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("outputMax"), kTTSym_parameter, &aData);
158  aData->setAttributeValue(kTTSym_type, kTTSym_decimal);
159  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
160  aData->setAttributeValue(kTTSym_description, TTSymbol("The high bound output value"));
161  x->subscriberObject->exposeAttribute(x->wrappedObject, TTSymbol("enable"), kTTSym_parameter, &aData);
162  aData->setAttributeValue(kTTSym_type, kTTSym_boolean);
163  aData->setAttributeValue(kTTSym_tags, kTTSym_generic);
164  aData->setAttributeValue(kTTSym_description, TTSymbol("Turn on and off the mapping"));
165  }
166  */
167 }
168 
169 void map_return_value(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
170 {
172  outlet_anything((t_outlet*)x->outlets[data_out], _sym_list, argc, argv);
173 }
174 
175 void map_return_input_going_down(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
176 {
178  outlet_anything((t_outlet*)x->dumpOut, gensym("input/going/down"), argc, argv);
179 }
180 
181 void map_return_input_going_up(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
182 {
184  outlet_anything((t_outlet*)x->dumpOut, gensym("input/going/up"), argc, argv);
185 }
186 
187 void map_return_output_going_down(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
188 {
190  outlet_anything((t_outlet*)x->dumpOut, gensym("output/going/down"), argc, argv);
191 }
192 
193 void map_return_output_going_up(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
194 {
196  outlet_anything((t_outlet*)x->dumpOut, gensym("output/going/up"), argc, argv);
197 }
198 
199 void map_bang(TTPtr self)
200 {
201  map_list(self, _sym_bang, 0, NULL);
202 }
203 
204 void map_float(TTPtr self, t_float value)
205 {
206  t_atom a;
207 
208  atom_setfloat(&a, value);
209  map_list(self, _sym_float, 1, &a);
210 }
211 
212 void map_list(TTPtr self, t_symbol *msg, long argc, t_atom *argv)
213 {
215  TTValue inputValue, outputValue;
216 
217  jamoma_ttvalue_from_Atom(inputValue, msg, argc, argv);
218 
219  x->wrappedObject.send(kTTSym_Map, inputValue, outputValue);
220 
221  // we don't send the output value here because there is callback for this
222 }
223 
224 void map_reset(TTPtr self)
225 {
227  long argc = 0;
228  t_atom *argv = NULL;
229 
230  jamoma_ttvalue_to_Atom(*EXTRA->arguments, &argc, &argv);
231 
232  // handle attribute args to reset to creation state
233  attr_args_process(x, argc, argv);
234 }
TTErr send(const TTSymbol aName)
Send a message to this object with no arguments.
Definition: TTObject.cpp:135
TTHandle outlets
an array of outlet
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.
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.
Wraps Jamoma Core classes as objects for PureData.
Data Structure for this object.
WrappedModularInstance * WrappedModularInstancePtr
Pointer to a wrapped instance of our object.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
TTErr wrapTTModularClassAsPdClass(TTSymbol &ttblueClassName, const char *pdClassName, WrappedClassPtr *c, ModularSpec *specificities)
Wrap a Jamoma class as a Pd class.