# Persistent PGS



## tonewill (Oct 19, 2011)

Hello,
Is it possible to make the PGS keys persistent? I have some keys with 128 elements that are required by another script. Thanks for any help.

Barry.


----------



## paoling (Oct 19, 2011)

Since PGS are not linked with a single script I'm not sure about what you intend for that, but what about interfacing the PGS keys with persistent arrays? If you can do this, you can load the values you set everytime you reload the patch.


----------



## Big Bob (Oct 19, 2011)

tonewill @ Wed Oct 19 said:


> Hello,
> Is it possible to make the PGS keys persistent? I have some keys with 128 elements that are required by another script. Thanks for any help.
> 
> Barry.



Hi Barry,

If you are using Nils' Editor, why not put the source code for the pgs definitions in a separate file and then import it into each script that needs to use it? That way a single copy can be used by multiple scripts with just a simple *import* statement.

Rejoice,

Bob

BTW If you aren't using Nils' Editor you should be :lol:


----------



## tonewill (Oct 19, 2011)

Thanks for replying Bob.

I don't have a problem accessing the PGS data (defined in one script) from both scripts, the problem is keeping the contents of the PGS keys 'between sessions' in a similar way to make_persistent does with normal variables. I can't find a way to make a PGS key persistent, I wondered if I was missing something obvious.

By the way, I am, of course, using NILs editor, we both commented on another thread about problems we found with the latest version :wink:. 

Thanks again,
Barry.


----------



## tonewill (Oct 19, 2011)

Hello paoling,
Sorry, I missed your reply. I understand but...

Let me put this a different way: Is there a way to know from a PGS callback, which index of a PGS KEY has been changed? If not, I'd have to copy the whole pgs key to an array every time any of the indexes are changed (by a knob on another script).

Hope that is intelligible,
Barry.


----------



## paoling (Oct 19, 2011)

Well, you could assign the values to the array BEFORE assegning them to the PGS KEY. In this way you already know what index position is.


----------



## tonewill (Oct 19, 2011)

Hello paoling,
The array is in a different script from the controls that alter the values, or I wouldn't need PGS in the first place. Thanks anyway.

I take it from the replies that PGS keys cannot be made persistent themselves and PGS callbacks cannot determine which index has been changed. I need three 128 index arrays whose values are to be determined from another script and whose values are to be kept between sessions.

The first part can be done with PGS alone, but the values aren't kept. I could loop through all 128 indexes and copy them to an array on every slight turn of a knob that alters just one index, but I just thought there might be a better way.

Thanks all,
Barry.


----------



## Big Bob (Oct 19, 2011)

Hi Barry,

Sorry I misunderstood your original post :oops: 

It sounds like maybe you have a script that maintains a persistent array that several other scripts need to read. If that's the situation, why can't you 'fake' the persistence part by using a post_init routine (executed in the pgs callback) to copy the persistent array values to the pgs arrays only when the first script is loaded or first run.

Since the foregoing suggestion seems kind of obvious, I have the feeling that I still don't have a clear picture of the problem yet :lol: 

Should that be the case, could you please restate the problem in its most basic form?

Rejoice,

Bob

EDIT: It just occured to me that maybe you are trying to run the 'slave' scripts by themselves when the data-changing script is no longer present?


----------



## tonewill (Oct 19, 2011)

Hello Bob, thanks for helping, I'll try explaining what I'm after in another way. I'll simplify it from what I'm actually doing to, well, simplify it!

Script one defines a PGS variable with 128 indexes, one for each note. Each index is a value that holds, say, volume, or pan, or tune, or whatever for each note. A menu selects a note (sound) and a knob changes the value and updates the corresponding pgs key and index. These values are not used in script one itself.

Script two uses these values directly by using pgs_get_key_val(key,index). This works absolutely fine. However, these values need to be retained. When you re-load the instrument, they are all set to zero.

I'm trying to find the best way of retaining the values. As mentioned, it seems a bit OTT to copy the whole pgs key (with 128 indexes) to a persistent array every time any one of these values is changed in script one. If Kontakt had an 'on_exit' callback, I could do it there once at the end of the session but, as you know, it hasn't.

Thanks for any help, hope I've explained it more clearly this time.

Barry.


----------



## Big Bob (Oct 19, 2011)

Hi Barry,

What still isn't clear to me relates to my post-script edit to my last post.

Are you saying that when you reload the 'client' scripts, the 'server' script is no longer present? Or possibly are you saying when you load and alter the 'server' script (thus updating some portion of the pgs arrays) , that the 'client' scripts are not present?

If all the scripts are present when you load the instrument, I don't see what the problem is nor why my suggested solution wouldn't work. So, please clarify whether or not all the scripts (the 'server' that alters and the 'clients' that read the pgs data) are loaded whenever the instrument is loaded. If so, maybe I just didn't present my suggestion clearly enough :lol: On the other hand if the scripts are not always present when the instrument is loaded, then please concentrate on that aspect of it when you describe the problem.

Sorry to be so dense, but, sometimes I have a senior moment :lol: 

Bob


----------



## tonewill (Oct 19, 2011)

