Ya vimos como crear tonos DTMF usando Matlab y han pedido en un par de comentarios [1] [2] cómo se haría a la inversa, así que aquí va
He cogido el script para generar los tonos del otro post y lo he cambiado para los pitidos duren 40ms (que se resume a cambiar que use 320 muestras en lugar de 1200 para cada pitido o silencio), para que sea un poco más real. El wav que voy a usar será el siguiente: ring.wav
Empezamos, ¿qué necesitamos? Cada pitido estará compuesto por una pareja de tonos así que para saber qué número es deberemos reconocer las dos frecuencias principales que tienen los pitidos, y conocer la frecuencia viene a ser lo mismo que saber el periodo.
Hace un tiempo hice una práctica de Tratamiento Digital de la Señal en la que se hacían cosas de estas, uno de los códigos no es mío, está indicado. El resto los hicimos Rafa y yo en su día.
Aprovechándonos de la Transformada de Fourier:
function [P,f]=periodograma(x,N) % [P f]=periodograma(x,N) % Calcula N muestras del periodograma de las muestras en x % N debe ser > que length(x) % % P: Periodograma propiamente % f frecuencias correspondientes k=0:N-1; f=k./N; L=length(x); P=1/L*(fft(x,N)).^2;
Pero lo propio será usar un programa que use ventanas para su propósito:
function [P,f]=periodmodif(x,ventana,N) % [P ,f]=periodmodif(x,ventana,N) % % Calcula N muestras del periodograma modificado de las muestras en x % N debe ser > que length(x) % % P: Periodograma propiamente % f frecuencias correspondientes if N <= length(x) error('N debe ser > que length(x)'); else k=0:N-1; f=k./N; L=length(x); m=0:L-1; U=1/L*(sum(ventana(m+1).^2)); P=1/(L*U)*abs(fft(x.*ventana,N)).^2; end
Cargamos el fichero ring.wav
>> [x,fs,nbits]= wavread('ring.wav') >> t=0:1/fs:1/fs*(length(x)-1); >> plot(x)
Ahora tendremos que calcular de cuanto es nuestra ventana mínima. La separación mínima entre tonos es de 320 muestras (que además en este caso es la misma entre todos los tonos) luego la frecuencia digital será 320 / fs = 320/8000 = 0.04
Y aquí un poco de teoría sobre ventanas gracias a los Apuntes de Pak:
Pero no voy a aburriros con ella así que nos quedaremos en que vamos a usar una ventana tipo Hamming, luego necesitaremos una longitud de ventana L = 4 / resolución = 4 / 0.04 = 100 muestras
Ahora vamos a determinar los dígitos, y para ello vamos a hacer uso de la siguiente función para búscar máximos:
function p=buscapicosu(x,umbral) %posi_picos=buscapicosu(x,umbral) % Busca los máximos locales de un vector mayores que un cierto umbral % umbral se expresa en % respecto al valor máximo del vector. % Ej. buscapicos(x,60) buscaria los picos mayores o iguales al 60% del % pico más alto % % posi_picos son los indices del vector de entrada correspondientes a los picos. % (C) Antonio Albiol , 2003 %Primero descarto los valores menores que el umbral umbral=max(x(:))*umbral/100; x=x.*(x>umbral); %Ahora buscaré los máximos %Primero creo un vector con dos valores muy pequeños en los extremos xe=[-inf;x(:);-inf]; %Ahora calculo la derivada d1=diff(xe); ld1=length(d1); %Ahora busco valores de la derivada de signo diferente consecutivos y que sean máximos p=find(sign(d1(2:ld1)).*sign(d1(1:(ld1-1)))<0 & sign(d1(1:ld1-1))>0);
Cada pitido y cada silencio dura 320 muestras luego calculamos periodos en esas zonas. Vamos a por el primer dígito, con ventana Hamming de 100 y usando 1024 puntos:
>> [P,f]=periodmodif(x(320:320+99),hamming(100),1024); >> buscapicosu(abs(P),50) ans = 110 190 836 916
En el espectro digital, de 0 a 1, veremos que las frecuencias se repiten en espejo a partir de 0.5. Luego la frecuencia 110 se corresponde con la 916, igualmente ocurre entre la de 190 y 836, son lo mismo. Así que sólo tenemos que ver a qué corresponden 110 y 190.
Nota a tener en cuenta: en las FFTs (Fast Fourier Transforms) el cálculo se hace mucho más rapido cuando N es una potencia de 2, por eso la elección de hacerlo en 1024 puntos no ha sido del todo al azar.
>> 110/1024*fs ans = 859.3750 >> 190/1024*fs ans = 1.4844e+003
Nos vamos a la tablita y vemos con qué 2 valores más cercanos concuerdan 859.375 y 1484.4 Hz. Claramente sería con 852 y 1477 Hz que juntos corresponden con el dígito 9.
Y así con cada uno de los dígitos
Sé que estaría mucho mejor un script que hiciera todo el proceso entero y obtuviera qué número es de la tabla pero últimamente necesito días de 30 horas así os tendréis que conformar con esto. ¿A qué número he llamado?
–
Fuente original en http://vierito.es/wordpress
Similar Posts:
- Llamando por teléfono con Matlab
- [Fprint] Procesado de la imagen – Huellas dactilares
- Cuestión de optimización



4 responses so far ↓
1 papanoel
// Nov 25, 2009 at 11:46 am
A….. Telefonicaaaaaaaaaaaaaaaaaaaaaaaaa, una pasión día a díaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
(realmente no es ese, pero lo dejo para el intrépido lector
2 vierito5
// Nov 25, 2009 at 2:50 pm
Una pasión día a díaaaaaaaaaaaa
http://www.megaupload.com/?d=JIFHKDRP
Vamos a dar lo mejooooooooor!
3 mageles
// Nov 25, 2009 at 5:12 pm
Os odio ¬¬
Perdón por el comentario troll, pero de lo de matlab no tengo nada que aportar :$
4 vierito5
// Nov 25, 2009 at 5:14 pm
Es que cuando hacíamos la parte de filtrado digital en LTDS usabamos la canción de Telefónica como conejillo de indias siempre jeje. No te creas que mejoraba mucho el asunto porque por defecto nos daban una canción de Julio Iglesias, también muy dura.
Leave a Comment