Issues when changing or adding racks in existing songs

Here’s another one for @brad:

  • I have a song that uses a specific rack - in my case a guitar amp rack. The state behavior for this rack has “Selected Rack State” active.
  • Now I replace this rack using “Use different rack” - with a rack that has different rack states, and none that correspond to the state names previously used in the song. E.g. previous rack had “Crunch sound” and “Heavy Crunch”, new rack has “Marshall Crunch” and “Marshall Heavy”.
  • I go to the first state (State 2, currently with an error message), select “Marshall Crunch” and update the state
  • I go to the next state, which now doesn’t display an error message, but dutifully shows “Marshall Crunch” and update the state.
  • Once I get to the first state that uses the “Heavy” state (State 10), I change it to “Marshall Heavy”, update the state and proceed to the next (that also is supposed to use heavy)
  • again, no error message, but I dutifully press “update state” and proceed.

At the end of this procedure, I would expect all states to have the correct rack states saved for the new rack. But it seems the only song states that have the correct rack states saved are States 2 and 10; all others still have the states of the old rack embedded (which also shows as an error when I verify the setlist).

So it seems that I need to go to every rack state and explicitly change the rack state (to a different value and then to the correct value) before updating. This is pretty un-intuitive and error-prone. At the very least, I’d expect the rack to show the error message with the “not found” rack state. Or, if the rack shows the new state kept over from the previous state, I’d expect the new rack state to be correctly stored when I update the song state.

@brad: hope something can be done here!

A second complication with song states: when I insert a new rack into a song with multiple song states and then set song state behavior for one or several of its parameters, there is no “default” value written to all the song states, so the values are undefined for all but the current song state. As a result, parameter values will carry over from the current state when I change states, which can be pretty unpredictable after some states have been updated.
Currently, I have to manually walk through all states and “update state” after I’ve inserted a new rack in an existing song to avoid this unpredictability. I’m not sure if “update all states” on the state behavior would work or if it will fail due to there being no stored values for this parameter at the moment.

I would very much prefer it if - when inserting a new rack in an existing song and activating state behavior for a specific parameter, the current value of this parameter would automatically be incorporated in all states of the song, so I don’t have any issues with that parameter being undefined in some states.

Makes sense?

Cheers,

Torsten

2 Likes

I had similar behavior with v3 several times. I went through all song states and switched all rack states back and forth and saved the song.

Hi @Torsten,

Thanks for bringing this up.

The first issue I couldn’t reproduce exactly, but I can see what the issue is. For the next build I’ve changed it so that when you load a song state, that references a rack state that doesn’t exist it doesn’t keep the currently loaded state - rather it reverts to “Missing: Old Name” like when you first replace the rack.

For the second issue, that’s a bit trickier to fix so I’ve logged it for now. In the meantime, Update All States should work.

Brad

Unfortunately, it doesn’t really. Case example:

  • Inserted a “Smoothie” rack into an existing song
  • set its “Output Gain” parameter state behavior to “ticked”
  • set the rack’s output gain to -oo, right-clicked “Output Gain” and selected “Update All States” - now I assume, all states should have their output gain set to -oo
  • now I go to a specific state, set its output gain to a different value (e.g. fully to the right) and update state
  • I then go to a different state I hadn’t updated explicitly before, and the value from the previous state (fully right) carries over
  • my expectation would have been for that different state to have been initialized with -oo from my “Update All States”, but apparently that one didn’t stick, so it seems I need to explicitly update states individually?

Seems this still needs a bit of work…

Cheers,

Torsten

1 Like

Hi @Torsten,

I’ll take a look at this in the morning.

Brad

Hey @Torsten,

I had a look at this and it seems to be working fine. Check this video and let me know if I’m doing something different to you.

Brad

FWIW I also have a similar “current state carrying over” issue in C3, and have for some time. I fix them exactly as ukm did. Yet, it only seems to occur on complex songs where I’ve been doing a lot of editing. For example, one song was edited and working great for several days. 2 days ago I opened it and the 2nd rack state was the same as the first, although it was supposed to be different. And I know it was previously saved and locked. So on each song state I selected another rack state, then the correct one, and saved. That seems to be the fix every time. Not a big deal for me since I test new songs several days before gigging, and it is only on very complex songs so it’s somewhat rare. But it does seem like the song file gets corrupted or something like that. I know that’s not the case but it does seem odd.
Tom
Tom

