Commit 1c7190e77afeb00acd07d3bb7cfefbd87e5e4114
Committed by
David Gräff
1 parent
9b32a462
Introduce PostProcessingSettings. Remove utils/dsoStrings and add translation me…
…thods directly to the location where the relevant enums are declared. Remove union for math-channel/coupling value: Some compilers have issues here.
Showing
25 changed files
with
316 additions
and
346 deletions
openhantek/readme.md
| ... | ... | @@ -52,8 +52,28 @@ and the graphical part. |
| 52 | 52 | |
| 53 | 53 | All OpenGL rendering takes place in the `GlScope` class. A helper class `GlScopeGraph` contains exactly one |
| 54 | 54 | data sample snapshot including all channels for voltage and spectrum and a pointer to the respective GPU buffer. |
| 55 | -`GlScope` works for OpenGL 3.2 and OpenGL ES 2.0, but this needs to be decided at compile time. Usually Qt | |
| 56 | -selects the right interface. | |
| 55 | +`GlScope` works for OpenGL 3.2 and OpenGL ES 2.0. If both is present, OpenGL will be prefered, but can be | |
| 56 | +overwritten by the user via a command flag. | |
| 57 | + | |
| 58 | +### Export | |
| 59 | + | |
| 60 | +All export related funtionality is within *src/exporting*. | |
| 61 | + | |
| 62 | +The following exporters are implemented: | |
| 63 | + | |
| 64 | +* Export to comma separated value file (CSV): Write to a user selected file, | |
| 65 | +* Export to an image/pdf: Writes an image/pdf to a user selected file, | |
| 66 | +* Print exporter: Creates a printable document and opens the print dialog. | |
| 67 | + | |
| 68 | +All export classes (exportcsv, exportimage, exportprint) implement the | |
| 69 | +ExporterInterface and are registered to the ExporterRegistry in the main.cpp. | |
| 70 | + | |
| 71 | +Some export classes are still using the legacyExportDrawer class to | |
| 72 | +draw the grid and paint all the labels, values and graphs. | |
| 73 | + | |
| 74 | +The plan is to retire this legacy class and replace the paint code with | |
| 75 | +a `GlScope` class shared OpenGL drawing code for at least the grid and the | |
| 76 | +scope graphs. | |
| 57 | 77 | |
| 58 | 78 | ## Data flow |
| 59 | 79 | ... | ... |
openhantek/src/configdialog/DsoConfigAnalysisPage.cpp
| ... | ... | @@ -15,14 +15,14 @@ DsoConfigAnalysisPage::DsoConfigAnalysisPage(DsoSettings *settings, QWidget *par |
| 15 | 15 | windowFunctionLabel = new QLabel(tr("Window function")); |
| 16 | 16 | windowFunctionComboBox = new QComboBox(); |
| 17 | 17 | windowFunctionComboBox->addItems(windowFunctionStrings); |
| 18 | - windowFunctionComboBox->setCurrentIndex((int)settings->scope.spectrumWindow); | |
| 18 | + windowFunctionComboBox->setCurrentIndex((int)settings->post.spectrumWindow); | |
| 19 | 19 | |
| 20 | 20 | referenceLevelLabel = new QLabel(tr("Reference level")); |
| 21 | 21 | referenceLevelSpinBox = new QDoubleSpinBox(); |
| 22 | 22 | referenceLevelSpinBox->setDecimals(1); |
| 23 | 23 | referenceLevelSpinBox->setMinimum(-40.0); |
| 24 | 24 | referenceLevelSpinBox->setMaximum(100.0); |
| 25 | - referenceLevelSpinBox->setValue(settings->scope.spectrumReference); | |
| 25 | + referenceLevelSpinBox->setValue(settings->post.spectrumReference); | |
| 26 | 26 | referenceLevelUnitLabel = new QLabel(tr("dBm")); |
| 27 | 27 | referenceLevelLayout = new QHBoxLayout(); |
| 28 | 28 | referenceLevelLayout->addWidget(referenceLevelSpinBox); |
| ... | ... | @@ -33,7 +33,7 @@ DsoConfigAnalysisPage::DsoConfigAnalysisPage(DsoSettings *settings, QWidget *par |
| 33 | 33 | minimumMagnitudeSpinBox->setDecimals(1); |
| 34 | 34 | minimumMagnitudeSpinBox->setMinimum(-40.0); |
| 35 | 35 | minimumMagnitudeSpinBox->setMaximum(100.0); |
| 36 | - minimumMagnitudeSpinBox->setValue(settings->scope.spectrumLimit); | |
| 36 | + minimumMagnitudeSpinBox->setValue(settings->post.spectrumLimit); | |
| 37 | 37 | minimumMagnitudeUnitLabel = new QLabel(tr("dBm")); |
| 38 | 38 | minimumMagnitudeLayout = new QHBoxLayout(); |
| 39 | 39 | minimumMagnitudeLayout->addWidget(minimumMagnitudeSpinBox); |
| ... | ... | @@ -59,7 +59,7 @@ DsoConfigAnalysisPage::DsoConfigAnalysisPage(DsoSettings *settings, QWidget *par |
| 59 | 59 | |
| 60 | 60 | /// \brief Saves the new settings. |
| 61 | 61 | void DsoConfigAnalysisPage::saveSettings() { |
| 62 | - settings->scope.spectrumWindow = (Dso::WindowFunction)windowFunctionComboBox->currentIndex(); | |
| 63 | - settings->scope.spectrumReference = referenceLevelSpinBox->value(); | |
| 64 | - settings->scope.spectrumLimit = minimumMagnitudeSpinBox->value(); | |
| 62 | + settings->post.spectrumWindow = (Dso::WindowFunction)windowFunctionComboBox->currentIndex(); | |
| 63 | + settings->post.spectrumReference = referenceLevelSpinBox->value(); | |
| 64 | + settings->post.spectrumLimit = minimumMagnitudeSpinBox->value(); | |
| 65 | 65 | } | ... | ... |
openhantek/src/docks/HorizontalDock.cpp
openhantek/src/docks/SpectrumDock.cpp
openhantek/src/docks/TriggerDock.cpp
| ... | ... | @@ -15,7 +15,6 @@ |
| 15 | 15 | #include "hantekdso/controlspecification.h" |
| 16 | 16 | #include "settings.h" |
| 17 | 17 | #include "sispinbox.h" |
| 18 | -#include "utils/dsoStrings.h" | |
| 19 | 18 | #include "utils/printutils.h" |
| 20 | 19 | |
| 21 | 20 | TriggerDock::TriggerDock(DsoSettingsScope *scope, const Dso::ControlSpecification *spec, QWidget *parent, | ... | ... |
openhantek/src/docks/VoltageDock.cpp
| ... | ... | @@ -14,7 +14,6 @@ |
| 14 | 14 | |
| 15 | 15 | #include "settings.h" |
| 16 | 16 | #include "sispinbox.h" |
| 17 | -#include "utils/dsoStrings.h" | |
| 18 | 17 | #include "utils/printutils.h" |
| 19 | 18 | |
| 20 | 19 | template<typename... Args> struct SELECT { |
| ... | ... | @@ -66,9 +65,9 @@ VoltageDock::VoltageDock(DsoSettingsScope *scope, const Dso::ControlSpecificatio |
| 66 | 65 | dockLayout->addWidget(b.invertCheckBox, (int)channel * 3 + 2, 1); |
| 67 | 66 | |
| 68 | 67 | if (channel < spec->channels) |
| 69 | - setCoupling(channel, scope->voltage[channel].couplingIndex); | |
| 68 | + setCoupling(channel, scope->voltage[channel].couplingOrMathIndex); | |
| 70 | 69 | else |
| 71 | - setMode(scope->voltage[channel].math); | |
| 70 | + setMode(scope->voltage[channel].couplingOrMathIndex); | |
| 72 | 71 | setGain(channel, scope->voltage[channel].gainStepIndex); |
| 73 | 72 | setUsed(channel, scope->voltage[channel].used); |
| 74 | 73 | |
| ... | ... | @@ -80,12 +79,11 @@ VoltageDock::VoltageDock(DsoSettingsScope *scope, const Dso::ControlSpecificatio |
| 80 | 79 | this->scope->voltage[channel].inverted = checked; |
| 81 | 80 | }); |
| 82 | 81 | connect(b.miscComboBox, SELECT<int>::OVERLOAD_OF(&QComboBox::currentIndexChanged), [this,channel,spec,scope](int index){ |
| 82 | + this->scope->voltage[channel].couplingOrMathIndex = (unsigned)index; | |
| 83 | 83 | if (channel < spec->channels) { |
| 84 | - this->scope->voltage[channel].couplingIndex = (unsigned)index; | |
| 85 | 84 | emit couplingChanged(channel, scope->coupling(channel, spec)); |
| 86 | 85 | } else { |
| 87 | - this->scope->voltage[channel].math = (Dso::MathMode) index; | |
| 88 | - emit modeChanged(this->scope->voltage[channel].math); | |
| 86 | + emit modeChanged(Dso::getMathMode(this->scope->voltage[channel])); | |
| 89 | 87 | } |
| 90 | 88 | }); |
| 91 | 89 | connect(b.usedCheckBox, &QAbstractButton::toggled, [this,channel](bool checked) { |
| ... | ... | @@ -119,9 +117,9 @@ void VoltageDock::setGain(ChannelID channel, unsigned gainStepIndex) { |
| 119 | 117 | channelBlocks[channel].gainComboBox->setCurrentIndex((unsigned)gainStepIndex); |
| 120 | 118 | } |
| 121 | 119 | |
| 122 | -void VoltageDock::setMode(Dso::MathMode mode) { | |
| 120 | +void VoltageDock::setMode(unsigned mathModeIndex) { | |
| 123 | 121 | QSignalBlocker blocker(channelBlocks[spec->channels].miscComboBox); |
| 124 | - channelBlocks[spec->channels].miscComboBox->setCurrentIndex((int)mode); | |
| 122 | + channelBlocks[spec->channels].miscComboBox->setCurrentIndex((int)mathModeIndex); | |
| 125 | 123 | } |
| 126 | 124 | |
| 127 | 125 | void VoltageDock::setUsed(ChannelID channel, bool used) { | ... | ... |
openhantek/src/docks/VoltageDock.h
| ... | ... | @@ -10,6 +10,7 @@ |
| 10 | 10 | |
| 11 | 11 | #include "scopesettings.h" |
| 12 | 12 | #include "hantekdso/controlspecification.h" |
| 13 | +#include "post/postprocessingsettings.h" | |
| 13 | 14 | |
| 14 | 15 | class SiSpinBox; |
| 15 | 16 | |
| ... | ... | @@ -28,7 +29,7 @@ class VoltageDock : public QDockWidget { |
| 28 | 29 | |
| 29 | 30 | /// \brief Sets the coupling for a channel. |
| 30 | 31 | /// \param channel The channel, whose coupling should be set. |
| 31 | - /// \param coupling The coupling-mode. | |
| 32 | + /// \param couplingIndex The coupling-mode index. | |
| 32 | 33 | void setCoupling(ChannelID channel, unsigned couplingIndex); |
| 33 | 34 | |
| 34 | 35 | /// \brief Sets the gain for a channel. |
| ... | ... | @@ -37,8 +38,8 @@ class VoltageDock : public QDockWidget { |
| 37 | 38 | void setGain(ChannelID channel, unsigned gainStepIndex); |
| 38 | 39 | |
| 39 | 40 | /// \brief Sets the mode for the math channel. |
| 40 | - /// \param mode The math-mode. | |
| 41 | - void setMode(Dso::MathMode mode); | |
| 41 | + /// \param mathModeIndex The math-mode index. | |
| 42 | + void setMode(unsigned mathModeIndex); | |
| 42 | 43 | |
| 43 | 44 | /// \brief Enables/disables a channel. |
| 44 | 45 | /// \param channel The channel, that should be enabled/disabled. | ... | ... |
openhantek/src/docks/dockwindows.cpp
openhantek/src/dsowidget.cpp
| ... | ... | @@ -10,10 +10,10 @@ |
| 10 | 10 | |
| 11 | 11 | #include "dsowidget.h" |
| 12 | 12 | |
| 13 | +#include "post/postprocessingsettings.h" | |
| 13 | 14 | #include "post/graphgenerator.h" |
| 14 | 15 | #include "post/ppresult.h" |
| 15 | 16 | |
| 16 | -#include "utils/dsoStrings.h" | |
| 17 | 17 | #include "utils/printutils.h" |
| 18 | 18 | |
| 19 | 19 | #include "glscope.h" |
| ... | ... | @@ -252,10 +252,6 @@ void DsoWidget::setupSliders(DsoWidget::Sliders &sliders) { |
| 252 | 252 | } |
| 253 | 253 | } |
| 254 | 254 | |
| 255 | -void DsoWidget::setExporterForNextFrame(std::unique_ptr<Exporter> exporter) { | |
| 256 | - this->exportNextFrame = std::move(exporter); | |
| 257 | -} | |
| 258 | - | |
| 259 | 255 | /// \brief Set the trigger level sliders minimum and maximum to the new values. |
| 260 | 256 | void DsoWidget::adaptTriggerLevelSlider(DsoWidget::Sliders &sliders, ChannelID channel) { |
| 261 | 257 | sliders.triggerLevelSlider->setLimits((int)channel, |
| ... | ... | @@ -422,7 +418,8 @@ void DsoWidget::updateVoltageCoupling(ChannelID channel) { |
| 422 | 418 | |
| 423 | 419 | /// \brief Handles modeChanged signal from the voltage dock. |
| 424 | 420 | void DsoWidget::updateMathMode() { |
| 425 | - measurementMiscLabel[spec->channels]->setText(Dso::mathModeString(scope->voltage[spec->channels].math)); | |
| 421 | + measurementMiscLabel[spec->channels]->setText( | |
| 422 | + Dso::mathModeString(Dso::getMathMode(scope->voltage[spec->channels]))); | |
| 426 | 423 | } |
| 427 | 424 | |
| 428 | 425 | /// \brief Handles gainChanged signal from the voltage dock. |
| ... | ... | @@ -486,15 +483,8 @@ void DsoWidget::updateZoom(bool enabled) { |
| 486 | 483 | |
| 487 | 484 | /// \brief Prints analyzed data. |
| 488 | 485 | void DsoWidget::showNew(std::shared_ptr<PPresult> data) { |
| 489 | - if (exportNextFrame) { | |
| 490 | - exportNextFrame->exportSamples(data.get()); | |
| 491 | - exportNextFrame.reset(nullptr); | |
| 492 | - } | |
| 493 | - | |
| 494 | - mainScope->showData(data.get()); | |
| 495 | - mainScope->update(); | |
| 496 | - zoomScope->showData(data.get()); | |
| 497 | - zoomScope->update(); | |
| 486 | + mainScope->showData(data); | |
| 487 | + zoomScope->showData(data); | |
| 498 | 488 | |
| 499 | 489 | if (spec->isSoftwareTriggerDevice) { |
| 500 | 490 | QPalette triggerLabelPalette = palette(); | ... | ... |
openhantek/src/dsowidget.h
| ... | ... | @@ -8,7 +8,6 @@ |
| 8 | 8 | #include <QGridLayout> |
| 9 | 9 | #include <memory> |
| 10 | 10 | |
| 11 | -#include "exporting/exporter.h" | |
| 12 | 11 | #include "glscope.h" |
| 13 | 12 | #include "levelslider.h" |
| 14 | 13 | #include "hantekdso/controlspecification.h" |
| ... | ... | @@ -36,7 +35,6 @@ class DsoWidget : public QWidget { |
| 36 | 35 | /// \param parent The parent widget. |
| 37 | 36 | /// \param flags Flags for the window manager. |
| 38 | 37 | DsoWidget(DsoSettingsScope* scope, DsoSettingsView* view, const Dso::ControlSpecification* spec, QWidget *parent = 0, Qt::WindowFlags flags = 0); |
| 39 | - void setExporterForNextFrame(std::unique_ptr<Exporter> exporter); | |
| 40 | 38 | |
| 41 | 39 | // Data arrived |
| 42 | 40 | void showNew(std::shared_ptr<PPresult> data); |
| ... | ... | @@ -87,7 +85,6 @@ class DsoWidget : public QWidget { |
| 87 | 85 | |
| 88 | 86 | GlScope *mainScope; ///< The main scope screen |
| 89 | 87 | GlScope *zoomScope; ///< The optional magnified scope screen |
| 90 | - std::unique_ptr<Exporter> exportNextFrame; | |
| 91 | 88 | |
| 92 | 89 | public slots: |
| 93 | 90 | // Horizontal axis | ... | ... |
openhantek/src/hantekdso/enums.cpp
| 1 | 1 | #include "enums.h" |
| 2 | +#include <QCoreApplication> | |
| 2 | 3 | |
| 3 | 4 | namespace Dso { |
| 4 | 5 | Enum<Dso::TriggerMode, Dso::TriggerMode::HARDWARE_SOFTWARE, Dso::TriggerMode::SINGLE> TriggerModeEnum; |
| 5 | 6 | Enum<Dso::Slope, Dso::Slope::Positive, Dso::Slope::Negative> SlopeEnum; |
| 6 | 7 | Enum<Dso::GraphFormat, Dso::GraphFormat::TY, Dso::GraphFormat::XY> GraphFormatEnum; |
| 8 | + | |
| 9 | + /// \brief Return string representation of the given channel mode. | |
| 10 | + /// \param mode The ::ChannelMode that should be returned as string. | |
| 11 | + /// \return The string that should be used in labels etc., empty when invalid. | |
| 12 | + QString channelModeString(ChannelMode mode) { | |
| 13 | + switch (mode) { | |
| 14 | + case ChannelMode::Voltage: | |
| 15 | + return QCoreApplication::tr("Voltage"); | |
| 16 | + case ChannelMode::Spectrum: | |
| 17 | + return QCoreApplication::tr("Spectrum"); | |
| 18 | + } | |
| 19 | + return QString(); | |
| 20 | + } | |
| 21 | + | |
| 22 | + /// \brief Return string representation of the given graph format. | |
| 23 | + /// \param format The ::GraphFormat that should be returned as string. | |
| 24 | + /// \return The string that should be used in labels etc. | |
| 25 | + QString graphFormatString(GraphFormat format) { | |
| 26 | + switch (format) { | |
| 27 | + case GraphFormat::TY: | |
| 28 | + return QCoreApplication::tr("T - Y"); | |
| 29 | + case GraphFormat::XY: | |
| 30 | + return QCoreApplication::tr("X - Y"); | |
| 31 | + } | |
| 32 | + return QString(); | |
| 33 | + } | |
| 34 | + | |
| 35 | + /// \brief Return string representation of the given channel coupling. | |
| 36 | + /// \param coupling The ::Coupling that should be returned as string. | |
| 37 | + /// \return The string that should be used in labels etc. | |
| 38 | + QString couplingString(Coupling coupling) { | |
| 39 | + switch (coupling) { | |
| 40 | + case Coupling::AC: | |
| 41 | + return QCoreApplication::tr("AC"); | |
| 42 | + case Coupling::DC: | |
| 43 | + return QCoreApplication::tr("DC"); | |
| 44 | + case Coupling::GND: | |
| 45 | + return QCoreApplication::tr("GND"); | |
| 46 | + } | |
| 47 | + return QString(); | |
| 48 | + } | |
| 49 | + | |
| 50 | + | |
| 51 | + /// \brief Return string representation of the given trigger mode. | |
| 52 | + /// \param mode The ::TriggerMode that should be returned as string. | |
| 53 | + /// \return The string that should be used in labels etc. | |
| 54 | + QString triggerModeString(TriggerMode mode) { | |
| 55 | + switch (mode) { | |
| 56 | + case TriggerMode::WAIT_FORCE: | |
| 57 | + return QCoreApplication::tr("Wait/Force"); | |
| 58 | + case TriggerMode::HARDWARE_SOFTWARE: | |
| 59 | + return QCoreApplication::tr("Hard-/Software"); | |
| 60 | + case TriggerMode::SINGLE: | |
| 61 | + return QCoreApplication::tr("Single"); | |
| 62 | + } | |
| 63 | + return QString(); | |
| 64 | + } | |
| 65 | + | |
| 66 | + /// \brief Return string representation of the given trigger slope. | |
| 67 | + /// \param slope The ::Slope that should be returned as string. | |
| 68 | + /// \return The string that should be used in labels etc. | |
| 69 | + QString slopeString(Slope slope) { | |
| 70 | + switch (slope) { | |
| 71 | + case Slope::Positive: | |
| 72 | + return QString::fromUtf8("\u2197"); | |
| 73 | + case Slope::Negative: | |
| 74 | + return QString::fromUtf8("\u2198"); | |
| 75 | + default: | |
| 76 | + return QString(); | |
| 77 | + } | |
| 78 | + } | |
| 79 | + | |
| 80 | + /// \brief Return string representation of the given graph interpolation mode. | |
| 81 | + /// \param interpolation The ::InterpolationMode that should be returned as | |
| 82 | + /// string. | |
| 83 | + /// \return The string that should be used in labels etc. | |
| 84 | + QString interpolationModeString(InterpolationMode interpolation) { | |
| 85 | + switch (interpolation) { | |
| 86 | + case INTERPOLATION_OFF: | |
| 87 | + return QCoreApplication::tr("Off"); | |
| 88 | + case INTERPOLATION_LINEAR: | |
| 89 | + return QCoreApplication::tr("Linear"); | |
| 90 | + case INTERPOLATION_SINC: | |
| 91 | + return QCoreApplication::tr("Sinc"); | |
| 92 | + default: | |
| 93 | + return QString(); | |
| 94 | + } | |
| 95 | + } | |
| 7 | 96 | } | ... | ... |
openhantek/src/hantekdso/enums.h
| ... | ... | @@ -2,6 +2,7 @@ |
| 2 | 2 | |
| 3 | 3 | #include "utils/enumclass.h" |
| 4 | 4 | #include <QMetaType> |
| 5 | +#include <QString> | |
| 5 | 6 | namespace Dso { |
| 6 | 7 | /// \enum ChannelMode |
| 7 | 8 | /// \brief The channel display modes. |
| ... | ... | @@ -52,6 +53,13 @@ enum InterpolationMode { |
| 52 | 53 | INTERPOLATION_SINC, ///< Smooth graph through the dots |
| 53 | 54 | INTERPOLATION_COUNT ///< Total number of interpolation modes |
| 54 | 55 | }; |
| 56 | + | |
| 57 | +QString channelModeString(ChannelMode mode); | |
| 58 | +QString graphFormatString(GraphFormat format); | |
| 59 | +QString couplingString(Coupling coupling); | |
| 60 | +QString triggerModeString(TriggerMode mode); | |
| 61 | +QString slopeString(Slope slope); | |
| 62 | +QString interpolationModeString(InterpolationMode interpolation); | |
| 55 | 63 | } |
| 56 | 64 | |
| 57 | 65 | Q_DECLARE_METATYPE(Dso::TriggerMode) | ... | ... |
openhantek/src/hantekdso/hantekdsocontrol.cpp
| ... | ... | @@ -22,30 +22,17 @@ using namespace Hantek; |
| 22 | 22 | using namespace Dso; |
| 23 | 23 | |
| 24 | 24 | /// \brief Start sampling process. |
| 25 | -void HantekDsoControl::startSampling() { | |
| 26 | - sampling = true; | |
| 25 | +void HantekDsoControl::enableSampling(bool enabled) { | |
| 26 | + sampling = enabled; | |
| 27 | 27 | |
| 28 | 28 | // Emit signals for initial settings |
| 29 | - emit availableRecordLengthsChanged(controlsettings.samplerate.limits->recordLengths); | |
| 30 | - updateSamplerateLimits(); | |
| 31 | - emit recordLengthChanged(getRecordLength()); | |
| 32 | - if (!isRollMode()) emit recordTimeChanged((double)getRecordLength() / controlsettings.samplerate.current); | |
| 33 | - emit samplerateChanged(controlsettings.samplerate.current); | |
| 29 | + // emit availableRecordLengthsChanged(controlsettings.samplerate.limits->recordLengths); | |
| 30 | + // updateSamplerateLimits(); | |
| 31 | + // emit recordLengthChanged(getRecordLength()); | |
| 32 | + // if (!isRollMode()) emit recordTimeChanged((double)getRecordLength() / controlsettings.samplerate.current); | |
| 33 | + // emit samplerateChanged(controlsettings.samplerate.current); | |
| 34 | 34 | |
| 35 | - if (specification->isFixedSamplerateDevice) { | |
| 36 | - // Convert to GUI presentable values (1e5 -> 1.0, 48e6 -> 480.0 etc) | |
| 37 | - QList<double> sampleSteps; | |
| 38 | - for (auto &v : specification->fixedSampleRates) { sampleSteps << v.samplerate / 1e5; } | |
| 39 | - emit samplerateSet(1, sampleSteps); | |
| 40 | - } | |
| 41 | - | |
| 42 | - emit samplingStarted(); | |
| 43 | -} | |
| 44 | - | |
| 45 | -/// \brief Stop sampling process. | |
| 46 | -void HantekDsoControl::stopSampling() { | |
| 47 | - sampling = false; | |
| 48 | - emit samplingStopped(); | |
| 35 | + emit samplingStatusChanged(enabled); | |
| 49 | 36 | } |
| 50 | 37 | |
| 51 | 38 | const USBDevice *HantekDsoControl::getDevice() const { return device; } |
| ... | ... | @@ -91,25 +78,27 @@ int HantekDsoControl::bulkCommand(const std::vector<unsigned char> *command, int |
| 91 | 78 | return device->bulkWrite(command->data(), command->size(), attempts); |
| 92 | 79 | } |
| 93 | 80 | |
| 94 | -unsigned HantekDsoControl::getChannelCount() { return specification->channels; } | |
| 81 | +unsigned HantekDsoControl::getChannelCount() const { return specification->channels; } | |
| 95 | 82 | |
| 96 | 83 | const ControlSettings *HantekDsoControl::getDeviceSettings() const { return &controlsettings; } |
| 97 | 84 | |
| 98 | -const std::vector<unsigned> &HantekDsoControl::getAvailableRecordLengths() { // | |
| 85 | +const std::vector<unsigned> &HantekDsoControl::getAvailableRecordLengths() const { // | |
| 99 | 86 | return controlsettings.samplerate.limits->recordLengths; |
| 100 | 87 | } |
| 101 | 88 | |
| 102 | -double HantekDsoControl::getMinSamplerate() { | |
| 89 | +double HantekDsoControl::getMinSamplerate() const { | |
| 103 | 90 | return (double)specification->samplerate.single.base / specification->samplerate.single.maxDownsampler; |
| 104 | 91 | } |
| 105 | 92 | |
| 106 | -double HantekDsoControl::getMaxSamplerate() { | |
| 93 | +double HantekDsoControl::getMaxSamplerate() const { | |
| 107 | 94 | if (controlsettings.usedChannels <= 1) |
| 108 | 95 | return specification->samplerate.multi.max; |
| 109 | 96 | else |
| 110 | 97 | return specification->samplerate.single.max; |
| 111 | 98 | } |
| 112 | 99 | |
| 100 | +bool HantekDsoControl::isSampling() const { return sampling; } | |
| 101 | + | |
| 113 | 102 | /// \brief Updates the interval of the periodic thread timer. |
| 114 | 103 | void HantekDsoControl::updateInterval() { |
| 115 | 104 | // Check the current oscilloscope state everytime 25% of the time the buffer |
| ... | ... | @@ -593,13 +582,21 @@ void HantekDsoControl::restoreTargets() { |
| 593 | 582 | } |
| 594 | 583 | |
| 595 | 584 | void HantekDsoControl::updateSamplerateLimits() { |
| 596 | - // Works only if the minimum samplerate for normal mode is lower than for fast | |
| 597 | - // rate mode, which is the case for all models | |
| 598 | - const double min = (double)specification->samplerate.single.base / specification->samplerate.single.maxDownsampler; | |
| 599 | - const double max = getMaxSamplerate(); | |
| 600 | - | |
| 601 | - emit samplerateLimitsChanged(min / specification->bufferDividers[controlsettings.recordLengthId], | |
| 602 | - max / specification->bufferDividers[controlsettings.recordLengthId]); | |
| 585 | + if (specification->isFixedSamplerateDevice) { | |
| 586 | + // Convert to GUI presentable values (1e5 -> 1.0, 48e6 -> 480.0 etc) | |
| 587 | + QList<double> sampleSteps; | |
| 588 | + for (auto &v : specification->fixedSampleRates) { sampleSteps << v.samplerate / 1e5; } | |
| 589 | + emit samplerateSet(1, sampleSteps); | |
| 590 | + } else { | |
| 591 | + // Works only if the minimum samplerate for normal mode is lower than for fast | |
| 592 | + // rate mode, which is the case for all models | |
| 593 | + const double min = | |
| 594 | + (double)specification->samplerate.single.base / specification->samplerate.single.maxDownsampler; | |
| 595 | + const double max = getMaxSamplerate(); | |
| 596 | + | |
| 597 | + emit samplerateLimitsChanged(min / specification->bufferDividers[controlsettings.recordLengthId], | |
| 598 | + max / specification->bufferDividers[controlsettings.recordLengthId]); | |
| 599 | + } | |
| 603 | 600 | } |
| 604 | 601 | |
| 605 | 602 | Dso::ErrorCode HantekDsoControl::setRecordLength(unsigned index) { |
| ... | ... | @@ -1175,7 +1172,7 @@ void HantekDsoControl::run() { |
| 1175 | 1172 | |
| 1176 | 1173 | // Check if we're in single trigger mode |
| 1177 | 1174 | if (controlsettings.trigger.mode == Dso::TriggerMode::SINGLE && this->_samplingStarted) |
| 1178 | - this->stopSampling(); | |
| 1175 | + this->enableSampling(false); | |
| 1179 | 1176 | |
| 1180 | 1177 | // Sampling completed, restart it when necessary |
| 1181 | 1178 | this->_samplingStarted = false; |
| ... | ... | @@ -1216,7 +1213,7 @@ void HantekDsoControl::run() { |
| 1216 | 1213 | |
| 1217 | 1214 | // Check if we're in single trigger mode |
| 1218 | 1215 | if (controlsettings.trigger.mode == Dso::TriggerMode::SINGLE && this->_samplingStarted) |
| 1219 | - this->stopSampling(); | |
| 1216 | + this->enableSampling(false); | |
| 1220 | 1217 | |
| 1221 | 1218 | // Sampling completed, restart it when necessary |
| 1222 | 1219 | this->_samplingStarted = false; | ... | ... |
openhantek/src/hantekdso/hantekdsocontrol.h
| ... | ... | @@ -52,7 +52,7 @@ class HantekDsoControl : public QObject { |
| 52 | 52 | |
| 53 | 53 | /// \brief Gets the physical channel count for this oscilloscope. |
| 54 | 54 | /// \return The number of physical channels. |
| 55 | - unsigned getChannelCount(); | |
| 55 | + unsigned getChannelCount() const; | |
| 56 | 56 | |
| 57 | 57 | /// Return the read-only device control settings. Use the set- Methods to change |
| 58 | 58 | /// device settings. |
| ... | ... | @@ -60,15 +60,17 @@ class HantekDsoControl : public QObject { |
| 60 | 60 | |
| 61 | 61 | /// \brief Get available record lengths for this oscilloscope. |
| 62 | 62 | /// \return The number of physical channels, empty list for continuous. |
| 63 | - const std::vector<unsigned> &getAvailableRecordLengths(); | |
| 63 | + const std::vector<unsigned> &getAvailableRecordLengths() const; | |
| 64 | 64 | |
| 65 | 65 | /// \brief Get minimum samplerate for this oscilloscope. |
| 66 | 66 | /// \return The minimum samplerate for the current configuration in S/s. |
| 67 | - double getMinSamplerate(); | |
| 67 | + double getMinSamplerate() const; | |
| 68 | 68 | |
| 69 | 69 | /// \brief Get maximum samplerate for this oscilloscope. |
| 70 | 70 | /// \return The maximum samplerate for the current configuration in S/s. |
| 71 | - double getMaxSamplerate(); | |
| 71 | + double getMaxSamplerate() const; | |
| 72 | + | |
| 73 | + bool isSampling() const; | |
| 72 | 74 | |
| 73 | 75 | /// Return the associated usb device. |
| 74 | 76 | const USBDevice *getDevice() const; |
| ... | ... | @@ -182,8 +184,8 @@ class HantekDsoControl : public QObject { |
| 182 | 184 | bool sampling = false; ///< true, if the oscilloscope is taking samples |
| 183 | 185 | |
| 184 | 186 | // Device setup |
| 185 | - const Dso::ControlSpecification* specification; ///< The specifications of the device | |
| 186 | - Dso::ControlSettings controlsettings; ///< The current settings of the device | |
| 187 | + const Dso::ControlSpecification *specification; ///< The specifications of the device | |
| 188 | + Dso::ControlSettings controlsettings; ///< The current settings of the device | |
| 187 | 189 | |
| 188 | 190 | // Results |
| 189 | 191 | DSOsamples result; |
| ... | ... | @@ -206,8 +208,10 @@ class HantekDsoControl : public QObject { |
| 206 | 208 | int bulkCommand(const std::vector<unsigned char> *command, int attempts = HANTEK_ATTEMPTS) const; |
| 207 | 209 | |
| 208 | 210 | public slots: |
| 209 | - void startSampling(); | |
| 210 | - void stopSampling(); | |
| 211 | + /// \brief If sampling is disabled, no samplesAvailable() signals are send anymore, no samples | |
| 212 | + /// are fetched from the device and no processing takes place. | |
| 213 | + /// \param enabled Enables/Disables sampling | |
| 214 | + void enableSampling(bool enabled); | |
| 211 | 215 | |
| 212 | 216 | /// \brief Sets the size of the oscilloscopes sample buffer. |
| 213 | 217 | /// \param index The record length index that should be set. |
| ... | ... | @@ -270,19 +274,21 @@ class HantekDsoControl : public QObject { |
| 270 | 274 | void forceTrigger(); |
| 271 | 275 | |
| 272 | 276 | signals: |
| 273 | - void samplingStarted(); ///< The oscilloscope started sampling/waiting for trigger | |
| 274 | - void samplingStopped(); ///< The oscilloscope stopped sampling/waiting for trigger | |
| 277 | + void samplingStatusChanged(bool enabled); ///< The oscilloscope started/stopped sampling/waiting for trigger | |
| 275 | 278 | void statusMessage(const QString &message, int timeout); ///< Status message about the oscilloscope |
| 276 | 279 | void samplesAvailable(const DSOsamples *samples); ///< New sample data is available |
| 277 | 280 | |
| 278 | 281 | void availableRecordLengthsChanged(const std::vector<unsigned> &recordLengths); ///< The available record |
| 279 | 282 | /// lengths, empty list for |
| 280 | 283 | |
| 281 | - void samplerateLimitsChanged(double minimum, double maximum); ///< The minimum or maximum samplerate has changed | |
| 282 | - void recordLengthChanged(unsigned long duration); ///< The record length has changed | |
| 283 | - void recordTimeChanged(double duration); ///< The record time duration has changed | |
| 284 | - void samplerateChanged(double samplerate); ///< The samplerate has changed | |
| 285 | - void samplerateSet(int mode, QList<double> sampleSteps); ///< The samplerate has changed | |
| 284 | + /// The available samplerate range has changed | |
| 285 | + void samplerateLimitsChanged(double minimum, double maximum); | |
| 286 | + /// The available samplerate for fixed samplerate devices has changed | |
| 287 | + void samplerateSet(int mode, QList<double> sampleSteps); | |
| 288 | + | |
| 289 | + void recordLengthChanged(unsigned long duration); ///< The record length has changed | |
| 290 | + void recordTimeChanged(double duration); ///< The record time duration has changed | |
| 291 | + void samplerateChanged(double samplerate); ///< The samplerate has changed | |
| 286 | 292 | |
| 287 | 293 | void communicationError() const; |
| 288 | 294 | }; | ... | ... |
openhantek/src/post/enums.cpp deleted
openhantek/src/post/mathchannelgenerator.cpp
| 1 | 1 | #include "mathchannelgenerator.h" |
| 2 | 2 | #include "scopesettings.h" |
| 3 | +#include "post/postprocessingsettings.h" | |
| 4 | +#include "enums.h" | |
| 3 | 5 | |
| 4 | 6 | MathChannelGenerator::MathChannelGenerator(const DsoSettingsScope *scope, unsigned physicalChannels) |
| 5 | 7 | : physicalChannels(physicalChannels), scope(scope) {} |
| ... | ... | @@ -27,7 +29,7 @@ void MathChannelGenerator::process(PPresult *result) { |
| 27 | 29 | std::vector<double>::const_iterator ch1Iterator = result->data(0)->voltage.sample.begin(); |
| 28 | 30 | std::vector<double>::const_iterator ch2Iterator = result->data(1)->voltage.sample.begin(); |
| 29 | 31 | for (std::vector<double>::iterator it = resultData.begin(); it != resultData.end(); ++it) { |
| 30 | - switch (scope->voltage[physicalChannels].math) { | |
| 32 | + switch (Dso::getMathMode(scope->voltage[physicalChannels])) { | |
| 31 | 33 | case Dso::MathMode::ADD_CH1_CH2: |
| 32 | 34 | *it = *ch1Iterator + *ch2Iterator; |
| 33 | 35 | break; | ... | ... |
openhantek/src/post/postprocessingsettings.cpp
0 → 100644
| 1 | +#include "postprocessingsettings.h" | |
| 2 | + | |
| 3 | +#include <QCoreApplication> | |
| 4 | +#include <QString> | |
| 5 | + | |
| 6 | +namespace Dso { | |
| 7 | + | |
| 8 | +Enum<Dso::MathMode, Dso::MathMode::ADD_CH1_CH2, Dso::MathMode::SUB_CH1_FROM_CH2> MathModeEnum; | |
| 9 | +Enum<Dso::WindowFunction, Dso::WindowFunction::RECTANGULAR, Dso::WindowFunction::FLATTOP> WindowFunctionEnum; | |
| 10 | + | |
| 11 | +/// \brief Return string representation of the given math mode. | |
| 12 | +/// \param mode The ::MathMode that should be returned as string. | |
| 13 | +/// \return The string that should be used in labels etc. | |
| 14 | +QString mathModeString(MathMode mode) { | |
| 15 | + switch (mode) { | |
| 16 | + case MathMode::ADD_CH1_CH2: | |
| 17 | + return QCoreApplication::tr("CH1 + CH2"); | |
| 18 | + case MathMode::SUB_CH2_FROM_CH1: | |
| 19 | + return QCoreApplication::tr("CH1 - CH2"); | |
| 20 | + case MathMode::SUB_CH1_FROM_CH2: | |
| 21 | + return QCoreApplication::tr("CH2 - CH1"); | |
| 22 | + } | |
| 23 | + return QString(); | |
| 24 | +} | |
| 25 | +/// \brief Return string representation of the given dft window function. | |
| 26 | +/// \param window The ::WindowFunction that should be returned as string. | |
| 27 | +/// \return The string that should be used in labels etc. | |
| 28 | +QString windowFunctionString(WindowFunction window) { | |
| 29 | + switch (window) { | |
| 30 | + case WindowFunction::RECTANGULAR: | |
| 31 | + return QCoreApplication::tr("Rectangular"); | |
| 32 | + case WindowFunction::HAMMING: | |
| 33 | + return QCoreApplication::tr("Hamming"); | |
| 34 | + case WindowFunction::HANN: | |
| 35 | + return QCoreApplication::tr("Hann"); | |
| 36 | + case WindowFunction::COSINE: | |
| 37 | + return QCoreApplication::tr("Cosine"); | |
| 38 | + case WindowFunction::LANCZOS: | |
| 39 | + return QCoreApplication::tr("Lanczos"); | |
| 40 | + case WindowFunction::BARTLETT: | |
| 41 | + return QCoreApplication::tr("Bartlett"); | |
| 42 | + case WindowFunction::TRIANGULAR: | |
| 43 | + return QCoreApplication::tr("Triangular"); | |
| 44 | + case WindowFunction::GAUSS: | |
| 45 | + return QCoreApplication::tr("Gauss"); | |
| 46 | + case WindowFunction::BARTLETTHANN: | |
| 47 | + return QCoreApplication::tr("Bartlett-Hann"); | |
| 48 | + case WindowFunction::BLACKMAN: | |
| 49 | + return QCoreApplication::tr("Blackman"); | |
| 50 | + // case WindowFunction::WINDOW_KAISER: | |
| 51 | + // return QCoreApplication::tr("Kaiser"); | |
| 52 | + case WindowFunction::NUTTALL: | |
| 53 | + return QCoreApplication::tr("Nuttall"); | |
| 54 | + case WindowFunction::BLACKMANHARRIS: | |
| 55 | + return QCoreApplication::tr("Blackman-Harris"); | |
| 56 | + case WindowFunction::BLACKMANNUTTALL: | |
| 57 | + return QCoreApplication::tr("Blackman-Nuttall"); | |
| 58 | + case WindowFunction::FLATTOP: | |
| 59 | + return QCoreApplication::tr("Flat top"); | |
| 60 | + } | |
| 61 | + return QString(); | |
| 62 | +} | |
| 63 | +} | ... | ... |
openhantek/src/post/enums.h renamed to openhantek/src/post/postprocessingsettings.h
| 1 | 1 | #pragma once |
| 2 | 2 | |
| 3 | -#include <QMetaType> | |
| 4 | 3 | #include "utils/enumclass.h" |
| 4 | +#include <QMetaType> | |
| 5 | 5 | namespace Dso { |
| 6 | 6 | |
| 7 | 7 | /// \enum MathMode |
| 8 | 8 | /// \brief The different math modes for the math-channel. |
| 9 | -enum class MathMode { | |
| 10 | - ADD_CH1_CH2, | |
| 11 | - SUB_CH2_FROM_CH1, | |
| 12 | - SUB_CH1_FROM_CH2 | |
| 13 | -}; | |
| 14 | -extern Enum<Dso::MathMode,Dso::MathMode::ADD_CH1_CH2,Dso::MathMode::SUB_CH1_FROM_CH2> MathModeEnum; | |
| 9 | +enum class MathMode : unsigned { ADD_CH1_CH2, SUB_CH2_FROM_CH1, SUB_CH1_FROM_CH2 }; | |
| 10 | +extern Enum<Dso::MathMode, Dso::MathMode::ADD_CH1_CH2, Dso::MathMode::SUB_CH1_FROM_CH2> MathModeEnum; | |
| 11 | + | |
| 12 | +template<class T> | |
| 13 | +inline MathMode getMathMode(T& t) { return (MathMode)t.couplingOrMathIndex; } | |
| 15 | 14 | |
| 16 | 15 | /// \enum WindowFunction |
| 17 | 16 | /// \brief The supported window functions. |
| 18 | 17 | /// These are needed for spectrum analysis and are applied to the sample values |
| 19 | 18 | /// before calculating the DFT. |
| 20 | -enum class WindowFunction: int { | |
| 19 | +enum class WindowFunction : int { | |
| 21 | 20 | RECTANGULAR, ///< Rectangular window (aka Dirichlet) |
| 22 | 21 | HAMMING, ///< Hamming window |
| 23 | 22 | HANN, ///< Hann window |
| ... | ... | @@ -32,12 +31,19 @@ enum class WindowFunction: int { |
| 32 | 31 | NUTTALL, ///< Nuttall window, cont. first deriv. |
| 33 | 32 | BLACKMANHARRIS, ///< Blackman-Harris window |
| 34 | 33 | BLACKMANNUTTALL, ///< Blackman-Nuttall window |
| 35 | - FLATTOP ///< Flat top window | |
| 34 | + FLATTOP ///< Flat top window | |
| 36 | 35 | }; |
| 37 | -extern Enum<Dso::WindowFunction,Dso::WindowFunction::RECTANGULAR,Dso::WindowFunction::FLATTOP> WindowFunctionEnum; | |
| 36 | +extern Enum<Dso::WindowFunction, Dso::WindowFunction::RECTANGULAR, Dso::WindowFunction::FLATTOP> WindowFunctionEnum; | |
| 38 | 37 | |
| 38 | +QString mathModeString(MathMode mode); | |
| 39 | +QString windowFunctionString(WindowFunction window); | |
| 39 | 40 | } |
| 40 | 41 | |
| 41 | 42 | Q_DECLARE_METATYPE(Dso::MathMode) |
| 42 | 43 | Q_DECLARE_METATYPE(Dso::WindowFunction) |
| 43 | 44 | |
| 45 | +struct DsoSettingsPostProcessing { | |
| 46 | + Dso::WindowFunction spectrumWindow = Dso::WindowFunction::HANN; ///< Window function for DFT | |
| 47 | + double spectrumReference = 0.0; ///< Reference level for spectrum in dBm | |
| 48 | + double spectrumLimit = -20.0; ///< Minimum magnitude of the spectrum (Avoids peaks) | |
| 49 | +}; | ... | ... |
openhantek/src/post/spectrumgenerator.cpp
| ... | ... | @@ -16,7 +16,8 @@ |
| 16 | 16 | #include "utils/printutils.h" |
| 17 | 17 | |
| 18 | 18 | /// \brief Analyzes the data from the dso. |
| 19 | -SpectrumGenerator::SpectrumGenerator(const DsoSettingsScope *scope) : scope(scope) {} | |
| 19 | +SpectrumGenerator::SpectrumGenerator(const DsoSettingsScope *scope, const DsoSettingsPostProcessing *postprocessing) | |
| 20 | + : scope(scope), postprocessing(postprocessing) {} | |
| 20 | 21 | |
| 21 | 22 | SpectrumGenerator::~SpectrumGenerator() { |
| 22 | 23 | if (lastWindowBuffer) fftw_free(lastWindowBuffer); |
| ... | ... | @@ -36,15 +37,15 @@ void SpectrumGenerator::process(PPresult *result) { |
| 36 | 37 | |
| 37 | 38 | // Calculate new window |
| 38 | 39 | size_t sampleCount = channelData->voltage.sample.size(); |
| 39 | - if (!lastWindowBuffer || lastWindow != scope->spectrumWindow || lastRecordLength != sampleCount) { | |
| 40 | + if (!lastWindowBuffer || lastWindow != postprocessing->spectrumWindow || lastRecordLength != sampleCount) { | |
| 40 | 41 | if (lastWindowBuffer) fftw_free(lastWindowBuffer); |
| 41 | 42 | lastWindowBuffer = fftw_alloc_real(sampleCount); |
| 42 | 43 | lastRecordLength = (unsigned)sampleCount; |
| 43 | 44 | |
| 44 | 45 | unsigned int windowEnd = lastRecordLength - 1; |
| 45 | - lastWindow = scope->spectrumWindow; | |
| 46 | + lastWindow = postprocessing->spectrumWindow; | |
| 46 | 47 | |
| 47 | - switch (scope->spectrumWindow) { | |
| 48 | + switch (postprocessing->spectrumWindow) { | |
| 48 | 49 | case Dso::WindowFunction::HAMMING: |
| 49 | 50 | for (unsigned int windowPosition = 0; windowPosition < lastRecordLength; ++windowPosition) |
| 50 | 51 | *(lastWindowBuffer + windowPosition) = 0.54 - 0.46 * cos(2.0 * M_PI * windowPosition / windowEnd); |
| ... | ... | @@ -210,8 +211,8 @@ void SpectrumGenerator::process(PPresult *result) { |
| 210 | 211 | // Finally calculate the real spectrum if we want it |
| 211 | 212 | if (scope->spectrum[channel].used) { |
| 212 | 213 | // Convert values into dB (Relative to the reference level) |
| 213 | - double offset = 60 - scope->spectrumReference - 20 * log10(dftLength); | |
| 214 | - double offsetLimit = scope->spectrumLimit - scope->spectrumReference; | |
| 214 | + double offset = 60 - postprocessing->spectrumReference - 20 * log10(dftLength); | |
| 215 | + double offsetLimit = postprocessing->spectrumLimit - postprocessing->spectrumReference; | |
| 215 | 216 | for (std::vector<double>::iterator spectrumIterator = channelData->spectrum.sample.begin(); |
| 216 | 217 | spectrumIterator != channelData->spectrum.sample.end(); ++spectrumIterator) { |
| 217 | 218 | double value = 20 * log10(fabs(*spectrumIterator)) + offset; | ... | ... |
openhantek/src/post/spectrumgenerator.h
| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | #include "ppresult.h" |
| 12 | 12 | #include "dsosamples.h" |
| 13 | 13 | #include "utils/printutils.h" |
| 14 | -#include "enums.h" | |
| 14 | +#include "postprocessingsettings.h" | |
| 15 | 15 | |
| 16 | 16 | #include "processor.h" |
| 17 | 17 | |
| ... | ... | @@ -23,12 +23,13 @@ struct DsoSettingsScope; |
| 23 | 23 | /// time-/frequencysteps between two values. |
| 24 | 24 | class SpectrumGenerator : public Processor { |
| 25 | 25 | public: |
| 26 | - SpectrumGenerator(const DsoSettingsScope* scope); | |
| 26 | + SpectrumGenerator(const DsoSettingsScope* scope, const DsoSettingsPostProcessing* postprocessing); | |
| 27 | 27 | virtual ~SpectrumGenerator(); |
| 28 | 28 | virtual void process(PPresult *data) override; |
| 29 | 29 | |
| 30 | 30 | private: |
| 31 | 31 | const DsoSettingsScope* scope; |
| 32 | + const DsoSettingsPostProcessing* postprocessing; | |
| 32 | 33 | unsigned int lastRecordLength = 0; ///< The record length of the previously analyzed data |
| 33 | 34 | Dso::WindowFunction lastWindow = (Dso::WindowFunction)-1; ///< The previously used dft window function |
| 34 | 35 | double *lastWindowBuffer = nullptr; | ... | ... |
openhantek/src/scopesettings.h
| ... | ... | @@ -7,7 +7,6 @@ |
| 7 | 7 | #include "hantekdso/controlspecification.h" |
| 8 | 8 | #include "hantekdso/enums.h" |
| 9 | 9 | #include "hantekprotocol/definitions.h" |
| 10 | -#include "post/enums.h" | |
| 11 | 10 | #include <vector> |
| 12 | 11 | |
| 13 | 12 | #define MARKER_COUNT 2 ///< Number of markers |
| ... | ... | @@ -52,37 +51,30 @@ struct DsoSettingsScopeSpectrum { |
| 52 | 51 | /// \brief Holds the settings for the normal voltage graphs. |
| 53 | 52 | /// TODO Use ControlSettingsVoltage |
| 54 | 53 | struct DsoSettingsScopeVoltage { |
| 55 | - double offset = 0.0; ///< Vertical offset in divs | |
| 56 | - double trigger = 0.0; ///< Trigger level in V | |
| 57 | - unsigned gainStepIndex = 6; ///< The vertical resolution in V/div (default = 1.0) | |
| 58 | - union { ///< Different enums, coupling for real- and mode for math-channels | |
| 59 | - Dso::MathMode math; | |
| 60 | - unsigned couplingIndex = 0; | |
| 61 | - int rawValue; | |
| 62 | - }; | |
| 63 | - QString name; ///< Name of this channel | |
| 64 | - bool inverted = false; ///< true if the channel is inverted (mirrored on cross-axis) | |
| 65 | - bool used = false; ///< true if this channel is enabled | |
| 54 | + double offset = 0.0; ///< Vertical offset in divs | |
| 55 | + double trigger = 0.0; ///< Trigger level in V | |
| 56 | + unsigned gainStepIndex = 6; ///< The vertical resolution in V/div (default = 1.0) | |
| 57 | + unsigned couplingOrMathIndex = 0; ///< Different index: coupling for real- and mode for math-channels | |
| 58 | + QString name; ///< Name of this channel | |
| 59 | + bool inverted = false; ///< true if the channel is inverted (mirrored on cross-axis) | |
| 60 | + bool used = false; ///< true if this channel is enabled | |
| 66 | 61 | }; |
| 67 | 62 | |
| 68 | 63 | /// \brief Holds the settings for the oscilloscope. |
| 69 | 64 | struct DsoSettingsScope { |
| 70 | 65 | std::vector<double> gainSteps = {1e-2, 2e-2, 5e-2, 1e-1, 2e-1, |
| 71 | 66 | 5e-1, 1e0, 2e0, 5e0}; ///< The selectable voltage gain steps in V/div |
| 72 | - Dso::WindowFunction spectrumWindow = Dso::WindowFunction::HANN; ///< Window function for DFT | |
| 73 | 67 | std::vector<DsoSettingsScopeSpectrum> spectrum; ///< Spectrum analysis settings |
| 74 | 68 | std::vector<DsoSettingsScopeVoltage> voltage; ///< Settings for the normal graphs |
| 75 | 69 | DsoSettingsScopeHorizontal horizontal; ///< Settings for the horizontal axis |
| 76 | 70 | DsoSettingsScopeTrigger trigger; ///< Settings for the trigger |
| 77 | - double spectrumReference = 0.0; ///< Reference level for spectrum in dBm | |
| 78 | - double spectrumLimit = -20.0; ///< Minimum magnitude of the spectrum (Avoids peaks) | |
| 79 | 71 | |
| 80 | 72 | double gain(unsigned channel) const { return gainSteps[voltage[channel].gainStepIndex]; } |
| 81 | 73 | bool anyUsed(ChannelID channel) { return voltage[channel].used | spectrum[channel].used; } |
| 82 | 74 | |
| 83 | - Dso::Coupling coupling(ChannelID channel, const Dso::ControlSpecification *deviceSpecification) { | |
| 84 | - return deviceSpecification->couplings[voltage[channel].couplingIndex]; | |
| 75 | + Dso::Coupling coupling(ChannelID channel, const Dso::ControlSpecification *deviceSpecification) const { | |
| 76 | + return deviceSpecification->couplings[voltage[channel].couplingOrMathIndex]; | |
| 85 | 77 | } |
| 86 | 78 | // Channels, including math channels |
| 87 | - unsigned countChannels() { return (unsigned)voltage.size(); } | |
| 79 | + unsigned countChannels() const { return (unsigned)voltage.size(); } | |
| 88 | 80 | }; | ... | ... |
openhantek/src/settings.cpp
| ... | ... | @@ -35,7 +35,7 @@ DsoSettings::DsoSettings(const Dso::ControlSpecification* deviceSpecification) { |
| 35 | 35 | scope.spectrum.push_back(newSpectrum); |
| 36 | 36 | |
| 37 | 37 | DsoSettingsScopeVoltage newVoltage; |
| 38 | - newVoltage.math = Dso::MathMode::ADD_CH1_CH2; | |
| 38 | + newVoltage.couplingOrMathIndex = (unsigned)Dso::MathMode::ADD_CH1_CH2; | |
| 39 | 39 | newVoltage.name = QApplication::tr("MATH"); |
| 40 | 40 | scope.voltage.push_back(newVoltage); |
| 41 | 41 | |
| ... | ... | @@ -106,19 +106,20 @@ void DsoSettings::load() { |
| 106 | 106 | for (ChannelID channel = 0; channel < scope.voltage.size(); ++channel) { |
| 107 | 107 | store->beginGroup(QString("vertical%1").arg(channel)); |
| 108 | 108 | if (store->contains("gainStepIndex")) scope.voltage[channel].gainStepIndex = store->value("gainStepIndex").toUInt(); |
| 109 | - if (store->contains("couplingIndex")) scope.voltage[channel].couplingIndex = store->value("couplingIndex").toUInt(); | |
| 109 | + if (store->contains("couplingOrMathIndex")) scope.voltage[channel].couplingOrMathIndex = store->value("couplingIndex").toUInt(); | |
| 110 | 110 | if (store->contains("inverted")) scope.voltage[channel].inverted = store->value("inverted").toBool(); |
| 111 | - if (store->contains("misc")) scope.voltage[channel].rawValue = store->value("misc").toInt(); | |
| 112 | 111 | if (store->contains("offset")) scope.voltage[channel].offset = store->value("offset").toDouble(); |
| 113 | 112 | if (store->contains("trigger")) scope.voltage[channel].trigger = store->value("trigger").toDouble(); |
| 114 | 113 | if (store->contains("used")) scope.voltage[channel].used = store->value("used").toBool(); |
| 115 | 114 | store->endGroup(); |
| 116 | 115 | } |
| 117 | - if (store->contains("spectrumLimit")) scope.spectrumLimit = store->value("spectrumLimit").toDouble(); | |
| 116 | + | |
| 117 | + // Post processing | |
| 118 | + if (store->contains("spectrumLimit")) post.spectrumLimit = store->value("spectrumLimit").toDouble(); | |
| 118 | 119 | if (store->contains("spectrumReference")) |
| 119 | - scope.spectrumReference = store->value("spectrumReference").toDouble(); | |
| 120 | + post.spectrumReference = store->value("spectrumReference").toDouble(); | |
| 120 | 121 | if (store->contains("spectrumWindow")) |
| 121 | - scope.spectrumWindow = (Dso::WindowFunction)store->value("spectrumWindow").toInt(); | |
| 122 | + post.spectrumWindow = (Dso::WindowFunction)store->value("spectrumWindow").toInt(); | |
| 122 | 123 | store->endGroup(); |
| 123 | 124 | |
| 124 | 125 | // View |
| ... | ... | @@ -209,17 +210,18 @@ void DsoSettings::save() { |
| 209 | 210 | for (ChannelID channel = 0; channel < scope.voltage.size(); ++channel) { |
| 210 | 211 | store->beginGroup(QString("vertical%1").arg(channel)); |
| 211 | 212 | store->setValue("gainStepIndex", scope.voltage[channel].gainStepIndex); |
| 212 | - store->setValue("couplingIndex", scope.voltage[channel].couplingIndex); | |
| 213 | + store->setValue("couplingOrMathIndex", scope.voltage[channel].couplingOrMathIndex); | |
| 213 | 214 | store->setValue("inverted", scope.voltage[channel].inverted); |
| 214 | - store->setValue("misc", scope.voltage[channel].rawValue); | |
| 215 | 215 | store->setValue("offset", scope.voltage[channel].offset); |
| 216 | 216 | store->setValue("trigger", scope.voltage[channel].trigger); |
| 217 | 217 | store->setValue("used", scope.voltage[channel].used); |
| 218 | 218 | store->endGroup(); |
| 219 | 219 | } |
| 220 | - store->setValue("spectrumLimit", scope.spectrumLimit); | |
| 221 | - store->setValue("spectrumReference", scope.spectrumReference); | |
| 222 | - store->setValue("spectrumWindow", (int)scope.spectrumWindow); | |
| 220 | + | |
| 221 | + // Post processing | |
| 222 | + store->setValue("spectrumLimit", post.spectrumLimit); | |
| 223 | + store->setValue("spectrumReference", post.spectrumReference); | |
| 224 | + store->setValue("spectrumWindow", (int)post.spectrumWindow); | |
| 223 | 225 | store->endGroup(); |
| 224 | 226 | |
| 225 | 227 | // View | ... | ... |
openhantek/src/settings.h
| ... | ... | @@ -7,22 +7,22 @@ |
| 7 | 7 | #include <QString> |
| 8 | 8 | #include <memory> |
| 9 | 9 | |
| 10 | +#include "exporting/exportsettings.h" | |
| 11 | +#include "post/postprocessingsettings.h" | |
| 10 | 12 | #include "scopesettings.h" |
| 11 | 13 | #include "viewsettings.h" |
| 12 | -#include "exporting/exportsettings.h" | |
| 13 | -#include "hantekdso/controlspecification.h" | |
| 14 | -#include "hantekdso/controlsettings.h" | |
| 15 | 14 | |
| 16 | 15 | /// \brief Holds the settings of the program. |
| 17 | 16 | class DsoSettings { |
| 18 | 17 | public: |
| 19 | - explicit DsoSettings(const Dso::ControlSpecification* deviceSpecification); | |
| 18 | + explicit DsoSettings(const Dso::ControlSpecification *deviceSpecification); | |
| 20 | 19 | bool setFilename(const QString &filename); |
| 21 | 20 | |
| 22 | - DsoSettingsExport exporting; ///< General options of the program | |
| 23 | - DsoSettingsScope scope; ///< All oscilloscope related settings | |
| 24 | - DsoSettingsView view; ///< All view related settings | |
| 25 | - bool alwaysSave = true; ///< Always save the settings on exit | |
| 21 | + DsoSettingsExport exporting; ///< General options of the program | |
| 22 | + DsoSettingsScope scope; ///< All oscilloscope related settings | |
| 23 | + DsoSettingsView view; ///< All view related settings | |
| 24 | + DsoSettingsPostProcessing post; ///< All post processing related settings | |
| 25 | + bool alwaysSave = true; ///< Always save the settings on exit | |
| 26 | 26 | |
| 27 | 27 | QByteArray mainWindowGeometry; ///< Geometry of the main window |
| 28 | 28 | QByteArray mainWindowState; ///< State of docking windows and toolbars | ... | ... |
openhantek/src/utils/dsoStrings.cpp deleted
| 1 | -//////////////////////////////////////////////////////////////////////////////// | |
| 2 | -// | |
| 3 | -// OpenHantek | |
| 4 | -// dso.cpp | |
| 5 | -// | |
| 6 | -// Copyright (C) 2010 Oliver Haag | |
| 7 | -// oliver.haag@gmail.com | |
| 8 | -// | |
| 9 | -// This program is free software: you can redistribute it and/or modify it | |
| 10 | -// under the terms of the GNU General Public License as published by the Free | |
| 11 | -// Software Foundation, either version 3 of the License, or (at your option) | |
| 12 | -// any later version. | |
| 13 | -// | |
| 14 | -// This program is distributed in the hope that it will be useful, but WITHOUT | |
| 15 | -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 16 | -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 17 | -// more details. | |
| 18 | -// | |
| 19 | -// You should have received a copy of the GNU General Public License along with | |
| 20 | -// this program. If not, see <http://www.gnu.org/licenses/>. | |
| 21 | -// | |
| 22 | -//////////////////////////////////////////////////////////////////////////////// | |
| 23 | - | |
| 24 | -#include <QApplication> | |
| 25 | - | |
| 26 | -#include "dsoStrings.h" | |
| 27 | - | |
| 28 | -namespace Dso { | |
| 29 | -/// \brief Return string representation of the given channel mode. | |
| 30 | -/// \param mode The ::ChannelMode that should be returned as string. | |
| 31 | -/// \return The string that should be used in labels etc., empty when invalid. | |
| 32 | -QString channelModeString(ChannelMode mode) { | |
| 33 | - switch (mode) { | |
| 34 | - case ChannelMode::Voltage: | |
| 35 | - return QApplication::tr("Voltage"); | |
| 36 | - case ChannelMode::Spectrum: | |
| 37 | - return QApplication::tr("Spectrum"); | |
| 38 | - } | |
| 39 | - return QString(); | |
| 40 | -} | |
| 41 | - | |
| 42 | -/// \brief Return string representation of the given graph format. | |
| 43 | -/// \param format The ::GraphFormat that should be returned as string. | |
| 44 | -/// \return The string that should be used in labels etc. | |
| 45 | -QString graphFormatString(GraphFormat format) { | |
| 46 | - switch (format) { | |
| 47 | - case GraphFormat::TY: | |
| 48 | - return QApplication::tr("T - Y"); | |
| 49 | - case GraphFormat::XY: | |
| 50 | - return QApplication::tr("X - Y"); | |
| 51 | - } | |
| 52 | - return QString(); | |
| 53 | -} | |
| 54 | - | |
| 55 | -/// \brief Return string representation of the given channel coupling. | |
| 56 | -/// \param coupling The ::Coupling that should be returned as string. | |
| 57 | -/// \return The string that should be used in labels etc. | |
| 58 | -QString couplingString(Coupling coupling) { | |
| 59 | - switch (coupling) { | |
| 60 | - case Coupling::AC: | |
| 61 | - return QApplication::tr("AC"); | |
| 62 | - case Coupling::DC: | |
| 63 | - return QApplication::tr("DC"); | |
| 64 | - case Coupling::GND: | |
| 65 | - return QApplication::tr("GND"); | |
| 66 | - } | |
| 67 | - return QString(); | |
| 68 | -} | |
| 69 | - | |
| 70 | -/// \brief Return string representation of the given math mode. | |
| 71 | -/// \param mode The ::MathMode that should be returned as string. | |
| 72 | -/// \return The string that should be used in labels etc. | |
| 73 | -QString mathModeString(MathMode mode) { | |
| 74 | - switch (mode) { | |
| 75 | - case MathMode::ADD_CH1_CH2: | |
| 76 | - return QApplication::tr("CH1 + CH2"); | |
| 77 | - case MathMode::SUB_CH2_FROM_CH1: | |
| 78 | - return QApplication::tr("CH1 - CH2"); | |
| 79 | - case MathMode::SUB_CH1_FROM_CH2: | |
| 80 | - return QApplication::tr("CH2 - CH1"); | |
| 81 | - } | |
| 82 | - return QString(); | |
| 83 | -} | |
| 84 | - | |
| 85 | -/// \brief Return string representation of the given trigger mode. | |
| 86 | -/// \param mode The ::TriggerMode that should be returned as string. | |
| 87 | -/// \return The string that should be used in labels etc. | |
| 88 | -QString triggerModeString(TriggerMode mode) { | |
| 89 | - switch (mode) { | |
| 90 | - case TriggerMode::WAIT_FORCE: | |
| 91 | - return QApplication::tr("Wait/Force"); | |
| 92 | - case TriggerMode::HARDWARE_SOFTWARE: | |
| 93 | - return QApplication::tr("Hard-/Software"); | |
| 94 | - case TriggerMode::SINGLE: | |
| 95 | - return QApplication::tr("Single"); | |
| 96 | - } | |
| 97 | - return QString(); | |
| 98 | -} | |
| 99 | - | |
| 100 | -/// \brief Return string representation of the given trigger slope. | |
| 101 | -/// \param slope The ::Slope that should be returned as string. | |
| 102 | -/// \return The string that should be used in labels etc. | |
| 103 | -QString slopeString(Slope slope) { | |
| 104 | - switch (slope) { | |
| 105 | - case Slope::Positive: | |
| 106 | - return QString::fromUtf8("\u2197"); | |
| 107 | - case Slope::Negative: | |
| 108 | - return QString::fromUtf8("\u2198"); | |
| 109 | - default: | |
| 110 | - return QString(); | |
| 111 | - } | |
| 112 | -} | |
| 113 | - | |
| 114 | -/// \brief Return string representation of the given dft window function. | |
| 115 | -/// \param window The ::WindowFunction that should be returned as string. | |
| 116 | -/// \return The string that should be used in labels etc. | |
| 117 | -QString windowFunctionString(WindowFunction window) { | |
| 118 | - switch (window) { | |
| 119 | - case WindowFunction::RECTANGULAR: | |
| 120 | - return QApplication::tr("Rectangular"); | |
| 121 | - case WindowFunction::HAMMING: | |
| 122 | - return QApplication::tr("Hamming"); | |
| 123 | - case WindowFunction::HANN: | |
| 124 | - return QApplication::tr("Hann"); | |
| 125 | - case WindowFunction::COSINE: | |
| 126 | - return QApplication::tr("Cosine"); | |
| 127 | - case WindowFunction::LANCZOS: | |
| 128 | - return QApplication::tr("Lanczos"); | |
| 129 | - case WindowFunction::BARTLETT: | |
| 130 | - return QApplication::tr("Bartlett"); | |
| 131 | - case WindowFunction::TRIANGULAR: | |
| 132 | - return QApplication::tr("Triangular"); | |
| 133 | - case WindowFunction::GAUSS: | |
| 134 | - return QApplication::tr("Gauss"); | |
| 135 | - case WindowFunction::BARTLETTHANN: | |
| 136 | - return QApplication::tr("Bartlett-Hann"); | |
| 137 | - case WindowFunction::BLACKMAN: | |
| 138 | - return QApplication::tr("Blackman"); | |
| 139 | - // case WindowFunction::WINDOW_KAISER: | |
| 140 | - // return QApplication::tr("Kaiser"); | |
| 141 | - case WindowFunction::NUTTALL: | |
| 142 | - return QApplication::tr("Nuttall"); | |
| 143 | - case WindowFunction::BLACKMANHARRIS: | |
| 144 | - return QApplication::tr("Blackman-Harris"); | |
| 145 | - case WindowFunction::BLACKMANNUTTALL: | |
| 146 | - return QApplication::tr("Blackman-Nuttall"); | |
| 147 | - case WindowFunction::FLATTOP: | |
| 148 | - return QApplication::tr("Flat top"); | |
| 149 | - default: | |
| 150 | - return QString(); | |
| 151 | - } | |
| 152 | -} | |
| 153 | - | |
| 154 | -/// \brief Return string representation of the given graph interpolation mode. | |
| 155 | -/// \param interpolation The ::InterpolationMode that should be returned as | |
| 156 | -/// string. | |
| 157 | -/// \return The string that should be used in labels etc. | |
| 158 | -QString interpolationModeString(InterpolationMode interpolation) { | |
| 159 | - switch (interpolation) { | |
| 160 | - case INTERPOLATION_OFF: | |
| 161 | - return QApplication::tr("Off"); | |
| 162 | - case INTERPOLATION_LINEAR: | |
| 163 | - return QApplication::tr("Linear"); | |
| 164 | - case INTERPOLATION_SINC: | |
| 165 | - return QApplication::tr("Sinc"); | |
| 166 | - default: | |
| 167 | - return QString(); | |
| 168 | - } | |
| 169 | -} | |
| 170 | -} |
openhantek/src/utils/dsoStrings.h deleted
| 1 | -// SPDX-License-Identifier: GPL-2.0+ | |
| 2 | - | |
| 3 | -#pragma once | |
| 4 | -#include <QString> | |
| 5 | -#include "post/enums.h" | |
| 6 | -#include "hantekdso/enums.h" | |
| 7 | - | |
| 8 | -#define MARKER_COUNT 2 ///< Number of markers | |
| 9 | - | |
| 10 | -/// \namespace Dso | |
| 11 | -/// \brief All DSO specific things for different modes and so on. | |
| 12 | -namespace Dso { | |
| 13 | - | |
| 14 | -QString channelModeString(ChannelMode mode); | |
| 15 | -QString graphFormatString(GraphFormat format); | |
| 16 | -QString couplingString(Coupling coupling); | |
| 17 | -QString mathModeString(MathMode mode); | |
| 18 | -QString triggerModeString(TriggerMode mode); | |
| 19 | -QString slopeString(Slope slope); | |
| 20 | -QString windowFunctionString(WindowFunction window); | |
| 21 | -QString interpolationModeString(InterpolationMode interpolation); | |
| 22 | -} |