예제 #1
0
 def toggle_range(self):
     ''' toggles whether the range is enabled or not '''
     if self.limitRange.isChecked():
         self.limitRange.setText('Cut')
         if self.audioStreams.count() > 0:
             duration_ms = int(self.__stream_duration_micros[
                 self.audioStreams.currentIndex()] / 1000)
             if duration_ms > 1:
                 from model.report import block_signals
                 with block_signals(self.rangeFrom):
                     self.rangeFrom.setTimeRange(
                         QTime.fromMSecsSinceStartOfDay(0),
                         QTime.fromMSecsSinceStartOfDay(duration_ms - 1))
                     self.rangeFrom.setTime(
                         QTime.fromMSecsSinceStartOfDay(0))
                     self.rangeFrom.setEnabled(True)
                 self.rangeSeparatorLabel.setEnabled(True)
                 with block_signals(self.rangeTo):
                     self.rangeTo.setEnabled(True)
                     self.rangeTo.setTimeRange(
                         QTime.fromMSecsSinceStartOfDay(1),
                         QTime.fromMSecsSinceStartOfDay(duration_ms))
                     self.rangeTo.setTime(
                         QTime.fromMSecsSinceStartOfDay(duration_ms))
     else:
         self.limitRange.setText('Enable')
         self.rangeFrom.setEnabled(False)
         self.rangeSeparatorLabel.setEnabled(False)
         self.rangeTo.setEnabled(False)
         if self.__executor is not None:
             self.__executor.start_time_ms = 0
             self.__executor.end_time_ms = 0
예제 #2
0
 def __propagate_y_range(self, _, range):
     ''' passes the updates range to the fields '''
     from model.report import block_signals
     with block_signals(self.__y_min):
         self.__y_min.setValue(range[0])
     with block_signals(self.__y_max):
         self.__y_max.setValue(range[1])
예제 #3
0
 def __init_channel_count_fields(self, channels, lfe_index=0):
     from model.report import block_signals
     with block_signals(self.lfeChannelIndex):
         self.lfeChannelIndex.setMaximum(channels)
         self.lfeChannelIndex.setValue(lfe_index)
     with block_signals(self.channelCount):
         self.channelCount.setMaximum(channels)
         self.channelCount.setValue(channels)
예제 #4
0
 def __select_filter(self, selected_filter):
     ''' Refreshes the params and display with the selected filter '''
     from model.report import block_signals
     self.__selected_id = selected_filter.id
     # populate the fields with values if we're editing an existing filter
     if hasattr(selected_filter, 'gain'):
         with block_signals(self.filterGain):
             self.filterGain.setValue(selected_filter.gain)
     if hasattr(selected_filter, 'q'):
         with block_signals(self.filterQ):
             self.filterQ.setValue(selected_filter.q)
     if hasattr(selected_filter, 'freq'):
         with block_signals(self.freq):
             self.freq.setValue(selected_filter.freq)
     if hasattr(selected_filter, 'order'):
         with block_signals(self.filterOrder):
             self.filterOrder.setValue(selected_filter.order)
     if hasattr(selected_filter, 'type'):
         displayName = 'Butterworth' if selected_filter.type is FilterType.BUTTERWORTH else 'Linkwitz-Riley'
         with block_signals(self.passFilterType):
             self.passFilterType.setCurrentIndex(
                 self.passFilterType.findText(displayName))
     if hasattr(selected_filter, 'count') and issubclass(
             type(selected_filter), Shelf):
         with block_signals(self.filterCount):
             self.filterCount.setValue(selected_filter.count)
     with block_signals(self.filterType):
         self.filterType.setCurrentText(selected_filter.display_name)
     # configure visible/enabled fields for the current filter type
     self.enableFilterParams()
     with block_signals(self.freq):
         self.freq.setMaximum(self.__signal.fs / 2.0)
예제 #5
0
 def __reset_time(time_widget):
     ''' resets and disables the supplied time field. '''
     from model.report import block_signals
     with block_signals(time_widget):
         time_widget.clearMaximumDateTime()
         time_widget.setTime(QTime())
         time_widget.setEnabled(False)
예제 #6
0
 def filter_content_type(self, txt: str):
     ''' filters the selected content types to match the given string '''
     with block_signals(self.contentTypeFilter):
         for i in range(self.contentTypeFilter.count()):
             item: QListWidgetItem = self.contentTypeFilter.item(i)
             item.setSelected(
                 len(txt.strip()) == 0
                 or item.text().casefold().find(txt.casefold()) > -1)
     self.apply_filter()
예제 #7
0
 def filter_max_year(self, max_year: int):
     ''' sets the max year filter '''
     min_year = self.yearMinFilter.value()
     with block_signals(self.yearFilter):
         for i in range(self.yearFilter.count()):
             item: QListWidgetItem = self.yearFilter.item(i)
             val = int(item.text())
             item.setSelected(min_year <= val <= max_year)
         self.yearMinFilter.setMaximum(max_year - 1)
     self.apply_filter()
예제 #8
0
 def __ensure_filter_is_selected(self, active_model, active_view):
     '''
     Filter model resets the model on every change, this clears the selection so we have to restore that selection
     to ensure the row remains visibly selected while also blocking signals to avoid a pointless update of the
     fields.
     '''
     for idx, f in enumerate(active_model):
         if f.id == self.__selected_id:
             from model.report import block_signals
             with block_signals(active_view):
                 active_view.selectRow(idx)
예제 #9
0
 def __init_resolution_selector(self, signal):
     ''' sets up the resolution selector based on the size of the underlying file. '''
     from model.report import block_signals
     with block_signals(self.analysisResolution):
         self.analysisResolution.clear()
         default_length = signal.get_segment_length()
         for m in MULTIPLIERS:
             freq_res = float(signal.fs) / (default_length * m)
             time_res = (m * default_length) / signal.fs
             self.analysisResolution.addItem(
                 f"{freq_res:.3f} Hz / {time_res:.3f} s")
         self.analysisResolution.setCurrentIndex(2)
예제 #10
0
 def __init__(self, preferences, signal_model, allow_load=True):
     super(AnalyseSignalDialog, self).__init__()
     self.setupUi(self)
     self.setWindowFlags(self.windowFlags() | Qt.WindowSystemMenuHint
                         | Qt.WindowMinMaxButtonsHint)
     self.__preferences = preferences
     self.filePicker.setIcon(qta.icon('fa5s.folder-open'))
     self.showLimitsButton.setIcon(qta.icon('fa5s.arrows-alt'))
     self.updateChart.setIcon(qta.icon('fa5s.sync'))
     self.saveChart.setIcon(qta.icon('fa5s.save'))
     self.saveLayout.setIcon(qta.icon('fa5s.save'))
     self.lockButton.setIcon(qta.icon('fa5s.lock-open'))
     self.minFreq.setValue(preferences.get(GRAPH_X_MIN))
     self.maxUnfilteredFreq.setValue(preferences.get(GRAPH_X_MAX))
     self.__info = None
     self.__signal = None
     self.__filtered_signals = {}
     self.__spectrum_analyser = MaxSpectrumByTime(self.spectrumChart,
                                                  self.__preferences, self)
     self.__waveform_analyser = Waveform(self.waveformChart, self)
     self.__signal_model = signal_model
     from model.report import block_signals
     with block_signals(self.markerType):
         self.markerType.addItem(POINT)
         self.markerType.addItem(ELLIPSE)
         self.markerType.addItem(SPECTROGRAM_CONTOURED)
         self.markerType.addItem(SPECTROGRAM_FLAT)
     self.markerType.setCurrentText(POINT)
     self.updateChart.setEnabled(False)
     self.__duration = 0
     self.loadButton.setEnabled(False)
     self.compareSignalsButton.setEnabled(False)
     self.__init_from_prefs()
     self.__clear()
     self.__allow_load = allow_load
     self.hideSidebar.setVisible(False)
     if allow_load:
         self.__init_for_load()
     else:
         self.__init_for_compare()
예제 #11
0
 def refresh_selector(self):
     ''' Updates the selector with the available signals. '''
     currently_selected = self.__selector.currentText()
     from model.report import block_signals
     with block_signals(self.__selector):
         self.__selector.clear()
         self.__selector.addItem('  ')
         for bm in self.__signal_model.bass_managed_signals:
             self.__selector.addItem(f"(BM) {bm.name}")
             for c in bm.channels:
                 if c.signal is not None:
                     self.__selector.addItem(c.name)
                 else:
                     self.__selector.addItem(f"-- {c.name}")
         for s in self.__signal_model.non_bm_signals:
             if s.signal is not None:
                 self.__selector.addItem(s.name)
             else:
                 self.__selector.addItem(f"-- {s.name}")
         idx = self.__selector.findText(currently_selected)
         if idx > -1:
             self.__selector.setCurrentIndex(idx)
         else:
             self.__reset_controls()
예제 #12
0
 def update_waveform(self, signal_name):
     ''' displays the waveform for the selected signal '''
     if self.__current_signal is not None:
         self.__current_signal.unregister_listener(self.on_filter_update)
     self.__current_signal = self.__get_signal_data(signal_name)
     if self.__current_signal is None:
         self.__reset_time(self.__start_time)
         self.__reset_time(self.__end_time)
         self.__load_signal_btn.setEnabled(True)
         self.__bm_headroom.setEnabled(False)
         self.__bm_lpf_position.setEnabled(False)
         self.__bm_hpf.setEnabled(False)
         self.__bm_hpf.setChecked(False)
         self.__bm_clip_before.setEnabled(False)
         self.__bm_clip_after.setEnabled(False)
         self.__show_stats_btn.setEnabled(False)
         self.__reset_controls()
         self.__active_signal = None
     else:
         self.__load_signal_btn.setEnabled(False)
         self.__show_stats_btn.setEnabled(True)
         metadata = self.__current_signal.metadata
         if metadata is not None:
             if SIGNAL_CHANNEL in metadata:
                 self.__source_file.setText(
                     f"{metadata[SIGNAL_SOURCE_FILE]} - C{metadata[SIGNAL_CHANNEL]}"
                 )
             else:
                 self.__source_file.setText(metadata[SIGNAL_SOURCE_FILE])
         from model.report import block_signals
         if signal_name.startswith('(BM) '):
             with block_signals(self.__bm_hpf):
                 self.__bm_hpf.setEnabled(False)
                 self.__bm_hpf.setChecked(False)
             with block_signals(self.__bm_headroom):
                 self.__bm_headroom.setEnabled(True)
                 self.__bm_headroom.setCurrentText(
                     self.__current_signal.bm_headroom_type)
             with block_signals(self.__bm_lpf_position):
                 self.__bm_lpf_position.setEnabled(True)
                 self.__bm_lpf_position.setCurrentText(
                     self.__current_signal.bm_lpf_position)
             with block_signals(self.__bm_clip_before):
                 self.__bm_clip_before.setEnabled(True)
                 self.__bm_clip_before.setChecked(
                     self.__current_signal.clip_before)
             with block_signals(self.__bm_clip_after):
                 self.__bm_clip_after.setEnabled(True)
                 self.__bm_clip_after.setChecked(
                     self.__current_signal.clip_after)
         else:
             if signal_name.endswith('LFE'):
                 with block_signals(self.__bm_hpf):
                     self.__bm_hpf.setEnabled(False)
                     self.__bm_hpf.setChecked(False)
             else:
                 with block_signals(self.__bm_hpf):
                     self.__bm_hpf.setEnabled(True)
                     self.__bm_hpf.setChecked(
                         self.__current_signal.high_pass)
             self.__bm_headroom.setEnabled(False)
             self.__bm_lpf_position.setEnabled(False)
             self.__bm_clip_before.setEnabled(False)
             self.__bm_clip_after.setEnabled(False)
         self.__current_signal.register_listener(self.on_filter_update)
         self.__start_time.setEnabled(True)
         duration = QTime(0, 0, 0).addMSecs(
             self.__current_signal.duration_seconds * 1000.0)
         self.__start_time.setMaximumTime(duration)
         self.__end_time.setEnabled(True)
         self.__end_time.setMaximumTime(duration)
         self.__end_time.setTime(duration)
         self.toggle_filter(
             Qt.Checked if self.__is_filtered.isChecked() else Qt.Unchecked)
예제 #13
0
    def __on_mso(self, mso):
        '''
        Handles mso message from the device sent after a getmso is issued.
        :param mso: the mso.
        '''
        version = mso['versions']['swVer']
        version = version[1:] if version[0] == 'v' or version[0] == 'V' else version
        try:
            self.__supports_shelf = semver.parse_version_info(version) > semver.parse_version_info('1.4.0')
        except:
            logger.error(f"Unable to parse version {mso['versions']['swVer']}")
            result = QMessageBox.question(self,
                                          'Supports Shelf Filters?',
                                          f"Reported software version is "
                                          f"\n\n    {version}"
                                          f"\n\nDoes this version support shelf filters?",
                                          QMessageBox.Yes | QMessageBox.No,
                                          QMessageBox.No)
            self.__supports_shelf = result == QMessageBox.Yes

        speakers = mso['speakers']['groups']
        channels = ['lf', 'rf']
        for group in [s for s, v in speakers.items() if 'present' in v and v['present'] is True]:
            if group[0:2] == 'lr' and len(group) > 2:
                channels.append('l' + group[2:])
                channels.append('r' + group[2:])
            else:
                channels.append(group)

        peq_slots = mso['peq']['slots']

        class Filters(dict):
            def __init__(self):
                super().__init__()

            def __missing__(self, key):
                self[key] = CompleteFilter(fs=HTP1_FS, sort_by_id=True)
                return self[key]

        tmp1 = Filters()
        tmp2 = Filters()
        raw_filters = {c: [] for c in channels}
        unknown_channels = set()
        for idx, s in enumerate(peq_slots):
            for c in channels:
                if c in s['channels']:
                    tmp1[c].save(self.__convert_to_filter(s['channels'][c], idx))
                    tmp2[c].save(self.__convert_to_filter(s['channels'][c], idx))
                    raw_filters[c].append(s['channels'][c])
                else:
                    unknown_channels.add(c)
        if unknown_channels:
            peq_channels = peq_slots[0]['channels'].keys()
            logger.error(f"Unknown channels encountered [peq channels: {peq_channels}, unknown: {unknown_channels}]")

        from model.report import block_signals
        with block_signals(self.filtersetSelector):
            now = self.filtersetSelector.currentText()
            self.filtersetSelector.clear()
            now_idx = -1
            for idx, c in enumerate(channels):
                self.filtersetSelector.addItem(c)
                if c == now:
                    now_idx = idx
            if now_idx > -1:
                self.filtersetSelector.setCurrentIndex(now_idx)

        self.__filters_by_channel = tmp1
        self.__current_device_filters_by_channel = tmp2
        self.__filters.filter = self.__filters_by_channel[self.filtersetSelector.itemText(0)]
        if not self.__channel_to_signal:
            self.load_from_signals()
        self.filterView.selectRow(0)
        self.__magnitude_model.redraw()
        self.syncStatus.setIcon(qta.icon('fa5s.link'))
        self.__last_received_msoupdate = None
        self.__last_requested_msoupdate = None
        self.showDetailsButton.setEnabled(False)