Hello Bob, Thanks again.
Both the scripts load fine! The problem is the contents of the pgs variable array is not retained because you cannot make it persistent, that's all. I'm trying to find the best way around that.

You cannot feel as dense as I do when I try and understand the equations in you math library :shock: :wink:. 

Barry.


----------



## Big Bob (Oct 19, 2011)

But you are still not answering the most important part of my question.

When you load an instrument that you wish had persistent pgs arrays, does that instrument contain both the 'server' and 'client' scripts?


----------



## tonewill (Oct 19, 2011)

Hello Bob,
Yes.


----------



## paoling (Oct 19, 2011)

Sorry, but:

Script 1 jobs:
on init - load the array persistent_array[128] and copy it to the PGS

on a callback that should modify the PGS
persistent_array[index] := value
set_PGS_KEY[index] := value

--------------
Script 2 jobs:

on PGS_KEY change
do something.

--------------

Sorry if this isn't the formal language of KSP, but in this schematic approach what's wrong? If the first script is the only one who modifies the PGS_KEY (so you are basically reserving a script for defining the GUI), and the others scripts just read it, you can use the first script to store in the persistent array the same values of PGS_KEYS.

Oh.! A question that briefly came to my mind, in a multiscript setting do anyone knows how the different script callbacks are handled? Sequentially? sorry to be OT, I'd just be content with a simple and short answer 

Paolo


----------



## Big Bob (Oct 19, 2011)

tonewill @ Wed Oct 19 said:


> Hello Bob,
> Yes.



OK Barry, in that case, I still think my original suggestion will work. Here's an illustration that may clarify what I meant.
_{ script #1 }_

*on init*
``pgs_create_key(ABC,128)
``*declare* p.ABC[128]
````make_persistent(p.ABC)
``pgs_create_key(XYZ,128)
``*declare* p.XYZ[128]
````make_persistent(p.XYZ)
``_{ etc }_

``_{ then put this at end of ICB }_
``*declare* n
``read_persistent_var(p.ABC)
``copy(ABC)
``read_persistent_var(p.XYZ)
``copy(XYZ)
``_{ etc }_
*end on*

_{ Now, whenever script#1 needs to alter the pgs data, use a macro like set_pgs which will
also alter the persistent array. The other scripts will see the pgs data as before and,
in addition, when you close and later reload the instrument, script #1 will
refresh the pgs arrays from the persistent arrays. }_

macro set_pgs(#name#,index,val)
``p.#name#[index] := val
``pgs_set_key_val(#name#,index,val)
*end* macro

macro copy(#name#)
``*for* n := 0 *to* 127
````pgs_set_key_val(#name#,n,p.#name#[n])
``*end for*
*end* macro




Why wouldn't something like the above give you equivalent of persistent pgs data with minimal runtime burden (only need to write the changes two places instead of one). The one-time refresh only occurs at the end of the ICB and not during the 'heat' of usage.

Rejoice,

Bob

Hey Paolo,

I'm not sure I followed your question. Are you asking about the scheduling order of MS callbacks. For example, ui_control versus midi_in or are you asking about the callback scheduling order for the script slots or what? :?


----------



## tonewill (Oct 19, 2011)

paoling and Bob, thank you so much! I'm sorry if that was what you were telling me previously, I didn't read it that way. I'm annoyed that I didn't think of this myself!

Thanks again,
Barry.


----------



## Big Bob (Oct 19, 2011)

tonewill @ Wed Oct 19 said:


> paoling and Bob, thank you so much! I'm sorry if that was what you were telling me previously, I didn't read it that way. I'm annoyed that I didn't think of this myself!
> 
> Thanks again,
> Barry.



You're a little young to be having a senior moment, but then, I guess it happens to the best of us :lol: 

Rejoice,

Bob


----------



## paoling (Oct 19, 2011)

I'm glad that you found our suggestion useful..!

Hi Bob, I was thinking about the handling of the same callbacks from different scripts.
If I press a note, how the "on note" callback will be handled by the two scripts? 
I'm also wondering about ID identities, can them be shared between callbacks like PGS Keys? 
Thank you, in advance


----------



## Big Bob (Oct 19, 2011)

Hmmm, what did you men then by the phrase 'in a multi-script setting' ? It now sounds like you are talking about instrument scripts since you mention 'on note' callbacks (which of course do not exist in the multiscript).

Again, I'm not sure what you mean by how the NCB is handled by different script slots. If no ignore_events intervene, the NCB of each script slot is triggered sequentially from slot 1 up to slot 5 in that order.

If your questions are more involved than that, have you read my note/release callback study yet? I'll attach it to this post in case you haven't seen it yet.

Rejoice,

Bob

EDIT: whoops! I forgot this:



> I'm also wondering about ID identities, can them be shared between callbacks like PGS Keys?



When you say 'shared between callbacks' do you mean shared between script slots? In any case, there is a full set of 'event parameters' which can be read and altered in each script slot and this can be very useful in coordinating multiple scripts. Again, I don't know if this is what you mean when you refer to 'ID identities'. Please try to use the correct terminology to avoid ambiguity :roll:


----------



## paoling (Oct 21, 2011)

Thank you so much Big Bob!


----------

