Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
| Download

📚 The CoCalc Library - books, templates and other resources

Views: 96178
License: OTHER
Kernel: Python 2

ThinkDSP

This notebook contains code examples from Chapter 4: Noise

Copyright 2015 Allen Downey

License: Creative Commons Attribution 4.0 International

from __future__ import print_function, division %matplotlib inline import warnings warnings.filterwarnings('ignore') import thinkdsp import thinkplot import thinkstats2 import numpy as np from ipywidgets import interact, interactive, fixed import ipywidgets as widgets
thinkdsp.random_seed(17)

The simplest noise to generate is uncorrelated uniform (UU) noise:

signal = thinkdsp.UncorrelatedUniformNoise() wave = signal.make_wave(duration=0.5, framerate=11025) wave.make_audio()

Here's what a segment of it looks like:

segment = wave.segment(duration=0.1) segment.plot(linewidth=1) thinkplot.config(xlabel='time', ylabel='amplitude', ylim=[-1.05, 1.05], legend=False)
Image in a Jupyter notebook

And here's the spectrum:

spectrum = wave.make_spectrum() spectrum.plot(linewidth=0.5) thinkplot.config(xlabel='frequency (Hz)', ylabel='amplitude', xlim=[0, spectrum.fs[-1]])
Image in a Jupyter notebook

In the context of noise it is more conventional to look at the spectrum of power, which is the square of amplitude:

spectrum.plot_power(linewidth=0.5) thinkplot.config(xlabel='frequency (Hz)', ylabel='power', xlim=[0, spectrum.fs[-1]])
Image in a Jupyter notebook

UU noise has the same power at all frequencies, on average, which we can confirm by looking at the normalized cumulative sum of power, which I call an integrated spectrum:

integ = spectrum.make_integrated_spectrum() integ.plot_power() thinkplot.config(xlabel='frequency (Hz)', ylabel='cumulative power', xlim=[0, spectrum.fs[-1]])
Image in a Jupyter notebook

A straight line in this figure indicates that UU noise has equal power at all frequencies, on average. By analogy with light, noise with this property is called "white noise".

Brownian noise

Brownian noise is generated by adding up a sequence of random steps.

signal = thinkdsp.BrownianNoise() wave = signal.make_wave(duration=0.5, framerate=11025) wave.make_audio()

The sound is less bright, or more muffled, than white noise.

Here's what the wave looks like:

wave.plot(linewidth=1) thinkplot.config(xlabel='time', ylabel='amplitude', ylim=[-1.05, 1.05])
Image in a Jupyter notebook

Here's what the power spectrum looks like on a linear scale.

spectrum = wave.make_spectrum() spectrum.plot_power(linewidth=0.5) thinkplot.config(xlabel='frequency (Hz)', ylabel='power', xlim=[0, spectrum.fs[-1]])
Image in a Jupyter notebook

So much of the energy is at low frequencies, we can't even see the high frequencies.

We can get a better view by plotting the power spectrum on a log-log scale.

# The f=0 component is very small, so on a log scale # it's very negative. If we clobber it before plotting, # we can see the rest of the spectrum better. spectrum.hs[0] = 0 spectrum.plot_power(linewidth=0.5) thinkplot.config(xlabel='frequency (Hz)', ylabel='power', xscale='log', yscale='log', xlim=[0, spectrum.fs[-1]])
Image in a Jupyter notebook

Now the relationship between power and frequency is clearer. The slope of this line is approximately -2, which indicates that P=K/f2P = K / f^2, for some constant KK.

signal = thinkdsp.BrownianNoise() wave = signal.make_wave(duration=0.5, framerate=11025) spectrum = wave.make_spectrum() result = spectrum.estimate_slope() result.slope
-1.771642032005627

The estimated slope of the line is closer to -1.8 than -2, for reasons we'll see later.

Pink noise

Pink noise is characterized by a parameter, β\beta, usually between 0 and 2. You can hear the differences below.

With β=0\beta=0, we get white noise:

signal = thinkdsp.PinkNoise(beta=0) wave = signal.make_wave(duration=0.5) wave.make_audio()

With β=1\beta=1, pink noise has the relationship P=K/fP = K / f, which is why it is also called 1/f1/f noise.

signal = thinkdsp.PinkNoise(beta=1) wave = signal.make_wave(duration=0.5) wave.make_audio()

With β=2\beta=2, we get Brownian (aka red) noise.

signal = thinkdsp.PinkNoise(beta=2) wave = signal.make_wave(duration=0.5) wave.make_audio()

The following figure shows the power spectrums for white, pink, and red noise on a log-log scale.

colors = ['#9ecae1', '#4292c6', '#2171b5'] betas = [0, 1, 2] for beta, color in zip(betas, colors): signal = thinkdsp.PinkNoise(beta=beta) wave = signal.make_wave(duration=0.5, framerate=1024) spectrum = wave.make_spectrum() spectrum.hs[0] = 0 spectrum.plot_power(linewidth=1, color=color) thinkplot.config(xlabel='frequency (Hz)', ylabel='power', xscale='log', yscale='log', xlim=[0, spectrum.fs[-1]])
Image in a Jupyter notebook

Uncorrelated Gaussian noise

An alternative to UU noise is uncorrelated Gaussian (UG noise).

signal = thinkdsp.UncorrelatedGaussianNoise() wave = signal.make_wave(duration=0.5, framerate=11025) wave.plot(linewidth=0.5) thinkplot.config(xlabel='time', ylabel='amplitude')
Image in a Jupyter notebook

The spectrum of UG noise is also UG noise.

spectrum = wave.make_spectrum() spectrum.plot_power(linewidth=1) thinkplot.config(xlabel='frequency (Hz)', ylabel='power', xlim=[0, spectrum.fs[-1]])
Image in a Jupyter notebook

We can use a normal probability plot to test the distribution of the power spectrum.

from thinkstats2 import NormalProbabilityPlot NormalProbabilityPlot(spectrum.real, label='real part') thinkplot.config(xlabel='normal sample', ylabel='power', ylim=[-250, 250], legend=True, loc='lower right')
Image in a Jupyter notebook

A straight line on a normal probability plot indicates that the distribution of the real part of the spectrum is Gaussian.

NormalProbabilityPlot(spectrum.imag, label='imag part') thinkplot.config(xlabel='normal sample', ylabel='power', ylim=[-250, 250], legend=True, loc='lower right')
Image in a Jupyter notebook

And so is the imaginary part.