# Kontakt Factory "Interval" script for different groups



## DJN (Jun 20, 2021)

> Hello,
> 
> I am using the Kontakt factory 'Interval' script on a instrument with 2 groups. It works great on both groups, but I would like to be able to change (duplicate?) the script, so that I can apply the effect to each group separately. One set of controls for group 1, and a separate set of controls for group 2.
> 
> I am a beginner at Kontakt scripting, so any help will be greatly appreciated!


----------



## A.G (Jun 20, 2021)

The easiest way is to make a minor modification (see below) of this factory script and load the modifications in KSP Slot 1 and Slot 2.

1. Load the factory script in Slot 1, click the "Edit" button and copy paste the following code right under the on note callback.



> disallow_group(find_group("Gr1_name"))
> allow_group(find_group("Gr2_name"))



NOTE: Rename "Gr1_name" and "Gr2_name" according to your Group names (I do not have an idea of your Group names).

2. Load the factory script in Slot 2 and insert the reversed Group code:



> disallow_group(find_group("Gr2_name"))
> allow_group(find_group("Gr1_name"))


Rename the groups accordingly.

BTW. It is a good idea to store Slot 1 as an user preset named say "Interval Gr.1" and the second slot with user name "Interval Gr.2".


----------



## DJN (Jun 20, 2021)

A.G said:


> The easiest way is to make a minor modification (see below) of this factory script and load the modifications in KSP Slot 1 and Slot 2.
> 
> 1. Load the factory script in Slot 1, click the "Edit" button and copy paste the following code right under the on note callback.
> 
> ...


Hi A.G,
Thank you for your reply and taking the time to provide your example. I just tried it and the result is only one (of the two) groups plays. I'm assuming this is a result of using the allow/disallow groups. Is there a way to apply the effect on each group separately, and still allow both groups to play at the same time?
Thanks again for your help!


----------



## A.G (Jun 21, 2021)

DJN said:


> Is there a way to apply the effect on each group separately, and still allow both groups to play at the same time?


Hi, you are right. I'm on a business trip having no music equipment so I improvised yesterday.
I think I have an idea where is the problem. In my previous post the script Slots 1 & 2 are routed serially, that's why the scheme did not work.

Now try a MIDI parallel input routing by following the instructions below:

1. Remove the 2nd Script slot and save your Kontakt instrument (with the two groups) if you have not stored it by now. I.e the instrument must has only only a script "Interval" insert!

2. Load the same instrument into Kontakt and set its MIDI Channel to the same Ch.# as the 1st instrument (or set both instruments to "omni" channel). When you play a Note on your external keyboard or via your DAW then both instruments must play in parallel.

3. Go to the 1st Instrument script and paste the following code under on note:
disallow_group($ALL_GROUPS)
allow_group(0)

4. Go to the 2nd Instrument script and paste the following code under on note:
disallow_group($ALL_GROUPS)
allow_group(1)

Now you might be able to control the "Interval" script UI separately and having separate Volume, Pan, FX for each instrument. I.e the original "Groups" will behave as separate instruments where you have a lot of user control possibilities.

You can also keep using the original "Interval" script without inserting (allow/disallow) code, just by deleting or soloing the opposite groups in both instruments.

BTW. Inserting the same Instrument multiple times into Kontakt does not get more RAM. For example, if the Instrument is 150MB and you load it 5 times, then Kontakt will get only 150MB (all copies will work as Instrument aliases).


----------



## DJN (Jun 21, 2021)

Thanks for the suggestion and your continued help finding a solution! If I can avoid it I would not like to have to load two separate instruments. There must be a way of doing this in a single instrument. Here is a suggested script that gets me a little closer, but I can't seem to get it working?

CODE:
{***********************************************
Interval
Author: Native Instruments
Written by: Nicki Marinic
Modified: Aug 10, 2009
*************************************************}

on init
message("")
make_perfview
set_script_title("Interval")
set_ui_height_px(200)

