next SuperCollider: Filtros bi-cuadráticos
up Ejemplos en SuperCollider
previous SuperCollider: Síntesis granular
  Índice General   Índice de Materias


SuperCollider: Patrones


TUTORIAL DE SUPERCOLLIDER 3 - PARTE 10
Rodrigo F. Cadiz, basado en apuntes de Gary S. Kendall
Northwestern University

(
   Server.internal.boot;
   Server.default = Server.internal;
   s = Server.default;
)

Patterns


Making Music with Patterns

Here is an example that uses a Pattern to create two instances of
the random melody stream.

(
	SynthDef( "SPE2", { arg i_out=0, i_dur=1, freq;
		var out;
		out = RLPF.ar(
			LFSaw.ar( freq ),
			LFNoise1.kr(1, 36, 110).midicps,
			0.1
		) * EnvGen.kr( Env.perc, levelScale: 0.3, 
							timeScale: i_dur, doneAction: 2 );
		4.do({ out = AllpassN.ar(out, 0.05, [0.05.rand, 0.05.rand], 4) });
		Out.ar( i_out, out );
	}).send(s);
)
(
// streams as a sequence of pitches
	var pattern, streams, dur, durDiff;
	dur = 1/7;
	durDiff = 3;
	pattern = Prout.new({
		loop({
			if (0.5.coin, {
				#[ 24,31,36,43,48,55 ].do({ arg fifth; fifth.yield });
			});
			rrand(2,5).do({
				// varying arpeggio
				60.yield;
				#[63,65].choose.yield;
				67.yield;
				#[70,72,74].choose.yield;
			});
			// random high melody
			rrand(3,9).do({  #[74,75,77,79,81].choose.yield });
		});
	});
	streams = [  // Stream.at(0)  combines Prout's output with Pfunc transposing notes randomly
		(pattern - Pfunc.new({ #[12, 7, 7, 0].choose })).midicps.asStream, // 0 in array
		pattern.midicps.asStream // 1 in array
	];
	Routine({
		loop({
			// Do this
			Synth( "SPE2", [ \freq, streams.at(0).next, \i_dur, dur * durDiff  ] );
			durDiff.do({  // then do this durDiff times
				Synth( "SPE2", [ \freq, streams.at(1).next, \i_dur, dur  ] );
				dur.wait;
			});
		})
	}).play
)

TUTORIAL DE SUPERCOLLIDER 3 - PARTE 11
Rodrigo F. Cadiz, basado en apuntes de Gary S. Kendall
Northwestern University

ListPatterns

ListPatterns are Patterns that iterate over arrays of objects in some fashion.
All ListPatterns have in common the instance variables list and repeats.
The list variable is some Array to be iterated over. The repeats variable is
some measure of the number of times to do something, whose meaning 
varies from subclass to subclass. The default value for repeats is 1.



Making Music with ListPatterns

Here is an example we have heard before rewritten to use ListPatterns.
It uses nested patterns and results in much more concise code.

(
SynthDef( "Allpass6", { arg freq, dur= 1.0;  // Frequency and duration parameters
	var out, env;
	out = RLPF.ar(
		LFSaw.ar( freq, mul: EnvGen.kr( Env.perc, levelScale: 0.15, timeScale: dur, doneAction: 2 ) ),
		LFNoise1.kr(1, 36, 110).midicps,
		0.1
	);
	6.do({ out = AllpassN.ar(out, 0.05, [0.05.rand, 0.05.rand], 4) });
	Out.ar( 0, out  );
}).send(s)
)

(   // This is a good more complex model
	var freqStream;

	freqStream = Pseq( // list, repeats, offset
		[Prand([ nil, Pseq(#[24, 31, 36, 43, 48, 55])]), 
						// no repeat, nil causes pattern to end
			Pseq([ 60, Prand(#[63, 65]), 67, Prand(#[70, 72, 74]) ], rrand(2, 5)),
			Prand(#[74, 75, 77, 79, 81], { rrand(3, 9) })
		], 
		inf).asStream.midicps;
	
	Task({
		loop({
			Synth( "Allpass6", [\freq, freqStream.next]);
			0.13.wait;
		});
	}).play;	
)

Here is an example that uses a Pattern to create a rhythmic solo. The values in the pattern 
specify the amplitudes of impulses fed to the Decay2 generator.

(
SynthDef( "Mridangam", { arg t_amp; // Amplitude is argument (dur isn't meaningful)
	var out;

	out = Resonz.ar( 
		WhiteNoise.ar(70) * Decay2.kr( t_amp, 0.002, 0.1 ),
		60.midicps, 0.02,4
	).distort * 0.4;
	Out.ar( 0, out  );
	DetectSilence.ar( out,  doneAction: 2 );
}).send(s);

SynthDef( "Drone", {
	var out;
	out = LPF.ar(
		Saw.ar([60, 60.04].midicps) + Saw.ar([67, 67.04].midicps), 
		108.midicps, 
		0.007
	);
	Out.ar( 0, out  );
}).send(s);
)

(// percussion solo in 10/8
var stream, pat, amp;

pat = Pseq([
	Pseq(#[0.0], 10),

	// intro
	Pseq(#[0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 2),
	Pseq(#[0.9, 0.0, 0.0, 0.2, 0.0, 0.0, 0.0, 0.2, 0.0, 0.0], 2),
	Pseq(#[0.9, 0.0, 0.0, 0.2, 0.0, 0.2, 0.0, 0.2, 0.0, 0.0], 2),
	Pseq(#[0.9, 0.0, 0.0, 0.2, 0.0, 0.0, 0.0, 0.2, 0.0, 0.2], 2),
	
	// solo
	Prand([
		Pseq(#[0.9, 0.0, 0.0, 0.7, 0.0, 0.2, 0.0, 0.7, 0.0, 0.0]),
		Pseq(#[0.9, 0.2, 0.0, 0.7, 0.0, 0.2, 0.0, 0.7, 0.0, 0.0]),
		Pseq(#[0.9, 0.0, 0.0, 0.7, 0.0, 0.2, 0.0, 0.7, 0.0, 0.2]),
		Pseq(#[0.9, 0.0, 0.0, 0.7, 0.2, 0.2, 0.0, 0.7, 0.0, 0.0]),
		Pseq(#[0.9, 0.0, 0.0, 0.7, 0.0, 0.2, 0.2, 0.7, 0.2, 0.0]),
		Pseq(#[0.9, 0.2, 0.2, 0.7, 0.2, 0.2, 0.2, 0.7, 0.2, 0.2]),
		Pseq(#[0.9, 0.2, 0.2, 0.7, 0.2, 0.2, 0.2, 0.7, 0.0, 0.0]),
		Pseq(#[0.9, 0.0, 0.0, 0.7, 0.2, 0.2, 0.2, 0.7, 0.0, 0.0]),
		Pseq(#[0.9, 0.0, 0.4, 0.0, 0.4, 0.0, 0.4, 0.0, 0.4, 0.0]),
		Pseq(#[0.9, 0.0, 0.0, 0.4, 0.0, 0.0, 0.4, 0.2, 0.4, 0.2]),
		Pseq(#[0.9, 0.0, 0.2, 0.7, 0.0, 0.2, 0.0, 0.7, 0.0, 0.0]),
		Pseq(#[0.9, 0.0, 0.0, 0.7, 0.0, 0.0, 0.0, 0.7, 0.0, 0.0]),
		Pseq(#[0.9, 0.7, 0.7, 0.0, 0.0, 0.2, 0.2, 0.2, 0.0, 0.0]),
		Pseq(#[0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
	], 30),
	// conclusion
	Pseq(#[2.0, 0.0, 0.2, 0.5, 0.0, 0.2, 0.9, 
		 1.5, 0.0, 0.2, 0.5, 0.0, 0.2, 0.9, 
		 1.5, 0.0, 0.2, 0.5, 0.0, 0.2], 3), 
	Pseq(#[5], 1),
	Pseq(#[0.0], inf)
]);
stream = pat.asStream;

Task({
	Synth("Drone");
	loop({
		if( ( amp = stream.next ) > 0,
			{ Synth("Mridangam", [ \t_amp, amp ]) }
		);
		(1/8).wait;
	})
}).play

)



next SuperCollider: Filtros bi-cuadráticos
up Ejemplos en SuperCollider
previous SuperCollider: Síntesis granular
  Índice General   Índice de Materias

Copyright © 2008-06-05
Rodrigo F. Cádiz   - Centro de Investigación en Tecnologías de Audio, Instituto de Música, Pontificia Universidad Católica de Chile