{"id":180,"date":"2012-03-02T13:36:47","date_gmt":"2012-03-02T11:36:47","guid":{"rendered":"http:\/\/www.joanillo.org\/?p=180"},"modified":"2020-09-16T12:46:11","modified_gmt":"2020-09-16T10:46:11","slug":"jugando-con-la-fft","status":"publish","type":"post","link":"https:\/\/www.joanillo.org\/?p=180&lang=es","title":{"rendered":"Jugando con la FFT"},"content":{"rendered":"<p>Hace ya mucho tiempo (realment mucho tiempo) que estudiaba la <strong>Transformada de Fourier<\/strong> (<a href=\"http:\/\/en.wikipedia.org\/wiki\/Fourier_transform\">http:\/\/en.wikipedia.org\/wiki\/Fourier_transform<\/a>) en la facultad, e incluso utilic\u00e9 el algoritmo de la <strong>FFT<\/strong> (Fast Fourier Transform, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Fast_Fourier_transform\">http:\/\/en.wikipedia.org\/wiki\/Fast_Fourier_transform<\/a>) en un aplicativo escrito en C para procesamiento digital de im\u00e1genes. Desde entonces no me hab\u00eda preocupado de la <strong>FFT<\/strong> y realmente lo ten\u00eda muy olvidado.<\/p>\n<p>Estos d\u00edas he vuelto a la carga con la <strong>FFT<\/strong> pues, con la idea de aprender las t\u00e9cnicas de programaci\u00f3n de aplicaciones de audio, quer\u00eda programar un afinador o un analizador de la potencia espectral de una se\u00f1al, que fuese compatible con JACK.<\/p>\n<p>Antes que nada hay que mirar qu\u00e9 algoritmo de FFT se podr\u00eda utilizar, con licencia GPL, y r\u00e1pidamente he visto que la elecci\u00f3n ser\u00eda <strong>FFTW<\/strong> (<a href=\"http:\/\/www.fftw.org\/\">http:\/\/www.fftw.org\/<\/a>):<\/p>\n<blockquote><p>FFTW is a C subroutine library for computing the discrete Fourier transform (DFT) in one or more dimensions, of arbitrary input size, and of both real and complex data (as well as of even\/odd data, i.e. the discrete cosine\/sine transforms or DCT\/DST). We believe that FFTW, which is free software, should become the FFT library of choice for most applications.<\/p><\/blockquote>\n<p>Me he puesto a compilar unos cuantos ejemplos y a familiarizarme con los c\u00e1lculos. En definitiva yo lo que quiero es calcular la potencia espectral de una se\u00f1al de audio, por tanto el se\u00f1al de entrada ser\u00e1n unas muestras reales (una sola dimensi\u00f3n). La salida de la FFT ser\u00e1n unos valores complejos, y he de tener en cuenta tanto la parte real como la parte imaginaria para hacer los c\u00e1lculos de la potencia espectral.<\/p>\n<blockquote><p>fftPlan = fftwf_plan_dft_r2c_1d(fftSize, fftIn, fftOut, FFTW_MEASURE); \/\/r2c_1d: real to complex, one dimension<\/p><\/blockquote>\n<p>Mirando si hay alg\u00fan afinador de c\u00f3digo libre, que trabaje en modo consola, y compatible con JACK, me he encontrado estos dos proyectos, que precisamente utilizan la librer\u00eda FFTW:<\/p>\n<ul>\n<li><strong>tuneit<\/strong>: A simple command-line instrument tuner for Linux (<a href=\"http:\/\/delysid.org\/tuneit.html\">http:\/\/delysid.org\/tuneit.html<\/a>, Mario Lang). Puede funcionar como client de JACK<\/li>\n<li><strong>sndfile-spectrogram<\/strong>: Generate a spectrogram as a PNG file from a given sound file (<a href=\"http:\/\/www.mega-nerd.com\/libsndfile\/tools\/\">http:\/\/www.mega-nerd.com\/libsndfile\/tools\/<\/a>, Erik de Castro Lopo)<\/li>\n<\/ul>\n<p>y tambi\u00e9n me ha sido \u00faltil para mi propio c\u00f3digo en este proyecto <em>capture_client<\/em>:<\/p>\n<ul>\n<li><strong>capture_client<\/strong>: (<a href=\"https:\/\/github.com\/jackaudio\/example-clients\/blob\/master\/capture_client.c\">https:\/\/github.com\/jackaudio\/example-clients\/blob\/master\/capture_client.c<\/a>, Paul Davis, Jack O&#8217;Quin)<\/li>\n<\/ul>\n<p>He dividido el problema en dos partes:<\/p>\n<ul>\n<li>Primero de todo capturo la se\u00f1al que proviene del micr\u00f3fono, y como resultado obtengo dos ficheros: el fichero de sonido wav y un fichero de texto donde pongo un n\u00famero suficiente de muestas.<\/li>\n<li>Segundo: abro el fichero de muestras, aplico una ventana de Hanning a les muestras como es habitual, calculo la FFT, calculo la potencia espectral de la se\u00f1al, y obtengo un fichero de salida para ser procesado con la utilidad de creaci\u00f3n de gr\u00e1ficos <strong>gnuplot<\/strong> (<a href=\"http:\/\/www.gnuplot.info\/\">http:\/\/www.gnuplot.info\/<\/a>).<\/li>\n<\/ul>\n<p>No hab\u00eda trabajado nunca con <strong>gnuplot<\/strong>, que ser\u00eda el equivalente a <strong>Matlab<\/strong> para el mundo Linux. Viendo la demo de <strong>gnuplot<\/strong> que se distribuye con el c\u00f3digo fuente, y que muestra de forma r\u00e1pida todas las posibilidades de gnuplot, me he quedado realmente sorprendido. En mi caso dibujar el gr\u00e1fico es muy f\u00e1cil:<\/p>\n<blockquote><p>$ gnuplot<br \/>\ngnuplot&gt; plot &#8220;data_440_trumpet_output.txt&#8221;<\/p><\/blockquote>\n<p>La prueba que presento se ha grabado con un mini teclado <a href=\"http:\/\/www.google.es\/search?q=CASIO+SK-8&amp;hl=ca&amp;prmd=imvns&amp;tbm=isch&amp;biw=1280&amp;bih=739\">Casio SK-8<\/a>, un mini-teclado de los a\u00f1os 80, escogiendo el sonido de trompeta, y obtengo el siguiente resultado.<\/p>\n<p><object height=\"81\" width=\"100%\"><param name=\"movie\" value=\"https:\/\/player.soundcloud.com\/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F38439858\"><param name=\"allowscriptaccess\" value=\"always\"><embed allowscriptaccess=\"always\" height=\"81\" src=\"https:\/\/player.soundcloud.com\/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F38439858\" type=\"application\/x-shockwave-flash\" width=\"100%\"><\/object>  <span><a href=\"http:\/\/soundcloud.com\/joanillo\/casio-sk-8-440hz-a-trumpet\">Casio SK-8 440Hz (A) trumpet, 44100 fps<\/a> by <a href=\"http:\/\/soundcloud.com\/joanillo\">joanillo<\/a><\/span><\/p>\n<p>Ahora quiero comparar el resultado de mis c\u00e1lculos con los obtenidos con <strong>Audacity<\/strong> y <strong>Ardour<\/strong>, para comprobar que los c\u00e1lculos son correctos:<\/p>\n<table>\n<tbody>\n<tr>\n<td>Mis c\u00e1lculos y Gnuplot<\/td>\n<td>Audacity<\/td>\n<td>Ardour<\/td>\n<\/tr>\n<tr>\n<td><a href=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2012\/03\/data_440_trumpet_gnuplot.jpg\"><img loading=\"lazy\" src=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2012\/03\/data_440_trumpet_gnuplot-300x238.jpg\" alt=\"\" title=\"Gnuplot. FFT. Casio SK-8 440_trumpet\" width=\"300\" height=\"238\"><\/a><\/td>\n<td><a href=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2012\/03\/data_440_trumpet_audacity.jpg\"><img loading=\"lazy\" src=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2012\/03\/data_440_trumpet_audacity-300x262.jpg\" alt=\"\" title=\"Audacity. FFT. Casio SK-8 440_trumpet\" width=\"300\" height=\"262\"><\/a><\/td>\n<td><a href=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2012\/03\/data_440_trumpet_ardour.jpg\"><img loading=\"lazy\" src=\"http:\/\/www.joanillo.org\/wp-content\/uploads\/2012\/03\/data_440_trumpet_ardour-300x273.jpg\" alt=\"\" title=\"Ardour. FFT. Casio SK-8 440_trumpet\" width=\"300\" height=\"273\"><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Perfecto! Lo he clavado!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hace ya mucho tiempo (realment mucho tiempo) que estudiaba la Transformada de Fourier (http:\/\/en.wikipedia.org\/wiki\/Fourier_transform) en la facultad, e incluso utilic\u00e9 el algoritmo de la FFT (Fast Fourier Transform, http:\/\/en.wikipedia.org\/wiki\/Fast_Fourier_transform) en un aplicativo escrito en C para procesamiento digital de im\u00e1genes. Desde entonces no me hab\u00eda preocupado de la FFT y realmente lo ten\u00eda muy olvidado. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[298,310,324,320],"tags":[],"_links":{"self":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/180"}],"collection":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=180"}],"version-history":[{"count":2,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/180\/revisions"}],"predecessor-version":[{"id":182,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=\/wp\/v2\/posts\/180\/revisions\/182"}],"wp:attachment":[{"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=180"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=180"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.joanillo.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=180"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}