基于谱减的语音降噪算法实现
% 读取带噪语音文件
[x, fs] = audioread('C:\Users\ASUS\Desktop\20230607_210020.wav');
x=x(:,1);
% 进行短时傅里叶变换(STFT)
L = 256; % 窗长(建议使用 2 的幂次方,例如 256、512、1024 等)
overlap = 0.75; % 重叠率
winlen = 0.5;
win = hamming(L); % 窗函数
nfft = 512; % FFT长度
[S,F,T,P] = spectrogram(x,round(winlen*fs), round((1-overlap)*winlen*fs), nfft, fs);
% 'S':STFT 谱矩阵,行数为 'nfft/2+1',列数为 STFT 小段数。'F':频率向量,单位为 Hz,长度为 'nfft/2+1'。'T':时间向量,单位为秒,长度为 STFT 小段数。'P':功率谱矩阵,与 STFT 谱矩阵 'S' 相同。
% 估计噪声功率谱
n = round(fs*0.1); % 取前100ms作为噪声参考信号
% 建议取多个噪声参考信号进行平均,以提高估计准确性
noise = x(:,1);
[~, ~, N] = spectrogram(noise,round(winlen*fs), round((1-overlap)*winlen*fs), nfft, fs);
N = mean(abs(N).^2, 2); % 平均噪声功率谱
% 计算信噪比(SNR)
X = abs(S).^2; % 信号功率谱
SNR = 10*log10(sum(X, 2)./sum(N)); % 信噪比(单位为 dB)
% 谱减增强
alpha = 2; % 谱减系数(建议进行调整以得到最佳增强效果)
H = max(0, 1 - alpha*repmat(SNR, 1, size(S, 2))./max(SNR)); % 谱减函数
X_enh = H.*S; % 增强后的信号功率谱
% 进行反变换
y= istft(X_enh,fs,'OverlapLength', round((1-overlap)*winlen*fs),'FFTLength', nfft); % 使用与 STFT 相同的重叠率和窗长参数
% 保存增强后的语音文件
audiowrite('C:\Users\ASUS\Desktop\11.wav',y,fs); % 使用与原始文件相同的采样率和位深度
原文地址: https://www.cveoy.top/t/topic/ozpX 著作权归作者所有。请勿转载和采集!