Engee 文档
Notebook

参数音频均衡器

在本演示中,我们将了解一个支持三个可调频段的参数音频均衡器。每个频段都使用不同的二次滤波器结构实现。 image.png

均衡器是一种无线电电子设备或计算机程序,可根据频率特性有选择地修正信号幅度。

在本演示中,我们还将比较EngeeMATLAB模型的工作情况。 为此,我们将连接必要的库,并考虑实施模型的结构。

In [ ]:
Pkg.add(["Statistics", "CSV"])
   Resolving package versions...
  No Changes to `~/.project/Project.toml`
  No Changes to `~/.project/Manifest.toml`
In [ ]:
using Plots
using MATLAB
using CSV
using DataFrames
using Statistics
In [ ]:
plotlyjs();
In [ ]:
mat"start_simulink"
mat"p = genpath('/user/start/examples'); addpath(p);"

模型由两大块组成:均衡器本身(包括 3 个滤波器块,滤波器系数位于上层)和离散传递函数估计器。下图显示了模型和估计器的设置。

image.png

image_2.png

如果我们考虑每个滤波器,它们的实现方式都是一样的,都包括一个离散滤波器系数采样单元和一个二次滤波器。

image_3.png

现在,让我们继续运行并比较该模型在EngeeSimulink中的实现情况。

运行和分析Engee模型

让我们来看看Engee建模的结果:

In [ ]:
function rum_model(NemeModel,Path_to_folder)
Path = Path_to_folder * "/" * NemeModel * ".engee"
   if NemeModel in [m.name for m in engee.get_all_models()] # Проверка условия загрузки модели в ядро
      model = engee.open(NemeModel) # Открыть модель
      engee.run(model, verbose=true); # Запустить модель
   else
      model = engee.load(Path, force=true) # Загрузить модель
      engee.run(model, verbose=true); # Запустить модель
      engee.close(NemeModel, force=true); # Закрыть модель
   end
end
Out[0]:
rum_model (generic function with 1 method)
In [ ]:
# Запуск модели
rum_model("Equalizer","/user/start/examples/dsp/equalizer")
Building...
Progress 0%
Progress 1%
Progress 32%
Progress 100%
Progress 100%
In [ ]:
function parse_csv_engee(filename :: String)
    file = open(filename)
    line = readline(file)
    name_idx = vcat(0,findall(',', line), length(line)+1)
    names = collect([line[(name_idx[it-1]+1):(name_idx[it]-1)] for it  2:length(name_idx)])
    data = collect([it for it  (line -> eval(Meta.parse(line)))(readline(file))])
    while !eof(file)
        data = ((a, b) -> [a;;;b]).(data, collect([it for it  (line -> eval(Meta.parse(line)))(readline(file))]))
    end
    close(file)
    return Dict(names .=> data)
end
Out[0]:
parse_csv_engee (generic function with 1 method)
In [ ]:
# Чтение CSV
out = parse_csv_engee("/user/start/examples/dsp/equalizer/out.csv");
out_t = out["time"];
out_data = out["1"];
In [ ]:
# Построение графиков
Eng_data = reshape(out_data,808)
plot(Eng_data[1:8:end])
plot!(Eng_data[2:8:end])
plot!(Eng_data[3:8:end])
plot!(Eng_data[4:8:end])
plot!(Eng_data[5:8:end])
plot!(Eng_data[6:8:end])
plot!(Eng_data[7:8:end])
plot!(Eng_data[8:8:end])
plot!(title = "Результаты моделирования в Engee", ylabel = "Данные", xlabel="Время, c")
Out[0]:

运行并分析Simulink模型

让我们比较一下EngeeSimulink的模拟结果。为此,我们首先对模型进行仿真。

In [ ]:
mat"run_test_model('Equalizer')";

让我们看看Simulink中的结果:

In [ ]:
mat"whos" # Вывести все переменные, хранящиеся в рабочей области
>> >> >>   Name                     Size                  Bytes  Class                             Attributes

  SimulationSteps        101x1                     808  double                                      
  SysOutput                1x1                    6800  timeseries                                  
  a                        1x6                      48  double                                      
  b                        1x6                      48  double                                      
  matlab_jl_has_ans        1x1                       8  double                                      
  n                        1x32                    256  double                                      
  out                      1x1                  847601  Simulink.SimulationOutput                   
  p                        1x585978            1171956  char                                        
  sig                      1x1                    7018  Simulink.SimulationData.Signal              

In [ ]:
# Чтение выхода модели
sim = mat"SysOutput.Data";
In [ ]:
# Построение графиков
Sim_data = reshape(sim,808)
plot(Sim_data[1:8:end])
plot!(Sim_data[2:8:end])
plot!(Sim_data[3:8:end])
plot!(Sim_data[4:8:end])
plot!(Sim_data[5:8:end])
plot!(Sim_data[6:8:end])
plot!(Sim_data[7:8:end])
plot!(Sim_data[8:8:end])
plot!(title = "Результаты моделирования в Simulink", ylabel = "Отклик", xlabel="Время, c")
Out[0]:

现在绘制SimulinkEngee的输出差值,并计算平均误差。

In [ ]:
plot(Sim_data-Eng_data)
Out[0]:
In [ ]:
print("Погрешность: " * string((sum(abs.(Sim_data-Eng_data)))/length(Eng_data)))
Погрешность: 2.3758486926991814e-12

从上图和平均误差计算结果可以看出,这两个模型的工作原理几乎完全相同。

结论

在本示例中,我们实现了 EQ,并比较了EngeeSimulink建模的功能,还展示了连接MATLAB内核的选项,以便在Engee开发环境中解决问题。