1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-22 08:04:49 -05:00

FFTW Wisdom program invocation dialog

This commit is contained in:
f4exb 2021-11-02 01:04:43 +01:00
parent 608a1e9908
commit 2638ee9a4b
7 changed files with 479 additions and 1 deletions

View File

@ -37,6 +37,7 @@ set(sdrgui_SOURCES
gui/featuresdock.cpp
gui/featurepresetsdialog.cpp
gui/featurewindow.cpp
gui/fftwisdomdialog.cpp
gui/glscope.cpp
gui/glscopegui.cpp
gui/glshadercolors.cpp
@ -125,6 +126,7 @@ set(sdrgui_HEADERS
gui/featuresdock.h
gui/featurepresetsdialog.h
gui/featurewindow.h
gui/fftwisdomdialog.h
gui/glscope.h
gui/glscopegui.h
gui/glshadercolors.h
@ -199,6 +201,7 @@ set(sdrgui_FORMS
gui/fmpreemphasisdialog.ui
gui/featureadddialog.ui
gui/featurepresetsdialog.ui
gui/fftwisdomdialog.ui
gui/glscopegui.ui
gui/glspectrumgui.ui
gui/pluginsdialog.ui

View File

@ -0,0 +1,135 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2021 F4EXB //
// written by Edouard Griffiths //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include <QStandardPaths>
#include <QDir>
#include <QFileDialog>
#include <QMessageBox>
#include <QProcess>
#include "fftwisdomdialog.h"
#include "ui_fftwisdomdialog.h"
FFTWisdomDialog::FFTWisdomDialog(QProcess *process, QWidget* parent) :
QDialog(parent),
ui(new Ui::FFTWisdomDialog),
m_process(process)
{
ui->setupUi(this);
QString pathVar = qgetenv("PATH");
QStringList findPaths = pathVar.split(QDir::listSeparator());
findPaths.append(QCoreApplication::applicationDirPath());
QString exePath = QStandardPaths::findExecutable("fftwf-wisdom", findPaths);
if (exePath.length() != 0)
{
m_fftwExecPath = exePath;
ui->executable->setText(exePath);
}
updateArguments(3, false);
}
FFTWisdomDialog::~FFTWisdomDialog()
{
delete ui;
}
void FFTWisdomDialog::on_showFileDialog_clicked()
{
QFileDialog fileDialog(this, "Select FFTW Wisdom file generator");
fileDialog.setOptions(QFileDialog::DontUseNativeDialog);
fileDialog.selectFile(m_fftwExecPath);
if (fileDialog.exec() == QDialog::Accepted)
{
QStringList fileNames = fileDialog.selectedFiles();
if (fileNames.size() > 0) {
m_fftwExecPath = fileNames.at(0);
}
}
}
void FFTWisdomDialog::on_fftwMaxSize_currentIndexChanged(int index)
{
updateArguments(index, ui->fftwReverse->isChecked());
}
void FFTWisdomDialog::on_fftwReverse_toggled(bool checked)
{
updateArguments(ui->fftwMaxSize->currentIndex(), checked);
}
void FFTWisdomDialog::accept()
{
m_process->start(m_fftwExecPath, m_fftwArguments);
qDebug("FFTWisdomDialog::accept: process started");
QDialog::accept();
}
void FFTWisdomDialog::reject()
{
QDialog::reject();
}
void FFTWisdomDialog::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
qDebug("FFTWisdomDialog::processFinished: process finished rc=%d (%d)", exitCode, (int) exitStatus);
if ((exitCode != 0) || (exitStatus != QProcess::NormalExit))
{
QMessageBox::critical(this, "FFTW Wisdom", "fftwf-widdsom program failed");
}
else
{
QString log = m_process->readAllStandardOutput();
QMessageBox::information(this, "FFTW Wisdom", QString("Success\n%1").arg(log));
}
delete m_process;
}
void FFTWisdomDialog::updateArguments(int fftMaxLog2, bool includeReverse)
{
QString filePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
filePath += QDir::separator();
filePath += "fftw-wisdom";
m_fftwArguments.clear();
m_fftwArguments.append("-v");
m_fftwArguments.append("-n");
m_fftwArguments.append("-o");
m_fftwArguments.append(filePath);
for (int i = 7; i <= 7+fftMaxLog2; i++)
{
m_fftwArguments.append(QString("%1").arg(1<<i));
if (includeReverse) {
m_fftwArguments.append(QString("b%1").arg(1<<i));
}
}
QString argStr = m_fftwArguments.join(' ');
qDebug("FFTWisdomDialog::updateArguments: %s %s", qPrintable(m_fftwExecPath), qPrintable(argStr));
ui->fftwCommand->setText(m_fftwExecPath + " " + argStr);
}

View File

@ -0,0 +1,57 @@
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2021 F4EXB //
// written by Edouard Griffiths //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRGUI_GUI_FFTWISDOMDIALOG_H_
#define SDRGUI_GUI_FFTWISDOMDIALOG_H_
#include <QDialog>
#include "export.h"
namespace Ui {
class FFTWisdomDialog;
}
class QProcess;
class SDRGUI_API FFTWisdomDialog : public QDialog {
Q_OBJECT
public:
explicit FFTWisdomDialog(QProcess *process, QWidget* parent = nullptr);
~FFTWisdomDialog();
QProcess *getProcess() { return m_process; }
private slots:
void on_showFileDialog_clicked();
void on_fftwMaxSize_currentIndexChanged(int index);
void on_fftwReverse_toggled(bool checked);
void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
void accept();
void reject();
private:
void updateArguments(int fftMaxLog2, bool includeReverse);
Ui::FFTWisdomDialog *ui;
QString m_fftwExecPath;
QStringList m_fftwArguments;
QProcess *m_process;
};
#endif // SDRGUI_GUI_FFTWISDOMDIALOG_H_

View File

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>FFTWisdomDialog</class>
<widget class="QDialog" name="FFTWisdomDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>427</width>
<height>158</height>
</rect>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="windowTitle">
<string>FFTW Wisdom file generator</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="exeLayout">
<item>
<widget class="QLabel" name="executableLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Path to fftwf-wisdom executable</string>
</property>
<property name="text">
<string>Program</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="executable">
<property name="toolTip">
<string>Channel marker title</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="showFileDialog">
<property name="minimumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Open file</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/res.qrc">
<normaloff>:/preset-load.png</normaloff>:/preset-load.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="argsLayout">
<item>
<widget class="QLabel" name="fftwMaxSizeLabel">
<property name="text">
<string>FFT max</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="fftwMaxSize">
<item>
<property name="text">
<string>128</string>
</property>
</item>
<item>
<property name="text">
<string>256</string>
</property>
</item>
<item>
<property name="text">
<string>512</string>
</property>
</item>
<item>
<property name="text">
<string>1k</string>
</property>
</item>
<item>
<property name="text">
<string>2k</string>
</property>
</item>
<item>
<property name="text">
<string>4k</string>
</property>
</item>
<item>
<property name="text">
<string>8k</string>
</property>
</item>
<item>
<property name="text">
<string>16k</string>
</property>
</item>
<item>
<property name="text">
<string>32k</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QCheckBox" name="fftwReverse">
<property name="toolTip">
<string>Sychronize with reverse API </string>
</property>
<property name="text">
<string>reverse FFT</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="commandLayout">
<item>
<widget class="QLineEdit" name="fftwCommand">
<property name="minimumSize">
<size>
<width>120</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>FFTW Wisdom program invocation</string>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../resources/res.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>FFTWisdomDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>FFTWisdomDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -57,6 +57,7 @@
#include "gui/deviceuserargsdialog.h"
#include "gui/sdrangelsplash.h"
#include "gui/mypositiondialog.h"
#include "gui/fftwisdomdialog.h"
#include "gui/ambedevicesdialog.h"
#include "dsp/dspengine.h"
#include "dsp/spectrumvis.h"
@ -101,7 +102,8 @@ MainWindow::MainWindow(qtwebapp::LoggerWithFile *logger, const MainParser& parse
m_inputGUI(0),
m_sampleRate(0),
m_centerFrequency(0),
m_sampleFileName(std::string("./test.sdriq"))
m_sampleFileName(std::string("./test.sdriq")),
m_fftWisdomProcess(nullptr)
{
qDebug() << "MainWindow::MainWindow: start";
@ -1778,6 +1780,48 @@ void MainWindow::on_action_DeviceUserArguments_triggered()
deviceUserArgsDialog.exec();
}
void MainWindow::on_action_FFT_triggered()
{
qDebug("MainWindow::on_action_FFT_triggered");
m_fftWisdomProcess = new QProcess(this);
connect(m_fftWisdomProcess,
SIGNAL(finished(int, QProcess::ExitStatus)),
this,
SLOT(fftWisdomProcessFinished(int, QProcess::ExitStatus)));
FFTWisdomDialog fftWisdomDialog(m_fftWisdomProcess, this);
if (fftWisdomDialog.exec() == QDialog::Rejected)
{
disconnect(m_fftWisdomProcess,
SIGNAL(finished(int, QProcess::ExitStatus)),
this,
SLOT(fftWisdomProcessFinished(int, QProcess::ExitStatus)));
delete m_fftWisdomProcess;
}
else
{
QMessageBox::information(this, "FFTW Wisdom", QString("Process %1 started").arg(m_fftWisdomProcess->processId()));
}
}
void MainWindow::fftWisdomProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
qDebug("MainWindow::fftWisdomProcessFinished: process finished rc=%d (%d)", exitCode, (int) exitStatus);
if ((exitCode != 0) || (exitStatus != QProcess::NormalExit))
{
QMessageBox::critical(this, "FFTW Wisdom", "fftwf-widdsom program failed");
}
else
{
QString log = m_fftWisdomProcess->readAllStandardOutput();
QMessageBox::information(this, "FFTW Wisdom", QString("Success\n%1").arg(log));
}
delete m_fftWisdomProcess;
}
void MainWindow::on_action_AMBE_triggered()
{
qDebug("MainWindow::on_action_AMBE_triggered");

View File

@ -22,6 +22,7 @@
#include <QMainWindow>
#include <QTimer>
#include <QList>
#include <QProcess>
#include "settings/mainsettings.h"
#include "util/message.h"
@ -119,6 +120,8 @@ private:
CommandKeyReceiver *m_commandKeyReceiver;
QProcess *m_fftWisdomProcess;
void loadSettings();
void loadPresetSettings(const Preset* preset, int tabIndex);
void savePresetSettings(Preset* preset, int tabIndex);
@ -173,6 +176,7 @@ private slots:
void on_commandKeyboardConnect_toggled(bool checked);
void on_action_Audio_triggered();
void on_action_Logging_triggered();
void on_action_FFT_triggered();
void on_action_AMBE_triggered();
void on_action_LimeRFE_triggered();
void on_action_My_Position_triggered();
@ -192,6 +196,7 @@ private slots:
void tabChannelsIndexChanged();
void tabFeaturesIndexChanged();
void commandKeyPressed(Qt::Key key, Qt::KeyboardModifiers keyModifiers, bool release);
void fftWisdomProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
};
#endif // INCLUDE_MAINWINDOW_H

View File

@ -126,6 +126,7 @@
<addaction name="action_Audio"/>
<addaction name="action_Logging"/>
<addaction name="action_My_Position"/>
<addaction name="action_FFT"/>
<addaction name="action_AMBE"/>
<addaction name="action_LimeRFE"/>
<addaction name="menuDevices"/>
@ -972,6 +973,11 @@
</font>
</property>
</action>
<action name="action_FFT">
<property name="text">
<string>FFT</string>
</property>
</action>
<zorder>presetDock</zorder>
<zorder>channelDock</zorder>
<zorder>commandsDock</zorder>