本文档为 DSP 课程项目3(人声变调实验)的项目说明,请仔细阅读后按步骤完成实验。
? 标记的地方需用合适的代码进行替换ex1 和 ex4 文件已完成,无需修改stft_custom.m 和 istft_custom.m 是辅助函数,用于兼容旧版MATLAB,无需修改test_Project3.p 是加密文件,无法打开,用于检查代码正确性test_project3 文件进行检查:
test_project3.p 文件,选择"运行"0=ex0, 21=方法一, 22=方法二, 3=ex3, 5=ex51 或 4 可验证已完成的ex1/ex4是否正常工作test_project3,键入 9 后按回车函数签名
function [y_interpolated, fs] = ex0_all(audioPath, alpha, Lwin, Ra, method)
功能说明
主函数,调用各子函数完成完整的变调流程。在完成 ex1-ex5 所有内容后执行。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
audioPath |
字符串 | 音频文件路径 |
alpha |
标量 | 变调系数(α > 1 升调,α < 1 降调) |
Lwin |
整数 | 分帧帧长(如1024) |
Ra |
整数 | 分析帧移(如256) |
method |
整数 | 方法选择(1或2) |
| 输出 | ||
y_interpolated |
向量 | 变调后的音频信号 |
fs |
标量 | 采样率 |
>> [y_interpolated, fs] = ex0_all('./audio/male2.wav', 2, 1024, 256, 2);
% 使用方法二将male2.wav升高2倍频率
函数签名
function Freq = ex1_analysis(x, fs, Lwin, Ra)
功能说明
对输入信号进行短时傅里叶变换(STFT),得到频谱矩阵。此函数已完成,无需修改。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
x |
向量 | 输入音频信号 |
fs |
标量 | 采样频率 |
Lwin |
整数 | 窗长(FFT长度) |
Ra |
整数 | 分析帧移 |
| 输出 | ||
Freq |
复数矩阵 | STFT频谱 [num_freqs × num_frames] |
stft 函数,项目提供了 stft_custom.m 文件。请阅读 ex1 的注释部分,理解该函数目的。
函数签名
function [Freq_out] = ex2_process_method1(Freq, Lwin, Ra, alpha)
功能说明
使用方法一(Phase Vocoder + 相位修正)实现频谱修改。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
Freq |
复数矩阵 | 输入频谱矩阵 |
Lwin |
整数 | 窗长(FFT长度) |
Ra |
整数 | 分析帧移 |
alpha |
标量 | 变调因子 |
| 输出 | ||
Freq_out |
复数矩阵 | 相位修正后的频谱 |
函数签名
function [Freq_out] = ex2_process_method2(Freq, Lwin, Ra, alpha)
功能说明
使用方法二(频谱帧操作)实现频谱修改。通过对频谱帧进行抽取或复制改变帧数。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
Freq |
复数矩阵 | 输入频谱矩阵 |
Lwin |
整数 | 窗长(FFT长度) |
Ra |
整数 | 分析帧移 |
alpha |
标量 | 变调因子 |
| 输出 | ||
Freq_out |
复数矩阵 | 帧操作后的频谱 |
函数签名
function new_Freq = ex3_formant(Freq_out, alpha)
功能说明
对频谱进行共振峰修正,保持原始音色不变。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
Freq_out |
复数矩阵 | 变调后的频谱 |
alpha |
标量 | 变调因子 |
| 输出 | ||
new_Freq |
复数矩阵 | 共振峰修正后的频谱 |
函数签名
function y = ex4_synthesis(Freq_out, Lwin, fs, Rs)
功能说明
对修改后的频谱进行逆短时傅里叶变换(ISTFT),重建时域信号。此函数已完成,无需修改。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
Freq_out |
复数矩阵 | 修改后的频谱 |
Lwin |
整数 | 窗长 |
fs |
标量 | 采样频率 |
Rs |
标量 | 合成帧移 |
| 输出 | ||
y |
向量 | 重建的时域信号 |
istft 函数,项目提供了 istft_custom.m 文件。请阅读 ex4 的注释部分,理解该函数目的。
函数签名
function [y_interpolated] = ex5_reformation(y, lx)
功能说明
通过插值将变调后的信号恢复到原始长度,实现变调但不变速。
| 参数 | 类型 | 说明 |
|---|---|---|
| 输入 | ||
y |
向量 | 重建后的信号(长度已改变) |
lx |
整数 | 目标长度(原始信号长度) |
| 输出 | ||
y_interpolated |
向量 | 插值后的信号(恢复原长度) |
interp1() 进行插值| 文件名 | 说明 | 用途 |
|---|---|---|
female1.wav, female2.wav |
女声音频 | 测试变调效果 |
male1.wav, male2.wav |
男声音频 | 测试变调效果 |
orig1.wav, orig2.wav |
音乐片段 | 原始参考 |
orig1_shift.wav, orig2_shift.wav |
升高1.5倍 | 完成ex2+ex5后对比 |
orig1_corr.wav, orig2_corr.wav |
共振峰修正 | 完成ex2+ex3+ex5后对比 |
orig*_shift.wav 一致orig*_corr.wav 一致在提交前,请确认:
synthesize_param 已正确填写(方法一用Ra*alpha,方法二用Ra)? 都已替换为正确代码test_project3.p,输入 9 检查,5个模块全部通过ex0_all 能够正常执行并听到变调音频Q1: 方法一和方法二有什么区别?
A:
Q2: 为什么变调后声音像"小黄人"?
A: 简单变调会同时改变基频和共振峰。当共振峰超出正常人类范围时,声音就会失真。需要使用 ex3 的共振峰修正来保持原始音色。
Q3: ex5 插值的作用是什么?
A: 变调处理后信号长度会改变(升调变短,降调变长)。插值的作用是将信号恢复到原始长度,实现"变调不变速"。
Q4: 如何调试代码?
A: 使用以下调试方法:
% 1. 检查维度
size(spectrum)
% 2. 可视化频谱
imagesc(abs(spectrum));
colorbar;
% 3. 播放音频对比
sound(y_original, fs);
pause(2);
sound(y_shifted, fs);
通过本实验,你将掌握:
思考:ex0 输入参数最后一项为 beta,该参数用于表示速度。在给定 beta 的情况下如何通过修改代码实现变调+变速?
本题选做,不考查。