# Lookup tables for Output volumes



## ScoringFilm (Mar 15, 2012)

Hi all,

Just wondered if anyone had any preset tables/functions or arrays already set-up for the Stereo Modeller output volume and Send FX Return Volume.

I want to actually retrieve the value in dB to display on a multiscript:

A multiscript knob is sending 0-1000000 values to an instrument for the above parameters, however there is no way to send the 'get_engine_par_disp' value back to the multiscript to display on the knob.

Thanks in advance,

Justin


----------



## Big Bob (Mar 15, 2012)

Hi Justin,

I haven't checked out that specific volume function but why don't you post a short tabulation with maybe 3 or 4 data points for me to look at. Once I see some data, I probably can relate it to something I have in stock :lol: 

The best data points to post would be something along these lines;

ep = 0, displayed volume -> ?? db
ep = 250000 -> ? db
ep = 500000 -> ? db
ep = 750000 -> ? db
ep = 1000000 -> ? db

Rejoice,

Bob


----------



## ScoringFilm (Mar 16, 2012)

Thanks Bob,

In the vol ranges I need;

This is Stereo Modeller output:

-24dB = 157000
-23db = 163500
-22db = 170000
-21db = 176500
-20db = 184000
-19db = 191000
-18db = 198400
-17db = 206000
-16db = 214000
-15db = 223000
-14db = 231500
-13db = 240500
-12db = 250000
-11db = 260000
-10db = 270000
-9db = 281000
-8db = 292000
-7db = 303000
-6db = 315000
-5db = 327000
-4db = 340000
-3db = 354000
-2db = 368000
-1db = 382000
0db = 397000
1db = 413000
2db = 429000
3db = 445000
4db = 463000
5db = 481000
6db = 500000

And Send FX return Vol:

-60db = 39300
-50db = 57800
-40db = 85200
-30db = 125000
-20db = 184000
-15db = 223000
-10dB = 270000
-9db = 281000
-8db = 292000
-7db = 303000
-6db = 315000
-5db = 327000
-4db = 340000
-3db = 354000
-2db = 368000
-1db = 382000
0db = 397000

There does obviously appear to be some correlation; I hope you find something!

Justin


----------



## Big Bob (Mar 16, 2012)

Hi Justin,

Your data looks just like NI's favorite 18db/octave (cubic) curve. So, you can just use the ep_to_mdb converter with about a 12 db offset.

Here's some illustrative code.

*import* "KSPMathV405.txt"

*on init*
``SetMathMode(0)
``*declare* ui_knob ep (0,500000,1)
``*declare* ui_label show (1,1)
``*declare* Vol
``*declare* @DB
``ep := 500000
``set_text(show,'6.000 db')
*end on*

*on ui_control* (ep)
``ep_to_mdb(ep,Vol)
``Vol := Vol + 12062
``D.FmtVal(Vol,3,DB)
``set_text(show,DB & ' db')``
*end on*


I'm also attaching a little demo instrument using the above script for you to see if the curve fit is good enough for you. Set any ep value with the knob and read the corresponding volume amount in db displayed on the label to its left.

Hope this will do the job for you.

Rejoice,

Bob


----------



## ScoringFilm (Mar 17, 2012)

Bob,

Many thanks indeed; just what I was looking for. Unfortunately I can't find v405 of your wonderful math library; was it posted recently?

