<< Chapter < Page Chapter >> Page >

Si imponga un inviluppo di ampiezza sulla oscillazione generata, come se a vibrare fosse una corda vincolata alleestremità.

Quella che segue è la soluzione a [link] con i vincoli aggiunti agli estremi: int B = 256; // lunghezza di tabella (risoluzione) int R = 20; // ratefloat f = 1.1; // frequenza in cicli al secondo float[]buf = new float[B];int HEIGHT = 128; // altezza della finestra float amp; // ampiezza della oscillazionefloat readPoint; // posizione orizzontale della cresta float decayFactor = 0.92; // fattore di decadimento dell'ondafloat tempo; float ampli=0;void setup() { size(B,HEIGHT);stroke(255); strokeWeight(2); for (int i = 0; i<buf.length; i++) buf[i] = sin(2*PI*(float)i/buf.length);} void mousePressed() {tempo = millis(); }void mouseReleased() { tempo = millis() - tempo; println(tempo);f = 500/tempo; }void draw() { background(0);if ((mouseX>= 0)&&(mouseX<B)&&(mousePressed)) { amp = 2*(HEIGHT/2 - mouseY)/float(HEIGHT);readPoint = mouseX;} for (int i = 0; i<buf.length; i++) { if (i<readPoint) ampli += 1/(float)readPoint; else ampli -= 1/(float)(B - readPoint);point(i, HEIGHT - HEIGHT/2 - HEIGHT/2*amp*ampli*buf[(i - round(readPoint) + B/4 + B)%B]);} ampli = 0;amp = decayFactor*amp; readPoint = (readPoint + (f*B/R))%B; // incremento dell'oscillatore}

Si renda l'oscillazione più fluida sostituendo l'arrotondamento ( round() ) con l'interpolazione lineare.

Oscillazioni video

L'oscillatore tabellare può essere la struttura di riferimento anche per ripetizioni cicliche, a frequenza controllabile, diframmenti video. In questo caso la tabella da leggere ciclicamente contiene una sequenza di immagini.

Iterazione di frammento video