declare !interval_names[14]
!interval_names[0] := "Unison"
!interval_names[1] := "mi 2nd"
!interval_names[2] := "2nd"
!interval_names[3] := "mi 3rd"
!interval_names[4] := "3rd"
!interval_names[5] := "4th"
!interval_names[6] := "+ 4th"
!interval_names[7] := "5th"
!interval_names[8] := "mi 6th"
!interval_names[9] := "6th"
!interval_names[10] := "mi 7th"
!interval_names[11] := "7th"
!interval_names[12] := "8ve"

declare $new_noteA
declare $new_velocityA
declare $new_idA

declare $new_noteB
declare $new_velocityB
declare $new_idB

declare ui_knob $interval_knob(-12,12,1)
set_text ($interval_knob,"Interval")
set_knob_defval($interval_knob,0)
$interval_knob := 7
set_knob_label($interval_knob,!Interval_names[abs($interval_knob)]) 
make_persistent($interval_knob)
set_control_help ($interval_knob,"Interval A: Sets the interval of the second note.")

declare ui_knob $interval_knob2(-12,12,1)
set_text ($interval_knob2,"Interval")
set_knob_defval($interval_knob2,0)
$interval_knob2 := 7
set_knob_label($interval_knob2,!Interval_names[abs($interval_knob)]) 
make_persistent($interval_knob2)
set_control_help ($interval_knob2,"Interval B: Sets the interval of the second note.")

declare ui_knob $octave_knob(-10,10,1)
set_text ($octave_knob,"Octave")
set_knob_unit($octave_knob,$KNOB_UNIT_OCT)
set_knob_defval($octave_knob,0)
$octave_knob := 0
make_persistent($octave_knob)
set_control_help ($octave_knob,"Octave A: Sets the octave offset of the second note.")

declare ui_knob $octave_knob2(-10,10,1)
set_text ($octave_knob2,"Octave")
set_knob_unit($octave_knob2,$KNOB_UNIT_OCT)
set_knob_defval($octave_knob2,0)
$octave_knob2 := 0
make_persistent($octave_knob2)
set_control_help ($octave_knob2,"Octave B: Sets the octave offset of the second note.")

declare ui_knob $velocity_knob(1,200,1)
set_text ($velocity_knob,"Velocity")
set_knob_unit($velocity_knob,$KNOB_UNIT_PERCENT)
set_knob_defval($velocity_knob,100)
$velocity_knob := 100
make_persistent($velocity_knob)
set_control_help ($velocity_knob,"Velocoty A: Sets the velocity of the second note as a percentage of the played velocity.")

declare ui_knob $velocity_knob2(1,200,1)
set_text ($velocity_knob2,"Velocity")
set_knob_unit($velocity_knob2,$KNOB_UNIT_PERCENT)
set_knob_defval($velocity_knob2,100)
$velocity_knob2 := 100
make_persistent($velocity_knob2)
set_control_help ($velocity_knob2,"Velocoty B: Sets the velocity of the second note as a percentage of the played velocity.")

move_control($interval_knob,2,4)
move_control($octave_knob,3,4)
move_control($velocity_knob,5,4)

move_control($interval_knob2,2,6)
move_control($octave_knob2,3,6)
move_control($velocity_knob2,5,6)


declare const $G_FIRST := 0 {6 groups}
declare const $G_LAST := 5
declare $i

declare ui_menu $group_menuA {Creating Menu A }
declare ui_menu $group_menuB {Creating Menu B }

$i:= $G_FIRST
while ($i < $NUM_GROUPS - 3)
add_menu_item ($group_menuA,group_name($i),$i)
inc($i)
end while
$i:= 3
while ($i < $NUM_GROUPS)
add_menu_item ($group_menuB,group_name($i),$i)
inc($i)
end while

declare ui_switch $PrevMenuA
declare ui_switch $NextMenuA 
declare ui_switch $PrevMenuB
declare ui_switch $NextMenuB

read_persistent_var($interval_knob)
read_persistent_var($interval_knob2)

