<?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/08/10 07:38:42 GMT-5</md:created>
  <md:revised>2008/05/19 12:49:36.326 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: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>roc@iuav.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.</md:abstract>
</metadata>

  <content>
    <section id="elementi_visuali">
      <name>Visual Elements</name>

    <section id="coordinates">
      <name>Coordinates </name> <para id="coordinatep"> In Processing,
      the representation of graphic objects is based on a cartesian 3D
      coordinate system, as displayed in <cnxn target="coordinatef"/>.
	<figure id="coordinatef">
	  <name>Coordinate system</name>
	  <media type="image/png" src="coordinate.png">
	  </media>
	  <caption>3D coordinate system used in Processing</caption>
	</figure>
	  2D images are processed by acting on the X-Y plane, thus
	  assuming that the Z coordinate is zero. The function
	  <code>size()</code> defines the display window size and the
	  <term>rendering engine</term> that will be used to paint
	  onto the window. The default engine is JAVA2D, the 2D
	  graphic Java libray. If one wants to program in 3D, he must
	  choose either the P3D (Processing 3D) rendering engine,
	  especially suited for web-oriented graphics, or OPENGL,
	  which delegates many typical 3D operations to the graphic
	  board thus freeing the CPU from many computations.

	</para>
    </section>
    <section id="immagini">
      <name>Images</name>
      <para id="immaginip">
	In Processing, an image can be assigned to an object of the
	class <code>PImage</code>. The function
	<code>loadImage("myImage")</code> takes a file (gif or jpg)
	<code>myImage</code>, containing the pixel coding of an image,
	and gives back the content of such image, which can be
	assigned to a variable of type <code>PImage</code>. The file
	<code>myImage</code> must be loaded in the <code>data</code>
	folder of the directory having the same name as the Processing
	sketch we are working at.  <note> When the <code>New</code>
	command is executed, processing opens up a folder named
	<code>sketch_???????</code> within the <code>Processing</code>
	directory, corresponding to the name assigned bye the system
	to the newly created file. Such folder is accessible from the
	Processing menu item <code>Sketch/Add File</code>.</note> The
	class <code>PImage</code> gives access, by the fields
	<code>width</code> and <code>height</code>, to the width and
	height of the loaded image. The image content is accessed via
	the <code>pixels[]</code> field.
      </para>
      <example id="gondolieri_ex1">
	<name>Loading and visualizing an image</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>Colors</name>
      <para id="colori_generalita">
	Since our color receptors (<emphasis>cones</emphasis>), each
	tuned to a wavelength region, are of three kinds, color models
	are always referred to a three-dimensional space.  In additive
	color models, each of three axes correspond to a base color,
	and by mixing three colored light beams one can obtain all
	colors within a <emphasis>gamut</emphasis> volume in the space
	defined by the three axes. The three base colors can be chosen
	arbitrarily or, more often, based on the application domain
	(e.g., color of three phosphors or laser beams). In printing
	processes, subtractive color models are used, where the
	starting point is the white surface and primary ink colors are
	used to subtract color from white.  <note>Guide to color
	models: <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> is a primitive type used to
	specify colors. It is realized by a 32-bit number, where the
	first byte specifies the alpha value, and the other bytes
	specify a triple either in the RGB or in the HSB model. The
	choice of one model or the other is made by the
	<code>colorMode()</code> function. With three bytes, a number
	of
	<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>  are representable.
      </para>
      <section id="rgb">
	<name>The RGB model</name> 
	<para id="rgbp">
	Colors are represented by a triple of numbers, each giving the
	intensity of the primary colors Red, Green, and Blue. Each
	number can be an unsigned integer, thus taking values between
	0 and 255, or be expressed as a floating point number between
	<m:math> <m:cn>0.0</m:cn> </m:math> and <m:math>
	<m:cn>1.0</m:cn> </m:math>. With even larger flexibility, the
	model, type, and range of colors can be set with the function
	<code>colorMode()</code>. The RGB model is additive. </para>
      </section>
      <section id="hsb">
	<name>HSB Model</name> 	
	<para id="hsbp">
	Colors are represented by a triple of numbers, the first
	number giving the Hue, the second giving Saturation, and the
	third giving the Brightness. <note>Often the model is called
	HSV, where V stands for Value.</note> The hue takes values in
	degrees between <m:math> <m:cn>0</m:cn> </m:math> (red) and
	<m:math> <m:cn>360</m:cn> </m:math>, being the various hues
	arranged along a circumference and being red positioned at
	<m:math> <m:cn>0</m:cn> <m:mtext>˚ </m:mtext>
	</m:math>. Saturation and brightness vary between <m:math>
	<m:cn>0</m:cn> </m:math> and <m:math> <m:cn>100</m:cn>
	</m:math>. The saturation is the degree of purity of color. If
	a pure color is added with a white light its degree of purity
	decreases until the color eventually sits on a gray scale when
	saturation is zero. In physical terms, the brightness is
	proportional to the signal power spectrum. Intuitively, the
	brightness is increased when the light intensity
	increases. The three-dimensional HSB space is well represented
	by a cylinder, with the hue (nominal scale) arranged along the
	circumference, the saturation (ratio scale) arranged along the
	radius, and the brightness (interval scale) arranged along the
	longitudinal axis. Alternatively, such three-dimensional space
	can be collapsed into two dimensions, as in the
	<emphasis>color chooser</emphasis> of the image-processing
	program <link src="http://www.gimp.org">Gimp</link>, displayed
	in <cnxn target="gimp_color"/>. Along the circumference, the
	three primary colors (red, green, and blue) are visible,
	<m:math> <m:cn>120</m:cn> <m:mtext>˚ </m:mtext>
	</m:math> apart from each other, separated from the secondary
	colors (magenta, cyan, yellow). Each secondary color is
	complementary to the primary color in front of it in the
	circumference. For instance, if we take the green component
	out of a white light, we obtain a magenta light. The triangle
	inscribed in the circumference has a vertex pointing to a
	selected hue. The opposite side contains the gray scale, thus
	representing colors with null saturation and variable
	brightness. Going from the reference vertex to the opposite
	side we have a gradual decrease in saturation.
	<figure id="gimp_color">
	  <name>Gimp color chooser</name>
	  <media type="image/gif" src="gimp_color.gif">
	  </media>
	  <caption>Color chooser of the software Gimp</caption>
	</figure>
	</para>
      </section>
      <section id="alpha">
	<name>Alpha channel</name> 
	<para id="alphap">
        It is a byte used to blend and interpolate between images, for
	example to render transparency. It can be obtained, from a
	variable of type <code>color</code>, with the method
	<code>alpha()</code>. The alpha channel can be manipulated
	with the method <code>blend()</code> of the class
	<code>PImage</code>.
	</para>
      </section>
      <example id="gondolieri_ex2">
	<name>Loading and visualizing an image with transparency</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 j = 0; j < b.height; j++)
 for (int i = 0; i < b.width; i++) {
   b.set(i, j, b.get(i,j) + 
     color(0,0,0, 255 - (int)((1-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, it is possible to assign a color to a variable of type <code>color</code> by means of the function
	<code>color()</code>, and the model can be previously set with <code>colorMode()</code>. The functions
	<code>red()</code>, <code>green()</code>, <code>blue()</code>,
	<code>hue()</code>, <code>saturation()</code>, and
	<code>brightness()</code> allow to move from one model to the other.
	<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));
	  // the variables c1, c2, and c3 contain the coding of the same color
	</code>
      </para>
      <section id="tinteggiatura">
	<name>Tinging an image</name> 
	<para id="tinteggiaturap">
	An image can be tinged with a color and its transparency can
	be set by assigning a given value to the alpha channel. For
	this purpose, the function <code>tint()</code> can be
	used. For example, a blue tone can be assigned to the inlaid
	image of <cnxn target="gondolieri_ex1"/> by just preceding
	the second <code>image()</code> command with <code>tint(0,
	153, 204, 126)</code> .
	</para>
     </section>
    </section>
    <section id="rotazioni_traslazioni">
      <name>Translations, Rotations, and Scale Transformations</name>
      <para id="rappresentazione_punti">
	<name>Representing Points and Vectors</name> In computer
	graphics, points and vectors are represented with the
	<definition id="coordinate_omogenee"> <term>homogeneous
	coordinates</term> <meaning>quadruples of numbers, where the
	first triple is to be read in the X-Y-Z space, while the
	fourth number indicates a <emphasis>vector</emphasis> if it
	takes value 0, or a <emphasis>point</emphasis> if it takes
	value 1.</meaning>
	</definition>
	A translation is obtained by adding, in homogeneous
	coordinates, a vector to a point, and the result is a
	point. Alternatively we ca see a translation as a
	matrix-vector product (see <cnxn document="m10090">Matrix
	Arithmetic</cnxn>), where the matrix is
	<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>, and the vector is the one representing the point
	<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>.
	An anti-clockwise rotation by the angle <m:math>
	  <m:ci>θ</m:ci>
	</m:math>
 around the axis <m:math> <m:ci>z</m:ci> </m:math>
	  (<emphasis>roll</emphasis>), is obtained by the rotation matrix
	<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>. Rotations around the axes <m:math> <m:ci>x</m:ci>
	  </m:math> (<emphasis>pitch</emphasis>) and <m:math>
	  <m:ci>y</m:ci> </m:math> (<emphasis>yaw</emphasis>) are
	  realized by means of rotation matrices of the same kind, and
	  a rotation around an arbitrary axis can be obtained by
	  composition (left multiply) of elementary rotations around
	  each of the main axes.
      </para>
      <para id="traslazioni">
	<name>Translations</name> The function
	<code>translate()</code> moves an object in the image
	window. It takes two or three parameters, being the
	displacements along the directions <m:math> <m:ci>x</m:ci>
	</m:math>, <m:math> <m:ci>y</m:ci> </m:math> (and <m:math>
	<m:ci>z</m:ci> </m:math>), respectively.
      </para>
      <para id="rotazioni">
	<name>Rotations</name> In two dimensions, the function
	<code>rotate()</code> is used to rotate objects in the image
	window.  This is obtained by (left) multiplying the
	coordinates of each pixel of the object by a rotation
	matrix. Rotations are always specified around the top left
	corner of the window (
	<m:math>
	  <m:list>
	    <m:cn>0</m:cn>
	    <m:cn>0</m:cn>
	  </m:list>
 	</m:math> coordinate). Translations can be used to move the
 	rotation axis to other points. Rotation angles are specified
 	in radians. Recall that
	<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>.  For example, insert the rotation
	<code>rotate(PI/3)</code> before the second
	<code>image()</code> command in <cnxn target="gondolieri_ex1"/>.  In three dimensions, we can use elementary rotations
	around the coordinate axes <code>rotateX()</code>,
	<code>rotateY()</code>, e <code>rotateZ()</code>.
	</para>
      <para id="scala"><name>Scale Transformations</name> The function
      <code>scale()</code> allows to expand or contract an object by
      multiplication of its point coordinates by a constant. When it
      is invoked with two or three parameters, different scalings can
      be applied to the three axes.
      </para>
    </section>
      <section id="tipografia">
	<name>Typographic Elements</name> <para id="tipip">Every tool
	or language for media manipulation gives the opportunity to
	work with written words and with their fundamental visual
	elements: typographic characters. </para> <para id="tipiaspettip">The aspect of a <term src="http://en.wikipedia.org/wiki/Typeface">type</term> has
	two main components: <term>font</term> and size.</para> <para id="fontsinprocessingp">Processing has the class
	<code>PFont</code> and the methods <code>loadFont()</code> (to
	load a font and assign it to an object of the
	<code>PFont</code> class) and <code>textFont()</code> (to
	activate a font with a specific size). In order to load a
	font, this has to be pre-loaded into the directory
	<code>data</code> of the current sketch. The tool <code>Create
	Font</code>, accessible from the <code>Tools</code> menu in
	Processing, creates the bitmaps of the characters that the
	programmer intends to use. The file with the bitmaps is put in
	the <code>data</code> directory. After these preliminary
	operations, the font can be used to write some text, using the
	function <code>text()</code>. With this function, a string of
	characters can be put in the 2D or 3D space, possibly
	inserting it within a rectangular box.  The alignment of
	characters in the box is governed by the function
	<code>textAlign()</code>. In the default configuration, the
	written text can be spatially transformed like any other
	object.  The color of characters can be set with the usual
	<code>fill()</code>, like for any other graphic object.
	</para>
      <example>
	<name>Overlapped text</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);
textFont(fonte, 24);
fill(200, 0, 0, 100);
text("ppnls", 25, 5, 50, 90);
]]>
	</code>
      </entry>
      </row>
      </tbody>
      </tgroup>
      </table>
      </example>
	<para id="fontdimp">Processing allows a tight control of the
	spatial occupation of characters and of the distance between
	contiguous characters (see <cnxn target="element-640"/>). The function <code>textWidth()</code>
	computes the horizontal extension of a character or a
	string. It can be used, together with the exact coordinates
	passed to <code>text()</code>, to control the <term src="http://en.wikipedia.org/wiki/Kerning">kerning</term> and
	the <term src="http://en.wikipedia.org/wiki/Tracking_%28typography%29">tracking</term>
	between characters.  The <code>textSize()</code> allows to
	redefine the size of characters. The
	<code>textLeading()</code> re-defines the distance in pixels
	between adjacent text lines. This distance is measured between
	the <emphasis>baselines</emphasis> of the strings of
	characters. Letters such as "p" or "q" extend below the
	baseline for a number of pixels that can be obtained with the
	<code>textDescent()</code>. Instead, the
	<code>textAscent()</code> gives back the maximum extension
	above the baseline (typically, the height of the letter
	"d").</para><figure id="element-640"><name>Typeface metrics</name>
 <media type="image/png" src="font.png"/>
 <caption>Typeface metrics</caption></figure>

      </section>
   </section>


  <section id="elementi_uditivi">
      <name> Auditory Elements</name>
    <section id="suoni">
    <name>Sounds</name> <para id="suonip">Untill version 112, Processing gave the possibility
    to program several audio functionalities by means of some core primitives. In those older versions only two
    basic primitives are available to playback
    and load <code>.wav</code> files. In more recent versions, Processing delegate sound management and processing functionalities to <link src="http://processing.org/reference/libraries/index.html">external libraries</link>. The most used libraries are <link src="http://www.tree-axis.com/Ess/">Ess</link>, <link src="http://code.compartmental.net/tools/minim/">Minim</link> and
    <link src="http://sonia.pitaru.com/">Sonia</link>.

As in the case of images, in order to process and playback sounds the source files have to be stored in the <code>data</code> folder of the current sketch. 

The library <link src="http://sonia.pitaru.com/"> Sonia
    </link> is the most complex one. With its functions, one can do <emphasis>sample
    playback</emphasis>, realtime Fourier-based spectral analysis,
    <code>.wav</code> file saving. In order to use the Sonia library,
    the programmer has to download the <code>.zip</code> file from
    <link src="http://sonia.pitaru.com/">Sonia</link>. Once
    decompressed, the directory <code>Sonia_?_?</code> has to be
    copied into the directory
    <code>Processing/libraries</code>. Finally, the command
    <code>import</code> has to be inserted into the code by selecting
    it from the menu item <code>Sketch / Import Library /
    Sonia_?_?</code>. <note>In order to run the applets produced with
    Sonia from a web browser, the Phil Burk's JSyn plugin has to be
    downloaded and installed from the site <link src="http://www.softsynth.com/jsyn/plugins/">http://www.softsynth.com/jsyn/plugins/</link>.</note>
    The library <link src="http://code.compartmental.net/tools/minim/">Minim</link>,
    based on <link src="http://java.sun.com/j2se/1.5.0/docs/guide/sound/programmer_guide/contents.html">Java
    Sound</link>, is more user-friendly, well-documented and recommended, if one wants to work with sounds employing high-level primitives, without dealing with low-level numerical details and buffer management.</para>
     </section>


      <section id="timbri"><name>Timbre</name> <para id="timbrop">In
	this section, we first use then analyze an application for the
	exploration of timbres, similar in conception to the Color
	Chooser of <cnxn target="gimp_color"/>, and here called Sound
	Chooser. For the moment, let us think about a sound timbre in
	analogy with color in images. For example, the various instruments of the
	orchestra have different and characterizing timbres (colors). Later on, we
	will define the physical and perceptual aspects of timbre more
	accurately. In the Sound Chooser applet, four sounds with
	different timbres can be played by clicking onto one of the
	marked radii. Each radius corresponds to a musical instrument
	(timbre/color). By changing position along the radius it is
	possible to hear how the brightness is changed. More
	precisely, as long as we proceed toward the centre, the sounds
	gets poorer.
	</para>
      
<para id="timbrop1">Let us analyze the Processing code that
	implements the Sound Chooser in its salient aspects. The
	<code>Sonia.start(this)</code> command is necessary to
	activate the Sonia audio engine. The line <code>Sample
	mySample1</code> declares a variable aimed at containing audio
	samples. Several methods can be applied to such
	variable. Among these, the <code>play</code> methods plays the
	sound sample back. In the <code>draw()</code> code section the
	graphic aspect of the applet is defined. Finally, by the
	function <code>mouseReleased()</code>, we detect when the mouse
	is released after being pressed, and where it has been
	released. At this point a sequenceo of <code>if</code>
	conditions finds what instrument/timbre has been selected
	according to the clicking point. Moreover, within the function
	<code>mouseReleased()</code> the function <code>filtra(float[]
	DATAF, float[] DATA, float RO, float WC)</code> is
	invoked. This function, which is implemented in the last
	segment of the code listing, performs a sound
	filtering. More precisely, it is a low-pass filter, thus a filter that leaves
	the low frequencies unaltered and reduces the intensity of
	the high frequencies. According to the radial position of the
	mouse click, the filtering effect changes, being more dramatic
	(that is the sound becomes darker) as the mouse is released closer and closer to the
	centre.

A lighter realization of the Sound Chooser by means of the library Minim is proposed in problem <cnxn target="minimproblem"/>. 

</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">Trumpet</link></entry>
		    </row>
		    <row>
		      <entry><link src="./oboe.wav">Oboe</link></entry>
		    </row>
		    <row>
		      <entry><link src="./violino.wav">Violin</link></entry>
		    </row>
		    <row>
		      <entry><link src="./flauto.aif">Flute</link></entry>
		    </row>
		    <row>
		      <entry>
		      <link src="./sound_chooser.html">Applet:
		    choosing a timbre and controlling its 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];
	  //recursive filtering 
  }
}

// safely stop the Sonia engine upon shutdown.
public void stop(){
  Sonia.stop();
  super.stop();
  }
            
             ]]>	      
	    </code>
		    </entry>
		  </row>
		</tbody>
	      </tgroup>
	    </table>   
  </section>
      <exercise id="gondolierproblem">
	<problem>
	  <para id="gprobp">
	    The content of a <code>PImage</code> object is accessible
	    through its <code>pixels[]</code> field. The pixels,
	    corresponding to a row-by-row reading of the image, are
	    contained in this array of size
	    <code>width*height</code>. Modify the code in <cnxn target="gondolieri_ex2"/> to use the field
	    <code>pixels[]</code> instead of the method
	    <code>get()</code>. The final outcome should remain the
	    same.
	  </para>
	</problem>
	<solution>
	  <para id="gsolp">
	    The invocation <code>b.set()</code> should be replaced by
	    <code type="block">
	       b.set(i,j,b.pixels[j*b.width+i]+ color(0,0,0, 255 - (int)((1-ramp)*255)) );
	    </code>
	  </para>
	</solution>
      </exercise>
      <exercise id="soniaproblem1">
	<problem>
	  <para id="prob1p">Complete the code reported in 
	  <cnxn target="sound_chooser"/> to obtain the complete
	  Sound Chooser applet.</para>
	</problem>
	<solution>
	  <para id="sol1p"> <link src="./sound_chooser.pde">Processing source code.  </link>
	  </para>
	</solution>
      </exercise>
      <exercise id="soniaproblem2">
	<problem>
	  <para id="prob2p">
	    Add some color to the radii of the Sound Chooser, by
	    replacing the <code>line</code> instructions with
	    <code>rect</code> instructions and coloring the bars with
	    a brightness that increases goint from the centre to the
	    periphery. </para>
	</problem>
	<solution><para id="sol2p"> <link src="./sound_chooser_color.html">Applet with Processing source code.
