如何在numpy的频率范围内产生噪音?

时间:2015-11-26 08:35:06

标签: python numpy signal-processing noise

我有一个主要信号,例如周期为200个样本的窦。

我想为此信号添加噪音。 “噪声信号部分”的周期应在5-30个样本的范围内。

我认为这足以在这个范围内产生多个具有不同随机选择幅度的窦:

noise = np.sin(np.array(range(N))/0.7)*np.random.random(1) + np.sin(np.array(range(N))/1.1)*np.random.random(1) + np.sin(np.array(range(N))/1.5)*np.random.random(1) 

但是这个解决方案对我来说仍然是“确定性的”。

如何随机改变幅度和周期产生噪声?

3 个答案:

答案 0 :(得分:10)

Here您可以找到Aslak Grinsted的matlab代码,创建具有指定功率谱的噪声。它可以很容易地移植到python:

def fftnoise(f):
    f = np.array(f, dtype='complex')
    Np = (len(f) - 1) // 2
    phases = np.random.rand(Np) * 2 * np.pi
    phases = np.cos(phases) + 1j * np.sin(phases)
    f[1:Np+1] *= phases
    f[-1:-1-Np:-1] = np.conj(f[1:Np+1])
    return np.fft.ifft(f).real

你可以像这样使用它:

def band_limited_noise(min_freq, max_freq, samples=1024, samplerate=1):
    freqs = np.abs(np.fft.fftfreq(samples, 1/samplerate))
    f = np.zeros(samples)
    idx = np.where(np.logical_and(freqs>=min_freq, freqs<=max_freq))[0]
    f[idx] = 1
    return fftnoise(f)

就我看来似乎工作似乎。听听你刚刚创造的噪音:

from scipy.io import wavfile

x = band_limited_noise(200, 2000, 44100, 44100)
x = np.int16(x * (2**15 - 1))
wavfile.write("test.wav", 44100, x)

答案 1 :(得分:0)

与其使用幅度不同的多个窦,不如将它们用于随机相位:

def band_limited_noise(min_freq, max_freq, samples=44100, samplerate=44100):

    freqs = np.arange(min_freq, max_freq+1, samples/samplerate)
    phases = np.random.rand(len(freqs))*2*np.pi

    signals = [np.sin(2*np.pi*freq*t + angle) for freq,angle in zip(freqs,angles)]
    signal = reduce(lambda a,b: a+b,signals)
    signal /= np.max(signal)

    return signal

背景:白噪声意味着功率谱包含每个频率,因此,如果您要限制频带的噪声,可以将频带内的每个频率加在一起。噪声部分来自随机相位。由于DFT是离散的,因此您只需要考虑在给定采样率的情况下实际发生的离散频率。

答案 2 :(得分:-1)

产生全光谱白噪声然后对其进行过滤,就像要将房子的墙壁粉刷成白色,因此您决定将整个房子粉刷成白色,然后将除墙壁以外的所有房屋粉刷一遍。是白痴。 (但是在电子方面很有道理。)

我编写了一个小型C程序,该程序可以在任何频率和任何带宽下产生白噪声(例如,在16kHz中心频率和2kHz“宽”频率下)。 不涉及过滤。

我所做的很简单: 在主(无限)循环中,我在中心频率+/-上产生一个正弦波,该正弦波介于-半带宽和+半带宽之间,然后我将该频率保留为任意数量的样本(粒度),这就是结果:

在中心频率为16kHz时2kHz宽的白噪声

White noise 2kHz wide at 16kHz center frequency

伪代码:

while (true)
{

    f = center frequency
    r = random number between -half of bandwidth and + half of bandwidth

<secondary loop (for managing "granularity")>

    for x = 0 to 8 (or 16 or 32....)

    {

        [generate sine Nth value at frequency f+r]

        output = generated Nth value
    }


}