Beat



Musician know the effect when tuning instruments: If two instruments are playing not quite the same tune, it sounds like the tune has a periodic variation in volume. The period gets larger the better tuned the two instruments are and stops when they both have the same tune. We call this effect "Beat".

Ham radio operators know the "opposite" of that effect when amplitude-modulating a radio frequency with a sine wave in the audio range: The result are two radio frequencies, one lower by the frequency of the audio sine wave, one higher by that frequency.

Amplitude modulation is simply a multiplication: We multiply the radio wave with the audio. We have

$$m(t) = A(t) \cdot\cos(2\pi f t)$$

Where $t$ is the time, $m(t)$ is the modulated signal, $\cos(2\pi f_r t)$ is the radio frequency signal with frequency $f_r$ and $A(t)$ is the audio signal. For a simple audio sine wave we get:

$$m(t) = \cos(2\pi f_a t)\cdot\cos(2\pi f_r t)$$

with $f_a$ the audio frequency.

Now we want to show that both effects are the same thing. We do not need radio frequencies, we can do the same in the audio spectrum.

From Wikipedia we take one of the trigonometric Product sum identities:

$$\displaystyle\cos\theta \cos\phi = \frac{\cos(\theta-\phi) + \cos(\theta+\phi)}{2}$$

When we apply this to our modulation example, we get:

$$\displaystyle \begin{align} \cos(2\pi f_a t) \cos(2\pi f_r t) & = \frac{\cos(2\pi f_r t-2\pi f_a t) + \cos(2\pi f_r t+2\pi f_a t)}{2} \\ & = \frac{\cos(2\pi(f_r-f_a)t)) + \cos(2\pi(f_r+f_a)t)}{2} \\ \end{align} $$

So multiplying two cosines with different frequencies results in the sum of two cosine functions, one with the frequency of the difference of the original frequencies, one with the sum.

So no matter how we create the modulated signal, by multiplying two signals or adding two signals we get the same result.

I the following example we multiply a 3Hz signal (the beat) with a 440 Hz signal (that's an 'A' in musical terms). We get a modulated signal that changes volume with the beat frequency as expected.

In [1]:
import numpy as np
# Three seconds with 18000 samples
t = np.linspace (0, 3, 18000)
# Product of 3Hz and 440Hz tune
y = np.cos (2*np.pi*3*t) * np.cos (2*np.pi*440*t)
# Plot only 1/9 of the three seconds = 1/3s = one period of the 3Hz signal
limit = int (2000)
In [2]:
import plotly.graph_objs as go
import plotly.io as pio
from plotly_fix_fn import setup_plotly
setup_plotly ('content/2024/05/plotly', '11-en')
show_opt = dict (include_plotlyjs = 'directory')

fig = go.Figure ()
fig.add_trace (go.Scatter (x = t [:limit], y = y [:limit]))
fig.update_layout (title = "Modulated signal", xaxis_title = "Time (s)", yaxis_title = "Amplitude")
#fig_widget = go.FigureWidget (fig)
fig.show (** show_opt)

Now we do a fourier transform of the result to see the frequency spectrum, we see that the result of the multiplication consists of two frequencies, one 3Hz below the 440 Hz and one 3Hz above.

In [3]:
from numpy.fft import rfft, fftfreq
fft   = rfft (y, norm = 'forward')
freqs = fftfreq (len (y), d = 3/18000)
fig = go.Figure ()
fig.add_trace (go.Scatter (x = freqs [:5000], y = np.abs (fft [:5000])))
fig.update_layout (title = "Frequency spectrum", xaxis_title = "Frequency (Hz)")
fig.update_xaxes (range = [430, 450])
fig.show (** show_opt)

We can arrive at the same result by just adding the two frequencies (and dividing by 2 to get the same amplitude):

In [4]:
y = 0.5 * (np.cos (2*np.pi*(440-3)*t) + np.cos (2*np.pi*(440+3)*t))
fig = go.Figure ()
fig.add_trace (go.Scatter (x = t [:limit], y = y [:limit]))
fig.update_layout (title = "Modulated signal", xaxis_title = "Time (s)", yaxis_title = "Amplitude")
fig.show (** show_opt)

Finally we verify again that this produces the same audio spectrum as before by doing another fourier analysis.

In [5]:
fft   = rfft (y, norm='forward')
freqs = fftfreq (len (y), d = 3/18000)
fig = go.Figure ()
fig.add_trace (go.Scatter (x = freqs [:5000], y = np.abs (fft [:5000])))
fig.update_layout (title = "Frequency spectrum", xaxis_title = "Frequency (Hz)")
fig.update_xaxes (range = [430, 450])
fig.show (** show_opt)

So what you hear when tuning instruments is not an illusion: Adding the two frequencies is the same thing as when modulating a tune with a beat frequency.