[feedback appreciated] HELP - code semantics - Alva Noto Style Attempt


(
	SynthDef(\sine1, {arg out = 0, amp = 1;
		var osc = SinOsc.ar(3222,0,1)!2;
		var env = EnvGen.kr(Env.perc, doneAction: Done.freeSelf);
		Out.ar(out, Pan2.ar(osc) * env * amp);
}).add;

	SynthDef(\sine2, {arg out = 0, amp = 1;
		var osc = SinOsc.ar(322,0,1)!2;
		var env = EnvGen.kr(Env.perc, doneAction: Done.freeSelf);
		Out.ar(out, Pan2.ar(osc) * env * amp);
}).add;

	SynthDef(\sine3, {arg out = 0, amp = 1;
		var osc = SinOsc.ar(99,0,1)!2;
		var env = EnvGen.kr(Env.perc, doneAction: Done.freeSelf);
		Out.ar(out, Pan2.ar(osc) * env * amp);
}).add;

	SynthDef(\whiteNoise, {arg out = 0, amp = 1;
		var osc = WhiteNoise.ar!2;
		var env = EnvGen.kr(Env.perc, doneAction: Done.freeSelf);
		Out.ar(out, Pan2.ar(osc) * env * amp);
}).add;
)

(
TempoClock.default.tempo = 164/60;
~p1 = Pxrand([
    Pbind(
        \instrument, \sine1,
        \dur, Pseq([0.75, 0.25, 0.25, 0.25, 0.5], 1),
        \legato, Pseq([0.9, 0.3, 0.3, 0.3, 0.3], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\sine1,
        \dur, Pseq([0.25, 0.25, 0.5], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\sine1,
        \dur, Pseq([0.25, 0.25, 0.25, 0.75], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\sine1,
        \dur, Pseq([0.25, 0.5, 0.25, 0.5], 1),
        \amp, 0.06, \detune, 1.005
    )
], inf).play(quant: 1);

~p2 = Pxrand([
    Pbind(
        \instrument, \sine2,
        \dur, Pseq([0.75, 0.25, 0.25, 0.25, 0.5], 1),
        \legato, Pseq([0.9, 0.3, 0.3, 0.3, 0.3], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\sine2,
        \dur, Pseq([0.25, 0.25, 0.5], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\sine2,
        \dur, Pseq([0.25, 0.25, 0.25, 0.75], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\sine2,
        \dur, Pseq([0.25, 0.5, 0.25, 0.5], 1),
        \amp, 0.06, \detune, 1.005
    )
], inf).play(quant: 1);

~p3 = Pxrand([
    Pbind(
        \instrument, \sine3,
        \dur, Pseq([0.75, 0.25, 0.25, 0.25, 0.5], 1),
        \legato, Pseq([0.9, 0.3, 0.3, 0.3, 0.3], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\sine3,
        \dur, Pseq([0.25, 0.25, 0.5], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\sine3,
        \dur, Pseq([0.25, 0.25, 0.25, 0.75], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\sine3,
        \dur, Pseq([0.25, 0.5, 0.25, 0.5], 1),
        \amp, 0.06, \detune, 1.005
    )
], inf).play(quant: 1);

~p4 = Pxrand([
    Pbind(
        \instrument, \whiteNoise,
        \dur, Pseq([0.75, 0.25, 0.25, 0.25, 0.5], 1),
        \legato, Pseq([0.9, 0.3, 0.3, 0.3, 0.3], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\whiteNoise,
        \dur, Pseq([0.25, 0.25, 0.5], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\whiteNoise,
        \dur, Pseq([0.25, 0.25, 0.25, 0.75], 1),
        \amp, 0.06, \detune, 1.005
    ),
    Pmono(\whiteNoise,
        \dur, Pseq([0.25, 0.5, 0.25, 0.5], 1),
        \amp, 0.06, \detune, 1.005
    )
], inf).play(quant: 1);

)

Given that there’s a lot of duplication in the patterns, you could consider shortening the code a bit by making a function to generate the patterns.
I also don’t really like if I have to boot the server manually, so I did a change there too.

(
s.waitForBoot {
	var make_pat, pat;
	
	SynthDef(\sine1, {arg out = 0, amp = 1;
		var osc = SinOsc.ar(3222,0,1)!2;
		var env = EnvGen.kr(Env.perc, doneAction: Done.freeSelf);
		Out.ar(out, Pan2.ar(osc) * env * amp);
	}).add;
	
	s.sync; 
	
	SynthDef(\sine2, {arg out = 0, amp = 1;
		var osc = SinOsc.ar(322,0,1)!2;
		var env = EnvGen.kr(Env.perc, doneAction: Done.freeSelf);
		Out.ar(out, Pan2.ar(osc) * env * amp);
	}).add;
	
	s.sync; 
	
	SynthDef(\sine3, {arg out = 0, amp = 1;
		var osc = SinOsc.ar(99,0,1)!2;
		var env = EnvGen.kr(Env.perc, doneAction: Done.freeSelf);
		Out.ar(out, Pan2.ar(osc) * env * amp);
	}).add;
	
	s.sync; 
	
	SynthDef(\whiteNoise, {arg out = 0, amp = 1;
		var osc = WhiteNoise.ar!2;
		var env = EnvGen.kr(Env.perc, doneAction: Done.freeSelf);
		Out.ar(out, Pan2.ar(osc) * env * amp);
	}).add;
	
	s.sync; 
	
	make_pat = {
		| instr_name |
		Pxrand([
			Pbind(
				\instrument, instr_name,
				\dur, Pseq([0.75, 0.25, 0.25, 0.25, 0.5], 1),
				\legato, Pseq([0.9, 0.3, 0.3, 0.3, 0.3], 1),
				\amp, 0.06, \detune, 1.005
			),
			Pmono(instr_name,
				\dur, Pseq([0.25, 0.25, 0.5], 1),
				\amp, 0.06, \detune, 1.005
			),
			Pmono(instr_name,
				\dur, Pseq([0.25, 0.25, 0.25, 0.75], 1),
				\amp, 0.06, \detune, 1.005
			),
			Pmono(instr_name,
				\dur, Pseq([0.25, 0.5, 0.25, 0.5], 1),
				\amp, 0.06, \detune, 1.005
			)
		], inf)
	};
	
	pat = Ppar([
		make_pat.(\sine1),
		make_pat.(\sine2),
		make_pat.(\sine3),
		make_pat.(\whiteNoise)
	], inf);
	
	fork {
		wait(thisThread.clock.elapsedBeats - thisThread.clock.beats); // needed if you create many and large patterns to avoid losing the first notes
		~player = pat.play(quant:1);
	};
}
)
1 Like

how would i theoretically fix the duplication in the synthdefs?
cheers

Acutally I think there’s a bit of a conceptual problem in your code: to the best of my knowledge it is difficult to use Pbind and Pmono with the same synth.

  • In Pbind, a new synth is instantiated for each note, so each synth must clean up after itself (Done.freeSelf).
  • In Pmono, a new synth is instantiated only once and then needs to remain alive while it’s used (probably should have used Done.none).

SynthDef duplication: Well, you have 3 defs that are the same except for frequency – that suggests the use of a frequency argument. A freq argument is a basic, standard technique; I’d guess there are a few hundred examples in the help system. For example, in the Getting Started tutorial series: http://doc.sccode.org/Tutorials/Getting-Started/10-SynthDefs-and-Synths.html#Creating%20Variety%20with%20SynthDefs

Also there’s really no point to using Pmono if the note isn’t changing.

Also a SynthDef used with Pmono should use a gated envelope and not Env.perc.

It isn’t necessary to sync between SynthDefs – just once after the last SynthDef is enough.

hjh