Skip navigation

Monthly Archives: Abril 2009

hoje introduzimos o openframeworks. primeiro configuramos os compiladores e as pastas do openframeworks, revemos as noções de programação com objectos em java no processing, e exemplificamos algumas aplicações feitas com o openframeworks.

configuração dos compiladores

as páginas de setup dos compiladores da equipa do openframeworks são claras e devem ser seguidas passo a passo com atenção. nos pc’s instalamos o codeblocks com mingw, e nos mac’s o xcode.

para ‘instalar’ o openframeworks, basta descarregar o ficheiro da nossa plataforma (006 xcode fat para mac e 006 codeblocks fat para windows), descomprimi-lo e mover a pasta para uma directoria de trabalho à nossa escolha. o que é importante é manter a estrutura de directorias das pastas dentro da versão of que descarregam:

of006/addons/
of006/apps/
of006/libs/
of006/other/

os nossos projectos para compilar consistem apenas do src folder. vamos ter de copiar um projecto dos exemplos do openframeworks.

primeiro temos de criar uma directoria de trabalho dentro da estrutura do openframeworks. criei a directoria apps/somdopensamento/. de seguida copiamos os ficheiros da sessão para dentro desta directoria. os ficheiros trazem uma pasta com o nome do projecto, e uma subpasta src que tem o source code. mas ainda faltam os projectos. este passo é importante, só assim os projectos estarão correctamente configurados para compilação. primeiro copiamos um projecto dos exemplos ou dos addons (se usarmos addons), das pastas nativas apps/examples, apps/addons. (em apps/examples/emptyexample, no xcode copia-se openFrameworks.xcodeproj e openFrameworks-Info.plist, no codeblocks copia-se apps/examples/emptyexample/openFrameworks.cbp). agora as nossas pastas dentro de apps/somdopensamento devem ter os projectos duplicados dos exemplos e uma subpasta ‘src’ que tem os ficheiros .h e .cpp onde está declarado o código c++ que tentamos compilar.

para a configuração dos project files nos compiladores, antes de a iniciarem, devem ter algo como

of006/apps/somdopensamento/sp15_circulo/src/main.cpp
of006/apps/somdopensamento/sp15_circulo/src/testApp.cpp
of006/apps/somdopensamento/sp15_circulo/src/testApp.h
of006/apps/somdopensamento/sp15_circulo/openFrameworks.xcodeproj
of006/apps/somdopensamento/sp15_circulo/openFrameworks-Info.plist

(para os pc’s é semelhante, copiamos o ficheiro de projecto codeblocks que está nos exemplos para este local)

abre-se o projecto no xcode ou codeblocks, e na área de browser do projecto, primeiro removemos todos os ficheiros que lá estão, depois introduzimos os ficheiros .h e .cpp que fazem parte do nosso projecto (no mac arrastam-se os ficheiros para a subpasta src no browser do projecto do xcode, no pc seleciona-se o projecto com o botão do lado direito e selecciona-se add files..). após este passo final, devemos ter o projecto configurado e pronto para o próximo passo, que corresponde à compilação do código fonte, corrigir eventuais erros devolvidos pelo compilador, e ligações às várias bibliotecas de código (linker) que se usam (opengl, opencv, rtaudio, freetype, etc, etc). para compilarmos há-de haver uma opção para build and run.

após a compilação deve surgir dentro da pasta do nosso projecto um ficheiro binário executável na nossa plataforma que corre o código exemplo simples da criação de um círculo que segue o rato.

oop (object oriented programming)

semelhante ao primeiro exemplo do processing, fomos passar as variáveis necessárias à criação de um circulo dentro de uma class, com variáveis e funções. em c++ a definição de classes é muito semelhante ao processing, apenas temos de em conta dois passos importantes.

o primeiro é a inclusão do header apenas uma vez, através das directivas #ifndef CIRCULO_H, #define CIRCULO_H e #endif. a outra noção é terminar a declaração da class no header com um ‘;’ após as chavetas ‘}’ que terminam a declaração da classe.

este é o header da class circulo, e a seguir o ficheiro cpp da mesma class.

15-classh

15-classcpp