set_knob_label($interval_knob,!Interval_names[abs($interval_knob)]) 
set_knob_label($interval_knob2,!Interval_names[abs($interval_knob2)]) 
end on

on note

{A}
$new_noteA:= $EVENT_NOTE + $interval_knob+($octave_knob*12)
$new_noteB:= $EVENT_NOTE + $interval_knob2+($octave_knob2*12)

if ($new_noteA < 0 or $new_noteB < 0)
$new_noteA := 0
$new_noteB := 0
end if
if ($new_noteA > 127 or $new_noteB > 127)
$new_noteA := 127
$new_noteB := 127
end if

$new_velocityA := ($EVENT_VELOCITY*$velocity_knob)/100
$new_velocityB := ($EVENT_VELOCITY*$velocity_knob2)/100

if ($new_velocityA < 1 or $new_velocityB < 1)
$new_velocityA := 1
$new_velocityB := 1
end if
if ($new_velocityA > 127 or $new_velocityB > 127)
$new_velocityA:= 127
$new_velocityB:= 127
end if

$new_idA := play_note($new_noteA,$new_velocityA,0,-1)
change_vol($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_VOLUME),1)
change_tune($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_TUNE),1)
change_pan($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_PAN),1)

$new_idB := play_note($new_noteB,$new_velocityB,0,-1)
change_vol($new_idB,get_event_par($EVENT_ID,$EVENT_PAR_VOLUME),1)
change_tune($new_idB,get_event_par($EVENT_ID,$EVENT_PAR_TUNE),1)
change_pan($new_idB,get_event_par($EVENT_ID,$EVENT_PAR_PAN),1)

end on

on ui_control ($interval_knob)
set_knob_label($interval_knob,!Interval_names[abs($interval_knob)])
end on

on ui_control ($interval_knob2)
set_knob_label($interval_knob2,!Interval_names[abs($interval_knob2)])
end on

on ui_control($PrevMenuA)
$group_menuA := (get_control_par(get_ui_id($group_menuA),$CONTROL_PAR_NUM_ITEMS)+$group_menuA-1) mod get_control_par(get_ui_id($group_menuA),$CONTROL_PAR_NUM_ITEMS)
$PrevMenuA := 0
end on

on ui_control($PrevMenuB)
$group_menuB := (get_control_par(get_ui_id($group_menuB),$CONTROL_PAR_NUM_ITEMS)+$group_menuB-1) mod get_control_par(get_ui_id($group_menuB),$CONTROL_PAR_NUM_ITEMS) + 3
$PrevMenuB := 0
end on

on ui_control($NextMenuA)
$group_menuA := ($group_menuA+1) mod get_control_par(get_ui_id($group_menuA),$CONTROL_PAR_NUM_ITEMS)
$NextMenuA := 0
end on

on ui_control($NextMenuB)
$group_menuB := ($group_menuB+1) mod get_control_par(get_ui_id($group_menuB),$CONTROL_PAR_NUM_ITEMS) + 3
$NextMenuB := 0
end on

on ui_control ($group_menuA) {Group Purge }
$i := 0
while ($i<=$G_LAST - 3)
purge_group($i,0)
inc($i)
end while
purge_group($group_menuA,1)
end on

on ui_control ($group_menuB) {Group Purge }
$i := 3
while ($i<=$G_LAST)
purge_group($i,0)
inc($i)
end while
purge_group($group_menuB,1)
end on


----------



## A.G (Jun 21, 2021)

DJN said:


> There must be a way of doing this in a single instrument. Here is a suggested script that gets me a little closer, but I can't seem to get it working?


Heh, I see that you want to learn KSP - congratulations!

You tried to duplicate A/B the code but it is not enough (specially for the Note callback) where you need groups indefication.

Well, I could recreate this script and optimize it a lot, however I decided to make an educational version for you so you can see what is changed. Note, I added "orig" variables to be able to "play" the original Note after its group is disallowed. You can check if all is OK by selecting and soloing the groups. Here is the new code:


