예제 #1
0
    def test_fir_filter(self):
        input_signal = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 42], dtype=np.complex64)
        filter_taps = [0.25, 0.25, 0.25, 0.25]

        fir_filter = Filter(filter_taps)

        filtered_signal = fir_filter.apply_fir_filter(input_signal)
        expected_filtered_signal = np.array([0.25, 0.75, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 16.5], dtype=np.complex64)

        self.assertTrue(np.array_equal(filtered_signal, expected_filtered_signal))
예제 #2
0
    def build_filter(self) -> Filter:
        if self.ui.radioButtonMovingAverage.isChecked():
            n = self.ui.spinBoxNumTaps.value()
            return Filter([1/n for _ in range(n)], filter_type=FilterType.moving_average)
        else:
            # custom filter
            try:
                taps = eval(self.ui.lineEditCustomTaps.text())
                try:
                    taps = list(map(float, taps))
                    self.error_message = ""
                    return Filter(taps)
                except (ValueError, TypeError) as e:
                    self.error_message = "Error casting taps:\n" + str(e)
                    return None

            except SyntaxError as e:
                self.error_message = "Error parsing taps:\n" + str(e)
                return None
예제 #3
0
    def test_fsk_live_capture(self):
        data = Signal(get_path_for_data_file("fsk_live.coco"), "").data

        n = 10
        moving_average_filter = Filter([1 / n for _ in range(n)],
                                       filter_type=FilterType.moving_average)
        filtered_data = moving_average_filter.apply_fir_filter(data)

        rect = afp_demod(filtered_data, 0.0175, 1)
        center = detect_center(rect)
        self.assertGreaterEqual(center, -0.0148, msg="Filtered")
        self.assertLessEqual(center, 0.01, msg="Filtered")

        rect = afp_demod(data, 0.0175, 1)
        center = detect_center(rect)
        self.assertGreaterEqual(center, -0.02, msg="Original")
        self.assertLessEqual(center, 0.01, msg="Original")
예제 #4
0
    def test_fsk_live_capture(self):
        data = Signal(get_path_for_data_file("fsk_live.coco"),
                      "").iq_array.data

        n = 10
        moving_average_filter = Filter([1 / n for _ in range(n)],
                                       filter_type=FilterType.moving_average)
        filtered_data = moving_average_filter.apply_fir_filter(
            data.flatten()).view(np.float32)
        filtered_data = filtered_data.reshape((len(filtered_data) // 2, 2))

        rect = afp_demod(filtered_data, 0.0175, "FSK", 2)
        center = detect_center(rect)
        self.assertGreaterEqual(center, -0.0148, msg="Filtered")
        self.assertLessEqual(center, 0.01, msg="Filtered")

        rect = afp_demod(data, 0.0175, "FSK", 2)
        center = detect_center(rect)
        self.assertGreaterEqual(center, -0.02, msg="Original")
        self.assertLessEqual(center, 0.01, msg="Original")
예제 #5
0
    def __init__(self,
                 proto_analyzer: ProtocolAnalyzer,
                 undo_stack: QUndoStack,
                 project_manager,
                 proto_bits=None,
                 parent=None):
        super().__init__(parent)

        self.undo_stack = undo_stack

        self.ui = Ui_SignalFrame()
        self.ui.setupUi(self)

        fixed_font = QFontDatabase.systemFont(QFontDatabase.FixedFont)
        fixed_font.setPointSize(QApplication.instance().font().pointSize())
        self.ui.txtEdProto.setFont(fixed_font)
        self.ui.txtEdProto.participants = project_manager.participants
        self.ui.txtEdProto.messages = proto_analyzer.messages

        self.ui.gvSignal.participants = project_manager.participants

        self.setAttribute(Qt.WA_DeleteOnClose)
        self.project_manager = project_manager

        self.proto_analyzer = proto_analyzer
        self.signal = proto_analyzer.signal if self.proto_analyzer is not None else None  # type: Signal

        self.dsp_filter = Filter([0.1] * 10, FilterType.moving_average)
        self.set_filter_button_caption()
        self.filter_dialog = FilterDialogController(self.dsp_filter,
                                                    parent=self)

        self.proto_selection_timer = QTimer(
        )  # For Update Proto Selection from ROI
        self.proto_selection_timer.setSingleShot(True)
        self.proto_selection_timer.setInterval(1)

        # Disabled because never used (see also set_protocol_visibilty())
        self.ui.chkBoxSyncSelection.hide()

        if self.signal is not None:
            self.filter_menu = QMenu()
            self.apply_filter_to_selection_only = self.filter_menu.addAction(
                self.tr("Apply only to selection"))
            self.apply_filter_to_selection_only.setCheckable(True)
            self.apply_filter_to_selection_only.setChecked(False)
            self.configure_filter_action = self.filter_menu.addAction(
                "Configure filter...")
            self.configure_filter_action.setIcon(QIcon.fromTheme("configure"))
            self.configure_filter_action.triggered.connect(
                self.on_configure_filter_action_triggered)
            self.ui.btnFilter.setMenu(self.filter_menu)

            if self.signal.qad_demod_file_loaded:
                self.ui.lSignalTyp.setText("Quad-Demod Signal (*.wav)")
            elif self.signal.wav_mode:
                self.ui.lSignalTyp.setText("Realpart Signal (*.wav)")
            else:
                self.ui.lSignalTyp.setText("Complex Signal")

            self.ui.gvLegend.hide()
            self.ui.lineEditSignalName.setText(self.signal.name)
            self.ui.lSamplesInView.setText("{0:,}".format(
                self.signal.num_samples))
            self.ui.lSamplesTotal.setText("{0:,}".format(
                self.signal.num_samples))
            self.sync_protocol = self.ui.chkBoxSyncSelection.isChecked()
            self.ui.chkBoxSyncSelection.hide()

            self.ui.splitter.setSizes([self.ui.splitter.height(), 0])

            self.protocol_selection_is_updateable = True

            self.scene_manager = SignalSceneManager(self.signal, self)
            self.ui.gvSignal.scene_manager = self.scene_manager
            self.ui.gvSignal.setScene(self.scene_manager.scene)

            self.jump_sync = True
            self.on_btn_show_hide_start_end_clicked()

            self.refresh_signal_information(block=True)
            self.create_connects()
            self.set_protocol_visibility()

            self.ui.chkBoxShowProtocol.setChecked(True)
            self.set_qad_tooltip(self.signal.noise_threshold)
            self.ui.btnSaveSignal.hide()

            self.show_protocol(refresh=False)

        else:
            self.ui.btnFilter.setDisabled(True)
            suffix = ""
            if not proto_analyzer.filename:
                suffix = ""
            elif proto_analyzer.filename.endswith(".proto"):
                suffix = " (*.proto)"
            elif proto_analyzer.filename.endswith(".txt"):
                suffix = " (*.txt)"
            self.ui.lSignalTyp.setText("Protocol" + suffix)

            scene, nsamples = SignalSceneManager.create_rectangle(proto_bits)

            self.ui.lSamplesInView.setText("{0:n}".format(int(nsamples)))
            self.ui.lSamplesTotal.setText("{0:n}".format(int(nsamples)))
            self.ui.gvSignal.setScene(scene)
            self.ui.spinBoxSelectionStart.setMaximum(nsamples)
            self.ui.spinBoxSelectionEnd.setMaximum(nsamples)
            self.ui.btnReplay.hide()

            self.create_connects()

            self.ui.gvSignal.sel_area_active = True

            self.ui.btnSaveSignal.hide()