Gist para organizar links e referências que apresentei durante o encontro da Noite de Processing Montando uma Algorave com Python. Mais sobre o que faço pode ser visto aqui.
Precisamos ter instalado:
A instalação default do SuperCollider já instala o jackd
para controlar o trânsito do áudio no sistema. O SuperCollider vai nos fornecer um servidor responsável por gerar o som. Exemplo de código em SuperCollider:
// modulate a sine frequency and a noise amplitude with another sine
// whose frequency depends on the horizontal mouse pointer position
// and pink noise depends on the vertical
{
var x = SinOsc.ar(MouseX.kr(1, 100));
var y = SinOsc.ar(MouseY.kr(1, 100));
SinOsc.ar(300 * x + 800, 0, 0.1)
+
PinkNoise.ar(0.1 * y + 0.1)
}.play;
Para o código acima funcionar, precisamos executá-lo por completo. Para isso, use os atalhos Ctrl + A
para selecionar todo o conteúdo e Ctrl + Enter
para executá-lo. O som deve variar de acordo com a posição do ponteiro do mouse. Experimente alterar o código para obter outros resultados. Se quiser fazer com que o som pare, utilize o atalho de teclado Ctrl + .
.
Para que o SuperCollider entenda o que é enviado pelo FoxDot, é necessário executar o seguinte script:
FoxDot.start
Agora podemos abrir o FoxDot e utilizar a sua API.
Ainda não saiu um release novo do FoxDot suportando essa funcionalidade, mas no master
do Github já está disponível por conta deste PR que já está mergeado no branch. Portando, ainda é necessário instalar o FoxDot com:
$ pip install git+https://github.com/Qirky/FoxDot.git@master
O FoxDot utiliza o protocolo OSC para enviar as mensagens para o servidor do SuperCollider. Então, precisamos rodar um servidor OSC de dentro do nosso sketch no Processing.
Para o código abaixo funcionar, é necessário ter instalada a biblioteca oscP5
. O código abaixo é o template base para levantar e escutar o servidor:
add_library('oscP5') # imports oscP5 lib
oscP5 = None # OSC server's global variable
def setup():
size(900, 900)
global oscP5
oscP5 = OscP5(this, 12000) # create a new server runnint at 127.0.0.1 at port 12000
oscP5.addListener(MyOscListener())
loc = NetAddress('127.0.0.1', 12000)
def stop():
global oscP5
oscP5.dispose()
def draw():
pass
class MyOscListener(OscEventListener):
@staticmethod
def oscEvent(m):
args = m.arguments()
print args
Agora precisamos fazer o FoxDot enviar as mensagens OSC também para o nosso servidor que roda em 127.0.0.1:12000
. Para isso, abra o FoxDot. Nos menus da barra superior, vá em Help & Settings --> Open config file (advanced)
. Isso abrirá uma nova janela com o conteúdo do arquivo conf.txt
.
Dentro desse arquivo, precisamos ḿodificar as seguintes variáveis com os seguintes valores e depois reiniciar o FoxDot:
FORWARD_ADDRESS='127.0.0.1'
FORWARD_PORT=12000
Com isso, conseguimos ligar tudo e ao executar uma linha como b1 >> bass(0)
no FoxDot, o log do Processing deverá parecer com algo como:
/127.0.0.1:44577 | /s_new siiisisfsf
/127.0.0.1:44577 | /s_new siiisisfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsf
/127.0.0.1:44577 | /s_new siiisisf
/127.0.0.1:44577 | /g_new iii
/127.0.0.1:44577 | /s_new siiisisfsf
/127.0.0.1:44577 | /s_new siiisisfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsf
/127.0.0.1:44577 | /s_new siiisisf
Esses logs são as os argumentos usados nas mensagens OSC enviadas para o servidor do SuperCollider. Aí que estão todos os dados e números que podemos usar para controlar o comportamento do código processing. Mais sobre como o protocolo organiza essas mensagens podem ser encontradas na documentação do SuperCollider.
Um exemplo de tratamento de evento pode ser visto no snippet abaixo:
class MyOscListener(OscEventListener):
@staticmethod
def oscEvent(m):
global bass_freq
args = m.arguments()
if str(args[0]) == 'bass':
bass_freq = int(args[7])
Se quiser olhar um exemplo mais complexo de integração, dê uma olhada neste código processing.py que fiz para a Algorave de encerramento da PythonNordeste 2019.