# Adding EQ in Group FX...



## Tod (Feb 25, 2011)

I've got an old client (friend) that I've been helping for the last 6 months putting together backing tracks for playing live. In the course of things he brought in a Steel Guitar player for a few songs and I ended up sampleing his steel to make a steel instrument in Kontakt. At first I didn't think it would turn out very well, the samples weren't great and the steel is a pretty complicated instrument. Anyway, by the time I put a script together with all the contollers (over 20), it actually sounds pretty good, quite convinceing actually. 

One of the things I did is use the ahdsr envelope on the amplifier to create more attack to give the illusion of picking it harder. I did this by makeing the Attack full, Hold very short (from 16 to 32ms), Decay (around 48 to 80ms), and then adjusting the Sustain from 0db to -12db while at the same time adding 0db to +12db on the Amplifier Volume. Effectively this gives me an added 0db to +12db (in 1db increments) attack without affecting the overall balance and level of the notes. This works great except that I'm missing one thing, a little added EQ on the higher end as the attack level goes up. Keep in mind that this is all controlled by one controller for each group and I want the EQ to last only as long as the attack.

So I added an EQ to the Group FX thinking I could add EQ to the front of the attack by useing an ahdsr envelope to the gain (you can add the ahdsr envelope to the gain on the EQ as a modulator). I set it up with full Attack, very short Hold and Decay, and 0db Sustain. 

Now the EQ gain is working properly, going up in small increments as the main attack is increaseing, but it's lasting through out the length of the note and doesn't seem to be affected by the EQ-Gain-ahdsr-envelope at all. :? 

What's wrong with my thinking on this? :? Is there a way to make the ahdsr on the EQ Gain work in this manner without adding more controllers? Heh heh, as it is I've got 3 Help screens in front of me all the time in order to work with it. :o 

Also I need this to work in Kontakt2. I have K4 but my client only has K2. :| 

Tod


----------



## Big Bob (Feb 25, 2011)

> So I added an EQ to the Group FX thinking I could add EQ to the front of the attack by useing an ahdsr envelope to the gain (you can add the ahdsr envelope to the gain on the EQ as a modulator). I set it up with full Attack, very short Hold and Decay, and 0db Sustain.



Hey Tod,

I'm a little rusty about the details of K's modulators but maybe you should try to set the envelope first for a long steady-state value (ie just a steady sustain level) and then listen to the combination of the EQ and envelope and find out how low you need to set the sustain level so that you no longer hear the EQ boost (this might have to be below 0db, possibly as low as minus infinity). Then, determine the steady sustain level that produces the amount of brightening you want. Once you have determined those two steady levels, you should be able to set the envelope to swing between these levels with the desired time profile?

It probably won't but, I hope this helps.

Rejoice,

Bob


----------



## EvilDragon (Feb 26, 2011)

You should modulate the gain 1/2/3 of the group EQ with a modulator. Use Existing, then pick the envelope that's modulating that group's volume.


----------



## Tod (Feb 26, 2011)

> You should modulate the gain 1/2/3 of the group EQ with a modulator. Use Existing, then pick the envelope that's modulating that group's volume.



Hi ED,

Thanks for the suggestion but K2 doesn't have "Existing" in it's menu so I've just been trying to add the ahdsr directly to the EQ Gain as a modulator.




> I'm a little rusty about the details of K's modulators but maybe you should try to set the envelope first for a long steady-state value (ie just a steady sustain level) and then listen to the combination of the EQ and envelope and find out how low you need to set the sustain level so that you no longer hear the EQ boost (this might have to be below 0db, possibly as low as minus infinity). Then, determine the steady sustain level that produces the amount of brightening you want. Once you have determined those two steady levels, you should be able to set the envelope to swing between these levels with the desired time profile?



Thanks Bob, actually that's basically the way I approached it the other day. I had it setup so I could directly a/b the differences and I came to the conclusion that the ahdsr wasn't affecting it at all.

However, I'm starting to think I may have had it setup wrong because I decided to get a little more serious with some tests today and am finding that the ahdsr is indeed working but not as I expected.

Today I recorded a 3.1K-hrz sine wav sample that I loaded into K2, added a 1 band EQ in Group FX, set the Frequency to 3.1K, Bandwidth at 1 Oct., and added the ahdsr to the Gain as a modulator. Leaving the Gain set at 0.0db on the EQ, I set the attack=0ms and the Sustain=0.0db on the ahdsr (effectively leaving it flat).

When I played the sample, the ahdsr raised the output by 23db. In other words, when I bypass the ahdsr the output is at a -24db but when I unbypass it, the ouput goes to -1db. So then when I set up the ahdsr (Hold=18ms, Decay=150ms, Sustain=-inf) it did work as expected but the output goes from -1db to -24db and that's with the EQ gain still set at 0db. Obviously that won't work.

As kind of a little side test I set the ahdsr back up for a flat envelope and then lowered the EQ Frequency down to 20hrz figureing the output would be next to nothing. However, there was a noticable bump at the front of the sample. So then I started raiseing the Freq starting at 50hz and sure enough, there was a noticable thumb that went up in tuneing as I raised the Frequency.

Thanks guys, at this point I'm rather baffled heh heh, so if you've got any other suggests. :?  

Tod


----------



## EvilDragon (Feb 26, 2011)

Please update. K2 is really getting old now. You should be on K4!


----------



## polypx (Feb 27, 2011)

> Leaving the Gain set at 0.0db on the EQ, I set the attack=0ms and the Sustain=0.0db on the ahdsr (effectively leaving it flat).



Todd, that description might be an envelope that's "flat", but one that's at maximum and flat.

I just tried it out here, and it seems to work as expected. Attached tiny instrument for K2. 

What wrong with the behaviour?

cheers
Dan


----------



## Big Bob (Feb 27, 2011)

> I just tried it out here, and it seems to work as expected. Attached tiny instrument for K2.
> 
> What wrong with the behaviour?
> 
> ...



Good going Dan o-[][]-o This is what I was trying (very clumsily) to say about the envelope settings in my first post.



> and find out how low you need to set the sustain level so that you no longer hear the EQ boost (*this might have to be below 0db*, possibly as low as minus infinity).



What about it Tod, has Dan solved your problem?

Rejoice,

Bob


----------



## Tod (Feb 27, 2011)

> Please update. K2 is really getting old now. You should be on K4!



Thanks ED, as I explained above, I've got K4 on my own computer but my client only has K2. Incidently, I need to apologize to you, I do have "Existing" in the K2 menu and I can see I could easily direct it to the vol-ahdsr. That has posibilities and is something for me to think about although I'm useing that envelope for other things too.



> The modulator's influence is of course affected by the Intensity slider and the polarity, etc. It may be that the modulator cannot raise the effect (only attenuate it). That's why I think you need to first determine the unmodulated effect of the EQ and then study the modulated effect when the modulator is a steady value. You of course will also have to study the effects of the Intensity slider, etc.



Thanks Bob, I think your right about the intensity slider. I played around with it some the other day and was allready thinking that might be the key but I was so confused about what the envelope was doing I didn't know how to proceed. Dan's little test nki has shed some light on this.



> Todd, that description might be an envelope that's "flat", but one that's at maximum and flat.
> 
> I just tried it out here, and it seems to work as expected. Attached tiny instrument for K2.



Thanks a lot Dan, I think I can clearly see what's happening now. Based on your little test nki it appears the ahdsr is adding about 12db to the gain which is actually around 24db-vu and cò ž   "™ ž   "™… ž   "¶¸ ž   "¶È ž   "þš ž   "þø ž   #
g ž   #
Š ž   #Hl ž   #HŠ ž   #P– ž   #P« ž   #PÂ ž   #PÖ ž   #dQ ž   #d  ž   #dð ž   #eE ž   #ls ž   #l| ž   #rŒ ž   #rÇ ž   #{¶ ž   #{½ ž   #¢> ž   #¢n ž   #¥Œ ž   #¥• ž   #§„ ž   #§š ž   #± ž   #±) ž   #³ ž   #³¬ ž   #Ý& ž   #Ý' ž   #îÂ ž   #îÒ ž   #ï ž   #ïe ž   #ðb ž   #ðy ž   $þ ž   $B ž   $vo ž   $vú ž   $‚R ž   $‚‹ ž   $ƒ@ ž   $ƒL ž   $ˆÿ ž   $‰ ž   $Ž@ ž   $Žj ž   $•r ž   $•Î ž   $Ò ž   $Òº ž   $áÇ ž   $áê ž   $â ž   $â¢ ž   $çÙ ž   $è! ž   %} ž   % ž   % Ÿ ž   % Ê ž   %!6 ž   %!c ž   %', ž   %'6 ž   %- ž   %- ž   %A6 ž   %Ag ž   %Lå ž


----------



## Tod (Feb 27, 2011)

Well I thought this was going to be easy but I'm finding it hard to access the EQ Gain-ahdsr(Intensity Slider). I've been looking through the Script Manual and basically found what I need but so far I can't get even thier simplest examples to work. 

For example, I loaded a New Instrument that has one group and added a filter in the first slot of the Group-FX. Then I added the ahdsr to the cutoff frequency, just like they show in the manual. Can any of you see whats wrong with this code, it's not working.


on init
declare ui_knob $Mod (0,1000000,1000000)
end on
on ui_control ($Mod)
_set_engine_par($ENGINE_PAR_INTMOD_INTENSITY,$Mod,0,0,1)
end on

If I can't even get this to work then I'm not sure how to proceed. :? :oops:


----------



## EvilDragon (Feb 27, 2011)

Try:

on init
declare ui_knob $Mod (0,1000000,1)
end on


However, dealing with modulators is VERY hard in K2 - because IIRC the find_mod and find_target commands were introduced in K3 - and they make dealing with modulators much easier (although still complicated). In K2 it's basically guesswork which modulator ID is declared for which modulator. Very, very hard.


I'd cajole your client into using K4. :lol:


----------



## Big Bob (Feb 27, 2011)

> If I can't even get this to work then I'm not sure how to proceed.



Whoops! I'm sorry if I led you into this Tod. When I suggested twiddling the Intensity slider I meant manually not under script control. I just meant it might be needed to get things set up so that the EQ would be effected by the desired amount when the envelope was at its peak and valley respectfully.

And what Mario says about controlling modulators via eps is quite true (especially in K2). So before you get involved in it, let's be sure you need to. Why does your K2 script need to control the Intensity slider?

And Mario, doesn't the 3rd parameter only affect the way the knob value is *displayed*? I don't think it affects the internal *value* given to the script at all does it?

Rejoice,

Bob


----------



## EvilDragon (Feb 27, 2011)

True that, Bob. I'm just used to using (0,1000000,1) for pretty much all ui_knobs. :lol:


----------



