Tuesday, July 14, 2020

Re: Question regarding transmission of a tone using QPSK

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#
# SPDX-License-Identifier: GPL-3.0
#
# GNU Radio Python Flow Graph
# Title: qpsk_audiochannel
# Author: lannanjiang
# GNU Radio version: 3.8.1.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
from gnuradio.filter import firdes
import sip
from gnuradio import analog
from gnuradio import blocks
from gnuradio import channels
from gnuradio import digital
from gnuradio import fec
from gnuradio import gr
import sys
import signal
from argparse import ArgumentParser
from gnuradio.eng_arg import eng_float, intx
from gnuradio import eng_notation
from gnuradio.qtgui import Range, RangeWidget
from gnuradio import qtgui

class QPSK_AUDIOCHANNEL(gr.top_block, Qt.QWidget):

def __init__(self):
gr.top_block.__init__(self, "qpsk_audiochannel")
Qt.QWidget.__init__(self)
self.setWindowTitle("qpsk_audiochannel")
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", "QPSK_AUDIOCHANNEL")

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
##################################################
self.sps = sps = 4
self.nfilts = nfilts = 32
self.timing_loop_bw = timing_loop_bw = 6.28/100.0
self.time_offset = time_offset = 1.00
self.taps = taps = [1.0, 0.25-0.25j, 0.50 + 0.10j, -0.3 + 0.2j]
self.samplingPluto = samplingPluto = 960000
self.samp_rate = samp_rate = 48000
self.rrc_taps = rrc_taps = firdes.root_raised_cosine(nfilts, nfilts, 1.0/float(sps), 0.35, 11*sps*nfilts)
self.qpsk = qpsk = digital.constellation_rect([0.707+0.707j, -0.707+0.707j, -0.707-0.707j, 0.707-0.707j], [0, 1, 2, 3],
4, 2, 2, 1, 1).base()
self.phase_bw = phase_bw = 6.28/100.0
self.noise_volt = noise_volt = 0.0001
self.interp = interp = 10
self.freq_offset = freq_offset = 0
self.excess_bw = excess_bw = 0.35
self.eq_gain = eq_gain = 0.01
self.delay = delay = 0
self.arity = arity = 4

