Embarrassing newb question

learning sc and wanted to add random decays being triggered by dust to simple synth…

I know the following dose not work but hopefully shows how I am trying to work it out…

(
SynthDef(\blips,{ 
	var sig, tig, env;
	tig = Dust.kr(12);
	env = Env.per(0.01,Exprand(0.01..1)gate:tig);
	sig = SinOsc.ar(ExpRand([400,2000]!2),mul:env);
	Out.ar(0, sig);
}).add;
)

Synth(\blips).play;

You were pretty close, just a few syntactic mistakes:

SynthDef(\blips,{ 
	var sig, tig, env;
	tig = Dust.kr(12);
	env = Env.perc(0.01, ExpRand(0.01, 1)).kr(gate:tig);
	sig = SinOsc.ar(ExpRand(400,2000),mul:env)!2;
	Out.ar(0, sig);
}).add;

Synth(\blips)

ExpRand values are only calculated once when instantiating the synth. If you want values to change while the sound is playing, use a Ugen like ie. LFNoise0:

(
SynthDef(\blips,{ 
	var sig, tig, env;
	tig = Dust.kr(12);
	env = Env.perc(0.01, LFNoise0.kr(2).range(0.1, 1)).kr(gate:tig);
	sig = SinOsc.ar(LFNoise0.kr(10).range(400,2000),mul:env)!2;
	Out.ar(0, sig);
}).add;
)
1 Like

thank you !!!

with no coding experience Im finding sc a challenge but its pure magic when it clicks at times.

Yes, I remember that feeling, I started with SC and coding in general about 3 years ago. Here are some suggestions in general:

  • all of Eli Fieldsteel’s videos (you probably already found those)
  • all the help docs, lots of nice little simple synthdefs which can work as starting points for further investigations
  • tons of great info by browsing posts in this forum.
  • anything you can find related to a more general understanding of DSP - it helps if you know about analog modular or something similar.

Here are some suggestion to work on your synthdef:

You would probably want to give yourself arguments for most of the parameters. Also I was in a little bit of a hurry when I wrote the first reply. The env is being triggered 12 times a second so I think it would make more sense to let the decay time be determined each time a new env is being triggered, I am using TRand for this. Also, I added an env for the signal, so you can do a nice release of synth. Try changing the LFNoise0 to LFNoise1 or LFNoise2 for a different character.

(
SynthDef(\blips,{ 
	var sig, tig, mulenv, env;
	tig = Dust.kr(\trigrate.kr(12));
	mulenv = Env.perc(0.01, TRand.kr(\loT.kr(0.05), \hiT.kr(0.1), tig)).kr(gate:tig);
	sig = SinOsc.ar(LFNoise0.kr(\rate.kr(10)).range(400,2000)) * mulenv;
	env = Env.asr(\atk.kr(0.1), 1, \rel.kr(2)).kr(2, \gate.kr(1));
	Out.ar(0, sig!2 * 0.3 * env * \amp.kr(1));
}).add;
)

x = Synth(\blips)

x.set(\rate, rrand(1, 20), \trigrate, rrand(3, 12), \loT, rrand(0.01, 0.05), \hiT, rrand(0.06, 1)) // evaluate several times, new randomized setting each time.

x.set(\rel, 3, \gate, 0) // release with a 3 sec. decay
1 Like

So funny this is exactly the next thing I was thinking about, have the decay reset on each env

Thanks for the helpful advice. Yes I come from using modular. But after moving to a new country decided to only focus on supercollider. ( it had been a long time coming ) Hoping to graduate to making compositions that I’m able to improvise on in life settings

Was nervous to post what assumed would be to easy of a question.

Thank you

The \atk.kr(0.1) in the Env. the \loT.kr(0.05), and \hiT.kr in the TRand
What are those? They look like keys. Where are they defined? Im new to sc too.

I think Thor_Madsen can answer this more definitely (as I am new )
but it seems like symbols can be function as args. - pretty cool

They are an alternative to declaring args at the top of the function. You can search for namedcontrols in the help files to read more. This style of declaring args has some benefits over the normal way - not so much in this case, but when you use arrays of values in a synthdef.

