Add support for rtl_power_fftw backend
This commit is contained in:
parent
1f48ebf351
commit
314118a7ff
3
PKGBUILD
3
PKGBUILD
@ -1,6 +1,6 @@
|
|||||||
# Maintainer: Michal Krenek (Mikos) <m.krenek@gmail.com>
|
# Maintainer: Michal Krenek (Mikos) <m.krenek@gmail.com>
|
||||||
pkgname=qspectrumanalyzer
|
pkgname=qspectrumanalyzer
|
||||||
pkgver=1.1.1
|
pkgver=1.2.0
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Spectrum analyzer for RTL-SDR (GUI for rtl_power based on PyQtGraph)"
|
pkgdesc="Spectrum analyzer for RTL-SDR (GUI for rtl_power based on PyQtGraph)"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
@ -8,6 +8,7 @@ url="https://github.com/xmikos/qspectrumanalyzer"
|
|||||||
license=('GPL3')
|
license=('GPL3')
|
||||||
depends=('python-pyqt4' 'python-pyqtgraph' 'rtl-sdr')
|
depends=('python-pyqt4' 'python-pyqtgraph' 'rtl-sdr')
|
||||||
makedepends=('python-setuptools')
|
makedepends=('python-setuptools')
|
||||||
|
optdepends=('rtl_power_fftw-git: alternative rtl_power implementation using FFTW library')
|
||||||
source=(https://github.com/xmikos/qspectrumanalyzer/archive/v$pkgver.tar.gz)
|
source=(https://github.com/xmikos/qspectrumanalyzer/archive/v$pkgver.tar.gz)
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Encoding=UTF-8
|
Encoding=UTF-8
|
||||||
Version=1.1.1
|
Version=1.2.0
|
||||||
Name=QSpectrumAnalyzer
|
Name=QSpectrumAnalyzer
|
||||||
GenericName=Spectrum analyzer
|
GenericName=Spectrum analyzer
|
||||||
Comment=Spectrum analyzer for RTL-SDR (GUI for rtl_power based on PyQtGraph)
|
Comment=Spectrum analyzer for RTL-SDR (GUI for rtl_power based on PyQtGraph)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import sys, csv, subprocess, signal
|
import sys, subprocess, signal, math, time, pprint
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
@ -28,21 +28,36 @@ class QSpectrumAnalyzerSettings(QtGui.QDialog, Ui_QSpectrumAnalyzerSettings):
|
|||||||
|
|
||||||
# Load settings
|
# Load settings
|
||||||
settings = QtCore.QSettings()
|
settings = QtCore.QSettings()
|
||||||
self.rtlPowerExecutableEdit.setText(str(settings.value("rtl_power_executable") or "rtl_power"))
|
self.executableEdit.setText(str(settings.value("rtl_power_executable") or "rtl_power"))
|
||||||
self.waterfallHistorySizeSpinBox.setValue(int(settings.value("waterfall_history_size") or 100))
|
self.waterfallHistorySizeSpinBox.setValue(int(settings.value("waterfall_history_size") or 100))
|
||||||
|
self.sampleRateSpinBox.setValue(int(settings.value("sample_rate") or 2560000))
|
||||||
|
|
||||||
|
backend = str(settings.value("backend") or "rtl_power")
|
||||||
|
i = self.backendComboBox.findText(backend)
|
||||||
|
if i == -1:
|
||||||
|
self.backendComboBox.setCurrentIndex(0)
|
||||||
|
else:
|
||||||
|
self.backendComboBox.setCurrentIndex(i)
|
||||||
|
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def on_rtlPowerExecutableButton_clicked(self):
|
def on_executableButton_clicked(self):
|
||||||
"""Open file dialog when button is clicked"""
|
"""Open file dialog when button is clicked"""
|
||||||
filename = QtGui.QFileDialog.getOpenFileName(self, "QSpectrumAnalyzer - rtl_power executable")
|
filename = QtGui.QFileDialog.getOpenFileName(self, "QSpectrumAnalyzer - executable")
|
||||||
if filename:
|
if filename:
|
||||||
self.rtlPowerExecutableEdit.setText(filename)
|
self.executableEdit.setText(filename)
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot(str)
|
||||||
|
def on_backendComboBox_currentIndexChanged(self, text):
|
||||||
|
"""Change executable when backend is changed"""
|
||||||
|
self.executableEdit.setText(text)
|
||||||
|
|
||||||
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.rtlPowerExecutableEdit.text())
|
settings.setValue("rtl_power_executable", self.executableEdit.text())
|
||||||
settings.setValue("waterfall_history_size", self.waterfallHistorySizeSpinBox.value())
|
settings.setValue("waterfall_history_size", self.waterfallHistorySizeSpinBox.value())
|
||||||
|
settings.setValue("sample_rate", self.sampleRateSpinBox.value())
|
||||||
|
settings.setValue("backend", self.backendComboBox.currentText())
|
||||||
QtGui.QDialog.accept(self)
|
QtGui.QDialog.accept(self)
|
||||||
|
|
||||||
|
|
||||||
@ -56,10 +71,9 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
|
|||||||
# Setup rtl_power thread and connect signals
|
# Setup rtl_power thread and connect signals
|
||||||
self.waterfall_history_size = 100
|
self.waterfall_history_size = 100
|
||||||
self.datacounter = 0
|
self.datacounter = 0
|
||||||
self.rtl_power_thread = RtlPowerThread()
|
self.datatimestamp = 0
|
||||||
self.rtl_power_thread.dataUpdated.connect(self.update_data)
|
self.rtl_power_thread = None
|
||||||
self.rtl_power_thread.rtlPowerStarted.connect(self.update_buttons)
|
self.setup_rtl_power_thread()
|
||||||
self.rtl_power_thread.rtlPowerStopped.connect(self.update_buttons)
|
|
||||||
|
|
||||||
# Update UI
|
# Update UI
|
||||||
self.create_plot()
|
self.create_plot()
|
||||||
@ -67,6 +81,22 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
|
|||||||
self.update_buttons()
|
self.update_buttons()
|
||||||
self.load_settings()
|
self.load_settings()
|
||||||
|
|
||||||
|
def setup_rtl_power_thread(self):
|
||||||
|
"""Create rtl_power_thread and connect signals to slots"""
|
||||||
|
if self.rtl_power_thread:
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
settings = QtCore.QSettings()
|
||||||
|
backend = str(settings.value("backend") or "rtl_power")
|
||||||
|
if backend == "rtl_power_fftw":
|
||||||
|
self.rtl_power_thread = RtlPowerFftwThread()
|
||||||
|
else:
|
||||||
|
self.rtl_power_thread = RtlPowerThread()
|
||||||
|
|
||||||
|
self.rtl_power_thread.dataUpdated.connect(self.update_data)
|
||||||
|
self.rtl_power_thread.rtlPowerStarted.connect(self.update_buttons)
|
||||||
|
self.rtl_power_thread.rtlPowerStopped.connect(self.update_buttons)
|
||||||
|
|
||||||
def create_plot(self):
|
def create_plot(self):
|
||||||
"""Create main spectrum plot"""
|
"""Create main spectrum plot"""
|
||||||
self.posLabel = self.mainPlotLayout.addLabel(row=0, col=0, justify="right")
|
self.posLabel = self.mainPlotLayout.addLabel(row=0, col=0, justify="right")
|
||||||
@ -135,6 +165,10 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
|
|||||||
self.update_plot(data)
|
self.update_plot(data)
|
||||||
self.update_waterfall(data)
|
self.update_waterfall(data)
|
||||||
|
|
||||||
|
timestamp = time.time()
|
||||||
|
self.show_status("Sweep time: {:.2f} s".format(timestamp - self.datatimestamp), timeout=0)
|
||||||
|
self.datatimestamp = timestamp
|
||||||
|
|
||||||
def update_plot(self, data):
|
def update_plot(self, data):
|
||||||
"""Update main spectrum plot"""
|
"""Update main spectrum plot"""
|
||||||
self.curve.setData(data["x"], data["y"])
|
self.curve.setData(data["x"], data["y"])
|
||||||
@ -171,7 +205,7 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
|
|||||||
self.startFreqSpinBox.setValue(float(settings.value("start_freq") or 87.0))
|
self.startFreqSpinBox.setValue(float(settings.value("start_freq") or 87.0))
|
||||||
self.stopFreqSpinBox.setValue(float(settings.value("stop_freq") or 108.0))
|
self.stopFreqSpinBox.setValue(float(settings.value("stop_freq") or 108.0))
|
||||||
self.binSizeSpinBox.setValue(float(settings.value("bin_size") or 10.0))
|
self.binSizeSpinBox.setValue(float(settings.value("bin_size") or 10.0))
|
||||||
self.intervalSpinBox.setValue(int(settings.value("interval") or 10))
|
self.intervalSpinBox.setValue(float(settings.value("interval") or 10.0))
|
||||||
self.gainSpinBox.setValue(int(settings.value("gain") or 0))
|
self.gainSpinBox.setValue(int(settings.value("gain") or 0))
|
||||||
self.ppmSpinBox.setValue(int(settings.value("ppm") or 0))
|
self.ppmSpinBox.setValue(int(settings.value("ppm") or 0))
|
||||||
self.cropSpinBox.setValue(int(settings.value("crop") or 0))
|
self.cropSpinBox.setValue(int(settings.value("crop") or 0))
|
||||||
@ -189,7 +223,7 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
|
|||||||
settings.setValue("start_freq", float(self.startFreqSpinBox.value()))
|
settings.setValue("start_freq", float(self.startFreqSpinBox.value()))
|
||||||
settings.setValue("stop_freq", float(self.stopFreqSpinBox.value()))
|
settings.setValue("stop_freq", float(self.stopFreqSpinBox.value()))
|
||||||
settings.setValue("bin_size", float(self.binSizeSpinBox.value()))
|
settings.setValue("bin_size", float(self.binSizeSpinBox.value()))
|
||||||
settings.setValue("interval", int(self.intervalSpinBox.value()))
|
settings.setValue("interval", float(self.intervalSpinBox.value()))
|
||||||
settings.setValue("gain", int(self.gainSpinBox.value()))
|
settings.setValue("gain", int(self.gainSpinBox.value()))
|
||||||
settings.setValue("ppm", int(self.ppmSpinBox.value()))
|
settings.setValue("ppm", int(self.ppmSpinBox.value()))
|
||||||
settings.setValue("crop", int(self.cropSpinBox.value()))
|
settings.setValue("crop", int(self.cropSpinBox.value()))
|
||||||
@ -207,15 +241,17 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
|
|||||||
settings = QtCore.QSettings()
|
settings = QtCore.QSettings()
|
||||||
self.waterfall_history_size = int(settings.value("waterfall_history_size") or 100)
|
self.waterfall_history_size = int(settings.value("waterfall_history_size") or 100)
|
||||||
self.datacounter = 0
|
self.datacounter = 0
|
||||||
|
self.datatimestamp = time.time()
|
||||||
if not self.rtl_power_thread.alive:
|
if not self.rtl_power_thread.alive:
|
||||||
self.rtl_power_thread.setup(float(self.startFreqSpinBox.value()),
|
self.rtl_power_thread.setup(float(self.startFreqSpinBox.value()),
|
||||||
float(self.stopFreqSpinBox.value()),
|
float(self.stopFreqSpinBox.value()),
|
||||||
float(self.binSizeSpinBox.value()),
|
float(self.binSizeSpinBox.value()),
|
||||||
interval=int(self.intervalSpinBox.value()),
|
interval=float(self.intervalSpinBox.value()),
|
||||||
gain=int(self.gainSpinBox.value()),
|
gain=int(self.gainSpinBox.value()),
|
||||||
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,
|
||||||
|
sample_rate=int(settings.value("sample_rate") or 2560000))
|
||||||
self.rtl_power_thread.start()
|
self.rtl_power_thread.start()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
@ -238,7 +274,8 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
|
|||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def on_action_Settings_triggered(self):
|
def on_action_Settings_triggered(self):
|
||||||
dialog = QSpectrumAnalyzerSettings(self)
|
dialog = QSpectrumAnalyzerSettings(self)
|
||||||
dialog.exec_()
|
if dialog.exec_():
|
||||||
|
self.setup_rtl_power_thread()
|
||||||
|
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def on_action_About_triggered(self):
|
def on_action_About_triggered(self):
|
||||||
@ -250,11 +287,11 @@ class QSpectrumAnalyzerMainWindow(QtGui.QMainWindow, Ui_QSpectrumAnalyzerMainWin
|
|||||||
|
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
"""Save settings when main window is closed"""
|
"""Save settings when main window is closed"""
|
||||||
self.rtl_power_thread.stop()
|
self.stop()
|
||||||
self.save_settings()
|
self.save_settings()
|
||||||
|
|
||||||
|
|
||||||
class RtlPowerThread(QtCore.QThread):
|
class RtlPowerBaseThread(QtCore.QThread):
|
||||||
"""Thread which runs rtl_power process"""
|
"""Thread which runs rtl_power process"""
|
||||||
dataUpdated = QtCore.pyqtSignal(object)
|
dataUpdated = QtCore.pyqtSignal(object)
|
||||||
rtlPowerStarted = QtCore.pyqtSignal()
|
rtlPowerStarted = QtCore.pyqtSignal()
|
||||||
@ -264,9 +301,6 @@ class RtlPowerThread(QtCore.QThread):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.alive = False
|
self.alive = False
|
||||||
self.process = None
|
self.process = None
|
||||||
self.params = {}
|
|
||||||
self.databuffer = {}
|
|
||||||
self.last_timestamp = ""
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""Stop rtl_power thread"""
|
"""Stop rtl_power thread"""
|
||||||
@ -274,8 +308,49 @@ class RtlPowerThread(QtCore.QThread):
|
|||||||
self.alive = False
|
self.alive = False
|
||||||
self.wait()
|
self.wait()
|
||||||
|
|
||||||
def setup(self, start_freq, stop_freq, bin_size, interval=10,
|
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
|
||||||
gain=-1, ppm=0, crop=0, single_shot=False):
|
ppm=0, crop=0, single_shot=False, sample_rate=2560000):
|
||||||
|
"""Setup rtl_power params"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def process_start(self):
|
||||||
|
"""Start rtl_power process"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def process_stop(self):
|
||||||
|
"""Terminate rtl_power process"""
|
||||||
|
if self.process:
|
||||||
|
try:
|
||||||
|
self.process.terminate()
|
||||||
|
except ProcessLookupError:
|
||||||
|
pass
|
||||||
|
self.process.wait()
|
||||||
|
self.process = None
|
||||||
|
|
||||||
|
def parse_output(self, line):
|
||||||
|
"""Parse one line of output from rtl_power"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
"""Rtl_power thread main loop"""
|
||||||
|
self.process_start()
|
||||||
|
self.alive = True
|
||||||
|
self.rtlPowerStarted.emit()
|
||||||
|
|
||||||
|
for line in self.process.stdout:
|
||||||
|
if not self.alive:
|
||||||
|
break
|
||||||
|
self.parse_output(line)
|
||||||
|
|
||||||
|
self.process_stop()
|
||||||
|
self.alive = False
|
||||||
|
self.rtlPowerStopped.emit()
|
||||||
|
|
||||||
|
|
||||||
|
class RtlPowerThread(RtlPowerBaseThread):
|
||||||
|
"""Thread which runs rtl_power process"""
|
||||||
|
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
|
||||||
|
ppm=0, crop=0, single_shot=False, sample_rate=2560000):
|
||||||
"""Setup rtl_power params"""
|
"""Setup rtl_power params"""
|
||||||
self.params = {
|
self.params = {
|
||||||
"start_freq": start_freq,
|
"start_freq": start_freq,
|
||||||
@ -287,16 +362,12 @@ class RtlPowerThread(QtCore.QThread):
|
|||||||
"crop": crop,
|
"crop": crop,
|
||||||
"single_shot": single_shot
|
"single_shot": single_shot
|
||||||
}
|
}
|
||||||
|
self.databuffer = {}
|
||||||
|
self.last_timestamp = ""
|
||||||
|
|
||||||
def process_stop(self):
|
print("rtl_power params:")
|
||||||
"""Terminate rtl_power process"""
|
pprint.pprint(self.params)
|
||||||
if self.process:
|
print()
|
||||||
try:
|
|
||||||
self.process.terminate()
|
|
||||||
except ProcessLookupError:
|
|
||||||
pass
|
|
||||||
self.process.wait()
|
|
||||||
self.process = None
|
|
||||||
|
|
||||||
def process_start(self):
|
def process_start(self):
|
||||||
"""Start rtl_power process"""
|
"""Start rtl_power process"""
|
||||||
@ -321,7 +392,8 @@ class RtlPowerThread(QtCore.QThread):
|
|||||||
universal_newlines=True)
|
universal_newlines=True)
|
||||||
|
|
||||||
def parse_output(self, line):
|
def parse_output(self, line):
|
||||||
"""Parse one preprocessed line of output from rtl_power"""
|
"""Parse one line of output from rtl_power"""
|
||||||
|
line = [col.strip() for col in line.split(",")]
|
||||||
timestamp = " ".join(line[:2])
|
timestamp = " ".join(line[:2])
|
||||||
start_freq = int(line[2])
|
start_freq = int(line[2])
|
||||||
stop_freq = int(line[3])
|
stop_freq = int(line[3])
|
||||||
@ -352,24 +424,131 @@ class RtlPowerThread(QtCore.QThread):
|
|||||||
# if stop_freq == self.params["stop_freq"] * 1e6:
|
# if stop_freq == self.params["stop_freq"] * 1e6:
|
||||||
if stop_freq > (self.params["stop_freq"] * 1e6) - step:
|
if stop_freq > (self.params["stop_freq"] * 1e6) - step:
|
||||||
self.dataUpdated.emit(self.databuffer)
|
self.dataUpdated.emit(self.databuffer)
|
||||||
return self.databuffer
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
"""Rtl_power thread main loop"""
|
|
||||||
self.process_start()
|
|
||||||
self.alive = True
|
|
||||||
self.rtlPowerStarted.emit()
|
|
||||||
|
|
||||||
reader = csv.reader(self.process.stdout, skipinitialspace=True,
|
class RtlPowerFftwThread(RtlPowerBaseThread):
|
||||||
delimiter=",", quoting=csv.QUOTE_NONE)
|
"""Thread which runs rtl_power_fftw process"""
|
||||||
for line in reader:
|
def setup(self, start_freq, stop_freq, bin_size, interval=10.0, gain=-1,
|
||||||
if not self.alive:
|
ppm=0, crop=0, single_shot=False, sample_rate=2560000):
|
||||||
break
|
"""Setup rtl_power_fftw params"""
|
||||||
self.parse_output(line)
|
crop = crop * 100
|
||||||
|
overlap = crop * 2
|
||||||
|
freq_range = stop_freq * 1e6 - start_freq * 1e6
|
||||||
|
min_overhang = sample_rate * overlap * 0.01
|
||||||
|
hops = math.ceil((freq_range - min_overhang) / (sample_rate - min_overhang))
|
||||||
|
overhang = (hops * sample_rate - freq_range) / (hops - 1) if hops > 1 else 0
|
||||||
|
bins = math.ceil(sample_rate / (bin_size * 1e3))
|
||||||
|
crop_freq = sample_rate * crop * 0.01
|
||||||
|
|
||||||
self.process_stop()
|
self.params = {
|
||||||
self.alive = False
|
"start_freq": start_freq,
|
||||||
self.rtlPowerStopped.emit()
|
"stop_freq": stop_freq,
|
||||||
|
"freq_range": freq_range,
|
||||||
|
"sample_rate": sample_rate,
|
||||||
|
"bin_size": bin_size,
|
||||||
|
"bins": bins,
|
||||||
|
"interval": interval,
|
||||||
|
"hops": hops,
|
||||||
|
"time": interval / hops,
|
||||||
|
"gain": gain * 10,
|
||||||
|
"ppm": ppm,
|
||||||
|
"crop": crop,
|
||||||
|
"overlap": overlap,
|
||||||
|
"min_overhang": min_overhang,
|
||||||
|
"overhang": overhang,
|
||||||
|
"single_shot": single_shot
|
||||||
|
}
|
||||||
|
self.freqs = [self.get_hop_freq(hop) for hop in range(hops)]
|
||||||
|
self.freqs_crop = [(f[0] + crop_freq, f[1] - crop_freq) for f in self.freqs]
|
||||||
|
self.databuffer = {"timestamp": [], "x": [], "y": []}
|
||||||
|
self.databuffer_hop = {"timestamp": [], "x": [], "y": []}
|
||||||
|
self.hop = 0
|
||||||
|
self.prev_line = ""
|
||||||
|
|
||||||
|
print("rtl_power_fftw params:")
|
||||||
|
pprint.pprint(self.params)
|
||||||
|
print()
|
||||||
|
|
||||||
|
def get_hop_freq(self, hop):
|
||||||
|
"""Get start and stop frequency for particular hop"""
|
||||||
|
start_freq = self.params["start_freq"] * 1e6 + (self.params["sample_rate"] - self.params["overhang"]) * hop
|
||||||
|
stop_freq = start_freq + self.params["sample_rate"] - (self.params["sample_rate"] / self.params["bins"])
|
||||||
|
return (start_freq, stop_freq)
|
||||||
|
|
||||||
|
def process_start(self):
|
||||||
|
"""Start rtl_power_fftw process"""
|
||||||
|
if not self.process and self.params:
|
||||||
|
settings = QtCore.QSettings()
|
||||||
|
cmdline = [
|
||||||
|
str(settings.value("rtl_power_executable") or "rtl_power_fftw"),
|
||||||
|
"-f", "{}M:{}M".format(self.params["start_freq"],
|
||||||
|
self.params["stop_freq"]),
|
||||||
|
"-b", "{}".format(self.params["bins"]),
|
||||||
|
"-t", "{}".format(self.params["time"]),
|
||||||
|
"-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["overlap"] > 0:
|
||||||
|
cmdline.extend(["-o", "{}".format(self.params["overlap"])])
|
||||||
|
if not self.params["single_shot"]:
|
||||||
|
cmdline.append("-c")
|
||||||
|
|
||||||
|
self.process = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
|
||||||
|
universal_newlines=True)
|
||||||
|
|
||||||
|
def parse_output(self, line):
|
||||||
|
"""Parse one line of output from rtl_power_fftw"""
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
# One empty line => new hop
|
||||||
|
if not line and self.prev_line:
|
||||||
|
self.hop += 1
|
||||||
|
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.dataUpdated.emit(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 line[0].isdigit():
|
||||||
|
freq, power = line.split()
|
||||||
|
freq, power = float(freq), float(power)
|
||||||
|
start_freq, stop_freq = self.freqs_crop[self.hop]
|
||||||
|
|
||||||
|
# Apply cropping
|
||||||
|
if freq >= start_freq and freq <= stop_freq:
|
||||||
|
# Skip overlapping frequencies
|
||||||
|
if not self.databuffer["x"] or freq > self.databuffer["x"][-1]:
|
||||||
|
#print(" {:.3f} MHz".format(freq / 1e6))
|
||||||
|
self.databuffer_hop["x"].append(freq)
|
||||||
|
self.databuffer_hop["y"].append(power)
|
||||||
|
else:
|
||||||
|
#print(" Overlapping {:.3f} MHz".format(freq / 1e6))
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
#print(" Cropping {:.3f} MHz".format(freq / 1e6))
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.prev_line = line
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -3,132 +3,132 @@
|
|||||||
<context>
|
<context>
|
||||||
<name>QSpectrumAnalyzerMainWindow</name>
|
<name>QSpectrumAnalyzerMainWindow</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="219"/>
|
<location filename="ui_qspectrumanalyzer.py" line="217"/>
|
||||||
<source>QSpectrumAnalyzer</source>
|
<source>QSpectrumAnalyzer</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="233"/>
|
<location filename="ui_qspectrumanalyzer.py" line="231"/>
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="230"/>
|
<location filename="ui_qspectrumanalyzer.py" line="228"/>
|
||||||
<source> MHz</source>
|
<source> MHz</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="232"/>
|
<location filename="ui_qspectrumanalyzer.py" line="230"/>
|
||||||
<source> kHz</source>
|
<source> kHz</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="236"/>
|
<location filename="ui_qspectrumanalyzer.py" line="234"/>
|
||||||
<source>auto</source>
|
<source>auto</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="226"/>
|
<location filename="ui_qspectrumanalyzer.py" line="224"/>
|
||||||
<source>Frequency</source>
|
<source>Frequency</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="222"/>
|
<location filename="ui_qspectrumanalyzer.py" line="220"/>
|
||||||
<source>Controls</source>
|
<source>Controls</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="239"/>
|
<location filename="ui_qspectrumanalyzer.py" line="237"/>
|
||||||
<source>Levels</source>
|
<source>Levels</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="qspectrumanalyzer.py" line="241"/>
|
<location filename="__main__.py" line="282"/>
|
||||||
<source>About</source>
|
<source>About</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="qspectrumanalyzer.py" line="241"/>
|
<location filename="__main__.py" line="282"/>
|
||||||
<source>QSpectrumAnalyzer {}</source>
|
<source>QSpectrumAnalyzer {}</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="220"/>
|
<location filename="ui_qspectrumanalyzer.py" line="218"/>
|
||||||
<source>&File</source>
|
<source>&File</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="221"/>
|
<location filename="ui_qspectrumanalyzer.py" line="219"/>
|
||||||
<source>&Help</source>
|
<source>&Help</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="223"/>
|
<location filename="ui_qspectrumanalyzer.py" line="221"/>
|
||||||
<source>&Start</source>
|
<source>&Start</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="224"/>
|
<location filename="ui_qspectrumanalyzer.py" line="222"/>
|
||||||
<source>S&top</source>
|
<source>S&top</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="225"/>
|
<location filename="ui_qspectrumanalyzer.py" line="223"/>
|
||||||
<source>Si&ngle shot</source>
|
<source>Si&ngle shot</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="240"/>
|
<location filename="ui_qspectrumanalyzer.py" line="238"/>
|
||||||
<source>&Settings...</source>
|
<source>&Settings...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="241"/>
|
<location filename="ui_qspectrumanalyzer.py" line="239"/>
|
||||||
<source>&Quit</source>
|
<source>&Quit</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="242"/>
|
<location filename="ui_qspectrumanalyzer.py" line="240"/>
|
||||||
<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="243"/>
|
<location filename="ui_qspectrumanalyzer.py" line="241"/>
|
||||||
<source>&About</source>
|
<source>&About</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="234"/>
|
<location filename="ui_qspectrumanalyzer.py" line="232"/>
|
||||||
<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="235"/>
|
<location filename="ui_qspectrumanalyzer.py" line="233"/>
|
||||||
<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="237"/>
|
<location filename="ui_qspectrumanalyzer.py" line="235"/>
|
||||||
<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="238"/>
|
<location filename="ui_qspectrumanalyzer.py" line="236"/>
|
||||||
<source>Crop [%]:</source>
|
<source>Crop [%]:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="227"/>
|
<location filename="ui_qspectrumanalyzer.py" line="225"/>
|
||||||
<source>Start:</source>
|
<source>Start:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="229"/>
|
<location filename="ui_qspectrumanalyzer.py" line="227"/>
|
||||||
<source>Stop:</source>
|
<source>Stop:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer.py" line="231"/>
|
<location filename="ui_qspectrumanalyzer.py" line="229"/>
|
||||||
<source>Bin size:</source>
|
<source>Bin size:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
@ -136,29 +136,44 @@
|
|||||||
<context>
|
<context>
|
||||||
<name>QSpectrumAnalyzerSettings</name>
|
<name>QSpectrumAnalyzerSettings</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer_settings.py" line="73"/>
|
<location filename="ui_qspectrumanalyzer_settings.py" line="90"/>
|
||||||
<source>QSpectrumAnalyzer - Settings</source>
|
<source>QSpectrumAnalyzer - Settings</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer_settings.py" line="74"/>
|
<location filename="ui_qspectrumanalyzer_settings.py" line="95"/>
|
||||||
<source>Rtl_power executable:</source>
|
|
||||||
<translation type="unfinished"></translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<location filename="ui_qspectrumanalyzer_settings.py" line="75"/>
|
|
||||||
<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="76"/>
|
<location filename="ui_qspectrumanalyzer_settings.py" line="96"/>
|
||||||
<source>...</source>
|
<source>...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="ui_qspectrumanalyzer_settings.py" line="77"/>
|
<location filename="ui_qspectrumanalyzer_settings.py" line="97"/>
|
||||||
<source>Waterfall history size:</source>
|
<source>Waterfall history size:</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="ui_qspectrumanalyzer_settings.py" line="91"/>
|
||||||
|
<source>Backend:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="ui_qspectrumanalyzer_settings.py" line="93"/>
|
||||||
|
<source>rtl_power_fftw</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="ui_qspectrumanalyzer_settings.py" line="94"/>
|
||||||
|
<source>Executable:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="ui_qspectrumanalyzer_settings.py" line="98"/>
|
||||||
|
<source>Sample rate:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1100</width>
|
<width>1100</width>
|
||||||
<height>680</height>
|
<height>731</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -52,7 +52,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1100</width>
|
<width>1100</width>
|
||||||
<height>27</height>
|
<height>30</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menu_File">
|
<widget class="QMenu" name="menu_File">
|
||||||
@ -240,22 +240,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QSpinBox" name="intervalSpinBox">
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>3600</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="QSpinBox" name="gainSpinBox">
|
<widget class="QSpinBox" name="gainSpinBox">
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
@ -315,6 +299,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="intervalSpinBox">
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>500</width>
|
<width>350</width>
|
||||||
<height>150</height>
|
<height>210</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -17,23 +17,44 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="formLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Rtl_power executable:</string>
|
<string>Backend:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="backendComboBox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>rtl_power</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>rtl_power_fftw</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Executable:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="rtlPowerExecutableEdit">
|
<widget class="QLineEdit" name="executableEdit">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>rtl_power</string>
|
<string>rtl_power</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="rtlPowerExecutableButton">
|
<widget class="QToolButton" name="executableButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
@ -41,14 +62,14 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Waterfall history size:</string>
|
<string>Waterfall history size:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QSpinBox" name="waterfallHistorySizeSpinBox">
|
<widget class="QSpinBox" name="waterfallHistorySizeSpinBox">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
@ -61,6 +82,29 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Sample rate:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QSpinBox" name="sampleRateSpinBox">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>25000000</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>10000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>2560000</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
@ -89,8 +133,8 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>rtlPowerExecutableEdit</tabstop>
|
<tabstop>executableEdit</tabstop>
|
||||||
<tabstop>rtlPowerExecutableButton</tabstop>
|
<tabstop>executableButton</tabstop>
|
||||||
<tabstop>waterfallHistorySizeSpinBox</tabstop>
|
<tabstop>waterfallHistorySizeSpinBox</tabstop>
|
||||||
<tabstop>buttonBox</tabstop>
|
<tabstop>buttonBox</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
|
|
||||||
# Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer.ui'
|
# Form implementation generated from reading ui file 'qspectrumanalyzer/qspectrumanalyzer.ui'
|
||||||
#
|
#
|
||||||
# Created: Mon Mar 2 23:12:42 2015
|
# Created by: PyQt4 UI code generator 4.11.4
|
||||||
# by: PyQt4 UI code generator 4.11.3
|
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
@ -26,7 +25,7 @@ except AttributeError:
|
|||||||
class Ui_QSpectrumAnalyzerMainWindow(object):
|
class Ui_QSpectrumAnalyzerMainWindow(object):
|
||||||
def setupUi(self, QSpectrumAnalyzerMainWindow):
|
def setupUi(self, QSpectrumAnalyzerMainWindow):
|
||||||
QSpectrumAnalyzerMainWindow.setObjectName(_fromUtf8("QSpectrumAnalyzerMainWindow"))
|
QSpectrumAnalyzerMainWindow.setObjectName(_fromUtf8("QSpectrumAnalyzerMainWindow"))
|
||||||
QSpectrumAnalyzerMainWindow.resize(1100, 680)
|
QSpectrumAnalyzerMainWindow.resize(1100, 731)
|
||||||
self.centralwidget = QtGui.QWidget(QSpectrumAnalyzerMainWindow)
|
self.centralwidget = QtGui.QWidget(QSpectrumAnalyzerMainWindow)
|
||||||
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
|
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
|
||||||
self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
|
self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
|
||||||
@ -56,7 +55,7 @@ class Ui_QSpectrumAnalyzerMainWindow(object):
|
|||||||
self.horizontalLayout.addWidget(self.plotSplitter)
|
self.horizontalLayout.addWidget(self.plotSplitter)
|
||||||
QSpectrumAnalyzerMainWindow.setCentralWidget(self.centralwidget)
|
QSpectrumAnalyzerMainWindow.setCentralWidget(self.centralwidget)
|
||||||
self.menubar = QtGui.QMenuBar(QSpectrumAnalyzerMainWindow)
|
self.menubar = QtGui.QMenuBar(QSpectrumAnalyzerMainWindow)
|
||||||
self.menubar.setGeometry(QtCore.QRect(0, 0, 1100, 27))
|
self.menubar.setGeometry(QtCore.QRect(0, 0, 1100, 30))
|
||||||
self.menubar.setObjectName(_fromUtf8("menubar"))
|
self.menubar.setObjectName(_fromUtf8("menubar"))
|
||||||
self.menu_File = QtGui.QMenu(self.menubar)
|
self.menu_File = QtGui.QMenu(self.menubar)
|
||||||
self.menu_File.setObjectName(_fromUtf8("menu_File"))
|
self.menu_File.setObjectName(_fromUtf8("menu_File"))
|
||||||
@ -134,13 +133,6 @@ class Ui_QSpectrumAnalyzerMainWindow(object):
|
|||||||
self.label_6 = QtGui.QLabel(self.groupBox_3)
|
self.label_6 = QtGui.QLabel(self.groupBox_3)
|
||||||
self.label_6.setObjectName(_fromUtf8("label_6"))
|
self.label_6.setObjectName(_fromUtf8("label_6"))
|
||||||
self.gridLayout_2.addWidget(self.label_6, 0, 1, 1, 1)
|
self.gridLayout_2.addWidget(self.label_6, 0, 1, 1, 1)
|
||||||
self.intervalSpinBox = QtGui.QSpinBox(self.groupBox_3)
|
|
||||||
self.intervalSpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
|
||||||
self.intervalSpinBox.setMinimum(1)
|
|
||||||
self.intervalSpinBox.setMaximum(3600)
|
|
||||||
self.intervalSpinBox.setProperty("value", 10)
|
|
||||||
self.intervalSpinBox.setObjectName(_fromUtf8("intervalSpinBox"))
|
|
||||||
self.gridLayout_2.addWidget(self.intervalSpinBox, 1, 0, 1, 1)
|
|
||||||
self.gainSpinBox = QtGui.QSpinBox(self.groupBox_3)
|
self.gainSpinBox = QtGui.QSpinBox(self.groupBox_3)
|
||||||
self.gainSpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.gainSpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.gainSpinBox.setMinimum(-1)
|
self.gainSpinBox.setMinimum(-1)
|
||||||
@ -164,6 +156,12 @@ class Ui_QSpectrumAnalyzerMainWindow(object):
|
|||||||
self.cropSpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.cropSpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.cropSpinBox.setObjectName(_fromUtf8("cropSpinBox"))
|
self.cropSpinBox.setObjectName(_fromUtf8("cropSpinBox"))
|
||||||
self.gridLayout_2.addWidget(self.cropSpinBox, 3, 1, 1, 1)
|
self.gridLayout_2.addWidget(self.cropSpinBox, 3, 1, 1, 1)
|
||||||
|
self.intervalSpinBox = QtGui.QDoubleSpinBox(self.groupBox_3)
|
||||||
|
self.intervalSpinBox.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.intervalSpinBox.setMaximum(999.0)
|
||||||
|
self.intervalSpinBox.setProperty("value", 1.0)
|
||||||
|
self.intervalSpinBox.setObjectName(_fromUtf8("intervalSpinBox"))
|
||||||
|
self.gridLayout_2.addWidget(self.intervalSpinBox, 1, 0, 1, 1)
|
||||||
self.verticalLayout_3.addWidget(self.groupBox_3)
|
self.verticalLayout_3.addWidget(self.groupBox_3)
|
||||||
self.groupBox_4 = QtGui.QGroupBox(self.dockWidgetContents)
|
self.groupBox_4 = QtGui.QGroupBox(self.dockWidgetContents)
|
||||||
self.groupBox_4.setObjectName(_fromUtf8("groupBox_4"))
|
self.groupBox_4.setObjectName(_fromUtf8("groupBox_4"))
|
||||||
|
@ -2,8 +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: Mon Mar 2 23:12:42 2015
|
# Created by: PyQt4 UI code generator 4.11.4
|
||||||
# by: PyQt4 UI code generator 4.11.3
|
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
@ -26,32 +25,50 @@ 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(500, 150)
|
QSpectrumAnalyzerSettings.resize(350, 210)
|
||||||
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()
|
||||||
self.formLayout.setObjectName(_fromUtf8("formLayout"))
|
self.formLayout.setObjectName(_fromUtf8("formLayout"))
|
||||||
|
self.label_3 = QtGui.QLabel(QSpectrumAnalyzerSettings)
|
||||||
|
self.label_3.setObjectName(_fromUtf8("label_3"))
|
||||||
|
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label_3)
|
||||||
|
self.backendComboBox = QtGui.QComboBox(QSpectrumAnalyzerSettings)
|
||||||
|
self.backendComboBox.setObjectName(_fromUtf8("backendComboBox"))
|
||||||
|
self.backendComboBox.addItem(_fromUtf8(""))
|
||||||
|
self.backendComboBox.addItem(_fromUtf8(""))
|
||||||
|
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"))
|
||||||
self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label)
|
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label)
|
||||||
self.horizontalLayout = QtGui.QHBoxLayout()
|
self.horizontalLayout = QtGui.QHBoxLayout()
|
||||||
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
|
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
|
||||||
self.rtlPowerExecutableEdit = QtGui.QLineEdit(QSpectrumAnalyzerSettings)
|
self.executableEdit = QtGui.QLineEdit(QSpectrumAnalyzerSettings)
|
||||||
self.rtlPowerExecutableEdit.setObjectName(_fromUtf8("rtlPowerExecutableEdit"))
|
self.executableEdit.setObjectName(_fromUtf8("executableEdit"))
|
||||||
self.horizontalLayout.addWidget(self.rtlPowerExecutableEdit)
|
self.horizontalLayout.addWidget(self.executableEdit)
|
||||||
self.rtlPowerExecutableButton = QtGui.QToolButton(QSpectrumAnalyzerSettings)
|
self.executableButton = QtGui.QToolButton(QSpectrumAnalyzerSettings)
|
||||||
self.rtlPowerExecutableButton.setObjectName(_fromUtf8("rtlPowerExecutableButton"))
|
self.executableButton.setObjectName(_fromUtf8("executableButton"))
|
||||||
self.horizontalLayout.addWidget(self.rtlPowerExecutableButton)
|
self.horizontalLayout.addWidget(self.executableButton)
|
||||||
self.formLayout.setLayout(0, QtGui.QFormLayout.FieldRole, self.horizontalLayout)
|
self.formLayout.setLayout(1, QtGui.QFormLayout.FieldRole, self.horizontalLayout)
|
||||||
self.label_2 = QtGui.QLabel(QSpectrumAnalyzerSettings)
|
self.label_2 = QtGui.QLabel(QSpectrumAnalyzerSettings)
|
||||||
self.label_2.setObjectName(_fromUtf8("label_2"))
|
self.label_2.setObjectName(_fromUtf8("label_2"))
|
||||||
self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_2)
|
self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_2)
|
||||||
self.waterfallHistorySizeSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings)
|
self.waterfallHistorySizeSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings)
|
||||||
self.waterfallHistorySizeSpinBox.setMinimum(1)
|
self.waterfallHistorySizeSpinBox.setMinimum(1)
|
||||||
self.waterfallHistorySizeSpinBox.setMaximum(10000000)
|
self.waterfallHistorySizeSpinBox.setMaximum(10000000)
|
||||||
self.waterfallHistorySizeSpinBox.setProperty("value", 100)
|
self.waterfallHistorySizeSpinBox.setProperty("value", 100)
|
||||||
self.waterfallHistorySizeSpinBox.setObjectName(_fromUtf8("waterfallHistorySizeSpinBox"))
|
self.waterfallHistorySizeSpinBox.setObjectName(_fromUtf8("waterfallHistorySizeSpinBox"))
|
||||||
self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.waterfallHistorySizeSpinBox)
|
self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.waterfallHistorySizeSpinBox)
|
||||||
|
self.label_4 = QtGui.QLabel(QSpectrumAnalyzerSettings)
|
||||||
|
self.label_4.setObjectName(_fromUtf8("label_4"))
|
||||||
|
self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_4)
|
||||||
|
self.sampleRateSpinBox = QtGui.QSpinBox(QSpectrumAnalyzerSettings)
|
||||||
|
self.sampleRateSpinBox.setMinimum(0)
|
||||||
|
self.sampleRateSpinBox.setMaximum(25000000)
|
||||||
|
self.sampleRateSpinBox.setSingleStep(10000)
|
||||||
|
self.sampleRateSpinBox.setProperty("value", 2560000)
|
||||||
|
self.sampleRateSpinBox.setObjectName(_fromUtf8("sampleRateSpinBox"))
|
||||||
|
self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.sampleRateSpinBox)
|
||||||
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)
|
||||||
@ -65,14 +82,18 @@ class Ui_QSpectrumAnalyzerSettings(object):
|
|||||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), QSpectrumAnalyzerSettings.accept)
|
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), QSpectrumAnalyzerSettings.accept)
|
||||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), QSpectrumAnalyzerSettings.reject)
|
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), QSpectrumAnalyzerSettings.reject)
|
||||||
QtCore.QMetaObject.connectSlotsByName(QSpectrumAnalyzerSettings)
|
QtCore.QMetaObject.connectSlotsByName(QSpectrumAnalyzerSettings)
|
||||||
QSpectrumAnalyzerSettings.setTabOrder(self.rtlPowerExecutableEdit, self.rtlPowerExecutableButton)
|
QSpectrumAnalyzerSettings.setTabOrder(self.executableEdit, self.executableButton)
|
||||||
QSpectrumAnalyzerSettings.setTabOrder(self.rtlPowerExecutableButton, self.waterfallHistorySizeSpinBox)
|
QSpectrumAnalyzerSettings.setTabOrder(self.executableButton, self.waterfallHistorySizeSpinBox)
|
||||||
QSpectrumAnalyzerSettings.setTabOrder(self.waterfallHistorySizeSpinBox, self.buttonBox)
|
QSpectrumAnalyzerSettings.setTabOrder(self.waterfallHistorySizeSpinBox, self.buttonBox)
|
||||||
|
|
||||||
def retranslateUi(self, QSpectrumAnalyzerSettings):
|
def retranslateUi(self, QSpectrumAnalyzerSettings):
|
||||||
QSpectrumAnalyzerSettings.setWindowTitle(_translate("QSpectrumAnalyzerSettings", "QSpectrumAnalyzer - Settings", None))
|
QSpectrumAnalyzerSettings.setWindowTitle(_translate("QSpectrumAnalyzerSettings", "QSpectrumAnalyzer - Settings", None))
|
||||||
self.label.setText(_translate("QSpectrumAnalyzerSettings", "Rtl_power executable:", None))
|
self.label_3.setText(_translate("QSpectrumAnalyzerSettings", "Backend:", None))
|
||||||
self.rtlPowerExecutableEdit.setText(_translate("QSpectrumAnalyzerSettings", "rtl_power", None))
|
self.backendComboBox.setItemText(0, _translate("QSpectrumAnalyzerSettings", "rtl_power", None))
|
||||||
self.rtlPowerExecutableButton.setText(_translate("QSpectrumAnalyzerSettings", "...", None))
|
self.backendComboBox.setItemText(1, _translate("QSpectrumAnalyzerSettings", "rtl_power_fftw", None))
|
||||||
|
self.label.setText(_translate("QSpectrumAnalyzerSettings", "Executable:", None))
|
||||||
|
self.executableEdit.setText(_translate("QSpectrumAnalyzerSettings", "rtl_power", None))
|
||||||
|
self.executableButton.setText(_translate("QSpectrumAnalyzerSettings", "...", None))
|
||||||
self.label_2.setText(_translate("QSpectrumAnalyzerSettings", "Waterfall history size:", None))
|
self.label_2.setText(_translate("QSpectrumAnalyzerSettings", "Waterfall history size:", None))
|
||||||
|
self.label_4.setText(_translate("QSpectrumAnalyzerSettings", "Sample rate:", None))
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
__version__ = "1.1.1"
|
__version__ = "1.2.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user