next SuperCollider: Modulación
up Ejemplos en SuperCollider
previous SuperCollider: Envolventes
  Índice General   Índice de Materias


SuperCollider: SynthDefs


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

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

SynthDefs (definicion de sintetizador)
- Equivalente a un "patch" or "preset"
- Se puede escribir codigo para un SynthDef
- SynthDefs con "compilados" por sclang en una especie de bytecode
- Se pueden precompilar y almacenar en disco
- Tienen dos partes: un nombre y una funcion (ugenGraphFunc)

SynthDef(
	"aSynthDef",			    			// primer argumento: nombre
	{ .... yo soy una ugenGraphFunc ... }	// segundo argumento: ugenGraphFunc
)

Ejemplo:
To make the template functional 

(
a = SynthDef(
	"aSynthDef", 					// nombre
	{ 								// funcion
		arg freq = 440;				// argumentos a la funcion
		x = SinOsc.ar(freq, 0, 0.5);
		Out.ar(0, x)
	}
).load(s);
)

load escribe la definicion y la envia al servidor

a.play(s);
or
a.play;

play ejecuta la synthdef


Notes:

Arguments are important because these can change from note to note.

The audio output of Synths is generally handled with the Out unit generator.

	*ar(bus, channelsArray)  - write a signal to an audio bus.
	
The output bus numbers start at 0 and go up by integer for each additional channels.  The stereo output channels are 0 and 1.



Synth
- Representacion en el cliente de un nodo de sintetizador en el servidor
- Representa una unica unidad productora de sonido
- Lo que hace depende de su SynthDef


Ejemplos:


y = Synth.new("aSynthDef"); 
o
y = Synth("aSynthDef", nil, s); 
o
y = Synth.new("aSynthDef", [\argument1, value,\argument2, value, etc.], s);

y.free;

// Con argumentos
y = Synth("aSynthDef", [\freq, 262]);
z = Synth("aSynthDef", [\freq, 392]);
y.free;
z.free;



Ejemplos

(  // DEFINIR UN SYNTHDEF
	SynthDef( "Ringing", { arg freq;	// frequencia es el unico argumento
		var out;
		out = RLPF.ar(
			LFSaw.ar( freq, mul: EnvGen.kr( Env.perc, levelScale: 0.3, doneAction: 2 )),
			LFNoise1.kr(1, 36, 110).midicps,
			0.1
		);
		4.do({ out = AllpassN.ar(out, 0.05, [0.05.rand, 0.05.rand], 4) });
		Out.ar( 0, out );
	}).send(s);
)

( {  // Tocar una nota
	Synth( "Ringing", [ \freq, 440 ] );
}).play(s);


(	// Tocar dos notas al mismo tiempo
	( {
		Synth( "Ringing", [ \freq, 440 ] );
		Synth( "Ringing", [ \freq, 660 ] );
	}).play;
)

( 	// Para tener pausas, Synth estar dentro de una Routine
	Routine({
		Synth( "Ringing", [ \freq, 440 ] );
		1.0.wait;
		Synth( "Ringing", [ \freq, 660 ] );
	}).play;
)

( 	// Loop dentro de la Routine permite repetir un patron
	Routine({
		loop ({
			Synth( "Ringing", [ \freq, 440 ] );
			1.0.wait;
			Synth( "Ringing", [ \freq, 660 ] );
			1.0.wait;
		});
	}).play;
)


Convirtiendo de forma antigua a nueva

Ejemplo anterior

{	
	var env, amp;
	env = Env.perc(attackTime:0.2);
	amp = EnvGen.kr(envelope: env, levelScale: 0.5, doneAction: 2);
	SinOsc.ar(freq: 440,phase: 0,mul: amp)
}.play;

Usando SynthDef y frecuencia como argumento

(  // DEFINIR UN SYNTHDEF
	SynthDef( "SinEnv", { arg frequency;	
		var out, env, amp;
		env = Env.perc(attackTime:0.2);
		amp = EnvGen.kr(envelope: env, levelScale: 0.5, doneAction: 2);
		// argument is now used as the frequency value
		out = SinOsc.ar(freq: frequency,phase: 0,mul: amp);
		Out.ar( 0, out );
	}).send(s);
)

(	// Tocar dos notas
	( {
		Synth( "SinEnv", [ \frequency, 440 ] );
		Synth( "SinEnv", [ \frequency, 660 ] );
	}).play;
)

( 	// Loop
	Routine({
		loop ({
			Synth( "SinEnv", [ \frequency, 440 ] );
			1.0.wait;
			Synth( "SinEnv", [ \frequency, 660 ] );
			1.0.wait;
		});
	}).play;
)

Se puede agregar un argumento para el canal de salida

(  // DEFINICION
	SynthDef( "SinEnv", { arg frequency, chan;
		var out, env, amp;
		env = Env.perc(attackTime:0.2);
		amp = EnvGen.kr(envelope: env, levelScale: 0.5, doneAction: 2);
		// argument is now used as the frequency value
		out = SinOsc.ar(freq: frequency,phase: 0,mul: amp);
		Out.ar( chan, out );
	}).send(s);
)

(	// Tocar dos notas
	( {
		Synth( "SinEnv", [ \frequency, 440,\chan, 0 ] );
		Synth( "SinEnv", [ \frequency, 660, \chan, 1] );
	}).play;
)

( 	// Loop
	Routine({
		loop ({
			Synth( "SinEnv", [ \frequency, 440,\chan, 0 ] );
			1.0.wait;
			Synth( "SinEnv", [ \frequency, 660, \chan, 1 ] );
			1.0.wait;
		});
	}).play;
)

Ejemplo mas complejo
( // Flujo de tonos basado en una escala de Do Mayor
	var stream, dur, cScale;
	
	dur = 1/4;
	cScale = [60, 62, 64, 65, 67, 69, 71, 72];
	// Routines pueden generar secuencias de tonos
	stream = Routine({
		loop({cScale.choose.yield});
	});
	// Rountines pueden ser tocadas
	Routine({
		loop({
			Synth( "Ringing", [ \freq, stream.next.midicps ] );
			dur.wait;      // used by .play to schedule next occurence
		})
	}).play
)

( // Ejemplo anterior, esta vez los tonos son aleatorios
	var stream, dur;
	dur = 1/4;
	// esta rutina produce una secuencia randon de tonos
	stream = Routine.new({
		loop({								
			if (0.5.coin, {
				// run of fifths: 
				24.yield; 	// C1
				31.yield; 	// G1
				36.yield; 	// C2
				43.yield; 	// G2
				48.yield; 	// C3
				55.yield; 	// G3
			});
			rrand(2,5).do({
				// arpegio variado
				60.yield;					// C4
				#[63,65].choose.yield;		// Eb, F	
				67.yield;					// G
				#[70,72,74].choose.yield;	// Bb, C5, D
			});
			// melodia aleatoria
			rrand(3,9).do({  #[74,75,77,79,81].choose.yield });  // D5, Eb, F, G, A
		});
	});
	// tocar la rutina
	Routine({
		loop({
			Synth( "Ringing", [ \freq, stream.next.midicps ] );
			dur.wait;     
		})
	}).play
)


next SuperCollider: Modulación
up Ejemplos en SuperCollider
previous SuperCollider: Envolventes
  Í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