利用纯净语音和噪声合成不同信噪比的训练数据

如题,这应该算是我前往语音这座大山的第一步,在此做出记录。

一、工作背景

  由于需要进行单通道降噪的实验,但是现在只有纯净语音和噪声数据,而在阅读文章的过程中,大家并没有将这个细小的内容写道论文中(的确也不应该,做出来之后确实感觉蛮简单的),所以只能自己通过纯净语音和噪声合成自己需要的数据。

二、数据生成

  需要复现的实验是基于单通道的语音增强,同时根据张晖老师博士学位论文,在合成数据时使用TIMIT语料库的核心训练集中的1000局作为训练用的目标语音。再将这些语音与各种噪声相混合(四种噪声随机一种),从NOISE-92中选取四种噪声:嘈杂噪声(babble noise)、工厂噪声(factory1)、驱动舰动力室噪声(destroyerops)和驱逐舰发动机噪声(destroyerengine)。
  每种噪声3分55秒,将每种噪声的前50%为训练集混合使用,后50%为测试集混合使用,这样训练出的模型应该会有较好的泛化性。混合过程中分别使用-5dB、0dB作为信噪比进行混合。


2.1 计算公式

  首先我们对于公式进行解释:
(2.1) S N R ( s ( t ) , n ( t ) ) = 10 ⋅ l o g 10 ∑ t s 2 ( t ) ∑ t n 2 ( t ) SNR(s(t),n(t))=10·log_{10}{\frac {\sum_t s^2(t)}{\sum_t n^2(t)}} \tag{2.1} SNR(s(t),n(t))=10log10tn2(t)ts2(t)(2.1)

  • S N R SNR SNR为信噪比,单位为dB
  • ∑ t s 2 ( t ) \sum_ts^2(t) ts2(t)为纯净语音能量
  • ∑ t n 2 ( t ) {\sum_t n^2(t)} tn2(t)为噪声能量
      为了合成特定信噪比的混合语音,我们需要对噪声能量进行调整,如:如需要q dB混合语音,调整噪声能量的大小为原来的 α \alpha α倍,即新的噪声信号为 α n ( t ) \alpha n(t) αn(t),新的公式为:
    (2.2) q = 10 ⋅ l o g 10 ∑ t s 2 ( t ) α 2 ∑ t n 2 ( t ) q=10·log_{10}{\frac {\sum_t s^2(t)}{ \alpha^2 \sum_t n^2(t)}} \tag{2.2} q=10log10α2tn2(t)ts2(t)(2.2)
      根据(2.2)可以推出:
    (2.3) α = ∑ t s 2 ( t ) 1 0 q 10 ∑ t n 2 ( t ) \alpha = \sqrt{\frac {\sum_t s^2(t)}{10^{\frac{q}{10}}\sum_t n^2(t)}} \tag{2.3} α=1010qtn2(t)ts2(t) (2.3)

2.2 数据准备

  噪声数据:
噪声数据
可以看到,babble.wav是噪声的原始文件,babble_test.wav为babble.wav后50%切片,babble_train.wav为babble.wav为噪声的前50%切片,其它同理。
切片实现:

from scipy.io import wavfile
import numpy as np
import soundfile as sf

sample_rate, sig = wavfile.read('D:/毕设数据/noise/factory1.wav')
# 采样率:1S内对声音信号的采样次数
# print("采样率: %d" % sample_rate)
# print(sig.shape)
# print(sig)
# 
# if sig.dtype == np.int16:
#     print("PCM16位整形")


half = sig.shape[0]/2
data_train = sig[:int(half)]
data_test = sig[int(half):]

sf.write('D:/毕设数据/noise/factory1_train.wav', data_train, sample_rate)
sf.write('D:/毕设数据/noise/factory1_test.wav', data_test, sample_rate)

2.3 数据合成
import numpy as np
import soundfile as sf
import librosa
import random
import os

sound_name = 'SI'


def switch(item):
    switcher = {
        0: 'babble',
        1: 'destroyerengine',
        2: 'destroyerops',
        3: 'factory1'
    }
    return switcher.get(item)


files = os.listdir('D:/毕设数据/TIMIT-TRAIN')

# 噪音的id
# [)
for i in range(0, 1000):

    # 随机噪声类型
    n_id = random.randint(0, 3)
    n_name = switch(n_id)
    # 原始语音
    a, a_sr = librosa.load('D:/毕设数据/TIMIT-TRAIN/' + files[i], sr=16000)
    # 噪音
    b, b_sr = librosa.load('D:/毕设数据/noise/' + n_name + '_train' + '.wav', sr=16000)
    # 随机取一段噪声,保证长度和纯净语音长度一致,保证不会越界
    start = random.randint(0, b.shape[0] - a.shape[0])
    # 切片
    n_b = b[int(start):int(start)+a.shape[0]]
    
    # 平方求和
    sum_s = np.sum(a ** 2)
    sum_n = np.sum(n_b ** 2)
    # 信噪比为-5dB时的权重
    x = np.sqrt(sum_s/(sum_n * pow(10, -0.5)))

    noise = x * n_b
    target = a + noise
    sf.write('D:/毕设数据/train_data/-5dB/mix_sound/' + files[i].split('.')[0] + '_' + n_name + '.wav', target, 16000)
    sf.write('D:/毕设数据/train_data/-5dB/sound/' + files[i].split('.')[0] + '.wav', a, 16000)
    sf.write('D:/毕设数据/train_data/-5dB/noise/' + files[i].split('.')[0] + '_' + n_name + '_train' + '.wav', noise, 16000)
2.4 合成结果

混合语音合成结果:
合成结果
噪声使用情况:
噪声使用情况
纯净语音:
纯净语音

三、数据集

评论 51
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值