In [1]:
import numpy as np
import matplotlib.pyplot as plt
import IPython.display as ipd
from scipy.signal import fftconvolve
import librosa

Comb Filter Solution

Below we create a comb filter impulse response. The width between impulses is the period of the resulting pitch. That is, given a frequency $f$ and a sample rate $sr$, the spacing between impulses is

$ T = sr / f$

Furthermore, the more pulses we take, the clearer the pitch is

In [3]:
sr = 44100
x = np.random.randn(sr) # Make a second of random noise

# Compute the period (spacing) from the note number
note_number = -12
f = 440*(2**(note_number/12))
T = int(sr/f)

# Create an impuse response array big enough to hold 20 pulses
h = np.zeros(T*20+1)
# Evenly space the pulses by the period, using slice notation
h[0::T] = 1
# Do the convolution
y = fftconvolve(x, h)
ipd.Audio(y, rate=sr)
Out[3]:

We can also a sound that's not noise, and we get a "robot voice" effect. This is a prelude to assignment 3 on vocoders

In [4]:
x, sr = librosa.load("robot.mp3", sr=sr)
ipd.Audio(x, rate=sr)
/home/ctralie/anaconda3/lib/python3.7/site-packages/librosa/core/audio.py:162: UserWarning: PySoundFile failed. Trying audioread instead.
  warnings.warn("PySoundFile failed. Trying audioread instead.")
Out[4]:
In [5]:
y = fftconvolve(x, h)
ipd.Audio(y, rate=sr)
Out[5]:
In [ ]: