語音信號處理基礎(四)—語音編輯

語音信號處理基礎(四)—語音編輯

實驗目的

1.掌握語音信號線性疊加的方法,實現非等長語音信號的疊加

2.熟悉語音信號卷積原理,實現兩語音卷積。

3.熟悉語音信號升採樣/降採樣方法。

實驗原理

1.信號的疊加

兩個信號X1和X2,通過短時信號的補零,使兩語音信號有相同的長度,疊加信號爲
Xnew=X1+X2 X_{new}=X_1+X_2
疊加白噪聲通過生成隨機信號的方法來實現

舉例

在一個音頻信號上疊加一個信噪比爲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高斯白噪聲後的語音

運行結果
在這裏插入圖片描述

2.信號的卷積

兩序列卷積的定義爲
y(n)=k=x1(k)x2(nk)=x1(n)x2(n) y(n)=\sum_{k=-\infty}^{\infty} x_{1}(k) x_{2}(n-k)=x_{1}(n) * x_{2}(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 

運行結果
在這裏插入圖片描述

3.信號採樣頻率的變換

採樣率變換是多采樣率信號處理的基礎,主要由兩個操作組成:抽取和內插。

抽取就是把原採樣序列x(n)每隔D-1點取一個值,形成一個新的序列:
xD(m)=x(mD) x_{D}(m)=x(m D)
其中,D爲正整數。

注:爲了避免抽取序列頻譜的混疊,通常需要在抽取前,將信號通過一個抗混疊濾波器。( 抗混疊濾波器是ADC之前爲了消除模擬信號中頻率高於奈奎斯特採樣頻率的信號成份,以讓系統過去正確的低頻信號,本質上,抗混疊濾波器是低通濾波器。)

內插器和抽取器作用相反,它在兩個原始序列的樣點之間插入I-1個值。設原始序列爲x(n),則內插後的序列x_I(m)爲:
x1(m)={x(mI),m=0,±I,±2I0, 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.
注:內插之後還要通過低通濾波器,抑制混疊信號

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倍採樣率採樣後的聲音

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章