Cabbage Logo
Back to Cabbage Site

Plugin feedback DAW automation

Automation and MIDI feedback both seem to work fine for internal and external plugins. But I don’t know of an example where the plugin parameters are changed internally after loading from a preset as in my application. The usual handling of presets (browsing for a preset with a mouse or keyboard) seems to use a different mechanism, which doesn’t brake automation.

Trying in Garageband, I see the knob stuttering with automation - not following smoothly. While it doesn’t break automation, I am not sure this is OK either.

Yes, this is something I’m looking for myself.

True. It may might not ‘break’ in other DAWs, but it probably doesn’t ‘work’ either.

Hi Rory,

I’ve been looking around a bit and testing some plugins. If at all possible, preset changing is always done using a dropdown menu, which can sometimes be scrolled through by using buttons. When a preset is changed this way, MIDI feedback about plugin parameter change is sent out to an external hardware controller. My overview is limited but it seem rare that plugin presets can also be changed via MIDI program change messages. In Live, MIDI program change can be sent from a separate channel by launching clips (MIDI mappable). There are also Max4Live devices that can translate CC to program change… However, it seems that when presets are changed via MIDI program change, plugins don’t send MIDI feedback (DAW is not notified about plugin parameter changes). I’m not sure how generally this applies.

It could be very useful and unique if we could have Cabbage plugins that can handle preset switching in a more claver way, which would open interesting new possibilities for live performance (when using appropriate hardware, e.g. with motorised or endless encoders). So now we either have automation working and no MIDI feedback when changing presets or automation breaking while MIDI feedback is available. This makes me think of a probably very naive idea: maybe we could have a new Cabbage widget - a “magic switch”, which could be flipped to enable feedback (notifying DAW of changes triggered within a plugin). Such a switch could be turned ON for live performance and turned OFF for “studio” use, when automation is needed. Of course the default should be no feedback, but perhaps feedback could be enabled by the user? I really hope something like this (or any other meaningful solution) is possible.

If we shall give up on this (for now), are you updating the code by rolling back the DAW notification changes you did in version 2.3.38 (I believe)? It would be good to know the limitations we have to adapt to.

BTW. How can I find different beta Cabbage versions? There seems to be a gap between #20200118.3 and #20200605.1.


I could add a special reserved channel to let you swap between these modes. That shouldn’t be too much working considering both parts are known to be working on their own.

The most recent beta are presented here. The current beta has reverted to the old behavior, i.e, chnsets from Csound won’t be automated in the DAW.

Wonderful that you could do that. Looking forward to try it :drooling_face:

Please let me know when you have it (and where to get it) and how can I use it. Will I be able to flip the state of that channel with a button or some other widget? Please tell me how it can be used.

The last version I can see is from Jun 19. Have you reverted the chnset behaviour already in that version (before I started this topic)?

Thank you so much!

Sorry, it looks like the latest version didn’t get built. I will run off a build later. I’ll also let you know when I have are the other stuff.

There is a new build available here now. There is a new reserved channel name AUTOMATION. Set it to 1 to have the host racks changes to a channel from Csound. Set it back to 0 for the default behaviour. I haven’t had time to extensively test this, so please have a good luck and see if it works. :wink:

Super! I’ll test it more these days, but just a quick feedback/question for now:

I can no longer see the cursor in Cabbage (MacOS 10.12.6). Anything obvious?

And just to be sure: can I just do something like chnset kAutomation, "AUTOMATION", where I get kAutomation from a button?

The “AUTOMATION switch” seems to work as expected when I load/reload the plugin, but if I add automation and let it loop over it, the switch stops working after a while. I tried this many times and I see that sooner or later the switch stops working. At first I thought that if I push the plugin buttons (more or less frenetically) breaks the switch functionality, but then I realized that I just need to let it run with automation for a while to break the switch. The automation slew doesn’t seem to matter.

Do you get the same behaviour? Any ideas?

My test code:

form caption("test automation fx 200707") size(300, 200), colour(58, 110, 182), pluginid("taf3")

