matlab音頻信號處理

首先來認識一下什么是音頻信號

通過matlab我們可以直接讀入一個音頻文件,同時直接繪圖
但是此時的橫坐標和縱坐標是什么呢?

>> [y,fs] = audioread('5num.wav');
>> plot(y)

不斷放大信號:

得到了這樣一幅圖

image

這時候縱坐標我們可以理解成幅度,但是橫坐標其實什么也不是
或者說就是一系列點而已,我們可以對這些點進行一定的組合,比如每160個點作為一組,這就是分幀

那頻率呢?
matlab在讀取一個音頻的時候還會返回一個頻率呀,這個頻率,也就是那個fs,到底是干嘛的,有什么意義呢?

不妨來計算一下:
我的這段音頻是29s,

>> length(y)/fs
ans =
   29.4400

此時用點的個數除以頻率fs,得到的就是時間!
這樣想,頻率的物理意義就是一秒鐘振動的次數,8khz就是一秒鐘要震動8000次,一個點震動一次,那么235520個點就要震動29.4400s!

同時可以知道這段音頻是16位量化的

可是我們老是說量化量化,量化究竟代表什么含義呢?

其實就理解成每一個點用16個bit來表示

那么,235520個點,每一個點都是16位的,相當于一個點就是2byte

那么就是 235520*2 字節
等價于460KB

查看文件大小


正好是460KB!!

現在理解這幾個參數的含義了吧

于是上面那幅圖我們需要改進一下

>>t = (0:length(y)-1)/fs;
>> plot(t,y);
>> xlabel('時間(.sec)')
>> ylabel('幅度')

這樣就能得到每一個時刻對應的幅度了

分幀?

到底什么是分幀呢?

首先需要確定分幀的長度:

比如采樣率是11025
語音信號每20ms分成一段

怎么想,一秒鐘有11025個點震動,那么20ms內就是大概220個點了,于是幀長為220,幀移默認就是一半110

問:為什么分幀?
答:語音信號是瞬時變化的,但在10~20ms內是相對穩定的,即在一小段內是相對穩定的,分幀就是將語音分成一段一段的。
問:問什么要有幀移呢?
答:幀移后的每一幀信號都有上一幀的成分,防止兩幀之間的不連續。語音信號雖然短時可以認為平穩,但是由于人說話并不是間斷的,每幀之間都是相關的,加上幀移可以更好地與實際的語音相接近。

如果采樣率都是8000hz,并且20ms為一幀
相當于160個點為一個幀

但是調用enframe函數返回的結果又是什么呢?

5885*160的矩陣

每一行,有160列

每一列,有5885行

你想啊,我是每160個點為一個幀,那么總共有多少個幀呢?

這個不難算

那么我可以單獨取出其中的一個幀來看


a = X(2000,:);
plot(a)

當然這里只是知道有160個點,但是對應的時間段卻是不知道的

也就是說每一行其實就是一個幀的數據了
之所以這張圖有點奇怪


橫坐標代表第多少幀,縱坐標代表振幅

因為有很多根曲線是重疊的

問題在于分幀之后,如何求自相關系數等
可不可以每一個幀求一次自相關系數呢?

補充一點,調用enframe函數如果不指定第三個參數那么幀之間就不會重疊的

如何求自相關系數?

首先試如何理解自相關系數

比如:

>> A = [1 2 3]
A =
     1     2     3
>> xcorr(A)
ans =
    3.0000    8.0000   14.0000    8.0000    3.0000
>> 

這個口算應該沒問題的

就是求出A的自相關系數

但是這個呢?

>> xcorr(A,4)
ans =
  1 至 7 列
         0         0    3.0000    8.0000   14.0000    8.0000    3.0000
  8 至 9 列
         0         0

是不是可以理解成延展了

按照規律來說是沒問題的,xcorr(A,4) 相當于兩個5列的向量
得到的就是2*5 - 1= 9個

解讀代碼

先把代碼放上來吧,方便你們copy

[y,fs] = audioread('5num.wav');

N = length(y);
t = (1:N-1)/fs;  %生成時間序列
win = hamming(N) %加窗
y = y.*win;
X = enframe(y,160); % 160個點為一幀,就沒要重疊了

% 然后就可以查看某個幀了


%%
% 求出自相關
num_frame = length(X);

ms2 = floor(fs/500);
ms20 = floor(fs/50);
F0 = zeros(num_frame,1);
% 直接對每一幀進行循環
for i=1:num_frame
    % 每一幀都可以求出自相關的系數
    r = xcorr(X(i,:), 160);
    r = r(floor(length(r)/2):end);
    [maxi,idx]=max(r(ms2:ms20));
    F0(i) = fs/(ms2+idx-1);
