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

LPC Анализ и синтез речи

Открыть пример в Engee

В этом примере показано как реализовать метод сжатия речи, используя функциональность библиотеки EngeeDSP. В данном примере реализовано кодирование с линейным предсказанием (LPC) - это метод, используемый в основном в обработки аудиосигнала и речи для представления спектральной огибающей цифрового сигнала речи в сжатой форме с использованием информации линейной модели прогнозирования. В модели реализуется анализ и синтез LPC речевого сигнала.

В разделе "анализ" извлекаются из сигнала коэффициенты отражения и используются для вычисления остаточного сигнала.

В разделе "синтеза" восстанавливается сигнал с помощью остаточного сигнала и коэффициентов отражения.

Остаточный сигнал и коэффициенты отражения требуют меньшего количества битов для кодирования, чем исходный речевой сигнал.

Подключение библиотек, объявление входных данных

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

In [ ]:
using .EngeeDSP;
using  Plots;
plotlyjs();
using WAV;
using Base64;

Объявление переменных

In [ ]:
sample = 80;
var_load = load_audio();
step = EngeeDSP.step;
In1 = step( var_load, "$(@__DIR__)/check_signal.wav", sample );

Объявление структур данных и функций LPC

В этой модели речевой сигнал делится на кадры размером 80 отсчетов с перекрытием 160 отсчетов.

Каждый кадр обрабатывается окном Хэмминга.

Находят коэффициенты автокорреляции десятого порядка, а затем из коэффициентов автокорреляции вычисляют коэффициенты отражения с использованием алгоритма Левинсона-Дарбина. Исходный речевой сигнал проходит через анализирующий фильтр, который представляет собой нулевой фильтр с коэффициентами, равными коэффициентам отражения, полученным выше. Выход фильтра – остаточный сигнал. Этот остаточный сигнал проходит через фильтр синтеза, который является обратным фильтру анализа.

Выход синтезирующего фильтра представляет собой исходный сигнал.

In [ ]:
mutable struct LPCAnalysisAndSynthesisOfSpeech
    obj_Pre_Emphasis
    obj_Overlap_Analysis_Windows
    obj_Window
    obj_Autocorrelation
    obj_Levinson_Durbin
    obj_Time_Varying_Analysis_Filter
    obj_Pad
    obj_FFT
    obj_MathFunction1
    obj_RC_To_InvSine
    obj_5_bit_Quantizer
    obj_6_bit_Quantizer
    obj_Inv_Sine_to_RC
    obj_Time_Varying_Synthesis_Filter
    obj_De_emphasis_Filter
    function LPCAnalysisAndSynthesisOfSpeech()
        new(
        DescretFIRFilter("Dialog parameters","Direct form",[1, -.95],"Columns as channels",0,false,"None"),
        Buffer(160,80,0),
        WindowFunction("Apply window to input","Hamming","Symmetric"),
        Autocorrelation("Biased",10),
        LevinsonDurbin("A and K",false,true),
        DescretFIRFilter("Input port","Lattice MA","Columns as channels",0,false,"None"),
        EngeeDSP.Pad("Columns","Specify via dialog",0,"User-specified",256,"End","None"),
        EngeeFFT("Auto",false,false,true),
        MathFunction("reciprocal","Exact","auto"),
        TrigonometricFunction("asin","auto",false),
        Quantizer(0.1,false),
        Quantizer(0.03125,false),
        TrigonometricFunction("sin","None","auto"),
        AllpoleFilter("Input port","Lattice AR","Columns as channels",0),
        AllpoleFilter("Dialog parameters","Direct form",[1 , -.95],"Columns as channels",0)
        )
    end
end

Настройка параметров LPC.

In [ ]:
function setup(obj::LPCAnalysisAndSynthesisOfSpeech,In1)
    Pre_Emphasis_set = EngeeDSP.setup(obj.obj_Pre_Emphasis,In1) 
    Overlap_Analysis_Windows_set = EngeeDSP.setup(obj.obj_Overlap_Analysis_Windows,Pre_Emphasis_set);
    Window_set = EngeeDSP.setup(obj.obj_Window,Overlap_Analysis_Windows_set);
    Autocorrelation_set = EngeeDSP.setup(obj.obj_Autocorrelation,Window_set);
    Levinson_Durbin_set = EngeeDSP.setup(obj.obj_Levinson_Durbin,Autocorrelation_set);
    Time_Varying_Analysis_Filter_set = EngeeDSP.setup(obj.obj_Time_Varying_Analysis_Filter,Pre_Emphasis_set,Levinson_Durbin_set[2]);
    RC_To_InvSine_set = EngeeDSP.setup(obj.obj_RC_To_InvSine,Levinson_Durbin_set[2]);
    bit_Quantizer_5_set = EngeeDSP.setup(obj.obj_5_bit_Quantizer,RC_To_InvSine_set);
    bit_Quantizer_6_set = EngeeDSP.setup(obj.obj_6_bit_Quantizer,Time_Varying_Analysis_Filter_set);
    Inv_Sine_to_RC_set = EngeeDSP.setup(obj.obj_Inv_Sine_to_RC,bit_Quantizer_5_set);
    Time_Varying_Synthesis_Filter_set = EngeeDSP.setup(obj.obj_Time_Varying_Synthesis_Filter,bit_Quantizer_6_set,Inv_Sine_to_RC_set);
    De_emphasis_Filter_set = EngeeDSP.setup(obj.obj_De_emphasis_Filter,Time_Varying_Synthesis_Filter_set);
