mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-21 06:13:41 +00:00
WIP: TDR/DFT improvements
This commit is contained in:
parent
4725942727
commit
acb79fa3bc
6 changed files with 147 additions and 51 deletions
|
|
@ -17,6 +17,8 @@ using namespace std;
|
||||||
Math::DFT::DFT()
|
Math::DFT::DFT()
|
||||||
{
|
{
|
||||||
automaticDC = true;
|
automaticDC = true;
|
||||||
|
removePaddingFromTDR = true;
|
||||||
|
revertWindowFromTDR = true;
|
||||||
DCfreq = 1000000000.0;
|
DCfreq = 1000000000.0;
|
||||||
|
|
||||||
destructing = false;
|
destructing = false;
|
||||||
|
|
@ -67,12 +69,23 @@ void Math::DFT::edit()
|
||||||
ui->windowBox->setLayout(new QVBoxLayout);
|
ui->windowBox->setLayout(new QVBoxLayout);
|
||||||
ui->windowBox->layout()->addWidget(window.createEditor());
|
ui->windowBox->layout()->addWidget(window.createEditor());
|
||||||
|
|
||||||
connect(ui->DCautomatic, &QRadioButton::toggled, [=](bool automatic){
|
connect(ui->removePadding, &QCheckBox::toggled, this, [=](bool remove){
|
||||||
|
removePaddingFromTDR = remove;
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->revertWindow, &QCheckBox::toggled, this, [=](bool revert){
|
||||||
|
revertWindowFromTDR = revert;
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->DCautomatic, &QRadioButton::toggled, this, [=](bool automatic){
|
||||||
automaticDC = automatic;
|
automaticDC = automatic;
|
||||||
ui->freq->setEnabled(!automatic);
|
ui->freq->setEnabled(!automatic);
|
||||||
updateDFT();
|
updateDFT();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ui->removePadding->setChecked(removePaddingFromTDR);
|
||||||
|
ui->revertWindow->setChecked(revertWindowFromTDR);
|
||||||
|
|
||||||
if(automaticDC) {
|
if(automaticDC) {
|
||||||
ui->DCautomatic->setChecked(true);
|
ui->DCautomatic->setChecked(true);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -84,7 +97,7 @@ void Math::DFT::edit()
|
||||||
ui->freq->setPrefixes(" kMG");
|
ui->freq->setPrefixes(" kMG");
|
||||||
ui->freq->setValue(DCfreq);
|
ui->freq->setValue(DCfreq);
|
||||||
|
|
||||||
connect(ui->freq, &SIUnitEdit::valueChanged, [=](double newval){
|
connect(ui->freq, &SIUnitEdit::valueChanged, this, [=](double newval){
|
||||||
DCfreq = newval;
|
DCfreq = newval;
|
||||||
updateDFT();
|
updateDFT();
|
||||||
});
|
});
|
||||||
|
|
@ -111,6 +124,8 @@ nlohmann::json Math::DFT::toJSON()
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
j["automatic_DC"] = automaticDC;
|
j["automatic_DC"] = automaticDC;
|
||||||
j["window"] = window.toJSON();
|
j["window"] = window.toJSON();
|
||||||
|
j["removePadding"] = removePaddingFromTDR;
|
||||||
|
j["revertWindow"] = revertWindowFromTDR;
|
||||||
if(!automaticDC) {
|
if(!automaticDC) {
|
||||||
j["DC"] = DCfreq;
|
j["DC"] = DCfreq;
|
||||||
}
|
}
|
||||||
|
|
@ -124,6 +139,8 @@ void Math::DFT::fromJSON(nlohmann::json j)
|
||||||
if(j.contains("window")) {
|
if(j.contains("window")) {
|
||||||
window.fromJSON(j["window"]);
|
window.fromJSON(j["window"]);
|
||||||
}
|
}
|
||||||
|
removePaddingFromTDR = j.value("removePadding", true);
|
||||||
|
revertWindowFromTDR = j.value("revertWindow", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Math::DFT::inputSamplesChanged(unsigned int begin, unsigned int end)
|
void Math::DFT::inputSamplesChanged(unsigned int begin, unsigned int end)
|
||||||
|
|
@ -169,38 +186,33 @@ void Math::DFTThread::run()
|
||||||
qDebug() << "DFT thread exiting";
|
qDebug() << "DFT thread exiting";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// limit update rate if configured in preferences
|
|
||||||
auto &p = Preferences::getInstance();
|
|
||||||
if(p.Acquisition.limitDFT) {
|
|
||||||
std::this_thread::sleep_until(lastCalc + duration<double>(1.0 / p.Acquisition.maxDFTrate));
|
|
||||||
lastCalc = system_clock::now();
|
|
||||||
}
|
|
||||||
// qDebug() << "DFT thread calculating";
|
// qDebug() << "DFT thread calculating";
|
||||||
|
if(!dft.input) {
|
||||||
|
// not connected, skip calculation
|
||||||
|
continue;
|
||||||
|
}
|
||||||
double DC = dft.DCfreq;
|
double DC = dft.DCfreq;
|
||||||
TDR *tdr = nullptr;
|
TDR *tdr = nullptr;
|
||||||
if(dft.automaticDC) {
|
// find the last TDR operation
|
||||||
// find the last operation that transformed from the frequency domain to the time domain
|
auto in = dft.input;
|
||||||
auto in = dft.input;
|
while(in->getType() != DFT::Type::TDR) {
|
||||||
while(in->getInput()->getDataType() != DFT::DataType::Frequency) {
|
in = dft.input->getInput();
|
||||||
in = dft.input->getInput();
|
if(!in) {
|
||||||
}
|
|
||||||
switch(in->getType()) {
|
|
||||||
case DFT::Type::TDR: {
|
|
||||||
tdr = static_cast<TDR*>(in);
|
|
||||||
if(tdr->getMode() == TDR::Mode::Lowpass) {
|
|
||||||
DC = 0;
|
|
||||||
} else {
|
|
||||||
// bandpass mode, assume DC is in the middle of the frequency data
|
|
||||||
DC = tdr->getInput()->getSample(tdr->getInput()->numSamples()/2).x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// unknown, assume DC is in the middle of the frequency data
|
|
||||||
DC = in->getInput()->getSample(in->getInput()->numSamples()/2).x;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(in) {
|
||||||
|
tdr = static_cast<TDR*>(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tdr && dft.automaticDC) {
|
||||||
|
if(tdr->getMode() == TDR::Mode::Lowpass) {
|
||||||
|
DC = 0;
|
||||||
|
} else {
|
||||||
|
// bandpass mode, assume DC is in the middle of the frequency data
|
||||||
|
DC = tdr->getInput()->getSample(tdr->getInput()->numSamples()/2).x;
|
||||||
|
}
|
||||||
|
}
|
||||||
auto samples = dft.input->rData().size();
|
auto samples = dft.input->rData().size();
|
||||||
auto timeSpacing = dft.input->rData()[1].x - dft.input->rData()[0].x;
|
auto timeSpacing = dft.input->rData()[1].x - dft.input->rData()[0].x;
|
||||||
vector<complex<double>> timeDomain(samples);
|
vector<complex<double>> timeDomain(samples);
|
||||||
|
|
@ -208,14 +220,34 @@ void Math::DFTThread::run()
|
||||||
timeDomain.at(i) = dft.input->rData()[i].y;
|
timeDomain.at(i) = dft.input->rData()[i].y;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fft::shift(timeDomain, false);
|
|
||||||
dft.window.apply(timeDomain);
|
dft.window.apply(timeDomain);
|
||||||
Fft::shift(timeDomain, true);
|
|
||||||
Fft::transform(timeDomain, false);
|
Fft::transform(timeDomain, false);
|
||||||
// shift DC bin into the middle
|
// shift DC bin into the middle
|
||||||
Fft::shift(timeDomain, false);
|
Fft::shift(timeDomain, false);
|
||||||
|
|
||||||
double binSpacing = 1.0 / (timeSpacing * timeDomain.size());
|
double binSpacing = 1.0 / (timeSpacing * timeDomain.size());
|
||||||
|
|
||||||
|
if(tdr) {
|
||||||
|
// split in padding and actual data sections
|
||||||
|
unsigned int padding = timeDomain.size() - tdr->getUnpaddedInputSize();
|
||||||
|
std::vector<std::complex<double>> pad_front(timeDomain.begin(), timeDomain.begin()+padding/2);
|
||||||
|
std::vector<std::complex<double>> data(timeDomain.begin()+padding/2, timeDomain.end()-padding/2);
|
||||||
|
std::vector<std::complex<double>> pad_back(timeDomain.end()-padding/2, timeDomain.end());
|
||||||
|
|
||||||
|
if(dft.revertWindowFromTDR) {
|
||||||
|
tdr->getWindow().reverse(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dft.removePaddingFromTDR) {
|
||||||
|
timeDomain = data;
|
||||||
|
} else {
|
||||||
|
// include padding
|
||||||
|
timeDomain = pad_front;
|
||||||
|
copy(data.begin(), data.end(), back_inserter(timeDomain));
|
||||||
|
copy(pad_back.begin(), pad_back.end(), back_inserter(timeDomain));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dft.data.clear();
|
dft.data.clear();
|
||||||
int DCbin = timeDomain.size() / 2, startBin = 0;
|
int DCbin = timeDomain.size() / 2, startBin = 0;
|
||||||
if(DC > 0) {
|
if(DC > 0) {
|
||||||
|
|
@ -225,16 +257,18 @@ void Math::DFTThread::run()
|
||||||
dft.data.resize(timeDomain.size()/2, TraceMath::Data());
|
dft.data.resize(timeDomain.size()/2, TraceMath::Data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse effect of frequency domain window function from TDR (if available)
|
|
||||||
if(tdr) {
|
|
||||||
tdr->getWindow().reverse(timeDomain);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = startBin;(unsigned int) i<timeDomain.size();i++) {
|
for(int i = startBin;(unsigned int) i<timeDomain.size();i++) {
|
||||||
auto freq = (i - DCbin) * binSpacing + DC;
|
auto freq = (i - DCbin) * binSpacing + DC;
|
||||||
dft.data[i - startBin].x = round(freq);
|
dft.data[i - startBin].x = round(freq);
|
||||||
dft.data[i - startBin].y = timeDomain.at(i);
|
dft.data[i - startBin].y = timeDomain.at(i);
|
||||||
}
|
}
|
||||||
emit dft.outputSamplesChanged(0, dft.data.size());
|
emit dft.outputSamplesChanged(0, dft.data.size());
|
||||||
|
|
||||||
|
// limit update rate if configured in preferences
|
||||||
|
auto &p = Preferences::getInstance();
|
||||||
|
if(p.Acquisition.limitDFT) {
|
||||||
|
std::this_thread::sleep_until(lastCalc + duration<double>(1.0 / p.Acquisition.maxDFTrate));
|
||||||
|
lastCalc = system_clock::now();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ private:
|
||||||
bool automaticDC;
|
bool automaticDC;
|
||||||
double DCfreq;
|
double DCfreq;
|
||||||
WindowFunction window;
|
WindowFunction window;
|
||||||
|
bool removePaddingFromTDR;
|
||||||
|
bool revertWindowFromTDR;
|
||||||
DFTThread *thread;
|
DFTThread *thread;
|
||||||
bool destructing;
|
bool destructing;
|
||||||
QSemaphore semphr;
|
QSemaphore semphr;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<class>DFTDialog</class>
|
<class>DFTDialog</class>
|
||||||
<widget class="QDialog" name="DFTDialog">
|
<widget class="QDialog" name="DFTDialog">
|
||||||
<property name="windowModality">
|
<property name="windowModality">
|
||||||
<enum>Qt::ApplicationModal</enum>
|
<enum>Qt::WindowModality::ApplicationModal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
|
|
@ -19,7 +19,21 @@
|
||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
|
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,1,0">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="removePadding">
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove possible padding from last TDR</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="revertWindow">
|
||||||
|
<property name="text">
|
||||||
|
<string>Revert window function from last TDR</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
|
@ -83,7 +97,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::StandardButton::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ TDR::TDR()
|
||||||
manualDC = 1.0;
|
manualDC = 1.0;
|
||||||
stepResponse = true;
|
stepResponse = true;
|
||||||
mode = Mode::Lowpass;
|
mode = Mode::Lowpass;
|
||||||
|
padding = 0;
|
||||||
|
|
||||||
destructing = false;
|
destructing = false;
|
||||||
thread = new TDRThread(*this);
|
thread = new TDRThread(*this);
|
||||||
|
|
@ -86,19 +87,23 @@ void TDR::edit()
|
||||||
ui->manualMag->setEnabled(enable);
|
ui->manualMag->setEnabled(enable);
|
||||||
};
|
};
|
||||||
|
|
||||||
connect(ui->mode, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index){
|
connect(ui->mode, qOverload<int>(&QComboBox::currentIndexChanged), this, [=](int index){
|
||||||
mode = (Mode) index;
|
mode = (Mode) index;
|
||||||
updateEnabledWidgets();
|
updateEnabledWidgets();
|
||||||
updateTDR();
|
updateTDR();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->computeStepResponse, &QCheckBox::toggled, [=](bool computeStep) {
|
connect(ui->padding, &QSpinBox::valueChanged, this, [=](int value) {
|
||||||
|
padding = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->computeStepResponse, &QCheckBox::toggled, this, [=](bool computeStep) {
|
||||||
stepResponse = computeStep;
|
stepResponse = computeStep;
|
||||||
updateEnabledWidgets();
|
updateEnabledWidgets();
|
||||||
updateTDR();
|
updateTDR();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->DCmanual, &QRadioButton::toggled, [=](bool manual) {
|
connect(ui->DCmanual, &QRadioButton::toggled, this, [=](bool manual) {
|
||||||
automaticDC = !manual;
|
automaticDC = !manual;
|
||||||
updateEnabledWidgets();
|
updateEnabledWidgets();
|
||||||
updateTDR();
|
updateTDR();
|
||||||
|
|
@ -114,6 +119,8 @@ void TDR::edit()
|
||||||
ui->mode->setCurrentIndex(1);
|
ui->mode->setCurrentIndex(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui->padding->setValue(padding);
|
||||||
|
|
||||||
ui->manualMag->setUnit("dBm");
|
ui->manualMag->setUnit("dBm");
|
||||||
ui->manualMag->setPrecision(3);
|
ui->manualMag->setPrecision(3);
|
||||||
ui->manualMag->setValue(Util::SparamTodB(manualDC));
|
ui->manualMag->setValue(Util::SparamTodB(manualDC));
|
||||||
|
|
@ -121,11 +128,11 @@ void TDR::edit()
|
||||||
ui->manualPhase->setPrecision(4);
|
ui->manualPhase->setPrecision(4);
|
||||||
ui->manualPhase->setValue(180.0/M_PI * arg(manualDC));
|
ui->manualPhase->setValue(180.0/M_PI * arg(manualDC));
|
||||||
|
|
||||||
connect(ui->manualMag, &SIUnitEdit::valueChanged, [=](double newval){
|
connect(ui->manualMag, &SIUnitEdit::valueChanged, this, [=](double newval){
|
||||||
manualDC = polar(pow(10, newval / 20.0), arg(manualDC));
|
manualDC = polar(pow(10, newval / 20.0), arg(manualDC));
|
||||||
updateTDR();
|
updateTDR();
|
||||||
});
|
});
|
||||||
connect(ui->manualPhase, &SIUnitEdit::valueChanged, [=](double newval){
|
connect(ui->manualPhase, &SIUnitEdit::valueChanged, this, [=](double newval){
|
||||||
manualDC = polar(abs(manualDC), newval * M_PI / 180.0);
|
manualDC = polar(abs(manualDC), newval * M_PI / 180.0);
|
||||||
updateTDR();
|
updateTDR();
|
||||||
});
|
});
|
||||||
|
|
@ -152,6 +159,7 @@ nlohmann::json TDR::toJSON()
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
j["bandpass_mode"] = mode == Mode::Bandpass;
|
j["bandpass_mode"] = mode == Mode::Bandpass;
|
||||||
j["window"] = window.toJSON();
|
j["window"] = window.toJSON();
|
||||||
|
j["padding"] = padding;
|
||||||
if(mode == Mode::Lowpass) {
|
if(mode == Mode::Lowpass) {
|
||||||
j["step_response"] = stepResponse;
|
j["step_response"] = stepResponse;
|
||||||
if(stepResponse) {
|
if(stepResponse) {
|
||||||
|
|
@ -170,6 +178,7 @@ void TDR::fromJSON(nlohmann::json j)
|
||||||
if(j.contains("window")) {
|
if(j.contains("window")) {
|
||||||
window.fromJSON(j["window"]);
|
window.fromJSON(j["window"]);
|
||||||
}
|
}
|
||||||
|
padding = j.value("padding", 0);
|
||||||
if(j.value("bandpass_mode", true)) {
|
if(j.value("bandpass_mode", true)) {
|
||||||
mode = Mode::Bandpass;
|
mode = Mode::Bandpass;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -224,6 +233,11 @@ void TDR::updateTDR()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int TDR::getUnpaddedInputSize() const
|
||||||
|
{
|
||||||
|
return unpaddedInputSize;
|
||||||
|
}
|
||||||
|
|
||||||
const WindowFunction& TDR::getWindow() const
|
const WindowFunction& TDR::getWindow() const
|
||||||
{
|
{
|
||||||
return window;
|
return window;
|
||||||
|
|
@ -254,14 +268,12 @@ void TDRThread::run()
|
||||||
qDebug() << "TDR thread exiting";
|
qDebug() << "TDR thread exiting";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// limit update rate if configured in preferences
|
|
||||||
auto &p = Preferences::getInstance();
|
|
||||||
if(p.Acquisition.limitDFT) {
|
|
||||||
std::this_thread::sleep_until(lastCalc + duration<double>(1.0 / p.Acquisition.maxDFTrate));
|
|
||||||
lastCalc = system_clock::now();
|
|
||||||
}
|
|
||||||
// qDebug() << "TDR thread calculating";
|
// qDebug() << "TDR thread calculating";
|
||||||
// perform calculation
|
// perform calculation
|
||||||
|
if(!tdr.input) {
|
||||||
|
// not connected, skip calculation
|
||||||
|
continue;
|
||||||
|
}
|
||||||
vector<complex<double>> frequencyDomain;
|
vector<complex<double>> frequencyDomain;
|
||||||
auto stepSize = (tdr.input->rData().back().x - tdr.input->rData().front().x) / (tdr.input->rData().size() - 1);
|
auto stepSize = (tdr.input->rData().back().x - tdr.input->rData().front().x) / (tdr.input->rData().size() - 1);
|
||||||
if(tdr.mode == TDR::Mode::Lowpass) {
|
if(tdr.mode == TDR::Mode::Lowpass) {
|
||||||
|
|
@ -321,6 +333,12 @@ void TDRThread::run()
|
||||||
}
|
}
|
||||||
|
|
||||||
tdr.window.apply(frequencyDomain);
|
tdr.window.apply(frequencyDomain);
|
||||||
|
tdr.unpaddedInputSize = frequencyDomain.size();
|
||||||
|
if(frequencyDomain.size() < tdr.padding) {
|
||||||
|
auto missing = tdr.padding - frequencyDomain.size();
|
||||||
|
frequencyDomain.insert(frequencyDomain.begin(), missing/2, 0);
|
||||||
|
frequencyDomain.insert(frequencyDomain.end(), missing/2, 0);
|
||||||
|
}
|
||||||
Fft::shift(frequencyDomain, true);
|
Fft::shift(frequencyDomain, true);
|
||||||
|
|
||||||
int fft_bins = frequencyDomain.size();
|
int fft_bins = frequencyDomain.size();
|
||||||
|
|
@ -341,5 +359,12 @@ void TDRThread::run()
|
||||||
tdr.updateStepResponse(false);
|
tdr.updateStepResponse(false);
|
||||||
}
|
}
|
||||||
emit tdr.outputSamplesChanged(0, tdr.data.size());
|
emit tdr.outputSamplesChanged(0, tdr.data.size());
|
||||||
|
|
||||||
|
// limit update rate if configured in preferences
|
||||||
|
auto &p = Preferences::getInstance();
|
||||||
|
if(p.Acquisition.limitDFT) {
|
||||||
|
std::this_thread::sleep_until(lastCalc + duration<double>(1.0 / p.Acquisition.maxDFTrate));
|
||||||
|
lastCalc = system_clock::now();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ public:
|
||||||
Mode getMode() const;
|
Mode getMode() const;
|
||||||
const WindowFunction& getWindow() const;
|
const WindowFunction& getWindow() const;
|
||||||
|
|
||||||
|
unsigned int getUnpaddedInputSize() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void inputSamplesChanged(unsigned int begin, unsigned int end) override;
|
void inputSamplesChanged(unsigned int begin, unsigned int end) override;
|
||||||
|
|
||||||
|
|
@ -55,6 +57,8 @@ private:
|
||||||
void updateTDR();
|
void updateTDR();
|
||||||
Mode mode;
|
Mode mode;
|
||||||
WindowFunction window;
|
WindowFunction window;
|
||||||
|
unsigned int padding;
|
||||||
|
unsigned int unpaddedInputSize;
|
||||||
bool stepResponse;
|
bool stepResponse;
|
||||||
bool automaticDC;
|
bool automaticDC;
|
||||||
std::complex<double> manualDC;
|
std::complex<double> manualDC;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<class>TDRDialog</class>
|
<class>TDRDialog</class>
|
||||||
<widget class="QDialog" name="TDRDialog">
|
<widget class="QDialog" name="TDRDialog">
|
||||||
<property name="windowModality">
|
<property name="windowModality">
|
||||||
<enum>Qt::ApplicationModal</enum>
|
<enum>Qt::WindowModality::ApplicationModal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
|
|
@ -43,6 +43,23 @@
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Padding:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="padding">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100000</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
@ -129,7 +146,7 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::StandardButton::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue