Hi there, welcome to the Sonic Pi community! It’s lovely to have you here.
Looking at your problem, it’s very much likely that your CPU is chewing too hard over the real-time requirements of running many simultaneous reverb FX.
Short answer, try adding , reps: 32
before the do
of each with_fx :reverb
such as:
with_fx :reverb, room: 0.9, reps: 32 do
.
.
end
Longer answer - when you’re experiencing bad performance (with glitchy sounds) you might benefit from throttling the number of FX synths that are created.
Sonic Pi uses a synthesis engine called SuperCollider to generate its sounds. SuperCollider in turn has a notion of synth nodes which are bits of code which are running and represent a live sound or bit of sound processing. Sonic Pi manages the full life cycle of these synth nodes for you - constantly creating and terminating them as new sounds are triggered and manipulated. Each sound comes from a synth node and each FX is implemented using synth nodes. Normally you don’t have to think about them (unless you want to control them). However, occasionally you do and this appears to be such a situation. Let’s explore this in a little more detail…
Each time the code executes with_fx
it creates a brand new FX synth just for that code block. It also ensures that the synth it created for the FX is terminated when it’s no longer needed.
This is kind of like a garbage collector for synths if that helps in any way as an analogy.
This therefore means that as a user of Sonic Pi you don’t have to worry about either creating the synths that power FX or correctly terminating them when they’re no longer needed. You just need to describe the scope of the code (within the do/end
block). In my experience this has made working with FX way easier and more fluent given it reduces the amount of code you have to write and the things you have to think about.
However, one caveat of this approach is that it’s very possible to get into situations where you generate more FX synths than you can process in real time. This is likely to be what’s causing your issues right now.
Looking at the code, I know that the reverb synth with a room size of 0.9
is held open for around 10s to allow for the the long tail of the reverberation to fully fade out. You are also generating 4 reverbs a second in the :drum
live loop alone. This means that after 10s you’ll have ~40 reverb synths running at the same time just to serve the audio requirements of the :drum
live loop. This is likely to be clogging things up somewhat.
One approach to fix this is to move the with_fx
block outside of the live loop. This will result in only 1 FX reverb synth being created. If you plan to never change the reverb FX (remove it, change its opts etc.) then this is probably the best option to take.
with_fx :reverb, room: 0.9 do
live_loop :drums do
.
.
.
end
end
However, if you do want to be able to change or remove the :reverb
, at least as of v3.1 you can only change with_fx
blocks that are within a live loop not outside it.
Unfortunately, the fact that the live loop spins round quickly, putting the FX within them can mean that they get triggered a lot. One way to reduce this effect is to use iteration within the live loop:
live_loop :drums do
with_fx :reverb do
16.times do
.
.
sleep 0.25
end
end
end
This means that we only get a new reverb synth every 16 times rather than every time. The live loop spins round 16 times slower as a result (although the inner code is spinning round just as fast). So in this case, even though the code is being repeated 4 times a second, it does 16 repetitions before spinning round the live loop again and triggering a new reverb FX.
This pattern is so useful that it’s been integrated into all FX as an opt called reps:
. The following code is equivalent to the example above:
live_loop :drums do
with_fx :reverb, reps: 16 do
.
.
sleep 0.25
end
end
This approach will drastically reduce the number of FX synths are created and hopefully give your CPU a little bit more room to breath.
BTW, the crunch sounds you were hearing are called x-runs. They points in the soundwave where the CPU couldn’t feed the right numbers in time, so just got a default value.
Hope that this helps