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

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!