我发现了以下代码: />
计算系数。然后,在音频样本中,我以这种方式“低通”它们:
void getLPCoefficientsButterworth2Pole(const int samplerate, const double cutoff, double* const ax, double* const by)
{
double PI = M_PI;
double sqrt2 = sqrt(2);
double QcRaw = (2 * PI * cutoff) / samplerate; // Find cutoff frequency in [0..PI]
double QcWarp = tan(QcRaw); // Warp cutoff frequency
double gain = 1 / ( 1 + sqrt2 / QcWarp + 2 / ( QcWarp * QcWarp ) );
by[2] = ( 1 - sqrt2 / QcWarp + 2 / ( QcWarp * QcWarp ) ) * gain;
by[1] = ( 2 - 2 * 2 / ( QcWarp * QcWarp ) ) * gain;
by[0] = 1;
ax[0] = 1 * gain;
ax[1] = 2 * gain;
ax[2] = 1 * gain;
}
以获得低通设计。
我想知道一些事情:
我以简单的float *数组接收音频样本。那浮点数是多少?我唯一看到的是一个数字,声音如何?
代码在每个样本的新计算中使用了过去的计算(其中三个)。这是否意味着前2个数据样本未正确过滤? (这并不重要,因为它只有2个样本,但只是想知道)
试图学习所有内容,我发现了Butterworth(第二极)滤波器的两个公式。这些公式在代码中如何体现?我发现的公式都没有这些计算可以在“ getLPCoefficientsButterworth2Pole()”函数中看到。
#1 楼
数字float *数组是指向该数组的指针。它是一个数字,包含浮点值数组的第一个元素的地址。
通常,初始条件(即x和y的初始“过去”元素)为0,但是如果它们的值是不等于0也不是什么大问题,因为过一会儿,初始条件对任何稳定滤波器的输出信号都没有影响。并且您的滤波器显然是稳定的。
具有巴特沃斯特性和截止频率$ \ omega_a = 2 * \ pi * f_a $(其中$ f_a $以赫兹为单位)的二阶低通传递函数由
$$ H(s)= \ frac {\ omega_a ^ 2} {s ^ 2 + \ sqrt {2} \ omega_a s + \ omega_a ^ 2} \ tag {1} $$
这是标准结果,您可以在网上轻松找到。为了获得离散时间滤波器,您可以应用所谓的双线性变换:
$$ s = 2f_s \ frac {z-1} {z + 1} \ tag {2} $ $
其中$ f_s $是采样频率。
这是必需的,因为需要将模拟信号($ 0 \ le f \ le \ infty $)的频率轴映射到离散时间信号的允许频率范围($ 0 \ le f \ le f_s / 2 $)。由于此变换会扭曲频率,因此我们需要根据离散时间域中的给定截止频率$ f_d $计算所需的模拟截止频率:
$$ \ omega_a = 2f_s \ tan(\ frac {\ omega_d} {2})\ text {with} \ omega_d = 2 \ pi f_d / f_s $$
如果将(2)插入(1),则会得到
$$ H(z)= k \ frac {z ^ 2 + b_1z + b_2} {z ^ 2 + a_1z + a_2} \ tag {3} $$
$$ k = \ frac {\ alpha ^ 2} {1+ \ sqrt {2} \ alpha + \ alpha ^ 2} \ text {(gain)} $$
$$ a_1 = \ frac {2(\ alpha ^ 2-1)} {1+ \ sqrt {2} \ alpha + \ alpha ^ 2},\ quad
a_2 = \ frac {1- \ sqrt {2} \ alpha + \ alpha ^ 2} {1+ \ sqrt {2} \ alpha + \ alpha ^ 2},\ quad
b_1 = 2,\ quad b_2 = 1 $$
我在哪里已使用$ \ alpha = \ tan(\ frac {\ omega_d} {2})$。
$$ y(n )= kx(n)+ kb_1x(n-1)+ kb_2x(n-2)-a_1y(n-1)-a_2y(n-2)$$
如您所见,您的代码有很多相似之处。但是,也存在一些差异,您应该检查滤波器的频率响应。我认为上述方程式是正确的,但是您可以检查它们并决定哪个版本是正确的。
评论
$ \ begingroup $
谢谢。我明白第一个。但这仍然是一个浮点数数组。我的意思是:单个浮点值代表什么?
$ \ endgroup $
–尼克·范德斯汀(Niek van der Steen)
13年4月17日在9:13
$ \ begingroup $
一个浮点值是您的输入样本之一。
$ \ endgroup $
– Matt L.
13年4月17日在9:19
$ \ begingroup $
简而言之:声音是气压的变化,通过换能器(麦克风)将其转换为电信号,其信号变化与气压相同。每秒测量N次(=采样率)电信号的幅度,以产生在float *数组中看到的数字序列。关于(音频)数字处理的在线演示有数十个,以更详细的方式解释了此过程。
$ \ endgroup $
–小食
13年4月17日在9:24
$ \ begingroup $
我已经编辑了答案,以解决您问题的最后一部分。
$ \ endgroup $
– Matt L.
13年4月17日在12:24
$ \ begingroup $
您正在使用x(n-something),x是什么?我假设输入样本为“ n”?好答案!
$ \ endgroup $
–尼克·范德斯汀(Niek van der Steen)
13年4月17日在13:49
#2 楼
您询问了低通滤波器的工作原理,并提到该滤波器使用的是您数据的过去值。这是关于低通滤波器发生情况的非技术性讨论。低通滤波器可以对信号进行不同的观察(随时间变化),缩放比例并将它们相加。您可以想象绘制3次信号,一次是电流,第二次是一个采样时间偏移,第三次是2个采样时间偏移。
在低频下,所有视图看起来都非常相似(单个样本的偏移几乎不会随时改变您在信号上的位置)。在这种情况下,这三个版本将以建设性(或至少非破坏性)的方式加在一起,因此信号将通过滤波器。
现在移动到更高的频率,信号的每个偏移版本在任何给定的瞬间(采样点)都变得更加清晰,实际上甚至可能反转符号。在这些较高的频率下,信号的三个版本趋向于抵消(相消地增加),从而使信号衰减。
不同类型的滤波器会导致这种相长/相消干扰发生。适当的频带以创建低通,带通或高通滤波器。
#3 楼
这取决于您想要的方式。对我来说,我已经在C
中实现了。所以,我所做的是我使用matlab
在firls
中生成了滤波器系数。然后,我将该滤波器系数存储在数组中,然后将这些滤波器系数传递给C
中的滤波器函数。在matlab
中,很容易生成滤波器系数,然后使用卷积运算或使用特定的滤波器。但是在C
中,您还必须实现过滤器。就我而言,我必须对DSP进行处理,因此在C
中实现,并使用mex函数在matlab
中得到了结果。要计算系数,请在matlab
中使用此命令:n=17 %filter order
f=[0 0.167 0.333 1] %Frequency band edges
a=[1 1 0 0] %Desired amplitudes
fir= firls (n, f,a )
评论
我并不是想在这里不恭敬,但是您的陈述“那是一种声音吗?”似乎表明您不了解时间离散处理的基本原理。如果不了解采样定理,量化,LTI系统等基础知识,将很难解决任何DSP问题。我建议您花些时间阅读一本好书。这是免费的dspguide.com/pdfbook.htm