From dd795612f0ca0d84e0a17075f8e56d783937bf10 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Thu, 18 Nov 2021 16:11:24 +0100 Subject: Begin frame sync block --- .../grc/fadingui_xor_frame_sync.block.yml | 37 +++++++------- src/gr-fadingui/python/datasource.py | 3 +- src/gr-fadingui/python/xor_frame_sync.py | 58 ++++++++++++++++++++-- 3 files changed, 76 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/gr-fadingui/grc/fadingui_xor_frame_sync.block.yml b/src/gr-fadingui/grc/fadingui_xor_frame_sync.block.yml index 92be2a8..35eb132 100644 --- a/src/gr-fadingui/grc/fadingui_xor_frame_sync.block.yml +++ b/src/gr-fadingui/grc/fadingui_xor_frame_sync.block.yml @@ -1,10 +1,10 @@ id: fadingui_xor_frame_sync -label: xor_frame_sync +label: XOR Correlation Synchronizer category: '[fadingui]' templates: imports: import fadingui - make: fadingui.xor_frame_sync() + make: fadingui.xor_frame_sync(sync_pattern=${pattern}, buffer_size=${buffer_size}) # Make one 'parameters' list entry for every parameter you want settable from the GUI. # Keys include: @@ -12,12 +12,17 @@ templates: # * label (label shown in the GUI) # * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...) parameters: -- id: ... - label: ... - dtype: ... -- id: ... - label: ... - dtype: ... +- id: pattern + label: Bit pattern + dtype: raw + +- id: pattern_len + label: Pattern length + dtype: raw + +- id: buffer_size + label: Delay buffer size + dtype: int # Make one 'inputs' list entry per input and one 'outputs' list entry per output. # Keys include: @@ -27,18 +32,14 @@ parameters: # * vlen (optional - data stream vector length. Default is 1) # * optional (optional - set to 1 for optional inputs. Default is 0) inputs: -- label: ... - domain: ... - dtype: ... - vlen: ... - optional: ... +- label: in + domain: stream + dtype: byte outputs: -- label: ... - domain: ... - dtype: ... - vlen: ... - optional: ... +- label: out + domain: stream + dtype: byte # 'file_format' specifies the version of the GRC yml format used in the file # and should usually not be changed. diff --git a/src/gr-fadingui/python/datasource.py b/src/gr-fadingui/python/datasource.py index 764b4d5..ab2f441 100644 --- a/src/gr-fadingui/python/datasource.py +++ b/src/gr-fadingui/python/datasource.py @@ -10,7 +10,8 @@ from gnuradio import gr class datasource(gr.sync_block): """ - Loads data from a file choosen in the graphical user interface. + Loads data from a file choosen in the graphical user interface, splits into + chunks and puts a preamble in front of it(frame). """ HEADER_LEN = 11; diff --git a/src/gr-fadingui/python/xor_frame_sync.py b/src/gr-fadingui/python/xor_frame_sync.py index 9d9064f..735a031 100644 --- a/src/gr-fadingui/python/xor_frame_sync.py +++ b/src/gr-fadingui/python/xor_frame_sync.py @@ -4,24 +4,76 @@ # Copyright 2021 Naoki Pross. -import numpy +import numpy as np +from numpy_ringbuffer import RingBuffer + from gnuradio import gr + class xor_frame_sync(gr.sync_block): """ docstring for block xor_frame_sync """ - def __init__(self, sync_pattern): + def __init__(self, sync_pattern, buffer_size): 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) + + # buffer to delay the data + self.delay_fifo = RingBuffer(buffer_size, dtype=np.byte) + + # buffers to store cross correlation data + self.xcorr = RingBuffer(buffer_size, dtype=np.dtype("uint8")) + + # synchronization state + self.synchronized = False + self.delay = 0 + + def xcorrelation(self): + """ + Compute the binary correlation between the stream and the stored + pattern. 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)) + def work(self, input_items, output_items): + """ + Process the inputs, that means: + + - Check that the buffer is synchronized, i.e. there is the sync + 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. + """ inp = input_items[0] out = output_items[0] - out[:] = inp + # 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()) + + peak = np.argmax(self.xcorr) + if self.xcorr[peak] != self.nbits: + print(f"Warning! XOR correlation is not perfect (peak value = {self.xcorr[peak]})") + + self.delay = peak + self.synchronized = True + + # return data with delay + out[:] = self.delay_fifo[self.delay] return len(output_items[0]) -- cgit v1.2.1