2014年8月23日 星期六

[Matlab/Octave] 音訊、波形圖、聲紋圖、頻譜圖

前年因為參加了聲學研討會,學到如何以聲音訊號來繪圖。聲音訊號可以繪出3種較為基本的圖,分別為波形圖、頻譜圖及聲紋圖,其中聲紋圖較為複雜,因為它是屬於3維的圖,但其中一個維度以顏色作為表示,因此是張2D3維圖。頻譜圖我也套用網路的程式碼作為運算基礎,因為我不懂其數學的基本原理,並沒有辦法自己寫出程式碼進行運算(參考連結)。































波形圖程式碼:
[x,fs]=wavread('123.wav'); %x為聲音訊號的振幅值,fs 為取樣頻率。簡單舉個例子,假如你有一個5秒的音訊檔,取樣頻率是44100,那麼這個音訊檔就會有5*44100個振幅值,但若此音訊檔為雙聲道,就變成5*44100*2。
x=x(:,1); %取左聲道的聲音訊號,若要取右聲道就將1改成2
t=(0:length(x)-1)/fs; %設定時間為0到聲音訊號長度(如上例:5*44100),再除以fs(44100)就可以得到音訊的秒數(5秒)
plot(t,x)% 這樣再畫出來就完成囉!!

聲紋圖程式碼:
Matlab:
spectrogram(x, 1024, 1000, [], fs, 'yaxis') %1024與1000是設定分析的框架大小及重複率,詳細我也不懂,但可以改變這兩個值得大小試試看,你會發現圖片精細度有差。[]為傅立葉分析的預設值NFFT,'yaxis'會將圖兩軸反轉,使其可與波形圖相對應。
Octave:
%若要使用signal package,必須先安裝,然後再以指令(pkg load signal)載入
specgram(x,256,fs,1024,1000)

頻譜圖程式碼:
N=length(x); %波形圖時沒有設定N,但這邊設定一下會比較好用
t=(0:N-1)/fs; %分析運算
win = hanning(N); K = sum(win)/N; % coherent amplification of the window
X = abs(fft(x.*win)); % fast fourier transform
Xm = X(1:N/2); % getting a first half of the spectrum without Nyquist frequency at N/2+1
Xm = Xm/(N/2); % computing of the amplitudes
Xm(1,1) = Xm(1,1)/2; % correction of the DC component
Xm = Xm/K; % correction due to coherent amplification
f = (0:N/2-1)*fs/N;
plot(f, Xm) %此時單位為Hz,若要改為kHz則對f除以1000

原本今天還不會使用Octave畫聲紋圖,經過整天的學習終於可以把它呈現出來了,話說要使用Octave真的很痛苦,三不五時程式自己出錯,就必須重跑,真的很麻煩!!但好像畫得比Matlab好看耶!!(下圖)

































參考資料:Hristo Zhivomirov. 2014. Sound analysis with Matlab Implementation. site: http://www.mathworks.com/matlabcentral/fileexchange/38837-sound-analysis-with-matlab-implementation. on 2014/8/24.


1 則留言:

  1. 您好,

    冒昧打擾,我是泰宇出版的產品專員姿儀。

    我們公司主要是出版高中職教科書的出版社,目前我們正在出版生活科技相關的教材,內容希望能引用您將聲紋圖轉成頻譜圖的圖照,作為傅立葉變換的舉例。

    希望能獲得您許可,讓我們能使用在教材中。感謝您的撥冗閱讀!期待收到您的回覆。

    回覆刪除

有任何問題可以詢問,我們會盡量回答