##################################################
# Blocks
##################################################
self.controls = Qt.QTabWidget()
self.controls_widget_0 = Qt.QWidget()
self.controls_layout_0 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.controls_widget_0)
self.controls_grid_layout_0 = Qt.QGridLayout()
self.controls_layout_0.addLayout(self.controls_grid_layout_0)
self.controls.addTab(self.controls_widget_0, 'Channel')
self.controls_widget_1 = Qt.QWidget()
self.controls_layout_1 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.controls_widget_1)
self.controls_grid_layout_1 = Qt.QGridLayout()
self.controls_layout_1.addLayout(self.controls_grid_layout_1)
self.controls.addTab(self.controls_widget_1, 'Receiver')
self.top_grid_layout.addWidget(self.controls, 0, 0, 1, 2)
for r in range(0, 1):
self.top_grid_layout.setRowStretch(r, 1)
for c in range(0, 2):
self.top_grid_layout.setColumnStretch(c, 1)
self._timing_loop_bw_range = Range(0.0, 0.2, 0.01, 6.28/100.0, 200)
self._timing_loop_bw_win = RangeWidget(self._timing_loop_bw_range, self.set_timing_loop_bw, 'Time: BW', "slider", float)
self.controls_grid_layout_1.addWidget(self._timing_loop_bw_win, 0, 0, 1, 1)
for r in range(0, 1):
self.controls_grid_layout_1.setRowStretch(r, 1)
for c in range(0, 1):
self.controls_grid_layout_1.setColumnStretch(c, 1)
self._time_offset_range = Range(0.999, 1.001, 0.0001, 1.00, 200)
self._time_offset_win = RangeWidget(self._time_offset_range, self.set_time_offset, 'Timing Offset', "counter_slider", float)
self.controls_grid_layout_0.addWidget(self._time_offset_win, 0, 2, 1, 1)
for r in range(0, 1):
self.controls_grid_layout_0.setRowStretch(r, 1)
for c in range(2, 3):
self.controls_grid_layout_0.setColumnStretch(c, 1)
self.received = Qt.QTabWidget()
self.received_widget_0 = Qt.QWidget()
self.received_layout_0 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.received_widget_0)
self.received_grid_layout_0 = Qt.QGridLayout()
self.received_layout_0.addLayout(self.received_grid_layout_0)
self.received.addTab(self.received_widget_0, 'Constellation')
self.received_widget_1 = Qt.QWidget()
self.received_layout_1 = Qt.QBoxLayout(Qt.QBoxLayout.TopToBottom, self.received_widget_1)
self.received_grid_layout_1 = Qt.QGridLayout()
self.received_layout_1.addLayout(self.received_grid_layout_1)
self.received.addTab(self.received_widget_1, 'Symbols')
self.top_grid_layout.addWidget(self.received, 2, 0, 1, 1)
for r in range(2, 3):
self.top_grid_layout.setRowStretch(r, 1)
for c in range(0, 1):
self.top_grid_layout.setColumnStretch(c, 1)
self._phase_bw_range = Range(0.0, 1.0, 0.01, 6.28/100.0, 200)
self._phase_bw_win = RangeWidget(self._phase_bw_range, self.set_phase_bw, 'Phase: Bandwidth', "slider", float)
self.controls_grid_layout_1.addWidget(self._phase_bw_win, 0, 2, 1, 1)
for r in range(0, 1):
self.controls_grid_layout_1.setRowStretch(r, 1)
for c in range(2, 3):
self.controls_grid_layout_1.setColumnStretch(c, 1)
self._noise_volt_range = Range(0, 1, 0.01, 0.0001, 200)
self._noise_volt_win = RangeWidget(self._noise_volt_range, self.set_noise_volt, 'Noise Voltage', "counter_slider", float)
self.controls_grid_layout_0.addWidget(self._noise_volt_win, 0, 0, 1, 1)
for r in range(0, 1):
self.controls_grid_layout_0.setRowStretch(r, 1)
for c in range(0, 1):
self.controls_grid_layout_0.setColumnStretch(c, 1)
self._freq_offset_range = Range(-0.1, 0.1, 0.001, 0, 200)
self._freq_offset_win = RangeWidget(self._freq_offset_range, self.set_freq_offset, 'Frequency Offset', "counter_slider", float)
self.controls_grid_layout_0.addWidget(self._freq_offset_win, 0, 1, 1, 1)
for r in range(0, 1):
self.controls_grid_layout_0.setRowStretch(r, 1)
for c in range(1, 2):
self.controls_grid_layout_0.setColumnStretch(c, 1)
self._eq_gain_range = Range(0.0, 0.1, 0.001, 0.01, 200)
self._eq_gain_win = RangeWidget(self._eq_gain_range, self.set_eq_gain, 'Equalizer: rate', "slider", float)
self.controls_grid_layout_1.addWidget(self._eq_gain_win, 0, 1, 1, 1)
for r in range(0, 1):
self.controls_grid_layout_1.setRowStretch(r, 1)
for c in range(1, 2):
self.controls_grid_layout_1.setColumnStretch(c, 1)
self._delay_range = Range(0, 200, 1, 0, 200)
self._delay_win = RangeWidget(self._delay_range, self.set_delay, 'Delay', "counter_slider", float)
self.top_grid_layout.addWidget(self._delay_win, 1, 0, 1, 1)
for r in range(1, 2):
self.top_grid_layout.setRowStretch(r, 1)
for c in range(0, 1):
self.top_grid_layout.setColumnStretch(c, 1)
self.qtgui_time_sink_x_0_0_1 = qtgui.time_sink_f(
500, #size
samp_rate, #samp_rate
'', #name
2 #number of inputs
)
self.qtgui_time_sink_x_0_0_1.set_update_time(0.10)
self.qtgui_time_sink_x_0_0_1.set_y_axis(-1, 2)

self.qtgui_time_sink_x_0_0_1.set_y_label('Amplitude', "")

