Midi velocity curve correction plugin


(roithamer) #1

Hi
Can you guys recommend a plugin (linux native preferably) for midi velocity curve correction?
I’m only aware of Robin’s “Midi Velocity Adjust” but as far as I understand it only lets you adjust Min and Max velocity values - nothing in between.


(roithamer) #2

Ok, so maybe it could be done via lua script? Something like:
if incoming midi velocity is in the range of 60-80 then convert it to 70
if incoming midi velocity is in the range of 80-100 then convert it to 90
etc
etc
Could it be easily done? If so I would be really grateful for any hints how to write it.


(Robin Gareus) #3

The “Midi Velocity Adjust” does linear interpolation of the values in the target-range for example to 32…68 (no offset) the mapping would be as depicted below (x-axis is input velocity, y-axis output):
midi-scale

It does however not offer control over the the curve and certainly not a piecewise function, but yes, you can do that with a Lua script: save the following to your config GNU/Linux: ~/.config/ardour5/scripts/mscale.lua and edit the function map_velocity as needed.

ardour {
  ["type"]    = "dsp",
  name        = "MIDI Velcocity Hack",
  category    = "Example", -- "Utility"
  license     = "MIT",
  author      = "Ardour Lua Task Force",
  description = [[An Example Midi Filter for prototyping.]]
}

function dsp_ioconfig ()
  return { { midi_in = 1, midi_out = 1, audio_in = 0, audio_out = 0}, }
end

function dsp_run (_, _, n_samples)
  local cnt = 1;
  function tx_midi (time, data)
    midiout[cnt] = {}
    midiout[cnt]["time"] = time;
    midiout[cnt]["data"] = data;
    cnt = cnt + 1;
  end

  function map_velocity (v)
    if v < 50 then
      return 1 -- min velocity for a note-on event is 1
    elseif v < 70 then -- 50 .. 69
      return 50
    elseif v < 90 then -- 70 ..89
      return 80
    else               -- 90 .. 127
      return 90 + math.floor (25 * ((v - 90) / 37)) -- maps linearly to 90..115                                                                                                                                                                                                                                                
    end
  end

  -- for each incoming midi event
  for _,b in pairs (midiin) do
    local t = b["time"] -- t = [ 1 .. n_samples ]
    local d = b["data"] -- get midi-event bytes
    local event_type
    if #d == 0 then event_type = -1 else event_type = d[1] >> 4 end
    if (#d == 3 and event_type == 9) then -- note on
      d[3] = map_velocity (d[3])
      tx_midi (t, d)
    else -- pass thru all other events unmodified
      tx_midi (t, d)
    end
  end
end

It is based on two existing script that may also provide further insights


(roithamer) #4

Yes! Ardour Lua Task Force to the rescue again :grinning:
Thank you so much Robin!


(Edouard S.) #5

For a simple “rounding”, the MIDI Transform tool can be enough, with something like:

Set [Velocity] to [this note's] [velocity]
/ [exactly] 20
* [exactly] 20
+ [exactly] 10

This will map [0 - 20[ to 10, [20 - 40[ to 30 etc…


(Robin Gareus) #6

PS. I do recall seeing a plugin that allows to draw curves, exponential mappings and such, similar to pianoteq’s built-in, but I was not able to find it anymore. In case someone happens stumbles upon this, I’d be interested as well.


(roithamer) #7

Nice trick, I didn’t know that one. Thank you!


(Julien "_FrnchFrgg_" RIVAUD) #8

Maybe at one point I’ll be tricked into writing a “gamma” lua dsp plugin with an inline UI…