Yes,
Max is more perfect than
Pd . Yes, a lot has been done in it for productive work. Finally, its interface does not slow down with a large number of objects in the patch. However, there is something magical in
Pd that forces you to open this simple interface written in
tcl / tk again and again, with its simple boxes and colors that please the night. Maybe this is the very open source magic that makes people use gentoo on the desktop?
In this article we will try to solve one sore subject of all users of this wonderful program, namely, the preservation of the parameters of numeric boxes, sliders, knobs, etc. It would seem a very important function. Why is there still no special object similar to the
preset in
Max ? The thing is that using the
PureData API you can not access data from other objects, so you have to get out.
Of course, there were attempts to implement presets. I looked at some of them, but their implementation seemed to me difficult (yes, I didn’t understand them completely) - I wanted something light and flexible. As a result, after a day of thought and evening of patching, such a system was born.
Formulation of the problem
To save the presets, we need:
- constantly monitor the saved parameters;
- be able to extract and save them at any time;
- be able to restore the state of objects from stored data.
I immediately remembered the
pattr and
pattrstorage objects from max. The first connects with a gui object, the value of which needs to be stored, and the second is the data store. It was decided to do something similar.
We represent how everything will be
So, our “analogue” of the
pattr object will monitor the parameter, and the analogue of
pattrstorage 'will, if necessary, poll it and save the values. We call these objects
store and
storage, respectively. All this should look something like this:
')

The
store object will store the current one, as well as assign a new value to the numeric box. That is why these objects are interconnected in such a way. Using the message
“save” storage will send a command to the
store so that it sends the current value of the numeric box to it.
“Recall” will do the opposite - to ask boxing a new value.
So, the general view is clear, moving on.
Making the base
Max presets information is stored in
json format. Theoretically,
Pd can work with it through the
PuREST library, but it is sharpened for online services, and why complicate things? The easiest way to write data to a .txt file is by using a
textfile object. It can save any number of messages and display them in sequence. More information about how it works, you can read in the help, and now proceed to create objects.

The picture above shows a screen with comments of three open patches.
root is a test patch in which we will check the operation of the
store and
storage . In the script, at this stage it is already possible to save and restore the value of one numeric box. The procedure is as follows:
- change the value of the numeric box;
- press “get” - this will clear the textfile , after which bang will be sent to [s presetTrigger] . The recipient of this bang will be a float object located in the store , which will output the stored number through its outlet and send it back to the store , where it will be output through [r presetGetAll]], will turn into a message like “add% number_from_box%” and go to the textfile ;
- press “store” - this will send a “write” message to the textfile and create a text file in the folder with the root patch, which will contain all the parameters of the preset;
- change the value of the numeric box, then press “recall” - the previously saved value should be restored.
We increase the functionality
So, we did the main part and successfully tested performance. However, at the moment you can save only one parameter, which is not good. As we remember, the
pattr object in the argument must specify the name of the parameter, the value of which will be remembered. Thus, max indexes the parameters in the json file so that you can later restore the data to the necessary gui objects. We will do something similar and do it slyly. Take a look at the screenshot:

As you can see, in the
root.pd patch
, now three numeric boxes are connected to three objects
[store one] ,
[store two] and
[store three] . Each saved parameter is given a name. Now, if you twist the parameters of the boxes and open the preset.txt, you can see something like this:
three 67;
two 43;
one 165;
That is, each parameter in the file was added an index corresponding to the argument entered in the
store object. This is done thanks to the so-called
abstraction creation arguments . If you look closely at the
store.pd patch, you will notice that the
route and
prepend objects have the argument
"$ 1" - these are the arguments. The bottom line is that when using a patch as an abstraction, inside is not $ 1, $ 2, $ 3, etc. are replaced by the first, second, and third arguments, respectively. That is, the
[route one] and
[prepend one] objects are actually in the
[store one] .
Now about that, for which, in fact,
prepend and
route were added. The first of them before sending the parameter in the
textfile creates the same index that we saw in the text file, and
route c filters out parameters with non-foreign indexes, when the entire contents of the text file are translated via
[p presetSetParam] .
As mentioned earlier, with
bang you can display one message from the
textfile . When the last message is reached, the object displays
bang through the right outlet.
In order to extract all messages, you need to go through the entire file, which makes the
until object. This is a very interesting object. If you submit any number, say,
ten , to the inlet, it will output 10
bang messages one by one . If the input is simply
bang , then
until will generate
bangs until
bang enters its right inlet.
Now you can figure out what happens when you click on the message
"recall" . First,
bang enters the
“read preset.txt, rewind” message , which loads the
preset.txt file
into the textfile , and then sends the
“rewind” message, which makes the next
bang received by the object output the first parameter from the file. Then
bang goes to the
until object, which generates
bangs one by one and sends them to the
textfile until the latter takes
bang out of its right outlet and stops
until .
At this point in the preset, you can only save numbers, but in order to be able to be used in real patches, you must add at least the preservation of lists. We do this by creating analogs of the
store store for other data types. Rename our
store to
sfloat and create a
slist object.

This is a slightly modified patch
sfloat.pd , adapted for lists.
The next step is to add the ability to save different presets. Considering how to implement this, I came to the conclusion that it is best to save each preset to a separate file. In this case, there is no need to construct additional logic that separates lines for different presets in a text file, and the smaller the patch's complexity, the more stable its work will be (after all, it’s one thing to save two or three parameters, and another when there will be a hundred).
So, in order to be able to manage multiple presets, we need to change the contents of the message boxes “read preset.txt” and “write preset.txt”, namely change the file names for the corresponding presets.
Take a look at the modified
storage.pd :

A new object appeared here:
makefilename . It is designed to generate file names and is perfect for us. When a number enters the inlet, the object displays a message like
“preset-% i.txt” , replacing
% i with a number. I also had to display “rewind” in a separate message box, since I did not find an easy way to generate a complex message with a comma.
Everything, now the system works. Now add convenience by making a small gui. Open storage.pd, right-click on an empty place and select Properties. In the window that appears, check the
“Graph on parent” box, after which a red rectangle appears in the patch. All interface objects, like buttons, numeric boxes and comments inside this rectangle will be displayed in the patch a la maxio
bpatcher . The size and position of the rectangle are set in the
canvas window using the
size and
margin parameters.

This is how the
storage object in the patch now looks like:
![Presets PureData. The final version of the object [storage].](http://pattr.ru/img/pd-preset/7.png)
Now
Pd has become a little more comfortable :)
At last
This system of presets is not enough to save the tables, but I will postpone it for the future, as it is likely that some tricky witch would be necessary for us to be comfortable. Also, it would be nice to add an inlet to the storage for external control of the presets, so that you can pull up some MIDI controller.
You can download files from the site
pattr.ru from the section
"Patches" , enjoy!
direct link