Cabbage Logo
Back to Cabbage Site

Unusual Dynamics Shaper

Hi, I’m relatively new to cabbage and I just finished my first project. Though I am not new to coding, I am also not really that professional at it (everything I know I learned it through the internet lol), and I had a few questions about how I made it work and how I could improve it.

It is an unusual multiband dynamics shaper that is based off a system that has been in my head for a few months (in fact, I just went to cabbage to make that system in the first place). It works by dividing the spectral field of a signal into a certain number of bands that is defined with a knob, and then independently getting the amplitude of each band in real time using different methods that the user can change for different tonality and character, and then each band uses it’s value to change the volume of the signal it comes out of it. Using this method, quiet frequencies get quieter and louder frequencies get louder. This can be used for obtaining really interesting characters and changing the tone of the sounds you put through it. I’ve tested it and it’s really fun to mess around with it as I had predicted, but I have one issue with it. The cpu performance could be better. And that might be because of how I wrote the code.

If you open the code you’ll see there’s a massive amount of lines that are basically duplications of the same snippet of code but with increasing numbers. That is the system that splits the audio’s spectrum into up to 100 different bands and processes the bands. I made it this way for two reasons to make the user able to decide what number of bands they want to split the audio into (this way the user can manage the cpu usage because the code for the bands that are not used is just ignored, saving cpu). I know I could have written it more efficiently using a for loop, but I thought it would be more straight-forward for the cpu to read it this way, and hopefully more efficient.

My question is, is using a for loop more optimal or not? and if it’s not, is there a better and more optimized way to write this apart from using a for loop?

Here’s the code so you can check it out:
Sharpener.csd (169.9 KB)

1 Like

Hi @KireJam, I’m sorry I didn’t get a chance to check this out earlier, but I will tomorrow. I’m looking forward to seeing what you’ve created. I’m sure we can reduce the amount of code. Whether it makes thing more CPU friendly or not I can’t say, but I like a challenge!

The reason for the CPU drain is because of the FFT display. It’s fine for a basic instrument, but in this kind of context it’s just going to cause audio dropouts. I’m using a pretty old PC here, and if I disable the FFT drawing the audio runs smoothly for me. It’s a pity, because the FFT stuff looks really nice. But is it really needed?

With regards to the code, yes, there is a lot you could do to simplify it. It might not help performance, but it would certainly make things easier to read and maintain. I’d start by turning each band block into a UDO. That on its own should reduce the code by about 80% :+1:

Just a quick though, would it perhaps be more effective to do the processing in the spectral domain? All the band-splitting would be relatively easy there. Also easier to manage the different number of bands (i.e. 2 bands vs 3 bands vs … 99 bands). I did not look deeply into the code (as it was so long…) so apologies if I missed the reason for doing it in the time domain.

And yes, I recognize the FFT display here :wink:

1 Like

I was thinking the same thing. You could use pvstencil and a masking table to achieve something similar.

Hey thanks for the reply! sorry I also could not check this earlier because stuff. Yeah it makes sense I might just remove that part of the code entirely. About the time domain thing… I dont quite get what you mean. I’m still really new to cabbage and also kinda new to this kind of coding so sorry if I don’t get some things (I also rarely code, I mainly make music and sound design lol). I’m assuming doing it on the spectral or time domain means two different ways of coding it, and I know what spectral means but I can’t understand what you mean with time domain, isn’t a band pass filter already affecting the spectral domain? or is it that specifically butterhp does it differently?
ps. yeah I directly snatched that fft display from a post because cabbagedisplay didn’t work for me and I had no idea how to code a svg display lmao sorry :sweat_smile:

Edit: I checked out pvstencil on the csound docs and I can see there’s a whole system of a different way to work with audio using fft transform, but looking at other docs I cant seem to get how I would split and process the bands using that system… could you provide some kind of example or explanation or amything just to get me going? Also, out of curiosity, is it really that better compared to what I did? If so, how so? like is it faster cpu wise, or is it cleaner sounding? thanks in advance!

Filters affect the spectral output of the sound, but they operate in the time domain, sample by sample. When you work in the frequency, or spectral domain, you first convert the incoming signal into a set of amplitude/frequency pairs. These are referred to as frequency bins. The output of an FFT is similar to placing 100s of bandpass filters across the frequency range of the signal. By measuring the output of each filter you can note the amount of energy at that frequency. In the spectral domain you only need query the amplitude of a particular bin to find out how much energy is around that frequency. So one FFT can provide you with the same info as 100s of bandpass filters.

The number of bands/bins in your FFT analysis is determined by the FFT size. An FFT size of 1024 will give you 512 equally spaced bin. As you can imagine, hard coding 512 bandpass filters would be a lot of work. But in the spectral domain it is just a matter of changing the FFT size.

My idea with pvstencil is that you could quickly shape the spectrum of the output signal with a table that defines the amount of boost/cut for each band. However, I’ve never actually used pvstencil, so let me take a look :rofl:

Btw, @Oeyvind is a master of the frequency domain :slight_smile:

Here is a simple example using pvstencil. I hadn’t used it before, but it seems nice. Maybe it can inspire some future work. The nice thing is that in a handful of lines of code one can implement broad band graphic EQ of sorts.

pvstencil.csd (1.2 KB)