From 889dd05f251037c5989e007dffcb55541824768f Mon Sep 17 00:00:00 2001 From: Johannes Pohl Date: Fri, 1 May 2020 13:49:32 +0200 Subject: [PATCH] proper support for complex16u (2xuint8) signals (#772) * proper support for complex16 (2xint8) signals * fix Modulator: give correct iq type * fix View: Use general min/max and not from signal * Remove Padding * fix requirements.txt (skip PyQt5.14.2 on Windows) * fix noise area drawing * fix demod view range for FSK and PSK * Autofit signal in ModulatorDialog.py * optimize Unittests --- data/azure-pipelines.yml | 2 ++ data/requirements.txt | 3 +- src/urh/controller/dialogs/ModulatorDialog.py | 19 +++-------- src/urh/controller/widgets/SignalFrame.py | 2 ++ src/urh/cythonext/signal_functions.pyx | 29 +++++++++++++++-- src/urh/settings.py | 2 +- src/urh/signalprocessing/IQArray.py | 4 +-- src/urh/signalprocessing/Modulator.py | 5 +-- src/urh/signalprocessing/Signal.py | 23 ++++++++++--- src/urh/ui/painting/ContinuousSceneManager.py | 2 -- src/urh/ui/painting/LiveSceneManager.py | 2 -- src/urh/ui/painting/SceneManager.py | 22 ++----------- src/urh/ui/painting/SignalSceneManager.py | 7 +++- src/urh/ui/painting/SniffSceneManager.py | 2 -- .../ui/painting/SpectrogramSceneManager.py | 2 +- src/urh/ui/views/LegendGraphicView.py | 32 ------------------- .../ui/views/ZoomAndDropableGraphicView.py | 15 +++++++-- src/urh/ui/views/ZoomableGraphicView.py | 5 --- tests/QtTestCase.py | 10 ------ tests/test_decoding_gui.py | 1 - tests/test_demodulations.py | 4 +-- tests/test_file_operator.py | 2 -- tests/test_fuzzing_profile.py | 1 - tests/test_generator.py | 1 - tests/test_maincontroller_gui.py | 1 - tests/test_modulator.py | 10 +++--- tests/test_modulator_gui.py | 2 -- tests/test_options_gui.py | 1 - tests/test_plugins.py | 5 +-- tests/test_project_manager.py | 9 ++---- tests/test_protocol_label_dialog.py | 2 -- tests/test_signal_tab_GUI.py | 9 +----- tests/test_simulator_tab_gui.py | 3 ++ 33 files changed, 96 insertions(+), 143 deletions(-) delete mode 100644 src/urh/ui/views/LegendGraphicView.py diff --git a/data/azure-pipelines.yml b/data/azure-pipelines.yml index d7651229cc..86649ca3a1 100644 --- a/data/azure-pipelines.yml +++ b/data/azure-pipelines.yml @@ -252,6 +252,8 @@ jobs: - script: | brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/8d748e26ccc9afc8ea0d0201ae234fda35de721e/Formula/boost.rb + brew reinstall https://raw.githubusercontent.com/Homebrew/homebrew-core/a806a621ed3722fb580a58000fb274a2f2d86a6d/Formula/icu4c.rb + brew link icu4c --force cd /tmp wget https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.tar.bz2 tar xf libusb-1.0.22.tar.bz2 diff --git a/data/requirements.txt b/data/requirements.txt index b6defe3507..1a03352b56 100644 --- a/data/requirements.txt +++ b/data/requirements.txt @@ -1,5 +1,6 @@ numpy>=1.9; sys_platform != 'win32' numpy>=1.9,!=1.16.0; sys_platform == 'win32' -pyqt5 +pyqt5; sys_platform != 'win32' +pyqt5!=5.14.2; sys_platform == 'win32' psutil cython diff --git a/src/urh/controller/dialogs/ModulatorDialog.py b/src/urh/controller/dialogs/ModulatorDialog.py index c7c0ab4f62..27853e432e 100644 --- a/src/urh/controller/dialogs/ModulatorDialog.py +++ b/src/urh/controller/dialogs/ModulatorDialog.py @@ -41,16 +41,6 @@ def __init__(self, modulators, tree_model=None, parent=None): self.modulators = modulators - for graphic_view in (self.ui.gVCarrier, self.ui.gVData): - graphic_view.scene_y_min = -1 - graphic_view.scene_y_max = 1 - graphic_view.scene_x_zoom_stretch = 1.1 - - min_max_mod = IQArray.min_max_for_dtype(self.current_modulator.get_dtype()) - self.ui.gVModulated.scene_y_min = min_max_mod[0] - self.ui.gVModulated.scene_y_max = min_max_mod[1] - self.ui.gVModulated.scene_x_zoom_stretch = 1.1 - self.set_ui_for_current_modulator() self.ui.cbShowDataBitsOnly.setText(self.tr("Show Only Data Sequence\n")) @@ -132,8 +122,7 @@ def closeEvent(self, event: QCloseEvent): @property def current_modulator(self): - mod = self.modulators[self.ui.comboBoxCustomModulations.currentIndex()] - return mod + return self.modulators[self.ui.comboBoxCustomModulations.currentIndex()] def set_ui_for_current_modulator(self): index = self.ui.comboBoxModulationType.findText("*(" + self.current_modulator.modulation_type + ")", @@ -188,7 +177,7 @@ def draw_data_bits(self): self.ui.gVData.update() def draw_modulated(self): - self.ui.gVModulated.plot_data(self.current_modulator.modulate(pause=0).imag.astype(numpy.float32)) + self.ui.gVModulated.plot_data(self.current_modulator.modulate(pause=0).imag) if self.lock_samples_in_view: siv = self.ui.gVOriginalSignal.view_rect().width() self.adjust_samples_in_view(siv) @@ -203,8 +192,8 @@ def draw_original_signal(self, start=0, end=-1): if end == -1: end = scene_manager.signal.num_samples - y = scene_manager.scene.sceneRect().y() - h = scene_manager.scene.sceneRect().height() + y = self.ui.gVOriginalSignal.view_rect().y() + h = self.ui.gVOriginalSignal.view_rect().height() self.ui.gVOriginalSignal.setSceneRect(start, y, end - start, h) self.ui.gVOriginalSignal.fitInView(self.ui.gVOriginalSignal.sceneRect()) scene_manager.show_scene_section(start, end) diff --git a/src/urh/controller/widgets/SignalFrame.py b/src/urh/controller/widgets/SignalFrame.py index 4d50758af5..e6e1f5a688 100644 --- a/src/urh/controller/widgets/SignalFrame.py +++ b/src/urh/controller/widgets/SignalFrame.py @@ -731,6 +731,7 @@ def on_cb_signal_view_index_changed(self): else: self.ui.stackedWidget.setCurrentWidget(self.ui.pageSignal) self.ui.gvSignal.scene_type = self.ui.cbSignalView.currentIndex() + self.scene_manager.mod_type = self.signal.modulation_type self.ui.gvSignal.redraw_view(reinitialize=True) self.ui.labelRSSI.show() @@ -1062,6 +1063,7 @@ def on_combobox_modulation_type_text_changed(self, txt: str): self.undo_stack.push(modulation_action) + self.scene_manager.mod_type = txt if self.ui.cbSignalView.currentIndex() == 1: self.scene_manager.init_scene() self.on_slider_y_scale_value_changed() diff --git a/src/urh/cythonext/signal_functions.pyx b/src/urh/cythonext/signal_functions.pyx index 45b9847edd..baa59c2ae5 100644 --- a/src/urh/cythonext/signal_functions.pyx +++ b/src/urh/cythonext/signal_functions.pyx @@ -54,6 +54,31 @@ cdef get_numpy_dtype(iq cython_type): raise ValueError("dtype {} not supported for modulation".format(cython.typeof(cython_type))) cpdef modulate_c(uint8_t[:] bits, uint32_t samples_per_symbol, str modulation_type, + float[:] parameters, uint16_t bits_per_symbol, + float carrier_amplitude, float carrier_frequency, float carrier_phase, float sample_rate, + uint32_t pause, uint32_t start, dtype=np.float32, + float gauss_bt=0.5, float filter_width=1.0): + + if dtype == np.int8: + return __modulate( + bits, samples_per_symbol, modulation_type, parameters, bits_per_symbol, carrier_amplitude, + carrier_frequency, carrier_phase, sample_rate, pause, start, 0, gauss_bt, filter_width + ) + elif dtype == np.int16: + return __modulate( + bits, samples_per_symbol, modulation_type, parameters, bits_per_symbol, carrier_amplitude, + carrier_frequency, carrier_phase, sample_rate, pause, start, 0, gauss_bt, filter_width + ) + elif dtype == np.float32: + return __modulate( + bits, samples_per_symbol, modulation_type, parameters, bits_per_symbol, carrier_amplitude, + carrier_frequency, carrier_phase, sample_rate, pause, start, 0.0, gauss_bt, filter_width + ) + else: + raise ValueError("Unsupported dtype for modulation {}".format(dtype)) + + +cpdef __modulate(uint8_t[:] bits, uint32_t samples_per_symbol, str modulation_type, float[:] parameters, uint16_t bits_per_symbol, float carrier_amplitude, float carrier_frequency, float carrier_phase, float sample_rate, uint32_t pause, uint32_t start, iq iq_type, @@ -316,8 +341,8 @@ cpdef np.ndarray[np.float32_t, ndim=1] afp_demod(IQ samples, float noise_mag, st else: raise ValueError("Unsupported dtype") - # Atan2 liefert Werte im Bereich von -Pi bis Pi - # Wir nutzen die Magic Constant NOISE_FSK_PSK um Rauschen abzuschneiden + # Atan2 yields values from -Pi to Pi + # We use the Magic Constant NOISE_FSK_PSK to cut off noise noise_sqrd = noise_mag * noise_mag NOISE = get_noise_for_mod_type(mod_type) result[0] = NOISE diff --git a/src/urh/settings.py b/src/urh/settings.py index be682acee5..c871190bb1 100644 --- a/src/urh/settings.py +++ b/src/urh/settings.py @@ -54,7 +54,7 @@ def get_qt_settings_filename(): SELECTION_COLOR = QColor("darkblue") # overwritten by system color (bin/urh) NOISE_COLOR = QColor("red") SELECTION_OPACITY = 1 -NOISE_OPACITY = 0.4 +NOISE_OPACITY = 0.33 # SEPARATION COLORS ONES_AREA_COLOR = Qt.darkGreen diff --git a/src/urh/signalprocessing/IQArray.py b/src/urh/signalprocessing/IQArray.py index 83b6f02fc3..bddbbb3856 100644 --- a/src/urh/signalprocessing/IQArray.py +++ b/src/urh/signalprocessing/IQArray.py @@ -189,13 +189,13 @@ def convert_to(self, target_dtype) -> np.ndarray: def from_file(filename: str): if filename.endswith(".complex16u") or filename.endswith(".cu8"): # two 8 bit unsigned integers - return IQArray(data=np.fromfile(filename, dtype=np.uint8)) + return IQArray(IQArray(data=np.fromfile(filename, dtype=np.uint8)).convert_to(np.int8)) elif filename.endswith(".complex16s") or filename.endswith(".cs8"): # two 8 bit signed integers return IQArray(data=np.fromfile(filename, dtype=np.int8)) elif filename.endswith(".complex32u") or filename.endswith(".cu16"): # two 16 bit unsigned integers - return IQArray(data=np.fromfile(filename, dtype=np.uint16)) + return IQArray(IQArray(data=np.fromfile(filename, dtype=np.uint16)).convert_to(np.int16)) elif filename.endswith(".complex32s") or filename.endswith(".cs16"): # two 16 bit signed integers return IQArray(data=np.fromfile(filename, dtype=np.int16)) diff --git a/src/urh/signalprocessing/Modulator.py b/src/urh/signalprocessing/Modulator.py index 92b323047e..6e0371aa6d 100644 --- a/src/urh/signalprocessing/Modulator.py +++ b/src/urh/signalprocessing/Modulator.py @@ -220,9 +220,6 @@ def modulate(self, data=None, pause=0, start=0) -> IQArray: dtype = self.get_dtype() a = self.carrier_amplitude * IQArray.min_max_for_dtype(dtype)[1] - type_code = "b" if dtype == np.int8 else "h" if dtype == np.int16 else "f" - type_val = array.array(type_code, [0])[0] - parameters = self.parameters if self.modulation_type == "ASK": parameters = array.array("f", [a*p/100 for p in parameters]) @@ -233,7 +230,7 @@ def modulate(self, data=None, pause=0, start=0) -> IQArray: self.modulation_type, parameters, self.bits_per_symbol, a, self.carrier_freq_hz, self.carrier_phase_deg * (np.pi / 180), - self.sample_rate, pause, start, type_val, + self.sample_rate, pause, start, dtype, self.gauss_bt, self.gauss_filter_width) return IQArray(result) diff --git a/src/urh/signalprocessing/Signal.py b/src/urh/signalprocessing/Signal.py index 6b2b1d0d3e..2199c8b091 100644 --- a/src/urh/signalprocessing/Signal.py +++ b/src/urh/signalprocessing/Signal.py @@ -51,6 +51,8 @@ def __init__(self, filename: str, name="Signal", modulation: str = None, sample_ self.noise_max_plot = 0 self.block_protocol_update = False + self.iq_array = IQArray(None, np.int8, 1) + self.wav_mode = filename.endswith(".wav") self.__changed = False if modulation is None: @@ -281,19 +283,32 @@ def noise_threshold(self, value): self._qad = None self.clear_parameter_cache() self._noise_threshold = value - self.noise_min_plot = -value - self.noise_max_plot = value + + middle = 0.5*sum(IQArray.min_max_for_dtype(self.iq_array.dtype)) + a = self.max_amplitude * value / self.max_magnitude + self.noise_min_plot = middle - a + self.noise_max_plot = middle + a self.noise_threshold_changed.emit() if not self.block_protocol_update: self.protocol_needs_update.emit() + @property + def max_magnitude(self): + mi, ma = IQArray.min_max_for_dtype(self.iq_array.dtype) + return (2 * max(mi**2, ma**2))**0.5 + + @property + def max_amplitude(self): + mi, ma = IQArray.min_max_for_dtype(self.iq_array.dtype) + return 0.5 * (ma - mi) + @property def noise_threshold_relative(self): - return self.noise_threshold / (self.iq_array.maximum**2.0 + self.iq_array.minimum**2.0)**0.5 + return self.noise_threshold / self.max_magnitude @noise_threshold_relative.setter def noise_threshold_relative(self, value: float): - self.noise_threshold = value * (self.iq_array.maximum**2.0 + self.iq_array.minimum**2.0)**0.5 + self.noise_threshold = value * self.max_magnitude @property def qad(self): diff --git a/src/urh/ui/painting/ContinuousSceneManager.py b/src/urh/ui/painting/ContinuousSceneManager.py index 68226f3de6..4c5bd6af22 100644 --- a/src/urh/ui/painting/ContinuousSceneManager.py +++ b/src/urh/ui/painting/ContinuousSceneManager.py @@ -10,8 +10,6 @@ def __init__(self, ring_buffer: RingBuffer, parent): self.__start = 0 self.__end = 0 - self.minimum, self.maximum = IQArray.min_max_for_dtype(self.ring_buffer.dtype) - @property def plot_data(self): return self.ring_buffer.view_data.real diff --git a/src/urh/ui/painting/LiveSceneManager.py b/src/urh/ui/painting/LiveSceneManager.py index 56ee25eb87..35c14e9967 100644 --- a/src/urh/ui/painting/LiveSceneManager.py +++ b/src/urh/ui/painting/LiveSceneManager.py @@ -8,8 +8,6 @@ def __init__(self, data_array, parent): self.plot_data = data_array self.end = 0 - self.minimum, self.maximum = IQArray.min_max_for_dtype(data_array.dtype) - @property def num_samples(self): return self.end diff --git a/src/urh/ui/painting/SceneManager.py b/src/urh/ui/painting/SceneManager.py index 134d41f239..e108d1df15 100644 --- a/src/urh/ui/painting/SceneManager.py +++ b/src/urh/ui/painting/SceneManager.py @@ -4,6 +4,7 @@ from PyQt5.QtCore import QObject from PyQt5.QtGui import QPen, QColor from PyQt5.QtWidgets import QGraphicsPathItem +from urh.signalprocessing.IQArray import IQArray from urh import settings from urh.cythonext import path_creator, util @@ -16,10 +17,6 @@ def __init__(self, parent): self.scene = ZoomableScene() self.__plot_data = None # type: np.ndarray self.line_item = self.scene.addLine(0, 0, 0, 0, QPen(settings.AXISCOLOR, 0)) - self.minimum = float("nan") # NaN = AutoDetect - self.maximum = float("nan") # NaN = AutoDetect - - self.padding = 1.25 @property def plot_data(self): @@ -66,24 +63,11 @@ def __limit_value(self, val: float) -> int: def show_full_scene(self): self.show_scene_section(0, self.num_samples) - def init_scene(self, apply_padding=True): + def init_scene(self): if self.num_samples == 0: return - if math.isnan(self.minimum) or math.isnan(self.maximum): - minimum, maximum = util.minmax(self.plot_data) - else: - minimum, maximum = self.minimum, self.maximum - - padding = self.padding if apply_padding else 1 - - if abs(minimum) > abs(maximum): - minimum = -padding * abs(minimum) - maximum = -padding * minimum - else: - maximum = padding * abs(maximum) - minimum = -padding * maximum - + minimum, maximum = IQArray.min_max_for_dtype(self.plot_data.dtype) self.scene.setSceneRect(0, minimum, self.num_samples, maximum - minimum) self.scene.setBackgroundBrush(settings.BGCOLOR) diff --git a/src/urh/ui/painting/SignalSceneManager.py b/src/urh/ui/painting/SignalSceneManager.py index 865b58d0d9..5fcc501126 100644 --- a/src/urh/ui/painting/SignalSceneManager.py +++ b/src/urh/ui/painting/SignalSceneManager.py @@ -1,3 +1,5 @@ +import math + from urh.signalprocessing.Signal import Signal from urh.ui.painting.SceneManager import SceneManager @@ -7,6 +9,7 @@ def __init__(self, signal: Signal, parent): super().__init__(parent) self.signal = signal self.scene_type = 0 # 0 = Analog Signal, 1 = QuadDemodView + self.mod_type = "ASK" def show_scene_section(self, x1: float, x2: float, subpath_ranges=None, colors=None): self.plot_data = self.signal.real_plot_data if self.scene_type == 0 else self.signal.qad @@ -19,7 +22,9 @@ def init_scene(self): else: self.plot_data = self.signal.qad - super().init_scene(apply_padding=self.scene_type == 0) + super().init_scene() + if self.scene_type == 1 and (self.mod_type == "FSK" or self.mod_type == "PSK"): + self.scene.setSceneRect(0, -4, self.num_samples, 8) self.line_item.setLine(0, 0, 0, 0) # Hide Axis diff --git a/src/urh/ui/painting/SniffSceneManager.py b/src/urh/ui/painting/SniffSceneManager.py index a2a724ab7d..6edee5a853 100644 --- a/src/urh/ui/painting/SniffSceneManager.py +++ b/src/urh/ui/painting/SniffSceneManager.py @@ -10,8 +10,6 @@ def __init__(self, data_array, parent, window_length=5 * 10**6): self.__end = 0 self.window_length = window_length - self.minimum, self.maximum = IQArray.min_max_for_dtype(data_array.dtype) - @property def plot_data(self): return self.data_array[self.__start:self.end] diff --git a/src/urh/ui/painting/SpectrogramSceneManager.py b/src/urh/ui/painting/SpectrogramSceneManager.py index ccc1365170..ff477d2412 100644 --- a/src/urh/ui/painting/SpectrogramSceneManager.py +++ b/src/urh/ui/painting/SpectrogramSceneManager.py @@ -67,7 +67,7 @@ def show_full_scene(self): # after we know how wide the spectrogram actually is self.scene.setSceneRect(0, 0, x_pos, self.spectrogram.freq_bins) - def init_scene(self, apply_padding=True): + def init_scene(self): pass def eliminate(self): diff --git a/src/urh/ui/views/LegendGraphicView.py b/src/urh/ui/views/LegendGraphicView.py deleted file mode 100644 index 9d298d010e..0000000000 --- a/src/urh/ui/views/LegendGraphicView.py +++ /dev/null @@ -1,32 +0,0 @@ -from PyQt5.QtCore import pyqtSignal -from PyQt5.QtGui import QWheelEvent -from PyQt5.QtWidgets import QGraphicsView - - -class LegendGraphicView(QGraphicsView): - resized = pyqtSignal() - - def __init__(self, parent=None): - self.y_sep = 0 - self.y_scene = -1 - self.scene_height = 2 - super().__init__(parent) - - def eliminate(self): - if self.scene() is not None: - self.scene().clear() - self.scene().setParent(None) - - def resizeEvent(self, event): - self.resized.emit() - - def refresh(self): - if self.scene() is not None: - self.resetTransform() - self.scene().setSceneRect(0, self.y_scene, self.width(), self.scene_height) - self.scene().draw_one_zero_arrows(self.y_sep) - self.fitInView(self.sceneRect()) - self.show() - - def wheelEvent(self, event: QWheelEvent): - return diff --git a/src/urh/ui/views/ZoomAndDropableGraphicView.py b/src/urh/ui/views/ZoomAndDropableGraphicView.py index f31326f22e..49aede97df 100644 --- a/src/urh/ui/views/ZoomAndDropableGraphicView.py +++ b/src/urh/ui/views/ZoomAndDropableGraphicView.py @@ -1,5 +1,8 @@ from PyQt5.QtCore import pyqtSignal from PyQt5.QtGui import QDragEnterEvent, QDropEvent +from urh.signalprocessing.IQArray import IQArray + +from urh.cythonext import util from urh.signalprocessing.ProtocolAnalyzer import ProtocolAnalyzer from urh.signalprocessing.Signal import Signal @@ -44,9 +47,6 @@ def dropEvent(self, event: QDropEvent): if signal is None: return - self.draw_signal(signal, proto_analyzer) - - def draw_signal(self, signal, proto_analyzer): if signal is None: return @@ -60,6 +60,15 @@ def draw_signal(self, signal, proto_analyzer): self.signal_loaded.emit(self.proto_analyzer) + def auto_fit_view(self): + super().auto_fit_view() + + plot_min, plot_max = util.minmax(self.signal.real_plot_data) + data_min, data_max = IQArray.min_max_for_dtype(self.signal.real_plot_data.dtype) + self.scale(1, (data_max - data_min) / (plot_max-plot_min)) + + self.centerOn(self.view_rect().x() + self.view_rect().width() / 2, self.y_center) + def eliminate(self): # Do _not_ call eliminate() for self.signal and self.proto_analyzer # as these are references to the original data! diff --git a/src/urh/ui/views/ZoomableGraphicView.py b/src/urh/ui/views/ZoomableGraphicView.py index d1def11146..600819e715 100644 --- a/src/urh/ui/views/ZoomableGraphicView.py +++ b/src/urh/ui/views/ZoomableGraphicView.py @@ -49,9 +49,6 @@ def __init__(self, parent=None): self.zoomed.connect(self.on_signal_zoomed) - self.scene_y_min = float("nan") # NaN = AutoDetect - self.scene_y_max = float("nan") # NaN = AutoDetect - self.scene_x_zoom_stretch = 1 @property @@ -161,8 +158,6 @@ def zoom_to_selection(self, start: int, end: int): def plot_data(self, data): if self.scene_manager is None: self.scene_manager = SceneManager(self) - self.scene_manager.minimum = self.scene_y_min - self.scene_manager.maximum = self.scene_y_max self.scene_manager.plot_data = data self.scene_manager.init_scene() diff --git a/tests/QtTestCase.py b/tests/QtTestCase.py index 6d507736d3..f4af7dba8f 100644 --- a/tests/QtTestCase.py +++ b/tests/QtTestCase.py @@ -19,8 +19,6 @@ class QtTestCase(unittest.TestCase): - CLOSE_TIMEOUT = 10 - WAIT_TIMEOUT_BEFORE_NEW = 10 SHOW = os.path.exists(os.path.join(os.path.dirname(os.path.realpath(__file__)), "show_gui")) @classmethod @@ -38,10 +36,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): cls.app.quit() - cls.app = None - QTest.qWait(10) - time.sleep(0.1) def setUp(self): ProtocolSniffer.BUFFER_SIZE_MB = 0.5 @@ -72,12 +67,7 @@ def tearDown(self): gc.collect() - def wait_before_new_file(self): - QApplication.instance().processEvents() - QTest.qWait(self.WAIT_TIMEOUT_BEFORE_NEW) - def add_signal_to_form(self, filename: str): - self.wait_before_new_file() self.form.add_signalfile(get_path_for_data_file(filename)) def get_path_for_filename(self, filename) -> str: diff --git a/tests/test_decoding_gui.py b/tests/test_decoding_gui.py index 71e3391c42..a0d9bd60a2 100644 --- a/tests/test_decoding_gui.py +++ b/tests/test_decoding_gui.py @@ -18,7 +18,6 @@ def setUp(self): # add empty signal path = os.path.join(tempfile.gettempdir(), "empty.complex") open(path, "w").close() - self.wait_before_new_file() self.form.add_signalfile(path) signal = self.form.signal_tab_controller.signal_frames[0].signal diff --git a/tests/test_demodulations.py b/tests/test_demodulations.py index 7e348119de..be831384ab 100644 --- a/tests/test_demodulations.py +++ b/tests/test_demodulations.py @@ -50,7 +50,7 @@ def test_fsk_short_bit_length(self): bits_str = "101010" bits = array.array("B", list(map(int, bits_str))) parameters = array.array("f", [-10e3, 10e3]) - result = modulate_c(bits, 8, "FSK", parameters, 1, 1, 40e3, 0, 1e6, 1000, 0, parameters[0]) + result = modulate_c(bits, 8, "FSK", parameters, 1, 1, 40e3, 0, 1e6, 1000, 0) signal = Signal("") signal.iq_array = IQArray(result) @@ -80,7 +80,7 @@ def test_psk(self): def test_4_fsk(self): bits = array.array("B", [1, 0, 1, 0, 1, 1, 0, 0, 0, 1]) parameters = array.array("f", [-20e3, -10e3, 10e3, 20e3]) - result = modulate_c(bits, 100, "FSK", parameters, 2, 1, 40e3, 0, 1e6, 1000, 0, parameters[0]) + result = modulate_c(bits, 100, "FSK", parameters, 2, 1, 40e3, 0, 1e6, 1000, 0) signal = Signal("") signal.iq_array = IQArray(result) diff --git a/tests/test_file_operator.py b/tests/test_file_operator.py index 9034d75deb..428dabe427 100644 --- a/tests/test_file_operator.py +++ b/tests/test_file_operator.py @@ -39,8 +39,6 @@ def test_uncompress_archives(self): data.tofile(name) zip.write(name) - QApplication.instance().processEvents() - QTest.qWait(self.WAIT_TIMEOUT_BEFORE_NEW) self.form.add_files(FileOperator.uncompress_archives(["test.tar.gz", "test.zip"], QDir.tempPath())) self.assertEqual(len(self.form.signal_tab_controller.signal_frames), 5) diff --git a/tests/test_fuzzing_profile.py b/tests/test_fuzzing_profile.py index 2c9b3109a0..44afa67890 100644 --- a/tests/test_fuzzing_profile.py +++ b/tests/test_fuzzing_profile.py @@ -28,7 +28,6 @@ def test_load_profile(self): pac.to_xml_file(filename, decoders=decoders, participants=self.form.project_manager.participants) - self.wait_before_new_file() self.form.add_files([os.path.join(tempfile.gettempdir(), "test.fuzz.xml")]) self.assertEqual(self.form.ui.tabWidget.currentWidget(), self.form.ui.tab_generator) diff --git a/tests/test_generator.py b/tests/test_generator.py index ebb8553744..c6afde4c86 100644 --- a/tests/test_generator.py +++ b/tests/test_generator.py @@ -233,7 +233,6 @@ def test_edit_data(self): with open(filename, "w") as f: f.writelines("\n".join(data)) - self.wait_before_new_file() self.form.add_files([filename]) self.add_signal_to_generator(signal_index=0) self.form.generator_tab_controller.ui.cbViewType.setCurrentText("Bit") diff --git a/tests/test_maincontroller_gui.py b/tests/test_maincontroller_gui.py index 2e95c8fa44..047e72296d 100644 --- a/tests/test_maincontroller_gui.py +++ b/tests/test_maincontroller_gui.py @@ -57,7 +57,6 @@ def test_open_plain_bits(self): f.write(os.linesep.join(bits)) self.form.compare_frame_controller.ui.cbProtoView.setCurrentIndex(0) - self.wait_before_new_file() self.form.add_files([filename]) for i, bit_seq in enumerate(bits): diff --git a/tests/test_modulator.py b/tests/test_modulator.py index 7d5f4649e9..81144aa412 100644 --- a/tests/test_modulator.py +++ b/tests/test_modulator.py @@ -89,21 +89,21 @@ def test_performance(self): def test_c_modulation_method_ask(self): bits = array.array("B", [1, 0, 1, 0, 1, 1, 0, 0, 0, 1]) parameters = array.array("f", [0, 0.25, 0.5, 1]) - result = modulate_c(bits, 100, "ASK", parameters, 2, 1, 40e3, 0, 1e6, 1000, 0, parameters[0]) + result = modulate_c(bits, 100, "ASK", parameters, 2, 1, 40e3, 0, 1e6, 1000, 0) #result.tofile("/tmp/test.complex") def test_c_modulation_method_fsk(self): bits = array.array("B", [1, 0, 1, 0, 1, 1, 0, 0, 0, 1]) parameters = array.array("f", [-20e3, -10e3, 10e3, 20e3]) - result = modulate_c(bits, 100, "FSK", parameters, 2, 1, 40e3, 0, 1e6, 1000, 0, parameters[0]) + result = modulate_c(bits, 100, "FSK", parameters, 2, 1, 40e3, 0, 1e6, 1000, 0) # result.tofile("/tmp/test_4fsk.complex") def test_c_modulation_method_psk(self): bits = array.array("B", [0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1]) parameters = array.array("f", [np.pi/4, 3*np.pi/4, 5*np.pi/4, 7*np.pi/4]) - result = modulate_c(bits, 100, "PSK", parameters, 2, 1, 40e3, 0, 1e6, 1000, 0, parameters[0]) + result = modulate_c(bits, 100, "PSK", parameters, 2, 1, 40e3, 0, 1e6, 1000, 0) # result.tofile("/tmp/test_psk.complex") @@ -134,13 +134,13 @@ def test_get_oqpsk_bits(self): def test_c_modulation_method_oqpsk(self): bits = array.array("B", [0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1]) parameters = array.array("f", [np.pi/4, 3*np.pi/4, 5*np.pi/4, 7*np.pi/4]) - result = modulate_c(bits, 100, "OQPSK", parameters, 2, 1, 40e3, 0, 1e6, 1000, 0, parameters[0]) + result = modulate_c(bits, 100, "OQPSK", parameters, 2, 1, 40e3, 0, 1e6, 1000, 0) # result.tofile("/tmp/test_oqpsk.complex") def test_c_modulation_method_gfsk(self): bits = array.array("B", [1, 0, 1, 0, 1, 1, 0, 0, 0, 1]) parameters = array.array("f", [-10e3, 10e3]) - result = modulate_c(bits, 100, "GFSK", parameters, 1, 1, 40e3, 0, 1e6, 1000, 0, parameters[0]) + result = modulate_c(bits, 100, "GFSK", parameters, 1, 1, 40e3, 0, 1e6, 1000, 0) # result.tofile("/tmp/test_gfsk.complex") diff --git a/tests/test_modulator_gui.py b/tests/test_modulator_gui.py index ff11287eeb..760c8247d0 100644 --- a/tests/test_modulator_gui.py +++ b/tests/test_modulator_gui.py @@ -16,8 +16,6 @@ def setUp(self): logger.debug("Preparing Modulation dialog") self.dialog, _ = self.form.generator_tab_controller.prepare_modulation_dialog() - QApplication.instance().processEvents() - QTest.qWait(self.WAIT_TIMEOUT_BEFORE_NEW) if self.SHOW: self.dialog.show() diff --git a/tests/test_options_gui.py b/tests/test_options_gui.py index c1dcd3d89a..a7b6b451db 100644 --- a/tests/test_options_gui.py +++ b/tests/test_options_gui.py @@ -52,7 +52,6 @@ def test_field_type_tab(self): n_rows = self.dialog.ui.tblLabeltypes.model().rowCount() self.assertGreater(n_rows, 1) self.dialog.ui.btnAddLabelType.click() - self.wait_before_new_file() self.assertEqual(n_rows + 1, self.dialog.ui.tblLabeltypes.model().rowCount()) self.dialog.ui.btnRemoveLabeltype.click() self.assertEqual(n_rows, self.dialog.ui.tblLabeltypes.model().rowCount()) diff --git a/tests/test_plugins.py b/tests/test_plugins.py index cbc9353dd5..8814ff078f 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -170,7 +170,4 @@ def test_insert_sine_plugin(self): sep = Formatter.local_decimal_seperator() self.assertEqual(dialog.lineEditTime.text(), "250" + sep + "000m") - # Close the dialog via finished - dialog.finished.emit(0) - QApplication.instance().processEvents() - QTest.qWait(self.CLOSE_TIMEOUT) + dialog.close() diff --git a/tests/test_project_manager.py b/tests/test_project_manager.py index 263788b9d0..0bbdba4a7e 100644 --- a/tests/test_project_manager.py +++ b/tests/test_project_manager.py @@ -24,7 +24,6 @@ def setUp(self): self.gframe = self.form.generator_tab_controller def test_load_protocol_file(self): - self.wait_before_new_file() self.form.add_protocol_file(self.get_path_for_filename("protocol_wsp.proto.xml")) self.assertEqual(len(self.form.compare_frame_controller.proto_analyzer.messages), 6) @@ -60,15 +59,13 @@ def test_save_modulations(self): def test_close_all(self): self.form.close_project() - QApplication.instance().processEvents() - QTest.qWait(self.CLOSE_TIMEOUT) + self.assertEqual(self.form.signal_tab_controller.num_frames, 0) self.add_signal_to_form("ask.complex") self.add_signal_to_form("fsk.complex") self.assertEqual(self.form.signal_tab_controller.num_frames, 2) self.form.close_project() - QApplication.instance().processEvents() - QTest.qWait(self.CLOSE_TIMEOUT) + self.assertEqual(self.form.signal_tab_controller.num_frames, 0) self.assertEqual(self.form.project_manager.project_file, None) @@ -109,7 +106,6 @@ def test_save_and_load_participants(self): self.form.save_project() self.form.close_all_files() - self.wait_before_new_file() self.assertEqual(self.form.compare_frame_controller.protocol_model.row_count, 0) self.form.project_manager.set_project_folder(target_dir, ask_for_new_project=False) @@ -152,7 +148,6 @@ def test_save_and_load_with_fieldtypes(self): self.assertEqual(self.form.compare_frame_controller.active_message_type[2].field_type, checksum_field_type) self.form.close_project() - self.wait_before_new_file() self.assertEqual(len(self.form.compare_frame_controller.active_message_type), 0) self.form.project_manager.set_project_folder(target_dir, ask_for_new_project=False) diff --git a/tests/test_protocol_label_dialog.py b/tests/test_protocol_label_dialog.py index 59cce33fa0..abc8f908bf 100644 --- a/tests/test_protocol_label_dialog.py +++ b/tests/test_protocol_label_dialog.py @@ -10,8 +10,6 @@ class TestProtocolLabelDialog(QtTestCase): def setUp(self): super().setUp() - QApplication.instance().processEvents() - QTest.qWait(self.WAIT_TIMEOUT_BEFORE_NEW) self.form.add_protocol_file(get_path_for_data_file("protocol.proto.xml")) self.cframe = self.form.compare_frame_controller diff --git a/tests/test_signal_tab_GUI.py b/tests/test_signal_tab_GUI.py index 7bc0a5d837..824172e021 100644 --- a/tests/test_signal_tab_GUI.py +++ b/tests/test_signal_tab_GUI.py @@ -15,8 +15,7 @@ def test_close_project(self): self.add_signal_to_form("esaver.complex16s") self.assertEqual(self.form.signal_tab_controller.num_frames, 1) self.form.close_all_files() - QApplication.instance().processEvents() - QTest.qWait(self.CLOSE_TIMEOUT) + self.assertEqual(self.form.signal_tab_controller.num_frames, 0) # Add a bunch of signals @@ -27,8 +26,6 @@ def test_close_project(self): self.assertEqual(self.form.signal_tab_controller.num_frames, num_frames) self.form.close_project() - QApplication.instance().processEvents() - QTest.qWait(self.CLOSE_TIMEOUT) self.add_signal_to_form("ask.complex") self.assertEqual(self.form.signal_tab_controller.num_frames, 1) @@ -55,8 +52,6 @@ def test_zoom(self): self.assertNotEqual(samples_in_view, frame.ui.lSamplesInView.text()) def test_load_proto(self): - QApplication.instance().processEvents() - QTest.qWait(self.WAIT_TIMEOUT_BEFORE_NEW) self.form.add_files([get_path_for_data_file("protocol.proto.xml")]) self.assertEqual(self.form.signal_tab_controller.signal_frames[0].ui.lSignalTyp.text(), "Protocol") @@ -215,8 +210,6 @@ def test_create_new_signal(self): frame.ui.gvSignal.sel_area_start_end_changed.emit(start, end) self.assertEqual(self.form.signal_tab_controller.num_frames, 1) - QApplication.instance().processEvents() - QTest.qWait(self.WAIT_TIMEOUT_BEFORE_NEW) frame.ui.gvSignal.on_create_action_triggered() QApplication.instance().processEvents() diff --git a/tests/test_simulator_tab_gui.py b/tests/test_simulator_tab_gui.py index a15b0f678d..29ce7b5b4b 100644 --- a/tests/test_simulator_tab_gui.py +++ b/tests/test_simulator_tab_gui.py @@ -377,12 +377,15 @@ def __wait_for_simulator_log_message(dialog, log_message): sender.send_raw_data(modulator.modulate("1" * 352), 1) time.sleep(0.5) sender.send_raw_data(IQArray(None, np.float32, 2000), 1) + time.sleep(0.5) __wait_for_simulator_log_message(dialog, "Waiting for message 2") sender.send_raw_data(modulator.modulate("10" * 176), 1) time.sleep(0.5) sender.send_raw_data(IQArray(None, np.float32, 2000), 1) + time.sleep(0.5) + __wait_for_simulator_log_message(dialog, "Mismatch for label:") dialog.on_timer_timeout() # enforce writing to text view