Cabbage Logo
Back to Cabbage Site

Can someone check if this program I wrote is CPU-heavy?

It’s just a sketch, but it’s giving me problems that I think are nothing more than overtaxing the CPU.

It’s not a complicated program, but it makes use of a gentable widget that refreshes 2 times per second to display a waveform.

What the program does: it plays a simple mono psytrance-style rolling kick/bass and displays the waveform on the screen. I wanted to duplicate the style of LFO tool - how it displays a single beat’s worth of waveform that updates on each beat so that instead of scrolling, the waveform is locked so that the same part of the beat is always at the same horizontal position within the waveform display. It’s more complicated to explain then to understand if you look at it.

My issue is that the context for all these problems are the very underpowered and old laptop I’m on. I was hoping someone with a decent computer could tell me whether the program struggles? I’m not sure if the program itself is much of a CPU hog or if my computer is just weak af.

If it’s also underperforming on decent computers, then the question becomes why and how to fix it, because it’s not a long program, and it’s certainly not the audio parts that are to blame.

<Cabbage>
form caption("Untitled") size(900, 300), guiMode("queue"), pluginId("def1")
gentable bounds(8, 8, 800, 286) channel("display") tableBackgroundColour("blue") tableNumber(99) fill(0)
button bounds(820,8,75,25) latched(1) channel("refresh") text("refresh") colour:0("blue") colour:1("green")
nslider  bounds(820,40,75,25) channel("bdlt")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
--displays -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

gibeats = sr*0.50 ;audio samples in a beat

cabbageSet "display", "sampleRange", 0, gibeats

gienv2 ftgen 0,0,16384,-7, 1, 16384, 1
gibuf ftgen 99,0,-gibeats,-2,0 ;empty buffer

instr 1

if (chnget:i("refresh"))==1 then
cabbageSet "display", "tableNumber", 99
cabbageSetValue "refresh", 0
endif

icps = cpspch(5.05)


anv expsega 1/100, 0.0005, 1, p3/8, 2/3, p3/4, 1/3, p3/8, 1/100
an2 tablei line:a(0,p3,1), gienv2, 1, 0, 0
af1 expsega icps*7, p3/16, icps, p3, icps
akik oscil anv*an2, af1

abasf init icps
asqr init 0
asaw init .95
abas squinewave abasf, asqr, asaw, asqr

aben expseg 0.00001, p3/4-0.0005, 0.00001, .0005, 1, p3/4-0.0005, 0.001, 0.0005, 1, p3/4-0.0005, .001, 0.0005, 1, p3/4-0.0005, 0.001, 0.0005, 0.00001
abas *= aben

kdlt chnget "bdlt"
abas vdelayx abas, a(kdlt/icps), 1.00, 16

adisp = akik+abas
andx line 0, p3, p3*sr
tablew adisp, andx, gibuf, 0, 0, 0

ares =.5*(akik+abas)
outs ares, ares
endin

</CsInstruments>
<CsScore>

;causes Csound to run for about 7000 years...
t 0 120
{64 x
i 1 [$x] 1
}
</CsScore>
</CsoundSynthesizer>

Does this question belong in Cabbage Recipes by the way?

It’s a nice instrument, so why not. But I guess this might be better in the Cabbage stew category, but it’s not a big deal. The Cabbage police will not be calling on you :laughing:

The slow down here is almost certainly due to the table size you’re using. The gentable widget is not great for constantly updating. The soundfiler should give better performance, but I’ll have to double check that its tables can be updated in realtime. Also, add a -m0d to your CsOptions to stop Cabbage from printing messages to the console. This is a bit of a CPU hog too. Finally, keep in mind that instruments will aways run faster as a plugin as they don’t have the added overhead of the Cabbage IDE.

1 Like

The slow down here is almost certainly due to the table size you’re using. The gentable widget is not great for constantly updating.

Great to know, and undoubtedly a factor, but I think my issue was simpler, and my fault entirely!

I realized today something I had forgotten: I didn’t set the loop to continue forever, but only 64 times (see <CsScore></CsScore> section). When the loop was finished, I thought the program was crashing!

It’s performance is a little weaker than the typical Cabbage program this size, but I thought it was a problem of a completely different nature. It’s not crashing or anything like that.

What I had to do, as you see in the program above, was use a refresh button instead of updating the image on every beat like I had wished. Of course, if I develop this, I would include a checkbox so that the user can choose to turn on continual updating if they have a better computer than me (almost everyone would).

On the whole my situation has been a constant proof that Cabbage lets you develop stuff (at least on the level of a musician’s personal use) using very limited resources. That’s the achilles heel of all the major DAWS: one always ends up having to buy the most cutting edge computers in order to have this year’s must-have plugins and whatnot. Even in the case of the gentable widget, once I made updates occasional and user-triggered, problem solved. At least mostly.

I will say a few things about using the program, since I’m here.

I forgot to mention that you have to click “refresh”. Otherwise the widget wont re-draw the data. For this I used the cabbageSet opcode with tableNumber(). Even though the actual value in the parenthesis never changes, every time you call the opcode the widget re-draws the data.

And I forgot to mention the mysterious nslider below the refresh button. This is the delay time for the bass, and the units are unusual. It is used to add very small amounts of delay time to the bass signal. This lets you change the phase relationship between the two instruments (kick and bass). The units for the nslider are adapted specifically for this purpose. A value of 0 means, of course, no delay. A value of 1.00 means 1/icps seconds, where icps is the fundamental frequency of the bass (the bass has no pitch envelope, so its pitch never varies).

In other words, the units are “fractions of a duty cycle of the bass oscillator”. Hope that makes sense.

Delay times can only go positive so that the bass lags in relation to the kick. Overdoing the delay here, of course, would change the rhythm. But the idea is to use a value less than 1.00 to align the phases for minimum phase cancellation.

Tip: change change asaw to be negative instead of positive for the sawtooth wave to go the opposite way. And play with the values of asqr and asaw to flavor the bass.

I’m glad you got it sorted. And yes, it’s definitely liberating to free yourself from the restrictions of commercial products :wink: