首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Python中的Soundfile将具有指定SNR的高斯噪声添加到音频文件中?

如何使用Python中的Soundfile将具有指定SNR的高斯噪声添加到音频文件中?
EN

Stack Overflow用户
提问于 2019-10-17 05:28:56
回答 1查看 1.8K关注 0票数 1
代码语言:javascript
复制
    print('Processing: ', filepath)
    path, file = os.path.split(filepath)
    noisy_path = path.replace('dev-clean', 'dev-noise-gassian')
    print(path, file)
    if not os.path.exists(noisy_path):
        os.makedirs(noisy_path)

    noisy_filepath = os.path.join(noisy_path, file)
    audio_signal, samplerate = sf.read(filepath)
    noise = np.random.normal(0, 0.1, audio_signal.shape[0])

    noisy_signal = audio_signal + noise

    print(audio_signal)
    print(noisy_signal)
    sf.write(noisy_filepath, noisy_signal, samplerate)

    quit()

这就是我正在做的,它增加了噪声,但我不知道噪声的信噪比是多少。如何校准添加的噪声以匹配指定的SNR?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-19 21:57:36

首先,一些theory

您可以通过将信号的平均功率除以噪声的平均功率来计算SNR。

对于任何给定的信号,您可以使用其power spectral density来估计其平均功率。简而言之,它是FFT的平均振幅。

下面是一个使用numpy FFT的工作示例:

代码语言:javascript
复制
import numpy as np
import soundfile as sf


sampling_rate = 42000 #42kHz sampling rate is enough for audio
Nsamples = 100000 # a bit more than 2 seconds of signal at the current sampling rate
freq = 440 # musical A
A = 5
noiseAmplitude = 5
noiseSigma = 0.1

noise = noiseAmplitude * np.random.normal(0, noiseSigma, Nsamples)

# Generate a pure sound sampled at our sampling_rate for a duration of roughly 2s
cleanSound = A*np.sin(2*np.pi*freq/sampling_rate*np.arange(Nsamples))

sampleSound = cleanSound + noise

# For a pure sine and a white noise, the theoretical SNR in dB is:
theoreticalSNR = 20*np.log10(A/(np.sqrt(2)*noiseAmplitude*noiseSigma)) # the sqrt of 2 is because of root-mean square amplitude

## Experimental measurement using FFT (we use sampling_rate//2 points for Nyquist)
# power spectrum of the clean sound (averaged spectral density)
cleanPS = np.sum(np.abs(np.fft.fft(cleanSound,sampling_rate//2)/Nsamples)**2)

# same for noise
noisePS = np.sum(np.abs(np.fft.fft(noise,sampling_rate//2)/Nsamples)**2)

# 10 instead of 20 because we're using power instead of RMS amplitude
measuredSNR = 10*np.log10(cleanPS/noisePS)

# write to output sound file
sf.write('/tmp/sample.wav',sampleSound,sampling_rate)

有了上面的值,我得到了16.989 dB的理论信噪比和16.946 dB的实测信噪比。因此,如果您想要将具有给定SNR的白噪声添加到任何给定的音频信号,您可以通过颠倒公式SNR = 10*np.log10(cleanPS/noisePS)来计算白噪声功率,并相应地选择noiseAmplitude和noiseSigma。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58421942

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档