☰
ClearerVoice-Studio 混响加噪训练数据生成指南:RIR 仿真、早期混响目标构建与 SNR 混合全流程
2026/10/4 14:26:36 网站建设 项目流程
  • 人工智能
  • 语音
  • 音频处理
  • 深度学习

【免费下载链接】ClearerVoice-Studio

An AI-Powered Speech Processing Toolkit and Open Source SOTA Pretrained Models, Supporting Speech Enhancement, Separation, and Target Speaker Extraction, etc.

项目地址:https://gitcode.com/gh_mirrors/cl/ClearerVoice-Studio
点击查看免费下载

导读

本文基于 generate_reverb_noisy_speech 模块,系统讲解 ClearerVoice-Studio 中"混响 + 加噪"训练数据的完整生成流程:从随机房间声学仿真生成房间冲激响应(RIR),到卷积生成混响语音、构造带早期混响的目标语音,再到按随机 SNR 混合背景噪声。读完本文,你将掌握该模块三个脚本的调用关系、config/para.cfg全部参数含义,以及如何为自己的语音增强模型(如 FRCRN_SE、MossFormer2_SE、MossFormerGAN_SE)批量生产可用于重训或微调的高质量reverb&noisy-clean-speech配对数据。

一、模块定位:为语音增强模型提供配对训练数据

在 ClearerVoice-Studio 中,train/speech_enhancement 目录负责 FRCRN_SE、MossFormer2_SE、MossFormerGAN_SE 等增强模型的训练,而本模块(generate_reverb_noisy_speech)正是其数据上游:通过"混响 + 加噪"两条路径,把干净的语音语料变换成更贴近真实场景的带噪语音,并同时输出对应的干净目标,从而构成监督训练所需的(noisy, target)配对样本。文档开篇即说明其用途:"This script generates training data for speech enhancement models. Once the data generation is complete, you can use the output to retrain or fine-tune your models."

整个模块由以下文件组成:

文件作用
run.sh一键串联三步生成流程的入口脚本
step1_gen_RIRs.py随机房间声学仿真,批量生成 RIR 并落盘为 wav
step2_gen_reverb_speech.py用 RIR 与干净语音卷积,生成混响语音与早期混响目标
step3_add_noise.py按目标 SNR 将背景噪声叠加到混响语音上
audiolib.py音频读写、SNR 混合、弱语音模拟等公共函数库
config/para.cfg加噪阶段的全部配置参数(INI 格式)
data/data_scp/speech.scp 与 data/data_scp/noise.scp干净语音与噪声的文件列表示例
requirements.txt依赖声明(rir_generator)

二、数据混合流程:六步生成 reverb & noisy 配对

原文档将混合流程归纳为六个步骤,下面结合源码逐一展开说明其物理意义与实现细节。

1. 房间冲激响应(RIR)生成

随机选择一个房间尺寸,在"麦克风—声源"位置组合下生成 RIR,并多次重复该过程。对应 step1_gen_RIRs.py 的实现,其随机参数范围如下:

  • 混响时间 RT:从均值为 0、标准差为 0.1 的高斯分布中采样后加 0.6,再裁剪到[0.2, 1.0]秒区间,保留两位小数,即RT = round(np.clip(random.gauss(0,0.1)+0.6, 0.2, 1.0), 2);
  • 房间尺寸:长 x 在[7, 11]m、宽 y 在[5, 7]m、高 z 在[3.4, 3.6]m 内均匀随机;
  • 麦克风位置:x/y 在[1, 尺寸-1]m、z 在[2, 3]m 内随机;
  • 声源位置:x/y 在[0.3, 尺寸-0.3]m、z 在[0.8, 1.8]m 内随机。

随后调用第三方库rir_generator的rir.generate()完成声学仿真,关键参数为声速c=340m/s、采样率fs、接收/声源/房间三维坐标、reverberation_time=RT,输出样本数取nsample=int(fs * RT)。每个 RIR 以rir_runX_i_RT_X.XX.wav命名保存,并同步写入wav.lst清单供第二步读取。注意坐标映射:源码中传给r、s、L的分别是[mic_x, mic_z, mic_y]、[src_x, src_z, src_y]、[rm_x, rm_z, rm_y],与常规[x, y, z]顺序不同,属于该模块的既有约定。

2. 干净语音文件选择

每生成一个 RIR,可为其挑选多条干净语音用于生成混响语音,由step2_gen_reverb_speech.py的--num_wavs_per_RIR(默认 3)控制:即每个 RIR 对应生成num_wavs_per_RIR条混响语音。语音文件从speech.scp中随机抽取,源码通过random.randint(0, num_clean_files-1)选索引后按行读取路径。

3. SNR 选择

为每条混合物在预定范围内随机选择一个信噪比。step3_add_noise.py读取para.cfg中的snr_lower(默认 0 dB)、snr_upper(默认 15 dB)与random_snr开关:当random_snr=True时,对每条混合在[snr_lower, snr_upper]内均匀随机采样一个 SNR(保留两位小数);否则按total_snrlevels(默认 2)在上下界之间线性插值出离散的 SNR 档位,为每条混合逐一使用。

4. 噪声采样

对每条混响语音随机选择一个噪声文件。step3_add_noise.py读取noise_list(默认./data/data_scp/noise.scp)中的噪声路径列表;训练模式下用np.random.randint随机取索引,测试模式下(test=True)则按固定轮转取噪声,保证可复现。读取失败的噪声文件会被跳过并重新采样。

5. 长度匹配

若噪声信号比干净语音短,则拼接额外的噪声片段以匹配时长。step3_add_noise.py的处理逻辑是:

  • 若噪声长于语音:在噪声中随机截取一段与语音等长的片段(st = np.random.randint(0, len_noise - len_clean));
  • 若噪声短于语音:循环拼接下一条噪声,段间插入silence_length秒(默认 0.1 s)的静音作为间隔,直到总长超过语音长度,再随机截取等长片段。拼接过程中还会把用到的噪声文件名记录下来,用于命名。

6. 目标语音生成(早期混响目标)

这是本模块最有特色的设计。原文档明确建议不要直接用原始干净语音作为目标,原因有二:其一,卷积过程引入时延,使混响信号与干净信号不再对齐(产生时间偏移);其二,两者长度也不匹配。为此,模块提出保留早期混响(early reverberations)作为目标——即将 RIR 截断后与干净语音卷积,生成"只含早期混响"的混响语音作为目标,早期混响长度可通过--target_rt调整,默认 0.1 s(100 ms)。

对应实现位于 step2_gen_reverb_speech.py:先计算截断点h_trim_point = int(args.sample_rate * args.target_rt),再把 RIR 在该点之后的位置全部置零得到h_trim:

h_trim_point = int(args.sample_rate * args.target_rt) h_trim, fs = sf.read(rir_path, always_2d=True) h_trim[h_trim_point:, :] = 0

随后分别用完整 RIR 与截断 RIR 与干净语音做scipy.signal.convolve卷积,得到混响信号signal_reverb与目标信号signal_target。两者按共同的最大绝对值归一化后统一乘 0.9,避免削波的同时保持相对电平一致:

signal_reverb = ss.convolve(h[:, None, :], signal[:, :, None]) signal_target = ss.convolve(h_trim[:, None, :], signal[:, :, None]) norm_term = max([max(abs(signal_reverb)), max(abs(signal_target))]) signal_reverb = signal_reverb / norm_term * 0.9 signal_target = signal_target / norm_term * 0.9

这样构造的目标与混响语音长度一致、时延一致,仅差"晚期混响 + 噪声",正好是增强模型应该去抑制的部分,训练目标更为合理。

三、环境依赖与目录结构

模块的依赖极简,requirements.txt 仅声明rir_generator(RIR 仿真的核心库)。脚本运行还隐式依赖numpy、scipy、soundfile、librosa、yamlargparse、configparser,这些在项目根目录 requirements.txt 中均有声明。

仓库自带的示例数据布局如下(相对仓库根目录):

train/data_generation/speech_enhancement/generate_reverb_noisy_speech/data/ ├── data_scp/ │ ├── speech.scp # 干净语音路径列表 │ └── noise.scp # 噪声路径列表 ├── noise/ # 示例噪声:ch03_sm001.wav 等 6 条 └── speech/ # 示例语音:p234_001.wav 等 9 条

speech.scp 的格式为每行一个语音文件路径:

./data/speech/p234_001.wav ./data/speech/p234_002.wav ...

noise.scp 的格式为每行一个噪声文件路径,同时兼容"名称\t路径"两列格式(见 audiolib.py 中get_filenames_ns对制表符的分割处理)。

四、使用步骤与一键运行

原文档给出三步使用指引,下面结合脚本与配置文件给出可落地的完整操作流程。

第 1 步:准备文件列表

按上述格式准备两份列表:干净语音列表(如speech.scp)与噪声列表(如noise.scp)。可直接修改data/data_scp/下的示例文件,或保留示例数据先做小规模冒烟测试。step2通过--speech_scp(默认./data/data_scp/speech.scp)读取语音列表,step3通过para.cfg中的noise_list(默认./data/data_scp/noise.scp)读取噪声列表。

第 2 步:配置参数

根据需求调整 config/para.cfg 中的加噪参数。完整配置如下(含注释说明):

# Configuration for generating Noisy Speech Dataset # - test: Specify if creating data for test, if False, creating data for training # - audioformat: default is .wav # - min_audio_length: Minimum Length of each audio clip (noisy and clean speech) in seconds # - max_audio_length: Maximum Length of each audio clip (noisy and clean speech) in seconds # - silence_length: Duration of silence introduced between clean speech utterances # - total_hours: Total number of hours of data required. Units are in hours # - snr_lower: Lower bound for SNR required (default: 0 dB) # - snr_upper: Upper bound for SNR required (default: 15 dB) # - random_snr: randomly generate one SNR mixer bounded between snr_lower and snr_upper # - total_snrlevels: Number of SNR levels if random_snr is False (default: 2) # - noise_list: A path to the noise script file # - save_noise: save background noise files, default: False [noisy_speech] test: False audioformat: *.wav min_audio_length: 3 max_audio_length: 25 silence_length: 0.1 total_hours: 0.05 snr_lower: 0 snr_upper: 15 random_snr: True total_snrlevels: 2 noise_list: ./data/data_scp/noise.scp suffix: reverb_noisy_utt_ save_noise: False

各参数含义与对生成结果的影响如下:

参数默认值作用说明
testFalseTrue时按固定轮转取噪声并生成带 SNR 标记的测试文件名;False时随机取噪声、文件名与语音同名,供训练使用
audioformat*.wav输出音频格式通配符,用于匹配中间产物
min_audio_length/max_audio_length3 / 25(秒)生成的音频片段时长区间;step3会将其换算为采样点(乘以目标采样率)
silence_length0.1(秒)拼接噪声片段时插入的静音间隔时长
total_hours0.05(小时)期望生成的数据总量,step3据此换算total_samples = total_hours*3600*target_fs作为样本数基准
snr_lower/snr_upper0 / 15(dB)SNR 上下界;random_snr=True时在此区间随机采样
random_snrTrue是否随机采样 SNR;False时按total_snrlevels线性取档
total_snrlevels2random_snr=False时的 SNR 档位数(在上下界间np.linspace插值)
noise_list./data/data_scp/noise.scp噪声文件列表路径
suffixreverb_noisy_utt_测试模式输出文件名的前缀
save_noiseFalse是否额外保存独立的背景噪声文件

第 3 步:运行脚本(可选循环生成)

run.sh是入口,它串联三个 Python 脚本并共享output_path、run_num、sample_rate三个全局变量。默认内容如下:

output_path=./data # output data to be saved to this dir run_num=1 #set 0, 1, 2, ... for different runs num_RIRs=10 #number of RIRs to be generated sample_rate=48000 ## Step 1: generate room impulse response (RIR) and save to wav files python step1_gen_RIRs.py \ --output_path $output_path \ --run_num $run_num \ --num_RIRs $num_RIRs \ --sample_rate $sample_rate ## Step 2: generate reverberant speech from clean speech by applying RIRs python step2_gen_reverb_speech.py \ --output_path $output_path \ --run_num $run_num \ --sample_rate $sample_rate ## Step3: add background noise to reverberant speech python step3_add_noise.py \ --output_path $output_path \ --run_num $run_num \ --sample_rate $sample_rate

运行bash run.sh即可完成演示。若想批量生成多份数据(例如为不同 run 生成互不重复的训练集),修改run_num为 0、1、2…… 重复执行即可——每个 run 的输出会隔离到独立的runX/子目录下,step1也会为每个 run 重新随机生成一批新的 RIR,天然实现数据多样化。需要注意run.sh中的run_num默认值为 1(非 0),而各脚本自身的默认值为'0',直接以命令行参数覆盖即可。此外可调高num_RIRs(默认 10)扩大声学场景覆盖面。

五、三步生成背后的源码实现

Step 1:随机声学环境仿真(step1_gen_RIRs.py)

脚本以yamlargparse解析参数,支持 YAML/命令行双重配置。核心循环中每次生成一个随机的 (房间尺寸, 混响时间, 麦克风位置, 声源位置) 四元组,调用rir.generate得到冲激响应序列h,用soundfile写为 wav 并登记到output_RIRs/wav.lst。其中nsample=int(fs*RT)使 RIR 长度随混响时间自适应,RT 越大冲激响应越长,晚期混响成分越多。

Step 2:卷积混响与目标截断(step2_gen_reverb_speech.py)

脚本按output_RIRs/wav.lst逐条读取 RIR,对每个 RIR 随机抽取num_wavs_per_RIR条干净语音,执行双路卷积并归一化(详见第二节第 6 点),产物写入output_reverb_speech/reverb/(混响语音)与output_reverb_speech/target/(早期混响目标),同时生成output_reverb_speech/wav.lst供 Step 3 遍历。此处有两个值得注意的断言:语音与 RIR 的采样率必须等于--sample_rate(默认 48000),否则直接报错——这要求你的干净语料与 RIR 保持同一采样率。

Step 3:SNR 混合加噪(step3_add_noise.py + audiolib.py)

step3_add_noise.py使用configparser读取para.cfg的[noisy_speech]节,遍历 Step 2 产出的混响语音,按前述"长度匹配"逻辑截取噪声,再调用 audiolib.py 中的snr_mixer_weak_voice完成混合。该函数与标准snr_mixer的关键差异在于:

  • 功率估计只用"大于均值功率"的样本(pow_clean[pow_clean > avg_pow_clean].mean()),等效于以语音活跃段为基准归一化到 -25 dB FS,避免静音段拉低 RMS;
  • 目标信号使用snr+50的噪声缩放系数叠加极弱噪声,保证目标干净但有微弱底噪;
  • 内含弱语音模拟:当信号长度超过 1 秒且有概率命中时,随机选取 0.1~1.0 s 的片段,将语音与目标乘上 0.1~0.9 的随机增益、噪声乘上 0.01~0.09 的随机衰减,模拟说话人忽远忽近、音量忽大忽小的真实场景,提升训练数据的鲁棒性。

混合后分别写出noisy(混响+噪声)与target(早期混响+微噪)两个目录,并生成output_reverb_noisy_speech/wav.lst记录所有带噪文件。

六、输出目录结构与下游衔接

一次完整运行(run_num=1为例)的产物组织如下:

./data/run1/ ├── output_RIRs/ # Step 1:随机 RIR(wav 与 wav.lst) ├── output_reverb_speech/ # Step 2:reverb/ 混响语音、target/ 早期混响目标、wav.lst └── output_reverb_noisy_speech/ # Step 3:noisy/ 带噪语音、target/ 配对目标、wav.lst

训练模式下,noisy/与target/下同名文件即为一对(noisy, target)监督样本,可直接用于 ClearerVoice-Studio 的语音增强训练。该数据生成模块与训练链路是解耦的:生成完成后,可参照 train/speech_enhancement 的 train.sh 与 solver.py 等既有流程,将产出的列表接入 FRCRN_SE、MossFormer2_SE 或 MossFormerGAN_SE 的数据集配置,即可实现重训或微调。

七、注意事项小结

  1. 采样率一致性:run.sh的sample_rate默认 48000,且step2强制要求干净语音与 RIR 采样率一致(不满足会断言失败),若语料为 16 kHz 需统一调整sample_rate与语料本身;
  2. 目标构造勿用原始干净语音:时延与长度失配会破坏训练对齐,务必使用模块默认的早期混响目标(--target_rt=0.1,可按需增大以保留更多早期反射,如 0.2 s);
  3. 随机性与可复现:test=True时噪声轮转固定、便于评估对比;训练建议保持random_snr=True以覆盖 0~15 dB 的多样化信噪比;
  4. 时长控制:min_audio_length/max_audio_length决定片段长度,total_hours控制总量,小数据冒烟测试可先用仓库自带的 9 条语音与 6 条噪声跑通全流程,再替换为完整语料规模化生成。

通过本模块,你可以快速、低成本地为语音增强模型构建带房间混响与真实噪声的配对训练集,且每个环节(房间仿真、混响卷积、早期混响目标、SNR 混合、弱语音模拟)均可通过配置文件与命令行参数精细调控。

  • 人工智能
  • 语音
  • 音频处理
  • 深度学习

【免费下载链接】ClearerVoice-Studio

An AI-Powered Speech Processing Toolkit and Open Source SOTA Pretrained Models, Supporting Speech Enhancement, Separation, and Target Speaker Extraction, etc.

项目地址:https://gitcode.com/gh_mirrors/cl/ClearerVoice-Studio
点击查看免费下载
上一篇:SteamAutoCrack:三分钟掌握自动化游戏破解的终极指南
下一篇:如何快速批量获取网易云和QQ音乐的LRC歌词?163MusicLyrics完整解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询