如何在Matlab中绘制0到Fs/2范围的信号幅度谱?
如何在Matlab中绘制音频幅度谱(0到Fs/2区间)
嘿,我来帮你搞定这个!你已经完成了读取音频和计算FFT幅度的第一步,接下来只需要处理频率轴并截取有效区间,就能得到想要的图像了。下面是完整的可运行代码,我会一步步解释关键部分:
% 读取音频文件 [y, Fs] = audioread('sound_noisy.wav'); % 处理立体声:如果是双声道,转成单声道(取左右声道的平均值) if size(y, 2) > 1 y = mean(y, 2); end N = length(y); % 获取音频信号的总长度 fft_result = fft(y); % 计算信号的FFT magnitude = abs(fft_result); % 提取FFT的幅度值 % 生成完整的频率轴:从0到Fs(实际是Fs*(N-1)/N,接近Fs) frequency_axis = (0:N-1) * (Fs / N); % 截取0到Fs/2的区间:实信号的FFT是共轭对称的,只需要前一半数据 half_length = floor(N/2) + 1; target_frequencies = frequency_axis(1:half_length); target_magnitude = magnitude(1:half_length); % 绘制幅度谱 figure; plot(target_frequencies, target_magnitude); title('音频幅度谱(0 到 Fs/2)'); xlabel('频率 (Hz)'); ylabel('幅度'); grid on;
关键细节说明:
- 立体声处理:如果你的音频是双声道(比如常见的音乐文件),直接做FFT会得到二维数组,所以先转成单声道避免出错。
- 频率轴计算:
(0:N-1)*(Fs/N)的作用是把FFT的每个点映射到对应的实际频率,这样x轴就是我们能看懂的Hz单位。 - 区间截取:因为实信号的FFT结果是左右对称的,Fs/2之后的部分和前半部分是镜像的,所以只保留前一半就足够了,这也是音频分析里的标准操作。
如果你想让幅度谱更符合专业音频分析的展示方式(比如用分贝刻度),可以试试这段调整后的代码:
% 归一化幅度(让幅度值和原始信号的幅值对应) normalized_magnitude = target_magnitude / N; % 转换为分贝(加eps是为了避免log(0)出现错误) db_magnitude = 20 * log10(normalized_magnitude + eps); % 绘制分贝幅度谱 figure; plot(target_frequencies, db_magnitude); title('音频幅度谱(分贝刻度,0 到 Fs/2)'); xlabel('频率 (Hz)'); ylabel('幅度 (dB)'); grid on;
这样绘制出来的图会更直观地展示不同频率的能量差异哦!
内容的提问来源于stack exchange,提问作者z.gomar




