Introduccion a Chuck

Inicialmente esta página servirá para colgar pequeños patches de chuck comentados en español que mas adelante serán usados para hacer talleres y enseñar.


JustKey

lo mínimo necesario para cargar el teclado y recibir respuestas impresas en la consola.
Hid entrada;
HidMsg mensaje;
0 => int device;
if( !entrada.openKeyboard( device ) ) me.exit(); //activar el teclado

while (1::samp => now){

entrada => now;
while (entrada.recv(mensaje))
{
if(mensaje.isButtonDown())
{
«< "printme" »>;
}
if(mensaje.isButtonUp())
{
«< "offit" »>;
}
}
}


lfo lfo osc LPF

un LFO controla la frecuencia del oscilador. Otro LFO a su vez controla la frecuencia del primer LFO. Comparar con el ejemplo siguiente "envosc"

SawOsc s => LPF f=> dac;
SinOsc lfo1 => blackhole;
SinOsc lfo2 => blackhole;
// set the frequency of the lfo2
.1 => lfo2.freq;
// set the Q of the filter
10 => f.Q;
.15 => s.gain;
while (1::samp => now){
( lfo1.last() * 300) + 400 => f.freq;
( (lfo2.last() + 1)*5) + .2 => lfo1.freq;
}


envosc

Este sencillo patch introduce el objeto 'step', que es el mecanismo utilizado para generar las envolventes que se encuentran corriendo en parches paralelos que van al 'blackhole'. Es de notar la diferencia entre asignar un LFO a la frecuencia del oscilador y una envolvente a la frecuencia del oscilador: si usamos envolventes necesitamos 'step' si usamos lfo no. Revisar este thread para ver detalles.

SinOsc s => dac;
220 => s.freq;

Step stp => Envelope e => blackhole;
// valor del step
1 => stp.next;
// valor de la envolvente igual al valor de la freq del oscilador (220)
s.freq() => e.value;
// valor final de la envolvente (220 *2 = 440)
s.freq() * 2 => e.target;
// tiempo que tarda la envolvente para llegar a 440 en segundos
10 => e.time;

// activar
e.keyOn();

while (20::ms => now){
e.last() => s.freq;
}


envfilter

Modificación de un filtro usando una envolvente que va al 'blackhole' y que es activada mediante 'step'

SawOsc s => LPF f => dac;
220 => s.freq;

Step stp => Envelope e => blackhole;
// valor del step
1 => stp.next;
// valor de la envolvente igual al valor de la freq del oscilador (220)
s.freq() => e.value;
// valor final de la envolvente (220 *2 = 440)
s.freq() * 8 => e.target;
// tiempo que tarda la envolvente para llegar a 440 en segundos
5 => e.time;
//ganancia del oscilador
s.gain(.2);

// activar
e.keyOn();

while (20::ms => now){
e.last() => f.freq;
}


kb

Este patch nos enseña a seleccionar un teclado, y a usar el objeto 'envolvente' para prender y apagar una onda senoidal usando el teclado del computador. Un patch muy básico, pero que sirve como una introducción al lenguaje. Nótese que el parámetro para abrir y cerrar la envolvente es el mismo '.keyOn' pero que lo usamos con 1 para prender y con 0 para apagar.

//name: kb
Hid entrada; //declarar lo que entra en 'entrada'
HidMsg mensaje; //guardarlo en mensaje

0 => int device; //seleccionar un teclado (el 0) guardarlo en 'device'
if( !entrada.openKeyboard( device ) ) me.exit(); //activar el teclado

//El patch
SinOsc o1 => Envelope e1 => dac;
200 => o1.freq;
0.020 => e1.time;

while (20::ms => now){ //loop infinito refrescado cada 20ms
entrada => now;
while( entrada.recv( mensaje ) ) //cuando 'entrada' reciba un 'mensaje'
{
if( mensaje.isButtonDown() )
{
«< "down:", mensaje.which, "(code)", mensaje.key, "(usb key)", mensaje.ascii, "(ascii)" »>;
1 => e1.keyOn; //enviar un valor 1 a la envolvente'e1'
}
if(mensaje.isButtonUp())
{
«< "up:", mensaje.which, "(code)", mensaje.key, "(usb key)", mensaje.ascii, "(ascii)" »>;
0 => e1.keyOn; //enviar un valor 0 a la envolvente 'e1'
}

}
}


kbtoosc

Este patch es derivado de kb.ck pero lo que hace es que nos permite usar el número de cada tecla del teclado para usarlo como si fuera un número MIDI. Para esto usamos la siguiente función: **(Math.pow(2,(mensaje.which * 0.0833333)))*25.9565777=> ff **.

Hid entrada; //declarar lo que entra en 'entrada'
HidMsg mensaje; //guardarlo en mensaje

