Engee 文档
Notebook

使用 Engee 函数的 AGC 模型

AGC(自动增益控制)是一种在通信系统中控制信号强度的方法。 是通信系统中的一种信号电平控制技术,其主要目的是 是通信系统中的一种信号电平控制技术,其主要目的 是通信系统中的一种信号电平控制技术,其主要目的是在输入信号的振幅发生变化时保持输出信号的稳定电平。

AGC 应用实例 1.在收音机中,无论接收信号的强度如何,它都能帮助稳定音量。 无论接收信号的强度如何。 2.在音频系统中,即使音源音量突然变化,它也能保持稳定的录音电平。 2. 在音频系统中,即使音源音量突然变化,它也能保持稳定的录音音量。

因此,AGC 可在各种条件下提供舒适和高质量的信号接收/回放。 在各种条件下接收/播放信号。 我们实现的模型如下。

image.png

该模型有一个 Engee 功能块,用于实现计算增益的算法。 计算增益的算法。包络变量是一个类似于 MATLAB 常量变量(持久)的变量。它是本地的 但同时,它在每一步计算中都不会被重置,而是会存储上一步的值。 也就是说,它们在函数调用之间被保存在内存中。 在两次函数调用之间保存在内存中。

让我们仔细看看这个函数的实现。

1.区块结构

块是一种继承于 AbstractCausalComponent 的结构。它包含一个 envelope 字段,其类型为 Float64,用于存储信号的包络值。 用于存储信号的包络值。 Block() 构造函数本身会初始化 一个新的 Block 对象,其初始 包络值等于 0。

image.png

2.调用功能

这是我们算法的主要函数。它 需要三个参数:t(时间)、电平和响度。

如果包络值小于 0.08,则 envelope_gain 设置为 0.08。 否则,将使用当前的包络值。

函数返回响度值除以 envelope_gain、 即增益的最终值 增益的最终值。 image.png

3.功能更新!

此函数更新对象 块。它计算电平与当前包络值之间的差值。 如果差值为正,则包络值将增加该差值的 80%。 差值。否则,包络值将减少该差值的 1%。因此 函数将返回一个更新后的 Block 对象,以便我们存储和重新定义它。 在每个计算步骤中,我们都可以存储和重新定义该值。 image_2.png

既然我们已经决定了如何组织模型,接下来就开始运行并分析结果吧。

辅助功能

In [ ]:
using WAV;
using .EngeeDSP;

function audioplayer(patch, Samples_per_audio_channel);
    s, fs = wavread(patch); 
    buf = IOBuffer();
    wavwrite(s, buf; Fs=fs);
    data = base64encode(unsafe_string(pointer(buf.data), buf.size));
    display("text/html", """<audio controls="controls" {autoplay}>
    <source src="data:audio/wav;base64,$data" type="audio/wav" />
    Your browser does not support the audio element.
    </audio>""");
    return s
end

# Подключение вспомогательной функции запуска модели.
function run_model( name_model)
    
    Path = (@__DIR__) * "/" * name_model * ".engee"
    
    if name_model in [m.name for m in engee.get_all_models()] # Проверка условия загрузки модели в ядро
        model = engee.open( name_model ) # Открыть модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
    else
        model = engee.load( Path, force=true ) # Загрузить модель
        model_output = engee.run( model, verbose=true ); # Запустить модель
        engee.close( name_model, force=true ); # Закрыть модель
    end
    sleep(5)
    return model_output
end
Out[0]:
run_model (generic function with 1 method)

运行和分析模型

In [ ]:
run_model("agc_code") # Запуск модели.
Building...
Progress 0%
Progress 0%
Progress 6%
Progress 6%
Progress 13%
Progress 13%
Progress 18%
Progress 18%
Progress 23%
Progress 23%
Progress 29%
Progress 29%
Progress 34%
Progress 34%
Progress 40%
Progress 40%
Progress 45%
Progress 45%
Progress 50%
Progress 50%
Progress 56%
Progress 56%
Progress 61%
Progress 61%
Progress 66%
Progress 66%
Progress 72%
Progress 72%
Progress 77%
Progress 77%
Progress 83%
Progress 83%
Progress 88%
Progress 88%
Progress 94%
Progress 94%
Progress 99%
Progress 99%
Progress 100%
Progress 100%
Progress 100%
Progress 100%
Out[0]:
SimulationResult(
    "Out" => WorkspaceArray("agc_code/Out"),
    "inp" => WorkspaceArray("agc_code/inp")
)

让我们比较一下模型输入和输出的第一个通道的其中一个帧。

In [ ]:
inp = collect(simout["agc_code/inp"])
inp = inp.value[10,1]
out = collect(simout["agc_code/Out"])
out = out.value[10,1]

plot([inp[:,1],out[:,1]], label=["input data" "output data"])
Out[0]:

我们可以看到,该帧输出信号的振幅明显低于输入信号的振幅。 比输入信号的振幅低得多、 这表明我们的函数工作正常。

现在让我们来听听这两个音轨的声音。

In [ ]:
audioplayer("$(@__DIR__)/speech_fade_48kHz.wav", 256);
In [ ]:
audioplayer("$(@__DIR__)/out_48kHz.wav", 256);

结论

从这个例子可以看出,我们的自动信号增益控制算法运行正常。