本项目用于对输入音频施加基于卷积的空间混响效果。程序默认读取 audio/input/Friendship Is Magic.wav,根据所选空间类型生成对应的混响结果,并将输出文件写入 audio/output/。
在离散信号处理中,若将原始音频记为 x[n],将某个空间的冲激响应记为 h[n],则该音频在该空间中的输出信号可表示为:
y[n] = Σ x[k] h[n - k]
其中:
x[n]表示输入音频h[n]表示空间冲激响应y[n]表示加入混响后的输出音频
本项目采用的思路是:使用一个简化的空间冲激响应来表示“直达声 + 若干早期反射 + 衰减尾音”,然后将输入音频与该冲激响应进行卷积,从而得到混响效果。
冲激响应可以理解为:如果向某个空间输入一个“非常短、近似瞬时”的声音,这个空间会输出怎样的响应结果。
在本项目中,冲激响应主要包含三部分:
- 直达声
- 若干早期反射
- 逐渐衰减的后期混响尾音
因此,冲激响应本质上就是“空间特性”的数学表达。
当输入音频与该冲激响应做卷积时,原始音频就会获得这个空间对应的混响效果。
从试听角度看,impulse_response.wav 往往不像正常音乐或对白,它更像一次短促的点击、若干回声以及随时间衰减的尾音。这是正常现象,因为它描述的是空间本身,而不是完整内容。
程序的主要模块如下:
- apply_reverb.py:命令行入口,负责读取参数并组织处理流程
- presets.py:负责读取
configs/spaces/*.yaml中的空间参数 - reverb_core.py:负责音频读取、冲激响应生成、卷积计算和 WAV 导出
若只关注“真正执行卷积”的核心实现,请直接查看:
- reverb_core.py 中的
apply_convolution_reverb()
该函数中的核心计算语句为:
wet_audio[:, channel_index] = fftconvolve(audio[:, channel_index], impulse_response, mode="full").astype(np.float32)这条语句对每个声道分别执行卷积运算,是本项目生成混响效果的核心步骤。
此外,以下两个函数也较为关键:
build_impulse_response():根据 YAML 参数构造空间冲激响应load_audio_file():将输入音频读取为 NumPy 数组
整体流程可概括为:
读取音频 -> 读取空间参数 -> 生成冲激响应 -> 执行卷积 -> 导出结果
项目使用 conda 环境 S_S_Homework。
若本机尚未创建该环境,请执行:
conda env create -f environment.yml
conda activate S_S_Homework若环境已存在,直接激活即可:
conda activate S_S_Homework程序默认读取以下文件:
audio/input/Friendship Is Magic.wav
因此在常规使用场景下,无需额外传入 --input 参数。
如需更换输入音频,可采用以下任一方式:
- 直接将新的音频文件替换为
audio/input/Friendship Is Magic.wav - 运行时显式指定其他输入路径,例如:
python src/apply_reverb.py --input "audio/input/你的音频.wav" --space-type hall推荐优先使用 wav 格式。程序同时兼容 .mp3、.m4a、.mp4 等常见音频格式。
查看当前可用的空间类型:
python src/apply_reverb.py --list-space-types生成小房间效果:
python src/apply_reverb.py --space-type small_room生成普通教室效果:
python src/apply_reverb.py --space-type classroom生成大厅效果:
python src/apply_reverb.py --space-type hall生成自定义效果:
python src/apply_reverb.py --space-type custom如需额外导出冲激响应音频:
python src/apply_reverb.py --space-type hall --export-impulse-response常规运行时,用户实际需要选择的核心参数只有一个:
--space-type
--export-impulse-response 是可选分析参数,默认关闭。
程序运行后,默认只会在 audio/output/ 下生成最终混响音频,例如:
Friendship_Is_Magic_small_room.wavFriendship_Is_Magic_classroom.wavFriendship_Is_Magic_hall.wavFriendship_Is_Magic_custom.wav
如果运行时额外加上 --export-impulse-response,还会生成对应空间的冲激响应文件,例如:
Friendship_Is_Magic_small_room_impulse_response.wavFriendship_Is_Magic_classroom_impulse_response.wavFriendship_Is_Magic_hall_impulse_response.wavFriendship_Is_Magic_custom_impulse_response.wav
这些文件记录的不是最终成品音频,而是当前空间模型本身。
如果将它与输入音频做卷积,就能得到对应空间下的混响结果。
若只需要试听最终效果,保持默认设置即可。
冲激响应文件主要用于原理分析、参数检查或辅助说明“空间特性”的来源,因此默认不导出。
small_room
- 反射到达较快
- 尾音较短
- 听感较紧凑
- 适合表现近距离、小空间效果
classroom
- 空间感适中
- 清晰度与混响感较为平衡
- 适合用作中等混响示例
hall
- 前置延迟较长
- 尾音较明显
- 空间感最强
- 适合表现开阔空间效果
custom
- 由用户自行设定参数
- 适合实验性调整和个性化配置
所有空间参数均存放于:
configs/spaces/
最常修改的文件通常为:
configs/spaces/custom.yaml
修改完成后,执行:
python src/apply_reverb.py --space-type custom各 YAML 文件中已经写入参数注释。主要参数含义如下:
pre_delay_ms:主要反射开始前的延迟时间;数值越大,空间通常显得越开阔reflection_delays_ms:各组早期反射到达的时间reflection_gains:各组早期反射的强度,必须与reflection_delays_ms一一对应tail_seconds:混响尾音持续时间;数值越大,尾音越长tail_decay:尾音衰减速度;数值越大衰减越快,数值越小拖尾越长tail_gain:尾音整体强度;数值越大,尾音越明显wet_mix:混响声在最终输出中的占比seed:用于固定尾音纹理的随机种子
若希望空间听起来更大,可优先尝试:
- 增大
pre_delay_ms - 增大
tail_seconds - 适当减小
tail_decay
若希望混响更加明显,可优先尝试:
- 增大
wet_mix - 增大
tail_gain - 适当增大部分
reflection_gains
若希望结果更接近原音,可优先尝试:
- 减小
wet_mix - 减小
tail_gain - 缩短
tail_seconds
列出所有空间类型:
python src/apply_reverb.py --list-space-types直接生成大厅效果:
python src/apply_reverb.py --space-type hall使用自定义 YAML:
python src/apply_reverb.py --space-type custom生成大厅效果并同时导出冲激响应:
python src/apply_reverb.py --space-type hall --export-impulse-response