Cabbage Logo
Back to Cabbage Site

[FIXED] Chnset not working Cabbage-wide

I’m having a strange problem—the chnset opcode seems not to be working for me for any .csd within the Cabbage application. If I run Miscellaneous/RandomCheckbox.csd the square just sits in the upper-left corner, none of the buttons do anything in Utilities/Calculated_F_Tables.csd, the .csds in this thread don’t work, my own uses of chnset don’t work, etc. etc.

What’s strange is that they used to work, I’d say as recently as yesterday or the day before or so. But now they don’t, and the problem seems very persistent. I’ve tried restarting, switching window managers, and even rebuilding Cabbage from source (using the cabbage package in the AUR), but nothing seems to help.

Does anyone have any idea what might be going on? I’m running Cabbage 64-bit v2.0.02 on Arch Linux with kernel v4.16.10. I’ve tried both JACK and PulseAudio for sound output; for some reason I get a lot of dropped samples when outputting to JACK, but the chnset problem persists in both cases.

I made some changes yesterday to the source, let me check…

[some time later]
It’s working here for me. Can you try the attached example. chnsetTest.csd (477 Bytes)

The only reason I can think of for it not to work would be that there are no valid audio devices selected. If Cabbage can’t connect to an audio device, the instrument never starts processing. The example above plays a simple tone. If it plays the tone Ok, but you still have no movement on the rslider then there is something seriously strange happening. Let me know.

Yeah, weirdly, it’s as you describe—I hear the tone, but the slider stays still.

1 Like

Hmm, how strange. Does chnget work Ok? Also, can you add this code to your orchestra and see if Cabbage prints the updated channel values:

schedule 2, 0, 100
schedule 3, 0, 100

instr 2
    kRand randh 100, 100
    if metro(1) == 1 then
        chnset kRand, "testChannel"
    endif
endin

instr 3
    printk2 chnget:k("testChannel")
endin

Very insteresting—instr 2 successfully changes the channel values and instr 3 successfully reads them, so both chnset and chnget are working on the Csound side. chnget works with Cabbage widgets as well, so I guess it’s just that Cabbage widgets and chnset aren’t getting along somehow.

Let me take a look and see if I can’t recreate this issue…

[edit] I’m seeing an issue with the random checkboxes instrument; the checkboxes are not updating their position. It’s working on OSX, so it could be something I changed recently. I’m looking into it. But oddly enough, the example I posted earlier works fine…

Interesting. 0_0 Thanks so much for looking into this! Let me know if there’s anything useful I could do to investigate further on my end—I’m not exactly a crack C++ dev but I probably know my way around well enough to follow relatively terse instructions.

I see some changes made to Csound on the 30th of April that might be causing an issue…

Can you pull from the latest Csound, rebuild, then rebuild Cabbage and then try the attached file? chnsetTest.csd (687 Bytes)

Sure thing, I’ll let you know what happens.

Okay! Thanks again for working on this. Here’s what I see:

I hear a tone, but the dial doesn’t move, nor does the label change.

This is with both the latest Csound and Cabbage code compiled from git. I ended up making a csound-git package in the AUR since there wasn’t one already.

Also, in the Linux buildCabbage script, you might want to consider moving all the built files into a local install directory instead of directly into the system directories. As written, Cabbage actually won’t build properly in Arch with that script, because the Arch package manager expects to move files into the system directories itself after the build process has completely finished, and runs the builds process without elevated privileges. Since the build directory is cleared after each step right now, most of the files are gone by the time the package manager expects to actually start moving them onto the system. I ended up patching buildCabbage to build into a local directory, and modified the AUR package’s build script to install everything from that directory afterwards. If you did make this change, you could have a separate install script people could run after buildCabbage if that made sense for them in their environment.

I can do that for sure. It guess it makes sense as some people may still want to simple install it locally. Are you going to continue to maintain an AUR pacakge for Csound? If so I can update the csound page to let people know it’s available?

I’m baffled as to why chnset is not working. I’ve created a new branch called archDebugBuild. Can you check it out from git and rebuild Cabbage in debug mode. The handiest way would be to open the CabbageIDE.jucer file in the Projucer and hit save. Then run make from the Cabbage LinuxMakefiles dir. That will build Cabbage ind ebug mode. When the program launches, run the instrument above once more. Then go to the console and see what text is being printed. It should be printing out a list of messages like this:

(...)
IdentifierText:label1
IdentifierText:text("0.002301")
IdentifierText:label1
IdentifierText:
IdentifierText:label1
(...)

Let’s see if your build does too. I won’t be at the PC all day today, but I’ll check back in now and then to see where you’re at.

Sure thing! I can give it a shot a bit later on and let you know what happens.

Also, I realize it was a bit silly of me not to suggest—if you like I can just make a pull request for the build script changes, since I already made that patch and so on. Making an install script to go with the modified build script wouldn’t take long at all.

EDIT: Oh, also, regarding the Csound package, I do plan on maintaining it now that it’s there. You’re welcome to update the page with it if you like. Should I email the mailing list as well? It’s not a particularly big thing I’d say—the main Csound package is in the official repos. There’s a tradition in Arch of having two packages for software, one that installs the latest official release and one that just gets the latest code from the VCS and builds it, so mine is in the latter category. I don’t know how much use it will really get, since most people will probably prefer to use the official package.

I’d send an email to the list. Would be good to make it known at least. I’m happy to take the pull request.

Sorry it took me longer than I expected to get around to this.

I’m getting errors trying to build Cabbage as you described; I managed to fix some of them but I’m stuck on this:

Compiling AudioGraph.cpp
../../Source/Audio/Graph/AudioGraph.cpp: In member function ‘void AudioGraph::setDefaultConnections(int)’:
../../Source/Audio/Graph/AudioGraph.cpp:228:103: error: no matching function for call to ‘juce::AudioProcessorGraph::addConnection(int, int, int&, int)’
     bool connectInput1 = graph.addConnection (internalNodeIds[InternalNodes::AudioInput], 0, nodeID, 0);
                                                                                                       ^
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note: candidate: ‘bool juce::AudioProcessorGraph::addConnection(const juce::AudioProcessorGraph::Connection&)’
     bool addConnection (const Connection&);
          ^~~~~~~~~~~~~
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note:   candidate expects 1 argument, 4 provided
../../Source/Audio/Graph/AudioGraph.cpp:229:103: error: no matching function for call to ‘juce::AudioProcessorGraph::addConnection(int, int, int&, int)’
     bool connectInput2 = graph.addConnection (internalNodeIds[InternalNodes::AudioInput], 1, nodeID, 1);
                                                                                                       ^
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note: candidate: ‘bool juce::AudioProcessorGraph::addConnection(const juce::AudioProcessorGraph::Connection&)’
     bool addConnection (const Connection&);
          ^~~~~~~~~~~~~
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note:   candidate expects 1 argument, 4 provided
../../Source/Audio/Graph/AudioGraph.cpp:231:102: error: no matching function for call to ‘juce::AudioProcessorGraph::addConnection(int&, int, int, int)’
     bool connection1 = graph.addConnection (nodeID, 0, internalNodeIds[InternalNodes::AudioOutput], 0);
                                                                                                      ^
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note: candidate: ‘bool juce::AudioProcessorGraph::addConnection(const juce::AudioProcessorGraph::Connection&)’
     bool addConnection (const Connection&);
          ^~~~~~~~~~~~~
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note:   candidate expects 1 argument, 4 provided
../../Source/Audio/Graph/AudioGraph.cpp:232:102: error: no matching function for call to ‘juce::AudioProcessorGraph::addConnection(int&, int, int, int)’
     bool connection2 = graph.addConnection (nodeID, 1, internalNodeIds[InternalNodes::AudioOutput], 1);
                                                                                                      ^
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note: candidate: ‘bool juce::AudioProcessorGraph::addConnection(const juce::AudioProcessorGraph::Connection&)’
     bool addConnection (const Connection&);
          ^~~~~~~~~~~~~
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note:   candidate expects 1 argument, 4 provided
../../Source/Audio/Graph/AudioGraph.cpp:237:172: error: no matching function for call to ‘juce::AudioProcessorGraph::addConnection(int, juce::AudioProcessorGraph::<unnamed enum>, int&, juce::AudioProcessorGraph::<unnamed enum>)’
     bool connection3 = graph.addConnection (internalNodeIds[InternalNodes::MIDIInput], AudioProcessorGraph::midiChannelIndex, nodeID, AudioProcessorGraph::midiChannelIndex);
                                                                                                                                                                            ^
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note: candidate: ‘bool juce::AudioProcessorGraph::addConnection(const juce::AudioProcessorGraph::Connection&)’
     bool addConnection (const Connection&);
          ^~~~~~~~~~~~~
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note:   candidate expects 1 argument, 4 provided
../../Source/Audio/Graph/AudioGraph.cpp: In member function ‘int AudioGraph::getNumConnections() const’:
../../Source/Audio/Graph/AudioGraph.cpp:385:18: error: ‘const class juce::AudioProcessorGraph’ has no member named ‘getNumConnections’; did you mean ‘getConnections’?
     return graph.getNumConnections();
                  ^~~~~~~~~~~~~~~~~
                  getConnections
../../Source/Audio/Graph/AudioGraph.cpp: In member function ‘const juce::AudioProcessorGraph::Connection* AudioGraph::getConnection(int) const’:
../../Source/Audio/Graph/AudioGraph.cpp:390:18: error: ‘const class juce::AudioProcessorGraph’ has no member named ‘getConnection’; did you mean ‘getConnections’?
     return graph.getConnection (index);
                  ^~~~~~~~~~~~~
                  getConnections
../../Source/Audio/Graph/AudioGraph.cpp: In member function ‘const juce::AudioProcessorGraph::Connection* AudioGraph::getConnectionBetween(uint32, int, uint32, int) const’:
../../Source/Audio/Graph/AudioGraph.cpp:396:18: error: ‘const class juce::AudioProcessorGraph’ has no member named ‘getConnectionBetween’; did you mean ‘getConnections’?
     return graph.getConnectionBetween (sourceFilterUID, sourceFilterChannel,
                  ^~~~~~~~~~~~~~~~~~~~
                  getConnections
../../Source/Audio/Graph/AudioGraph.cpp: In member function ‘bool AudioGraph::canConnect(uint32, int, uint32, int) const’:
../../Source/Audio/Graph/AudioGraph.cpp:404:62: error: ‘bool juce::AudioProcessorGraph::canConnect(juce::AudioProcessorGraph::Node*, int, juce::AudioProcessorGraph::Node*, int) const’ is private within this context
                              destFilterUID, destFilterChannel);
                                                              ^
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:397:10: note: declared private here
     bool canConnect (Node* src, int sourceChannel, Node* dest, int destChannel) const noexcept;
          ^~~~~~~~~~
../../Source/Audio/Graph/AudioGraph.cpp:403:30: error: invalid conversion from ‘uint32’ {aka ‘unsigned int’} to ‘juce::AudioProcessorGraph::Node*’ [-fpermissive]
     return graph.canConnect (sourceFilterUID, sourceFilterChannel,
                              ^~~~~~~~~~~~~~~
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:397:28: note:   initializing argument 1 of ‘bool juce::AudioProcessorGraph::canConnect(juce::AudioProcessorGraph::Node*, int, juce::AudioProcessorGraph::Node*, int) const’
     bool canConnect (Node* src, int sourceChannel, Node* dest, int destChannel) const noexcept;
                      ~~~~~~^~~
../../Source/Audio/Graph/AudioGraph.cpp:404:30: error: invalid conversion from ‘uint32’ {aka ‘unsigned int’} to ‘juce::AudioProcessorGraph::Node*’ [-fpermissive]
                              destFilterUID, destFilterChannel);
                              ^~~~~~~~~~~~~
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:397:58: note:   initializing argument 3 of ‘bool juce::AudioProcessorGraph::canConnect(juce::AudioProcessorGraph::Node*, int, juce::AudioProcessorGraph::Node*, int) const’
     bool canConnect (Node* src, int sourceChannel, Node* dest, int destChannel) const noexcept;
                                                    ~~~~~~^~~~
../../Source/Audio/Graph/AudioGraph.cpp: In member function ‘bool AudioGraph::addConnection(uint32, int, uint32, int)’:
../../Source/Audio/Graph/AudioGraph.cpp:411:78: error: no matching function for call to ‘juce::AudioProcessorGraph::addConnection(uint32&, int&, uint32&, int&)’
                                              destFilterUID, destFilterChannel);
                                                                              ^
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note: candidate: ‘bool juce::AudioProcessorGraph::addConnection(const juce::AudioProcessorGraph::Connection&)’
     bool addConnection (const Connection&);
          ^~~~~~~~~~~~~
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:243:10: note:   candidate expects 1 argument, 4 provided
../../Source/Audio/Graph/AudioGraph.cpp: In member function ‘void AudioGraph::removeConnection(int)’:
../../Source/Audio/Graph/AudioGraph.cpp:450:34: error: no matching function for call to ‘juce::AudioProcessorGraph::removeConnection(const int&)’
     graph.removeConnection (index);
                                  ^
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:246:10: note: candidate: ‘bool juce::AudioProcessorGraph::removeConnection(const juce::AudioProcessorGraph::Connection&)’
     bool removeConnection (const Connection&);
          ^~~~~~~~~~~~~~~~
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:246:10: note:   no known conversion for argument 1 from ‘const int’ to ‘const juce::AudioProcessorGraph::Connection&’
../../Source/Audio/Graph/AudioGraph.cpp: In member function ‘void AudioGraph::removeConnection(uint32, int, uint32, int)’:
../../Source/Audio/Graph/AudioGraph.cpp:458:65: error: no matching function for call to ‘juce::AudioProcessorGraph::removeConnection(uint32&, int&, uint32&, int&)’
                                 destFilterUID, destFilterChannel))
                                                                 ^
In file included from ../../JuceLibraryCode/modules/juce_audio_processors/juce_audio_processors.h:116,
                 from ../../JuceLibraryCode/../JuceLibraryCode/JuceHeader.h:20,
                 from ../../Source/Audio/Graph/AudioGraph.h:23,
                 from ../../Source/Audio/Graph/AudioGraph.cpp:20:
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:246:10: note: candidate: ‘bool juce::AudioProcessorGraph::removeConnection(const juce::AudioProcessorGraph::Connection&)’
     bool removeConnection (const Connection&);
          ^~~~~~~~~~~~~~~~
../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h:246:10: note:   candidate expects 1 argument, 4 provided
../../Source/Audio/Graph/AudioGraph.cpp: In member function ‘juce::XmlElement* AudioGraph::createXml() const’:
../../Source/Audio/Graph/AudioGraph.cpp:644:31: error: ‘const class juce::AudioProcessorGraph’ has no member named ‘getNumConnections’; did you mean ‘getConnections’?
     for (int i = 0; i < graph.getNumConnections(); ++i)
                               ^~~~~~~~~~~~~~~~~
                               getConnections
../../Source/Audio/Graph/AudioGraph.cpp:646:65: error: ‘const class juce::AudioProcessorGraph’ has no member named ‘getConnection’; did you mean ‘getConnections’?
         const AudioProcessorGraph::Connection* const fc = graph.getConnection (i);
                                                                 ^~~~~~~~~~~~~
                                                                 getConnections
../../Source/Audio/Graph/AudioGraph.cpp: In member function ‘juce::XmlElement* AudioGraph::createConnectionsXml() const’:
../../Source/Audio/Graph/AudioGraph.cpp:665:31: error: ‘const class juce::AudioProcessorGraph’ has no member named ‘getNumConnections’; did you mean ‘getConnections’?
     for (int i = 0; i < graph.getNumConnections(); ++i)
                               ^~~~~~~~~~~~~~~~~
                               getConnections
