<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE document PUBLIC "-//CNX//DTD CNXML 0.5 plus MathML//EN" "http://cnx.rice.edu/cnxml/0.5/DTD/cnxml_mathml.dtd">
<document xmlns="http://cnx.rice.edu/cnxml" xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:bib="http://bibtexml.sf.net/" id="None">
  <name>Media Representation in Processing</name>
  <metadata>
  <md:version>1.7</md:version>
  <md:created>2005/02/01 05:43:48 US/Central</md:created>
  <md:revised>2005/05/20 07:57:57 GMT-5</md:revised>
  <md:authorlist>
      <md:author id="drocchesso">
      <md:firstname>Davide</md:firstname>
      
      <md:surname>Rocchesso</md:surname>
      <md:email>Davide.Rocchesso@univr.it</md:email>
    </md:author>
      <md:author id="ppolotti">
      <md:firstname>Pietro</md:firstname>
      
      <md:surname>Polotti</md:surname>
      <md:email>polotti@sci.univr.it</md:email>
    </md:author>
  </md:authorlist>

  <md:maintainerlist>
    <md:maintainer id="drocchesso">
      <md:firstname>Davide</md:firstname>
      
      <md:surname>Rocchesso</md:surname>
      <md:email>Davide.Rocchesso@univr.it</md:email>
    </md:maintainer>
    <md:maintainer id="ppolotti">
      <md:firstname>Pietro</md:firstname>
      
      <md:surname>Polotti</md:surname>
      <md:email>polotti@sci.univr.it</md:email>
    </md:maintainer>
  </md:maintainerlist>
  
  <md:keywordlist>
    <md:keyword>color models</md:keyword>
    <md:keyword>coordinate system</md:keyword>
    <md:keyword>image representation</md:keyword>
    <md:keyword>sound representation</md:keyword>
    <md:keyword>translation and rotation</md:keyword>
  </md:keywordlist>

  <md:abstract>Introduction on how images and sounds are represented (including colors and coordinates) in processing (in Italian).</md:abstract>
