Skip to content

Commit

Permalink
Fixed [ZXTR-15] Implement parsing paremeters settings
Browse files Browse the repository at this point in the history
  • Loading branch information
lgolouz committed Dec 22, 2020
1 parent cabbcdb commit a840914
Show file tree
Hide file tree
Showing 12 changed files with 610 additions and 16 deletions.
2 changes: 2 additions & 0 deletions ZXTapeReviver.pro
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ SOURCES += \
sources/controls/waveformcontrol.cpp \
sources/core/waveformparser.cpp \
sources/core/wavreader.cpp \
sources/models/parsersettingsmodel.cpp \
sources/models/suspiciouspointsmodel.cpp

HEADERS += \
Expand All @@ -28,6 +29,7 @@ HEADERS += \
sources/controls/waveformcontrol.h \
sources/core/waveformparser.h \
sources/core/wavreader.h \
sources/models/parsersettingsmodel.h \
sources/models/suspiciouspointsmodel.h

RESOURCES += qml/qml.qrc
Expand Down
2 changes: 1 addition & 1 deletion qml/Frequency.qml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Dialog {

Text {
id: textWithField
text: "Measured frequency: "
text: "Measured frequency:"
}

TextField {
Expand Down
206 changes: 206 additions & 0 deletions qml/ParserSettings.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
//*******************************************************************************
// ZX Tape Reviver
//-----------------
//
// Author: Leonid Golouz
// E-mail: [email protected]
//*******************************************************************************

import QtQuick 2.3
import QtQuick.Controls 1.3
import QtQuick.Dialogs 1.3
import QtQuick.Layouts 1.15

import com.models.zxtapereviver 1.0

Dialog {
id: parserSettingsDialog

visible: false
title: "Parser settings"
standardButtons: StandardButton.Ok | StandardButton.RestoreDefaults
modality: Qt.WindowModal

Grid {
id: grid
columns: 4

GroupBox {
title: "Pilot-tone settings:"
ColumnLayout {
Layout.fillHeight: true
Text {
text: "Pilot half frequency:"
}

TextField {
text: ParserSettingsModel.pilotHalfFreq;
onTextChanged: {
ParserSettingsModel.pilotHalfFreq = parseInt(text, 10);
}
}

Text {
text: "Pilot frequency:"
}

TextField {
text: ParserSettingsModel.pilotFreq;
onTextChanged: {
ParserSettingsModel.pilotFreq = parseInt(text, 10);
}
}

Text {
text: "Pilot delta:"
}

TextField {
text: ParserSettingsModel.pilotDelta
onTextChanged: {
ParserSettingsModel.pilotDelta = text;
}
}
}
}

GroupBox {
title: "Synchro signal settigns:"
ColumnLayout {
Text {
text: "Synchro first half frequency:"
}

TextField {
text: ParserSettingsModel.synchroFirstHalfFreq;
onTextChanged: {
ParserSettingsModel.synchroFirstHalfFreq = parseInt(text, 10);
}
}

Text {
text: "Synchro second half frequency:"
}

TextField {
text: ParserSettingsModel.synchroSecondHalfFreq;
onTextChanged: {
ParserSettingsModel.synchroSecondHalfFreq = parseInt(text, 10);
}
}

Text {
text: "Synchro frequency:"
}

TextField {
text: ParserSettingsModel.synchroFreq;
onTextChanged: {
ParserSettingsModel.synchroFreq = parseInt(text, 10);
}
}

Text {
text: "Synchro delta:"
}

TextField {
text: ParserSettingsModel.synchroDelta
onTextChanged: {
ParserSettingsModel.synchroDelta = text;
}
}
}
}

GroupBox {
title: "Zero digit settings:"
ColumnLayout {
Text {
text: "Zero half frequency:"
}

TextField {
text: ParserSettingsModel.zeroHalfFreq;
onTextChanged: {
ParserSettingsModel.zeroHalfFreq = parseInt(text, 10);
}
}

Text {
text: "Zero frequency:"
}

TextField {
text: ParserSettingsModel.zeroFreq;
onTextChanged: {
ParserSettingsModel.zeroFreq = parseInt(text, 10);
}
}

Text {
text: "Zero delta:"
}

TextField {
text: ParserSettingsModel.zeroDelta
onTextChanged: {
ParserSettingsModel.zeroDelta = text;
}
}
}
}

GroupBox {
title: "One digit settings:"
ColumnLayout {
Text {
text: "One half frequency:"
}

TextField {
text: ParserSettingsModel.oneHalfFreq;
onTextChanged: {
ParserSettingsModel.oneHalfFreq = parseInt(text, 10);
}
}

Text {
text: "One frequency:"
}

TextField {
text: ParserSettingsModel.oneFreq;
onTextChanged: {
ParserSettingsModel.oneFreq = parseInt(text, 10);
}
}

Text {
text: "One delta:"
}

TextField {
text: ParserSettingsModel.oneDelta
onTextChanged: {
ParserSettingsModel.oneDelta = text;
}
}
}
}
}
CheckBox {
anchors.top: grid.bottom
anchors.topMargin: 5

text: "Check for abnormal sine when parsing"
checked: ParserSettingsModel.checkForAbnormalSine
onCheckedChanged: {
ParserSettingsModel.checkForAbnormalSine = checked;
}
}

onReset: {
ParserSettingsModel.restoreDefaultSettings();
}
}
13 changes: 13 additions & 0 deletions qml/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,15 @@ ApplicationWindow {
MenuItem {
text: "Reparse"
}

MenuSeparator { }

MenuItem {
text: "Parser settings..."
onTriggered: {
parserSettingsDialog.open();
}
}
}
}

Expand Down Expand Up @@ -754,6 +763,10 @@ ApplicationWindow {
}
}

ParserSettings {
id: parserSettingsDialog
}

Frequency {
id: frequencyDialog
Component.onCompleted: {
Expand Down
1 change: 1 addition & 0 deletions qml/qml.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
<file>main.qml</file>
<file>GoToAddress.qml</file>
<file>Frequency.qml</file>
<file>ParserSettings.qml</file>
</qresource>
</RCC>
29 changes: 20 additions & 9 deletions sources/core/waveformparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//*******************************************************************************

#include "waveformparser.h"
#include "sources/models/parsersettingsmodel.h"
#include <QDebug>
#include <QDateTime>
#include <QByteArray>
Expand Down Expand Up @@ -45,23 +46,32 @@ void WaveformParser::parse(uint chNum)
uint8_t bit = 0;
uint8_t parity = 0;

const auto& parserSettings = ParserSettingsModel::instance()->getParserSettings();
auto isSineNormal = [&parserSettings, sampleRate](const WaveformPart& b, const WaveformPart& e, bool zeroCheck) -> bool {
if (parserSettings.checkForAbnormalSine) {
return isFreqFitsInDelta(sampleRate, b.length, zeroCheck ? parserSettings.zeroHalfFreq : parserSettings.oneHalfFreq, zeroCheck ? parserSettings.zeroDelta : parserSettings.oneDelta, 0.5) &&
isFreqFitsInDelta(sampleRate, e.length, zeroCheck ? parserSettings.zeroHalfFreq : parserSettings.oneHalfFreq, zeroCheck ? parserSettings.zeroDelta : parserSettings.oneDelta, 0.5);
}
return true;
};

while (currentState != NO_MORE_DATA) {
auto prevIt = it;
switch (currentState) {
case SEARCH_OF_PILOT_TONE:
it = std::find_if(it, parsed.end(), [sampleRate, chNum, this](const WaveformPart& p) {
it = std::find_if(it, parsed.end(), [&parserSettings, sampleRate, chNum, this](const WaveformPart& p) {
fillParsedWaveform(chNum, p, 0);
return isFreqFitsInDelta(sampleRate, p.length, SignalFrequencies::PILOT_HALF_FREQ, pilotDelta, 2.0);
return isFreqFitsInDelta(sampleRate, p.length, parserSettings.pilotHalfFreq, parserSettings.pilotDelta, 2.0);
});
if (it != parsed.end()) {
currentState = PILOT_TONE;
}
break;

case PILOT_TONE:
it = std::find_if(it, parsed.end(), [sampleRate, chNum, this](const WaveformPart& p) {
it = std::find_if(it, parsed.end(), [&parserSettings, sampleRate, chNum, this](const WaveformPart& p) {
fillParsedWaveform(chNum, p, pilotTone ^ sequenceMiddle);
return isFreqFitsInDelta(sampleRate, p.length, SignalFrequencies::SYNCHRO_FIRST_HALF_FREQ, synchroDelta);
return isFreqFitsInDelta(sampleRate, p.length, parserSettings.synchroFirstHalfFreq, parserSettings.synchroDelta);
});
if (it != parsed.end()) {
auto eIt = std::prev(it);
Expand All @@ -84,7 +94,8 @@ void WaveformParser::parse(uint chNum)
case SYNCHRO_SIGNAL:
it = std::next(it);
if (it != parsed.end()) {
if ((isFreqFitsInDelta(sampleRate, it->length, SignalFrequencies::SYNCHRO_SECOND_HALF, synchroDelta)) && (isFreqFitsInDelta(sampleRate, it->length + prevIt->length, SignalFrequencies::SYNCHRO_FREQ, synchroDelta, 2.0))) {
if ((isFreqFitsInDelta(sampleRate, it->length, parserSettings.synchroSecondHalfFreq, parserSettings.synchroDelta)) &&
(isFreqFitsInDelta(sampleRate, it->length + prevIt->length, parserSettings.synchroFreq, parserSettings.synchroDelta, 2.0))) {
fillParsedWaveform(chNum, *prevIt, synchroSignal ^ sequenceMiddle);
fillParsedWaveform(chNum, *it, synchroSignal ^ sequenceMiddle);
parsedWaveform[prevIt->begin] = synchroSignal ^ sequenceBegin;
Expand Down Expand Up @@ -118,7 +129,7 @@ void WaveformParser::parse(uint chNum)
it = std::next(it);
if (it != parsed.end()) {
const auto len = it->length + prevIt->length;
if (isFreqFitsInDelta(sampleRate, len, SignalFrequencies::ZERO_FREQ, zeroDelta)) { //ZERO
if (isFreqFitsInDelta(sampleRate, len, parserSettings.zeroFreq, parserSettings.zeroDelta) && isSineNormal(*prevIt, *it, true)) { //ZERO
fillParsedWaveform(chNum, *prevIt, zeroBit ^ sequenceMiddle);
fillParsedWaveform(chNum, *it, zeroBit ^ sequenceMiddle);
parsedWaveform[prevIt->begin] = zeroBit ^ sequenceBegin;
Expand Down Expand Up @@ -146,7 +157,7 @@ void WaveformParser::parse(uint chNum)
bit ^= bit;
}
}
else if (isFreqFitsInDelta(sampleRate, len, SignalFrequencies::ONE_FREQ, oneDelta)) { //ONE
else if (isFreqFitsInDelta(sampleRate, len, parserSettings.oneFreq, parserSettings.oneDelta) && isSineNormal(*prevIt, *it, false)) { //ONE
fillParsedWaveform(chNum, *prevIt, oneBit ^ sequenceMiddle);
fillParsedWaveform(chNum, *it, oneBit ^ sequenceMiddle);
parsedWaveform[prevIt->begin] = oneBit ^ sequenceBegin;
Expand Down Expand Up @@ -351,6 +362,6 @@ QVariantList WaveformParser::getParsedChannel1() const

WaveformParser* WaveformParser::instance()
{
static WaveformParser p;
return &p;
static QScopedPointer<WaveformParser> p { new WaveformParser() };
return p.get();
}
9 changes: 6 additions & 3 deletions sources/core/wavreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "wavreader.h"
#include "sources/models/suspiciouspointsmodel.h"
#include "sources/models/parsersettingsmodel.h"
#include <QVariant>
#include <QVariantList>
#include <QDateTime>
Expand Down Expand Up @@ -390,6 +391,8 @@ void WavReader::normalizeWaveform2(uint chNum)
return lessThanZero(o1) == lessThanZero(o2);
};

const auto& parserSettings = ParserSettingsModel::instance()->getParserSettings();

//Trying to find a sine
auto bIt = ch.begin();

Expand Down Expand Up @@ -440,7 +443,7 @@ void WavReader::normalizeWaveform2(uint chNum)
if (it != ch.end()) {
bIt = it;
double freq = getSampleRate() / std::distance(peaks[0], peaks[3]);
if (freq <= ZERO_HALF_FREQ) {
if (freq <= parserSettings.zeroHalfFreq) {
auto it = peaks[2];
for (int i = 0; i < 2 && it != ch.end(); ++i, ++it) {
auto val = *it;
Expand Down Expand Up @@ -470,6 +473,6 @@ WavReader::~WavReader()

WavReader* WavReader::instance()
{
static WavReader w;
return &w;
static QScopedPointer<WavReader> w { new WavReader() };
return w.get();
}
Loading

0 comments on commit a840914

Please sign in to comment.