## Big Bob (Feb 27, 2011)

> For example, I loaded a New Instrument that has one group and added a filter in the first slot of the Group-FX. Then I added the ahdsr to the cutoff frequency, just like they show in the manual. Can any of you see whats wrong with this code, it's not working.
> 
> 
> on init
> ...



BTW Tod,

I probably shouldn't have just sidestepped your question about the above code. I think what you need to change is the group, slot, generic parameter string from 0,0,1 to 0,1,0.

Since you said you loaded a new default instrument I believe it will already have an AHDSR assigned as a modulator so its Intensity slider would be addressed as 0,0,0. I don't think I want to try to explain NI's somewhat convoluted indexing scheme (or even if I can :? ), but, if you just have to have your script control your AHDSR Intensity slider, try changing the parameters to 0,1,0. If that works, just enjoy it. :lol: 

Rejoice,

Bob


----------



## Tod (Feb 27, 2011)

> Try:
> 
> on init
> declare ui_knob $Mod (0,1000000,1)
> ...



Thanks ED, but that didn't work either although it might be better once I get it going. I'm assumeing 0% on the Slider will probably be 500000. I had no problem getting the EQ Gain to work but you might be right about a modulator. 



> I'd cajole your client into using K4.



I'd love to and wish he could but he simply can't afford it right now. As it is I used my 2nd K2 lisence to get it on his computer because I'm the one doing all the programing and I use Kontakt for almost everything. I suppose I could put my 2nd K4 on there too but I'm hopeing to upgrade my own computer sometime in the not too distant future and might like to have it on both the old and new. Of course I could always take K4 off his computer if and when that time came but that's kind of like, heh heh, leaveing a friend up the river without a paddle.



> Whoops! I'm sorry if I led you into this Tod. When I suggested twiddling the Intensity slider I meant manually not under script control. I just meant it might be needed to get things set up so that the EQ would be effected by the desired amount when the envelope was at its peak and valley respectfully.
> 
> And what Mario says about controlling modulators via eps is quite true (especially in K2). So before you get involved in it, let's be sure you need to. Why does your K2 script need to control the Intensity slider?



Hey my friend you didn't lead me there, I was already headed in that direction. You confirmed what I allready kind of suspected but wasn't sure. Then with Dan's little nki program I think I now know exactly what's happening. 

It would be great if I could simply set the intensity to a certain value and leave it but it has to (should) coincide with the controllers for the Volume ahdsr envelope otherwise all the samples will be affected all the time because it's the intensity, not the Gain that's controlling the Gain (heh heh did all that make any sense). Also it would be great if the EQ amount went along with the scaled attack adjustments to make it a little more authentic and work better (sound better).

Thankyou guys, you've allready helped so much. Heh heh, keep thinking if you will, we might still get this solved yet. :D 

Tod


----------



## Big Bob (Feb 27, 2011)

Hey Tod,

Well, as long as you have to have script control of the slider, we just have to get it working for you and thats that :wink: . 

So, did you try what I suggested in the post prior to yours? Doing the 0,1,0 thing should work for the simple default instrument you described. Please let me know if it doesn't work for you. I'm a little puzzled that your last post didn't mention anything about 0,1,0 thing. :roll: 

Rejoice,

Bob


----------



## Big Bob (Feb 28, 2011)

Hi Tod,

Glad to hear that the 0,1,0 thing worked for your simple instrument. At least that should allow you to experiment with Intensity settings and such.

But, as far as trying to figure out what indices to use for your complete instrument, I'm afraid I won't be able to help you much with that. What Dan posted pretty much describes the horrible situation.



> The groups might look identical, but part of the problem with the modulator assignments before K3 is that they often weren't identical. So making a slider that affected all the groups in the same way was a nightmare.



Nils, at least at one time, was our 'resident expert' on K2's modulator index assignment logic (or perhaps I should say illogic :lol: ). I personally used to try to figure it out with a lot of trial and error (and hair pulling, what little I have left :lol: ).



> One thing I've been thinking about, Mario mentioned "find_mod and find_target commands". Could I easily use these on my old computer that does have K4 to find the values I need for all this and would they be the same for K2?



You could certainly try this (using Marios suggested method) and, even if it didn't translate over to K2 one to one, it might get you close enough to greatly reduce the remaining trial and error process.

Maybe if Nils reads this post he can offer a more organized approach for K2 but I'm afraid that right now I'm at the 'Peter Principle' (at least I think that's what its called when one rises to ones own level of incompetence) :lol:

If you do decide to translate it from K4, it sounds like Mario is pretty much on top of the situation. 

But Rejoice, for this too shall pass.

Bob


----------



## Tod (Feb 28, 2011)

Thanyou guys, I can't tell you how much I appreciate all your help.

I'm starting to think that trying to do this in K2 might not be worth the effort. My friend will hopefully be able to upgrade to K4 sometime in the future and then it will be a mute issue. As it is the Steel is sounding good even with out the EQ so I think it's best to leave K2 as it is right now.

However, I've now got Nils latest script editor and I'd like to persue this with K4, I think adding this EQ will really polish it off. So my first question is: 

Can I expect the relationship between the EQ and ahdsr envelope to be the same in K4 as it is in K2 or might it be different? I will be testing this all out later but for now if anyone knows the answer to this it will save me some time.

Once I get into this I know I will probably have more questions. I haven't even cracked the K4 script manual yet but, heh heh, I'm about to.  

Thanks so much again guys. o=< 

Tod


----------



## Big Bob (Feb 28, 2011)

Hey Mario,

Since you are now probably our resident expert on K4 modulator stuff, I'll direct these questions to you. I'm sure that Tod will soon be wondering about these issues also so I'll jump in first. 

1. Where does one find the list of modulator names such as ENV_AHDSR to use with find_mod?

2. How does one use find_mod to get the index of a 2nd or 3rd ENV_AHDSR that might be assigned to the same group? Or, does find_mod only return the first such modulator assigned and we're still stuck with keeping track of the order of additional assignments?

Let's take for example Tod's simple default instrument with an EQ effect inserted in the first Group FX slot and an AHSDR modulator assigned to the EQ. 

using set_engine_par(ENGINE_PAR_INTMOD_INTENSITY,Mod,x,y,z)

We already know that the Intensity slider for the Amplifier's AHDSR modulator is addressed with x,y,z = 0,0,0 whereas the Intensity slider for the EQ's AHDSR modulator is addressed with 0,1,0. How does one use find_mod to get the index for the EQ's AHDSR modulator? Using find_mod(0,ENV_AHDSR) will of course return 0 for the Amp's AHDSR but how do we specify the EQ's AHDSR in the find_mod function? Or do we simply have to resort to saying that we know the EQ's AHDSR happened to be the 2nd AHDSR assigned and so we have to add +1 to the index returned by find_mod. If this is the case, I don't see that find_mod is all that helpful. But, then remember, I'm still coming up to speed and I'm probably not really understanding all this new K4 stuff too well yet :? 

Rejoice,

Bob


----------



## polypx (Feb 28, 2011)

Hi Bob,

"ENV_AHDSR" is just Kontakt's default name. You can see the names assigned to modulators, and change them, if you hold down the control key and you click on a modulator... WHILE THE SCRIPT EDITOR IS OPEN. (sorry, didn't mean to shout, but it only works if the editor is open) 

So if you have more than one envelope, it's best that it has a different name.

Maybe Mario will go into more detail...

cheers
Dan


----------



## EvilDragon (Feb 28, 2011)

When you have script editor Edit window opened (but you CAN have the Script editor hidden, it's important that Edit window is opened!), by right-clicking the modulator (NOT the modulation intensity strip!) you will get the modulator name. You use this name with find_mod(). You can also freely rename it (and in such way make distinction between two AHDSRs, for example). The caveat is that you need to do the renamings for _each group separately_, even if "Edit All Groups" is on!

When you right-click the modulator intensity strip, then you get the modulation target name, which you can also rename. You use this with find_target(). Oh, also, find_target() is only viable for internal modulators. For external modulators, you use -1 in the last argument of get/set_engine_par, I think.

Here's an example that I did in K4 to explain approaching modulators via KSP to Thonex!

http://www.mediafire.com/?v2xk0yf5i2a8eet


Cheers


----------



## Big Bob (Feb 28, 2011)

Thanks Dan and Mario,

I think that pretty well clears it up for me but I'll let you know if I get re-puzzled :lol: 

And, Mario, thanks for the .nki demo. I'll play with it later to see if I can glean something additional from it but I think you guys have already filled in the gaps.

Thanks o-[][]-o .

Rejoice,

Bob


----------



## Tod (Feb 28, 2011)

> When you have script editor Edit window opened (but you CAN have the Script editor hidden, it's important that Edit window is opened!), by right-clicking the modulator (NOT the modulation intensity strip!) you will get the modulator name. You use this name with find_mod(). You can also freely rename it (and in such way make distinction between two AHDSRs, for example). The caveat is that you need to do the renamings for each group separately, even if "Edit All Groups" is on!
> 
> When you right-click the modulator intensity strip, then you get the modulation target name, which you can also rename. You use this with find_target(). Oh, also, find_target() is only viable for internal modulators. For external modulators, you use -1 in the last argument of get/set_engine_par, I think.



Thanks Mario,

I can see the Name for the ahdsr and how to change it (even copy to clipboard, "cool") but when I right click on the intensity strip all I get is "Learn MIDI CC# Automation"?

Also the little script that worked in K2 to access the ahdsr intensity slider isn't working in K4. I loaded it exactly the same as I did for K2, "Files/New instrument" and then added the EQ in the GouprFX with the ahdsr as a modulator in the first slot.

on init 
declare ui_knob $Mod (0,1000000,1000000) 
end on 
on ui_control ($Mod) 
_set_engine_par($ENGINE_PAR_INTMOD_INTENSITY,$Mod,0,1,0) 
end on

Any ideas?


----------



## EvilDragon (Feb 28, 2011)

Oh, don't click the modulation intensity SLIDER. Click the green background of the modulation intensity strip 

In K4 things are very different. You'll need to play with find_mod() and find_target(). I'm assuming you're using 1-band EQ, right? In that case, here's the code. I have added an EQ to first group FX slot, then added envelope modulation to it. I have renamed the modulation intensity strip to "ENV_AHDSR_EQ_GAIN_1", and envelope modulator to "ENV_AHDSR_EQ". The code is as follows:

http://pastebin.com/raw.php?i=dBDHWEsa


----------



## Tod (Feb 28, 2011)

Thanks Mario,



> Oh, don't click the modulation intensity SLIDER. Click the green background of the modulation intensity strip



Okay, I misunderstood what you said above but got it now.  



> In K4 things are very different. You'll need to play with find_mod() and find_target(). I'm assuming you're using 1-band EQ, right? In that case, here's the code. I have added an EQ to first group FX slot, then added envelope modulation to it. I have renamed the modulation intensity strip to "ENV_AHDSR_EQ_GAIN_1", and envelope modulator to "ENV_AHDSR_EQ". The code is as follows:
> 
> http://pastebin.com/raw.php?i=dBDHWEsa



Thanks for the script, at this point in time I would never have figured that one out. However it's not working as it is, even though I went through and changed all the names to reflect the names in the nki (New instrument) that I have loaded. There were some minor differences.

It compiles fine in both the K4 script editor and Nils script editor. 

Any ideas? :?


----------



## EvilDragon (Feb 28, 2011)

It should work - you might've named modulator intensity slider and modulator itself in reverse... Let's try this NKI:

http://www.mediafire.com/?d9x8lnvccc5vv05

You're gonna need K4.1.3.



What are "minor differences" you're having, exactly?


----------



## Big Bob (Feb 28, 2011)

> Also the little script that worked in K2 to access the ahdsr intensity slider isn't working in K4. I loaded it exactly the same as I did for K2, "Files/New instrument" and then added the EQ in the GouprFX with the ahdsr as a modulator in the first slot.
> 
> on init
> declare ui_knob $Mod (0,1000000,1000000)
> ...



Hey Tod,

For what it's worth, if you are talking about your simple default instrument that we got working in K2 with the 0,1,0 - I loaded that very same instrument into K4 and it still worked OK with 0,1,0. Perhaps you redid the instrument and did something slightly different? Or, I tried it with K4.2 and maybe you are using some earlier version of K4 and something changed?

If you still have the original test instrument, ie the .nki with the script using 0,1,0 that works in K2, can you just load that instrument into K4 and see if it works (rather than recreating the instrument).

In any case I leave you in very capable hands with Mario and Dan, now that you are exploring K4. These guys are more on top of it than I am because I'm still playing catch up with all the new K4 goodies (but I'm getting there).

Rejoice,

Bob


----------



## Tod (Feb 28, 2011)

> You're gonna need K4.1.3.



Aahh, that's probably it. I've got it but haven't updated it yet. That's the next step and doing it now.  



> What are "minor differences" you're having, exactly?



Instead of "ENV_AHDSR_EQ_GAIN_1" it was "ENV_AHDSR_EQ_FREQ_1". Don't know why, I clearly have it on the Gain.

Instead of "ENV_AHDSR_EQ" it was just "ENV_AHDSR".

Thanks Mario.


----------



## EvilDragon (Feb 28, 2011)

Tod @ 1.3.2011 said:


> Instead of "ENV_AHDSR_EQ_GAIN_1" it was "ENV_AHDSR_EQ_FREQ_1". Don't know why, I clearly have it on the Gain.



When you change the modulation destination, Kontakt DOES NOT automatically rename the modulator name. You have to do it manually.


Stupid, I know. Kontakt has a LOT of illogical behavior bugs like that, I got to know them pretty well. :roll:



Oh, and BTW, if you read my post with pastebin link, you'll clearly see that I mentioned that I renamed both the modulator and modulation intensity slider beforehand!


----------



## Tod (Feb 28, 2011)

> If you still have the original test instrument, ie the .nki with the script using 0,1,0 that works in K2, can you just load that instrument into K4 and see if it works (rather than recreating the instrument).



I just updated to 4.1.3 a minute ago. I'll check out just loading the instrument, good ideal.  



> In any case I leave you in very capable hands with Mario and Dan, now that you are exploring K4. These guys are more on top of it than I am because I'm still playing catch up with all the new K4 goodies (but I'm getting there).



Well I'm about 10 miles behind you but, heh heh, I got a rope tied to your bumper.


----------



## Big Bob (Feb 28, 2011)

Hey Mario,
 
I just got done playing with the .nki you made for Andrew and nothing unexpected popped up so I thought I had it down pat. However, I decided just for fun I would try one more thing.

So, I took the simple Instrument that Dan posted for Tod and I added this script.

*on init*
``*declare* ui_knob Mod(0, 1000000, 1) 
*end on*