</metadata>

  <content>
    <section id="elementi_visuali">
      <name>Elementi Visuali</name>

    <section id="coordinates">
      <name>Coordinate </name>
      <para id="coordinatep"> 
	L´elaborazione grafica in processing
	utilizza un sistema di coordinate cartesiane 3D, come
	rappresentato in <cnxn target="coordinatef"/>.
	<figure id="coordinatef">
	  <name>Sistema di coordinate</name>
	  <media type="image/png" src="coordinate.png">
	  </media>
	  <caption>Sistema di coordinate 3D in uso in processing</caption>
	</figure>
	  L´elaborazione di immagini bidimensionali si effettua agendo
	  sul piano X-Y, assumendo quindi la coordinata Z a zero.  La
	  funzione <code>size()</code> definisce la dimensione della
	  finestra di display e stabilisce quale <term>motore di
	  rendering</term> sarà utilizzato per disegnare su tale
	  finestra. Il motore di default è JAVA2D, cioè la libreria di
	  grafica bidimensionale di Java. Se si desidera operare sulle
	  tre dimensioni è necessario impostare il rendering P3D
	  (Processing 3D), particolarmente efficiente per la grafica
	  su web, oppure OPENGL, che consente di delegare alla scheda
	  grafica molte operazioni tipiche della grafica 3D.

	</para>
    </section>
    <section id="immagini">
      <name>Immagini</name>
      <para id="immaginip">
	In processing, una immagine può essere assegnata ad un oggetto
	di tipo <code>PImage</code>. La funzione
	<code>loadImage("myImage")</code> preleva il file (gif o jpg)
	<code>myImage</code>, contenente la codifica di una immagine,
	e restituisce in uscita il contenuto in pixel della immagine
	stessa, il quale può essere assegnato ad una variabile di tipo
	<code>PImage</code>. Il file <code>myImage</code> deve essere
	caricato nella cartella <code>data</code> della directory
	avente lo stesso nome dello sketch processing al quale si sta
	lavorando.  <note>Quando si esegue il comando
	<code>New</code>, processing apre una cartella di nome
	<code>sketch_???????</code>, all'interno di una directory
	<code>Processing</code>, corrispondente al nome
	assegnato dal sistema al file al quale si comincia a
	lavorare. Tale cartella è accessibile tramite i comandi del
	menu <code>File/Sketch</code> di processing.</note> La classe
	<code>PImage</code> rende accessibili, mediante i campi
	<code>width</code> e <code>height</code>, rispettivamente la
	larghezza e la altezza della immagine caricata. Il contenuto è
	invece accessibile mediante il campo <code>pixels[]</code>.
      </para>
      <example id="gondolieri_ex1">
	<name>Caricamento e visualizzazione di una immagine</name>
	<code type="block">
	  size(400,300);
	  PImage b;
	  b = loadImage("gondoliers.jpg");
	  println("width=" + b.width + " height=" + b.height);
	  image(b, 0, 0, 400, 300); // position (0,0); width=400; height=300;
	  image(b, 20, 10, 100, 80); // position (20,10); width=100; height=80;
	</code>
      </example>
    </section>
    <section id="colori">
      <name>Colori</name>
      <para id="colori_generalita">
        Poiché i nostri ricettori oculari di colore
        (<emphasis>coni</emphasis>), ciascuno sintonizzato su una
        regione di lunghezze d'onda, sono in numero di tre, i modelli
        di colore sono sempre riferiti ad uno spazio a tre
        dimensioni. Nei modelli di colore di tipo additivo vengono
        individuati tre assi coordinati, ciascuno corrispondente ad un
        colore base, e mediante miscelazione di tre corrispondenti
        fasci luminosi, si possono ottenere tutti i colori
        appartenenti ad un volume (<emphasis>gamut</emphasis>)
        individuato da tali assi. I tre colori base sono scelti in
        maniera arbitraria o, più spesso, sulla base del campo di
        applicazione (es., colore di una terna di fosfori o di
        laser). Nei processi di stampa si usano modelli di tipo
        sottrattivo, nei quali si parte da una superficie bianca e si
        usano inchiostri primari per sottrarre colore dal
        bianco. <note>Guida ai modelli di colore: <link src="http://en.wikipedia.org/wiki/color_space">
        http://en.wikipedia.org/wiki/color_space</link>
        </note>
      </para>
      <para id="color_type">
	In processing <code>color</code> è un tipo primitivo usato per
	specificare il colore. E' realizzato mediante un numero di 32
	bit, in cui il primo byte specifica il valore alpha, e gli
	altri byte successivi specificano una terna nel modello RGB o
	in quello HSB. La scelta di un modello piuttosto che
	dell'altro è fatta mediante la funzione
	<code>colorMode()</code>. I colori rappresentabili mediante
	tre byte sono in numero di 
	<m:math>
	  <m:apply>
	    <m:eq/>
	  <m:apply>
	    <m:times/>
	    <m:cn>256</m:cn>
	    <m:cn>256</m:cn>
	    <m:cn>256</m:cn>
	  </m:apply>
	    <m:cn>16777216</m:cn>
	  </m:apply>
	</m:math> .
      </para>
      <section id="rgb">
	<name>Modello RGB</name> 
	<para id="rgbp">
	  I colori si rappresentano con una terna di numeri, ciascuno
	rappresentante rispettivamente le intensità dei colori primari
	rosso (Red), verde (Green), e blu (Blue). Ciascun numero può
	essere un intero senza segno e quindi assumere valori tra 0 e
	255, oppure essere espresso come un numero floating point
	compreso tra 0 e 1.0. Queste possibilità possono essere
	specificate mediante la funzione <code>colorMode()</code>. Il
	modello RGB è di tipo additivo. </para>
      </section>
      <section id="hsb">
	<name>Modello HSB</name> 	
	<para id="hsbp">
	  I colori si rappresentano con una terna di numeri, ciascuno
	rappresentante rispettivamente la tinta o lunghezza d'onda
	dominante(Hue), la saturazione (Saturation), e l'intensità o
	brillantezza (Brightness).<note>Spesso il modello viene
	chiamato HSV, dove la V sta per Value.</note> La hue assume
	valori in gradi tra 0 (rosso) e 360, essendo le diverse tinte
	rappresentate lungo una circonferenza ed essendo il rosso
	convenzionalmente situato a <m:math> <m:cn>0</m:cn>
	<m:mtext>˚ </m:mtext> </m:math>. Saturation e
	brightness variano tra 0 e 100. La saturazione è il grado di
	purezza del colore. Se ad un colore pure viene aggiunta della
	luce bianca il suo grado di purezza diminuisce, fino a che il
	colore viene a trovarsi sulla scala dei grigi, in
	corrispondenza di saturazione nulla. In termini fisici, la
	brillantezza è proporzionale alla potenza spettrale. In
	termini intuitivi, la brillantezza aumenta con la intensità
	della luce. Lo spazio è ben rappresentato da un cilindro, con
	hue (scala nominale) arrangiata lungo la circonferenza,
	saturation (scala rapporto) arrangiata lungo il raggio, e
	brightness (scala intervallo) arrangiata lungo l'asse. Oppure
	si da una rappresentazione bidimensionale dello spazio, come
	nel <emphasis>color chooser</emphasis> del programma di
	elaborazione di immagini <link src="http://www.gimp.org">Gimp</link>, rappresentato in <cnxn target="gimp_color"/>. Lungo la circonferenza sono visibili i
	tre colori primari (rosso, verde, e blu), che distano di
	<m:math> <m:cn>360</m:cn> <m:mtext>˚ </m:mtext>
	</m:math> l'uno dall'altro, separati dai tre colori secondari
	(magenta, ciano, giallo). Ogni colore secondario è il
	complementare del colore primario che gli sta di fronte nella
	circonferenza. Ad esempio, se alla luce bianca si toglie la
	componente verde, si ottiene una luce magenta. Il triangolo
	inscritto nella circonferenza ha un vertice che punta alla
	tinta di riferimento. Il lato opposto a tale vertice è
	adagiato sulla scala dei grigi, e quindi rappresenta colori a
	saturazione nulla e brillantezza variabile. Andando dal
	vertice di riferimento al lato ad esso opposto si ha una
	graduale diminuzione della saturazione.
	<figure id="gimp_color">
	  <name>Gimp color chooser</name>
	  <media type="image/gif" src="gimp_color.gif">
	  </media>
	  <caption>Color chooser del software Gimp</caption>
	</figure>
	</para>
      </section>
      <section id="alpha">
	<name>Alpha channel</name> 
	<para id="alphap">
	  E' un byte di informazione usato per effettuare
	interpolazione tra immagini, ad esempio allo scopo di rendere
	la trasparenza. Esso si può ottenere, da una variabile di tipo
	<code>color</code>, con il metodo <code>alpha()</code>. La
	manipolazione dell'alpha channel si svolge mediante il metodo
	<code>blend()</code> della classe <code>PImage</code>.
	</para>
      </section>
      <example id="gondolieri_ex2">
	<name>Caricamento e visualizzazione di una immagine con trasparenza</name>
	<table id="gondolieri_table" frame="all">
	<tgroup cols="2" align="left" colsep="1" rowsep="1">
	<colspec colname="col1" colnum="1" colwidth="200"/>
	<colspec colname="col2" colnum="2" colwidth="260"/>
	<tbody>
	<row>
<!--	<entry><media type="image/tif" src="gondolieri.tiff">
		  </media>
	</entry> -->
	<entry><media type="image/gif" src="gondolieri.gif">
		  </media>
	</entry>
	<entry>
	<code type="block">
          <![CDATA[
size(400,300);
PImage b = loadImage("gondoliers.jpg");
PImage a = loadImage("gondoliers.jpg");
float ramp = 0;
for (int i = 0; i < b.height; i++)
  for (int j = 0; j < b.width; j++) {
      b.set(i, j, b.get(i,j) + 
      color(0,0,0,(int)(ramp*255)) );   
      ramp = ramp + 1/(float)(b.width * b.height); 
      }
a.blend(b, 0, 0, b.width, b.height,  
	80, 10, 450, 250, BLEND);
image(a, 0, 0, 400, 300);
          ]]>
	</code>
      </entry>
      </row>
      </tbody>
      </tgroup>
      </table>
      </example>
      <para id="conversione_modello_colore">
	In Processing, è possibile assegnare un colore ad una
	variabile di tipo <code>color</code> mediante la funzione
	<code>color()</code>, essendo il modello precedentemente stato
	definito mediante <code>colorMode()</code>. Le funzioni
	<code>red()</code>, <code>green()</code>, <code>blue()</code>,
	<code>hue()</code>, <code>saturation()</code>, e
	<code>brightness()</code> consentono di passare da un modello
	all'altro.
	<code type="block">
	  colorMode(RGB);
	  color c1 = color(102, 30,29);
	  colorMode(HSB);
	  color c2 = color(hue(c1), saturation(c1), brightness(c1));
	  colorMode(RGB);
	  color c3 = color(red(c2), green(c2), blue(c2));
	  // le variabili c1, c2, c3 contengono codifica dello stesso colore
	</code>
      </para>
      <section id="tinteggiatura">
	<name>Tinteggiatura di una immagine</name> 
	<para id="tinteggiaturap"> 
	Una immagine può
	essere tinteggiata con un colore e resa più o meno trasparente
	mediante assegnazione di un valore alpha. La funzione da usare
	a questo scopo è <code>tint()</code>. Ad esempio, per dare un
	tono blu all'immagine incastonata nel <cnxn target="gondolieri_ex1"/>, è sufficiente far precedere il
	secondo comando <code>image()</code> da <code>tint(0, 153, 204,
	126)</code> .
	</para>
     </section>
    </section>
    <section id="rotazioni_traslazioni">
      <name>Traslazioni, Rotazioni, e Trasformazioni di Scala</name>
      <para id="rappresentazione_punti">
	<name>Rappresentazione di Punti e Vettori</name> In computer
	graphics, punti e vettori sono rappresentati in <definition id="coordinate_omogenee"> <term>Coordinate Omogenee</term>
	<meaning>quaterne di numeri, in cui i primi tre vanno letti
	nello spazio X-Y-Z, mentre il quarto denota un
	<emphasis>vettore</emphasis> se assume valore 0, e denota un
	<emphasis>punto</emphasis> se assume valore 1.</meaning>
	</definition>
	Una traslazione si ottiene sommando, in coordinate omogenee,
	un vettore a un punto, ed il risultato è, ovviamente, un
	punto. Oppure, si può vedere la traslazione come un prodotto
	matrice-vettore, dove la matrice è
	<m:math>
	  <m:matrix>
	    <m:matrixrow>
	      <m:cn>1 </m:cn>
	      <m:cn>0 </m:cn>
	      <m:cn>0 </m:cn>
	      <m:ci><m:msub>
		  <m:mi>t</m:mi>
		  <m:mn>x</m:mn>
		</m:msub>
	      </m:ci>
	    </m:matrixrow>
	    <m:matrixrow>
	      <m:cn>0 </m:cn>
	      <m:cn>1 </m:cn>
	      <m:cn>0 </m:cn>
	      <m:ci><m:msub>
		  <m:mi>t</m:mi>
		  <m:mn>y</m:mn>
		</m:msub>
	      </m:ci>
	    </m:matrixrow>
	    <m:matrixrow>
	      <m:cn>0 </m:cn>
	      <m:cn>0 </m:cn>
	      <m:cn>1 </m:cn>
	      <m:ci><m:msub>
		  <m:mi>t</m:mi>
		  <m:mn>z</m:mn>
		</m:msub>
	      </m:ci>
	    </m:matrixrow>
	    <m:matrixrow>
	      <m:cn>0 </m:cn>
	      <m:cn>0 </m:cn>
	      <m:cn>0 </m:cn>
	      <m:cn>1 </m:cn>
	    </m:matrixrow>
	  </m:matrix>
	</m:math>, e il vettore è quello che rappresenta il punto
	<m:math>
	  <m:vector>
	    <m:ci>x</m:ci>
	    <m:ci>y</m:ci>
	    <m:ci>z</m:ci>
	    <m:cn>1</m:cn>
	  </m:vector>
	</m:math>.
	Una rotazione antioraria di un angolo <m:math>
	  <m:ci>θ</m:ci>
	</m:math>
 rispetto all'asse <m:math> <m:ci>z</m:ci> </m:math>
	  (<emphasis>roll</emphasis> o rollio), viene realizzata
	  mediante la matrice di rotazione
	<m:math>
	  <m:matrix>
	    <m:matrixrow>
	      <m:apply>
		<m:cos/>
		<m:ci>θ</m:ci>
	      </m:apply>
	      <m:apply>
		  <m:minus/>
		<m:apply>
		<m:sin/>
		<m:ci>θ</m:ci>
		</m:apply>
	      </m:apply>
	      <m:cn>0 </m:cn>
	      <m:cn>0 </m:cn>
	    </m:matrixrow>
	    <m:matrixrow>
	      <m:apply>
		<m:sin/>
		<m:ci>θ</m:ci>
	      </m:apply>
	      <m:apply>
		<m:cos/>
		<m:ci>θ</m:ci>
	      </m:apply>
	      <m:cn>0 </m:cn>
	      <m:cn>0 </m:cn>
	    </m:matrixrow>
	    <m:matrixrow>
	      <m:cn>0 </m:cn>
	      <m:cn>0 </m:cn>
	      <m:cn>1 </m:cn>
	      <m:cn>0 </m:cn>
	    </m:matrixrow>
	    <m:matrixrow>
	      <m:cn>0 </m:cn>
	      <m:cn>0 </m:cn>
	      <m:cn>0 </m:cn>
	      <m:cn>1 </m:cn>
	    </m:matrixrow>
	  </m:matrix>
	</m:math>. Rotazioni rispetto agli assi <m:math>
	  <m:ci>x</m:ci> </m:math> (<emphasis>pitch</emphasis> o
	  beccheggio) e <m:math> <m:ci>y</m:ci> </m:math>
	  (<emphasis>yaw o imbardata</emphasis>) si realizzano con
	  matrici di rotazione di tipo analogo, e la rotazione
	  rispetto ad un asse arbitrario si può realizzare mediante
	  composizione (moltiplicazione a sinistra) di rotazioni
	  elementari rispetto a ciascun asse.
      </para>
      <para id="traslazioni">
	<name>Traslazioni</name>
	La funzione <code>translate()</code> consente di spostare
	  oggetti sulla finestra di immagine. Ammette due o tre
	  argomenti, che sono rispettivamente gli spostamenti lungo le
	  direzioni <m:math> <m:ci>x</m:ci> </m:math>, <m:math>
	  <m:ci>y</m:ci> </m:math> (e <m:math> <m:ci>z</m:ci>
	  </m:math>).
      </para>
      <para id="rotazioni">
	<name>Rotazioni</name> In due dimensioni, la funzione
	<code>rotate()</code> consente di ruotare oggetti sulla
	finestra di immagine. Ciò avviene mediante una moltiplicazione
	(a sinistra) delle coordinate di ciascun pixel dell'oggetto
	non ruotato per una matrice di rotazione. La rotazione avviene
	sempre rispetto all'angolo superiore sinistro (coordinate
	<m:math>
	  <m:list>
	    <m:cn>0</m:cn>
	    <m:cn>0</m:cn>
	  </m:list>
 	</m:math>), e quindi va opportunamente accompagnata da una
 	traslazione. L'angolo di rotazione viene fornito secondo la
 	misura in radianti. Si ricordi che
	<m:math>
	  <m:apply>
	  <m:eq/>
	    <m:mrow>
	  <m:apply>
	    <m:times/>
	    <m:cn>2 </m:cn>
	    <m:pi/>
	  </m:apply>
	      <m:mtext>rad</m:mtext> 
	    </m:mrow>
	    <m:mrow>
	      <m:cn>360</m:cn>
	    <m:mtext>˚ </m:mtext> 
	    </m:mrow>
	  </m:apply>
 	</m:math>.  Ad esempio, si inserisca la rotazione
