Cabbage Logo
Back to Cabbage Site

cabbageGetStateValue problems and missing opcodes after installing latest build

i’m trying to use cabbageGetStateValue and cabbageSetStateValue` to save the value of stuff in the DAW without needing to keep track of a JSON file (which is the downside of the opcodes that save all widget channel values).

But it seems my build of Cabbage, which is your latest dev build, doesn’t have these opcodes.

I copied your code verbatim (except I had to add guiMode("queue") to the form)

<Cabbage>
form caption("State example") size(400, 300), colour(60, 60, 60), guiMode("queue"), pluginId("def1")
rslider bounds(14, 14, 100, 100), channel("sliderValue"), range(0, 1, 0.5, 1, 0.01), text("SliderValue"), trackerColour(0, 255, 0, 255), outlineColour(0, 0, 0, 50), textColour(0, 0, 0, 255)
button bounds(122, 16, 120, 40), channel("showData"), text("Print State Data")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d 
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

instr 1
   a1 oscili 1, 200
   outs a1, a1
endin

instr 2

   kSlider chnget "sliderValue"

   if changed2(kSlider) == 1 then
       event "i", "SetFloatValue", 0, 0
   endif

   if changed:k(chnget:k("showData")) == 1 then
       event "i", "ShowData", 0, 0
   endif

endin

instr UpdateData
   iRes cabbageWriteStateData 1, "{\"happy\": true, \"pi\": 1.141, \"test\": \"hello\", \"list\":[1, 0, 2, 3, 4, 5, 2, 3, 6],\"stringList\":[\"hi\", \"who\", \"goes\", \"there\"]"
   if iRes == -1 then
       prints "Couldn't write JSON data"
   endif
   if iRes == -1 then
       prints "Couldn't write JSON data"
   endif
endin

instr ShowData
   prints cabbageReadStateData()
endin

instr GetFloatValue
   kVal cabbageGetStateValue "pi"
   printk2 kVal
endin

instr GetFloatArrayValue
   kVal[] cabbageGetStateValue "list"
   printarray kVal, 1, "%d"
endin

instr GetStringValue
   SVal cabbageGetStateValue "test"
   prints SVal
endin

instr GetStringArrayValue
   SVal[] cabbageGetStateValue "stringList"
   printarray SVal, 1, "%s"
endin

instr SetFloatValue
   iRes cabbageSetStateValue "pi", chnget:i("sliderValue")
endin

instr SetFloatArrayValue
   kArr[] fillarray 1, 2, 3, 4
   kRes cabbageSetStateValue "list", kArr
endin

instr SetStringArrayValue
   SArr[] fillarray "1", "2", "3", "4"
   kRes cabbageSetStateValue "stringList", SArr
endin
</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
i2 0 z
;starts instrument 1 and runs it for a week
;i"WriteData" 0 1
;i"ShowData" + 1  
i"UpdateData" 0 1
;i"ShowData" 2 1
;i"GetFloatValue" 3 1
;i"GetFloatArrayValue" 4 1
;i"GetStringValue" 5 1
;i"GetStringArrayValue" 6 1
;i"SetFloatValue" 2 1
i"SetStringArrayValue" 1 1
i"ShowData" 3 1
i"GetStringArrayValue" 4 1
</CsScore>
</CsoundSynthesizer>

And when I hit save I get this in the console:

STARTING FILE
Creating options
Creating orchestra
closing tag
Creating score
rtaudio: PortAudio module enabled ...
using callback interface

error: syntax error, unexpected T_OPCODE0  (token "cabbageWriteStateData") from file FILEPATH (1)
 line 36:
>>>    iRes cabbageWriteStateData <<<
Unexpected untyped word iRes when expecting a variable
Parsing failed due to invalid input!
Stopping on parser failure
cannot compile orchestra

I don’t know if this is related, but I also think that after installing your latest build (and I always have the installer install Csound when I do this), I lost a few opcodes, including sterrain. It’s not there when I check csound -z and I know I had it working in a project I was working on right before installing your dev build. (I installed your dev build recently for the new MIDI opcodes).

I think there was another opcode I noticed was oddly missing from my Csound too, I can’t remember what it is now. Why would installing Cabbage with Csound delete opcodes from Csound?

Upon further experimentation:

Cabbage does recognize:

  • cabbageGetStateValue (unless the output argument is a string, then you get a “unable to find with matching argument types” error - string arrays do work however)
  • cabbageReadStateData

But does not recognize:

  • cabbageSetStateValue
  • cabbageWriteStateData

For example, the following code runs without error in my Cabbage. Note the commented lines

 <Cabbage>
form caption("State example") size(400, 300), colour(60, 60, 60), guiMode("queue"), pluginId("def1")
rslider bounds(14, 14, 100, 100), channel("sliderValue"), range(0, 1, 0.5, 1, 0.01), text("SliderValue"), trackerColour(0, 255, 0, 255), outlineColour(0, 0, 0, 50), textColour(0, 0, 0, 255)
button bounds(122, 16, 120, 40), channel("showData"), text("Print State Data")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d 
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

instr 1
    a1 oscili 1, 200
    outs a1, a1
endin

instr 2

    kSlider chnget "sliderValue"

    if changed2(kSlider) == 1 then
        event "i", "SetFloatValue", 0, 0
    endif

    if changed:k(chnget:k("showData")) == 1 then
        event "i", "ShowData", 0, 0
    endif

endin

instr UpdateData
    ;iRes cabbageWriteStateData 1, "{\"happy\": true, \"pi\": 1.141, \"test\": \"hello\", \"list\":[1, 0, 2, 3, 4, 5, 2, 3, 6],\"stringList\":[\"hi\", \"who\", \"goes\", \"there\"]"
    ;if iRes == -1 then
    ;    prints "Couldn't write JSON data"
    ;endif
    ;if iRes == -1 then
    ;    prints "Couldn't write JSON data"
    ;endif
endin

instr ShowData
    prints cabbageReadStateData()
endin

instr GetFloatValue
    kVal cabbageGetStateValue "pi"
    printk2 kVal
endin

instr GetFloatArrayValue
    kVal[] cabbageGetStateValue "list"
    printarray kVal, 1, "%d"
endin

instr GetStringValue
    ;SVal cabbageGetStateValue "test"
    ;prints SVal
endin

instr GetStringArrayValue
    SVal[] cabbageGetStateValue "stringList"
    printarray SVal, 1, "%s"
endin

instr SetFloatValue
    ;iRes cabbageSetStateValue "pi", chnget:i("sliderValue")
endin

instr SetFloatArrayValue
    kArr[] fillarray 1, 2, 3, 4
    ;kRes cabbageSetStateValue "list", kArr
endin

instr SetStringArrayValue
    SArr[] fillarray "1", "2", "3", "4"
    ;;kRes cabbageSetStateValue "stringList", SArr
endin
</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
i2 0 z
;starts instrument 1 and runs it for a week
;i"WriteData" 0 1
;i"ShowData" + 1  
;i"UpdateData" 0 1
;i"ShowData" 2 1
;i"GetFloatValue" 3 1
;i"GetFloatArrayValue" 4 1
;i"GetStringValue" 5 1
;i"GetStringArrayValue" 6 1
;i"SetFloatValue" 2 1
;i"SetStringArrayValue" 1 1
i"ShowData" 3 1
;i"GetStringArrayValue" 4 1
</CsScore>
</CsoundSynthesizer>

check out the example that ships with cabbage. “PluginStateOpcodes.csd” in the mics. examples folder. I just tried it there and all but the string version of cabbageGetStateValue work fine. i will take a look and see why that version is not working.

Well, first of all with that example (the one that ships with Cabbage under Examples>Misc) you need guiMode("queue") to be set in the header, but that’s done easily enough…

And lo and behold, if you comment out just line 62 (and therefore line 63 too), it works.

I figured out what was wrong in the example I posted in the OP. Problem was the syntax for cabbageSetStateValue. You must have changed the syntax since you wrote that code. It no longer wants an output argument “iRes”. Same with cabbageWriteStateData

Working:

  • cabbageWriteStateData 1, Sjson
  • Sjson cabbageReadStateData
  • cabbageSetStateValue "key", kval/kArr/Sval/Sarr
  • kval cabbageGetStateValue "float"
  • kval[] cabbageGetStateValue "floatArray"
  • Sval[] cabbageGetStateValue "stringArray"

NOT* working (no matching syntax error):

  • Sval cabbageGetStateValue "string"
1 Like

I made the following minimal example to show you the two remaining bugs I’m getting.

The first bug is about cabbageSetStateValue and only applies if the data type is a lone string.

The second bug is about cabbageGetStateValue and what happens is that when it runs, the value isn’t successfully being recalled.

See the comments, they explain everything.

<Cabbage>
form caption("Untitled") size(450, 300), guiMode("queue"), pluginId("def1")
csoundoutput bounds(8, 78, 400, 205)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>

ksmps = 32
nchnls = 2
0dbfs = 1

/* Set state value - data is a string */
instr 100
    cabbageSetStateValue "loneStringKey", "whatever"
endin

/* Retrieve state calue - data is a string */
/* BUG #1: REMOVE SEMICOLONS BELOW TO PRODUCE MATCHING-ARGUMENTS ERROR WHEN COMPILED */
instr 101
;Sdata cabbageGetStateValue "loneStringKey"
;prints Sdata
endin


/* Set state value - data is array of strings */
instr 200
Sdata[] init 2
Sdata[0] = "what"
Sdata[1] = "ever"
    cabbageSetStateValue "stringArrKey", Sdata
endin

/* Retrieve state calue - data is array of string */
/* BUG #2 RUNNING THE FOLLOWING INSTR FAILS TO RETRIEVE DATA*/
/* Expected output:
    String 1 = what
    String 2 = ever
*/
/* Unexpected output:
    String 1 = overwrite
    String 2 = me
*/
instr 201
Sdata[] fillarray "overwrite", "me"
Sdata[] cabbageGetStateValue "stringArrKey"
printf_i "\nString 1 = %s \nString 2 = %s \n\n", 1, Sdata[0], Sdata[1]
endin

</CsInstruments>
<CsScore>

i 100 0 1
i 101 1 1 ; BUG #1 (if semicolon is removed)

i 200 3 1
i 201 4 1 ; BUG #2

f0 z
</CsScore>
</CsoundSynthesizer>

this sounds like an issue that came up before. I’m searching through threads. btw, you’re testing this in a DAW?

p.s. I just had fairly major hand surgery so I’m currently very much one-handed…but I’ll try to track down the problem. it will just take me longer than usual…

an you have a llok at this thread:


I explain the problem here, and propose some code that may address it. it might not fix your issue, but might steer things in the right direction…

btw, you’re testing this in a DAW?

Yes, the problem is the same whether the plugin is hosted in Cakewalk, NanoHost, or Cantabile.

I just had fairly major hand surgery so I’m currently very much one-handed…but I’ll try to track down the problem. it will just take me longer than usual…

Not in a hurry! I hope you recover swiftly though.

Can you have a llok at this thread… I explain the problem here

While that is interesting, the bugs I’m seeing are different. In the last Cabbage code I posted, cabbageGetStateValue is called 4 seconds into performance and still doesn’t find any data. It’s not a problem with the first k-cycle.

You can easily modify the code (use printf with a metro instead of printf_i) to see that while instr 201 runs for 1 second it never gets the data like it should. So it’s not a problem with the first k-cycle of the instrument event, either.

Just in case I also tried adding 2 seconds to the start time of all the events in my example. Doesn’t change anything.

Also, in that thread you just linked, you posted an example after you fixed the k-cycle problem. That example doesn’t work for me. I get the same matching-argument error about cabbageGetStateValue having a string output argument. Same as Bug #1 in my example above.

This seems to be something new…

thank @cybilopsin, it could be something i changed recently. i’ll take a look when i can use my hand again :+1: for now i’m only capable of a typing a few short sentences :frowning:

1 Like

How time flies @rorywalsh… I wish your health is the best and you recover soon from your hand :+1:. In my case, as you will remember, the sight told me Enough! :sunglasses: Which has forced me to put on the brakes.
The truth is that it has been a very rewarding experience due to the interaction that has occurred. Surely one of these days, I will return with a new project, because it is very tempting to work with this wonderful tool :wink:.

I decided to see the latest advances of Cabbage, realizing something… I observed that until version 2.9.73 resize works correctly (memorizes the resize percentage in the DAW, when closing and opening session). As of version 2.9.74 it is no longer possible until the latest build 2.9.106.
Is it possible that this has something to do with it?

Greetings!

Thanks @Gerbo, I’ll take a look. Might be best to start a new thread about this :slight_smile:

I would be happy to do what I can :grinning:

Hi @cybilopsin. So the problem here is that the string versions of the state opcodes only run at k-rate. So calling them at init time will result in undefined behavior. Based on discussions in the thread I linked earlier, the decision was made to make all state opcodes k-rate because the state might not be known at init time. The big issue with this is that strings are explicitly irate (even though we can manipulate them at k-rate - strings suck in Csound).

I am going to add back the i-rate versions of the string state opcodes. People will just have to be careful when using them and make sure state has been found before querying. I’ve triggered a new build, and attached a slightly modified version of your instrument that I was testing with. It passes all tests, oh and I also fixed the bug with the single string version of getState.

CabbagePluginEffect.csd (1.6 KB)