ThinkDSP
This notebook contains code examples from Chapter 1: Sounds and Signals
Copyright 2015 Allen Downey
Signals
Here are the modules we'll need.
thinkdsp
is a module that accompanies Think DSP and provides classes and functions for working with signals.thinkplot
is a wrapper around matplotlib.
Instantiate cosine and sine signals.
Plot the sine and cosine signals. By default, plot
plots three periods.
Notice that the frequency of the sine signal is doubled, so the period is halved.
The sum of two signals is a SumSignal.
Here's the documentation for thinkdsp.py
: http://greenteapress.com/thinkdsp/thinkdsp.html
Waves
A Signal represents a mathematical function defined for all values of time. If you evaluate a signal at a sequence of equally-spaced times, the result is a Wave. framerate
is the number of samples per second.
IPython provides an Audio widget that can play a wave.
Wave also provides make_audio()
, which does the same thing:
The ys
attribute is a NumPy array that contains the values from the signal. The interval between samples is the inverse of the framerate.
Signal objects that represent periodic signals have a period
attribute.
Wave provides segment
, which creates a new wave. So we can pull out a 3 period segment of this wave.
Wave provides plot
normalize
scales a wave so the range doesn't exceed -1 to 1.
apodize
tapers the beginning and end of the wave so it doesn't click when you play it.
You can write a wave to a WAV file.
wave.write
writes the wave to a file so it can be used by an exernal player.
read_wave
reads WAV files. The WAV examples in the book are from freesound.org. In the contributors section of the book, I list and thank the people who uploaded the sounds I use.
I pulled out a segment of this recording where the pitch is constant. When we plot the segment, we can't see the waveform clearly, but we can see the "envelope", which tracks the change in amplitude during the segment.
Spectrums
Wave provides make_spectrum
, which computes the spectrum of the wave.
Spectrum provides plot
The frequency components above 10 kHz are small. We can see the lower frequencies more clearly by providing an upper bound:
Spectrum provides low_pass
, which applies a low pass filter; that is, it attenuates all frequency components above a cutoff frequency.
The result is a spectrum with fewer components.
We can convert the filtered spectrum back to a wave:
And then normalize it to the range -1 to 1.
Before playing it back, I'll apodize it (to avoid clicks).
And I'll do the same with the original segment.
Finally, we can listen to the original segment and the filtered version.
The original sounds more complex, with some high-frequency components that sound buzzy. The filtered version sounds more like a pure tone, with a more muffled quality. The cutoff frequency I chose, 3000 Hz, is similar to the quality of a telephone line, so this example simulates the sound of a violin recording played over a telephone.
Exercise 1: Run the code in the following cells to create a Signal
with two frequency components, and then create a Wave
that contains a half-second sample from the Signal
.
Add code to compute and plot the Spectrum
of this Wave
.
Then add another Signal
to the mix, recompute the Wave
and look at the Spectrum
.
Interaction
The following example shows how to use interactive IPython widgets.
Adjust the sliders to control the start and duration of the segment and the cutoff frequency applied to the spectrum.