I’ve been trying to get my head around the requirements for State Reset but not having much luck figuring out how to implement this so I’m opening it to discussion in the hope of clarifying some things.
First some background… the idea for this originated out of pre-loaded set lists where you have a rack active in one song, it get’s modified in some way (typically via bindings) and when you move to the next song it’s left in that modified state and the rack isn’t really how you might expect it in the new song.
Lets call these changes “transient changes” - ie: changes typically made via bindings, but possibly also by tweaking the settings in the UI.
There’s a couple of situations here:
If the rack has the same state selected in the next song, then Cantabile doesn’t bother switching states because it figures it’s already in the correct state. Transient changes aren’t reset even if controlled by the selected state behaviours.
If the rack is in a different state in the next song, then Cantabile will load the new state but only the selected state behaviours are applied (as is normal when switching states). Any transient changes not covered by the selected state behaviours won’t be reset and will carry over from the previous song.
Also, around this topic some other points have been raised:
Sometimes when transitioning between two songs you actually do want the parameters from the previous song to carry over.
It would be handy to have a song/rack/state reset command to manually reset a state to how it was when originally loaded - kind of like a revert to loaded state command.
Ability to control which plugins (or objects) are affected by these state resets.
When resetting a plugin - only the modified parameters should be restored (since that’s fast) rather than reloading the entire plugin state (which can be slow depending on the plugin).
That’s what I’ve gathered together as the problem/requirements.
The solution I’m considering is to add one new setting to each state called “Revert transient changes since previous state” which would be off by default (to maintain the current behaviour) but when turned on would cause Cantabile to revert (ie: undo) any transient changes to the previous state before loading the new state.
This would also apply when loading a song with a rack in the same state as currently selected - if the state has the revert option turned on then the transient changes would be reverted and the state restored to how it was previously.
Some more notes, comments, questions:
This logic would apply to all state controllable object - not just plugins.
For plugins there would be some special case handling such that transient changes only includes parameters - not the “Entire bank” behaviours.
Would this option make more sense on the previous state rather than the next state? (ie: “Revert transient changes when leaving this state” as opposed to “Revert transient changes when entering this state”).
This new setting would be on the top level state object - so you could create two linked states, one with revert turned on and one with it off.
There will probably also be a “Revert State” command added to the state panel’s context menu. This will reset the state regardless of the revert setting. Similarly there could be a “Revert Object State” command so you could manually reset one plugin for example.
I’m not sure about including one more per-object setting that says to “always/never” revert transient changes. This would override the state’s revert setting. (ie: when loading a state with revert turned on, you could override this setting on a per-plugin basis). This has been asked for, but not sure how important it is - it makes it more complex and I think can be worked around to some extent by having different objects in different racks.
I’m not sure I’m following the technical aspects of this discussion, but occasionally when switching from one state to the next, I would like for the last sound from state 1 to continue to decay and die naturally, even when I play a new sound after switching to the State 2.
To me this seems more of a per-user setting. Not a per-song or per-rack setting.
Given the choice, I would like to define in the settings that I want my songs to revert back to the state they were saved in when I load them or switch to them from the set list. I want to set this once then forget about it.
And I would really like to see a “revert to saved” button so I could get my song back to the state it was in when I saved it. This would be especially useful in edit mode when I’m tinkering around with parameters and end up messing up the song. (With a preloaded set list it isn’t enough to “reload” the song because it doesn’t restore the original settings…)
Perhaps the behaviour could be different between live mode and edit mode? In edit mode - the songs and state revert to saved, in live mode the state of a rack persists betweens songs?
OK, yesterday I wrote the code to actually be able to do a transient change reset, but I think I’m going to set it aside for the moment. This area is still very grey to me and I don’t want to make it worse by introducing something that’s not right.
Please keep the suggestions and discussion going though - this is obviously an area that could use some improvement but I need some more insight and I think just some more time to dwell on it.
@brad, I think your suggested solution would nicely fix the general problem of racks being left in an unpredictable state because of bindings used in a previous song, which I guess is the really unpleasant scenario (and I guess now having implemented it, you’ve tested it!).
Would it ever be useful on states other than the first (or entry) state of a song, i.e. for states part-way through a song? My understanding is that Cantabile is able to reliably track changes to parameters via bindings and so as you step through the states, the changes will be reliably set, even if two consecutive states have the same value for a parameter and the parameter has been modified via binding.
Honestly, I’m not sure that the benefits of state reset will outweigh the risks and complications. Currently, I’m pretty happy with the way things are; I just use explicit initialization of my changing parameters via triggers, which can be switched on and off per state. This makes things extremely controllable in very fine detail. The only complication is that it is necessary to create these triggers for every song - which is easy to solve via template songs.
And now that we have loopback ports, I think I’ll re-work my triggers: instead of sending individual MIDI controllers to all potentially affected racks (volume, modulation for leslie level or tremolo, …), I’ll simply create one trigger for each of my input controllers (Expression, modulation, sliders) and send them to loopback for my main keyboard. This will also avoid having “dangling” triggers in my template song when racks get deleted. Plus, it will probably help me with jump prevention (will have to check that one out - haven’t gotten around to it yet…)
But maybe @WeepingBoil’s idea has some interesting aspects: simply have a command to revert a song to its saved state regarding any modified parameters. This command should then be addressable
via the menu / a hotkey (convenient in editing mode)
by a binding - so it could be controlled with a button on your keyboard (kind of a “panic button” when a song doesn’t behave like it should)
by a trigger (e.g. on song load --> reset song) - enables automatic song reset
That could actually be a fully optional solution for people who want / need a full reset without any bad impact on people like me who prefer a more fine-grained initialization
@Torsten I quite like the idea of having a full song reset accessible via trigger, so songs could trigger it on load to ensure they’re working from the correct saved state (or not, if you deliberately want to leave racks in the previous state, to provide controller continuity when playing songs into each other).
My only concern is that for many users it might seem overly fiddly/complicated to have to set up a trigger, just to make songs behave as they would expect, i.e. work in performance the same as it did when setting up. I fell foul of this one at a gig a while ago - for one particular song I’d never practiced it immediately after another song that ended with a pedal fade-out, but that’s the order we played it at the gig, and I found myself on stage with no sound. To make it worse, I didn’t have (or need) an expression pedal binding set up in that song, so I couldn’t even fade up the sound. In the heat of the gig I was puzzled, because it had always worked when practicing. It feels to me that this problem needs to be easily solved for the majority of cases, without the need for users to remember to set up triggers, because it only needs you to forget that trigger once to cause a problem you may not find until you’re on stage.
It feels like the default behaviour should be that songs behave as you’ve saved them, always, regardless of what song was played before, unless you override this. So my vote would be for a song-level flag to say “Reset to saved state”, which defaults to false for existing songs (so that existing behaviour isn’t changed), and defaults to true for newly-created songs.
That’s why I suggested the option to assign song reset to a binding (which you can put into your background rack) - this way, if something goes pear-shaped, simply hit your “panic” button, and your song should reset itself.
But I think I could live very well with your suggestion of a song-level flag.
Maybe both solutions (on-load-flag plus explicit command) could work well in combination…
Hmm, my only worry about this is the same as with my “trigger” method: they are hard-coded into the song, so it always resets. Often, the necessity to keep levels consistent from one song to the other lies in the sequence - a reset is useful between “Song A” and “Song B”, but when playing “Song C” and “Song B” in sequence, levels should stay the same. In this case, I would probably leave all of my songs to never reset themselves and always use a manual binding to reset when necessary - probably more intuitive this way.
Need to think about this a bit more - I rarely have the necessity to blend from one song to the other…
Ah yes, actually I hadn’t thought about putting the trigger in the background rack - perfect! Even so, it means new users who are using bindings are likely to have to learn about triggers and set this up, just to get their songs to behave the same each time, which seems wrong to me.
Hmmm yes, good point about alternative set orderings. But then I guess it’s arguable that if you want a song in one context to follow on from what came before, and the song in another context to start from fresh, setting up levels etc., then perhaps it’s acceptable for the user to either have two versions of the song, or trigger the reset manually.
I think with things like this, there will always be edge-cases where the generally good solution won’t work well. But fortunately, Cantabile is flexible enough to usually offer several alternative ways to achieve the goal. We’re probably over-thinking this.
That feels like the most straightforward approach so far, and perhaps easier for users to get right than @brad’s state-based approach.
I’ve been thinking about this over the last few days and I think the best solution is one per-rack/song setting called “reset transient changes when loading new song”. This will give a more expected experience and leaves the more complex - in-song scenarios up to the user.
It also solves some problems around when to capture the pre-transient state and interactions with auto save states.
This new setting will on by default for new racks, and off for previously saved rack - so as to not break existing setups.
This is how I handled C2 projects - if something needs to be in certain condition, and there’s a chance something else may have tweaked it, then a trigger or a bank load is the guarantee.
A further ‘reset state’ option is not necessarily a bad thing, nor does it limit one’s ability to use the trigger option.
It’s the kind of thing the user would need to watch - not unlike the Automatically Update States option.
As long as we’re looping back around on this, I agree with @Torsten and @Ade. If you NEED something to be in a certain state (i.e. configuration), set it manually. However, I do find when I go fiddling around in a song and want to put it back like it was, a “Reload/Reset to last (manual) save” would be very helpful.
I’ve hit this a couple of times lately while experimenting with the new Bindings.I’m about to go in an experiment some today and I’ll likely wish I had it again.
I’ve been meaning to get back to this topic for a while now. With the new bindings support I think the requirement for this has changed somewhat. Rather than Cantabile trying to automatically reconfigure things I think it’s better if the song/racks use bindings to set this stuff up explicitly.
I agree however that the ability to reload a state or song and all it’s rack states is probably a useful editing feature (as opposed to something used during performance).