Spectral Analysis of Musical Sound

Sasha Bakker

Physics 281 Shubha Tewari 12/17/2018

In [3]:
"""
SPECTRAL ANALYSIS OF MUSICAL SOUND
This program loads the waveforms of a piano note and a trumpet note,
Calculates its discrete Fourier transform, and plots the waveforms 
Along with the discrete Fourier transforms of the audio data. 
It also calculates and prints the frequency at which the FT peak occurs. 

"""

# Import Packages
import numpy as np
from numpy import real, imag
import matplotlib.pyplot as plt
from numpy.fft import rfft

# Initialize Variables
piano = np.loadtxt("piano.txt") # piano volumes
trumpet = np.loadtxt("trumpet.txt") # trumpet volumes
frequency = 44100 # samples/second
N = len(piano) # number of samples
t = N/frequency # sampling time
nyq = (frequency/2)-1 # Nyquist sampling frequency
times = np.arange(0,t,t/N) # time array


# Descrete FT for trumpet
transformT = rfft(trumpet)
freqsT = np.linspace(0,nyq,len(transformT))

# Descrete FT for piano
transformP = rfft(piano)
freqsP = np.linspace(0,nyq,len(transformP))

# Initialize variables to find the note played
realTrumpet = real(transformT) # real of trumpet FT
realPiano = real(transformP) # real of piano FT
maxT, maxP, indexT, indexP = 0,0,0,0 # maximums and indices

# Find the index of the maximum FT coefficient 
for i in range(len(realTrumpet)):
    
    # Temporary current coefficient values
    theT = realTrumpet[i]
    theP = realPiano[i]
    
    # Update coefficient and indicies
    if freqsT[i] <= 800:
        if theT > maxT:
            maxT = theT
            indexT = i
    if freqsP[i] <= 800:
        if theP > maxP:
            maxP = theP
            indexP = i
    
    if freqsP[i] and freqsT[i] > 800:
        break

# Find the frequency the note is played at
noteT = freqsT[indexT]
noteP = freqsP[indexP]

# Create messages to output the note played
messageT = "\nThe frequency the trumpet sounds is " + str(noteT) + " Hz which is C5."
messageP = "The frequency the piano sounds is " + str(noteP) + " Hz which is C5."
html = "https://www.audiology.org/sites/default/files/ChasinConversionChart.pdf"

# Create a figure
plt.figure(figsize=(15,7))

# Plot trumpet volume
plt.subplot(221)
plt.plot(times,trumpet,color='red')
plt.title("Trumpet Volume vs. Time")
plt.ylabel("Volume")
plt.xlabel("Time (s)")

# Plot piano volume
plt.subplot(223)
plt.plot(times,piano,color='green')
plt.title("Piano Volume vs. Time")
plt.ylabel("Volume")
plt.xlabel("Time (s)")

# Plot trumpet transform (absolute)
plt.subplot(222)
plt.plot(freqsT,abs(transformT))
plt.title("Trumpet abs(FT)")
plt.ylabel("Magnitudes of Fourier coefficients")
plt.xlabel("Frequency Hz")
plt.xlim(0,10000)

# Plot piano transform (absolute)
plt.subplot(224)
plt.plot(freqsP,abs(transformP))
plt.title("Piano abs(FT)")
plt.ylabel("Magnitudes of Fourier coefficients")
plt.xlabel("Frequency Hz")
plt.xlim(0,10000)

# Show the plots
plt.subplots_adjust(hspace=1) # adjust spacing between plots
plt.show() 

# Create a new figure
plt.figure(figsize=(15,7))

# Plot trumpet transform (Real and Imaginary)
plt.subplot(211)
plt.plot(freqsT,real(transformT),label='real')
plt.plot(freqsT,imag(transformT),label='imaginary')
plt.legend()
plt.title("Trumpet Fourier Transform")
plt.ylabel("Magnitudes of Fourier coefficients")
plt.xlabel("Frequency Hz")
plt.xlim(0,10000)


# Plot piano transform (Real and Imaginary)
plt.subplot(212)
plt.plot(freqsP,real(transformP),label='real')
plt.plot(freqsP,imag(transformP),label='imaginary')
plt.legend()
plt.title("Piano Fourier Transform")
plt.ylabel("Magnitudes of Fourier coefficients")
plt.xlabel("Frequency Hz")
plt.xlim(0,10000)

# Show the plots
plt.subplots_adjust(hspace=1) # adjust spacing between plots
plt.show()

# Print the notes played
print(messageT)
print(messageP)
print("Source: ",html)
    
The frequency the trumpet sounds is 520.79738 Hz which is C5.
The frequency the piano sounds is 525.20718 Hz which is C5.
Source:  https://www.audiology.org/sites/default/files/ChasinConversionChart.pdf

Part D.

The plots in part C represent the real part of the fourier transform. The plots for sum of the real and imaginary components follow a similar pattern to that of the real component alone, such that the peak for both plots are at the same frequency; there is also a quick rise in coefficient magnitude before the peak, and a slower fall in coefficient magnitude after the peak.

Part F.

Both the trumpet and the piano FT plots have the same first frequency with a coefficient. This first frequency is the fundamental frequency and therefore the pitch which names the note played. This note, however, is not necessarily the most dominat note heard. The other frequencies with coefficients contribute to the timbre of the instrument and are whole number multiples of the fundamental frequency, which are called harmonics. The combination of these waves defines the quality and richness of the sound heard. This is largely due to the varying amplitudes of the coefficients, since the amplitude determines the strength of the harmonic in audio. The trumpet range of frequencies with coefficients extends longer than the piano range of frequencies with coefficients, such that the trumpet has more FT coefficients than the piano. This is because the trumpet has more harmonics than the piano note, giving the trumpet a fuller, richer tone than the piano, meaning, the timbre of the instruments differ. These differences are due to how the note is executed. For the trumpet, the air causes standing wave vibration in the trumpet's air column, with the waves manipulated by pressing keys. On the other hand, the piano notes are made by striking a string with a hammer, with the note determined by the quality of the string such as its thickness, tension, and length. Therefore, even though both instruments are playing the same note, the sound quality is much different.

Part G.

The note played by both instruments is C5. This was determined by finding the frequency with the first coefficient peak on the plot, and converting the freqeucny to a note with a musical note to frequency chart. These coefficients were chosen for the frequencies at which the note is played because it is the the fundamental frequency, meaning, all other frequencies are a multiple of this frequency. The frequencies are not exact to 523 due to human error in tuning the instruments to the note.