$ y(t) = \cos(2 \pi f t + \phi) $
A chirp is a more general sinuoid where any function of time is put inside of a cosine, not just a line
$ y(t) = \cos(2 \pi f(t) ) $, where $f(t)$ is some arbitrary function of time
Ex) A sinusoid is a chirp
$f(t) = at + b$
$y(t) = \cos(2 \pi (at + b)) = \cos(2 \pi a t + 2 \pi b)$
$f = a$, $\phi = 2 \pi b$
Ex) $f(t) = 440t^2$
$ y(t) = \cos(2 \pi * 440t^2)$
import numpy as np
import matplotlib.pyplot as plt
import IPython.display as ipd
sr = 44100
t = np.arange(sr)/sr
y = np.cos(2*np.pi*440*t**2)
ipd.Audio(y, rate = sr)
Ex) $f(t) = 440t^3$
$ y(t) = \cos(2 \pi * 440t^3)$
y2 = np.cos(2*np.pi*440*t**3)
ipd.Audio(y2, rate = sr)
Ex) $f(t) = 440t^4$
$ y(t) = \cos(2 \pi * 440t^4)$
y3 = np.cos(2*np.pi*440*t**4)
ipd.Audio(y3, rate = sr)
What's interesitng about these is that their functions all start at 0 and end at 440, but we can clearly hear that the ending note is higher in each successive example
plt.plot(t, 440*t**2)
plt.plot(t, 440*t**3)
plt.plot(t, 440*t**4)
plt.xlabel("time (Seconds)")
plt.legend(["$t^2$", "$t^3$", "$t^4$"])
We actually don't hear the frequency of f, but the derivative of f! This explains both why the frequencies moved up faster, but also why the ended up higher for higher powers of $t$ over the interval $[0, 1]$, due to the power rule of calculus
Ex) $f(t) = 440t$, $f'(t) = 440$
Ex) $f(t) = 440t^2$, $f'(t) = 880t$
Ex) $f(t) = 440t^3$, $f'(t) = 1320t^2$
Ex) $f(t) = 440t^4$, $f'(t) = 1680t^3$
We can use this idea to design frequency trajectories in audio by specifying the derivative of f, and then taking its antiderivative
Ex) I want to start at 220hz and end at 1680 hz over an interval of 3 seconds, going linearly in frequency
$f'(t) = 220 + (1680-220)*t/3$
$f(t) = 220t + 1460*t^2/6 + c$
We can specify the antiderivative uniquely up to a phase here, but the phase doesn't affect the frequency we hear for a single chirp
sr = 44100
t = np.arange(sr*3)/sr
f = 220*t + 1460*t**2/6
y = np.cos(2*np.pi*f)
ipd.Audio(y, rate=sr)
Ex) Let's now say we want a chirp that starts at 220hz and ends at 1680hz and that takes a linear increase in pitch over an interval of 3 seconds. This means that we actually want an exponential increase in frequency
$f'(t) = 220*2^{t}$
Because we're lazy, we can actually integrate by taking a numerical approximation which is the cumulative sum of a bunch of thin rectangles, whose widths are the time interval between successive samples and whose heights are the values of the derivative fo frequency. The function "cumsum" helps us to perform such a cumulative sum for the numerical integration (NOTE: There are better schemes such as the trapezoidal scheme and Simpson's rule, but this will do for now). We indeed hear that we go up exactly one octave every second now
df = 220*2**t
f = np.cumsum((t[1]-t[0])*df) # Integral numerically in python using rectangles
y2 = np.cos(2*np.pi*f)
ipd.Audio(y2, rate=sr)