基于MATLAB實現傳統譜減法以及兩種改進的譜減法(增益函數譜減法、多帶譜減法)的語音增強代碼示例:
傳統譜減法
function enhanced = traditional_spectral_subtraction(noisy, fs, wlen, inc, NIS, a, b)% 參數說明:% noisy - 帶噪語音信號% fs - 采樣頻率% wlen - 幀長% inc - 幀移% NIS - 前導無話段幀數% a - 過減因子% b - 增益補償因子% 計算噪聲功率譜noise_frames = buffer(noisy(1:NIS*inc), wlen, wlen-inc);noise_frames = noise_frames(:, 1:NIS);noise_power = mean(abs(fft(noise_frames)).^2, 2);% 分幀frames = buffer(noisy, wlen, wlen-inc);num_frames = size(frames, 2);% 初始化增強后的語音enhanced = zeros(size(noisy));% 譜減法處理for i = 1:num_frames% FFTX = fft(frames(:, i));X_mag = abs(X);X_phase = angle(X);% 譜減法S_mag = max(X_mag - a * sqrt(noise_power), b * sqrt(noise_power));% 逆FFTS = S_mag .* exp(1j * X_phase);enhanced_frame = real(ifft(S));% 重疊相加enhanced((i-1)*inc+1:(i-1)*inc+wlen) = enhanced((i-1)*inc+1:(i-1)*inc+wlen) + enhanced_frame;end
end
增益函數譜減法
function enhanced = gain_function_spectral_subtraction(noisy, fs, wlen, inc, NIS, alpha, beta)% 參數說明:% noisy - 帶噪語音信號% fs - 采樣頻率% wlen - 幀長% inc - 幀移% NIS - 前導無話段幀數% alpha - 過減因子% beta - 增益補償因子% 計算噪聲功率譜noise_frames = buffer(noisy(1:NIS*inc), wlen, wlen-inc);noise_frames = noise_frames(:, 1:NIS);noise_power = mean(abs(fft(noise_frames)).^2, 2);% 分幀frames = buffer(noisy, wlen, wlen-inc);num_frames = size(frames, 2);% 初始化增強后的語音enhanced = zeros(size(noisy));% 譜減法處理for i = 1:num_frames% FFTX = fft(frames(:, i));X_mag = abs(X);X_phase = angle(X);% 增益函數G = (X_mag - alpha * sqrt(noise_power)) ./ X_mag;G = max(G, beta);% 增強后的頻譜S_mag = G .* X_mag;% 逆FFTS = S_mag .* exp(1j * X_phase);enhanced_frame = real(ifft(S));% 重疊相加enhanced((i-1)*inc+1:(i-1)*inc+wlen) = enhanced((i-1)*inc+1:(i-1)*inc+wlen) + enhanced_frame;end
end
多帶譜減法
function enhanced = multiband_spectral_subtraction(noisy, fs, wlen, inc, NIS, num_bands)% 參數說明:% noisy - 帶噪語音信號% fs - 采樣頻率% wlen - 幀長% inc - 幀移% NIS - 前導無話段幀數% num_bands - 子帶數量% 計算噪聲功率譜noise_frames = buffer(noisy(1:NIS*inc), wlen, wlen-inc);noise_frames = noise_frames(:, 1:NIS);noise_power = mean(abs(fft(noise_frames)).^2, 2);% 分幀frames = buffer(noisy, wlen, wlen-inc);num_frames = size(frames, 2);% 初始化增強后的語音enhanced = zeros(size(noisy));% 子帶劃分band_width = wlen / num_bands;% 譜減法處理for i = 1:num_frames% FFTX = fft(frames(:, i));X_mag = abs(X);X_phase = angle(X);% 多帶譜減法S_mag = zeros(size(X_mag));for j = 1:num_bandsband_start = (j-1) * band_width + 1;band_end = j * band_width;band_noise_power = noise_power(band_start:band_end);S_mag(band_start:band_end) = max(X_mag(band_start:band_end) - band_noise_power, 0);end% 逆FFTS = S_mag .* exp(1j * X_phase);enhanced_frame = real(ifft(S));% 重疊相加enhanced((i-1)*inc+1:(i-1)*inc+wlen) = enhanced((i-1)*inc+1:(i-1)*inc+wlen) + enhanced_frame;end
end
使用示例
% 讀取帶噪語音信號
[noisy, fs] = audioread('noisy_speech.wav');% 參數設置
wlen = 256; % 幀長
inc = 128; % 幀移
NIS = 10; % 前導無話段幀數
a = 4; % 過減因子
b = 0.001; % 增益補償因子
alpha = 4; % 增益函數過減因子
beta = 0.001; % 增益函數增益補償因子
num_bands = 4; % 多帶譜減法子帶數量% 傳統譜減法
enhanced_traditional = traditional_spectral_subtraction(noisy, fs, wlen, inc, NIS, a, b);% 增益函數譜減法
enhanced_gain_function = gain_function_spectral_subtraction(noisy, fs, wlen, inc, NIS, alpha, beta);% 多帶譜減法
enhanced_multiband = multiband_spectral_subtraction(noisy, fs, wlen, inc, NIS, num_bands);% 保存增強后的語音
audiowrite('enhanced_traditional.wav', enhanced_traditional, fs);
audiowrite('enhanced_gain_function.wav', enhanced_gain_function, fs);
audiowrite('enhanced_multiband.wav', enhanced_multiband, fs);
說明
- 傳統譜減法:直接從帶噪語音頻譜中減去噪聲功率譜,可能會導致“音樂噪聲”問題。
- 增益函數譜減法:通過引入增益函數來平滑頻譜,減少“音樂噪聲”。
- 多帶譜減法:將語音頻譜劃分為多個子帶進行獨立處理,減少“音樂噪聲”的影響。
你可以根據實際需求調整參數,以獲得更好的語音增強效果。