Also is there a way to limit the label db display to 1 decimal place (i.e. the same as Kontakt's knob display for vol)?

Regards,

Justin


----------



## mk282 (Mar 17, 2012)

ScoringFilm @ 17.3.2012 said:


> Also is there a way to limit the label db display to 1 decimal place (i.e. the same as Kontakt's knob display for vol)?



Only if you're willing to use really big string arrays and then display that instead of get_engine_par_disp depending on knob values... Otherwise, we all know Kontakt's string processing is close to non-existant, so not really possible any other way.


----------



## ScoringFilm (Mar 17, 2012)

mk282 @ 17/3/2012 said:


> Only if you're willing to use really big string arrays and then display that instead of get_engine_par_disp depending on knob values... Otherwise, we all know Kontakt's string processing is close to non-existant, so not really possible any other way.



mk282 - thanks for the input; I just thought there may be a way to 'round' the number up to one decimal place.

Justin


----------



## Big Bob (Mar 17, 2012)

Hi Justin,

As to rounding the display to one decimal, that's easy, just change:

D.FmtVal(Vol,3,DB)

to

D.FmtVal((Vol+50)/100,1,DB)

What this does is divide the number of mdb by 100 (with rounding, thus the +50) and then reduce the *dd* parameter (number of decimals) from 3 to 1. The D.FmtVal function is described in the User's Guide Addendum for V405 on page 9.

As to V405 of the Math Library, just send me a PM with your email address and I'll send it to you. There will also be a version 450 forthcoming to take advantage of the new return-value function feature of Nils' Editor but, I have no idea when I'll get around to that :lol: 

Rejoice,

Bob


----------



## ScoringFilm (Mar 17, 2012)

Many thanks Bob; it's good to have your expertise help around this forum.

Regards,

Justin


----------



## Big Bob (Mar 17, 2012)

Glad to be of help Justin.

It also just occured to me that, since you don't have V405 yet, you can't try the format change I suggested. :oops: So, I'm attaching a revised .nki for you to try.

*import* "KSPMathV405.txt"

*on init*
``make_perfview
``SetMathMode(0)
``*declare* ui_knob ep (0,500000,1)
``*declare* ui_label show (1,1)
``*declare* Vol
``*declare* @DB
``ep := 500000
``set_text(show,'6.0 db')
*end on*

*on ui_control* (ep)
``ep_to_mdb(ep,Vol)
``Vol := Vol + 12062
``D.FmtVal((Vol+50)/100,1,DB)
``set_text(show,DB & ' db')``
*end on*


I should also mention that while the *D.FmtVal *routine displays only a fixed number of decimal places, it can be used together with some simple external code to provide a more 'floating-point' type of display similar to what you get with *get_engine_par_disp*. So, if you need something like that, just let me know and I can suggest some easy-to-write 'external' functions that you can use with *D.FmtVal *to generate whatever kind of display format you need.

Rejoice,

Bob


----------



## ScoringFilm (Mar 17, 2012)

Big Bob @ 17/3/2012 said:


> I should also mention that while the *D.FmtVal *routine displays only a fixed number of decimal places, it can be used together with some simple external code to provide a more 'floating-point' type of display similar to what you get with *get_engine_par_disp*. So, if you need something like that, just let me know and I can suggest some easy-to-write 'external' functions that you can use with *D.FmtVal *to generate whatever kind of display format you need.



That sounds fantastic Bob - the idea is to display the *get_engine_par_disp* value from an instrument on a multiscript.

Unfortunately your code crashes Kontakt when applied as a multiscript. I'm not sure why as there doesn't seem to be any code that is reliant on normal KSP commands rather than midi commands.

**EDIT - Problem solved!**

I have found the problem; the following line is created when compiled. Once removed the script will function at multiscript level (as there is no PGS in multiscript):



> pgs_create_key(pgsmath,1)



Regards,

Justin


----------



## Big Bob (Mar 17, 2012)

Hi Again Justin,

Ah yes, the post-init thingy. Maybe when I do V450 I'll add a multi-script option to the SetMathMode option list. I must admit that I didn't think about how well the library would adapt to MS use :oops: 

Anyway, glad you found the culprit. As long as you don't need to execute any math functions in the ICB, you should be OK. If you do need to execute library functions in the ICB (and you don't have the pgs callback available), you may have to massage things a bit more because some of the library routines now use the KSP 'call' mechanism and it can't be used in the ICB. That's why I provided the post-init machinery.

Rejoice,

Bob


----------



## ScoringFilm (Mar 17, 2012)

Thanks Bob,

I don't need any math functions in the ICB and everything is working as it should. :D 

Thanks for taking the time to look at this, very much appreciated. o-[][]-o 

Justin


----------



## ScoringFilm (Apr 25, 2012)

Bob,

Further to Tod's recent request/thread http://www.vi-control.net/forum/viewtopic.php?t=25806, would the same idea work with the script you recently helped me with?

I certainly don't just expect that you have the time for this and will understand if you decline.

Regards,

Justin


----------



## Big Bob (Apr 25, 2012)

Hi Justin,

I don't see why not. Right now I'm in the thick of something that I better not interrupt or I might make another dumb mistake (like I did when I jumped on MK's modulator idea :lol: ). However, what you're asking for should be fairly easy so I can probably sketch it out for you later today.

BTW Does all the control id stuff work OK in multiscripts? I haven't had a chance to try that yet.

Rejoice,

Bob


----------



## ScoringFilm (Apr 25, 2012)

Thanks Bob,

Great news,

The only thing that doesn't work (other than the obvious difference in on_midi vs on_note) is the pgs - I simply remove this once compiled (it is added by the math lib).

If you mean set/get_control_par with knobs etc then yes it does work, however I obviously don't need to address any $ENGINE_PAR as I am simply sending/using 0-100000 values with a dB readout display.

Regards,

Justin


----------



## Big Bob (Apr 25, 2012)

> If you mean set/get_control_par with knobs etc then yes it does work,



Good, and yes, that's what I meant. 8) 

Hang in there a while and I'll get back to you my friend.

God Bless,

Bob

Whoops! I forgot to ask you, is it sufficient if my coding example just properly adjusts ep1, ep2, and ep3? I presume you are broadcasting these three ep values to the instrument scripts some way that I needn't be concerned about?


----------



## ScoringFilm (Apr 25, 2012)

Big Bob @ 25/4/2012 said:


> > If you mean set/get_control_par with knobs etc then yes it does work,
> 
> 
> 
> ...


That is indeed exactly what I am doing.
Sent from my mobile!
Regards, Justin


----------



## Big Bob (Apr 25, 2012)

OK Justin,

Rosie was a little late with lunch so I banged out this edited version of TodsKnobs which is attached. I tried it quickly as an instrument script and, at least superficially, it appears to work. However, when I try to load it as mulitscript it seems to crash K4.

I don't have time right now to chase down why that is happening (Rosie is finally calling me for lunch) but, I thought you might want to fiddle with what I have so far (if you are still awake that is :lol: ).

Rejoice,

Bob


----------



## Big Bob (Apr 25, 2012)

OK I'm back from lunch and I took a look at the multiscipt problem. It was apparently just the pgs create thingy that you already discovered in a prior lifetime :lol: 

One question that occured to me as I was recoding TodsKnobs is why are you using separate labels to display the db value when you could just as easily display it with the knobs (instead of displaying the ep)? You will probably notice that a certain amount of cumulative error builds up over time because of the Log/Exp conversions not being perfect. And, you will probably see more disparity in the ep values than in the db values so you may want to display only the db values with the knobs. Just a thought.

God Bless,

Bob


----------



## Big Bob (Apr 26, 2012)

Hi Justin,

Just to finish this off, I'm attaching a V406 of the Math Library. This version will not compile the pgs var if you don't include TI in the option list. So, if you change your import statement to use V406, you won't have to manually remove the pgs create code line.

I'm also including a 2nd version of your knobs script to illustrate a couple of things you might want to consider. One change is to add some range clamping to prevent moving the slave knobs outside the -60 to +6 db range. The 2nd change is to illustrate displaying the db value directly on the knobs themselves instead of using separate labels. However, I see that the 'db' unit tends to be chopped off for low negative db values so maybe that's the reason you decided to use separate labels. You could also consider variable formatting based on value as I suggested earlier in this thread. For example, when the value get below -10.0 db, you could drop the decimal digit perhaps. Just a few random thoughts.

OK, now I have to get back to WIPS (it's getting near completion so things are getting exciting).

Rejoice,

Bob


----------



## ScoringFilm (Apr 26, 2012)

Bob,

Apologies for the delay in replying - it's the time-zone thing, plus work, plus kids etc (you get the picture!)

Many thanks indeed; this is exactly what I was looking for. The separate labels are for a reason; not least because I'm actually using sliders with animation, however it's useful to have the knob display as an alternative.

Also very useful that the Math Lib can now be automatically compiled into MultiScript. I have forgotten to remove the additional 'pgs' a couple of times which caused a complete crash/restart.



> You could also consider variable formatting based on value as I suggested earlier in this thread. For example, when the value get below -10.0 db, you could drop the decimal digit perhaps.



This sounds a great idea. I have read back through the previous posts and can't decipher how I should do this - maybe I'm missing something obvious!

Anyway, thanks again and I look forward to WIPS (btw this is also used as an abbreviation for 'Workplace Induction Programmes' - not that this bears any relation!).

Regards,

Justin


----------



## Big Bob (Apr 26, 2012)

Hi Justin,



> This sounds a great idea. I have read back through the previous posts and can't decipher how I should do this - maybe I'm missing something obvious!



I just meant you could format based on the number range, something like this:

*import* "KSPMathV406.txt" 

*on init*
``message('')
``make_perfview
``SetMathMode(0)
``*declare* ui_knob freq (0,100000,1)
``*declare* ui_label show_freq (1,1)
``*declare* @Val
*end on*

*on ui_control*(freq)
``*call* show_value
*end on*

*function* show_value
``*select* freq
````*case* 0 *to* 999
``````Val := freq & ' Hz'
````*case* 1000 *to* 9999
``````D.FmtVal((freq+5)/10,2,Val)
``````Val := Val & ' KHz'
````*case* 10000 *to* 100000
``````D.FmtVal((freq+50)/100,1,Val)
``````Val := Val & ' KHz'
``*end select*
``set_text(show_freq,Val)
*end function*



I'm also attaching a demo .nki using the above script fragment with a knob similating a 0 to 100KHz frequency source.



> Anyway, thanks again and I look forward to WIPS (btw this is also used as an abbreviation for 'Workplace Induction Programmes' - not that this bears any relation!).



Yes, and it's also an abbreviation for 'Wireless Intrusion Prevention System' :lol: 

(and I suppose a kagillion other things)

Anyway, I'm glad the code example will be useful to you. BTW There is an easier way to do this mathematically but since the KSP doesn't have floating point, I took the easy way out by just using the log/exp routines to cover the necessary dynamic range of the ratios involved without a lot of fiddling around with scaling and such. Maybe when Nils gets around to posting my 64-bit muldiv function, we can revisit this project and see if we can't utilize that to do the job with simple ratios.

Rejoice,

Bob


----------



## ScoringFilm (Apr 30, 2012)

Bob,

Spent a few days experimenting with this and almost got it to where I want. I have stuck with the first example (JustinKnobs) for several reasons, however is there a way to limit the displayed output?

i.e. if knob one is set (using ALT) to a lower level than the other two (e.g. -60dB). When knob one is pushed up the other two labels overshoot the 6dB limit (i.e. they can display upto 72 dB!).

Justin


----------



## Big Bob (Apr 30, 2012)

Hi Justin,

I thought I already covered that. Take a closer look a few posts back, specifically see:



> I'm also including a 2nd version of your knobs script to illustrate a couple of things you might want to consider. *One change is to add some range clamping to prevent moving the slave knobs outside the -60 to +6 db range. *



Just extract the 'clamping' code that I illustrated in Knobs2 and add it to the JustinsKnobs version. :lol: 

Or, am I misunderstanding what you are saying now? :? 

Rejoice,

Bob

EDIT:

Oh, Justin, there is one other thing I keep forgetting to mention regarding displaying mdb with only one decimal digit. Since the mdb value can be positive or negative, the rounding used with the division by 100 should be signed rounding.

In other words, instead of:


```
D.FmtVal((Vol+50)/100,1,DB)
```
 use something like this for more accurate displays:


```
D.FmtVal(rdiv(Vol,100),1,DB)
```

Where rdiv (rounded divide is a function something like this)

```
function rdiv(a,b) -> result  { a/b with signed rounding }
  result := (a + a mod b)/b
end function
```

Rejoice,

Bob


----------



## ScoringFilm (May 1, 2012)

Many thanks Bob,

You are most probably right and it looks like I've got some more studying to do! Give me a couple of days!!

Regards,

Justin


----------

