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

Этот пример показывает, как реализовать метод сжатия речи, известный как Линейное Предсказание Кодирования (LPC), используя функциональность DSP System Toolbox™, доступную в командной строке MATLAB ®.

Введение

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

Блок-схема ниже показывает систему, которую вы будете реализовывать.

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

Инициализация

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

Инициализируйте переменные.

frameSize = 1600;
fftLen = 2048;

Здесь вы создаете Системный объект, чтобы считать из аудиофайла и определить частоту дискретизации аудио файла.

audioReader = dsp.AudioFileReader('SamplesPerFrame', frameSize, ...
            'OutputDataType', 'double');

fileInfo = info(audioReader);
Fs = fileInfo.SampleRate;

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

preEmphasisFilter = dsp.FIRFilter(...
        'Numerator', [1 -0.95]);

Создайте буферный системный объект и установите его свойства таким образом, чтобы вы получили выход в два раза больше длины frameSize с длиной перекрытия frameSize.

signalBuffer = dsp.AsyncBuffer(2*frameSize);

Создайте окно Системный объект. Здесь вы будете использовать окно по умолчанию, которое является Hamming.

hammingWindow = dsp.Window;

Создайте автокоррелятор и установите его свойства Системному объекту чтобы вычислить лаги в области значений [0:12], масштабируемой на длину входа.

autoCorrelator = dsp.Autocorrelator( ...
            'MaximumLagSource', 'Property', ...
            'MaximumLag', 12, ...
            'Scaling', 'Biased');

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

levSolver = dsp.LevinsonSolver( ...
                'AOutputPort', true, ...
                'KOutputPort', true);

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

analysisFilter = dsp.FIRFilter(...
                    'Structure','Lattice MA',...
                    'ReflectionCoefficientsSource', 'Input port');

synthesisFilter = dsp.AllpoleFilter('Structure','Lattice AR');

deEmphasisFilter = dsp.AllpoleFilter('Denominator',[1 -0.95]);

Создайте системный объект, чтобы воспроизвести полученный звук.

audioWriter = audioDeviceWriter('SampleRate', Fs);

% Setup plots for visualization.
scope = dsp.SpectrumAnalyzer('SampleRate', Fs, ...
    'PlotAsTwoSidedSpectrum', false, 'YLimits', [-140, 0], ...
    'FrequencyResolutionMethod', 'WindowLength', 'WindowLength', fftLen,...
    'FFTLengthSource', 'Property', 'FFTLength', fftLen, ...
    'Title', 'Linear Prediction of Speech', ...
    'ShowLegend', true, 'ChannelNames', {'Signal', 'LPC'});

Цикл обработки потока

Здесь вы вызываете цикл обработки, где вы делаете анализ LPC и синтез входного аудиосигнала с помощью системных объектов, которые вы создали.

Цикл останавливается, когда вы достигаете конца входного файла, который обнаруживается AudioFileReader Системный объект.

while ~isDone(audioReader)
    % Read audio input
    sig = audioReader();

    % Analysis
    % Note that the filter coefficients are passed in as an argument to the
    % analysisFilter System object.
    sigpreem     = preEmphasisFilter(sig);
    write(signalBuffer,sigpreem);
    sigbuf       = read(signalBuffer,2*frameSize, frameSize);
    sigwin       = hammingWindow(sigbuf);
    sigacf       = autoCorrelator(sigwin);
    [sigA, sigK] = levSolver(sigacf); % Levinson-Durbin
    siglpc       = analysisFilter(sigpreem, sigK);

    % Synthesis
    synthesisFilter.ReflectionCoefficients = sigK.';
    sigsyn = synthesisFilter(siglpc);
    sigout = deEmphasisFilter(sigsyn);

    % Play output audio
    audioWriter(sigout);

    % Update plots
    sigA_padded = zeros(size(sigwin), 'like', sigA); % Zero-padded to plot
    sigA_padded(1:size(sigA,1), :) = sigA;
    scope([sigwin, sigA_padded]);
end

Релиз

Здесь вы вызываете метод release для системных объектов, чтобы закрыть все открытые файлы и устройства.

release(audioReader);
pause(10*audioReader.SamplesPerFrame/audioReader.SampleRate); % Wait until audio finishes playing
release(audioWriter);
release(scope);

Заключение

Вы видели здесь реализацию метода сжатия речи с помощью Linear Prediction Coding. В реализации использовалась функциональность DSP System Toolbox, доступная в командной строке MATLAB. Код включает только вызов последовательных системных объектов с соответствующими входными параметрами. Это не включает в себя отслеживание ручного состояния, подверженного ошибкам, которое может быть, например, для реализации буфера MATLAB.