DTMF双音拨号信号产生与分析

 可私信沟通

clear;clc;close all;
tel_number = input('请输入电话号码:','s');          % 请求用户输入号码     
ftable = [697,1209;697,1336;697,1477;697,1633;      % 1 2 3 A
            770,1209;770,1336;770,1477;770,1633;    % 4 5 6 B
            852,1209;852,1336;852,1477;852,1633;    % 7 8 9 C
            941,1209;941,1336;941,1477;941,1633];   % * 0 # D    每个按键对应的频率
fs = 8000;              % 采样频率 8000样值/秒
T = 100e-3;             % 每个按键时隙100MS
N = T*fs;               % 每个按键时隙的采样序列长度
T1 = 50e-3;             % 每个按键音频持续时间50MS
N1 = T1*fs;             % 每个按键音频持续时间采样序列长度
t1 = (0:N1-1).*(1/fs);  % 音频持续时间序列
L = length(tel_number); % 电话号码长度
tel_signal = zeros(1, L*N); % 电话拨号信号
% 产生双音拨号信号
for I = 1:L
    % 循环  每个键对应一对频率
    if tel_number(I) == '1' ,ff = ftable(1, :);
    elseif tel_number(I) == '2', ff = ftable(2, :);
    elseif tel_number(I) == '3', ff = ftable(3, :);
    elseif tel_number(I) == 'A', ff = ftable(4, :);
    elseif tel_number(I) == '4', ff = ftable(5, :);
    elseif tel_number(I) == '5', ff = ftable(6, :);
    elseif tel_number(I) == '6', ff = ftable(7, :);
    elseif tel_number(I) == 'B', ff = ftable(8, :);
    elseif tel_number(I) == '7', ff = ftable(9, :);
    elseif tel_number(I) == '8', ff = ftable(10, :);
    elseif tel_number(I) == '9', ff = ftable(11, :);
    elseif tel_number(I) == 'C', ff = ftable(12, :);
    elseif tel_number(I) == '*', ff = ftable(13, :);
    elseif tel_number(I) == '0', ff = ftable(14, :);
    elseif tel_number(I) == '#', ff = ftable(15, :);
    elseif tel_number(I) == 'D', ff = ftable(16, :);
    else
        disp('输入有误!');
        return;
    end
    % 根据频率 产生两个正弦信号叠加的信号
    tel_signal(1, (I-1)*N+1:(I-1)*N+N1) = sin(2*pi.*ff(1, 1).*t1) + sin(2*pi.*ff(1, 2).*t1);
end

n_num = L;                              % 电话拨号个数
f = (-N1/2:N1/2-1).*(fs/N1);            % 频率变量
% 将信号分段(每个拨号声分为一段)
sound_singal = zeros(n_num, N1);
sound_singal_fft = zeros(n_num, N1);
f_result = zeros(n_num, 2);             % 分段信号频率值
for I = 1:n_num
    sound_singal(I, :) = tel_signal(1, 1+(I-1)*2*N1:(I-1)*2*N1+N1);
    sound_singal_fft(I, :) = fftshift(fft(sound_singal(I, :)));     % 对分段信号做傅里叶变换
    [pk,loc] = findpeaks(abs(sound_singal_fft(I, N1/2+2:N1)),'SortStr','descend','NPeaks',2);     % 寻找两个频率值
    loc = loc.*(fs/N1);
    f_result(I,:) = loc;
    f_result(I,:) = sort(f_result(I,:));        % 排序
end

% 找到最接近频率,并对应其拨号字符
number_table = '123A456B789C*0#D';                     % 所有的按键
recognition_tel = char(zeros(1, 8));                   % 初始化识别的电话号码
for I = 1:n_num                                 
    err = zeros(1, 16);
    for J = 1:16
        err(1, J) = (f_result(I, 1) - ftable(J, 1)).^2 + (f_result(I, 2) - ftable(J, 2)).^2;
        [err_min, err_idx] = min(err);
    end
    recognition_tel(I) = number_table(err_idx);
end
disp_result = ['识别的电话号码为:', recognition_tel];
disp(disp_result);               % 在命令行窗口展示识别的电话号码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值