MIDI CC Curve

Status
Not open for further replies.
Yes, exactly. Symmetrical arcs are much more applicable in my case, if possible.

I'll bring the coffee :) As I'm not sure I could figure out the math for this
 
Last edited:
How can I send you the desmos graph? I've entered in some figures, and the coordinates that cross in the middle of the arc are:

89.803, 37.197

Screen Shot 2017-03-17 at 2.31.39 PM.png

Heres a screenshot
 
Last edited:
Code:
void setup() {
  while (!Serial) ;
  delay(100);
  for (int i=0; i <= 127; i++) {
    float x = (float)i / 127.0;
    if (x < 0) x = 0;
    if (x > 1.0) x = 1.0;
    float y = sqrtf(1.0 - (x * x));
    int out = y * 127.0;
    Serial.println(out);
  }
}

void loop() {
}
 
Thanks Paul, this is the outcome:

Screen Shot 2017-03-17 at 3.04.30 PM.png

Isn't it meant to be the other way around? Because we are starting from (0,0)
 
Perhaps you could take it from here, try experimenting with simple math (like subtraction) to convert this curve to other orientations? Maybe even post the code, as I've just done for you?
 
I have tried simple math (like subtraction) and do edit the code however have still yet to make it work.

I have played around with:
float y = sqrtf(-0.5 - (x * x));
float y = sqrtf(1.0 - (x * -x));
float y = sqrtf(0.5 - (x * x));
float y = sqrtf(1.0 - (x * 2));
etc

However not really sure if that is even the correct parameter to change.
 
Last edited:
Think about this problem a little more. You already have the right curve, just not oriented the way you want. So don't change the curve itself. Take the curve you already have (the result of the square root) and do things to manipulate it after the sqrt computes it. You can do this....
 
haha, or just use the answer from oddson!

But really, there comes a point where everyone needs to stand on their own and solve some problems. I'm confident you can.
 
Thank you Oddson, the curve did orientate correctly.

Thank you Paul for the code.

The issue is still apparent in the initial stages, showing little to no movement as compared to the top of the curve.
Screen Shot 2017-03-17 at 3.29.08 PM.png
Screen Shot 2017-03-17 at 3.29.59 PM.png

I understand the output values will be small, but not 0 for several MIDI values of the potentiometer
 
showing little to no movement as compared to the top of the curve.

Maybe it's time for you to switch to use the (text based) serial monitor and actually look at the numbers. I believe you'll see why this is.

Again, I want to emphasize the need to start investigating and relying on your own skills. You can't forever expect others to do everything. You need to rise up to this occasion...
 
Circles will be less simple when you go to do the less hard and less soft curves... as you have to make the radius bigger than 1 (or 127 depending on how you do the math, you may find it easier to do the math on a unit circle and then scale the output range)

Here's some of the math explained....

http://www.mathwarehouse.com/geometry/circle/equation-of-a-circle.php


There's also a concept called a cubic-spline... it would provide the most general solutions for this kind of remapping but it's not beginners math.

https://en.wikipedia.org/wiki/Spline_interpolation#Example

I keep thinking you're doing velocity mapping but your post says CC Curve... what's the intended function of these curves? You may find there is simpler math that gets you usable results without worrying about symmetry etc.
 
Paul, I ask questions to learn, same way someone would go to college to study a certain field. When I don't understand something, I ask. I'm not asking those to do it for me, simply those to guide or instruct of how to learn.

Perhaps you could provide me some resources as to where to learn more about utilizing this platform (Arduino / Teensy). Books? Courses?
 
Oddson, thank you.

I understand it may be called Response Curve or Velocity Curve. The intended function is to change the output 'curve' of a linear potentiometer. Rather than it being straight (linear), I would like the option of when moving the potentiometer knob from 1 - 127, it does so with a curve:

Soft - (slow start from 1 then ramps up towards 127)
Aggressive - (ramps up quickly from 1 then flattens out until 127)

The potentiometer physical range is still the same, however the output values sent and converted change to replicate a curvature that is either softer or more aggressive.

Hope that makes sense.
 
Well let's agree Paul has helped enough...

Paul has spent many an hour providing help on MIDI controllers to musicians with limited math and coding background...

I'm happy to help further...

I could unpack the code fragment Paul gave line-by-line for you if that helps.
 
