利用matlab时频域语音信号的分析与处理

设计目标】对语音信号进行时频域分析和处理的基本方法【设计工具】MATLAB【设计要求】
1)分别录制一段男生和女生语音文件及相应有明显高频或低频干扰的语音文件*.wav,并将文件导入Matlab中;
2)分别分析各段语音的频谱,绘制其频谱图,分析语音信号和干扰信号的频段;
3)设计相应的滤波器,剔除含干扰的语音段的干扰信号,并分析滤波信号的频谱;
4)生成滤波后的语音文件,分析听觉效果。

引ChatGPT部分内容参考回答:
1、录制语音文件并导入MATLAB中

% 录制男生语音文件
recObj = audiorecorder;
disp('Start speaking.')
recordblocking(recObj, 5);
disp('End of Recording.');
% 保存录制的语音文件
male_voice = getaudiodata(recObj);
audiowrite('male_voice.wav', male_voice, recObj.SampleRate);

% 录制女生语音文件
recObj = audiorecorder;
disp('Start speaking.')
recordblocking(recObj, 5);
disp('End of Recording.');
% 保存录制的语音文件
female_voice = getaudiodata(recObj);
audiowrite('female_voice.wav', female_voice, recObj.SampleRate);

% 录制带干扰的语音文件
recObj = audiorecorder;
disp('Start speaking.')
recordblocking(recObj, 5);
disp('End of Recording.');
% 保存录制的语音文件
noisy_voice = getaudiodata(recObj);
audiowrite('noisy_voice.wav', noisy_voice, recObj.SampleRate);

% 导入语音文件
male_voice = audioread('male_voice.wav');
female_voice = audioread('female_voice.wav');
noisy_voice = audioread('noisy_voice.wav');

2、分析语音信号的频谱并绘制频谱图

% 分析男生语音信号的频谱
male_voice_fft = fft(male_voice);
male_voice_fft = abs(male_voice_fft(1:length(male_voice)/2+1));
male_voice_freq = linspace(0,recObj.SampleRate/2,length(male_voice_fft));
% 绘制男生语音信号的频谱图
figure;
plot(male_voice_freq, male_voice_fft);
title('Male Voice Spectrum');
xlabel('Frequency (Hz)');
ylabel('Magnitude');

% 分析女生语音信号的频谱
female_voice_fft = fft(female_voice);
female_voice_fft = abs(female_voice_fft(1:length(female_voice)/2+1));
female_voice_freq = linspace(0,recObj.SampleRate/2,length(female_voice_fft));
% 绘制女生语音信号的频谱图
figure;
plot(female_voice_freq, female_voice_fft);
title('Female Voice Spectrum');
xlabel('Frequency (Hz)');
ylabel('Magnitude');

% 分析带干扰的语音信号的频谱
noisy_voice_fft = fft(noisy_voice);
noisy_voice_fft = abs(noisy_voice_fft(1:length(noisy_voice)/2+1));
noisy_voice_freq = linspace(0,recObj.SampleRate/2,length(noisy_voice_fft));
% 绘制带干扰的语音信号的频谱图
figure;
plot(noisy_voice_freq, noisy_voice_fft);
title('Noisy Voice Spectrum');
xlabel('Frequency (Hz)');
ylabel('Magnitude');

3、设计滤波器并剔除干扰信号

% 设计带通滤波器,剔除带外的干扰信号
% 以男生语音信号为例,其频率范围为85Hz-255Hz
% 以带宽为10Hz的带通滤波器为例
male_voice_filtered = bandpass(male_voice, [75 265], recObj.SampleRate, 'Steepness', 0.9);

% 设计低通滤波器,剔除高频干扰信号
% 以带截止频率为4kHz的低通滤波器为例
noisy_voice_filtered = lowpass(noisy_voice, 4000, recObj.SampleRate, 'Steepness', 0.9);

4、分析滤波后的语音信号的频谱并绘制频谱图

