# KSP help with showing decibels



## Casey Edwards (Nov 14, 2012)

Okay folks, I've went from completely noob to semi-competent thanks to the help of you guys and a tremendous help from Casey at TreeBark Audio. However, I still have tons to learn about what can and can't be done in KSP and idiomatic workarounds.

Okay, so the problem: I have a 3 custom knobs(sliders) across 3 separate groups that all have 3 edit_value boxes to display so that they relay info to each other. The slider will readout the proper value into the value box and you can also input a number of your own and the slider will change accordingly. All that I've found is quite easy to setup over some time. The part where I'm having trouble is the slider is connected to the amplifier volume knob and all my values are being shown in integers from 0 to 1000000 still instead of decibels and I can't find the proper solution to change this. (We do know that 631000 is 0.0dB, not sure if that helps) It's easy enough to change the units to a % and I did find this equation info online to turn % into dB, but I'm not sure how reliable it is, nor do I know how to use log functions in KSP.

dB = 10log (1 + X)
Example X = %
Thus,
dB = 10log( 1 + 0.01)
dB = 0.0432

I also tried to use the get_engine_par_display funciton similiar to that of how set_knob_value is used but with the value edit box instead, but to no avail. That section of code looks like this:


```
on ui_control($volRange1)
    set_engine_par($ENGINE_PAR_VOLUME,%layerTable1[$layerKnob/7874]/1000 * $volRange1/1000,0,-1,-1)
    set_control_par(get_ui_id($volDisplay11),$CONTROL_PAR_VALUE,$volRange1)
    set_control_par_str(get_ui_id($volDisplay11),$ENGINE_PAR_VOLUME,get_engine_par_disp($ENGINE_PAR_VOLUME,0,-1,-1))
end on

on ui_control($volDisplay11)
    set_control_par(get_ui_id($volRange1),$CONTROL_PAR_VALUE,$volDisplay11)
    set_engine_par($ENGINE_PAR_VOLUME,$volDisplay11,0,-1,-1)
    set_control_par_str($volDisplay11,$ENGINE_PAR_VOLUME,get_engine_par_disp($ENGINE_PAR_VOLUME,0,-1,-1))
end on
```

The complicated part of this, that Casey from TreeBark will be able to explain better than me, is how it's connected to a custom table. These sliders are merely a way for the user to set the max volume in which that layer will reach in decibels. I hope this makes sense, and here is a quick screen grab of the place holder layout until I get things figured out.

http://caseyedwardsmusic.com/wp-content/uploads/2012/11/CEMusicAlphaPatch.jpg


----------



## mk282 (Nov 14, 2012)

ui_value_edit does not work with get_engine_par_disp. This is only for ui_knob, ui_label, and (eventually, but not really good idea) ui_button/ui_switch.

My suggestion is just using knobs or sliders for this. Typing in a value you want to have in KSP is a good idea, but quite complex to implement, because KSP doesn't support floating point numbers. And, as you can see, value edits don't work with them either, nor can they work with get_engine_par_disp.


----------



## TBAudio (Nov 14, 2012)

Hey guys, that I might add a few details. thanks for the shout out Casey.

So basically the table array you see in the image directly controls the volume of a specific layer. There is table for each layer. All the tables are attached to the same knob that controls the position or loaded value from the arrays.

This is great except that as some of you might of imagined this ends up being a problem controlling the volumes of the layer... 

So then I helped show how to setup a separate variable (slider) for each layer which will scale the full value from a given table down to a given value (slider), hence a max volume control, but I just hastily made the label a linear percentage. 

Obviously you can't use get engine par cause the volume of the group is relative to the position of the table array. I have started trying to learn Bob's math lib (many thanks Bob) but so far all it does it make me feel stupid. To be able to display a dB based on kontakts default range would be much better than the percentage I setup as a temp label. 

Looking back I think maybe a mistake was bypassing the volume modulator and controlling the volume directly. If the table controlled a modulation sources intensity instead, then the volume set on the group would actually represent the max volume...

I would still love to know how to get a dB value from a slider without using get_engine_par, but for me it's gonna take more research on these forums I think.


----------



## Raptor4 (Nov 14, 2012)

> I also tried to use the get_engine_par_display funciton similiar to that of how set_knob_value is used but with the value edit box instead, but to no avail.


Hi Casey,
The trick is simple - you just add an ui_label under the objects which do not support direct get_engine_par_display like the slider or value edit etc. This is the way shown in your image link.
Here is a simple example code:

```
on init
  declare ui_slider $Level(0, 1000000) 
  move_control($Level,2,1)
  make_persistent($Level)
  declare ui_label $Lev_Mon(0, 0) 
  set_text($Lev_Mon,get_engine_par_disp($ENGINE_PAR_VOLUME,0,-1,-1) & " dB")
  move_control($Lev_Mon,2,2)
end on

on ui_control($Level)
  set_engine_par($ENGINE_PAR_VOLUME,$Level,0,-1,-1)
  set_text($Lev_Mon,get_engine_par_disp($ENGINE_PAR_VOLUME,0,-1,-1) & " dB")
end on
```
You can re-size the ui_label as you wish and place it where you want, change its background etc.
Regards,

R4


----------



## mk282 (Nov 15, 2012)

Yes, that is a solution, indeed. But only for displaying the value. If they need value input by typing it, it doesn't help unfortunately. :(


----------



## TGV (Nov 15, 2012)

BTW, I think your formula is wrong. Adding 0% is a change of 0dB, that is correct. But adding 100% gives a change of 3dB or 6dB, depending on whether you're indicating pressure or power, so you'll need to multiply it by 10 or 20.

If I'm not mistaken, an extra bit is usually considered 6dB in a DAW (so 16 bits is 96dB of dynamic range, 24 bits is 144dB), so you should probably multiply by 20. Perhaps someone more seasoned in this can chime in?

PS Now I see from your example that you mean 10 times the 10-base logarithm of x when you write 10log(x). So perhaps you should multiply by 20 instead of 10.


----------



## Big Bob (Nov 15, 2012)

Hi Guys,

re:


> I would still love to know how to get a dB value from a slider without using get_engine_par, but for me it's gonna take more research on these forums I think.


I realize that the Math Library User's Guide is not exactly an easy read but, if you really have a need to convert from an engine parameter (0..1000000) to or from a Volume setting expressed in db (in numerical rather than in text string form), I suggest you take a look in Section 5.4 of the User's Guide and find the routine named: *epVolume*

http://www.bigbobsmusicworld.com/kontak ... th-library

This routine can convert either direction and probably can be pressed into service for solving your problem.

Rejoice,

Bob


----------



## Casey Edwards (Nov 15, 2012)

Thanks to EVERYONE for your kind efforts to help me in this endeavor!

Bob, I'll admit, your math library scares the buhjeezes out of me at this point!  Not to any failing on your part of course. But unless I had a third grade level walk through on how to implement and use those functions I would be scratching my head for quite a while. I really do want to impress upon you how awesome it is that you've released such an amazing tool for us to use though. I will learn to harness its power one day. ~o)


----------



## Big Bob (Nov 15, 2012)

Hi Casey,

I'm sorry but I really didn't mean to frighten anyone when I wrote the Math Library :lol: 

I don't want to take the time to study your specific application but, what I could do is post some simple code to illustrate how you could use the *epVolume* function if that would help you. You would then of course have to recast it for your specific application. Would you like me to do that?

Rejoice,

Bob


----------



## Casey Edwards (Nov 15, 2012)

Big Bob @ Thu Nov 15 said:


> Hi Casey,
> 
> I'm sorry but I really didn't mean to frighten anyone when I wrote the Math Library :lol:
> 
> ...



Bob, if you have the time and the energy to do so, I'd be happy to see an example of any magnitude. Thank you very much!


----------



## Big Bob (Nov 15, 2012)

OK Casey,

Here's a simple script that illustrates how to convert from the engine parameter (0..1000000) to the numerical mdb equivalent in the variable *Vol*. For the label named *ShowVolume* I'm displaying the mdb value from *epVolume* directly.

However, if you want to mimic NI's display format in dB with one decimal digit, you can use the library routine named *D.FmtVal*. Since the mdb value has to be divided by 100 to express the result in 0.1 DB untis, you also need to do a rounded division using the *RoundDiv* routine. I illustrated that by displaying the formatted value in the label named *ShowDB*.

Here's the script:

*import* "KSPMathV450.txt"

*on init*
``message('')
``SetMathMode(0)
``*declare* ui_slider Volume (0,1000000)
``*declare* ui_label ShowVolume (1,1)
``*declare* ui_label ShowDB (1,1)
``*declare* Vol
``*declare* @DB
*end* on

*on ui_control* (Volume)
``set_engine_par(ENGINE_PAR_VOLUME,Volume,0,-1,-1)
``Vol := epVolume(E2V,Volume)
``set_text(ShowVolume,Vol & ' mdb')
``DB := D.FmtVal(RoundDiv(Vol,100),1)
``set_text(ShowDB,DB & ' dB')
*end* on

I'm also attaching a demo .nki for you to try this out.

Rejoice,

Bob


----------



## TBAudio (Nov 15, 2012)

I am so blown away right now I can't properly express it. I was all over the map in my head, thinking even if it was possible that there would be no way to deal with the decimal without some crazy workaround. Yet there it is perfect ,precise, and clean.

There was a way to work around needing to translate to dB, but I still think this is cooler.

Hope my comment about your math lib didn't come across negative, I just need some more alone time with it. 

Thanks for being so exact and for this great example. It has opened my eyes to a few things.


----------



## Big Bob (Nov 16, 2012)

Hi TB,



> Hope my comment about your math lib didn't come across negative, I just need some more alone time with it.



No, not at all. I realize that math isn't everyone's favorite subject :lol: 

