# AM & Ringmodulation: Formula & Spectrum

## Amplitude Modulation vs Ringmodulation

The basic formula is the same for amplitude modulation and ringmodulation:

$$y[n] = x[n] \cdot m[n]$$

However, for ringmodulation the modulation signal is symmetric:

$$y[n] = \sin\left(2 \pi f_1 \frac{n}{f_s}\right) \cdot \left(\sin\left[2 \pi f_m \frac{n}{f_s}\right]\right)$$

Whereas for amplitude modulation, the signal ist asymetric:

$$y[n] = \sin\left(2 \pi f_1 \frac{n}{f_s}\right) \cdot \left( 1+ \sin\left[2 \pi f_m \frac{n}{f_s}\right]\right)$$

This differnce has an influence on the resulting spectrum and on the sound, as the following examples show.

import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook
from scipy import signal
from IPython.display import display, Markdown, clear_output
import IPython.display as ipd

from ipywidgets import *

# define functions for AM and ringmod

def am(f1, f2, t):

x = np.sin(2*np.pi*f1*t)
m = 1+np.sin(2*np.pi*f2*t)

y = x*m
return(y,m,x)

def ringmod(f1, f2, t):

x = np.sin(2*np.pi*f1*t)
m = np.sin(2*np.pi*f2*t)

y = x*m
return(y,m,x)


### AM Spectrum

$$Y = DFT(y)$$

The spectrum for amplitude modulation can be calculated as follows:

$$Y[k] = \sum_{n=0}^{N-1} y[n] \cdot e^{-j 2 \pi k \frac{n}{N}}$$

$$= \sum_{n=0}^{N-1} \sin\left(2 \pi f_1 \frac{n}{f_s}\right) \cdot \left( 1+ \sin\left[2 \pi f_m \frac{n}{f_s}\right]\right) \cdot e^{-j 2 \pi k \frac{n}{N}}$$

$$=\sum_{n=0}^{N-1} \left( \sin\left(2 \pi f_1 \frac{n}{f_s}\right) + 0.5 \left( \cos\left(2 \pi (f_1 - f_m)\frac{n}{f_s}\right) - \cos\left(2 \pi (f_1 + f_m)\frac{n}{f_s}\right) \right) \right) \cdot e^{-j 2 \pi k \frac{n}{N}}$$

$$= delta[f_1] + 0.5 \delta[f_1 - f_m] + 0.5 \ \delta[f_1 + f_m]$$

AM creates a spectrum with a peak at the carrier frequency and two peaks below and above it. Their position is defined by the difference between carrier and modulator.

# visualization in the time domain

# basic parameters
fs = 48000
L  = 48000

t  = np.linspace(0,1,L)
f  = np.linspace(-0.5,0.5,L)

f_car = 400
f_mod = 170
[x, x_car, x_sig] = ringmod(f_mod, f_car, t)

fig1, ax1 = plt.subplots()

plt.title("Modulated Signal")

ax1.set_xlabel('t/s')
ax1.set_ylabel('x' ,color = [ 0.3, 0.3, 0.3])
ax1.set_xlim(0, 0.15)

ipd.display(ipd.Audio(x, rate=fs))

line, = ax1.plot(t,x);

def update( f_mod = widgets.IntSlider(min = 1, max= 1000, step=1, value=170),
f_car = widgets.IntSlider(min = 1, max= 1000, step=1, value=400)):

[x, x_car, x_sig] = ringmod(f_mod, f_car, t)

line.set_ydata(x)
fig1.canvas.draw_idle()

ipd.display(ipd.Audio(x, rate=fs))

interact(update);

<IPython.core.display.Javascript object>

interactive(children=(IntSlider(value=170, description='f_mod', max=1000, min=1), IntSlider(value=400, descripâ€¦

# visualization in the frequency domain

f_car = 400
f_mod = 170
[x, x_car, x_sig] = ringmod(f_mod, f_car, t)

# fft stuff
X = np.fft.fftshift(np.fft.fft(x))
X = X/(L)

X_car = np.fft.fftshift(np.fft.fft(x_car))
X_car = X_car/(L)

X_sig = np.fft.fftshift(np.fft.fft(x_sig))
X_sig = X_sig/(L)

fig1, ax1 = plt.subplots()

ax1.set_xlabel('$\omega$')
ax1.set_ylabel('|X|' ,color = [ 0.3, 0.3, 0.3])
ax1.set_xlim(-0.1, 0.1)

# for static HTML output:
line, = ax1.plot(f,abs(X));
ipd.display(ipd.Audio(x, rate=fs))

# for interactive output:
def update(  f_mod = widgets.IntSlider(min = 1, max= 1000, step=1, value=170),
f_car = widgets.IntSlider(min = 1, max= 1000, step=1, value=400)):

[x, x_car, x_sig] = ringmod(f_mod, f_car, t)

X = np.fft.fftshift(np.fft.fft(x))
X = X/(L)

X_car = np.fft.fftshift(np.fft.fft(x_car))
X_car = X_car/(L)

X_sig = np.fft.fftshift(np.fft.fft(x_sig))
X_sig = X_sig/(L)

line.set_ydata(abs(X))
fig1.canvas.draw_idle()

ipd.display(ipd.Audio(x, rate=fs))

interact(update);

<IPython.core.display.Javascript object>

interactive(children=(IntSlider(value=170, description='f_mod', max=1000, min=1), IntSlider(value=400, descripâ€¦


### Ringmod Spectrum

$$\mathcal{F} [ y(t)] = \int\limits_{-\inf}^{\inf} y(t) e^{-j 2 \pi f t} \mathrm{d}t$$

$$= \int\limits_{-\inf}^{\inf} \left( \sin(2 \pi f_c t) \sin(2 \pi f_s t) \right) e^{-j 2 \pi f t} \mathrm{d}t$$

$$= \frac{1}{2 j} \int\limits_{-\inf}^{\inf} \left( (-e^{-j 2 \pi f_c t} +e^{j 2 \pi f_c t}) (-e^{-j 2 \pi f_s t} +e^{j 2 \pi f_s t}) \right) \ e^{-j 2 \pi f t} \mathrm{d}t$$

$$= \frac{1}{2 j} \int\limits_{-\inf}^{\inf} \left( e^{j 2 \pi (f_c+f_s) t} - e^{j 2 \pi (f_c-f_s) t} - e^{j 2 \pi (-f_c+f_s) t} + e^{j 2 \pi (-f_c-f_s) t} \right) e^{-j 2 \pi f t}$$

$$= \frac{1}{2 j} \left[ \delta(f_c+f_s) -\delta(f_c-f_s) - \delta(-f_c+f_s) + \delta(-f_c-f_s) \right]$$

Ringmodulation creates a spectrum with
two peaks below and above the carrier frequency. Their position is defined by the difference between carrier and modulator.
The modulator is supressed, since it is symmetric.
# visualization in the time domain

# basic parameters
fs = 48000
L  = 48000

t  = np.linspace(0,1,L)
f  = np.linspace(-0.5,0.5,L)

f_car = 500
f_mod = 100
[x, x_car, x_sig] = am(f_mod, f_car, t)

fig1, ax1 = plt.subplots()

plt.title("Modulated Signal")

ax1.set_xlabel('t/s')
ax1.set_ylabel('x' ,color = [ 0.3, 0.3, 0.3])
ax1.set_xlim(0, 0.15)

ipd.display(ipd.Audio(x, rate=fs))

line, = ax1.plot(t,x);

def update( f_mod = widgets.IntSlider(min = 1, max= 1000, step=1, value=40),
f_car = widgets.IntSlider(min = 1, max= 1000, step=1, value=500)):

[x, x_car, x_sig] = am(f_mod, f_car, t)

line.set_ydata(x)
fig1.canvas.draw_idle()

ipd.display(ipd.Audio(x, rate=fs))

interact(update);

<IPython.core.display.Javascript object>

interactive(children=(IntSlider(value=40, description='f_mod', max=1000, min=1), IntSlider(value=500, descriptâ€¦

# visualization in the frequency domain

f_car = 400
f_mod = 170
[x, x_car, x_sig] = am(f_mod, f_car, t)

# fft stuff
X = np.fft.fftshift(np.fft.fft(x))
X = X/(L)

X_car = np.fft.fftshift(np.fft.fft(x_car))
X_car = X_car/(L)

X_sig = np.fft.fftshift(np.fft.fft(x_sig))
X_sig = X_sig/(L)

fig1, ax1 = plt.subplots()

ax1.set_xlabel('$\omega$')
ax1.set_ylabel('|X|' ,color = [ 0.3, 0.3, 0.3])
ax1.set_xlim(-0.1, 0.1)

# for static HTML output:
line, = ax1.plot(f,abs(X));
ipd.display(ipd.Audio(x, rate=fs))

# for interactive output:
def update(  f_mod = widgets.IntSlider(min = 1, max= 1000, step=1, value=400),
f_car = widgets.IntSlider(min = 1, max= 1000, step=1, value=170)):

[x, x_car, x_sig] = am(f_mod, f_car, t)

X = np.fft.fftshift(np.fft.fft(x))
X = X/(L)

X_car = np.fft.fftshift(np.fft.fft(x_car))
X_car = X_car/(L)

X_sig = np.fft.fftshift(np.fft.fft(x_sig))
X_sig = X_sig/(L)

line.set_ydata(abs(X))
fig1.canvas.draw_idle()

ipd.display(ipd.Audio(x, rate=fs))

interact(update);

<IPython.core.display.Javascript object>