如何将具有指定 SNR 的高斯噪声添加到 Soundfile in Python 的音频文件中?
How can I add gaussian noise with a specified SNR to an audio file with Soundfile in Python?
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?
谢谢
首先,一些theory:
您可以用信号的平均功率除以噪声的平均功率来计算 SNR。
对于任何给定的信号,您可以使用其 power spectral density 来估算其平均功率。简而言之,它是其FFT的平均幅度。
这是一个使用 numpy FFT 的工作示例:
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 的理论 SNR 和 16.946 dB 的测量 SNR。
因此,如果您想将具有给定 SNR 的白噪声添加到任何给定的音频信号,您可以通过反转公式计算白噪声功率:SNR = 10*np.log10(cleanPS/noisePS)
并相应地选择 noiseAmplitude 和 noiseSigma。
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?
谢谢
首先,一些theory:
您可以用信号的平均功率除以噪声的平均功率来计算 SNR。
对于任何给定的信号,您可以使用其 power spectral density 来估算其平均功率。简而言之,它是其FFT的平均幅度。
这是一个使用 numpy FFT 的工作示例:
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 的理论 SNR 和 16.946 dB 的测量 SNR。
因此,如果您想将具有给定 SNR 的白噪声添加到任何给定的音频信号,您可以通过反转公式计算白噪声功率:SNR = 10*np.log10(cleanPS/noisePS)
并相应地选择 noiseAmplitude 和 noiseSigma。