Jamoma API  0.6.0.a19
j.cubicInterpolate.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternals
4  *
5  * @brief j.cubicInterpolate - External for Jamoma: j.cubicInterpolate - Cubic interpolation on a stream of floats
6  *
7  * @details
8  *
9  * @authors Trond Lossius, Tim Place
10  *
11  * @copyright Copyright © 2006, 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 "JamomaForMax.h"
18 
19 typedef struct _cubic_interp{ // Data structure for this object
20  t_object ob; // Must always be the first field; used by Max
21  float value[4]; // Four y values used for interpolation
22  float mu; // Previous interpolated x-position
23  float attr_step; // ATTRIBUTE: step size
24  char clearflag;
25  void *outlet2; // Pointer to outlet. need one for each outlet
26  void *outlet;
27 } t_cubic_interp;
28 
29 // Prototypes for methods: need a method for each incoming message
30 void *cubic_interpolate_new(t_symbol *msg, long argc, t_atom *argv);
31 t_max_err cubic_interpolation_setstep(t_cubic_interp *x, void *attr, long argc, t_atom *argv);
32 void cubic_interpolate_bang(t_cubic_interp *x);
33 void cubic_interpolate_int(t_cubic_interp *x, long n);
34 void cubic_interpolate_float(t_cubic_interp *x, double f);
35 void cubic_interpolate_clear(t_cubic_interp *x);
36 void cubic_interpolate_assist(t_cubic_interp *x, void *b, long msg, long arg, char *dst);
37 
38 
39 
40 // Globals
41 t_class *this_class; // Required. Global pointing to this class
42 
43 
44 
45 /************************************************************************************/
46 // Main() Function
47 
48 int JAMOMA_EXPORT_MAXOBJ main(void)
49 {
50  long attrflags = 0;
51  t_class *c;
52  t_object *attr;
53 
54  common_symbols_init();
55 
56  // Define our class
57  c = class_new("j.cubicInterpolate",(method)cubic_interpolate_new, (method)0L, sizeof(t_cubic_interp),
58  (method)0L, A_GIMME, 0);
59 
60  // Make methods accessible for our class:
61  class_addmethod(c, (method)cubic_interpolate_bang, "bang", A_CANT, 0);
62  class_addmethod(c, (method)cubic_interpolate_int, "int", A_LONG, 0);
63  class_addmethod(c, (method)cubic_interpolate_float, "float", A_FLOAT, 0);
64  class_addmethod(c, (method)cubic_interpolate_assist, "assist", A_CANT, 0);
65  class_addmethod(c, (method)cubic_interpolate_clear, "clear", 0);
66  class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
67 
68  // Add attributes to our class:
69  // ATTRIBUTE: step size - clipped to the range [0, 1]
70  attr = attr_offset_new("step", _sym_float, attrflags,
71  (method)0L, (method)cubic_interpolation_setstep, calcoffset(t_cubic_interp, attr_step));
72  class_addattr(c, attr);
73 
74  // Finalize our class
75  class_register(CLASS_BOX, c);
76  this_class = c;
77  return 0;
78 }
79 
80 
81 /************************************************************************************/
82 // Object Life
83 
84 void *cubic_interpolate_new(t_symbol *msg, long argc, t_atom *argv)
85 {
86  t_cubic_interp *x;
87 
88  x = (t_cubic_interp *)object_alloc(this_class); // create the new instance and return a pointer to it
89 
90  if (x) {
91  object_obex_store((void *)x, _sym_dumpout, (object *)outlet_new(x,NULL)); // dumpout
92  x->outlet2 = bangout(x); // create 2nd outlet. Used to ask for new value
93  x->outlet = floatout(x); // create the outlet
94  cubic_interpolate_clear(x); // initilaize instance
95  x->attr_step = 1.; // default value
96  attr_args_process(x, argc, argv); // handle attribute args
97  }
98  return (x); // return the pointer
99 }
100 
101 
102 /************************************************************************************/
103 // Methods bound to input/inlets
104 
105 
106 // ATTRIBUTE: step
107 t_max_err cubic_interpolation_setstep(t_cubic_interp *x, void *attr, long argc, t_atom *argv)
108 {
109  float f;
110 
111  f = atom_getfloat(argv);
112  if (f<0) f = 0;
113  if (f>1) f = 1;
114 
115  x->attr_step = f;
116  return MAX_ERR_NONE;
117 }
118 
119 // BANG input
120 void cubic_interpolate_bang(t_cubic_interp *x)
121 {
122  double y0, y1, y2, y3, mu, mu2;
123  double a0,a1,a2,a3;
124 
125  if (x->clearflag) {
126  outlet_bang(x->outlet2); // ask for a new value
127  if (x->clearflag) { // check again
128  outlet_float(x->outlet, 0); // if we still have not received any points, return 0
129  return;
130  }
131  }
132 
133  if (x->attr_step>1)
134  x->attr_step=1;
135  if (x->attr_step<0.)
136  x->attr_step=0;
137  mu = x->mu + x->attr_step;
138  if (mu>=1.) {
139  outlet_bang(x->outlet2); // ask for a new value
140  mu = mu - 1.;
141  }
142  mu2 = mu*mu;
143 
144  y0 = x->value[0];
145  y1 = x->value[1];
146  y2 = x->value[2];
147  y3 = x->value[3];
148 
149  a0 = y3 - y2 - y0 + y1;
150  a1 = y0 - y1 - a0;
151  a2 = y2 - y0;
152  a3 = y1;
153 
154  outlet_float(x->outlet, a0*mu*mu2+a1*mu2+a2*mu+a3);
155  x->mu = mu;
156 }
157 
158 
159 // INT input
160 void cubic_interpolate_int(t_cubic_interp *x, long n)
161 {
162  cubic_interpolate_float(x, (double)n);
163 }
164 
165 
166 // FLOAT input
167 void cubic_interpolate_float(t_cubic_interp *x, double f)
168 {
169  long i;
170 
171  if (x->clearflag) {
172  for (i=0; i<4; i++)
173  x->value[i] = f;
174  x->clearflag = 0;
175  }
176  else {
177  for (i=0; i<3; i++)
178  x->value[i] = x->value[i+1];
179  x->value[3] = f;
180  }
181 }
182 
183 
184 // CLEAR input
185 void cubic_interpolate_clear(t_cubic_interp *x)
186 {
187  x->mu = 0.;
188  x->clearflag = 1;
189 }
190 
191 
192 // Method for Assistance Messages
193 void cubic_interpolate_assist(t_cubic_interp *x, void *b, long msg, long arg, char *dst) // Display assistance messages
194 {
195  if (msg==1)
196  {
197  switch(arg)
198  {
199  case 0: strcpy(dst, "(bang/float) interpolate, set next");
200  break;
201  }
202  }
203  else if (msg==2)
204  {
205  switch(arg)
206  {
207  case 0: strcpy(dst, "(float) interpolated value"); break;
208  case 1: strcpy(dst, "(bang) need new target value"); break;
209  case 2: strcpy(dst, "dumpout"); break;
210  }
211  }
212 }
Various utilities for interfacing with Max that are not specific to JamomaModular as such...
int JAMOMA_EXPORT_MAXOBJ main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
t_class * this_class
Required. Global pointing to this class.
Definition: j.envexp.cpp:108