3
$\begingroup$

(Questions after code block.)

For now, I am generating the sinusoid and the noise separately and then normalising the amplitude so I can write the signal to a .wav file (16-bit, 16kHz).

def genSine(f0,fs,dur):
    sinusoid = []
    for t in range(dur):
        sinusoid.append(math.sin(2*math.pi*t(*freq/fs)))
    sinusoid = normalise(sinusoid)
    return sinusoid

def genNoise(dur):
    noise = np.random.normal(0,1,dur))
    noise = normalise(noise)
    return noise

def normalise(x,MAX_INT16):
    maxamp = max(x)
    amp = floor(MAX_INT16/maxamp)
    norm = np.zeros(len(x))
    for i in range(len(x)):
        norm[i] = amp*x[i]
    return norm

def writeWav(w):
    # audiophilic magic

if __name__ == '__main__':
    f0 = 440
    fs = 16000
    dur = 1*fs                      #seconds
    MAX_INT16 = 32767
    sinusoid = genSine(f0,fs,dur)
    noise = genNoise(dur)
    sum = x + y
    sum = normalise(sum,MAX_INT16)
    writeWav(sum)
  1. Is there a more efficient way to sum the two signals (sine + noise), perhaps bypassing/incorporating the normalisation step (it is currently called three times, in genSine, genNoise and main)?

  2. How can I ensure set the amplitude ratio between the sine and noise signals?

I'm new to Python and stackexchange so any help is appreciated!

$\endgroup$
1
$\begingroup$

The are some ways to improve your solution.

First, use numpy and vectorize your code:

def genSine(f0,fs,dur):
    sinusoid = []
    for t in range(dur):
        sinusoid.append(math.sin(2*math.pi*t(*freq/fs)))
    sinusoid = normalise(sinusoid)
    return sinusoid

becomes

import numpy as np
def genSine(f0, fs, dur):
    t = np.arange(dur)
    sinusoid = np.sin(2*np.pi*t*(f0/fs))
    sinusoid = normalise(sinusoid)
    return sinusoid

You will see the biggest improvment in efficiency when vectorizing all your code like this.

Second, concerning the normalization, you should consider the mathematics of your problem instead of doing it 3 times. You have 3 pieces of signal, the sinusoid, the noise, the mix. The first is already normalized (between -1 and 1), the second also (hence the name normal distribution for describing the noise). So you should only normalize the third.

Hope this helps!

$\endgroup$
  • $\begingroup$ Actually, the normal distribution leads to a signal with Gaussian distribution that has unit variance. The amplitude of the signal is not restricted to a maximum. $\endgroup$ – Brian Aug 14 '15 at 20:00
  • $\begingroup$ I said normalized, not bounded - for clarity let's not confuse different norm definitions. I do not see how that desserves a down vote, anyway :-) $\endgroup$ – meduz Aug 28 '15 at 15:07
  • $\begingroup$ Not my downvote :-) $\endgroup$ – Brian Aug 28 '15 at 19:07
  • $\begingroup$ Thanks meduz! I had a feeling it was something essential like numpy... (Not my downvote either, btw) $\endgroup$ – yunque Sep 1 '15 at 10:12
  • $\begingroup$ why isn't there something like awgn (mathworks.com/help/comm/ref/awgn.html) in python? $\endgroup$ – Charlie Parker Oct 12 '16 at 5:01

protected by jojek Aug 25 '15 at 9:47

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.