aboutsummaryrefslogtreecommitdiffstats
path: root/notebooks/FrameSynchronization.ipynb
diff options
context:
space:
mode:
Diffstat (limited to 'notebooks/FrameSynchronization.ipynb')
-rw-r--r--notebooks/FrameSynchronization.ipynb73
1 files changed, 35 insertions, 38 deletions
diff --git a/notebooks/FrameSynchronization.ipynb b/notebooks/FrameSynchronization.ipynb
index a659a7b..e0187b2 100644
--- a/notebooks/FrameSynchronization.ipynb
+++ b/notebooks/FrameSynchronization.ipynb
@@ -3,7 +3,7 @@
{
"cell_type": "code",
"execution_count": 1,
- "id": "5d5acf43",
+ "id": "57a55a8c",
"metadata": {},
"outputs": [],
"source": [
@@ -16,7 +16,7 @@
},
{
"cell_type": "markdown",
- "id": "4b294887",
+ "id": "dc4b9dfd",
"metadata": {},
"source": [
"# Digital Frame Synchronization\n"
@@ -24,22 +24,21 @@
},
{
"cell_type": "code",
- "execution_count": 2,
- "id": "5bec50ff",
- "metadata": {},
+ "execution_count": 27,
+ "id": "025c6919",
+ "metadata": {
+ "scrolled": false
+ },
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "Header sequence (N=16): [1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1]\n",
- "Cross correlation: [ 3. 4. 5. 5. 6. 4. 4. 6. 4. 4. 5. 8. 7. 10. 8. 7. 8. 10.\n",
- " 7. 8. 8. 9. 14. 11. 9. 10. 12. 9. 13. 9. 9. 11. 13. 9. 12. 11.\n",
- " 9. 9. 13. 10. 9. 11. 9. 14. 12. 9. 10. 11. 8. 11. 6. 9. 8. 11.\n",
- " 6. 7. 9. 8. 7. 4. 4. 9. 9. 7. 6. 7. 9. 11. 8. 7. 10. 12.\n",
- " 10. 11. 11. 10. 9. 10. 9. 7. 10. 7. 9. 6. 7. 6. 5. 4. 5. 2.\n",
- " 4. 3.]\n",
- "Correlation peak value: 14.0\n"
+ "Header (N=16): [1 0 1 1 1 1 1 0 1 1 1 0 1 1 1 1]\n",
+ "Stream (N=80): [0 0 1 1 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 1 1 0 1 1 1\n",
+ " 1 1 0 1 1 1 0 1 1 1 1 1 0 1 1 1 0 1 1 0 1 0 1 1 0 0 1 1 1 0 0 1 1 1 1 1 0\n",
+ " 0 1 1 1 0 1]\n",
+ "Correlation peak value: 16 at i=47\n"
]
},
{
@@ -48,13 +47,13 @@
"<StemContainer object of 3 artists>"
]
},
- "execution_count": 2,
+ "execution_count": 27,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
- "image/png": "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\n",
+ "image/png": "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\n",
"text/plain": [
"<Figure size 1800x360 with 1 Axes>"
]
@@ -67,42 +66,40 @@
],
"source": [
"# Create test data\n",
- "seq = np.array([(0xbeef >> i) & 0x1 for i in range(4 * 4)])\n",
- "# seq = np.array([1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1])\n",
- "\n",
+ "seq = np.unpackbits(np.array([0xbe, 0xef], dtype=np.dtype(\"uint8\")))\n",
"stream = np.concatenate([\n",
- " np.random.randint(low=0, high=2, size=30), seq, np.random.randint(low=0, high=2, size=30)\n",
+ " np.random.randint(low=0, high=2, size=32), seq, np.random.randint(low=0, high=2, size=32)\n",
"])\n",
"\n",
- "print(f\"Header sequence (N={len(seq)}): {seq}\")\n",
- "# print(f\"Data stream: {stream}\")\n",
+ "print(f\"Header (N={len(seq)}): {seq}\")\n",
+ "print(f\"Stream (N={len(stream)}): {stream}\")\n",
"\n",
- "# compute cross correlation\n",
- "def distance(v):\n",
- " return len(seq) - sum(np.logical_xor(v, seq))\n",
- "\n",
- "fifo = RingBuffer(len(seq))\n",
- "xcorr = RingBuffer(len(stream) + len(seq))\n",
+ "# Create buffers for cross correlation\n",
+ "fifo = RingBuffer(len(seq), dtype=np.dtype(\"uint8\"))\n",
+ "xcorr = RingBuffer(len(stream) + len(seq), dtype=np.dtype(\"uint8\"))\n",
"\n",
"## fill FIFO with zeros\n",
"fifo.extend(np.zeros(fifo.maxlen))\n",
"\n",
- "for i in range(len(stream) + len(seq)):\n",
- " #print(np.array(fifo))\n",
- " xcorr.append(distance(np.array(fifo)))\n",
+ "def correlation(v):\n",
+ " n = len(seq)\n",
+ " d = np.logical_xor(v, seq) # or bitwise_xor, no difference in this case\n",
+ " return n - sum(d)\n",
+ " \n",
+ "for i in range(len(stream) + len(seq) + 1):\n",
+ " xcorr.append(correlation(np.array(fifo)))\n",
" \n",
+ " # append stream data\n",
" # if the stream is finished use zeros\n",
- " fifo.pop()\n",
- " if i < len(stream):\n",
- " fifo.appendleft(stream[i])\n",
- " else:\n",
- " fifo.appendleft(0)\n",
+ " fifo.append(stream[i] if i < len(stream) else 0)\n",
"\n",
- "print(f\"Cross correlation: {np.array(xcorr)}\")\n",
- "print(f\"Correlation peak value: {max(np.array(xcorr))}\")\n",
+ "# unwrap values\n",
+ "xc = np.array(xcorr)\n",
+ "# print(f\"Cross correlation: {xc}\")\n",
+ "print(f\"Correlation peak value: {np.amax(xc)} at i={np.argmax(xc)}\")\n",
"\n",
"plt.figure(figsize = (25, 5))\n",
- "plt.stem(np.array(xcorr))"
+ "plt.stem(xc)"
]
}
],