The SupeDirtMixer v1.0 is out now!

This is soooo cool! Thank you!
I managed to install and run it (after I did the small fix you mentioned in SuperDirt).
But something is not working as expected. The volume faders for the different channels seem to have no effect on the sound (even if turn it to zero I still hear the sound). The panning and effect knobs do work as expected.

You may run into troubles because there are functions and Buses in the defaultParentEvent that can't be written to json. One could separate these out using a dictionary with a parent (with all "private" stuff in the parent).

Gotcha, this is true!

It is in the quark's dependency list:

Ah yes, of course you meant the dependency list of the quark.

Actually, there is also TidalVST, which may not be necessary?

No it's not needed. I control a VST effect with the SuperDirtMixer, but in the end I just change a custom defaultParentEvent attribute and change something totally different.

Btw. it actually works with the EQui gitlab url. The dependency should be clean now.

This is soooo cool! Thank you!

I am glad to hear that! :slight_smile:

I managed to install and run it (after I did the small fix you mentioned in SuperDirt).

I can proudly say, that this small fix is now officially available on the latest version on the develop branch.

The volume faders for the different channels seem to have no effect on the sound (even if turn it to zero I still hear the sound).

You can try to change the value of the first volume fader and check whether the gain value changes for the first orbit with ~dirt.orbits[0].defaultParentEvent.at(\gain) . My assumption is, that you override gain with a TidalCycles pattern or you override it in your SuperCollider/SuperDirt setup somewhere. Basically when you change the value with i.e. ~dirt.orbits[0].defaultParentEvent.put(\gain, 0.5), then you should hear a difference.

1 Like

You are correct, I did override the gain parameter in my pattern. When I don't override it the fader work as expected :slight_smile:
The problem is that I override and pattern the gain parameter in almost every tidal pattern I create so the fader are unusable for me. Maybe instead of overriding it you can multiply the gain by the fader value? Or instead of gain override amp?

Just to note, this can be done more conveniently: ~dirt.set(\gain, 0.5) or ~dirt.orbits[0].set(\gain, 0.5)

You have many options. The formula in DirtEvent is:

amp = amp * pow(gain.min(2) + overgain, 4);

you can use amp in your pattern, e.g. or overgain

My suggestion is that the mixer will override amp so people that use gain in their patterns can continue doing so. BTW I was not aware of overgain, nice to learn about it

Why not use a different parameter name? The mixer has its own synthdef (dirt_global_eq2), so it can also have its own gain control.

Btw. why does it use the parameter reverbWet ?

Just to note, this can be done more conveniently: ~dirt.set(\gain, 0.5) or ~dirt.orbits[0].set(\gain, 0.5)

It's definitely good to be aware of this! Thanks for sharing :slight_smile:

The problem is that I override and pattern the gain parameter in almost every tidal pattern I create so the fader are unusable for me

@ShaiR This was a design decision I made, but I assume it's not what you would expect intuitive. The idea was to be able to override these values with TidalCycles pattern at any time to detach events from the mix.

The mixer has its own synthdef (dirt_global_eq2 ), so it can also have its own gain control.

@julian This sounds like a valid way to do. Maybe we can switch between the current gain handling and an own gain control. I would say an own gain control would be the default behaviour, because this is what you expect from an external mixer. The same should be applied for the panning.

Btw. why does it use the parameter reverbWet ?

Of course the name is misleading and a copy/pasta mistake, I already changed this (locally). The parameter is not changing something right now, but I wanted to activate and deactivate the global effect with this, because I wanted to be able to bypass the eq. This is why I didn't wanted to use alwaysRun(true). In theory it could be used as dry/wet control but it's not useful at all. But I assume that this parameter should not be there and I need to find a better way to achieve this. The calculation is something that I usually use, when I mix a custom global effect with my dryBus, to prevent a change in the loudness. Just a side note, this is how I mix my dry and wet signals in the end:

SynthDef(\masterSynth, { |out, fxBus|
	var size = 14;
	var wetSound = In.ar(fxBus, numChannels);
	var dryBusses = NamedControl.kr(\dryBusses, (0 ! size ));
	var wetSums = NamedControl.kr(\wetSums, (0 ! size));

	var drySound = size.collect({
		arg i;
		ReplaceOut.ar (dryBusses[i], In.ar(dryBusses[i], numChannels) * (1/(wetSums[i] +1) ));
	});

	Out.ar(out, wetSound);
}).add;

@Julian but I assume that I need to adjust the eq synth anyway. I wonder why the panning is broken(you see this easily with more extreme values). I saw this for other effects that I wanted to create before. You might have an idea what the reason could be? And btw. I use the dryBus for this, because the globalEffectBus will just add this to the dry signal on top. And for the synthBus I would need to use the orbit group, but maybe this would be better? But I assume that this will become quite hacky, because this EQ mechanism fits pretty well with the concept of an orbit wide global effect.

