What's new

Kontakt: scripting specific release groups (SOLVED)

10Dman

New Member
Got a question about releases in KSP. So I'm trying to make the releases so that when group 1 has been played it will trigger on release group 2 no matter what, and the same pattern for the other groups. Got 8 groups in total. I believe it has to be scripted, or else the releases on chords just triggers a bunch of the other groups which it can't in this case.
What am I doing wrong here? Having a hard time understanding the KSP reference manual on these parameters, so any help would be greatly appreciated! The chord time tolerance script is from Nils Liberg originally posted on Native Instruments Kontakt forum, just need it to work with multiple groups with their respective release groups.
The comments in the on release part is just what I thought the code would do, but doesn't seem to do.

on init
declare $rr { round-robin state (range: 0-7) }
declare $last_note_time
declare const $CHORD_TIME_TOLERANCE := 25 { milliseconds }

end on

on note
{ go to next round-robin state if not too close in time to previous note }
if ($ENGINE_UPTIME - $last_note_time > $CHORD_TIME_TOLERANCE)
$rr := ($rr + 2) mod 8
$last_note_time := $ENGINE_UPTIME
end if

{ allow only the group with index corresponding to the RR state }
disallow_group($ALL_GROUPS)
allow_group($rr)
end on


on release
disallow_group($ALL_GROUPS)
allow_group(1)
allow_group(3)
allow_group(5)
allow_group(7)
if ($ENGINE_UPTIME - $last_note_time > $CHORD_TIME_TOLERANCE)
$last_note_time := $ENGINE_UPTIME
end if
if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,0) = 0) {if the note is from this group, 0 (which is group 1)}
set_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,0,1) {change the note destination to 1 (which is group 2, the release)}
play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0) {play the note in 1 (group 2, the release)}
end if

if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,2) = 2)
set_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,0,3)
play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)
end if

if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,4) = 4)
set_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,0,5)
play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)
end if

if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,6) = 6)
set_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,0,7)
play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)
end if

end on
 
Using disallow_group($ALL_GROUPS) resets the $EVENT_ID's $EVENT_PAR_ALLOW_GROUP status for some reason. One solution is to use disallow_group() after retrieving $EVENT_PAR_ALLOW_GROUP. Let me know if it works there.


Code:
on init
    message("")
    SET_CONDITION(NO_SYS_SCRIPT_RLS_TRIG)
    declare $rr { round-robin state (range: 0-7) }
    declare $last_note_time
    declare const $CHORD_TIME_TOLERANCE := 25 { milliseconds }

end on

on note
    { go to next round-robin state if not too close in time to previous note }
    if ($ENGINE_UPTIME - $last_note_time > $CHORD_TIME_TOLERANCE)
        $rr := ($rr + 2) mod 8
        $last_note_time := $ENGINE_UPTIME
    end if

    { allow only the group with index corresponding to the RR state }
    disallow_group($ALL_GROUPS)
    allow_group($rr)
end on


on release

    if ($ENGINE_UPTIME - $last_note_time > $CHORD_TIME_TOLERANCE)
        $last_note_time := $ENGINE_UPTIME
    end if

    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,0) = 1) {if the note is from this group, 0 (which is group 1)}
        disallow_group($ALL_GROUPS)
        allow_group(1)                                                                                            {change the note destination to 1 (which is group 2, the release)}
        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)                                     {play the note in 1 (group 2, the release)}
    end if

    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,2) = 1)
        disallow_group($ALL_GROUPS)
        allow_group(3)
        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)
    end if

    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,4) = 1)
        disallow_group($ALL_GROUPS)
        allow_group(5)
        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)
    end if

    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,6) = 1)
        disallow_group($ALL_GROUPS)
        allow_group(7)
        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)
    end if

end on
 
Using disallow_group($ALL_GROUPS) resets the $EVENT_ID's $EVENT_PAR_ALLOW_GROUP status for some reason. One solution is to use disallow_group() after retrieving $EVENT_PAR_ALLOW_GROUP. Let me know if it works there.

Thank you so much, it works great now! I tried it without the chord time tolerance part in the on release section and it as well, works just the same with or without it. Guess on doesn't need it when all the incoming notes are being sent to the right release groups anyways in the if statements.

Hmm, the =1) at the end of get_event_par_arr, what does that mean? Not sure I quite understand.
It's only in the manual in some examples, but couldn't find an explanation like the other 3 parameters.
 
=1) at the end of get_event_par_arr , what does that mean?

Let's say for each $EVENT_ID, certain groups are only allowed. get_event_par_arr() will let us know if a particular group is allowed for an event_id.

In our case, if(get....0) =1) means, if the group id '0' was allowed during the on note callback. If it was not allowed, then (get....0) =0.

Page no. 95 in KSP reference has a simple monitor example also.
 
@Suganthan Thanks for the explanation!
I've been trying to add another dimension to the script and wondering if you can see what I'm getting wrong here? Comments in the on controller and on note is just what I think it is doing like in the original post, and might be all wrong. It's currently not working.
What I'm trying to achieve here is when the sustain is on, the same group is retriggered when playing by not moving to the next RR/group. This is to be able to play polyphonic within the same group.


Code:
on init

    SET_CONDITION(NO_SYS_SCRIPT_RLS_TRIG)

    SET_CONDITION(NO_SYS_SCRIPT_PEDAL)

    declare $rr { round-robin state (range: 0-7) }

    declare $last_note_time

    declare const $CHORD_TIME_TOLERANCE := 50 { milliseconds }



    declare $sustain



end on



on note

    { go to next round-robin state if not too close in time to previous note }

    if ($sustain = 1) {sustain off}

        while ($ENGINE_UPTIME - $last_note_time > $CHORD_TIME_TOLERANCE)

            $rr := ($rr + 2) mod 8

            $last_note_time := $ENGINE_UPTIME

        end while

    end if



    if ($sustain = 0) {sustain on}

            $rr := ($rr + 0) mod 0 {sustain is on, the current group is not moving forward with RR}

    end if



    { allow only the group with index corresponding to the RR state }

    disallow_group($ALL_GROUPS)

    allow_group($rr)



end on



on controller

  if ($CC_NUM = 64) {sustain CC number}

    if (%CC[$CC_NUM] > 64) {if current CC value is higher than 64}

      $sustain := 0        {sustain is on}

    else

      $sustain := 1         {sustain is off}

    end if

      %CC[$CC_NUM] := 1 {if current CC value is exactly 64 the sustain is off, aka 1}

    end if

end on



on release



    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,0) = 1)

        disallow_group($ALL_GROUPS)

        allow_group(1)                     

        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)

    end if



    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,2) = 1)

        disallow_group($ALL_GROUPS)

        allow_group(3)

        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)

    end if



    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,4) = 1)

        disallow_group($ALL_GROUPS)

        allow_group(5)

        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)

    end if



    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,6) = 1)

        disallow_group($ALL_GROUPS)

        allow_group(7)

        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)

    end if



end on
 
You are almost there, I just had to remove some lines, etc. See if it works,

Code:
on init

    SET_CONDITION(NO_SYS_SCRIPT_RLS_TRIG)

    SET_CONDITION(NO_SYS_SCRIPT_PEDAL)

    declare $rr { round-robin state (range: 0-7) }

    declare $last_note_time

    declare const $CHORD_TIME_TOLERANCE := 50 { milliseconds }

    declare $sustain

end on

on persistence_changed 

    if (%CC[64] > 64)        {updates the sustain value after the patch loading}

        $sustain := 0        {sustain is on}

    else

        $sustain := 1         {sustain is off}

    end if

end on

on note


    if ($sustain = 1) {if only sustain is off, change rr}

        if ($ENGINE_UPTIME - $last_note_time > $CHORD_TIME_TOLERANCE)    { go to next round-robin state if not too close in time to previous note }

            $rr := ($rr + 2) mod 8

            $last_note_time := $ENGINE_UPTIME

        end if

    end if


    disallow_group($ALL_GROUPS)

    allow_group($rr)

end on



on controller

      if ($CC_NUM = 64) {sustain CC number}

        if (%CC[$CC_NUM] > 64) {if current CC value is higher than 64}

            $sustain := 0        {sustain is on}

        else

            $sustain := 1         {sustain is off}

        end if

    end if

end on



on release


    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,0) = 1)

        disallow_group($ALL_GROUPS)

        allow_group(1)                     

        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)

    end if



    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,2) = 1)

        disallow_group($ALL_GROUPS)

        allow_group(3)

        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)

    end if



    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,4) = 1)

        disallow_group($ALL_GROUPS)

        allow_group(5)

        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)

    end if



    if (get_event_par_arr($EVENT_ID,$EVENT_PAR_ALLOW_GROUP,6) = 1)

        disallow_group($ALL_GROUPS)

        allow_group(7)

        play_note ($EVENT_NOTE,$EVENT_VELOCITY,0,0)

    end if


end on


This can be further written shortly. I think, It is not going to make any significant improvements here, but anyway. Here is my attempt to short it,

Code:
on init

    message("")
    SET_CONDITION(NO_SYS_SCRIPT_RLS_TRIG)
    SET_CONDITION(NO_SYS_SCRIPT_PEDAL)

    declare $rr := 0 { round-robin state (range: 0-7) }
    declare $last_note_time
    declare const $CHORD_TIME_TOLERANCE := 50 { milliseconds }
    declare $i

end on

on note

    if ( ($ENGINE_UPTIME - $last_note_time > $CHORD_TIME_TOLERANCE) and (%CC[64] <= 64) )    { go to next round-robin state if not too close in time to previous note and if sustain is off}

        $rr := ($rr + 2) mod 8
        $last_note_time := $ENGINE_UPTIME

    end if

    disallow_group($ALL_GROUPS)
    allow_group($rr)

end on


on release

    $i := 0

    while ($i<=6)

        if (get_event_par_arr ($EVENT_ID, $EVENT_PAR_ALLOW_GROUP, $i) = 1)

            disallow_group ($ALL_GROUPS)
            allow_group ($i + 1)
            play_note ($EVENT_NOTE, $EVENT_VELOCITY, 0, 0)
            $i := 10

        end if

        $i := $i + 2

    end while

end on
 
@Suganthan Works perfectly now! Thank you very much for the help!
Some really nice tools I'll be sure to keep in mind for the future when scripting.
Gonna have to study the on release in the last example, as I don't quite understand what's going on yet.
 
Question: I dont have a sustain-pedal. So...is CC "64" the standard-cc for sustain-pedals? I want to setup my korg nanokontrol 2 with it to use sustain.
 
Question: I dont have a sustain-pedal. So...is CC "64" the standard-cc for sustain-pedals? I want to setup my korg nanokontrol 2 with it to use sustain.

Yep! CC “64” is the standard cc assignment for sustain pedals. Values below 63 indicate the sustain pedal is off and values above indicate it is on.
 
Top Bottom