aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNao Pross <np@0hm.ch>2021-11-20 17:05:04 +0100
committerNao Pross <np@0hm.ch>2021-11-20 17:05:04 +0100
commit2bb4a947d4d55e605e6912dec3ff95fbe541615a (patch)
tree094e54706b8a26d38636ff2115aac6ed4e85a21a
parentFrames (diff)
downloadFading-2bb4a947d4d55e605e6912dec3ff95fbe541615a.tar.gz
Fading-2bb4a947d4d55e605e6912dec3ff95fbe541615a.zip
Implement Frame Object
-rw-r--r--src/gr-fadingui/grc/fadingui_datasource.block.yml28
-rw-r--r--src/gr-fadingui/grc/fadingui_deframer.block.yml1
-rw-r--r--src/gr-fadingui/grc/fadingui_frame_obj.block.yml25
-rw-r--r--src/gr-fadingui/grc/fadingui_xor_frame_sync.block.yml8
-rw-r--r--src/gr-fadingui/python/CMakeLists.txt1
-rw-r--r--src/gr-fadingui/python/datasource.py105
-rw-r--r--src/gr-fadingui/python/deframer.py4
-rw-r--r--src/gr-fadingui/python/frame_obj.py77
-rw-r--r--src/gr-fadingui/python/logger.py14
-rw-r--r--src/gr-fadingui/python/xor_frame_sync.py14
-rwxr-xr-xtests/fadingui/QAM/hammingtest.py14
-rw-r--r--tests/fadingui/QAM/qam_nogui.grc213
-rwxr-xr-xtests/fadingui/QAM/qam_nogui.py162
13 files changed, 423 insertions, 243 deletions
diff --git a/src/gr-fadingui/grc/fadingui_datasource.block.yml b/src/gr-fadingui/grc/fadingui_datasource.block.yml
index 5f34591..6c31995 100644
--- a/src/gr-fadingui/grc/fadingui_datasource.block.yml
+++ b/src/gr-fadingui/grc/fadingui_datasource.block.yml
@@ -1,10 +1,10 @@
id: fadingui_datasource
-label: UI Framed Data Source
+label: Framed Data Source
category: '[fadingui]'
templates:
imports: import fadingui
- make: fadingui.datasource(vec_len=${vec_len}, header_len=${header_len}, sock_addr=${sock_addr}, file_list=${file_list})
+ make: fadingui.datasource(frame_obj=${frame_obj}, filename=${fname})
# Make one 'parameters' list entry for every parameter you want settable from the GUI.
# Keys include:
@@ -12,25 +12,12 @@ templates:
# * label (label shown in the GUI)
# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...)
parameters:
-- id: vec_len
- label: Vector length
- dtype: int
- default: 501
-
-- id: header_len
- label: Header length
- dtype: int
- default: 11
-
-- id: sock_addr
- label: Socket Address
- dtype: string
- default: "udp://"
-
-- id: file_list
+- id: frame_obj
+ label: Frame Object
+ type: raw
+- id: fname
label: List of files
- dtype: raw
- default: "[]"
+ dtype: file_open
# Make one 'inputs' list entry per input and one 'outputs' list entry per output.
# Keys include:
@@ -45,7 +32,6 @@ outputs:
- label: out
domain: stream
dtype: byte
- vlen: ${ vec_len + header_len }
# '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/grc/fadingui_deframer.block.yml b/src/gr-fadingui/grc/fadingui_deframer.block.yml
index b5d6cfe..02db246 100644
--- a/src/gr-fadingui/grc/fadingui_deframer.block.yml
+++ b/src/gr-fadingui/grc/fadingui_deframer.block.yml
@@ -1,6 +1,7 @@
id: fadingui_deframer
label: Deframer
category: '[fadingui]'
+labels: [ python ]
templates:
imports: import fadingui
diff --git a/src/gr-fadingui/grc/fadingui_frame_obj.block.yml b/src/gr-fadingui/grc/fadingui_frame_obj.block.yml
index 8fee3a3..c655306 100644
--- a/src/gr-fadingui/grc/fadingui_frame_obj.block.yml
+++ b/src/gr-fadingui/grc/fadingui_frame_obj.block.yml
@@ -1,10 +1,7 @@
id: fadingui_frame_obj
label: Frame Object
category: '[fadingui]'
-
-templates:
- imports: import fadingui
- make: fadingui.frame_obj()
+flags: [ show_id, python ]
# Make one 'parameters' list entry for every parameter you want settable from the GUI.
# Keys include:
@@ -14,22 +11,20 @@ templates:
parameters:
- id: preamble
label: Preamble
- dtype: raw
- default: [0xbe, 0xef]
+ dtype: int_vector
+ default: '[0xbe, 0xef]'
- id: payload_len
label: Payload length
dtype: int
default: 4096
-# Make one 'inputs' list entry per input and one 'outputs' list entry per output.
-# Keys include:
-# * label (an identifier for the GUI)
-# * domain (optional - stream or message. Default is stream)
-# * dtype (e.g. int, float, complex, byte, short, xxx_vector, ...)
-# * vlen (optional - data stream vector length. Default is 1)
-# * optional (optional - set to 1 for optional inputs. Default is 0)
-inputs:
-outputs:
+value: ${ fadingui.frame_obj }
+
+
+templates:
+ imports: import fadingui
+ var_make: |-
+ self.${id} = ${id} = fadingui.frame_obj(preamble=${preamble}, payload_len=${payload_len})
# '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/grc/fadingui_xor_frame_sync.block.yml b/src/gr-fadingui/grc/fadingui_xor_frame_sync.block.yml
index 35eb132..1a8640d 100644
--- a/src/gr-fadingui/grc/fadingui_xor_frame_sync.block.yml
+++ b/src/gr-fadingui/grc/fadingui_xor_frame_sync.block.yml
@@ -1,6 +1,7 @@
id: fadingui_xor_frame_sync
label: XOR Correlation Synchronizer
category: '[fadingui]'
+flags: [ python ]
templates:
imports: import fadingui
@@ -15,14 +16,9 @@ parameters:
- id: pattern
label: Bit pattern
dtype: raw
-
-- id: pattern_len
- label: Pattern length
- dtype: raw
-
- id: buffer_size
label: Delay buffer size
- dtype: int
+ dtype: raw
# Make one 'inputs' list entry per input and one 'outputs' list entry per output.
# Keys include:
diff --git a/src/gr-fadingui/python/CMakeLists.txt b/src/gr-fadingui/python/CMakeLists.txt
index c277a73..1318857 100644
--- a/src/gr-fadingui/python/CMakeLists.txt
+++ b/src/gr-fadingui/python/CMakeLists.txt
@@ -32,6 +32,7 @@ endif()
GR_PYTHON_INSTALL(
FILES
__init__.py
+ logger.py
datasource.py
dearpygui_sink.py
xor_frame_sync.py
diff --git a/src/gr-fadingui/python/datasource.py b/src/gr-fadingui/python/datasource.py
index c7d68f1..69a2122 100644
--- a/src/gr-fadingui/python/datasource.py
+++ b/src/gr-fadingui/python/datasource.py
@@ -8,88 +8,75 @@ import io
import numpy as np
from gnuradio import gr
+from fadingui.logger import get_logger
+log = get_logger("datasource")
-class datasource(gr.sync_block):
+
+class datasource(gr.basic_block):
"""
- Loads data from a file choosen in the graphical user interface, splits into
- chunks and puts a preamble in front of it(frame).
+ Loads data from a file choosen splits into chunks and pack them into
+ frames.
"""
- HEADER_LEN = 11;
-
- def __init__(self, vec_len, header_len, sock_addr, file_list):
- # FIXME: find a better solution
- assert(header_len == datasource.HEADER_LEN)
-
- gr.sync_block.__init__(self,
+ def __init__(self, frame_obj, filename):
+ gr.basic_block.__init__(self,
name="datasource",
in_sig=None,
- out_sig=[np.dtype(f'{vec_len + header_len}b')])
+ out_sig=[np.byte])
- # parameters
- self.vec_len = vec_len
- self.sock_addr = sock_addr
- self.file_list = file_list
+ # Frame object
+ self.frame = frame_obj
# file members
- self.fdata = None
- self.fsize = None
- self.fpos = 0
-
- # cache
- self.header_cache = None
-
- # TODO: make it possible to choose from UI
- self.load_file(file_list[0])
-
- def load_file(self, fname):
- self.fdata = np.fromfile(fname, np.byte)
+ self.fname = filename
+ self.fdata = np.fromfile(self.fname, np.byte)
self.fsize = len(self.fdata)
- # TODO: remove debugging statements or create logger
- print(f"datasource: loaded file size={self.fsize}, head:")
- print(self.fdata[:10])
+ # a frame has 5 id bits so, there can only be 2 ** 5 chunks per file
+ # see docstring of frame_obj for more details
+ nblocks = int(self.fsize / self.frame.payload_length)
+ log.debug(f"Loaded {self.fsize} bytes = {nblocks} blocks from name={self.fname}")
+ assert nblocks < 2 ** 5, "Payload size too small or file too big"
- def make_header(self, data_size):
- # TODO: check that data_size is not too big
- pilot = 0xbeef
+ self.fpos = 0
+ self.blocknr = 0
- # TODO: implement hamming code for header
- header = f"p{pilot:04x}s{data_size:04x}d".encode("ascii")
+ # would have been nice to have but does not work
+ # self.set_min_noutput_items(frame_obj.length)
- arr = np.frombuffer(header, dtype=np.dtype("byte"))
- return arr
+ # FIXME: implement buffering
+ # output buffer
+ self.outbuffer = np.array([])
- def work(self, input_items, output_items):
+ def general_work(self, input_items, output_items):
out = output_items[0]
- if self.fpos + self.vec_len > self.fsize:
- # FIXME: repair broken code below
- # TODO: create logger
- print(f"WARNING: the last {self.fsize - self.fpos} bytes were not sent!")
- self.fpos = 0
- return 0;
- rest = self.fsize - self.fpos
+ # FIXME: if there is leftover buffer add that first
+ # if self.outbuffer.size > 0:
+ # log.debug("Frame did not fit into buffer")
+ # out[:len(self.outbuffer)] = self.outbuffer
- # cannot use cached header
- header = self.make_header(rest)
- data = self.fdata[self.fpos:rest]
+ if self.fpos + self.frame.payload_length > self.fsize:
+ # FIXME: implement edge case
+ log.warning(f"The last {self.fsize - self.fpos} bytes were not sent!")
+ self.fpos = 0
+ self.blocknr = 0
- frame_size = datasource.HEADER_LEN + rest
- out[:] = np.concatenate([header, data])
+ log.debug("File finished, starting over")
+ return 0;
- self.fpos = 0
- return rest
+ data = self.fdata[self.fpos:self.fpos + self.frame.payload_length]
+ frame_bytes = self.frame.make(self.blocknr, self.frame.payload_length, data)
- # cache header if not saved
- if self.header_cache == None:
- self.header = self.make_header(self.vec_len)
+ out[:] = frame_bytes[:len(out)]
+ self.outbuffer = frame_bytes[len(out):]
- data = self.fdata[self.fpos:self.fpos + self.vec_len]
+ log.debug(f"Sent frame nr={self.blocknr}")
+ log.debug(f"Set bytes {out}")
- out[:] = np.concatenate([self.header, data])
+ self.fpos += self.frame.payload_length
+ self.blocknr += 1
- self.fpos += self.vec_len
- return len(output_items[0])
+ return self.frame.length
diff --git a/src/gr-fadingui/python/deframer.py b/src/gr-fadingui/python/deframer.py
index b7ee663..2af5ee0 100644
--- a/src/gr-fadingui/python/deframer.py
+++ b/src/gr-fadingui/python/deframer.py
@@ -8,9 +8,9 @@ from gnuradio import gr
class deframer(gr.sync_block):
"""
- docstring for block deframer
+ Check for integrity and remove frame header from packet.
"""
- def __init__(self):
+ def __init__(self, frame_obj):
gr.sync_block.__init__(self,
name="deframer",
in_sig=[np.byte],
diff --git a/src/gr-fadingui/python/frame_obj.py b/src/gr-fadingui/python/frame_obj.py
index b9dae70..136fce0 100644
--- a/src/gr-fadingui/python/frame_obj.py
+++ b/src/gr-fadingui/python/frame_obj.py
@@ -10,65 +10,82 @@ import numpy as np
from gnuradio import gr
-class frame_obj(gr.basic_block):
+class frame_obj:
"""
Frame Object: Contains informations about a data frame.
-------------------------------------------------------------------------------
| Preamble | Padding | ID | Data Length | Parity | Payload | Padding |
- | k bytes | 1 bit | 4 bits | 22 bits | 5 bits | | if necessary |
+ | k bytes | 1 bit | 5 bits | 21 bits | 5 bits | | if necessary |
-------------------------------------------------------------------------------
- | (31, 26) Hamming code EC |
- -----------------------------------
+ | (31, 26) Hamming EC code |
+ ---------------------------------
- The preamble is user defined.
- - The ID (11 bits) + Data length (22 bits) together are a 31 bits, followed
- by 26 parity bits computed using a (31,26) hamming code.
+ - The ID (5 bits) + Data length (21 bits) together are a 26 bits, followed
+ by 5 parity bits computed using a (31,26) hamming code.
- This constraints the maximum payload size to 64 MB and the number IDs to
- 1024 (i.e. max file size is 1 GB, more than enough for many thing)
+ This constraints the maximum payload size to 2 MiB and the number IDs to
+ 32, i.e. max file size is 64 MiB.
"""
def __init__(self, preamble, payload_len):
- gr.basic_block.__init__(self, name="frame_obj",
- in_sig=None, out_sig=None)
+ self._preamble = np.array(preamble, dtype=np.uint8)
- self.preamble = np.array(preamble, dtype=np.uint8)
+ self._preamble_len = len(self._preamble)
+ self._payload_len = payload_len
- self.preamble_len = len(self.preamble)
- self.payload_len = payload_len
+ @property
+ def header_length(self) -> int:
+ """Get header length in bytes"""
+ # 4 is the number of bytes for the hamming part
+ return self._preamble_len + 4
+
+ @property
+ def payload_length(self) -> int:
+ return self._payload_len
+
+ @property
+ def length(self) -> int:
+ """Get frame lenght in bytes"""
+ # 8 is the size of the hamming ECC part + 1 bit
+ return self.header_length + self.payload_length
@property
- def length(self):
- """Frame lenght in bytes"""
- return self.preamble_len + self.payload_len + 8
+ def preamble(self):
+ """Get preamble"""
+ return self._preamble
def parity(self, bits):
"""Compute the 5 parity bits for an unpacked array of 26 bits"""
assert(len(bits) == 26)
# FIXME: does not work
- # gen = np.array(
- # [[1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0],
- # [0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1],
- # [0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0],
- # [0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0],
- # [0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1]],
- # dtype=np.uint8)
# return np.matmul(bits, gen) % 2
return np.array([0, 0, 0, 0, 0])
def make(self, idv, data_len, data):
"""Make a frame"""
- return np.concatenate(self.preamble, np.packbits(hamming), data)
+ # get lower 4 bits of idv
+ idv_bits = np.unpackbits([np.uint8(idv)])[:5]
+
+ # get lower 22 bits of data_len
+ data_len_bytes = list(map(np.uint8, data_len.to_bytes(4, byteorder='little')))
+ data_len_bits = np.unpackbits(data_len_bytes)[:21]
+
+ # compute 5 parity bits
+ metadata = np.concatenate([idv_bits, data_len_bits])
+ parity_bits = self.parity(metadata)
+
+ # add padding
+ hamming_bits = np.concatenate([[0], metadata, parity_bits])
+ assert(len(hamming_bits) == 32)
+
+ # pack 32 bits into 4 bytes and add the rest
+ hamming = np.packbits(hamming_bits)
+ return np.concatenate([self.preamble, hamming, data])
def syndrome(self, bits):
"""Compute the syndrome (check Hamming code) for an unpacked array of 31 bits"""
assert(len(bits) == 31)
return reduce(op.xor, [i for i, bit in enumerate(bits) if bit])
- def general_work(self, input_items, output_items):
- """
- This block has no inputs or output
- """
- return 0;
-
diff --git a/src/gr-fadingui/python/logger.py b/src/gr-fadingui/python/logger.py
new file mode 100644
index 0000000..a189aeb
--- /dev/null
+++ b/src/gr-fadingui/python/logger.py
@@ -0,0 +1,14 @@
+import logging
+import sys
+
+formatter = logging.Formatter("[%(name)s] %(levelname)s: %(message)s")
+stdout_handler = logging.StreamHandler(sys.stdout)
+
+def get_logger(module):
+ log = logging.getLogger(module)
+
+ log.addHandler(stdout_handler)
+ stdout_handler.setFormatter(formatter)
+
+ log.setLevel(logging.DEBUG)
+ return log
diff --git a/src/gr-fadingui/python/xor_frame_sync.py b/src/gr-fadingui/python/xor_frame_sync.py
index e8d202c..51af35a 100644
--- a/src/gr-fadingui/python/xor_frame_sync.py
+++ b/src/gr-fadingui/python/xor_frame_sync.py
@@ -9,6 +9,9 @@ from numpy_ringbuffer import RingBuffer
from gnuradio import gr
+from fadingui.logger import get_logger
+log = get_logger("xor_frame_sync")
+
class xor_frame_sync(gr.sync_block):
"""
@@ -26,6 +29,7 @@ class xor_frame_sync(gr.sync_block):
self.nbytes = len(sync_pattern)
self.nbits = len(self.pattern)
+ log.debug(f"Loaded pattern {self.pattern} length={self.nbits}")
assert(self.nbits % 8 == 0)
# packed buffer to delay the data
@@ -84,12 +88,14 @@ class xor_frame_sync(gr.sync_block):
self.delaybuf.appendleft(v)
peak = np.argmax(self.xcorrs)
- self.delay = peak
- self.synchronized = True
+ if self.xcorrs[peak] == self.nbits:
+ self.delay = peak
+ self.synchronized = True
+ log.debug(f"Synchronized with delay={peak}")
- if self.xcorrs[peak] != self.nbits:
+ else:
self.synchronized = False
- print(f"Warning! XOR correlation did not find a peak (max = {self.xcorrs[peak]} should be {self.nbits})")
+ log.warning(f"Did not find a peak (max={self.xcorrs[peak]}, should be {self.nbits})")
# return data with delay
diff --git a/tests/fadingui/QAM/hammingtest.py b/tests/fadingui/QAM/hammingtest.py
new file mode 100755
index 0000000..b72e386
--- /dev/null
+++ b/tests/fadingui/QAM/hammingtest.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+import numpy as np
+from fadingui import frame_obj
+
+f = frame_obj([1,0], 10)
+q = np.random.randint(0, 2, size=26)
+
+parity = f.parity(q)
+enc = np.concatenate([q, parity])
+
+print(q)
+print(parity)
+print(enc)
+print(f.syndrome(enc))
diff --git a/tests/fadingui/QAM/qam_nogui.grc b/tests/fadingui/QAM/qam_nogui.grc
index 83c8059..c3d886e 100644
--- a/tests/fadingui/QAM/qam_nogui.grc
+++ b/tests/fadingui/QAM/qam_nogui.grc
@@ -8,7 +8,7 @@ options:
description: ''
gen_cmake: 'On'
gen_linking: dynamic
- generate_options: no_gui
+ generate_options: qt_gui
hier_block_src_path: '.:'
id: qam_nogui
max_nouts: '0'
@@ -18,7 +18,7 @@ options:
realtime_scheduling: '1'
run: 'True'
run_command: '{python} -u {filename}'
- run_options: prompt
+ run_options: run
sizing_mode: fixed
thread_safe_setters: ''
title: QAM
@@ -59,7 +59,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [440, 604.0]
+ coordinate: [448, 436.0]
rotation: 0
state: true
- name: eq_gain
@@ -110,6 +110,20 @@ blocks:
coordinate: [536, 268.0]
rotation: 0
state: true
+- name: frame
+ id: fadingui_frame_obj
+ parameters:
+ alias: ''
+ comment: ''
+ payload_len: '32768'
+ preamble: '[190, 239]'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [192, 180.0]
+ rotation: 0
+ state: true
- name: freq_offset
id: variable
parameters:
@@ -138,7 +152,7 @@ blocks:
id: variable
parameters:
comment: ''
- value: 100e-6
+ value: '0'
states:
bus_sink: false
bus_source: false
@@ -150,7 +164,7 @@ blocks:
id: variable
parameters:
comment: ''
- value: 2 * 3.141592653589793 / 100
+ value: '.002'
states:
bus_sink: false
bus_source: false
@@ -158,27 +172,6 @@ blocks:
coordinate: [1792, 428.0]
rotation: 0
state: true
-- name: qam_const
- id: variable_constellation_rect
- parameters:
- comment: ''
- const_points: '[(-3-3j), (-1-3j), (1-3j), (3-3j), (-3-1j), (-1-1j), (1-1j), (3-1j),
- (-3+1j), (-1+1j), (1+1j), (3+1j), (-3+3j), (-1+3j), (1+3j), (3+3j)]'
- imag_sect: '1'
- precision: '4'
- real_sect: '1'
- rot_sym: '4'
- soft_dec_lut: None
- sym_map: '[0, 4, 12, 8, 1, 5, 13, 9, 3, 7, 15, 11, 2, 6, 14, 10]'
- w_imag_sect: '1'
- w_real_sect: '1'
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [440, 444.0]
- rotation: 0
- state: true
- name: rrc_taps
id: variable
parameters:
@@ -200,7 +193,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [192, 12.0]
+ coordinate: [232, 12.0]
rotation: 0
state: enabled
- name: sps
@@ -239,18 +232,6 @@ blocks:
coordinate: [1184, 556.0]
rotation: 0
state: true
-- name: variable_4
- id: variable
- parameters:
- comment: ''
- value: '0'
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [1312, 556.0]
- rotation: 0
- state: true
- name: blocks_null_sink_0
id: blocks_null_sink
parameters:
@@ -265,7 +246,7 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [2584, 456.0]
+ coordinate: [2824, 312.0]
rotation: 0
state: true
- name: blocks_throttle_0
@@ -284,27 +265,9 @@ blocks:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [688, 356.0]
+ coordinate: [720, 356.0]
rotation: 0
state: enabled
-- name: blocks_vector_to_stream_0
- id: blocks_vector_to_stream
- parameters:
- affinity: ''
- alias: ''
- comment: ''
- maxoutbuf: '0'
- minoutbuf: '0'
- num_items: '2048'
- type: byte
- vlen: '1'
- states:
- bus_sink: false
- bus_source: false
- bus_structure: null
- coordinate: [248, 360.0]
- rotation: 0
- state: true
- name: channels_channel_model_0
id: channels_channel_model
parameters:
@@ -461,17 +424,15 @@ blocks:
affinity: ''
alias: ''
comment: ''
- file_list: '["./lena512color.tiff"]'
- header_len: '11'
+ fname: /home/god/Documents/Fading/tests/fadingui/QAM/lena512color.tiff
+ frame_obj: frame
maxoutbuf: '0'
minoutbuf: '0'
- sock_addr: udp://
- vec_len: '2037'
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [72, 212.0]
+ coordinate: [144, 284.0]
rotation: 0
state: true
- name: fadingui_dearpygui_sink_0
@@ -489,39 +450,149 @@ blocks:
coordinate: [2096, 180.0]
rotation: 0
state: disabled
+- name: fadingui_deframer_0
+ id: fadingui_deframer
+ parameters:
+ affinity: ''
+ alias: ''
+ comment: ''
+ frame_obj: frame
+ maxoutbuf: '0'
+ minoutbuf: '0'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [2592, 452.0]
+ rotation: 0
+ state: true
- name: fadingui_xor_frame_sync_0
id: fadingui_xor_frame_sync
parameters:
affinity: ''
alias: ''
- buffer_size: '2048'
+ buffer_size: frame.length * 4
comment: ''
maxoutbuf: '0'
minoutbuf: '0'
- pattern: '[0xbe, 0xef]'
- pattern_len: '16'
+ pattern: frame.preamble
states:
bus_sink: false
bus_source: false
bus_structure: null
- coordinate: [2312, 436.0]
+ coordinate: [2312, 444.0]
rotation: 0
state: true
+- name: qtgui_const_sink_x_0
+ id: qtgui_const_sink_x
+ parameters:
+ affinity: ''
+ alias: ''
+ alpha1: '1.0'
+ alpha10: '1.0'
+ alpha2: '1.0'
+ alpha3: '1.0'
+ alpha4: '1.0'
+ alpha5: '1.0'
+ alpha6: '1.0'
+ alpha7: '1.0'
+ alpha8: '1.0'
+ alpha9: '1.0'
+ autoscale: 'False'
+ axislabels: 'True'
+ color1: '"blue"'
+ color10: '"red"'
+ color2: '"red"'
+ color3: '"red"'
+ color4: '"red"'
+ color5: '"red"'
+ color6: '"red"'
+ color7: '"red"'
+ color8: '"red"'
+ color9: '"red"'
+ comment: ''
+ grid: 'False'
+ gui_hint: ''
+ label1: ''
+ label10: ''
+ label2: ''
+ label3: ''
+ label4: ''
+ label5: ''
+ label6: ''
+ label7: ''
+ label8: ''
+ label9: ''
+ legend: 'True'
+ marker1: '0'
+ marker10: '0'
+ marker2: '0'
+ marker3: '0'
+ marker4: '0'
+ marker5: '0'
+ marker6: '0'
+ marker7: '0'
+ marker8: '0'
+ marker9: '0'
+ name: '""'
+ nconnections: '3'
+ size: '1024'
+ style1: '0'
+ style10: '0'
+ style2: '0'
+ style3: '0'
+ style4: '0'
+ style5: '0'
+ style6: '0'
+ style7: '0'
+ style8: '0'
+ style9: '0'
+ tr_chan: '0'
+ tr_level: '0.0'
+ tr_mode: qtgui.TRIG_MODE_FREE
+ tr_slope: qtgui.TRIG_SLOPE_POS
+ tr_tag: '""'
+ type: complex
+ update_time: '0.10'
+ width1: '1'
+ width10: '1'
+ width2: '1'
+ width3: '1'
+ width4: '1'
+ width5: '1'
+ width6: '1'
+ width7: '1'
+ width8: '1'
+ width9: '1'
+ xmax: '2'
+ xmin: '-2'
+ ymax: '2'
+ ymin: '-2'
+ states:
+ bus_sink: false
+ bus_source: false
+ bus_structure: null
+ coordinate: [2040, 32.0]
+ rotation: 0
+ state: enabled
connections:
- [blocks_throttle_0, '0', channels_channel_model_0, '0']
-- [blocks_vector_to_stream_0, '0', digital_constellation_modulator_0, '0']
- [channels_channel_model_0, '0', digital_pfb_clock_sync_xxx_0, '0']
- [digital_cma_equalizer_cc_0, '0', digital_costas_loop_cc_0, '0']
+- [digital_cma_equalizer_cc_0, '0', qtgui_const_sink_x_0, '1']
- [digital_constellation_decoder_cb_0, '0', digital_diff_decoder_bb_0, '0']
- [digital_constellation_modulator_0, '0', blocks_throttle_0, '0']
- [digital_costas_loop_cc_0, '0', digital_constellation_decoder_cb_0, '0']
- [digital_costas_loop_cc_0, '0', fadingui_dearpygui_sink_0, '0']
+- [digital_costas_loop_cc_0, '0', qtgui_const_sink_x_0, '2']
- [digital_diff_decoder_bb_0, '0', digital_map_bb_0, '0']
- [digital_map_bb_0, '0', fadingui_xor_frame_sync_0, '0']
- [digital_pfb_clock_sync_xxx_0, '0', digital_cma_equalizer_cc_0, '0']
-- [fadingui_datasource_0, '0', blocks_vector_to_stream_0, '0']
-- [fadingui_xor_frame_sync_0, '0', blocks_null_sink_0, '0']
+- [digital_pfb_clock_sync_xxx_0, '0', qtgui_const_sink_x_0, '0']
+- [fadingui_datasource_0, '0', digital_constellation_modulator_0, '0']
+- [fadingui_deframer_0, '0', blocks_null_sink_0, '0']
+- [fadingui_xor_frame_sync_0, '0', fadingui_deframer_0, '0']
metadata:
file_format: 1
diff --git a/tests/fadingui/QAM/qam_nogui.py b/tests/fadingui/QAM/qam_nogui.py
index 1da693e..6cde63d 100755
--- a/tests/fadingui/QAM/qam_nogui.py
+++ b/tests/fadingui/QAM/qam_nogui.py
@@ -9,6 +9,21 @@
# Author: Pross Naoki, Halter Sara Cinzia
# GNU Radio version: 3.8.2.0
+from distutils.version import StrictVersion
+
+if __name__ == '__main__':
+ import ctypes
+ import sys
+ if sys.platform.startswith('linux'):
+ try:
+ x11 = ctypes.cdll.LoadLibrary('libX11.so')
+ x11.XInitThreads()
+ except:
+ print("Warning: failed to XInitThreads()")
+
+from PyQt5 import Qt
+from gnuradio import qtgui
+import sip
from gnuradio import blocks
from gnuradio import channels
from gnuradio.filter import firdes
@@ -21,11 +36,40 @@ from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
import fadingui
+from gnuradio import qtgui
-class qam_nogui(gr.top_block):
+class qam_nogui(gr.top_block, Qt.QWidget):
def __init__(self):
gr.top_block.__init__(self, "QAM")
+ Qt.QWidget.__init__(self)
+ self.setWindowTitle("QAM")
+ qtgui.util.check_set_qss()
+ try:
+ self.setWindowIcon(Qt.QIcon.fromTheme('gnuradio-grc'))
+ except:
+ pass
+ self.top_scroll_layout = Qt.QVBoxLayout()
+ self.setLayout(self.top_scroll_layout)
+ self.top_scroll = Qt.QScrollArea()
+ self.top_scroll.setFrameStyle(Qt.QFrame.NoFrame)
+ self.top_scroll_layout.addWidget(self.top_scroll)
+ self.top_scroll.setWidgetResizable(True)
+ self.top_widget = Qt.QWidget()
+ self.top_scroll.setWidget(self.top_widget)
+ self.top_layout = Qt.QVBoxLayout(self.top_widget)
+ self.top_grid_layout = Qt.QGridLayout()
+ self.top_layout.addLayout(self.top_grid_layout)
+
+ self.settings = Qt.QSettings("GNU Radio", "qam_nogui")
+
+ try:
+ if StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
+ self.restoreGeometry(self.settings.value("geometry").toByteArray())
+ else:
+ self.restoreGeometry(self.settings.value("geometry"))
+ except:
+ pass
##################################################
# Variables
@@ -33,16 +77,14 @@ class qam_nogui(gr.top_block):
self.sps = sps = 4
self.nfilts = nfilts = 32
self.excess_bw = excess_bw = 350e-3
- self.variable_4 = variable_4 = 0
self.timing_loop_bw = timing_loop_bw = 2 * 3.141592653589793 / 100
self.time_offset = time_offset = 1
self.samp_rate = samp_rate = 32000
self.rrc_taps = rrc_taps = firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), excess_bw, 45*nfilts)
- self.qam_const = qam_const = digital.constellation_rect([(-3-3j), (-1-3j), (1-3j), (3-3j), (-3-1j), (-1-1j), (1-1j), (3-1j), (-3+1j), (-1+1j), (1+1j), (3+1j), (-3+3j), (-1+3j), (1+3j), (3+3j)], [0, 4, 12, 8, 1, 5, 13, 9, 3, 7, 15, 11, 2, 6, 14, 10],
- 4, 1, 1, 1, 1).base()
- self.phase_bw = phase_bw = 2 * 3.141592653589793 / 100
- self.noise_volt = noise_volt = 100e-6
+ self.phase_bw = phase_bw = .002
+ self.noise_volt = noise_volt = 0
self.freq_offset = freq_offset = 0
+ self.frame = frame = fadingui.frame_obj(preamble=[190, 239], payload_len=32768)
self.eq_ntaps = eq_ntaps = 15
self.eq_mod = eq_mod = 1
self.eq_gain = eq_gain = 10e-3
@@ -52,8 +94,49 @@ class qam_nogui(gr.top_block):
##################################################
# Blocks
##################################################
- 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.qtgui_const_sink_x_0 = qtgui.const_sink_c(
+ 1024, #size
+ "", #name
+ 3 #number of inputs
+ )
+ self.qtgui_const_sink_x_0.set_update_time(0.10)
+ self.qtgui_const_sink_x_0.set_y_axis(-2, 2)
+ self.qtgui_const_sink_x_0.set_x_axis(-2, 2)
+ self.qtgui_const_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, "")
+ self.qtgui_const_sink_x_0.enable_autoscale(False)
+ self.qtgui_const_sink_x_0.enable_grid(False)
+ self.qtgui_const_sink_x_0.enable_axis_labels(True)
+
+
+ labels = ['', '', '', '', '',
+ '', '', '', '', '']
+ widths = [1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1]
+ colors = ["blue", "red", "red", "red", "red",
+ "red", "red", "red", "red", "red"]
+ styles = [0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0]
+ markers = [0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0]
+ alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
+ 1.0, 1.0, 1.0, 1.0, 1.0]
+
+ for i in range(3):
+ if len(labels[i]) == 0:
+ self.qtgui_const_sink_x_0.set_line_label(i, "Data {0}".format(i))
+ else:
+ self.qtgui_const_sink_x_0.set_line_label(i, labels[i])
+ self.qtgui_const_sink_x_0.set_line_width(i, widths[i])
+ self.qtgui_const_sink_x_0.set_line_color(i, colors[i])
+ self.qtgui_const_sink_x_0.set_line_style(i, styles[i])
+ self.qtgui_const_sink_x_0.set_line_marker(i, markers[i])
+ self.qtgui_const_sink_x_0.set_line_alpha(i, alphas[i])
+
+ self._qtgui_const_sink_x_0_win = sip.wrapinstance(self.qtgui_const_sink_x_0.pyqwidget(), Qt.QWidget)
+ self.top_grid_layout.addWidget(self._qtgui_const_sink_x_0_win)
+ self.fadingui_xor_frame_sync_0 = fadingui.xor_frame_sync(sync_pattern=frame.preamble, buffer_size=frame.length * 4)
+ self.fadingui_deframer_0 = fadingui.deframer(frame_obj=frame)
+ self.fadingui_datasource_0 = fadingui.datasource(frame_obj=frame, filename='/home/god/Documents/Fading/tests/fadingui/QAM/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])
self.digital_diff_decoder_bb_0 = digital.diff_decoder_bb(4)
@@ -75,7 +158,6 @@ class qam_nogui(gr.top_block):
taps=chn_taps,
noise_seed=0,
block_tags=False)
- self.blocks_vector_to_stream_0 = blocks.vector_to_stream(gr.sizeof_char*1, 2048)
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_gr_complex*1, samp_rate,True)
self.blocks_null_sink_0 = blocks.null_sink(gr.sizeof_char*1)
@@ -85,18 +167,26 @@ class qam_nogui(gr.top_block):
# Connections
##################################################
self.connect((self.blocks_throttle_0, 0), (self.channels_channel_model_0, 0))
- self.connect((self.blocks_vector_to_stream_0, 0), (self.digital_constellation_modulator_0, 0))
self.connect((self.channels_channel_model_0, 0), (self.digital_pfb_clock_sync_xxx_0, 0))
self.connect((self.digital_cma_equalizer_cc_0, 0), (self.digital_costas_loop_cc_0, 0))
+ self.connect((self.digital_cma_equalizer_cc_0, 0), (self.qtgui_const_sink_x_0, 1))
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.qtgui_const_sink_x_0, 2))
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))
- self.connect((self.fadingui_datasource_0, 0), (self.blocks_vector_to_stream_0, 0))
- self.connect((self.fadingui_xor_frame_sync_0, 0), (self.blocks_null_sink_0, 0))
+ self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.qtgui_const_sink_x_0, 0))
+ self.connect((self.fadingui_datasource_0, 0), (self.digital_constellation_modulator_0, 0))
+ self.connect((self.fadingui_deframer_0, 0), (self.blocks_null_sink_0, 0))
+ self.connect((self.fadingui_xor_frame_sync_0, 0), (self.fadingui_deframer_0, 0))
+
+ def closeEvent(self, event):
+ self.settings = Qt.QSettings("GNU Radio", "qam_nogui")
+ self.settings.setValue("geometry", self.saveGeometry())
+ event.accept()
def get_sps(self):
return self.sps
@@ -119,12 +209,6 @@ class qam_nogui(gr.top_block):
self.excess_bw = excess_bw
self.set_rrc_taps(firdes.root_raised_cosine(self.nfilts, self.nfilts, 1.0/float(self.sps), self.excess_bw, 45*self.nfilts))
- def get_variable_4(self):
- return self.variable_4
-
- def set_variable_4(self, variable_4):
- self.variable_4 = variable_4
-
def get_timing_loop_bw(self):
return self.timing_loop_bw
@@ -153,12 +237,6 @@ class qam_nogui(gr.top_block):
self.rrc_taps = rrc_taps
self.digital_pfb_clock_sync_xxx_0.update_taps(self.rrc_taps)
- def get_qam_const(self):
- return self.qam_const
-
- def set_qam_const(self, qam_const):
- self.qam_const = qam_const
-
def get_phase_bw(self):
return self.phase_bw
@@ -180,6 +258,12 @@ class qam_nogui(gr.top_block):
self.freq_offset = freq_offset
self.channels_channel_model_0.set_frequency_offset(self.freq_offset)
+ def get_frame(self):
+ return self.frame
+
+ def set_frame(self, frame):
+ self.frame = frame
+
def get_eq_ntaps(self):
return self.eq_ntaps
@@ -220,26 +304,34 @@ class qam_nogui(gr.top_block):
def main(top_block_cls=qam_nogui, options=None):
if gr.enable_realtime_scheduling() != gr.RT_OK:
print("Error: failed to enable real-time scheduling.")
+
+ if StrictVersion("4.5.0") <= StrictVersion(Qt.qVersion()) < StrictVersion("5.0.0"):
+ style = gr.prefs().get_string('qtgui', 'style', 'raster')
+ Qt.QApplication.setGraphicsSystem(style)
+ qapp = Qt.QApplication(sys.argv)
+
tb = top_block_cls()
- def sig_handler(sig=None, frame=None):
- tb.stop()
- tb.wait()
+ tb.start()
- sys.exit(0)
+ tb.show()
+
+ def sig_handler(sig=None, frame=None):
+ Qt.QApplication.quit()
signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)
- tb.start()
+ timer = Qt.QTimer()
+ timer.start(500)
+ timer.timeout.connect(lambda: None)
- try:
- input('Press Enter to quit: ')
- except EOFError:
- pass
- tb.stop()
- tb.wait()
+ def quitting():
+ tb.stop()
+ tb.wait()
+ qapp.aboutToQuit.connect(quitting)
+ qapp.exec_()
if __name__ == '__main__':
main()