```
{***********************************************
Interval DUO
Author: Native Instruments
Written by: Nicki Marinic
Modified: June 21, 2021
*************************************************}

on init
message("")
make_perfview
set_script_title("Interval")
set_ui_height_px(200)

declare !interval_names[14]
!interval_names[0] := "Unison"
!interval_names[1] := "mi 2nd"
!interval_names[2] := "2nd"
!interval_names[3] := "mi 3rd"
!interval_names[4] := "3rd"
!interval_names[5] := "4th"
!interval_names[6] := "+ 4th"
!interval_names[7] := "5th"
!interval_names[8] := "mi 6th"
!interval_names[9] := "6th"
!interval_names[10] := "mi 7th"
!interval_names[11] := "7th"
!interval_names[12] := "8ve"

declare $orig_noteA
declare $new_noteA
declare $orig_velocityA
declare $new_velocityA
declare $orig_idA
declare $new_idA

declare $orig_noteB
declare $new_noteB
declare $orig_velocityB
declare $new_velocityB
declare $orig_idB
declare $new_idB

declare ui_knob $interval_knob(-12,12,1)
set_text ($interval_knob,"Interval")
set_knob_defval($interval_knob,0)
$interval_knob := 7
set_knob_label($interval_knob,!Interval_names[abs($interval_knob)])
make_persistent($interval_knob)
set_control_help ($interval_knob,"Interval A: Sets the interval of the second note.")

declare ui_knob $interval_knob2(-12,12,1)
set_text ($interval_knob2,"Interval")
set_knob_defval($interval_knob2,0)
$interval_knob2 := 7
set_knob_label($interval_knob2,!Interval_names[abs($interval_knob)])
make_persistent($interval_knob2)
set_control_help ($interval_knob2,"Interval B: Sets the interval of the second note.")

declare ui_knob $octave_knob(-10,10,1)
set_text ($octave_knob,"Octave")
set_knob_unit($octave_knob,$KNOB_UNIT_OCT)
set_knob_defval($octave_knob,0)
$octave_knob := 0
make_persistent($octave_knob)
set_control_help ($octave_knob,"Octave A: Sets the octave offset of the second note.")

declare ui_knob $octave_knob2(-10,10,1)
set_text ($octave_knob2,"Octave")
set_knob_unit($octave_knob2,$KNOB_UNIT_OCT)
set_knob_defval($octave_knob2,0)
$octave_knob2 := 0
make_persistent($octave_knob2)
set_control_help ($octave_knob2,"Octave B: Sets the octave offset of the second note.")

declare ui_knob $velocity_knob(1,200,1)
set_text ($velocity_knob,"Velocity")
set_knob_unit($velocity_knob,$KNOB_UNIT_PERCENT)
set_knob_defval($velocity_knob,100)
$velocity_knob := 100
make_persistent($velocity_knob)
set_control_help ($velocity_knob,"Velocoty A: Sets the velocity of the second note as a percentage of the played velocity.")

declare ui_knob $velocity_knob2(1,200,1)
set_text ($velocity_knob2,"Velocity")
set_knob_unit($velocity_knob2,$KNOB_UNIT_PERCENT)
set_knob_defval($velocity_knob2,100)
$velocity_knob2 := 100
make_persistent($velocity_knob2)
set_control_help ($velocity_knob2,"Velocoty B: Sets the velocity of the second note as a percentage of the played velocity.")

move_control($interval_knob,2,4)
move_control($octave_knob,3,4)
move_control($velocity_knob,5,4)

move_control($interval_knob2,2,6)
move_control($octave_knob2,3,6)
move_control($velocity_knob2,5,6)


declare const $G_FIRST := 0 {6 groups}
declare const $G_LAST := 5
declare $i

declare ui_menu $group_menuA {Creating Menu A }
declare ui_menu $group_menuB {Creating Menu B }

$i:= $G_FIRST
while ($i < $NUM_GROUPS - 3)
add_menu_item ($group_menuA,group_name($i),$i)
inc($i)
end while
$i:= 3
while ($i < $NUM_GROUPS)
add_menu_item ($group_menuB,group_name($i),$i)
inc($i)
end while

declare ui_switch $PrevMenuA
declare ui_switch $NextMenuA
declare ui_switch $PrevMenuB
declare ui_switch $NextMenuB

read_persistent_var($interval_knob)
read_persistent_var($interval_knob2)

set_knob_label($interval_knob,!Interval_names[abs($interval_knob)])
set_knob_label($interval_knob2,!Interval_names[abs($interval_knob2)])
end on

on note
        $orig_noteA:=$EVENT_NOTE
        $new_noteA:= $EVENT_NOTE + $interval_knob+($octave_knob*12)
      
        if ($new_noteA < 0)
            $new_noteA := 0
        end if
        if ($new_noteA > 127)
            $new_noteA := 127
        end if
      
        $orig_velocityA:= $EVENT_VELOCITY
        $new_velocityA := ($EVENT_VELOCITY*$velocity_knob)/100
                  
        if ($new_velocityA < 1)
            $new_velocityA := 1
        end if
        if ($new_velocityA > 127)
            $new_velocityA := 127
        end if
      
    disallow_group($ALL_GROUPS)
    allow_group(0)
        $orig_idA:= play_note($orig_noteA,$orig_velocityA,0,-1)
        $new_idA := play_note($new_noteA,$new_velocityA,0,-1)
        change_vol($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_VOLUME),1)
        change_tune($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_TUNE),1)
        change_pan($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_PAN),1)

{***************************************}

        $orig_noteB:=$EVENT_NOTE
        $new_noteB:= $EVENT_NOTE + $interval_knob2+($octave_knob2*12)

        if ($new_noteB < 0)
            $new_noteB := 0
        end if
        if ($new_noteB > 127)
            $new_noteB := 127
        end if
      
        $orig_velocityB:= $EVENT_VELOCITY
        $new_velocityB := ($EVENT_VELOCITY*$velocity_knob2)/100
                  
        if ($new_velocityB < 1)
            $new_velocityB := 1
        end if
        if ($new_velocityB > 127)
            $new_velocityB := 127
        end if

            disallow_group($ALL_GROUPS)
    allow_group(1)
        $orig_idB:= play_note($orig_noteB,$orig_velocityB,0,-1)
        $new_idB := play_note($new_noteB,$new_velocityB,0,-1)
        change_vol($new_idB,get_event_par($EVENT_ID,$EVENT_PAR_VOLUME),1)
        change_tune($new_idB,get_event_par($EVENT_ID,$EVENT_PAR_TUNE),1)
        change_pan($new_idB,get_event_par($EVENT_ID,$EVENT_PAR_PAN),1)
end on

on ui_control ($interval_knob)
set_knob_label($interval_knob,!Interval_names[abs($interval_knob)])
end on

on ui_control ($interval_knob2)
set_knob_label($interval_knob2,!Interval_names[abs($interval_knob2)])
end on

on ui_control($PrevMenuA)
$group_menuA := (get_control_par(get_ui_id($group_menuA),$CONTROL_PAR_NUM_ITEMS)+$group_menuA-1) mod get_control_par(get_ui_id($group_menuA),$CONTROL_PAR_NUM_ITEMS)
$PrevMenuA := 0
end on

on ui_control($PrevMenuB)
$group_menuB := (get_control_par(get_ui_id($group_menuB),$CONTROL_PAR_NUM_ITEMS)+$group_menuB-1) mod get_control_par(get_ui_id($group_menuB),$CONTROL_PAR_NUM_ITEMS) + 3
$PrevMenuB := 0
end on

on ui_control($NextMenuA)
$group_menuA := ($group_menuA+1) mod get_control_par(get_ui_id($group_menuA),$CONTROL_PAR_NUM_ITEMS)
$NextMenuA := 0
end on

on ui_control($NextMenuB)
$group_menuB := ($group_menuB+1) mod get_control_par(get_ui_id($group_menuB),$CONTROL_PAR_NUM_ITEMS) + 3
$NextMenuB := 0
end on

on ui_control ($group_menuA) {Group Purge }
$i := 0
while ($i<=$G_LAST - 3)
purge_group($i,0)
inc($i)
end while
purge_group($group_menuA,1)
end on

on ui_control ($group_menuB) {Group Purge }
$i := 3
while ($i<=$G_LAST)
purge_group($i,0)
inc($i)
end while
purge_group($group_menuB,1)
end on
```


