# A problem I've never seen before??



## Tod (Jan 31, 2020)

I've got a script that does not process past the init "end on". You can see all the messages I have and the last one that shows is the "end(on init)" message. Below is just smidgen of the script I copied for demonstration.

The "on persistence_changed" is not getting processed when I hit apply in Kontakt. Nor are any of the other messages when I move the sliders I have programmed.

It's probably something simple, but I'm stumped at the moment. Anybody got any ideas?


```
on init
    message("Start")
    set_control_par_str($INST_WALLPAPER_ID,$CONTROL_PAR_PICTURE,"SAB_wallpaper.png")
    make_perfview
  declare $c1
  declare $init_flag
    $init_flag := 1
  declare %Sldr_ID[9]
  declare ui_slider $Slider_5(0, 1000000)
    %Sldr_ID[4] := get_ui_id($Slider_5)
    set_control_par_str(%Sldr_ID[4],$CONTROL_PAR_PICTURE,"Tod Vert Slider 3")
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_MOUSE_BEHAVIOUR,-2500)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_WIDTH,12)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_HEIGHT,128)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_POS_X,357)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_POS_Y,88)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_HIDE,$HIDE_PART_NOTHING)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_VALUE,0)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_DEFAULT_VALUE,0)
    make_persistent($Slider_5)
      message("end (on init)")
end on
on persistence_changed
  message("on persistence")
  if ($init_flag=1)
    $c1 := 4
    set_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE,500000)
    set_engine_par($ENGINE_PAR_VOLUME,get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE),-1,-1,$NI_BUS_OFFSET)
    message("Slider_1 value = " & get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE))
  else
    $init_flag := 0
  end if
end on
on ui_control($Slider_5)
  message("Name = " & $Slider_5 & "   idx = " & 4)
  $c1 := 4
  call set_slider
end on
function set_slider
  select ($c1)
    case 4
      set_engine_par($ENGINE_PAR_VOLUME,get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE),-1,-1,$NI_BUS_OFFSET)
      message("Slider_1 value = " & get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE))
  end select
end function
```


----------



## P.N. (Jan 31, 2020)

Hi, Tod.

I got an error with it in which the UICB needed to come after the function.
After moving it, it seems to work.


----------



## Tod (Jan 31, 2020)

Thanks my friend, do you mean putting the function before the "on persistent_changed"?

When I compile the script I posted here in Sublime Text, it automatically puts the function above the on persisstent_changed.

Are you getting the messages that show *beyond* the "end on" for the "on init"?



P.N. said:


> Hi, Tod.
> 
> I got an error with it in which the UICB needed to come after the function.
> After moving it, it seems to work.


----------



## Mike Greene (Jan 31, 2020)

I get the same result as P.N. It seems that the function needs to come before it is actually used. In this case, it needed to be before the "on ui_control($Slider_5)" callback.

In this particular example, the set_slider function doesn't _have_ to be before the persistence_changed callback, though, since it's not actually needed until later. But it does have to be before the Slider_5 UI callback (that's what P.N. meant by "UICB"), where it _is_ needed.

My guess is that Sublime puts _all_ the functions _before_ the persistence_changed callback, though, because in general, persistence_changed _might_ have a function used inside it, so Sublime might as well put _all_ functions ahead of persistence_changed, rather than deciding on a case by case basis where to put them.

Until checking this, I never realized any of this, by the way. I had always assumed the order didn't matter. Learn something every day!


----------



## Tod (Jan 31, 2020)

Thanks Mike, are you getting the "messages" in the "on persistence_changed"?

The problem I'm having is that nothing is functioning below the "on init" even though it is seems to be compiling everything correctly.

And yeah, until now I also thought the order didn't matter.


----------



## P.N. (Jan 31, 2020)

Hello, again, Tod.

I looked at your script more carefully and there are a couple of changes i'd suggest, unless you're doing some of these procedures for a particular reason.

You set $CONTROL_PAR_HEIGHT and width for the slider, but sliders don't require this. They depend directly on the image for that control. Still, it's alright to include it, specially if you set up an array of controls of different types.

I didn't understand why you're setting up init flags, but i didn't see a reason to use it.
In fact, the way you set it up meant that the instrument would never recall persistent control values on init, which is probably not a good thing for users that just save the instrument and don't use snapshots at all.
Since i'm not sure if this is the goal, i can't comment too much on it.
But there's another issue.

You should also set your snaphot_type to 1 so that the ICB is only called once.
In your previous example, not having this command present, and using the init flags i mentioned above, meant that the instrument would never recall persistent controls, even when changing snapshots. (it would always call up the initial callback, so it would always set your $init_flag to 1, thus never triggering the persistent callback tasks correctly.)

By changing the snapshot_type to 1, (therefore only calling up the persistence callback when changing snapshots) can result in improved performance for complex intruments.
You just need to make sure all other tasks that require updates (images, text, etc) are present in the persistence callback.

I kept it in the same structure you had before, with a "set_slider" function which can be reused, since you already got a select condition in place.

I did change the slider index to 0, since there's only one control in your example script.
The loop in the persistence changed whould then update all the other controls, when present.

I cleaned it up a little, just for readability.



Spoiler: Code suggestion





```
on init
    set_control_par_str($INST_WALLPAPER_ID,$CONTROL_PAR_PICTURE,"SAB_wallpaper.png")
    make_perfview
    set_snapshot_type(1)
 
    declare const $NUM_CONTROLS := 1
 
    declare $c1
    declare %Sldr_ID[$NUM_CONTROLS]

    declare ui_slider $Slider_5(0, 1000000)
    %Sldr_ID[0] := get_ui_id($Slider_5)
    set_control_par_str(%Sldr_ID[0],$CONTROL_PAR_PICTURE,"Tod Vert Slider 3")
    set_control_par(%Sldr_ID[0],$CONTROL_PAR_MOUSE_BEHAVIOUR,-2500)
    set_control_par(%Sldr_ID[0],$CONTROL_PAR_POS_X,357)
    set_control_par(%Sldr_ID[0],$CONTROL_PAR_POS_Y,88)
    set_control_par(%Sldr_ID[0],$CONTROL_PAR_DEFAULT_VALUE,500000)
    set_control_par(%Sldr_ID[0],$CONTROL_PAR_VALUE,500000)
    make_persistent($Slider_5)
end on

function set_slider
    select ($c1)
        case 0
            set_engine_par($ENGINE_PAR_VOLUME,get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE),-1,-1,$NI_BUS_OFFSET)
            message("Slider_" & $c1 + 1 & " = " & get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE))
    end select
end function

on persistence_changed
    $c1 := 0
    while ($c1 < $NUM_CONTROLS)
      call set_slider
      inc($c1)
    end while
end on

on ui_control($Slider_5)
  $c1 := 0
  call set_slider
end on
```




Cheers,
Paulo.


----------



## Tod (Jan 31, 2020)

Thanks so much Paulo, that little script I show doesn't show the whole script. I understand about the height and width of the slider, I was desperate when I couldn't get the slider to work so I put it in. 



> I didn't understand why you're setting up init flags, but i didn't see a reason to use it.
> In fact, the way you set it up meant that the instrument would never recall persistent control values on init, which is probably not a good thing for users that just save the instrument and don't use snapshots at all.



I'm not sure I understand this, using the "$init_flag" as I do here has always worked for retrieving the previous settings on a save and then recall. In fact that's what the KSP manual seems to say. But I have to tell you, I could be wrong, and if I am please explain.

Now please understand, I do not have that "on persistent_changed" set up any where near what it will be when I am finished with the script, maybe that's throwing you off.

But you're also talking about snapshots and I've never setup my scripts for them, so there's probably something here I'm not understanding.

Thanks Paulo, you've always been a big help.


----------



## P.N. (Jan 31, 2020)

Tod said:


> I'm not sure I understand this, using the "$init_flag" as I do here has always worked for retrieving the previous settings on a save and then recall. In fact that's what the KSP manual seems to say. But I have to tell you, I could be wrong, and if I am please explain.



I'm looking at the manual example you're refering to.
The manual is only trying to illustrate a point, or a possible use case scenario. 
It's not something they're suggesting we should do.

In your example you have:


```
on persistence_changed
  message("on persistence")
  if ($init_flag=1)
    $c1 := 4
    set_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE,500000)
    set_engine_par($ENGINE_PAR_VOLUME,get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE),-1,-1,$NI_BUS_OFFSET)
    message("Slider_1 value = " & get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE))
  else
    $init_flag := 0
  end if
end on
```

This means that, when restarting the instrument, your previous values will not be recalled.
The control will always revert to 500000 so it's not affected by the make_persistent command.

Both the instrument and snaphots will automatically recall the control (the control is persistent in your example) and the engine_pars.
So you could reverse that $init_flag and fix the issue for this example, but if you need to set up text or image states (and possibly other stuff, it depends on what else you need to be updated), this will complicate your script later on, in my opinion.

In fact, for your exact example, you wouldn't actually need anything in the persistence callback.
I was just suggesting an approach that you could follow when you need more controls and parameters added later on.

Paulo


----------



## P.N. (Jan 31, 2020)

Another thing.

I did say that engine_pars are saved in both the NKI and snapshots.

In your example (i mean, the one i edited), the function that's called on persistence is setting up the engine par for volume.


```
function set_slider
    select ($c1)
        case 0
            set_engine_par($ENGINE_PAR_VOLUME,get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE),-1,-1,$NI_BUS_OFFSET)
            message("Slider_" & $c1 + 1 & " = " & get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE))
    end select
end function
```

It's not necessary to call this function on persistence changed as it is now.
(i mean, there's the message there, but i assumed that's just for testing purposes).

If you had a label with text, or image states, then you'd need it.

Since this is a simple $ENGINE_PAR_VOLUME, it's not a huge deal that it's updated everytime the instrument is loaded (or a snapshot is changed).

However, in the case of engine_pars() that are asynchronous, we'd be forcing a waiting period on that persistent callback when it's not necessary.
The new wait_async() command helps in this regards, but if performance and optimization is important in more complex instruments, i'd take another approach.


```
function set_slider
    select ($c1)
        case 0
            if($NI_CALLBACK_TYPE # $NI_CB_TYPE_PERSISTENCE_CHANGED)
                set_engine_par($ENGINE_PAR_VOLUME,get_control_par(%Sldr_ID[$c1],$CONTROL_PAR_VALUE),-1,-1,$NI_BUS_OFFSET)
            end if
            {do all other text and image stuff here}
    end select
end function
```

This condition checks if the instrument was restarted or a snapshot was change and will not set the engine parameter in those cases, which do not require the engine parameter update.

The function would still be called upon from all the other $NI_CALLBACK_TYPES.


I don't know if i went off topic here, but... Sorry if i did.

Cheers.


----------



## Tod (Jan 31, 2020)

Thankyou Paulo, I'm truly sorry, I've mislead you with my example script. What I show is not at all the way my actual script is. My actual script will set all the controls up depending on what they are when the DAW or instrument is saved. During the first initial setup or save, it will save all the default values I have for each control. 

My whole purpose for the script I posted was to see if the "messages" showed up properly. It's not a working script. In my actual script I have these messages setup to see what's going on and the only message that shows at the bottom of Kontakt is ("end (on init)"). This means it's not even going beyond the ICB.

Does that explain a little better?


----------



## P.N. (Jan 31, 2020)

Tod said:


> Does that explain a little better?



Sure. I was just pointing out some things that could help.

Cheers.


----------



## Tod (Feb 1, 2020)

I'm sorry Paulo, I was on such a tight schedule yesterday that I hurried through everything including my first post. Some of the code I used was a desperate attempt to try find out what was going on. 

Here's some code that's not performing as I'd expect. When it's applied in Kontakt, the message at the bottom of Kontakt should be "$init_flag=1" but instead it's "end (on init)". 

Also when the slider is moved, the message should be "Slider_1 value = %Sldr_ID[c1]->value" (%Sldr_ID[c1]->value beeing the actual value of the slider). 

What is wrong with this code to make it do this, or better yet, where is my thinking wrong? 


```
on init
    message("Start")
    set_ui_height_px(260)
    make_perfview
  declare $c1
  declare $init_flag
    $init_flag := 1
  declare %Sldr_ID[9]
  declare ui_slider $Slider_5(0, 1000000)
    %Sldr_ID[4] := get_ui_id($Slider_5)
    //set_control_par_str(%Sldr_ID[4],$CONTROL_PAR_PICTURE,"Tod Vert Slider 3")
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_MOUSE_BEHAVIOUR,-2500)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_POS_X,357)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_POS_Y,88)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_HIDE,$HIDE_PART_NOTHING)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_VALUE,0)
    set_control_par(%Sldr_ID[4],$CONTROL_PAR_DEFAULT_VALUE,0)
    make_persistent($Slider_5)
      message("end (on init)")
end on
function set_slider
  select ($c1)
    case 4
      set_engine_par($ENGINE_PAR_VOLUME,%Sldr_ID[c1]->value,-1,-1,$NI_BUS_OFFSET+c1)
      message("Slider_1 value = " & %Sldr_ID[c1]->value)
  end select
end function
on persistence_changed
  message("on persistence")
  if ($init_flag=1)
    message("$init_flag=1")
  else
    $init_flag := 0
    message("$init_flag=0")
  end if
end on
on ui_control($Slider_5)
  message("Slider_5 = " & $Slider_5)
  $c1 := 4
  call set_slider
end on
```


----------



## P.N. (Feb 1, 2020)

Tod said:


> Here's some code that's not performing as I'd expect. When it's applied in Kontakt, the message at the bottom of Kontakt should be "$init_flag=1" but instead it's "end (on init)".



The message is "$init_flag=1" here, Tod. 
Using latest Kontakt 6.2.2.


----------



## Tod (Feb 1, 2020)

Thanks a bunch Paulo, I've tried it in my current nki as well as a couple of new nki files from the menu and I'm always getting "end (on init)". This is in Kontakt 5.6.6.

I just finished up a script for a client that had sliders and had no problems at all using K5.6.6.

Can you get the slider to control the first bus volume? That's what it's programed to control?


----------



## Tod (Feb 1, 2020)

Also notice I have the slider setup so that it should be vertical, but it's horizontal in K5.6.6?

"set_control_par(%Sldr_ID[4],$CONTROL_PAR_MOUSE_BEHAVIOUR,-2500)"

Maybe K5.6.6 is fawed is some way?


----------



## P.N. (Feb 1, 2020)

No, it's controlling bus 5 volume but that's what's on the script.

$NI_BUS_OFFSET+c1

c1 equals 4, so $NI_BUS_OFFSET+4 points to bus 5.

Edit: Your mouse settings are correct.


----------



## Tod (Feb 1, 2020)

Wow, ha ha, in my original script I've $NI_BUS_OFFSET+0. However, when I change it to $NI_BUS_OFFSET+0, it's still not working here.

I'm going to change Kontakt 5 versions and see what happens and I'll be back.

Thanks for sticking with me Paulo.


----------



## Tod (Feb 1, 2020)

Okay, I changed it back to Kontakt 5.5 and now it's working so Kontakt 5.6.6 must be buggy?

However, the slider was still horizontal? But then I assigned a nkr and a vertical image of a slider and it went vertical.

I managed to go to Kontakt 7.1 and now everything is working so my main problem is solved. I should have started out with K5.5, that's always worked well. I want to keep it in K5 because not everybody has switched to K6.

Okay Paulo, thank you very much, I think I can proceed now.


----------



## EvilDragon (Feb 1, 2020)

Note that most people who use K5 are not on K5.5, but rather the latest, 5.8.1.


----------



## Tod (Feb 1, 2020)

Yeah Mario, I understand, but in all honesty I haven't updated to that yet, simply because I've been holding back. I've also got Kontakt 6 and I'm sure I will have to get into that.

I've got a question for you, does the KSP 8.1 manual cover everything that's relevant to it that goes beyond all the rest of the updates?

That's one of the things I've found missing in many of the KSP manuals, a thorough explanation of everything that's new and what it means.


----------



## EvilDragon (Feb 2, 2020)

Current KSP reference that is on the website covers everything until 6.2


----------



## Tod (Feb 2, 2020)

Thanks Mario, where can I get the manuals for the various K5 versions? I've searched/looked all over NI and can't find them.


----------



## EvilDragon (Feb 2, 2020)

You can't. There's latest version only. But at the end of KSP reference you can see which features were added in which particular Kontakt version, then use that as a guideline.


----------

