这篇文章上次修改于 199 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

线性预测

取语音信号“电子信息工程”进行线性预测分析:
MATLAB代码

clear;clc
N=128*4;
M=8;
[s1 f1]=audioread('D:\englishapp\MATLAB\single\mvoice.wav');
y=s1(:,1)';
y=endpoint_v(y);
[a e]=lpc(y(1:N),M);
y_lpc=filter([0 -a(2:end)],1,y(1:N));
y_lpc_all=filter([0 -a(2:end)],1,y);
figure
plot(y(1:N))
hold on
plot(y_lpc,'-r')
figure
plot(y_lpc_all)
hold on
plot(y,'-r')

结果如图:
2awv_ltac99rm4@n3k3b30e.png
2awv_ltac99rm4@n3k3b30e.png
由图可以看出,图1为128*4采样率的线性预测与原始语音比较图,图2为全部有效数据段采样率的线性预测与原始语音比较图,如图所示。线性预测在初期阶段预测较为准确,与原始信号相似,随着时间的推移,预测的准确性越来越低,与原始语音的相似度降低,预测开始偏移。

语音合成

MATLAB代码:

close all
clear all
clc
FL = 80;                % 帧长
WL = 240;               % 窗长
P = 10;                 % 预测系数个数
[y,fs]=audioread('D:\englishapp\MATLAB\single\mvoice.wav');
s=y(:,1)';
s=endpoint_v(s);
L = length(s);          % 读入语音长度
FN = floor(L/FL)-2;     % 计算帧数
 
% 预测和重建
exc = zeros(L,1);       % 激励信号(预测误差)
zi_pre = zeros(P,1);    % 预测滤波器的状态
s_rec = zeros(L,1);     % 重建语音
zi_rec = zeros(P,1);
 
% 合成
exc_syn = zeros(L,1);   % 合成的激励信号(脉冲串)
s_syn = zeros(L,1);     % 合成语音
zi_syn = zeros(P,1);
 
hw = hamming(WL)';       % 汉明窗
 
% 依次处理每帧语音
for n = 3:FN
    % 计算预测系数
    s_w = s(n*FL-WL+1:n*FL).*hw;    %汉明窗加权后的语音
    [A E] = lpc(s_w, P);            %用线性预测法计算P个预测系数
    % A是预测系数,E会被用来计算合成激励的能量
    
    s_f = s((n-1)*FL+1:n*FL);       % 本帧语音
    
    % 用filter函数s_f计算激励,注意保持滤波器状态
    [Y,zi_pre] = filter(A,[1,zeros(1,P)],s_f,zi_pre);     
    %filter函数
    %当刚开始计算差分方程时,x(n-1),x(n-2)等值还没输入,默认为零。当有初始值时,有利于系统状态连续。
    exc((n-1)*FL+1:n*FL) = Y;        % exc((n-1)*FL+1:n*FL) = ... 得到的激励
%     %用filter函数和exc重建语音,注意保持滤波器状态
%     [Y,zi_rec] = filter([1,zeros(1,P)],A,Y,zi_rec);
%     s_rec((n-1)*FL+1:n*FL) = Y;        % s_rec((n-1)*FL+1:n*FL) = ... 得到的重建语音
    
    % 得到exc后才会计算正确
    s_Pitch = exc(n*FL-222:n*FL);
    PT = findpitch(s_Pitch);    % 计算基音周期PT
    G = sqrt(E*PT);           % 计算合成激励的能量G
    
    % 生成合成激励,并用激励和filter函数产生合成语音
    if n == 3                   % first loop
        cursor = (n-1)*FL+1;    % initialize cursor
        m = n;                  % initialize m
    end
    
    while m == n                % cursor still point into current frame
        exc_syn(cursor) = 1;
        cursor = cursor + PT;   % next cursor
        m = ceil(cursor/FL);    % locate next cursor
    end
    
    [s_syn((n-1)*FL+1:n*FL),zi_syn] = filter([1,zeros(1,P)],A,G*exc_syn((n-1)*FL+1:n*FL),zi_syn);
        % exc_syn((n-1)*FL+1:n*FL) = ... 得到合成激励
        % s_syn((n-1)*FL+1:n*FL) = ...   得到合成语音
        %exc_syn,每一个基音周期,产生一个脉冲
end
    figure
    plot(s)
    hold on
    plot(s_syn,'-r')  %比较原来语音和合成的语音
    
    sound(s)
    pause(2)
sound(s_syn)  %听听有否区别

2awv_ltac99rm4@n3k3b30e.png
根据线性预测技术合成语音原理,用所求预测器参数合成的一帧语音信号,合成语音信号和原始语音信号几乎没有区别,精准度高。但是合成的语音信号在音调上会比原始语音信号更高点。

LPC谱计算

close all
clear all
clc
 
N=128*4;
P=24*16;
M=8;
lpcc=[];
 
% [y,fs]=audioread('e:\instruction\15-16-02\instruction\02\myei.wav');
[s fs]=audioread('D:\englishapp\MATLAB\single\mvoice.wav');
 
y=s(:,1)';
y=endpoint_v(y);
data=y(2*N+1:3*N);
 
[a e]=lpc(data,P);
[h f]=freqz(1,a,N,fs);
 
datah=hilbert(data);
dataf=fft(datah);
 
plot(linspace(1,fs/2,N/2),20*log(abs(dataf(1:N/2))))
hold on
plot(linspace(1,fs/2,N),20*log(abs(h)),'-r')

运行结果:
2awv_ltac99rm4@n3k3b30e.png