../../Source/Audio/Graph/AudioGraph.cpp:667:65: error: ‘const class juce::AudioProcessorGraph’ has no member named ‘getConnection’; did you mean ‘getConnections’?
         const AudioProcessorGraph::Connection* const fc = graph.getConnection (i);
                                                                 ^~~~~~~~~~~~~
                                                                 getConnections
In file included from ../../Source/Audio/Graph/AudioGraph.cpp:21:
../../Source/Audio/Graph/../../Application/CabbageMainComponent.h: In member function ‘FileTab* CabbageMainComponent::getFileTabForNodeId(int32)’:
../../Source/Audio/Graph/../../Application/CabbageMainComponent.h:113:5: warning: control reaches end of non-void function [-Wreturn-type]
     }
     ^
make: *** [Makefile:188: build/intermediate/Debug/AudioGraph_b22f6a5b.o] Error 1

The errors I managed to get around were things like ComboBoxListener needing to be ComboBox::Listener in CabbagePluginEditor.h and attempts to access things like sourceNodeID on a juce::AudioProcessorGraph::Connection needing to be directed to its NodeAndChannel source and destination members. I’m not really sure what’s going on with the above errors, though, since they seem to be trying to call things like getNumConnections() on a juce::AudioProcessorGraph that I can’t find signs of or analogs for in the JUCE library code. I could easily be missing something, of course, since I don’t really know my way around the library. I sort of wonder if this Cabbage code was written against a different version of JUCE or something like that? The version I have is 5.3.2; it looks like you bundled JUCE along with Cabbage but maybe when I opened and saved the project from the Projucer it changed things.

I’ll be out for a while, but I’ll try to get you that pull request this evening.

Can you check out version 5.2.0 of JUCE, build the Projucer and try again? I should get some time soon to update to 5.2.2, but in the meantime we’re stuck with .5.2.0

Okay! I got the pull request to you. Let me know if you have any questions or would like me to change anything.

Also I did get the debug version building. Sorry I missed the bit about the JUCE version in the readme. Here’s the output from opening the program, opening the more recent chnsetTest.csd, pressing the “play” button, pressing the “stop” button, then closing the program:

JUCE v5.2.0
Plugin constructor
0dBFS level = 32768.0
--Csound version 6.12 (double samples) May 25 2018
[commit: 302c15aff34ef904ca9bd7896adcc6b93ab7d284]
libsndfile-1.0.28
Plugin destructor
0dBFS level = 32768.0
--Csound version 6.12 (double samples) May 25 2018
[commit: 302c15aff34ef904ca9bd7896adcc6b93ab7d284]
libsndfile-1.0.28
UnifiedCSD:  /tmp/temp_de96d86e.csoundCabbageCsdText
STARTING FILE
Creating options
Creating orchestra
closing tag
Creating score
rtaudio: ALSA module enabled
rtmidi: ALSA Raw MIDI module enabled
sample rate overrides: esr = 44100.0000, ekr = 1378.1250, ksmps = 32
Elapsed time at end of orchestra compile: real: 0.001s, CPU: 0.001s
sorting score ...
        ... done
Elapsed time at end of score sort: real: 0.001s, CPU: 0.001s
displays suppressed
0dBFS level = 1.0
orch now loaded
audio buffered in 256 sample-frame blocks
SECTION 1:
new alloc for instr 1:

Shutdown
Plugin destructor

It seems to be almost the same as the output from the release build; as far as I can tell the only differences are the JUCE version number and the plugin constructor/destructor messages. The IdentiferText messages don’t seem to be showing up for me.

Sorry, I should have said that these messages will be printed to the terminal window, if you launch Cabbage from the terminal. Thanks for the PR. I’ll get around to merging that soon.

Oh, yeah, that actually was the terminal output. Sorry, I didn’t really specify that.

EDIT: Sure thing about the pull request :slight_smile:

I merged that pull request. Sorry for the delay. Back to the problem reported here, I think it’s caused by the same issue preventing the GUI editor from passing on property updates to the editor. The troubling thing is that both of thee mechanism rely on the use of JUCE’s ValueTree class. I think the first thing I should do is update Cabbage so it builds with the latest version of JUCE. If we’re lucky it will resolve itself!