0 => int device; //seleccionar un teclado (el 0) guardarlo en 'device'
if( !entrada.openKeyboard( device ) ) me.exit(); //activar el teclado

El patch
SinOsc o1 => Envelope e1 => dac;
200 => o1.freq;
0.020 => e1.time;
float ff;

while (20::ms => now){ //loop infinito refrescado cada 20ms
entrada => now;
while( entrada.recv( mensaje ) ) //cuando 'entrada' reciba un 'mensaje'
{
if( mensaje.isButtonDown() )
{
(Math.pow(2,(mensaje.which * 0.0833333)))*25.9565777=> ff; //mensaje.which a freq como si fuera MIDI
ff => o1.freq; //enviar ff a la frecuencia del osc
«< "number:", mensaje.which,"frequency:",ff »>; //imprimir el
1 => e1.keyOn; //enviar un valor 1 a la envolvente'e1'
}

if(mensaje.isButtonUp())
{
«< "up:", mensaje.which, "(code)", mensaje.key, "(usb key)", mensaje.ascii, "(ascii)" »>;
0 => e1.keyOn;
enviar un valor 0 a la envolvente 'e1'
}

}
}


JoystickEnvolvente

// name: JoystickEnvolvente
// Basado en el patch de Spencer Salazar aprendemos a usar .envelope
// para hacer triggers de audio cuando se presione cualquier botón
// del joystick. Buscar las notas en "e.KeyOn()" y "e.KeyOff()" que se usa
// para iniciar y finalizar la envolvente.
// Para entender el código:
// Buscar cuando se le asignan valores a 'e' como en 'e.duration' o 'e.gain'.
// Revisar cuando las variables ao, a1 y a2 reciben valores.
// Revisar en la función de final "fun" como se asignan valores a las variables
// de la síntesis FM.

0 => int device; // Si hay varios joysticks conectados se puede seleccionar
if( me.args() ) me.arg(0) => Std.atoi => device; // get from command line

// patch: modulador>carrier>envolvente>reverb>dac
SinOsc m => SinOsc c => Envelope e => PRCRev g => dac;

220 => c.freq; // carrier frequency
550 => m.freq; // modulator frequency
1000 => m.gain; // index of modulation
2 => c.sync; // (0)sinc freq al input, (1)sync fase to input, (2)fm synth
.5 =>g.gain; // ganancia de la reverb

10::ms => e.duration; // duración de el ataque y el release
.5 => e.gain; //gain no aparece entre los parámetros de Envelope

// variables
int boton;
float a0;
float a1;
float a2;
int count; //contador de veces que se unde un botón

set( boton, a0, a1, a2 ); // start things¿¿¿¿????

// hid objects
Hid hi;
HidMsg msg;//Todo lo que reciba del joystick lo guarda en 'msg'

// trata de conectar el joystick
if( !hi.openJoystick( device ) ) me.exit();
«< "joystick '" + hi.name() + "' ready…", "" »>;

while( true )// crea un loop infinito
{
hi => now; // esperar hasta que reciba info de 'hi'
while( hi.recv( msg ) ) // mientras 'hi' reciba cualquier mensaje

{
if( msg.isAxisMotion() )//si el mensaje es 'movimiento del eje'
{
//dependiendo del número de elemento del mensaje 'msg', asignar a las
//diferentes variables el valor de 'msg'. Así podremos separar los
//valores de cada eje de movimiento y asignarlos a sus correspondientes
//receptores a1,a2,a3
if( msg.which == 0 ) msg.axisPosition => a0;
else if( msg.which == 1 ) msg.axisPosition => a1;
else if( msg.which == 2 ) msg.axisPosition => a2;
set( boton, a0, a1, a2 );
}

else if( msg.isButtonDown() )
{
msg.which => boton;asignar a 'boton' el número del elemento de 'msg'
count++;
sumar cada que se unde un botón
if( count == 1 ) e.keyOn();//
set( boton, a0, a1, a2 );
}

else if( msg.isButtonUp() )// apagar la env
{
msg.which => boton;asignar a 'base' el número del elemento de 'msg'
count—;
if( !count ) e.keyOff();
apaga la env si el contador se resetea
}
}
}

// enganchar los valores del joystick con el modulador(m) y el carrier(c)
fun void set( int boton, float a0, float a1, float a2 )
{
( 500 + 5*boton + ( 500 * a0) ) => m.freq;// frecuencia del modulador
( 220 + (220 * a2) ) => c.freq; // frecuencia del carrier
( 1000 * (a1+1) ) => m.gain; // cantidad de la modulación
//«< "carrier:", c.freq(), "modulator:", m.freq(), "index:", m.gain() »>;
«< boton, a0, a1, a2 »>;
}


Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License