Clase 4

// Taller de SuperCollider Básico

BUAP

 

Sesión 4

  07/04/09

   

 

*SynthDefs

*UGens como argumentos de UGens

*Generadores de ruido como controladores

*Ejercicios

 

Acá puedes bajar la clase en los formatos PDF y docx

 

//SynthDefs

 

SynthDef es una definición de sonido (un sonido creado por nosotros) o una definición de síntesis que puede ser invocada y manipulada independientemente de otros. Un SynthDef es el método por el cual creamos nuestros sonidos en SuperCollider.

 

SuperCollider utiliza la definición de synth [SynthDef] como un template para la creación de synth node que es una unidad productora de sonido en el servidor.

 

Un SynthDef tiene una sintaxis específica que comprende dos partes fundamentales:

el nombre del SynthDef que se escribe como un string o un símbolo (ej :“prueba” o \prueba) por el cual podremos  manipular el synth independientemente de otros synth y un UGenGraphFunc= una función en donde se especifica la intercomunicación entre variables y argumentos.

 

ejemplo de la clase anterior

(

SynthDef(“prueba”, {|gate,frecuencia=15| Out.ar(0,Pulse.ar(frecuencia)*EnvGen.kr(Env.asr(0.01,1,3),gate,doneAction:2))}).send(s)

)

 

a=Synth(\prueba,[\gate,1])

a.set(\gate,0)

 

 

(

//una sintaxis de SynthDef comienza con el objeto SynthDef

SynthDef(“prueba”, //el synthdef debe llevar un tag (nombre) que lo identifique, en este caso “prueba”.

 {|gate|          //argumento, es el lugar destinado para los parámetros que queremos interpretar.

  //[**Los argumentos son también espacios virtuales de memoria que sirven para guardar información pero ésta, a diferencia de las variables es creada para ser modificada.]

 Out.ar(0,         //canal de salida, 0 y 1

      Pulse.ar(15)*EnvGen.kr(Env.asr(0.01,1,3),gate,doneAction:2)) //salida

      }).send(s)         //se envía el synth al servidor designado por default con la letra s

)  

 

(

SynthDef(“prueba”,{|gate=1|

       var sen,env;

           sen=Pulse.ar(15,0.2,0.1);

             env=EnvGen.kr(Env.asr(0.01,1,3),gate,doneAction:2);

                Out.ar(0,sen*env)

                }).send(s)

 )

 

 (

SynthDef(“prueba”,{arg gate=1;

       var sen,env;

           sen=Pulse.ar(15,0.2,0.1);

             env=EnvGen.kr(Env.asr(0.01,1,3),gate,doneAction:2);

                Out.ar(0,sen*env)

                }).send(s)

 )


(

{

var sen,env;

sen=Pulse.ar(15,0.2,0.5);

env=EnvGen.kr(Env.perc(0,0.1),Impulse.kr(2));

sen*env

}.play

)

 

Synth(“prueba”)

 

Una vez creada la estructura del SynthDef es necesario invocarlo para que suene, el SynthDef no suena por si solo.

 

Tenemos dos maneras de hacerlo: una de ellas es la llamada Object Style.

 

1.- Object Style

 

Synth(nombre, [\argumento1, valor1, … \argumentoN, valorN ], target, addAction)  

 

(

Synth(     // utilizamos el método new

    // de la clase Synth. 

     

“prueba”,      // un string que especifique

    // el nombre del SynthDef

    // a utilizar para crear el

    // nuevo synth

     

[\gate, 1, \frecuencia, 20],      // un Array opcional que espe-

    // cifique los valores iniciales

    // para los argumentos del

    // SynthDef

    // estos valores son mandados 

    // en parejas, el nombre del 

    // argumento como symbol y su

    // valor:

    // [\nombre1, valor1,

    //  \nombre2, valor2 ] 

     

s,      // el target: el grupo donde será

    // creado el nodo de este synth.

    // si especificamos al servidor como

    // target, nuestro synth será creado

    // en el grupo default del servidor, 

    // que es el 1

 

\addToTail         // la addAction: especificamos en qué

        // lugar del grupo será creado nuestro

        // synth

)

)

 

