概述
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=10⋅log10PnoisePsignal=10⋅log10(AnoiseAsignal)2=20⋅log10(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=10⋅log10PnPs
对上式整理可得:其中
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(k⋅ni)2=N(kn1)2+(kn2)2+⋅⋅⋅⋅⋅⋅+(knN)2=Nk2(n12+n22+⋅⋅⋅⋅⋅⋅+nN2)=k2⋅Pn1
对上边推导的式子进行整理,则有:
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}}}
k2⋅Pn1=103Psk=103⋅Pn1Psk=1010SNR⋅Pn1Ps
求出这个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.完整代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复