In questo esempio, quando si manda in esecuzione il programma un frammento di 4 secondi di video viene ripresodalla videocamera a 16 frame al secondo. Poi tale frammento è riprodotto ciclicamente a 20 frame al secondo, con lapossibilità di controllare la velocità di riproduzione (frequenza di oscillazione) cliccando in diverse posizioniorizzontali del mouse. import processing.video.*;Capture myCapture; int captureRate = 16;float f=1; int B = 64;int R = 20; PImage[]sequenza = new PImage[B];int i; float j=0;float inc = f*B/R; boolean via = false;void setup() { for (int i=0; i<B; i++) sequenza[i]=loadImage("vetro.jpg"); // immagine dummy, per inizializzaresize(200, 200); String s = "IIDC FireWire Video";myCapture = new Capture(this, width, height, s, 30); myCapture.frameRate(captureRate);frameRate(R); }void mousePressed(){f = float(mouseX)/width; inc = f*B/R; }void draw() { if (!via) {if(myCapture.available()) { // Reads the new framemyCapture.read(); sequenza[i].copy(myCapture,0,0,myCapture.width,myCapture.height,0,0,sequenza[i].width,sequenza[i].height); i = (i+1)%B;println(i); if (i==0) via = true;} }if (via) { image(sequenza[floor(j)], 0, 0,200,200);j = (j+inc); if (j>=B) j=j-B; }}

Oscillazioni nel visual programming

Nel visual programming le oscillazioni tabellari spesso si costruiscono utilizzando un segnale sawtooth che consente di percorre ciclicamente gli indici dell'array, ad una velocità dipendente dalla frequenza del segnale stesso.

In questo patch sono dichiarati due array onda1 e onda2 di 64 elementi ciascuno. Il segnale a dente di sega viene generato ad una frequenza di 139 cicli alsecondo. Il suo range viene moltiplicato per 64 in maniera da occupare tutto il campo degli indici (da 0 a 63) dell'array onda1 . Ogni volta che si preme il bottone di bang , 64 campioni del segnale prodotto dalla lettura della tabella onda1 vengono scritti nella tabella onda2 . Il segnale prodotto dalla lettura ciclica della tabella onda1 è udibile attraverso conversione da digitale ad analogico ( dac~ ). Si noti che in Pd tutti gli operatori che hanno il simbolo ditilde lavorano in maniera sincrona ad audio rate, e quindi la lettura dalla tabella onda1 fornisce campioni al sample rate di funzionamento (per default 44100 Hz). Si notianche la scalinatura del segnale scritto nella tabella onda2 , dovuto alla lettura non interpolata dei campioni di onda1 .

Come si può evitare la scalinatura nella forma d'onda prodotta dall'oscillatore tabellare di [link] ?

Basta sostituire tabread~ con tabread4~ , in questo modo facendo una lettura interpolata di ordine 3. In altri termini, l'interpolatorefa passare un polinomio di terzo grado (una cubica) per quattro punti contigui della tabella.

Ritardi variabili

Nei sistemi interattivi c'è spesso la necessità di ritardare nel tempo un segnale, un processo, o un evento. Ad esempio, seci sono più flussi di video o audio in streaming, ciascuno viaggiante su canali indipendenti per i quali non è possibileavere lo stesso tempo di propagazione da trasmittente a fruitore, è opportuno ritardare diversamente ciascun flusso inmaniera da avere un riallineamento ed una sincronizzazione in ricezione. In campo audio, le linee di ritardo a lunghezza variabile sono alla base di molti effetti , quali sono echi e riverberazione.

La struttura di supporto per la realizzazione delle linee di ritardo è il buffer circolare, cioè un array ai cui elementisi accede con aritmetica circolare dei puntatori. In particolare, c'è una variabile IN , chiamata puntatore di ingresso, che contiene l'indice dell'elementodell'array nel quale si va a scrivere. Una variabile OUT , chiamata puntatore di uscita, contiene l'indice dell'elemento dell'array dal quale si va aleggere. Si tratta di incrementare i puntatori di accesso in maniera circolare, mantenendo la loro distanza relativa parial numero di passi temporali di cui si vuole che sia fatto il ritardo. Ad ogni passo temporale (o istante di campionamento)il segnale di ingresso è scritto nella locazione puntata da IN e letto dalla locazione puntata da OUT , D passi indietro. Quindi, i due puntatori sono aggiornati con le operazioni IN = (IN + 1) % B; OUT = (OUT + 1) % B; dove B è la lunghezza del buffer, scelta in maniera da essere maggiore del più grande valore di ritardo D che si intende usare. Il ritardo D può variare dinamicamente, ad esempio oscillando tra un minimo ed un massimo, ma è chiaro che se esso assume un valore nonintero bisognerà adottare una strategia di interpolazione per la lettura del segnale ritardato. Ad esempio, si può ancorauna volta fare interpolazione lineare tra locazioni adiacenti, oppure scegliere l'intero immediatamente inferiore a D .

Si costruisca un programma Processing che legge caratteri dalla tastiera e nefornisce una eco sulla finestra grafica con un ritardo crescente mano a mano che si aggiungono linee di testo.

PFont font;int B = 1000; int INTERLINEA = 30;int xpos=0, ypos=INTERLINEA; char[]buffer = new char[B];int OUT = 0; int IN = 0;int D = 0; char carattere;char inchar = '\0'; void setup() {size(800,800); font = loadFont("Courier-48.vlw");textFont(font, 32); frameRate(30);} void keyReleased() {inchar = key; }void draw() { if (inchar=='\n') {D+=10; IN = (OUT + D)%B;xpos = 0; ypos += INTERLINEA;inchar='\0'; }else { buffer[IN] = inchar;carattere = buffer[OUT];text(carattere, xpos, ypos); xpos += textWidth(carattere);IN = (IN + 1)%B; OUT = (OUT + 1)%B; }inchar = '\0'; }

Get Jobilize Job Search Mobile App in your pocket Now!

Get it on Google Play Download on the App Store Now




Source:  OpenStax, Programmazione di artefatti interattivi. OpenStax CNX. Dec 09, 2010 Download for free at http://cnx.org/content/col10417/1.9
Google Play and the Google Play logo are trademarks of Google Inc.

Notification Switch

Would you like to follow the 'Programmazione di artefatti interattivi' conversation and receive update notifications?

Ask