# Why isn't sin() function working in KSP?

Member Posts: 20 Member
edited January 4

I have `\$v := (sin((\$v/10)-8)+1)/2`in the script below. But the `sin(x)` function isn't working despite `sin(x)` being in the KSP manual. In fact, none of the trigonometric functions appear to be working, at least in a `note on` without some special activating code or something NOT described in the KSP manual.

```on init
set_script_title("Humanize Timing & Velocity")

declare ui_knob \$Timing (0,100,1)
set_knob_unit (\$Timing, \$KNOB_UNIT_PERCENT)
set_text (\$Timing,"Note On")
\$Timing := 0
make_persistent (\$Timing)
move_control (\$Timing,3,2)
declare \$new_event

declare ui_knob \$v (0,100,1)
set_knob_unit (\$v, \$KNOB_UNIT_PERCENT)
set_text (\$v,"Velocity")
\$v := 0
make_persistent (\$v)
move_control (\$v,4,2)
end on

on note
ignore_event(\$EVENT_ID)
wait(random(0, \$Timing * 1000))
\$new_event := play_note(\$EVENT_NOTE, \$EVENT_VELOCITY, 0, -1)

if(\$EVENT_VELOCITY > 1)
\$v := \$EVENT_VELOCITY + (random(-\$v,\$v))
if (\$v >= 96)
\$v := (sin((\$v/10)-8)+1)/2
end if
change_velo(\$new_event, \$v)
end if
end on
```

• Moderator Posts: 1,018 mod

Please post the code. You cannot mix floating point and integer variables in one statement, you have to use the casting operators (`real()` and `int()`) as needed.

• Member Posts: 20 Member

I have not been able to get ANY of the advanced functions (sin, cosine, power, exponents, sqrt etc) and I have no idea why. Went with a different approach and settled on linear equations. At velocities below 32, the "eccentricity" of the randomness added to the velocity linearly decreases, and same thing for 96 and up. This makes writing for low dynamics more realistic, and makes writing for high dynamics more predictable.

I don't know if posting this is even allowed, but this is actually an edited version of the Humanize script that comes with Kontakt. The only problem is the stock script is flawed. If more than one note is played at the same time, the velocity randomness is applied to all notes equally. This means that if you have different dynamics in each hand of a marimba for example, they will all be stuck to one dynamic. That's fixed with this.

The other functions are omitted (pan, volume, tune) since they're not useful for percussion stationary acoustic percussion.

I'm not a programmer by any means so use at your own risk.

```on init
set_script_title("Humanize Timing & Velocity")

declare ui_knob \$Timing (0,100,1)
set_knob_unit (\$Timing, \$KNOB_UNIT_PERCENT)
set_text (\$Timing,"Note On")
\$Timing := 0
make_persistent (\$Timing)
move_control (\$Timing,3,2)
declare \$new_event

declare ui_knob \$e (0,100,1) {velocity eccentricity}
set_knob_unit (\$e, \$KNOB_UNIT_PERCENT)
set_text (\$e,"V Eccen.")
\$e := 0
make_persistent (\$e)
move_control (\$e,4,2)
declare \$v
declare \$m {-minimum, maximum}
end on

on note
ignore_event(\$EVENT_ID)
wait(random(0, \$Timing * 1000))
\$new_event := play_note(\$EVENT_NOTE, \$EVENT_VELOCITY, 0, -1)

\$v := \$EVENT_VELOCITY
\$m := 127
if(\$v <= 32)
\$m := 127 / 31 * \$v - 127 / 31
end if
if(\$v >= 96)
\$m := 127 / -31 * \$v + 127 * 127 / 31
end if
change_velo(\$new_event, \$v + random(-\$m, \$m) * \$e / 200)
end on
```
• Moderator Posts: 1,018 mod

• Member Posts: 20 Member

Thanks for your response, EvilDragon. I did try this and still getting the "expression expected" error.

• Moderator Posts: 1,018 mod

Please post the code. You cannot mix floating point and integer variables in one statement, you have to use the casting operators (`real()` and `int()`) as needed.

• Member Posts: 20 Member

This got me there! The script below is non-working because I just tested your advice and will incorporate it into a working script later. But no error finally! The only thing that worked however for me was `real_to_int(sin(~z))  `

`real(sin(~z))` and `int(sin(~z))`still produced the expression expected error. I'm on K6, is this perhaps a K7+ thing?

Is there any plan in the cue to make KSP more flexible, like how javascript can be? I don't understand practically why integers and real numbers cannot be mixed without "assistance" in KSP when they can be all other languages I've encountered. This is just one example.

Another would be, why do variables need to be declared at all, and especially in the on init? Why can't they just be defined where needed and the definition acts as the declaration?

Thanks again, EvilDragon!

```on init
set_script_title("Humanize Timing & Velocity")
declare ui_knob \$t {timing} (0,100,1)
set_knob_unit (\$t, \$KNOB_UNIT_PERCENT)
set_text (\$t,"Note On")
\$t := 0
make_persistent (\$t)
move_control (\$t,3,2)
declare \$n {new event}
declare ui_knob \$e (0,100,1) {velocity eccentricity}
set_knob_unit (\$e, \$KNOB_UNIT_PERCENT)
set_text (\$e,"V Eccen.")
\$e := 0
make_persistent (\$e)
move_control (\$e,4,2)
declare \$v
declare \$m := 127 {-minimum, maximum}
declare ~z
end on

on note
ignore_event(\$EVENT_ID)
wait(random(0, \$t * 1000))
\$n := play_note(\$EVENT_NOTE, \$v, 0, -1)
\$v := \$EVENT_VELOCITY
if(\$v < 32)
\$m := 127 / 31 * \$v - 127 / 31
end if
if(\$v > 96)
\$m := {127 / -31 * \$v + 127 * 127 / 31} real_to_int(sin(~z))
end if
change_velo(\$n, \$v + random(-\$m, \$m) * \$e / 200)
end on
```
• Moderator Posts: 1,018 mod
edited January 10

KSP is never going to be like JavaScript, sorry to say. It is a realtime executed language and it has to react fast and with a hard deadline to comply with the audio buffer (it's ran in the realtime audio thread), hence why you need to declare variables in init (which basically means: when script is parsed, in order to preallocate enough memory to be used in advance).

BTW note that if you just convert sin(x) to integer, you will just get 0 or 1. You need to scale the result up to the range you need, before casting it back to integer.

• Member Posts: 20 Member

All makes sense. Thanks once again. Take care of yourself.