第一次接触语音信号处理时,我被那些跳动的波形图弄得一头雾水。直到后来才发现,原来我们平时听到的声音,在计算机眼里就是一串数字而已。想象一下麦克风就像个高速拍照的相机,每隔一小段时间就记录下此刻空气的振动强度,这就是采样的过程。
在MATLAB中,一段15秒的音频可能长这样:
matlab复制[x, fs] = audioread('speech.wav');
disp(size(x)); % 显示音频数据的长度
这里的fs就是采样率,比如8000表示每秒采集8000个点。我常跟新手说,采样率就像拍照的帧率 - 帧率越高,动作越连贯;采样率越高,声音细节越丰富。不过要注意,采样率不是越高越好,就像用单反拍文档纯属浪费,一般语音处理16kHz就够用了。
刚开始学FFT(快速傅里叶变换)时,我总把它想得很神秘。后来发现它就像给一杯混合果汁做成分分析 - 告诉你里面有多少橙汁、多少苹果汁。FFT做的正是这件事:把复杂的声音分解成不同频率的正弦波。
用MATLAB做FFT特别简单:
matlab复制x_fd = fft(x); % fd表示频域(Frequency Domain)
但这里有个坑我踩过好几次 - FFT结果是对称的,通常我们只需要前半部分:
matlab复制N = length(x);
f = (0:N-1)*(fs/N); % 频率轴
plot(f(1:N/2), abs(x_fd(1:N/2))); % 只画前半部分
幅度谱可能是最直观的频谱了,它告诉我们每个频率成分的强度。记得第一次看到音乐频谱跳动时,我突然明白为什么重金属音乐听起来那么"重" - 因为低频部分特别突出。
绘制幅度谱时有个细节要注意:
matlab复制magnitude = abs(x_fd); % 取模得到幅度
plot(f(1:N/2), magnitude(1:N/2));
xlabel('Frequency (Hz)'); ylabel('Magnitude');
这里abs()函数就像给复数拍了个X光,只看它的"大小"不管"方向"。
相位谱常常被新手忽略,但它其实超级重要。我曾经做过实验:把一首歌的幅度谱和另一首歌的相位谱组合,结果听到的是第二首歌的旋律!这说明相位信息携带了大量声音特征。
绘制相位谱要用angle()函数:
matlab复制phase = angle(x_fd); % 获取相位角(弧度)
phase_deg = phase * 180/pi; # 转成角度(可选)
plot(f(1:N/2), phase_deg(1:N/2));
不过相位数据看起来总是很乱,这是因为相位值对时间偏移特别敏感。有个小技巧是对信号做加窗处理,能让相位谱看起来整洁些。
功率谱简单说就是幅度谱的平方,它反映的是信号的能量分布。在语音识别中,功率谱比幅度谱更常用,因为人耳对声音强度的感知更接近对数关系。
计算功率谱有两种常用方法:
matlab复制% 方法1:直接平方
power_spectrum = abs(x_fd).^2;
% 方法2:实部虚部平方和
power_spectrum = real(x_fd).^2 + imag(x_fd).^2;
语谱图是我最喜欢的语音可视化工具,它就像声音的"指纹"。横轴是时间,纵轴是频率,颜色深浅表示能量强弱。看语谱图能直观分辨元音、辅音,甚至能看出说话人的口型特点。
绘制语谱图需要用到短时傅里叶变换(STFT),这里分享一个我调试多次的MATLAB代码:
matlab复制[x, fs] = audioread('speech.wav');
window = 256; % 窗长
noverlap = 192; % 重叠样本数
nfft = 512; % FFT点数
spectrogram(x, window, noverlap, nfft, fs, 'yaxis');
colormap('jet'); % 使用jet颜色映射更清晰
参数设置很有讲究:
在开发语音识别系统时,我很少直接使用原始频谱。经过多次尝试,发现以下几种处理特别重要:
matlab复制% 简单的梅尔频谱计算示例
[melSpectrum, frequencies] = mfcc(x, fs);
imagesc(melSpectrum); % 绘制梅尔频谱图
遇到过最头疼的问题是频谱出现镜像频率,后来发现是因为忘记做FFT移位了。正确的做法是:
matlab复制x_fd_shifted = fftshift(x_fd); % 将零频移到中心
另一个常见问题是频谱泄漏,表现为能量"污染"到邻近频率。解决方法是用合适的窗函数(如汉明窗):
matlab复制window = hamming(N); % 生成汉明窗
x_windowed = x .* window; % 加窗
x_fd = fft(x_windowed); % 再做FFT
语音信号处理就像给声音做CT扫描,时域信号是整体外观,频域特征则是内部结构。记得刚开始工作时,我对着频谱图能看一整天,观察不同发音带来的细微变化。现在处理语音信号时,我习惯先快速浏览语谱图获取整体印象,再针对特定时段分析频谱细节。这种时频结合的分析方法,往往能发现很多单纯时域分析容易忽略的特征。