Engee documentation
Notebook

Polyphase sampling frequency converter

In this example, the application of the FIR Rate Conversion block is analyzed.
This unit performs an efficient polyphase
conversion of the sampling frequency
using a rational coefficient.
L/M along the first dimension.

The block treats each column of the input
signal as a separate channel and resamples
the data in them independently of each other.

Now let's look at the model itself, developed
for this example. It generates a complex signal,
to which a polyphase conversion of the sampling frequency is applied.

image.png

Auxiliary functions

In [ ]:
# Подключение вспомогательной функции запуска модели.
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

using FFTW
# Расчёт спектра сигнала
function compute_spectrum(signal, fs)
    n = length(signal)
    spectrum = abs.(fft(signal)) / n
    freqs = (0:n-1) .* (fs / n)
    spectrum[1:Int(n/2)], freqs[1:Int(n/2)]  # Вернуть половину спектра (для удобства)
end
Out[0]:
compute_spectrum (generic function with 1 method)

Launching the model and analyzing the calculation

In this example, the filter coefficients will be taken from a MAT file pre-recorded for this model.

In [ ]:
Pkg.add("MAT")
In [ ]:
using MAT
# Чтение данных из .mat файла
file = matopen("$(@__DIR__)/Hm.mat")
var_names = names(file)
print("$var_names")

for var_name in var_names
    value = read(file, var_name)# Получаем значение переменной из файла
    @eval $(Symbol(var_name)) = $value # Динамическое создание переменной с именем var_name
end
# Закрытие файла
close(file)
["Hm3_Numerator", "Hm1_Numerator", "Hm2_Numerator"]
In [ ]:
run_model("Rate_Conversion") # Запуск модели.
Building...
Progress 0%
Progress 0%
Progress 7%
Progress 14%
Progress 20%
Progress 26%
Progress 32%
Progress 38%
Progress 44%
Progress 53%
Progress 63%
Progress 75%
Progress 84%
Progress 94%
Progress 100%
Progress 100%
Out[0]:
SimulationResult(
    "out" => WorkspaceArray{Matrix{ComplexF64}}("Rate_Conversion/out")
,
    "inp" => WorkspaceArray{ComplexF64}("Rate_Conversion/inp")

)

Now let's compare the input and output data.

In [ ]:
inp = collect(simout["Rate_Conversion/inp"])
sim_time = vcat([m[] for m in inp.time]...)  # Извлекаем значения из матриц
inp = vcat([m[] for m in inp.value]...)  # Извлекаем значения из матриц

out = collect(simout["Rate_Conversion/out"])
out = vcat([vec(m2) for m2 in out.value]...)  # Преобразуем каждую матрицу в вектор

println("Кол-во входных залогированных данных: $(length(inp))")
print("Кол-во выходных залогированных данных: $(length(out))")
Кол-во входных залогированных данных: 8001
Кол-во выходных залогированных данных: 16002

As we can see, the output contains 2 times more values
than the input. This indicates that
interpolation has been performed – the process of increasing the sampling frequency of a signal
by adding new samples between existing ones.

In [ ]:
gr()
A = plot(real(inp[1:1000]), imag(inp[1:1000]), seriestype=:scatter, legend=false,
     xlabel="Re", ylabel="Im", title="Вход")
B = plot(real(out[1:1000]), imag(out[1:1000]), seriestype=:scatter, legend=false,
     xlabel="Re", ylabel="Im", title="Выход")
plot(A,B)
Out[0]:

Based on the results of data visualization, it can be seen
that the amplitude of the distribution of values at the output
differs significantly from the values at the input.

Now let's look at the results of the spectral comparison of the input and output.

In [ ]:
spectrum_inp, freqs_inp = compute_spectrum(inp[1:4000], 1000)
spectrum_out, freqs_out = compute_spectrum(out[1:4000], 1000)
plot(
plot(freqs_inp, spectrum_inp, xlabel="Frequency (Hz)", ylabel="Amplitude", title="Вход", label=""),
plot(freqs_out, spectrum_out, xlabel="Frequency (Hz)", ylabel="Amplitude", title="Выход",  label="")
)
Out[0]:

This comparison showed that the signal spectrum was significantly
distorted, and the useful signal was lost after the transformations, based on the
results of spectral analysis.

Conclusion

In this demonstration, we examined a polyphase
sampling frequency converter and the possibilities of using it to change
the sampling frequency of a signal. This option will be very useful for your projects.