keni Posted May 28, 2019 Share Posted May 28, 2019 Hello! I created a tool that lets you create custom MIDI velocity curves that you can load in Scripter. The tool is browser-based, and is available here: https://sumire-io.gitlab.io/midi-velocity-curve-generator/ You can move the points to generate a velocity curve that suits your playing style (double click to add or remove points). The Scripter JavaScript code is generated in real-time in the editor below. The first line of the code (comment) is the curve data in JSON format. You can paste this JSON string into the input field to load an existing velocity curve in the curve editor. I created this tool because my Yamaha keyboard has a very weird velocity curve (maximum velocity is about 110). This has caused problems with sampled piano libraries, because I cannot reach any velocities over 110 when I'm playing. I'm aware of the Velocity Processor MIDI Plugin in Logic, but it can only do very basic velocity manipulation in my opinion. 1 Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted May 28, 2019 Share Posted May 28, 2019 keni, VERY cool! I'd like to hear more about how you setup the webpage on gitlab. Clever way to provide a UI, I like it! It makes me think I'd like to use a similar approach for some other Scripter things i have that badly need a better UI. Quote Link to comment Share on other sites More sharing options...
keni Posted May 28, 2019 Author Share Posted May 28, 2019 keni, VERY cool! I'd like to hear more about how you setup the webpage on gitlab. Clever way to provide a UI, I like it! It makes me think I'd like to use a similar approach for some other Scripter things i have that badly need a better UI. Thank you very much. The webpage is a git repository on Gitlab. The source code repository is available here: https://gitlab.com/sumire-io/midi-velocity-curve-generator. You can use Gitlab Pages to host static HTML pages on Gitlab. Here is a step-by-step tutorial: https://about.gitlab.com/2016/04/07/gitlab-pages-setup/. If your repository consists only of a static HTML site, like in my case, it's very simple. You just need to create one file in the root folder, as instructed in the tutorial (Option A section). Github has a similar Github Pages feature as well, if you prefer Github. https://help.github.com/en/articles/what-is-github-pages Quote Link to comment Share on other sites More sharing options...
68time Posted March 16, 2021 Share Posted March 16, 2021 Brilliant- this helped me out a lot with my old controller! Still wish there was a simple velocity mapper that could be placed in the MIDI fx slot for on the fly adjustment Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 16, 2021 Share Posted March 16, 2021 You could use the above and modify it only slightly to handle velocity... Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 16, 2021 Share Posted March 16, 2021 otherwise, this is probably easiest to handle in the environment. Quote Link to comment Share on other sites More sharing options...
ValliSoftware Posted March 16, 2021 Share Posted March 16, 2021 Still wish there was a simple velocity mapper that could be placed in the MIDI fx slot for on the fly adjustment Add a Modulator and set to Volume Quote Link to comment Share on other sites More sharing options...
68time Posted March 17, 2021 Share Posted March 17, 2021 I'm not very versed in MIDI, so good chance that I don't get it... but the LFO controlling the volume is something different from just applying a fixed factor to a velocity value based on a table/function/factor. Quote Link to comment Share on other sites More sharing options...
ValliSoftware Posted March 17, 2021 Share Posted March 17, 2021 I'm not very versed in MIDI, so good chance that I don't get it... but the LFO controlling the volume is something different from just applying a fixed factor to a velocity value based on a table/function/factor. The Modulator doesn't just do a curve, but the patterns can be anything. Here's just a few but it's up to. you to create ANY type of pattern as well as following a RATE. The other thing I'll mention as well is, put this on a External Instrument track using IAC and you'll be able to capture the pattern and then you can further modify this as well. Quote Link to comment Share on other sites More sharing options...
68time Posted March 17, 2021 Share Posted March 17, 2021 All I need is a really simple, but SPECIFIC pattern: exponential curve I don't see how I can put THAT curve into the Modulator Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 17, 2021 Share Posted March 17, 2021 The environment is the nest place to do this with a transformer map, so that the velocity adjusted midi will be recorded to track regions. Otherwise the above website generates a script you can tweak slightly to use in scripter for velocity. If those don’t work I have a velocity curve script I shared in the midifx sub forum a few years ago that should work for you. Quote Link to comment Share on other sites More sharing options...
68time Posted March 17, 2021 Share Posted March 17, 2021 Using the above works fine. Still I would love to find a MIDI fx plugin with similar functionality to the Velocity Editor in Pianoteq. What's nice about that: curve can have any shape, visual feedback while playing/creating curves, easier to use than environment transformer. In the meantime I can get by with the script fed by the tool above. Ultimately I'll have to get a better masterkeyboard at some point Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 17, 2021 Share Posted March 17, 2021 I have looked many times and unfortunately there isn’t a dedicated velocity curve midifx plugin for Mac out there. Quote Link to comment Share on other sites More sharing options...
68time Posted March 17, 2021 Share Posted March 17, 2021 I have looked many times and unfortunately there isn’t a dedicated velocity curve midifx plugin for Mac out there. I was questioning my google-skills because of this Seems to me this is such a frequent use-case... curious that such a plugin does not exist Maybe a business opportunity for some smart people here on the forum Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 17, 2021 Share Posted March 17, 2021 (edited) It would not be a hard one to do in JUCE maybe I will eventually. here is a script I made a few years ago that might help you since its a little more interactive, you can slide a slider to dial in an exponential curve that works, you just can't really see what the curve looks like... Well I think there is a way to have it display some kind of textual curve on the Scripter window if you hit a button or something, I can't remember now, but it works, last time I checked which was a few years ago. NOTE - looks like I didn't include velocity in this version, but I can add that later, I am running out the door right now, or you can, it would not be a hard add. // // EventGamma // Version 0.4 // // This script will provide a non-linear accleration to CC, Pitchbend and // aftertouch midi events. The factor value establishes the amount of curve // above or below the linear line. A factor of zero will be the linear line // // TODO, generate a lookup table to avoid using math during PLAY var NeedsTimingInfo = true; var PluginParameters = []; function HandleMIDI(event) { var gamma = GuiParameter(0); // if the gamma is 1 then just forward the event. if (gamma==1) { event.send(); return; } // if CC events are being included, then range is 0-127 if (event instanceof ControlChange && GuiParameter(3) == 1) { event.value = scale(event.value, 127, gamma); } // if Pitch Bend events, the range is -8291 to 8192 else if (event instanceof PitchBend && GuiParameter(4) == 1) { // if event.value is not zero, then accelerate it. use offset to // force positive range if (event.value!=0) { const OFFSET = 8192; var temp = event.value+OFFSET; var maxPitch = OFFSET+OFFSET; event.value = scale(event.value, maxPitch, gamma)-OFFSET; } } // if aftertouch, then range is 0-127 else if (event instanceof ChannelPressure && GuiParameter(5) == 1) { event.value = scale(event.value, 127, gamma); } else if (event instanceof PolyPressure && GuiParameter(6) == 1) { event.value = scale(event.value, 127, gamma); } // send event event.send(); } //============================================ // couple of globals related to the graphing //============================================ var gGraphFlush = false; var gGraph = []; const MAXFLUSH = 10; //====================================================== // Scales the value based on gamma and range // function scale(value, range, gamma) { // off means off, no matter what. Should we do this? if(value == 0) { return 0; } // calculate scaled value var out = Math.round(range * Math.pow((value/range),gamma)); // for incoming value over 1, always scale to at least 1 if(out == 0) { out = 1; } return out; } //=================================================================== // function that will send to console a graph if the selected curve // function plotCurve(gamma) { // if flush in progress then ignore this if (gGraphFlush) { return; } var graph = new Array(64); for (var x=0;x<64;x++) { graph[x] = new Array(32); for (var y=0;y<32;y++) { graph[x][y] = 0; } } // calculate Y values, cut X size in half and cut Y value in half again to shrink height of graph for (var x=0;x<64;x++) { var y = scale(x*2, 127, gamma)/4; graph[x][Math.round(y)] = 1; } // build output strings, for(var y=31;y>=0;y--) { var str = "|"; for (var x=0;x<64;x++) { if (graph[x][y] == 1) { str = str + "x"; } else if (x/2==y) { str = str + "."; } else { str = str + " "; } } gGraph.push(str); } // add x axis var xaxis = "+"; for(var x=0;x<64;x++) { xaxis = xaxis + "-"; } gGraph.push(xaxis); gGraphFlush = true; } //============================================= // handle when they hit the show graph button // function ParameterChanged(idx, val) { PluginParameters[idx].data = val; if (idx == 1) { plotCurve(GuiParameter(0)); } } //========================================================= // use Idle() function to flush graph to console // function Idle() { if(gGraphFlush) { // Trace("printing graph"); var i = 0; while( gGraph.length > 0 && i < MAXFLUSH) { Trace(gGraph.shift()); i++ } if (gGraph.length <= 0) { gGraphFlush = false; } } } PluginParameters.push({ name: "Gamma", type: "log", defaultValue: 1, minValue: .1, maxValue: 7.9, numberOfSteps: 100, hidden: false, disableAutomation: false }); PluginParameters.push({ name: "Show Graph", type: "momentary", hidden: false, disableAutomation: true }); PluginParameters.push({ name: "-------- Filter -------", type: "text", hidden: false, disableAutomation: true }); PluginParameters.push({ name: "Control Change", type: "checkbox", defaultValue: 1, hidden: false, disableAutomation: true }); PluginParameters.push({ name: "Pitch Bend", type: "checkbox", defaultValue: 0, hidden: false, disableAutomation: true }); PluginParameters.push({ name: "Channel Pressure", type: "checkbox", defaultValue: 0, hidden: false, disableAutomation: true }); PluginParameters.push({ name: "Poly Pressure", type: "checkbox", defaultValue: 0, hidden: false, disableAutomation: true }); function GuiParameter(id) { // if script was recently initialized, reload GUI value if(PluginParameters[id].data == undefined) { PluginParameters[id].data = GetParameter(id); } if(id < PluginParameters.length) { return PluginParameters[id].data; } } function Reset() { } Reset(); Edited March 17, 2021 by Dewdman42 Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 17, 2021 Share Posted March 17, 2021 And here is a much much much simpler script I did a long time ago, along similar lines, there is no GUI, but you could add a slider easily enough to make it interactive to dial it in viewtopic.php?f=45&t=132971&p=678514&hilit=gamma#p678514 Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 17, 2021 Share Posted March 17, 2021 if you're just wanting a simple curve....which is kind of like compression, then there is also the built in midi compressor: https://support.apple.com/guide/logicpro/velocity-processor-overview-lgce332342da/mac Quote Link to comment Share on other sites More sharing options...
68time Posted March 17, 2021 Share Posted March 17, 2021 Thanks @Dewdman42! But coding looks mostly like gibberish to me If you ever decide to do the JUCE-thing... I'll bookmark this post Quote Link to comment Share on other sites More sharing options...
Dewdman42 Posted March 17, 2021 Share Posted March 17, 2021 Here, I made a simple one for velocity, no coding required. Just open Scripter, copy and paste this into the script editor and hit the Run Script button. You'll see a slider you can slide to more or less aggressive curves...this mimics video gamma curves I guess. viewtopic.php?f=45&t=132971&p=818934#p818934 Quote Link to comment Share on other sites More sharing options...
68time Posted March 17, 2021 Share Posted March 17, 2021 Oh wow- thank's a lot for this, Dewdman!!! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.