diff --git a/decoders/cw-decoder-old/cw-decoder.cpp b/decoders/cw-decoder-old/cw-decoder.cpp deleted file mode 100644 index e03209f..0000000 --- a/decoders/cw-decoder-old/cw-decoder.cpp +++ /dev/null @@ -1,580 +0,0 @@ -# -/* - * Copyright (C) 2011, 2012, 2013 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Programming - * - * This file is part of swradio - * - * swradio 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; either version 2 of the License, or - * (at your option) any later version. - * - * swradio 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with swradio; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -# -#include -#include -#include "cw-decoder.h" -#include "utilities.h" - -#define USECS_PER_SEC 1000000 -#define MODE_IDLE 0100 -#define MODE_IN_TONE 0200 -#define MODE_AFTER_TONE 0300 -#define MODE_END_OF_LETTER 0400 - -#define CW_DOT_REPRESENTATION '.' -#define CW_DASH_REPRESENTATION '_' -#define CW_IF 0 -/* - * The standard morse wordlength (i.e. - * PARIS) is 50 bits, then for a wpm of 1, - * one bit takes 1.2 second or 1.2 x 10^6 microseconds - */ -#define DOT_MAGIC 1200000 - -extern const char *const codetable []; - - cwDecoder::cwDecoder (int32_t inRate, - RingBuffer> *buffer, - QSettings *s) : - virtualDecoder (inRate, buffer), - inputBuffer (inRate), - inputConverter (inRate, 2000), - localShifter (10 * 2000) { - theRate = inRate; - (void)s; - myFrame = new QFrame; - setupUi (myFrame); - myFrame -> show (); // - workingRate = 2000; - setup_cwDecoder (workingRate); - screenwidth = workingRate / 4; - x_axis = new double [screenwidth]; - for (int i = 0; i < screenwidth; i ++) - x_axis [i] = - screenwidth / 2 + i; - y_values = new double [screenwidth]; - - fillP = 0; - theFilter = new decimatingFIR (35, screenwidth / 2, workingRate, 8); - cwViewer = new waterfallScope (cwScope, - screenwidth, 15); - the_fft = new common_fft (workingRate / 4); - fftBuffer = the_fft -> getVector (); - - connect (cwViewer, SIGNAL (clickedwithLeft (int)), - this, SLOT (handleClick (int))); -} - - cwDecoder::~cwDecoder (void) { - delete SmoothenSamples; - delete thresholdFilter; - delete spaceFilter; - delete cwViewer; - delete the_fft; - delete[] x_axis; - delete[] y_values; - delete myFrame; -} - -void cwDecoder::setup_cwDecoder (int32_t rate) { - - CycleCount = rate / 10; - cw_IF = CW_IF; - - SmoothenSamples = new average (4); - thresholdFilter = new average (8); - spaceFilter = new average (16); -/* - * the filter will be set later on - */ - cw_BandPassFilter = NULL; - cwCurrent = 0; - agc_peak = 0; - noiseLevel = 0; - cwState = MODE_IDLE; - cwPreviousState = MODE_IDLE; - - cw_setFilterDegree (FilterDegree -> value ()); - cw_setSquelchValue (SquelchLevel -> value ()); - cw_setWordsperMinute (WPM -> value ()); - cwTracking = true; /* default */ - CycleCount = workingRate / 10; - - connect (SquelchLevel, SIGNAL (valueChanged (int)), - this, SLOT (cw_setSquelchValue (int))); - connect (WPM, SIGNAL (valueChanged (int)), - this, SLOT (cw_setWordsperMinute (int))); - connect (FilterDegree, SIGNAL (valueChanged (int)), - this, SLOT (cw_setFilterDegree (int))); - connect (Tracker, SIGNAL (clicked (void)), - this, SLOT (cw_setTracking (void))); - - CWrange = cwDefaultSpeed / 2; - cwSpeed = cwDefaultSpeed; - lowerBoundWPM = cwDefaultSpeed - CWrange; - upperBoundWPM = cwDefaultSpeed + CWrange; - cwSpeed = cwDefaultSpeed; /* initial */ - - cwDefaultDotLength = DOT_MAGIC / cwDefaultSpeed; - cwDotLength = cwDefaultDotLength; - cwSpaceLength = cwDefaultDotLength; - cwDotLengthMax = DOT_MAGIC / lowerBoundWPM; - cwDotLengthMin = DOT_MAGIC / upperBoundWPM; - - cwDashLength = 3 * cwDotLength; - cwDashLengthMax = 3 * cwDotLengthMax; - cwDashLengthMin = 3 * cwDotLengthMin; - - cw_adaptive_threshold = 2 * cwDefaultDotLength; - cwNoiseSpike = cwDotLength / 3; - - cwStartTimestamp = 0; - cwEndTimestamp = 0; - - cwCurrent = 0; - agc_peak = 0; - noiseLevel = 0; - - memset (dataBuffer, 0, sizeof (dataBuffer)); - thresholdFilter -> clear (2 * cwDotLength); - spaceFilter -> clear (cwDotLength); - cw_clrText (); - cwCharbox -> setText (QString (" ")); -} - -void cwDecoder::cw_setWordsperMinute (int n) { - cwDefaultSpeed = n; - speedAdjust (); -} - -void cwDecoder::cw_setTracking (void) { - cwTracking = !cwTracking; - if (cwTracking) - Tracker -> setText (QString ("Tracking off")); - else - Tracker -> setText (QString ("Tracking on")); - speedAdjust (); -} - -void cwDecoder::cw_setSquelchValue (int s) { - SquelchValue = s; -} - -void cwDecoder::cw_setFilterDegree (int n) { - cwFilterDegree = n; - if (cw_BandPassFilter != NULL) - delete cw_BandPassFilter; - cw_BandPassFilter = new bandpassFIR (2 * cwFilterDegree + 1, - cw_IF - 30, - cw_IF + 20, - workingRate); -} - -void cwDecoder::speedAdjust () { - cwSpeed = cwDefaultSpeed; /* init */ - CWrange = cwSpeed / 2; - lowerBoundWPM = cwDefaultSpeed - CWrange; - upperBoundWPM = cwDefaultSpeed + CWrange; - - cwDefaultDotLength = DOT_MAGIC / cwDefaultSpeed; - cwDotLength = cwDefaultDotLength; - cw_adaptive_threshold = 2 * cwDefaultDotLength; - - cwDotLengthMax = DOT_MAGIC / lowerBoundWPM; - cwDotLengthMin = DOT_MAGIC / upperBoundWPM; - - cwDashLength = 3 * cwDotLength; - cwDashLengthMax = 3 * cwDotLengthMax; - cwDashLengthMin = 3 * cwDotLengthMin; - - cwNoiseSpike = cwDotLength / 3; - cwStartTimestamp = 0; - cwEndTimestamp = 0; - - cwState = MODE_IDLE; - cwCurrent = 0; - memset (dataBuffer, 0, sizeof (dataBuffer)); - thresholdFilter -> clear (2 * cwDotLength); - cw_clrText (); - cwCharbox -> setText (QString (" ")); -} - -void cwDecoder::process (std::complex z) { - audioOut -> putDataIntoBuffer (&z, 1); - processBuffer (&z, 1); - if (++CycleCount > theRate / 10){ - CycleCount = 0; - cw_showdotLength (cwDotLength); - cw_showspaceLength (cwSpaceLength); - cw_showspeed (cwSpeed); - cw_showagcpeak (clamp (agc_peak * 1000.0, 0.0, 100.0)); - cw_shownoiseLevel (clamp (noiseLevel * 1000.0, 0.0, 100.0)); - audioAvailable (theRate / 10, theRate); - setDetectorMarker ((int)cw_IF); - } -} - -void cwDecoder::processBuffer (std::complex *buffer, - int32_t amount) { -int32_t inSize = inputConverter. bufferSize_in (); -int32_t outSize = inputConverter. bufferSize_out () + 10; -std::complex inBuffer [inSize]; -std::complex outBuffer [outSize]; -int32_t i; - - inputBuffer. putDataIntoBuffer (buffer, amount); - while ((int32_t)(inputBuffer. GetRingBufferReadAvailable ()) > inSize) { - inputBuffer. getDataFromBuffer (inBuffer, inSize); - inputConverter. convert_in (inBuffer); - amount = inputConverter. hasData (); - inputConverter. dataOut (outBuffer, amount); - for (i = 0; i < amount; i ++) - processSample (outBuffer [i]); - } -} - -void cwDecoder::processSample (std::complex z) { -DSPCOMPLEX ret; -int32_t lengthOfTone; -int32_t lengthOfSilence; -int32_t t; -int i; -char buffer [4]; -std::complex s; -std::complex res; -std::complexv [2000]; - - s = cw_BandPassFilter -> Pass (s); - s = localShifter. do_shift (z, cw_IF * 10); - value = abs (s); - - if (theFilter -> Pass (s, &res)) { - fftBuffer [fillP ++] = res; - if (fillP >= workingRate / 8) { - for (int i = 0; i < workingRate / 8; i ++) - fftBuffer [workingRate / 8 + i] = std::complex (0, 0); - the_fft -> do_FFT (); - for (i = 0; i < workingRate / 8; i ++) { - v [i] = fftBuffer [workingRate / 8 + i]; - v [workingRate / 8 + i] = fftBuffer [i]; - } - for (i = 0; i < screenwidth; i ++) - y_values [i] = - abs (v [i]); - cwViewer -> display (x_axis, y_values, - amplitudeSlider -> value (), 0, 0); - fillP = 0; - } - } - if (value > agc_peak) - agc_peak = decayingAverage (agc_peak, value, 50.0); - else - agc_peak = decayingAverage (agc_peak, value, 500.0); - - currentTime += USECS_PER_SEC / workingRate; - switch (cwState) { - case MODE_IDLE: - if ((value > 0.67 * agc_peak) && - (value > SquelchValue * noiseLevel)) { -/* - * we seem to start a new tone - */ - cwState = MODE_IN_TONE; - currentTime = 0; - cwCurrent = 0; - cwStartTimestamp = currentTime; - cwPreviousState = cwState; - } - else - noiseLevel = decayingAverage (noiseLevel, - value, 500.0); - break; /* just wait */ - - case MODE_IN_TONE: -/* - * we are/were receiving a tone, either continue - * or stop it, depending on some threshold value. - */ - if (value > 0.33 * agc_peak) - break; /* just go on */ -/* - * if we are here, the tone has ended - */ - cwEndTimestamp = currentTime; - lengthOfTone = currentTime - cwStartTimestamp; - - if (lengthOfTone < cwNoiseSpike) { - cwState = cwPreviousState; - break; - } - - noiseLevel = decayingAverage (noiseLevel, value, 500.0); - - if (lengthOfTone <= cw_adaptive_threshold) - dataBuffer [cwCurrent ++] = CW_DOT_REPRESENTATION; - else - dataBuffer [cwCurrent ++] = CW_DASH_REPRESENTATION; - -/* - * if we gathered too many dots and dashes, we end up - * with garbage. - */ - if (cwCurrent >= CW_RECEIVE_CAPACITY) { - cwCurrent = 0; - cwState = MODE_IDLE; - break; - } - - dataBuffer [cwCurrent] = 0; - cwCharbox -> setText (QString (dataBuffer)); - cwState = MODE_AFTER_TONE; - - if (cwTracking) { - t = newThreshold (lengthofPreviousTone, lengthOfTone); - if (t > 0) { - cw_adaptive_threshold = thresholdFilter -> filter (t); - cwDotLength = cw_adaptive_threshold / 2; - cwDashLength = 3 * cwDotLength; - cwSpeed = DOT_MAGIC / cwDotLength; - cwNoiseSpike = cwDotLength / 3; - } - } - - lengthofPreviousTone = lengthOfTone; - break; - - case MODE_AFTER_TONE: -/* - * following the end of the tone, we might go back for the - * next dash or dot, or we might decide that we reached - * the end of the letter - */ - if ((value > 0.67 * agc_peak) && - (value > SquelchValue * noiseLevel)) { - int t = currentTime - cwEndTimestamp; - cwSpaceLength = spaceFilter -> filter (t); - cwState = MODE_IN_TONE; - cwStartTimestamp = currentTime; - cwPreviousState = cwState; - break; - } -// no tone, adjust noiselevel and handle silence - noiseLevel = decayingAverage (noiseLevel, value, 500.0); - lengthOfSilence = currentTime - cwEndTimestamp; - - if ((lengthOfSilence >= 2 * (cwDotLength + cwSpaceLength) / 2)) { - lookupToken (dataBuffer, buffer); - cwCurrent = 0; - cwState = MODE_END_OF_LETTER; - cw_addText (buffer [0]); - } -// otherwise, silence too short, do nothing as yet - break; -/* - * end_of_letter may be followed by another letter or an end - * of word indication - */ - case MODE_END_OF_LETTER: /* almost MODE_IDLE */ - if ((value > 0.67 * agc_peak) && - (value > SquelchValue * noiseLevel)) { - cwState = MODE_IN_TONE; - cwStartTimestamp = currentTime; - cwPreviousState = cwState; - } - else { -/* - * still silence, look what to do - */ - noiseLevel = decayingAverage (noiseLevel, - value, 500.0); - lengthOfSilence = currentTime - cwEndTimestamp; - if (lengthOfSilence > 4.0 * (cwSpaceLength + cwDotLength) / 2) { - cw_addText (' '); /* word space */ - cwState = MODE_IDLE; - } - } - break; - - default: - break; - } -} -/* - * check for dot/dash or dash/dot sequence to adapt the - * threshold. - */ -int32_t cwDecoder::newThreshold (int32_t prev_element, int32_t curr_element) { - - if ((prev_element > 0) && (curr_element > 0)) { - if ((curr_element > 2 * prev_element) && - (curr_element < 4 * prev_element)) - return getMeanofDotDash (prev_element, curr_element); -/* - * check for dash dot sequence - */ - if ((prev_element > 2 * curr_element) && - (prev_element < 4 * curr_element)) - return getMeanofDotDash (curr_element, prev_element); - } - return -1; -} -/* - * if we have a dot/dash sequence, we might adapt - * the adaptive threshold if both dot and dash length - * are reasonable. - */ -int32_t cwDecoder::getMeanofDotDash (int32_t idot, int32_t idash) { -int32_t dot, dash; - - if (idot > cwDotLengthMin && idot < cwDotLengthMax) - dot = idot; - else - dot = cwDotLength; - - if (idash > cwDashLengthMin && idash < cwDashLengthMax) - dash = idash; - else - dash = cwDashLength; - - return (dash + dot) / 2; -} - -void cwDecoder::printChar (char a, char er) { - if ((a & 0x7f) < 32) { - switch (a) { - case '\n': break; - case '\r': return; - case 8: break; - case 9: break; - default: a = ' '; - } - } - - switch (er) { - case 0: printf("%c",a);break; - case 1: printf("\033[01;42m%c\033[m",a); break; - case 2: printf("\033[01;41m%c\033[m",a); break; - case 3: printf("\033[01;43m%c\033[m",a); break; - case 4: - case 5: - case 6: - case 7: printf("\033[2J\033[H\n"); break; - default: - break; - } -} - -const char * const codetable[] = { - "A._", - "B_...", - "C_._.", - "D_..", - "E.", - "F.._.", - "G__.", - "H....", - "I..", - "J.___", - "K_._", - "L._..", - "M__", - "N_.", - "O___", - "P.__.", - "Q__._", - "R._.", - "S...", - "T_", - "U.._", - "V..._", - "W.__", - "X_.._", - "Y_.__", - "Z__..", - "0_____", - "1.____", - "2..___", - "3...__", - "4...._", - "5.....", - "6_....", - "7__...", - "8___..", - "9____.", - ".._._._", - ",__..__", - "?..__..", - "~" - }; - -void cwDecoder::lookupToken (char *in, char *out) { -int i; - - for (i = 0; codetable [i][0] != '~'; i ++) { - if (strcmp (&codetable [i][1], in) == 0) { - out [0] = codetable [i][0]; - return; - } - } - out [0] = '*'; -} - -void cwDecoder::cw_clrText () { - cwText = QString (""); - cwTextbox -> setText (cwText); -} - -void cwDecoder::cw_addText (char c) { - if (c < ' ') c = ' '; - cwText.append (QString (QChar (c))); - if (cwText. length () > 75) - cwText. remove (0, 1); - cwTextbox -> setText (cwText); -} - -void cwDecoder::cw_showdotLength (int l) { - dotLengthdisplay -> display (l); -} - -void cwDecoder::cw_showspaceLength (int l) { - spaceLengthdisplay -> display (l); -} - -void cwDecoder::cw_showagcpeak (int l) { - agcPeakdisplay -> display (l); -} - -void cwDecoder::cw_shownoiseLevel (int l) { - noiseLeveldisplay -> display (l); -} - -void cwDecoder::cw_showspeed (int l) { - actualWPM -> display (l); -} - -void cwDecoder::cw_adjustFrequency (int f) { - cw_IF += f; - if (cw_IF > workingRate / 2 - workingRate / 20) - cw_IF = workingRate / 2 - workingRate / 20; - if (cw_IF < - workingRate / 2 + workingRate / 20) - cw_IF = -workingRate / 2 + workingRate / 20; - setDetectorMarker (cw_IF); - -} - -void cwDecoder::handleClick (int a) { - fprintf (stderr, "adjusting with %d\n", a); - adjustFrequency (a / 2); -} - - diff --git a/decoders/cw-decoder-old/cw-decoder.h b/decoders/cw-decoder-old/cw-decoder.h deleted file mode 100644 index f066471..0000000 --- a/decoders/cw-decoder-old/cw-decoder.h +++ /dev/null @@ -1,147 +0,0 @@ -# -/* - * Copyright (C) 2017 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Computing - * - * This file is part of the swradio - * - * swradio 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; either version 2 of the License, or - * (at your option) any later version. - * - * swradio 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with swradio; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __CW_DECODER__ -#define __CW_DECODER__ -# -#include -#include "radio-constants.h" -#include "virtual-decoder.h" -#include "ringbuffer.h" -#include "shifter.h" -#include "downconverter.h" -#include "fir-filters.h" -#include "ui_cw-decoder.h" -#include "waterfall-scope.h" -#include "fft.h" - -class Oscillator; -class average; -class QFrame; -class QSettings; - -#define CWError 1000 -#define CWNewLetter 1001 -#define CWCarrierUp 1002 -#define CWCarrierDown 1005 -#define CWStroke 1003 -#define CWDot 1004 -#define CWendofword 1006 -#define CWFailing 1007 - -#define CW_RECEIVE_CAPACITY 040 - -class cwDecoder: public virtualDecoder, public Ui_cwDecoder { -Q_OBJECT -public: - cwDecoder (int32_t, - RingBuffer *, - QSettings *); - ~cwDecoder (void); - void processBuffer (std::complex *, int32_t); - void process (std::complex); -private slots: - void cw_setWordsperMinute (int); - void cw_setTracking (void); - void cw_setFilterDegree (int); - void cw_setSquelchValue (int); - void cw_adjustFrequency (int); - void handleClick (int); - -private: - waterfallScope *cwViewer; - double *x_axis; - double *y_values; - common_fft *the_fft; - std::complex *fftBuffer; - int screenwidth; - int fillP; - decimatingFIR *theFilter; - int32_t theRate; - QFrame *myFrame; - RingBuffer> inputBuffer; - downConverter inputConverter; - shifter localShifter; - bandpassFIR *cw_BandPassFilter; - void processSample (std::complex); - void setup_cwDecoder (int32_t); - void cw_clrText (void); - void cw_addText (char); - QString cwText; - void cw_showdotLength (int); - void cw_showspaceLength (int); - void cw_showspeed (int); - void cw_showagcpeak (int); - void cw_shownoiseLevel (int); -// - void speedAdjust (void); - void printChar (char, char); - void addtoStream (double); - void add_cwTokens (char *); - int32_t newThreshold (int32_t, int32_t); - int32_t getMeanofDotDash (int32_t, int32_t); - void lookupToken (char *, char *); - - int32_t cwPhaseAcc; - - int32_t CycleCount; - int16_t cwFilterDegree; - average *SmoothenSamples; - average *thresholdFilter; - average *spaceFilter; - - float agc_peak; - float noiseLevel; - float value; - float metric; - double cw_IF; - int32_t cwDotLength; - int32_t cwSpaceLength; - int32_t cwDashLength; - int16_t SquelchValue; - int16_t cwState; - int16_t cwPreviousState; - int32_t cw_adaptive_threshold; - int32_t currentTime; - int32_t cwCurrent; - int16_t cwSpeed; - int16_t cwDefaultSpeed; - char dataBuffer [CW_RECEIVE_CAPACITY]; - int32_t CWrange; - int32_t cwDefaultDotLength; - int32_t lowerBoundWPM; - int32_t upperBoundWPM; - int32_t cwDotLengthMin; - int32_t cwDotLengthMax; - int32_t cwDashLengthMin; - int32_t cwDashLengthMax; - int32_t lengthofPreviousTone; - int32_t cwNoiseSpike; - int32_t cwStartTimestamp; - int32_t cwEndTimestamp; - bool cwTracking; - -signals: -}; -#endif - diff --git a/decoders/cw-decoder-old/cw-decoder.ui b/decoders/cw-decoder-old/cw-decoder.ui deleted file mode 100644 index 0f7008e..0000000 --- a/decoders/cw-decoder-old/cw-decoder.ui +++ /dev/null @@ -1,247 +0,0 @@ - - - cwDecoder - - - - 0 - 0 - 726 - 223 - - - - cw-decoder - - - - - 10 - 0 - 701 - 211 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 90 - 30 - 101 - 21 - - - - <html><head/><body><p>The &quot;dots&quot;, &quot;dashes&quot; and &quot;spaces&quot; in the current word.</p></body></html> - - - QFrame::Box - - - 2 - - - - - - - - - 10 - 10 - 491 - 21 - - - - QFrame::Box - - - - - - - - - 10 - 30 - 71 - 21 - - - - <html><head/><body><p>Squelch level, signal strength below this level is assumed to be noise.</p></body></html> - - - 5 - - - - - - 10 - 50 - 71 - 21 - - - - <html><head/><body><p>Word length guess. Used to guess the length of &quot;dots&quot;, &quot;dashed&quot; and &quot;spaces&quot;. </p><p>Most amateur transmissions are synchronized on with the default selection of 30.</p><p>Fast transmissions - noted by the fact that everything becomes a &quot;dot&quot;, need a higher setting.</p></body></html> - - - 30 - - - - - - 10 - 70 - 71 - 21 - - - - <html><head/><body><p>Order of the filter that is used to isolate the selected signal from the surrounding &quot;noise&quot;.</p></body></html> - - - 12 - - - - - - 90 - 50 - 64 - 20 - - - - <html><head/><body><p>Guess of the wordlength.</p></body></html> - - - QLCDNumber::Flat - - - - - - 90 - 90 - 81 - 21 - - - - Tracker on - - - - - - 10 - 140 - 64 - 23 - - - - <html><head/><body><p>Average noise Level.</p></body></html> - - - QLCDNumber::Flat - - - - - - 10 - 160 - 64 - 23 - - - - <html><head/><body><p>Signal peak level.</p></body></html> - - - QLCDNumber::Flat - - - - - - 10 - 90 - 64 - 23 - - - - <html><head/><body><p>Guess of the duration of a &quot;space&quot; (in samples).</p></body></html> - - - QLCDNumber::Flat - - - - - - 10 - 110 - 64 - 23 - - - - <html><head/><body><p>Guess of the length of &quot;dots&quot; (in samples).</p></body></html> - - - QLCDNumber::Flat - - - - - - 200 - 60 - 471 - 131 - - - - - - - 170 - 60 - 24 - 131 - - - - 50 - - - Qt::Vertical - - - - - - - QwtPlot - QFrame -
qwt_plot.h
-
-
- - -
diff --git a/decoders/fax-decoder-old/fax-decoder.cpp b/decoders/fax-decoder-old/fax-decoder.cpp deleted file mode 100644 index 93b6689..0000000 --- a/decoders/fax-decoder-old/fax-decoder.cpp +++ /dev/null @@ -1,763 +0,0 @@ -# -/* - * Copyright (C) 2011, 2012, 2013 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair programming - * - * Parts of this fax decoder is derived/copied from - * hamfax -- an application for sending and receiving amateur - * radio facsimiles - * Copyright (C) 2001 Christof Schmitt, - * DH1CS - * All copyrights gratefully acknowledged. - * - * SDR-J 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; either version 2 of the License, or - * (at your option) any later version. - * - * SDR-J 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with SDR-J; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include "fax-decoder.h" -#include "fax-demodulator.h" -#include "fax-filenames.h" -#include "fax-image.h" -#include "shifter.h" - -#define FAX_IF 1000 -#define FILTER_DEFAULT 21 - -faxParams _faxParams [] = { - {"Wefax288", 288, 675, 450, false, 120}, - {"Wefax576", 576, 300, 450, false, 120}, - {"HamColor", 204, 200, 450, true, 360}, - {"Ham288b", 240, 675, 450, false, 240}, - {"Color240", 288, 200, 450, true, 240}, - {"FAX480", 204, 500, 450, false, 480}, - {NULL, -1, -1, -1, false, -1} -}; - - - faxDecoder::faxDecoder (int32_t rate, - RingBuffer> *b, - QSettings *s): - virtualDecoder (rate, b), - localMixer (rate) { - theRate = rate; - audioOut = b; - faxSettings = s; - - myFrame = new QFrame; - setupUi (myFrame); - myFrame -> show (); - faxContainer = new faxScroller (NULL); - faxContainer -> resize (200, 200); - faxContainer -> show (); - setup_faxDecoder (faxSettings); - faxCycleCounter = 0; -} - - faxDecoder::~faxDecoder (void) { - faxSettings -> beginGroup ("faxDecoder"); - faxSettings -> setValue ("fax_iocSetter", - iocSetter -> currentText ()); - faxSettings -> setValue ("fax_phaseSetter", - phaseSetter -> currentText ()); - faxSettings -> setValue ("fax_deviationSetter", - deviationSetter -> value ()); - faxSettings -> endGroup (); -// - delete myDemodulator; - delete theImage; - delete faxLowPass; - delete faxContainer; - delete nameGenerator; - delete myFrame; -} - -void faxDecoder::setup_faxDecoder (QSettings *s) { -QString h; -int k; - faxLowPass = new LowPassFIR (FILTER_DEFAULT, - deviation + 50, - theRate); - faxAverager = new average (20); - myDemodulator = new faxDemodulator (FAX_FM, - theRate, - deviation); -/* - * restore some of the settings - */ - s -> beginGroup ("faxDecoder"); - h = s -> value ("fax_iocSetter", "576"). toString (); - k = iocSetter -> findText (h); - if (k != -1) - iocSetter -> setCurrentIndex (k); - -// -// OK, we know now -faxParams *myfaxParameters = getFaxParams (iocSetter -> currentText ()); - lpmSetter -> setValue (myfaxParameters -> lpm); - lpm = myfaxParameters -> lpm;; - samplesperLine = theRate * 60 / lpm; - fax_IOC = myfaxParameters -> IOC; - numberofColums = M_PI * fax_IOC; - faxColor = myfaxParameters -> color ? - FAX_COLOR: FAX_BLACKWHITE; - carrier = FAX_IF; // default - phaseInvers = false; - lastRow = 100; // will change - theImage = new faxImage (numberofColums, lastRow); - rawData. resize (1024 * 1024); -// - pointNeeded = false; - faxState = APTSTART; - aptCount = 0; - apt_upCrossings = 0; - whiteSide = false; - pixelValue = 0; - pixelSamples = 0; - currentSampleIndex = 0; - set_savingRequested (false); - set_autoContinue (false); - nameGenerator = new faxFilenames (0); -// - startSetter -> setValue (myfaxParameters -> aptStart); - stopSetter -> setValue (myfaxParameters -> aptStop); - - fax_setstartFreq (startSetter -> value ()); - fax_setstopFreq (stopSetter -> value ()); - fax_setCarrier (carrierSetter -> value ()); - fax_setDeviation (deviationSetter -> value ()); - setDetectorMarker (carrier); - showState -> setText (QString ("APTSTART")); - theImage -> clear (); - fax_displayImage (theImage -> getImage ()); -// -// - connect (colorSetter, SIGNAL (activated (const QString &)), - this, SLOT (fax_setColor (const QString &))); - connect (skipSetter, SIGNAL (clicked (void)), - this, SLOT (fax_setSkip (void))); - connect (iocSetter, SIGNAL (activated (const QString &)), - this, SLOT (fax_setIOC (const QString &))); - connect (modeSetter, SIGNAL (activated (const QString &)), - this, SLOT (fax_setMode (const QString &))); - connect (startSetter, SIGNAL (valueChanged (int)), - this, SLOT (fax_setstartFreq (int))); - connect (stopSetter, SIGNAL (valueChanged (int)), - this, SLOT (fax_setstopFreq (int))); - connect (carrierSetter, SIGNAL (valueChanged (int)), - this, SLOT (fax_setCarrier (int))); - connect (deviationSetter, SIGNAL (valueChanged (int)), - this, SLOT (fax_setDeviation (int))); - connect (lpmSetter, SIGNAL (valueChanged (int)), - this, SLOT (fax_setLPM (int))); - connect (phaseSetter, SIGNAL (activated (const QString &)), - this, SLOT (fax_setPhase (const QString &))); - connect (resetButton, SIGNAL (clicked (void)), - this, SLOT (reset (void))); - connect (saveButton, SIGNAL (clicked (void)), - this, SLOT (fax_setsavingonDone (void))); - connect (faxContainer, SIGNAL (fax_Clicked (int, int)), - this, SLOT (fax_setClicked (int, int))); - connect (autoContinueButton, SIGNAL (clicked (void)), - this, SLOT (fax_setautoContinue (void))); - h = s -> value ("fax_modeSetter", "FM"). toString (); - k = modeSetter -> findText (h); - if (k != -1) - modeSetter -> setCurrentIndex (k); - - h = s -> value ("fax_phaseSetter", "phase"). toString (); - k = phaseSetter -> findText (h); - if (k != -1) - phaseSetter -> setCurrentIndex (k); - - k = s -> value ("fax_deviationSetter", 400). toInt (); - deviationSetter -> setValue (k); - s -> endGroup (); -} - -////////////////////////////////////////////// -static inline -bool realWhite (int16_t x) { - return x > 229; -} - -static inline -bool realBlack (int16_t x) { - return x < 25; -} - -static inline -bool isWhite (int16_t x) { - return x > 128; -} - -void faxDecoder::reset (void) { - faxState = APTSTART; - showState -> setText (QString ("APTSTART")); - aptCount = 0; - apt_upCrossings = 0; - whiteSide = false; - pixelValue = 0; - pixelSamples = 0; - currentSampleIndex = 0; - currPhaseLength = 0; - whiteLength = 0; - delayCounter = 0; - rawData. resize (1024 * 1024); - theImage -> clear (); - fax_displayImage (theImage -> getImage ()); -} -// -// as always, we "process" one sample at the time. -// -static -bool inRange (int16_t x, int16_t y) { - return y - 2 <= x && x <= y + 2; -} - -#define we_are_Black (!whiteSide) - -void faxDecoder::process (std::complex z) { -int16_t sampleValue; - - audioOut -> putDataIntoBuffer (&z, 1); - if (++faxCycleCounter >= theRate / 10) { - faxCycleCounter = 0; - setDetectorMarker (carrier); - audioAvailable (theRate / 10, theRate); - } -// -// When we are in autoContinue mode, we just wait at least for -// 30 seconds after detecting the FAX_DONE before resetting - if (faxState == FAX_DONE) { - if (autoContinue && delayCounter ++ > theRate * 30) { - reset (); // will a.o set the state - delayCounter = 0; - } else - return; - } - - z = localMixer. do_shift (z, carrier); - z = faxLowPass -> Pass (z); - sampleValue = myDemodulator -> demodulate (z); - - if (phaseInvers) - sampleValue = 256 - sampleValue; - if (faxColor == FAX_BLACKWHITE) - sampleValue = isWhite (sampleValue) ? 255 : 0; - fax_oldz = z; - currentValue = sampleValue; - -// We count the number of times the decoded values -// goes up from black to white. If in a period of half a second -// (i.e. we had theRate / 2 samples), the number -// of upCrossings is aptStartFreq / 2, we have a start -// if the number is aptStopFreq and we are -// not DONE or APT_START then we finish the transmission - - if (we_are_Black && realWhite (sampleValue)) { - whiteSide = true; - apt_upCrossings ++; - } - else - if (whiteSide && realBlack (sampleValue)) - whiteSide = false; - -// if we have samples for about half a second of samples, -// check the frequency -// to see whether we are ready for phasing or for exit - if (++aptCount >= theRate / 2) { - int16_t freq = 2 * apt_upCrossings; - aptFreq -> display (freq); - aptCount = 0; - apt_upCrossings = 0; - - if ((faxState == APTSTART) && - inRange (freq, aptStartFreq)) { - faxState = FAX_PHASING; -// carrier -= freq - aptStartFreq; - initPhasing (); - return; - } - - if (((faxState & (FAX_PHASING | FAX_IMAGING)) != 0) && - inRange (freq, aptStopFreq)) { - rawData. resize (currentSampleIndex); - faxState = FAX_DONE; - showState -> setText (QString ("Done")); - fax_displayImage (theImage -> getImage (), - 0, - faxColor == FAX_COLOR ? lastRow / 3 : lastRow); - if (savingRequested || autoContinue) { - fax_saveFile (theImage -> getImage (), autoContinue); - set_savingRequested (false); - } - return; - } -// -// otherwise: fall through - } - - if (faxState == FAX_PHASING) - addtoPhasing (sampleValue); - - if ((faxState == FAX_PHASING) || (faxState == FAX_IMAGING)) - if (lpm > 0) // just a precaution - addtoImage (sampleValue); -} - -void faxDecoder::initPhasing (void) { - faxState = FAX_PHASING; - lpm = 0; - f_lpm = 0; - lpmSum = 0; - currPhaseLength = 0; - whiteLength = 0; - whiteSide = currentValue >= 128 ? true : false; - phaseLines = 0; - showState -> setText (QString ("Phasing")); - theImage -> clear (); -} - -/* - * Note that +400 Hz is white and the - 400 Hz is black. - * Phasing lines consists of 2.5% white at the beginning, - * 95 % black and again 2.5 % white at the end (or inverted). - * In normal cases we try to count the length between the - * white-black transitions. If the line has a reasonable - * amount of white (4.8 % - 5.2 %) and the length fits in - * the range of 60 -- 360 lpm (plus some tolerance) it is considered - * a valid phasing line. Then the start of a line and the - * lpm is calculated - */ - -bool faxDecoder::weFoundaValidPhaseline (void) { -double bound1 = 0.048 * currPhaseLength; -double bound2 = 0.052 * currPhaseLength; - -// first check the ratio of white - if ((whiteLength < bound1) || (whiteLength > bound2)) - return false; -// then, the LPM should be not too large - if ((double)currPhaseLength < 0.15 * theRate) - return false; // too high LPM -// ... or too small - if ((double)currPhaseLength > 1.1 * theRate) - return false; -// -// everything OK, so - return true; -} - - -void faxDecoder::addtoPhasing (int16_t x) { - x = faxAverager -> filter (x); - currPhaseLength ++; - - if (isWhite (x)) - whiteLength ++; -// -// Is this a start of segment of white ? - if (!whiteSide && realWhite (x)) { - whiteSide = true; - return; - } - -// are we getting a switch to black, then start working - if (whiteSide && realBlack (x)) { - whiteSide = false; -// -// We look for - at least - 5 successive phaselines -// - if (weFoundaValidPhaseline ()) { - lpmSum += 60.0 * theRate / currPhaseLength; - currPhaseLength = 0; - whiteLength = 0; - phaseLines ++; - } - else // we might already be imaging - if (phaseLines >= 10) { - lpm = lpmSum / phaseLines; - f_lpm = lpmSum / phaseLines; - if (lpm == 0) // should not happen - lpm = 120; // just a default - samplesperLine = theRate * 60 / lpm; - currentSampleIndex = (int)(1.0 * 60.0 / lpm * theRate); -// currentSampleIndex = (int)(1.025 * 60.0 / lpm * theRate); - faxState = FAX_IMAGING; - showState -> setText (QString ("Image")); - double pos = fmod ((double)currentSampleIndex, - (double)theRate * 60 / lpm); -// pos /= theRate * 60.0 / lpm; - currentColumn = (int)(pos * numberofColums); - pixelValue = 0; - lastRow = 100; - phaseLines = 0; - currPhaseLength = 0; - whiteLength = 0; - } - else { // check for garbage, and clean up -// if (currPhaseLength > 5 * theRate) { - currPhaseLength = 0; - whiteLength = 0; - phaseLines = 0; - lpmSum = 0; - } - } -} -/* - * we add the demodulated value (x) to the - * current pixel, so first we find out - * the position of the current pixel - * - * Number of samples per line = - * theRate * 60.0 / lpm - * samplenumber in currentline = - * fmod (currentSampleIndex, theRate * 60.0 / lpm) - * position of sample in current column = - * samplenumber in current line / number of samples per Line * x - * - * - * What we really want is to distribute the value of the sample - * over the pixels it belongs to!!! - */ -void faxDecoder::addtoImage (int16_t x) { -int32_t samplenum = currentSampleIndex % samplesperLine; -float temp = (float)samplenum / samplesperLine; -int32_t columnforSample = floor (temp * numberofColums); -int32_t currentRow = (int32_t) - (currentSampleIndex * lpm / 60.0 / theRate); -// -// First check to see whether there is space to store the sample - if ((int32_t) (rawData. size ()) <= currentSampleIndex) - rawData. resize (rawData. size () + 1024 * 1024); - rawData [currentSampleIndex ++] = x; -// -// A sample may contribute to more than one pixel. E.g., for a samplerate -// of 8000, and an IOC of 576, there are 4.42 samples contributing. -// We therefore look for the partial contribution of the first -// and the last sample for a pixel - if (columnforSample == currentColumn) { // still dealing with the same pixel - if (temp * numberofColums > currentColumn) { // partial contribution - float part_0, part_1; - part_0 = temp * numberofColums - currentColumn; // for this pixel - // and part_1 is for the next one - part_1 = (1 - (temp * numberofColums - currentColumn)); - pixelValue += part_0 * x; - pixelSamples += part_0; - addSampletoImage (pixelValue / pixelSamples, - currentColumn, currentRow); - currentColumn ++; - pixelValue = part_1 * x; - pixelSamples = part_1; - return; - } - - pixelValue += x; - pixelSamples ++; - return; - } -// -// we expect here currentCol > currentColumn - if (pixelSamples > 0) // simple "assertion" - addSampletoImage (pixelValue / pixelSamples, - currentColumn, currentRow); - - currentColumn = columnforSample; - pixelValue = x; - pixelSamples = 1; -} - -void faxDecoder::addSampletoImage (float val, int32_t col, int32_t row) { -int32_t realRow = faxColor == FAX_COLOR ? row / 3 : row; - - theImage -> setPixel (col, realRow, val, - faxColor == FAX_COLOR ? row % 3 : 3); - if (lastRow != row) { - lineNumber -> display (row); - fax_displayImage (theImage -> getImage (), 0, row); - lastRow = row; - currentColumn = 0; - } -} -// -void faxDecoder::correctWidth (int16_t w) { - theImage -> correctWidth (w); -} -// -// This function is called from the GUI -void faxDecoder::fax_setIOC (const QString &s) { -int numberofSamples; - -faxParams *myfaxParameters = getFaxParams (s); - fax_IOC = myfaxParameters -> IOC; - numberofColums = M_PI * fax_IOC; - startSetter -> setValue (myfaxParameters -> aptStart); - stopSetter -> setValue (myfaxParameters -> aptStop); - lpmSetter -> setValue (myfaxParameters -> lpm); - lpm = myfaxParameters -> lpm; - samplesperLine = theRate * 60 / lpm; - numberofColums = M_PI * fax_IOC; - lastRow = 100; // will change - lastRow = 100; - pixelValue = 0; - currentSampleIndex = 0; - if (faxState != FAX_DONE) { - delete theImage; - theImage = new faxImage (numberofColums, lastRow); - rawData. resize (1024 * 1024); - theImage -> clear (); - fax_displayImage (theImage -> getImage ()); - return; - } -/* - * apply the changes to the current image - */ - numberofSamples = rawData. size (); - for (int i = 0; i < numberofSamples; i ++) { - addtoImage (rawData [i]); - } -} - -void faxDecoder::fax_setMode (const QString &s) { - faxMode = s == "am" ? FAX_AM : FAX_FM; - myDemodulator -> setMode (faxMode); -} - -void faxDecoder::fax_setDeviation (int m) { - deviation = m; - delete faxLowPass; - faxLowPass = new LowPassFIR (FILTER_DEFAULT, - deviation + 50, - theRate); - myDemodulator -> setDeviation (deviation); -} -/* - * fax_setSkip is called through a signal - * from the GUI - */ -void faxDecoder::fax_setSkip (void) { -double pos; - - set_autoContinue (false); - switch (faxState) { - case APTSTART: - faxState = FAX_PHASING; - lpm = 120; - lpmSum = 0; - currPhaseLength = 0; - phaseLines = 0; - whiteLength = 0; - whiteSide = currentValue >= 128 ? true : false; - showState -> setText (QString ("Phasing")); - currentSampleIndex = 0; - theImage -> clear (); - break; - - case FAX_PHASING: - faxState = FAX_IMAGING; - lpm = 120; - pos = fmod ((double)currentSampleIndex, - (double)theRate * 60 / lpm); - pos /= theRate * 60.0 / lpm; - currentColumn = (int) pos * numberofColums; - pixelValue = 0; - pixelSamples = 0; - lastRow = 100; - showState -> setText (QString ("Imaging")); - break; - - case FAX_IMAGING: - faxState = FAX_DONE; - rawData. resize (currentSampleIndex); - showState -> setText (QString ("Done")); - fax_displayImage (theImage -> getImage (), - 0, - faxColor == FAX_COLOR ? lastRow / 3 : lastRow); - if (savingRequested) { - fax_saveFile (theImage -> getImage (), autoContinue); - set_savingRequested (false); - } - break; - - default: // cannot happen - case FAX_DONE: // reset everything - faxState = APTSTART; - aptCount = 0; - apt_upCrossings = 0; - whiteSide = false; - pixelValue = 0; - pixelSamples = 0; - currentSampleIndex = 0; - theImage -> clear (); - rawData. resize (1024 * 1024); - fax_displayImage (theImage -> getImage (), - 0, - faxColor == FAX_COLOR ? lastRow / 3 : lastRow); - showState -> setText (QString ("APTSTART")); - set_savingRequested (false); - break; - } -} - -/* - * Called from both the GUI as well as from elsewhere in - * the program. - */ -void faxDecoder::fax_setLPM (int f) { - fax_setLPM ((float)f); -} - -void faxDecoder::fax_setLPM (float f) { -int64_t numberofSamples; - - if (faxState != FAX_DONE) // just ignore - return; - - lpm = f; - pixelValue = 0; - pixelSamples = 0; - currentSampleIndex = 0; - lastRow = 100; - currentColumn = 0; - numberofSamples = rawData. size (); - for (int i = 0; i < numberofSamples; i ++) { - addtoImage (rawData [i]); - } -} - -void faxDecoder::fax_setPhase (const QString &s) { - phaseInvers = s == "inverse"; -} - -void faxDecoder::fax_setColor (const QString &s) { - if (s == "BW") - faxColor = FAX_BLACKWHITE; - else - if (s == "COLOR") - faxColor = FAX_COLOR; - else - faxColor = FAX_GRAY; -} - -void faxDecoder::fax_setstartFreq (int m) { - aptStartFreq = m; -} - -void faxDecoder::fax_setstopFreq (int m) { - aptStopFreq = m; -} - -void faxDecoder::fax_setCarrier (int m) { - carrier = m; - setDetectorMarker (carrier); -} - -void faxDecoder::fax_setClicked (int x_coord, int y_coord) { -float lpma; -float adjustment; -QPoint x (x_coord, y_coord); - - if (pointNeeded) { - pointNeeded = false; - slant2 = x; - lpma = ((float)(slant2. x() - slant1. x())) / (slant1. y () - slant2. y ()); - lpma = lpma / theImage -> getCols (); - adjustment = 1.0 + (faxColor != FAX_BLACKWHITE ? lpma / 3 : lpma); - fprintf (stderr, "adjusting lpm with %f\n", adjustment); - fax_setLPM (adjustment); - slantText -> setText(QString ("")); - return; - } - - pointNeeded = true; - slant1 = x; - slantText -> setText (QString ("mark a second point")); -} - -void faxDecoder::fax_displayImage (QImage image) { -QLabel *imageLabel = new QLabel; - - imageLabel -> setPixmap (QPixmap::fromImage (image)); - faxContainer -> setWidget (imageLabel); - imageLabel -> show (); -} - -void faxDecoder::fax_displayImage (QImage image, int x, int y) { -QLabel *imageLabel = new QLabel; - - imageLabel -> setPixmap (QPixmap::fromImage (image)); - faxContainer -> setWidget (imageLabel); - imageLabel -> show (); - faxContainer -> ensureVisible (x, y); -} - -void faxDecoder::fax_saveFile (QImage image, bool getName) { -QFile outFile; -QString file; - - if (getName) - file = nameGenerator -> newFileName (); - else - file = QFileDialog::getSaveFileName (myFrame, - tr ("save file as .."), - QDir::homePath (), - tr ("Images (*.jpg)")); - - outFile. setFileName (file); - if (!outFile. open (QIODevice::WriteOnly)) { - qDebug () << "Cannot open" << file; - return; - } - - image. save (&outFile); - outFile. close (); -} - -void faxDecoder::fax_setsavingonDone (void) { - set_savingRequested (!savingRequested); -} - -void faxDecoder::set_savingRequested (bool b) { - savingRequested = b; - if (b) - saveButton -> setText ("will save"); - else - saveButton -> setText ("press for save"); -} - -void faxDecoder::fax_setautoContinue (void) { - set_autoContinue (!autoContinue); -} - -void faxDecoder::set_autoContinue (bool b) { - autoContinue = b; - if (b) - autoContinueButton -> setText ("will continue"); - else - autoContinueButton -> setText ("press for autoContinue"); -} - -faxParams *faxDecoder::getFaxParams (QString s) { -int16_t i; - - for (i = 0; _faxParams [i].Name != NULL; i ++) - if (s == _faxParams [i]. Name) - return &_faxParams [i]; - return NULL; -} - diff --git a/decoders/fax-decoder-old/fax-decoder.h b/decoders/fax-decoder-old/fax-decoder.h deleted file mode 100644 index dc931cf..0000000 --- a/decoders/fax-decoder-old/fax-decoder.h +++ /dev/null @@ -1,168 +0,0 @@ -# -/* - * Copyright (C) 2008, 2009, 2010 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Computing - * - * This file is part of the SDR-J. - * - * SDR-J 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; either version 2 of the License, or - * (at your option) any later version. - * - * SDR-J 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with SDR-J; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __FAX_DECODER__ -#define __FAX_DECODER__ - -#include -#include -#include -#include -#include -#include "utilities.h" -#include "ui_fax-decoder.h" -#include "radio-constants.h" -#include "virtual-decoder.h" -#include "fax-scroller.h" -#include "fir-filters.h" -#include "fax-params.h" -#include "shifter.h" -#include "ringbuffer.h" - -class RadioInterface; -class common_fft; -class faxDemodulator; -class faxImage; -class faxFilenames; - -/* - * states: - * we look at the bits - */ -#define APTSTART 0001 -#define FAX_PHASING 0002 -#define FAX_IMAGING 0004 -#define FAX_DONE 0010 - -class faxDecoder: public virtualDecoder, public Ui_fax_decoder { -Q_OBJECT -public: - faxDecoder (int32_t, - RingBuffer> *, - QSettings *); - ~faxDecoder (); - void process (std::complex); - - enum Teint { - FAX_COLOR = 1, - FAX_GRAY = 2, - FAX_BLACKWHITE = 3 - }; - - enum Mode { - FAX_AM = 100, - FAX_FM = 101 - }; - -private: - QSettings *faxSettings; - int32_t theRate; - QFrame *myFrame; - void setup_faxDecoder (QSettings *); - void initPhasing (void); - common_fft *myfft; - std::complex *fftVector; - int32_t getFreq (std::complex *); - faxParams *getFaxParams (QString); - shifter localMixer; -private slots: - void reset (void); - void fax_setIOC (const QString &); - void fax_setMode (const QString &); - void fax_setPhase (const QString &); - void fax_setColor (const QString &); - void fax_setDeviation (int); - void fax_setSkip (void); - void fax_setLPM (int); - void fax_setstartFreq (int); - void fax_setstopFreq (int); - void fax_setCarrier (int); - void fax_setsavingonDone (void); - void fax_setClicked (int, int); - void fax_setautoContinue (void); -private: - void correctWidth (int16_t); - void addtoPhasing (int16_t); - void addtoImage (int16_t); - void endReception (void); - bool weFoundaValidPhaseline (void); - void correctLPM (float); - void fax_saveFile (QImage, bool); - void fax_displayImage (QImage, int, int); - void fax_displayImage (QImage); - void fax_setLPM (float); - - faxFilenames *nameGenerator; - faxScroller *faxContainer; - - RingBuffer> *audioOut; - int faxCycleCounter; - bool savingRequested; - void set_savingRequested (bool); - bool autoContinue; - void set_autoContinue (bool); - void addSampletoImage (float, int32_t, int32_t); - int32_t delayCounter; - faxImage *theImage; - faxDemodulator *myDemodulator; - LowPassFIR *faxLowPass; - average *faxAverager; - QByteArray rawData; - uint8_t faxState; - int32_t currentSampleIndex; - std::complex fax_oldz; - int16_t fax_IOC; - float lpm; - float f_lpm; - int16_t deviation; - int16_t aptCount; - int16_t apt_upCrossings; - int16_t aptStartFreq; - int16_t aptStopFreq; - int16_t txLPM; - bool phaseInvers; - uint8_t faxColor; - double lpmSum; - bool whiteSide; - int16_t currPhaseLength; - int16_t whiteLength; - int16_t phaseLines; - int16_t noPhasingLines; - int16_t carrier; - uint8_t faxMode; - int32_t samplesperLine; - int16_t numberofColums; - int16_t currentColumn; - int16_t lastRow; - int32_t pixelValue; - float pixelSamples; - int16_t currentValue; - bool savingFlag; -// for adjusting, we need - QPoint slant1; - QPoint slant2; - bool pointNeeded; -}; - -#endif - diff --git a/decoders/fax-decoder-old/fax-decoder.pro b/decoders/fax-decoder-old/fax-decoder.pro deleted file mode 100644 index ac13aa3..0000000 --- a/decoders/fax-decoder-old/fax-decoder.pro +++ /dev/null @@ -1,54 +0,0 @@ -# -TEMPLATE = lib -CONFIG += plugin -QT += core gui widgets - -INCLUDEPATH += . \ - ../ ../.. \ - ../decoder-utils \ - ../../../includes \ - ../../../includes/filters \ - ../../../includes/various - -HEADERS = ../decoder-interface.h \ - ./fax-decoder.h \ - ./fax-demodulator.h \ - ./fax-image.h \ - ./fax-scroller.h \ - ./fax-filenames.h \ - ../../../includes/filters/iir-filters.h \ - ../../../includes/filters/fir-filters.h \ - ../../../includes/various/oscillator.h \ - ../../../includes/various/utilities.h \ - ../../../includes/various/fft.h \ - ../../../includes/swradio-constants.h -SOURCES = ./fax-decoder.cpp \ - ./fax-demodulator.cpp \ - ./fax-image.cpp \ - ./fax-scroller.cpp \ - ./fax-filenames.cpp \ - ../../../src/filters/iir-filters.cpp \ - ../../../src/filters/fir-filters.cpp \ - ../../../src/various/oscillator.cpp \ - ../../../src/various/utilities.cpp \ - ../../../src/various/fft.cpp \ - ./main.cpp -TARGET = $$qtLibraryTarget(faxdecoder) -FORMS += widget.ui - -win32 { -DESTDIR = ../../../../../../windows-bin/decoder-plugins -# includes in mingw differ from the includes in fedora linux -INCLUDEPATH += /usr/i686-w64-mingw32/sys-root/mingw/include -INCLUDEPATH += /usr/i686-w64-mingw32/sys-root/mingw/include/qt5/qwt -LIBS += -lfftw3f -LIBS += -lqwt-qt5 -LIBS += -lole32 -LIBS += -lwinmm -} - -unix { -DESTDIR = ../../../../../linux-bin/decoder-plugins -INCLUDEPATH += /usr/include/qt5/qwt -} - diff --git a/decoders/fax-decoder-old/fax-decoder.ui b/decoders/fax-decoder-old/fax-decoder.ui deleted file mode 100644 index dc65ae1..0000000 --- a/decoders/fax-decoder-old/fax-decoder.ui +++ /dev/null @@ -1,397 +0,0 @@ - - - fax_decoder - - - - 0 - 0 - 574 - 155 - - - - fax-decoder - - - - - 0 - 0 - 571 - 141 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - 440 - 110 - 121 - 21 - - - - - 14 - - - - fax decoder - - - - - - 450 - 40 - 101 - 31 - - - - <html><head/><body><p>Current state of operation.</p></body></html> - - - QFrame::Box - - - - - - - - - 490 - 80 - 64 - 23 - - - - 0 - - - QLCDNumber::Flat - - - - - - 410 - 80 - 64 - 23 - - - - 0 - - - QLCDNumber::Flat - - - - - - 270 - 110 - 151 - 20 - - - - - - - - - - 340 - 10 - 101 - 29 - - - - <html><head/><body><p>Black and white or color.</p></body></html> - - - - BW - - - - - GRAY - - - - - COLOR - - - - - - - 450 - 10 - 101 - 31 - - - - <html><head/><body><p>Skip the current operation state and go the next one. Comes in handy when there is signal, but beyond the initial synchronization.</p></body></html> - - - skip Mode - - - - - - 10 - 90 - 121 - 29 - - - - <html><head/><body><p>FAX mode, implies some settings.</p></body></html> - - - - Wefax576 - - - - - Wefax288 - - - - - HamColor - - - - - Ham288b - - - - - Color240 - - - - - FAX480 - - - - - - - 160 - 70 - 141 - 41 - - - - - FM - - - - - AM - - - - - - - 10 - 10 - 91 - 21 - - - - <html><head/><body><p>Start frequency, normally 300.</p></body></html> - - - 1000 - - - 300 - - - - - - 10 - 30 - 91 - 21 - - - - <html><head/><body><p>Stop frequency of a transmission. Normally 450.</p></body></html> - - - 1000 - - - 450 - - - - - - 120 - 10 - 121 - 21 - - - - <html><head/><body><p>Offset of the central carrier of the signal. In mechanical FAX machines this is normally 1900, we choose for a smaller value.</p></body></html> - - - 2500 - - - 1000 - - - - - - 10 - 50 - 91 - 21 - - - - <html><head/><body><p>Deviation of the central signal frequency.</p></body></html> - - - 1000 - - - 400 - - - - - - 460 - 130 - 151 - 21 - - - - - - - - - - 10 - 70 - 91 - 21 - - - - <html><head/><body><p>Lines per minute.</p></body></html> - - - 200 - - - 120 - - - - - - 240 - 10 - 101 - 29 - - - - <html><head/><body><p>Normal or inverse (i.e.back and white).</p></body></html> - - - - phase - - - - - inverse - - - - - - - 300 - 70 - 97 - 41 - - - - reset - - - - - - 160 - 40 - 131 - 31 - - - - <html><head/><body><p>Save the picture when the end is reached. A menu will apear at the end with which a file(name) can be selected.</p></body></html> - - - save on Done - - - - - - 290 - 40 - 151 - 31 - - - - continue - - - - - - - diff --git a/decoders/fax-decoder-old/fax-demodulator.cpp b/decoders/fax-decoder-old/fax-demodulator.cpp deleted file mode 100644 index 6b31458..0000000 --- a/decoders/fax-decoder-old/fax-demodulator.cpp +++ /dev/null @@ -1,62 +0,0 @@ -# -/* - * Copyright (C) 2011, 2012, 2013 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair programming - * - * This file is part of the SDR-J. - * - * SDR-J 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; either version 2 of the License, or - * (at your option) any later version. - * - * SDR-J 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with SDR-J; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "fax-demodulator.h" -#include "utilities.h" -#include "fax-decoder.h" - - faxDemodulator::faxDemodulator (int8_t mode, - int32_t rate, - int32_t dev) { - - this -> mode = mode; - this -> Rate = rate; - deviation = dev; - prevSample = 0; -} - - faxDemodulator::~faxDemodulator () { -} - -void faxDemodulator::setMode (int8_t m) { - mode = m; -} - -void faxDemodulator::setDeviation (int16_t dev) { - deviation = dev; -} -// -// demodulate returns a value in the range -127 .. 127 -int16_t faxDemodulator::demodulate (std::complex z) { -float res; - - z = cdiv (z, abs (z)); - if (mode == faxDecoder::FAX_AM) - return abs (z) * 255.0; - - res = arg (conj (prevSample) * z) / (2 * M_PI) * Rate; - res = clamp (res, - deviation, + deviation); - prevSample = z; - return (int16_t)(res / deviation * 128 + 127); -} - diff --git a/decoders/fax-decoder-old/fax-demodulator.h b/decoders/fax-decoder-old/fax-demodulator.h deleted file mode 100644 index ef671bd..0000000 --- a/decoders/fax-decoder-old/fax-demodulator.h +++ /dev/null @@ -1,46 +0,0 @@ -# -/* - * Copyright (C) 2011, 2012, 2013 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Computing - * - * This file is part of the SDR-J. - * Many of the ideas as implemented in SDR-J are derived from - * other work, made available through the GNU general Public License. - * All copyrights of the original authors are recognized. - * - * SDR-J 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; either version 2 of the License, or - * (at your option) any later version. - * - * SDR-J 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with SDR-J; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __FAX_DEMODULATOR__ -#define __FAX_DEMODULATOR__ - -#include "radio-constants.h" - -class faxDemodulator { -public: - faxDemodulator (int8_t, int32_t, int32_t); - ~faxDemodulator (void); - int16_t demodulate (std::complex); - void setMode (int8_t); - void setDeviation (int16_t); -private: - int8_t mode; - int32_t Rate; - int32_t deviation; - std::complex prevSample; -}; - -#endif - diff --git a/decoders/fax-decoder-old/fax-filenames.cpp b/decoders/fax-decoder-old/fax-filenames.cpp deleted file mode 100644 index 87e2123..0000000 --- a/decoders/fax-decoder-old/fax-filenames.cpp +++ /dev/null @@ -1,48 +0,0 @@ -# -/* - * - * Copyright (C) 2011, 2012, 2013 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Computing - * - * This file is part of the SDR-J. - * Many of the ideas as implemented in SDR-J are derived from - * other work, made available through the GNU general Public License. - * All copyrights of the original authors are recognized. - * - * SDR-J 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; either version 2 of the License, or - * (at your option) any later version. - * - * SDR-J 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with SDR-J; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "fax-filenames.h" -#include -#include - - faxFilenames::faxFilenames (int16_t n) { - base = "sdr-j-fax-"; - base. append (QDate::currentDate (). toString ()); - counter = n; -} - - faxFilenames::~faxFilenames (void) { -} - - QString faxFilenames::newFileName (void) { -QString temp = base; - temp. append (QString::number (counter ++)); - temp. append (QString(".png")); - return temp; -} - - diff --git a/decoders/fax-decoder-old/fax-filenames.h b/decoders/fax-decoder-old/fax-filenames.h deleted file mode 100644 index 641de8f..0000000 --- a/decoders/fax-decoder-old/fax-filenames.h +++ /dev/null @@ -1,40 +0,0 @@ -# -/* - * Copyright (C) 2011, 2012, 2013 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Computing - * - * This file is part of the SDR-J. - * - * SDR-J 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; either version 2 of the License, or - * (at your option) any later version. - * - * SDR-J 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with SDR-J; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __FAX_FILENAMES__ -#define __FAX_FILENAMES__ - -#include -#include "radio-constants.h" - -class faxFilenames { -public: - faxFilenames (int16_t n); - ~faxFilenames (void); - QString newFileName (void); -private: - QString base; - int16_t counter; -}; - -#endif - diff --git a/decoders/fax-decoder-old/fax-image.cpp b/decoders/fax-decoder-old/fax-image.cpp deleted file mode 100644 index e4fe2d8..0000000 --- a/decoders/fax-decoder-old/fax-image.cpp +++ /dev/null @@ -1,116 +0,0 @@ -# -/* - * Copyright (C) 2011, 2012, 2013 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Computing - * - * This file is part of the SDR-J. - * Many of the ideas as implemented in SDR-J are derived from - * other work, made available through the GNU general Public License. - * All copyrights of the original authors are recognized. - * - * SDR-J 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; either version 2 of the License, or - * (at your option) any later version. - * - * SDR-J 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with SDR-J; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "fax-image.h" - - faxImage::faxImage (int w, int h, QWidget *p) { -int i, j; - - (void)p; - image = QImage (w, h, QImage::Format_RGB32); - for (i = 0; i < w; i ++) - for (j = 0; j < h; j ++) - image. setPixel (QPoint(i, j), qRgb (i % 256, i % 256, j % 256)); -} - - faxImage::~faxImage () { -} - -void faxImage::clear (void) { -int i, j; - - for (i = 0; i < image. width (); i ++) - for (j = 0; j < image. height (); j ++) - image. setPixel (QPoint(i, j), qRgb (i % 256, i % 256, j % 256)); -} - -QImage faxImage::getImage (void) { -// return image. scaled (QSize (576, 300), Qt::IgnoreAspectRatio); - return image; -} - -bool faxImage::setPixel (int col, int row, int value, int rgbg) { -QRgb oldColor; -QRgb color; - - if (col >= image. width ()) - return false; - if (row >= image. height () + 1) - return false; - - if (row >= image. height ()) - resizeHeight (50); - - oldColor = image. pixel (col, row); - switch (rgbg) { - case 0: - color = qRgb (value, qGreen (oldColor), qBlue (oldColor)); - break; - - case 1: - color = qRgb (qRed (oldColor), value, qBlue (oldColor)); - break; - - case 2: - color = qRgb (qRed (oldColor), qGreen (oldColor), value); - break; - - default: - color = qRgb (value, value, value); - break; - } - - image. setPixel (QPoint(col, row), (uint)color); - - return true; -} - -void faxImage::newSize (int a, int b, int c, int d) { - (void)a; - (void)b; - (void)c; - (void)d; -} - -void faxImage::resizeHeight (int h) { -int imageW = image. width (); -int imageH = image. height (); - image = image. copy (0, 0, imageW, imageH + h); - -} - -int faxImage::getCols () { - return image. width (); -} - -int faxImage::getHeight () { - return image. height (); -} - -void faxImage::correctWidth (int w) { - image = QImage (w, image.height (), QImage::Format_RGB32); -} - diff --git a/decoders/fax-decoder-old/fax-image.h b/decoders/fax-decoder-old/fax-image.h deleted file mode 100644 index a02a517..0000000 --- a/decoders/fax-decoder-old/fax-image.h +++ /dev/null @@ -1,58 +0,0 @@ -# -/* - * - * Copyright (C) 2011, 2012, 2013 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Computing - * - * The fax implementation is a rewrite of hamfax - * Copyright (c) 2001, 2002 - * Christof Schmitt, DH1CS - * - * This file is part of the SDR-J. - * Many of the ideas as implemented in SDR-J are derived from - * other work, made available through the GNU general Public License. - * All copyrights of the original authors are recognized. - * - * SDR-J 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; either version 2 of the License, or - * (at your option) any later version. - * - * SDR-J 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with JSDR; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __FAXIMAGE__ -#define __FAXIMAGE__ - -#include "radio-constants.h" -#include -#include -#include - -class faxImage { - -public: - faxImage (int, int, QWidget *parent = NULL); - ~faxImage (void); - void newSize (int, int, int, int); - bool setPixel (int, int, int, int); - int getCols (void); - int getHeight (void); - QImage getImage (); - void correctWidth (int); - void clear (void); -private: - void resizeHeight (int); - QImage image; -}; - -#endif - diff --git a/decoders/fax-decoder-old/fax-params.h b/decoders/fax-decoder-old/fax-params.h deleted file mode 100644 index 8552b05..0000000 --- a/decoders/fax-decoder-old/fax-params.h +++ /dev/null @@ -1,27 +0,0 @@ -# -// This file is to be included to get/set the parameters -// - -#ifndef __FAX_PARAMS -#define __FAX_PARAMS - -enum FaxModes { - Wefax576, - Wefax288, - HamColor, - Color240, - FAX480 -}; - -typedef struct fax_params { - const char *Name; - int16_t IOC; - int16_t aptStart; - int16_t aptStop; - bool color; - int16_t lpm; -} faxParams; - - -#endif - diff --git a/decoders/fax-decoder-old/fax-scroller.cpp b/decoders/fax-decoder-old/fax-scroller.cpp deleted file mode 100644 index dbe09ea..0000000 --- a/decoders/fax-decoder-old/fax-scroller.cpp +++ /dev/null @@ -1,43 +0,0 @@ -# -/* - * - * Copyright (C) 2008, 2009, 2010 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Computing - * - * This file is part of the SDR-J. - * Many of the ideas as implemented in SDR-J are derived from - * other work, made available through the GNU general Public License. - * All copyrights of the original authors are recognized. - * - * SDR-J 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; either version 2 of the License, or - * (at your option) any later version. - * - * SDR-J 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with SDR-J; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "fax-scroller.h" -#include -#include - - faxScroller::faxScroller (QWidget *parent): QScrollArea (parent) { -} - - faxScroller::~faxScroller (void) { -} - -void faxScroller::mousePressEvent (QMouseEvent *m) { -QPoint pos = widget () -> mapFromParent (m -> pos ()); - - emit fax_Clicked ((int)(pos. x()), (int)(pos. y())); -} - diff --git a/decoders/fax-decoder-old/fax-scroller.h b/decoders/fax-decoder-old/fax-scroller.h deleted file mode 100644 index 91034b8..0000000 --- a/decoders/fax-decoder-old/fax-scroller.h +++ /dev/null @@ -1,48 +0,0 @@ -# -/* - * Copyright (C) 2008, 2009, 2010 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Computing - * - * This file is part of the SDR-J. - * - * SDR-J 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; either version 2 of the License, or - * (at your option) any later version. - * - * SDR-J 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 for more details. - * - * You should have received a copy of the GNU General Public License - * along with SDR-J; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __FAX_SCROLLER__ -#define __FAX_SCROLLER__ - -#include -#include -#include -#include -#include -// -// In the designer we promoted the QScrollarea to this -// nice class faxScroller, such that we are able to attach -// the mouse events. -class faxScroller: public QScrollArea { -Q_OBJECT -public: - faxScroller (QWidget *parent = 0); - -virtual ~faxScroller (void); -signals: - void fax_Clicked (int, int); -private: -virtual void mousePressEvent (QMouseEvent *); -}; -#endif - diff --git a/decoders/fax-decoder-old/main.cpp b/decoders/fax-decoder-old/main.cpp deleted file mode 100644 index 570c592..0000000 --- a/decoders/fax-decoder-old/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ - -#include "fax-decoder.h" - -int main (int argc, char *argv []) { - return 0; -} - diff --git a/decoders/ft8-decoder/ft8-decoder.cpp b/decoders/ft8-decoder/ft8-decoder.cpp index 97d8706..a03b80d 100644 --- a/decoders/ft8-decoder/ft8-decoder.cpp +++ b/decoders/ft8-decoder/ft8-decoder.cpp @@ -93,7 +93,10 @@ this, SLOT (handle_identityButton ())); connect (pskReporterButton, SIGNAL (clicked ()), this, SLOT (handle_pskReporterButton ())); - + connect (presetFrequencies, SIGNAL (activated (const QString &)), + this, SLOT (handle_presetFrequencies (const QString &))); + connect (this, SIGNAL (setFrequency (quint64)), + mr, SLOT (setFrequency (quint64))); show_pskStatus (false); teller = 0; } @@ -126,21 +129,23 @@ void ft8_Decoder::process (std::complex z) { inBuffer [inPointer ++] = z; if (inPointer < toneLength / FRAMES_PER_TONE) return; + + teller += inPointer; inPointer = 0; - if (theWriter != nullptr) { - static int counter = 0; - if (++counter >= 100) { - counter = 0; - theWriter -> sendMessages (); - } + + locker. lock (); + if ((theWriter != nullptr) && (teller > inputRate * 30)) { + teller = 0; + theWriter -> sendMessages (); } + locker. unlock (); int content = (FRAMES_PER_TONE - 1) * toneLength / FRAMES_PER_TONE; int newAmount = toneLength / FRAMES_PER_TONE; // // shift the inputBuffer to left memmove (inputBuffer, &inputBuffer [newAmount], - content * sizeof (std::complex)); + content * sizeof (std::complex)); // // copy the data that is read, into the buffer memcpy (&inputBuffer [content], inBuffer, @@ -427,10 +432,12 @@ bool ft8_Decoder::pskReporterReady () { } void ft8_Decoder::handle_pskReporterButton () { + locker. lock (); if (theWriter != nullptr) { delete theWriter; pskReady = false; theWriter = nullptr; + locker. unlock (); show_pskStatus (false); return; } @@ -441,6 +448,7 @@ void ft8_Decoder::handle_pskReporterButton () { } catch (int e) { pskReady = false; } + locker. unlock (); show_pskStatus (pskReady); } @@ -448,10 +456,12 @@ void ft8_Decoder::addMessage (const QString &call, const QString &grid, int frequency, int snr) { + locker. lock (); if (theWriter != nullptr) theWriter -> addMessage (call. toStdString (), grid. toStdString (), frequency, snr); + locker. unlock (); } void ft8_Decoder::handle_identityButton () { @@ -469,3 +479,8 @@ void ft8_Decoder::show_pskStatus (bool b) { void ft8_Decoder::print_statistics () { } +void ft8_Decoder::handle_presetFrequencies (const QString &freq) { +int selectedFrequency = freq. toInt (); + setFrequency (selectedFrequency * 1000); +} + diff --git a/decoders/ft8-decoder/ft8-decoder.h b/decoders/ft8-decoder/ft8-decoder.h index aebdf34..77643b6 100644 --- a/decoders/ft8-decoder/ft8-decoder.h +++ b/decoders/ft8-decoder/ft8-decoder.h @@ -29,6 +29,7 @@ #include #include #include +#include #include "virtual-decoder.h" #include "ui_ft8-decoder.h" #include "kiss_fft.h" @@ -67,6 +68,7 @@ Q_OBJECT int32_t outputRate; int32_t samplesperSymbol; bool pskReady; + std::mutex locker; std::atomic filePointer; void peakFinder (float *V, int begin, int end, std::vector &cache); @@ -117,6 +119,9 @@ private slots: void handle_filesaveButton (); void handle_identityButton (); void handle_pskReporterButton (); + void handle_presetFrequencies (const QString &); +signals: + void setFrequency (quint64); }; #endif diff --git a/decoders/ft8-decoder/ft8-decoder.ui b/decoders/ft8-decoder/ft8-decoder.ui index 3b090d2..437b855 100644 --- a/decoders/ft8-decoder/ft8-decoder.ui +++ b/decoders/ft8-decoder/ft8-decoder.ui @@ -87,6 +87,135 @@ + + + + + 1840 + + + + + 3753 + + + + + 5357 + + + + + 7056 + + + + + 7071 + + + + + 7074 + + + + + 10130 + + + + + 10132 + + + + + 10136 + + + + + 14074 + + + + + 14090 + + + + + 18100 + + + + + 18104 + + + + + 21704 + + + + + 21091 + + + + + 24915 + + + + + 28074 + + + + + 50310 + + + + + 50313 + + + + + 50323 + + + + + 50328 + + + + + 70100 + + + + + 144174 + + + + + 222065 + + + + + 432065 + + + + diff --git a/decoders/ft8-decoder/ft8-processor.cpp b/decoders/ft8-decoder/ft8-processor.cpp index 7b79b5c..2a5a8ab 100644 --- a/decoders/ft8-decoder/ft8-processor.cpp +++ b/decoders/ft8-decoder/ft8-processor.cpp @@ -179,7 +179,6 @@ int errors; int freq = theBuffer [blockToRead]. frequency + theDecoder -> tunedFrequency (); addMessage (callIdent, locator, freq, snr); } - } } } diff --git a/decoders/ft8-decoder/pack-handler.cpp b/decoders/ft8-decoder/pack-handler.cpp index ee41adb..4ae8d39 100644 --- a/decoders/ft8-decoder/pack-handler.cpp +++ b/decoders/ft8-decoder/pack-handler.cpp @@ -123,6 +123,7 @@ const char *theTable = nullptr; default: return '?'; } + if (theTable == nullptr) return '_'; // cannot happen else @@ -517,7 +518,6 @@ QString packHandler::handle_type04 (const uint8_t *m_in) { QString packHandler::handle_type05 (const uint8_t *m_in) { uint8_t sym = getBits (m_in, 0, 3); int index; -int teller = 0; QString result; result. push_back (table_2 [sym]); @@ -584,6 +584,7 @@ QStringList result; uint8_t i3 = getBits (m_in, 74, 3); switch (i3) { case 0: // dispatch further + return extract_call_type_0 (m_in); return result; case 1: // c28 r1 c28 r1 R1 g15 @@ -591,6 +592,7 @@ QStringList result; return extract_call_type_1 (m_in, i3); case 3: // t1 c28 c28 R1 r3 s13 + return extract_call_type_3 (m_in); return result; case 4: // h12 c58 h1 r2 c1 @@ -605,6 +607,55 @@ QStringList result; return result; // cannot happen } + +bool test_cq (uint32_t k) { + if (k == 2) + return true; + if ((k >= CQ_3DIGITS) && (k <= CQ_3DIGITS_E)) + return true; + if ((k >= CQ_1LETTER) && (k <= CQ_1LETTER_E)) + return true; + if ((k >= CQ_2LETTER) && (k <= CQ_2LETTER_E)) + return true; + if ((k >= CQ_3LETTER) && (k <= CQ_3LETTER_E)) + return true; + if ((k >= CQ_4LETTER) && (k <= CQ_4LETTER_E)) + return true; + return false; +} + +QStringList packHandler::extract_call_type_0 (const uint8_t *m_in) { +uint32_t c28a; +uint32_t c28b; +QStringList result; +QString call; + + uint8_t i3 = getBits (m_in, 74, 3); + if ((i3 == 0) ||(i3 == 6)) + return result; + c28a = getLBits (m_in, 0, 28); // callsign + c28b = getLBits (m_in, 29, 28); // callsign + if (c28a > HASH_END) { // normal call + for (int i = 0; i < gehad. size (); i ++) + if (gehad. at (i) == c28a) + return result; + call = getCallsign (c28a); + gehad. push_back (c28a); + result << call; + return result; + } + if ((c28a < CQ_4LETTER_E) && (test_cq (c28a))) { + for (int i = 0; i < gehad. size (); i ++) + if (gehad. at (i) == c28b) + return result; + call = getCallsign (c28b); + gehad. push_back (c28b); + result << call; + return result; + } + return result; +} + // // for now, we assume that interest is in the caller QStringList packHandler::extract_call_type_1 (const uint8_t *m_in, int type) { @@ -622,7 +673,7 @@ QStringList result; g15 = getBits (m_in, 59, 15); // g15, potential grid // Check for special tokens DE, QRZ, CQ, CQ_nnn, CQ_xxxx - if (c28a == 2) { // It is a cq + if ((c28a < HASH_END) && (test_cq (c28a))) { if (R1 > 0) return result; for (int i = 0; i < gehad. size (); i ++) @@ -681,3 +732,30 @@ QStringList result; } +// type 3 format: t1 c28 c28 R1 r3 s13 +QStringList packHandler::extract_call_type_3 (const uint8_t *m_in) { +uint8_t t1 = getBits (m_in, 0, 1); +uint32_t c28a = getLBits (m_in, 1, 28); // callsign +uint32_t c28b = getLBits (m_in, 30, 28); // callsign +QStringList result; +QString call; +// Check for special tokens DE, QRZ, CQ, CQ_nnn, CQ_xxxx + if (c28a < CQ_4LETTER_E) { // It is a cq + for (int i = 0; i < gehad. size (); i ++) + if (gehad. at (i) == c28b) + return result; + call = getCallsign (c28b); + gehad. push_back (c28b); + result << call; + return result; + } + if (c28a > HASH_END) { // seems a regular call + for (int i = 0; i < gehad. size (); i ++) + if (gehad. at (i) == c28a) + return result; + call = getCallsign (c28a); + result << call; + return result; + } + return result; +} diff --git a/decoders/ft8-decoder/pack-handler.h b/decoders/ft8-decoder/pack-handler.h index 3355c28..3a96d45 100644 --- a/decoders/ft8-decoder/pack-handler.h +++ b/decoders/ft8-decoder/pack-handler.h @@ -62,7 +62,10 @@ Q_OBJECT void pack_bits (const uint8_t bit_array [], int num_bits, uint8_t packed []); QString getCallsign (const uint32_t n28); + QStringList extract_call_type_0 (const uint8_t *m_in); QStringList extract_call_type_1 (const uint8_t *m_in, int type); + QStringList extract_call_type_3 (const uint8_t *m_in); + std::vector gehad; signals: diff --git a/decoders/ft8-decoder/psk-writer.cpp b/decoders/ft8-decoder/psk-writer.cpp index 3a8935c..f7d1b11 100644 --- a/decoders/ft8-decoder/psk-writer.cpp +++ b/decoders/ft8-decoder/psk-writer.cpp @@ -77,10 +77,17 @@ struct hostent *host; homeCall. c_str (), homeGrid. c_str (), antenna. c_str ()); -#ifndef __MINGW32__ - if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { +#ifdef __MINGW32__ +WSADATA wsaData; + + int res = WSAStartup (MAKEWORD (2, 2), &wsaData); + if (res != NO_ERROR) { + fprintf (stderr, "WSAstartup failed\n"); + throw (21); + } + if ((sock = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { #else - if ((sock = socket (PF_INET, SOCK_DGRAM, 0)) < 0) { + if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) < 0) { #endif fprintf (stderr, "Cannot open socket %d.\n", errno); throw (22); diff --git a/mocinclude.opt b/mocinclude.opt deleted file mode 100644 index 8bc7d5d..0000000 --- a/mocinclude.opt +++ /dev/null @@ -1,53 +0,0 @@ --I/usr/i686-w64-mingw32/sys-root/mingw/share/qt5/mkspecs/mingw-w64-g++ --I/usr/shared/systems/swradio-8 --I/usr/shared/systems/swradio-8 --I/usr/shared/systems/swradio-8/decimators --I/usr/shared/systems/swradio-8/filters --I/usr/shared/systems/swradio-8/various --I/usr/shared/systems/swradio-8/output --I/usr/shared/systems/swradio-8/scopes-qwt6 --I/usr/shared/systems/swradio-8/devices --I/usr/shared/systems/swradio-8/devices/filereader --I/usr/shared/systems/swradio-8/decoders --I/usr/i686-w64-mingw32/sys-root/mingw/include --I/usr/i686-w64-mingw32/sys-root/mingw/include/eigen3 --I/usr/i686-w64-mingw32/sys-root/mingw/include/qt5/qwt --I/usr/local/include --I/usr/shared/systems/swradio-8/C:\msys32\mingw32\include\qwt --I/usr/shared/systems/swradio-8/devices/sdrplay-handler --I/usr/shared/systems/swradio-8/devices/sdrplay-handler-v3 --I/usr/shared/systems/swradio-8/devices/sdrplay-handler-v3/include-v3 --I/usr/shared/systems/swradio-8/devices/hackrf-handler --I/usr/shared/systems/swradio-8/devices/rtlsdr-handler --I/usr/shared/systems/swradio-8/decoders/am-decoder --I/usr/shared/systems/swradio-8/decoders/ssb-decoder --I/usr/shared/systems/swradio-8/decoders/cw-decoder --I/usr/shared/systems/swradio-8/decoders/amtor-decoder --I/usr/shared/systems/swradio-8/decoders/psk-decoder --I/usr/shared/systems/swradio-8/decoders/ft8-decoder-win --I/usr/shared/systems/swradio-8/decoders/ft8-decoder-win/fft --I/usr/shared/systems/swradio-8/decoders/rtty-decoder --I/usr/shared/systems/swradio-8/decoders/fax-decoder --I/usr/shared/systems/swradio-8/fdk-aac --I/usr/shared/systems/swradio-8/decoders/drm-decoder --I/usr/shared/systems/swradio-8/decoders/drm-decoder --I/usr/shared/systems/swradio-8/decoders/drm-decoder/fac --I/usr/shared/systems/swradio-8/decoders/drm-decoder/equalizer --I/usr/shared/systems/swradio-8/decoders/drm-decoder/msc --I/usr/shared/systems/swradio-8/decoders/drm-decoder/ofdm --I/usr/shared/systems/swradio-8/decoders/drm-decoder/parameters --I/usr/shared/systems/swradio-8/decoders/drm-decoder/sdc --I/usr/shared/systems/swradio-8/decoders/drm-decoder/data --I/usr/shared/systems/swradio-8/decoders/drm-decoder/support --I/usr/local/include/fdk-aac --I/usr/i686-w64-mingw32/sys-root/mingw/include/qt5 --I/usr/i686-w64-mingw32/sys-root/mingw/include/qt5/QtWidgets --I/usr/i686-w64-mingw32/sys-root/mingw/include/qt5/QtGui --I/usr/i686-w64-mingw32/sys-root/mingw/include/qt5/QtXml --I/usr/i686-w64-mingw32/sys-root/mingw/include/qt5/QtCore --I/usr/include/c++/11 --I/usr/include/c++/11/x86_64-redhat-linux --I/usr/include/c++/11/backward --I/usr/lib/gcc/x86_64-redhat-linux/11/include --I/usr/local/include --I/usr/include diff --git a/radio.h b/radio.h index 5f09f5a..399d434 100644 --- a/radio.h +++ b/radio.h @@ -122,13 +122,12 @@ private slots: RingBuffer> *); void adjustFrequency_hz (int); void adjustFrequency_khz (int); - void handle_myLine (void); + void handle_myLine (); void set_hfscopeLevel (int); void set_lfscopeLevel (int); virtualDecoder *selectDecoder (const QString &); - void setFrequency (quint64); void setStreamOutSelector (int idx); - void handle_freqButton (void); + void handle_freqButton (); void wheelEvent (QWheelEvent *); void set_mouseIncrement (int); void setBand (const QString &); @@ -146,6 +145,7 @@ public slots: void sampleHandler (int amount); void processAudio (int, int); void setDetectorMarker (int); + void setFrequency (quint64); #ifdef HAVE_EXTIO // and for the extio handling diff --git a/swradio-8.pro b/swradio-8.pro index 7f0a20d..d4e3ae9 100644 --- a/swradio-8.pro +++ b/swradio-8.pro @@ -6,6 +6,7 @@ QT += widgets xml CONFIG += console #CONFIG -= console TARGET = swradio-9 +QMAKE_CXXFLAGS += -std=c++14 QMAKE_CFLAGS += -O3 -ffast-math QMAKE_CXXFLAGS += -O3 -ffast-math #QMAKE_CXXFLAGS += -fsanitize=address -g @@ -169,7 +170,8 @@ CONFIG += cw-decoder CONFIG += amtor-decoder CONFIG += psk-decoder CONFIG += rtty-decoder -CONFIG += ft8-decoder-win +CONFIG += ft8-decoder +#CONFIG += ft8-decoder-win CONFIG += fax-decoder CONFIG += drm-decoder-fdk # diff --git a/swradio-psk-widget.png b/swradio-psk-widget.png index dceb8c5..0c866fa 100644 Binary files a/swradio-psk-widget.png and b/swradio-psk-widget.png differ diff --git a/swradio-rtty-widget.png b/swradio-rtty-widget.png index 8562bc1..6dae6a6 100644 Binary files a/swradio-rtty-widget.png and b/swradio-rtty-widget.png differ