Para facilitar la invocación del SynthDef podemos utilizar las instrucciones mas básicas dejando por default el target y la addAction:

 

ejemplo      

a=Synth(\prueba)

a=Synth(“prueba”)                                             

a=Synth(“prueba”, [\gate, 1]) // Lo prenden

a.set(“gate”, 0)  // Lo apagan

 

Como notarán, igualamos la variable a un SynthDef que se llama “prueba” para luego modificar sus argumentos por el metodo .set

Los argumentos a los que nos referimos son los que creamos en el SynthDef y esta es la manera en la que cambiamos su valor.

 

Hay ciertos componentes de esta estrucutura de los SynthDef que pueden escribirse de otro modo:

 

(

SynthDef(\prueba, //el tag cambia de comilla a diagonal (cambia de string a symbol)

 {arg gate;       //los argumentos pueden enumerarse despues de la palabra arg y concluye con punto y  coma(;)..similar a 

      //las variables

 Out.ar(0,         //canal de salida, 0 y 1

      Pulse.ar(15)*EnvGen.kr(Env.asr(0.01,1,3),gate,doneAction:2)) //salida

      }).send(s)         //se envia el synth al servidor designado por default con la letra s

)  

 

a=Synth(\prueba, [\gate, 1]) // las comillas se cambian por diagonales

a.set(\gate, 0)  // Lo apagan

 

////////////////

 

(

SynthDef(\mi_primer_synth,{|frecuencia,amplitud|

     var sen,env,trig;

       trig=Impulse.kr(2);

         sen=Saw.ar(frecuencia*[0.988889,1.011],amplitud);

            env=EnvGen.kr(Env.perc(0.01,0.5),trig);

               Out.ar(0,sen*env)

               }).send(s)

               )

 

a=Synth(\mi_primer_synth)

a=Synth(\mi_primer_synth,[\frecuencia,200,\amplitud,0.3]) //

a.set(\frecuencia,12)

a.free

 

/////////////////

SynthDef con envolvente percusiva mas un argumento para el trigger:

 

(

SynthDef(\mi_primer_synth,{|frecuencia=100,amplitud=0.6,frecuenciatrig=2|

     var sen,env,trig;

       trig=Impulse.kr(frecuenciatrig);

         sen=Saw.ar(frecuencia*[0.988889,1.011],amplitud);

            env=EnvGen.kr(Env.perc(0.01,0.5),trig);

               Out.ar(0,sen*env)

               }).send(s)

               )

 

a=Synth(\mi_primer_synth)

a.set(\frecuenciatrig,1)

 

a.set(\frecuenciatrig,5.rrand(10),\frecuencia,101.rrand(1820))

a.free

 

101.rrand(1820)

5.rrand(10)

 

/////////////////

SynthDef con envolvente asr

(

SynthDef(\mi_segundo_synth,{|frecuencia=100,amplitud=0.6,gate=1|

     var sen,env;

       sen=Saw.ar(frecuencia*[0.988889,1.011],amplitud);

            env=EnvGen.kr(Env.asr(3.6,1,4.5),gate,doneAction:2);

               Out.ar(0,sen*env)

               }).send(s)

               )

 

a=Synth(\mi_segundo_synth)

a.set(\frecuencia,170)

a.set(\gate,0)

 

 

 

En este ejemplo mostramos cómo podemos crear diferentes Synth a partir de un SynthDef.

 

 

(

SynthDef(\hola,{|frec=430,amp=0.2,gate=1,trig=10|

    var sen,env;

        sen=SinOsc.ar(frec*[1,1.01],0,amp);

            env=EnvGen.kr(Env.perc(0,0.1),Impulse.kr(trig));

                Out.ar(0,sen*env)

                }).send(s)

                )

 

