Generating a noisy sine wave in Python, efficiently (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)



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)?
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!
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!