Arxiu mensual: març de 2012

Jugant amb la FFT

>Fa ja molt de temps (realment molt de temps) que estudiava la Transformada de Fourier (http://en.wikipedia.org/wiki/Fourier_transform) a la facultat, i fins i tot vaig utilitzar l’algorisme de la FFT (Fast Fourier Transform, http://en.wikipedia.org/wiki/Fast_Fourier_transform) en un aplicatiu escrit amb C per a processament digital d’imatges. Des d’aleshores ençà que no m’havia preocupat de la FFT i realment ho tenia molt oblidat.

Aquests dies he tornat a la càrrega amb la FFT doncs, amb la idea d’aprendre les tècniques de programació d’aplicacions d’audio, volia fer o un afinador o un analitzador de la potència espectral d’un senyal, que fos compatible amb JACK.

Primer de tot he mirat quin algorisme de FFT es podria utilitzar, amb llicència GPL, i ràpidament he vist que la tria seria FFTW (http://www.fftw.org/):

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.

M’he posat a compilar uns quants exemples i familiaritzar-me amb els càlculs. En definitiva jo el que vull és calcular la potència espectral d’un senyal d’audio, per tant el senyal d’entrada seran unes mostres reals (una sola dimensió). La sortida de la FFT seran uns valors complexos, i he de tenir en compte tant la part real com la part imaginària per tal de calcular la potència espectral.

fftPlan = fftwf_plan_dft_r2c_1d(fftSize, fftIn, fftOut, FFTW_MEASURE); //r2c_1d: real to complex, one dimension

Mirant si hi ha algun afinador de codi lliure, que treballi per la consola, i compatible amb JACK, m’he trobat amb aquests dos projectes, que precisament utilitzen la llibreria FFTW:

i també m’ha sigut últil per fer el meu propi codi el projecte capture_client:

He dividit el problema en dues parts:

  • Primer de tot capturo el senyal que prové del micròfon, i com a resultat obtinc dos fitxers: el fitxer de so wav i un fitxer de text on fico un número suficient de mostres.
  • Segon: obro el fitxer de mostres, aplico una finestra de Hanning a les mostres com és habitual, calculo la FFT, calculo la potència espectral del senyal, i obtinc un fitxer de sortida per a ser processat amb la utilitat de creació de gràfics gnuplot (http://www.gnuplot.info/).

No havia treballat mai amb gnuplot, que seria l’equivalent a Matlab per al món Linux. Veient la demo de gnuplot que es distribueix amb el codi font, i que mostra de forma ràpida totes les possibilitats de gnuplot, m’he quedat realment sorprès. En el meu cas dibuixar el gràfic és molt fàcil:

$ gnuplot
gnuplot> plot “data_440_trumpet_output.txt”

La prova que presento s’ha gravat amb mini teclat Casio SK-8, un mini-teclat dels anys 80, escollint el so de trompeta, i obtinc el següent resultat.

Casio SK-8 440Hz (A) trumpet, 44100 fps by joanillo

Ara vull comparar el resultat dels meus càlculs amb els obtinguts amb Audacity i Ardour, per comprovar que els càlculs són correctes:

Els meus càlculs i Gnuplot Audacity Ardour

Perfecte! L’he clavat!