</link> </para>
	</solution>
      </exercise>


      <exercise id="minimproblem">
	<problem>
	  <para id="probMin">Produce a new version of the Sound Chooser of problem <cnxn target="soniaproblem1"/> employing the library Minim. Note the gained compact form and simplicity of the code.
 </para>
	</problem>
	<solution><para id="solMin"> 
	    <code type="block"><![CDATA[    
import ddf.minim.*;
import ddf.minim.effects.*;

AudioPlayer mySample1, mySample2, mySample3, mySample4;
LowPassSP lpf1, lpf2, lpf3, lpf4;
float cutoff1, cutoff2, cutoff3, cutoff4;

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

  mySample1 = Minim.loadFile("flauto.aif");
    mySample2 = Minim.loadFile("oboe.wav");
      mySample3 = Minim.loadFile("tromba.wav");
        mySample4 = Minim.loadFile("violino.wav");
        
  lpf1 = new LowPassSP(4000, mySample1.sampleRate());
  lpf2 = new LowPassSP(4000, mySample2.sampleRate());
  lpf3 = new LowPassSP(4000, mySample3.sampleRate());
  lpf4 = new LowPassSP(4000, mySample4.sampleRate());
  mySample1.addEffect(lpf1);
  mySample2.addEffect(lpf2);
  mySample3.addEffect(lpf3);
  mySample4.addEffect(lpf4);
  
}

void draw()
{
  stroke(255);
  strokeWeight(1);
  fill(0, 88, 88);
  ellipseMode(CORNER);
  ellipse(50,50,100,100);

  beginShape(LINES);
  vertex(50, 100);
  vertex(90, 100);

  vertex(110, 100);
  vertex(150, 100);

  vertex(100, 50);
  vertex(100, 90);

  vertex(100, 110);
  vertex(100, 150);
  endShape();
}

void mouseReleased()
{

  // FLUTE
  if ((mouseX > 95) && (mouseX < 105)&& (mouseY > 50)&& (mouseY < 90)) {  
    cutoff1 = map(mouseY, 50, 90, 1000, 30);
    lpf1.setFreq(cutoff1);
    println(mouseY + " +  " +cutoff1);
    mySample1.rewind();
    mySample1.play();  
  }

  // OBOE
  if ((mouseX > 110) && (mouseX < 149)&& (mouseY > 95)&& (mouseY < 105)) {
    cutoff2 = map(mouseX, 110, 149, 30, 1000);
    lpf2.setFreq(cutoff2);
    println(mouseX + " +  " +cutoff2);
    mySample2.rewind();
    mySample2.play(); 
  }

  // TRUMPET
  if ((mouseX > 95) && (mouseX < 105)&& (mouseY > 110)&& (mouseY < 149)) {
    cutoff3 = map(mouseY, 110, 149, 30, 1000);
    lpf3.setFreq(cutoff3);
    println(mouseY + " +  " +cutoff3);
    mySample3.rewind();
    mySample3.play();
  }

  // VIOLIN
  if ((mouseX > 50) && (mouseX < 90)&& (mouseY > 95)&& (mouseY < 105)) {
    cutoff4 = map(mouseX, 50, 90, 1000, 30);
    lpf4.setFreq(cutoff4);
    println(mouseX + " +  " +cutoff4);
    mySample4.rewind();
    mySample4.play(); 
  }
}

// safely stop the Minim engine upon shutdown.
public void stop(){
  mySample1.close();
  mySample2.close();
  mySample3.close();
  mySample4.close();
  Minim.stop();
  super.stop();
  
}

	      ]]>	      
	    </code>  
	  </para>
	</solution>
      </exercise>

</section>
</content>
  
</document>