Here is the same synthdef written with normal style arg-declarations. Notice also that I am using the shorter syntactic alternative to EnvGen.kr(Env…) in both cases.

(
SynthDef(\blips,{ arg trigrate = 12, loT = 0.05, hiT = 0.1, atk = 0.1, rel = 1, gate = 1, amp = 1, rate = 10;
	var sig, tig, mulenv, env;
	tig = Dust.kr(trigrate);
	mulenv = Env.perc(0.01, TRand.kr(loT, hiT, tig)).kr(gate:tig);
	sig = SinOsc.ar(LFNoise0.kr(rate).range(400,2000)) * mulenv;
	env = Env.asr(atk, 1, rel).kr(2, gate);
	Out.ar(0, sig!2 * 0.3 * env * amp);
}).add;
)

Im still far to new to really know the befits of one style over the other but did I find namedcontrols had an ease when it came to reading the code.

FWIW, when I use this style of control-input declaration for arrays, I usually write out NamedControl.kr(\name, value) precisely because \name.kr is not self-documenting i.e. likely to confuse new users. Pedantic? Maybe… but good for readability, especially since I declare inputs at the top instead of interpersing them throughout the SynthDef body. (I also use function args for “normal” – single-value control-rate – inputs.)

I also try to be consistent, when writing about SC, to refer to synth inputs as “inputs” or “control inputs” and not “args” – because they’re different from function args.

hjh

1 Like

Don’t be. I’ve learned a lot from questions that I’ve asked and that others have asked. Often what seems easy/simple to one person is also not at all obvious to another. And if the question really is easy then someone will have the thirty seconds required to answer it.

2 Likes

ok then here goes…haha
I know that mul and add are super important. I able to understand how mul works as an amplitude multiplier for on signals. And I can see how add can offset a sig on a scope… but I am little unclear as to why you would need to offset… would love to get how to use add unpacked a bit.

Here’s another opinionated but IMO helpful thread from @nathan on this topic:

In general, audio signals should not be offset – DC is bad for speakers.

Control signals may have an arbitrary range, however, which need not be centered on 0. In that case, an offset may be necessary (whether you write it with add or +).

(FWIW I hardly ever use mul/add at all anymore.)

hjh

In general, adding a constant to a signal can be useful when applying distortion (I think it makes odd harmonics?).
Something like this…

var snd = ...;
snd = snd + 0.5; // offset
snd = snd.tanh; // non-linear process (waveshaping)
snd = snd - 0.5; // reset offset

But you probably shouldn’t use the mul and add arguments in the UGens, they are remnants of an old optimisation.

tanh on its own makes odd harmonics: a sine wave (before) becomes more like a square wave after. I think an offset before distortion makes the resulting “square” wave more like a pulse wave where pulse width != 0.5.

“Shouldn’t” may be a bit strong; I’d say certainly there’s no good reason to prefer mul/add over math operators, and probably some good reasons to prefer the math operators – but people can do as they like.

hjh

It’s interesting to see that recently, more and more people are attempting to establish a uniform coding style in SuperCollider. I don’t recall this happening before. Even in small stylistic details like this.

Interesting so are you primarily only scaling your signals down at that the output…

This is fine, as long as I am the one deciding what that uniform style will be :wink:

Tongue in cheek there. Everyone has different priorities. For me, “no mul/add” barely makes the list at all, while inconsistent indentation and spacing concretely make it harder to read code and help with questions here, so I more often remark on that. I personally am not at all a fan of \symbol.kr inline synth input definition, but I know some people like it very much, so I keep my mouth shut (though, if that ever became part of a strongly encouraged or enforced coding style, then I wouldn’t keep quiet). And so on… try to strike a friendly balance.

hjh

Yes, I know some extreme cases that the person recreates the syntax, changing all operators for functions application and composition. But he also writes “I don’t realistically expect anyone to use it”. But it’s out there, some people use it probably.

That’s actually fun and healthy, the community discuss and see alternatives.