a=Synth(\hola)

a.set(\frec,1700)

a.free

 

 

b=Synth(\hola,[\frec,1240])

b.set(\frec,800)

b.free

 

 

c=Synth(\hola,[\frec,900])

c.free 

 

Cuando copilamos la línea de código a=Synth(\hola) las post nos devuelve

Synth(“hola” :1000)

 

Esta línea nos dice el nombre de la SynthDef utilizada por el synth y el nodo en donde éste último se encuentra (1000). El número de nodo (nodeID) fue seleccionado automáticamente por la clase Synth, ésta simplemente buscó un número de nodo que estuviese libre.

 

Nodo. Un objeto con el que se puede establecer comunicación. Se encuentra en un árbol de nodos manejado por el servidor de síntesis. El árbol define el orden de ejecución de todos los synths. Hay dos tipos de nodos:  groups y synths. Todos los nodos llevan un número entero por nombre ( nodeID ).             

 

/////////////////////////////////////////////Tarea🙂

 

 

 

(

SynthDef(\pozole,{|freq,vol,gate|

   var sen,env;

      sen=SinOsc.ar(freq,0,vol);

       env=EnvGen.kr(Env.perc(0,2),gate,doneAction:2);

            Out.ar(0,sen*env)

            }).send(s)

            )

 

a=Synth(\pozole)

a.set(\freq, 1000, \vol, 0.6, \gate, 1)

 

 

 

(

——(\—-,{|—,—,—,—-|

   var —-,—-,—-;

       —-=—-.ar(Saw.ar(—-,—-),—–,0.2);

         —=EnvGen.kr(Env.perc(0,—-),doneAction:2);

            Out.ar(—-,—-*—-)

            }).—-(s)

            )

 

Crea tus propios SynthDef

 

////////////////////////

 

//UGens como argumentos de UGens

 

Como hemos visto los UGens tienen argumentos específicos que pueden ser determinados:

 

Pulse.ar(frecuencia, ancho del pulso, mul, adición)

 

A estos argumentos se les pueden asignar valores fijos:

 

{Pulse.ar(456,0.34,0.45,0)}.play;

 

También podemos meter a los UGens dentro de una estructura de SynthDef y cambiar sus argumentos desde afuera:

 

(

SynthDef(\cacahuate, {|gate=1, freq=456, ancho=0.34, amp=0.45|

  var sig, env;

  sig=Pulse.ar(freq,ancho,amp,0);

  env=EnvGen.kr(Env.asr(2,1,1),gate, doneAction:2);

  Out.ar(0,sig*env);

  }).send(s)

)

 

c=Synth(\cacahuate)  

c.set(\freq, [1,2,3,4,5,6].choose*456)

c.set(\ancho, [1,2,3,4,5,6].choose*0.1)

c.set(\gate, 0)

 

Ahora veremos una manera diferente de hacer que los argumentos de un UGen cambien de valor. Primero que nada observemos los datos que arroja un UGen en particular, digamos un SinOsc

 

{SinOsc.ar(1,0,1,0)}.play   // no se preocupen, no se oye nada por que la frecuencia es muy baja!

 

Este UGen nos da 1 ciclo por segundo de una onda senoidal. La amplitud es de 1, asi que el recorrido de la onda parte de 0, sube a 1, baja a -1 y regresa a 0 en un segundo. Podemos decir que el rango de esta función va de -1 a 1. El tercer elemento del SinOsc es el mul y el valor que asignemos ahi multiplicará a los valores de nuestra función. Siempre pedimos que sea  1 el máximo valor por que siempre hemos usado el mul como valor para la amplitud de un sonido. Lo que sucede con el rango de nuestra senoide al ser multiplicado por distintos valores del mul podemos observarlo en las siguientes líneas de código:

 

[-1,1]*1

[-1,1]*0.5

[-1,1]*0.25

[-1,1]*0

 

 

