<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE document PUBLIC "-//CNX//DTD CNXML 0.5 plus MathML//EN" "http://cnx.rice.edu/technology/cnxml/schema/dtd/0.5/cnxml_mathml.dtd">
<document xmlns="http://cnx.rice.edu/cnxml" xmlns:md="http://cnx.rice.edu/mdml/0.4" xmlns:bib="http://bibtexml.sf.net/" xmlns:m="http://www.w3.org/1998/Math/MathML" id="new">
  <name>Programmazione Visuale</name>
  <metadata>
  <md:version>1.5</md:version>
  <md:created>2007/06/18 05:58:16 GMT-5</md:created>
  <md:revised>2008/03/12 09:04:52.840 GMT-5</md:revised>
  <md:authorlist>
      <md:author id="drocchesso">
      <md:firstname>Davide</md:firstname>
      
      <md:surname>Rocchesso</md:surname>
      <md:email>roc@iuav.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>roc@iuav.it</md:email>
    </md:maintainer>
  </md:maintainerlist>
  
  <md:keywordlist>
    <md:keyword>Pure Data</md:keyword>
    <md:keyword>Visual programming</md:keyword>
  </md:keywordlist>

  <md:abstract>Si presenta una breve introduzione alla programmazione visuale per mezzo del linguaggio Pure Data (PD)</md:abstract>
