Operador ChucK
Talvez o conceito mais importante da linguagem ChucK seja o operador => que é chamado ChucK. Ele serve, de uma maneira geral, para conectar dois Unit Generators. Estes últimos podem ser imaginados como se fossem um fluxo (de leitura ou de escrita) de áudio.
Esta abstração permite uma maneira bem expressiva de denotar uma cadeia de síntese:
// conecta o oscilador s no dac (a saída de áudio)
SinOsc s => dac;
// conecta um oscilador de onda dente-de-serra
// no objeto Gain e depois no dac
SawOsc so => Gain g => dac;
// uma onda quadrada ligada num filtro
// mudando os parâmetros do filtro podemos
// fazer, por exemplo, síntese subtrativa
SqrOsc sq => Filter f => dac;
440 => sq.freq; //frequência da onda quadrada
200 => f.freq; //frequência de corte
Usando o operador ChucK podemos montar redes de geradores de sinal, de uma maneira muito similar aos sintetizadores modulares. Além disso o operador => é sobrecarregado para ser usado como atribuição de valores, como pode ser visto nos exemplos, o que deixa a sintaxe da linguagem mais agradável e consistente.
Unit Generators
Unit Generators ou UGens são geradores de função que emitem sinais que podem ser usados como áudio ou como sinal de controle para outros UGens. Em ChucK eles são versões especializados do UGen orginal e portanto podem ser manipulados por meio de alguns comandos comuns, como por exemplo gain, op, channels, chan ,last, freq e outros.
Por padrão são definidos três UGens: dac
, adc
e blackhole
que são respectivamente a entrada de som, a saída de som e um buraco negro que engole todo o sinal mandado para lá e não o repassa. Como visto na seção anterior, podemos conectar vários geradores entre si e a outros objetos para obter a cadeia desejada. Este sistema tem decorrências interessantes, como o código a seguir.
// conecta a entrada de som à sáida
adc => dac;
Poderíamos facilmente estender esse código para adicionar algum processamento entre as duas pontas e por exemplo falar algo no nosso microfone e ouvir o resultado nas caixas de som. De fato, vou demonstrar isso agora, gravando o som de uma guitarra.
Fluxo normal adc -> dac
// conecta a entrada de som à sáida
adc => dac;
2::week => now; // avança o tempo "indefinidamente"
Clique aqui para ouvir (arquivo .mp3)
Fluxo adc -> Filtro Passa Bandas -> dac
// mesma cadeia, mas agora com o filtro
adc => BPF filter => dac;
// editando os padrões do filtro
11 => filter.Q;
440 => filter.freq;
2::week => now; // avança o tempo "indefinidamente"
Clique aqui para ouvir (arquivo .mp3)
O efeito que foi aplicado é uma filtro que só deixa passar certas frequências intermediárias de uma onda, nesse caso centrei ele em 440Hz. Não é nada muito científico, só inventei uns parâmetros da minha cabeça aqui e testei. Parece o efeito que eu chamo de “som de telefone” por se assemelhar ao som que ouvimos quando falamos com alguém no (dãh) telefone. Algumas bandas usam umas versões mais complexas da técnica para dar uma tensão a mais. Veja aqui de 0:00 até 0:07 e ali à partir de 8:54 , por exemplo.
Isto demonstra de uma maneira bem simples como podemos construir cadeias de processamento usando o operador ChucK.