1.掌握语音信号线性叠加的方法,实现非等长语音信号的叠加
2.熟悉语音信号卷积原理,实现两语音卷积。
3.熟悉语音信号升采样/降采样方法。
两个信号X1和X2,通过短时信号的补零,使两语音信号有相同的长度,叠加信号为
X n e w = X 1 + X 2 X_{new}=X_1+X_2 Xnew=X1+X2
叠加白噪声通过生成随机信号的方法来实现
举例
在一个音频信号上叠加一个信噪比为10dB的高斯白噪声,并播放声音对比
实现代码
%语音信号叠加
clc
clear all
[x,fs]=audioread('C2_2_y.wav');
s=1:length(x);
t=s/fs;
xmax=max(abs(x)); %归一化处理
x=x/xmax;
y=awgn(x,10); %在原始信号上叠加信噪比为10dB的高斯白噪声
ymax=max(abs(y));
y1=y/ymax;
subplot(211)
plot(t,x); %画出原始信号的幅度谱
xlabel('时间/s');
ylabel('归一化幅值');
title('(a)原始信号');
subplot(212)
plot(t,y1); %画出加10dB高斯白噪声后归一化的幅度谱
xlabel('时间/s');
ylabel('归一化幅值');
title('(b)随机序列');
sound(x); %播放原始语音
pause(7);
sound(y1); %播放加10dB高斯白噪声后的语音
两序列卷积的定义为
y ( n ) = ∑ k = − ∞ ∞ x 1 ( k ) x 2 ( n − k ) = x 1 ( n ) ∗ x 2 ( n ) y(n)=\sum_{k=-\infty}^{\infty} x_{1}(k) x_{2}(n-k)=x_{1}(n) * x_{2}(n) y(n)=k=−∞∑∞x1(k)x2(n−k)=x1(n)∗x2(n)
注意:产生的序列y(n)长度为两序列长度之和减1
MATLAB中自带的卷积函数为conv()
语法
w=conv(u,v)
此函数将矢量u和v进行卷积运算。从代数上讲,卷积是与多项式相乘。这此多项式的系数就是u和v中的元素。
例 一个语音信号与等长的随机序列进行卷积
实现代码
%:语音信号卷积
clc
clear all
[x,fs]=audioread('C2_2_y.wav');
s=1:length(x);
t=s/fs;
xmax=max(abs(x)); %归一化
x=x/xmax;
y=randn(size(x)); %产生同x相同长度的随机序列
ymax=max(abs(y)); %归一化
y=y/ymax;
z=conv(x,y);
zmax=max(abs(z));
z=z/zmax;
t2=(1:length(z))/fs;
figure(1)
subplot(311)
plot(t,x); %画出原始信号
xlabel('时间/s');
ylabel('归一化幅值');
title('(a)原始信号');
subplot(312)
plot(t,y); %画出随机序列
xlabel('时间/s');
ylabel('归一化幅值');
title('(b)随机序列');
subplot(313)
plot(t2,z); %画出卷积结果
xlabel('时间/s');
ylabel('归一化幅值');
title('(c)信号卷积');
实现代码
%不调用conv()函数,实现语音信号的卷积
clc
clear all
[x,fs]=audioread('C2_2_y.wav');%读取语音信号
s=1:length(x);
t=s/fs;
xmax=max(abs(x)); %归一化
x=x/xmax;
y=randn(size(x)); %产生同x相同长度的随机序列
ymax=max(abs(y)); %归一化
y=y/ymax;
z = my_conv(x,y); %计算卷积
zmax=max(abs(z)); %归一化
z=z/zmax;
t2=(1:length(z))/fs;
subplot(311)
plot(t,x); %画出原始信号
xlabel('时间/s');
ylabel('归一化幅值');
title('(a)原始信号');
subplot(312)
plot(t,y); %画出随机序列
xlabel('时间/s');
ylabel('归一化幅值');
title('(b)随机序列');
subplot(313)
plot(t2,z); %画出卷积结果
xlabel('时间/s');
ylabel('归一化幅值');
title('(c)信号卷积');
function a=my_conv(b,c) %定义自卷积函数
bs=size(b); %求b和c的大小
cs=size(c);
i=any(bs-cs); %判断b和c的大小是否相等
if i %如果相等
error('error')
end
i=any(~(bs-1));
if ~i %如果不相等
error('error')
end
ko=0;
if bs(1)>bs(2) %调整b中的元素,使其按从小到大排序,并转置
b=b';
c=c';
ko=1;
end
bs=size(b);
cs=size(c);
ss=2*bs(2)-1;
a=zeros(1,ss);
for i=1:cs(2) %相乘后再相加
q=zeros(1,i-1);
p=zeros(1,ss-cs(2)+1-i);
ba=[q,c,p];
ma=b(i)*ba;
a=a+ma;
end
if ko %如果元素排好序后,取转置
a=a';
end
end
采样率变换是多采样率信号处理的基础,主要由两个操作组成:抽取和内插。
抽取就是把原采样序列x(n)每隔D-1点取一个值,形成一个新的序列:
x D ( m ) = x ( m D ) x_{D}(m)=x(m D) xD(m)=x(mD)
其中,D为正整数。
注:为了避免抽取序列频谱的混叠,通常需要在抽取前,将信号通过一个抗混叠滤波器。( 抗混叠滤波器是ADC之前为了消除模拟信号中频率高于奈奎斯特采样频率的信号成份,以让系统过去正确的低频信号,本质上,抗混叠滤波器是低通滤波器。)
内插器和抽取器作用相反,它在两个原始序列的样点之间插入I-1个值。设原始序列为x(n),则内插后的序列x_I(m)为:
x 1 ( m ) = { x ( m I ) , m = 0 , ± I , ± 2 I ⋯ 0 , others x_{1}(m)=\left\{\begin{array}{ll}{x\left(\frac{m}{I}\right),} & {m=0, \pm I, \pm 2 I \cdots} \\ {0,} & {\text { others }}\end{array}\right. x1(m)={x(Im),0,m=0,±I,±2I⋯ others
注:内插之后还要通过低通滤波器,抑制混叠信号
MATLAB中自带函数**resample()**能实现采样率的变换
语法
y = resample(x,p,q)
-采用多相滤波器对时间序列进行重采样,得到的序列y的长度为原来的序列x的长度的p/q倍,p和q都为正整数.此时,默认采用使用FIR方法设计的抗混叠的低通滤波器.
y = resample(x,p,q,n)
采用chebyshev IIR型低通滤波器对时间序列进行重采样,滤波器的长度与n成比例,n默认值为10
例:
对简单的线性序列进行为原采样率3/2倍的重采样
实现代码
%语音信号采样频率变换
clc
clear all
[x,fs]=audioread('C2_2_y.wav'); %读取音频文件
s=1:length(x); %采样长度
t=s/fs; %采样时间
xmax=max(abs(x)); %归一化处理
x=x/xmax;
figure(1)
subplot(311)
axis([0 5 -1 1]); %设定x轴与y轴的显示范围
plot(t,x); %画出原始信号的幅度谱
xlabel('时间/s');
ylabel('归一化幅值');
title('(a)原始信号');
p=2;q=1; %设定初始值
x1=resample(x,p,q); %采样率变换,得到的序列y的长度为原来的序列x的长度的p/q倍
x1max=max(abs(x1)); %归一化
x1=x1/x1max;
fs1=fs*p/q; %得到原始采样频率2倍的采样频率
t1=(1:length(x1))/fs1; %得到在新的采样频率对应的采样时间
subplot(312);
axis([0 5 -1 1]); %设定x轴与y轴的显示范围
plot(t1,x1); %画出2倍采样频率下的幅度谱
xlabel('时间/s');
ylabel('归一化幅值');
title('(b)2倍采样率');
p=1;q=2; %设定初始值
x2=resample(x,p,q); %采样率变换,得到的序列y的长度为原来的序列x的长度的p/q倍
x2max=max(abs(x2)); %归一化
x2=x2/x2max;
fs2=fs*p/q; %得到原始采样频率1/2倍的采样频率
t2=(1:length(x2))/fs2;
subplot(313);
axis([0 5 -1 1]); %设定x轴与y轴的显示范围
plot(t2,x2); %画出1/2倍采样频率下的幅度谱
xlabel('时间/s');
ylabel('归一化幅值');
title('(c)1/2采样率');
实现代码
%语音信号采样频率变换
clc
clear all
[x,fs]=audioread('C2_2_y.wav'); %读取音频文件
s=1:length(x); %采样长度
t=s/fs; %采样时间
xmax=max(abs(x)); %归一化处理
x=x/xmax;
p=2;q=1; %设定初始值
x1=resample(x,p,q); %得到的序列y的长度为原来的序列x的长度的p/q倍
x1max=max(abs(x1)); %归一化
x1=x1/x1max;
fs1=fs*p/q; %得到原始采样频率2倍的采样频率
t1=(1:length(x1))/fs1; %得到在新的采样频率对应的采样时间
p=1;q=2; %设定初始值
x2=resample(x,p,q); %得到的序列y的长度为原来的序列x的长度的p/q倍
x2max=max(abs(x2)); %归一化
x2=x2/x2max;
fs2=fs*p/q; %得到原始采样频率1/2倍的采样频率
t2=(1:length(x2))/fs2;
sound(x,fs); %播放以初始采样率采样后的声音
pause(5) %暂停4s,与后面的声音分开
sound(x1,fs1); %播放以1/2倍采样率采样后的声音
pause(5) %暂停4s,与后面的声音分开
sound(x2,fs2); %播放以2倍采样率采样后的声音