That has been my experience as well in some cases - simply using “update state” didn’t help - I needed to explicitly select a different state and back to make Cantabile register the correct rack state to save.

You’re definitely doing different things: what you are doing is editing states WITHIN the Smoothie rack.

What I am doing is happening at SONG level: the Output gain parameter that I mean is the “Outer” output gain; and “Update All States” also is at SONG level, not within the rack.

I am using the Smoothie rack to create smooth volume transitions for one or more other racks in my songs - when I set a state-specific (outer) output gain of the Smoothie rack, it will create a smooth transition internally and provide it to song-level bindings at its (internal) output gain, used for song-level bindings that control the gain level of other plugins.

Now say an existing song has 14 states (not so rare for me, since I also use states to switch lights). I load Smoothie 1 into this song, set its (outer) output gain state behavior and also its “selected rack state” state behavior to on.

Next I will create a first “default” configuration of the Smoothie rack, with the level set to 0 dB and the selected rack state set to 0.3. After clicking “Update All states” for both parameters, I would expect all 14 song states to be initialized with these values.

Now I’ll go to state 7 and set the level to -3 dB and the rack state to “2” for 2 seconds smooth time. Update state - should be fine, shouldn’t I. So I’d expect all other states to have 0 dB and 0.3 seconds stored and ready to run. So this is what things should look like:

state 1: 0 - 0.3 sec
state 2: 0 - 0.3 sec
state 3: 0 - 0.3 sec
state 4: 0 - 0.3 sec
state 5: 0 - 0.3 sec
state 6: 0 - 0.3 sec
state 7: -3 - 2 sec
state 8: 0 - 0.3 sec
...

But on going from state 7 to state 4 (just to pick one), I see that the -3 dB and the 2 seconds have carried over, so it seems that no song-specific state information has been stored with the other states, aside from state 1 (that I used to create the initial “default” configuration. I would expect for state 4 to have the information 0 dB, 0.3 seconds stored and recalled when I change from state 7 to state 4.

Next, I try this the hard way: I go to state 1, set the values back to 0 dB and rack state 0.3 and step through states 1 to 6, pressing CTRL-U to save the information in the rack state. But after hitting preset 7 (with the correct information stored and recalled, I go back to state 6 (which has been updated with the values set for state 1 and carried through) only to find that the rack state stays at “2” for 2 seconds. So I need to change the rack state of the Smoothie rack from 2 to .3 and update state 6 again - then it will stick for state 6. TBH, not sure if the same applies for the output gain, but this definitely happens for the “selected rack state”.

So next step: go from state 6 to state 5 (which is also to be set to 0dB and 0.3) - all is fine, since we come from state 6 which is set to the same values. Press CTRL-U to be sure… But now we go to state 7 (-3 dB, 2 seconds) and go directly to state 5 from there - and the rack state stays at 2 seconds instead of switching to 0.3.

So to be sure that the correct rack state is saved with every song state, whilst having a sequence of identical settings, I seem to need to go through all song states, select a different rack state from the pre-existing correct one, then select the correct one again - only then, the setting will “stick”, and I will get the correct value when I switch from state 7 to state 5.

So my speculation is as follows:

  • when inserting a new rack into a song and activating state behavior for some of its parameters, the current values for these parameters aren’t immedially written to all other states - so the values stay “undefined” for all states
  • when hitting CTRL-U or selecting “Update State …”, Cantabile should write these values to the respective state for all relevant parameters, but appears to only do so for as-yet “undefined” values if these actually have been manually changed from their previous values (so Cantabile recognizes them as “dirty”.
  • But if a state-specific value is currently “undefined”, and the current values are carried over from switching from a previous state, Cantabile will not know that it needs to save them, since they apparently haven’t been marked as needing to be saved. Looks like on “update state” Cantabile doesn’t go exhaustively through all parameters marked as song-specific and creates values if they haven’t been defined yet, as long as these haven’t been touched.

To be sure, this is just my speculation what might cause this, but maybe worth exploring

  • The “update all states” doesn’t seem to reliably create and initialize the values for “Selected Rack State” for all song states.
  • I’m not sure if the same applies for the Output Gain parameter - will have to test this again to be sure, but it is definitely the case for the selected rack state.

Hope this clarifies!

Cheers,

Torsten

Hi @Torsten,

Ah ok… this is a much trickier problem because in this case “update all states” effectively means update all states in all songs that use this rack and I don’t want to have to go find all the songs that use it.

I need to think very carefully about this so give me a couple of days while I sort out a bunch of other random issues and can then focus on fixing it properly.

Brad

Not sure why this needs to go through all songs??? State behavior of rack parameters is song-specific.

I am only expecting “update all states” to go through all states of the currently loaded song, create a state behavior value in every state where there isn’t one yet and set it to the current value of this parameter. No need at all to touch any other songs.

Just to be sure: I am NOT changing anything in the Smoothie Rack; I am simply inserting this rack into an existing song and then (at song level) setting the State Behavior of two parameters of this rack (Output Gain and selected State) to “On”. The problem then is that then saving these song-specific state parameters via “update all states” or “Update State …” doesn’t stick.

Other songs shouldn’t be affected at all - I believe this problem is completely local to one song.

I have a diagnostic idea to follow up on - will see if this works and get back to you :wink:

OK, did some experimentation - sorry, this will be a long post…

Inserted the rack Smoothie 1, set its parameters “Output Gain” and “Selected Rack State” to be controlled by song states. Initialized the first state with default values (gain 1, selected state “0.3”). Saved the song file - the rack section looks like this:

	{
		"kind": "RackHost",
		"embeddedRack": null,
		"RackFile": "C:\\Cantabile\\Racks\\Smoothie 1.cantabileRack",
		"gain": 1,
		"rackState": "0.3",
		"exportedRackState": null,
		"RackFileRelative": "..\\..\\Racks\\Smoothie 1.cantabileRack",
		"userNotes": null,
		"primaryView": false,
		"resetRackState": false,
		"runMode": "Running",
		"stateManager": 
		{
			"behaviour": 6,
			"indexedBehaviour": null,
			"externalBehaviour": 0,
			"externalIndexedBehaviour": null,
			"nonLinkedBehaviour": 0,
			"nonLinkedIndexedBehaviour": null,
			"resetBehaviour": 0,
			"resetIndexedBehaviour": null,
			"states": 
			{
				"22": 
				{
					"runMode": "Running",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": true,
					"savedBehaviour": 1023
				}
			},
			"resetState": null
		},
		"solo": false,
		"soloControl": true,
		"wiringPositionX": 0,
		"wiringPositionY": 0,
		"nextUniqueID": 1,
		"uniqueId": 86,
		"routes": [],
		"name": "Smoothie 1",
		"sendBalance": 0,
		"displayExpanded": true,
		"slotColor": "Default"
	}

So, as expected only one state defined, rest “undefined”.

Now did an “update all states” on the two parameters and then changed the values for one specific state (State “13”) to gain 0, rack state “2”. Saved the song.

This is what it looks like now:

	{
		"kind": "RackHost",
		"embeddedRack": null,
		"RackFile": "C:\\Cantabile\\Racks\\Smoothie 1.cantabileRack",
		"gain": 0,
		"rackState": "2",
		"exportedRackState": null,
		"RackFileRelative": "..\\..\\Racks\\Smoothie 1.cantabileRack",
		"userNotes": null,
		"primaryView": false,
		"resetRackState": false,
		"runMode": "Running",
		"stateManager": 
		{
			"behaviour": 6,
			"indexedBehaviour": null,
			"externalBehaviour": 0,
			"externalIndexedBehaviour": null,
			"nonLinkedBehaviour": 0,
			"nonLinkedIndexedBehaviour": null,
			"resetBehaviour": 0,
			"resetIndexedBehaviour": null,
			"states": 
			{
				"22": 
				{
					"runMode": "Running",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": true,
					"savedBehaviour": 1023
				},
				"1": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"5": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"23": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"13": 
				{
					"runMode": "Running",
					"sendBalance": 0,
					"selectedState": "2",
					"resetRackState": false,
					"outputGain": 0,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": true,
					"savedBehaviour": 1023
				},
				"14": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"15": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"19": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"16": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"2": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"20": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"17": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"18": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				},
				"21": 
				{
					"runMode": "Unloaded",
					"sendBalance": 0,
					"selectedState": "0.3",
					"resetRackState": false,
					"outputGain": 1,
					"exportedState": null,
					"userNotes": null,
					"slotColor": "Default",
					"solo": false,
					"soloControl": false,
					"savedBehaviour": 0
				}
			},
			"resetState": null
		},
		"solo": false,
		"soloControl": true,
		"wiringPositionX": 0,
		"wiringPositionY": 0,
		"nextUniqueID": 1,
		"uniqueId": 86,
		"routes": [],
		"name": "Smoothie 1",
		"sendBalance": 0,
		"displayExpanded": true,
		"slotColor": "Default"
	}

So it looks that song state information was created for the rack for all song states, so no “undefined” values.

Now when I jump between states “13” and “22”, the parameters of the Smoothie rack get applied correctly, but when I jump from state “13” to state “1” or “5”, the values from “22” carry over.

Looking at the state parameters in the song file in detail, I notice two key differences between states “13” and “22” and the rest:

  • runMode of all other states is (incorrectly) set to “Unloaded”
  • savedBehaviour is set to 0 instead of 1023

So I just did some manual patching of the song file and used “revert song” to re-load. Just changing runMode to “Running” didn’t help, but as soon as I also set “savedBehavior” to 1023 for all rack states, things changed for the better - now all rack states load correctly, no values carried over from previous states.

Now changing values via “Update State” properly sticks for this rack for all states.

Summary:

  • when using “Update All States” for a newly created rack, Cantabile does create new song state information for the rack, but incorrectly sets their runMode and savedBehavior values
  • this makes these parameters not load correctly for the un-edited song states for the rack in this song - rack parameters will be carried over from the previously loaded song state
  • setting savedBehavior to 1023 manually and reloading the song fixes that problem - the song state information now loads correctly with changing song states - no more carry over

So to fix this, I guess, you’ll need to teach Cantabile to set the “savedBehavior” to 1023 (and runMode to “Running”) when creating new song state information for a rack via Update All States.

Makes sense?

Cheers,

Torsten

Oh, BTW: just saw that also the “soloControl” was set differently for all state information created by “update all states”. Not relevant in this case, but for consistency, I think the best way for “Update All States” to work would be: if there is no current state information for the rack, then copy the currently set values - not create some default values, which has the potential to mess up things royally…

Hi Torsten,

You’re right of course I was thinking too conceptually and not practically.

I had a quick look at this today and updating a single behaviour for exported states isn’t trivial because of the way they’re managed. Not impossible, but it’ll take some time to implement.

I was hoping to get more time on this today, but I’ve been distracted by a couple of long-standing quirks in bindings that I’m trying to improve.

Brad

Hey @brad - I think we are still talking about two different things. I am NOT talking about making changes inside a rack and propagating them to containing songs somehow, which seems to be what you are discussing.

My main problem is an apparent malfunction of the “Update All States” functionality at SONG level when applied to a newly inserted rack - nothing to do at all with making ANY changes WITHIN the rack.

Trying to reduce this down to the core:

  • I add an existing rack to an existing song that already has a number of song states
  • I make some EXTERNAL attributes of that rack (selected rack state, output gain) dependent on SONG states
  • I use “Update All States” for the selected parameters of the new rack at SONG level to initialize all song states for the new rack to something useful
  • the song state information created for the new rack host by “Update All States” is simply wrong, which causes it not to be loaded when loading a state
  • specifically, it seems to be the parameter "savedBehavior", set to 0 for the newly created state information, that prevents the song state infornation from being loaded.
  • But there are also some other state parameter (running mode, solo control) that are initialized incorrectly by “Update All States”
  • the problem can clearly be seen in the song file (see my post above)
  • patching the song file manually and re-loading the song immediately fixes the issue

So the solution seems to be simple: there is a bug in the “Update All States” function, causing it to create the wrong song state information for “rackHosts” when there isn’t any existing state information. Once the “Update All States” function is fixed, the problem should be gone.

Again, nothing to do with “updating a single behaviour for exported states” - we are talking about a simple malfunction of “Update All States” at song level.

Hope this clarifies?

Cheers,

Torsten

Just a quick update on this. I tried to find a workaround to this problem (short of manually editing the song file every time I add a rack): what does seem be a valid workaround is:

  • add the new rack to an existing song
  • set the correct song state behavior, but DO NOT use “update all states”
  • step through the song one state at a time and use “update state” to save the current configuration - this creates correct state information for the new rack
  • using keyboard shortcuts, this is just a sequence of “P - CTRL-U”

Now the song state information for the new rack is initialized correctly. Tedious, but safe…

You’ll need to do this every time you insert a new rack into an existing song

Do NOT use “Update All States” before having done this - “Update All States” will create incorrect song state information in this situation, which will create difficulties with editing.

After having gone through the above procedure, you can now safely use “Update All States” to make changes, since the state information is now initialized correctly.

@twaw, @ukm - maybe give this procedure a try - should address the “state carrying over” issue - until @brad can fix the “update all states” functionality

Thanks for your info.
In addition to the procedure I described above I use “verify” on my setlist(s) where problematic songs/song states are marked red so that I can see what has to be corrected before I run into a “live dilemma”.

Some more comprehensive thinking about this, so @brad, maybe read this before you dig into my other posts

This whole complication is created because of the way Cantabile creates and stores state-specific information. For simplicity, I’ll be talking about “states”, but in this context I mean “song states”.

  • state specific information is stored in the song with the individual component - rack, plugin, route. At least that’s what things look like in the song files; I assume this reflects the internal data structure of Cantabile. So every rack, plugin or route in a song has a structure attached to it that stores its configuration for individual song states
  • state information is created when (1) creating a new state or (2) updating a state that has no existing state information
  • whenever Cantabile loads a state that has no stored state information for any component (rack, plugin, route), it will simply skip over the loading - the component will stay as it is, which is determined by the previously loaded state or any changes the user has made since loading a state

This isn’t so bad when creating a song from scratch - new song states are created one by one, so every component gets their song state specific information then.

But when inserting a new component (in my case, mostly racks and routes) into an existing song with multiple song states, you get to an increasingly complicated situation: the new component does not have any stored state specific information when it is inserted. This information is only created (one state at a time) whenever you explicitly use the “update state” command. For all other states (that you haven’t updated yet), the state information for this rack stays “undefined”, and the rack parameters will stay at where they were previously.

So if I have a song with 12 states, insert a new rack and I only update states 1 and 5, the rack’s configuration for e.g. state 2 will depend on what state I previously loaded. If I go state 1–>2, state 2 will have the rack in the configuration from state 1; if I go state 5–>2, state 2 will have the rack in the configuration from state 5. Not good from a predictability / “principle of least surprise” perspective.

After a few edits, I have no way of knowing which states have valid state information and which don’t (unless I look into the song file with a text editor) - Cantabile does not show if there is valid state information stored for a component in any given state. This, TBH, creates an unholy mess for me as a user…

The only way to be sure that there is valid state information for every state stored with my new rack is to manually go through all states in the song and do an “update state”. This will create valid state information for the rack for all states, so now I can go on editing without any nasty “carry-over-effects”.

Unfortunately, the “Update All States” function is buggy in that it creates incorrect state information for states where there isn’t any stored information. It will correctly update states where there is existing state information, but it will not solve the issue with “undefined” state information; in fact it creates more of a mess due to the “savedBehavior” parameter. So using the “Update All States” function on components with “undefined” state information should actually be avoided until this behavior can be fixed.

What’s the solution? My suggestion: whenever a new component (rack, plugin, route) is inserted in a song with existing state information, Cantabile should immediately create state information for ALL states for this component. Now we have a well-defined situation for all states, without “undefined data” that isn’t visible to the user.

(Not sure how this would work for plugins, with all the vst parameters and especially the “entire bank” parameter. Maybe create this information only when “ticking” the respective state behavior?)

Hope this clarifies - @brad, also happy to take this directly via email…

Hi @Torsten,

Thanks for your detailed write up. This is now top of my list for Monday morning when I hope to find a couple of quiet hours to focus on this properly. (Last week was a bit chaotic)

Brad

1 Like

Sounds great - let me know if I can help defining the to-be behavior / mode of operation