写个博客记录一下自己的蠢劲儿,之前我想用 FFT 模块做一些信号分析的东西,官方的 FFT 模块必须输入与 FFT 大小一致的数据,然后我也想到了使用 stream to vector 将流数据转换为固定长度的向量数据,然后再一次性喂给 FFT 模块,但是,stream to vector 模块我用的不对,导致 stream to vector 的输出连接 FFT 模块的那条线就一直是红色,我就以为官方的 FFT模块不好用,因此自己就做了 C++ OOT FFT 模块方便自己使用,今天突发奇想,官方做的应该不会有问题,会不会是我自己的使用不当,果真如此,这真是一次教训啊,做这个 FFT 花费了不少时间,既然是教训,那就吃亏是福吧。
stream to vector 模块介绍:
之前我的做法是将 Vec Length 设置成了1024,将 Num items 设置为 1,因此导致输入输出 IO size 不同,犯了这个低级错误,导致自己造轮子重新造了一个 FFT 模块:GNU Radio创建FFT、IFFT C++ OOT块
复刻官方的 demo 示例 grc 图。
其中:
:信号功率谱密度的对数,单位为 dB
:为信号的功率谱密度
:傅里叶变换长度
在进行快速傅里叶变换 (FFT) 时,输出的幅度与输入的样本数量相关。对于
个输入样本,FFT 的输出通常需要缩放
以保持幅度一致,如果要保持输入信号和 FFT 输出的能量一致,需要对 FFT 的结果进行归一化。
是最常见的归一化系数。
从上图可知,运行结果一致。
如何对现有的信号做叠加频偏呢?我们来看一下如何实现
旋转器(Rotator)块执行频率平移操作。这种操作被称为旋转,因为如果将复数采样(实部和虚部)中的实部和虚部绘制在复数单位圆上,在这个圆上进行旋转会产生一个给定频率的波形。顺时针或逆时针进行这样的旋转会产生正频率或负频率,这正是这个块在数学上执行的操作。
相位增量(以弧度为单位)是每次采样时信号增加的额外相移量。因此,该块相当于用复数正弦进行乘法操作。
我们正在处理采样信号,因此我们只能在每个采样间隔
观察它,在两个采样时刻之间,相位会增长
,因此,为了实现特定的频率偏移
,必须从目标频率计算相位增量。
其中 Rotator 的参数 Phase Increment 值如下:
上面我们将 freq_offset 也就是频率偏移设置为 4 KHz,因此经过频偏后的信号应该在原信号的基础上频谱会偏移 4KHz。
原信号频率为 1KHz,经过频偏后的信号为 5KHz