<code>rotate(PI/3)</code> prima del secondo comando
<code>image()</code> in <cnxn target="gondolieri_ex1"/>.  In tre
dimensioni, si possono usare le rotazioni elementari rispetto agli
assi coordinati <code>rotateX()</code>, <code>rotateY()</code>, e
<code>rotateZ()</code>.
	</para>
      <para id="scala"><name>Trasformazioni di Scala</name> La
	funzione <code>scale()</code> consente di espandere o
	contrarre un oggetto mediante moltiplicazione per una costante
	delle coordinate dei punti che lo compongono. Se invocata con
	due o tre parametri, gli scalamenti possono anche essere
	diversi lungo i diversi assi cartesiani.
      </para>
    </section>
      <section id="tipografia">
	<name>Elementi tipografici</name> <para id="tipip">Ogni
	strumento o linguaggio per la manipolazione di media offre
	anche la possibilità di lavorare con la parola scritta e con i
	suoi elementi visuali fondamentali: i caratteri
	tipografici.</para> <para id="tipiaspettip">L'aspetto di un
	<term src="http://en.wikipedia.org/wiki/Typeface">tipo</term>
	di carattere ha due componenti principali: il
	<term>font</term> e la dimensione.</para> <para id="fontsinprocessingp">Processing mette a disposizione la
	classe <code>PFont</code> ed i metodi <code>loadFont()</code>
	(per caricare un font ed assegnarlo ad un oggetto di classe
	<code>PFont</code>) e <code>textFont()</code> (per attivare un
	font con una specifica dimensione). Per poter essere caricato,
	il font deve essere stato precedentemente inserito nella
	directory <code>data</code> dello sketch corrente. Il tool
	<code>Create Font</code>, accessibile dal menu
	<code>Tools</code> di Processing, consente di creare le bitmap
	dei caratteri che si andranno ad usare e ne colloca il file
	relativo nella directory <code>data</code>. In seguito a
	queste operazioni preliminari, il font può essere usato per
	scrivere del testo, usando la funzione
	<code>text()</code>. Questa consente di collocare una stringa
	di caratteri nello spazio bidimensionale o tridimensionale,
	eventualmente inserendola all'interno di una box
	rettangolare. L'allineamento dei caratteri all'interno della
	box è governato dalla <code>textAlign()</code>. Nella
	configurazione di default, il testo scritto può essere
	sottoposto a trasformazioni spaziali come ogni altro
	oggetto. Se però si vogliono avere caratteri di alta qualità
	bisogna usare la direttiva <code>textMode(SCREEN)</code>, la
	quale li colloca nella finestra immagine alla dimensione piena
	con cui sono stati creati. Per quanto riguarda il colore dei
	caratteri, esso può essere impresso con la funzione
	<code>fill()</code>, come per ogni altro oggetto grafico.
	</para>
      <example>
	<name>Sovrapposizione di scritte</name>
	<table id="pipposcritte" frame="all">
	<tgroup cols="2" align="left" colsep="1" rowsep="1">
	<colspec colname="col1" colnum="1" colwidth="100"/>
	<colspec colname="col2" colnum="2" colwidth="340"/>
	<tbody>
	<row>
	<entry><media type="image/gif" src="pippo.gif">
		  </media>
	</entry>
	<entry>
	<code type="block">