end
Out[0]:
setup (generic function with 1 method)

Объявление настроек для первого шага обработки.

In [ ]:
function step1(obj::LPCAnalysisAndSynthesisOfSpeech,In1)
    Pre_Emphasis_out = EngeeDSP.step(obj.obj_Pre_Emphasis,In1); 
    Overlap_Analysis_Windows_out = EngeeDSP.step(obj.obj_Overlap_Analysis_Windows,Pre_Emphasis_out); 
    Window_out = EngeeDSP.step(obj.obj_Window,Overlap_Analysis_Windows_out); 
    Autocorrelation_out = EngeeDSP.step(obj.obj_Autocorrelation,Window_out); 
    Levinson_Durbin_out = EngeeDSP.step(obj.obj_Levinson_Durbin,Autocorrelation_out);
    Time_Varying_Analysis_Filter_out = EngeeDSP.step(obj.obj_Time_Varying_Analysis_Filter,Pre_Emphasis_out,Levinson_Durbin_out[2]);
    Pad_out = EngeeDSP.step(obj.obj_Pad,Levinson_Durbin_out[1]);
    FFT_out = EngeeDSP.step(obj.obj_FFT,Pad_out);
    MathFunction1_out = EngeeDSP.step(obj.obj_MathFunction1,FFT_out);
    RC_To_InvSine_out = EngeeDSP.step(obj.obj_RC_To_InvSine,Levinson_Durbin_out[2]);
    bit_Quantizer_5_out = EngeeDSP.step(obj.obj_5_bit_Quantizer,RC_To_InvSine_out);
    bit_Quantizer_6_out = EngeeDSP.step(obj.obj_6_bit_Quantizer,Time_Varying_Analysis_Filter_out); 
    Inv_Sine_to_RC_out = EngeeDSP.step(obj.obj_Inv_Sine_to_RC,bit_Quantizer_5_out);
    Time_Varying_Synthesis_Filter_out = EngeeDSP.step(obj.obj_Time_Varying_Synthesis_Filter,bit_Quantizer_6_out,Inv_Sine_to_RC_out);
    De_emphasis_Filter_out = EngeeDSP.step(obj.obj_De_emphasis_Filter,Time_Varying_Synthesis_Filter_out);
    De_emphasis_Filter_out,MathFunction1_out;
end
Out[0]:
step1 (generic function with 1 method)

Реализация алгоритма LPC

Вызов функции и обработка выхода эквалайзера.

In [ ]:
obj = LPCAnalysisAndSynthesisOfSpeech() 
setup(obj,In1[1]);
Out_a = zeros(size(vcat(In1...)))
Out_p = In1.*1im
size(In1,1)

for i = 0:size(In1,1) - 2

    output_a = step1(obj,In1[i+1]) 
    Out_a[sample*i + 1 : sample*(i + 1)] = output_a[1]
    
    output_p  = step1(obj,In1[i+1]) 
    Out_p[i+1] = output_p[2]
end

Обработка и анализ результатов

Настройка плеера.

In [ ]:
In2 = vcat(In1...);
function audioplayer(s, fs);
  buf = IOBuffer();
  wavwrite(s, buf; Fs=fs);
  data = base64encode(unsafe_string(pointer(buf.data), buf.size));
  markup = """<audio controls="controls" {autoplay}>
              <source src="data:audio/wav;base64,$data" type="audio/wav" />
              Your browser does not support the audio element.
              </audio>"""
  display("text/html", markup);
  end
Out[0]:
audioplayer (generic function with 1 method)

Воспроизведение оригинального аудио-файла

In [ ]:
audioplayer(In2, 8000)

Воспроизведение шифрованного аудио-файла.

In [ ]:
audioplayer(Out_a, 8000)

График визуального сравнения оригинального и шифрованного файлов.

In [ ]:
plot(In2)
  plot!(Out_a)
Out[0]:

Вывод графика спектрального анализатора.

In [ ]:
u1 = Out_p[1]; u2 = Out_p[2];
uSubset1 = u1[1:floor(Int,length(u1)/2+1)];
uSubset2 = u2[1:floor(Int,length(u2)/2+1)];
y1 = 6.02059991327962 .* log2.(abs.(uSubset1)+hypot.(eps.(real(uSubset1)),eps.(imag(uSubset1))));
y2 = 6.02059991327962 .* log2.(abs.(uSubset2)+hypot.(eps.(real(uSubset2)),eps.(imag(uSubset2))));
In [ ]:
plot([1:129], y1[:], fillrange = -20, fillalpha = 0.35, c = 1, ylabel = "Mag^2", legend = false)
a = plot!([1:129],y1[:], msw = 0, ms = 2.5, xlabel = "Frequency")
plot([1:129], y2[:], fillrange = -20, fillalpha = 0.35, c = 1, ylabel = "Mag^2", legend = false)
b = plot!([1:129],y2[:], msw = 0, ms = 2.5, xlabel = "Frequency")
plot!(a,b)
Out[0]:

Вывод

По итогам данной демонстрации мы разобрали методы взаимодействия с функциями из библиотеки EngeeDSP, а также продемонстрировали возможность создания интерактивных блоков внутри скриптов, данный пример наглядно демонстрирует работу метода LPC кодирования и позволяет нам оценить его эффективность. Это один из самых мощных методов анализа речи и один из самых полезных методов кодирования речи хорошего качества с низкой скоростью передачи данных, обеспечивающий высокоточные оценки параметров речи.