*on ui_control*(Mod)
``set_engine_par(ENGINE_PAR_INTMOD_INTENSITY,Mod,0,find_mod(0,"VEL"), ...
`````````find_target(0,find_mod(0,"VEL"),"VEL_VOLUME"))
*end on*

I was expecting the Mod knob to now control the velocity Intensity slider but it doesn't. Interestingly, K4 reports that it can't find VEL_VOLUME yet that's the name they give to the velocity modulator's slider. I assumed, since they named it that, the modulator itself must be named VEL (even though of course such an animal is not visible).

So, what is the falacy in my thinking here? Maybe I still don't understand this stuff after all :? 

Rejoice,

Bob


----------



## Big Bob (Feb 28, 2011)

Pardon my dumb dumb and forget the last post. I think I figured it out. Velocity itself would be considered an external modulator wouldn't it?

:oops:


----------



## polypx (Feb 28, 2011)

Yep. 

Try this one:

on init
declare ui_knob $Mod(0, 1000000, 1)
end on

on ui_control($Mod)
set_engine_par($ENGINE_PAR_MOD_TARGET_INTENSITY,$Mod,0,find_mod(0,"VEL_VOLUME"), -1)
end on


EDIT

And to find the mod target for the EQ gain:

```
on init
declare ui_knob $Mod(0, 1000000, 1)
end on

on ui_control($Mod)
set_engine_par($ENGINE_PAR_INTMOD_INTENSITY,$Mod,0,find_mod(0,"ENV_AHDSR"),...
 find_target(0,find_mod(0,"ENV_AHDSR"),"ENV_AHDSR_EQ_GAIN_3"))
end on
```


----------



## Big Bob (Feb 28, 2011)

Thanks Dan, I guess I did understand it after all, I just didn't think about the fact that velocity originates outside. Instead I just thought about it as being some kind of 'invisible' modulator with the name VEL. Dumb, dumb, I know :oops: 

BTW I forgot to change ENGINE_PAR_INTMOD_INTENSITY to ENGINE_PAR_MOD_TARGET_INTENSITY when I first tried the change and interestingly enough it works with INTMOD as well as MOD_TARGET. :? 

But I shall Rejoice,

Bob

EDIT: Whoops, I just saw you had appended something. Will that actually work without first renaming the 1ST ENV_AHSDR so the 2nd one will have a unique name? I'll have to try this out and get back to you.


----------



## polypx (Feb 28, 2011)

> BTW I forgot to change ENGINE_PAR_INTMOD_INTENSITY to ENGINE_PAR_MOD_TARGET_INTENSITY when I first tried the change and interestingly enough it works with INTMOD as well as MOD_TARGET.



That's interesting.

If I switch between them for an internal modulator (ie. my EG to EQ gain) both work... but! --- INTMOD is a bipolar control, and MOD_TARGET is unipolar.

And here I was thinking I knew what was going on. 

cheers
Dan


EDIT



> EDIT: Whoops, I just saw you had appended something. Will that actually work without first renaming the 1ST ENV_AHSDR so the 2nd one will have a unique name? I'll have to try this out and get back to you.



Ah yes you're right, it CAN get confused, in which case it does nothing. Better to name the second EG "AHDSR2" or something.


----------



## polypx (Feb 28, 2011)

On a slight tangent Bob, you may want to watch out for modulators or targets that you've named changing themselves back to a default name upon the addition or deletion of other modulators.

I think Mario's probably gone to bed now, but we've discussed this bug before.

I haven't noticed it happen in 4.2 yet, and can't make it happen now, so I'm hoping it has been fixed. Maybe Mario can confirm with his own experience later.


----------



## Big Bob (Feb 28, 2011)

Yes, I think when there is more than one modulator with the same name, the first one defined is the index always returned by find_mod. In any case simply changing at least one of the names seems to work OK.

I didn't even pick up on the fact that using INTMOD resulted in bi-polar and MOD_TARGET unipolar operation, kudos. So, all my bumbling around led us to something that may possibly be useful, no? :idea: 

Thanks again Dan for all your help. I'm sure when Mario wakes up he'll be surprised at all the further activity on Tod's battered thread :lol: 

Rejoice,

Bob

EDIT Oh phooey, I see you slipped in yet another post while I was posting the above. Maybe we better both retire for the day too. 

Yes, I think Mario has mentioned the renaming problem to me but I don't know whether he has retested for it with K4.2. Let's hope it is fixed, this stuff is tricky enough without 'gotcha' problems in addition :roll:


----------



## polypx (Feb 28, 2011)

> I didn't even pick up on the fact that using INTMOD resulted in bi-polar and MOD_TARGET unipolar operation, kudos. So, all my bumbling around led us to something that may possibly be useful, no?



Yes, this is really interesting.

I have a lò ¥   Nc ¥   Nd ¥   Ne ¥   Nf ¥   Ng ¥    = ¥    =‘ ¥    =’ ¥    =“ ¥    =” ¥    =• ¥    ´. ¥   ,¼ ¥   ,½ ¥   ,¾ ¥   ,¿ ¥   ,À ¥   ,Á ¥   ,Â ¥   ,Ã ¥   ã ¥   ãN ¥   òe ¥   òØ ¥   2  ¥   2Ê ¥   }ß ¥   ~E ¥


----------



## polypx (Mar 1, 2011)

Tod,

You can use the same name in different groups. ie. Grp_EQ_Gain. Since the modulation control (engine parameter) has a group designation in the call to it, you don't need to name the same function in each group differently.

However, if you use two envelopes WITHIN a single group, name these differently.

cheers
Dan


----------



## Tod (Mar 1, 2011)

> You can use the same name in different groups. ie. Grp_EQ_Gain. Since the modulation control (engine parameter) has a group designation in the call to it, you don't need to name the same function in each group differently.



Aahh, thanks Dan, that's good to know. How about string vaiables like @EQname, or just @EQ?


----------



## EvilDragon (Mar 1, 2011)

Keep the names consistent for all groups. This is because when using find_mod() and find_target(), the first parameter is group index. So, if you want to set up the modulation intensity slider to work in tandem for all 5 groups, you need both the modulators and modulations intensity sliders to be names exactly the same, so you can sweep them all in a while loop.


----------



## Tod (Mar 1, 2011)

> so you can sweep them all in a while loop.


 
Good point Mario, thanks. Any ideas on my Reaper issue with K4 as a VSTi.


----------



## Tod (Mar 1, 2011)

> Dunno, I can't replicate that issue. Works here.



Huumm, that's strange. I wonder if it could be something in "Preferences"?



> I always develop my scripts in standalone mode, though!



I really need to do this in a DAW because I've got to send it exact midi info in order to get the correct numbers, especially for the EQ. I also need the metering the DAW provides. I could do it in Sonar but I've got Reaper setup so well for this, I hate to do it that way.

I've "Maple midi ports" and maybe I could set K4 up in standalone mode to use with Reaper. Heh heh, I'm not sure, I've never done that before except in Sonar.


----------



## EvilDragon (Mar 1, 2011)

Tod @ 1.3.2011 said:


> Huumm, that's strange. I wonder if it could be something in "Preferences"?



I doubt it. Nothing in Preferences is related to scripting.



Tod @ 1.3.2011 said:


> I really need to do this in a DAW because I've got to send it exact midi info in order to get the correct numbers, especially for the EQ.



Elaborate, please.


----------



## Tod (Mar 1, 2011)

> Elaborate, please.



OK, heh heh, this is the way I go about this and there might be a better way. :?  

Assumeing I have a nki setup with the EQ + ahdsr envelope on the Gain and have my 3khrz sample loaded.

1st> I've got a 3K sample set up just for this. It could just as easily be 4K or 5K, I could use any one of them to get correct readings from the intesity slider as long as I've got the EQ Frequency setup to match.

2nd> I add a midi track and put in a midi note to match the position that I've loaded the sample into Kontakt's Mapping Editor. I usually put this with a velocity of 127, the important thing is to set it and leave it. At this point I won't add any controllers because I think it's easier to make manual adjustments to get everything calibrated.

3rd> I'll play the note (with ZERO Gain on the EQ) and adjust K4's main volume output so that I get a -24.5db reading on the DAW meters. Why -24.5db? Because I've already determined that the ahdsr adds 12db to the EQ Gain when the intensity slider is at 100%. I've also determined that there is a 2 to 1 ratio between the EQ Gain and vu-output on the DAW meters. In other words the vu-meter adds 24db when the Gain is set at +12db vrs 0db. So the -24.5db is to give me .5db headroom.

4th> Since there are always upper and lower boundries in Kontakt's actual #s for any exact db reading, I personally like to try get the exact center # and I've got a small simple script I made that I can quickly and easily do this. The important thing for me is that I end up with numbers that I believe are correct and can have confidence in.

Whew, heh heh, that's pretty much it. I'm sure all this can easily be done mathematically, especially if Kontakts numbers are linear, but I never know if they are??? :oops:


----------



## EvilDragon (Mar 1, 2011)

Nope, most Kontakt parameters are, in fact, not 100% linear. :lol:


----------



## Tod (Mar 3, 2011)

Hi all,

Well I finally got some numbers to go along with the EQ-ahdsr Slider. They're definitely not linear, more likely analogous. I think the numbers are fairly accurate allthough I don't know for sure how accurate the balistics of the VU meters are. However, after all the testing I've done I feel pretty confident with these numbers.

what I ultimately want to do is add a menu to the script to select the maximum amount of EQ-Gain to use on the attack, from 0db to +6db in 1db increments. Keep in mind that +6db of EQ-Gain equates to +12db vu. So I need to break down the menu selection into an analog output based on 127 divisions or there-a-bouts.

So can any of you math gurus glean anything from these numbers and possibly give me a formula. Heh heh, Big Bob? :mrgreen: 


```
Kontakt     Slider       Vu
Numbers      (%)       Value
_______    ______   ________
500000.......0.0%     -12.0db
675063.......4.3%     -11.0db
719885.......8.5%     -10.0db
751020.......12.7%     -9.0db
775689.......16.8%     -8.0db
796495.......20.9%     -7.0db
814717.......24.9%     -6.0db
831077.......29.0%     -5.0db
846039.......33.1%     -4.0db
859908.......37.3%     -3.0db
872905.......41.5%     -2.0db
885191.......45.7%     -1.0db
896888.......50.0%     -0.0db
```


----------



## EvilDragon (Mar 3, 2011)

Hmmm...

http://img705.imageshack.us/img705/8834/curveg.png


----------



## Big Bob (Mar 3, 2011)

Hi Tod,

I'm really not sure what you want to convert from and to :? . The first column says Kontakt numbers which look like engine parms (ep) but what are they the eps for?

The 2nd column looks like Intensity slider amounts displayed by Kontakt, is that right? And the 3rd column is db of analog output?

Could you describe better what you want to convert to what? Are you looking for a pair of formulae? 

1. To convert from db of output to ep (the first column)
2. To convert from db of output to slider percent

When you say 127 steps or so, do you mean that the output level from 0 to 12 db will only have a resolution of 12/127 db per step?

I'm afraid you need to spell this all out more clearly for me to understand exactly what you want. Preferably without me having to understand what you intend to do with it :lol: 

Rejoice,

Bob

EDIT: Oh I see Mario slipped in a post while I was typing the above. Looks like the curve relating your column 1 and column 2 maybe?


----------



## EvilDragon (Mar 3, 2011)

Yep, it's exactly that - vertically, engine parameters, horizontally, modulator intensity percentages. They're correlated.


----------



## Tod (Mar 3, 2011)

Thanks Bob and Mario. I'm sorry for not giving you enough info, I was pretty tired when I posted. I'll give you more in the morning when I can think a little clearer. :? 

Mario, how did you come up with that graph, it looks like it might go along somewhat with my numbers? Or heh heh, is that what it is?  

It's hard to know exactly how the percentages fall because of the wide swing for each (.1%) but for the most part I think they reflect a pretty good linear tendency.

Anyway, I'll get back to you in the morning and thanks a lot guys. o-[][]-o 

Tod


----------



## EvilDragon (Mar 4, 2011)

Tod @ 4.3.2011 said:


> Mario, how did you come up with that graph, it looks like it might go along somewhat with my numbers? Or heh heh, is that what it is?



Microsoft Excel.


----------



## Tod (Mar 4, 2011)

Okay guys, I'll try to explain the best I can.

Like I mentioned above, I want to add a menu where I can choose the maximum level for the EQ. The choices in the menu will be from 0db to 6db in 1db increments. In other words ( 0.0db Maximum)( 1.0db Maximum)( 2.0db Maximum) etc. up to (6.0db Maximum).

Once the maximum EQ level has selected in the menu, I then plan on useing a "while" loop to fill an array. I mentioned 127 but I will more likely use an array with 122 elements because I want to use cc 1 to 5 to effectively turn the EQ off.

I could easily take the maximum number, subtract 500000, and divide that by 122 but that obviously doesn't reflect the actual numbers of the intensity slider very well. 


```
$AddCnt = ($MaxEQ - 500000) / 122
    $CurrentCnt = 500000
    $Cnt1 = 0

while ($Cnt1 < 122)
    $CurrentCnt = $CurrentCnt + $AddCnt
    %Array[$Cnt1] = $CurrentCnt
    inc($Cnt1)
end while
```

As I said, this linear approach doesn't reflect the actual numbers well at all, so I was wondering if you guys have a better way to deal with it. I did use your math library on a few of my scripts back 3 to 4 years ago Bob, but my old brain can't recall what I did. I also looked over your manuals for the library yesterday but heh heh, all I got was overwhelmed. 

Anyway, I hope this gives you guys a better idea of what I'm trying to do. :( :?  

Tod


----------



## Big Bob (Mar 4, 2011)

HI Tod,

Maybe I misunderstood your prior post with the 3 columns of data. I thought you wanted to sort of fill in the gaps with a smooth function that could be mathematically expressed so that you could convert from one set of parameters to a different one. For example to take ep value (1st column), plug it into a function and obtain the corresponding values from the 2nd and/or 3rd column.

Of course I don't know which direction you want to do the conversion (ie what will your input to the function or functions be and what outputs do you need). For example, again referring to your 3 tables, you might want to input a value from column 3 and get outputs for columns 1 & 2.

Then again, maybe the 3 columns you posted interelations for aren't what you are trying to convert between. I'm afraid you are not expressing what you want very clearly. If you want some special conversion functions, I need to know what you want to convert to what.

If I name your 3 columns of data: ep, intensity_percent, and eq_gain respectively (even though these names may not be entirely accurate), I need you to say for example:

I want a function named ep_to_intensity_percent(ep,intensity) such that I can call it with an ep value and it will return an intensity value, etc etc.

I'm sorry that so far, it's not clear precisely what you need along these lines.

Rejoice,

Bob


----------



## Big Bob (Mar 4, 2011)

Hi Tod,

I think what you need is a function that computes the ep (column 1) for any given column 3 value. For example, let's name such a function vu_to_ep(vu,ep). Let's also assume that a reasonable unit for VU might be mdb.

Now, for a max vu of -4db for example, (since the min vu is always -12db), you now want to populate an array of 122 elements with the ep values that *correspond* with the range of VUs from -400 mdb to -12000 mdb.

Once you have the vu_to_ep function you could use a code fragment something like this:


```
cnt := 0
while cnt < 122
  vu := -12000 + (Vmax + 12000)*cnt/121
  vu_to_ep(vu,ep)
  epa[cnt] := ep
  inc(cnt)
end while
```

Notice that when cnt = 0, vu = -12000 (it's in mdb remember) and the function will return 500000 for ep. When cnt = 121, vu = Vmax, which for our example would be -4000 mbd and so the function will return 846039. And, of course, because the function provides all the 'in-between' values as well, the epa array is filled with the desired values.

To populate the epa array when the max vu is some other value, for example -6db, all you have to do is load Vmax with -6000 before entering the while loop.

Ponder the above :roll: and if you agree that this is what you need, I'll see if I can whip up a vu_to_ep function that will accurately track the data you have provided in columns 1 and 3. 

Rejoice my friend, this too shall pass.

Bob


----------



## Tod (Mar 5, 2011)

Hi Bob, 



> I think what you need is a function that computes the ep (column 1) for any given column 3 value. For example, let's name such a function vu_to_ep(vu,ep). Let's also assume that a reasonable unit for VU might be mdb.



Do you mean dbm? I vaguely remember back in old days things like dbm, dbu, dbv. Or is this just an arbitrary name.



> Now, for a max vu of -4db for example, (since the min vu is always -12db), you now want to populate an array of 122 elements with the ep values that correspond with the range of VUs from -400 mdb to -12000 mdb.



Heh heh, I'm sorry but I'm already getting confused :oops: and I think the way I presented the table above may have been totally misleading. The "vu" readings were meant to only show how I derived the ep numbers. So let's just forget the vu because it's meaningless now.

Basically we're only concerned with 2 numbers because they are the only knowns, the amount of "eq_gain" and the "ep" number associated with it.

The reason we know the eq_gain is because I'm associating it with the actual Gain knob of the EQ. For instance, the Maximum EQ menu will look something like this.


```
Maximum   
   EQ         
_________ 
 0.0db Max
+1.0db Max
+2.0db Max
+3.0db Max
+4.0db Max
+5.0db Max
+6.0db Max
```

So the equivalent of a "+2.0db Max" is the same as if we turned the EQ-Gain knob up to +2.0db.

Now if we were to add the ep number to the menu it would look something like this.


```
Maximum          ep
   EQ             #
_________       ______
 0.0db Max......500000
+1.0db Max......719885
+2.0db Max......775689
+3.0db Max......814717
+4.0db Max......846039
+5.0db Max......872905
+6.0db Max......896888
```

So now for example lets pick a +3.0db Max which has an equivalent ep# of 814717. Further I want to divide the +3db up into 122 elements to go along with my controller "%CC[$CC_NUM]", or to be more specific I want to divide the difference between (814717 - 500000) up into 122 elements. 

To do this linearly (in a linear sequence) is very simple as I illustrated in the "while" loop I showed in my previous post and if push comes to shove, that will probably work. However, being the perfectionist that I am :oops: , I would rather have the 122 elements divided up in an analogous sequence. To futher explain let me say this:

In my script I already have a $CC_NUM for each group to control the Amplifier volume and the Sustain of the ahdsr which is a Modulator on the Volume. By controlling the Sustain and Volume in equal inverted amounts I can add attack without changeing the overall level of the notes or samples. In other words by lowering the Sustain (-3db) and raiseing the Volume (+3db) the overall level of the note stays the same but adds +3db to the attack. This works very well, so now to make it even better and more authentic I would like to add a little EQ on the higher end. Also I will be useing the same $CC_NUM for the EQ. As the attack of the note goes up I also want the EQ to rise too, however I would like it to be in an analogous manner with the maximum EQ based on the menu selection.

I should also add, don't confuse the attack I mention above with the Attack of the ahdsr, the Attack of the ahdsr will always be "0ms".

Thanks for sticking with me my friend, if I had your smarts I could explain this much better but then if I had your smarts I probably wouldn't need your help. :D 

Tod


----------



## Tod (Mar 5, 2011)

Heh heh, thanks Bob, you're getting real technical on me and going over my head but that's OK, I'm going to learn something here. I've allready put an intense effert into understanding what your saying here but I need to examine it closer. I'll get back to you tomarrow and hopefully have some good answers for you. :D 

Tod


----------



## Big Bob (Mar 5, 2011)

HI Tod, 

Fair enough. I'll wait for you think about this a bit.

However, maybe this will help. As you are 'walking through' your ep array to retrieve values (as you move a CC or whatever), is not each successive element of the array that you fetch supposed to cause an equal change in db?

I think the reason you want the ep values to not step an equal amount per array element because you actually want equal steps in the db control. To get a linear db control, the ep control must be non-linear.

Let's say for example that you are indexing into your array by moving a CC. What do you want to happen to the db boost for the EQ gain as you move the CC? Don't you want it to track the CC?

For example, with a drop-down setting of +2db (min VU will be -12db and max will be -8db, a total swing range of 4db) right? With the CC at 0 (and ostensibly your VU meter at -12db), when you move the CC to max, I presume you want the VU meter to reach -8db. Now where do you want the VU meter to be when the CC is half way? If I understood what you have said, aren't you wanting a 50% CC position to correspond to a VU output of -8db (half the 4 db swing from -12 db to the max of -8db)?

Unfortunately, the above again presumes I have correctly understood how your drop-down setting relates to the VU meter range. For example, if you choose 0 db with the drop down, doesn't the VU meter stay at -12db as you move the CC to 'walk thru' the array?

I think part of the reason this has been so confusing is that you are ultimately interested in controlling EQ gain, but, you presented your 3 column table in terms of VU meter readings instead. Why don't we add a 4th column to your 3-column table. The values for each line can be calculated by adding 12 db to each value in column 3 and then dividing by 2. The 4th column will then run from 0 to +6db in 0.5db steps. Now if you add this 4th column, for any given drop-down menu selection, lets try +4db for example, the ep values in the array are to range from 500000 to 846039, is this not true? If so, please note that 846039 is the ep value on the same line as +4db in column 4.

If none of the above (or in my last post) makes any sense to you then I have probably totally misunderstood what kind of function you wanted me to whip up for you. :roll: 

Rejoice,

Bob

BTW I'll probably be pretty busy tomorrow with church activities, etc so I may not be able to respond until Monday. You have a great weekend my friend.


----------



## Tod (Mar 6, 2011)

> As you are 'walking through' your ep array to retrieve values (as you move a CC or whatever), is not each successive element of the array that you fetch supposed to cause an equal change in db?



Yes I think that's exactly what I've been trying to say.



> I think the reason you want the ep values to not step an equal amount per array element because you actually want equal steps in the db control. To get a linear db control, the ep control must be non-linear.



Right, if you look at the ep#s for each db as they advance from top to bottom, you can easily see how the difference between the ep#s gets smaller and smaller.



> Let's say for example that you are indexing into your array by moving a CC. What do you want to happen to the db boost for the EQ gain as you move the CC? Don't you want it to track the CC? For example, with a drop-down setting of +2db (min VU will be -12db and max will be -8db, a total swing range of 4db) right? With the CC at 0 (and ostensibly your VU meter at -12db), when you move the CC to max, I presume you want the VU meter to reach -8db.



Exactly right.



> Now where do you want the VU meter to be when the CC is half way? If I understood what you have said, aren't you wanting a 50% CC position to correspond to a VU output of -8db (half the 4 db swing from -12 db to the max of -8db)?



When you say "50% CC position to correspond to a VU output of -8db", don't you mean -10db? But yes, I think that would be right. I think it's quite possible that the CC could relate to the ep#s and vu-readings in a similar way that the (%) does. 



> Unfortunately, the above again presumes I have correctly understood how your drop-down setting relates to the VU meter range. For example, if you choose 0 db with the drop down, doesn't the VU meter stay at -12db as you move the CC to 'walk thru' the array?



Right, if 0.0db is selected, that actually turns the EQ off.



> I think part of the reason this has been so confusing is that you are ultimately interested in controlling EQ gain, but, you presented your 3 column table in terms of VU meter readings instead.



Yes, and the reason I did it that way was because it was the only reasonable way I could get any meaningful measuremets from the intensity slider.



> Why don't we add a 4th column to your 3-column table. The values for each line can be calculated by adding 12 db to each value in column 3 and then dividing by 2. The 4th column will then run from 0 to +6db in 0.5db steps. Now if you add this 4th column, for any given drop-down menu selection, lets try +4db for example, the ep values in the array are to range from 500000 to 846039, is this not true? If so, please note that 846039 is the ep value on the same line as +4db in column 4.



Good, if that makes it easier to relate to then by all means. Of course that would only correspond to the even numbers but that's okay, they're the ones we're intrested in anyway.

Thanks Bob, I think we're getting closer. :D 

Tod


----------



## Big Bob (Mar 6, 2011)

Hi Tod,



> When you say "50% CC position to correspond to a VU output of -8db", don't you mean -10db? But yes, I think that would be right. I think it's quite possible that the CC could relate to the ep#s and vu-readings in a similar way that the (%) does.



OOps, my bad. You're right it should be -10db, I made a typo :oops: 



> Good, if that makes it easier to relate to then by all means. Of course that would only correspond to the even numbers but that's okay, they're the ones we're intrested in anyway.



Well I just thought it might make it easier for us to communicate back and forth until we get on the same page. But, since you now seem to be agreeing with what I'm saying, adding a 4th column to your table may not be necessary. o-[][]-o 



> Thanks Bob, I think we're getting closer.



I think it will be all 'downhill' after this 8) 

Actually, the example script I posted a few posts back really was right on but you just didn't recognize it :lol: .

Here's all that remains to be done:

1. I need to create a function (named something like *EQgain_to_ep*) that fits the data you supplied in columns 1 & 3 (or possibly 1 and 4 would be better considering how I think you intend to use it).

2. I'll then write a sample enclosing function (named something like *FillArray*, using *EQgain_to_ep* to populate your 122 element array.

3. I'll post the above for you and then we can wrestle back and forth until it works like you want it to. :lol: 

So, one last question. When your script gets to the place where it needs to populate the array, you will invoke *FillArray(in,out)*, where *in* and *out* are your two parameters. Shall I presume that your input parameter will be an integer constant or variable, having a value from 0 to 6 (which represents the maximum EQ gain)? Shall I also presume that the output parameter will be the name of an array that you have declared and dimensioned with 122 elements? 

I'll start working on the *EQgain_to_ep *function as soon as I can get an uninterrupted block of time. Then as soon as you respond to the prior pair of questions, I'll be able to write the enclosing *FillArray* function. That part will be fairly trivial. The *EQgain_to_ep *function may be easy or it may be hard, I haven't taken any time yet to examine the relationship since I wanted to be sure I understood what you wanted first. Now, the fun starts :roll: 

Rejoice,

Bob


----------



## Tod (Mar 7, 2011)

> Actually, the example script I posted a few posts back really was right on but you just didn't recognize it.



Your right, I did look at it pretty close but couldn't get the connection. :oops: I wasn't sure what "Vmax" stood for and at the end of the formula you have "cnt/121". Won't "cnt/121" always be zero until cnt=121 because Kontakt doesn't deal with fractions?



> 1. I need to create a function (named something like EQgain_to_ep) that fits the data you supplied in columns 1 & 3 (or possibly 1 and 4 would be better considering how I think you intend to use it).



"EQgain_to_ep" sounds like a good name to me.



> 2. I'll then write a sample enclosing function (named something like FillArray, using EQgain_to_ep to populate your 122 element array.



Of course at this point I don't know what you have in mind but I'm anxious to see where your going with all this.



> 3. I'll post the above for you and then we can wrestle back and forth until it works like you want it to.



Sounds good.



> So, one last question. When your script gets to the place where it needs to populate the array, you will invoke FillArray(in,out), where in and out are your two parameters. Shall I presume that your input parameter will be an integer constant or variable, having a value from 0 to 6 (which represents the maximum EQ gain)? Shall I also presume that the output parameter will be the name of an array that you have declared and dimensioned with 122 elements?



It's hard for me to give you any answers here untill I have a better idea of what you have in mind. There are basically 3 knowns: 

1> Maximum Menu #s (0 thru 6), ($MaxEQMenu)
2> An array of the ep#s that goes along with the $MaxEQMenu. (%Max_EQ_ary[7])
3> Possibly a vu_db amount associated with the ep#s. This could be designated in what ever manner you think works best. (%vu_db_ary[7])

Incidently, I just thew those names out there Bob, but I want you to use whatever names work best for you.



> The EQgain_to_ep function may be easy or it may be hard, I haven't taken any time yet to examine the relationship since I wanted to be sure I understood what you wanted first. Now, the fun starts



I'm excited to see what you've got in mind and I'm ready to help in any way I can. :D 

Tod


----------



## Big Bob (Mar 7, 2011)

Hi Tod,



> Your right, I did look at it pretty close but couldn't get the connection. I wasn't sure what "Vmax" stood for ...




```
cnt := 0 
while cnt < 122 
  vu := -12000 + (Vmax + 12000)*cnt/121 
  vu_to_ep(vu,ep) 
  epa[cnt] := ep 
  inc(cnt) 
end while
```

Let me first say that understanding the above code fragment is no longer too important since I now know what you need (or at least I think I do). However, just in case you want to study it for fun, I'll explain what Vmax was intended to be in the above code. Again, this is going to be somewhat confusing because I expressed it in terms of your 3rd, VU column rather than in terms of your drop-down index. If we name your drop-down index value, *eqm*, (the max EQ gain setting which ranges from 0..6 and is ostensibly in units of db), then Vmax in the above code fragment is given by:

Vmax = (2*eqm - 12)*1000 { expressed in mdb }

If I rewrite the code fragment in terms of eqm, it would look like this:

```
cnt := 0 
while cnt < 122 
  vu := -12000 +2000*eqm*cnt/121 
  vu_to_ep(vu,ep) 
  epa[cnt] := ep 
  inc(cnt) 
end while
```
Better yet, it will be cleaner if we don't involve *vu* at all and just create a function that converts from the desired EQgain to ep. And, to get some finer resolution we will want to express gains in mdb instead of db. So let's call the desired EQgain, *eqg*. And, lets call the maximum eq gain, *EQmax* and also express it in mdb. Then we could rewrite the above code fragment more like it will be eventually when I give it to you.

```
cnt := 0 
while cnt < 122 
  eqg := EQmax*cnt/121
  EQgain_to_ep(eqg,ep) 
  epa[cnt] := ep 
  inc(cnt) 
end while
```

Now note that the while loop swings the value of eqg from 0 to EQmax as it populates the epa array with the corresponding ep values. Incidentally, what do you actually use these eps to control, the intensity slider of the envelope modulator?



> ... and at the end of the formula you have "cnt/121". Won't "cnt/121" always be zero until cnt=121 because Kontakt doesn't deal with fractions?



It would be if we didn't *first* multiply by (Vmax + 12000) in the original post or by *EQmax* in the last variant above. 



> It's hard for me to give you any answers here untill I have a better idea of what you have in mind. There are basically 3 knowns:
> 
> 1> Maximum Menu #s (0 thru 6), ($MaxEQMenu)
> 2> An array of the ep#s that goes along with the $MaxEQMenu. (%Max_EQ_ary[7])
> 3> Possibly a vu_db amount associated with the ep#s. This could be designated in what ever manner you think works best. (%vu_db_ary[7])



This comment is a bit of a head scratcher :roll: I understand the 1st 'known' because its the drop_down index I have been calling EQmax (actually my EQmax is 1000 times your $MaxEQMenu values of 0 to 6).

However, you say your 2nd 'known' is a 7 element array of eps???? I thought you want to fill possibly 7 different arrays, each containing 122 eps. The way you're saying it above sounds like you want also (or instead of) to have a 7 element array that only contains the max ep value that corresponds with each MaxEQMenu index???

Your 'known' #3 is also puzzling :? While you may want such an array for some other purpose within you script, I don't see that it has anything to do with the process of populating your ep arrays (which I thought is what you wanted me to help you with). :roll: 

I was pretty sure I understood what you needed me to do for you until your last trio of statements and now I'm not so sure any more :shock: 

BTW Do you have V215 of my math library handy? If so, when I deliver your script, I'll just 'import' it to get the functions I may need to support the script. If you don't have the library, I can just extract what I need and hard code it into the script.

To be continued ....


Rejoice,

Bob


----------



## Tod (Mar 7, 2011)

> However, you say your 2nd 'known' is a 7 element array of eps???? I thought you want to fill possibly 7 different arrays, each containing 122 eps. The way you're saying it above sounds like you want also (or instead of) to have a 7 element array that only contains the max ep value that corresponds with each MaxEQMenu index???



I'm sorry, I thought we would need an array of the actual ep#s (maximum ep#s) that are associated with the menu index. I thought we would need those numbers to make the calculations to fill (propagate) the ep array with 122 elements (ep#s).

Further I thought we would only need one array for the 122 ep#s and that they would be repropagated when ever the Max-EQ-menu was used or changed.



> Your 'known' #3 is also puzzling While you may want such an array for some other purpose within you script, I don't see that it has anything to do with the process of populating your ep arrays (which I thought is what you wanted me to help you with).



No Bob, I just mentioned it because it is somewhat of a known. I actually mentioned back a few posts ago that I thought we could forget about them, I'm sorry for the confusion. :? 



> BTW Do you have V215 of my math library handy? If so, when I deliver your script, I'll just 'import' it to get the functions I may need to support the script. If you don't have the library, I can just extract what I need and hard code it into the script.



No I've got V205 but I think I could download V215 if it's still available. I'll check it out and download it if it's there. When I saw FillArray(in,out) with the added arguments I kind of thought that's what you might be doing.

Thanks Bob, does this clear things up?  

Tod


----------



## Big Bob (Mar 7, 2011)

Hi Tod,



> Further I thought we would only need one array for the 122 ep#s and that they would be repropagated when ever the Max-EQ-menu was used or changed.



Oh sure that's fine, I just thought after seeing your '3 knows' post that maybe you wanted to pre-compute all 6 sets of eps so you could switch rapidly at runtime without the need to recalculate on the fly. If you aren't concerned about the time it takes to re-populate the array, then you only need one. Alternatively, you could use an 854 element array (7, 122 element arrays put together) and you could compute a starting index based on your drop-down index. However you want to do all this stuff is just picky details :lol: 



> No I've got V205 but I think I could download V215 if it's still available. I'll check it out and download it if it's there.



I'm not sure what new functions may have been added since V205, but I think as long as it has the current cube root function it should be OK.

A function that fits your data pretty good is of the form:

ep = A + B*G^(1/3)

If I choose A and B so that the two end points exactly match your data, ie ep = 500000 for G = 0 and ep = 896888 for G = 6, the maximum error is around +0.08% and -0.25%. Of course we could juggle A and B a little to balance the +/- errors but then the end points will no longer be exact (ie zero error). Do I presume correctly that less than 0.25% error will be OK?

BTW You didn't answer my question about what you are using the ep to control, I'll repeat it here>



> Incidentally, what do you actually use these eps to control, the intensity slider of the envelope modulator?



To be continued ... 

Rejoice my friend, we're almost there o-[][]-o 

Bob


----------



## Tod (Mar 7, 2011)

> I'm not sure what new functions may have been added since V205, but I think as long as it has the current cube root function it should be OK.



The only thing I could find in V205 related to &qò ½   Áws ½   Áxº ½   Áx½ ½   Áy& ½   ÁyG ½   Á{w ½   Á{® ½   Á  ½   ÁË ½   Á€¦ ½   Á€Ö ½   Áî ½   Á‚× ½   Á‹ ½   Á‹o ½   ÁŒÅ ½   Á ½   Á¤ ½   Á´ ½   Áñ ½   ÁŽ; ½   ÁŽÂ ½   Á ½   Áˆ ½   Á² ½   Á’^ ½   Á’² ½   Á•Ý ½   Á–Š ½   ÁšÝ ½   Á› ½   Áž@ ½   Ážƒ ½   Á¡È ½   Á¡Î ½   Á¤ ½   Á¤E ½   Á¤ª ½   Á¤± ½   Á¦è ½   Á§ ½   Á«ê ½   Á­8 ½   Á¯ ½   Á¯E ½   Á°€ ½   Á°ž ½   Á²e ½   Á²ñ ½   Áµ% ½   Áµj ½   Á·? ½   Á·f ½   Á¹º ½   Á¹Â ½   ÁÃq ½   ÁÄ> ½   ÁÍj ½   ÁÎV ½   ÁÔ ½   ÁÔ/ ½   ÁÜÊ ½   ÁÜï ½


----------



## Big Bob (Mar 7, 2011)

Hi Tod,

The Math Library function you will need is named Root3. Here is the old link I have for the package. I don't know if Andrew still has it up on his site or not.

http://www.andrewkmusic.com/filearea/SI ... ryV215.zip

Let me know if it's still there and if so, I'll redo my original post for the benefit of newcomers.

Rejoice,

Bob


BTW Thanks for the additional data but I don't think we'll need it unless you just want to check it out against the function I'll be giving you.


EDIT: The link still appears to be active so I've started a new thread with the info.


----------



## Tod (Mar 7, 2011)

> The Math Library function you will need is named Root3. Here is the old link I have for the package. I don't know if Andrew still has it up on his site or not.
> 
> http://www.andrewkmusic.com/filearea/SI ... ryV215.zip
> 
> Let me know if it's still there and if so, I'll redo my original post for the benefit of newcomers.



Got it Bob, thanks. I unziped it and it looks like it's all there.


----------



## Big Bob (Mar 7, 2011)

Thanks Tod, I just posted it in a new thread.

Bob


----------



## Big Bob (Mar 7, 2011)

OK Tod, here's phase 1 (of two phases). Try out this demo script which will allow you to check the accuracy of the proposed function. You can set either the EQgain value or the VU value and the corresponding engine parameter (as computed by the EQgain_to_ep function) will be displayed. You can enter fractional values for either EQgain or VU by double-clicking the value edit box and entering, for example 1.56
no?

You can play around with this a little until I get another block of time to write the enclosing function for you. You may notice that I changed the units of the eqg to micro-db. I did this to allow us to improve the precision of the eqg value we will be computing for EQgainMax*cnt/122 as we populate the array. You won't have to worry about this however because it will all become obvious once I write the enclosing FillArray function.

*import* "KSPMathV215_KSM.txt"

*on init*
``*declare* ui_value_edit EQgain (0,6000000,1000000)
````move_control(EQgain,1,2)
````EQgain := 0
``*declare* ui_label Cap1 (1,1)
````move_control(Cap1,1,1)
````set_text(Cap1,'Set EQgain in db')
``*declare* ui_value_edit VU (-12000,0,1000)
````move_control(VU,2,2)
````VU := -12000
``*declare* ui_label Cap2 (1,1)
````move_control(Cap2,2,1)
````set_text(Cap2,'Set VU out in db')
``*declare* ui_label engine_par (1,1)
````move_control(engine_par,3,2) 
````set_control_par(get_ui_id(engine_par),$CONTROL_PAR_TEXT_ALIGNMENT,2)`````
````set_text(engine_par,'500000')```
``*declare* ui_label Cap3 (1,1)
````move_control(Cap3,3,1)
````set_text(Cap3,'Engine Parameter') 
``*declare* N``
``
``message('')`````
*end on*

*on ui_control*(EQgain)
``EQgain_to_VU
``EQgain_to_ep(EQgain,N)
``set_text(engine_par,N)
*end on*

*on ui_control*(VU)
``VU_to_EQgain
``EQgain_to_ep(EQgain,N)
``set_text(engine_par,N)
*end on*

*function* EQgain_to_VU
``VU := ((2*EQgain - 12000000) + 500)/1000
*end function*

*function* VU_to_EQgain
``EQgain := 6000000 + VU*500
*end function*

_{ Next is the primary 'inner' function we will need. I've included the other
functions just to support this demo script so you will have something to
play with. }_

*function* EQgain_to_ep(eqg,ep)
``_{ Computes ep = 500000 + 218416*G^(1/3), where G is eq gain in db
required input value eqg, is G scaled by 1000000, ie G in micro db }_
``*declare* r
``Root3(eqg,r)
``ep := 500000 + r*73/10*16/100*17/10*11/1000
``_{ This weird chain of multiplies and divides is equivalent to }_
``_{ multiplying by 218416 and dividing by 10000000. I did it this }_
``_{ way so as to preserve maximum precision in the arithmetic }_
``_{ without incurring 32 bit, 2's complement overflow }_
*end function*


Please let me know if you have any problems getting this to run with K4, it runs fine here.

Rejoice,

Bob


----------



## Tod (Mar 7, 2011)

Heh heh okay, got it.

One big question, do I need the math library in the exact same folder as the script?

No problem to do so, just want to make sure.

Thanks my friend, there's no turning back now!! o=<


----------



## Tod (Mar 7, 2011)

Hi Bob,

The script is working, of course I can increment the value edits and come up with what appears to be fairly correct ep#s.

I'm going to start hand typeing in some #s and see what I get. Heh heh, I think that last table I posted with 1/10 db increments sill come in handy here.

Love yah, and get back. :D


----------



## Big Bob (Mar 7, 2011)

Hi Tod,

Glad you got it working. If you want to put the Math Library in a different folder, you just need to add the path to the import statement.

I think you will find the largest error is near 0 db. For example at 0.5 db (ie VU = -11db), the calculated ep = 673,356 is -1706 lower than your empirically determined value. That's about a -0.25% error. the largest positive error occurs around eqg = 4 db. The calculated ep = 846,713 is high by 674 which is about a +0.08% error.

The enclosing FillArray routine will be forthcoming soon.

Rejoice,

Bob


----------



## Tod (Mar 7, 2011)

Hi Bob,

Well it appears to be pretty close. I haven't figured out exactly where it is percentage wise but you mentioned .25% and that might be right. At this point it's far better then I could of hoped for and who knows, the balistics and accuracy of the meters I used might not be all that perfect anyway.

I think we're in the ballpark and It looks good to me so heh heh, what's the next step?  :D 

Tod


----------



## Big Bob (Mar 7, 2011)

Hi Tod,

I've written the *FillArray* function and I added it to the end of the simple test script. I also added a few more ui elements so that you can play around with it and satisfy yourself that it's what you wanted. 

Here's the deal, whenever you hit K4's apply button (which of course executes the script's ICB), the array is zeroed out. The array's contents is displayed one bin at a time. You can select the bin for viewing with the Index edit box. You can populate (or re-populate) the array by setting the drop-down to the desired EQmax value and then clicking the Fill Array button.

I declared a constant named *size* and set it to 122. If you want to experiment with different sized arrays, just edit this constant.

*import* "KSPMathV215_KSM.txt"

*on init*
``*declare* ui_value_edit EQgain (0,6000000,1000000)
````move_control(EQgain,1,2)
````EQgain := 0
``*declare* ui_label Cap1 (1,1)
````move_control(Cap1,1,1)
````set_text(Cap1,'Set EQgain in db')
``*declare* ui_value_edit VU (-12000,0,1000)
````move_control(VU,2,2)
````VU := -12000
``*declare* ui_label Cap2 (1,1)
````move_control(Cap2,2,1)
````set_text(Cap2,'Set VU out in db')
``*declare* ui_label engine_par (1,1)
````move_control(engine_par,3,2) 
````set_control_par(get_ui_id(engine_par),$CONTROL_PAR_TEXT_ALIGNMENT,2)`````
````set_text(engine_par,'500000')```
``*declare* ui_label Cap3 (1,1)
````move_control(Cap3,3,1)
````set_text(Cap3,'Engine Parameter') 
``*declare* N
``
``*declare* *const* size := 122``_{ array size }_
``
``*declare* ui_menu EQmax
````add_menu_item (EQmax,'0 db',0)
````add_menu_item (EQmax,'1 db',1)
````add_menu_item (EQmax,'2 db',2)
````add_menu_item (EQmax,'3 db',3)
````add_menu_item (EQmax,'4 db',4)
````add_menu_item (EQmax,'5 db',5)
````add_menu_item (EQmax,'6 db',6)
````move_control(EQmax,6,2)
``*declare* ui_label menu (1,1)
````move_control(menu,6,1)
````set_text(menu,' EQmax Menu')
``*declare* ui_value_edit I (0,size - 1,1)
````move_control(I,5,2)
````set_text(I,'Index = ')
``*declare* ui_button Fill
````move_control(Fill,4,2)
````set_text(Fill,' Fill Array')
``*declare* ui_label Show (2,1)
````move_control(Show,4,1) 
``*declare* EPA[size] := (0)
``
``I := 0
``set_text(Show,'EPA[0] = 0')
``
``message('')`````
*end on*

*on ui_control*(EQgain)
``EQgain_to_VU
``EQgain_to_ep(EQgain,N)
``set_text(engine_par,N)
*end on*

*on ui_control*(VU)
``VU_to_EQgain
``EQgain_to_ep(EQgain,N)
``set_text(engine_par,N)
*end on*

*function* EQgain_to_VU
``VU := ((2*EQgain - 12000000) + 500)/1000
*end function*

*function* VU_to_EQgain
``EQgain := 6000000 + VU*500
*end function*

*on ui_control*(Fill)
``Fill := 0
``FillArray(EQmax,EPA,size)
``set_text(Show,'EPA[' & I & '] = ' & EPA[ I ])
*end on*

*on ui_control*(I)
``set_text(Show,'EPA[' & I & '] = ' & EPA[ I ])
*end on*

_{ Next is the primary 'inner' function we will need. I've included the other
functions just to support this demo script so you will have something to
play with. }_

*function* EQgain_to_ep(eqg,ep)
``_{ Computes ep = 500000 + 218416*G^(1/3), where G is eq gain in db
required input value eqg, is G scaled by 1000000, ie G in micro db }_
``*declare* r
``Root3(eqg,r)
``ep := 500000 + r*73/10*16/100*17/10*11/1000
``_{ This weird chain of multiplies and divides is equivalent to }_
``_{ multiplying by 218416 and dividing by 10000000. I did it this }_
``_{ way so as to preserve maximum precision in the arithmetic }_
``_{ without incurring 32 bit, 2's complement overflow }_
*end function*

*function* FillArray(eqm,epa,n)
``_{ Input: eqm = the max eq gain desired, in db
this is assumed to be an integer from 0 to 6
n = the dimension of the ep array to be filled
Output: epa this argument should be the name of an array with n elements

Action: The epa array will be populated with the engine parameter values
that will control the AHDSR modulator intensity slider to provide
EQ gains from 0 to eqm linear in db over the n steps of the array

NOTE: A value of n around 122 was assumed insofar as arithmetic scaling
precision issues are concerned. Satisfactory accuracy should easily be
maintained over an n range as high as 300 or so. }_
``*declare* I
``*declare* eqg

``*for* I := 0 *to* n - 1
````eqg := eqm*1000000*I/(n - 1)
````EQgain_to_ep(eqg,epa_)
``*end for*
*end function*
__

Hopefully, you can take it from here but please let me know if something isn't clear or doesn't work the way you wanted it.

Rejoice,

Bob

EDIT: I notice there is an extraneous  in the comments that you may have to strip out. If the script doesn't compile, let me know and I'll email the .txt file to you._


----------



## Tod (Mar 8, 2011)

Good morning Bob,

Sorry I crapped out on you last night, I ate supper and fell asleep in my big chair, heh heh, common occurance these days. :oops: 

Anyway, the script had a couple of little problems but I got them fixed and I'm playing around with it right now, everything seems to be working properly.



> I declared a constant named size and set it to 122. If you want to experiment with different sized arrays, just edit this constant.



That's great and good thinking. I may actually end up changeing this to 127.

At this point it looks good. I'm going to have to examine it closely to see exactly which parts I need ;and I may have a question or two for you.

I'm not sure if all the intensity sliders work the same in Kontact but for those that work like the one for the EQ-Gain-ahdsr, this could be a very valuable little tool. o=< 

Incidently, for anyone who might want to check this out there are two little fixes.

> Just below the "on ui_control(I).....end on" there is "_{ Next is __". Either delete the "" or put the brace on the inside of it.

> In the "on ui_control(Fill)" change "set_text(Show,'EPA[' & I & '] = ' & EPA)" to "set_text(Show,'EPA[' & I & '] = ' & EPA)". It was missing the "".

Thanks so much my friend, my next step is to try incorporate this into my Steel script. Heh heh, I can already see a couple questions but I'll get back to you after I've examined it a little closer. o-[][]-o 

Tod_


----------



## Tod (Mar 8, 2011)

Okay, my first question. In the "on init" callback as far as the declarations go. I think all I need from your script are these right?

declare ui_menu EQmax 
declare N 
declare const size := 122
declare EPA[size] := (0)

Of course that's besides what gets imported with your imported math file, I know they have to be there.

2nd Q: I don't need the two functions dealing with the "VU" do I?

I'm still contemplateing how I'm going to incorporate all this into the "on ui_control( EQmax )" callback but I want to look it over a little more before I ask any more questions.



> Sure, but, make it soon because my memory of this will begin to fade rapidly



Yep, that's another part of getin' old. Heh heh, I need to get this all done before I forget why I'm doing it. :oops: :D 

Tod


----------



## Big Bob (Mar 8, 2011)

HI Tod,

You probably don't need N either. In fact, all you really need is the function *FillArray* and its support function *EQgain_to_ep*. It's up to the rest of your script to decide how you deliver the 3 parameters to FillArray. The first parameter should be a value from 0..6 that probably will represent a drop-down index such as that illustrated with the EQmax declaration but this is not necessary. You can provide the first parameter any way you like.

The 2nd parameter should be the name of an array that you declare. If you want to use EPA as a name that's OK but, you can call it anything you want. Just use its name for the 2nd parameter when you invoke FillArray.

Now, as to the array size, I only used a named constant, *size*, so that you could conveniently change the size while you are still experimenting. For this reason, I wrote FillArray to accomodate a variable array size. Therefore, in addition to the array name you have to tell FillArray how big the array is and thus the 3rd parameter passed in my example code is *size*. 

However, once you have determined the size of the array that you want to use, you will probably not need to change it any more after that. So, at that point you can eliminate the 3rd parameter of FillArray and no longer will require the *size* constant.

For example, suppose that you eventually decide to use an array size of 128 (a likely choice if you are indexing the array with a MIDI CC, whose values run from 0 to 127). In this case you could re-write FillArray to look like this:

_{ This variant of Fill Array assumes an array size of 128 }_

*function* FillArray(eqm,epa)
``_{ Input: eqm = the max eq gain desired, in db
this is assumed to be an integer from 0 to 6
Output: epa this argument should be the name of an array with 128 elements

Action: The epa array will be populated with the engine parameter values
that will control the AHDSR modulator intensity slider to provide
EQ gains from 0 to eqm linear in db over the 128 steps of the array }_

``*declare* I
``*declare* eqg

``*for* I := 0 *to* 127
````eqg := eqm*1000000*I/(127)
````EQgain_to_ep(eqg,epa[ I ])
``*end for*
*end function*

_{ The next function can be inlined in FillArray if you like, but, there is no
penaly for leaving it factored out and it may be useful somewhere else in
your script }_
*function* EQgain_to_ep(eqg,ep)
``_{ Computes ep = 500000 + 218416*G^(1/3), where G is eq gain in db
required input value eqg, is G scaled by 1000000, ie G in micro db }_
``*declare* r
``Root3(eqg,r)
``ep := 500000 + r*73/10*16/100*17/10*11/1000
``_{ This weird chain of multiplies and divides is equivalent to }_
``_{ multiplying by 218416 and dividing by 10000000. I did it this }_
``_{ way so as to preserve maximum precision in the arithmetic }_
``_{ without incurring 32 bit, 2's complement overflow }_
*end function*



> 2nd Q: I don't need the two functions dealing with the "VU" do I?



No, you don't need those functions, they were just for the demo to help you relate.



> Of course that's besides what gets imported with your imported math file, I know they have to be there.



Actually, all you need is Root3 and its support table but the Math Library is designed so that that's all that will be loaded provided your script doesn't reference any other library routines.

BTW I haven't gotten to it yet but eventually I will update the Math Library to take advantage of the new native support for user functions that NI has added in K4. This will not be too important unless your script has to invoke FillArray from mulitple locations. If it does, remember that all the code that supports FillArray will be inline expanded each time you call it.

You have a great day my friend.

Bob


----------



## Tod (Mar 8, 2011)

Thanks Bob,

This is going to be a big big big help o=< 

I'll get back to you as soon as I can. Heh heh, it's supper time and the big chair awaits me, ZZZzzzzzzz... o/~  

I just can't thank you enough. o-[][]-o 

Tod


----------



## Tod (Mar 10, 2011)

Hi Bob,

I finally got a chance to narrow the script down and just want you to take a look to make sure I haven't left anything out. I changed some of the names so that when I get it into my main script I can tell at a glance what everything stands for. Of course this part of the script is just to fill the array.



```
import "KSPMathV215_KSM.txt" 

on init 
  declare const $EPAsize := 122 
  declare %EP_ary[$EPAsize] := (0) 

  declare ui_menu $EQmax_Menu 
    add_menu_item ($EQmax_Menu,'0 db',0) 
    add_menu_item ($EQmax_Menu,'1 db',1) 
    add_menu_item ($EQmax_Menu,'2 db',2) 
    add_menu_item ($EQmax_Menu,'3 db',3) 
    add_menu_item ($EQmax_Menu,'4 db',4) 
    add_menu_item ($EQmax_Menu,'5 db',5) 
    add_menu_item ($EQmax_Menu,'6 db',6) 
    move_control($EQmax_Menu,6,2) 
  message('')      
end on 

on ui_control($EQmax_Menu) 
  Fill := 0 
  FillArray($EQmax_Menu,%EP_ary,$EPAsize) 
end on 

function EQgain_to_ep(eqg,ep) 
  declare r 
  Root3(eqg,r) 
  ep := 500000 + r*73/10*16/100*17/10*11/1000 
end function 

function FillArray(eqm,%EP_ary,n) 
  declare I 
  declare eqg 

  for I := 0 to n - 1 
    eqg := eqm*1000000*I/(n - 1) 
    EQgain_to_ep(eqg,%EP_ary[I]) 
  end for 
end function
```


----------



## Big Bob (Mar 10, 2011)

Hi Tod,

Yeah that's it, except, you won't need the Fill := 0 line in the menu callback. That line was just to make the Fill button work as a momentary button instead of as a toggle. Since you are invoking the FillArray function in the menu callback, you don't need to do anything but call FillArray.

Rejoice,

Bob


----------



## Tod (Apr 4, 2011)

Hi Bob,

The script is working beautifully. o=< 



Big Bob @ Sun Mar 13 said:


> As to the initialization thing, you can probably easily convert the Root3 function to a native KSP function and then use the 'pgs trick' to also trigger FillArray from the ICB. Just a thought, in case you want to get involved in stuff like that :lol:



I decided I do need the make_persistent / read _persistent functionality.

I assume what you mean is to copy/paste the Root3 function to my main script and then delete the "Import" line, is that right?

*@ "and then use the 'pgs trick' to also trigger FillArray from the ICB"*

Heh heh, okay what is the "pgs trick" all about? :?  

Tod


----------



## Big Bob (Apr 4, 2011)

Hi Tod,

What I'm referring to is the not uncommon situation where you have to call on a lengthy function in the ICB in order to initialize things when your script first starts up and then you need to also invoke the same lengthy function in one or more ui_control callbacks when the user changes something.

I your particular case, the FillArray function (including its Root3 support) is a fair number of code lines so if you have to invoke FillArray both from the ICB and from one or more ui callbacks, you might want to do it more efficiently than just inlining it everywhere you need it.

One way to accomplish that would be to use K4's native support for user functions. When you do that, you define the function once and then you can invoke it from several places using the new 'call' keyword. There are however, two potential problems.

(1) Native ksp functions do not include any native support for parameter passing.

(2) Native ksp functions cannot be invoked from the ICB.

You can work around the first problem rather easily in your case by the simple expedient of using global variables that the code body of the native ksp function can easily then access.

The 2nd problem of not being able to invoke native functions from the ICB is where you can use the pgs trick that Nils described here:

http://www.vi-control.net/forum/viewtopic.php?t=16811

I just thought you might want to 'get your fee' wet' with some of this stuff :lol: 

Rejoice,

Bob


----------



## Hannes_F (Apr 4, 2011)

Tod @ Sat Feb 26 said:


> he brought in a Steel Guitar player for a few songs and I ended up sampleing his steel to make a steel instrument in Kontakt



I hope you did not make the library from the material you recorded for the songs.


----------



## Tod (Apr 4, 2011)

Thanks much Bob,

It'll take me a while to decipher all this. One silly question, what exactly are you refereing to when you say "ICB"? I know it's probably very simple but heh heh, you gurus throw abbreviations like this around all the time and sometimes I don't know what you're talking about, only to find out later it was one of those "dahh" :oops: things. Not to mention, this old brain has a tendency be out to lunch. :cry: 

Heh heh, maybe we should have a *sticky for a glossary of terms* you guys use. :D o=< 



Hannes_F @ Mon Apr 04 said:


> Tod @ Sat Feb 26 said:
> 
> 
> > he brought in a Steel Guitar player for a few songs and I ended up sampleing his stò 9   ÏÈ% 9   ÏÈJ 9   Ïõ¥ 9   ÏõÆ 9   Ï÷æ 9   Ïø
> >  9   Ïü0 9   Ïü; 9   Ïü— 9   Ïü£ 9   Ïþ 9   Ïþ- 9   ÏþÊ 9   Ïÿr 9   ÐÅ 9   Ðì 9   Ð» 9   ÐS 9   Ð† 9   Ðë 9   Ð1é 9   Ð3 9   Ð?¤ 9   Ð@Ù 9   Ð@å 9   ÐA7 9   ÐSà 


----------



## Tod (Apr 4, 2011)

Heh heh, wow Bob, I feel pretty stupid, I knew it would be one those "Daahh" :oops: things.

So what would happen if I copied all the functions (includeing BuildR3Table) from your math library into my main script, put the "FillArray" in the appropiote place in the heh heh (ICB), and then included the appropriate "make_persistent and read_persistent" statements in the ICB? Would that work?

My script is'nt that big yet, less than 450 lines, and I know that where ever I have the "FillArray" fucntion it will include all the lines that go with that each time. I haven't tried this yet, what do you think?  

Tod


----------



## Big Bob (Apr 4, 2011)

Hi Tod,



> So what would happen if I copied all the functions (includeing BuildR3Table) from your math library into my main script, put the "FillArray" in the appropiote place in the heh heh (ICB), and then included the appropriate "make_persistent and read_persistent" statements in the ICB? Would that work?



Sure, that's what the import statement does anyway (I presume you know that it only loads the parts of the Math Library that you actually reference in your script). But, if you prefer to make your script standalone, all you have to include with your script are the functions Root3 and its support function BuildR3Table. You can simply put these with your other functions. Or, if you like, you can just declare the R3Tbl[128] in your ICB with your other data declarations and then remove the BuildR3Table line from the Root3 function (its only purpose is to declare the R3Tbl).

As far as the make/read persistent stuff, I presume you mean so that a reload of the script will assume the last set conditions? If so, yep, that's the way to do it.

Finally, if you don't mind inlining all the code lines everytime you invoke FillArray in your script, then don't worry about the rest of what I said. I only suggested it because it might make your code leaner and meaner. It might also be a good way for you to explore a few new things but hey, sometimes the path of least resistance is the best, no? :lol: 

Rejoice,

Bob


----------



## Hannes_F (Apr 5, 2011)

Tod @ Mon Apr 04 said:


> Hannes_F @ Mon Apr 04 said:
> 
> 
> > Tod @ Sat Feb 26 said:
> ...



Obviously I must be smirky because I did not understand your answer. Please explain again.


----------



## Tod (Apr 5, 2011)

Hannes_F @ Tue Apr 05 said:


> Tod @ Mon Apr 04 said:
> 
> 
> > Hannes_F @ Mon Apr 04 said:
> ...



I'm sorry Hannes, I didn't mean to offend or illude you in any way, you do have a nice smile.  I just thought you were kidding around. I did indeed record the samples separtely. :D 

@Bob, I am going to persue this further. Since I'm under a time frame I just wanted someithing simple for now. Trust me I do want to get my feet wet.  Once again I just can't thank you enough and I'll get back to you as I progress.

tod


----------