<![CDATA[
PFont fonte;
/*The font have been previously created 
in the data folder*/
fonte = loadFont("HoeflerText-Black-48.vlw");
textFont(fonte, 12);
fill(10, 20, 250, 80);
textAlign(RIGHT);
text("pippo pippo non lo sa", 10, 14, 35, 70);
fill(200, 0, 0, 100);
textMode(SCREEN);
text("ppn", 25, 5, 30, 90);
]]>
	</code>
      </entry>
      </row>
      </tbody>
      </tgroup>
      </table>
      </example>
	<para id="fontdimp">Processing consente anche un controllo
	completo dell'occupazione spaziale dei caratteri e della
	distanza tra caratteri contigui. La funzione
	<code>textWidth()</code> calcola l'estensione orizzontale di
	una carattere o di una stringa. Essa può essere usata, insieme
	alle coordinate esatte di posizionamento passate alla
	<code>text()</code>, per controllare il <term src="http://en.wikipedia.org/wiki/Kerning">kerning</term> ed
	il <term src="http://en.wikipedia.org/wiki/Tracking_%28typography%29">tracking</term>
	tra caratteri. La <code>textSize()</code> consente di
	ridefinire la dimensione dei caratteri. La
	<code>textLeading()</code> ridefinisce la distanza in pixel
	tra linee contigue di testo. Questa distanza si misura tra le
	<emphasis>baseline</emphasis> su cui si adagiano le stringhe
	di caratteri. Lettere quali "p" o "q" si estendono al di sotto
	della baseline per una quantità di pixel calcolabile con
	<code>textDescent()</code>. Invece, la
	<code>textAscent()</code> restituisce l'estensione massima al
	di sopra della baseline (tipicamente, l'altezza della lettera
	"d").</para>

      </section>
   </section>


  <section id="elementi_uditivi">
      <name> Elementi Uditivi</name>
    <section id="suoni">
    <name>Suoni</name> <para id="suonip"> Processing non fornisce
    solamente un ambiente per la programmazione grafica, ma prevede
    anche la possibilità di utilizzare diverse funzionalità audio.
    Nella versione Beta sono disponibili due primitive di base, che
    consentono la semplice riproduzione dei file <code>.wav</code>:
    <code>PSound</code> e <code>loadSound()</code>. Quest'ultima
    permette di caricare un suono in una variabile di tipo
    <code>PSound</code> predefinita. Si possono caricare solo file
    <code>.wav</code>. Per poterli importare, i file di suono devono
    essere archiviati nella directory <code>data</code> dello sketch
    corrente. La sintassi è <code>soundA = loadSound(filename)</code>,
    dove <code>soundA</code> è una variabile di tipo PSound. Per
    riprodurre i suoni i comandi a disposizione sono
    <code>soundA.play()</code>, oppure <code>soundA.loop()</code> se
    si vuole far suonare il campione in circolo.  Una collezione di
    primitive più ricca è invece raccolta all'interno di una libreria
    denominata <link src="http://processing.org/reference/libraries/sonia/"> Sonia
    </link>.  Tale libreria contiene, per esempio, delle funzioni che
    permettono di riprodurre campioni audio (<emphasis>sample
    playback</emphasis>), di eseguire un'analisi di Fourier in tempo
    reale (ovvero un'analisi del suono che viene captato da un
    microfono collegato al computer: <emphasis>realtime
    FFT</emphasis>), nonchè di salvare dei file <code>.wav</code> sul
    disco. Per poter utilizzare la libreria Sonia è necessario
    scaricare il file <code>.zip</code> dal sito <link src="http://www.pitaru.com/sonia/">http://www.pitaru.com/sonia/</link>.
    Bisogna poi decomprimere il tutto e copiare la directory
    <code>Sonia_?_?</code> dentro la directory
    <code>Processing/libraries</code>. Infine, dopo aver riavviato
    Processing, si deve aggiungere un comando <code>import</code>,
    selezionandolo direttamente dal menu <code>Sketch / Import Library
    / Sonia_?_?</code>. <note>Le applet prodotte con Sonia, per poter
    essere eseguite all'interno di un browser, necessitano del plugin
    JSyn di Phil Burk che può essere scaricato e installato dal sito
    <link src="http://www.softsynth.com/jsyn/plugins/">http://www.softsynth.com/jsyn/plugins/</link>.</note>
    Come nel caso della primitiva <code>loadSound()</code>, per poter
    utilizzare dei campioni audio è necessario copiarli all'interno
    della cartella <code>data</code>, così come fatto nel caso delle
    immagini. A questo punto siamo pronti per poter imparare a
    lavorare con il suono in Processing.
    </para>
     </section>


      <section id="timbri"><name>Timbri</name> <para id="timbrop">In questa sezione del modulo proveremo prima ad
	utilizzare e poi ad analizzare un'applicazione per
	l'esplorazione dei timbri, simile nella concezione al Color
	Chooser di <cnxn target="gimp_color"/>, denominata Sound
	Chooser. Per adesso possiamo pensare al timbro di un suono
	come al "colore" di un'immagine. O se si vuole possiamo
	pensare al timbro come al diverso "colore" dei diversi
	strumenti. Più avanti nel corso vedremo con maggior precisione
	a cosa corrispondono dal punto di vista fisico e percettivo
	sia il colore sia il timbro. Nella applet sound chooser si
	possono far suonare 4 suoni con timbri diversi, facendo click
	con il mouse su uno qualsiasi dei raggi. Ciascuno dei raggi
	corrisponde ad uno strumento musicale (timbro/colore)
	diverso. Cambiando posizione lungo il raggio e facendo click,
	è possible sentire come la brillantezza del timbro
	corrispondente cambia. Più precisamente, man mano che si
	procede verso il centro, il suono si fa vieppiù povero.
	</para>
      </section>

      <section id="trasformazioni"><name>Trasformazioni</name> <para id="codicep"> Vediamo ora in cosa consiste il codice
	Processing necessario per implementare il Sound Chooser nei
	tratti salienti. Il comando <code>Sonia.start(this)</code> è
	indispensabile per attivare il motore audio di Sonia. La linea
	<code>Sample mySample1</code> dichiara una variabile atta a
	contenere campioni audio. A tale variabile possono essere
	applicati vari metodi, tra i quali il metodo <code>play</code>
	per riprodurre il campione.  Nel <code>loop()</code> viene
	definito l'aspetto grafico della applet.  Infine, tramite la
	funzione <code>mouseReleased()</code> viene rilevato quando il
	mouse viene rilasciato dopo essere stato premuto e in quale
	area del cerchiello. A quel punto una successione di
	condizioni <code>if</code> stabilisce quale strumento/timbro
	debba essere riprodotto a seconda del punto di
	interazione. Inoltre, all'interno della funzione
	<code>mouseReleased()</code> viene invocata un'altra funzione:
	<code>filtra(float[] DATAF, float[] DATA, float RO, float
	WC)</code>. Questa funzione, che viene implementata alla fine
	del listato di questa applet, esegue un filtraggio sul suono
	che viene riprodotto. In particolare si tratta di un
	filtraggio passa-basso, vale a dire che lascia passare le basse
	frequenze ma non le alte. A seconda se il mouse viene
	rilasciato più o meno vicino al centro, l'effetto del
	filtraggio cambia. Più in particolare il filtraggio sarà più
	drastico (le alte frequenze sono maggiormente attenuate, con
	l'effetto di un maggior incupimento del suono) se il mouse
	viene rilasciato in prossimità del centro e il suono risulterà
	più povero (scolorito).
</para>

<table id="sound_chooser" frame="all">
	      <tgroup cols="2" align="left" colsep="1" rowsep="1">
		<colspec colname="col1" colnum="1" colwidth="150"/>
		<colspec colname="col2" colnum="2" colwidth="400"/>
		<tbody>
		  <row>
		<entrytbl cols="1">
		  <tbody>
		    <row>
		      <entry><link src="./tromba.wav">Tromba</link></entry>
		    </row>
		    <row>
		      <entry><link src="./oboe.wav">Oboe</link></entry>
		    </row>
		    <row>
		      <entry><link src="./violino.wav">Violino</link></entry>
		    </row>
		    <row>
		      <entry><link src="./flauto.aif">Flauto</link></entry>
		    </row>
		    <row>
		      <entry>
		      <link src="./sound_chooser.html">Applet: scelta di un
		    timbro e controllo di brillantezza (brightness)
		    </link> </entry>
		    </row>
		  </tbody>
		</entrytbl>
	<!--	    <entry>
		      <link src="./soundch.html">Applet che
permette di scegliere un timbro e modificarne la brillantezza (brightness) </link>
		    </entry> -->
		    <entry>
	    <code type="block">
          <![CDATA[       
import pitaru.sonia_v2_9.*;

Sample mySample1, mySample2, mySample3, mySample4;
Sample mySample1F, mySample2F, mySample3F, mySample4F;

float[] data1, data2, data3, data4;
float[] data1F, data2F, data3F, data4F;

int sr = 11025;  // sampling rate


void setup()
{
  size(200, 200);
  colorMode(HSB, 360, height, height);
  Sonia.start(this);

  mySample1 = new Sample("flauto.aif");
    mySample2 = new Sample("oboe.wav");
      mySample3 = new Sample("tromba.wav");
        mySample4 = new Sample("violino.wav");

  mySample1F = new Sample("flauto.aif");
 // ... OMISSIS ...

  data1  = new float[mySample1.getNumFrames()]; 
	  // creates new arrays the length of the sample
	  // for the original sound
 // ... OMISSIS ...

  data1F  = new float[mySample1.getNumFrames()]; 
	  // creates new arrays the length of the sample
	  // for the filtered sound
// ... OMISSIS ...


  mySample1.read(data1);
// ... OMISSIS ...

}

void draw()
{
// ... OMISSIS ...
}

void mouseReleased()
{

float ro;
float roLin;
float wc;


  // FLAUTO
  if ((mouseX > 95) && (mouseX < 105)&& (mouseY > 50)&& (mouseY < 90)) {

    roLin = (mouseY-49.99)/41;
    ro = pow(roLin,.33);
    wc = 298*(TWO_PI/sr);
    filtra(data1F, data1, wc, ro);

    mySample1F.write(data1F);
    mySample1F.play();
  }
// ... OMISSIS ...

}

//filtra = new function
void filtra(float[] DATAF, float[] DATA, float WC, float RO) {

  float G;
  float RO2;
  RO2 = pow(RO, 2);
  G = (1-RO)*sqrt(1-2*RO*cos(2*WC)+RO2)*4; // (*4) is for having it louder
 
  for(int i = 3; i < DATA.length; i++){
    DATAF[i] = G*DATA[i]+2*RO*cos(WC)*DATAF[i-1]-RO2*DATAF[i-2];
	  //filtraggio ricorsivo
  }
}

// safely stop the Sonia engine upon shutdown.
public void stop(){
  Sonia.stop();
  super.stop();
  }
            
             ]]>	      
	    </code>
		    </entry>
		  </row>
		</tbody>
	      </tgroup>
	    </table>   
  </section>
      <exercise id="soniaproblem1">
	<problem>
	  <para id="prob1p">Completare il codice riportato in 
	  <cnxn target="sound_chooser"/> per ottenere l'applet
	  Sound Chooser completa.</para>
	</problem>
	<solution>
	  <para id="sol1p"> <link src="./sound_chooser.pde">Codice sorgente
Processing.  </link>
	  </para>
	</solution>
      </exercise>
      <exercise id="soniaproblem2">
	<problem>
	  <para id="prob2p">
	    Aggiungere ai raggi del Sound Chooser del colore,
	    sostituendo le <code>line</code> con dei <code>rect</code>
	    e colorando le barrette ottenute con una variazione di
	    brillantezza, crescente dal centro verso l'esterno.</para>
	</problem>
	<solution><para id="sol2p"> <link src="./sound_chooser_color.html">Applet con codice sorgente
Processing.  </link> </para>
	</solution>
      </exercise>
</section>
</content>
  
</document>
