AnyMath 文档
Notebook

EngeeDSP系统对象

系统对象是Engee技术计算环境中的专用软件结构。 对象用于实现和建模具有时变输入的动态系统。 它们简化了Engee脚本中流处理系统的构建。

作为动态系统的一个例子,我们可以考虑读取一个长文件中记录的几个信号样本的"帧",然后用数字滤波器处理这个帧,或者使用FFT方法或滤波器组进行频谱分析。 该链中的所有链接可以由相应的系统对象序列表示。

so.png

在这个例子中,我们将考虑实现类似于Engee参考模型的流处理和可视化方案的可能性,该模型是由可参数化块组装而成的。 引用_FFT。engee模型是前面讨论过的模型的变体this примера.

修改后的模型使用具有有限脉冲响应(FIR)的低通滤波器(LPF)处理具有线性频率调制(lfm)的真实信号,然后缓冲数据帧并计算加窗快速傅立叶变换(FFT)的结果,![reference_fft--1773861203257.png](附件:reference_fft--1773861203257。png)

在"信号可视化"窗口中运行模型时,可以观察到DSP算法的预期行为。 我们在***的脚本中实现这个处理链。基于EngeeDSP库的系统对象的ngscript**格式。

我们将指出所使用的DSP的系统对象和功能库。:

In [ ]:
using EngeeDSP
using EngeeDSP.Functions

我们将设置数字系统的基本参数,例如采样频率和处理帧的大小。:

In [ ]:
fs = 8000;
framesize = 512;

流信号的来源

我们将使用SineWaveDSP系统对象作为具有线性变化采样频率的信号源。 它产生正弦振荡,频率可以在一个周期内变化,从而近似FM信号源的行为。 我们将给他采样频率和帧大小的参数。:

In [ ]:
source = SineWaveDSP();
source.SampleTime = 1//fs;
source.SamplesPerFrame = framesize;
source
Out[0]:
SineWaveDSP:
    Amplitude=1
    Frequency=100
    PhaseOffset=0
    SampleMode=Discrete
    OutputComplexity=Real
    ComputationMethod=Trigonometric fcn
    SampleTime=1//8000
    SamplesPerFrame=512
    ResettingStatesWhenReEnabled=Restart at time zero

考虑对象在调用和状态重置时的行为。:

In [ ]:
release!(source)
In [ ]:
x = source();
plot(x, leg=false)
Out[0]:

低通滤波器

让我们从原型设计一个合适的低通滤波器开始。 为此,我们使用EngeeDSP中的综合和分析函数。函数库。:

In [ ]:
n = 15;
firwin = window("hamming", n+1)
b = fir1(n, 2000/(fs/2), firwin, "low");
freqz(b, 1, 512, fs, out=:plot)
Out[0]:

我们将滤波器原型的传递函数的分子的系数转移到**DiscreteFIRFilter系统对象。**滤波器状态对处理信号形状的影响在[本社区示例]中有更详细的描述(https://engee.com/community/ru/catalogs/projects/sistemnyi-obekt-kikh-filtra ):

In [ ]:
FIR = DiscreteFIRFilter();
FIR.Coefficients = b;
setup!(FIR, zeros(framesize));
plot(b, l=:stem, m=:c)
Out[0]:

窗口功能

没有必要为窗口函数使用系统对象,因为它的数学不会根据以前的信号值和状态而改变。 只需在时域中生成一个数据帧大小的汉明窗口值的向量就足够了:

In [ ]:
hamwin = window("hamming", framesize);
plot(hamwin,l=:stem,label="Hamming window")
Out[0]:

FFT的

EngeeFFT系统对象将继承输入帧的大小,但我们将用复数样本的数值除以FFT的长度。:

In [ ]:
FFT = EngeeFFT();
FFT.DivideOutputFFTLength = true;
FFT
Out[0]:
EngeeFFT:
    FFTImplementation=Radix-2
    OutputInBitReversedOrder=false
    DivideOutputFFTLength=true
    InheritFFTLength=true
    FFTLength=64
    WrapInputData=true

转换为dBm

DbConverion对象允许您设置输入和输出信号的参数。 在我们的例子中,我们将幅度转换为dBm:

In [ ]:
dbconv = dBConversion()
dbconv.ConvertTo = "dBm";
dbconv
Out[0]:
dBConversion:
    ConvertTo=dBm
    InputSignal=Amplitude
    LoadResistance=1
    AddEpsToInputToProtectAgainst=false

访问系统对象的主要周期

让我们设置正弦信号源重复频率变化值的数值向量 freq_range. 频率将以50Hz为增量从50Hz变化到4000Hz。

我们还初始化频率网格向量 freqvec 于随后的光谱的显示。

主循环的迭代次数将对应于正弦波频率的增加值的矢量的长度。 处理的结果将逐帧放置在矩阵中 spectrum:

In [ ]:
freq_range = 50:50:Int(fs/2);
freqvec = LinRange(0.0,fs/2,Int(framesize/2));
count = length(freq_range);
spectrum = zeros(Int(framesize/2),count);

在周期的每一步,改变正弦波发生器的系统对象的频率参数,并将正弦的一段记录在变量中。 sine_chunk,用FIR滤波器处理此帧,应用窗口函数,计算复数FFT矢量,将其裁剪到"中间",计算模数并将其从幅度转换为dBm:

In [ ]:
for k = 1:count
    source.Frequency = freq_range[k];
    sine_chunk = source();
    LPF = FIR(sine_chunk);
    complexFFT = FFT(LPF .* hamwin);
    absFFT = abs(complexFFT[1:Int(framesize/2)]);
    spectrum[:,k] = dbconv(absFFT);
end

可视化

让我们使用三维表面显示"动态模拟"整个时间内动力学中的光谱变化。:

In [ ]:
surface(1:count, freqvec, spectrum)
Out[0]:

我们还可视化了频谱变化的动画。:

In [ ]:
anim = @animate for i = 1:count
    plot(freqvec, spectrum[:,i], 
                    lw=2, 
                    ylim = (-120,30), 
                    leg = false, 
                    title = "Lfm信号的频谱",
                    yguide = "dBm",
                    xguide = "频率(Hz)",
                    size = (800,200))
end
gif(anim, "dynamic_spectrum.gif", fps = 10)
Out[0]:
No description has been provided for this image

结论

我们已经考虑了基于系统对象EngeeDSP构建流处理和信号可视化的完整动态模型的可能性。 该模型包括功能节点:

*具有不同重复率的正弦信号源
*FIR低通滤波器
*窗口功能
*快速傅立叶变换
*以dBm计算信号频谱
*可视化