<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nightly build &#187; Code</title>
	<atom:link href="http://slack.codemaniacs.com/blog/category/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://slack.codemaniacs.com/blog</link>
	<description>&#34;Give me six hours to chop down a tree and I will spend the first four sharpening the axe.&#34; - Abraham Lincoln</description>
	<lastBuildDate>Wed, 16 Dec 2009 12:24:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>ResaCON 2009</title>
		<link>http://slack.codemaniacs.com/blog/2009/12/15/resacon-2009/</link>
		<comments>http://slack.codemaniacs.com/blog/2009/12/15/resacon-2009/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 01:16:47 +0000</pubDate>
		<dc:creator>slack</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Demoscene]]></category>
		<category><![CDATA[Stories]]></category>

		<guid isPermaLink="false">http://slack.codemaniacs.com/blog/?p=66</guid>
		<description><![CDATA[Todo surgió de esta idea: Con lo interesantes que se ponen las conversaciones a veces cuando nos vamos de cena, ¿por qué no montamos una con y nos contamos las cosas que hacemos como $DEITY manda? Después de un periodo de incertidumbre y de apurar un poco con las fechas (una deadline es una deadline [...]]]></description>
			<content:encoded><![CDATA[<p>Todo surgió de esta idea:</p>
<blockquote><p>
Con lo interesantes que se ponen las conversaciones a veces cuando nos vamos de cena, ¿por qué no montamos una <a href="http://en.wikipedia.org/wiki/Convention_%28meeting%29">con</a> y nos contamos las cosas que hacemos como $DEITY manda?
</p></blockquote>
<p>Después de un periodo de incertidumbre y de apurar un poco con las fechas (una deadline es una deadline al fin y al cabo), el pasado fin de semana tuvo lugar la ResaCON 2009: once amigos y yo, cada uno con una presentación bajo el brazo, una pantalla grande, una nevera con refrescos y algo para picar. El resultado fue espectacular: se habló de gráficos, IA, emulación, videojuegos, lenguajes de programación, robotitos, proyectos personales varios, silverlight, profiling y hasta de creación de empresas&#8230; todo ello en un ambiente familiar y distendido.</p>
<p>Por supuesto luego hubo tiempo para irnos de cena y de fiesta :D</p>
<p>En definitiva, he disfrutado de lo lindo y espero que repitamos el año que viene (¡muchas gracias a todos, moláis un gritón!) . En los próximos días subiré a algún sitio las presentaciones que me dejen subir, permanezcan en sintonía. De momento os dejo con un enlace a mi presentación de <a href="http://slack.codemaniacs.com/misc/resacon2009_clojure">introducción a Clojure</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://slack.codemaniacs.com/blog/2009/12/15/resacon-2009/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Valgrind: tracking the origin of undefined values</title>
		<link>http://slack.codemaniacs.com/blog/2009/10/16/valgrind-tracking-the-origin-of-undefined-values/</link>
		<comments>http://slack.codemaniacs.com/blog/2009/10/16/valgrind-tracking-the-origin-of-undefined-values/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 15:55:49 +0000</pubDate>
		<dc:creator>slack</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://slack.codemaniacs.com/blog/?p=51</guid>
		<description><![CDATA[Today I was wondering if one of those warnings about uninitialized values was located in library code or in my own code, and I noticed a new message in Valgrind&#8217;s output: Use –track-origins=yes to see where uninitialised values come from This feature was first added to Valgrind 3.4.0 back in January, and it&#8217;s great! I [...]]]></description>
			<content:encoded><![CDATA[<p>Today I was wondering if one of those warnings about uninitialized values was located in library code or in my own code, and I noticed a new message in Valgrind&#8217;s output:</p>
<pre>
Use –track-origins=yes to see where uninitialised values come from
</pre>
<p>This feature was first added to Valgrind 3.4.0 back in January, and it&#8217;s great! I wish I had known it before, because it would have spent me a few headaches in the past months, so I decided to write it here just in case I can help someone :)</p>
]]></content:encoded>
			<wfw:commentRss>http://slack.codemaniacs.com/blog/2009/10/16/valgrind-tracking-the-origin-of-undefined-values/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>crash handling</title>
		<link>http://slack.codemaniacs.com/blog/2009/07/01/crash-handling/</link>
		<comments>http://slack.codemaniacs.com/blog/2009/07/01/crash-handling/#comments</comments>
		<pubDate>Wed, 01 Jul 2009 00:07:36 +0000</pubDate>
		<dc:creator>slack</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://slack.codemaniacs.com/blog/?p=34</guid>
		<description><![CDATA[Estaba yo preguntándome esta tarde si sería posible lanzar de forma automática gdb cuando un programa cascara, sin necesidad de ponerse a depurar después, reproducir el bug, etc, al estilo del manejador de errores que instala Visual Studio en Windows que pregunta si se desea depurar la aplicación. Me ha salido algo como esto (HTML [...]]]></description>
			<content:encoded><![CDATA[<p>Estaba yo preguntándome esta tarde si sería posible lanzar de forma automática <code>gdb</code> cuando un programa cascara, sin necesidad de ponerse a depurar después, reproducir el bug, etc, al estilo del manejador de errores que instala Visual Studio en Windows que pregunta si se desea depurar la aplicación.</p>
<p>Me ha salido algo como esto (HTML horrible para el coloreado de sintaxis patrocinado por Vim):<br />
<font face="monospace"><br />
</font><font color="#a020f0">#include </font><font color="#ff00ff">&lt;sys/types.h&gt;</font><br />
<font color="#a020f0">#include </font><font color="#ff00ff">&lt;unistd.h&gt;</font><br />
<font color="#a020f0">#include </font><font color="#ff00ff">&lt;signal.h&gt;</font><br />
<font color="#a020f0">#include </font><font color="#ff00ff">&lt;stdio.h&gt;</font><br />
<font color="#a020f0">#include </font><font color="#ff00ff">&lt;stdlib.h&gt;</font></p>
<p><font color="#2e8b57"><b>void</b></font>&nbsp;attach_gdb(<font color="#2e8b57"><b>int</b></font>&nbsp;signum)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;pid_t gdbpid;<br />
&nbsp;&nbsp;&nbsp;&nbsp;pid_t debuggee_pid = getpid();<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#2e8b57"><b>int</b></font>&nbsp;gdb_exit_status;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#2e8b57"><b>char</b></font>&nbsp;pidbuf[<font color="#ff00ff">100</font>];<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#2e8b57"><b>char</b></font>&nbsp;exebuf[<font color="#ff00ff">100</font>]; <font color="#0000ff">// should be safe unless PIDs reach ~90 digits ;P</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;sprintf(pidbuf, <font color="#ff00ff">&quot;</font><font color="#6a5acd">%d</font><font color="#ff00ff">&quot;</font>, debuggee_pid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;sprintf(exebuf, <font color="#ff00ff">&quot;/proc/</font><font color="#6a5acd">%d</font><font color="#ff00ff">/exe&quot;</font>, debuggee_pid);<br />
&nbsp;&nbsp;&nbsp;&nbsp;printf(<font color="#ff00ff">&quot;Signal </font><font color="#6a5acd">%d</font><font color="#ff00ff">&nbsp;received. Attaching GDB to process. PID=</font><font color="#6a5acd">%d</font><font color="#6a5acd">\n</font><font color="#ff00ff">&quot;</font>, signum, debuggee_pid);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#a52a2a"><b>if</b></font>&nbsp;((gdbpid = fork()) == <font color="#ff00ff">0</font>)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;execlp(<font color="#ff00ff">&quot;gdb&quot;</font>, <font color="#ff00ff">&quot;gdb&quot;</font>, exebuf, pidbuf, <font color="#ff00ff">NULL</font>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(<font color="#ff00ff">&quot;execlp&quot;</font>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(<font color="#ff00ff">1</font>);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;waitpid(gdbpid, &amp;gdb_exit_status, <font color="#ff00ff">0</font>); <font color="#0000ff">// hold on, we want to be debugged</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;exit(<font color="#ff00ff">1</font>);<br />
}</p>
<p><font color="#2e8b57"><b>void</b></font>&nbsp;__attribute__((constructor)) setup_handler()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#2e8b57"><b>struct</b></font>&nbsp;sigaction sa, old_sa;<br />
&nbsp;&nbsp;&nbsp;&nbsp;sa.sa_handler = attach_gdb;<br />
&nbsp;&nbsp;&nbsp;&nbsp;sigemptyset(&amp;sa.sa_mask);<br />
&nbsp;&nbsp;&nbsp;&nbsp;sa.sa_flags=<font color="#ff00ff">0</font>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">// Register the handler for all actions which dump core by default</font><br />
&nbsp;&nbsp;&nbsp;&nbsp;sigaction(<font color="#ff00ff">SIGSEGV</font>, &amp;sa, &amp;old_sa);<br />
&nbsp;&nbsp;&nbsp;&nbsp;sigaction(<font color="#ff00ff">SIGFPE</font>, &amp;sa, &amp;old_sa);<br />
&nbsp;&nbsp;&nbsp;&nbsp;sigaction(<font color="#ff00ff">SIGABRT</font>, &amp;sa, &amp;old_sa);<br />
&nbsp;&nbsp;&nbsp;&nbsp;sigaction(<font color="#ff00ff">SIGILL</font>, &amp;sa, &amp;old_sa);<br />
&nbsp;&nbsp;&nbsp;&nbsp;sigaction(<font color="#ff00ff">SIGQUIT</font>, &amp;sa, &amp;old_sa);<br />
}</p>
<p>Si se compila como librería dinámica y se enlaza a cualquiera de nuestros programas (o se precarga con <code>LD_PRELOAD</code>) lanza un <code>gdb</code> asociado al proceso al recibir cualquiera de las señales que causarían un core dump y terminación del programa :D.</p>
<p>¿Alguna idea para mejorarlo y que sea práctico? ¿Existe ya algo asi en un paquete Debian que hace mil cosas molonas más? (seguro que sí XD).</p>
]]></content:encoded>
			<wfw:commentRss>http://slack.codemaniacs.com/blog/2009/07/01/crash-handling/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Jugando con Qt</title>
		<link>http://slack.codemaniacs.com/blog/2009/03/13/jugando-con-qt/</link>
		<comments>http://slack.codemaniacs.com/blog/2009/03/13/jugando-con-qt/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 03:16:34 +0000</pubDate>
		<dc:creator>slack</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[wenboi]]></category>

		<guid isPermaLink="false">http://slack.codemaniacs.com/blog/?p=29</guid>
		<description><![CDATA[El otro día me encontré con edb (una especie de OllyDbg para linux) y al ver la buena pinta que tenía me acordé de lo bonito que sería tener una interfaz gráfica para depurar en mi emulador de GameBoy. Me he puesto a juguetear con Qt y me está gustando. Está muy bien documentada y [...]]]></description>
			<content:encoded><![CDATA[<p>El otro día me encontré con <a href="http://www.codef00.com/projects.php#Debugger">edb</a> (una especie de OllyDbg para linux) y al ver la buena pinta que tenía me acordé de lo bonito que sería tener una interfaz gráfica para depurar en mi <a href="http://slack.codemaniacs.com/wenboi">emulador de GameBoy</a>. Me he puesto a juguetear con Qt y me está gustando. Está muy bien documentada y es bastante agradable de usar, una vez se pasa el susto de ver esas cosas raras como &#8220;public slots:&#8221; en mitad de la declaración de una clase en C++. </p>
<p>De momento he conseguido integrar el emu en una ventana de Qt, el redibujado va bastante más rápido de lo que me esperaba, y tengo el emulador en un hilo y la parte gráfica en otro. Ahora me falta empezar de verdad con el debugger. Ahi va un shot :)</p>
<p><img src="http://slack.codemaniacs.com/wenboi/shots/qtboi1.png" alt="qtboi screenshot" /></p>
]]></content:encoded>
			<wfw:commentRss>http://slack.codemaniacs.com/blog/2009/03/13/jugando-con-qt/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>wenboi</title>
		<link>http://slack.codemaniacs.com/blog/2008/09/24/wenboi/</link>
		<comments>http://slack.codemaniacs.com/blog/2008/09/24/wenboi/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 22:50:02 +0000</pubDate>
		<dc:creator>slack</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[wenboi]]></category>
		<category><![CDATA[emulation]]></category>

		<guid isPermaLink="false">http://slack.codemaniacs.com/blog/?p=25</guid>
		<description><![CDATA[Llevo algún tiempo escribiendo a ratos un emulador de Game Boy. Me picaba el tema de la emulación y shash me había comentado que la Game Boy era facililla de emular y me pasó algo de documentación. Pues bien, ha llegado el momento de que vea la luz. Con todos ustedes&#8230; wenboi! Todavía está en [...]]]></description>
			<content:encoded><![CDATA[<p>Llevo algún tiempo escribiendo a ratos un emulador de Game Boy. Me picaba el tema de la emulación y shash me había comentado que la Game Boy era facililla de emular y me pasó algo de documentación. Pues bien, ha llegado el momento de que vea la luz. Con todos ustedes&#8230; wenboi!</p>
<p><img src="http://slack.codemaniacs.com/wenboi/shots/shot6.jpg" alt="wenboi screenshot" /></p>
<p>Todavía está en pañales pero ya se puede empezar una partida de Tetris y colocar piezas, y es éste el hito que me ha llevado a poner la etiqueta de &#8220;version 0.1&#8243; y hablar un poquito del emulador aqui ;)</p>
<p>Por si alguien quiere cotillear, he creado una pequeña <a href="http://slack.codemaniacs.com/wenboi">homepage de wenboi</a> con información sobre el acceso al repositorio de <a href="http://git.or.gz">Git</a> y tambien he dado de alta a <a href="https://www.ohloh.net/projects/wenboi">wenboi en Ohloh</a> para que me analicen el repositorio, me saquen graficos de actividad y me digan que pongo pocos comentarios en el código. También hay un pequeño devlog que no sé si actualizaré demasiado.</p>
<p>Happy hacking!</p>
]]></content:encoded>
			<wfw:commentRss>http://slack.codemaniacs.com/blog/2008/09/24/wenboi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ctypes</title>
		<link>http://slack.codemaniacs.com/blog/2008/06/06/ctypes/</link>
		<comments>http://slack.codemaniacs.com/blog/2008/06/06/ctypes/#comments</comments>
		<pubDate>Fri, 06 Jun 2008 18:40:58 +0000</pubDate>
		<dc:creator>slack</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://slack.codemaniacs.com/blog/?p=24</guid>
		<description><![CDATA[El otro día me encontré con un módulo interesante de python que no conocía: ctypes. Sirve para comunicarse con librerías en C: permite cargar librerías dinámicas y llamar a sus funciones, definir tipos equivalentes a los de C para pasarlos de un lado a otro e incluso especificar funciones python como callbacks de C. Vamos, [...]]]></description>
			<content:encoded><![CDATA[<p>El otro día me encontré con un módulo interesante de python que no conocía: ctypes. Sirve para comunicarse con librerías en C: permite cargar librerías dinámicas y llamar a sus funciones, definir tipos equivalentes a los de C para pasarlos de un lado a otro e incluso especificar funciones python como callbacks de C. Vamos, que se pueden crear <i>bindings</i> a librerías externas escribiendo únicamente código python.</p>
<p>Ahi va un ejemplillo tonto usando la libavformat:</p>
<pre>
#!/usr/bin/python
import sys
from ctypes import *
import ctypes.util

av = CDLL(ctypes.util.find_library("avformat"))
filename = sys.argv[1]
# pFormatCtx deberia ser un puntero a AVFormatContext,
# pero esto es solo un ejemplo simple :)
pFormatCtx = c_void_p() 

av.av_register_all()
av.av_open_input_file(byref(pFormatCtx), filename, None, 0, None)
av.dump_format(pFormatCtx, 0, filename, 0)
</pre>
<p>Por supuesto para hacer algo más serio habría que declarar en python las estructuras como AVFormatContext que se definen en las cabeceras correspondientes y cosas así, pero entonces el programa de ejemplo sería demasiado engorroso como para leerlo en un blog ;). El ejemplo muestra una salida como esta:</p>
<pre>
$ ./av.py test.avi
Input #0, avi, from 'test.avi':
  Duration: N/A, bitrate: N/A
  Stream #0.0: Video: mpeg4, 512x420,   inf fps(c)
  Stream #0.1: Audio: vorbis, 22050 Hz, stereo, 24 kb/s
</pre>
<p>Referencias:</p>
<ul>
<li><a href="http://docs.python.org/lib/ctypes-ctypes-tutorial.html">Tutorial de ctypes</a></li>
<li><a href="http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html">Using libavformat and libavcodec</a></li>
<li><a href="http://www.inb.uni-luebeck.de/~boehme/libavcodec_update.html">Using libavformat and libavcodec: An Update</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://slack.codemaniacs.com/blog/2008/06/06/ctypes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Síntesis musical para mí (o para torpes en general :) III</title>
		<link>http://slack.codemaniacs.com/blog/2007/05/24/sintesis-musical-para-mi-o-para-torpes-en-general-iii/</link>
		<comments>http://slack.codemaniacs.com/blog/2007/05/24/sintesis-musical-para-mi-o-para-torpes-en-general-iii/#comments</comments>
		<pubDate>Thu, 24 May 2007 14:30:22 +0000</pubDate>
		<dc:creator>slack</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Demoscene]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Music]]></category>

		<guid isPermaLink="false">http://slack.codemaniacs.com/blog/2007/05/24/sintesis-musical-para-mi-o-para-torpes-en-general-iii/</guid>
		<description><![CDATA[3) Más ondas básicas No solo de senos vive el hombre (salvo que nos pongamos a hacer síntesis aditiva), así que vamos a ver unas cuantas ondas más que podemos utilizar como base para construir sonidos. Onda cuadrada: Get the Flash Player to see this player. var FO = { movie:"https://media.dreamhost.com/mediaplayer.swf",width:"200",height:"20",majorversion:"7",build:"0",bgcolor:"#FFFFFF", flashvars:"file=http://slack.codemaniacs.com/misc/tutorial_sintesis/square.mp3&#38;showdigits=true&#38;autostart=false" }; UFO.create(FO,"square.mp3"); Se [...]]]></description>
			<content:encoded><![CDATA[<p><strong>3) Más ondas básicas</strong></p>
<p>No solo de senos vive el hombre (salvo que nos pongamos a hacer síntesis aditiva), así que vamos a ver unas cuantas ondas más que podemos utilizar como base para construir sonidos.</p>
<ul>
<li><b><a href="http://en.wikipedia.org/wiki/Square_wave">Onda cuadrada</a>:</b>
<p><script type="text/javascript" src="https://media.dreamhost.com/ufo.js"></script></p>
<p id="square.mp3"><a href="http://www.macromedia.com/go/getflashplayer">Get the Flash Player</a> to see this player.</p>
<p><script type="text/javascript">
  var FO = { movie:"https://media.dreamhost.com/mediaplayer.swf",width:"200",height:"20",majorversion:"7",build:"0",bgcolor:"#FFFFFF",
flashvars:"file=http://slack.codemaniacs.com/misc/tutorial_sintesis/square.mp3&amp;showdigits=true&amp;autostart=false" };
UFO.create(FO,"square.mp3");
</script></p>
<p>Se obtiene alternando dos valores (en nuestro caso +1 y -1) con la frecuencia deseada. Expresado en código, podría ser algo como esto:</p>
<blockquote><pre>
// Generacion del i-esimo sample de una onda cuadrada
// de frecuencia f
float t = i/sampling_rate; // instante i en segundos
float periodo = 1.0f / f; // periodo de la onda en segundos
if (fmodf(t,periodo) &lt; periodo/2.0f)
    y[i] = 1.0f;
else
    y[i] = -1.0f;
</pre>
</blockquote>
<p><img src="http://slack.codemaniacs.com/images/tutorial_sintesis/square.png" alt="Onda cuadrada." /></p>
<p>Otra posibilidad es hacer que las zonas a +1 y -1 no tengan la misma longitud (<a href="http://en.wikipedia.org/wiki/Pulse_width_modulation">pulse width modulation</a>)
</li>
<li><b><a href="http://en.wikipedia.org/wiki/Sawtooth_wave">Onda de diente de sierra</a>:</b>
<p id="sawtooth.mp3"><a href="http://www.macromedia.com/go/getflashplayer">Get the Flash Player</a> to see this player.</p>
<p><script type="text/javascript">
  var FO = { movie:"https://media.dreamhost.com/mediaplayer.swf",width:"200",height:"20",majorversion:"7",build:"0",bgcolor:"#FFFFFF",
flashvars:"file=http://slack.codemaniacs.com/misc/tutorial_sintesis/sawtooth.mp3&amp;showdigits=true&amp;autostart=false" };
UFO.create(FO,"sawtooth.mp3");
</script></p>
<p>En cada periodo, aumenta linealmente desde -1 a 1, cayendo bruscamente a -1 en el comienzo del siguiente periodo. Dicho en C viene a ser:</p>
<blockquote><pre>
// Sample i-esimo, frecuencia f
float t = i/sampling_rate;
float periodo = 1.0f / f;
y[i] = 2.0f*(fmodf(t, periodo)/periodo)-1.0f;
</pre>
</blockquote>
<p><img src="http://slack.codemaniacs.com/images/tutorial_sintesis/sawtooth.png" alt="Onda de diente de sierra." /></p>
</li>
<li><b><a href="http://en.wikipedia.org/wiki/Triangle_wave">Onda triangular</a>:</b>
<p id="triangle.mp3"><a href="http://www.macromedia.com/go/getflashplayer">Get the Flash Player</a> to see this player.</p>
<p><script type="text/javascript">
  var FO = { movie:"https://media.dreamhost.com/mediaplayer.swf",width:"200",height:"20",majorversion:"7",build:"0",bgcolor:"#FFFFFF",
flashvars:"file=http://slack.codemaniacs.com/misc/tutorial_sintesis/triangle.mp3&amp;showdigits=true&amp;autostart=false" };
UFO.create(FO,"triangle.mp3");
</script></p>
<p>Es parecida a la anterior, pero durante la mitad del periodo crece linealmente de -1 a 1, y durante la otra mitad decrece linealmente volviendo a -1, sin discontinuidad.</p>
<blockquote><pre>
// Sample i-esimo, frecuencia f
float t = i/sampling_rate;
float periodo = 1.0 / f;
float semiperiodo = periodo/2.0f;
if (fmodf(t,periodo) &lt; periodo/2.0f)
    y[i] = 2.0f*(fmodf(t,semiperiodo)/semiperiodo)-1.0f;
else
    y[i] = 1.0f-2.0f*fmod(t,semiperiodo)/semiperiodo;
</pre>
</blockquote>
<p><img src="http://slack.codemaniacs.com/images/tutorial_sintesis/triangle.png" alt="Onda triangular." />
</li>
</ul>
<p>En el <a href="http://slack.codemaniacs.com/misc/tutorial_sintesis/sintesis03_ondas.zip"> programa de ejemplo</a> de este capítulo (ahora con un 100% más de Makefile) está todo esto en forma compilable para poder probarlo fácilmente. Por cierto, ninguno de los ejemplos está optimizado porque pretenden ser lo más claros posible, si alguien tiene sugerencias sobre como implementar mejor cualquier cosa nos lo podemos pasar muy bien comentándolas :)</p>
<p>En fin, esto es todo por hoy. En el próximo post, cosillas sobre espectros de frecuencias y aliasing (supongo que la pereza me obligará a dejarme los filtros para dentro de dos posts :)</p>
<p><strong>EDIT:</strong> A peticion de pplux, ahi van los enlaces a los posts anteriores:</p>
<ul>
<li><a href="http://slack.codemaniacs.com/blog/2007/04/22/sintesis-musical-para-mi-o-para-torpes-en-general-ii/">Parte II: Senos!!!</a></li>
<li><a href="http://slack.codemaniacs.com/blog/2007/04/17/sintesis-de-audio-para-mi-o-para-torpes-en-general/">Parte I: Haciendo ruido</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://slack.codemaniacs.com/blog/2007/05/24/sintesis-musical-para-mi-o-para-torpes-en-general-iii/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Síntesis musical para mí (o para torpes en general :) II</title>
		<link>http://slack.codemaniacs.com/blog/2007/04/22/sintesis-musical-para-mi-o-para-torpes-en-general-ii/</link>
		<comments>http://slack.codemaniacs.com/blog/2007/04/22/sintesis-musical-para-mi-o-para-torpes-en-general-ii/#comments</comments>
		<pubDate>Sun, 22 Apr 2007 01:41:40 +0000</pubDate>
		<dc:creator>slack</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Demoscene]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Music]]></category>

		<guid isPermaLink="false">http://slack.codemaniacs.com/blog/2007/04/22/sintesis-musical-para-mi-o-para-torpes-en-general-ii/</guid>
		<description><![CDATA[2) Senos!!! Después del ruido del capitulo anterior, vamos a pasar a algo ligeramente más interesante: la onda senoidal. Como podéis ver si seguís el enlace a la pagina sobre la onda senoidal en la wikipedia, junto con dibujitos y explicaciones interesantes, la formula es: y = A·sin(w·t + fase) donde A es la amplitud [...]]]></description>
			<content:encoded><![CDATA[<p><strong>2) Senos!!! </strong></p>
<p>Después del ruido del capitulo anterior, vamos a pasar a algo ligeramente más interesante: la <a href="http://en.wikipedia.org/wiki/Sine_wave">onda senoidal</a>. Como podéis ver si seguís el enlace a la pagina sobre la onda senoidal en la wikipedia, junto con dibujitos y explicaciones interesantes, la formula es:</p>
<blockquote><p> <em>y</em> = <em>A</em>·sin(<em>w·t</em> + <em>fase</em>) </p></blockquote>
<p>donde <em>A</em> es la amplitud de la onda (la distancia entre una cresta y un valle), <em>w</em> es la frecuencia en radianes/segundo y <em>t</em> es el tiempo. Vamos a ignorar la fase porque no nos hace falta :)</p>
<p>Como nos gusta trabajar con frecuencias en hercios, multiplicamos por 2·pi. Además, tenemos que t = samples generados / frecuencia de muestreo. Por lo tanto en el código tendremos algo como:</p>
<blockquote><p> y[i] = A*sin(2*pi*frecuencia*(i/sampling_rate))</p></blockquote>
<p>para el sample i-ésimo desde el inicio del sonido. Vamos a ver el trozo de código correspondiente (lo que falta es, básicamente, la inicialización del capítulo anterior):</p>
<pre>
void play(void *userdata, Uint8 *stream, int len)
{
    int num_samples = len / 2;
    Sint16 *dst_buf = (Sint16*) stream;
    for (int i=0; i&lt;num_samples ; ++i)
        buffer[i] = sin(2.0*M_PI*440.0f*(i+pos)/(float)SAMPLING_RATE);

    // Clipping y conversion a Sint16
    for (int i=0; i&lt;num_samples; ++i)
    {
        float v = buffer[i];
        if (v &gt; 1.0f)
            v = 1.0f;
        else if (v&lt; -1.0f)
            v = -1.0f;

        dst_buf[i] = (Sint16)(32767.0f*v);
    }
    pos += num_samples;

}
</pre>
<p>Detalles destacables de esta función:</p>
<ul>
<li>se trabaja con un buffer de floats y se convierte a entero al final. No mola ir perdiendo precisión por el camino, sobre todo cuando hagamos cosas mas complejas</li>
<li>hay clipping a [-1.0, 1.0]. Ahora mismo es completamente innecesario porque sin() devuelve valores en ese intervalo, pero cuando empecemos a mezclar varios sonidos vendrá bien :) </li>
<li>en la llamada a sin(), el 440.0f es la <a href="http://en.wikipedia.org/wiki/Piano_key_frequencies">frecuencia</a> de la nota que suena (un <a href="http://en.wikipedia.org/wiki/A440">La4</a>), y pos es una variable global que guarda el índice del ultimo sample generado entre llamadas a play(). Es feo, pero para un ejemplo pequeño va bien.
</li>
</ul>
<p>En el próximo episodio (ahora es tarde y tengo sueño), veremos otros osciladores típicos y cosas interesantes que se pueden hacer con ellos.</p>
<p><b>EDIT:</b> <a href="http://herotyc.com/">herotyc</a> me ha enviado una <a href="http://slack.codemaniacs.com/misc/tutorial_sintesis/sintesis02_senos.c">versión stand-alone del ejemplo</a> de este capítulo. ¡Muchas gracias! :)</p>
]]></content:encoded>
			<wfw:commentRss>http://slack.codemaniacs.com/blog/2007/04/22/sintesis-musical-para-mi-o-para-torpes-en-general-ii/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Síntesis musical para mí (o para torpes en general :)</title>
		<link>http://slack.codemaniacs.com/blog/2007/04/17/sintesis-de-audio-para-mi-o-para-torpes-en-general/</link>
		<comments>http://slack.codemaniacs.com/blog/2007/04/17/sintesis-de-audio-para-mi-o-para-torpes-en-general/#comments</comments>
		<pubDate>Tue, 17 Apr 2007 17:34:37 +0000</pubDate>
		<dc:creator>slack</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Demoscene]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Music]]></category>

		<guid isPermaLink="false">http://slack.codemaniacs.com/blog/2007/04/17/sintesis-de-audio-para-mi-o-para-torpes-en-general/</guid>
		<description><![CDATA[Por petición popular (hola pplux) voy a hacer una pequeña introducción a la síntesis de audio desde el punto de vista de un coder sin experiencia previa en DSP que pretende hacer un sintetizador para intros de 4k (yo). Por supuesto, incluirá ejemplos de código. C99 y SDL for teh win. 0) Disclaimer Esto no [...]]]></description>
			<content:encoded><![CDATA[<p>Por petición popular (hola pplux) voy a hacer una pequeña introducción a la síntesis de audio desde el punto de vista de un coder sin experiencia previa en DSP que pretende hacer un sintetizador para intros de 4k (yo). Por supuesto, incluirá ejemplos de código. C99 y SDL for teh win.</p>
<p><strong>0) Disclaimer</strong><br />
Esto no tiene por qué ser la forma correcta de hacer las cosas. Hasta donde yo sé funciona, pero seguro que hay muchos fallos en muchos sitios. Son bienvenidos los comentarios, tanto para corregirme los fallos como para comentar cualquier otra cosa al respecto :). Y como se suele decir en estos casos, si alguno de los ejemplos de código rompe algo o deja sordo a alguien yo no me hago responsable.</p>
<p><strong>1) Haciendo ruido</strong></p>
<p>En primer lugar, el clásico trozo de codigo de inicialización que todo el mundo copia y pega y nadie lee:</p>
<p><code></p>
<pre>
#include "SDL.h"

#define BUFFER_SIZE 1024    // Longitud del buffer, en samples

// Este comentario esta extraido de SDL_audio.h, porque me ha molado
/* This function is called when the audio device needs more data.
 * 'stream' is a pointer to the audio data buffer
 * 'len' is the length of that buffer in bytes.
 * Once the callback returns, the buffer will no longer be valid.
 * Stereo samples are stored in a LRLRLR ordering.
 */
void play(void *userdata, Uint8 *stream, int len)
{
    int num_samples = len / 2;
    Sint16 *buf = (Sint16*) stream;
    for (int i = 0; i&lt;num_samples ; ++i)
        buf[i] = rand()%65535-32768;

}

int main(int argc, char **argv)
{
    SDL_AudioSpec desired;
    desired.freq     = 44100;        // Frecuencia de muestreo
    desired.format   = AUDIO_S16SYS; // Formato de las muestras
    desired.channels = 1;            // Numero de canales
    desired.samples  = BUFFER_SIZE;  // Tamaño del buffer en samples
                                     // (potencia de 2)
    desired.callback = play;         // Callback
    desired.userdata = NULL;         // Puntero a datos

    SDL_Init(SDL_INIT_AUDIO);
    SDL_OpenAudio(&#038;desired, NULL);
    SDL_PauseAudio(0);
    getchar();
    SDL_PauseAudio(1);
    SDL_CloseAudio();
    SDL_Quit();
}
</pre>
<p></code></p>
<p>La parte importante esta en buf[i] = rand()%65535-32768; Como hemos elegido AUDIO_S16SYS significa que utilizamos muestras de 16 bits con signo [-32768, 32767], con endianismo dependiente del sistema (como accedemos al buffer con punteros a entero de 16 bits, el endianismo no será problema). Generamos numeros aleatorios en ese rango y ya tenemos <a href="http://en.wikipedia.org/wiki/White_noise">ruido blanco</a> saliendo de nuestros altavoces.</p>
<p>No se pierdan el proximo episodio.</p>
<p><strong>EDIT:</strong> He cambiado el titulo, de &#8220;sintesis de audio&#8221; a &#8220;sintesis musical&#8221; porque lo primero era demasiado general :)</p>
]]></content:encoded>
			<wfw:commentRss>http://slack.codemaniacs.com/blog/2007/04/17/sintesis-de-audio-para-mi-o-para-torpes-en-general/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Historias de hackers y espías</title>
		<link>http://slack.codemaniacs.com/blog/2007/01/01/historias-de-hackers-y-espias/</link>
		<comments>http://slack.codemaniacs.com/blog/2007/01/01/historias-de-hackers-y-espias/#comments</comments>
		<pubDate>Mon, 01 Jan 2007 05:24:41 +0000</pubDate>
		<dc:creator>slack</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Stories]]></category>

		<guid isPermaLink="false">http://slack.codemaniacs.com/blog/2007/01/01/historias-de-hackers-y-espias/</guid>
		<description><![CDATA[Una de las cosas más interesantes que conozco es oir a un hacker contar batallitas. Esta noche, entre uvas, comida y demás jolgorio, Gus me ha comentado que habia estado viendo un vídeo en el que un tal tmbinc contaba como saltarse las protecciones de la Wii, con momentos de grandes risas durante la explicación. [...]]]></description>
			<content:encoded><![CDATA[<p>Una de las cosas más interesantes que conozco es oir a un hacker contar batallitas. Esta noche, entre uvas, comida y demás jolgorio, Gus me ha comentado que habia estado viendo <a href="http://www.youtube.com/watch?v=uTx2MAOspS4">un vídeo</a> en el que un tal tmbinc contaba como saltarse las protecciones de la Wii, con momentos de grandes risas durante la explicación.</p>
<p>Dicho vídeo procede de una charla más larga, llamada &#8220;<a href="http://cryptosystem.org/video/tmbinc-consolehacking2k6.ogm">Console Hacking 2006</a>&#8221; (ogm, 140Mb), que a su vez formaba parte del <a href="http://events.ccc.de/congress/2006/Home">23C3</a> (23ª edición del Chaos Communication Congress, organizado por el célebre Chaos Computer Club), que ha tenido lugar del 27 al 30 de diciembre. Pues bien, todo el congreso ha sido emitido por <em>streaming</em> de video y las grabaciones de las ponencias se pueden descargar desde los <a href="http://events.ccc.de/congress/2006/Streams#Recordings">mirrors</a>. Esto supone <a href="http://events.ccc.de/congress/2006/Fahrplan/day_1.en.html">horas y horas</a> de charla interesante sobre temas como seguridad informática, lingüística, sociedad, videojuegos, software libre, comunicaciones, hardware&#8230;</p>
<p>Por cierto, me molaria MUCHO, pero MUCHO MUCHO, asistir al proximo CCC. ¿Alguien se anima?</p>
<p>En otro orden de cosas, llevo un par de dias leyendo sobre las <a href="http://en.wikipedia.org/wiki/Number_stations"><em>number stations</em></a>, estaciones de radio (no comerciales) de onda corta que emiten mensajes cifrados, en forma de ristras de números leídos por voces monótonas e incansables, supuestamente controladas por los gobiernos de algunos países para enviar información a sus espías.</p>
<p><a href="http://www.archive.org/details/ird059">The Conet Project</a> es una recopilación de grabaciones de diferentes estaciones de números. Algunos radioaficionados se dedican a hacer <a href="http://www.simonmason.karoo.net/page30.html">seguimientos</a> a estas estaciones, les ponen nombre basándose en lo que suena en esas frecuencias antes o después de las retahílas de números (por ejemplo, existe una conocida como &#8220;Magnetic Fields&#8221; porque utilizan el tema de Jarre con ese nombre como preludio), y controlan los horarios y frecuencias de emisión. Mi buen amigo <a href="http://stg7.net">stage7</a>, tras una conversación con él sobre el tema, consiguió grabar <a href="http://www.youtube.com/watch?v=avTkcgi4XcM">un fragmento</a> de la emision de la estación conocida como &#8220;<a href="http://en.wikipedia.org/wiki/Lincolnshire_Poacher_%28numbers_station%29">Lincolnshire Poacher</a>&#8220;, supuestamente controlada por el MI5 británico y que emite desde Chipre. Resulta curioso que en pleno siglo 21 siga siendo efectivo un método de envio de mensajes tan rústico.<br />
Todo esto da un poco de miedo ¿no? :)</p>
<p>¡Feliz año nuevo!</p>
<p>P.D.: ¿He dicho ya que me gustaría mucho asistir al próximo CCC? :D</p>
]]></content:encoded>
			<wfw:commentRss>http://slack.codemaniacs.com/blog/2007/01/01/historias-de-hackers-y-espias/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.384 seconds -->
