Our World Is Made More Beautiful By Harmonics (and Python)

Prof Bill Buchanan OBE
Nov 24 · 3 min read

What makes a guitar sound nice? Is it the chords, the key or the notes that are played? Not quite, as an A note on its own is rather boring. If you have ever heard an A note on an audio generator it sounds rather dull and plain. In fact it is just a 440 Hz sine wave [here], with a single frequency in the frequency domain:

So why does a guitar sound so interesting? Well it produces harmonics of the fundamental frequency, such as at three times the fundamental frequency, and five times the fundamental frequency. Our ear generally likes these odd harmonics, and a well designed guitar will make sure that that these are well supporte. In the following we have a wave which has a 3rd harmonic with 40% of the amplitude of the fundamental and a 5th harmonic with 20% of the amplitude of the fundamental [here]. We see a more characteristic waveform for sound, and also see three spikes for the frequencies in the frequency domain:

In Python, we can easily convert from the time domain into the frequency domain using a FFT (Fast Fourier Transform) and using mighty Numpy (np) library:

Y = np.fft.fft(y)/n # fft computing and normalization

In Python, we can also use the matplotlib library, too, in order to illustrate the time and the frequency domain plots. And, so, here is the full code. I have used a 5 Hz fundamental wave, and which gives a period of 0.2 seconds:

import matplotlib.pyplot as plot
import numpy as np
import sys

a1=0.0
a2=0.0
a3=0.0
a4=0.0
file ='1111'

if (len(sys.argv)>1):
file=str(sys.argv[1])
if (len(sys.argv)>2):
a1=float(sys.argv[2])
if (len(sys.argv)>3):
a2=float(sys.argv[3])
if (len(sys.argv)>4):
a3=float(sys.argv[4])
if (len(sys.argv)>5):
a4=float(sys.argv[5])
if (len(sys.argv)>6):
a5=float(sys.argv[6])

Fs = 150.0; # sampling rate
Ts = 1.0/Fs; # sampling interval

freq = 5; # frequency of the signal

t = np.arange(0,1,Ts)

y = a1*np.sin(2*np.pi*freq*t) + a2* np.sin(2*np.pi*2*freq*t) + a3* np.sin(2*np.pi*3*freq*t) + a4* np.sin(2*np.pi*4*freq*t) + a5* np.sin(2*np.pi*5*freq*t)


n = len(y) # length of the signal
k = np.arange(n)
T = n/Fs
frq = k/T # two sides frequency range
frq = frq[range(n/2)] # one side frequency range
Y = np.fft.fft(y)/n # fft computing and normalization
Y = Y[range(n/2)]

fig,myplot = plot.subplots(2, 1)
myplot[0].plot(t,y)
myplot[0].set_xlabel('Time')
myplot[0].set_ylabel('Amplitude')

myplot[1].plot(frq,abs(Y),'r') # plotting the spectrum
myplot[1].set_xlabel('Freq (Hz)')
myplot[1].set_ylabel('|Y(freq)|')

plot.savefig(file)
plot.show()

If you are interested, here is a demo of analysing signals in Python [tutorial]:

and with some theory:

Conclusions

Go do some Python. It is a great tool kit for learning. If your kids are learning maths, it is a great playground for coding and learning. For you, just go learn Python!

ASecuritySite: When Bob Met Alice

Prof Bill Buchanan OBE

Written by

Professor of Cryptography. Serial innovator. Believer in fairness, justice & freedom. EU Citizen. Auld Reekie native. Old World Breaker. New World Creator.

ASecuritySite: When Bob Met Alice

This publication brings together interesting articles related to cyber security.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade