Cabbage Logo
Back to Cabbage Site

Blinking lights and a vague debugging question

Hi! This might be a bit of a vague and convoluted question.

I have a complex instrument, which is crashing Cabbage (2.7.7) and I am using Csound 6.16 from 6.16.1 beta (due to the turnoff issue, Csound and Cabbage beta - incompatibilities?). In essence, it is a complex sequencer with lots of randomizations including tempo, scale, timbre etc.

I find it difficult to debug my instrument due to many parameters and crashing occurring after some time of running the beast (maybe after 10 min)… I couldn’t detect any abnormal CPU spikes during performance or before crashes.

I believe I narrowed down the source of crashing to the blinking lights, which I am using to indicate a discrete random change of tempo and a note sequence shuffle. After removing the “blinkers”, I had the instrument running for several hours now without a crash. However, I can’t reproduce the crashing by just extracting the blinking mechanism out of the entire thing (see example below).

  • I’m wondering if there is a way to log Csound and/or Cabbage errors, could they be detected before a Cabbage crash? I feel I am getting more creative in modular code debugging, but I am wondering if there are any tools/tricks I could use and if you could give me any advices on this?

  • I realize that the inner workings of Cabbage might be chaotic and mysterious (surely to me), e.g. the recent issue with the recursive loop in the checkbox widget (Little GUI widget slugs and wishes). I’m thus wondering if my crashing issue could be due to something similar.

  • I tried with image instead of checkbox with similar results. So, I am wondering if it could be due to my method of “blinking” and maybe related to the devoted “blinking instruments” used here?

In the example below, I have three knobs: (1) METRO for base frequency (kMetroFrq0), (2) DIS-F (kDisorderFrq) for disordering frequency, (3) RND for amount of randomization and a SYNC button to switch type of randomization. I’m setting a frequency (kMetroFrq) as a multiple of kMetroFrq0 and two types of randomisers selected by the SYNC button: (1) smooth jspline or (2) a discrete multiplier read from an array at kMetroFrq*kDisorderFrq. I am also shuffling notes (commented in this example) at frequency kDisorderFrq. There are two lights blinking: (1) at kDisorderFrq and (2) at discrete jumps when SYNC = 1. In both cases kMetroFrq0>0 for lights to blink. So sorry, this became a really long description! :hot_face:

image

<Cabbage>
form caption("Test") size(150, 150), colour(0,0,0), guiMode("queue"), pluginId("tmb1")

rslider bounds(20, 28, 36, 36) range(0, 1, 0, 0.7, 1e-06) channel("SL_MetroFrq") colour(255, 255, 0, 255)  trackerColour(255, 255, 100, 255) markerColour(0, 0, 0, 255) popupText("0")
label   bounds(20, 64, 36, 10) text("METRO") fontColour(255, 255, 0, 255) channel("label5")

button bounds(96, 22, 25, 10) channel("SL_MetroRndFrqSync") text("SYNC", "SYNC")  colour:0(255, 255, 0, 50) colour:1(255, 255, 0, 255)  fontColour:1(0, 0, 0, 255)

rslider bounds(92, 32, 32, 32) range(0, 1, 0, 1, 1e-06) channel("SL_MetroRndFrqAmp") colour(255, 180, 0, 255)  trackerColour(255, 255, 100, 255) markerColour(0, 0, 0, 255) popupText("0")
label   bounds(92, 64, 32, 10) text("RND") fontColour(255, 180, 0, 255) channel("label10")

checkbox bounds(122, 23, 10, 10), shape("circle") colour:0(255, 255, 0, 150), colour:1(255, 255, 0, 255) channel("MetroRndBlink")active(0) automatable(0)

checkbox bounds(84, 94, 10, 10), shape("circle") colour:0(255, 255, 0, 150), colour:1(255, 255, 0, 255) channel("DisorderBlink") active(0) automatable(0)

rslider bounds(54, 94, 32, 32) range(0, 1, 0, 0.5, 1e-06) channel("SL_DisorderFrq") colour(200, 255, 100, 255) trackerColour(255, 255, 220, 255) markerColour(0, 0, 0, 255) popupText("0")
label   bounds(54, 126, 32, 10) text("DIS-F") fontColour(200, 255, 100, 255) channel("label20")


</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d 
</CsOptions>
<CsInstruments>
ksmps = 32

giMetroRndFrqMultiplier87[] fillarray 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 2/3, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 3/4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4/3, 4/3, 4/3, 4/3, 4/3, 4/3, 4/3, 4/3, 4/3, 3/2, 3/2, 3/2, 3/2, 3/2, 3/2, 3/2, 3/2

#define	MIDI_low_lim #0.007874015748# ;1/127 = 0.007874015748

