3-4.Audio Quantization



在Matlab版本分水嶺較新版本(R2012以後)
讀取聲音檔的API都用audioread,早期版本用wavread。

audioread('speech.au')

通常可支援的音訊檔格式如下
Platform SupportFile Format
All platformsAIFC (.aifc)
AIFF (.aiff.aif)
AU (.au)
FLAC (.flac)
OGG (.ogg)
OPUS (.opus)
WAVE (.wav)
Windows® 7 (or later), Macintosh, and Linux®MP3 (.mp3)
MPEG-4 AAC (.m4a.mp4)


此函數的對應輸出有兩個
1.取樣點: 音頻的矩陣型態,單聲道還是有左右兩聲道。
2.取樣頻率:8K , 16K....Hz

因此需用以下語法來承接對應輸出的變數結果
[y,Fs] = audioread(filename)

第一階段.讀音檔程式
要確保你兩個音檔在當前matlab運行的所在目錄下

% 讀取音頻檔案
[speech, Fs_speech] = audioread('speech.au');
[music, Fs_music] = audioread('music.au');

效果(對應輸出)



可以見到以下兩個音檔各自的矩陣型態是double 都是8k hz的取樣頻率
speech.au 是 23759x1的維度
music.au  是 82543x1的維度

這裡可打開workspace中的變數監看式查看
取樣點值域位於-1~+1之間



讀取進來後若想播放出來聽看看怎麼辦?
可藉由sound的函數來傳入剛剛兩個參數即可




第二階段.將讀進來的音檔進行可視化plot呈現

% 讀取音頻檔案
[speech, Fs_speech] = audioread('speech.au');
[music, Fs_music] = audioread('music.au');
%sound(speech,Fs_speech); %播放出來測試聽看看
%sound(music, Fs_music);  %播放出來測試聽看看

figure;
plot((1:length(speech))/Fs_speech, speech);
title('speech信號');
xlabel('時間 (秒)');
ylabel('振幅');

figure;
plot((1:length(music))/Fs_music, music);
title('music信號');
xlabel('時間 (秒)');
ylabel('振幅');



接續產生下一張圖的訊號圖


每一張圖起手式就是先打一下
figure;
代表要創建新的一張圖


這邊再補充若是點資訊想進行疊圖
則輸入
figure;
hold on;


如何將上述程式產生兩張波形圖figure存出來?點這邊就好了

speech原始波形

music原始波形



第三階段.指定不同7、4、2和1比特/樣本,進行均勻量化,觀察量化對音質的影響。
聆聽原始和量化後的信號差異

這邊我新建一個.m的script檔案自己取名
然後可以不用像前面美輸入一行就立即有回饋互動,恢復成傳統寫好一個段落在RUN的模式。
比方我取名hw3_4.m (要英文起頭)





新建一個 UquantAudio 函數
裡面會做到量化還有將量化過波形圖結果跟量化過音檔存出來的過程



跑觀測運行效果


第三階段主程式
透過片歷 bits陣列,(用於量化的位元數):7、4、2 和 1 位元/樣本
用 saveas 函數將當前的圖形(由 gcf 獲得)保存為一個 .PNG 圖檔,
檔名存為 quantized_speech.png。

% 讀取音頻檔案
[speech, Fs_speech] = audioread('speech.au');
[music, Fs_music] = audioread('music.au');

% 設定量化的位元/樣本
bits = [7, 4, 2, 1];


% 繪製語音信號的量化結果
figure;
orient tall;
for i = 1:length(bits)
    subplot(4,1,i);
    quantized_speech = UquantAudio(speech, 2^bits(i));
    plot(7201:7400, quantized_speech(7201:7400));
    title(['speech信號量化 - ', num2str(bits(i)), ' 位元/樣本']);
end

% 保存語音信號的圖片
saveas(gcf, 'quantized_speech.png');

% 繪製音樂信號的量化結果
figure;
orient tall;
for i = 1:length(bits)
    subplot(4,1,i);
    quantized_music = UquantAudio(music, 2^bits(i));
    plot(7201:7400, quantized_music(7201:7400));
    title(['music信號量化 - ', num2str(bits(i)), ' 位元/樣本']);
end

% 保存音樂信號的圖片
saveas(gcf, 'quantized_music.png');

