Query menu item numbers in another script slot?

Discussion in 'KONTAKT: Sampling, Programming & Scripting' started by Tod, Oct 7, 2018.

  1. Tod

    Tod Senior Member

    This is probably really simple, but I've been trying to figure out how to get the menu item numbers from other script slots/tabs.

    I've been using "on pgs_changed" to decipher this, but I'm wondering if there isn't something much simpler?
     
  2. OP
    OP
    Tod

    Tod Senior Member

    So I guess I can assume this is not doable. :cautious:
     
  3. P.N.

    P.N. Senior Member

    313
    109
    Aug 14, 2015
    Hi.
    Never tried this before, but you should be able to assign the $CONTROL_PAR_SELECTED_ITEM_IDX to a pgs key and get the menu index value in the target scripts. It should work...

    Best regards,

    Paulo
     
  4. EvilDragon

    EvilDragon KSP Wizard

    5,197
    2,973
    May 25, 2010
    Croatia
    Yeh, PGS does make it possible. You just have to be careful to refresh the PGS key value whenever the menu value changes.
     
  5. P.N.

    P.N. Senior Member

    313
    109
    Aug 14, 2015
    It's a question of setting the PGS key value (overwriting the previous one) on the "on ui control" for the menu.

    So, something like:

    Code:
    on ui_control($menu)
      pgs_set_key_val(key-id,key-idx,get_control_par(get_ui_id($menu),$CONTROL_PAR_SELECTED_ITEM_IDX))
      {do menu things}
    end on
    Paulo
     
  6. EvilDragon

    EvilDragon KSP Wizard

    5,197
    2,973
    May 25, 2010
    Croatia
    Yes, and in persistence_changed as well.
     
    P.N. likes this.
  7. OP
    OP
    Tod

    Tod Senior Member

    Wow, ha ha, I would never have figured this out. :grin: I'm assuming the double "key-id" is a typo?

    Thanks Paulo and Mario, I'll be checking this out soon.
     
    P.N. likes this.
  8. P.N.

    P.N. Senior Member

    313
    109
    Aug 14, 2015
    Hi, Tod.
    They were just placeholders.
    One of them, key-id refers to the id of the potencial key you could create and use for this task.
    The other is key-idx, just refers to the element index for that key.
    If you create a key with only one element (if you only needed PGS for this task), you set that "key-idx" to zero.

    For example:
    Code:
    pgs_create_key(MENU_PGS, 1)
    Than, in the $menu (on ui control) and on persistence changed, you do the same as above, but replace the "key_id" and "key_idx", so it would be something like:

    Code:
    pgs_set_key_val(MENU_PGS, 0, get_control_par(get_ui_id($menu),$CONTROL_PAR_SELECTED_ITEM_IDX))
     
  9. OP
    OP
    Tod

    Tod Senior Member

    Aah, so you mean I can pass both the variable as well as the element number in the same "pgs_set_key" command? I'm going to tell you exactly what I'm doing because I have a feeling I'll be back.

    Right now I've got 2 Tabs, Tab1 has 6 sliders and 2 convolution verbs, while Tab2 has all my FX as well as all my presets. When I save a preset I not only save all the FX controls, but I'm also saving the sliders and convo-verb menu settings on Tab1. Checking the presets after they're saved, all have the right numbers including the convo-verb menu settings. However, when I load the presets, everything loads properly except the menus for the convo-verbs.

    I might add, I also have an "Import/Export" menu for saving all the presets to the "Data" folder. Checking their numbers they all are exactly as they should be.

    Thanks Paulo.
     
  10. OP
    OP
    Tod

    Tod Senior Member

    Hi again Paulo, I just got to looking over your "pgs_set_key_val" and I think I've been using that all along, I'm just not using the menu ID, although I do already have one. I won't bother putting this in code, but this is what I'm using. The REV_1 is the pgs key I created and it only has 1 element. $RV_1_Menu is the name of the menu. Is this not basically the same thing?

    pgs_set_key_val(REV_1,0,$RV_1_Menu)
     
  11. P.N.

    P.N. Senior Member

    313
    109
    Aug 14, 2015
    When you load the presets, your preset loading tasks should not only correctly set the required menu index but also call the apropriate function that updates the menu, otherwise, your convulation IRs won't load properly.

    This would be the case if your conv menu was in the same script as the save/load command.

    But since it's not, it's a little more complicated:

    - You have your custom IRs defined in a string array that is integrated in the convolution menu, correct?
    - In that case, if you already have a function for it, you could re-use it below. If not, you can write new code just for this. You'll see what works best in your case.

    - When loading presets, refresh the pgs_key on the load/save script tab. (more precisely, after the load_array is completed). You should probably use on async complete for this.
    It will refresh the pgs_key for the menu_index after the preset values are loaded.

    - On the conv_tab, on pgs_changed, call the conv-menu function (tweaked to use the pgs key generated in the other script), or write new code that sets the menu idx based on that same pgs_key that was just refreshed from the load/save script tab.
    Then you write the rest of the code that loads the IR based on the current menu index.

    That should do the trick.

    Maybe i complicated some things. If i have time, later on i'll test this and come up with an example that's similar to your script configuration.

    No, it's different.
    $CONTROL_PAR_SELECTED_ITEM_IDX gets the menu index for the currently selected menu item.
    What you wrote gets the value for the currently selected menu item.

    Then we have get_menu_item_value(), where we can query values for a menu index of our choosing.
     
  12. OP
    OP
    Tod

    Tod Senior Member

    Thanks again Paulo, and I can't thank you enough, this is the first time I've tried to do this with a menu. I'm going to dig into this deeply tomorrow, it's rather late here. Let me see what I can do with the info you've given me and I'll let you know what I come up with. :)
     
  13. P.N.

    P.N. Senior Member

    313
    109
    Aug 14, 2015
    I took a small break from my scripting project and i... scripted a little more.

    Here's an example:

    Code:
    on init
        set_ui_height_px(200)
        make_perfview
     
        declare $count
     
        {CONVOLUTION SLOTS/GEN}
        declare $IRC1_SLOT:=0
        declare $IRC1_GEN:=1
     
        declare $IRC2_SLOT:=1
        declare $IRC2_GEN:=1
     
        {IR PATHS/NAMES}
        declare @ir_path1
        @ir_path1:= "C:/Program Files/Common Files/Native Instruments/Kontakt 5/Presets/Effects/Convolution/08 Tiny Rooms/IR Samples/"
     
        declare @ir_path2
        @ir_path2:= "C:/Program Files/Common Files/Native Instruments/Kontakt 5/Presets/Effects/Convolution/10 Big Rooms/IR Samples/"
     
        declare !ir_names[6]
        !ir_names[0] := "Small Ambience"
        !ir_names[1] := "Medium Booth"
        !ir_names[2] := "Gym Shower"
        !ir_names[3] := "Masterverb Hall"
        !ir_names[4] := "Roomy Hall"
        !ir_names[5] := "Environmental"
     
        {CONVOLUTION MENUS}
        declare ui_menu $conv_menu1
        declare ui_menu $conv_menu2
        make_persistent($conv_menu1)
        make_persistent($conv_menu2)
     
        $count:=0
        while($count<3)
            add_menu_item($conv_menu1,!ir_names[$count],$count)
            add_menu_item($conv_menu2,!ir_names[$count+3],$count+3)
            inc($count)
        end while
     
        {INSERT CONVOLUTION FX}
        set_engine_par($ENGINE_PAR_EFFECT_TYPE,$EFFECT_TYPE_IRC,-1,$IRC1_SLOT,$IRC1_GEN)
        set_engine_par($ENGINE_PAR_EFFECT_TYPE,$EFFECT_TYPE_IRC,-1,$IRC2_SLOT,$IRC2_GEN)
     
        {PGS KEYS}
        pgs_create_key(IRCVAL,2)
        pgs_create_str_key(IRCSTR1)
        pgs_create_str_key(IRCSTR2)
    end on
    
    function pgs_update
        pgs_set_key_val(IRCVAL,0,$conv_menu1)
        pgs_set_key_val(IRCVAL,1,$conv_menu2)
        pgs_set_str_key_val(IRCSTR1,get_menu_item_str(get_ui_id($conv_menu1),get_control_par(get_ui_id($conv_menu1),$CONTROL_PAR_SELECTED_ITEM_IDX)))
        pgs_set_str_key_val(IRCSTR2,get_menu_item_str(get_ui_id($conv_menu2),get_control_par(get_ui_id($conv_menu2),$CONTROL_PAR_SELECTED_ITEM_IDX)))
    end function
    
    function load_ir
        load_ir_sample(@ir_path1 & !ir_names[$conv_menu1] & ".wav",$IRC1_SLOT,$IRC1_GEN)
        load_ir_sample(@ir_path2 & !ir_names[$conv_menu2] & ".wav",$IRC2_SLOT,$IRC2_GEN)
    end function
    
    on persistence_changed
        call load_ir
        call pgs_update
    end on
    
    on pgs_changed
        $conv_menu1:=pgs_get_key_val(IRCVAL,0)
        $conv_menu2:=pgs_get_key_val(IRCVAL,1)
        call load_ir
        call pgs_update
    end on
    
    on ui_control($conv_menu1)
        load_ir_sample(@ir_path1 & !ir_names[$conv_menu1] & ".wav",$IRC1_SLOT,$IRC1_GEN)
        call pgs_update
    end on
    
    on ui_control($conv_menu2)
        load_ir_sample(@ir_path2 & !ir_names[$conv_menu2] & ".wav",$IRC2_SLOT,$IRC2_GEN)
        call pgs_update
    end on

    Code:
    on init
        set_ui_height_px(200)
        make_perfview
     
        declare $count
        declare $load_arr_id
        $load_arr_id := -1
        declare $save_arr_id
        $save_arr_id := -1
     
        declare %preset[2]
     
        declare ui_label $conv1_name (1,1)
        declare ui_label $conv2_name (1,1)
     
        declare ui_button $save
        declare ui_button $load
     
    end on
    
    function pgs_update
        %preset[0]:=pgs_get_key_val(IRCVAL,0)
        %preset[1]:=pgs_get_key_val(IRCVAL,1)
     
        set_text($conv1_name,pgs_get_str_key_val(IRCSTR1))
        set_text($conv2_name,pgs_get_str_key_val(IRCSTR2))
    end function
    
    on persistence_changed
        call pgs_update
    end on
    
    on pgs_changed
        call pgs_update
    end on
    
    on ui_control($load)
        $load_arr_id:=load_array(%preset,0)
    end on
    
    on ui_control($save)
        $save_arr_id:=save_array(%preset,0)
    end on
    
    on async_complete
        if($NI_ASYNC_ID=$load_arr_id)
            $load_arr_id:=-1
            $Load:=0
         
            if($NI_ASYNC_EXIT_STATUS=1)
                pgs_set_key_val(IRCVAL,0,%preset[0])
                pgs_set_key_val(IRCVAL,1,%preset[1])
            end if
        end if
     
        if ($NI_ASYNC_ID=$save_arr_id)
            $save_arr_id:=-1
            $Save:=0
        end if
    end on

    Please ignore some of the stuff (inserting the conv FXs on init, lazy menu entries that set the IR name but are also used as a path reference... etc. The save/load part is basically just pulled from the KSP manual. I just wanted a quick and dirty way to see this in action - using some of Kontakt's factory IRs).

    On a side note, this may also serve as a demonstration for passing pgs strings between scripts.
    In this case, the "tab B" script has 2 labels that get the string values of the selected convolution menus. Maybe you can find a use for that.

    Best regards,
    Paulo
     
  14. OP
    OP
    Tod

    Tod Senior Member

    Thanks so much again Paulo, I've definitely learned a few things here.

    I've looked very closely at your scripts as well as closely examined your posts. From what I can tell, I think I've basically already been doing everything the way you've showed me with a few exceptions.

    One is "$NI_ASYNC_EXIT_STATUS" inside the "on async_complete", I think that's a good idea. I've been using the "on async_complete", but only for sending a message that it worked.

    Another is the way you load your IRs, I've got my convo-verbs in the Send Effects and this is what I've been using.
    Code:
    load_ir_sample(get_folder($GET_FOLDER_FACTORY_DIR)&"presets/effects/convolution/<<<K4IR.nkx>>>/K4 IR Samples/"&!Rev1_IR[$RV_1_Menu],5,0)

    Okay, I think I might be getting to understand, "$CONTROL_PAR_SELECTED_ITEM_IDX" is index number that the IR has in NI's IR folder, is that right?

    Okay, regarding the code I've been using, Here's what I've got in Tab1 for sending the menu selections:
    Code:
    on ui_control($RV_1_Menu)
      load_ir_sample(get_folder($GET_FOLDER_FACTORY_DIR)&"presets/effects/convolution/<<<K4IR.nkx>>>/K4 IR Samples/"&!Rev1_IR[$RV_1_Menu],5,0)
      pgs_set_key_val(REV_1,0,$RV_1_Menu)}
    end on
    
    on ui_control($RV_2_Menu)
      load_ir_sample(get_folder($GET_FOLDER_FACTORY_DIR)&"presets/effects/convolution/<<<K4IR.nkx>>>/K4 IR Samples/"&!Rev2_IR[$RV_2_Menu],6,0)
      pgs_set_key_val(REV_2,0,$RV_2_Menu)}
    end on
    This is what I got in Tab2 for getting the IR menu values. The %Pre_T1[] array is one I've got for the all the knobs and 2 convo-verbs on Tab1 and it gets saved to the %Pre arrays when I save a preset.
    Code:
    on pgs_changed
      if(pgs_key_exists(REV_1))
        %Pre_T1[6]:=pgs_get_key_val(REV_1,0)
      end if
      if(pgs_key_exists(REV_2))
        %Pre_T1[7]:=pgs_get_key_val(REV_1,0)
    end if
    end on 
    This is what I got in Tab2 regarding sending the knobs and convo-verbs to Tab1 when loading presets:
    Code:
    cnt3:=0
    for cnt1:=Ttl_Df to Ttl_Df+7
        pgs_set_key_val(INDEX,0,cnt3)
        pgs_set_key_val(TAB2, cnt3, %Pre1[cnt1])
        wait(1)
        inc(cnt3)
    end for
    
    And this is what I've got in Tab1 when a preset is sent.
    Code:
    on pgs_changed
      if(pgs_key_exists(TAB2) and pgs_key_exists(INDEX))
        cnt3:=pgs_get_key_val(INDEX,0)}
        %Knb_ID[cnt3]->value := pgs_get_key_val(TAB2,cnt3)}
     
        if (cnt3 < 6)                                                  {Sets the 6 knobs}
          call Set_Controls
        else                                                                {for loading the IRs}
          if (cnt3 = 6)
            $RV_1_Menu:=%Knb_ID[6]
            load_ir_sample(get_folder($GET_FOLDER_FACTORY_DIR)&"presets/effects/convolution/<<<K4IR.nkx>>>/K4 IR Samples/"&!Rev1_IR[$RV_1_Menu],5,0)
          else
            $RV_2_Menu:=%Knb_ID[7]
            load_ir_sample(get_folder($GET_FOLDER_FACTORY_DIR)&"presets/effects/convolution/<<<K4IR.nkx>>>/K4 IR Samples/"&!Rev2_IR[$RV_2_Menu],6,0)
          end if
        end if
      end if
    end on
    Is there any reason this should not work?
     
    Last edited: Oct 11, 2018 at 8:59 AM
  15. P.N.

    P.N. Senior Member

    313
    109
    Aug 14, 2015
    That's really not the way i load my IRs. :) That was just lazy scripting so i could get small "load_ir_sample" lines and make the test bed less confusing. (Again, please don't pay any attention to that part of the code).
    I just picked up a few specific IRs from different folders and defined them on init so i wouldn't have to mess around with if statements and what not.
    This way i could just focus on the pgs and save/load tasks.
    Your method is the way to go regarding factory IRs.

    You're using 2 different PGS keys. But, in order to simplify, you could use just one as i did in my example.
    I did state before that you could set your PGS index to 0, but i forgot you had 2 menus, not 1.

    When i did the example, i went ahead and used the same pgs, but assigned each menu to a different PGS index.
    (you could put up to 256 elements in a PGS key, if i'm not mistaken, so 1 single PGS could even be enough for situations with many ui_). "Normal" PGS behave like arrays.
    The string PGS is different. That one absolutely needs 1 pgs per value because it behaves as a variable.

    There's a mistake there, but it might just be a typo when you posted. %Pre_T1[7]:=Reverb2
    This needs to refer to your REV_2 PGS key.

    The rest of the code is a little bit harder to understand, to be honest. You have other aspects going on and i'm not sure what they all mean...

    I'll try to sum up the relevant steps:

    Convolution tab:
    -On ui_control, set the PGS based on the menu idx (and load the IRs).
    -On pgs_changed, set the menus based on the tab 2 refreshed PGS, load your IRs, but also (after), refresh the PGS based on the menu. This way, your second tab (the presets) will keep updated too.
    - Also refresh the PGS and load_arrays on persistence changed.

    Presets tab:
    - On async_complete, for save, you don't need to do anything to the PGS keys, because they were already refreshed in the Convolution Tab. (if you followed the steps for the Conv tab above)
    - On async_complete, for load, you set the PGS based on the preset array value.
    - On pgs_changed, set the presets based on the PGS.
    - Also refresh the PGS on persistence changed.

    Some of this back and forward may seem redundant at times, and there might be some steps that could be ommited, but this way you have all your bases covered.

    Paulo
     
  16. OP
    OP
    Tod

    Tod Senior Member

    Hi Paulo, I found the problem, it was a really stupid mistake.

    In TAB1 for on pgs_changed I had this.
    Code:
    on pgs_changed
      if(pgs_key_exists(TAB2) and pgs_key_exists(INDEX))
        cnt3:=pgs_get_key_val(INDEX,0)
        %Knb_ID[cnt3]->value := pgs_get_key_val(TAB2,cnt3)   {<<<<<<<<}  
        if (cnt3 < 6)
          call Set_Controls
        else
          if (cnt3 = 6)
            $RV_1_Menu:=%Knb_ID[6]
            load_ir_sample(get_folder($GET_FOLDER_FACTORY_DIR)&"presets/effects/convolution/<<<K4IR.nkx>>>/K4 IR Samples/"&!Rev1_IR[$RV_1_Menu],5,0)
          else
            $RV_2_Menu:=%Knb_ID[7]
            load_ir_sample(get_folder($GET_FOLDER_FACTORY_DIR)&"presets/effects/convolution/<<<K4IR.nkx>>>/K4 IR Samples/"&!Rev2_IR[$RV_2_Menu],6,0)
          end if
        end if}
      end if
    end on
    
    Notice where "%Knb_ID[cnt3]->value := pgs_get_key_val(TAB2,cnt3)" is?

    It should have been this.
    Code:
    on pgs_changed
      if(pgs_key_exists(TAB2) and pgs_key_exists(INDEX))
        cnt3:=pgs_get_key_val(INDEX,0)}
        if (cnt3 < 6)
          %Knb_ID[cnt3]->value:=pgs_get_key_val(TAB2,cnt3)   {<<<<<<<<}
          call Set_Controls
        else
          %Knb_ID[cnt3]:=pgs_get_key_val(TAB2,cnt3)   {<<<<<<<<}  
          if (cnt3 = 6)
            $RV_1_Menu:=%Knb_ID[6]
            load_ir_sample(get_folder($GET_FOLDER_FACTORY_DIR)&"presets/effects/convolution/<<<K4IR.nkx>>>/K4 IR Samples/"&!Rev1_IR[$RV_1_Menu],5,0)
          else
            $RV_2_Menu:=%Knb_ID[7]
            load_ir_sample(get_folder($GET_FOLDER_FACTORY_DIR)&"presets/effects/convolution/<<<K4IR.nkx>>>/K4 IR Samples/"&!Rev2_IR[$RV_2_Menu],6,0)
          end if
        end if}
      end if
    end on
    
    Only 0 to 5 had a "$CONTROL_PAR_VALUE", the other 2 were just a regular variable.

    Thank you so much for sticking with me Paulo, I learned a lot from you help. ;)
     
    P.N. likes this.
  17. P.N.

    P.N. Senior Member

    313
    109
    Aug 14, 2015
    Your welcome. I've never done this type of feature before, so i learned something too.

    Glad you solved it.

    Cheers,
    Paulo
     
  18. OP
    OP
    Tod

    Tod Senior Member

    There's a little more to add to this story. I ended up having to pass another pgs key variable (1) from Tab2 to Tab1 telling Tab1 when information was being sent. Then when it was done send a pgs key variable (0) to tell Tab1 it was done.

    The reason for this is because when saving & loading and instrument, it wasn't loading correctly, the knobs were not correct. :eek:
     
  19. P.N.

    P.N. Senior Member

    313
    109
    Aug 14, 2015
    Was it in async_complete, to make sure the pgs where only updated when the commands where completed successfuly?
     
  20. OP
    OP
    Tod

    Tod Senior Member

    Thanks Paulo, this hasn't got anything to do with loading a file. The actual presets that I'm sending to Tab1 from Tab2 are in arrays.

    I use Reaper and what happened is that when I saved the Reaper project and then reopen it, a couple of the knobs would be wrong. I finally determined that the "on pgs_changed" was being called when I opened the project and causing this to happen.

    When I added the other pgs key alerting Tab1 that a message was coming and then used the same pgs key alerting that it was done, that fixed it.
     

Share This Page