Last edited:
...If you mean to take an analog signal and map that to midi with some curve then then any additional resolution can be used to give a smoother input/output mapping... you still have the 127 steps of output but your input steps are smoother and there can be a range of inputs that map to all the possible outputs and still have some curve...
Recall this... if you're reading a voltage off a pot you will have 1024 levels (10-bits of data) and so you're not mapping 128 levels to 128 levels but 0-1023 to 0-127... this won't really help on the edges but you'll get a much more responsive feel in the middle if you don't drop that extra resolution before remapping...

That's why I gave the steps as I did...

For now... I think you should stick to adapting y=xa -- in code: y = powf(x, a); .. it should give you symmetrical enough output if you restrict the exponent to moderate values... and you get as many soft/hard profiles with just one parameter.
 
If you're sending as a MIDI CC message, the final result always has to end up as an integer between 0 to 127, no matter what math you use. For certain types of steep curves, the coarse 0-127 result necessarily means a stairstep-looking result when plotted.
 
Hmmmm ok, so is it not advisable to use a curve when sending as a MIDI CC message?

Oddson, yes please could you unpack the code line by line. That would help?
 
Oddson, yes please could you unpack the code line by line.

Perhaps you could try adding Serial.print() lines into the code and observe the results in the Arduino Serial Monitor.

Earlier you asked:

Perhaps you could provide me some resources as to where to learn more about utilizing this platform (Arduino / Teensy)

Well, *this*, experimenting and examining code, is the very best resource for learning.

Please, do yourself a favor by digging into how the code actually works. Doing this yourself by watching what the code actually does is a far better learning experience than asking someone to explain it all to you line by line!
 
A couple cups of coffee later and I figured it out with the help of this page Finding the Center of a Circle from 2 Points and Radius

I had wanted to do this myself a while ago and couldn't think of the mathematical solution, but couldn't spend any time on figuring it out properly. Here's one of the two solutions, switch some signs to get the others. What you are solving for is the center of a circle that is equidistant from 0,0 and 127,127, which there are two of.

https://www.desmos.com/calculator/jy21vtnwav
 
Last edited:
Wow, that is some math. Thank you

I see its 2048, double to analog value of each linear potentiometer. My next question is how would this be used to calculate the value for sending as MIDI CC, if possible?
 
2048 has no significance, other than I thought it looks about straight there, you could raise it much higher, it will just trend towards a straight line but never quite get there.

I used a ti-89 emulator and solve() to do this math to solve for y and it spit out this, which is correct. I became dependent on this in school, which was bad and 'cheating', but hey it works, I wouldn't have solved this without it.

s = 127
q = sqrt(s^2 + s^2)
w = sqrt(r^2 - (q/2)^2)*(-s/q)
y = (-sqrt(4*r^2-s^2-4*s*(w-x)-4*(w^2-2*w*x+x^2))-s+2*w)/2 god i hope I retyped that right, it copy and pastes funny out of desmos

Either way you can see that painfully long solution working in all of it's glory in desmos if I did type it wrong.
where x is the number between 0 and 127 you would like to compress and r is a number between 127-2048+ that represents how much you would like the returning y variable to be compressed.

https://www.desmos.com/calculator/hhpynxmgfp

That is a LOT of math to do every time you want to compress a midi number, so I would suggest creating some lookup tables with this math to translate with if you don't need fast response from different r values. If it were me, I would figure it out in processing, have it spit out the tables to serial, and copy and paste that into the arduino code.


edit: http://codepen.io/ohnoitsaninja/pen/MprbvJ
Here is a javascript version with a working demo. You could copy and paste into arduino, switch the vars to floats and it would work.
Code:
  var s = 127;
  var s2 = s*s;
  var r2 = r*r;
  var q = sqrt(s2 + s2);
  
  var s4 = 4*s;
  var w = sqrt(r2 - (q/2)*(q/2)) *(-s/q);
  var w2 = w*w;
  var p = 4*r2-s2;
  var k = -s+2*w;
  var white = color(255);
  
  for (var x = 0; x < 128;x++){
     var y = -((sqrt(p-s4*(w-x)-4*(w2-2*w*x+x*x)))+k)/2;
     set(200+x, 200-y, white);
   }

http://codepen.io/ohnoitsaninja/pen/xqpVJz/?editors=0010
Here is a different attempt trying to average between two circles, wrong, not symmetric and couldn't get it to work.
 
Last edited:
Status
Not open for further replies.
Back
Top