self.qtgui_time_sink_x_0_0_1.enable_tags(True)
self.qtgui_time_sink_x_0_0_1.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "")
self.qtgui_time_sink_x_0_0_1.enable_autoscale(False)
self.qtgui_time_sink_x_0_0_1.enable_grid(True)
self.qtgui_time_sink_x_0_0_1.enable_axis_labels(True)
self.qtgui_time_sink_x_0_0_1.enable_control_panel(False)
self.qtgui_time_sink_x_0_0_1.enable_stem_plot(False)


labels = ['Rx Bits', 'Tx Bits', '', '', '',
'', '', '', '', '']
widths = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
colors = ['blue', 'red', 'green', 'black', 'cyan',
'magenta', 'yellow', 'dark red', 'dark green', 'dark blue']
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
styles = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
markers = [-1, -1, -1, -1, -1,
-1, -1, -1, -1, -1]


for i in range(2):
if len(labels[i]) == 0:
self.qtgui_time_sink_x_0_0_1.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_time_sink_x_0_0_1.set_line_label(i, labels[i])
self.qtgui_time_sink_x_0_0_1.set_line_width(i, widths[i])
self.qtgui_time_sink_x_0_0_1.set_line_color(i, colors[i])
self.qtgui_time_sink_x_0_0_1.set_line_style(i, styles[i])
self.qtgui_time_sink_x_0_0_1.set_line_marker(i, markers[i])
self.qtgui_time_sink_x_0_0_1.set_line_alpha(i, alphas[i])

self._qtgui_time_sink_x_0_0_1_win = sip.wrapinstance(self.qtgui_time_sink_x_0_0_1.pyqwidget(), Qt.QWidget)
self.top_grid_layout.addWidget(self._qtgui_time_sink_x_0_0_1_win, 2, 1, 1, 1)
for r in range(2, 3):
self.top_grid_layout.setRowStretch(r, 1)
for c in range(1, 2):
self.top_grid_layout.setColumnStretch(c, 1)
self.qtgui_time_sink_x_0_0 = qtgui.time_sink_f(
500, #size
samp_rate, #samp_rate
'', #name
1 #number of inputs
)
self.qtgui_time_sink_x_0_0.set_update_time(0.10)
self.qtgui_time_sink_x_0_0.set_y_axis(-1, 4)

self.qtgui_time_sink_x_0_0.set_y_label('Amplitude', "")

self.qtgui_time_sink_x_0_0.enable_tags(True)
self.qtgui_time_sink_x_0_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "")
self.qtgui_time_sink_x_0_0.enable_autoscale(False)
self.qtgui_time_sink_x_0_0.enable_grid(False)
self.qtgui_time_sink_x_0_0.enable_axis_labels(True)
self.qtgui_time_sink_x_0_0.enable_control_panel(False)
self.qtgui_time_sink_x_0_0.enable_stem_plot(False)


labels = ['Symbols', '', '', '', '',
'', '', '', '', '']
widths = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
colors = ['blue', 'red', 'green', 'black', 'cyan',
'magenta', 'yellow', 'dark red', 'dark green', 'dark blue']
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
styles = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
markers = [-1, -1, -1, -1, -1,
-1, -1, -1, -1, -1]


for i in range(1):
if len(labels[i]) == 0:
self.qtgui_time_sink_x_0_0.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_time_sink_x_0_0.set_line_label(i, labels[i])
self.qtgui_time_sink_x_0_0.set_line_width(i, widths[i])
self.qtgui_time_sink_x_0_0.set_line_color(i, colors[i])
self.qtgui_time_sink_x_0_0.set_line_style(i, styles[i])
self.qtgui_time_sink_x_0_0.set_line_marker(i, markers[i])
self.qtgui_time_sink_x_0_0.set_line_alpha(i, alphas[i])

