Buscar en este blog

sábado, 12 de febrero de 2011

Hola Susana, te estamos decodificando...

Cada número de un teléfono tiene asignado un sonido distinto. Si nuestro oido fuera capaz de diferenciar entre estos sonidos, podríamos saber qué número fue discado con solo escuchar el sonido que este emite al presionarlo.

Esto resulta muy difícil sino imposible. Sin embargo, usando herramientas matemáticas, podemos deducir el o los números que fueron presionados.


Eso es lo que intento hacer con la "Diva de los Teléfonos".

En la siguiente tabla se puede ver como está compuesto el sonido asociado a cada una de las teclas de un teléfono usual:

Componentes de frecuencia de cada número del teléfono

Por ejemplo, el número 7, se compone de la suma de una sinusoide de 852Hz y otra de 1209Hz.

Audio de Susana

Yo lo que hice fue buscar en Youtube un video de Susana discando y luego me quedé con el audio de ese video y en particular con los segundos en los que ella disca. Para extraer el audio utilizé el programa Audacity basándome en la siguiente guía donde indica como grabar el audio que estamos escuchando. En este caso el de Youtube.

Configuración del Audacity de acuerdo a la guía anterior

Programa "alsamixer" (ejecutado en consola) que controla la tarjeta de sonido

Audio grabado mediante Audacity desde el video en Youtube

En la imagen anterior, se puede ver que "silencié" el audio de Susana hablando ("Cuando suene el teléfono le va a dar un infarto") entre los primeros números que disca. De esta forma el espectrograma queda más "limpio".

Este audio lo guardo con el nombre "susana_millon.wav" en la misma carpeta donde voy a escribir el código en Python.

Herramientas matemáticas

Una vez que se tiene este audio, lo que queremos es ver cuales son las frecuencias presentes cada vez que Susana presiona una tecla para así poder buscar en la tabla a que número corresponden.

Hay una transformación (o transformada) matemática que permite hacer esto mismo. Esta es la "Transformada de Fourier".

Podríamos entonces transformar nuestra señal mediante Fourier, graficar el resultado y ver qué frecuencias hay presentes.

Esto último podría funcionar si Susana discara un único número para llamar a la persona. Pero supongamos que Susana disca dos números: el 3 y el 7. De la tabla, esperaríamos encontrar las siguientes frecuencias en el gráfico de la transformada de Fourier de la señal:

697Hz, 852Hz, 1209Hz y 1477Hz

Esto seguramente sea así pero, ¿cómo sabemos qué par de frecuencias apareció primero?. Es decir, no sabemos si discó 37 o 73. Cualquier combinación hubiese producido el mismo gráfico de Fourier pues ambas contienen las mismas componentes de frecuencias.

Una solución a este problema podría ser dividir el audio en tantas partes como números discados y generar luego un gráfico de Fourier por cada parte del audio. Esto resulta poco práctico y además ya existe otro tipo de gráfico que soluciona nuestro problema.

Este tipo de gráfico es lo que se denomina "espectrograma". Un espectrograma nos dá la información no sólo de las componentes de frecuencias presentes en el audio sino que nos dice en qué momento están presentes esas componentes.

Lo que voy a hacer entonces es graficar el espectrograma del audio de Susana discando y luego, mirando la tabla, ver que números está discando en cada momento.

Para eso utilizo los módulos Wave y Pylab de Python y sus funciones open() para leer el audio y specgram() para realizar el espectrograma.

Código

El código utilizado es el siguiente:

from pylab import *
from wave import *
import struct

audio = open('susana_millon.wav')    # abro el archivo de audio

### en las dos siguientes lineas no se que es lo que hace pero me soluciono la vida
frames = audio.readframes(audio._nframes)
v = array(struct.unpack("%sh"% audio._nframes*audio._nchannels, frames), dtype='float' ).flatten()
###

specgram(v, Fs=audio._framerate, NFFT=2048, noverlap=1024)    # genero el espectrograma

ylim(500,1600)    # acoto frecuencias mostradas al rango de interes
yticks( [697,770,852,941,1209,1336,1477] )    # marco frecuencias de interes

title('Espectrograma del discado de Susana')    # titulo
xlabel('Tiempo (s)')
ylabel('Frecuencia (Hz)')

show()    # muestro el espectrograma


Este código lo guardan con el nombre "susana.py" en el mismo directorio donde tienen el audio y luego, en una consola, ejecutan lo siguiente para que genere el espectrograma:

python susana.py

Resultados

El gráfico (espectrograma) obtenido es:


Comparando con la tabla, se puede ver que los números discados son:
  • 0
  • 2
  • 2
  • 1
  • 4
  • 7
  • 0
  • 9
  • 6
  • 0
  • 7
Se observa que los 4 primeros números discados (0221), coinciden con el número de característica que dice Susana al aire.

Correctoooooooooo!!!

Fuentes

10 comentarios:

  1. Muy util desde el punto de vista educacional. pero seria mas facil con decodificador de tonos. un simple circuito integrado hace todo ese laburo.
    por ejemplo el MT8880

    ResponderEliminar
  2. El MT8880 funciona (y bien) pero no puede ser tan acurado como un filtro digital echo a medida. Generalmente esos trastos (entiendo el MT8880) tienen tan solo una serie de filtros BP y bastante anchos tambien. Por mi, tendria mucha mas confianza en los resultados de Charlie, YMMV.

    ResponderEliminar
  3. Me pregunto ( o no deberia) si esto no puede ser aplicado tambien al keypad de los cajeros banelco, que cuando uno ingresa el numero, emiten tambien su equivalente tono. Siempre me parecio muy contraproducente que tengan esta "habilidad" porque algun rainman, o un Charlie, podria adivinar nuestra clave escuchando los tonos.

    ResponderEliminar
  4. Hola he intentado ejecutar el codigo pero dado un problema que me surge en la consola te hago una pregunta:

    ImportError: No module named pylab

    ¿pylab viene integrada en python o hay que instalarla de alguna manera?

    ResponderEliminar
  5. pylab esta en el modulo python-matplotlib.

    ResponderEliminar
  6. wow! que bien explicado :D
    muchas gracias, ahora entiendo un poco mas de las fft y como ver la información de un archivo de audio.

    ResponderEliminar
  7. @ruso el verdadero problema es si alguien te pincha el teléfono mientras estás metiendo la clave de tu homebanking.
    uops! :B

    ResponderEliminar
  8. Hello!

    La versión que utilice la audacity?

    ¿Y podría usted explicar cómo se descarga "alsamixer" y "python" para Windows 7.

    Gracias a ser claro, porque no entiendo mucho.

    Saludos.

    ResponderEliminar
  9. Los teléfonos fijos envian por la linea un tono de doble frecuencia(de audio) específico para cada número, sistema conocido por DMTF (dual tone multifrecuency), Windows(todos) cuenta con librerías (.dll) dedicadas específicamente a decodificar estos tonos con sus respectivos números, es cuestión de utilizar el buscador con una clave parecida a:"decodificar DMTF en Windows", alguna vez lo ví en Excel.

    ResponderEliminar