no testApp.h, o local onde começamos a programar a nossa função, em vez de termos variáveis float posx, posy, rad como no primeiro exemplo, temos agora um objecto circulo do tipo Circulo que definimos nos ficheiros circulo.h e circulo.cpp anteriores.

15-browser-circulo-class

a função update da testApp no ficheiro testApp.cpp chama a go_mouse(); e a draw simplesmente desenha o circulo no ecran

void testApp::draw(){

ofBackground(58,95,83);

circulo.draw();

}

devemos ver isto.

15-circulo

um segundo exemplo cria uma array de objectos Circulo e todos eles chamam a draw e fazem o update das coordenadas em relação ao rato.

15-circulos

o terceiro exemplo mostra como ter um apontador para objectos de um tipo que nós definimos, class Part, no testApp.h declaramos

Part *p; // um pointer para partículas

int num_p; // o número de partículas

e alocamos memória para o apontador na função

void init_n_parts(int num);

que é declarada no ficheiro testApp.cpp desta forma:

void testApp::init_n_parts(int num){ //pedimos memória para o apontador com tamanho para array com num elementos p = new Part[num]; num_p = num; float w = ofGetWidth()/2.0f; float h = ofGetHeight()/2.0f; for(int i=0; i<num;i++){ float x = w+ofRandom(-100,100); float y = h+ofRandom(-100,100); p[i].init(x,y); } } 15-parts

o quarto exemplo é um port do starfield que vimos como exemplo inicial 3d em processing. aqui o mais importante é o uso de um apontador dentro da class Star que aponta para um valor dentro da testApp, que será igual para todas as estrelas. o apontador é inicializado na função testApp::setup() e a partir desse momento podemos escrever o mesmo valor global para cada estrela.

15-starfield

o quinto exemplo é um exemplo de computer vision, onde exploramos algumas técnicas de identificar blobs nas imagens e tentar usar os dados para representar objectos. já é um exemplo mais complexo, onde criamos um objecto class ComputerVision que vai iniciar a câmara e fazer um tracking de blobs usando o addon ofxOpenCv, que coloca à nossa disposição a biblioteca opencv da intel.

15-blosc

Anúncios

a sessão de hoje foi dedicada ao arduino. revimos noções base de ligar sensores ao arduino; analisámos modos de leitura de maior precisão; ligação de piezos (besouros / buzzers / contact mics) como input de pressão/contacto ou output de tons sonoros; ligação de motores e controlo de velocidade; mistura de circuitos 5v com circuitos de maior potência.

1. leitura melhor precisão

no lado do arduino colocamos um sensor, e enviamos o valor através do modo DEC. este modo envia cada dígito que compõe o valor em caracter ascii. imediatamente a seguir escrever um caracter new line(\n = 10,13 ascii) que funciona como caracter de controlo identificador do fim do número.

14-arduino_ldr_6203

assim, do lado do pd ou processing ou outro programa, abrimos ligação à porta série do arduino, lemos cada caracter ascii, convertemos em representação numérica, e finalmente eliminamos os espaços para agrupar o número final. este último passo apenas é realizado quando chega o caracter de controlo.

2. piezos

as chapas de cerâmica dos buzzers, além de poderem servir como microfones de contacto, podem ser utilizadas ainda como um sensor de pressão/toque, ou como emissor de tons.

14-arduino_piezo_7315

para funcionarem como sensores, conectamos a cabo preto ao ground e o vermelho à entrada analógica do arduino, e lemos os valores que chegam à porta analógica.

14-arduino_tocar_piezo_10426

para funcionarem como colunas, basta alterar o cabo vermelho para uma porta de saída pwm do arduino, e fazer o upload do código que emite tons para o piezo.

14-arduino_lerpiezo_9490

3. motores

começamos com motores dc de 5v, com algum cuidado podemos ligar directamente ao arduino. com algum cuidado porque costumam enviar picos de corrente em sentido inverso quando desligamos a voltagem. para prevenir esta situação usamos diodos, que bloqueiam a passagem da corrente em sentido inverso.

os motores dc têm 2 pins, um para ground, outro para voltagem. se trocarem a ordem alteram a direcção de rotação. há pontes h para fazer as duas direcções.

14-arduino_motores5v_0941

4. circuitos com ac

é muito comum usar-se o arduino como circuito de controlo de circuitos que requerem mais voltagem e mais intensidade de corrente, além de que já são perigosos, podem queimar o arduino e o computador se as coisas estiverem mal feitas.

como exemplo, ligamos uma ventoinha de 12v e colocamos um potenciómetro a controlar a velocidade da ventoinha. para tal, alimentamos a ventoinha com corrente vinda dum transformador 12v que passa num potenciómetro e escala a voltagem de saída. ainda vimos mais usos com relés, diodos, condensadores e de que formas controlamos aparelhos num circuito mais pesado através das saídas digitais e analógicas do arduino.

14-arduino_ventoinha12v_1232

hoje vemos mais processos áudio de síntese, e iniciamos arduino com dois sensores ligados a um patch de som e um sketch de processing.

1. audio
os patches que analisamos são quase todos do pd-extended, e acedem-se melhor através do browser do pd (menu help > browser ou maçã/ctrl+b). dentro do browser, são tudo exemplos de audio (help browser > 3.audio.examples > c08.etc)

começamos com emulação de sintetisador analógicos, e fomos ver mais patches de samplehold, síntese aditiva, vibrato, complex fm, delay loops e resíntese por fft. aqui ficam algumas imagens dos patches a correrem.

13-c8

13-complexfm1

13-delayfeedback

 

13-fft-resintese

 

 

2. arduino

o arduino é um aparelho que digitaliza o mundo analógico, ou para ele envia voltagens, através do protocolo série (rs-232). hoje vamos ligar dois sensores às portas analógicas do arduino; fazemos um mini-programa no chip do arduino que lê os valores dos sensores e os envia para o computador; por fim criamos um patch e um sketch que lêem os valores e fazem coisas simples, dois osciladores, e dois quadrados.

usamos um LDR, que é uma resistência variável foto-voltaica, e um knob, um potenciometro (ou pot), que também é uma resistência variável, e faz variar a resposta voltaica dos sensores que vamos ler para fazer interagir esses dados.

do arduino fazemos conexões do +5v e do ground para as fileiras horizontais da breadboard. um pin do ldr entra directamente num dos pins de +5v da fileira da breadboard; o outro pin liga-se a uma fileira horizontal. da fileira horizontal da breadboard lemos o sinal para uma das portas analógicas do arduino e finalizamos a ligar uma resistência do fim da fileira para a linha de ground da fileira horizontal da breadboard.

o potenciómetro é mais simples, visto que já tem 3 pins; os exteriores ligam-se aos +5v e ao ground, e ligamos o pin do meio a uma porta analógica do arduino.

13-arduino_4496

depois criamos os programas no arduino ide, e fazemos upload para o chip atmega168 do arduino; o código começa logo a funcionar no chip e a correr os programas que  se seguem. usamos duas versões, um lê um sensor apenas, e outra lê dois valores analógicos:

/// arduino ler um sensor
int valor = 0; // variavel para o valor
int pin = 5; // variavel para o pin de entrada do valor

void setup() {
// open the serial port at 9600 bps:
Serial.begin(9600);
digitalWrite(13,HIGH); //turn on led
}

void loop() {
// ler o valor do pin
valor = analogRead(pin);
// escrever para a porta série o valor
Serial.print(valor, BYTE);
// esperar 10 ms próxima leitura
delay(10);
}

 

/// arduino ler dois sensores
// aqui enviamos um caracter que sincroniza
// no fim da mensagem

int valorldr = 0;
int valorpot = 0;
int pinldr = 5;
int pinpot = 3;

void setup() {
// open the serial port at 9600 bps:
Serial.begin(9600);
digitalWrite(13,HIGH); //turn on led
}

void loop() {
// ler os valores do pin
valorldr = analogRead(pinldr);
valorpot = analogRead(pinpot)/4;
// escrever para a porta série a mensagem
Serial.print(valorldr, BYTE);
Serial.print(valorpot, BYTE);
Serial.print(9); // tab = 9 ascii
// esperar 10 ms próxima leitura
delay(10);
}

 

do lado físico as coisas já estão finalizadas: os valores dos sensores já são enviados para o computador. agora precisamos de os ler. no pd usamos o [comport], um objecto que lê tudo o que chega através de série, no processing fazemos o import da serial lib, configuramos a porta e lemos a data. aqui ficam algumas imagens dos patches e sketches que criámos para começar a ler os valores e brincar com eles. na próxima semana vamos rever esta introdução ao arduino e introduzir actuação física com alguns motores.

13-sensor1

 

13-sensor21

13-p5sensor2

a sessão 12 foi em torno de noções de síntese e manipulação de áudio.

analisámos processos de reprodução e manipulação de ficheiros de áudio, entradas dinâmicas de som em tempo-real, alguns processos de síntese sonora, e ainda alguns processos mais avançados como compressão/expansão temporal na reprodução de um som sem lhe alterar o pitch, phase vocoding através de fft. 

no final, misturamos os processos num único patch, e fizemos variar alguns parâmetros de alguns efeitos, e testámos a gravação de samples directamente para o disco do computador.

 

aqui ficam os tópicos e imagens dos patches que analisamos hoje:

1. inputs, outputs, sample rate, placas de som, midi in/out

input/output som no pd (menu media >  portaudio) neste menu podemos configurar a placa de som, a sample rate a que a cadeia de som funciona, os canais de entrada e saída de som.

12-portaudio

 

no mesmo menu (menu media >  test audio and midi)

abre um patch que testa e analisa o som e midi

12-testaudiomidi

 

 

2. audio playback

12-samples

 

 

3. objectos gráficos gui

os objectos gráficos do pd extented

12-gui_obj

 

4. síntese aditiva / ring modulation / fm

12-ringmod

 

 

5. time compression/expansion

12-timecompexp

 

 

6. filtragem de som

12-filtragem-som

 

 

7. phase vocoding /fft

12-phasevoc

 

 

8. reverb

12-reverb

programação em ambientes visuais. breve história, o patch, o metro, o bang, o toggle, o número, os sliders, e objectos de controlo de fluxo, como o gate, o switch, o select; objectos de sensores como as teclas no objecto key, o objecto  suddenmotionsensor que analisa a orientação dos portáteis mac; objectos de áudio, diferenças entre fluxos de controlo e fluxos de áudio.

 

1. introdução programação visual

o pd (puredata) surge da mente do miller puckette — e hoje em dia muitos mais outros developers espalhados pelo mundo — como a alternativa open source ao max/msp. o max foi iniciado no ircam em meados de 1980’s pelo miller puckette, e foi desenhado para ser usado por compositores, tentando simplificar a tarefa da compilação e sobretudo da programação de algoritmos que possam ser aplicados em tempo real ao som que é gerado por instrumentos. são ambientes de programação visuais, onde pequenos módulos (objectos) já se encontram compilados, apenas temos de os criar num patch, uma janela branca inicialmente vazia, e ligá-los uns aos outros através de patch cords  para criar qualquer tipo de programa. aqui estamos libertos da compilação do programa, o patch está sempre operacional, e pode ser editado à medida que corre. 

os módulos realizam tarefas de vários níveis, simples, como o caso dos bangs, toggles, números, e mais elaboradas como objectos áudio, o osc~ ,  44100 valores por segundo em forma de onda sinusoidal a determinada frequência são emitidos para outros objectos que manipulam ou expõem o áudio. 

todos os objectos têem um help files e os objectos gráficos (bang, toggle, sliders, num,…) têem propriedades que podem ser editadas. crtl+click ou butão direito do rato em cima de qualquer objecto, e seleccionar help ou properties. o help file tem informações das mensagens que o objecto recebe e uma curta explicação do seu funcionamento.

11-bang_properties

2. primeiros patches

há dois modos principais do programa: o modo de edição  e o de interacção ( maçã/ctrl+e , ou menu edit > edit mode). no de edição podemos criar novas caixas de objectos (através do menu put > object, ou maçã/ctrl+1) e depositá-las com um click algures na janela do patch. no de interacção, interagimos com os objectos que o permitem, interruptores, números, mensagens.

no modo de edição, escrevemos ‘metro’ na caixa e clickamos fora da janela. a caixa transforma-se de tracejada para uma caixa com 2 inlets e 1 outlet. clickamos novamente na caixa e a seguir a metro, espaço, 500. este 500 será o argumento em milisegundos para o objecto metro. este objecto emite bangs de x em x ms. em cima do metro colocamos um toggle (menu put > toggle) e já aparece um objecto gráfico distinto dos objectos. ligamos a outlet do toggle ao metro. colocamos um bang em baixo do metro e ligamos da outlet do metro à inlet do bang. passamos agora para o modo de interacção ( maçã/ctrl+e ou menu edit > edit mode) e clickamos no toggle. o toggle emite a mensagem ‘1’ que o metro recebe e interpreta-a ligando-se, emite bangs de meio em meio segundo.

11-bang

depois criámos mais dois objectos, um ‘random 127’ e um ‘counter 127’. estes recebem os bangs e geram números aleatórios até 126 ou contando de 0 a 127. para tal basta ligar do bang aos dois objectos, e de cada objecto a um número para observar os resultados.

11-p0_randomcounter

agora convertemos os resultados numéricos em pitchs de osciladores. estes resultados numéricos de 0-127 estão numa escala midi que é transformada em hz, a unidade da frequência dos osciladores. há um objecto ‘mtof’ que aplica internamente esta conversão. depois colocamos os objectos da cadeia de áudio. um osc~, um *~ que escala o volume do sinal, um dac~, digital to analogue converter, que emite o sinal de áudio para as colunas. notem que as cores das cordas áudio são diferentes das cores fluxo normal. isso indica que esses objectos comunicam entre si à sampling rate do funcionamento da cadeia de audio. o input output do áudio pode ser configurado no menu media > portaudio. e o ligar e desligar do processamento audio é realizado na window > pd window, a consola onde o programa vai escrevendo mensagens de erro ou coisas que nós printemos para lá (objecto print). aí, tem de se ligar o compute audio que liga internamente a compilação de todos os objectos áudio (objectos que terminam em til ~)

11-audio0

 

3. osciladores lfo e leitura de samples

um lfo é um oscilador que tem um centro numa  frequência e somamos a  esse valor outro oscilador que vai induzir uma oscilação de maior ou menor frequência e profundidade em torno da frequência fundamental.

11-lfo

para lermos ficheiros do disco ou lemos com o objecto readsf~, ou lemos para arrays, que são objectos do pd que armazenam o som na memória do computador. 

quando o som está nas arrays pode ser acedido através de outros objectos que os podem reproduzir à velocidade normal, ou fazer variar este valor.

11-readsf11-arraysom

4. delays

para fazer delays ao sinal áudio, há objectos que comunicam por nome, como é o caso da comunicação array / tabread4~. aí a array tem o nome soundarray e cada objecto tabread4~ tem como argumento soundarray. nos delays vamos ter o delwrite~ <nome do delay> <tempo máximo ms delay>. e depois podemos criar vários delread~ <nome do delay> <tempo de delay, entre 0 e tempo máximo>, cada um destes objectos lê a cadeia de som atrasada x ms. 

introduzimos aqui também a gravação de ficheiros de som para o disco e o uso de microfones do computador através do objecto adc~ , analogue to digital converter.

11-delays

5. comunicação pure-data <-> processing através de osc

criamos uma comunicação via localhost (morada ip: 127.0.0.1) entre o processing e o pd através de osc encapsulado em servidores udp. no pd precisamos dos objectos udpsend e udpreceive, e no processing da biblioteca oscp5. uma vez instaladas as bibliotecas ( a do processing, no pd-extended já temos os externos de rede), podemos criar uma ligação do pd para o processing e do processing para o pd. (quem diz pd, diz também max, of, etc). 

a ligação pd->processing vai para o ip da própria máquina, para a porta 12000. a ligação processing->pd vai para o mesmo ip para a porta 12001. o processing lê da porta 12000 e envia para a 12001, o pd lê da 12001 e envia para a 12000.

em cada um dos lados, verificamos o identificador da mensagem osc ( /audio, /b1, /x,…) e atribuímos a variáveis no programa que executam tarefas.

11-p5-pd

 

ainda vimos um último exemplo que correspondia à integração de audio em pd no sketch bolas e obstáculos 7 do processing. para tal, sempre que há lançamento de explosões enviamos uma mensagem osc do processing para o pd que despoleta a reprodução de samples.

11-pdprocessing-bolas