However, it occured to me after I posted the example and shut down last night that you might need to convert in the reverse direction also and I should have posted an example of that as well. I'll try to remedy that oversight now. :oops: 

In the following script, you can enter the desired Amp Volume in dB into the edit box and the group Volume knob should track with your edit box setting. I'm also attaching another demo instrument to illustrate this. Demo#2 has this script in slot 1 and the prior script with the slider and pair of labels in script slot 2.

*import* "KSPMathV450.txt"

*on init*
``message('')
``SetMathMode(0)
``*declare* ui_value_edit Volume (-1800,120,10)
``*declare* Vol
*end* on

*on ui_control* (Volume)
``Vol := epVolume(V2E,Volume*100)
``set_engine_par(ENGINE_PAR_VOLUME,Vol,0,-1,-1)
*end* on



Hope this helps.

God Bless,

Bob


----------



## TBAudio (Nov 16, 2012)

Just how... I.. don't understand...decimals in the value edit....you are breaking my head right now. I can't explain to you just how amazing I think what you've done here is.

You have gone above and beyond, for once I don't mind being wrong. I'll have to go thru my what can be done list and make a few changes.


----------



## Big Bob (Nov 16, 2012)

> you are breaking my head right now



Oh oh, maybe you had better give your head a rest for a while, I wouldn't want to be responsible for it exploding or imploding :lol: 

Anyway, I'm glad you found my examples helpful and I wish you the best with your project.

Rejoice,

Bob


----------



## Big Bob (Nov 17, 2012)

After thinking about your surprise that value edits can be used to input fractional values, it occured to me that it may not be generally too well known that edit boxes can also be used for output as well as input of fractional values. For example, with the following script, changing the amplifier volume will cause the edit box to show the same value and, alternatively, you can double-click the edit box and enter a decimal value and the amplifier volume will go to the same value.

*import* "KSPMathV450.txt"

*on init*
``message('')
``SetMathMode(0)
``*declare* ui_value_edit Volume (-1800,120,10)
``*declare* Vol
``*declare* Val
*end* on

*on ui_update*
``Val := epVolume(E2V,get_engine_par(ENGINE_PAR_VOLUME,0,-1,-1))
``Volume := RoundDiv(Val,100)
*end* on

*on ui_control* (Volume)
``Vol := epVolume(V2E,Volume*100)
``set_engine_par(ENGINE_PAR_VOLUME,Vol,0,-1,-1)
*end* on

As a final example to tie all this together, the following script has 3 controls on the script panel; an edit box, a knob, and a slider. Changing any of these causes the other panel controls and the amp volume knob to show the same dB value and vice versa.

*import* "KSPMathV450.txt"

*on init*
``message('')
``SetMathMode(PI)
``*declare* ui_value_edit VolEdit (-1800,120,10)
````set_text(VolEdit,'Vol in dB')
``*declare* ui_knob VolKnob (-1800,120,10)
````set_knob_unit(VolKnob,KNOB_UNIT_DB)
````set_text(VolKnob,'Volume')
``*declare* ui_slider VolSlide (-1800,120)
````move_control(VolSlide,3,1)
``*declare* ui_label ShowSlide(1,1)
````move_control(ShowSlide,3,2)
``*declare* Vol``_{ volume in dB scaled by 10 }_
*end* on

on_pgs_do_post(*call* get_amp_vol)

*on ui_update*
``*call* get_amp_vol
*end* on

*on ui_control* (VolEdit)
``Vol := VolEdit
``*call* update_panel
``*call* update_amp_volume
*end* on

*on ui_control* (VolKnob)
``Vol := VolKnob
``*call* update_panel
``*call* update_amp_volume
*end* on

*on ui_control* (VolSlide)
``Vol := VolSlide
``*call* update_panel
``*call* update_amp_volume
*end* on

*function* get_amp_vol
``Vol := epVolume(E2V,get_engine_par(ENGINE_PAR_VOLUME,0,-1,-1))
``Vol := RoundDiv(Vol,100)``
``*call* update_panel``
*end* *function*

*function* update_amp_volume
``*declare* ep
``ep := epVolume(V2E,Vol*100)
``set_engine_par(ENGINE_PAR_VOLUME,ep,0,-1,-1)``
*end* *function*

*function* update_panel
``*declare* @DB``_{ text form of Vol }_
``VolEdit := Vol 
``VolKnob := Vol
``VolSlide := Vol
``DB := D.FmtVal(Vol,1)
``set_knob_label(VolKnob,DB)
``set_text(ShowSlide,'Volume: ' & DB & ' dB')``
*end* *function*

This script also illustrates how to use the post-initialization option of the Math Library. The attached instrument file, DB-Demo#4 demonstrates this script in action.

Rejoice,

Bob


----------



## Casey Edwards (Nov 17, 2012)

Bob, I can't thank you enough for all of this! It was very generous of you to post such specific code. I'm going to figure out how to use all this inside my already existing code and label it as {Bob's chunk of genius.} :wink:


----------

