# $event_par_mod_value_id and its full range



## aaronventure (Apr 4, 2022)

Where does the -1000000 to 0 part of this parameter get used?


----------



## EvilDragon (Apr 5, 2022)

It's used with "from script" modulator. However due to a bug, if you use the modulation shaper on "from script" modulator, it will clamp things to unipolar positive range only. I'm hoping this gets fixed in next version of Kontakt.


----------



## aaronventure (Apr 5, 2022)

EvilDragon said:


> It's used with "from script" modulator. However due to a bug, if you use the modulation shaper on "from script" modulator, it will clamp things to unipolar positive range only. I'm hoping this gets fixed in next version of Kontakt.


Ah, that explains it. 

Do you think this will get fixed? The feature has been here for the past 6 months, plenty of time for instruments to be made with this feature at their core. It is an absolute gamechanger for complex instruments, so what are the odds this gets left as it is and another one gets implemented to be bipolar?

There are simple, but not quite elegant workarounds to the current clamping problem but if this gets fixed then it will break the functionality of patches using these workarounds unless the values are hard-limited to the positive range.


----------



## EvilDragon (Apr 5, 2022)

I don't think there's gonna be another "from script" modulator that has this fixed. Seems a lot more trouble than worth. What makes more sense (to me at least) is to just make it properly bipolar, and upon loading the patch force a modification of all active mod shapers belonging to "from script" modulators to the top right half (left half would be pinned to 50%), which would retain their existing behavior. But that's just my 2c. This gets complicated if you're in Table mode, though, because you effectively lose half of your values this way... And actually in regular curve mode, the curve becomes really weird constrained to that top right quarter... So I don't know what will ultimately happen. Maybe it also just becomes bipolar and if anyone used "from script" + mod shaper would have to update. Needs to be discussed.

I'd also argue using the mod shaper with "from script" modulator is not really super necessary, since you decide what you want the modulator value to be in the script itself anyways...


----------



## aaronventure (Apr 5, 2022)

Good points all. Remains to be seen. 



EvilDragon said:


> I'd also argue using the mod shaper with "from script" modulator is not really super necessary, since you decide what you want the modulator value to be in the script itself anyways...


In the end, yes, but the shaper makes it super easy to try out curves on the fly without having to plot them first, delineate the dataset, then import into the script, or be adjusting the equation all the time. It's not very fun. Just tweaking the shaper until you find the right curve, on the other hand, is .

I think I'll live if this stays as it is. Good to know that it's a known issue.

Still wish I could copy and paste the shaper curves with a click. You don't happen to have a trick up your sleeve for this, too (right now I save it to "new preset", then just load it up on another one)?


----------



## EvilDragon (Apr 5, 2022)

Yeah I'm using presets for that too.


----------



## olmerk (Aug 5, 2022)

Hello wizards! I'd like to recreate a curve of built-in velocity-to-volume modulator using exclusively "from script" feature. Is the curve known at all? I was told it's (decadic) logarithm, but as I've coded such dependency I can hear that it's not close at all to the behaviour of built-in velocity-to-volume modulator. It gives too "compressed" sound (too narrow dynamic range). Either it’s not a decadic logarithm or I've built it wrong.


----------



## aaronventure (Aug 5, 2022)

olmerk said:


> built-in velocity-to-volume modulator


Not sure what you mean by this?


----------



## olmerk (Aug 5, 2022)

aaronventure said:


> Not sure what you mean by this?


This one:


----------



## aaronventure (Aug 6, 2022)

olmerk said:


> This one:


The modulation slider? It's a power curve, `y=ax^b`. 

In this case, for the range of 0-1000000, constants are `a=100000` and `b=0.5`. Input your desired percentage (what is shown above the slider when you drag it inside Kontakt) as `x`. 

So if you wish to get a value for 30% (the one you set with set_engine_par), you calculate `value = 100000 * 30.0^0.5` (which gets you 547722).

Now just convert the 0-100 percentage scale to velocity. and there you have it. 






The formula for getting the KSP modulator intensity value from desired intensity percentage


I didn't see this documented anywhere so I'll post it here. It appears that Kontakt's modulation intensity slider follows a power curve (y = ax^b). Here's a formula that will return a value from 0-1000000 when you put in a desired percentage. value = 100000 * percentage ^ 0.5 So if you wish...




vi-control.net


----------



## olmerk (Aug 7, 2022)

aaronventure said:


> The modulation slider?


No, no. I don't need to control the slider via script. I'd like to recreate, using "from script" feature, the curve of velocity-to-volume dependence:


----------



## aaronventure (Aug 7, 2022)

Ah, I get it, when you try to scale the velocity response to the EVENT_PAR_MOD_VALUE_ID parameter, it doesn't behave the same as the velocity-sourced mod when it comes to volume.

Yeah, that's a weird one. As you said, you can do it with the tables, but regarding the curve, I did some testing and managed to make it null at velocity 64 and EVENT_PAR_MOD_VALUE_ID value 127976.

If we scale the 0-127 scale to 0-1000000, 64 gives us 503937 (rounded). Knowing that, we can plot a power curve through these points and get the equation `y = 10000.01*x^0.3333333`, which looks suspicious . At least confirms I'm on the right track.

It's much simpler, for implementation, to use this data and find a few more null points along this curve and get a more accurate equation for converting 7-bit velocity values to the 0-1000000-range values for use with EVENT_PAR_MOD_VALUE_ID. NI seem to be converting the 1000000-range to 127, I imagine for easier scalability/future-proofing.

Anyway, we find a few more null points, input the data and get to `y = 0.4881742*x^3.000007`. Simply input EVENT_VELOCITY instead of X, and use this as the parameter value for EVENT_PAR_MOD_VALUE_ID.

Confirmed to null 100% across the entire velocity range between two phase-inverted groups, one using the velocity mod, the other using "from script" with this equation.


----------



## olmerk (Aug 7, 2022)

aaronventure said:


> Ah, I get it, when you try to scale the velocity response to the EVENT_PAR_MOD_VALUE_ID parameter, it doesn't behave the same as the velocity-sourced mod when it comes to volume.
> 
> Yeah, that's a weird one. As you said, you can do it with the tables, but regarding the curve, I did some testing and managed to make it null at velocity 64 and EVENT_PAR_MOD_VALUE_ID value 127976.
> 
> ...


Thanks a lot! However I have three issue here:
1) Why have you suggested power dependence? I mean why the curve has y=a*x^b type? Because it's an inversion of log?
2) Have you found that the velocity=64 corresponds to 127976 parameter by just trying to null two physical signals, inverting the phase?
3) I've discovered that using param=0 in set_event_par_arr(event_id,$EVENT_PAR_MOD_VALUE_ID,0,mod_id) doesn't choke the sound at all. It happens only with param=-1000000. Seems that NI widened the range.


----------



## aaronventure (Aug 7, 2022)

The model fit the data. I can't give you a proper academic answer as to why. A few years ago I was documenting some Kontakt behavior and was trying out different models. Power function always seemed to be the answer. 

I first narrowed down the ballpark by eyeballing the middle point of the modulation position while keeping eye on the peak level meter. All the while I had the velocity 64 note playing on repeat, one group with the velocity modulator and phase inverted, the other with the "from script" mod. Started with 150000, then moved down. Larger intervals, then smaller as the meter went down. It nulled at 127976 for velocity value 64. This only took a minute or so.


----------



## olmerk (Aug 7, 2022)

aaronventure said:


> The model fit the data. I can't give you a proper academic answer as to why. A few years ago I was documenting some Kontakt behavior and was trying out different models. Power function always seemed to be the answer.
> 
> I first narrowed down the ballpark by eyeballing the middle point of the modulation position while keeping eye on the peak level meter. All the while I had the velocity 64 note playing on repeat, one group with the velocity modulator and phase inverted, the other with the "from script" mod. Started with 150000, then moved down. Larger intervals, then smaller as the meter went down. It nulled at 127976 for velocity value 64. This only took a minute or so.


I understand, thank you for the explanation. 

So you at your side successfully confirmed the nulling of the entire curve by phase-inverting in the range of 0 to 1000000? Because I'm getting -inf volume only at -1000000 value, not 0. That's bugging me. I'm on Kontakt 6.7.1


----------



## polypx (Aug 8, 2022)

Velocity 0 is note off, no? It will never be processed by this curve.


----------



## olmerk (Aug 8, 2022)

polypx said:


> Velocity 0 is note off, no? It will never be processed by this curve.


No, no, I'm talking about 0 of the pararmter for "from script", not velocity.


----------



## polypx (Aug 8, 2022)

Isn't the only way to get 0 for 'from script' in this case with 0 velocity?


----------



## olmerk (Aug 8, 2022)

aaronventure said:


> The model fit the data. I can't give you a proper academic answer as to why. A few years ago I was documenting some Kontakt behavior and was trying out different models. Power function always seemed to be the answer.
> 
> I first narrowed down the ballpark by eyeballing the middle point of the modulation position while keeping eye on the peak level meter. All the while I had the velocity 64 note playing on repeat, one group with the velocity modulator and phase inverted, the other with the "from script" mod. Started with 150000, then moved down. Larger intervals, then smaller as the meter went down. It nulled at 127976 for velocity value 64. This only took a minute or so.


