Krotos Modules 3
Loading...
Searching...
No Matches
KwidgetProcessor_XyPad.cpp
Go to the documentation of this file.
1namespace krotos
2{
4 : KwidgetProcessor(owner), m_mode(CurveMode::Exponential)
5 {
6 auto currentMode = dynamic_cast<Kwidget_XyPad*>(&getOwner())->getCurrentMode();
7 // number of modulators determmined from the xyMode
8 int numModulators;
9
10 std::shared_ptr<KParameter> param;
11
12 switch (currentMode)
13 {
15 numModulators = 2;
16 m_paramValues.resize(static_cast<size_t>(numModulators));
17 // for the two position parameters
18 for (int i = 0; i < numModulators; i++)
19 {
20 m_paramValues[static_cast<size_t>(i)] = 0.0f;
21 addModulator(false);
22 getModulator(i)->setValues(&(m_paramValues[static_cast<size_t>(i)]), 1);
25
26 m_listenerObjects.add(new KParameter::AudioListenerObject(param, [=](float x) {
27 m_paramValues[static_cast<size_t>(i)] = x;
29 }));
30 }
31 break;
32 }
34 // Get KParameter pointers to set the callbacks when their values change
37 numModulators = 4;
38 m_paramValues.resize(2);
39
40 for (int i = 0; i < numModulators; i++)
41 {
42 // Add 4 slow Modulators
43 addModulator(false);
44 }
45
46 // Initialize vector of the 2 parameter values
47 for (int i = 0; i < m_paramValues.size(); i++)
48 {
49 // first address is held for posX param and second for posY.
50 m_paramValues[static_cast<size_t>(i)] = 0.0f;
51 // Each modulators float* points to the vector of the two param values.
53 getModulator(i + 2)->setValues(&(m_paramValues[i]), 1);
54 // Assign mappingFunction to modulators 2 and 3 to map incoming data to curves.
56 }
57
58 m_listenerObjects.add(new KParameter::AudioListenerObject(paramX, [=](float x) {
59 // position 0 is pointing to the posX param
60 m_paramValues[static_cast<size_t>(posX)] = x;
63 }));
64
65 m_listenerObjects.add(new KParameter::AudioListenerObject(paramY, [=](float y) {
66 // position 1 is pointing to the posY param
67 m_paramValues[static_cast<size_t>(posY)] = y;
70 }));
71 break;
72 }
74 // Get KParameter pointers to set the callbacks when their values change
77 numModulators = 4;
78 m_paramValues.resize(2);
79
80 // Initialize vector of the 2 parameter values
81 for (int i = 0; i < m_paramValues.size(); i++)
82 {
83 // first address is held for posX param and second for posY.
84 m_paramValues[static_cast<size_t>(i)] = 0.0f;
85 }
86
87 for (int i = 0; i < numModulators; i++)
88 {
89 // Add 4 slow Modulators
90 addModulator(false);
91 // Each modulators float* points to the vector of the two param values.
93 }
94
95 // Assign mappingFunction to each modulator from TopLeft to BottomRight corner
96 // TODO: have an array of function pointers. this way you could map infinite function pointer mappings.
101
102 m_listenerObjects.add(new KParameter::AudioListenerObject(paramX, [=](float x) {
103 // position 0 is pointing to the posX param
104 m_paramValues[static_cast<size_t>(0)] = x;
105
106 for (int i = 0; i < numModulators; i++)
107 {
109 }
110 }));
111
112 m_listenerObjects.add(new KParameter::AudioListenerObject(paramY, [=](float y) {
113 // position 1 is pointing to the posY param
114 m_paramValues[static_cast<size_t>(1)] = y;
115
116 for (int i = 0; i < numModulators; i++)
117 {
119 }
120 }));
121 break;
122 }
124 // Get KParameter pointers to set the callbacks when their values change
127 numModulators = 4;
128 m_paramValues.resize(2);
129
130 // Initialize vector of the 2 parameter values
131 for (int i = 0; i < m_paramValues.size(); i++)
132 {
133 // first address is held for posX param and second for posY.
134 m_paramValues[static_cast<size_t>(i)] = 0.0f;
135 }
136
137 for (int i = 0; i < numModulators; i++)
138 {
139 // Add 4 slow Modulators
140 addModulator(false);
141 // Each modulators float* points to the vector of the two param values.
143 }
144
145 // Assign mappingFunction to each modulator from TopLeft to BottomRight corner
146 // TODO: have an array of function pointers. this way you could map infinite function pointer mappings.
150
151 m_listenerObjects.add(new KParameter::AudioListenerObject(paramX, [=](float x) {
152 // position 0 is pointing to the posX param
153 m_paramValues[static_cast<size_t>(0)] = x;
154
155 for (int i = 0; i < numModulators; i++)
156 {
158 }
159 }));
160
161 m_listenerObjects.add(new KParameter::AudioListenerObject(paramY, [=](float y) {
162 // position 1 is pointing to the posY param
163 m_paramValues[static_cast<size_t>(1)] = y;
164
165 for (int i = 0; i < numModulators; i++)
166 {
168 }
169 }));
170 break;
171 }
173 {
174 numModulators = 4;
175 m_paramValues.resize(static_cast<size_t>(numModulators));
176 //Get KParameter pointers to set the callbacks when their values change
179 //Initialize vector of the 2 parameter values
180 for (int i = 0; i < m_paramValues.size(); i++)
181 {
182 //first address is held for posX param and second for posY.
183 m_paramValues[static_cast<size_t>(i)] = 0.0f;
184 }
185 for (int i = 0; i < numModulators; i++)
186 {
187 //Add 4 slow Modulators
188 addModulator(false);
189 }
190 // Set modulator values and mapping functions
191 getModulator(0)->setValues(&m_paramValues[0], 1); // x-linear
192 getModulator(1)->setValues(&m_paramValues[1], 1); // y-linear
193 getModulator(2)->setValues(&m_paramValues[0], 2); // Distance Decreasing
195 getModulator(3)->setValues(&m_paramValues[0], 2); // Distance Increasing
197
198 m_listenerObjects.add(new KParameter::AudioListenerObject(paramX, [=](float x) {
199 // position 0 is pointing to the posX param
200 m_paramValues[static_cast<size_t>(0)] = x;
204 }));
205 m_listenerObjects.add(new KParameter::AudioListenerObject(paramY, [=](float y) {
206 // position 1 is pointing to the posY param
207 m_paramValues[static_cast<size_t>(1)] = y;
208 // only the first - seoncd modulators (distance) should be called here
212 }));
213 break;
214 }
215 }
216
219 m_listenerObjects.add(new KParameter::AudioListenerObject(paramX, [=](float x) { m_puckX.setInput(x); }));
220
221 m_listenerObjects.add(new KParameter::AudioListenerObject(paramY, [=](float y) { m_puckY.setInput(y); }));
222
224 addModulator(true);
225 }
226
227 void KwidgetProcessor_XyPad::prepare(double sampleRate, int samplesPerBlock)
228 {
229 //added calls to update any listeners of the modulators
230 getOwner()
232 ->sendValueChangedMessageToListeners(getOwner().getParameterToAttach(Parameters::posX)->getValue());
233 getOwner()
235 ->sendValueChangedMessageToListeners(getOwner().getParameterToAttach(Parameters::posY)->getValue());
236
237 m_sampleRate = sampleRate;
238 m_samplesPerBlock = samplesPerBlock;
239
240 m_puckX.prepare(sampleRate, samplesPerBlock);
241 m_puckY.prepare(sampleRate, samplesPerBlock);
242
243 m_buffer.setSize(1, samplesPerBlock);
244
245 getModulator(m_indexOfVelocityModulator)->setValues(m_buffer.getReadPointer(0), samplesPerBlock);
246 }
247
248 void KwidgetProcessor_XyPad::process(AudioBuffer<float>& buffer)
249 {
250 auto numSamples = buffer.getNumSamples();
251 auto bufferPtr = m_buffer.getWritePointer(0);
252
255
256 nextBlock(numSamples);
257
258 for (int i = 0; i < numSamples; i++)
259 {
260 nextSample();
261 bufferPtr[i] = Point<float>(m_puckX.getOutput(), m_puckY.getOutput()).getDistanceFromOrigin();
262 }
263 }
264
265 float KwidgetProcessor_XyPad::mapToCurve(const float* incomingValues, const float depth)
266 {
267 // calculate parameters of equation y = ax^2 + bx + c
268 float c = 1.0f - depth;
269 float a = (c - 1.0f) / 0.25f;
270 float b = -1.0f * a;
271 // calculate the mapped value on that equation
272 float mappedValue = a * powf(incomingValues[0], 2.0f) + b * incomingValues[0] + c;
273
274 return mappedValue;
275 }
276
277 float KwidgetProcessor_XyPad::mapToLine(const float* incomingValues, const float depth)
278 {
279 float max = 1.0f;
280 // minimum values are determined by the depth parameter.
281 float min = 1.0f - depth;
282
283 if (incomingValues[0] <= 0.5f)
284 {
285 // calculate the gradient of the line for 0<=x<=0.5
286 float lamda = (max - min) / 0.5f;
287 // insert input parameter x to the line equation
288 float mappedValue = lamda * incomingValues[0] + min;
289 return mappedValue;
290 }
291 else
292 {
293 // calculate the gradient of the line for 0.5<x<=1
294 float lamda = (min - max) / 0.5f;
295 float mappedValue = lamda * incomingValues[0] + (max + depth);
296 return mappedValue;
297 }
298 }
299
300 const Point<float> KwidgetProcessor_XyPad::m_topLeft{0.f, 1.f};
301 const Point<float> KwidgetProcessor_XyPad::m_topRight{1.f, 1.f};
302 const Point<float> KwidgetProcessor_XyPad::m_bottomLeft{0.f, 0.f};
303 const Point<float> KwidgetProcessor_XyPad::m_bottomRight{1.f, 0.f};
304 const Point<float> KwidgetProcessor_XyPad::m_centre{0.5f, 0.5f};
306
308 {
309 // return(sqrtf(val)); // Sqrt equal power crossfading
310 return sinf(val * MathConstants<float>::halfPi); // Sine law equal power crossfading
311 }
312
313 float KwidgetProcessor_XyPad::attenuationCurve(float val) { return std::sqrtf(std::abs(1.0f - (2.0f * val))); }
314
315 float KwidgetProcessor_XyPad::increaseCurve(float val) { return std::sqrtf(std::abs((2.0f * val) - 1.0f)); }
316
317 float KwidgetProcessor_XyPad::distanceYTop(const float* incomingValues)
318 {
319 // Calculate the distance to top Y
320 float puckY{incomingValues[1]};
321 return jmin<float>(std::abs(1.0f - puckY), 1.f); // Clamp to 1
322 }
323
324 float KwidgetProcessor_XyPad::mapToDistance(const float* incomingValues, const float depth,
325 const Point<float> corner)
326 {
327 // Calculate the distance to the supplied corner
328 Point<float> puckVector{incomingValues[0], incomingValues[1]};
329 float distanceToCorner = jmin<float>(puckVector.getDistanceFrom(corner), 1.f); // Clamp to 1
330
331 // We are now in gain space, so do the scaling
332 float modulationValue = constPower(1.f - distanceToCorner * depth);
333
334 return modulationValue;
335 }
336
337 float KwidgetProcessor_XyPad::mapToDistanceTL(const float* incomingValues, const float depth)
338 {
339 return mapToDistance(incomingValues, depth, m_topLeft);
340 }
341
342 float KwidgetProcessor_XyPad::mapToDistanceTR(const float* incomingValues, const float depth)
343 {
344 return mapToDistance(incomingValues, depth, m_topRight);
345 }
346
347 float KwidgetProcessor_XyPad::mapToDistanceBL(const float* incomingValues, const float depth)
348 {
349 return mapToDistance(incomingValues, depth, m_bottomLeft);
350 }
351
352 float KwidgetProcessor_XyPad::mapToDistanceBR(const float* incomingValues, const float depth)
353 {
354 return mapToDistance(incomingValues, depth, m_bottomRight);
355 }
356
357 float KwidgetProcessor_XyPad::mapToDistDecreasing(const float* incomingValues, const float depth)
358 {
359 // Calculate the distance to top Y
360 float distanceToTop = distanceYTop(incomingValues);
361
362 // We are now in gain space, so do the scaling
363 float modulationValue;
364 if (0.0f <= distanceToTop && distanceToTop <= 0.5f)
365 modulationValue = attenuationCurve(distanceToTop * depth);
366 else
367 modulationValue = 1.0f - depth;
368
369 return modulationValue;
370 }
371
372 float KwidgetProcessor_XyPad::mapToDistBranched(const float* incomingValues, const float depth)
373 {
374 // Calculate the distance to top Y
375 float distanceToTop = distanceYTop(incomingValues);
376
377 // Two branch function
378 float modulationValue;
379 if (0.0f <= distanceToTop && distanceToTop <= 0.5f)
380 {
381 // shift to negative axis (from 0<=x<=0.5 to -0.5<=x<=0)
382 distanceToTop -= 0.5f;
383 modulationValue = std::sqrtf(std::abs(1.0f + 2.0f * distanceToTop * depth));
384 }
385 else
386 {
387 //(from 0.5 <x <= 1 to 0<x<=0.5)
388 distanceToTop -= 0.5f;
389 modulationValue = std::sqrtf(std::abs(1.0f - (2.0f * distanceToTop * depth)));
390 }
391
392 return modulationValue;
393 }
394
395 float KwidgetProcessor_XyPad::mapToDistIncreasing(const float* incomingValues, const float depth)
396 {
397 // Calculate the distance to top Y
398 float puckY{incomingValues[1]};
399 float distanceToTop = jmin<float>(std::abs(1.0f - puckY), 1.f); // Clamp to 1
400
401 // We are now in gain space, so do the scaling
402 // Two branch function
403 float modulationValue;
404 if (0.0f <= distanceToTop && distanceToTop < 0.5f)
405 modulationValue = 1.0f - depth;
406 else
407 modulationValue = increaseCurve(distanceToTop * depth);
408
409 return modulationValue;
410 }
411
412 float KwidgetProcessor_XyPad::mapToRadiusDecreasing(const float* incomingValues, const float depth)
413 {
414 // Cartesian to polar radius conversion - distance from centre
415 Point<float> puckVector{incomingValues[0], incomingValues[1]};
416 float distanceToCentre = jmin<float>(puckVector.getDistanceFrom(m_centre), 1.f); // Clamp to 1
417 // Normalize
418 distanceToCentre /= m_cntrDiag;
419 float modValue = /*constPower */ (1.f - distanceToCentre * depth); // TODO: See how it behaved with constPower
420
421 return modValue;
422 }
423
424 float KwidgetProcessor_XyPad::mapToRadiusIncreasing(const float* incomingValues, const float depth)
425 {
426 // Cartesian to polar radius conversion - distance from centre
427 Point<float> puckVector{incomingValues[0], incomingValues[1]};
428 float distanceToCentre = jmin<float>(puckVector.getDistanceFrom(m_centre), 1.f); // Clamp to 1
429 // Normalize
430 distanceToCentre /= m_cntrDiag;
431 // Calculate the modulation factor using linear interpolation between 1 and distanceToCentre
432 float modValue = 1.0f + depth * (distanceToCentre - 1.0f);
433
434 return modValue;
435 }
436} // namespace krotos
Definition Kwidget_XyPad.h:4
xyMode getCurrentMode()
Definition Kwidget_XyPad.h:50
@ Peak
Definition Kwidget_XyPad.h:23
@ Polar
Definition Kwidget_XyPad.h:26
@ FourZone
Definition Kwidget_XyPad.h:24
@ Simple
Definition Kwidget_XyPad.h:22
@ Distance
Definition Kwidget_XyPad.h:25
Definition Kwidget.h:8
KParameter * getParameter(const String &parameterID) const noexcept
Get a raw pointer to a KParameter belonging to this Kwidget's KwidgetProcessor. Useful for low overhe...
Definition Kwidget.cpp:168
std::shared_ptr< KParameter > getParameterToAttach(const String &parameterID) const noexcept
Get a shared pointer to a KParameter, for use with KParameter::Listener objects and situations where ...
Definition Kwidget.cpp:178
static float mapToDistDecreasing(const float *incomingValues, const float depth)
Definition KwidgetProcessor_XyPad.cpp:357
static float mapToRadiusDecreasing(const float *incomingValues, const float depth)
Definition KwidgetProcessor_XyPad.cpp:412
static float mapToDistanceTR(const float *incomingValues, const float depth)
Definition KwidgetProcessor_XyPad.cpp:342
int m_indexOfVelocityModulator
Definition KwidgetProcessor_XyPad.h:73
void prepare(double sampleRate, int samplesPerBlock) override
Definition KwidgetProcessor_XyPad.cpp:227
static float mapToLine(const float *incomingValue, const float depth)
Definition KwidgetProcessor_XyPad.cpp:277
static float mapToDistIncreasing(const float *incomingValues, const float depth)
Definition KwidgetProcessor_XyPad.cpp:395
static float attenuationCurve(float val)
Definition KwidgetProcessor_XyPad.cpp:313
CurveMode
Definition KwidgetProcessor_XyPad.h:10
@ Exponential
Definition KwidgetProcessor_XyPad.h:12
static float mapToDistance(const float *incomingValues, const float depth, const Point< float > corner)
Definition KwidgetProcessor_XyPad.cpp:324
static const Point< float > m_bottomLeft
Definition KwidgetProcessor_XyPad.h:59
std::vector< float > m_paramValues
Definition KwidgetProcessor_XyPad.h:66
static float mapToDistanceBR(const float *incomingValues, const float depth)
Definition KwidgetProcessor_XyPad.cpp:352
static float distanceYTop(const float *incomingValues)
Definition KwidgetProcessor_XyPad.cpp:317
CurveMode m_mode
Definition KwidgetProcessor_XyPad.h:71
static float increaseCurve(float val)
Definition KwidgetProcessor_XyPad.cpp:315
static const Point< float > m_centre
Definition KwidgetProcessor_XyPad.h:61
@ posY
Definition KwidgetProcessor_XyPad.h:52
@ posY2
Definition KwidgetProcessor_XyPad.h:54
@ posX
Definition KwidgetProcessor_XyPad.h:51
@ posX2
Definition KwidgetProcessor_XyPad.h:53
static const Point< float > m_bottomRight
Definition KwidgetProcessor_XyPad.h:60
void process(AudioBuffer< float > &buffer) override
Definition KwidgetProcessor_XyPad.cpp:248
OwnedArray< KParameter::AudioListenerObject > m_listenerObjects
Definition KwidgetProcessor_XyPad.h:65
MouseVelocityExtractor m_puckY
Definition KwidgetProcessor_XyPad.h:79
static float mapToDistanceBL(const float *incomingValues, const float depth)
Definition KwidgetProcessor_XyPad.cpp:347
static float constPower(float val)
Definition KwidgetProcessor_XyPad.cpp:307
static float mapToDistBranched(const float *incomingValues, const float depth)
Definition KwidgetProcessor_XyPad.cpp:372
static const Point< float > m_topRight
Definition KwidgetProcessor_XyPad.h:58
static float mapToCurve(const float *incomingValue, const float depth)
Definition KwidgetProcessor_XyPad.cpp:265
static const Point< float > m_topLeft
Definition KwidgetProcessor_XyPad.h:57
static float mapToDistanceTL(const float *incomingValues, const float depth)
Definition KwidgetProcessor_XyPad.cpp:337
double m_sampleRate
Definition KwidgetProcessor_XyPad.h:75
static constexpr float m_cntrDiag
Definition KwidgetProcessor_XyPad.h:70
static float mapToRadiusIncreasing(const float *incomingValues, const float depth)
Definition KwidgetProcessor_XyPad.cpp:424
KwidgetProcessor_XyPad(Kwidget &owner)
Definition KwidgetProcessor_XyPad.cpp:3
static const float m_topYCoordinate
Definition KwidgetProcessor_XyPad.h:62
int m_samplesPerBlock
Definition KwidgetProcessor_XyPad.h:76
MouseVelocityExtractor m_puckX
Definition KwidgetProcessor_XyPad.h:78
AudioBuffer< float > m_buffer
Definition KwidgetProcessor_XyPad.h:74
An interface for an audio processor designed for modular use.
Definition KwidgetProcessor.h:8
Modulator * getModulator(int index)
Definition KwidgetProcessor.cpp:34
void nextBlock(int numSamples)
Definition KwidgetProcessor.cpp:50
int getNumModulators() const
Definition KwidgetProcessor.cpp:32
Kwidget & getOwner() const
Definition KwidgetProcessor.h:164
void nextSample()
Definition KwidgetProcessor.cpp:59
void addModulator(bool useAudioRate)
Definition KwidgetProcessor.h:139
void callListeners()
Definition ModulationSource.cpp:9
float(* mappingFunctionPtr)(const float *parameterValuesVector, const float depth)
Definition ModulationSource.h:58
void setValues(const float *values, int numValues)
Definition ModulationSource.h:34
void process()
Do the calculation.
Definition OscillatorUtils.cpp:250
float getOutput()
Fetch the processed output.
Definition OscillatorUtils.cpp:260
void prepare(double sampleRate, int samplesPerBlock)
Set the sample rate and block size.
Definition OscillatorUtils.cpp:271
void setInput(float val)
Input the value to be processed.
Definition OscillatorUtils.cpp:258
Definition AirAbsorptionFilter.cpp:2
A KParameter Listener which can be used to trigger a callback syncrhonously.
Definition KParameter.h:30
static const String posX
Definition Kwidget_XyPad.h:33
static const String posY
Definition Kwidget_XyPad.h:34