aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNao Pross <np@0hm.ch>2021-11-18 19:07:03 +0100
committerNao Pross <np@0hm.ch>2021-11-18 19:07:03 +0100
commitd00bb6d29ceae9d2ee958b57549af335e977edc6 (patch)
treeb1e2a3d05724b936ced4182c435d48ebddff3e79
parentAdd PDFs (diff)
downloadFading-d00bb6d29ceae9d2ee958b57549af335e977edc6.tar.gz
Fading-d00bb6d29ceae9d2ee958b57549af335e977edc6.zip
Partially implement xor correlator (untested)
-rwxr-xr-xsrc/gr-fadingui/install.sh (renamed from src/gr-fadingui/build.sh)0
-rw-r--r--src/gr-fadingui/python/datasource.py3
-rw-r--r--src/gr-fadingui/python/xor_frame_sync.py70
-rw-r--r--tests/fadingui/QAM/qam_nogui.grc10
-rwxr-xr-xtests/fadingui/QAM/qam_nogui.py4
5 files changed, 53 insertions, 34 deletions
diff --git a/src/gr-fadingui/build.sh b/src/gr-fadingui/install.sh
index 29697af..29697af 100755
--- a/src/gr-fadingui/build.sh
+++ b/src/gr-fadingui/install.sh
diff --git a/src/gr-fadingui/python/datasource.py b/src/gr-fadingui/python/datasource.py
index ab2f441..c7d68f1 100644
--- a/src/gr-fadingui/python/datasource.py
+++ b/src/gr-fadingui/python/datasource.py
@@ -8,6 +8,7 @@ import io
import numpy as np
from gnuradio import gr
+
class datasource(gr.sync_block):
"""
Loads data from a file choosen in the graphical user interface, splits into
@@ -51,7 +52,7 @@ class datasource(gr.sync_block):
def make_header(self, data_size):
# TODO: check that data_size is not too big
- pilot = 0x1248
+ pilot = 0xbeef
# TODO: implement hamming code for header
header = f"p{pilot:04x}s{data_size:04x}d".encode("ascii")
diff --git a/src/gr-fadingui/python/xor_frame_sync.py b/src/gr-fadingui/python/xor_frame_sync.py
index 735a031..af7aa85 100644
--- a/src/gr-fadingui/python/xor_frame_sync.py
+++ b/src/gr-fadingui/python/xor_frame_sync.py
@@ -12,36 +12,48 @@ from gnuradio import gr
class xor_frame_sync(gr.sync_block):
"""
- docstring for block xor_frame_sync
+ Performs a frame synchronization by XOR matching a preamble bit sequence
"""
def __init__(self, sync_pattern, buffer_size):
+ # TODO: buffer size should be in packets
gr.sync_block.__init__(self,
name="xor_frame_sync",
in_sig=[np.byte],
out_sig=[np.byte])
# binary pattern to match
- self.pattern = np.array(sync_pattern, dtype=np.dtype("uint8"))
- self.nbits = len(sync_pattern)
+ self.pattern = np.unpackbits(np.array(sync_pattern, dtype=np.uint8))[::-1]
+ self.nbytes = len(sync_pattern)
+ self.nbits = len(self.pattern)
- # buffer to delay the data
- self.delay_fifo = RingBuffer(buffer_size, dtype=np.byte)
+ assert(self.nbits % 8 == 0)
- # buffers to store cross correlation data
- self.xcorr = RingBuffer(buffer_size, dtype=np.dtype("uint8"))
+ # packed buffer to delay the data
+ self.delaybuf = RingBuffer(buffer_size, dtype=np.uint8)
+ self.delay = 0
+
+ # unpacked buffer to compute correlation values, initially filled with zeros
+ self.corrbuf = RingBuffer(self.nbits)
+ self.corrbuf.extend(np.zeros(self.nbits))
+
+ # buffer to store correlation values
+ self.xcorrs = RingBuffer(buffer_size)
# synchronization state
self.synchronized = False
- self.delay = 0
- def xcorrelation(self):
+ def xcorrelation(self, v):
"""
- Compute the binary correlation between the stream and the stored
- pattern. Binary correlation between two bit vectors is just size of the
+ Compute the binary correlations between the stored pattern and
+ correlation buffer, while shifting v into the buffer.
+
+ Binary correlation between two bit vectors is just size of the
vector(s) minus the number of bits that differ.
"""
- unpacked = np.unpackbits(self.delay_fifo[0])
- return self.nbits - sum(np.logical_xor(unpacked, self.pattern))
+ v_arr = np.array(v, dtype=np.uint8)
+ for b in np.unpackbits(v_arr):
+ self.corrbuf.appendleft(b)
+ yield self.nbits - np.sum(np.logical_xor(self.corrbuf, self.pattern))
def work(self, input_items, output_items):
"""
@@ -51,29 +63,37 @@ class xor_frame_sync(gr.sync_block):
pattern appears every k bits, where k is the size of the packet.
- If the buffer is not synchronized, compute a binary cross
- correlation to find how by much the stream should be delayed.
+ correlation to find how much the stream should be delayed.
+
+ Notes:
+
+ - Even though the block input is of type np.byte, inp is an array
+ of 255 bytes, probably for performance reasons.
+ TODO: block processing
"""
inp = input_items[0]
out = output_items[0]
- # Add data to delay buffer
- self.delay_fifo.appendleft(inp)
-
- # TODO: check for synchronization, else compute
-
- # Compute correlation
if not self.synchronized:
- self.xcorr.append(self.xcorrelation())
+ for v in inp:
+ # compute the cross correlation
+ xcs = self.xcorrelation(v)
- peak = np.argmax(self.xcorr)
- if self.xcorr[peak] != self.nbits:
- print(f"Warning! XOR correlation is not perfect (peak value = {self.xcorr[peak]})")
+ # add cross correlations to buffer and save value
+ self.xcorrs.extend(list(xcs))
+ self.delaybuf.appendleft(v)
+ peak = np.argmax(self.xcorrs)
self.delay = peak
self.synchronized = True
+ if self.xcorrs[peak] != self.nbits:
+ self.synchronized = False
+ print(f"Warning! XOR correlation is not perfect (peak value = {self.xcorrs[peak]})")
+
+
# return data with delay
- out[:] = self.delay_fifo[self.delay]
+ out[:] = self.delaybuf[self.delay]
return len(output_items[0])
diff --git a/tests/fadingui/QAM/qam_nogui.grc b/tests/fadingui/QAM/qam_nogui.grc
index e9028b6..83c8059 100644
--- a/tests/fadingui/QAM/qam_nogui.grc
+++ b/tests/fadingui/QAM/qam_nogui.grc
@@ -488,23 +488,23 @@ blocks:
bus_structure: null
coordinate: [2096, 180.0]
rotation: 0
- state: true
+ state: disabled
- name: fadingui_xor_frame_sync_0
id: fadingui_xor_frame_sync
parameters:
affinity: ''
alias: ''
- buffer_size: '128'
+ buffer_size: '2048'
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
- pattern: '[]'
- pattern_len: '10'
+ pattern: '[0xbe, 0xef]'
+ pattern_len: '16'
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [2304, 436.0]
+ coordinate: [2312, 436.0]
rotation: 0
state: true
diff --git a/tests/fadingui/QAM/qam_nogui.py b/tests/fadingui/QAM/qam_nogui.py
index 56fc49b..1da693e 100755
--- a/tests/fadingui/QAM/qam_nogui.py
+++ b/tests/fadingui/QAM/qam_nogui.py
@@ -52,8 +52,7 @@ class qam_nogui(gr.top_block):
##################################################
# Blocks
##################################################
- self.fadingui_xor_frame_sync_0 = fadingui.xor_frame_sync(sync_pattern=[], buffer_size=128)
- self.fadingui_dearpygui_sink_0 = fadingui.dearpygui_sink(sock_addr='udp://localhost:31415', ui_element_id=0)
+ self.fadingui_xor_frame_sync_0 = fadingui.xor_frame_sync(sync_pattern=[0xbe, 0xef], buffer_size=2048)
self.fadingui_datasource_0 = fadingui.datasource(vec_len=2037, header_len=11, sock_addr='udp://', file_list=["./lena512color.tiff"])
self.digital_pfb_clock_sync_xxx_0 = digital.pfb_clock_sync_ccf(sps, timing_loop_bw, rrc_taps, nfilts, nfilts/2, 1.5, 1)
self.digital_map_bb_0 = digital.map_bb([0, 1, 3, 2])
@@ -92,7 +91,6 @@ class qam_nogui(gr.top_block):
self.connect((self.digital_constellation_decoder_cb_0, 0), (self.digital_diff_decoder_bb_0, 0))
self.connect((self.digital_constellation_modulator_0, 0), (self.blocks_throttle_0, 0))
self.connect((self.digital_costas_loop_cc_0, 0), (self.digital_constellation_decoder_cb_0, 0))
- self.connect((self.digital_costas_loop_cc_0, 0), (self.fadingui_dearpygui_sink_0, 0))
self.connect((self.digital_diff_decoder_bb_0, 0), (self.digital_map_bb_0, 0))
self.connect((self.digital_map_bb_0, 0), (self.fadingui_xor_frame_sync_0, 0))
self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.digital_cma_equalizer_cc_0, 0))