📚 The CoCalc Library - books, templates and other resources
License: OTHER
"""This file contains code used in "Think DSP",1by Allen B. Downey, available from greenteapress.com23Copyright 2015 Allen B. Downey4License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html5"""67from __future__ import print_function, division89import math10import numpy as np1112import thinkdsp13import thinkplot1415import matplotlib.pyplot as pyplot1617import warnings18warnings.filterwarnings('ignore')1920PI2 = math.pi * 2212223def linear_chirp_evaluate(ts, low=440, high=880, amp=1.0):24"""Computes the waveform of a linear chirp and prints intermediate values.2526low: starting frequency27high: ending frequency28amp: amplitude29"""30print('ts', ts)3132freqs = np.linspace(low, high, len(ts)-1)33print('freqs', freqs)3435dts = np.diff(ts)36print('dts', dts)3738dphis = np.insert(PI2 * freqs * dts, 0, 0)39print('dphis', dphis)4041phases = np.cumsum(dphis)42print('phases', phases)4344ys = amp * np.cos(phases)45print('ys', ys)4647return ys484950def discontinuity(num_periods=30, hamming=False):51"""Plots the spectrum of a sinusoid with/without windowing.5253num_periods: how many periods to compute54hamming: boolean whether to apply Hamming window55"""56signal = thinkdsp.SinSignal(freq=440)57duration = signal.period * num_periods58wave = signal.make_wave(duration)5960if hamming:61wave.hamming()6263print(len(wave.ys), wave.ys[0], wave.ys[-1])64spectrum = wave.make_spectrum()65spectrum.plot(high=880)666768def three_spectrums():69"""Makes a plot showing three spectrums for a sinusoid.70"""71thinkplot.preplot(rows=1, cols=3)7273pyplot.subplots_adjust(wspace=0.3, hspace=0.4,74right=0.95, left=0.1,75top=0.95, bottom=0.1)7677xticks = range(0, 900, 200)7879thinkplot.subplot(1)80thinkplot.config(xticks=xticks)81discontinuity(num_periods=30, hamming=False)8283thinkplot.subplot(2)84thinkplot.config(xticks=xticks, xlabel='Frequency (Hz)')85discontinuity(num_periods=30.25, hamming=False)8687thinkplot.subplot(3)88thinkplot.config(xticks=xticks)89discontinuity(num_periods=30.25, hamming=True)9091thinkplot.save(root='windowing1')929394def window_plot():95"""Makes a plot showing a sinusoid, hamming window, and their product.96"""97signal = thinkdsp.SinSignal(freq=440)98duration = signal.period * 10.2599wave1 = signal.make_wave(duration)100wave2 = signal.make_wave(duration)101102ys = np.hamming(len(wave1.ys))103ts = wave1.ts104window = thinkdsp.Wave(ys, ts, wave1.framerate)105106wave2.hamming()107108thinkplot.preplot(rows=3, cols=1)109110pyplot.subplots_adjust(wspace=0.3, hspace=0.3,111right=0.95, left=0.1,112top=0.95, bottom=0.05)113114thinkplot.subplot(1)115wave1.plot()116thinkplot.config(axis=[0, duration, -1.07, 1.07])117118thinkplot.subplot(2)119window.plot()120thinkplot.config(axis=[0, duration, -1.07, 1.07])121122thinkplot.subplot(3)123wave2.plot()124thinkplot.config(axis=[0, duration, -1.07, 1.07],125xlabel='Time (s)')126127thinkplot.save(root='windowing2')128129130def chirp_spectrum():131"""Plots the spectrum of a one-second one-octave linear chirp.132"""133signal = thinkdsp.Chirp(start=220, end=440)134wave = signal.make_wave(duration=1)135136thinkplot.preplot(3, cols=3)137duration = 0.01138wave.segment(0, duration).plot(xfactor=1000)139thinkplot.config(ylim=[-1.05, 1.05])140141thinkplot.subplot(2)142wave.segment(0.5, duration).plot(xfactor=1000)143thinkplot.config(yticklabels='invisible',144xlabel='Time (ms)')145146thinkplot.subplot(3)147wave.segment(0.9, duration).plot(xfactor=1000)148thinkplot.config(yticklabels='invisible')149150thinkplot.save('chirp3')151152153spectrum = wave.make_spectrum()154spectrum.plot(high=700)155thinkplot.save('chirp1',156xlabel='Frequency (Hz)',157ylabel='Amplitude')158159160def chirp_spectrogram():161"""Makes a spectrogram of a one-second one-octave linear chirp.162"""163signal = thinkdsp.Chirp(start=220, end=440)164wave = signal.make_wave(duration=1, framerate=11025)165spectrogram = wave.make_spectrogram(seg_length=512)166167print('time res', spectrogram.time_res)168print('freq res', spectrogram.freq_res)169print('product', spectrogram.time_res * spectrogram.freq_res)170171spectrogram.plot(high=700)172173thinkplot.save('chirp2',174xlabel='Time (s)',175ylabel='Frequency (Hz)')176177178def overlapping_windows():179"""Makes a figure showing overlapping hamming windows.180"""181n = 256182window = np.hamming(n)183184thinkplot.preplot(num=5)185start = 0186for i in range(5):187xs = np.arange(start, start+n)188thinkplot.plot(xs, window)189190start += n/2191192thinkplot.save(root='windowing3',193xlabel='Index',194axis=[0, 800, 0, 1.05])195196197def invert_spectrogram():198"""Tests Spectrogram.make_wave.199"""200signal = thinkdsp.Chirp(start=220, end=440)201wave = signal.make_wave(duration=1, framerate=11025)202spectrogram = wave.make_spectrogram(seg_length=512)203204wave2 = spectrogram.make_wave()205206for i, (y1, y2) in enumerate(zip(wave.ys, wave2.ys)):207if abs(y1 - y2) > 1e-14:208print(i, y1, y2)209210211def main():212chirp_spectrum()213chirp_spectrogram()214overlapping_windows()215window_plot()216three_spectrums()217218219if __name__ == '__main__':220main()221222223