Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
| Download

📚 The CoCalc Library - books, templates and other resources

Views: 96177
License: OTHER
Kernel: Python 3

ThinkDSP

This notebook contains code examples from Chapter 2: Harmonics

Copyright 2015 Allen Downey

License: Creative Commons Attribution 4.0 International

from __future__ import print_function, division %matplotlib inline import thinkdsp import thinkplot from ipywidgets import interact, interactive, fixed import ipywidgets as widgets from IPython.display import display

Waveforms and harmonics

Create a triangle signal and plot a 3 period segment.

signal = thinkdsp.TriangleSignal(200) duration = signal.period*3 segment = signal.make_wave(duration, framerate=10000) segment.plot()

Make a wave and play it.

wave = signal.make_wave(duration=0.5, framerate=10000) wave.apodize() wave.make_audio()

Compute its spectrum and plot it.

spectrum = wave.make_spectrum() spectrum.plot()

Make a square signal and plot a 3 period segment.

signal = thinkdsp.SquareSignal(200) duration = signal.period*3 segment = signal.make_wave(duration, framerate=10000) segment.plot() thinkplot.config(ylim=[-1.05, 1.05], legend=False)

Make a wave and play it.

wave = signal.make_wave(duration=0.5, framerate=10000) wave.apodize() wave.make_audio()

Compute its spectrum and plot it.

spectrum = wave.make_spectrum() spectrum.plot()

Create a sawtooth signal and plot a 3 period segment.

signal = thinkdsp.SawtoothSignal(200) duration = signal.period*3 segment = signal.make_wave(duration, framerate=10000) segment.plot()

Make a wave and play it.

wave = signal.make_wave(duration=0.5, framerate=10000) wave.apodize() wave.make_audio()

Compute its spectrum and plot it.

spectrum = wave.make_spectrum() spectrum.plot()

Aliasing

Make a cosine signal at 4500 Hz, make a wave at framerate 10 kHz, and plot 5 periods.

framerate = 10000 signal = thinkdsp.CosSignal(4500) duration = signal.period*5 segment = signal.make_wave(duration, framerate=framerate) segment.plot()

Make a cosine signal at 5500 Hz, make a wave at framerate 10 kHz, and plot the same duration.

With framerate 10 kHz, the folding frequency is 5 kHz, so a 4500 Hz signal and a 5500 Hz signal look exactly the same.

signal = thinkdsp.CosSignal(5500) segment = signal.make_wave(duration, framerate=framerate) segment.plot()

Make a triangle signal and plot the spectrum. See how the harmonics get folded.

signal = thinkdsp.TriangleSignal(1100) segment = signal.make_wave(duration=0.5, framerate=10000) spectrum = segment.make_spectrum() spectrum.plot()

Amplitude and phase

Make a sawtooth wave.

signal = thinkdsp.SawtoothSignal(500) wave = signal.make_wave(duration=1, framerate=10000) segment = wave.segment(duration=0.005) segment.plot()

Play it.

wave.make_audio()

Extract the wave array and compute the real FFT (which is just an FFT optimized for real inputs).

import numpy as np hs = np.fft.rfft(wave.ys) hs

Compute the frequencies that match up with the elements of the FFT.

n = len(wave.ys) # number of samples d = 1 / wave.framerate # time between samples fs = np.fft.rfftfreq(n, d) fs

Plot the magnitudes vs the frequencies.

magnitude = np.absolute(hs) thinkplot.plot(fs, magnitude)

Plot the phases vs the frequencies.

angle = np.angle(hs) thinkplot.plot(fs, angle)

What does phase sound like?

Shuffle the phases.

import random random.shuffle(angle) thinkplot.plot(fs, angle)

Put the shuffled phases back into the spectrum. Each element in hs is a complex number with magitude AA and phase ϕ\phi, with which we can compute AeiϕA e^{i \phi}

i = complex(0, 1) spectrum = wave.make_spectrum() spectrum.hs = magnitude * np.exp(i * angle)

Convert the spectrum back to a wave (which uses irfft).

wave2 = spectrum.make_wave() wave2.normalize() segment = wave2.segment(duration=0.005) segment.plot()

Play the wave with the shuffled phases.

wave2.make_audio()

For comparison, here's the original wave again.

wave.make_audio()

Although the two signals have different waveforms, they have the same frequency components with the same amplitudes. They differ only in phase.

Aliasing interaction

The following interaction explores the effect of aliasing on the harmonics of a sawtooth signal.

def view_harmonics(freq, framerate): signal = thinkdsp.SawtoothSignal(freq) wave = signal.make_wave(duration=0.5, framerate=framerate) spectrum = wave.make_spectrum() spectrum.plot(color='blue') thinkplot.show(xlabel='frequency', ylabel='amplitude') display(wave.make_audio())
from ipywidgets import interact, interactive, fixed import ipywidgets as widgets slider1 = widgets.FloatSlider(min=100, max=10000, value=100, step=100) slider2 = widgets.FloatSlider(min=5000, max=40000, value=10000, step=1000) interact(view_harmonics, freq=slider1, framerate=slider2);