Jamoma API  0.6.0.a19
TTFreeHandFunction.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup dspFunctionLib
4  *
5  * @brief #TTFreeHandFunction Unit for Jamoms DSP
6  *
7  * @details A piecewise function unit that allows to load a function unit per defined domain. @n
8  * The default configuration is a linear function for X[0::1], Y[0::1] domain. @n
9  * Setup the curveList attribute to change the configuration. @n
10  * For example setting curveList to the < 0.3 0.6 exponential base 0.5 1. 1. logarithm base 0.8 > value @n
11  * you will imply the following behavior :
12  * - if x belongs to [0::0.3] domain, it will use the exponential function and the result will belong to [0.::0.6] domain.
13  * - if x belongs to ]0.3::1.] domain, it will use the logarithm function and the result will belong to ]0.6::1.] domain.
14  *
15  * @authors Théo de la Hogue, Trond Lossius
16  *
17  * @copyright Copyright © 2013 by Théo de la Hogue @n
20  */
21
22
23 #include "TTFreeHandFunction.h"
24 #include <math.h>
25
26 #define thisTTClass TTFreeHandFunction
27 #define thisTTClassName "freehand"
28 #define thisTTClassTags "dspFunctionLib, audio, processor, function"
29
30
31 TT_AUDIO_CONSTRUCTOR
32 {
34
35  setProcessMethod(processAudio);
36  setCalculateMethod(calculateValue);
37
38  Clear();
39 }
40
41 TTFreeHandFunction::~TTFreeHandFunction()
42 {
43  ;
44 }
45
47 {
48  TTBoolean firstFunction = YES;
49
50  mFunctions.begin();
51
52  // for each point
53  for (mPoints.begin(); mPoints.end(); mPoints.next()) {
54
55  // append the point coordinate
56  value.append(mPoints.current());
57
58  // the first function is always an exponential base 1. function
59  if (firstFunction) {
60
61  value.append(TTSymbol("exponential"));
62  value.append(TTSymbol("base"));
63  value.append(1.);
64
65  firstFunction = NO;
66  continue;
67  }
68
69  // append function info
70  if (mFunctions.end()) {
71
72  TTObject aFunction = mFunctions.current()[0];
73
74  if (aFunction.valid()) {
75
76  TTValue attributeNames;
77  TTUInt8 i;
78
79  // append function name
80  value.append(aFunction.name());
81
82  // for all attributes
83  aFunction.attributes(attributeNames);
84
85  for (i = 0; i < attributeNames.size(); i++) {
86
87  TTSymbol aName = attributeNames[i];
88
89  if (aName == kTTSym_bypass || aName == TTSymbol("mute") || aName == kTTSym_maxNumChannels || aName == kTTSym_sampleRate)
90  continue; // don't publish these datas
91
92  // append attribute name
93  value.append(aName);
94
95  // append attribute value
96  TTValue v;
97  aFunction.get(aName, v);
98  value.append(v);
99  }
100  }
101
102  mFunctions.next();
103  }
104  }
105
106  return kTTErrNone;
107 }
108
110 {
111  TTUInt8 curveId;
112  TTUInt32 i, next, size;
113  TTFloat64 x, y;
114  TTSymbol function, parameterName;
115  TTObject aFunction;
116  TTValue v;
117  TTErr err = kTTErrNone;
118
119  locked = YES;
120
121  // clear all existing points
122  mPoints.clear();
123
124  // clear all existing functions
125  mFunctions.clear();
126
127  // set all points and curves
128  size = value.size();
129  curveId = 0;
130  for (i = 0; i < size; i = i + next) {
131
132  // check size
133  if (i+1 >= size)
134  err = kTTErrGeneric;
135
136  // append a point : x y
137  if (value[i].type() == kTypeFloat64 && value[i+1].type() == kTypeFloat64) {
138
139  x = value[i];
140  y = value[i+1];
141
142  v = TTValue(x);
143  v.append(y);
144  mPoints.append(v);
145
146  next = 2;
147  }
148  else
149  err = kTTErrGeneric;
150
151  // create a function
152  aFunction = NULL;
153
154  // check size
155  if (i+2 >= size) {
156  aFunction = TTObject("linear", 1); // 1 is the numChannel
157
158  // set function type
159  } else if (value[i+2].type() == kTypeSymbol) {
160
161  function = value[i+2];
162  aFunction = TTObject(function, 1); // 1 is the numChannel
163
164  next = 3;
165
166  // check size
167  if (i+5 > size)
168  ;
169
170  // set function parameter
171  else if (value[i+3].type() == kTypeSymbol) {
172
173  parameterName = value[i+3];
174
175  v.copyRange(value, i+4, i+5);
176  aFunction.set(parameterName, v);
177
178  next = 5;
179  }
180  else
181  err = kTTErrGeneric;
182  }
183  else
184  aFunction = TTObject("linear", 1); // 1 is the numChannel
185
186  // for the first point : release the function
187  if (!curveId)
188  aFunction = TTObject();
189
190  // append the function
191  else
192  mFunctions.append(aFunction);
193
194  curveId++;
195  }
196
197  locked = NO;
198
199  return err;
200 }
201
203 {
204  TTValue init;
205
206  init.append(0.);
207  init.append(0.);
208
209  init.append(1.);
210  init.append(1.);
211
212  return setCurveList(init);
213 }
214
216 {
217  TTFloat64 lastX, lastY;
218  TTFloat64 currentX, currentY;
219  TTFloat64 scaledX, scaledY;
220  TTObject aFunction;
221  TTErr err;
222
223  if (locked)
224  return kTTErrGeneric;
225
226  if (mPoints.isEmpty())
227  return kTTErrNone;
228
229  mPoints.begin();
230  lastX = mPoints.current()[0];
231  lastY = mPoints.current()[1];
232
233  if (x < lastX) {
234  y = lastY;
235  return kTTErrNone;
236  }
237
238  mPoints.next();
239
240  // select the function to use
241  for (mFunctions.begin(); mFunctions.end(); mFunctions.next()) {
242
243  currentX = mPoints.current()[0];
244  currentY = mPoints.current()[1];
245
246  if (x < currentX) {
247
248  aFunction = mFunctions.current()[0];
249
250  // scale x
251  scaledX = (x - lastX) / (currentX - lastX);
252
253  // use function
254  err = TTAudioObjectBasePtr(aFunction.instance())->calculate(scaledX, scaledY);
255
256  // scale y
257  y = (currentY - lastY) * scaledY + lastY;
258
259  return err;
260  }
261
262  lastX = currentX;
263  lastY = currentY;
264  mPoints.next();
265  }
266
267  y = lastY;
268
269  return kTTErrNone;
270 }
271
272
274 {
275  TT_WRAP_CALCULATE_METHOD(calculateValue);
276 }
277
TTErr(TTObjectBase::* TTSetterMethod)(const TTAttribute &attribute, const TTValue &value)
A type that can be used to store a pointer to a message for an object.
Definition: TTObjectBase.h:78
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
TTErr Clear()
Clear all functions.
Create and use Jamoma object instances.
Definition: TTObject.h:29
size_type size() const noexcept
Return the number of elements.
TTErr calculate(const TTFloat64 &x, TTFloat64 &y)
Calculate a single sample of output for a single sample of input.
#define setProcessMethod(methodName)
A convenience macro to be used by subclasses for setting the process method.
Symbol type.
Definition: TTBase.h:282
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
This is a special type used by TTAttribute to indicate that a value is a TTValue and is locally maint...
Definition: TTBase.h:286
void append(const T &anElementValueToAppend)
Insert a single TTElement at the end.
Definition: TTValue.h:243
TTErr get(const TTSymbol aName, T &aReturnedValue) const
Get an attribute value for an object.
#define setCalculateMethod(methodName)
A convenience macro to be used by subclasses for setting the calculate method.
TTAudioObjectBase * TTAudioObjectBasePtr
Pointer to a TTAudioObjectBase.
64-bit floating point
Definition: TTBase.h:272
TTSymbol name() const
Return the name of this class.
Definition: TTObject.cpp:129
TTFreeHandFunction Unit for Jamoms DSP
TTErr calculateValue(const TTFloat64 &x, TTFloat64 &y, TTPtrSizedInt data)
y = f(x) for a single value
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
The TTSymbol class is used to represent a string and efficiently pass and compare that string...
Definition: TTSymbol.h:26
TTErr setCurveList(const TTValue &value)
Set all points and functions using a list of < x y function parameterName parameterValue > ...
A simple container for an array of TTAudioSignal pointers.
long TTPtrSizedInt
An integer that is the same size as a pointer.
Definition: TTBase.h:240
TTErr getCurveList(TTValue &value)
Get all points and functions as a list of < x y function parameterName parameterValue > ...
Something went wrong, but what exactly is not known. Typically used for context-specific problems...
Definition: TTBase.h:344
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
void attributes(TTValue &returnedAttributeNames) const
Return a list of names of the available attributes.
Definition: TTObject.cpp:111
std::uint32_t TTUInt32
32 bit unsigned integer
Definition: TTBase.h:178
TTObjectBase * instance() const
Return a direct pointer to the internal instance.
Definition: TTObject.cpp:105
No Error.
Definition: TTBase.h:343
TTErr processAudio(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
A standard audio processing method as used by Jamoma DSP objects.
void copyRange(const TTValue &obj, TTUInt16 startIndex, TTUInt16 endIndex)
Copy a value starting from an index until another index.
Definition: TTValue.h:138
TTBoolean valid() const
Determine if the object contained by this TTObject is truly ready for use.
Definition: TTObject.cpp:179
TTErr(TTObjectBase::* TTGetterMethod)(const TTAttribute &attribute, TTValue &value)
A type that can be used to store a pointer to a message for an object.
Definition: TTObjectBase.h:73
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
unsigned char TTUInt8
8 bit unsigned integer (char)
Definition: TTBase.h:174