Add preliminary support for soapy_power and rx_power

This commit is contained in:
Michal Krenek (Mikos) 2017-02-13 22:00:10 +01:00
parent 6cf2694708
commit 2ffa466b58
10 changed files with 420 additions and 214 deletions

View File

@ -5,7 +5,7 @@ import sys, signal, time
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from qspectrumanalyzer.version import __version__ from qspectrumanalyzer.version import __version__
from qspectrumanalyzer.backend import RtlPowerThread, RtlPowerFftwThread from qspectrumanalyzer.backend import RtlPowerThread, RtlPowerFftwThread, SoapyPowerThread, RxPowerThread
from qspectrumanalyzer.data import DataStorage from qspectrumanalyzer.data import DataStorage
from qspectrumanalyzer.plot import SpectrumPlotWidget, WaterfallPlotWidget from qspectrumanalyzer.plot import SpectrumPlotWidget, WaterfallPlotWidget
from qspectrumanalyzer.utils import color_to_str, str_to_color from qspectrumanalyzer.utils import color_to_str, str_to_color
@ -30,17 +30,19 @@ class QSpectrumAnalyzerSettings(QtGui.QDialog, Ui_QSpectrumAnalyzerSettings):
# Load settings # Load settings
settings = QtCore.QSettings() settings = QtCore.QSettings()
self.executableEdit.setText(settings.value("rtl_power_executable", "rtl_power")) self.executableEdit.setText(settings.value("executable", "soapy_power"))
self.waterfallHistorySizeSpinBox.setValue(settings.value("waterfall_history_size", 100, int)) self.waterfallHistorySizeSpinBox.setValue(settings.value("waterfall_history_size", 100, int))
self.deviceIndexSpinBox.setValue(settings.value("device_index", 0, int)) self.deviceEdit.setText(settings.value("device", ""))
self.sampleRateSpinBox.setValue(settings.value("sample_rate", 2560000, int)) self.sampleRateSpinBox.setValue(settings.value("sample_rate", 2560000, int))
backend = settings.value("backend", "rtl_power") backend = settings.value("backend", "soapy_power")
self.backendComboBox.blockSignals(True)
i = self.backendComboBox.findText(backend) i = self.backendComboBox.findText(backend)
if i == -1: if i == -1:
self.backendComboBox.setCurrentIndex(0) self.backendComboBox.setCurrentIndex(0)
else: else:
self.backendComboBox.setCurrentIndex(i) self.backendComboBox.setCurrentIndex(i)
self.backendComboBox.blockSignals(False)
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def on_executableButton_clicked(self): def on_executableButton_clicked(self):
@ -53,13 +55,14 @@ class QSpectrumAnalyzerSettings(QtGui.QDialog, Ui_QSpectrumAnalyzerSettings):
def on_backendComboBox_currentIndexChanged(self, text): def on_backendComboBox_currentIndexChanged(self, text):
"""Change executable when backend is changed""" """Change executable when backend is changed"""
self.executableEdit.setText(text) self.executableEdit.setText(text)
self.deviceEdit.setText("")
def accept(self): def accept(self):
"""Save settings when dialog is accepted""" """Save settings when dialog is accepted"""
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.setValue("rtl_power_executable", self.executableEdit.text()) settings.setValue("executable", self.executableEdit.text())
settings.setValue("waterfall_history_size", self.waterfallHistorySizeSpinBox.value()) settings.setValue("waterfall_history_size", self.waterfallHistorySizeSpinBox.value())
settings.setValue("device_index", self.deviceIndexSpinBox.value()) settings.setValue("device", self.deviceEdit.text())
settings.setValue("sample_rate", self.sampleRateSpinBox.value()) settings.setValue("sample_rate", self.sampleRateSpinBox.value())
settings.setValue("backend", self.backendComboBox.currentText()) settings.setValue("backend", self.backendComboBox.currentText())
QtGui.QDialog.accept(self) QtGui.QDialog.accept(self)
@ -157,18 +160,18 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
# Link main spectrum plot to waterfall plot # Link main spectrum plot to waterfall plot
self.spectrumPlotWidget.plot.setXLink(self.waterfallPlotWidget.plot) self.spectrumPlotWidget.plot.setXLink(self.waterfallPlotWidget.plot)
# Setup rtl_power thread and connect signals # Setup power thread and connect signals
self.prev_data_timestamp = None self.prev_data_timestamp = None
self.data_storage = None self.data_storage = None
self.rtl_power_thread = None self.power_thread = None
self.setup_rtl_power_thread() self.setup_power_thread()
self.update_buttons() self.update_buttons()
self.load_settings() self.load_settings()
def setup_rtl_power_thread(self): def setup_power_thread(self):
"""Create rtl_power_thread and connect signals to slots""" """Create power_thread and connect signals to slots"""
if self.rtl_power_thread: if self.power_thread:
self.stop() self.stop()
settings = QtCore.QSettings() settings = QtCore.QSettings()
@ -183,14 +186,18 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
self.data_storage.peak_hold_max_updated.connect(self.spectrumPlotWidget.update_peak_hold_max) self.data_storage.peak_hold_max_updated.connect(self.spectrumPlotWidget.update_peak_hold_max)
self.data_storage.peak_hold_min_updated.connect(self.spectrumPlotWidget.update_peak_hold_min) self.data_storage.peak_hold_min_updated.connect(self.spectrumPlotWidget.update_peak_hold_min)
backend = settings.value("backend", "rtl_power") backend = settings.value("backend", "soapy_power")
if backend == "rtl_power_fftw": if backend == "soapy_power":
self.rtl_power_thread = RtlPowerFftwThread(self.data_storage) self.power_thread = SoapyPowerThread(self.data_storage)
elif backend == "rx_power":
self.power_thread = RxPowerThread(self.data_storage)
elif backend == "rtl_power_fftw":
self.power_thread = RtlPowerFftwThread(self.data_storage)
else: else:
self.rtl_power_thread = RtlPowerThread(self.data_storage) self.power_thread = RtlPowerThread(self.data_storage)
self.rtl_power_thread.rtlPowerStarted.connect(self.update_buttons) self.power_thread.powerThreadStarted.connect(self.update_buttons)
self.rtl_power_thread.rtlPowerStopped.connect(self.update_buttons) self.power_thread.powerThreadStopped.connect(self.update_buttons)
def set_dock_size(self, dock, width, height): def set_dock_size(self, dock, width, height):
"""Ugly hack for resizing QDockWidget (because it doesn't respect minimumSize / sizePolicy set in Designer) """Ugly hack for resizing QDockWidget (because it doesn't respect minimumSize / sizePolicy set in Designer)
@ -284,9 +291,9 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
def update_buttons(self): def update_buttons(self):
"""Update state of control buttons""" """Update state of control buttons"""
self.startButton.setEnabled(not self.rtl_power_thread.alive) self.startButton.setEnabled(not self.power_thread.alive)
self.singleShotButton.setEnabled(not self.rtl_power_thread.alive) self.singleShotButton.setEnabled(not self.power_thread.alive)
self.stopButton.setEnabled(self.rtl_power_thread.alive) self.stopButton.setEnabled(self.power_thread.alive)
def update_data(self, data_storage): def update_data(self, data_storage):
"""Update GUI when new data is received""" """Update GUI when new data is received"""
@ -297,7 +304,7 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
self.show_status( self.show_status(
self.tr("Frequency hops: {} | Sweep time: {:.2f} s | FPS: {:.2f}").format( self.tr("Frequency hops: {} | Sweep time: {:.2f} s | FPS: {:.2f}").format(
self.rtl_power_thread.params["hops"] or self.tr("N/A"), self.power_thread.params["hops"] or self.tr("N/A"),
sweep_time, sweep_time,
1 / sweep_time 1 / sweep_time
), ),
@ -305,7 +312,7 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
) )
def start(self, single_shot=False): def start(self, single_shot=False):
"""Start rtl_power thread""" """Start power thread"""
settings = QtCore.QSettings() settings = QtCore.QSettings()
self.prev_data_timestamp = time.time() self.prev_data_timestamp = time.time()
@ -338,8 +345,8 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
self.spectrumPlotWidget.clear_average() self.spectrumPlotWidget.clear_average()
self.spectrumPlotWidget.clear_persistence() self.spectrumPlotWidget.clear_persistence()
if not self.rtl_power_thread.alive: if not self.power_thread.alive:
self.rtl_power_thread.setup(float(self.startFreqSpinBox.value()), self.power_thread.setup(float(self.startFreqSpinBox.value()),
float(self.stopFreqSpinBox.value()), float(self.stopFreqSpinBox.value()),
float(self.binSizeSpinBox.value()), float(self.binSizeSpinBox.value()),
interval=float(self.intervalSpinBox.value()), interval=float(self.intervalSpinBox.value()),
@ -347,14 +354,14 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
ppm=int(self.ppmSpinBox.value()), ppm=int(self.ppmSpinBox.value()),
crop=int(self.cropSpinBox.value()) / 100.0, crop=int(self.cropSpinBox.value()) / 100.0,
single_shot=single_shot, single_shot=single_shot,
device_index=settings.value("device_index", 0, int), device=settings.value("device", ""),
sample_rate=settings.value("sample_rate", 2560000, int)) sample_rate=settings.value("sample_rate", 2560000, int))
self.rtl_power_thread.start() self.power_thread.start()
def stop(self): def stop(self):
"""Stop rtl_power thread""" """Stop power thread"""
if self.rtl_power_thread.alive: if self.power_thread.alive:
self.rtl_power_thread.stop() self.power_thread.stop()
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def on_startButton_clicked(self): def on_startButton_clicked(self):
@ -458,7 +465,7 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
def on_action_Settings_triggered(self): def on_action_Settings_triggered(self):
dialog = QSpectrumAnalyzerSettings(self) dialog = QSpectrumAnalyzerSettings(self)
if dialog.exec_(): if dialog.exec_():
self.setup_rtl_power_thread() self.setup_power_thread()
@QtCore.pyqtSlot() @QtCore.pyqtSlot()
def on_action_About_triggered(self): def on_action_About_triggered(self):

View File

@ -1,13 +1,13 @@
import subprocess, math, pprint import subprocess, math, pprint, re
import numpy as np import numpy as np
from PyQt4 import QtCore from PyQt4 import QtCore
class RtlPowerBaseThread(QtCore.QThread): class BasePowerThread(QtCore.QThread):
"""Thread which runs rtl_power process""" """Thread which runs Power Spectral Density acquisition and calculation process"""
rtlPowerStarted = QtCore.pyqtSignal() powerThreadStarted = QtCore.pyqtSignal()
rtlPowerStopped = QtCore.pyqtSignal() powerThreadStopped = QtCore.pyqtSignal()
def __init__(self, data_storage, parent=None): def __init__(self, data_storage, parent=None):
super().__init__(parent) super().__init__(parent)
@ -16,22 +16,22 @@ class RtlPowerBaseThread(QtCore.QThread):
self.process = None self.process = None
def stop(self): def stop(self):
"""Stop rtl_power thread""" """Stop power process thread"""
self.process_stop() self.process_stop()
self.alive = False self.alive = False
self.wait() self.wait()
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
ppm=0, crop=0, single_shot=False, device_index=0, sample_rate=2560000): ppm=0, crop=0, single_shot=False, device=0, sample_rate=2560000):
"""Setup rtl_power params""" """Setup power process params"""
raise NotImplementedError raise NotImplementedError
def process_start(self): def process_start(self):
"""Start rtl_power process""" """Start power process"""
raise NotImplementedError raise NotImplementedError
def process_stop(self): def process_stop(self):
"""Terminate rtl_power process""" """Terminate power process"""
if self.process: if self.process:
try: try:
self.process.terminate() self.process.terminate()
@ -41,14 +41,14 @@ class RtlPowerBaseThread(QtCore.QThread):
self.process = None self.process = None
def parse_output(self, line): def parse_output(self, line):
"""Parse one line of output from rtl_power""" """Parse one line of output from power process"""
raise NotImplementedError raise NotImplementedError
def run(self): def run(self):
"""Rtl_power thread main loop""" """Power process thread main loop"""
self.process_start() self.process_start()
self.alive = True self.alive = True
self.rtlPowerStarted.emit() self.powerThreadStarted.emit()
for line in self.process.stdout: for line in self.process.stdout:
if not self.alive: if not self.alive:
@ -57,20 +57,102 @@ class RtlPowerBaseThread(QtCore.QThread):
self.process_stop() self.process_stop()
self.alive = False self.alive = False
self.rtlPowerStopped.emit() self.powerThreadStopped.emit()
class RtlPowerThread(RtlPowerBaseThread): class RxPowerThread(BasePowerThread):
"""Thread which runs rx_power process"""
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
ppm=0, crop=0, single_shot=False, device=0, sample_rate=2560000):
"""Setup rx_power params"""
self.params = {
"start_freq": start_freq,
"stop_freq": stop_freq,
"bin_size": bin_size,
"interval": interval,
"device": device,
"hops": 0,
"gain": gain,
"ppm": ppm,
"crop": crop,
"single_shot": single_shot
}
self.databuffer = {}
self.last_timestamp = ""
print("rx_power params:")
pprint.pprint(self.params)
print()
def process_start(self):
"""Start rx_power process"""
if not self.process and self.params:
settings = QtCore.QSettings()
cmdline = [
settings.value("executable", "rx_power"),
"-f", "{}M:{}M:{}k".format(self.params["start_freq"],
self.params["stop_freq"],
self.params["bin_size"]),
"-i", "{}".format(self.params["interval"]),
"-d", "{}".format(self.params["device"]),
"-p", "{}".format(self.params["ppm"]),
"-c", "{}".format(self.params["crop"])
]
if self.params["gain"] >= 0:
cmdline.extend(["-g", "{}".format(self.params["gain"])])
if self.params["single_shot"]:
cmdline.append("-1")
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
universal_newlines=True)
def parse_output(self, line):
"""Parse one line of output from rx_power"""
line = [col.strip() for col in line.split(",")]
timestamp = " ".join(line[:2])
start_freq = int(line[2])
stop_freq = int(line[3])
step = float(line[4])
samples = float(line[5])
x_axis = list(np.arange(start_freq, stop_freq, step))
y_axis = [float(y) for y in line[6:]]
if len(x_axis) != len(y_axis):
print("ERROR: len(x_axis) != len(y_axis), use newer version of rx_power!")
if len(x_axis) > len(y_axis):
print("Trimming x_axis...")
x_axis = x_axis[:len(y_axis)]
else:
print("Trimming y_axis...")
y_axis = y_axis[:len(x_axis)]
if timestamp != self.last_timestamp:
self.last_timestamp = timestamp
self.databuffer = {"timestamp": timestamp,
"x": x_axis,
"y": y_axis}
else:
self.databuffer["x"].extend(x_axis)
self.databuffer["y"].extend(y_axis)
# This have to be stupid like this to be compatible with old broken version of rx_power. Right way is:
# if stop_freq == self.params["stop_freq"] * 1e6:
if stop_freq > (self.params["stop_freq"] * 1e6) - step:
self.data_storage.update(self.databuffer)
class RtlPowerThread(BasePowerThread):
"""Thread which runs rtl_power process""" """Thread which runs rtl_power process"""
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
ppm=0, crop=0, single_shot=False, device_index=0, sample_rate=2560000): ppm=0, crop=0, single_shot=False, device=0, sample_rate=2560000):
"""Setup rtl_power params""" """Setup rtl_power params"""
self.params = { self.params = {
"start_freq": start_freq, "start_freq": start_freq,
"stop_freq": stop_freq, "stop_freq": stop_freq,
"bin_size": bin_size, "bin_size": bin_size,
"interval": interval, "interval": interval,
"device_index": device_index, "device": device,
"hops": 0, "hops": 0,
"gain": gain, "gain": gain,
"ppm": ppm, "ppm": ppm,
@ -89,12 +171,12 @@ class RtlPowerThread(RtlPowerBaseThread):
if not self.process and self.params: if not self.process and self.params:
settings = QtCore.QSettings() settings = QtCore.QSettings()
cmdline = [ cmdline = [
settings.value("rtl_power_executable", "rtl_power"), settings.value("executable", "rtl_power"),
"-f", "{}M:{}M:{}k".format(self.params["start_freq"], "-f", "{}M:{}M:{}k".format(self.params["start_freq"],
self.params["stop_freq"], self.params["stop_freq"],
self.params["bin_size"]), self.params["bin_size"]),
"-i", "{}".format(self.params["interval"]), "-i", "{}".format(self.params["interval"]),
"-d", "{}".format(self.params["device_index"]), "-d", "{}".format(self.params["device"]),
"-p", "{}".format(self.params["ppm"]), "-p", "{}".format(self.params["ppm"]),
"-c", "{}".format(self.params["crop"]) "-c", "{}".format(self.params["crop"])
] ]
@ -142,10 +224,10 @@ class RtlPowerThread(RtlPowerBaseThread):
self.data_storage.update(self.databuffer) self.data_storage.update(self.databuffer)
class RtlPowerFftwThread(RtlPowerBaseThread): class RtlPowerFftwThread(BasePowerThread):
"""Thread which runs rtl_power_fftw process""" """Thread which runs rtl_power_fftw process"""
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1, def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
ppm=0, crop=0, single_shot=False, device_index=0, sample_rate=2560000): ppm=0, crop=0, single_shot=False, device=0, sample_rate=2560000):
"""Setup rtl_power_fftw params""" """Setup rtl_power_fftw params"""
crop = crop * 100 crop = crop * 100
overlap = crop * 2 overlap = crop * 2
@ -160,7 +242,7 @@ class RtlPowerFftwThread(RtlPowerBaseThread):
"start_freq": start_freq, "start_freq": start_freq,
"stop_freq": stop_freq, "stop_freq": stop_freq,
"freq_range": freq_range, "freq_range": freq_range,
"device_index": device_index, "device": device,
"sample_rate": sample_rate, "sample_rate": sample_rate,
"bin_size": bin_size, "bin_size": bin_size,
"bins": bins, "bins": bins,
@ -197,12 +279,12 @@ class RtlPowerFftwThread(RtlPowerBaseThread):
if not self.process and self.params: if not self.process and self.params:
settings = QtCore.QSettings() settings = QtCore.QSettings()
cmdline = [ cmdline = [
settings.value("rtl_power_executable", "rtl_power_fftw"), settings.value("executable", "rtl_power_fftw"),
"-f", "{}M:{}M".format(self.params["start_freq"], "-f", "{}M:{}M".format(self.params["start_freq"],
self.params["stop_freq"]), self.params["stop_freq"]),
"-b", "{}".format(self.params["bins"]), "-b", "{}".format(self.params["bins"]),
"-t", "{}".format(self.params["time"]), "-t", "{}".format(self.params["time"]),
"-d", "{}".format(self.params["device_index"]), "-d", "{}".format(self.params["device"]),
"-r", "{}".format(self.params["sample_rate"]), "-r", "{}".format(self.params["sample_rate"]),
"-p", "{}".format(self.params["ppm"]), "-p", "{}".format(self.params["ppm"]),
] ]
@ -267,3 +349,104 @@ class RtlPowerFftwThread(RtlPowerBaseThread):
pass pass
self.prev_line = line self.prev_line = line
class SoapyPowerThread(BasePowerThread):
"""Thread which runs soapy_power process"""
re_two_floats = re.compile(r'^[-+\d.eE]+\s+[-+\d.eE]+$')
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
ppm=0, crop=0, single_shot=False, device="", sample_rate=2560000):
"""Setup soapy_power params"""
self.params = {
"start_freq": start_freq,
"stop_freq": stop_freq,
"device": device,
"sample_rate": sample_rate,
"bin_size": bin_size,
"interval": interval,
"hops": 0,
"gain": gain * 10,
"ppm": ppm,
"crop": crop * 100,
"single_shot": single_shot
}
self.databuffer = {"timestamp": [], "x": [], "y": []}
self.databuffer_hop = {"timestamp": [], "x": [], "y": []}
self.hop = 0
self.run = 0
self.prev_line = ""
print("soapy_power params:")
pprint.pprint(self.params)
print()
def process_start(self):
"""Start soapy_power process"""
if not self.process and self.params:
settings = QtCore.QSettings()
cmdline = [
settings.value("executable", "soapy_power"),
"-f", "{}M:{}M".format(self.params["start_freq"],
self.params["stop_freq"]),
"-B", "{}k".format(self.params["bin_size"]),
"-T", "{}".format(self.params["interval"]),
"-d", "{}".format(self.params["device"]),
"-r", "{}".format(self.params["sample_rate"]),
"-p", "{}".format(self.params["ppm"]),
]
if self.params["gain"] >= 0:
cmdline.extend(["-g", "{}".format(self.params["gain"])])
if self.params["crop"] > 0:
cmdline.extend(["-k", "{}".format(self.params["crop"])])
if not self.params["single_shot"]:
cmdline.append("-c")
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
universal_newlines=True)
def parse_output(self, line):
"""Parse one line of output from soapy_power"""
line = line.strip()
# One empty line => new hop
if not line and self.prev_line:
self.hop += 1
print(' => HOP:', self.hop)
self.databuffer["x"].extend(self.databuffer_hop["x"])
self.databuffer["y"].extend(self.databuffer_hop["y"])
self.databuffer_hop = {"timestamp": [], "x": [], "y": []}
# Two empty lines => new set
elif not line and not self.prev_line:
self.hop = 0
self.run += 1
print(' * RUN:', self.run)
self.data_storage.update(self.databuffer)
self.databuffer = {"timestamp": [], "x": [], "y": []}
# Get timestamp for new hop and set
elif line.startswith("# Acquisition start:"):
timestamp = line.split(":", 1)[1].strip()
if not self.databuffer_hop["timestamp"]:
self.databuffer_hop["timestamp"] = timestamp
if not self.databuffer["timestamp"]:
self.databuffer["timestamp"] = timestamp
# Skip other comments
elif line.startswith("#"):
pass
# Parse frequency and power
elif self.re_two_floats.match(line):
try:
freq, power = line.split()
except ValueError:
return
freq, power = float(freq), float(power)
self.databuffer_hop["x"].append(freq)
self.databuffer_hop["y"].append(power)
self.prev_line = line

View File

@ -3,37 +3,37 @@
<context> <context>
<name>QSpectrumAnalyzerColors</name> <name>QSpectrumAnalyzerColors</name>
<message> <message>
<location filename="ui_qspectrumanalyzer_colors.py" line="113"/> <location filename="../ui_qspectrumanalyzer_colors.py" line="113"/>
<source>Colors - QSpectrumAnalyzer</source> <source>Colors - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_colors.py" line="114"/> <location filename="../ui_qspectrumanalyzer_colors.py" line="114"/>
<source>Main curve color:</source> <source>Main curve color:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_colors.py" line="123"/> <location filename="../ui_qspectrumanalyzer_colors.py" line="123"/>
<source>...</source> <source>...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_colors.py" line="120"/> <location filename="../ui_qspectrumanalyzer_colors.py" line="120"/>
<source>Average color:</source> <source>Average color:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_colors.py" line="122"/> <location filename="../ui_qspectrumanalyzer_colors.py" line="122"/>
<source>Persistence color:</source> <source>Persistence color:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_colors.py" line="116"/> <location filename="../ui_qspectrumanalyzer_colors.py" line="116"/>
<source>Max. peak hold color:</source> <source>Max. peak hold color:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_colors.py" line="118"/> <location filename="../ui_qspectrumanalyzer_colors.py" line="118"/>
<source>Min. peak hold color:</source> <source>Min. peak hold color:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -41,182 +41,182 @@
<context> <context>
<name>QSpectrumAnalyzerMainWindow</name> <name>QSpectrumAnalyzerMainWindow</name>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="307"/> <location filename="../ui_qspectrumanalyzer.py" line="311"/>
<source>QSpectrumAnalyzer</source> <source>QSpectrumAnalyzer</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="321"/> <location filename="../ui_qspectrumanalyzer.py" line="325"/>
<source>Settings</source> <source>Settings</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="318"/> <location filename="../ui_qspectrumanalyzer.py" line="322"/>
<source> MHz</source> <source> MHz</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="320"/> <location filename="../ui_qspectrumanalyzer.py" line="324"/>
<source> kHz</source> <source> kHz</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="324"/> <location filename="../ui_qspectrumanalyzer.py" line="328"/>
<source>auto</source> <source>auto</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="314"/> <location filename="../ui_qspectrumanalyzer.py" line="318"/>
<source>Frequency</source> <source>Frequency</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="310"/> <location filename="../ui_qspectrumanalyzer.py" line="314"/>
<source>Controls</source> <source>Controls</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="336"/> <location filename="../ui_qspectrumanalyzer.py" line="340"/>
<source>Levels</source> <source>Levels</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="__main__.py" line="465"/> <location filename="../__main__.py" line="472"/>
<source>QSpectrumAnalyzer {}</source> <source>QSpectrumAnalyzer {}</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="308"/> <location filename="../ui_qspectrumanalyzer.py" line="312"/>
<source>&amp;File</source> <source>&amp;File</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="309"/> <location filename="../ui_qspectrumanalyzer.py" line="313"/>
<source>&amp;Help</source> <source>&amp;Help</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="311"/> <location filename="../ui_qspectrumanalyzer.py" line="315"/>
<source>&amp;Start</source> <source>&amp;Start</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="312"/> <location filename="../ui_qspectrumanalyzer.py" line="316"/>
<source>S&amp;top</source> <source>S&amp;top</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="313"/> <location filename="../ui_qspectrumanalyzer.py" line="317"/>
<source>Si&amp;ngle shot</source> <source>Si&amp;ngle shot</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="337"/> <location filename="../ui_qspectrumanalyzer.py" line="341"/>
<source>&amp;Settings...</source> <source>&amp;Settings...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="338"/> <location filename="../ui_qspectrumanalyzer.py" line="342"/>
<source>&amp;Quit</source> <source>&amp;Quit</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="339"/> <location filename="../ui_qspectrumanalyzer.py" line="343"/>
<source>Ctrl+Q</source> <source>Ctrl+Q</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="340"/> <location filename="../ui_qspectrumanalyzer.py" line="344"/>
<source>&amp;About</source> <source>&amp;About</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="322"/> <location filename="../ui_qspectrumanalyzer.py" line="326"/>
<source>Interval [s]:</source> <source>Interval [s]:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="323"/> <location filename="../ui_qspectrumanalyzer.py" line="327"/>
<source>Gain [dB]:</source> <source>Gain [dB]:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="325"/> <location filename="../ui_qspectrumanalyzer.py" line="329"/>
<source>Corr. [ppm]:</source> <source>Corr. [ppm]:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="326"/> <location filename="../ui_qspectrumanalyzer.py" line="330"/>
<source>Crop [%]:</source> <source>Crop [%]:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="315"/> <location filename="../ui_qspectrumanalyzer.py" line="319"/>
<source>Start:</source> <source>Start:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="317"/> <location filename="../ui_qspectrumanalyzer.py" line="321"/>
<source>Stop:</source> <source>Stop:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="319"/> <location filename="../ui_qspectrumanalyzer.py" line="323"/>
<source>Bin size:</source> <source>Bin size:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="332"/> <location filename="../ui_qspectrumanalyzer.py" line="336"/>
<source>Smoothing</source> <source>Smoothing</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="335"/> <location filename="../ui_qspectrumanalyzer.py" line="339"/>
<source>...</source> <source>...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="__main__.py" line="298"/> <location filename="../__main__.py" line="305"/>
<source>N/A</source> <source>N/A</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="__main__.py" line="465"/> <location filename="../__main__.py" line="472"/>
<source>About - QSpectrumAnalyzer</source> <source>About - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="334"/> <location filename="../ui_qspectrumanalyzer.py" line="338"/>
<source>Persistence</source> <source>Persistence</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="331"/> <location filename="../ui_qspectrumanalyzer.py" line="335"/>
<source>Average</source> <source>Average</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="328"/> <location filename="../ui_qspectrumanalyzer.py" line="332"/>
<source>Colors...</source> <source>Colors...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="327"/> <location filename="../ui_qspectrumanalyzer.py" line="331"/>
<source>Main curve</source> <source>Main curve</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="__main__.py" line="298"/> <location filename="../__main__.py" line="305"/>
<source>Frequency hops: {} | Sweep time: {:.2f} s | FPS: {:.2f}</source> <source>Frequency hops: {} | Sweep time: {:.2f} s | FPS: {:.2f}</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="329"/> <location filename="../ui_qspectrumanalyzer.py" line="333"/>
<source>Max. hold</source> <source>Max. hold</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer.py" line="330"/> <location filename="../ui_qspectrumanalyzer.py" line="334"/>
<source>Min. hold</source> <source>Min. hold</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -224,27 +224,27 @@
<context> <context>
<name>QSpectrumAnalyzerPersistence</name> <name>QSpectrumAnalyzerPersistence</name>
<message> <message>
<location filename="ui_qspectrumanalyzer_persistence.py" line="68"/> <location filename="../ui_qspectrumanalyzer_persistence.py" line="68"/>
<source>Persistence - QSpectrumAnalyzer</source> <source>Persistence - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_persistence.py" line="72"/> <location filename="../ui_qspectrumanalyzer_persistence.py" line="72"/>
<source>Persistence length:</source> <source>Persistence length:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_persistence.py" line="69"/> <location filename="../ui_qspectrumanalyzer_persistence.py" line="69"/>
<source>Decay function:</source> <source>Decay function:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_persistence.py" line="70"/> <location filename="../ui_qspectrumanalyzer_persistence.py" line="70"/>
<source>linear</source> <source>linear</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_persistence.py" line="71"/> <location filename="../ui_qspectrumanalyzer_persistence.py" line="71"/>
<source>exponential</source> <source>exponential</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
@ -252,95 +252,105 @@
<context> <context>
<name>QSpectrumAnalyzerSettings</name> <name>QSpectrumAnalyzerSettings</name>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="112"/> <location filename="../ui_qspectrumanalyzer_settings.py" line="111"/>
<source>rtl_power</source> <source>rtl_power</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="113"/> <location filename="../ui_qspectrumanalyzer_settings.py" line="114"/>
<source>...</source> <source>...</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="110"/> <location filename="../ui_qspectrumanalyzer_settings.py" line="110"/>
<source>rtl_power_fftw</source> <source>rtl_power_fftw</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="108"/> <location filename="../ui_qspectrumanalyzer_settings.py" line="107"/>
<source>&amp;Backend:</source> <source>&amp;Backend:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="111"/> <location filename="../ui_qspectrumanalyzer_settings.py" line="112"/>
<source>E&amp;xecutable:</source> <source>E&amp;xecutable:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="114"/> <location filename="../ui_qspectrumanalyzer_settings.py" line="117"/>
<source>&amp;Waterfall history size:</source> <source>&amp;Waterfall history size:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="116"/> <location filename="../ui_qspectrumanalyzer_settings.py" line="116"/>
<source>Sa&amp;mple rate:</source> <source>Sa&amp;mple rate:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="__main__.py" line="48"/> <location filename="../__main__.py" line="50"/>
<source>Select executable - QSpectrumAnalyzer</source> <source>Select executable - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="107"/> <location filename="../ui_qspectrumanalyzer_settings.py" line="106"/>
<source>Settings - QSpectrumAnalyzer</source> <source>Settings - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_settings.py" line="115"/> <location filename="../ui_qspectrumanalyzer_settings.py" line="113"/>
<source>&amp;Device index:</source> <source>soapy_power</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="115"/>
<source>Device:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui_qspectrumanalyzer_settings.py" line="109"/>
<source>rx_power</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context> <context>
<name>QSpectrumAnalyzerSmooth</name> <name>QSpectrumAnalyzerSmooth</name>
<message> <message>
<location filename="ui_qspectrumanalyzer_smooth.py" line="74"/> <location filename="../ui_qspectrumanalyzer_smooth.py" line="74"/>
<source>&amp;Window function:</source> <source>&amp;Window function:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_smooth.py" line="75"/> <location filename="../ui_qspectrumanalyzer_smooth.py" line="75"/>
<source>rectangular</source> <source>rectangular</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_smooth.py" line="76"/> <location filename="../ui_qspectrumanalyzer_smooth.py" line="76"/>
<source>hanning</source> <source>hanning</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_smooth.py" line="77"/> <location filename="../ui_qspectrumanalyzer_smooth.py" line="77"/>
<source>hamming</source> <source>hamming</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_smooth.py" line="78"/> <location filename="../ui_qspectrumanalyzer_smooth.py" line="78"/>
<source>bartlett</source> <source>bartlett</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_smooth.py" line="79"/> <location filename="../ui_qspectrumanalyzer_smooth.py" line="79"/>
<source>blackman</source> <source>blackman</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_smooth.py" line="80"/> <location filename="../ui_qspectrumanalyzer_smooth.py" line="80"/>
<source>Window len&amp;gth:</source> <source>Window len&amp;gth:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="ui_qspectrumanalyzer_smooth.py" line="73"/> <location filename="../ui_qspectrumanalyzer_smooth.py" line="73"/>
<source>Smoothing - QSpectrumAnalyzer</source> <source>Smoothing - QSpectrumAnalyzer</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

View File

@ -107,7 +107,7 @@ class SpectrumPlotWidget:
"""Get alpha value for persistence curve (linear decay)""" """Get alpha value for persistence curve (linear decay)"""
return (-x / length) + 1 return (-x / length) + 1
def decay_exponential(self, x, length, const=1/3): def decay_exponential(self, x, length, const=1 / 3):
"""Get alpha value for persistence curve (exponential decay)""" """Get alpha value for persistence curve (exponential decay)"""
return math.e**(-x / (length * const)) return math.e**(-x / (length * const))
@ -236,6 +236,7 @@ class SpectrumPlotWidget:
self.plot.removeItem(curve) self.plot.removeItem(curve)
self.create_persistence_curves() self.create_persistence_curves()
class WaterfallPlotWidget: class WaterfallPlotWidget:
"""Waterfall plot""" """Waterfall plot"""
def __init__(self, layout, histogram_layout=None): def __init__(self, layout, histogram_layout=None):

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>325</width> <width>420</width>
<height>259</height> <height>255</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -30,7 +30,12 @@
<widget class="QComboBox" name="backendComboBox"> <widget class="QComboBox" name="backendComboBox">
<item> <item>
<property name="text"> <property name="text">
<string>rtl_power</string> <string>soapy_power</string>
</property>
</item>
<item>
<property name="text">
<string>rx_power</string>
</property> </property>
</item> </item>
<item> <item>
@ -38,6 +43,11 @@
<string>rtl_power_fftw</string> <string>rtl_power_fftw</string>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>rtl_power</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
@ -55,7 +65,7 @@
<item> <item>
<widget class="QLineEdit" name="executableEdit"> <widget class="QLineEdit" name="executableEdit">
<property name="text"> <property name="text">
<string>rtl_power</string> <string>soapy_power</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -69,52 +79,19 @@
</layout> </layout>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>&amp;Waterfall history size:</string> <string>Device:</string>
</property> </property>
<property name="buddy"> <property name="buddy">
<cstring>waterfallHistorySizeSpinBox</cstring> <cstring>deviceEdit</cstring>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QSpinBox" name="waterfallHistorySizeSpinBox"> <widget class="QLineEdit" name="deviceEdit"/>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>10000000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>&amp;Device index:</string>
</property>
<property name="buddy">
<cstring>deviceIndexSpinBox</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="deviceIndexSpinBox">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>99</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Sa&amp;mple rate:</string> <string>Sa&amp;mple rate:</string>
@ -124,7 +101,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="3" column="1">
<widget class="QSpinBox" name="sampleRateSpinBox"> <widget class="QSpinBox" name="sampleRateSpinBox">
<property name="minimum"> <property name="minimum">
<number>0</number> <number>0</number>
@ -140,6 +117,29 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&amp;Waterfall history size:</string>
</property>
<property name="buddy">
<cstring>waterfallHistorySizeSpinBox</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="waterfallHistorySizeSpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>10000000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@ -171,9 +171,9 @@
<tabstop>backendComboBox</tabstop> <tabstop>backendComboBox</tabstop>
<tabstop>executableEdit</tabstop> <tabstop>executableEdit</tabstop>
<tabstop>executableButton</tabstop> <tabstop>executableButton</tabstop>
<tabstop>waterfallHistorySizeSpinBox</tabstop> <tabstop>deviceEdit</tabstop>
<tabstop>deviceIndexSpinBox</tabstop>
<tabstop>sampleRateSpinBox</tabstop> <tabstop>sampleRateSpinBox</tabstop>
<tabstop>waterfallHistorySizeSpinBox</tabstop>
<tabstop>buttonBox</tabstop> <tabstop>buttonBox</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
@ -185,8 +185,8 @@
<slot>accept()</slot> <slot>accept()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>236</x> <x>242</x>
<y>252</y> <y>248</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>157</x> <x>157</x>
@ -201,8 +201,8 @@
<slot>reject()</slot> <slot>reject()</slot>
<hints> <hints>
<hint type="sourcelabel"> <hint type="sourcelabel">
<x>304</x> <x>310</x>
<y>252</y> <y>248</y>
</hint> </hint>
<hint type="destinationlabel"> <hint type="destinationlabel">
<x>286</x> <x>286</x>

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer.ui' # Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer.ui'
# #
# Created by: PyQt4 UI code generator 4.11.4 # Created by: PyQt4 UI code generator 4.12
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -77,6 +77,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object):
self.controlsDockWidgetContents = QtGui.QWidget() self.controlsDockWidgetContents = QtGui.QWidget()
self.controlsDockWidgetContents.setObjectName(_fromUtf8("controlsDockWidgetContents")) self.controlsDockWidgetContents.setObjectName(_fromUtf8("controlsDockWidgetContents"))
self.gridLayout_2 = QtGui.QGridLayout(self.controlsDockWidgetContents) self.gridLayout_2 = QtGui.QGridLayout(self.controlsDockWidgetContents)
self.gridLayout_2.setMargin(0)
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
self.startButton = QtGui.QPushButton(self.controlsDockWidgetContents) self.startButton = QtGui.QPushButton(self.controlsDockWidgetContents)
self.startButton.setObjectName(_fromUtf8("startButton")) self.startButton.setObjectName(_fromUtf8("startButton"))
@ -104,6 +105,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object):
self.frequencyDockWidgetContents.setObjectName(_fromUtf8("frequencyDockWidgetContents")) self.frequencyDockWidgetContents.setObjectName(_fromUtf8("frequencyDockWidgetContents"))
self.formLayout = QtGui.QFormLayout(self.frequencyDockWidgetContents) self.formLayout = QtGui.QFormLayout(self.frequencyDockWidgetContents)
self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow) self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow)
self.formLayout.setMargin(0)
self.formLayout.setObjectName(_fromUtf8("formLayout")) self.formLayout.setObjectName(_fromUtf8("formLayout"))
self.label_2 = QtGui.QLabel(self.frequencyDockWidgetContents) self.label_2 = QtGui.QLabel(self.frequencyDockWidgetContents)
self.label_2.setObjectName(_fromUtf8("label_2")) self.label_2.setObjectName(_fromUtf8("label_2"))
@ -167,6 +169,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object):
self.settingsDockWidgetContents = QtGui.QWidget() self.settingsDockWidgetContents = QtGui.QWidget()
self.settingsDockWidgetContents.setObjectName(_fromUtf8("settingsDockWidgetContents")) self.settingsDockWidgetContents.setObjectName(_fromUtf8("settingsDockWidgetContents"))
self.gridLayout = QtGui.QGridLayout(self.settingsDockWidgetContents) self.gridLayout = QtGui.QGridLayout(self.settingsDockWidgetContents)
self.gridLayout.setMargin(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.label_4 = QtGui.QLabel(self.settingsDockWidgetContents) self.label_4 = QtGui.QLabel(self.settingsDockWidgetContents)
self.label_4.setObjectName(_fromUtf8("label_4")) self.label_4.setObjectName(_fromUtf8("label_4"))
@ -248,6 +251,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object):
self.levelsDockWidgetContents = QtGui.QWidget() self.levelsDockWidgetContents = QtGui.QWidget()
self.levelsDockWidgetContents.setObjectName(_fromUtf8("levelsDockWidgetContents")) self.levelsDockWidgetContents.setObjectName(_fromUtf8("levelsDockWidgetContents"))
self.verticalLayout_6 = QtGui.QVBoxLayout(self.levelsDockWidgetContents) self.verticalLayout_6 = QtGui.QVBoxLayout(self.levelsDockWidgetContents)
self.verticalLayout_6.setMargin(0)
self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6")) self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6"))
self.histogramPlotLayout = GraphicsLayoutWidget(self.levelsDockWidgetContents) self.histogramPlotLayout = GraphicsLayoutWidget(self.levelsDockWidgetContents)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Expanding) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Ignored, QtGui.QSizePolicy.Expanding)

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_colors.ui' # Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_colors.ui'
# #
# Created by: PyQt4 UI code generator 4.11.4 # Created by: PyQt4 UI code generator 4.12
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_persistence.ui' # Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_persistence.ui'
# #
# Created by: PyQt4 UI code generator 4.11.4 # Created by: PyQt4 UI code generator 4.12
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_settings.ui' # Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_settings.ui'
# #
# Created by: PyQt4 UI code generator 4.11.4 # Created by: PyQt4 UI code generator 4.12
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -25,7 +25,7 @@ except AttributeError:
class Ui_QSpectrumAnalyzerSettings(object): class Ui_QSpectrumAnalyzerSettings(object):
def setupUi(self, QSpectrumAnalyzerSettings): def setupUi(self, QSpectrumAnalyzerSettings):
QSpectrumAnalyzerSettings.setObjectName(_fromUtf8("QSpectrumAnalyzerSettings")) QSpectrumAnalyzerSettings.setObjectName(_fromUtf8("QSpectrumAnalyzerSettings"))
QSpectrumAnalyzerSettings.resize(325, 259) QSpectrumAnalyzerSettings.resize(420, 255)
self.verticalLayout = QtGui.QVBoxLayout(QSpectrumAnalyzerSettings) self.verticalLayout = QtGui.QVBoxLayout(QSpectrumAnalyzerSettings)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.formLayout = QtGui.QFormLayout() self.formLayout = QtGui.QFormLayout()
@ -37,6 +37,8 @@ class Ui_QSpectrumAnalyzerSettings(object):
self.backendComboBox.setObjectName(_fromUtf8("backendComboBox")) self.backendComboBox.setObjectName(_fromUtf8("backendComboBox"))
self.backendComboBox.addItem(_fromUtf8("")) self.backendComboBox.addItem(_fromUtf8(""))
self.backendComboBox.addItem(_fromUtf8("")) self.backendComboBox.addItem(_fromUtf8(""))
self.backendComboBox.addItem(_fromUtf8(""))
self.backendComboBox.addItem(_fromUtf8(""))
self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.backendComboBox) self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.backendComboBox)
self.label = QtGui.QLabel(QSpectrumAnalyzerSettings) self.label = QtGui.QLabel(QSpectrumAnalyzerSettings)
self.label.setObjectName(_fromUtf8("label")) self.label.setObjectName(_fromUtf8("label"))
@ -50,34 +52,31 @@ class Ui_QSpectrumAnalyzerSettings(object):
self.executableButton.setObjectName(_fromUtf8("executableButton")) self.executableButton.setObjectName(_fromUtf8("executableButton"))
self.horizontalLayout.addWidget(self.executableButton) self.horizontalLayout.addWidget(self.executableButton)
self.formLayout.setLayout(1, QtGui.QFormLayout.FieldRole, self.horizontalLayout) self.formLayout.setLayout(1, QtGui.QFormLayout.FieldRole, self.horizontalLayout)
self.label_2 = QtGui.QLabel(QSpectrumAnalyzerSettings)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_2)
self.waterfallHistorySizeSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings)
self.waterfallHistorySizeSpinBox.setMinimum(1)
self.waterfallHistorySizeSpinBox.setMaximum(10000000)
self.waterfallHistorySizeSpinBox.setProperty("value", 100)
self.waterfallHistorySizeSpinBox.setObjectName(_fromUtf8("waterfallHistorySizeSpinBox"))
self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.waterfallHistorySizeSpinBox)
self.label_5 = QtGui.QLabel(QSpectrumAnalyzerSettings) self.label_5 = QtGui.QLabel(QSpectrumAnalyzerSettings)
self.label_5.setObjectName(_fromUtf8("label_5")) self.label_5.setObjectName(_fromUtf8("label_5"))
self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_5) self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_5)
self.deviceIndexSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings) self.deviceEdit = QtGui.QLineEdit(QSpectrumAnalyzerSettings)
self.deviceIndexSpinBox.setMinimum(0) self.deviceEdit.setObjectName(_fromUtf8("deviceEdit"))
self.deviceIndexSpinBox.setMaximum(99) self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.deviceEdit)
self.deviceIndexSpinBox.setProperty("value", 0)
self.deviceIndexSpinBox.setObjectName(_fromUtf8("deviceIndexSpinBox"))
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.deviceIndexSpinBox)
self.label_4 = QtGui.QLabel(QSpectrumAnalyzerSettings) self.label_4 = QtGui.QLabel(QSpectrumAnalyzerSettings)
self.label_4.setObjectName(_fromUtf8("label_4")) self.label_4.setObjectName(_fromUtf8("label_4"))
self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_4) self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_4)
self.sampleRateSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings) self.sampleRateSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings)
self.sampleRateSpinBox.setMinimum(0) self.sampleRateSpinBox.setMinimum(0)
self.sampleRateSpinBox.setMaximum(25000000) self.sampleRateSpinBox.setMaximum(25000000)
self.sampleRateSpinBox.setSingleStep(10000) self.sampleRateSpinBox.setSingleStep(10000)
self.sampleRateSpinBox.setProperty("value", 2560000) self.sampleRateSpinBox.setProperty("value", 2560000)
self.sampleRateSpinBox.setObjectName(_fromUtf8("sampleRateSpinBox")) self.sampleRateSpinBox.setObjectName(_fromUtf8("sampleRateSpinBox"))
self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.sampleRateSpinBox) self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.sampleRateSpinBox)
self.label_2 = QtGui.QLabel(QSpectrumAnalyzerSettings)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.formLayout.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_2)
self.waterfallHistorySizeSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings)
self.waterfallHistorySizeSpinBox.setMinimum(1)
self.waterfallHistorySizeSpinBox.setMaximum(10000000)
self.waterfallHistorySizeSpinBox.setProperty("value", 100)
self.waterfallHistorySizeSpinBox.setObjectName(_fromUtf8("waterfallHistorySizeSpinBox"))
self.formLayout.setWidget(4, QtGui.QFormLayout.FieldRole, self.waterfallHistorySizeSpinBox)
self.verticalLayout.addLayout(self.formLayout) self.verticalLayout.addLayout(self.formLayout)
spacerItem = QtGui.QSpacerItem(20, 21, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) spacerItem = QtGui.QSpacerItem(20, 21, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem) self.verticalLayout.addItem(spacerItem)
@ -88,9 +87,9 @@ class Ui_QSpectrumAnalyzerSettings(object):
self.verticalLayout.addWidget(self.buttonBox) self.verticalLayout.addWidget(self.buttonBox)
self.label_3.setBuddy(self.backendComboBox) self.label_3.setBuddy(self.backendComboBox)
self.label.setBuddy(self.executableEdit) self.label.setBuddy(self.executableEdit)
self.label_2.setBuddy(self.waterfallHistorySizeSpinBox) self.label_5.setBuddy(self.deviceEdit)
self.label_5.setBuddy(self.deviceIndexSpinBox)
self.label_4.setBuddy(self.sampleRateSpinBox) self.label_4.setBuddy(self.sampleRateSpinBox)
self.label_2.setBuddy(self.waterfallHistorySizeSpinBox)
self.retranslateUi(QSpectrumAnalyzerSettings) self.retranslateUi(QSpectrumAnalyzerSettings)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), QSpectrumAnalyzerSettings.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), QSpectrumAnalyzerSettings.accept)
@ -98,20 +97,22 @@ class Ui_QSpectrumAnalyzerSettings(object):
QtCore.QMetaObject.connectSlotsByName(QSpectrumAnalyzerSettings) QtCore.QMetaObject.connectSlotsByName(QSpectrumAnalyzerSettings)
QSpectrumAnalyzerSettings.setTabOrder(self.backendComboBox, self.executableEdit) QSpectrumAnalyzerSettings.setTabOrder(self.backendComboBox, self.executableEdit)
QSpectrumAnalyzerSettings.setTabOrder(self.executableEdit, self.executableButton) QSpectrumAnalyzerSettings.setTabOrder(self.executableEdit, self.executableButton)
QSpectrumAnalyzerSettings.setTabOrder(self.executableButton, self.waterfallHistorySizeSpinBox) QSpectrumAnalyzerSettings.setTabOrder(self.executableButton, self.deviceEdit)
QSpectrumAnalyzerSettings.setTabOrder(self.waterfallHistorySizeSpinBox, self.deviceIndexSpinBox) QSpectrumAnalyzerSettings.setTabOrder(self.deviceEdit, self.sampleRateSpinBox)
QSpectrumAnalyzerSettings.setTabOrder(self.deviceIndexSpinBox, self.sampleRateSpinBox) QSpectrumAnalyzerSettings.setTabOrder(self.sampleRateSpinBox, self.waterfallHistorySizeSpinBox)
QSpectrumAnalyzerSettings.setTabOrder(self.sampleRateSpinBox, self.buttonBox) QSpectrumAnalyzerSettings.setTabOrder(self.waterfallHistorySizeSpinBox, self.buttonBox)
def retranslateUi(self, QSpectrumAnalyzerSettings): def retranslateUi(self, QSpectrumAnalyzerSettings):
QSpectrumAnalyzerSettings.setWindowTitle(_translate("QSpectrumAnalyzerSettings", "Settings - QSpectrumAnalyzer", None)) QSpectrumAnalyzerSettings.setWindowTitle(_translate("QSpectrumAnalyzerSettings", "Settings - QSpectrumAnalyzer", None))
self.label_3.setText(_translate("QSpectrumAnalyzerSettings", "&Backend:", None)) self.label_3.setText(_translate("QSpectrumAnalyzerSettings", "&Backend:", None))
self.backendComboBox.setItemText(0, _translate("QSpectrumAnalyzerSettings", "rtl_power", None)) self.backendComboBox.setItemText(0, _translate("QSpectrumAnalyzerSettings", "soapy_power", None))
self.backendComboBox.setItemText(1, _translate("QSpectrumAnalyzerSettings", "rtl_power_fftw", None)) self.backendComboBox.setItemText(1, _translate("QSpectrumAnalyzerSettings", "rx_power", None))
self.backendComboBox.setItemText(2, _translate("QSpectrumAnalyzerSettings", "rtl_power_fftw", None))
self.backendComboBox.setItemText(3, _translate("QSpectrumAnalyzerSettings", "rtl_power", None))
self.label.setText(_translate("QSpectrumAnalyzerSettings", "E&xecutable:", None)) self.label.setText(_translate("QSpectrumAnalyzerSettings", "E&xecutable:", None))
self.executableEdit.setText(_translate("QSpectrumAnalyzerSettings", "rtl_power", None)) self.executableEdit.setText(_translate("QSpectrumAnalyzerSettings", "soapy_power", None))
self.executableButton.setText(_translate("QSpectrumAnalyzerSettings", "...", None)) self.executableButton.setText(_translate("QSpectrumAnalyzerSettings", "...", None))
self.label_2.setText(_translate("QSpectrumAnalyzerSettings", "&Waterfall history size:", None)) self.label_5.setText(_translate("QSpectrumAnalyzerSettings", "Device:", None))
self.label_5.setText(_translate("QSpectrumAnalyzerSettings", "&Device index:", None))
self.label_4.setText(_translate("QSpectrumAnalyzerSettings", "Sa&mple rate:", None)) self.label_4.setText(_translate("QSpectrumAnalyzerSettings", "Sa&mple rate:", None))
self.label_2.setText(_translate("QSpectrumAnalyzerSettings", "&Waterfall history size:", None))

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_smooth.ui' # Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer_smooth.ui'
# #
# Created by: PyQt4 UI code generator 4.11.4 # Created by: PyQt4 UI code generator 4.12
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!