% 分析滤波后的男生语音信号的频谱
male_voice_filtered_fft = fft(male_voice_filtered);
male_voice_filtered_fft = abs(male_voice_filtered_fft(1:length(male_voice_filtered)/2+1));
male_voice_filtered_freq = linspace(0,recObj.SampleRate/2,length(male_voice_filtered_fft));
% 绘制滤波后的男生语音信号的频谱图
figure;
plot(male_voice_filtered_freq, male_voice_filtered_fft);
title('Filtered Male Voice Spectrum');
xlabel('Frequency (Hz)');
ylabel('Magnitude');

% 分析滤波后的带干扰的语音信号的频谱
noisy_voice_filtered_fft = fft(noisy_voice_filtered);
noisy_voice_filtered_fft = abs(noisy_voice_filtered_fft(1:length(noisy_voice_filtered)/2+1));
noisy_voice_filtered_freq = linspace(0,recObj.SampleRate/2,length(noisy_voice_filtered_fft));
% 绘制滤波后的带干扰的语音信号的频谱图
figure;
plot(noisy_voice_filtered_freq, noisy_voice_filtered_fft);
title('Filtered Noisy Voice Spectrum');
xlabel('Frequency (Hz)');
ylabel('Magnitude');

5、生成滤波后的语音文件并分析听觉效果

% 保存滤波后的男生语音文件
audiowrite('male_voice_filtered.wav', male_voice_filtered, recObj.SampleRate);

% 保存滤波后的带干扰的语音文件
audiowrite('noisy_voice_filtered.wav', noisy_voice_filtered, recObj.SampleRate);

% 播放原始男生语音文件
sound(male_voice, recObj.SampleRate);

% 播放滤波后的男生语音文件
sound(male_voice_filtered, recObj.SampleRate);

% 播放原始带干扰的语音文件
sound(noisy_voice, recObj.SampleRate);

% 播放滤波后的带干扰的语音文件
sound(noisy_voice_filtered, recObj.SampleRate);

参考GPT和自己的思路:
【设计步骤】

  1. 导入语音文件并绘制频谱图

示例代码:

male_voice = audioread('male_voice.wav'); % 读取男生语音文件
female_voice = audioread('female_voice.wav'); % 读取女生语音文件
male_noise = audioread('male_noise.wav'); % 读取含干扰的男生语音文件
female_noise = audioread('female_noise.wav'); % 读取含干扰的女生语音文件

% 绘制男生语音的频谱图
male_voice_spec = abs(fft(male_voice)); % 计算男生语音的频域幅值
male_voice_spec = male_voice_spec(1:length(male_voice)/2+1); % 只留下一半幅度值
freq_axis = linspace(0, 1, length(male_voice_spec)) * 44100 / 2; % 构建频率轴
plot(freq_axis, male_voice_spec)
xlabel('Frequency (Hz)')
ylabel('Magnitude')
title('Male Voice Spectrum')

% 绘制女生语音的频谱图
% ...

% 绘制含干扰的男生语音的频谱图
% ...

% 绘制含干扰的女生语音的频谱图
% ...

  1. 分析语音信号和干扰信号的频段

通过频谱图可以观察到语音信号和干扰信号的频段范围,并根据需求进行选择。例如,如果想要剔除高频干扰,可以设计一个低通滤波器,截止频率为干扰信号的频段。

  1. 设计滤波器并滤波

根据前面分析的结果,设计相应的滤波器。在Matlab中,可以使用数字滤波器函数设计和滤波。例如,设计一个一阶巴特沃斯低通滤波器,截止频率为5000Hz:

[b, a] = butter(1, 5000/(44100/2), 'low'); % 设计一阶巴特沃斯低通滤波器
male_voice_filtered = filter(b, a, male_voice); % 滤波男生语音文件

  1. 分析滤波后的语音文件的频谱和听觉效果

示例代码:

% 绘制滤波后男生语音的频谱图
male_voice_filtered_spec = abs(fft(male_voice_filtered)); % 计算滤波后男生语音的频域幅值
male_voice_filtered_spec = male_voice_filtered_spec(1:length(male_voice_filtered)/2+1); % 只留下一半幅度值
freq_axis = linspace(0, 1, length(male_voice_filtered_spec)) * 44100 / 2; % 构建频率轴
plot(freq_axis, male_voice_filtered_spec)
xlabel('Frequency (Hz)')
ylabel('Magnitude')
title('Filtered Male Voice Spectrum')

% 播放滤波后男生语音
sound(male_voice_filtered, 44100)

观察频谱图,如果干扰信号被成功剔除,频率范围内应该只留下原始语音信号的频率成分。听取滤波后的语音文件,观察是否听起来干扰更少,更清晰。可以对比原始语音文件听觉效果,进行分析。

这个录音可能要您自己录制了,具体实现的思路和示例如下:
思路:
1、通过 audioread 函数读入语音文件,并且获取采样率 Fs。
2、绘制语音信号时域波形图,并且在四个子图中绘制四个不同的语音信号。
3、对每个语音信号进行 FFT 计算,获得信号的频谱。采用幅值谱表示频谱,而非相位谱。
4、在四个子图中绘制四个语音信号的频谱图。
5、分析语音信号和干扰信号的频段。对于这里,选择了 500Hz 和 3000Hz 之间的频率作为语音信号的主要频段,剩余部分认为是噪声。
6、设计均衡化滤波器来滤除含干扰的语音段的干扰信号。滤波器的设计方法很简单:设置通带和阻带之外的所有系数为 0;通带和阻带之间的系数为1。
7、对滤波后的语音信号进行 FFT 计算,并绘制频谱图。
8、利用函数 audiowrite 将滤波后的语音信号写入文件。
9、播放原始语音文件和滤波后的语音文件来比较听觉效果。使用 sound 函数播放音频文件。
源码示例如下:


% 读入语音文件
[signal_male, Fs] = audioread('male.wav');
[signal_female, Fs] = audioread('female.wav');
[signal_noise_high, Fs] = audioread('noise_high.wav');
[signal_noise_low, Fs] = audioread('noise_low.wav');

% 时域分析
% 绘制语音信号
subplot(2, 2, 1);
plot(signal_male);
title('Male voice');

subplot(2, 2, 2);
plot(signal_female);
title('Female voice');

subplot(2, 2, 3);
plot(signal_noise_high);
title('Noise with high frequency');

subplot(2, 2, 4);
plot(signal_noise_low);
title('Noise with low frequency');

% 频域分析
% 绘制语音信号频谱
N = length(signal_male);   % 采样点数
f = (0:N-1)*Fs/N;          % 频率刻度
Y_male = abs(fft(signal_male));   % 语音信号频域分析结果
Y_female = abs(fft(signal_female));
Y_noise_high = abs(fft(signal_noise_high));
Y_noise_low = abs(fft(signal_noise_low));

% 绘制幅度谱
figure();
subplot(2, 2, 1);
plot(f(1:N/2), Y_male(1:N/2));
title('Amplitude spectrum of male voice');
xlabel('Frequency / Hz');
ylabel('Amplitude');

subplot(2, 2, 2);
plot(f(1:N/2), Y_female(1:N/2));
title('Amplitude spectrum of female voice');
xlabel('Frequency / Hz');
ylabel('Amplitude');

subplot(2, 2, 3);
plot(f(1:N/2), Y_noise_high(1:N/2));
title('Amplitude spectrum of noise with high frequency');
xlabel('Frequency / Hz');
ylabel('Amplitude');

subplot(2, 2, 4);
plot(f(1:N/2), Y_noise_low(1:N/2));
title('Amplitude spectrum of noise with low frequency');
xlabel('Frequency / Hz');
ylabel('Amplitude');

% 频段分析
% 分析语音信号和干扰信号的频段
male_high = Y_male(f>3000);     % 提取高频段
male_low = Y_male(f<500);       % 提取低频段
female_high = Y_female(f>3000);
female_low = Y_female(f<500);
noise_high = Y_noise_high(f>3000);
noise_low = Y_noise_low(f<500);

% 滤波器设计
% 根据分析结果,设计相应的滤波器,剔除含干扰的语音段的干扰信号
% 均衡化滤波(模拟高通、低通)
H_male = ones(size(Y_male));
H_male(f<500 | f>3000) = 0;    % 高频和低频截止
Y_male_filtered = Y_male.*H_male;
signal_male_filtered = real(ifft(Y_male_filtered));   % 滤波后的语音信号

H_female = ones(size(Y_female));
H_female(f<500 | f>3000) = 0;
Y_female_filtered = Y_female.*H_female;
signal_female_filtered = real(ifft(Y_female_filtered));

H_noise_high = ones(size(Y_noise_high));
H_noise_high(f<500 | f>3000) = 0;
Y_noise_high_filtered = Y_noise_high.*H_noise_high;
signal_noise_high_filtered = real(ifft(Y_noise_high_filtered));

H_noise_low = ones(size(Y_noise_low));
H_noise_low(f<500 | f>3000) = 0;
Y_noise_low_filtered = Y_noise_low.*H_noise_low;
signal_noise_low_filtered = real(ifft(Y_noise_low_filtered));

% 滤波后频域分析
% 绘制滤波后的语音信号频谱
N = length(signal_male_filtered);
f = (0:N-1)*Fs/N;
Y_male_filtered = abs(fft(signal_male_filtered));
Y_female_filtered = abs(fft(signal_female_filtered));
Y_noise_high_filtered = abs(fft(signal_noise_high_filtered));
Y_noise_low_filtered = abs(fft(signal_noise_low_filtered));

figure();
subplot(2, 2, 1);
plot(f(1:N/2), Y_male_filtered(1:N/2));
title('Amplitude spectrum of filtered male voice');
xlabel('Frequency / Hz');
ylabel('Amplitude');

subplot(2, 2, 2);
plot(f(1:N/2), Y_female_filtered(1:N/2));
title('Amplitude spectrum of filtered female voice');
xlabel('Frequency / Hz');
ylabel('Amplitude');

subplot(2, 2, 3);
plot(f(1:N/2), Y_noise_high_filtered(1:N/2));
title('Amplitude spectrum of filtered noise with high frequency');
xlabel('Frequency / Hz');
ylabel('Amplitude');

subplot(2, 2, 4);
plot(f(1:N/2), Y_noise_low_filtered(1:N/2));
title('Amplitude spectrum of filtered noise with low frequency');
xlabel('Frequency / Hz');
ylabel('Amplitude');

% 写入文件
audiowrite('male_filtered.wav', signal_male_filtered, Fs);
audiowrite('female_filtered.wav', signal_female_filtered, Fs);
audiowrite('noise_high_filtered.wav', signal_noise_high_filtered, Fs);
audiowrite('noise_low_filtered.wav', signal_noise_low_filtered, Fs);

% 听觉效果分析
% 播放原始语音文件和滤波后的语音文件,对比听觉效果
sound(signal_male, Fs);
pause(length(signal_male)/Fs);   % 等待播放完成

sound(signal_male_filtered, Fs);
pause(length(signal_male_filtered)/Fs);

sound(signal_female, Fs);
pause(length(signal_female)/Fs);

sound(signal_female_filtered, Fs);
pause(length(signal_female_filtered)/Fs);

sound(signal_noise_high, Fs);
pause(length(signal_noise_high)/Fs);

sound(signal_noise_high_filtered, Fs);
pause(length(signal_noise_high_filtered)/Fs);

sound(signal_noise_low, Fs);
pause(length(signal_noise_low)/Fs);

sound(signal_noise_low_filtered, Fs);
pause(length(signal_noise_low_filtered)/Fs);

我可以根据参考资料和目前的知识给出一些初步建议:

  1. 首先需要了解如何读取音频文件和进行傅里叶变换和频谱分析。可以使用MATLAB中的audioread()函数读取音频文件,使用fft()来进行傅里叶变换,使用abs()来计算幅值,再用plot()进行可视化绘制频谱图

img