----------



## DJN (Jun 21, 2021)

Hi A.G!
Thank you, this a HUGE help! Not only for making it work, but also walking me through my first steps into Kontakt scripting (I've got a lot of catching up to do!). I'll A/B the codes to see and try to understand what changes you made and why. Once I get a grip on how you did this, then I can venture into ways of optimizing the code (baby steps).

I really appreciate you taking the time and effort to help, thank you so much!


----------



## DJN (Jun 22, 2021)

Hey A.G,
I was able to create a new instrument using the script you provided, the effect on each individual group works as expected, with one possible issue.

It sounds to me like the 'original note' is being doubled when the script is active. Can you please confirm this? I'm using a heavy synth sound, and the volume of the original note seems to increase with an active script, no matter where the value knobs are set. While bypassing the script I can hear the difference in volume.

When you have time please let me know your thoughts and confirmation whether this 'doubling' is happening. Thank you again for all your help!


----------



## EvilDragon (Jun 22, 2021)

Yes, you're missing an ignore_event($EVENT_ID) at the beginning of note callback.


----------



## DJN (Jun 22, 2021)

EvilDragon said:


> Yes, you're missing an ignore_event($EVENT_ID) at the beginning of note callback.


Thank you!!!
Question - I insert this only once, right after 'on note' callback?


----------



## EvilDragon (Jun 22, 2021)

Yes, in this case.


----------



## DJN (Jun 22, 2021)

EvilDragon said:


> Yes, in this case.


Thank you for your help!!
Is it true that when all the knobs are set at 12 o'clock (interval=Unison, octave=0, velocity=100%) this is still producing a 'double' (unison) of the original note? I would like to have a setting that will bypass the effect, until I make a change up or down, is this possible?

Here is the current updated code I'm working with:

{***********************************************
Interval DUO
Author: Native Instruments
Written by: Nicki Marinic
Modified: June 21, 2021
*************************************************}

on init
message("")
make_perfview
set_script_title("Interval")
set_ui_height_px(200)

declare !interval_names[14]
!interval_names[0] := "Unison"
!interval_names[1] := "mi 2nd"
!interval_names[2] := "2nd"
!interval_names[3] := "mi 3rd"
!interval_names[4] := "3rd"
!interval_names[5] := "4th"
!interval_names[6] := "+ 4th"
!interval_names[7] := "5th"
!interval_names[8] := "mi 6th"
!interval_names[9] := "6th"
!interval_names[10] := "mi 7th"
!interval_names[11] := "7th"
!interval_names[12] := "8ve"

declare $orig_noteA
declare $new_noteA
declare $orig_velocityA
declare $new_velocityA
declare $orig_idA
declare $new_idA

declare $orig_noteB
declare $new_noteB
declare $orig_velocityB
declare $new_velocityB
declare $orig_idB
declare $new_idB

declare ui_knob $intervalA(-12,12,1)
set_text ($intervalA,"Interval")
set_knob_defval($intervalA,0)
$intervalA := 7
set_knob_label($intervalA,!Interval_names[abs($intervalA)])
make_persistent($intervalA)
set_control_help ($intervalA,"Interval A: Sets the interval of the second note.")

declare ui_knob $intervalB(-12,12,1)
set_text ($intervalB,"Interval")
set_knob_defval($intervalB,0)
$intervalB := 7
set_knob_label($intervalB,!Interval_names[abs($intervalB)])
make_persistent($intervalB)
set_control_help ($intervalB,"Interval B: Sets the interval of the second note.")

declare ui_knob $octaveA(-10,10,1)
set_text ($octaveA,"Octave")
set_knob_unit($octaveA,$KNOB_UNIT_OCT)
set_knob_defval($octaveA,0)
$octaveA := 0
make_persistent($octaveA)
set_control_help ($octaveA,"Octave A: Sets the octave offset of the second note.")

declare ui_knob $octaveB(-10,10,1)
set_text ($octaveB,"Octave")
set_knob_unit($octaveB,$KNOB_UNIT_OCT)
set_knob_defval($octaveB,0)
$octaveB := 0
make_persistent($octaveB)
set_control_help ($octaveB,"Octave B: Sets the octave offset of the second note.")

declare ui_knob $velocityA(1,200,1)
set_text ($velocityA,"Velocity")
set_knob_unit($velocityA,$KNOB_UNIT_PERCENT)
set_knob_defval($velocityA,100)
$velocityA := 100
make_persistent($velocityA)
set_control_help ($velocityA,"Velocoty A: Sets the velocity of the second note as a percentage of the played velocity.")

declare ui_knob $velocityB(1,200,1)
set_text ($velocityB,"Velocity")
set_knob_unit($velocityB,$KNOB_UNIT_PERCENT)
set_knob_defval($velocityB,100)
$velocityB := 100
make_persistent($velocityB)
set_control_help ($velocityB,"Velocoty B: Sets the velocity of the second note as a percentage of the played velocity.")

move_control($intervalA,2,4)
move_control($octaveA,3,4)
move_control($velocityA,5,4)

move_control($intervalB,2,6)
move_control($octaveB,3,6)
move_control($velocityB,5,6)

read_persistent_var($intervalA)
read_persistent_var($intervalB)

set_knob_label($intervalA,!Interval_names[abs($intervalA)])
set_knob_label($intervalB,!Interval_names[abs($intervalB)])
end on

on note
ignore_event($EVENT_ID)

$orig_noteA:=$EVENT_NOTE
$new_noteA:= $EVENT_NOTE + $intervalA+($octaveA*12)

if ($new_noteA < 0)
$new_noteA := 0
end if
if ($new_noteA > 127)
$new_noteA := 127
end if

$orig_velocityA:= $EVENT_VELOCITY
$new_velocityA := ($EVENT_VELOCITY*$velocityA)/100

if ($new_velocityA < 1)
$new_velocityA := 1
end if
if ($new_velocityA > 127)
$new_velocityA := 127
end if

disallow_group($ALL_GROUPS)
allow_group(0)
$orig_idA:= play_note($orig_noteA,$orig_velocityA,0,-1)
$new_idA := play_note($new_noteA,$new_velocityA,0,-1)
change_vol($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_VOLUME),1)
change_tune($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_TUNE),1)
change_pan($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_PAN),1)

{***************************************}

$orig_noteB:=$EVENT_NOTE
$new_noteB:= $EVENT_NOTE + $intervalB+($octaveB*12)

if ($new_noteB < 0)
$new_noteB := 0
end if
if ($new_noteB > 127)
$new_noteB := 127
end if

$orig_velocityB:= $EVENT_VELOCITY
$new_velocityB := ($EVENT_VELOCITY*$velocityB)/100

if ($new_velocityB < 1)
$new_velocityB := 1
end if
if ($new_velocityB > 127)
$new_velocityB := 127
end if

disallow_group($ALL_GROUPS)
allow_group(1)
$orig_idB:= play_note($orig_noteB,$orig_velocityB,0,-1)
$new_idB := play_note($new_noteB,$new_velocityB,0,-1)
change_vol($new_idB,get_event_par($EVENT_ID,$EVENT_PAR_VOLUME),1)
change_tune($new_idB,get_event_par($EVENT_ID,$EVENT_PAR_TUNE),1)
change_pan($new_idB,get_event_par($EVENT_ID,$EVENT_PAR_PAN),1)
end on

on ui_control ($intervalA)
set_knob_label($intervalA,!Interval_names[abs($intervalA)])
end on

on ui_control ($intervalB)
set_knob_label($intervalB,!Interval_names[abs($intervalB)])
end on


