You are on page 1of 10

Marcacin por tonos

En telefona, el sistema de marcacin por tonos, tambin llamado sistema multifrecuencial


o DTMF (Dual-Tone Multi-Frequency), consiste en lo siguiente:
Cuando el usuario pulsa en el teclado de su telfono la tecla correspondiente al dgito que quiere
marcar, se envan dos tonos, de distinta frecuencia: uno por columna y otro por fila en la que est la
tecla, que la central descodifica a travs de filtros especiales, detectando instantneamente qu dgito
se marc.
La Marcacin por tonos fue posible gracias al desarrollo de circuitos integrados que generan estos tonos
desde el equipo terminal, consumiendo poca corriente de la red y sustituyendo el sistema mecnico de
interrupcin-conexin (el anticuado disco de marcar).
Este sistema supera al de marcacin por pulsos por cuanto disminuye la posibilidad de errores de
marcacin, al no depender de un dispositivo mecnico. Por otra parte es mucho ms rpido ya que no
hay que esperar tanto tiempo para que la central detecte las interrupciones, segn el nmero marcado.
No obstante, las modernas centrales telefnicas de conmutacin digital, controladas por ordenador,
siguen admitiendo la conexin de terminales telefnicos con ambos tipos de marcacin ms rpida.

Frecuencias DTMF (con sus sonidos)

1209 Hz

1336 Hz

1477 Hz

1633 Hz

697 Hz

770 Hz

852 Hz

941 Hz

Descodificar tonos DTMF usando


Matlab
November 25th, 2009 10 Comments programming

Ya vimos como crear tonos DTMF usando Matlab y han


pedido en un par de comentarios [1] [2] cmo se hara 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 ms 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
nmero 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 prctica de Tratamiento Digital
de la Seal en la que se hacan cosas de estas, uno de los
cdigos no es mo, est indicado. El resto los
hicimos Rafa y yo en su da.
Aprovechndonos 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


use ventanas para su propsito:

un

programa

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)

que

Ahora tendremos que calcular de cuanto es nuestra


ventana mnima. La separacin mnima entre tonos es de
320 muestras (que adems 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 teora 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 / resolucin
= 4 / 0.04 = 100 muestras
Ahora vamos a determinar los dgitos, y para ello vamos a
hacer uso de la siguiente funcin para bscar mximos:
function p=buscapicosu(x,umbral)
%posi_picos=buscapicosu(x,umbral)
% Busca los mximos locales de un vector mayores que un cierto umbral
% umbral se expresa en % respecto al valor mximo del vector.
% Ej. buscapicos(x,60) buscaria los picos mayores o iguales al 60% del
% pico ms 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 mximos
%Primero creo un vector con dos valores muy pequeos 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 mximos
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
dgito, 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 slo tenemos que ver a
qu corresponden 110 y 190.
Nota a tener en cuenta: en las FFTs (Fast Fourier
Transforms) el clculo se hace mucho ms rapido cuando

N es una potencia de 2, por eso la eleccin 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 ms


cercanos concuerdan 859.375 y 1484.4 Hz. Claramente
sera con 852 y 1477 Hz que juntos corresponden con el
dgito 9.

Y as con cada uno de los dgitos :)


S que estara mucho mejor un script que hiciera todo el
proceso entero y obtuviera qu nmero es de la tabla pero
ltimamente necesito das de 30 horas as os tendris que
conformar con esto. A qu nmero he llamado?

Llamando por telfono con Matlab


January 15th, 2009 19 Comments programming

Maana tengo examen de laboratorio de tratamiento


digital de la seal y cuando ya no tienes ganas de estudiar
slo tienes ganas de hacer el meln. As que aqu tenis un
script de Matlab al cual le pasas un nmero telefnico y te
genera y reproduce un wav con los tonos DTMF para hacer
la llamada. Descolgis el telfono, lo acercis a los
altavoces y ejecutis ring(numero).
Lo quera hacer en Octave (por aquello del software libre y
tal) pero es una _censored_ patata pinchada en un palo y
me he cansado de sus pejigueras.
En qu se basa esto? A cada nmero se le asigna una
pareja de tonos segn la tabla siguiente y se enva la suma
de stos, el nombre es bastante explicativo: Dual Tone
Multi Frequency.

En mi porttil no funciona porque mis altavoces estn


cascadsimos y no reproducen como deberan xDDD En el
porttil de Rafa s que iba.
Aqu est el cdigo:

function y = ring(x)
number = x;
numberstr = int2str(number);
% Sampling Frequency
fs = 8000;
% initializing arrays, 1200 samples
digit = 0:1199;
silence = zeros(1,1200);
disp('Calculating DTMF tones...');
% row sinusoids
sin697 = sin(2*pi*697*digit/fs);
sin770 = sin(2*pi*770*digit/fs);
sin852 = sin(2*pi*852*digit/fs);
sin941 = sin(2*pi*941*digit/fs);
% column sinusoids
sin1209 = sin(2*pi*1209*digit/fs);
sin1336 = sin(2*pi*1336*digit/fs);
sin1477 = sin(2*pi*1477*digit/fs);
% numbers
num1 = (sin1209+sin697)/2;
num2 = (sin1336+sin697)/2;
num3 = (sin1477+sin697)/2;
num4 = (sin1209+sin770)/2;
num5 = (sin1336+sin770)/2;
num6 = (sin1477+sin770)/2;
num7 = (sin1209+sin852)/2;
num8 = (sin1336+sin852)/2;
num9 = (sin1477+sin852)/2;
num0 = (sin1336+sin941)/2;
% an asterisk would be: (sin1336+sin941)/2);
% a pad would be: (sin1477+sin941)/2);
% insert a silence in the begining
y = zeros(1, 1200);
% fill the rest
for i = 1:length(numberstr)
num = str2num(numberstr(i));
switch num
case 0
dtmf = num0;
case 1
dtmf = num1;
case 2
dtmf = num2;
case 3
dtmf = num3;
case 4
dtmf = num4;
case 5
dtmf = num5;
case 6
dtmf = num6;

case 7
case 8
case 9

dtmf = num7;
dtmf = num8;

dtmf = num9;
otherwise
disp('O_o');

end
% insert the number samples
y = [y dtmf];
% insert the silence samples
y = [y silence];
end
wavwrite(y,fs,'ring.wav');
disp('Ringing number:');
disp(numberstr);
% play it
wavplay(y,fs);
disp('Happy talking');