Jspectrograma

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Estudi tuneit

L'he descarregat a la carpeta /home/joan/projectes/jspectrograma/tuneit

Compilació directa sense el configure:

$ gcc -Wall -o tuneit -ljack -lfftw3 -lasound tuneit.c

He d'incloure el fitxer config.h que està dins del projecte de fftw3

la versió 0.3 de tuneit que faig servir és del 2005, mentre que compilo contra les últimes versions de FFTW i JACK. Per tal que compili s'han de fer els següents canvis.

Canviar:

Bàsicament és canviar tot els que sigui fftwf per fftw

Canvio

static float *fftIn;
fftIn = fftw_malloc(sizeof(float) * 2 * (fftSize/2+1));

per

static double *fftIn;
fftIn = fftw_malloc(sizeof(double) * 2 * (fftSize/2+1));

canvio

if ((jackClient = jack_client_new(PACKAGE_NAME)) == 0) {

per

if ((jackClient = jack_client_open (PACKAGE_NAME,JackNullOption,NULL)) == 0) {

versió meva: tuneit_joan.c

$ gcc -Wall -o tuneit_joan -ljack -lfftw3 -lasound tuneit_joan.c

Canvio el sample rate per defecte de 48000 a 44100:

static unsigned int rate = 44100;

Els meus ports de captura són (el micròfon):

$ ./tuneit_joan -i -j
system:capture_1
system:capture_2
$ ./tuneit_joan -f -j system:capture_1

Funciona bé, tot i que a vegades la freqüència que em mostra és una mica inestable. Una de les gràcies del projecte és que funcional tant per ALSA com per JACK (amb l'opció -j). No s'aprecia diferències entre fer el càlcul amb la FFT i amb l'altre algorisme.

jspectrograma: prova amb el Casio SK-8

carpeta: /home/joan/projectes/jspectrograma

Es tracta de poder gravar un fitxer d'audio amb el micròfon (system:capture_1) o un altre port de JACK, i després analitzar-ne l'espectre de freqüències. Aixi doncs, divideixo el problema en dos.

1) captar el audio i generar un fitxer amb les mostres. Parteixo de capture_client i el modifico: capture_client_modified.c. El programa treballa amb fils i no hi ha cap problema de overruns

$ gcc -Wall -o jackrec_modified -ljack -lsndfile capture_client_modified.c

$ ./jackrec_modified 
usage: jackrec -f filename -o outputfilename [ -d second ] [ -b bitdepth ] [ -B bufsize ] port1 [ port2 ... ]

$ ./jackrec_modified -f prova_veu.wav -o prova_veu.txt -d 1 system:capture_1

Per defecte el número de mostres a agafar és 10*buffer_jack (per ex, 10*512=5120). És important utilitzar l'opció -d per tal de què el programa acabi bé i tenir en el fitxer de sortida les 5120 mostres. Si acabo amb Ctrl-C, encara que 5120 mostres són molt poques, a dins del fitxer de sortida no hi són totes.

2) Processar el fitxer, fer la FFT i calcular l'espectre de freqüències.

$ g++ -Wall -o audio-fft -lfftw3 fftw++.cc audio-fft-0.0.4.cpp 
$ ./audio-fft prova_veu.txt prova_veu_output.txt

Per poder compilar he d'incloure diferents fitxers del projecte de fftw++ (que és una extensió de FFTW per a C++). Finalment, per veure l'espectrograma:

$ gnuplot
gnuplot> plot "prova_veu_output.txt" with lines

Així de senzill. No cal ficar l'eix y logarítmic perquè en la fórmula per calcular la potència espectral ja he calculat el logaritme. El resultat que s'obté és idèntic al que es troba amb Audacity o Ardour.


jspectrograma: Paisatge sonor d'un biberó

carpeta: /home/joan/projectes/jspectrograma

El procediment és en principi el mateix que l'anterior, però a la pràctica no s'ha trobat els resultats esperats. La freqüència a la que vibra el biberó és de l'ordre de 5-15Hz (al principi vibra més ràpid, al cap d'un minut vibra més lent).

Quan faig la FFT no es troben les freqüències en aquest rang. He augmentat molt el número de samples, i en l'opció -d he ficat 10 segons, i fent un zoom de l'espectre que em dóna el audacity he arribat a trobar la freqüència de xarxa de 50Hz. Clar que l'audacity deu fer l'anàlisi espectral sobre totes les mostres, els 10 segons.

Surten freqüències altres, cap a 800 Hz i pics més amunt cap a 5Khz, i això deu emmascarar el meu senyal de 5-10Hz.

M'he de documentar i practicar, però bàsicament la idea és que per augmentar la resolució de freqüència he d'augmentar el número de mostres, i que si jo connec el rang de freqüències que vull trobar (de l'ordre de 5-10Hz) he d'aplicar un filtre passa-baix molt potent.

Bé, però la cosa no és tan senzilla, no té res a veure amb els filtres passa-baixos. De fet idealment jo el que tinc és un tren d'impulos (impulse train, Dirac comb), i la transformada de fourier d'un tren d'impulsos està molt ben definida: tots els components de l'espectre tenen el mateix pes (1/T, on T és el periode del tren d'impulsos).

I té certa lògica: un impuls, o una delta de Dirichlet, està introduint altes freqüècies. Si la meva T són 5Hz jo esperava trobar un pic a 5Hz, però això només és cert si tinc un sinus a 5Hz! No és cert si tinc pics a 5Hz. Per tant, el que jo esperava trobar és fals. Com que T és de l'ordre de 5Hz-15Hz és molt alt, 1/T és molt petit i l'error que puc estar calculant és molt gran. Que totes les freqüències aporten el mateix a la potència espectral seria cert si fossin deltes ideal, però com veig editant amb el Audacity, no són deltes ideals i el meu soroll del biberó té una riquesa harmònica. Podria fer filtat, normalització, detecció de pics per tal de convertir els meus pulsos a pulsos cada vegada més ideals, i aleshores el meu wav modificat tornar-lo a ficar dins la cadena (en comptes del senyal del micro) per obtenir una DSP que hauria de ser plana... però me n'estit anant de l'objectiu.

Per resoldre el projecte i per poder escriure una cosa més o menys interessants em centraré en com varia la T al llarg del temps, i faré una gràfica en què mostraré la variació del periode d'oscil.lació en funció del temps. Només em cal gravar el so durant bastant de temps (posem 5 minuts), i amb l'Audacity analitzar el senyal durant aquests 5 minuts i fer una taula. Aleshores de la taula fer-ne una gràfica amb gnuplot i ja està. Un article (i en l'article explicar per què la freqüència va variant amb el temps).


creat per Joan Quintana Compte, febrer 2012

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
Institut Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines