# Trying to create dropdown menu that changes mapping



## Scooter Fort (Jul 10, 2019)

I'm trying to create a simple dropdown menu that will allow the user to remap the snare to whichever note they prefer - I haven't been able to find any information on this at all I've been searching through the forums and the reference manual for a couple hours 

Any help would be appreciated!


----------



## P.N. (Jul 10, 2019)

Hi, there.
A menu would be quite long... (if you fill it with all 128 possible keys)

I'd recommend a ui_value_edit, which has a nice built in mode which automatically displays note names.
Other benefits of using it with this special mode ($VALUE_EDIT_MODE_NOTE_NAMES) is the ability to double-click and write down a note (C3, etc) in plain alphabet, or a regular number that represents a midi note number.

You could also add a small "learn" button next to it so that it will automatically set the mapping to the next note you play, then turn off the learning button.

As you're aware, the script won't physically move samples positions.
It will simply take the current zone note and reference it to another value.

So the script detects if the note you played matches the note you specified in the ui_value_edit.
If this condition is met, the script will ignore the ID and play the note where the zone is physically mapped.

Of course, there would be a lot of stuff that could be added to this, like not allowing the learn function (or the ui_value_edit) to remap the snare to notes that are already being used for other parts of the drums, etc.

Here's a barebones quick example with a basic learn function:
(You'd need to change the $def_snare_note constant to match the actual note number where your zone is physically mapped.)



Spoiler: Remap Snare Example





```
on init
    make_perfview
  
    declare ui_value_edit $remap_ve (0, 127, $VALUE_EDIT_MODE_NOTE_NAMES)
    make_persistent($remap_ve)
    set_control_par(get_ui_id($remap_ve), $CONTROL_PAR_WIDTH, 100)
    set_control_par(get_ui_id($remap_ve), $CONTROL_PAR_POS_X, 5)
    set_control_par_str(get_ui_id($remap_ve), $CONTROL_PAR_TEXT, "Snare Note")
  
    declare ui_button $learn_snare
    set_control_par(get_ui_id($learn_snare), $CONTROL_PAR_WIDTH, 100)
    set_control_par(get_ui_id($learn_snare), $CONTROL_PAR_POS_X, 115)
    set_control_par_str(get_ui_id($learn_snare), $CONTROL_PAR_TEXT, "Learn")
    set_control_par(get_ui_id($learn_snare), $CONTROL_PAR_TEXT_ALIGNMENT, 1)
  
    declare const $def_snare_note := 60
    declare $snare_new_note
    declare $snare_new_id
  
    $remap_ve := $def_snare_note
end on

on note
    if($learn_snare = 1)
        $remap_ve := $EVENT_NOTE
        $learn_snare := 0
    end if

    if($EVENT_NOTE = $remap_ve)
        ignore_event($EVENT_ID)
        $snare_new_note := $def_snare_note
        $snare_new_id := play_note($def_snare_note, $EVENT_VELOCITY, 0,0)
    end if
end on
```




Cheers.


----------



## Scooter Fort (Jul 12, 2019)

P.N. said:


> Hi, there.
> A menu would be quite long... (if you fill it with all 128 possible keys)
> 
> I'd recommend a ui_value_edit, which has a nice built in mode which automatically displays note names.
> ...


Thank you so much!! This worked perfectly


----------



## Scooter Fort (Jul 13, 2019)

P.N. said:


> Hi, there.
> A menu would be quite long... (if you fill it with all 128 possible keys)
> 
> I'd recommend a ui_value_edit, which has a nice built in mode which automatically displays note names.
> ...



I'm trying to also have the key color change to the specified note, but I can't wrap my brain around why it wouldn't work.

I'm thinking


```
{SET KEY COLORS}

    declare $counter
    declare %key_color[128]
    declare %black_keys[5] := (1, 3, 6, 8, 10)

    { default to all black }
    $counter := 0
    while ($counter <= 127)
        if (search(%black_keys, $counter mod 12) # -1)
            %key_color[$counter] := $KEY_COLOR_WHITE
        else
            %key_color[$counter] := $KEY_COLOR_BLACK
        end if
        inc($counter)
    end while


    { set an example keyswitch }
    %key_color[$snare_new_note] := $KEY_COLOR_TURQUOISE

    { set key colors }
    $counter := 0
    while ($counter <= 127)
        set_key_color($counter, %key_color[$counter])
        inc($counter)
    end while

{END SET KEY COLORS}
```

Shouldn't this work? Isn't one of the defined variables for the key switch holding the number of the new note? So, in theory, it should change the color of whatever the "defined" note is? I've tried switching the variable with all of them with no luck


----------



## P.N. (Jul 13, 2019)

Alright.

I see i put in an extra variable there, which is not needed at all. (maybe i was planning to do something else with it, i don't know...)

In any case, here's a new version, with comments and an extra rule for not allowing the mapped zone to also be triggered when the mapped key is different from the physical zone key.

PS: Careful with the keycolours initialization. It will reset all your keys, even the ones that are already mapped in default colour.
If you don't have aditional code for the other parts of the instrument, just comment it out, set all your keymap colours on init, or either call specialized funtions or use a blip note to reset mapped notes to default (on persistence changed).

If you need to remap other parts of the instrument, then you should probably work with arrays and a single function to handle all the key colours.




Spoiler: Remap Snare with colours





```
on init
    make_perfview
    message("")
   
    {Variables / Iterators}
    declare $count
    declare $snare_new_id
    declare $last_snare_key
   
    {Constants}
    declare const $def_snare_note := 60
    declare const $SNARE_COLOUR := $KEY_COLOR_RED
   
    {Resets the keyboard colours. Careful when using this as it will turn all keys to default, even the ones already mapped.}
    {If no additional functions exist on persistence changed (for the other keys), this should be commented out.}
    $count := 0
    while($count < 128)
        set_key_color($count, $KEY_COLOR_NONE)
        inc($count)
    end while
   
    {Value Edit Snare Remapper}
    declare ui_value_edit $remap_ve (0, 127, $VALUE_EDIT_MODE_NOTE_NAMES)
    make_persistent($remap_ve)
    set_control_par(get_ui_id($remap_ve), $CONTROL_PAR_WIDTH, 100)
    set_control_par(get_ui_id($remap_ve), $CONTROL_PAR_POS_X, 5)
    set_control_par_str(get_ui_id($remap_ve), $CONTROL_PAR_TEXT, "Snare Note")
   
    {Snare Remapper Learn Button}
    declare ui_button $learn_snare
    set_control_par(get_ui_id($learn_snare), $CONTROL_PAR_WIDTH, 100)
    set_control_par(get_ui_id($learn_snare), $CONTROL_PAR_POS_X, 115)
    set_control_par_str(get_ui_id($learn_snare), $CONTROL_PAR_TEXT, "Learn")
    set_control_par(get_ui_id($learn_snare), $CONTROL_PAR_TEXT_ALIGNMENT, 1)
   
    {Default remapping. Only used when the nki was note saved - the first time the code is initialized.}
    {After the nki was saved, the Snare remapped key will be retrieved from the value edit persistency.}
    $remap_ve := $def_snare_note
   
end on


function set_snare_colour
    {Resets the last mapped snare key based on the last known value, updates the new mapped snare key colour and sets it as the last known value.}
    set_key_color($last_snare_key, $KEY_COLOR_NONE)
    set_key_color($remap_ve,  $SNARE_COLOUR)
    $last_snare_key  := $remap_ve
end function

on persistence_changed
    call set_snare_colour
end on

on ui_control($remap_ve)
    call set_snare_colour
end on

on note
   
    {If the played note matches the mapped note and remapping is in place, ignore the EVENT_ID.}
    if($EVENT_NOTE = $def_snare_note and $remap_ve # $def_snare_note)
        ignore_event($EVENT_ID)
    end if
   
    {If the played note matches the remapped note and, ignore its EVENT_ID and play the mapped note.}
    if($EVENT_NOTE = $remap_ve)
        ignore_event($EVENT_ID)
        $snare_new_id := play_note($def_snare_note, $EVENT_VELOCITY, 0,0)
    end if
   
    {If the if the learn button is active, set the mapping to the played note, disable the learn button and call the colour function.}
    if($learn_snare = 1)
        $remap_ve := $EVENT_NOTE
        $learn_snare := 0
        call set_snare_colour
    end if
end on
```




Cheers.


----------



## Scooter Fort (Jul 13, 2019)

P.N. said:


> Alright.
> 
> I see i put in an extra variable there, which is not needed at all. (maybe i was planning to do something else with it, i don't know...)
> 
> ...


Thanks so much for the quick reply! This line of code is giving an error

```
declare const $SNARE_COLOUR := $KEY_COLOR_RED
```


----------



## Scooter Fort (Jul 13, 2019)

Scooter Fort said:


> Thanks so much for the quick reply! This line of code is giving an error
> 
> ```
> declare const $SNARE_COLOUR := $KEY_COLOR_RED
> ```


found it,


```
$SNARE_COLOUR
```
 can't be a constant

changing it to


```
declare SNARE_COLOUR := $KEY_COLOR_RED
```

works!


----------



## P.N. (Jul 13, 2019)

That's strange. Colours are constants internally, and that line doesn't give me any error.
Glad you could sort it out, but which version of Kontakt are you using?
This works fine in 5.8.1.

Edit: Works fine in Kontakt 6 too. It was probably a bug that was fixed in earlier versions.


----------



## geronimo (Jul 13, 2019)

P.N. said:


> That's strange. Colours are constants internally, and that line doesn't give me any error.


Me too: no error at home but no sound on the new note .


----------



## Scooter Fort (Jul 13, 2019)

P.N. said:


> That's strange. Colours are constants internally, and that line doesn't give me any error.
> Glad you could sort it out, but which version of Kontakt are you using?
> This works fine in 5.8.1.
> 
> Edit: Works fine in Kontakt 6 too. It was probably a bug that was fixed in earlier versions.


I'm in the newest version of 6


----------



## P.N. (Jul 13, 2019)

geronimo said:


> Me too: no error at home but no sound on the new note .


Strange. This works fine here. Did you change the default note constant to match the zone location?



Scooter Fort said:


> I'm in the newest version of 6


Alright, i don't know then.

I did only try this with a sample now and i see that the color of the mapped note remains there, even after changing the mapping.
It would probably be best resetting the default colour of the mapped zone to either black or white too, depending on what the note is (you can use your first mod colour note code for that purpose.), otherwise it will remain in the default colour and ruin the effect.


----------



## Scooter Fort (Jul 13, 2019)

geronimo said:


> Me too: no error at home but no sound on the new note .


Yeah you have to change the default constant to the correct note


----------



## P.N. (Jul 13, 2019)

Scooter Fort said:


> Yeah you have to change the default constant to the correct note


Yeah, it needs to know which note is to be remapped.
This could be done automatically (finding the snare note), simply by searching a zone name, or alternatively by getting the snare note duration and using that as a search criteria on persistence changed.

Here's just a small fix to reset the mapped note to either black or white.

PS: There may be issues with using $KEY_COLOR_WHITE or $KEY_COLOR_BLACK, but i believe this is only applicable to NKS certified instruments.
Still, as a matter of good practice, this example uses the NKS safe $KEY_COLOR_INACTIVE instead, which is actually simpler code (no array mod searches).



Spoiler: Remap Snare with mapped zone reset fix.





```
on init
    make_perfview
    message("")
    
    {Variables / Iterators}
    declare $count
    declare $snare_new_id
    declare $last_snare_key

    {Constants}
    declare const $def_snare_note := 60
    declare const $SNARE_COLOUR := $KEY_COLOR_RED

    {Resets the keyboard colours. Careful when using this as it will turn all keys to default, even the ones already mapped.}
    {If no additional functions exist on persistence changed (for the other keys), this should be commented out.}
    $count := 0
    while($count < 128)
        set_key_color($count, $KEY_COLOR_NONE)
        inc($count)
    end while

    {Value Edit Snare Remapper}
    declare ui_value_edit $remap_ve (0, 127, $VALUE_EDIT_MODE_NOTE_NAMES)
    make_persistent($remap_ve)
    set_control_par(get_ui_id($remap_ve), $CONTROL_PAR_WIDTH, 100)
    set_control_par(get_ui_id($remap_ve), $CONTROL_PAR_POS_X, 5)
    set_control_par_str(get_ui_id($remap_ve), $CONTROL_PAR_TEXT, "Snare Note")
    
    {Snare Remapper Learn Button}
    declare ui_button $learn_snare
    set_control_par(get_ui_id($learn_snare), $CONTROL_PAR_WIDTH, 100)
    set_control_par(get_ui_id($learn_snare), $CONTROL_PAR_POS_X, 115)
    set_control_par_str(get_ui_id($learn_snare), $CONTROL_PAR_TEXT, "Learn")
    set_control_par(get_ui_id($learn_snare), $CONTROL_PAR_TEXT_ALIGNMENT, 1)
    
    {Default remapping. Only used when the nki was note saved - the first time the code is initialized.}
    {After the nki was saved, the Snare remapped key will be retrieved from the value edit persistency.}
    $remap_ve := $def_snare_note
    
end on


function set_snare_colour

    {Resets the last mapped snare key based on the last known value, updates the new mapped snare key colour and sets it as the last known value.}
    set_key_color($last_snare_key, $KEY_COLOR_NONE)
    set_key_color($remap_ve,  $SNARE_COLOUR)
    $last_snare_key  := $remap_ve
    
    {Reset the mapped zone key colour if remapping is in place.}
    if($remap_ve # $def_snare_note)
        $count := 0
        while ($count < 128)
            if($count = $def_snare_note)
                set_key_color($def_snare_note, $KEY_COLOR_INACTIVE)
            end if
            inc($count)
        end while
    end if
end function

on persistence_changed
    call set_snare_colour
end on

on ui_control($remap_ve)
    call set_snare_colour
end on

on note
    
    {If the played note matches the mapped note and remapping is in place, ignore the EVENT_ID.}
    if($EVENT_NOTE = $def_snare_note and $remap_ve # $def_snare_note)
        ignore_event($EVENT_ID)
    end if
    
    {If the played note matches the remapped note and, ignore its EVENT_ID and play the mapped note.}
    if($EVENT_NOTE = $remap_ve)
        ignore_event($EVENT_ID)
        $snare_new_id := play_note($def_snare_note, $EVENT_VELOCITY, 0,0)
    end if
    
    {If the if the learn button is active, set the mapping to the played note, disable the learn button and call the colour function.}
    if($learn_snare = 1)
        $remap_ve := $EVENT_NOTE
        $learn_snare := 0
        call set_snare_colour
    end if
end on
```




Cheers.


----------



## Scooter Fort (Jul 13, 2019)

P.N. said:


> Strange. This works fine here. Did you change the default note constant to match the zone location?
> 
> 
> Alright, i don't know then.
> ...


Got it working!! Thank you so much for your help


----------



## geronimo (Jul 14, 2019)

Scooter Fort said:


> Yeah you have to change the default constant to the correct note


Many thanks; const $def_snare_note edited, at home .


----------



## Scooter Fort (Oct 1, 2019)

Any idea how I could modify this to work with multiple keys? 

So it worked perfectly for my last instrument which was just a snare, but now I've created a multi-instrument (drum kit shells, so we've got kick, snare and three toms) is there a way I could adapt this script to work for multiple keys? Or would that be way more complex? I've been trying to wrap my brain around it but I haven't scripted in a few months


----------



## EvilDragon (Oct 1, 2019)

Sure, you'd store your mapping in an array, which should be the size of number of sounds you want to remap.


----------



## Scooter Fort (Nov 22, 2019)

EvilDragon said:


> Sure, you'd store your mapping in an array, which should be the size of number of sounds you want to remap.



Which value would I store in the array? Sorry to sound a bit noobish I haven't learned much about arrays yet


----------



## Scooter Fort (Nov 22, 2019)

For instance what I'm working on right now is a snare sample with normal hits and flam hits, mapped to D1 and D#1 I'd like to be able to remap the both of those individually


----------