----------



## EvilDragon (Jun 22, 2021)

You would need to wrap the parts related to $new_idA and $new_idB in an if clause that tests if value of $IntervalA (or $IntervalB) is different from 0.


----------



## DJN (Jun 22, 2021)

Like this?:

if ($intervalA < 0)
$new_idA := play_note($new_noteA,$new_velocityA,0,-1)
end if


----------



## EvilDragon (Jun 22, 2021)

Yes. And other stuff that uses $new_idA variable - like change_vol/pan/tune etc. should go inside that if clause.


----------



## DJN (Jun 22, 2021)

OK! Thank you again for all your help EvilDragon!

A new issue: This all changed the way the knobs work together as the original. Now, the 'interval' knob only works when it's 'left' of center, for adding the new note below. Right of center does nothing now. To add the new note above the original, I have to adjust the 'interval' to the left (down), then I adjust the 'octave' knob to the right of center to place the new note an octave above. 

Does that make sense?


----------



## DJN (Jun 22, 2021)

EDIT:
When I change: "if ($intervalA < 0)" to "if ($intervalA > 0)" It reverses the process, now I get the upper register without the lower register.

So - Using the (<0) and (>0) seems to be the issue. Is there a way to have both <0, and >0, while excluding only '0' or the 'unison' on the 'interval' knob'?