So after I discovered that only -1000000 mutes the volume completely, not 0, I tried a new curve of type y=a*x^b+c. I calculated the coefficients a,b,c using extreme and an auxiliary points and built a new dependence. Now mathematically for velocity 0 it gives -100000, for 64 gives 127976 and for 127 provides 1000000. Looks good. But in reality it doesn't recreate velocity-to-volume modulator at all. At lower velocities the volume is really low. I'm perplexed. Seems like y=a*x^b+c is not the case and a different dependence type should be used...


----------



## olmerk (Aug 8, 2022)

polypx said:


> Isn't the only way to get 0 for 'from script' in this case with 0 velocity?


Yes, param=0 comes only if velocity would be 0. But it mustn't cause the major fault. The curve can be easily tweaked to have param=0 with velocity=1 and 1000000 with velocity=127.

The major issue now is that param=0 is way too far away from muting the volume. To my ears it gives just -6dB or so. It turns out that only -1000000 shuts the sound completely.


----------



## aaronventure (Aug 8, 2022)

polypx said:


> Velocity 0 is note off, no? It will never be processed by this curve.


Yes, but in this case the plot is the same. Calculating for x=1 gives us 0.4881742 (which is our coefficient), which KSP rounds down to 0.


----------



## polypx (Aug 27, 2022)

Hi Aaron, I wonder if you have an idea how to adjust the equation for the power curve when the velocity (or from_script) depth is not at 100%? It only seems to null properly at full depth, below that the curve doesn't seem 'deep' enough.

Can we adjust the formula somehow based on the current modulation depth?


----------



## aaronventure (Aug 27, 2022)

If you don't set it to 100%, it won't go down all the way. If you need your velocity range to be smaller, either scale it down (which will give you fewer steps), or scale it across a range than 0-1mil (say, 200000-1000000 and use these values with this function:



aaronventure said:


> If we scale the 0-127 scale to 0-1000000, 64 gives us 503937 (rounded). Knowing that, we can plot a power curve through these points and get the equation `y = 10000.01*x^0.3333333`, which looks suspicious . At least confirms I'm on the right track.


Linear scaling goes like this: `return := (variable - oldmin) * (newmax - newmin) / (oldmax - oldmin) + newmin`, where old values are 0-127 (or 1-127) and new 0-1mil or whatever you choose. If you then have a control for scaling the velocity range, it would simply change the newmin value in this equation, the result of which would be fed into the function above.


----------



## polypx (Aug 28, 2022)

Yes, this works, but it doesn't match the depth control of the velocity modulator, at least not in my implementation.

If I map the values calculated for 0 - 1000000 onto 500000 - 1000000, it does of course reduce the dynamic range, but not in the same way as the builtin depth control for velocity at 50%. 

As with just reducing the "from_script" depth itself, the result is not as "deep" as the Kontakt velocity modulator at lower values.


----------



## EvilDragon (Aug 28, 2022)

I have emulated the vel > volume slider via change_vol() commands and a 2D lookup array. Not sure if that would be of much help for you, though, but here you go.

(If anything, these are millidecibel values which one could use to plot the 11 curves in Excel or something, then figure out the trend...)


----------



## aaronventure (Aug 28, 2022)

polypx said:


> Yes, this works, but it doesn't match the depth control of the velocity modulator, at least not in my implementation.
> 
> If I map the values calculated for 0 - 1000000 onto 500000 - 1000000, it does of course reduce the dynamic range, but not in the same way as the builtin depth control for velocity at 50%.
> 
> As with just reducing the "from_script" depth itself, the result is not as "deep" as the Kontakt velocity modulator at lower values.


If you use `value = 100000 * percentage ^ 0.5` to give you the correct value value needed by inputting the desired percentage (that you would set for velocity), does that work?


----------



## polypx (Aug 28, 2022)

Ah good point. That makes sense.

It's still not perfectly nulling though at lower velocities, but definitely closer.


----------



## polypx (Aug 29, 2022)

I found some points that nulled with the velocity at 50% depth and at 20% depth, to try and get a better idea of what the depth control is doing to the curve. I've plotted these against the full value set for 100% here. 


Red values are 50% depth, orange 20% depth. I'm not really sure how you go about "fitting" a curve to the values tho.


----------



## aaronventure (Aug 29, 2022)

polypx said:


> I found some points that nulled with the velocity at 50% depth and at 20% depth, to try and get a better idea of what the depth control is doing to the curve. I've plotted these against the full value set for 100% here.


Huh, looks like the coefficients are changing as well. It's great that we're all supposed to just go and figure this stuff out on our own :D



polypx said:


> I'm not really sure how you go about "fitting" a curve to the values tho.


Basic trend line stuff can be done in Excel (or LibreOffice Calc). For advanced stuff like more types of functions and smoothing, MATLAB.


----------

