this message goes out especially to Will Pirkle.
I have discovered that when you port your nicely made RACKAFX GUI into AU form that builds correctly into Xcode, no problems there.
However when open in my local DAW which is Logic Pro X, you are able to select presets and create new ones but when saving the project then reopening it, RACKAFX plugins Initialise to default settings instead of remaining how you left them when saving the project file meaning if you didn't save a preset, its tough luck and if you did you have to reload the preset again which is tedious to say the least.
I tested this with my own plugin in designed in RACKAFX as well as the standard MiniSynth template both produce the same results. Any advice on this?
I just checked this and the problem is because the host is not calling RestoreState( ) on the plugin to set the state when the plugin loads. To be honest I am kind of stumped on this as my "native" synth book plugins have no issues with this. I will continue to debug and let you know if/when I find anything.
If anyone else knows why RestoreState( ) would not be called, please let me know!
Thanks for replying Will,
I had tested the native synth plugins as well and noticed the same thing, that they do not have this issue.
I have been messing with the code for most of the day to correct this but no results yet. I thought that perhaps a work around is, I could setup some kind of temporary preset that stored when logic is closed and is recalled when the host reloads the project. But I'm not sure if this is possible also that may not be the best way to store the information, I have been playing about with the SaveState function to try and recall last current state but I'm sure if this will work?
For sure something is amiss; the SaveState( ) and RestoreState( ) mechanism is supposed to be somewhat "automatic" (it is called "magic" in the Apple documentation) and it is as if the Host knows not to even try to call RestoreState( ) -- it does call SaveState( ) when you save your session...
I have also been playing around with the code for most of the day and remain stumped; even resorted to calling a buddy at SoundToys...
We really need for the Save/Restore mechanism to work properly and not mess with workarounds : (
Yes this is definitely annoying, I can't believe it is such a big issue. I was hoping I was just missing some code in user interface update and there was a couple lines of magic code for the solution.
SoundToys do some impressive plugins! I hope they were some kind of help.
I did try to implement the rough idea of the JUCE code by having the save state and the restore state goto some CF mutable dictionary and back again, I'm not sure whether this would work fully or whether it is just another run around.
I will keep at it for now, see if there is any tweak that may work.
OK I found the problem - one line of code. But when debugging I also found a couple of other things regarding the synchronization between the custom GUI and the default interface which also needs addressing; the restore state requires tight synchronization between the two.
I will have a fix for you later.
Brilliant work Will!
I knew you'd figure it out quicker than I could, I have had limited success with the JUCE idea and now I seem to have faltered the plugin save system, this may sound like a foolish mistake but I swapped the inData for the outData in restore-state just for curiosity and now it seems that whenever I try to save a preset it initialises instead of saving the parameters, I swapped them back after but the problem remains. But perhaps your fix will do this problem at the same time... Its funny because the problem spread to the mini synth even though I didn't recompile it...hope some internal permissions aren't broken or something is disturbed...
EDIT:Just had a development on this issue, if I adjust the setting in the GUI and save them the preset initialises and doesn't save the parameters but if I go to controls instead of showing the GUI and alter then save, it works and then it's reflected in the GUI, so just the GUI doesn't save parameters to presets, so I will investigate the issue further.
Yes, I've also fixed that as well. The parameter sync must be strict between the GUI and the default "controls" and presets are also affected. The good news is that there's not much code that has changed and there was no need to mess with the inherent save/restore mechanism so no kludge code or band-aids; all Apple approved.
I will make a post when I've got files for you to use.
Ah thats great Will. Thanks for responding and being patient with me about this problem. Also Apple have just pushed LPX 10.2.2 update stating "This update addresses overall stability and performance issues" whether this will give any boost is unknown but the timing is both a coincidence and interesting
OK, I've got a simple file-copying fix until the next rev of RackAFX (which should be coming soon!). Download the file here:
and follow the instructions in readme.txt to apply the fix. You will need to use Make AU again in order to get the new corrected project. Please let me know if you have any issues. This fixes the problem with RestoreState() and the synchronization between the GUI and the default controls. Presets should now work properly with both interfaces and changes on one interface will cause the correct changes in the other.
AMAZING! I have just downloaded the file and placed the fix into folders you said about.
it is working perfectly, saving presets working great, no initialisation when saving presets, logics icon goes transparent which prompts you to save after any adjustments in my new plugin upon closing and appears right where I left it last time even if I didn't save a preset.
Many thanks Will, you have not only made this RackAFX user very happy, you have solved the problem for future users!
I'm experiencing similar problems with the RAFX/VST-dll. I've tested with simple plugins and they seem to restore their state after recreation, so it could be that for my case I destroyed that funtionality somewhere along the way. But by chance, could it be that my problem is somehow related to what you discussed? Also, what is the VST equivalent to SaveState( ) and RestoreState( )?
No, the AU and VST3 implementations are unrelated. The RAFX DLL-as-VST3 is done with a static library I wrote, however, you can see the nearly identical code that I use by using Make VST and porting your project as a full-blown VST3 project (you can even port a simple volume control, the code doesn't change).
The equivalent functions can be found in the Processor.cpp file where your presets are serialized. Interestingly, there are three functions to implement:
getState() and setState() are for the processor part of the plugin. You then have to add a third function named setComponentState() to handle updating the GUI when presets are loaded.
This is the READ part of the serialization process. We get the stream interface and use it
to read from the filestream.
NOTE: The datatypes/read order must EXACTLY match the getState() version or crashes may happen or variables
not initialized properly.
tresult PLUGIN_API Processor::setState(IBStream* fileStream)
This is the WRITE part of the serialization process. We get the stream interface and use it
to write to the filestream. This is important because it is how the Factory Default is set
at startup, as well as when writing presets.
tresult PLUGIN_API Processor::getState(IBStream* fileStream)
This is the serialization-read function so the GUI can
be updated from a preset or startup.
fileStream - the IBStream interface from the client
tresult PLUGIN_API Processor::setComponentState(IBStream* fileStream)
If you need to serialize state information that is not based on RackAFX declared variables, then you will need to append some code to serialize that information. If you look at the Make VST code it should be fairly straightforward to see how to read and write your data to and from the preset file.
Somehow, the setState() function is not working properly for my (make-VST version) synth. I tracked the filestream from both get- and setState() and they write and read the right values. However, these never make it into the Synth, which is in initialised mode, just some controls are really odd valued. I tried to block out setState() and the values weren't odd then, so I know somethings wrong in there. I also noticed setState() is called twice upon creation. I guess thats the RAFX-plugin initialising? (I'm wondering, because the controls are initialised in the RAFX-plugin contructor anyway.)
I know you're rather busy at the moment, I'm not expecting you to give me a solution here. But if anything comes to your mind while reading this I'd be happy if you dropped me a quick note.
First, the RackAFX plugin does not call any VST3 functions. The multiple calls to get/setState (or any of the VST3 functions) are being done by the host, and I have also noticed multiple calls as well. You also need to implement the third function setComponentState( ). In getState( ), you can watch the data get written into the RackAFX variables to see your plugin get initalized:
e.g. for a float variable that is one of your synth parameters:
setComponentState( ) is used to synchronize the parameters which are set in the initialize() function and are the parameter-bindings for the GUI to stay in sync.
If you have other variables that are not RackAFX controls, then you need to write the serialization code for them. Another thing to check is this - if your Synth variables are initialized properly in getState( ) which you can watch, place a breakpoint in the doControlUpdate( ) function which is called from process( ) to see if somehow they are being overwritten with bad data - that would also be coming from the host, perhaps as a bogus preset?
The serialization operations in get/set state AND setComponentState must be identical (ie the variables are read and written in the same order) so each variable is properly read and written. If you are modifying those functions then you need to keep that in mind.
thanks for your fast answer. I got it working after deleting unused RAFX presets that I used to test parts of the synth. I'm still not certain what happened, since none of the presets matched the odd values loaded.
Anyway it's working. Now I just have to make a nice skin and then it's time to release this baby 🙂
In VST the presets are serialized in order that you write them. If you change the order of read/write then the presets will be wrong. This paradigm exists in other serialization schemes as well. In RackAFX the presets are saved in a file that binds them to the Control ID value in the RAFX GUI. The order of the data is not important. While that solves the problem of keeping read/write in sync, it opens another problem: if you make a RAFX preset, then you decide later to re-assign the GUI control to another variable (which will likely have different default/preset value), the preset will still hold the old value. That is what I think happened to you.
In any event, glad that you are up and running - please send a link to the release page when you are done, and I'd also like to have a bunch of screen shots of your awesome GUI for the GUI Gallery!
I found out what caused the odd values, since I'm comming across them again. It's sendUpdateGUI(). For the RAFX version it works fine, but in the make-vst version it sets exponential controls to where they were if they were linear controls. The underlying variables are fine though. Any chance I can look at the code that "sets" the GUI-controls? sendUpdateGUI sends a message, but where is it going?
#if defined _WINDOWS || defined _WINDLL
SendMessage(m_hParentWnd, SEND_UPDATE_GUI, 0, 0);
m_uPlugInEx = 1; // flag
Which version of RackAFX did you use to create the VST Project initially? Older versions of RackAFX treated the Log and Volt/Octave controls the same way.
If you look in the Processor::initialize( ) function you should find this:
param = new LogParameter(USTRING(pName),
i, /* INDEX !! */
param->setPrecision(pUICtrl->uUserDataType == intData ? 0 : 2); // fractional sig digits
param = new VoltOctaveParameter(USTRING(pName),
i, /* INDEX !! */
param->setPrecision(pUICtrl->uUserDataType == intData ? 0 : 2); // fractional sig digits
If you do NOT have the param = new VoltOctaveParameter(...) code, then I can understand why this happens. In older versions, both log and exp controls used the same LogParameter taper object, instead of a separate VoltOctaveParameter taper object. If you have the older version, then let me know and I can show you how to fix it.
The sendUpdateGUI ( ) message is handled in
which calls updatePluginParams( )
which updates the parameters with:
The setParamNormalized( ) method uses the taper object (log or volt octave) to move the GUI controls to the proper locations. If you have an older version of Make VST, then it would be using that Log taper object for Exp controls.
Let me know - you can email me directly if you want.
Most Users Ever Online: 152
Currently Browsing this Page:
Guest Posters: 1
Newest Members:Mistahbrock, Jas, Rowan, sojourn, fabhenr, rg1, Niklas, Wutru, Tim Campbell, Danny Jonel
Moderators: W Pirkle: 573
Administrators: Tom: 74, JD Young: 80, Will Pirkle: 0, W Pirkle: 573, VariableCook: 3