项目1提供实验文件如下:
📁 项目文件夹 ├── 📁 audio/ │ └── 🎵 greatest_work.flac ├── 📄 README.MD ├── 📝 ex0_all.m ├── 📝 ex1_read_audio_cut.m ├── 📝 ex2_dct_x_cut.m ├── 📝 ex3_energy_cut.m ├── 📝 ex4_quantization.m ├── 📝 ex5_idct_quant.m ├── 📝 ex6_recombine_I_X.m ├── 📝 ex7_analyze.m ├── 🔒 test_project1.p └── 📋 基于DCT原理的音频压缩.html
? 标记的地方需用合适的代码进行替换? 标记,填写合适的代码test_project1.p 文件test_project1.p 程序应显示正确或错误test_project1.p 文件20230001_张三.ziptest_project1.p 对于每个 ex 的批改是独立的audio 文件夹下提供了 greatest_work.flac 作为示例文件ex0_all.m 的内容功能:调用所有子函数完成完整的音频压缩流程(无需修改)
参数设置
window = 512 - 窗函数大小perc = 0.99 - 能量阈值(保留99%能量)处理流程
音频读取 → DCT变换 → 能量阈值 → 量化 → IDCT → 合并 → 分析 ex1 → ex2 → ex3 → ex4 → ex5 → ex6 → ex7
函数签名
function [x_cut, N, nb] = ex1_read_audio_cut(window, path)
功能说明
读取音频文件,并根据指定的窗函数大小对音频数据进行分段处理。每段长度为window个采样点。该步骤有助于后续处理,比如进行DCT变换和量化等操作。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
window |
整数 | 窗口大小(如512) |
path |
字符串 | 音频文件路径 |
| 输出 | ||
x_cut |
矩阵 | 分段后的音频(每列一段) |
N |
整数 | 音频总长度(采样点数) |
nb |
整数 | 分段数量 |
函数签名
function [X_CUT, row, col] = ex2_dct_x_cut(x_cut)
功能说明
对输入的分段后的时域音频信号x_cut的每一列进行离散余弦变换(DCT),将时域信号转换为频域信号。这一操作在信号处理和压缩算法(如音频压缩编码)中非常有用。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
x_cut |
矩阵 | 分段后的时域信号 |
| 输出 | ||
X_CUT |
矩阵 | DCT变换后的频域信号 |
row |
整数 | 矩阵行数 |
col |
整数 | 矩阵列数 |
函数签名
function [X_CUT_99, ind, i] = ex3_energy_cut(X_CUT, perc)
功能说明
根据能量阈值保留重要的DCT系数,丢弃能量较小的系数。这是音频压缩的核心步骤之一。通过保留指定百分比(如99%)能量的系数,其余系数置零,实现数据压缩。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
X_CUT |
矩阵 | DCT系数矩阵 |
perc |
小数 | 能量保留百分比(0.99) |
| 输出 | ||
X_CUT_99 |
矩阵 | 阈值化后的系数 |
ind |
单元数组 | 每列保留系数的索引 |
i |
向量 | 每列保留的系数数量 |
函数签名
function [q, tmp, quant] = ex4_quantization(X_CUT_99)
功能说明
对DCT系数进行量化和解量化。量化是将连续值映射到离散级别的过程,是有损压缩的关键步骤。本函数实现均匀量化,将系数值量化到有限的离散级别,然后再解量化恢复。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
X_CUT_99 |
矩阵 | 阈值化后的系数 |
| 输出 | ||
q |
标量 | 量化步长 |
tmp |
矩阵 | 量化后的整数值 |
quant |
矩阵 | 解量化后的值 |
函数签名
function I_X_quant = ex5_idct_quant(quant)
功能说明
对量化后的DCT系数进行逆变换。将频域的DCT系数通过IDCT(逆离散余弦变换)变换回时域信号,为后续音频重建做准备。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
quant |
矩阵 | 量化后的DCT系数 |
| 输出 | ||
I_X_quant |
矩阵 | 逆变换后的时域信号 |
函数签名
function [dis, reconstruct] = ex6_recombine_I_X(I_X_quant)
功能说明
将IDCT后的片段合并重建完整音频。将分段处理后的音频片段重新组合成完整的音频信号,并保存为音频文件。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
I_X_quant |
矩阵 | IDCT后的信号片段 |
| 输出 | ||
dis |
整数 | 重建信号总长度 |
reconstruct |
向量 | 完整重建信号 |
函数签名
function ratio = ex7_analyze(reconstruct, show_plot)
功能说明
分析压缩效果并可视化对比。计算压缩比和均方误差(MSE),评估压缩质量。可选显示原始信号与重建信号的对比图,包括时域波形对比和重建误差分析。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
reconstruct |
向量 | 重建后的音频 |
show_plot |
布尔 | 是否显示图形 |
| 输出 | ||
ratio |
标量 | 压缩比 |
评估指标
在提交前,请确认:
? 都已替换为正确代码test_project1.p 输入1-7全部通过ex0_all.m 能够正常执行Q1: 代码中的 ? 应该填什么?
A: 根据注释提示,填写对应的MATLAB表达式。例如:
N = ? → N = length(x);X_CUT = ? → X_CUT = zeros(row, col);Q2: test_project1.p 显示错误怎么办?
A:
Q3: 可以修改变量名吗?
A: 不可以!test_project1.p 会检查预定义的变量名,修改后会导致检查失败。
Q4: 如何调试代码?
A: 使用以下调试方法:
1. 分步验证
% 在函数中添加输出语句
disp(['N = ', num2str(N)]);
fprintf('段数: %d\n', nb);
% 单独测试函数
window = 512;
path = './audio/greatest_work.flac';
[x_cut, N, nb] = ex1_read_audio_cut(window, path);
disp(size(x_cut)); % 查看维度
2. 检查变量
% 查看变量类型和大小
whos x_cut
% 查看矩阵维度
size(x_cut)
[row, col] = size(X_CUT)
% 查看部分内容
x_cut(1:5, 1) % 第1列的前5个元素
3. 索引调试
% 验证索引计算
n = 1;
start_idx = (n-1)*window + 1 % 应该是1
end_idx = n*window % 应该是512
% 检查是否越界
if end_idx > length(x)
error('索引超出范围!');
end
4. 可视化调试
% 绘制信号波形
plot(x_cut(:,1));
title('第1段音频');
% 查看矩阵热图
imagesc(X_CUT);
colorbar;
title('DCT系数矩阵');
% 对比原始和重建信号
figure;
subplot(2,1,1); plot(x_original(1:1000));
subplot(2,1,2); plot(reconstruct(1:1000));
5. 断点调试
6. 常见错误排查
% 维度不匹配
% 错误:x_cut(:, n) = x(1:window)
% 正确:x_cut(:, n) = x((n-1)*window+1 : n*window)
% 变量名拼写错误
% 错误:X_cut (大小写)
% 正确:X_CUT
% 索引越界
% 确保:end_idx <= length(x)
Q5: 音频文件路径找不到怎么办?
A: 确保:
audio 文件夹与 .m 文件在同一目录./audio/...通过本实验,你将掌握: