Ключевым фактом является то, что (это математика, а не код)
SNR = mean(s) / std(n)
Умножение шума на некоторую константу A
приводит к новому SNR - SNR_new
mean(s) / std(A*n)
= mean(s) / (A * std(n))
= (1 / A) * (mean(s) / std(n))
= SNR / A
= SNR_new
Итак, работая в обратном направлении, я думаю, это правильный подход в python:
def add_noise(signal, snr):
'''
signal: np.ndarray
snr: float
returns -> np.ndarray
'''
# Generate the noise as you did
noise = acoustics.generator.white(signal.size).reshape(*signal.shape)
# For the record I think np.random.random does exactly the same thing
# work out the current SNR
current_snr = np.mean(signal) / np.std(noise)
# scale the noise by the snr ratios (smaller noise <=> larger snr)
noise *= (current_snr / snr)
# return the new signal with noise
return signal + noise