rslider bounds(2, 22, 120, 120) range(0.5, 10000, 220, 0.25, 0.001) channel("OscFrq") identchannel("OscFrqID") popuptext("0") colour(0, 255, 0, 255) trackercolour(255, 0, 0, 255)
button bounds(126, 20, 65, 65) latched(0) channel("OscFrqMultiplier2")  text("x2","x2") value(0)  corners(3) colour:0(255, 0, 0, 255) colour:1(255, 255, 0, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(160, 0, 0, 255)
button bounds(126, 88, 65, 65) latched(0) channel("OscFrqMultiplier05") text("/2","/2")  value(0)  corners(3) colour:0(0, 255, 0, 255) colour:1(255, 255, 0, 255) fontcolour:0(0, 0, 0, 255) fontcolour:1(160, 0, 0, 255)

button bounds(196, 20, 92, 134) channel("automationON") text("AUTOMATION switch", "AUTOMATION switch") colour:1(255, 255, 0, 255) fontcolour:1(0, 0, 0, 255)
label   bounds(2, 164, 286, 22), identchannel("textID")

-n -d -+rtmidi=NULL -M0 -m0d 
ksmps = 32
nchnls = 2
0dbfs = 1

instr 1
;chnset chnget:k("automationON"), "AUTOMATION" ; test 1 (a shorter version of the block below)

kAutomationON chnget "automationON"; test 2 
if kAutomationON == 1 then
chnset k(1), "AUTOMATION"
elseif kAutomationON == 0 then
chnset k(0), "AUTOMATION"

ka chnget "AUTOMATION"
Stext = sprintfk("text(AUTOMATION = %d)", ka)
chnset Stext, "textID"
kOscFrq chnget "OscFrq"

; -------- internal parameter change -------    

if (trigger(chnget:k("OscFrqMultiplier2"), .5, 0) == 1) then; 0->1
    kOscFrq *= 2
    chnset  kOscFrq, "OscFrq" 
if (trigger(chnget:k("OscFrqMultiplier05"), .5, 0) == 1) then; 0->1
   kOscFrq *= 0.5
   chnset  kOscFrq, "OscFrq" 


;causes Csound to run for about 7000 years...
f0 z
;starts instrument 1 and runs it for a week
i1 0 [60*60*24*7] 

I’m sorry for not getting back to your first message. You seem to have worked it out. As to why it’s not working, I’m not sure. It could have something to do with the fact that the button you are using to set automation mode is itself automatable? Ha, this is quite meta :laughing:

Can you try setting the automation mode only using Csound, and not with an actual widget? For example, the following code should enable disable AUTOMATION mode every 10 seconds.

kAuto init 0
if metro(.1) == 1 then
    if kAuto == 1 then
        kAuto = 0
        printks "Setting automation mode to 1", 0
        chnset kAuto, "AUTOMATION"
        kAuto = 1
        printks "Setting automation mode to 0", 0
        chnset kAuto, "AUTOMATION"

If this works then we know that using standard widgets to control automation might not work…

I tested your code for changing automation mode only using Csound. Similarly as with the widget, it works fine if I let the plugin sit without automation, but when I run automation it breaks and DAW stops getting info from internal changes of plugin parameters. I actually noticed a similar behaviour in the previous Cabbage version when we had automation mode fixed. It seems like something weird might be going on with sending info to DAW.

I then tried initiating “AUTOMATION” = 1 without changing it. No notifications are sent to DAW just as with “AUTOMATION” = 0. If instead I set “AUTOMATION” = 1 at k-rate then it works… until it breaks. It seems that “AUTOMATION” needs to be repeatedly set to 1? Even though the printed state is 1 after initiation, it seem like it’s not really doing its job as it should in state 1. Hope this may give some clues.

BTW., just wanted to remind you of the cursor missing in Cabbage editor (2.3.45).

I’m away for a few days but look into this, and the other issue when I get back. :+1:

Hi Rory,
I hope you’re well.
I’m curious if you managed to look into the issues above?

Briefly, but I didn’t have enough time I’m afraid. It’s on my todo list, but my time is fairly restricted at the moment :frowning:

I hope you had a good summer.
Any progress on this issue? I hope you at least have some ideas to keep my hopes up :worried:

The last I remember, I entered some kind of automation black hole. Everything after that is a bit of a blur! I just couldn’t figure out a way to do this as the automation and channels are so tightly connected. Each channel is a plugin parameter.

Anyway, to summarise, the last attempt used an AUTOMATION channel to disable/enable the plugin from broadcasting changes to the host? Is that right?

The black hole is leaking. That’s the funny part! :confused:
The AUTOMATION switch works for a while but eventually breaks and then neither feedback nor automation work properly.

Yes that is correct. I tried it now again with version 2.4.7 and I have the same observations as before (in this thread). An important one seems to be:

I like the switch idea, but it doesn’t help much if MIDI feedback (to controller) stops working. Again, MIDI feedback stops working also for chnset k(1), "AUTOMATION" without switching it to 0. It is also puzzling to me why AUTOMATION can’t be set at i-rate.

If I’d need to chose weather my synths would have either automation or feedback working, I’d most often prefer feedback, since I could always record audio output. I hope at least the option of permanent choice could be available. But of course I still hope for a better solution with both features available.

Thanks again for all your great work!

Are we trying to break cycles in what should be a directed acyclic graph? :slight_smile:

Would it perhaps be possible to “tag” each message that is received for broadcasting with its sender, so that we never send back broadcast messages to their senders (thereby breaking the cycle)?

Or if this is not feasbile, but processing is single-threaded, then you could have one (per instance global) “sender” variable that gets set when the message broadcast processing gets triggered. Then the broadcast gets processed, discovering all recipients in the process (who, in turn, might broadcast to further recipients… ad infinitum). Along the way of the processing, whenever a (re)broadcast message is to be sent, skip sending if the destinee is the original “sender” (happening to be the host/DAW). This way whatever complex broadcast graph is within the plugin, the currently processed message never gets sent back out to the host/DAW. Finally – upon conclusion of the broadcast processing – the “sender” variable gets cleared.

This way, when the user triggers a change on the plugin UI, the sender of that change (broadcast message) is not the host/DAW, so the broadcasting process will eventually do send the message to the host/DAW. (Apologies for unclear wording.)

Alternatively, make the messages idempotent: have them only rebroadcast if they actually effected a change – and not just (re)state the current value (which is in effect no change, so no need to broadcast about it).

This topic was brought to life again recently. It turns out that it might have been something to do with @Samo’s setup. So I think the issue is more or less resolved.


I just wanted to mention that apart from the particularities of my setup, the feedback issue is illustrated also by other Cabbage plugins, as described recently. Rory introduced the reserved channel CHNSET_GESTURES to resolve this.

Now we can either have DAW automation playback working while internal parameter changes (by chnset) are not broadcast to the host (default, chnset 0, "CHNSET_GESTURES") or we can broadcast changes, e.g. triggered by a preset change, but no automation playback enabled (chnset 1, "CHNSET_GESTURES"). Perhaps one could refer to the two states as the automation playback and record/performance modes. For me, this works fine since I don’t need playback and record/performance modes simultaneously. I’d refer you to this Rory’s example: AutoTest.csd (889 Bytes)

I have some issues with AUs (which might be particular to my setup) but it works perfectly with VSTs.

1 Like