如何找到Rosenberg Glottal模型的频率响应

时间:2014-12-04 01:55:58

标签: matlab

有没有简单的方法来计算以下函数的频率响应?

enter image description here

我尝试过使用重质功能,但没有运气。

基本上我想编写一个函数来根据输入N1和N2以及0和pi之间的点数(比如x)返回频率响应

输出将是一个向量,它返回相应频率的频率响应的x值=> 0:PI / X:PI

1 个答案:

答案 0 :(得分:1)

假设N1 + N2 < num_points,其中num_points是序列的长度,你可以简单地编写函数:

function [gr] = rosenburg(N1, N2, num_points)
gr = zeros(num_points,1);
range1 = 0:N1;
range2 = N1+1:N1+N2;
gr(range1+1) = 0.5*(1 - cos(pi*range1/N1));
gr(range2+1) = cos(pi*(range2-N1) / (2*N2));
end

函数原型rosenburg接收N1N2以及您希望此函数接收的总点数num_points。这段代码的工作原理是我们首先分配一个大小为num_points的零的数组。然后,我们计算两个线性范围:一个来自0 <= n <= N1,另一个来自N1 < n <= N2。请注意,第二个范围首先将N1偏移1,因为我们已经计算了n = N1处的值。一旦我们计算了这些范围,我们就可以在正确的范围内应用正确的关系。请注意,当我将关系分配给数组中的正确间隔时,我需要偏移1,因为MATLAB开始在索引1处索引数组。其余的值由于在开头的初始化而为零。功能

现在,如果您想查找此信号的频率响应,请使用fft Fast Fourier Transform。这是在数字基础上找到离散输入信号的频域版本的经典方法。因此,一旦使用rosenburg函数创建信号,就将其输入FFT函数。你怎么称呼它是这样的:

X = fft(gr);

这计算N点FFT,其中N是信号gr的长度。或者,您可以提供要为其计算FFT的点数。具体做法是:

X = fft(gr, N);

基本上,N越高,频率分量越细或越精细。请注意,频率轴在0到2*pi之间归一化,因此N越高,轴上相邻点之间的分辨率就越高。具体而言,该轴上的每个点具有以下频率:

w = i*(2*pi)/x;

i将是x - 轴上的索引(0,1,2,...,num_points-1),x将是总点数FFT。通常情况下,人们会显示-pi <= w <= pi之间的频谱,因此有些人会应用fftshift来移动频谱,以便DC分量位于频谱的中心,这就是我们如何自然地将频谱感知到是

当您说&#34;频率响应&#34;时,我认为您指的是幅度,因此请使用abs来计算每个值的复杂幅度,如fft通常是复杂的。因此,假设您希望将FFT计算为与信号长度一样多的点,并且让我们选择N1 = 4, N2 = 8并且我们想要64点,并且我们想要绘制频谱。只需这样做:

gr = rosenburg(4, 8, 64);
X = fft(gr);
Xshift = fftshift(X);
plot(linspace(-pi,pi,64), abs(Xshift));
grid;

上述代码将移动频谱,然后将其幅度绘制在-pipi之间。这就是我得到的:

enter image description here

作为一个例子,在我们应用fftshift

之前,这就是频谱的样子

enter image description here

以下是生成上图的代码:

plot(linspace(0,2*pi,64), abs(X));
grid;

您可以看到光谱是对称的。在频率pi处,您可以看到它是镜像反射的,这从pi2*pi的范围是有意义的,精确地映射到-pi为0。信号是真实的,频谱是对称的。实际上,我们可以将此信号称为Hermitian symmetric。显然,频率分量有点稀疏。将点总数增加到256可能会更好。这是我将点数更改为256时得到的结果:

enter image description here

非常流畅!现在,如果要将频率分量从0提取到pi,则需要提取存储在X中的一半频率分解。因此,您只需:

f = X(1:numel(X)/2);

numel确定数组或矩阵中有多少个元素。但请记住,每个频率点都定义为:

w = i*(2*pi)/x

你特别想要:

w = i*pi/x

因此,您需要首先以两倍的信号计算FFT,然后以相同的方式提取一半的光谱。例如,64点:

gr = rosenburg(4, 8, 64);
X = fft(gr, 128);
f = X(1:numel(X)/2);

这应该有希望让你开始。祝你好运!