Jamoma API  0.6.0.a19
j.unit.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternals
4  *
5  * @brief j.unit - Max external that converts values from one kind of unit to another kind of unit
6  *
7  * @details The convertions make use of the DataspaceLib
8  *
9  * @authors Tim Place, Trond Lossius
10  *
11  * @copyright Copyright © 2007 Tim Place, Trond Lossius @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 "TTClassWrapperMax.h"
18 
19 
20 // Data Structure for this object
21 typedef struct _dataspace{
22  Object ob;
23  TTPtr outlet_native;
24  TTObjectBasePtr dataspace;
25  t_symbol* attr_dataspace; // name of the dataspace -- e.g. "temperature"
26  t_symbol* attr_dataspace_active; // name of the current unit within the dataspace -- e.g. "celsius"
27  t_symbol* attr_dataspace_native; // name of the desired native unit within the dataspace -- e.g. "celsius"
28 } t_dataspace;
29 
30 
31 // Prototypes for methods
32 void* dataspace_new(t_symbol *name, long argc, t_atom *argv);
33 void dataspace_free(t_dataspace *self);
34 void dataspace_assist(t_dataspace *self, void *b, long m, long a, char *s);
35 void dataspace_int(t_dataspace *self, long x);
36 void dataspace_float(t_dataspace *self, double x);
37 void dataspace_list(t_dataspace *self, t_symbol *msg, long argc, t_atom *argv);
38 void dataspace_getDataspaces(t_dataspace *self);
39 void dataspace_getUnits(t_dataspace *self);
40 t_max_err dataspace_setDataspace(t_dataspace *self, void *attr, long argc, t_atom *argv);
41 t_max_err dataspace_setDataspaceActive(t_dataspace *self, void *attr, long argc, t_atom *argv);
42 t_max_err dataspace_setDataspaceNative(t_dataspace *self, void *attr, long argc, t_atom *argv);
43 
44 
45 // Globals
46 static t_class* dataspace_class;
47 
48 
49 #pragma mark -
50 #pragma mark main
51 /************************************************************************************/
52 // Main() Function
53 
54 int C74_EXPORT main(void)
55 {
56  t_class* c;
57 
58  TTFoundationInit();
59  common_symbols_init();
60 
61  // Define our class
62  c = class_new("j.unit",(method)dataspace_new, (method)dataspace_free, sizeof(t_dataspace), (method)0L, A_GIMME, 0);
63 
64  // Make methods accessible for our class:
65  class_addmethod(c, (method)dataspace_int, "int", A_LONG, 0);
66  class_addmethod(c, (method)dataspace_float, "float", A_FLOAT, 0);
67  class_addmethod(c, (method)dataspace_list, "list", A_GIMME, 0);
68  class_addmethod(c, (method)dataspace_getDataspaces, "dataspaces.get", 0);
69  class_addmethod(c, (method)dataspace_getUnits, "units.get", A_GIMME, 0);
70  class_addmethod(c, (method)dataspace_assist, "assist", A_CANT, 0);
71  class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
72 
73  class_addattr(c,
74  attr_offset_new("dataspace", _sym_symbol, 0,
75  (method)0, (method)dataspace_setDataspace, calcoffset(t_dataspace, attr_dataspace)));
76 
77  CLASS_ATTR_SYM(c, "input", 0, t_dataspace, attr_dataspace_active);
78  CLASS_ATTR_ACCESSORS(c, "input", NULL, dataspace_setDataspaceActive);
79 
80  CLASS_ATTR_SYM(c, "output", 0, t_dataspace, attr_dataspace_native);
81  CLASS_ATTR_ACCESSORS(c, "output", NULL, dataspace_setDataspaceNative);
82 
83  // Finalize our class
84  class_register(CLASS_BOX, c);
85  dataspace_class = c;
86  return 0;
87 }
88 
89 
90 #pragma mark -
91 #pragma mark life cycle
92 /************************************************************************************/
93 // Object Life
94 
95 void *dataspace_new(t_symbol *name, long argc, t_atom *argv)
96 {
97  t_dataspace *self;
98  TTValue none;
99 
100  self = (t_dataspace *)object_alloc(dataspace_class);
101  if (self) {
102  object_obex_store((void*)self, _sym_dumpout, (object*)outlet_new(self, NULL));
103 
104  // Make sure that environment sample rate is set correctly at instantiated,
105  // as it is used by time dataspace for conversions to and from sample
106  TTValue sr(sys_getsr());
107  ttEnvironment->setAttributeValue(kTTSym_sampleRate, sr);
108 
109  self->outlet_native = outlet_new(self, 0);
110  TTObjectBaseInstantiate(TT("dataspace"), &self->dataspace, none);
111 
112  attr_args_process(self, argc, argv);
113  if (!self->dataspace)
114  object_attr_setsym(self, gensym("dataspace"), gensym("temperature"));
115  }
116  return self;
117 }
118 
119 
120 void dataspace_free(t_dataspace *self)
121 {
122  TTObjectBaseRelease(&self->dataspace);
123 }
124 
125 
126 
127 #pragma mark -
128 #pragma mark methods
129 /************************************************************************************/
130 // Methods bound to input/inlets
131 
132 // Method for Assistance Messages
133 void dataspace_assist(t_dataspace *self, void *b, long msg, long arg, char *dst)
134 {
135  if (msg==1) // Inlets
136  strcpy(dst, "x");
137  else if (msg==2) { // Outlets
138  switch(arg) {
139  case 0: strcpy(dst, "y=f(x)"); break;
140  default: strcpy(dst, "dumpout"); break;
141  }
142  }
143 }
144 
145 
146 void dataspace_int(t_dataspace *self, long x)
147 {
148  dataspace_float(self, (double)x);
149 }
150 
151 
152 void dataspace_float(t_dataspace *self, double x)
153 {
154  TTValue v(x);
155 
156  self->dataspace->sendMessage(TT("convert"), v, v);
157  outlet_float(self->outlet_native, v.getFloat64(0));
158 }
159 
160 
161 void dataspace_list(t_dataspace *self, t_symbol *msg, long argc, t_atom *argv)
162 {
163  TTValue v;
164 
165  v.resize(argc);
166  for (int i=0; i<argc; i++)
167  v.set(i, atom_getfloat(argv+i));
168 
169  //TODO: add dataspace support for lists of single dimensional data conversion #42
170  self->dataspace->sendMessage(TT("convert"), v, v);
171 
172  argc = v.getSize(); // in case the output list is longer than the input list (e.g. quaternions)
173  t_atom* rv = new t_atom[argc];
174 
175  for (int i=0; i<argc; i++)
176  atom_setfloat(rv+i, v.getFloat64(i));
177 
178  outlet_anything(self->outlet_native, _sym_list, argc, rv);
179 }
180 
181 
182 void dataspace_getDataspaces(t_dataspace *self)
183 {
184  t_atom a[2];
185  TTValue v;
186 
187  atom_setsym(a+0, gensym("clear"));
188  object_obex_dumpout(self, gensym("DataspacesMenu"), 1, a);
189 
190  self->dataspace->sendMessage(TT("getAvailableDataspaces"), v, v);
191  for (int i=0; i < v.getSize(); i++) {
192  TTSymbol name;
193 
194  v.get(i, name);
195  atom_setsym(a+0, gensym("append"));
196  atom_setsym(a+1, gensym(name.c_str()));
197  object_obex_dumpout(self, gensym("DataspacesMenu"), 2, a);
198  }
199 }
200 
201 
202 void dataspace_getUnits(t_dataspace *self)
203 {
204  t_atom a[2];
205  TTValue v;
206 
207  atom_setsym(a+0, gensym("clear"));
208  object_obex_dumpout(self, gensym("UnitMenu"), 1, a);
209 
210  self->dataspace->sendMessage(TT("getAvailableUnits"), v, v);
211  for (int i=0; i < v.getSize(); i++) {
212  TTSymbol name;
213 
214  v.get(i, name);
215  atom_setsym(a+0, gensym("append"));
216  atom_setsym(a+1, gensym(name.c_str()));
217  object_obex_dumpout(self, gensym("UnitMenu"), 2, a);
218  }
219 }
220 
221 
222 
223 #pragma mark -
224 #pragma mark attributes
225 
226 t_max_err dataspace_setDataspace(t_dataspace *self, void *attr, long argc, t_atom *argv)
227 {
228  TTValue v;
229  TTSymbol s;
230 
231  self->attr_dataspace = atom_getsym(argv);
232  self->dataspace->setAttributeValue(TT("dataspace"), TT(self->attr_dataspace->s_name));
233 
234  self->dataspace->getAttributeValue(TT("inputUnit"), v);
235  v.get(0, s);
236  self->attr_dataspace_active = gensym(s.c_str());
237 
238  self->dataspace->getAttributeValue(TT("outputUnit"), v);
239  v.get(0, s);
240  self->attr_dataspace_native = gensym(s.c_str());
241 
242  return MAX_ERR_NONE;
243 }
244 
245 
246 t_max_err dataspace_setDataspaceActive(t_dataspace *self, void *attr, long argc, t_atom *argv)
247 {
248  self->attr_dataspace_active = atom_getsym(argv);
249  self->dataspace->setAttributeValue(TT("inputUnit"), TT(self->attr_dataspace_active->s_name));
250  return MAX_ERR_NONE;
251 }
252 
253 
254 t_max_err dataspace_setDataspaceNative(t_dataspace *self, void *attr, long argc, t_atom *argv)
255 {
256  self->attr_dataspace_native = atom_getsym(argv);
257  self->dataspace->setAttributeValue(TT("outputUnit"), TT(self->attr_dataspace_native->s_name));
258  return MAX_ERR_NONE;
259 }
260 
TTUInt16 getSize() const
DEPRECATED.
Definition: TTValue.h:521
TTErr TTObjectBaseRelease(TTObjectBasePtr *anObject)
DEPRECATED.
TTFOUNDATION_EXPORT TTEnvironment * ttEnvironment
The environment object has one instance, which is global in scope.
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.unit.cpp:54
Base class for all first-class Jamoma objects.
Definition: TTObjectBase.h:109
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
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTErr TTObjectBaseInstantiate(const TTSymbol className, TTObjectBasePtr *returnedObjectPtr, const TTValue arguments)
DEPRECATED.
void get(const TTUInt16 index, T &returnedElementValue) const
DEPRECATED.
Definition: TTValue.h:591
const char * c_str() const
Return a pointer to the internal string as a C-string.
Definition: TTSymbol.h:77
void set(const TTUInt16 index, const T &anElementValue)
DEPRECATED.
Definition: TTValue.h:569
TTFloat64 getFloat64(TTUInt16 index=0) const
DEPRECATED.
Definition: TTValue.h:642
void resize(size_type n)
Change the number of elements.
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34