File size: 1,481 Bytes
bbff8a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import numpy as np
from scipy.io.wavfile import read, write
import librosa


def mix_audio(signal_file, noise_file, snr):
    # if the audio is longer than the noise
    # play the noise in repeat for the duration of the audio
    signal_samples,s_rate= librosa.load(signal_file, sr=16000)
    noise_samples, s_rate= librosa.load(noise_file, sr=16000)
    print(signal_samples.shape, noise_samples.shape)

    signal=np.array(signal_samples,dtype=float)
    noise= np.array(noise_samples,dtype=float)

    noise = noise[np.arange(len(signal)) % len(noise)]
    
    # if the audio is shorter than the noi
    # this is important if loading resulted in 
    # uint8 or uint16 types, because it would cause overflow
    # when squaring and calculating mean
    noise = noise.astype(np.float32)
    signal = signal.astype(np.float32)
    
    # get the initial energy for reference
    signal_energy = np.mean(signal**2)
    noise_energy = np.mean(noise**2)
    # calculates the gain to be applied to the noise 
    # to achieve the given SNR
    g = np.sqrt(10.0 ** (-snr/10) * signal_energy / noise_energy)
    
    # Assumes signal and noise to be decorrelated
    # and calculate (a, b) such that energy of 
    # a*signal + b*noise matches the energy of the input signal
    a = np.sqrt(1 / (1 + g**2))
    b = np.sqrt(g**2 / (1 + g**2))
    print(g, a, b)

    monaural= a * signal + b * noise
    write('output.wav', 16000, monaural)


    # mix the signals
    return monaural