summaryrefslogtreecommitdiff
path: root/talk.ipynb
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2018-05-26 13:16:24 +0300
committerYuval Adam <_@yuv.al>2018-05-26 13:16:24 +0300
commit9d44d520177a8e67ac76ce40b9e5777608b0031e (patch)
tree7feac62b12483a722a798faeb18c280b3e6e17a2 /talk.ipynb
parent02fd57fbf3c106c634d30c42829e4e78192cd996 (diff)
Fix signal processing, use files
Diffstat (limited to 'talk.ipynb')
-rw-r--r--talk.ipynb87
1 files changed, 56 insertions, 31 deletions
diff --git a/talk.ipynb b/talk.ipynb
index d8e8de0..220e47e 100644
--- a/talk.ipynb
+++ b/talk.ipynb
@@ -24,7 +24,6 @@
"## Yuval Adam\n",
"\n",
" - Full stack developer and systems architecture consultant\n",
- " - But I also like to play with radios\n",
" - https://yuv.al\n",
" - @yuvadm\n",
"\n"
@@ -42,7 +41,7 @@
"\n",
" - I never learned physics, RF engineering or signal processing\n",
" - But radios are pretty cool!\n",
- " - Hopefully in 25 minutes I can show you some neat things\n",
+ " - Hopefully I can show you some neat things\n",
" - Slides and code @ https://github.com/yuvadm/radio-pyconil-2018"
]
},
@@ -54,10 +53,11 @@
}
},
"source": [
- "## Agenda\n",
+ "## Radio Waves\n",
+ "\n",
+ "![static/dipole.gif](static/dipole.gif)\n",
"\n",
- " - What are radio waves?\n",
- " - Hardware vs software radio"
+ "*Source: https://en.wikipedia.org/wiki/Antenna_(radio)*\n"
]
},
{
@@ -68,20 +68,22 @@
}
},
"source": [
- "## Radio Waves\n",
- "\n",
- "![static/dipole.gif](static/dipole.gif)\n",
+ "## Hardware Radio\n",
"\n",
- "*Source: https://en.wikipedia.org/wiki/Antenna_(radio)*\n"
+ "![static/radio.jpg](static/radio.jpg)"
]
},
{
"cell_type": "markdown",
- "metadata": {},
+ "metadata": {
+ "slideshow": {
+ "slide_type": "subslide"
+ }
+ },
"source": [
"## Hardware Radio\n",
"\n",
- "![static/radio.jpg](static/radio.jpg)"
+ "![static/gsm.jpg](static/gsm.jpg)"
]
},
{
@@ -201,6 +203,17 @@
]
},
{
+ "cell_type": "markdown",
+ "metadata": {
+ "slideshow": {
+ "slide_type": "slide"
+ }
+ },
+ "source": [
+ "## GQRX"
+ ]
+ },
+ {
"cell_type": "code",
"execution_count": null,
"metadata": {
@@ -219,15 +232,13 @@
"sdr.center_freq = 91.8e6 # 91,800,00 Hz frequency for the radio station\n",
"sdr.gain = 'auto' # tune the gain (AKA \"volume\") automatically\n",
"\n",
- "samples = sdr.read_samples(1.2e6 * 8) # collect samples during 8 seconds\n",
- "sdr.close()\n",
- "\n",
- "print(samples[:5])"
+ "samples = sdr.read_samples(1.2e6 * 10)\n",
+ "sdr.close()"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@@ -235,16 +246,20 @@
},
"outputs": [],
"source": [
- "# Load the samples into a numpy array\n",
+ "# Alternatively, load previously captured samples from rtl_sdr\n",
+ "# and convert them from unsigned 8-bit samples to a complex IQ array\n",
"\n",
"import numpy as np\n",
"\n",
- "samples = np.array(samples).astype('complex64')"
+ "raw = np.fromfile('/tmp/samples.in', np.uint8).astype(np.float64)\n",
+ "raw += -127\n",
+ "raw /= 2**7\n",
+ "samples = (raw[0::2] + 1j * raw[1::2]).astype(np.complex64)"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@@ -265,7 +280,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@@ -274,14 +289,14 @@
"outputs": [],
"source": [
"# Apply the Frequency DEmodulation\n",
- "# We use something called polar discriminator\n",
+ "# We use something called a polar discriminator\n",
"\n",
"samples = np.angle(samples[1:] * np.conj(samples[:-1]))"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@@ -302,7 +317,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"metadata": {
"slideshow": {
"slide_type": "subslide"
@@ -316,22 +331,32 @@
"AUDIO_RATE = 50e3\n",
"DECIMATION_RATE = int(BANDWIDTH / AUDIO_RATE) # Decimation factor of 4\n",
"\n",
- "samples = signal.decimate(samples, DECIMATION_RATE)"
+ "samples = signal.decimate(samples, DECIMATION_RATE)\n",
+ "\n",
+ "# Amplify the signal volume\n",
+ "samples *= 10000\n",
+ "samples = samples.astype('int16')"
]
},
{
"cell_type": "code",
- "execution_count": null,
- "metadata": {
- "slideshow": {
- "slide_type": "subslide"
- }
- },
+ "execution_count": 6,
+ "metadata": {},
"outputs": [],
"source": [
"# HIT IT\n",
"\n",
- "whatever.play(samples)"
+ "import alsaaudio\n",
+ "\n",
+ "device = alsaaudio.PCM(alsaaudio.PCM_PLAYBACK, device='default')\n",
+ "device.setchannels(1)\n",
+ "device.setrate(50000)\n",
+ "device.setformat(alsaaudio.PCM_FORMAT_S16_LE)\n",
+ "device.setperiodsize(120)\n",
+ "\n",
+ "# Write data in chunks\n",
+ "for s in np.array_split(samples, 120):\n",
+ " device.write(s)"
]
},
{