instr 1

kMetroFrq0 = 50*cabbageGetValue:k("SL_MetroFrq")
kMetroFrq = kMetroFrq0

kMetroRndFrqAmp = cabbageGetValue:k("SL_MetroRndFrqAmp")
kDisorderFrq = round(cabbageGetValue:k("SL_DisorderFrq")*32)/32/6
kMetroRndFrqSync = cabbageGetValue:k("SL_MetroRndFrqSync")

kind init 64

; tempo randomization
if kMetroRndFrqAmp > $MIDI_low_lim then
    
    ; smooth jitter tempo 
    if kMetroRndFrqSync == 0 then
        kMetroFrq *= 1 + kMetroRndFrqAmp*jspline:k(0.9, .1+kMetroFrq0, .1+kMetroFrq0)
    endif
    
    ; reset tempo (array index)
    if trigger(kDisorderFrq,$MIDI_low_lim,1)==1 then
        kind = 64
    endif
    
    ; discrete tempo change (via table) - triggered frequency given by kMetroFrq*kDisorderFrq        
    if kMetroRndFrqSync == 1 && kDisorderFrq > $MIDI_low_lim then
        if metro:k(kMetroFrq*kDisorderFrq) == 1 then
            event "i", "Show_MetroRndBlink", 0, 1/ksmps           
            kind = 64 + kMetroRndFrqAmp^2*random:k(-64, 22)
        endif
        kMetroFrq *= giMetroRndFrqMultiplier87[round(kind)]
    endif
        
endif

; SHUFFLE
kDisorderTrig = metro:k(kMetroFrq*round(cabbageGetValue:k("SL_DisorderFrq")*32)/32/6)
if kDisorderTrig == 1 then 
    event "i", "Show_DisorderBlink", 0, 1/ksmps
    ;tableshuffle giSequenceShuffle
endif

endin

instr Show_MetroRndBlink
cabbageSetValue "MetroRndBlink", trighold:k(1,1/ksmps) ; blink
endin

instr Show_DisorderBlink
cabbageSetValue "DisorderBlink", trighold:k(1,1/ksmps) ; blink
endin

</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
i1 0 z
</CsScore>
</CsoundSynthesizer>

What should I be looking out for in this instrument?

The example is just an extract of the part that I suspect causes Cabbage to crash. It is really strange, if I have this blinking lights in my instrument, Cabbage crashes after a while, but by itself the mechanism seems to works fine.

I was on the edge of posting this question, I know it is very vague, but I though you might have a hunch what could be causing the crashes and I combined it with some additional and more general questions above. I’m specifically interested in learning how could I debug such cases, and catch the error causing a crash. I am sory that I am not able to ask a more straightforward question in this case.

I normally record a video with OBS showing how I can trigger a a bug I’ve found. Maybe it could be helpful to post a clip of it here?

Sure and I’ve done it before. But in this case I haven’t found a clear bug and all I could show now is Cabbage crashing really. I’ll try to isolate it further and if I find something more clear I’ll post an example. Meanwhile I hoped you guys might have some ideas regarding any potential issues with the above blinking mechanism and advice regarding Cabbage/Csound debugging. I might be stretching myself a bit here, because I don’t have background knowledge on how to find or understand Csound error messages. I’m interested to know whether any logging of errors is possible, if it could help at all etc. I guess we all miss some debugging functionality or there is something super useful for me to learn here? :slight_smile:

If you really wanted to help out we could work on getting a debug build of Cabbage running on your machine. You’d need to install XCode. It’s a monster download, but if could run Cabbage through the debugger there it would be a great help. Unless the issue is with Csound in which case we’re in the dark until we can easily recreate the problem.

Another option is running Cabbage through gdb, that was you won’t need Xcode. Let me check here and see if that will work…

Actually it is lldb that is needed. Can you try typing lldb from your command line and seeing if it is installed? If you can run that I can send you a debug version of Cabbage to test with. When it crashes lldb should give us something to go on.

I’m afraid I am getting myself into a black hole now :cold_sweat: and just be a nuisance to you.
But still curious if this could help me find the error without completely disassembling my instrument.

On MacOS 10.14.6 I have lldb-1001.0.13.3 Swift-5.0.

I’ll send you a debug version later. I’m away from the pc now for a bit :+1:

Now I found what was crashing Cabbage! Apparently it helps if I put myself under some pressure :slight_smile: I hope you don’t feel I am abusing this wonderful space.

It was a stupid mistake really. I was changing colour of a button too fast.

Try having a button and a slider like:

button bounds(20, 114, 50, 18) channel("Button") text("BUTTON", "BUTTON") corners(2) latched(0) colour:0(255, 255, 0, 50) colour:1(255, 255, 0, 255)
rslider bounds(20, 24, 96, 69) range(0, 100, 0, 0.7, 1) channel("Slider") colour(255, 255, 0, 255) valueTextBox(1) popupText("0")

and then do this silly thing

if metro:k(cabbageGetValue:k("Slider")) == 1 then
cabbageSet 1, "Button", "fontColour:0", 200, 255, 100, 255        
endif

When I reach about 100 Hz it crashes (ksmps = 32). Of course one should never do such a thing, but perhaps it would make sense to add some internal limit to 30 Hz or something reasonable? And maybe the crashing could inform you of something else that could cause issues down the line? In this case, the crashing actually acted as a brutal but efficient warning system :rofl:

Although I feel a bit less motivated at the moment, the debugging adventure is still interesting!
It wont be long till I screw up something else :wink:

It’s hard to prevent things like this without taking away higher levels of control for users. The older system has brakes in it to stop people updating the GUI too fast, but it would lead to UI latency at times which was frustrating. The new system will update at k-rate if you let it, but no GUI needs to be updated that fast. I find metro(10) is more than speedy.

I’m not seeing any crash with that. I can even push the slider to 10000 without any crashes. And it barely causes a spike in my CPU. Does this crash for you with even a simple instrument?

Yeah, higher levels of control should be priority.

Yes. But…totally confusing… I couldn’t get it to crash again now. Then after a while it happened again. I suspect the blinking light might do something, but it crashed also after I commented it. Before I started messing with this blinkers I had no such unexpected crashes. It feels like ones Cabbage sees the blinkers it becomes sensitive, moody and traumatised, and maybe if it doesn’t see them for a while it become cool again… This is really so confusing and bizarre.

This is the instrument that triggers crashes for me.

<Cabbage>
form caption("Test") size(150, 150), colour(0,0,0), guiMode("queue"), pluginId("tmb1")

rslider bounds(20, 24, 96, 69) range(0, 100, 0, 0.7, 1) channel("MetroFrq") colour(255, 255, 0, 255) valueTextBox(1) popupText("0")
button bounds(20, 114, 50, 18) channel("Button") text("BUTTON", "BUTTON") corners(2) latched(0) colour:0(255, 255, 0, 50) colour:1(255, 255, 0, 255)
checkbox bounds(116, 24, 20, 20), shape("circle") colour:0(255, 255, 0, 150), colour:1(255, 255, 0, 255) channel("MetroBlink")active(0) automatable(0)

</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d 
</CsOptions>
<CsInstruments>
ksmps = 32


instr 1

kMetroFrq = cabbageGetValue:k("MetroFrq")
if metro:k(kMetroFrq) == 1 then
    cabbageSet 1, "Button", "fontColour:0", 200, 255, 100, 255 
    event "i", "Show_MetroBlink", 0, 1/ksmps           
endif
        
endin

instr Show_MetroBlink
cabbageSetValue "MetroBlink", trighold:k(1,1/ksmps) ; blink
endin


</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
i1 0 z
</CsScore>
</CsoundSynthesizer>

It is known among vegetable farmers that Cabbage don’t like blinking lights. As you have observed, it brings on noticeable mood swings. I’m currently working on a new and revolutionary blinking light beta blocker. Once I have perfecting the formula I will start administering it to all future Cabbage releases :wink:

1 Like

New beta-blocking mode is now ready for testing :+1:

Is this really true - you’re not joking? It is a relief if it is true, because then I know how to make my instrument stable again (at least with some decent probability). BTW. I think Cabbage crash means standalone crash (observed), probably also plugin crash(not sure) and DAW crash (hope not!). Do you know how the crash propagates? Just curious because I’m going to use it in Ableton to record other musicians + my plugin.

I’ll start testing the new beta tonight. Thanks so much!
[edit] could you please explain what you did and do you think I could continue using the blinking mechanism above or do you have any other advice how to do this better?

Blink away. The queue was pushing and popping things too fast for the message thread. Should be all good now.

Are you joking? :thinking:

No, I though you were serious and there was a known issue with blinking lights :rofl:
Thanks for the clarification! I’ll test now.

And what about crashing DAWs? Is this feature implemented? :no_mouth:

There should not be any crash in a host, but most hosts now sandbox their plugins, so a crash in a plugin won’t take down the host. :+1:

Thanks! I’ve been torturing my beast (screen-shot) now for 2 hours - couldn’t get it crash! Now it feels safe for some live noise :smile: I’m so so… so happy!

It is maybe a placebo, but it seems that it uses a bit more CPU when less notes are playing, like it doesn’t save so much power as before. But no problem at all! I prefer melting down my computer in the summer heat than crashing Cabbage! :rofl: Thanks again!

1 Like