</metadata>
  <content>
    <section>
      <name>Programmazione Visuale</name>
      <para id="visualpp">Un <link src="http://en.wikipedia.org/wiki/Visual_programming">linguaggio
	di programmazione visuale</link> permette di specificare
	programmi mediante manipolazione di elementi grafici. I
	linguaggi più usati in ambito artistico e di produzione
	multimediale (tra questi <link src="http://en.wikipedia.org/wiki/Pure_Data">Pure Data</link>,
	<link src="http://en.wikipedia.org/wiki/Max/MSP">MAX/MSP</link>, <link src="http://vvvv.org/">vvvv</link>, e
	<link src="http://en.wikipedia.org/wiki/Quartz_Composer">Quartz
	Composer</link> sono basati sul paradigma di calcolo <link src="http://en.wikipedia.org/wiki/Dataflow_language">dataflow</link>,
	nel quale i dati (piuttosto che le sequenze di operazioni)
	sono al centro dell'attenzione. Le operazioni sono "scatole
	nere" che elaborano l'input, non appena questo è disponibile,
	producendo un output che può essere dato in input ad altre
	scatole di elaborazione. Un programma dataflow assomiglia ad
	una rete di catene di montaggio, esplicita in maniera
	intrinseca il parallelismo, e non nasconde uno stato. Oltre
	che prestarsi alla parallelizzazione automatica, i programmi
	dataflow sono in un certo senso "auto-documentati" e si
	prestano al debugging mediante sonde.
      </para>
      <para id="pdp"><link src="http://en.wikipedia.org/wiki/Pure_Data">Pure
	Data</link> è un linguaggio di programmazione visuale
	inizialmente concepito da <link src="http://crca.ucsd.edu/~msp/">Miller Puckette</link> per la
	computer music in tempo reale, poi esteso ad opera di una
	comunità di programmatori ed oggi diffuso anche tra artisti
	visuali, performer e interaction designer. Pure Data è un
	software libero, ed ha uno stretto grado di parentela con
	<link src="http://en.wikipedia.org/wiki/Max_%28software%29">MAX/MSP</link>.
	Essendo nato per elaborare e controllare segnale audio, Pure
	Data supporta la comunicazione dei dati da un operatore
	all'altro a due rate: il sample rate che per default è di
	44100 campioni al secondo, ed il control rate ad un
	sessantaquattresimo del sample rate. Più precisamente, gli
	operatori che elaborano segnale audio (caratterizzati dal
	suffisso <code>~</code>) prendono campioni di ingresso in
	maniera sincrona ad audio rate e allo stesso rate producono
	segnali di uscita. Tutti gli altri operatori elaborano dati
	non appena questi sono disponibili (dataflow) ad un rate
	massimo di circa 690 Hz (per default, un sessantaquattresimo
	del sample rate). Tutti i calcoli sono effettuati su numeri
	floating-point a 32 bit. La documentazione di Pure Data è
	disponibile dalla voce <code>Help</code> del suo menu, oppure
	è consultabile <link src="http://crca.ucsd.edu/~msp/Pd_documentation/">online</link>. Questo
	modulo è parzialmente basato su tale documentazione e sulla
	<link src="http://www.music.mcgill.ca/~gary/306/week13/pd.html">lezione
	di Gary Scavone</link>.
      </para>

      <para id="pdobjectsp">
	I programmi Pure Data sono chiamati <emphasis>patch</emphasis>
	e si presentano come grafi di elaborazione di flussi di
	dati. Ogni programma ha una finestra principale e può avere un
	numero arbitrario di sottofinestre.  Il software Pure Data ha una <link src="http://en.wikipedia.org/wiki/Mode_%28computer_interface%29">interfaccia
	modale</link>, in quanto ci sono due modi distinti di
	operazione: run mode e edit mode. Si passa dall'uno all'altro
	con <code>command-E</code> e il feedback sul modo corrente è
	dato dalla forma del puntatore del mouse. I blocchi che si possono
	connettere in forma di grafo di dataflow sono di tipo: object,
	message, atom (number o symbol), GUI, e comment.
      </para>
      <para id="hellop">
	<figure id="helloi">
	  <media type="image/jpg" src="hello.jpg">
	  </media>
	</figure>
	In <cnxn target="helloi"/> è illustrato un semplicissimo <link src="./hello.pd">patch</link> che stampa sulla consolle la scritta
 <code>x1: Hello World</code>. Esso contiene due oggetti message (lato
 destro concavo) ed un oggetto object (rettangolo con comando
 <code>print x1</code>). L'oggetto object rapresenta un comando con
 eventuali parametri di default. Il quadrato con cerchio all'interno è
 uno speciale messaggio senza contenuto, chiamato
 <emphasis>bang</emphasis>, che invia un evento ai blocchi ad esso
 collegati.
      </para>

<section>
	<name>Idiosincrasie grafiche</name>
      <para id="idiop"><figure id="idioi">
	  <media type="image/png" src="depth-first.png">
	  </media>
	</figure>
	  Ogniqualvolta un messaggio è inviato ad un oggetto, questi
	  può diventare mittente a sua volta verso altri oggetti. In
	  altri termini, si configura un albero di ricezioni di
	  messaggi. Secondo il <link src="http://crca.ucsd.edu/~msp/Pd_documentation/x2.htm#s3.2"> manuale di Pure Data </link> l'ordine di esecuzione utilizzato è
	  <link src="http://en.wikipedia.org/wiki/Depth-first_search">depth-first</link>,
	  cioè ogni ramo è esplorato fino alle foglie prima di
	  procedere con gli altri rami. L'ordine di esecuzione tra
	  nodi allo stesso livello dell'albero sarebbe invece da considerarsi
	  indeterminato. In realtà, provando ad eseguire l'<link src="./depth-first.pd">esempio</link> di <cnxn target="idioi"/> e ridisponendo le connessioni tra i nodi dell'albero con ordini diversi ci si accorge che non si può nemmeno contare sull'ordine depth-first. In Max/MSP la situazione è ancora peggiore perché muovendo messaggi e bang in posti diversi della finestra, a parità di configurazione topologica, si ottengono sequenze di attivazione diverse. 

	  L'elaborazione di tipo dataflow può dare luogo a loop non
	  computabili, quale è quello riportato in <cnxn target="noncomploop"/>. Pure Data, in questo caso, riporta
	  un messaggio di "stack overflow" sulla consolle. Per rendere
	  il loop computabile è sufficiente inserire un elemento di
	  disaccoppiamento quale è un <code>pipe</code> (si veda <cnxn target="ritardip"/>). Per quanto sia piccolo il parametro
	  ritardo di questo pipe (al limite anche nullo), esso
	  terrà memoria del dato in ingresso per consumarlo al ciclo
	  successivo di calcolo.
	<figure id="noncomploop">
	  <media type="image/png" src="noncomploop.png">
	  </media>
	</figure>

      </para>

	<para id="rightleft">
	  Nella maggior parte degli oggetti, la inlet di sinistra è
	  <emphasis>hot</emphasis>, nel senso che messaggi che ad essa
	  arrivano scatenano messaggi in output. 

	  E' spesso desiderabile inviare messaggi a due o più inlet di
	  un oggetto, ma il risultato dell'operazione può dipendere
	  dall'ordine con cui si sono fatte le connessioni. Ciò mina
	  l'efficacia semantica del programma visuale, in quanto
	  potremmo avere due patch apparentemente identiche che però
	  si comportano diversamente perché costruite con un ordine
	  diverso. Ad esempio, si provi a fare la somma di un numero
	  con sè stesso secondo la <cnxn target="plus"/>. 
	  <figure id="plus">
	  <media type="image/png" src="plus.png">
	  </media>
	</figure>
	  La sequenza di creazione delle connessioni determina la
          correttezza o meno del risultato. Per imporre chiarezza
          semantica al patch è opportuno inserire un oggetto
          <code>trigger</code> che forza l'ordine di attivazione delle
          outlet da destra a sinistra, come indicato in <cnxn target="plust"/>.
	<figure id="plust">
	  <media type="image/png" src="plust.png">
	  </media>
	</figure>
	</para>
</section>

      <section>
	<name>Elementi di GUI</name>
      <para id="metrop">
	<figure id="metroi">
	  <media type="image/jpg" src="metro.jpg">
	  </media>
	</figure>
	In <cnxn target="metroi"/> è illustrata l'utilizzazione di un
	  <link src="./metro.pd">generatore periodico di
	  bang</link>. Si noti il parametro di <code>metro</code> che
	  stabilisce l'intervallo (di 500 millisecondi) tra due
	  bang. Il quadrato in alto è un elemento di GUI detto toggle
	  switch, in pratica un interruttore.
      </para>

      <para id="sliderp">
	<figure id="slideri">
	  <media type="image/jpg" src="slider.jpg">
	  </media>
	</figure>
	Un altro elemento di GUI, il <link src="./slider.pd">vslider</link>, è illustrato in <cnxn target="slideri"/>. In questo patch è anche visibile un
	oggetto number, il quale invia un numero in uscita
	(<emphasis>outlet</emphasis>) ogni volta che ne viene cambiato
	il valore, per dragging con il mouse o per immissione di
	numeri dal suo imput.
      </para>
      </section>

      <section>
	<name>Array</name>
      <para id="arrayp">
	<figure id="arrayi">
	  <media type="image/jpg" src="table.jpg">
	  </media>
	</figure>
	  In Pure Data, un array è un contenitore di numeri ed un
	      elemento di visualizzazione al tempo stesso. Infatti,
	      l'oggetto <code>table</code> istanzia l'array e crea un
	      subpatch che ne visualizza la rappresentazione
	      grafica. Questa rappresentazione è anche uno strumento
	      di input, in quanto i valori dell'array possono essere
	      "disegnati" con il mouse. Per leggere e scrivere i
	      singoli elementi dell'array si usano gli oggetti
	      <code>tabread</code> e
	      <code>tabwrite</code>. L'utilizzazione di
	      <code>tabread</code> per <link src="./table.pd">scandire un array</link> è illustrata
	      in <cnxn target="arrayi"/>.
      </para>

      </section>

      <section>
	<name>Selezioni, routing, multiplexing</name>
      <para id="comparisonp">
	<figure id="comparisoni">
	  <media type="image/jpg" src="comparisons.jpg">
	  </media>
	</figure>
	In <cnxn target="comparisoni"/> sono illustrati <link src="./comparisons.pd">blocchi di confronto e
	selezione</link>. In particolare, il blocco
	<code>select</code> attiva l'uscita di sinistra se l'ingresso
	  (<emphasis>inlet</emphasis>) è uguale al suo parametro,
	altrimenti attiva l'uscita di destra.
      </para>

 <para id="routingp"><figure id="routingi">
	  <media type="image/jpg" src="routing.jpg">
	  </media>
	</figure>
	In <cnxn target="routingi"/> sono illustrati tre <link src="./routing.pd">elementi di routing</link>. Il blocco
	    <code>spigot</code> trasmette messaggi dall'inlet di
	    sinistra all'outlet in dipendenza dallo stato
	    dell'ingresso (di controllo) di destra. In sostanza si
	    tratta di un <emphasis>gate</emphasis> con controllo di
	    apertura e chiusura. Invece, <code>moses</code> consente
	    di smistare alle uscite sinistra e destra i valori di
	    ingresso che sono rispettivamente minori o maggiori (o
	    uguali) del valore di controllo passato dalla inlet di
	    destra. Infine, <code>route</code> smista dei messaggi
	    ricevuti in ingresso sulla base del loro primo elemento,
	    mettendolo a confronto con gli argomenti. Un <link src="http://en.wikipedia.org/wiki/Multiplexer">multiplexer</link> si
	    può ottenere combinando la <code>route</code> con la
	    <code>pack</code>.
      </para>
	<exercise id="muxprob">
	  <problem>
	    <para id="muxp">
	      Realizzare un multiplexer e un demultiplexer utilizzando
	      gli oggetti <code>pack</code>, <code>route</code> e
	      <code>spigot</code>.
	    </para>
	  </problem>
	  <solution>
	    <para id="muxs">
	    <link src="./muxdemux.pd">Pure Data patch</link>.
	    </para>
	  </solution>
	</exercise>
      </section>

      <section>
	<name>Ritardi, code e gestione del tempo</name>

  <para id="ritardip">
	<figure id="ritardii">
	  <media type="image/jpg" src="delays.jpg">
	  </media>
	</figure>
	In <cnxn target="ritardii"/> è illustrata l'utilizzazione di
	  <link src="./delays.pd">ritardi e code</link>. La
	  <code>delay</code> ritarda un bang in ingresso di un numero
	  di millisecondi pari al suo argomento. Se si vuole ritardare
	  un flusso di dati bisogna usare la <code>pipe</code>, la
	  quale è realizzata come <cnxn document="m14556" target="codep">coda a buffer circolare</cnxn>. 
      </para>

  <para id="tempop">
	<figure id="tempoi">
	  <media type="image/jpg" src="timing.jpg">
	  </media>
	</figure>
	  In <cnxn target="tempoi"/> si vedono alcuni oggetti che
	  consentono di <link src="./timing.pd">scandire, misurare, e
	  avanzare</link> il tempo. Rispettivamente, ciò si ottiene
	  con <code>metro</code>, <code>timer</code>, e
	  <code>line</code>. Quest'ultimo oggetto genera una rampa
	  lineare, da un valore iniziale a uno finale, in un certo
	  tempo.
      </para>
	<exercise id="arrayex">
	  <problem>
	    <para id="arrayexp">
	      Nel patch di <cnxn target="arrayi"/>, si provi a
	      rimuovere e ripristinare i collegamenti che arrivano
	      alla inlet di destra dell'oggetto <code>float</code>, e
	      si verifichi che il reset dell'indice una volta
	      raggiunto il limite di 128 può non avere luogo. Perché?
	      Come si può introdurre in maniera deterministica il
	      reset dell'indice?
	    </para>
	  </problem>
	  <solution>
	    <para id="arrayexs">
	      E' sufficiente introdurre un elemento di
	      disaccoppiamento (ad esempio, una <code>pipe 0</code>)
	      che imponga un ordine tra l'immissione del numero
	      incrementato e l'immissione di 0 nella inlet di destra.
	    </para>
	  </solution>
	</exercise>
      </section>

      <section>
	<name>Message Passing</name>
	<para id="mpp">
	  Il funzionamento dataflow di Pure Data avviene mediante
	  <emphasis>pipe</emphasis> che corrispondono alle connessioni
	  tra oggetti. E' anche possibile operare in regime di <link src="http://en.wikipedia.org/wiki/Message_passing">message
	  passing</link>, cioè ricevere (<link src="./receive.pd">receive</link>) e spedire (<link src="./receive.pd">send</link>) dati tra diverse parti di un
	  patch o tra patch diversi. Ciò è illustrato in <cnxn target="messagei"/>. Invece, l'oggetto <code>value</code>
	  realizza una sorta di variabile globale.
	<figure id="messagei">
	  <media type="image/jpg" src="send.jpg">
	  </media>
	</figure>
	</para>
      </section>
      <section>
	<name>Modularità</name>
	<para id="modulep">
	  Nella programmazione visuale la modularità si ottiene con i
	  meccanismi di <emphasis>subpatching</emphasis> che, in Pure
	  Data, sono di due tipi:
	  <list id="subpatches">
	    <item><name>Subpatch</name> Si utilizza l'oggetto
	    <code>pd</code> per dichiarare un subpatch. In
	    quest'ultimo, si specificano le <code>inlet</code> e
	      <code>outlet</code>. Si veda <cnxn target="subpatch"/>.</item>
	    <item><name>Abstraction</name> Si costruisce un patch come
	    file separato, che a questo punto diventa uno degli
	    oggetti a disposizione di Pure Data. Si veda <cnxn target="abstraction"/>.</item>
	  </list>
	<figure id="subpatch">
	  <media type="image/jpg" src="sub.jpg">
	  </media>
	</figure>
	<figure id="abstraction">
	  <media type="image/jpg" src="abstraction.jpg">
	  </media>
	</figure>
	</para>
      </section>
    </section>
  </content>
  
</document>