self._qtgui_time_sink_x_0_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0_0.pyqwidget(), Qt.QWidget)
self.received_grid_layout_1.addWidget(self._qtgui_time_sink_x_0_0_win, 0, 0, 1, 1)
for r in range(0, 1):
self.received_grid_layout_1.setRowStretch(r, 1)
for c in range(0, 1):
self.received_grid_layout_1.setColumnStretch(c, 1)
self.qtgui_time_sink_x_0 = qtgui.time_sink_f(
1024, #size
samp_rate, #samp_rate
"", #name
1 #number of inputs
)
self.qtgui_time_sink_x_0.set_update_time(0.10)
self.qtgui_time_sink_x_0.set_y_axis(-1, 1)

self.qtgui_time_sink_x_0.set_y_label('Amplitude', "")

self.qtgui_time_sink_x_0.enable_tags(True)
self.qtgui_time_sink_x_0.set_trigger_mode(qtgui.TRIG_MODE_FREE, qtgui.TRIG_SLOPE_POS, 0.0, 0, 0, "")
self.qtgui_time_sink_x_0.enable_autoscale(False)
self.qtgui_time_sink_x_0.enable_grid(False)
self.qtgui_time_sink_x_0.enable_axis_labels(True)
self.qtgui_time_sink_x_0.enable_control_panel(False)
self.qtgui_time_sink_x_0.enable_stem_plot(False)


labels = ['Signal 1', 'Signal 2', 'Signal 3', 'Signal 4', 'Signal 5',
'Signal 6', 'Signal 7', 'Signal 8', 'Signal 9', 'Signal 10']
widths = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
colors = ['blue', 'red', 'green', 'black', 'cyan',
'magenta', 'yellow', 'dark red', 'dark green', 'dark blue']
alphas = [1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0]
styles = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]
markers = [-1, -1, -1, -1, -1,
-1, -1, -1, -1, -1]


for i in range(1):
if len(labels[i]) == 0:
self.qtgui_time_sink_x_0.set_line_label(i, "Data {0}".format(i))
else:
self.qtgui_time_sink_x_0.set_line_label(i, labels[i])
self.qtgui_time_sink_x_0.set_line_width(i, widths[i])
self.qtgui_time_sink_x_0.set_line_color(i, colors[i])
self.qtgui_time_sink_x_0.set_line_style(i, styles[i])
self.qtgui_time_sink_x_0.set_line_marker(i, markers[i])
self.qtgui_time_sink_x_0.set_line_alpha(i, alphas[i])

self._qtgui_time_sink_x_0_win = sip.wrapinstance(self.qtgui_time_sink_x_0.pyqwidget(), Qt.QWidget)
self.top_grid_layout.addWidget(self._qtgui_time_sink_x_0_win)
self.qtgui_number_sink_0 = qtgui.number_sink(
gr.sizeof_float,
0,
qtgui.NUM_GRAPH_HORIZ,
1
)
self.qtgui_number_sink_0.set_update_time(0.10)
self.qtgui_number_sink_0.set_title("")

labels = ['', '', '', '', '',
'', '', '', '', '']
units = ['', '', '', '', '',
'', '', '', '', '']
colors = [("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"),
("black", "black"), ("black", "black"), ("black", "black"), ("black", "black"), ("black", "black")]
factor = [1, 1, 1, 1, 1,
1, 1, 1, 1, 1]

for i in range(1):
self.qtgui_number_sink_0.set_min(i, -1)
self.qtgui_number_sink_0.set_max(i, 1)
self.qtgui_number_sink_0.set_color(i, colors[i][0], colors[i][1])
if len(labels[i]) == 0:
self.qtgui_number_sink_0.set_label(i, "Data {0}".format(i))
else:
self.qtgui_number_sink_0.set_label(i, labels[i])
self.qtgui_number_sink_0.set_unit(i, units[i])
self.qtgui_number_sink_0.set_factor(i, factor[i])

