Документация Engee

Генератор тональных сигналов

DTMF — двухтональный многочастотный аналоговый сигнал, иначе говоря каждому символу соответствует набор из двух частот.

Сфера применения тональных сигналов: автоматическая телефонная сигнализация между устройствами. В частности, такие тональные сигналы используются для управления соединением между аналоговым оборудованием.

Реализация DTMF

Подключение библиотек.

using Plots
using FFTW
using DSP
using WAV

Объявление параметров системы

# symbols = ["1", "5", "0", "8", "6", "4", "7", "7", "0", "0", "0"]; # Набор символов
symbols = ["5", "0", "8"]; # Набор символов
lfg = [697 770 852 941]; # Группа нижних частот
hfg = [1209 1336 1477];  # Группа верхних частот
f = [reshape(ones(3, 1) * lfg, 1, 12); repeat(hfg, 1, 4)];
Fs = 8000;       # Частота дискретизации 8 кГц
N = 800;        # Длительность тональности 100 мс
t = [0:N-1;] ./ Fs; # 800 дискретов на Fs
pit = t * 2 * pi;
tones = zeros(N, length(symbols));

Заполнение тональностей

for i = 1:length(symbols)
    if symbols[i] == "1"
        tones[:, i] = sum(sin.(f[:, 1] * pit'), dims=1)'
    elseif symbols[i] == "2"
        tones[:, i] = sum(sin.(f[:, 2] * pit'), dims=1)'
    elseif symbols[i] == "3"
        tones[:, i] = sum(sin.(f[:, 3] * pit'), dims=1)'
    elseif symbols[i] == "4"
        tones[:, i] = sum(sin.(f[:, 4] * pit'), dims=1)'
    elseif symbols[i] == "5"
        tones[:, i] = sum(sin.(f[:, 5] * pit'), dims=1)'
    elseif symbols[i] == "6"
        tones[:, i] = sum(sin.(f[:, 6] * pit'), dims=1)'
    elseif symbols[i] == "7"
        tones[:, i] = sum(sin.(f[:, 7] * pit'), dims=1)'
    elseif symbols[i] == "8"
        tones[:, i] = sum(sin.(f[:, 8] * pit'), dims=1)'
    elseif symbols[i] == "9"
        tones[:, i] = sum(sin.(f[:, 9] * pit'), dims=1)'
    elseif symbols[i] == "*"
        tones[:, i] = sum(sin.(f[:, 10] * pit'), dims=1)'
    elseif symbols[i] == "0"
        tones[:, i] = sum(sin.(f[:, 11] * pit'), dims=1)'
    elseif symbols[i] == "#"
        tones[:, i] = sum(sin.(f[:, 12] * pit'), dims=1)'
    end
end

Задание пауз между тональностями.

    N8::Int64 = N / 8
    tones = [tones; 0.05 * randn(N8, length(symbols))];
    tones = [0.05 * randn(N8, 1); tones[:]];

Анализ результатов

Построим график сигнала.

N = length(tones);
t = [0:N-1;] / Fs;
plot(1e3 * t, tones, xlabel="Время, мс", ylabel="Амплитуда", title="DTMF сигнал")

interactive-scripts/images/communication_Tone_gen/e35650d1eede39c408e1ec36e40ffe2ae1070d63

Построение графика спектра.

Спектр построим, используя быстрое преобразование Фурье.

Spec = 10 * log10.(abs.(fftshift(fft(tones)) ./ 1000) .^ 2);
freqs = fftshift(fftfreq(length(t), Fs))
plot(freqs, Spec, xlim=(650, 1500), xticks=650:100:1500, xlabel="Частота, Гц", ylabel="Мощьность, дБ", title="Спектр DTMF сигнала")

interactive-scripts/images/communication_Tone_gen/24a335c1381a43593ebf18828e52ddcf1db5245a

По представленным графикам сложно наглядно понять какой был изначальный набор символов. Для более удобного представления построим спектрограмму исходного сигнала.

spgr = spectrogram(tones[:,1], 255, 128; fs = Fs); # Создание спектрограммы исходного DTMF сигнала
Plots.heatmap(spgr.time.*1000, spgr.freq, pow2db.(spgr.power), xguide = "Время, мс", yguide = "Частота, Гц",ylim =(500, 1500), yticks=650:100:1500)

interactive-scripts/images/communication_Tone_gen/834a0d0f56f5e232a92ef708917aaa8f6b8a834b

Из спектрограммы следует, что набор символов был: 5,0,8.

Вывод

По итогам разработки данного примера вам были продемонстрированны возможности реализации в Engee генератора тональных сигналов, а также возможности визуализации модулированных сигналов для выполнения удобного анализа этих сигналов.