end

figure(1);
plot(F0); %橫坐標代表幀
xlabel('幀')
ylabel('基音頻率')

% 經過探測我讀0時候的基音位于第210幀

%% 選出第210幀的數據
figure(2)
y210 = X(211,:);
subplot(311);
plot(y210);
xlabel('點');
ylabel('振幅');
title('210幀原始信號')
ai = lpc(y210, 10);
est_x=filter([0 -ai(2:end)],1,y210);%估計信號
subplot(312);
plot(est_x);
xlabel('點');
ylabel('振幅');
title('210幀估計信號');
err = y210-est_x;
subplot(313);
plot(err);
xlabel('點');
ylabel('振幅');
title('預測誤差');
%%
% 求預測增益

En=zeros(1,160);
for i=1:160
   u=err(i);%取出一樣點
   u2=u.*u;%求出能量
   En(i)=sum(u2);%對每一樣點累加求和
end
%計算原始能量
En1=zeros(1,160);
for i=1:160
   u=y210(i);%取出一樣點
   u2=u.*u;%求出能量
   En1(i)=sum(u2);%對每一樣點累加求和
end
CA=zeros(1,160);
for i=1:160
   en1=En1(i);%取出一樣點
   en=En(i);
   CA(i)=abs(en1)/abs(en);
end
figure(3);
subplot(311);plot(En1);xlabel('取樣點數/個');ylabel('En');title('短時能量');title('E0');
subplot(312);plot(En);xlabel('取樣點數/個');ylabel('En');title('短時能量');title('Ep');
subplot(313);plot(CA);xlabel('取樣點數/個');ylabel('En');title('短時能量');title('預測增益');

1. 加窗分幀

[y,fs] = audioread('5num.wav');

N = length(y);
t = (1:N-1)/fs;  %生成時間序列
win = hamming(N) %加窗
y = y.*win;
X = enframe(y,160); % 160個點為一幀,就沒要重疊了

其實加窗的過程也不是很難理解,就是生成一個函數然后去乘就好了

然后通過enframe函數進行分幀處理

返回的是一個矩陣,行數代表了幀數,列數代表了每一幀有多少個點

2. 求自相關

num_frame = length(X);

ms2 = floor(fs/500);
ms20 = floor(fs/50);
F0 = zeros(num_frame,1);
% 直接對每一幀進行循環
for i=1:num_frame
    % 每一幀都可以求出自相關的系數
    r = xcorr(X(i,:), 160);
    r = r(floor(length(r)/2):end);
    [maxi,idx]=max(r(ms2:ms20));
    F0(i) = fs/(ms2+idx-1);
end

這個過程也不是很難理解

得到的圖形是這樣子的

橫坐標就是每一個幀,縱坐標代表對應的基音頻率

其實這個圖確實有點奇怪,因為它是倒過來的

我后來仔細想了想,周圍沒有聲音的時候,基音頻率反而是最大的

然后又去翻書,發現人的聲音基音頻率大概也就是200~500hz左右,而且男聲本來就低,所以這個圖顯然是沒問題的

而且我總共只讀了5個音,0 1 2 3 4

基本正確地反映出來了

然后通過肉眼觀察,嗯,我讀0的那個幀就是210幀了

3. 通過LPC預測信號,同時計算增益

預測增益的方法就是LPC

增益系數我暫時不太清楚怎么求,就直接抄同學的了

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 第三章 語音信號特征分析 語音合成音質的好壞,語音識別率的高低,都取決于對語音信號分析的準確度和精度。例如,利用線...
    鍋鍋Iris閱讀 10,378評論 3 8
  • ### YUV顏色空間 視頻是由一幀一幀的數據連接而成,而一幀視頻數據其實就是一張圖片。 yuv是一種圖片儲存格式...
    天使君閱讀 3,372評論 0 4
  • 一、傅立葉變換的由來 關于傅立葉變換,無論是書本還是在網上可以很容易找到關于傅立葉變換的描述,但是大都是些故弄玄虛...
    constant007閱讀 4,471評論 1 10
  • 從GSM系統參數開始,信號從輸入到輸出的各個環節都大致講一遍,每個模塊的技術細節會在后續的博文中作為獨立專題逐一講...
    鄉村騎士閱讀 7,226評論 0 6
  • 在匆忙中度過,時刻感覺有個聲音在指引自己前行,不管有多累有多苦,一切都是成功的墊腳石。 今天有幸看到對脈輪的分享,...
    王澤華wzh閱讀 448評論 0 0