self.qtgui_number_sink_0.enable_autoscale(False)
self._qtgui_number_sink_0_win = sip.wrapinstance(self.qtgui_number_sink_0.pyqwidget(), Qt.QWidget)
self.top_grid_layout.addWidget(self._qtgui_number_sink_0_win)
self.qtgui_const_sink_x_0 = qtgui.const_sink_c(
1024, #size
"", #name
1 #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(1):
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.received_grid_layout_0.addWidget(self._qtgui_const_sink_x_0_win, 0, 0, 1, 1)
for r in range(0, 1):
self.received_grid_layout_0.setRowStretch(r, 1)
for c in range(0, 1):
self.received_grid_layout_0.setColumnStretch(c, 1)
self.fec_ber_bf_0 = fec.ber_bf(False, 100, -7.0)
self.digital_pfb_clock_sync_xxx_0 = digital.pfb_clock_sync_ccf(sps, timing_loop_bw, rrc_taps, nfilts, nfilts/2, 1.5, 2)
self.digital_map_bb_0 = digital.map_bb([0,1,2,3])
self.digital_diff_decoder_bb_0 = digital.diff_decoder_bb(4)
self.digital_costas_loop_cc_0 = digital.costas_loop_cc(phase_bw, arity, False)
self.digital_constellation_modulator_0 = digital.generic_mod(
constellation=qpsk,
differential=True,
samples_per_symbol=sps,
pre_diff_code=True,
excess_bw=excess_bw,
verbose=False,
log=False)
self.digital_constellation_decoder_cb_0 = digital.constellation_decoder_cb(qpsk)
self.digital_cma_equalizer_cc_0 = digital.cma_equalizer_cc(15, 1, eq_gain, 2)
self.channels_channel_model_0 = channels.channel_model(
noise_voltage=noise_volt,
frequency_offset=freq_offset,
epsilon=time_offset,
taps=taps,
noise_seed=0,
block_tags=False)
self.blocks_unpack_k_bits_bb_0_0 = blocks.unpack_k_bits_bb(8)
self.blocks_unpack_k_bits_bb_0 = blocks.unpack_k_bits_bb(2)
self.blocks_throttle_0 = blocks.throttle(gr.sizeof_char*1, samp_rate,True)
self.blocks_delay_0 = blocks.delay(gr.sizeof_float*1, int(delay))
self.blocks_char_to_float_1 = blocks.char_to_float(1, 1)
self.blocks_char_to_float_0_1 = blocks.char_to_float(1, 1)
self.blocks_char_to_float_0_0_0 = blocks.char_to_float(1, 1)
self.blocks_char_to_float_0_0 = blocks.char_to_float(1, 1)
self.analog_sig_source_x_0 = analog.sig_source_b(samp_rate, analog.GR_COS_WAVE, 1000, 1, 0, 0)

##################################################
# Connections
##################################################
self.connect((self.analog_sig_source_x_0, 0), (self.blocks_char_to_float_1, 0))
self.connect((self.analog_sig_source_x_0, 0), (self.blocks_throttle_0, 0))
self.connect((self.analog_sig_source_x_0, 0), (self.blocks_unpack_k_bits_bb_0_0, 0))
self.connect((self.blocks_char_to_float_0_0, 0), (self.qtgui_time_sink_x_0_0_1, 0))
self.connect((self.blocks_char_to_float_0_0_0, 0), (self.blocks_delay_0, 0))
self.connect((self.blocks_char_to_float_0_1, 0), (self.qtgui_time_sink_x_0_0, 0))
self.connect((self.blocks_char_to_float_1, 0), (self.qtgui_time_sink_x_0, 0))
self.connect((self.blocks_delay_0, 0), (self.qtgui_time_sink_x_0_0_1, 1))
self.connect((self.blocks_throttle_0, 0), (self.digital_constellation_modulator_0, 0))
self.connect((self.blocks_unpack_k_bits_bb_0, 0), (self.blocks_char_to_float_0_0, 0))
self.connect((self.blocks_unpack_k_bits_bb_0, 0), (self.fec_ber_bf_0, 1))
self.connect((self.blocks_unpack_k_bits_bb_0_0, 0), (self.blocks_char_to_float_0_0_0, 0))
self.connect((self.blocks_unpack_k_bits_bb_0_0, 0), (self.fec_ber_bf_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_constellation_decoder_cb_0, 0), (self.blocks_char_to_float_0_1, 0))
self.connect((self.digital_constellation_decoder_cb_0, 0), (self.digital_map_bb_0, 0))
self.connect((self.digital_constellation_modulator_0, 0), (self.channels_channel_model_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, 0))
self.connect((self.digital_diff_decoder_bb_0, 0), (self.blocks_unpack_k_bits_bb_0, 0))
self.connect((self.digital_map_bb_0, 0), (self.digital_diff_decoder_bb_0, 0))
self.connect((self.digital_pfb_clock_sync_xxx_0, 0), (self.digital_cma_equalizer_cc_0, 0))
self.connect((self.fec_ber_bf_0, 0), (self.qtgui_number_sink_0, 0))

def closeEvent(self, event):
self.settings = Qt.QSettings("GNU Radio", "QPSK_AUDIOCHANNEL")
self.settings.setValue("geometry", self.saveGeometry())
event.accept()

def get_sps(self):
return self.sps

def set_sps(self, sps):
self.sps = sps
self.set_rrc_taps(firdes.root_raised_cosine(self.nfilts, self.nfilts, 1.0/float(self.sps), 0.35, 11*self.sps*self.nfilts))

def get_nfilts(self):
return self.nfilts

def set_nfilts(self, nfilts):
self.nfilts = nfilts
self.set_rrc_taps(firdes.root_raised_cosine(self.nfilts, self.nfilts, 1.0/float(self.sps), 0.35, 11*self.sps*self.nfilts))

def get_timing_loop_bw(self):
return self.timing_loop_bw

def set_timing_loop_bw(self, timing_loop_bw):
self.timing_loop_bw = timing_loop_bw
self.digital_pfb_clock_sync_xxx_0.set_loop_bandwidth(self.timing_loop_bw)

def get_time_offset(self):
return self.time_offset

def set_time_offset(self, time_offset):
self.time_offset = time_offset
self.channels_channel_model_0.set_timing_offset(self.time_offset)

def get_taps(self):
return self.taps

def set_taps(self, taps):
self.taps = taps
self.channels_channel_model_0.set_taps(self.taps)

def get_samplingPluto(self):
return self.samplingPluto

def set_samplingPluto(self, samplingPluto):
self.samplingPluto = samplingPluto

def get_samp_rate(self):
return self.samp_rate

def set_samp_rate(self, samp_rate):
self.samp_rate = samp_rate
self.analog_sig_source_x_0.set_sampling_freq(self.samp_rate)
self.blocks_throttle_0.set_sample_rate(self.samp_rate)
self.qtgui_time_sink_x_0.set_samp_rate(self.samp_rate)
self.qtgui_time_sink_x_0_0.set_samp_rate(self.samp_rate)
self.qtgui_time_sink_x_0_0_1.set_samp_rate(self.samp_rate)

def get_rrc_taps(self):
return self.rrc_taps

def set_rrc_taps(self, rrc_taps):
self.rrc_taps = rrc_taps
self.digital_pfb_clock_sync_xxx_0.update_taps(self.rrc_taps)

def get_qpsk(self):
return self.qpsk

def set_qpsk(self, qpsk):
self.qpsk = qpsk

def get_phase_bw(self):
return self.phase_bw

def set_phase_bw(self, phase_bw):
self.phase_bw = phase_bw
self.digital_costas_loop_cc_0.set_loop_bandwidth(self.phase_bw)

def get_noise_volt(self):
return self.noise_volt

def set_noise_volt(self, noise_volt):
self.noise_volt = noise_volt
self.channels_channel_model_0.set_noise_voltage(self.noise_volt)

def get_interp(self):
return self.interp

def set_interp(self, interp):
self.interp = interp

def get_freq_offset(self):
return self.freq_offset

def set_freq_offset(self, freq_offset):
self.freq_offset = freq_offset
self.channels_channel_model_0.set_frequency_offset(self.freq_offset)

def get_excess_bw(self):
return self.excess_bw

def set_excess_bw(self, excess_bw):
self.excess_bw = excess_bw

def get_eq_gain(self):
return self.eq_gain

def set_eq_gain(self, eq_gain):
self.eq_gain = eq_gain
self.digital_cma_equalizer_cc_0.set_gain(self.eq_gain)

def get_delay(self):
return self.delay

def set_delay(self, delay):
self.delay = delay
self.blocks_delay_0.set_dly(int(self.delay))

def get_arity(self):
return self.arity

def set_arity(self, arity):
self.arity = arity

def main(top_block_cls=QPSK_AUDIOCHANNEL, options=None):

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()
tb.start()
tb.show()

def sig_handler(sig=None, frame=None):
Qt.QApplication.quit()

signal.signal(signal.SIGINT, sig_handler)
signal.signal(signal.SIGTERM, sig_handler)

timer = Qt.QTimer()
timer.start(500)
timer.timeout.connect(lambda: None)

def quitting():
tb.stop()
tb.wait()
qapp.aboutToQuit.connect(quitting)
qapp.exec_()


if __name__ == '__main__':
main()

Hi Jeff Long,
   Thank you so much for your reply.

   I understand the plot of the signal source now. I have the mpsk_stage6.grc running properly from the tutorial, and was able to compare the transmitting and receiving bit streams. I attached the grc file to this email. Additionally, could you please elaborate more on the byte output of the signal source? Are they packed? Unpacked?
   Moreover, as you stated that i should encode an analog signal to data before transmission, so does that mean I also have to use codecs in order to transmit a tone?
   My last question would be: if I were to transmit an mp3 file, which is already encoded, will i be able to recover the audio using audio decoders? 

  Thanks again for your help!

   Lannan Jiang

   ps: I apologize for my many questions as they may seem very basic. I am an engineering student and I am greatly thankful for your advice. 

  


From: Discuss-gnuradio <discuss-gnuradio-bounces+jln925=live.com@gnu.org> on behalf of Jeff Long <willcode4@gmail.com>
Sent: Tuesday, July 14, 2020 9:57 PM
To: GNURadio Discussion List <discuss-gnuradio@gnu.org>
Subject: Re: Question regarding transmission of a tone using QPSK
 
A better explanation of why that plot is correct: if you sample a tone twice per cycle, you see [-1,1,-1,1,...]. Four times per cycle, looks like [-1,0,1,0,...]. Even though it looks discontinuous, it will sound like a tone when played through your sound card due to filtering in the audio software and/or hardware.

That tutorial goes through the low level portions of the digital chain, including timing recovery. Framing, error correction and (optionally) an audio codec would all be in addition to the blocks shown in the tutorial.

On Tue, Jul 14, 2020 at 9:03 PM Jeff Long <willcode4@gmail.com> wrote:
Depending on your sample rate and tone frequency, that plot would be correct.

The analog signal needs to be encoded somehow as data before transmission. While you could feed an audio file 2 bits at a time into a QPSK modulator, it's pretty unlikely that you will be able to recover the audio. If you're thinking of "transmitting audio", look into audio codecs. If you're thinking of sending a wav file, you're really just sending packets. Either way, you will need a complete chain that includes error correction, clock recovery, etc.

On Tue, Jul 14, 2020 at 3:58 PM lannan jiang <jln925@live.com> wrote:
Hi all,
    I have been following the PSK guided tutorial https://wiki.gnuradio.org/index.php/Guided_Tutorial_PSK_Demodulation . I am on the mpsk_stage6.grc, but I want to transmit a simple tone instead of a random source, so I added a signal source which generates a sine wave. However, here are my questions:

   1.  I select the output of the signal source as bytes, and the time plot of it is attached. As you can see, the plot looks like bursts. But if I add an audio sink after signal source directly, I hear a constant tone. This does not make sense to me, as I thought I should hear discontinuous sound as the plot shows, could someone explain this?  

    2. With the first question being said,  I am using a constellation modulator (QPSK) that takes 2 bits/symbol.
    How can I feed the output  of signal source ( a 16-bit audio file later on) to the constellation modulator properly?  

Thanks in advance!

Regards,
Lannan Jiang

No comments:

Post a Comment