[Innard Help] Problems with GlobalDirtEffect's while coding a compressor

I'm trying to make a compressor for SuperDirt, specifically because I want to achieve " Sidechain Compression in Tidal? ". I've been running into many problems and my main concern right now is default values.

Setup

I added the global effect to the orbits globalEffects array:

~dirt.orbits.do { |x|
	var l = x.globalEffects.size;
	x.globalEffects = x.globalEffects.insert(l-2,
		GlobalDirtEffect(\dirt_compressor,['comp','thresh','atktime','reltime','upcomp','makeup','sidechain']));
	x.initNodeTree;
};

I defined some default values to the arguments of the SynthDef as one usually does:

~dryBuses = [];
~dirt.orbits.do { |x|
	~dryBuses = ~dryBuses ++ x.dryBus
}
(
SynthDef.new("dirt_compressor" ++ ~dirt.numChannels,
	{|dryBus, effectBus, comp=1, thresh=0.5, atktime=0.01, reltime=0.1, upcomp=1, makeup=1, sidechain=(-1)|
		var sound, in, control, chs;
		chs = ~dirt.numChannels;
		in = In.ar(dryBus, chs);
		control = if ( sidechain == (-1), {in}, {In.ar(Select.kr(sidechain,~dryBuses),chs)});
		// if a sidechain orbit is picked, use it as the control signal instead of the regular input
		sound = Compander.ar(in, control, thresh: thresh, slopeAbove: (1/comp),
			clampTime: atktime, relaxTime: reltime, mul: makeup, slopeBelow: (1/upcomp));
		Out.ar(effectBus, sound)
}, [\ir, \ir]).add;
s.freeAll;
)

And set my params in tidal as such:

let comp = pF "comp" -- compression ratio
    thresh = pF "thresh" -- threshold
    atktime = pF "atktime" -- attack time
    reltime = pF "reltime" -- release time
    upcomp = pF "upcomp" --upwards compression ratio
    makeup = pF "makeup" --amplitude of the output
    sidechain = pI "sidechain" --orbit from which to sidechain

Results

d1 $ s "bd*2" # makeup 1 # comp 1 # thresh 1

^ This is a neutral state of compression, nothing is happening, and sound is coming out as expected: the same as with no effects.

d1 $ s "bd*2" # makeup 0 # comp 1 # thresh 1

^ This should produce no sound, yet it does, at a lower volume than before. I'd say about half the volume; so, is it running on parallel?

d1 $ s "bd*2"

^ This should sound the same as in the beginning, but it sounds the same as the previous example.
I figured it must have to do with default values or something so I checked the node tree:

8768 dirt_compressor2
        dryBus: 48 effectBus: 50 comp: 0 thresh: 0 atktime: 0.0099999997764826 reltime: 0.10000000149012 upcomp: 1 makeup: 0 sidechain: -1
      8767 dirt_rms2

Here I run into my first problem: When erasing a paramater, it doesn't go back into its default value.
I'm guessing SC just ignores the last change of values into 0 since it would generate a division by zero error, hence the same output as before.

d1 $ s "bbtdr*2" # makeup 1 # comp 1 # thresh 1

^ This one is mind-boggling to me. After that mess of division by zero, when I try to go back into the neutral state of compression, now I hear nothing! There's no output.

Here's the whole node tree of the first orbit:

2 group
         9347 group
            -101992 dirt_sample_2_2
              out: 46 bufnum: 44 sustain: 0.41246938705444 begin: 0 end: 1 speed: 1 endSpeed: 1 freq: 261.62557983398 pan: 0 span: 1
            -102000 dirt_gate2
              out: 48 in: 46 sustain: 0.41246938705444 fadeInTime: 0 fadeTime: 0.0010000000474975 gain: 1 overgain: 0 amp: 0.40000000596046 sample: 1436622976 gateSample: 0 cutAll: 0
      8771 dirt_delay2
        dryBus: 48 effectBus: 50 gate: 1 delaytime: 0 delayfeedback: 0 delaySend: 1 delayAmp: 0 lock: 0 cps: 0.5625 resumed: 0
      8770 dirt_reverb2
        dryBus: 48 effectBus: 50 gate: 1 room: 0 size: 0.10000000149012 dry: 0 resumed: 0
      8769 dirt_leslie2
        dryBus: 48 effectBus: 50 gate: 1 leslie: 0.5 lrate: 6.6999998092651 lsize: 0.30000001192093 resumed: 0
      8768 dirt_compressor2
        dryBus: 48 effectBus: 50 comp: 1 thresh: 1 atktime: 0.0099999997764826 reltime: 0.10000000149012 upcomp: 1 makeup: 1 sidechain: -1
      8767 dirt_rms2
        dryBus: 48 effectBus: 50 gate: 1 rmsReplyRate: 0 rmsPeakLag: 0 orbitIndex: 0 resumed: 0
      8766 dirt_monitor2
        dryBus: 48 effectBus: 50 outBus: 0 gate: 1 limitertype: 1 resumed: 0

I realized that every global effect except the one I'm trying to add has the argument resmued at the end. I tried looking for it in the SuperDirt repo but couldn't really figure out what it is exactly.

Final questions

  • What is the 'resumed' argument in all GlobalDirtEffect's?
  • How do I make it so parameters go back into their default value state when erasing them from Tidal code?
  • Why does setting the 'makeup' to 0 still produce a fair amount of sound?

Thank you for reading all this mess ! Love

Global effects are generally set up as "send" effects (i.e. in parallel) so I think that's one thing you're hearing. You're actually hearing a doubled sound at first, and then the original in the next two examples.

Parameters should not go back to default values when erasing them from Tidal code, that's not how global effects work. They should be remaining at their previous value, I'm not sure why things seem to be going to zero in your example. I suspect it has to do with this line:

control = if ( sidechain == (-1), {in}, {In.ar(Select.kr(sidechain,~dryBuses),chs)});

You can't really do conditional code execution inside a SynthDef, see this page: If statements in a SynthDef » SuperCollider for some explanation about this.

1 Like

ohhhhhh rightttt i remember reading this page 2 years ago lol
totally went off my head
i'll try something like

control = In.ar(Select.kr(sidechain+1,[in]++~dryBuses),2);

thx so much! i'll let you know what i get out of it

nope, same results :frowning: