IF
Con el mensaje if podemos condicionar la ejecución de funciones.
Este mensaje recibe una expresión que al ser evaluada debe
regresar los valores true o false (valores booleanos).
Si la expresión es cierta, se ejecutará la función
que se encuentra en el segundo argumento. Si es falsa, se
ejecutará la función que se encuentra en el tercer
argumento.
El mensaje if nos regresará el resultado de la
función que haya sido evaluada. Si no hay ninguna función
para ser evaluada en el caso de que la expresión haya sido
falsa, el resultado del mensaje será nil.
if ( expression, { trueFunction }, { falseFunction } )
(
if(
2.0.rand.postln > 1
, // la expresión
booleana
{"la expresion fue cierta" }, //
la función a evaluar si
// la expresión es cierta
{"la expresion fue falsa"};
// la función a
evaluar si
// la expresión es falsa
)
)
// si la expresión es falsa y no hay ninguna función que
sea evaluada,
// if nos dará nil
if ( 1000.rand > 900, {"mayor que 900"})
// Evalúa el siguiente código varias veces
(
{
var opciones;
opciones = [ \aditiva,
\substractiva ];
if ( opciones.choose == \aditiva,
{"aditiva".postln;
a = Mix.fill(10, {SinOsc.ar(exprand(30.0,
300.0), 0, 0.07)}) },
{"substractiva".postln;
a = Mix.fill(10, {BPF.ar(BrownNoise.ar, f =
exprand(300.0, 3000.0),
0.5/f, 4)})}
);
a ! 2 }.scope
)
// Evalúa las siguientes líneas
Expresiones booleanas
1 < 2 // menor que
1 > 2 // mayor que
1 == 2 // igual que
(Atención: es muy común cometer el error de
//
sólo poner un signo de igual ( = ) en vez de dos ( == )
1 != 2 // distinto que
1 <= 2 // menor o igual que
1 >= 2 // mayor o igual que
1.odd // ¿es un
número non?
1.even // ¿es un
número par?
////////////////////////////////////////////////////////////////////
Evaluando algunas funciones
Si quisieramos evaluar una función es necesario seguir algunos
pasos.
Primero construimos la función que queremos evaluar. Por ejemplo:
x={|n| if(n>10,{"es mayor a 10"},{"es menor a 10"})} //construimos
la funcion x en donde
n
(argumento) es nuestra incognita;
//compilamos el codigo
//collider nos contesta a Function
Para darle valores a la función x es necesario la siguiente
linea de codigo:
x.value(1) //en donde dentro de los parentesis asignamos el valor que
tomara n
Supongamos que queremos evaluar lo siguiente:
a={|n| if(n>10,{"es mayor a 10"},{"es menor a 10"})}
a.value(45)
a={|n| if(n.even,{"es numero par"},{"es numero impar"})}
a.value(8)
a={|n| if(n!=10,{"es distinto a 10"},{"es 10"})}
a.value(10)
//Ahora con Tdef
(
a={|n| if(n>10,{"es mayor a 10"},{"es menor a 10"})};
Tdef(\hu,{
inf.do{a.value(rrand(2,20)).postln;
0.5.wait
}}
)
)
Tdef(\hu).play
Tdef(\hu).stop
////////////////////////////////////////////////////////////////////
RELOJES
iteración
Una operación presenta valores de entrada y de salida. En el
siguiente ejemplo a y b toman los valores de entrada y salida
a = 2
b = a + 1
Una iteración es un proceso en el que el valor de salida de una
operación se utiliza como un nuevo valor de entrada. Ejemplo
a=0
b=a+1
a=b
b=a+1
a=b
b=a+1
a=b
b=a+1
a=b
b=a+1
a=b
b=a+1
a=b
b=a+1
Pero este algoritmo se simplifica de esta manera.
b = 0
b = b + 1
Si no damos la informaciónn previa éste algoritmo
podría interpretarse como una contradicción por lo cual
es importante que seamos concientes de lo que implica el algoritmo de
iteración dentro del lenguaje de SuperCollider.
Matemáticamente el algorítmo simplificado significa esto:
b = 0
b = b + 1 => 0 = 0 + 1 ! Contradicción
Pero dentro del lenguaje de SuperCollider y otros varios
este algorítmo significa la iteración que
hemos explicado.
////////////////////////////////////////////////////////////////////
Mediante una simple interación como la que vimos podemos
construir una estructura que nos será muy útil.
Esta estructucra simula un contador que nos devuelve una secuencia de
números extraída del algoritmo x = x + 1
Veamos como funciona dentro de un Tdef:
(
Tdef(\reloj,{var contador = 0;
inf.do{contador = contador + 1;
contador.postln;
0.1.wait
}}
)
)
Tdef(\reloj).play
Tdef(\reloj).stop
Pero esta estructura nos devuelve una lista de números
infinitos¡¡¡...
En ciertas circunstancias necesitaremos limitar la secuencia a cierto
número máximo después del cual se reenicia la
cuenta.
Para esto es necesario utilizar el modulo (%)
(
Tdef(\reloj,{var contador = 0;
inf.do{contador = contador + 1;
(contador % 10).postln;
0.5.wait
}}
)
)
Tdef(\reloj).play
Tdef(\reloj).stop
////////////////////////////////////////////////////////////////////
SWITCH
Es una herramienta que nos permite evaluar una variable y, dependiendo
de su valor, asignar acciones en respuesta. Observen como en el ejemplo
siguiente podemos asignar un valor a la variable 'a' y el switch
realizará las acciones que le indiquemos dependiendo si 'a' vale
0, 1, 2, 3 ó 4.
(
a = 3;
switch(a, 0,{'a es igual a cero'.postln;},
1,{'a es igual a
uno'.postln},
2,{'a es igual a
dos'.postln},
3,{'a es igual a
tres'.postln},
4,{'a es igual a
cuatro'.postln}
);
)
Podemos asignar más de una acción dentro de la
función de respuesta. Llamemos a un Synth además del
postln.
(
SynthDef(\switch, {|freq=100|
var sig, env;
sig=Pulse.ar(freq,Line.kr(0.5,0.01,0.1))!2;
env=EnvGen.kr(Env.perc(0,01,0.1),doneAction:2);
Out.ar(0,sig*env);
}).send(s);
);
Synth(\switch)
(
a=1;
switch(a, 0,{'a es igual a cero'.postln; Synth(\switch, [\freq, 100])},
1,{'a es igual a
uno'.postln; Synth(\switch, [\freq, 2000])},
2,{'a es igual a
dos'.postln; Synth(\switch, [\freq, 300])},
3,{'a es igual a
tres'.postln; Synth(\switch, [\freq, 400])},
4,{'a es igual a
cuatro'.postln; Synth(\switch, [\freq, 500])},
24,{'a es igual a
cuatro'.postln; Synth(\switch, [\freq, 500])}
);
)
En definitiva el Switch se puede ver como un conjunto de varios if pero
que nos ahorra trabajo de escritura. Vean cómo resolvemos el
código anterior pero hecho con if.
(
a=4;
if(a==0,{'a es igual a cero'.postln; Synth(\switch, [\freq, 100])});
if(a==1,{'a es igual a uno'.postln; Synth(\switch, [\freq, 200])});
if(a==2,{'a es igual a dos'.postln; Synth(\switch, [\freq, 300])});
if(a==3,{'a es igual a tres'.postln; Synth(\switch, [\freq, 400])});
if(a==4,{'a es igual a cuatro'.postln; Synth(\switch, [\freq, 500])});
)
////////////////////////////////////////////////////////////////////
(
(
SynthDef(\puls, {|freq|
var sig, env;
sig=Pulse.ar(300,Line.kr(0.5,0.01,0.1));
env=EnvGen.kr(Env.perc(0,01,0.1),doneAction:2);
Out.ar(0,sig*env);
}).send(s);
);
(
SynthDef(\sin, {|freq|
var sig, env;
sig=SinOsc.ar(2000,0,0.3);
env=EnvGen.kr(Env.perc(0,01,0.1),doneAction:2);
Out.ar(0,sig*env);
}).send(s);
);
(
SynthDef(\saw, {|freq|
var sig, env;
sig=Saw.ar(2000,0.8);
env=EnvGen.kr(Env.perc(0,01,0.1),doneAction:2);
Out.ar(0,sig*env);
}).send(s);
);
)
(
Tdef(\sw,{var contador = 0;
inf.do{contador = contador + 1;
(contador
%3).postln;
switch(contador%3, 0,{Synth(\puls)},
1,{Synth(\sin)},
2,{Synth(\saw)}
);
0.3.wait
}}
)
)
Tdef(\sw).play
Tdef(\sw).stop
////////////////////////////////////////////////////////////////////
(
SynthDef(\saw, {|freq|
var sig, env;
sig=Saw.ar(freq,0.8)!2;
env=EnvGen.kr(Env.perc(0,01,0.1),doneAction:2);
Out.ar(0,sig*env);
}).send(s);
);
(
Tdef(\sw,{var contador=0;
inf.do{contador=contador+1;
(contador%3).postln;
Synth(\saw,[\freq,((contador%[3,10].choose)+1)*100]);
0.1.wait
}}
)
)
Tdef(\sw).play
Tdef(\sw).stop