使用 subplot 繪製量化後的音頻訊號
PS:subplot 函數可以讓我們在一個圖形窗口中創建多個小圖,需要將量化後的四個語音信號繪製在同一圖形中。

指定了特定索引範圍為介於 7201 到 7400的音頻信號段落,如此一來能更清楚地觀察和比較量化對音頻訊號的差異及影響。

orient tall 是在matlab指令中提供以下指令,用於設置圖形頁面方向的命令

figure;
orient tall;

這邊指定垂直直立式頁面呈現(適用在當圖形包含多個垂直排列的元素)。

這邊也有額外定義出另一個function叫做UquantAudio
主要負責將輸入訊號 X 量化到 N 個等級
function Y = UquantAudio(X, N)
    max_val = max(X);
    min_val = min(X);
    Delta = (max_val - min_val) / (N - 1);
    Y = min_val + Delta * round((X - min_val) / Delta);
end

由於量化的級別數量是基於位元數的,每增加一位元,可表示的級別數量就翻倍。
1位元可以表示2個級別(2^1)
2位元可以表示4個級別(2^2)....以此類推。



我們產生的訊號能量波形圖
水平軸:
代表樣本索引也就是時間。在數位音頻處理中,每一點通常對應於一個特定的時間點。
由於音頻數據是以一定的採樣率(樣本/秒)採樣的,因此
水平軸上的每個單位代表了音頻信號的一個樣本,從7201到7400的樣本索引共200個sample。

縱軸:
代表訊號的振幅也就是能量強度。表示聲音的響度或壓力變化。
在量化後,縱軸上的值會反映出量化步階,原始信號的連續振幅值也被映射到
固定的間距。

music信號量化


7位元/樣本:圖中顯示信號仍保持著相對平滑的波形,音質與原始信號相比差異較小。
4位元/樣本:波形開始出現明顯的階梯效應,音質開始受到量化噪聲的影響。
2位元/樣本:波形的細節進一步減少,階梯鋸齒感更明顯,這會導致音質顯著下降。
1位元/樣本:這時,信號已經變成幾乎只有兩個水平的極端波形,顯示出信號幾乎所有的細節都已經丟失,音質極大降低。

speech信號量化

7位元/樣本:與原先訊號差異不大,仍保留了大部分的原始波形,音質變化不大。
4位元/樣本:訊號開始也有階梯效應,但比music信號的影響要小,這可能是因為speech信號的浮動範圍相對較小。
2位元/樣本:類似於音樂信號,speech波形失去了很多細節,但仍然可以識別一些語音特徵。
1位元/樣本:在這個量化級別上,speech信號也只剩下幾乎是二值的波形,大部分語音信息都已經丟失。


二值波形(Binary waveform)
指的就是只含兩種可能振幅值的信號(不是1就0)


想將量化後的音檔存出來

可以藉由audiowrite 函數


第四階段主程式
% 讀取音頻檔案
[speech, Fs_speech] = audioread('speech.au');
[music, Fs_music] = audioread('music.au');

% 設定量化的位元/樣本
bits = [7, 4, 2, 1];


% 繪製語音信號的量化結果
figure;
orient tall;
for i = 1:length(bits)
    subplot(4,1,i);
    quantized_speech = UquantAudio(speech, 2^bits(i));
    plot(7201:7400, quantized_speech(7201:7400));
    title(['speech信號量化 - ', num2str(bits(i)), ' 位元/樣本']);
    filename = sprintf('%d_bits_speech.au', bits(i));
    audiowrite(filename, quantized_speech, Fs_speech);
end

% 保存語音信號的圖片
saveas(gcf, 'quantized_speech.png');

% 繪製音樂信號的量化結果
figure;
orient tall;
for i = 1:length(bits)
    subplot(4,1,i);
    quantized_music = UquantAudio(music, 2^bits(i));
    plot(7201:7400, quantized_music(7201:7400));
    title(['music信號量化 - ', num2str(bits(i)), ' 位元/樣本']);
    filename = sprintf('%d_bits_music.au', bits(i));
    audiowrite(filename, quantized_music, Fs_music);
end

% 保存音樂信號的圖片
saveas(gcf, 'quantized_music.png');


副檔名格式看起來有指錯會有中斷運行報錯

原因是該函數只能存以下格式

這邊就改.wav格式觀察
播放出來基本上眾所周知就是取樣bit數愈少的音質愈差







留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header