113 lines
4.1 KiB
Plaintext
113 lines
4.1 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "e67c2a43",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Frequency Shift"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "6482d25c",
|
||
"metadata": {},
|
||
"source": [
|
||
"```{figure} img/reference/raw_waterfall.webp\n",
|
||
"---\n",
|
||
"name: fig:raw_waterfall.en\n",
|
||
"---\n",
|
||
"Waterfall diagram. We can see both copies of the spectrum at $\\pm2.4\\text{kHz}$.\n",
|
||
"```"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "cbe50415",
|
||
"metadata": {},
|
||
"source": [
|
||
"As a first step, we want to shift the copy of the spectrum at 2.4 kHz to zero.\n",
|
||
"\n",
|
||
"In the frequency domain, we can represent this shift as a convolution with a singular peak at -2.4kHz.\n",
|
||
"How can we create such a peak?\n",
|
||
"\n",
|
||
"We remember:\n",
|
||
"$\\sin(2\\pi f t)$ and $\\cos(2\\pi f t)$ have peaks at $\\pm f$.\n",
|
||
"\n",
|
||
"To be precise:\n",
|
||
"```{math}\n",
|
||
"\\begin{align*}\n",
|
||
"\\sin(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\n",
|
||
" \\frac{1}{2}i &∶& f = -f_0 \\\\\n",
|
||
" -\\frac{1}{2}i &:& f = f_0 \\\\\n",
|
||
" 0 &:& \\text{otherwise} \\\\\n",
|
||
"\\end{array}\\right. \\\\\n",
|
||
"\\cos(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\n",
|
||
" \\frac{1}{2} &∶& f \\in \\{-f_0, f_0\\} \\\\\n",
|
||
" 0 &:& \\text{otherwise} \\\\\n",
|
||
"\\end{array}\\right. \\\\\n",
|
||
"\\end{align*}\n",
|
||
"```\n",
|
||
"\n",
|
||
"That is two peaks each\n",
|
||
"We can however combine sine and cosine so that one of them cancels out:\n",
|
||
"If we multiply the sine term with $i$, we get:\n",
|
||
"```{math}\n",
|
||
"i \\cdot \\sin(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\n",
|
||
" i \\cdot \\frac{1}{2}i = -\\frac{1}{2} &∶& f = -f_0 \\\\\n",
|
||
" i \\cdot -\\frac{1}{2}i = \\frac{1}{2} &:& f = f_0 \\\\\n",
|
||
" 0 &:& \\text{otherwise} \\\\\n",
|
||
"\\end{array}\\right.\n",
|
||
"```\n",
|
||
"And if we now add the cosine term:\n",
|
||
"```{math}\n",
|
||
"\\cos(2\\pi f_0 t) + i\\sin(2\\pi f_0 t) \\,&\\circ\\!\\!-\\!\\!\\bullet\\, \\left\\{\\begin{array}{rcl}\n",
|
||
" \\frac{1}{2} -\\frac{1}{2} = 0 &∶& f = -f_0 \\\\\n",
|
||
" \\frac{1}{2} + \\frac{1}{2} = 1 &:& f = f_0 \\\\\n",
|
||
" 0 &:& \\text{otherwise} \\\\\n",
|
||
"\\end{array}\\right.\n",
|
||
"```\n",
|
||
"This yields exactly one peak at $f_0$.\n",
|
||
"\n",
|
||
"```{note}\n",
|
||
"The expression $\\cos(x) + i\\sin(x)$ may be familliar from [Euler's formula](https://en.wikipedia.org/wiki/Euler's_formula).\n",
|
||
"```\n",
|
||
"\n",
|
||
"To perform the frequency shift, we can simply multiply in the time domain (= each sample) with this function.\n",
|
||
"We do this as follows:\n",
|
||
"- For every sample $s$, we calculate the current time $t$.\n",
|
||
" Since the sampling rate $f_S$ equals $16640\\text{Hz}$ we know that the duration in between two samples is exactly $1/16640\\text{s}$.\n",
|
||
"- We then calculate $\\cos(2\\pi \\cdot -2400 \\cdot t) + i \\cdot \\sin(2\\pi \\cdot -2400 \\cdot t)$ and obtain a complex result $a + bi$.\n",
|
||
"- We multiply $s$ with this, resulting in $a \\cdot s + (b \\cdot s)i$, which we save as our new (complex) sample.\n",
|
||
"\n",
|
||
"```{note}\n",
|
||
"For this project, it is sufficient to represent complex numbers as pairs of two real numbers.\n",
|
||
"But in some programming languages, there are explicit types for complex numbers, e.g., [std::complex](https://en.cppreference.com/w/cpp/numeric/complex) in C++.\n",
|
||
"In Python, you can simply use `a + b * 1j`.\n",
|
||
"```"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3 (ipykernel)",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.11.13"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
}
|