4.6 Goertzel算法演示程序
列表1是我们编写的一个演示程序以便读者测试Goertzel算法。其中的代码均采用免费的DJGPP C/C++编译器编写和测试。读者可通过修改文件顶部的#defines语句来改变N值、采样频率(sampling_rate)和目标频率(target_frequency)。
该演示程序可进行两种演示。演示一,采用Goertzel优化算法和Goertzel基本算法计算三个不同的合成信号的相关幅度平方值和幅度值。这三个信号中,一个频率低于目标频率,一个与目标频率相等,一个高于目标频率。通过演示程序可以很容易发现,不论采用哪种算法所得到的结果几乎相同。同时,检测结果在目标频率附近出现峰值。
在第二个演示中,我们进行了频率扫描仿真,并只给出了Goertzel基本算法的处理结果。可以看到,检测输出结果在目标频率附近出现非常明显的峰值。列表2给出了列表1中代码的输出。
为了避免程序代码出现误检,我们可能还需要通过一种去抖动技术来限制原始检测器的读出结果,例如,要求必须在一系列处理中多次检测到某音调之后,才能向用户报告检测到音调的存在。
5 DTMF信号的产生与识别仿真实现
下面先介绍MATLAB工具箱函数goertzel,然后介绍DTMF信号的产生与识别仿真实验程序。Goerztel函数的调用格式额为
Xgk=goertzel(xn,K)
xn是被变换的时域序列,用于DTMF信号检测时,xn就是DTMF信号的205个采样值。
K是要求计算的DFT[xn]的频点序号向量,用N表示xn的长度,则要求1≤K≤N。由表10.2.2可知,如果只计算DTMF信号8个基频时,
K=[18,20,22,24,31,34,38,42],
如果同时计算8个基频及其二次谐波时,
K=[18,20,22,24,31,34,35,38,39,42,43,47,61,67,74,82]。
Xgk是变换结果向量,其中存放的是由K指定的频率点的DFT[x(n)]的值。设X(k)= DFT[x(n)],则 。
DTMF信号的产生与识别仿真实验在MATLAB环境下进行,编写仿真程序,运行程序,送入8位电话号码,程序自动产生每一位号码数字相应的DTMF信号,并送出双频声音,再用DFT进行谱分析,显示每一位号码数字的DTMF信号的DFT幅度谱,安照幅度谱的最大值确定对应的频率,再安照频率确定每一位对应的号码数字,最后输出6位电话号码,程序名为exp8。
程序分四段:第一段(2—7行)设置参数,并读入8位电话号码;第二段(9—20行)根据键入的8位电话号码产生时域离散DTMF信号,并连续发出8位号码对应的双音频声音;第三段(22—25行)对时域离散DTMF信号进行频率检测,画出幅度谱;第四段(26—33行)根据幅度谱的两个峰值,分别查找并确定输入8位电话号码。根据程序中的注释很容易分析编程思想和处理算法。程序清单如下:
% DTMF双频拨号信号的生成和检测程序
%clear all;clc;
tm=[1,2,3,65;4,5,6,66;7,8,9,67;42,0,35,68]; % DTMF信号代表的16个数
N=205;K=[18,20,22,24,31,34,38,42];
f1=[697,770,852,941]; % 行频率向量
f2=[1209,1336,1477,1633]; % 列频率向量
TN=input('键入8位电话号码= '); % 输入6位数字
TNr=0; %接收端电话号码初值为零
毕业论文http://www.751com.cn/ 论文网http://www.751com.cn/
for p=1:4;
for q=1:4;
if tm(p,q)==abs(d); break,end % 检测码相符的列号q
end
if tm(p,q)==abs(d); break,end % 检测码相符的行号p
end
n=0:1023; % 为了发声,加长序列
x = sin(2*pi*n*f1(p)/8000) + sin(2*pi*n*f2(q)/8000);% 构成双频信号
sound(x,8000); % 发出声音
pause(0.1)
% 接收检测端的程序
X=goertzel(x(1:205),K+1); % 用Goertzel算法计算八点DFT样本
val = abs(X); % 列出八点DFT向量
subplot(4,2,l);
stem(K,val,'.');grid;xlabel('k');ylabel('|X(k)|') % 画出DFT(k)幅度
axis([10 50 0 120])
limit = 80; %
for s=5:8;
if val(s) > limit, break, end % 查找列号
end
for r=1:4;
if val(r) > limit, break, end % 查找行号
end
TNr=TNr+tm(r,s-4)*10^(8-l);
end
disp('接收端检测到的号码为:') % 显示接收到的字符
disp(TNr)
运行程序,根据提示键入8位电话号码12345678,回车后可以听见8位电话号码对应的DTMF信号的声音,并输出相应的8幅频谱图如图(1)所示,左上角的第一个图在k=18和k=31两点出现峰值,所以对应第一位号码数字1。最后显示检测到的电话号码12345678。
上一页 [1] [2] [3] [4] [5] [6] 下一页