El cuarto argumento del SinOsc es el add o adición. Siempre hemos usado el add en cero por default. Este valor se suma a la función de nuestro UGen y se refleja en el rango. En el ejemplo que estamos viendo nuestro rango es de [-1,1] por eso al sumarle 0 no se ve afectado.

 

[-1,1]+0

 

Ahora veamos cómo se afecta este rango al combinar diferentes valores del mul y el add.

 

[-1,1]*1+1

 

[-1,1]*10+10

 

[-1,1]*100+100

 

[-1,1]*100+200

 

Si nos fijamos en el ejemplo [-1,1]*100+200 vemos que nuestro rango va de 100 a 300. Entonces sabemos ahora que un SinOsc con frecuencia 1, fase 0, mul 100 y add 200 nos da una onda sinoidal que varía su frecuencia entre  100 y 200.

 

{SinOsc.ar(1,0,100,200)}.play

 

Claro que cuando lo queremos oir no no podemos por que la frecuencia sigue siendo de 1 y es muy baja. Pero podemos aprovechar que el juego entre el mul y el add nos arroja números que pueden ser utilizados como valores para la frecuencia de OTRO SinOsc. Así que simplemente colocamos el código anterior en el argumento de frecuencia de otro SinOsc:

 

{SinOsc.ar(SinOsc.ar(1,0,100,200))}.play

 

Ahora tenemos una senoide que cambia su argumento de frecuencia moviendo su valor entre 100 y 200 una vez por segundo. Este ejemplo en particular es llamado FM o Frecuencia Modulada por que estamos modulando o cambiando la frecuencia de un sonido periódicamente. Veamos cómo se escucha con distintos valores de freq, mul y add. Vamos a cambiar el Audio rate por Kontrol rate en el SinOsc que esté como argumento de frecuencia por que este SinOsc no esta generando una señal sino que solo controla un argumento.

 

{SinOsc.ar(SinOsc.kr(10,0,100,200))}.play

 

{SinOsc.ar(SinOsc.kr(1,0,100,1000))}.play

 

{SinOsc.ar(SinOsc.kr(10,0,100,1000))}.play

 

{SinOsc.ar(SinOsc.kr(100,0,10000,10200))}.play

 

Pero bueno… mejor usemos un SynthDef.

 

(

SynthDef(\fm, {|gate=1, freq=1, mul=100, add=1000, amp=1|

  var modulacion, sig, env;

  modulacion=SinOsc.kr(freq,0,mul,add);

  sig=SinOsc.ar(modulacion,0,amp);

  env=EnvGen.kr(Env.asr(2,1,2),gate,doneAction:2);

  Out.ar(0,sig*env);

  }).send(s)

)

 

m=Synth(\fm)

m.set(\freq, 40, \mul, 900, \add, 1000)

m.set(\gate, 0)

 

Podemos usar cualquier oscilador como controlador de otro UGen y de igual manera que hemos controlado la frecuencia de un SinOsc podemos controlar su amplitud o cualquier otro argumento. Cuando modulamos la amplitud de un oscilador se le llama AM o Amplitud Modulada. Veamos cómo suena poniendo un SinOsc.kr en el argumento de amplitud de un SinOsc.ar. Cuidado con los valores que escogemos para el mul y el add ya que al estar trabajando con la amplitud no debemos superar el 1.

 

{SinOsc.ar(440,0,SinOsc.kr(1,0,0.5,0.5))}.play

 

Escogí los valores 0.5 para el mul y 0.5 para el add por que me arrojan un rango entre 0 y 1 que son el máximo y el mínimo recomendados para la amplitud. 

 

[-1,1]*0.5+0.5

 

Hagamos un SynthDef para generar una AM.

 

(

SynthDef(\am, {|gate=1, portadora=1000, moduladora=10, amp=1|

  var modulacion, sig, env;

  modulacion=SinOsc.kr(moduladora,0,0.5,0.5);

  sig=SinOsc.ar(portadora,0,modulacion);

  env=EnvGen.kr(Env.asr(2,1,2),gate,doneAction:2);

  Out.ar(0,sig*env*amp);

  }).send(s)

)

 

a=Synth(\am)

a.set(\moduladora, 2000)

a.set(\gate, 0)

 

//Generadores de ruido como controladores

 

LFNoise0, LFNoise1 y LFNoise2

 

Veamos ahora un nuevo generador de ruido que podemos usar como UGen de control como en los ejemplos anteriores. El LFNoise o Ruido de Baja Frecuencia tiene 3 modalidades: 

 

LFNoise0 – genera valores aleatorios saltando de uno a otro valor.

LFNoise1 – genera valores aleatorios creando una línea que recorre los valores intermedios entre estos.

LFNoise2 – genera valores aleatorios creando una curva cuadrática que recorre los valores intermedios entre estos. Esto es muy útil cuando queremos controlar frecuencias, ya que las frecuencias altas ocupan la mayoría del rango de frecuencias y debemos de compensar esto para tener igual oportunidad de obtener las frecuencias bajas.

 

Escuchemos cómo se oyen estos generadores de ruido por sí mismos. Los argumentos de los tres generadores son los mismos : freq, mul y add.

 

s.quit;

s=Server.internal.boot

 

{LFNoise0.ar(1000,1,0)}.scope 

 

{LFNoise1.ar(1000,1,0)}.scope

 

{LFNoise2.ar(1000,1,0)}.scope

Observando el osciloscopio podemos ver gráficamente la característica de cada tipo de LFNoise

 

Ahora usémoslos como controladores. El principio del rango es igual que en el ejemplo del SinOsc por que, como la mayoría de los osciladores, los LFNoise trabajan con un rango inicial de -1 a 1.

 

[-1,1]*9990+10010 //números entre 20 y 20000

[-1,1]*50+350 //números entre 20 y 20000

 

{SinOsc.ar(LFNoise0.kr(10,9990,10010),0,0.5)}.scope // Cambia su frecuencia por salto entre 20hz y 20000hz 10 veces por segundo.

{SinOsc.ar(LFNoise1.kr(10,9990,10010),0,0.5)}.scope // Cambia su frecuencia linealmente entre 20hz y 20000hz 10 veces por segundo.

{SinOsc.ar(LFNoise2.kr(10,9990,10010),0,0.5)}.scope // Cambia su frecuencia cuadráticamente entre 20hz y 20000hz 10 veces por segundo. 

 

Para obtener el valor del mul y el add a partir de un rango conocido podemos utilizar la siguiente fórmula:

 

mul=(máximo-mínimo)/2

add=mul+mínimo

 

Por ejemplo, para obtener un rango entre 20hz y 20000hz

 

mínimo=20

máximo=20000

mul=(máximo-mínimo)/2=

(20000-20)/2

add=mul+mínimo=

9990+20

 

[-1,1]*9990+10010

 

Así, con esta fórmula podemos hacer un SynthDef creando argumentos para el mínimo y el máximo del rango en el control de una frecuencia:

 

s.quit;

s=Server.local.boot;

 

(

SynthDef(\controlNoise, {|gate=1, freq=10, min=20, max=20000, amp=1|

  var control, mul, add, sig, env;

  mul=(max-min)/2;

  add=mul-min;

  control=LFNoise2.kr(freq,mul,add);

  sig=SinOsc.ar(control,0,amp);

  env=EnvGen.kr(Env.asr(2,1,2),gate,doneAction:2);

  Out.ar(0,sig*env);

  }).send(s)

)

 

n=Synth(\controlNoise)

n.set(\freq, 10, \min, 10, \max, 3000)

n.set(\gate, 0)

 

//TAREA: Crea tu propio SynthDef para mostrarlo en la próxima clase!

Creative Commons License
Taller de SuperCollider Básico by https://basicsupercollider.wordpress.com is licensed under a Creative Commons Attribution-Noncommercial 2.5 Mexico License.1)}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: