Open In Colab 要在GitHub上执行或查看/下载此笔记本

环境腐败

在实际的语音处理场景中,麦克风捕捉到的信号经常被不需要的元素所破坏,例如噪声混响。这一挑战在远场(远距离)情况下尤为明显,其中说话者和参考麦克风之间的距离相当远。这种情况的例子包括由Google Home、Amazon Echo、Kinect等流行设备录制的信号。

在神经语音处理中的一个常见策略是从干净的语音录音开始,然后人为地引入噪声和混响来模拟现实世界中的条件。这个过程被称为环境破坏语音污染

从干净的信号开始,可以控制引入各种类型的噪声和混响,使环境干扰成为一种有效的正则化技术。这种正则化有助于神经网络在测试期间暴露于现实世界的嘈杂条件时更好地泛化。

环境腐败过程将干净的信号\(x[n]\)通过以下方程转换为带有噪声和混响的信号:

\(y[n] = x[n] * h[n] + n[n]\)

其中 \(n[n]\) 表示噪声序列,而 \(h[n]\) 是引入混响效果的脉冲响应。

在接下来的部分中,我们将深入探讨如何进行这种转换。在此之前,让我们下载一些在本教程的其余部分中必不可少的信号。

%%capture
!wget https://www.dropbox.com/s/vwv8xdr7l3b2tta/noise_sig.csv
!wget https://www.dropbox.com/s/aleer424jumcs08/noise2.wav
!wget https://www.dropbox.com/s/eoxxi2ezr8owk8a/noise3.wav
!wget https://www.dropbox.com/s/pjnub2s5hql2vxs/rir1.wav
!wget https://www.dropbox.com/s/nyno6bqbmiy2rv8/rirs.csv
!wget https://www.dropbox.com/s/u8qyvuyie2op286/spk1_snt1.wav
%%capture
# Installing SpeechBrain
BRANCH = 'develop'
!git clone https://github.com/speechbrain/speechbrain.git -b $BRANCH
%cd /content/speechbrain/
!python -m pip install .

一个干净的语音信号看起来像这样:

import matplotlib.pyplot as plt
from speechbrain.dataio.dataio import read_audio
from IPython.display import Audio

clean = read_audio('/content/spk1_snt1.wav').squeeze()

# Plots
plt.subplot(211)
plt.plot(clean)
plt.xlabel('Time')

plt.subplot(212)
plt.specgram(clean,Fs=16000)
plt.xlabel('Time')
plt.ylabel('Frequency')

Audio(clean, rate=16000)

1. 加性噪声

在SpeechBrain中,我们设计了一个能够用噪声污染语音信号的类(speechbrain.augment.time_domanin.AddNoise)。这个类接收一个CSV文件作为输入,该文件列举了一系列噪声信号:

ID, duration, wav, wav_format, wav_opts
noise2, 5.0, noise2.wav, wav,
noise3, 1.0, noise3.wav, wav,

当调用时,AddNoise 从这个噪声集合中采样,并以随机的信噪比(SNR)将选定的噪声添加到干净信号中。

import torch
from speechbrain.augment.time_domain import AddNoise

noisifier = AddNoise('tests/samples/annotation/noise.csv', replacements={'noise_folder': 'tests/samples/noise'})
noisy = noisifier(clean.unsqueeze(0), torch.ones(1))

# Plots
plt.subplot(211)
plt.plot(noisy.squeeze())
plt.xlabel('Time')

plt.subplot(212)
plt.specgram(noisy.squeeze(),Fs=16000)
plt.xlabel('Time')
plt.ylabel('Frequency')

Audio(noisy.squeeze(0), rate=16000)

噪声的量可以通过定义SNR采样范围的snr_lowsnr_high参数进行调整。长度向量是必需的,因为我们可以并行处理不同长度的信号批次。长度向量包含批次中每个句子的相对长度(例如,对于两个示例,我们可以有长度=[0.8 1.0],其中1.0是批次中最长句子的长度)。

2. 混响

在房间内说话时,我们的语音信号会被墙壁、地板、天花板以及声学环境中的物体多次反射。因此,远距离麦克风记录的最终信号将包含原始信号的多个延迟副本。所有这些副本相互干扰,并显著影响语音信号的清晰度。

这种多路径传播被称为混响。在给定的房间内,源和接收器之间的混响通过脉冲响应来建模:

rir = read_audio('/content/rir1.wav')

# Impulse response
plt.subplot(211)
plt.plot(rir[0:8000])
plt.xlabel('Time')
plt.ylabel('h(t)')

# Zoom on early reflections
plt.subplot(212)
plt.plot(rir[2150:2500])
plt.xlabel('Time')
plt.ylabel('h(t)')

脉冲响应是声音从源到接收器传播过程中所经历变化的完整描述。特别是,脉冲响应中的每个峰值对应于到达接收器的副本。第一个峰值对应于直接路径。然后,我们可以看到墙壁、天花板、地板上的一阶反射(见第二张图)。

全球范围内,脉冲响应遵循指数衰减。这种衰减在低混响时间的干燥房间中更快,而在大而空旷的环境中则较慢。

通过在干净信号和脉冲响应之间执行卷积来添加混响。在SpeechBrain中,此操作由speechbrain.processing.speech_augmentation.AddReverb执行。

当调用时,AddRev 从给定的csv文件中采样一个脉冲响应:

ID, duration, wav, wav_format, wav_opts
rir1, 1.0, rir1.wav, wav,
....
from speechbrain.augment.time_domain import AddReverb

reverb = AddReverb('tests/samples/annotation/RIRs.csv', replacements={'rir_folder': 'tests/samples/RIRs'})
reverbed = reverb(clean)

# Plots
plt.subplot(211)
plt.plot(reverbed.squeeze())
plt.xlabel('Time')

plt.subplot(212)
plt.specgram(reverbed.squeeze(),Fs=16000)
plt.xlabel('Time')
plt.ylabel('Frequency')

Audio(reverbed.squeeze(0), rate=16000)

混响是一种卷积噪声,它在时间上“平滑”信号(参见在干净信号中原本静音的区域出现的长尾)和频域。

混响的量由参数rir_scale_factor控制。如果rir_scale_factor < 1,脉冲响应会被压缩(混响减少),而如果rir_scale_factor > 1,脉冲响应会被扩展(混响增加)。请随意在前面的示例中尝试它!

参考文献

[1] M. Ravanelli, P. Svaizer, M. Omologo, “用于远场语音识别的真实多麦克风数据模拟”, 发表于2016年Interspeech会议 ArXiv

[2] M. Ravanelli, M. Omologo, “用于鲁棒DNN-HMM远场语音识别的污染语音训练方法”,发表于INTERSPEECH 2015会议论文集。 ArXiv

[3] M. Ravanelli, M. Omologo, “关于基于受污染语音训练的远场语音识别中脉冲响应的选择”,发表于 INTERSPEECH 2014 会议论文集。 ArXiv

[4] M. Ravanelli, A. Sosi, P. Svaizer, M.Omologo, “在混响环境中用于鲁棒语音识别的脉冲响应估计”,在欧洲信号处理会议(EUSIPCO 2012)的会议录中。ArXiv

引用SpeechBrain

如果您在研究中或业务中使用SpeechBrain,请使用以下BibTeX条目引用它:

@misc{speechbrainV1,
  title={Open-Source Conversational AI with {SpeechBrain} 1.0},
  author={Mirco Ravanelli and Titouan Parcollet and Adel Moumen and Sylvain de Langen and Cem Subakan and Peter Plantinga and Yingzhi Wang and Pooneh Mousavi and Luca Della Libera and Artem Ploujnikov and Francesco Paissan and Davide Borra and Salah Zaiem and Zeyu Zhao and Shucong Zhang and Georgios Karakasidis and Sung-Lin Yeh and Pierre Champion and Aku Rouhe and Rudolf Braun and Florian Mai and Juan Zuluaga-Gomez and Seyed Mahed Mousavi and Andreas Nautsch and Xuechen Liu and Sangeet Sagar and Jarod Duret and Salima Mdhaffar and Gaelle Laperriere and Mickael Rouvier and Renato De Mori and Yannick Esteve},
  year={2024},
  eprint={2407.00463},
  archivePrefix={arXiv},
  primaryClass={cs.LG},
  url={https://arxiv.org/abs/2407.00463},
}
@misc{speechbrain,
  title={{SpeechBrain}: A General-Purpose Speech Toolkit},
  author={Mirco Ravanelli and Titouan Parcollet and Peter Plantinga and Aku Rouhe and Samuele Cornell and Loren Lugosch and Cem Subakan and Nauman Dawalatabad and Abdelwahab Heba and Jianyuan Zhong and Ju-Chieh Chou and Sung-Lin Yeh and Szu-Wei Fu and Chien-Feng Liao and Elena Rastorgueva and François Grondin and William Aris and Hwidong Na and Yan Gao and Renato De Mori and Yoshua Bengio},
  year={2021},
  eprint={2106.04624},
  archivePrefix={arXiv},
  primaryClass={eess.AS},
  note={arXiv:2106.04624}
}