MATLAB音频信号采样频率实验:时域频域分析与界面实现
MATLAB音频信号采样频率实验:时域频域分析与界面实现
本项目利用MATLAB编程实现对音频信号进行不同采样频率的采样,并分析其时域和频域特性。最终建立一个包含按钮的界面,通过点击不同按钮输出对应采样频率的信号时域图和频谱图。
实验步骤:
- 读取音频: 使用
audioread函数读取音频文件,获取音频信号和采样频率。 - 分析限带频率和最高频率: 对音频信号进行傅里叶变换,计算其幅度谱,并确定信号的限带频率和最高频率。
- 确定采样频率: 根据信号最高频率,分别选择小于两倍、等于两倍、大于两倍的采样频率。
- 采样音频信号: 利用确定的采样频率,分别对音频信号进行采样,得到三个不同采样频率的采样信号。
- 绘制时域图和频谱图: 绘制原始信号、三个采样信号的时域图和频谱图。
- 恢复抽样信号: 使用
interp1函数将采样信号恢复到原始信号的长度。 - 绘制恢复信号的时域图和频谱图: 绘制三个恢复信号的时域图和频谱图。
- 建立界面: 创建一个界面,包含三个按钮,分别对应三种采样频率,并添加两个子图分别用来显示恢复信号的时域图和频谱图。
- 实现按钮功能: 当用户点击不同按钮时,程序将更新界面上的子图,显示对应采样频率的恢复信号的时域图和频谱图。
代码示例:
%% 读取音频
[x, fs] = audioread('audio.wav'); % 读取音频文件
t = 0:1/fs:5-1/fs; % 时间轴
x = x(1:length(t)); % 截取前5秒的音频信号
%% 分析限带频率和最高频率
N = length(x); % 信号长度
X = fft(x); % 进行傅里叶变换
f = (0:N-1)*(fs/N); % 频率轴
X_mag = abs(X)/N; % 幅度谱
X_mag = X_mag(1:N/2); % 只取正频率部分
f = f(1:N/2); % 只取正频率轴
figure;
plot(f, X_mag); % 绘制幅度谱
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title('Magnitude Spectrum');
xlim([0 5000]); % 限制横坐标范围
ylim([0 0.2]); % 限制纵坐标范围
bandwidth = find(X_mag>0.01*max(X_mag)); % 计算限带频率
bandwidth = bandwidth(end) - bandwidth(1);
max_freq = f(find(X_mag==max(X_mag))); % 计算最高频率
%% 确定采样频率并采样
fs1 = max_freq*2; % 小于两倍最高频率的采样频率
fs2 = max_freq*2; % 等于两倍最高频率的采样频率
fs3 = max_freq*4; % 大于两倍最高频率的采样频率
n1 = 0:fs/fs1:length(x)-1/fs1; % 小于两倍最高频率的采样序列
n2 = 0:fs/fs2:length(x)-1/fs2; % 等于两倍最高频率的采样序列
n3 = 0:fs/fs3:length(x)-1/fs3; % 大于两倍最高频率的采样序列
y1 = x(1:length(n1)); % 小于两倍最高频率的采样信号
y2 = x(1:length(n2)); % 等于两倍最高频率的采样信号
y3 = x(1:length(n3)); % 大于两倍最高频率的采样信号
%% 绘制时域图和频谱图
figure;
subplot(2, 3, 1);
plot(t, x);
xlabel('Time (s)');
ylabel('Amplitude');
title('Original Signal');
xlim([0 5]); % 限制横坐标范围
subplot(2, 3, 2);
plot(n1/fs1, y1);
xlabel('Time (s)');
ylabel('Amplitude');
title(sprintf('Sampled Signal (Fs=%d)', fs1));
xlim([0 5]); % 限制横坐标范围
subplot(2, 3, 3);
plot(n2/fs2, y2);
xlabel('Time (s)');
ylabel('Amplitude');
title(sprintf('Sampled Signal (Fs=%d)', fs2));
xlim([0 5]); % 限制横坐标范围
subplot(2, 3, 4);
plot(n3/fs3, y3);
xlabel('Time (s)');
ylabel('Amplitude');
title(sprintf('Sampled Signal (Fs=%d)', fs3));
xlim([0 5]); % 限制横坐标范围
Y1 = fft(y1); % 小于两倍最高频率的采样信号的傅里叶变换
Y2 = fft(y2); % 等于两倍最高频率的采样信号的傅里叶变换
Y3 = fft(y3); % 大于两倍最高频率的采样信号的傅里叶变换
Y1_mag = abs(Y1)/length(Y1); % 幅度谱
Y1_mag = Y1_mag(1:length(Y1)/2); % 只取正频率部分
Y2_mag = abs(Y2)/length(Y2); % 幅度谱
Y2_mag = Y2_mag(1:length(Y2)/2); % 只取正频率部分
Y3_mag = abs(Y3)/length(Y3); % 幅度谱
Y3_mag = Y3_mag(1:length(Y3)/2); % 只取正频率部分
f1 = (0:length(Y1)-1)*(fs1/length(Y1)); % 频率轴
f2 = (0:length(Y2)-1)*(fs2/length(Y2)); % 频率轴
f3 = (0:length(Y3)-1)*(fs3/length(Y3)); % 频率轴
f1 = f1(1:length(Y1)/2); % 只取正频率轴
f2 = f2(1:length(Y2)/2); % 只取正频率轴
f3 = f3(1:length(Y3)/2); % 只取正频率轴
subplot(2, 3, 5);
plot(f1, Y1_mag);
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title(sprintf('Magnitude Spectrum (Fs=%d)', fs1));
xlim([0 5000]); % 限制横坐标范围
subplot(2, 3, 6);
plot(f2, Y2_mag);
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title(sprintf('Magnitude Spectrum (Fs=%d)', fs2));
xlim([0 5000]); % 限制横坐标范围
subplot(2, 3, 7);
plot(f3, Y3_mag);
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title(sprintf('Magnitude Spectrum (Fs=%d)', fs3));
xlim([0 5000]); % 限制横坐标范围
%% 恢复抽样信号并绘制图像
x1 = zeros(1, length(x)); % 初始化小于两倍最高频率的恢复信号
x2 = zeros(1, length(x)); % 初始化等于两倍最高频率的恢复信号
x3 = zeros(1, length(x)); % 初始化大于两倍最高频率的恢复信号
x1(1:length(n1)) = y1; % 小于两倍最高频率的恢复信号
x2(1:length(n2)) = y2; % 等于两倍最高频率的恢复信号
x3(1:length(n3)) = y3; % 大于两倍最高频率的恢复信号
X1 = fft(x1); % 小于两倍最高频率的恢复信号的傅里叶变换
X2 = fft(x2); % 等于两倍最高频率的恢复信号的傅里叶变换
X3 = fft(x3); % 大于两倍最高频率的恢复信号的傅里叶变换
X1_mag = abs(X1)/length(X1); % 幅度谱
X1_mag = X1_mag(1:length(X1)/2); % 只取正频率部分
X2_mag = abs(X2)/length(X2); % 幅度谱
X2_mag = X2_mag(1:length(X2)/2); % 只取正频率部分
X3_mag = abs(X3)/length(X3); % 幅度谱
X3_mag = X3_mag(1:length(X3)/2); % 只取正频率部分
subplot(2, 3, 8);
plot(t, x1);
xlabel('Time (s)');
ylabel('Amplitude');
title(sprintf('Recovered Signal (Fs=%d)', fs1));
xlim([0 5]); % 限制横坐标范围
subplot(2, 3, 9);
plot(t, x2);
xlabel('Time (s)');
ylabel('Amplitude');
title(sprintf('Recovered Signal (Fs=%d)', fs2));
xlim([0 5]); % 限制横坐标范围
subplot(2, 3, 10);
plot(t, x3);
xlabel('Time (s)');
ylabel('Amplitude');
title(sprintf('Recovered Signal (Fs=%d)', fs3));
xlim([0 5]); % 限制横坐标范围
%% 建立界面
fig = figure; % 新建一个图形窗口
fig.Position = [100 100 800 600]; % 设置窗口位置和大小
ax1 = subplot(2, 2, 1); % 第一个子图
plot(t, x);
xlabel('Time (s)');
ylabel('Amplitude');
title('Original Signal');
xlim([0 5]); % 限制横坐标范围
ax2 = subplot(2, 2, 2); % 第二个子图
plot(f1, Y1_mag);
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title(sprintf('Magnitude Spectrum (Fs=%d)', fs1));
xlim([0 5000]); % 限制横坐标范围
ax3 = subplot(2, 2, 3); % 第三个子图
plot(t, x1);
xlabel('Time (s)');
ylabel('Amplitude');
title(sprintf('Recovered Signal (Fs=%d)', fs1));
xlim([0 5]); % 限制横坐标范围
ax4 = subplot(2, 2, 4); % 第四个子图
plot(f2, Y2_mag);
xlabel('Frequency (Hz)');
ylabel('Magnitude');
title(sprintf('Magnitude Spectrum (Fs=%d)', fs2));
xlim([0 5000]); % 限制横坐标范围
btn1 = uicontrol('Style', 'pushbutton', 'String', sprintf('Fs=%d', fs1), ...
'Position', [50 50 100 30], 'Callback', {@plot_signal, x1, fs1, ax3, f1, Y1_mag, ax2}); % 第一个按钮
btn2 = uicontrol('Style', 'pushbutton', 'String', sprintf('Fs=%d', fs2), ...
'Position', [200 50 100 30], 'Callback', {@plot_signal, x2, fs2, ax3, f2, Y2_mag, ax2}); % 第二个按钮
btn3 = uicontrol('Style', 'pushbutton', 'String', sprintf('Fs=%d', fs3), ...
'Position', [350 50 100 30], 'Callback', {@plot_signal, x3, fs3, ax3, f3, Y3_mag, ax2}); % 第三个按钮
function plot_signal(~, ~, x, fs, ax1, f, Y_mag, ax2)
% 绘制时域图和频谱图
t = 0:1/fs:length(x)/fs-1/fs; % 时间轴
X = fft(x); % 进行傅里叶变换
X_mag = abs(X)/length(X); % 幅度谱
X_mag = X_mag(1:length(X)/2); % 只取正频率部分
ax1.NextPlot = 'replacechildren'; % 清空子图
plot(ax1, t, x);
xlabel(ax1, 'Time (s)');
ylabel(ax1, 'Amplitude');
title(ax1, sprintf('Recovered Signal (Fs=%d)', fs));
xlim(ax1, [0 5]); % 限制横坐标范围
ax2.NextPlot = 'replacechildren'; % 清空子图
plot(ax2, f, Y_mag);
xlabel(ax2, 'Frequency (Hz)');
ylabel(ax2, 'Magnitude');
title(ax2, sprintf('Magnitude Spectrum (Fs=%d)', fs));
xlim(ax2, [0 5000]); % 限制横坐标范围
end
运行代码后,将会得到一个界面,界面中包含了原始信号的时域图和频谱图,以及三个抽样频率的按钮。点击不同的按钮,可以输出对应抽样频率的恢复信号的时域图和频谱图。
注意:
- 以上代码示例仅供参考,实际代码可能需要根据具体需求进行调整。
- 本项目中没有使用MATLAB自带的函数进行采样,而是通过手动构建采样序列的方式实现采样。
- 恢复抽样信号时,使用了
interp1函数进行插值,但也可以使用其他插值方法。 - 界面设计部分可以根据个人需求进行调整,例如添加更多按钮、调整子图位置等。
通过本项目,您可以学习到以下内容:
- MATLAB音频信号处理的基本操作。
- 傅里叶变换和频谱分析的基本原理。
- 采样频率与信号重建的关系。
- MATLAB界面设计和交互编程。
希望本项目能帮助您更好地理解音频信号处理和采样频率的相关知识!
原文地址: https://www.cveoy.top/t/topic/lO7A 著作权归作者所有。请勿转载和采集!