----------



## EvilDragon (Jun 22, 2021)

You need to use "not equal", not "less than" or "more than". See KSP reference


----------



## DJN (Jun 22, 2021)

Update:

After much experimentation I think I've found a solution so far, this is the code at the of the "A" on-note callback (similar adjustment is made on the "B" section:

disallow_group($ALL_GROUPS)
allow_group(0)
$orig_idA:= play_note($orig_noteA,$orig_velocityA,0,-1)
if ($intervalA + $octaveA = 0) 
$new_idA := 0
else
$new_idA := play_note($new_noteA,$new_velocityA,0,-1)
change_vol($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_VOLUME),1)
change_tune($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_TUNE),1)
change_pan($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_PAN),1)
end if


----------



## EvilDragon (Jun 22, 2021)

There is no need for an else clause here. Just a "not equal" comparison as mentioned above


----------



## DJN (Jun 22, 2021)

Yes, I just tried it - perfect!! Thanks again for your help walking me through this. 
Is using the "+" the right way to say it?

disallow_group($ALL_GROUPS)
allow_group(0)
$orig_idA:= play_note($orig_noteA,$orig_velocityA,0,-1)
if ($intervalA + $octaveA # 0) 
$new_idA := play_note($new_noteA,$new_velocityA,0,-1)
change_vol($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_VOLUME),1)
change_tune($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_TUNE),1)
change_pan($new_idA,get_event_par($EVENT_ID,$EVENT_PAR_PAN),1)
end if


----------



## A.G (Jun 22, 2021)

DJN said:


> It sounds to me like the 'original note' is being doubled when the script is active. Can you please confirm this?


It is not doubled at all cause the disallow_group($ALL_GROUPS) kills the original Note event. This is the reason I added the original Note Event & Velocity registrations to be able to push the original Note via the following string:

$orig_idA:= play_note($orig_noteA,$orig_velocityA,0,-1)

You can test that:

1. Enable the "Group Editor", select the 1st group and enable the "Group Solo" button.
2. Place brackets {} around the original play_note code to ignore it just for the test:

{ $orig_idA:= play_note($orig_noteA,$orig_velocityA,0,-1) }

What do you hear? The original Note is ignored and only the "Interval" Note is playing.

The modified "DUO" script seems to work as expected cause it is a 100% A/B duplication of the original.


----------

