我是靠谱客的博主 怕孤单鞋子,最近开发中收集的这篇文章主要介绍python对语音文件加入高斯白噪声(含公式推导)1. 信噪比概念及计算公式2.已知信噪比,如何去产生固定功率的噪声3.完整代码,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

python对语音文件加入高斯白噪声(带公式推导)

  • 1. 信噪比概念及计算公式
  • 2.已知信噪比,如何去产生固定功率的噪声
  • 3.完整代码

1. 信噪比概念及计算公式

信噪比(Signal-to-noise ratio,缩写为 SNR 或 S/N),也称作信杂比或讯杂比。
信噪比,为有用信号功率(Power of Signal)与噪声功率(Power of Noise)的比。因此为幅度(Amplitude)比的平方:
S N R = P s i g n a l P n o i s e = ( A s i g n a l A n o i s e ) 2 SNR=frac{P_{signal}}{P_{noise}}=(frac{A_{signal}}{A_{noise}})^2 SNR=PnoisePsignal=(AnoiseAsignal)2
它的单位一般使用分贝,其值为十倍对数信号与噪声功率比:
S N R = 10 ⋅ l o g 10 P s i g n a l P n o i s e = 10 ⋅ l o g 10 ( A s i g n a l A n o i s e ) 2 = 20 ⋅ l o g 10 ( A s i g n a l A n o i s e ) SNR=10cdot log_{10}frac{P_{signal}}{P_{noise}}=10cdot log_{10}(frac{A_{signal}}{A_{noise}})^2=20cdot log_{10}(frac{A_{signal}}{A_{noise}}) SNR=10log10PnoisePsignal=10log10(AnoiseAsignal)2=20log10(AnoiseAsignal)
公式中的各字母含义如下:


P s i g n a l P_{signal} Psignal:为信号功率(Power of Signal)。
P n o i s e P_{noise} Pnoise:为噪声功率(Power of Noise)。
A s i g n a l A_{signal} Asignal: 为信号幅度(Amplitude of Signal)。
A n o i s e A_{noise} Anoise: 为噪声幅度(Amplitude of Noise)。


2.已知信噪比,如何去产生固定功率的噪声

在我们想要向语音中添加一定信噪比的高斯白噪声,在这时,我们已知以下条件:

1.信噪比(假设我们要生成30dB信噪比的数据);
2.输入语音信号的功率;

我们下一步就是要去生成高斯白噪声,其生成可调用如下:

random_values = np.random.rand(len(voice_data))
#voice_data为我们输入的语音数据

计算语音信号的功率 P s P_s Ps 和生成噪声的功率 P n 1 P_{n1} Pn1 (设其长度均为N):
P s = Σ i = 1 N ( x i ) 2 N P n 1 = Σ i = 1 N ( n i ) 2 N qquad P_s=frac{Σ_{i=1}^{N}(x_i)^2}{N}\qquad\qquad P_{n1}=frac{Σ_{i=1}^{N}(n_i)^2}{N} Ps=NΣi=1N(xi)2Pn1=NΣi=1N(ni)2
需要注意的是,此时我们生成的白噪声,其与语音信号的信噪比肯定不是我们需求的30dB,也就是说我们需要对噪声数据都乘一个数值k,使其功率满足我们的要求,那这个k值又该如何求解呢?
30 d B = 10 ⋅ l o g 10 P s P n 30dB=10cdot log_{10}frac{P_s}{P_n} 30dB=10log10PnPs
对上式整理可得:其中 P n P_n Pn 为我们最终需要的高斯白噪声的功率:
P n = P s 1 0 3 = Σ i = 1 N ( k ⋅ n i ) 2 N = ( k n 1 ) 2 + ( k n 2 ) 2 + ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ + ( k n N ) 2 N = k 2 ( n 1 2 + n 2 2 + ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ + n N 2 ) N = k 2 ⋅ P n 1 P_n=frac{P_s}{10^3}\qquad\= frac{Σ_{i=1}^{N}(kcdot n_i)^2}{N}\qquad\= frac{(kn_1)^2+(kn_2)^2+cdotcdotcdotcdotcdotcdot+(kn_N)^2}{N}\qquad\= frac{k^2(n_1^2+n_2^2+cdotcdotcdotcdotcdotcdot+n_N^2)}{N}\qquad\=k^2cdot P_{n1} Pn=103Ps=NΣi=1N(kni)2=N(kn1)2+(kn2)2++(knN)2=Nk2(n12+n22++nN2)=k2Pn1
对上边推导的式子进行整理,则有:
k 2 ⋅ P n 1 = P s 1 0 3 k = P s 1 0 3 ⋅ P n 1 k = P s 1 0 S N R 10 ⋅ P n 1 k^2cdot P_{n1}=frac{P_s}{10^3}\qquad\k=sqrt{frac{P_s}{10^3cdot P_{n1}}}\qquad\k=sqrt{frac{P_s}{{10^{frac{SNR}{10}}}cdot P_{n1}}} k2Pn1=103Psk=103Pn1Ps k=1010SNRPn1Ps
求出这个k值之后,我们便可以对我们之前生成的噪声数据都乘这个数值k

random_values_we_need=random_values*k
#将我们的噪声数据都乘 k

然后将我们噪声数据与原始语音数据相加可得叠加噪声后的数据。

3.完整代码

import soundfile as sf
import math
import librosa
import numpy as np


def add_noise(audio_path, noise_path,out_path, SNR, sr=16000):
    #读取语音文件data和fs
    src, sr = librosa.core.load(audio_path, sr=sr)
    #
    random_values = np.random.rand(len(src))
    #计算语音信号功率Ps和噪声功率Pn1
    Ps = np.sum(src ** 2) / len(src)
    Pn1 = np.sum(random_values ** 2) / len(random_values)

    # 计算k值
    k=math.sqrt(Ps/(10**(SNR/10)*Pn1))
    #将噪声数据乘以k,
    random_values_we_need=random_values*k
    #计算新的噪声数据的功率
    Pn=np.sum(random_values_we_need**2)/len(random_values_we_need)
    #以下开始计算信噪比
    snr=10*math.log10(Ps/Pn)
    print("当前信噪比:",snr)

    #单独将噪音数据写入文件
    sf.write(noise_path,random_values_we_need, sr)
    #将噪声数据叠加到纯净音频上去
    outdata=src+random_values_we_need
    # 将叠加噪声的数据写入文件
    sf.write(out_path, outdata, sr)


def main():

    filename='./splits/train/京_0.wav'
    #纯净语音文件路径
    noisename='noise.wav'
    #产生的噪声数据路径
    outname='add_noise.wav'
    #叠加了噪声后的数据
    SNR=-5
    #选定信噪比
    add_noise(filename,noisename,outname,SNR)
    #调用函数,直接生成数据


if __name__=="__main__":
    main()

最后

以上就是怕孤单鞋子为你收集整理的python对语音文件加入高斯白噪声(含公式推导)1. 信噪比概念及计算公式2.已知信噪比,如何去产生固定功率的噪声3.完整代码的全部内容,希望文章能够帮你解决python对语音文件加入高斯白噪声(含公式推导)1. 信噪比概念及计算公式2.已知信噪比,如何去产生固定功率的噪声3.完整代码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部