yes, the mixer shouldn't mess with the patterns. All its parameters can be separate.

OK, yes, call it whatever makes sense.

I would have thought that you want the mixer be the last thing after everything else has happened in the orbit.

The problem is that you'd need to be before the dirt_monitor, but dirt_monitor does the mix of the dryBus and the effectBus. We could separate out the mixing and the routing into two DirtGlobalEffects.

But, you could take advantage of this problem by giving gain control over dry and wet bus separately. But then you need to write something like this:



SynthDef("master_mix" ++ numChannels, { |dryBus, effectBus, gate = 1, masterGainDry = 1, masterGainWet = 1, gainControlLag = 0.1|
	var drySignal = In.ar(dryBus, numChannels);
	var wetSignal = In.ar(effectBus, numChannels);
	var env = EnvGen.kr(Env.asr, gate);
	drySignal = drySignal * masterGainDry.lag(gainControlLag);
	wetSignal = wetSignal * masterGainWet.lag(gainControlLag);
	DirtPause.ar(drySignal + wetSignal, graceTime:4);
	XOut.ar(dryBus, env, drySignal); 
	XOut.ar(wetBus, env, wetSignal); 
}, [\ir, \ir, \kr, \kr, \kr, \kr]).add;

This can then be inserted just before the dirt_monitor.

EDIT (I needed to fix a few things in the above code, so updated)

Does the mixer synth break panning?

1 Like

I would have thought that you want the mixer be the last thing after everything else has happened in the orbit.

Yes exactly, this is what I want to achieve now. My masterSynth example is an optional synth for my custom global fx bus, where I send every dryBus of every orbit into one effect before. But it was the additional explanation of the eq synth calculation in Out.

The problem is that you'd need to be before the dirt_monitor , but dirt_monitor does the mix of the dryBus and the effectBus . We could separate out the mixing and the routing into two DirtGlobalEffects.

Yes, and I see that this might be the reason, why global effects always increases the "loudness". If every global effect would have a dry/wet parameter, then we could do a little bit more complex calculation for adding global fx dignal to the dry signal without changing the loudness of the moxed signal. And gotcha, to change gain and panning on the sum of dry/wet signals, I need to do it in between mixing and routing. Thanks for pointing this out, it makes it a lot clearer now.

But, you could take advantage of this problem by giving gain control over dry and wet bus separately. But then you need to write something like this:

Thanks! This looks promising! But I will give it a try to separate mixing and routing later as well.

I will polish the mixer with everything that we discussed so far. I got some really interesting insights, so thank you very much! :pray:

Let me know if you want to do it this way, then we have to change the way superdirt does the mixing and routing. But I think you can just do it the other way, processing dry and fx signals separately and passing them on without mixing them.

Here the latest update:

It looked like, but I fixed it in the latest version. I needed to fix the load synth file function. I assume that the numChannels were set incorrectly (maybe to 1?). Now it behaves like I would expect it and the name for the eq synth is "dirt_global_eq" ++ numChannels now.

But I think you can just do it the other way, processing dry and fx signals separately and passing them on without mixing them.

I added it like you suggest it. It's not needed to change this in SuperDirt. But for now I just change dry and wet with one param. The new param for this is called masterGain and works independently von gain, amp and overgain :slight_smile:

Just to note, this can be done more conveniently: ~dirt.set(\gain, 0.5) or ~dirt.orbits[0].set(\gain, 0.5)

I changed this, where it was applicable.

there is a convenient library for JSON that allows you to ave and load dictionaries, maybe that is useful for saving presets?

This will be the next topic I want to tackle in the next days.

1 Like

HEADS UP

I switched the preset management from csv to json. This means that the latest change has a breaking change in the preset management.

Basically I polished the mixer code a little bit. Now it should be easier to extend for some future plans I might have :eyes:.

1 Like

Hi,
I managed to get this installed, which was a pleasant surprise considering my skills.
But i have a question:

When i set up the mixer in Supercollider startup file so, that "~mixer = SuperDirtMixer...." etc is after the section of defining mutable instruments' effect UGens as global (verb and clouds),
i get an error message upon trying to open the gui (running "~mixer.gui" results in audio stopping and "Server 'localhost' exited with exit code 0. Server 'localhost' disconnected shared memory interface")

When i move the mutable instruments UGens effect setup further down the .scd file (so it's after "~mixer.enableMasterPeakRMS(0);), then the gui opens no problem BUT the moving the EQ points/parameters does nothing to the sound itself. Panning, gain, mute etc works fine.

Would you have an idea how to remedy this / what i have set up wrong?
Thank you.

Other question would be has anyone set this mixer up so that it would be using for example said Mutable Instrument's verb UGen?

1 Like