diff --git a/:q b/:q deleted file mode 100644 index 5dd08b5..0000000 --- a/:q +++ /dev/null @@ -1,851 +0,0 @@ -# -/* - * Copyright (C) 2020 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Computing - * - * This file is part of sw radio - * - * 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 version 2 of the License. - * - * 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 "sdrplay-handler-v3.h" -#include -#include -#include -#include -#include -#include -#include "sdrplay-commands.h" -#include "radio.h" -// -// The Rsp's -#include "Rsp-device.h" -#include "RspDx-handler.h" -#include "Rsp1A-handler.h" -#include "RspII-handler.h" -#include "RspDuo-handler.h" - -#define WAITING 0100 -#define FAILED 0101 -#define SUCCESS 0102 - -#define SDRPLAY_RSP1_ 1 -#define SDRPLAY_RSP1A_ 255 -#define SDRPLAY_RSP2_ 2 -#define SDRPLAY_RSPduo_ 3 -#define SDRPLAY_RSPdx_ 4 - - sdrplayHandler_v3::sdrplayHandler_v3 (RadioInterface *mr, - int32_t outputRate, - RingBuffer> *r, - QSettings *s): - deviceHandler (mr), - myFrame (nullptr) { - this -> outputRate = outputRate; - sdrplaySettings = s; - setupUi (&myFrame); - myFrame. show (); - antennaSelector -> hide (); - amPortSelector -> hide (); - tunerSelector -> hide (); - this -> inputRate = kHz (2112); - this -> _I_Buffer = r; - nrBits = 12; // default - denominator = 2048; // default - sampleCnt = 0; -// See if there are settings from previous incarnations -// and config stuff - - sdrplaySettings -> beginGroup ("sdrplaySettings"); - GRdBSelector -> setValue ( - sdrplaySettings -> value ("sdrplay-ifgrdb", 20). toInt()); - GRdBValue = GRdBSelector -> value (); - - lnaGainSetting -> setValue ( - sdrplaySettings -> value ("sdrplay-lnastate", 4). toInt()); - lnaState = lnaGainSetting -> value (); - - ppmControl -> setValue ( - sdrplaySettings -> value ("sdrplay-ppm", 0). toInt()); - - agcMode = - sdrplaySettings -> value ("sdrplay-agcMode", 0). toInt() != 0; - if (agcMode) { - agcControl -> setChecked (true); - GRdBSelector -> hide (); - gainsliderLabel -> hide (); - } - biasT = - sdrplaySettings -> value ("biasT", 0). toInt () != 0; - if (biasT) - biasT_selector -> setChecked (true); - sdrplaySettings -> endGroup (); - -// and be prepared for future changes in the settings - connect (GRdBSelector, SIGNAL (valueChanged (int)), - this, SLOT (set_ifgainReduction (int))); - connect (lnaGainSetting, SIGNAL (valueChanged (int)), - this, SLOT (set_lnagainReduction (int))); - connect (agcControl, SIGNAL (stateChanged (int)), - this, SLOT (set_agcControl (int))); - connect (ppmControl, SIGNAL (valueChanged (int)), - this, SLOT (set_ppmControl (int))); - connect (antennaSelector, SIGNAL (activated (const QString &)), - this, SLOT (set_selectAntenna (const QString &))); - connect (amPortSelector, SIGNAL (activated (const QString &)), - this, SLOT (set_amPortSelect (const QString &))); - connect (biasT_selector, SIGNAL (stateChanged (int)), - this, SLOT (set_biasT (int))); -// - filter = new decimatingFIR (inputRate / outputRate * 5 - 1, - + outputRate / 2, - inputRate, - inputRate / outputRate); - - vfoFrequency = KHz (14070); - theGain = -1; - debugControl -> hide (); -// -// we have to wait for the task to initialize its - status. store (WAITING); - start (); - usleep (2000); - while (status. load () == WAITING) - usleep (1000); - fprintf (stderr, "status = %o\n", status. load ()); - if (status. load () == FAILED) - throw (23); -} - - sdrplayHandler_v3::~sdrplayHandler_v3 () { - threadRuns. store (false); - while (isRunning ()) - usleep (1000); -// thread should be stopped by now - sdrplaySettings -> beginGroup ("sdrplaySettings"); - sdrplaySettings -> setValue ("sdrplay-ppm", - ppmControl -> value ()); - sdrplaySettings -> setValue ("sdrplay-ifgrdb", - GRdBSelector -> value ()); - sdrplaySettings -> setValue ("sdrplay-lnastate", - lnaGainSetting -> value ()); - sdrplaySettings -> setValue ("sdrplay-agcMode", - agcControl -> isChecked() ? 1 : 0); - sdrplaySettings -> setValue ("biasT", - biasT_selector -> isChecked () ? 1 : 0); - sdrplaySettings -> endGroup (); - sdrplaySettings -> sync(); - - myFrame. hide (); - fprintf (stderr, "end of sdrplay-handler-v3\n"); -} - -///////////////////////////////////////////////////////////////////////// -// Implementing the interface -///////////////////////////////////////////////////////////////////////// - - -void sdrplayHandler_v3::setVFOFrequency (quint64 f) { -restartRequest r ( (uint32_t)f); - (void)messageHandler (&r); - vfoFrequency = f; -} - -void sdrplayHandler_v3::set_biasT (int c) { -bool b = biasT_selector -> isChecked (); -biasTRequest r (b); - (void)c; - (void)messageHandler (&r); -} - -quint64 sdrplayHandler_v3::getVFOFrequency() { - return vfoFrequency; -} - -bool sdrplayHandler_v3::restartReader () { -restartRequest r ((uint32_t)vfoFrequency); - if (receiverRuns. load ()) - return true; - return messageHandler (&r); -} - -void sdrplayHandler_v3::stopReader () { -stopRequest r; - if (!receiverRuns. load ()) - return; - messageHandler (&r); -} - -void sdrplayHandler_v3::set_ifgainReduction (int GRdB) { -GRdBRequest r (GRdB); - if (!receiverRuns. load ()) - return; - messageHandler (&r); -} - -void sdrplayHandler_v3::set_lnagainReduction (int lnaState) { -lnaRequest r (lnaState); - if (!receiverRuns. load ()) - return; - messageHandler (&r); -} - -// -void sdrplayHandler_v3::resetBuffer () { - _I_Buffer -> FlushRingBuffer(); -} - -int16_t sdrplayHandler_v3::bitDepth () { - return nrBits; -} - -int32_t sdrplayHandler_v3::getRate () { - return KHz (2112); -} - -/////////////////////////////////////////////////////////////////////////// -// Handling the GUI -////////////////////////////////////////////////////////////////////// - -void sdrplayHandler_v3::set_nrBits (int b) { - nrBits = b; - denominator = nrBits == 12 ? 2048 : 4096; -} - -void sdrplayHandler_v3::set_lnabounds(int low, int high) { - lnaGainSetting -> setRange (low, high); -} - -void sdrplayHandler_v3::set_deviceName (const QString& s) { - deviceLabel -> setText (s); -} - -void sdrplayHandler_v3::set_serial (const QString& s) { - serialNumber -> setText (s); -} - -void sdrplayHandler_v3::set_apiVersion (float version) { - api_version -> display (version); -} - -void sdrplayHandler_v3::show_lnaGain (int g) { - lnaGRdBDisplay -> display (g); -} - -void sdrplayHandler_v3::set_agcControl (int dummy) { -bool agcMode = agcControl -> isChecked (); -agcRequest r (agcMode, 30); - (void)dummy; - messageHandler (&r); - if (agcMode) { - GRdBSelector -> hide (); - gainsliderLabel -> hide (); - } - else { - GRdBSelector -> show (); - gainsliderLabel -> show (); - } -} - -void sdrplayHandler_v3::set_ppmControl (int ppm) { -ppmRequest r (ppm); - messageHandler (&r); -} - -void sdrplayHandler_v3::set_selectAntenna (const QString &s) { -antennaRequest r (s == "Antenna A" ? 'A' : - s == "Antenna B" ? 'B' : 'C'); - messageHandler (&r); -} - -void sdrplayHandler_v3::set_amPortSelect (const QString &s) { -amPortRequest r (s == "amPort on" ? 1 : 0); - messageHandler (&r); -} - -void sdrplayHandler_v3::report_dataAvailable (void) { - emit dataAvailable (10); -} - -// -//////////////////////////////////////////////////////////////////////// -// showing data -//////////////////////////////////////////////////////////////////////// -void sdrplayHandler_v3::set_antennaSelect (int n) { - if (n > 0) { - antennaSelector -> addItem ("Antenna B"); - if (n > 1) { // It is a "DX" - antennaSelector -> addItem ("Antenna C"); - amPortSelector -> show (); - } - antennaSelector -> show (); - } - else { - antennaSelector -> hide (); - amPortSelector -> hide (); - } -} - -void sdrplayHandler_v3::show_tunerSelector (bool b) { - if (b) - tunerSelector -> show (); - else - tunerSelector -> hide (); -} - -// -/////////////////////////////////////////////////////////////////////// -// the real controller starts here -/////////////////////////////////////////////////////////////////////// - -bool sdrplayHandler_v3::messageHandler (generalCommand *r) { - server_queue. push (r); - serverjobs. release (1); - while (!r -> waiter. tryAcquire (1, 1000)) - if (!threadRuns. load ()) - return false; - return true; -} - -static -void StreamACallback (short *xi, short *xq, - sdrplay_api_StreamCbParamsT *params, - unsigned int numSamples, - unsigned int reset, - void *cbContext) { -sdrplayHandler_v3 *p = static_cast (cbContext); -std::complex localBuf [numSamples]; -int cnt = 0; - - (void)params; - if (reset) - return; - if (!p -> receiverRuns. load ()) - return; - - for (int i = 0; i < (int)numSamples; i ++) { - std::complex tmp = - std::complex ((float)xi [i] / p -> denominator, - (float)xq [i] / p -> denominator); - if (p -> filter -> Pass (tmp, &localBuf [cnt])) - if (localBuf [cnt] == localBuf [cnt]) - cnt ++; - - } - p -> _I_Buffer -> putDataIntoBuffer (localBuf, cnt); - p -> sampleCnt += cnt; - if (p -> sampleCnt > p -> outputRate / 8) { - p -> report_dataAvailable (); - p -> sampleCnt = 0; - } -} - -static -void StreamBCallback (short *xi, short *xq, - sdrplay_api_StreamCbParamsT *params, - unsigned int numSamples, unsigned int reset, - void *cbContext) { - (void)xi; (void)xq; (void)params; (void)cbContext; - if (reset) - printf ("sdrplay_api_StreamBCallback: numSamples=%d\n", numSamples); -} - -void EventCallback (sdrplay_api_EventT eventId, - sdrplay_api_TunerSelectT tuner, - sdrplay_api_EventParamsT *params, - void *cbContext) { -sdrplayHandler_v3 *p = static_cast (cbContext); - (void)tuner; - p -> theGain = params -> gainParams. currGain; - switch (eventId) { - case sdrplay_api_GainChange: - break; - - case sdrplay_api_PowerOverloadChange: - p -> update_PowerOverload (params); - break; - - default: - fprintf (stderr, "event %d\n", eventId); - break; - } -} - -void sdrplayHandler_v3:: - update_PowerOverload (sdrplay_api_EventParamsT *params) { - sdrplay_api_Update (chosenDevice -> dev, - chosenDevice -> tuner, - sdrplay_api_Update_Ctrl_OverloadMsgAck, - sdrplay_api_Update_Ext1_None); - if (params -> powerOverloadParams.powerOverloadChangeType == - sdrplay_api_Overload_Detected) { -// fprintf (stderr, "Qt-DAB sdrplay_api_Overload_Detected"); - } - else { -// fprintf (stderr, "Qt-DAB sdrplay_api_Overload Corrected"); - } -} - -void sdrplayHandler_v3::run () { -sdrplay_api_ErrT err; -sdrplay_api_DeviceT devs [6]; -uint32_t ndev; - - threadRuns. store (false); - receiverRuns. store (false); - - chosenDevice = nullptr; - - connect (this, SIGNAL (set_serial_signal (const QString &)), - this, SLOT (set_serial (const QString &))); - connect (this, SIGNAL (set_apiVersion_signal (float)), - this, SLOT (set_apiVersion (float))); - - denominator = 2048; // default - nrBits = 12; // default - - Handle = fetchLibrary (); - if (Handle == nullptr) { - status. store (FAILED); - return; - } - -// load the functions - bool success = loadFunctions (); - if (!success) { - releaseLibrary (); - status. store (FAILED); - return; - } - - fprintf (stderr, "functions loaded\n"); - -// try to open the API - err = sdrplay_api_Open (); - if (err != sdrplay_api_Success) { - fprintf (stderr, "sdrplay_api_Open failed %s\n", - sdrplay_api_GetErrorString (err)); - releaseLibrary (); - status. store (FAILED); - return; - } - - fprintf (stderr, "api opened\n"); - -// Check API versions match - err = sdrplay_api_ApiVersion (&apiVersion); - if (err != sdrplay_api_Success) { - fprintf (stderr, "sdrplay_api_ApiVersion failed %s\n", - sdrplay_api_GetErrorString (err)); - goto closeAPI; - } - - if (apiVersion < (SDRPLAY_API_VERSION - 0.01)) { - fprintf (stderr, "API versions don't match (local=%.2f dll=%.2f)\n", - SDRPLAY_API_VERSION, apiVersion); - goto closeAPI; - } - - fprintf (stderr, "api version %f detected\n", apiVersion); -// -// lock API while device selection is performed - sdrplay_api_LockDeviceApi (); - { int s = sizeof (devs) / sizeof (sdrplay_api_DeviceT); - err = sdrplay_api_GetDevices (devs, &ndev, s); - if (err != sdrplay_api_Success) { - fprintf (stderr, "sdrplay_api_GetDevices failed %s\n", - sdrplay_api_GetErrorString (err)); - goto unlockDevice_closeAPI; - } - } - - if (ndev == 0) { - fprintf (stderr, "no valid device found\n"); - goto unlockDevice_closeAPI; - } - - fprintf (stderr, "%d devices detected\n", ndev); - chosenDevice = &devs [0]; - err = sdrplay_api_SelectDevice (chosenDevice); - if (err != sdrplay_api_Success) { - fprintf (stderr, "sdrplay_api_SelectDevice failed %s\n", - sdrplay_api_GetErrorString (err)); - goto unlockDevice_closeAPI; - } - -// assign callback functions -// will be effectuated when initing the device - cbFns. StreamACbFn = StreamACallback; - cbFns. StreamBCbFn = StreamBCallback; - cbFns. EventCbFn = EventCallback; - -// we have a device, unlock and go on with the specified device - sdrplay_api_UnlockDeviceApi (); - -// - serial = devs [0]. SerNo; - hwVersion = devs [0]. hwVer; - try { - switch (hwVersion) { - case SDRPLAY_RSPdx_ : - theRsp = new RspDx_handler (this, - chosenDevice, - inputRate, - KHz (14070), - agcMode, - lnaState, - GRdBValue, - biasT); - break; - - case SDRPLAY_RSP1A_ : - theRsp = new Rsp1A_handler (this, - chosenDevice, - inputRate, - KHz (14070), - agcMode, - lnaState, - GRdBValue, - biasT); - break; - - case SDRPLAY_RSP2_ : - theRsp = new RspII_handler (this, - chosenDevice, - inputRate, - KHz (14070), - agcMode, - lnaState, - GRdBValue, - biasT); - break; - - case SDRPLAY_RSPduo_ : - theRsp = new RspDuo_handler (this, - chosenDevice, - inputRate, - KHz (14070), - agcMode, - lnaState, - GRdBValue, - biasT); - break; - - default: - theRsp = new Rsp_device (this, - chosenDevice, - 2112000, - KHz (14070), - agcMode, - lnaState, - GRdBValue, - biasT); - break; - } - } catch (int e) { - goto closeAPI; - } - - set_serial_signal (serial); - set_apiVersion_signal (apiVersion); - - threadRuns. store (true); // it seems we can do some work - status. store (SUCCESS); - while (threadRuns. load ()) { - while (!serverjobs. tryAcquire (1, 1000)) - if (!threadRuns. load ()) - goto normal_exit; -// -// here we could assert that the server_queue is not empty - switch (server_queue. front () -> cmd) { - case RESTART_REQUEST: { - restartRequest *p = (restartRequest *)(server_queue. front ()); - server_queue. pop (); - p -> result = theRsp -> restart (p -> freq); - receiverRuns. store (true); - p -> waiter. release (1); - break; - } - - case STOP_REQUEST: { - stopRequest *p = (stopRequest *)(server_queue. front ()); - server_queue. pop (); - receiverRuns. store (false); - p -> waiter. release (1); - break; - } - - case AGC_REQUEST: { - agcRequest *p = (agcRequest *)(server_queue. front ()); - server_queue. pop (); - p -> result = theRsp -> set_agc (-p -> setPoint, p -> agcMode); - p -> waiter. release (1); - break; - } - - case GRDB_REQUEST: { - GRdBRequest *p = (GRdBRequest *)(server_queue. front ()); - server_queue. pop (); - p -> result = theRsp -> set_GRdB (p -> GRdBValue); - p -> waiter. release (1); - break; - } - - case PPM_REQUEST: { - ppmRequest *p = (ppmRequest *)(server_queue. front ()); - server_queue. pop (); - p -> result = theRsp -> set_ppm (p -> ppmValue); - p -> waiter. release (1); - break; - } - - case LNA_REQUEST: { - lnaRequest *p = (lnaRequest *)(server_queue. front ()); - server_queue. pop (); - p -> result = theRsp -> set_lna (p -> lnaState); - p -> waiter. release (1); - break; - } - - case ANTENNASELECT_REQUEST: { - antennaRequest *p = (antennaRequest *)(server_queue. front ()); - server_queue. pop (); - p -> result = theRsp -> set_antenna (p -> antenna); - p -> waiter. release (1); - break; - } - - case AMPORT_REQUEST: { - amPortRequest *p = (amPortRequest *)(server_queue. front ()); - server_queue. pop (); - p -> result = theRsp -> set_amPort (p -> amPort); - p -> waiter. release (1); - break; - } - - case BIAST_REQUEST: { - biasTRequest *p = (biasTRequest *)(server_queue. front ()); - server_queue. pop (); - p -> result = theRsp -> set_biasT (p -> checked); - p -> waiter. release (1); - break; - } - - default: // cannot happen - break; - } - } - -normal_exit: - err = sdrplay_api_Uninit (chosenDevice -> dev); - if (err != sdrplay_api_Success) - fprintf (stderr, "sdrplay_api_Uninit failed %s\n", - sdrplay_api_GetErrorString (err)); - - err = sdrplay_api_ReleaseDevice (chosenDevice); - if (err != sdrplay_api_Success) - fprintf (stderr, "sdrplay_api_ReleaseDevice failed %s\n", - sdrplay_api_GetErrorString (err)); - -// sdrplay_api_UnlockDeviceApi (); ?? - sdrplay_api_Close (); - if (err != sdrplay_api_Success) - fprintf (stderr, "sdrplay_api_Close failed %s\n", - sdrplay_api_GetErrorString (err)); - - releaseLibrary (); - fprintf (stderr, "library released, ready to stop thread\n"); - msleep (200); - return; - -unlockDevice_closeAPI: - sdrplay_api_UnlockDeviceApi (); -closeAPI: - sdrplay_api_ReleaseDevice (chosenDevice); - sdrplay_api_Close (); - releaseLibrary (); - status. store (FAILED); - fprintf (stderr, "De taak is gestopt\n"); -} - -///////////////////////////////////////////////////////////////////////////// -// handling the library -///////////////////////////////////////////////////////////////////////////// - -HINSTANCE sdrplayHandler_v3::fetchLibrary () { -HINSTANCE Handle = nullptr; -#ifdef __MINGW32__ -HKEY APIkey; -wchar_t APIkeyValue [256]; -ULONG APIkeyValue_length = 255; - - wchar_t *libname = (wchar_t *)L"sdrplay_api.dll"; - Handle = LoadLibrary (libname); - if (Handle == nullptr) { - if (RegOpenKey (HKEY_LOCAL_MACHINE, - TEXT("Software\\MiricsSDR\\API"), - &APIkey) != ERROR_SUCCESS) { - fprintf (stderr, - "failed to locate API registry entry, error = %d\n", - (int)GetLastError()); - return nullptr; - } - - RegQueryValueEx (APIkey, - (wchar_t *)L"Install_Dir", - nullptr, - nullptr, - (LPBYTE)&APIkeyValue, - (LPDWORD)&APIkeyValue_length); -// Ok, make explicit it is in the 32/64 bits section - wchar_t *x = - wcscat (APIkeyValue, (wchar_t *)L"\\x86\\sdrplay_api.dll"); -// wcscat (APIkeyValue, (wchar_t *)L"\\x64\\sdrplay_api.dll"); - RegCloseKey(APIkey); - - Handle = LoadLibrary (x); - if (Handle == nullptr) { - fprintf (stderr, "Failed to open sdrplay_api.dll\n"); - return nullptr; - } - } -#else - Handle = dlopen ("libusb-1.0.so", RTLD_NOW | RTLD_GLOBAL); - Handle = dlopen ("libsdrplay_api.so", RTLD_NOW); - if (Handle == nullptr) { - fprintf (stderr, "error report %s\n", dlerror()); - return nullptr; - } -#endif - return Handle; -} - -void sdrplayHandler_v3::releaseLibrary () { -#ifdef __MINGW32__ - FreeLibrary (Handle); -#else - dlclose (Handle); -#endif -} - -bool sdrplayHandler_v3::loadFunctions () { - sdrplay_api_Open = (sdrplay_api_Open_t) - GETPROCADDRESS (Handle, "sdrplay_api_Open"); - if ((void *)sdrplay_api_Open == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_Open\n"); - return false; - } - - sdrplay_api_Close = (sdrplay_api_Close_t) - GETPROCADDRESS (Handle, "sdrplay_api_Close"); - if (sdrplay_api_Close == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_Close\n"); - return false; - } - - sdrplay_api_ApiVersion = (sdrplay_api_ApiVersion_t) - GETPROCADDRESS (Handle, "sdrplay_api_ApiVersion"); - if (sdrplay_api_ApiVersion == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_ApiVersion\n"); - return false; - } - - sdrplay_api_LockDeviceApi = (sdrplay_api_LockDeviceApi_t) - GETPROCADDRESS (Handle, "sdrplay_api_LockDeviceApi"); - if (sdrplay_api_LockDeviceApi == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_LockdeviceApi\n"); - return false; - } - - sdrplay_api_UnlockDeviceApi = (sdrplay_api_UnlockDeviceApi_t) - GETPROCADDRESS (Handle, "sdrplay_api_UnlockDeviceApi"); - if (sdrplay_api_UnlockDeviceApi == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_UnlockdeviceApi\n"); - return false; - } - - sdrplay_api_GetDevices = (sdrplay_api_GetDevices_t) - GETPROCADDRESS (Handle, "sdrplay_api_GetDevices"); - if (sdrplay_api_GetDevices == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_GetDevices\n"); - return false; - } - - sdrplay_api_SelectDevice = (sdrplay_api_SelectDevice_t) - GETPROCADDRESS (Handle, "sdrplay_api_SelectDevice"); - if (sdrplay_api_SelectDevice == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_SelectDevice\n"); - return false; - } - - sdrplay_api_ReleaseDevice = (sdrplay_api_ReleaseDevice_t) - GETPROCADDRESS (Handle, "sdrplay_api_ReleaseDevice"); - if (sdrplay_api_ReleaseDevice == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_ReleaseDevice\n"); - return false; - } - - sdrplay_api_GetErrorString = (sdrplay_api_GetErrorString_t) - GETPROCADDRESS (Handle, "sdrplay_api_GetErrorString"); - if (sdrplay_api_GetErrorString == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_GetErrorString\n"); - return false; - } - - sdrplay_api_GetLastError = (sdrplay_api_GetLastError_t) - GETPROCADDRESS (Handle, "sdrplay_api_GetLastError"); - if (sdrplay_api_GetLastError == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_GetLastError\n"); - return false; - } - - sdrplay_api_DebugEnable = (sdrplay_api_DebugEnable_t) - GETPROCADDRESS (Handle, "sdrplay_api_DebugEnable"); - if (sdrplay_api_DebugEnable == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_DebugEnable\n"); - return false; - } - - sdrplay_api_GetDeviceParams = (sdrplay_api_GetDeviceParams_t) - GETPROCADDRESS (Handle, "sdrplay_api_GetDeviceParams"); - if (sdrplay_api_GetDeviceParams == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_GetDeviceParams\n"); - return false; - } - - sdrplay_api_Init = (sdrplay_api_Init_t) - GETPROCADDRESS (Handle, "sdrplay_api_Init"); - if (sdrplay_api_Init == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_Init\n"); - return false; - } - - sdrplay_api_Uninit = (sdrplay_api_Uninit_t) - GETPROCADDRESS (Handle, "sdrplay_api_Uninit"); - if (sdrplay_api_Uninit == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_Uninit\n"); - return false; - } - - sdrplay_api_Update = (sdrplay_api_Update_t) - GETPROCADDRESS (Handle, "sdrplay_api_Update"); - if (sdrplay_api_Update == nullptr) { - fprintf (stderr, "Could not find sdrplay_api_Update\n"); - return false; - } - - return true; -} - diff --git a/README.md b/README.md index 741be97..1a90db0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ Improved support for SDRplay RSP's --------------------------------------------------------------------- Support for the SDRplay RSP's is rewritten (and improved). For the DX version, -antennas A, B and C can be selected now. +antennas A, B and C can be selected now, and its antenna setting is +kept between invocations. ----------------------------------------------------------------- @@ -19,9 +20,6 @@ The software supports hackrf devices, rtlsdr devices (For the rtlsdr based devices, use was made of a special version of the library, the one by Oliver Jowett. Sources are included in the source tree of this program.) -It can be configured to use the "classic" PMSDR device, the precompiled -versions for Linux (i.e. an AppImage) and Windows (i.e. an installer) -are configured for the other ones. ![swradio-8](/swradio-overview.png?raw=true) @@ -83,7 +81,7 @@ With the second combobox above the main spectrum a choice can be made among a list of bandwidths symmetrical around 0 (200, 500, 1000, 1500, 2000, am (9 KHz) and wide (full 12 KHz), as well as selectors for usb (upper band) and lsb (lower band), each of 2500 Hz). -It is assumed that - if needed - the decoder implmementation will do further +It is assumed that - if needed - the decoder implementation will do further filtering an decimation (as an example, the CW and PSK decoders use 2000 Hz as "operating" samplerate). @@ -146,6 +144,10 @@ As known, (B)PSK is encoded using phase jumps of 180 degrees, while reasonable idea of the stability of the phase jumps, and therefore of the success in decoding. +(Note that while when I wrote the decoder, about 10 years ago, the band was +full with psk signals, now one hardly sees one. That is why the decoder +picture is taken from some file input. + ------------------------------------------------------------------------- A note on the amtor (navtex) decoder ------------------------------------------------------------------------- @@ -164,7 +166,7 @@ A note on the RTTY decoder While the use of RTTY on amateur bands seems to decrease, it is an interesting mode. I used to listen around 14080 KHz, but do not see much activity on -RTTY there. +RTTY there anymore. Of course there are lots of parameters. Amateurs use RTTY with a shift of 170 Hz and a baudrate of 45. Sometimes @@ -175,10 +177,13 @@ To aid is tuning - a 170 Hz signal remains small - there are some indicators on the left side of the widget * the frequency offset, as measured between the mark and the space; - * the guessed baudrate + * the estimated baudrate ![swradio-8](/swradio-rtty-widget.png?raw=true) +As with psk, while a decade ago the 14080 KHz was full (overloaded) with rtty +signals, one now only ocxasionally sees such signals. + ------------------------------------------------------------------------- A note on the ft8 decoder ------------------------------------------------------------------------- @@ -194,7 +199,7 @@ derived from his work. Anyway, FT8 is a small signal, using tones with a predefined length and a well defined distance between successive ones. The signal width is 7 times 6.25 Hz, i.e. about 45 Hz, and messages have a defined -length of 79 tones, with 6 tones per second. +length of 79 tones, with 6 tones per second (i.e. app 12.5 seconds). The decoder has three control elements @@ -205,7 +210,7 @@ The decoder has three control elements The current version has as option sending (some parts of) the messages to the pskreporter, i.e. using the decoder as "Monitor", the map on pskreporter.info will then show you as "monitor". -The pskreporter (see report.pskreporter.info) obviously wants to know +The **pskreporter** (see report.pskreporter.info) obviously wants to know who is sending the data, so there is a possibility to fill in your callsign (I do not have a callsign, not being a "real" amateur, but I have an official number as "listener", obtained from the VERON, the association of radio amateurs in the Netherlands), the maiddenhead grid indication of your locatio (which helps the pskreportet to position your description on the map) and @@ -223,18 +228,16 @@ Note: the decoder is experimental and will definitely not catch all transmitted ![swradio-8](/swradio-ft8-widget.png?raw=true) - ------------------------------------------------------------------------- a note on the weatherfax decoder ------------------------------------------------------------------------- Even in this time of internet and satelites, weatherfaxes still can be received on a variety of frequencies. In my region, I can receive -faxes on 3588, 4610, 7880 and 8020 KHz. +faxes on 3588, 4610, 7880 and 8040 KHz. ![swradio-8](/swradio-wfax-widget.png?raw=true) - Receiving a fax takes quite some time, and tuning into the frequency will show a running transmission. To " pop-in", the decoder has a "cheat" button, a button with which a synchronization can be faked and the @@ -246,18 +249,39 @@ a note on the DRM decoder ------------------------------------------------------------------------- DRM, Digital Radio Mondiale, is digital radio over shortwave. -There are not many drm transmissions these days, but it is interesting -to compare drm with DAB. The latter of course on much higher frequencies -with a much higher bandwidth. +There are not many DRM transmissions these days, but it is interesting +to compare DRM with DAB. The latter of course on much higher frequencies +with a much higher bandwidth (and with much higher payload). + +The DRM signal is transmitted - an OFDM signal - with app 300 carriers, +close to each other (carrier distance is app 45 Hz). +Decoding is coherent, so the signal as transmitted has to be restored. +To aid in "undoing" the channel effects, a number of carriers, pilots, +are transmitted, carriers with predefined amplitude and phase. -![swradio-8](/swradio-drm-widget.png?raw=true) +![swradio-8](/swradio-drm-widget-1.png?raw=true) The decoder widget gives quite some information. The "scopes" show the -correction to be applied to the signal (blue line is the phase, red line -the amplitude), as well as the constellation. +correction to be applied to the signal. +In the current version one may choose between looking at the +correction factors to be applied to the "pilot carriers", +or looking at the channel impulse. + +The picture above shows the **correction** to be applied to the pilot carriers +(from which the correction to the other carriers is computed). The yellow +lines tell about the amplitude, the white lines about the phase correction. +(Correction is here: divide the measured signal on the pily carrier by +the correction fctor). Such correction is needed, since decoding is coherent. -Note that, other than in previous versions, the drm decoder now -uses the fdk-aac library. Therefore, the decoder is able to handle both AAC and xHE-AAC encoded services. +![swradio-8](/swradio-drm-widget-2.png?raw=true) + +The second picture shows the **channel impulse**, i.e. +the **filtering** as applied on the signal in the transport from +transmitter to receiver. +Again, the yellow line tells the amplitude value of the filter component, +while the white line does so for the phase. + +In general, DRM is retty difficult to decode, due to channel conditions. -------------------------------------------------------------------------- Using the swradio @@ -271,7 +295,7 @@ A selected frequency can be stored by pressing the save frequency button. If touched, one is asked to specify a name to be used to label that frequency. The pair (name, frequency) then is added to the list. -Selecting such a "preferred program" is just by clicking the mouse on +Selecting such a **preferred program** is just by clicking the mouse on the programname or the associated field with the frequency. Buttons and slider are equipped with a *tooltip*, touching the button or @@ -304,12 +328,6 @@ It is of course possible to create your own executable, the ".pro" file for use with qmake and the CMakeList.txt file for use with cmake can be used to generate a makefile. -------------------------------------------------------------------------- -Using a pmSDR device and a soundcard -------------------------------------------------------------------------- - -The software can be configured to use the PMSDR. - ------------------------------------------------------------------------- -------------------------------------------------------------------------- diff --git a/decoders/am-decoder/am-decoder.cpp b/decoders/am-decoder/am-decoder.cpp index 64d462a..ad1fb64 100644 --- a/decoders/am-decoder/am-decoder.cpp +++ b/decoders/am-decoder/am-decoder.cpp @@ -41,8 +41,8 @@ adaptiveFiltersize = 15; /* the default */ adaptive = new adaptiveFilter (15, 0.2); adaptiveFiltering = false; - connect (adaptiveFilterButton, SIGNAL (clicked (void)), - this, SLOT (set_adaptiveFilter (void))); + connect (adaptiveFilterButton, SIGNAL (clicked ()), + this, SLOT (set_adaptiveFilter ())); connect (adaptiveFilterSlider, SIGNAL (valueChanged (int)), this, SLOT (set_adaptiveFiltersize (int))); connect (lowpassFilterslider, SIGNAL (valueChanged (int)), @@ -53,13 +53,13 @@ } - amDecoder::~amDecoder (void) { + amDecoder::~amDecoder () { delete adaptive; delete lowpassFilter; delete myFrame; } -void amDecoder::set_adaptiveFilter (void) { +void amDecoder::set_adaptiveFilter () { adaptiveFiltering = !adaptiveFiltering; if (adaptiveFiltering) { adaptiveFilterButton -> setText ("on"); diff --git a/decoders/cw-decoder/cw-decoder.cpp b/decoders/cw-decoder/cw-decoder.cpp index dcb400a..4419eee 100644 --- a/decoders/cw-decoder/cw-decoder.cpp +++ b/decoders/cw-decoder/cw-decoder.cpp @@ -333,11 +333,11 @@ static int oldOffset = 0; /* * we seem to start a new tone */ + cwPreviousState = cwState; cwState = MODE_IN_TONE; currentTime = 0; cwCurrent = 0; cwStartTimestamp = currentTime; - cwPreviousState = cwState; } else noiseLevel = decayingAverage (noiseLevel, diff --git a/decoders/cw-new/cw-new.cpp b/decoders/cw-new/cw-new.cpp deleted file mode 100644 index aee5b66..0000000 --- a/decoders/cw-new/cw-new.cpp +++ /dev/null @@ -1,115 +0,0 @@ -# -/* - * Copyright (C) 2010, 2011, 2012, 2013 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Programming - * - * This file is part of the SDR-J (JSDR). - * - * 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 -#include "cw-new.h" -#include "iir-filters.h" -#include "shifter.h" -#include "radio.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 DOTLENGTH 1250 -// -// dotlength = 1.2 / speed (WPM) seconds. -// So 20 words per minute (just an example) means 1.2 / 20 = 1200 / 20 -// 60 milliseconds -// For a 12000 samples/second signal this means app 5000 samples -// If we want to be able to identiy dots where at least 4 successive -// FFT elements carry a positive value, then we need an FFT taken -// once per 1250 samples -// -#define CW_DOT_REPRESENTATION '.' -#define CW_DASH_REPRESENTATION '_' -#define CW_IF 0 -/* - */ - - cwDecoder::cwDecoder (RadioInterface *mir, - int32_t rate, - RingBuffer > *b, - QSettings *s): - myFrame (nullptr), - virtualDecoder (rate, b), - localShifter (rate) { - theRate = rate; - inputRate = 12000; - audioData = b; - cwSettings = s; - setupUi (&myFrame); - myFrame. show (); - - fftBuffer = (std::complex *) fftwf_malloc (sizeof (std::complex) * inputRate); - plan = fftwf_plan_dft_1d (inputRate, - reinterpret_cast (fftBuffer), - reinterpret_cast (fftBuffer), - FFTW_FORWARD, FFTW_ESTIMATE); - - x_axis = new double [inputRate]; - for (int i = 0; i < inputRate; i ++) - x_axis [i] = - inputRate / 2 + i; - y_values = new double [inputRate]; - cwViewer = new waterfallScope (cwScope, - inputRate, 80); - buffp = 0; -} -// -// - cwDecoder::~cwDecoder () { - fftwf_free (fftBuffer); - fftwf_destroy_plan (plan); -} - -int32_t cwDecoder::rateOut () { - return theRate; -} - -void cwDecoder::process (std::complex s) { - fftBuffer [buffp] = s; - buffp ++; - if (buffp > DOTLENGTH) { // one dot - for (int i = DOTLENGTH; i < inputRate; i ++) - fftBuffer [i] = std::complex (0, 0); - addBuffer (fftBuffer); - buffp = 0; - } -} - -void cwDecoder::addBuffer (std::complex *v) { - fftwf_execute (plan); - for (int i = 0; i < inputRate / 2; i ++) { - y_values [inputRate / 2 + i] = abs (fftBuffer [i]); - y_values [i] = abs (fftBuffer [inputRate / 2 + i]); - } - - cwViewer -> display (x_axis, y_values, - amplitudeSlider -> value (), 0, 0); -} diff --git a/decoders/cw-new/cw-new.h b/decoders/cw-new/cw-new.h deleted file mode 100644 index cd94b86..0000000 --- a/decoders/cw-new/cw-new.h +++ /dev/null @@ -1,70 +0,0 @@ -# -/* - * Copyright (C) 2010, 2011, 2012, 2013 - * 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 __NEW_CW__ -#define __NEW_CW__ -# - -#include -#include "radio-constants.h" -#include "virtual-decoder.h" -#include "ui_cw-new.h" -#include "shifter.h" -#include -#include "waterfall-scope.h" -#include - -class LowPassIIR; -class QSettings; -class shifter; -class RadioInterface; - -class cwDecoder: public virtualDecoder, public Ui_new_cw { -Q_OBJECT -public: - cwDecoder (RadioInterface *, - int32_t, - RingBuffer > *, - QSettings *); - ~cwDecoder (); - void process (std::complex); - int32_t rateOut (); -private: - QFrame myFrame; - shifter localShifter; - QSettings *cwSettings; - double *x_axis; - double *y_values; - int buffp; - std::complex *fftBuffer; - fftwf_plan plan; - waterfallScope *cwViewer; - int inputRate; - void addBuffer (std::complex *); - int32_t theRate; - RingBuffer > *audioData; -}; - -#endif - - diff --git a/decoders/cw-new/cw-new.ui b/decoders/cw-new/cw-new.ui deleted file mode 100644 index 1c41f31..0000000 --- a/decoders/cw-new/cw-new.ui +++ /dev/null @@ -1,62 +0,0 @@ - - - new_cw - - - - 0 - 0 - 622 - 389 - - - - cw decoder - - - - - - - - 50 - - - Qt::Vertical - - - - - - - - 16777215 - 301 - - - - - - - - - - QFrame::Panel - - - - - - - - - - - QwtPlot - QFrame -
qwt_plot.h
-
-
- - -
diff --git a/decoders/drm-decoder/basics.h b/decoders/drm-decoder/basics.h index ff7f7c8..e6d0f61 100755 --- a/decoders/drm-decoder/basics.h +++ b/decoders/drm-decoder/basics.h @@ -181,5 +181,8 @@ int16_t Kmin (uint8_t, uint8_t); int16_t Kmax (uint8_t, uint8_t); int16_t ususedCarriers (uint8_t); DRM_FLOAT sinc (DRM_FLOAT); + +#define SHOW_CHANNEL 0100 +#define SHOW_PILOTS 0200 #endif diff --git a/decoders/drm-decoder/data/xheaac-processor.cpp b/decoders/drm-decoder/data/xheaac-processor.cpp index 1333f3c..cd2bb54 100755 --- a/decoders/drm-decoder/data/xheaac-processor.cpp +++ b/decoders/drm-decoder/data/xheaac-processor.cpp @@ -30,7 +30,7 @@ #include #include #include -#ifndef __MINGW#@__ +#ifndef __MINGW32__ #include #endif @@ -273,6 +273,8 @@ static bool convOK = false; int16_t cnt; int32_t rate; +float ff = 0; + decodeFrame (f. data (), f. size (), // f. size () - 2, @@ -333,8 +335,9 @@ void xheaacProcessor::writeOut (int16_t *buffer, int16_t cnt, buffer [2 * i + 1] / 8192.0); int amount; bool b = theConverter -> convert (tmp, local, &amount); - if (b) + if (b) { toOutput (local, amount); + } } } diff --git a/decoders/drm-decoder/drm-decoder.cpp b/decoders/drm-decoder/drm-decoder.cpp index 7a3f2a3..bf13295 100755 --- a/decoders/drm-decoder/drm-decoder.cpp +++ b/decoders/drm-decoder/drm-decoder.cpp @@ -51,10 +51,12 @@ &iqBuffer), theState (1, 3) { this -> theRadio = theRadio; + drmSettings = s; setupUi (&myFrame); my_eqDisplay = new EQDisplay (equalizerDisplay); my_iqDisplay = new IQDisplay (iqPlotter, 512); + scopeMode = SHOW_PILOTS; myFrame. show (); running. store (false); @@ -62,6 +64,17 @@ nSymbols = 25; modeInf. Mode = 2; modeInf. Spectrum = 3; + int st = s -> value ("strength", 0). toInt (); + strengthSelector -> setValue (st); + st = s -> value ("f_cut_k", 20). toInt (); + f_cutSelector -> setValue (st); + + connect (strengthSelector, SIGNAL (valueChanged (int)), + this, SLOT (handle_strengthSelector (int))); + connect (f_cutSelector, SIGNAL (valueChanged (int)), + this, SLOT (handle_f_cutSelector (int))); + connect (modeSelector, SIGNAL (activated (const QString &)), + this, SLOT (handle_modeSelector (const QString &))); connect (this, SIGNAL (setTimeSync (bool)), this, SLOT (executeTimeSync (bool))); @@ -157,8 +170,11 @@ float sampleclockOffset = 0; equalizer_1 my_Equalizer (this, modeInf.Mode, modeInf.Spectrum, - 1, + strengthSelector -> value (), + f_cutSelector -> value (), &eqBuffer); + + my_Equalizer. set_scopeMode (scopeMode); std::vector> displayVector; displayVector. resize (Kmax (modeInf. Mode, modeInf. Spectrum) - Kmin (modeInf. Mode, modeInf. Spectrum) + 1); @@ -217,6 +233,7 @@ float sampleclockOffset = 0; symbol_no = 0; frameReady = false; while (running. load () && !frameReady) { + my_Equalizer. set_scopeMode (scopeMode); my_wordCollector.getWord (inbank.element(lc), modeInf.freqOffset_integer, lc == 0, // no-op @@ -268,6 +285,7 @@ float sampleclockOffset = 0; while (true) { + my_Equalizer. set_scopeMode (scopeMode); // when we are here, we can start thinking about SDC's and superframes // The first frame of a superframe has an SDC part if (isFirstFrame (&theState)) { @@ -637,8 +655,11 @@ void drmDecoder::audioAvailable () { void drmDecoder::show_eqsymbol (int amount) { std::complex line [amount]; - eqBuffer. getDataFromBuffer (line, amount); - my_eqDisplay -> show (line, amount); + eqBuffer. getDataFromBuffer (line, amount); + if (scopeMode == SHOW_PILOTS) + my_eqDisplay -> show_pilots (line, amount); + else + my_eqDisplay -> show_channel (line, amount); } void drmDecoder::showIQ (int amount) { @@ -660,6 +681,19 @@ int scopeWidth = scopeSlider -> value(); my_iqDisplay -> DisplayIQ (Values, scopeWidth / avg); } +void drmDecoder::handle_strengthSelector (int s) { + drmSettings -> setValue ("strength", s); +} + +void drmDecoder::handle_f_cutSelector (int n) { + drmSettings -> setValue ("f_cut_k", n); +} + +void drmDecoder::handle_modeSelector (const QString &m) { + scopeMode = m == "Pilots" ? SHOW_PILOTS : SHOW_CHANNEL; +} + + void drmDecoder::select_channel_1 () { theState. activate_channel_1 (); } diff --git a/decoders/drm-decoder/drm-decoder.h b/decoders/drm-decoder/drm-decoder.h index f0dbf7b..cf55c86 100755 --- a/decoders/drm-decoder/drm-decoder.h +++ b/decoders/drm-decoder/drm-decoder.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -45,6 +46,7 @@ Q_OBJECT private: QFrame myFrame; + QSettings *drmSettings; std::thread * m_worker; RingBuffer> inputBuffer; RingBuffer> iqBuffer; @@ -82,6 +84,7 @@ Q_OBJECT int Raw_Rate; // // + int scopeMode; int16_t nSymbols; int32_t sampleRate; int8_t windowDepth; @@ -106,6 +109,10 @@ Q_OBJECT private slots: void select_channel_1 (); void select_channel_2 (); + void handle_strengthSelector (int); + void handle_f_cutSelector (int); + void handle_modeSelector (const QString &); + public slots: void set_faadSyncLabel (bool); void set_messageLabel (const QString &); diff --git a/decoders/drm-decoder/drmdecoder.ui b/decoders/drm-decoder/drmdecoder.ui index 8734697..b2440e8 100755 --- a/decoders/drm-decoder/drmdecoder.ui +++ b/decoders/drm-decoder/drmdecoder.ui @@ -6,8 +6,8 @@ 0 0 - 581 - 380 + 567 + 401 @@ -232,51 +232,92 @@ - + - - - QFrame::Box - - - + + + 5 - - - QFrame::Box + + + 10 - - + + 200 - - - - - - QFrame::Box + + 5 - - + + 20 - - - QFrame::Box - - - - - + + + + + QFrame::Box + + + + + + + + + + QFrame::Box + + + + + + + + + + QFrame::Box + + + + + + + + + + QFrame::Box + + + + + + + + + + + + Pilots + + + + + channel + + + + @@ -348,7 +389,7 @@ - + @@ -373,7 +414,7 @@ - 16777215 + 221 141 diff --git a/decoders/drm-decoder/eqdisplay.cpp b/decoders/drm-decoder/eqdisplay.cpp index 4eecf9e..240c655 100755 --- a/decoders/drm-decoder/eqdisplay.cpp +++ b/decoders/drm-decoder/eqdisplay.cpp @@ -4,7 +4,7 @@ EQDisplay::EQDisplay (QwtPlot *plotgrid) { this -> plotgrid = plotgrid; - plotgrid -> setCanvasBackground (QColor ("white")); + plotgrid -> setCanvasBackground (QColor ("black")); grid = new QwtPlotGrid; #if defined QWT_VERSION && ((QWT_VERSION >> 8) < 0x0601) grid -> setMajPen (QPen(QColor ("black"), 0, Qt::DotLine)); @@ -21,12 +21,12 @@ grid -> attach (plotgrid); spectrumCurve = new QwtPlotCurve (""); - spectrumCurve -> setPen (QPen(Qt::red)); + spectrumCurve -> setPen (QPen(Qt::yellow)); spectrumCurve -> setOrientation (Qt::Horizontal); spectrumCurve -> setBaseline (0); spectrumCurve -> attach (plotgrid); phaseCurve = new QwtPlotCurve (""); - phaseCurve -> setPen (QPen(Qt::blue)); + phaseCurve -> setPen (QPen(Qt::white)); phaseCurve -> setOrientation (Qt::Horizontal); phaseCurve -> setBaseline (0); phaseCurve -> attach (plotgrid); @@ -34,7 +34,7 @@ EQDisplay::~EQDisplay () {} -void EQDisplay::show (std::complex *v, int amount) { +void EQDisplay::show_pilots (std::complex *v, int amount) { double max = 0; int i; double X_axis [amount]; @@ -62,3 +62,31 @@ double phaseData [amount]; plotgrid -> replot (); } +void EQDisplay::show_channel (std::complex *v, int amount) { +double max = 0; +int i; +double X_axis [amount]; +double plotData [amount]; +double phaseData [amount]; + + for (i = 0; i < amount; i ++) { + X_axis [i] = i; + plotData [i] = abs (v [i]); + if (plotData [i] > max) + max = plotData [i]; + } + for (i = 0; i < amount; i ++) + plotData [i] = plotData [i] / max * 10; + for (i = 0; i < amount; i ++) + phaseData [i] = arg (v [i]) + 5; + + plotgrid -> setAxisScale (QwtPlot::xBottom, + (double)X_axis [0], + (double)X_axis [amount - 1]); + plotgrid -> enableAxis (QwtPlot::xBottom); + plotgrid -> setAxisScale (QwtPlot::yLeft, 0, 10); + spectrumCurve -> setSamples (X_axis, plotData, amount); + phaseCurve -> setSamples (X_axis, phaseData, amount); + plotgrid -> replot (); +} + diff --git a/decoders/drm-decoder/eqdisplay.h b/decoders/drm-decoder/eqdisplay.h index 37d7b5d..b9f1fe8 100755 --- a/decoders/drm-decoder/eqdisplay.h +++ b/decoders/drm-decoder/eqdisplay.h @@ -4,20 +4,20 @@ * Jan van Katwijk (J.vanKatwijk@gmail.com) * Lazy Chair Computing * - * This file is part of the Qt-DAB + * This file is part of the drm decoder * - * Qt-DAB is free software; you can redistribute it and/or modify + * drm decoder 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. * - * Qt-DAB is distributed in the hope that it will be useful, + * drm-decoder 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 Qt-DAB; if not, write to the Free Software + * along with drm-decoder; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __EQDISPLAY__ @@ -47,12 +47,16 @@ class EQDisplay { public: EQDisplay (QwtPlot *); ~EQDisplay (); -void show (std::complex *, int); +void show_channel (std::complex *, int); +void show_pilots (std::complex *, int); +void set_scopeMode (int); + private: QwtPlot *plotgrid; QwtPlotGrid *grid; QwtPlotCurve *spectrumCurve; QwtPlotCurve *phaseCurve; + int scopeMode; }; #endif diff --git a/decoders/drm-decoder/equalizer/equalizer-1.cpp b/decoders/drm-decoder/equalizer/equalizer-1.cpp index 32a33bd..82fd6d7 100644 --- a/decoders/drm-decoder/equalizer/equalizer-1.cpp +++ b/decoders/drm-decoder/equalizer/equalizer-1.cpp @@ -54,6 +54,7 @@ #include "basics.h" #include "equalizer-1.h" #include "estimator-1.h" +#include "estimator-eigen-2.h" #include "matrix2.h" #include "drm-decoder.h" @@ -72,7 +73,8 @@ equalizer_1::equalizer_1 (drmDecoder *parent, uint8_t Mode, uint8_t Spectrum, - int8_t strength, + int strength, + int f_cut_param, RingBuffer> *b): equalizer_base (Mode, Spectrum) { int16_t i, window; @@ -82,17 +84,17 @@ float **PHI; float **PHI_2; float *THETA; + this -> scopeMode = SHOW_PILOTS; this -> eqBuffer = b; connect (this, SIGNAL (show_eqsymbol (int)), parent, SLOT (show_eqsymbol (int))); - strength = 0; - + // Based on table 92 ETSI ES 201980 // Just for experimentation, we added some alternatives -int16_t symbols_per_window_list_0 [] = {4, 2, 2, 4}; -//int16_t symbols_per_window_list_0 [] = {6, 4, 4, 6}; +//int16_t symbols_per_window_list_0 [] = {4, 2, 2, 6}; +int16_t symbols_per_window_list_0 [] = {6, 4, 4, 6}; int16_t symbols_per_window_list_1 [] = {10, 6, 8, 6}; int16_t symbols_per_window_list_2 [] = {12, 8, 8, 6}; int16_t symbols_per_window_list_3 [] = {14, 10, 8, 6}; @@ -119,7 +121,8 @@ int16_t symbols_per_window_list_5 [] = {15, 15, 15, 6}; Ts = Ts_of (Mode); Tu = Tu_of (Mode); Tg = Tg_of (Mode); -// + + scopeMode = SHOW_PILOTS; // we kunnen het aantal trainers redelijk schatten door // het aantal pilots per symbol te benaderen (carriers / afstand) // en te vermenigvuldigen met het aantal symbols per window @@ -143,9 +146,9 @@ int16_t symbols_per_window_list_5 [] = {15, 15, 15, 6}; // // values taken from diorama f_cut_t = 0.0675 / symbols_to_delay; - f_cut_k = 1.75 * (float) Tg / (float) Tu; - f_cut_k = 2 * (float) Tg / (float) Tu; - f_cut_k = 1 * (float) Tg / (float) Tu; + f_cut_t = 0.001 / symbols_to_delay; +// f_cut_k = 1.75 * (float) Tg / (float) Tu; + f_cut_k = f_cut_param / 100.0 * (float) Tg / (float) Tu; // // This code is based on the diorama Matlab code, and a // (complete)rewrite of the C translation of this Matlab code by Ties Bos. @@ -252,16 +255,18 @@ int16_t symbols_per_window_list_5 [] = {15, 15, 15, 6}; // The W_symbol_blk filters are ready now // // and finally, the estimators - Estimators = new estimator_1 *[symbolsinFrame]; + estimators = new estimator_1 *[symbolsinFrame]; for (i = 0; i < symbolsinFrame; i ++) - Estimators [i] = new estimator_1 (refFrame, Mode, Spectrum, i); + estimators [i] = new estimator_1 (refFrame, Mode, Spectrum, i); + estimator_channel = new estimator_2 (refFrame, Mode, Spectrum, 0); } - equalizer_1::~equalizer_1 (void) { + equalizer_1::~equalizer_1 () { int16_t i; for (i = 0; i < symbolsinFrame; i ++) - delete Estimators [i]; - delete [] Estimators; + delete estimators [i]; + delete [] estimators; + delete estimator_channel; // // W_symbol_blk is a matrix with three dimensions for (int window = 0; window < windowsinFrame; window ++) { @@ -392,13 +397,22 @@ int16_t i; *delta_freq_offset = arg (offs1) / (3 * (symbolsinFrame - 1)); *delta_freq_offset = arg (offs7) / periodforSymbols; // *delta_freq_offset = (arg (offs1) + arg (offs7) / periodforSymbols) / 2; -// fprintf (stderr, "freq error: freq pilots = %f, all pilots = %f\n", -// arg (offs1) / (3 * (symbolsinFrame - 1)), -// arg (offs7) / periodforSymbols); -// - Estimators [newSymbol] -> + + std::vector> VV; + if ((newSymbol == 0) && scopeMode == SHOW_CHANNEL) { + estimator_channel -> estimate (testFrame [0], + pilotEstimates [0]. data (), VV); + std::complex xx [K_max - K_min + 1]; + for (int index = 0; index < VV. size (); index ++) { + xx [index] = VV [index]; + } + eqBuffer -> putDataIntoBuffer (xx, VV. size ()); + show_eqsymbol (VV. size ()); + } + estimators [newSymbol] -> estimate (testFrame [newSymbol], pilotEstimates [newSymbol]. data ()); + // For equalizing symbol X, we need the pilotvalues // from the symbols X - symbols_to_delay .. X + symbols_to_delay - 1 @@ -410,6 +424,12 @@ int16_t i; processSymbol (symbol_to_process, outFrame -> element (symbol_to_process), v); +// static int teller = 0; +// if (++teller >= 40) { +// teller = 0; +// Estimators [symbol_to_process] -> testQuality ( +// outFrame -> element (symbol_to_process)); +// } // If we have a frame full of output: return true return symbol_to_process == symbolsinFrame - 1; @@ -501,8 +521,14 @@ int16_t carrier; cdiv (refFrame [symbol][indexFor (carrier)], sum); } - if (symbol == 0) { - eqBuffer -> putDataIntoBuffer (refFrame [symbol], K_max - K_min + 1); + if ((symbol == 4) && (scopeMode == SHOW_PILOTS)) { + std::complex xx [K_max - K_min + 1]; + for (int carrier = K_min; carrier <= K_max; carrier ++) + if (isPilotCell (Mode, symbol, carrier)) + xx [carrier - K_min] = refFrame [symbol][carrier - K_min]; + else + xx [carrier - K_min] = std::complex (0, 0); + eqBuffer -> putDataIntoBuffer (xx, K_max - K_min + 1); show_eqsymbol (K_max - K_min + 1); } @@ -523,3 +549,7 @@ int16_t carrier; } } +void equalizer_1::set_scopeMode (int mode) { + scopeMode = mode; +} + diff --git a/decoders/drm-decoder/equalizer/equalizer-1.h b/decoders/drm-decoder/equalizer/equalizer-1.h index f216761..36cf735 100644 --- a/decoders/drm-decoder/equalizer/equalizer-1.h +++ b/decoders/drm-decoder/equalizer/equalizer-1.h @@ -31,6 +31,7 @@ #include #include "my-array.h" class estimator_1; +class estimator_2; class drmDecoder; typedef struct { int16_t symbol; @@ -43,9 +44,10 @@ Q_OBJECT equalizer_1 (drmDecoder *, uint8_t Mode, uint8_t Spectrum, - int8_t strength, + int strength, + int f_cut_k, RingBuffer> *); - ~equalizer_1 (void); + ~equalizer_1 (); bool equalize (std::complex *, int16_t, myArray*, @@ -57,12 +59,14 @@ Q_OBJECT float *, float *, std::vector> &); + void set_scopeMode (int); private: RingBuffer> *eqBuffer; void getRelAddress (int16_t, int16_t *, int16_t *); int16_t buildTrainers (int16_t); int16_t rndcnt; - estimator_1 **Estimators; + estimator_2 *estimator_channel; + estimator_1 **estimators; int16_t windowsinFrame; int16_t periodforPilots; int16_t periodforSymbols; @@ -80,6 +84,8 @@ Q_OBJECT int16_t Ts; int16_t Tu; int16_t Tg; + + int scopeMode; signals: void show_eqsymbol (int); }; diff --git a/decoders/drm-decoder/equalizer/estimator-2.cpp-eigen b/decoders/drm-decoder/equalizer/estimator-eigen-2.cpp similarity index 63% rename from decoders/drm-decoder/equalizer/estimator-2.cpp-eigen rename to decoders/drm-decoder/equalizer/estimator-eigen-2.cpp index d95e765..d7ce577 100644 --- a/decoders/drm-decoder/equalizer/estimator-2.cpp-eigen +++ b/decoders/drm-decoder/equalizer/estimator-eigen-2.cpp @@ -4,19 +4,20 @@ * 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 + * This file is part of the drm receiver + * + * drm receiver 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, + * drm receiver 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 + * along with drm receiver; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Simple channel estimator for DRM based on private communication @@ -24,7 +25,7 @@ */ #include #include "referenceframe.h" -#include "estimator-2.h" +#include "estimator-eigen-2.h" #include "matrix2.h" #include "basics.h" #include @@ -59,16 +60,21 @@ int16_t pilotIndex, tap; fftSize = Tu_of (Mode); numberofCarriers = K_max - K_min + 1; numberofPilots = getnrPilots (refSymbol); - numberofTaps = numberofPilots; -// numberofTaps = Tg_of (Mode) - 1; + numberofTaps = 2 * Tg_of (Mode) - 1; +// numberofTaps = numberofPilots; F_p = MatrixXd (numberofPilots, numberofTaps); S_p = MatrixXd (numberofPilots, numberofPilots); - F_p_inv = MatrixXd (numberofTaps, numberofPilots); + A_p = MatrixXd (numberofPilots, numberofTaps); + A_p_inv = MatrixXd (numberofTaps, numberofPilots); // pilotTable = new int16_t [numberofPilots]; // S_p is a diagonal matrix with the pilot values as they should be + for (int row = 0; row < numberofPilots; row ++) + for (int col = 0; col < numberofPilots; col ++) + S_p (row, col) = std::complex (0, 0); + for (carrier = K_min; carrier <= K_max; carrier ++) if (isPilotCell (Mode, refSymbol, carrier)) { pilotTable [next] = carrier; @@ -86,42 +92,65 @@ int16_t pilotIndex, tap; cdiv (createExp (2 * M_PI * (fftSize / 2 + pilotTable [pilotIndex]) * tap / fftSize), sqrt (fftSize)); -// cx_fmat M_A = S_p * F_p; // taps * pilots -// cx_fmat M_AT = M_A. t (); // pilots * taps -// cx_fmat M_B = M_AT * M_A; // taps * taps -// M_B = pinv (M_B); // taps * taps; -// F_p_inv = M_B * M_AT; // taps * pilots - F_p_inv = S_p * F_p; -// F_p_inv = temp. inverse (); + +// +// Note that A_p is not a square matrix, the number of taps +// is larger than the number of pilots, so we have to apply +// the formula +// A_p_inv = (A_p. transpose ()) * (A_p_transpose () * A_p). inverse () +// see: https://math.stackexchange.com/questions/1335693/invertible-matrix-of-non-square-matrix + A_p = S_p * F_p; + A_p_inv = A_p. transpose () * (A_p * A_p. transpose ()). inverse (); } - estimator_2::~estimator_2 (void) { + estimator_2::~estimator_2 () { delete[] pilotTable; } // void estimator_2::estimate (std::complex *testRow, - std::complex *resultRow) { -int16_t index; -//cx_fvec h_td (numberofTaps); -//cx_fvec H_fd (numberofPilots); -//cx_fvec X_p (numberofPilots); + std::complex *resultRow, + std::vector> &channel) { Vector h_td (numberofTaps); Vector H_fd (numberofPilots); Vector X_p (numberofPilots); -// - for (index = 0; index < numberofPilots; index ++) +// X_p are the observed values, and we have to "solve" +// X_p = A_P * h_td +// h_td = A_p_inv * X_p; +// H_fd = F_p * h_td; + + + for (int index = 0; index < numberofPilots; index ++) X_p (index) = testRow [indexFor (pilotTable [index])]; // //// Ok, the matrices are filled, now computing the channelvalues - h_td = F_p_inv. solve (X_p); + h_td = A_p_inv * X_p; H_fd = F_p * h_td; // - for (index = 0; index < numberofPilots; index ++) - resultRow [indexFor (pilotTable [index])] = - H_fd [index]; + for (int index = 0; index < numberofPilots; index ++) + resultRow [indexFor (pilotTable [index])] = H_fd [index]; + + channel. resize (numberofPilots); + for (int index = 0; index < numberofPilots; index ++) + channel. at (index) = h_td [index]; } +float estimator_2::testQuality (ourSignal *v) { +std::complex res = 0; +int count = 0; + + for (int carrier = K_min; carrier <= K_max; carrier ++) { + if (carrier == 0) + continue; + if (isPilotCell (Mode, refSymbol, carrier)) { + count ++; + res += v [indexFor (carrier)]. signalValue / + getPilotValue (Mode, Spectrum, refSymbol, carrier); + } + } + fprintf (stderr, "%f %f\n", arg (res), abs (res)/ count); + return abs (res); +} int16_t estimator_2::indexFor (int16_t carrier) { return carrier - K_min; } @@ -139,5 +168,3 @@ int16_t amount = 0; } return amount; } - - diff --git a/decoders/drm-decoder/equalizer/estimator-2.h-eigen b/decoders/drm-decoder/equalizer/estimator-eigen-2.h similarity index 73% rename from decoders/drm-decoder/equalizer/estimator-2.h-eigen rename to decoders/drm-decoder/equalizer/estimator-eigen-2.h index 4c9c100..79329b6 100644 --- a/decoders/drm-decoder/equalizer/estimator-2.h-eigen +++ b/decoders/drm-decoder/equalizer/estimator-eigen-2.h @@ -4,39 +4,45 @@ * 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 + * This file is part of the drm receiver + * + * drm receiver 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, + * drm receiver 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 + * along with drm receiver; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ # -#ifndef __ESTIMATOR_4__ -#define __ESTIMATOR_4__ +#ifndef __ESTIMATOR_EIGEN__ +#define __ESTIMATOR_EIGEN__ #include #include #include "radio-constants.h" -# +#include + using namespace Eigen; // The processor for estimating the channel(s) of a single -// symbol +// symbol using the "Eigen" library +// class estimator_2 { public: estimator_2 (std::complex **, uint8_t, uint8_t, int16_t); ~estimator_2 (); - void estimate (std::complex *, std::complex *); + void estimate (std::complex *, + std::complex *, + std::vector> &); + float testQuality (ourSignal *); private: std::complex **refFrame; uint8_t Mode; @@ -56,7 +62,8 @@ class estimator_2 { typedef Matrix, Dynamic, 1> Vector; MatrixXd F_p; MatrixXd S_p; - MatrixXd F_p_inv; + MatrixXd A_p; + MatrixXd A_p_inv; std::complex *pilotVector; int16_t *pilotTable; }; diff --git a/decoders/drm-decoder/msc/msc-processor.h b/decoders/drm-decoder/msc/msc-processor.h index a7bd09c..50f9f2f 100755 --- a/decoders/drm-decoder/msc/msc-processor.h +++ b/decoders/drm-decoder/msc/msc-processor.h @@ -6,7 +6,7 @@ * * This file is part of the SDRunoPlugin_drm * - * dmr plugin is free software; you can redistribute it and/or modify + * DRM plugin 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. diff --git a/decoders/fax-decoder/:1 b/decoders/fax-decoder/_1 old mode 100755 new mode 100644 similarity index 100% rename from decoders/fax-decoder/:1 rename to decoders/fax-decoder/_1 diff --git a/decoders/fax-decoder/fax-decoder.cpp b/decoders/fax-decoder/fax-decoder.cpp index 45c5b77..a7923b5 100755 --- a/decoders/fax-decoder/fax-decoder.cpp +++ b/decoders/fax-decoder/fax-decoder.cpp @@ -604,7 +604,6 @@ faxParams *myfaxParameters = getFaxParams (s); currentSampleIndex = 0; faxState = APTSTART; delete theImage; - delete theImage; theImage = new faxImage (numberofColumns, lastRow); rawData. resize (1024 * 1024); theImage -> clear (); diff --git a/decoders/psk-decoder-ok/viterbi.cpp b/decoders/psk-decoder-ok/viterbi.cpp deleted file mode 100644 index 3c92459..0000000 --- a/decoders/psk-decoder-ok/viterbi.cpp +++ /dev/null @@ -1,286 +0,0 @@ -# -/* - * Copyright (C) 2010, 2011, 2012 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Programming - * - * 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 - * - * viterbi.c -- Viterbi decoder - * - * Copyright (C) 2001, 2002, 2003 - * Tomi Manninen (oh2bns@sral.fi) - * - * This file is part of gMFSK. - * It is adapted for use in the JSDR - * software. - * - * gMFSK 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. - * - * gMFSK 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 gMFSK; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "viterbi.h" -/* - * The viterbi algorithm has been recoded for fitness in the - * SDR-J framwork. - * In this recoding, emphasis was on improved readability - */ - viterbi::viterbi (int32_t k, int32_t poly1, int32_t poly2) { -int32_t i, j; - - v_traceback = PATHMEM - 1; - v_chunksize = 8; - NumberofStates = 1 << (k - 1); - LengthofShiftregister = k - 1; - Poly1 = poly1; - Poly2 = poly2; - - dibitTable [0] = new int32_t [NumberofStates]; - dibitTable [1] = new int32_t [NumberofStates]; - for (i = 0; i < NumberofStates; i ++) { - dibitTable [0] [i] = Dibitsfor (i, 0); - dibitTable [1] [i] = Dibitsfor (i, 1); - } - - metrics = new int32_t *[PATHMEM]; - history = new int32_t *[PATHMEM]; - sequence = new int32_t [PATHMEM]; - - for (i = 0; i < PATHMEM; i++) { - metrics [i] = new int32_t [NumberofStates]; - history [i] = new int32_t [NumberofStates]; - sequence [i] = 0; - for (j = 0; j < NumberofStates; j ++) { - metrics [i][j] = 0; - history [i][j] = 0; - } - } -/* - * Initialize metrics table - * Assume a symbol value of 0 is the strongest possible 0 - * and a symbol value of 255 is the strongest possible 1 - * a symbol of 128 is an erasure. - */ - for (i = 0; i < 256; i++) { - mettab [0][i] = 128 - i; - mettab [1][i] = i - 128; - } - - ptr = 0; -} - - viterbi::~viterbi () { -int32_t i; - delete[] dibitTable [0]; - delete[] dibitTable [1]; - for (i = 0; i < PATHMEM; i++) { - delete[] metrics [i]; - delete[] history [i]; - } - - delete[] sequence; - delete[] metrics; - delete[] history; -} -/* - * when in state "state" and we receive bit "bit" - * we output two dibits - * one using the "top" register and polynome, - * the other one using the "bottom" register and polynome - */ -int32_t viterbi::Dibitsfor (uint32_t state, int32_t bit) { -int32_t i; -uint32_t topRegister, bottomRegister; -uint32_t firstDibit = 0; -uint32_t secondDibit = 0; - - topRegister = ((state << 1) | (bit & 01)) & Poly1; - bottomRegister = ((state << 1) | (bit & 01)) & Poly2; -/* - * now xor the individual bits - */ - for (i = 0; i < LengthofShiftregister + 1; i++) { - firstDibit ^= topRegister & 01; - topRegister >>= 1; - } - - for (i = 0; i < LengthofShiftregister + 1; i ++) { - secondDibit ^= bottomRegister & 01; - bottomRegister >>= 1; - } - - return (secondDibit << 1) | firstDibit; -} - -int32_t viterbi::viterbi_decode (unsigned char *sym, int32_t *metric) { -uint32_t currptr, prevptr; -uint32_t CurrentState, bestState; -int32_t i, j, metricsAddition [4], bestMetric; - - currptr = ptr; - prevptr = (ptr - 1) % PATHMEM; - - metricsAddition [0] = mettab [0][sym [1]] + mettab [0][sym [0]]; - metricsAddition [1] = mettab [0][sym [1]] + mettab [1][sym [0]]; - metricsAddition [3] = mettab [1][sym [1]] + mettab [1][sym [0]]; - metricsAddition [2] = mettab [1][sym [1]] + mettab [0][sym [0]]; - - for (CurrentState = 0; - CurrentState < (uint32_t)NumberofStates; CurrentState ++) { - int32_t predecessorState_0, predecessorState_1; - int32_t metrics_0; - int32_t metrics_1; - int32_t entrybit = CurrentState & 01; -/* - * we know that each state has two predecessors, to be obtained - * by shifting the "youngest" bit out and adding "oldest" bits - * zero or one. - */ - predecessorState_0 = (CurrentState >> 1) | - (0 << (LengthofShiftregister - 1)); - predecessorState_1 = (CurrentState >> 1) | - (1 << (LengthofShiftregister - 1)); -/* - * we look for the additional metrics, obtained - * by looking at the metricsAddition applied to the - * dibits being outputted in the predecessorstate - */ - metrics_0 = metrics [prevptr][predecessorState_0] + - metricsAddition [dibitTable [entrybit][predecessorState_0]]; - metrics_1 = metrics [prevptr][predecessorState_1] + - metricsAddition [dibitTable [entrybit][predecessorState_1]]; - - if (metrics_0 > metrics_1) { - metrics [currptr][CurrentState] = metrics_0; - history [currptr][CurrentState] = predecessorState_0; - } else { - metrics [currptr][CurrentState] = metrics_1; - history [currptr][CurrentState] = predecessorState_1; - } - } -/* - * OK, now for this pointerposition, all states have - * got their "best" metrics and the predecessor to - * get here. - */ - ptr = (ptr + 1) % PATHMEM; - if ((ptr % v_chunksize) == 0) { - bestMetric = INT_MIN; - bestState = 0; - - for (i = 0; i < NumberofStates; i++) { - if (metrics [currptr][i] > bestMetric) { - bestMetric = metrics [currptr][i]; - bestState = i; - } - } - - return traceback (currptr, bestState, metric); - } - - if (metrics [currptr][0] > INT_MAX / 2) { - for (i = 0; i < PATHMEM; i++) - for (j = 0; j < NumberofStates; j++) - metrics [i][j] -= INT_MAX / 2; - } - - if (metrics [currptr][0] < INT_MIN / 2) { - for (i = 0; i < PATHMEM; i++) - for (j = 0; j < NumberofStates; j++) - metrics [i][j] += INT_MIN / 2; - } - - return -1; -} -/* - * Trace back 'traceback' steps, starting from the best state - * and decode the "chuncksize" amount of bits - */ -int32_t viterbi::traceback (uint32_t p, int32_t beststate, int32_t *metric) { -uint32_t c; // the result -uint32_t prev; // pointer -int32_t localMetrics; -int32_t i; - - sequence [p] = beststate; - for (i = 0; i < v_traceback; i++) { - prev = (p - 1) % PATHMEM; - sequence [prev] = history [p][sequence[p]]; - p = prev; - } - - localMetrics = metrics [p][sequence[p]]; -/* - * Decode 'chunksize' bits - */ - c = 0; - for (i = 0; i < v_chunksize; i++) { -/* - * low bit of state is the previous input bit - */ - c = (c << 1) | (sequence [p] & 1); - p = (p + 1) % PATHMEM; - } - - localMetrics = metrics [p][sequence [p]] - localMetrics; - if (metric) - *metric = localMetrics; - - return c; -} - -int32_t viterbi::viterbi_set_traceback (int32_t traceback) { - if (traceback < 0 || traceback > PATHMEM - 1) - return -1; - - v_traceback = traceback; - return 0; -} - -int32_t viterbi::viterbi_set_chunksize (int32_t chunksize) { - if (chunksize < 1 || chunksize > v_traceback) - return -1; - - v_chunksize = chunksize; - return 0; -} - -void viterbi::viterbi_reset() { -int32_t i; - - for (i = 0; i < PATHMEM; i++) { - memset (metrics [i], 0, NumberofStates * sizeof(int)); - memset (history [i], 0, NumberofStates * sizeof(int)); - } - - ptr = 0; -} - diff --git a/decoders/psk-decoder-ok/viterbi.h b/decoders/psk-decoder-ok/viterbi.h deleted file mode 100644 index 907c294..0000000 --- a/decoders/psk-decoder-ok/viterbi.h +++ /dev/null @@ -1,81 +0,0 @@ -# -/* - * Copyright (C) 2010, 2011, 2012 - * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Programming - * - * 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 - * - * viterbi.h -- Viterbi decoder - * - * Copyright (C) 2001, 2002, 2003 - * Tomi Manninen (oh2bns@sral.fi) - * - * This file is adapted from gMFSK for use in the ESDR software. - * - * gMFSK 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. - * - * gMFSK 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 gMFSK; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __VITERBI_DECODER_H__ -#define __VITERBI_DECODER_H__ -#include -#include -#include -#include - -#define PATHMEM 64 - -class viterbi { -public: - viterbi (int32_t, int32_t, int32_t); - ~viterbi (); - int32_t viterbi_set_traceback (int32_t); - int32_t viterbi_set_chunksize (int32_t); - int32_t viterbi_decode (unsigned char *, int32_t *); - void viterbi_reset (void); -private: - int32_t traceback (uint32_t, int32_t, int32_t *); - int32_t v_traceback; - int32_t LengthofShiftregister; - int32_t NumberofStates; - int32_t Poly1; - int32_t Poly2; - int32_t *dibitTable [2]; - int32_t Dibitsfor (uint32_t, int32_t); - int32_t v_chunksize; - int32_t **metrics; - int32_t **history; - int32_t *sequence; - int32_t mettab [2][256]; - uint32_t ptr; -}; -#endif diff --git a/decoders/psk-decoder/psk-decoder.cpp b/decoders/psk-decoder/psk-decoder.cpp index 8d6675e..1e60e84 100644 --- a/decoders/psk-decoder/psk-decoder.cpp +++ b/decoders/psk-decoder/psk-decoder.cpp @@ -62,19 +62,22 @@ myFrame. show (); setup_pskDecoder (rate); + screenwidth = 256; screenwidth = 1000; x_axis = new double [screenwidth]; for (int i = 0; i < screenwidth; i ++) x_axis [i] = - screenwidth / 2 + i; y_values = new double [screenwidth]; - newFilter = new LowPassFIR (21, searchRange / 2, theRate); + theFilter = new decimatingFIR (35, screenwidth / 2, PSKRATE, 2); + newFilter = new LowPassFIR (21, screenwidth / 2, theRate); pskViewer = new waterfallScope (pskScope, screenwidth, 30); + the_fft = new common_fft (screenwidth); + fftBuffer = the_fft -> getVector (); newFFT = new slidingFFT (screenwidth, 0, screenwidth - 1); connect (pskViewer, SIGNAL (clickedwithLeft (int)), this, SLOT (handleClick (int))); - psk_setup (); restore_GUISettings (pskSettings); @@ -87,12 +90,6 @@ psk_setFilterDegree (pskFilterDegreeTrigger -> value ()); pskText = QString (); - pskSettings -> beginGroup ("pskDecoder"); - searchRange = pskSettings -> value ("psk_searchRange", 400). toInt (); - pskSettings -> endGroup (); - psk_rangeSetter -> setValue (searchRange); - connect (psk_rangeSetter, SIGNAL (valueChanged (int)), - this, SLOT (set_searchRange (int))); connect (pskAfconTrigger, SIGNAL (activated (const QString &)), this, SLOT (psk_setAfcon (const QString &))); connect (pskReverseTrigger, SIGNAL (activated (const QString &)), @@ -120,8 +117,6 @@ pskModeTrigger -> currentText ()); pskSettings -> setValue ("pskFilterDegreeTrigger", pskFilterDegreeTrigger -> value ()); - pskSettings -> setValue ("psk_searchRange", searchRange); - pskSettings -> endGroup (); delete viterbiDecoder; delete BPM_Filter; @@ -318,9 +313,9 @@ std::complex v [PSKRATE / 8]; audioOut -> putDataIntoBuffer (&z, 1); // we down-mix the signal to a zero-centered one, old_z = z; - z = newFilter -> Pass (z); - z = localShifter. do_shift (z, psk_IF); z = BPM_Filter -> Pass (z); + z = localShifter. do_shift (z, psk_IF); + z = newFilter -> Pass (z); // // and resample to PSKRATE @@ -330,29 +325,35 @@ std::complex v [PSKRATE / 8]; #define NO_OFFSET_FOUND -500 std::complex outV [2000]; - +static int fftTeller = 0; // Now we are on PSKRATE for (i = 0; i < cnt; i ++) { int j; - newFFT -> do_FFT (out [i], outV); - fillP ++; - if (fillP < screenwidth / 2) - continue; - for (int j = 0; j < screenwidth; j ++) - y_values [j] = - abs (outV [(screenwidth / 2 + j) % screenwidth]); + std::complex res; + if (theFilter -> Pass (out [i], &res)) { + fftBuffer [fillP ++] = res; + newFFT -> do_FFT (res, outV); + if (fillP < screenwidth / 2) + continue; + for (int j = fillP; j < screenwidth; j ++) + fftBuffer [j] = std::complex< float> (0, 0); +// the_fft -> do_FFT (); + for (int j = 0; j < screenwidth; j ++) + y_values [j] = + abs (outV [(screenwidth / 2 + j) % screenwidth]); pskViewer -> display (x_axis, y_values, amplitudeSlider -> value (), 0, 0); fillP = 0; - int offs = offset (outV); - if ((offs != NO_OFFSET_FOUND) && (abs (offs) >= 3)) { - if ((- searchRange / 2 < psk_IF + offs) && - (psk_IF + offs / 2 < searchRange)) { + fftTeller ++; + if (fftTeller >= 4) { + int offs = offset (outV); + fprintf (stderr, "offset = %d\n", offs); + if ((offs != NO_OFFSET_FOUND) && (abs (offs) >= 3)) psk_IF += offs / 2; - } - } - - newFFT -> reset (); + fftTeller = 0; + newFFT -> reset (); + } + } } for (i = 0; i < cnt; i ++) { @@ -361,6 +362,7 @@ std::complex outV [2000]; doDecode (out [i]); } } + /* * now we are finally back on 16 samples per symbol * to apply the "standard" algorithm @@ -634,35 +636,37 @@ int k; } void pskDecoder::handleClick (int a) { -// fprintf (stderr, "adjust %d\n", a); + fprintf (stderr, "adjust %d\n", a); adjustFrequency (a); } -#define MAX_SIZE 20 +#define MAX_SIZE 50 int pskDecoder::offset (std::complex *v) { float avg = 0; float max = 0; float supermax = 0; int superIndex = 0; +// for (int i = 0; i < screenwidth; i ++) +// v [(screenwidth / 2 + i) % screenwidth] = +// std::complex (2 * sin ((float)i / (M_PI)), 0); for (int i = 0; i < screenwidth; i ++) avg += abs (v [i]); avg /= screenwidth; - - int index = screenwidth - searchRange / 2; + int index = screenwidth - 200; for (int i = 0; i < MAX_SIZE; i ++) max += abs (v [index + i]); supermax = max; - for (int i = MAX_SIZE; i < searchRange; i ++) { + for (int i = MAX_SIZE; i < 400; i ++) { max -= abs (v [(index + i - MAX_SIZE) % screenwidth]); max += abs (v [(index + i) % screenwidth]); if (max > supermax) { - superIndex = (index + i - MAX_SIZE / 2); + superIndex = (index + i - MAX_SIZE / 2) % screenwidth; supermax = max; } } -// fprintf (stderr, "%f (%f) %d\n", supermax / MAX_SIZE, avg, superIndex); + fprintf (stderr, "%f (%f) %d\n", supermax / MAX_SIZE, avg, superIndex); if (supermax / MAX_SIZE > 3 * avg) return superIndex > screenwidth / 2 ? superIndex - screenwidth : @@ -670,9 +674,3 @@ int superIndex = 0; else return NO_OFFSET_FOUND; } - -void pskDecoder::set_searchRange (int n) { - searchRange = n; - newFilter -> newKernel (n / 2); -} - diff --git a/decoders/psk-decoder/psk-decoder.h b/decoders/psk-decoder/psk-decoder.h index cf022d1..73ffa7e 100644 --- a/decoders/psk-decoder/psk-decoder.h +++ b/decoders/psk-decoder/psk-decoder.h @@ -61,7 +61,6 @@ private slots: void psk_setMode (const QString &); void psk_setFilterDegree (int); void handleClick (int); - void set_searchRange (int); private: enum PskMode { @@ -138,8 +137,6 @@ private slots: std::vector theTable; std::vector > inTable; int16_t tablePointer; - - int searchRange; // // former signals are now handled locally QString pskText; diff --git a/decoders/psk-decoder/psk-decoder.ui b/decoders/psk-decoder/psk-decoder.ui index 61c8800..b52e0ab 100644 --- a/decoders/psk-decoder/psk-decoder.ui +++ b/decoders/psk-decoder/psk-decoder.ui @@ -260,28 +260,6 @@ - - - - 10 - 130 - 121 - 31 - - - - 100 - - - 800 - - - 25 - - - 400 - - diff --git a/decoders/psk-decoder-ok/CMakeLists.txt b/decoders/psk-decoder/psk-decoder/CMakeLists.txt similarity index 100% rename from decoders/psk-decoder-ok/CMakeLists.txt rename to decoders/psk-decoder/psk-decoder/CMakeLists.txt diff --git a/decoders/psk-decoder-ok/psk-decoder.cpp b/decoders/psk-decoder/psk-decoder/psk-decoder.cpp similarity index 92% rename from decoders/psk-decoder-ok/psk-decoder.cpp rename to decoders/psk-decoder/psk-decoder/psk-decoder.cpp index 1e60e84..ba2c6da 100644 --- a/decoders/psk-decoder-ok/psk-decoder.cpp +++ b/decoders/psk-decoder/psk-decoder/psk-decoder.cpp @@ -2,7 +2,7 @@ /* * Copyright (C) 2010, 2011, 2012, 2013 * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Programming + * Lazy Chair Computing * * This file is part of the swradio * @@ -62,22 +62,19 @@ myFrame. show (); setup_pskDecoder (rate); - screenwidth = 256; screenwidth = 1000; x_axis = new double [screenwidth]; for (int i = 0; i < screenwidth; i ++) x_axis [i] = - screenwidth / 2 + i; y_values = new double [screenwidth]; - theFilter = new decimatingFIR (35, screenwidth / 2, PSKRATE, 2); - newFilter = new LowPassFIR (21, screenwidth / 2, theRate); + newFilter = new LowPassFIR (21, searchRange / 2, theRate); pskViewer = new waterfallScope (pskScope, screenwidth, 30); - the_fft = new common_fft (screenwidth); - fftBuffer = the_fft -> getVector (); newFFT = new slidingFFT (screenwidth, 0, screenwidth - 1); connect (pskViewer, SIGNAL (clickedwithLeft (int)), this, SLOT (handleClick (int))); + psk_setup (); restore_GUISettings (pskSettings); @@ -90,6 +87,12 @@ psk_setFilterDegree (pskFilterDegreeTrigger -> value ()); pskText = QString (); + pskSettings -> beginGroup ("pskDecoder"); + searchRange = pskSettings -> value ("psk_searchRange", 400). toInt (); + pskSettings -> endGroup (); + psk_rangeSetter -> setValue (searchRange); + connect (psk_rangeSetter, SIGNAL (valueChanged (int)), + this, SLOT (set_searchRange (int))); connect (pskAfconTrigger, SIGNAL (activated (const QString &)), this, SLOT (psk_setAfcon (const QString &))); connect (pskReverseTrigger, SIGNAL (activated (const QString &)), @@ -117,6 +120,8 @@ pskModeTrigger -> currentText ()); pskSettings -> setValue ("pskFilterDegreeTrigger", pskFilterDegreeTrigger -> value ()); + pskSettings -> setValue ("psk_searchRange", searchRange); + pskSettings -> endGroup (); delete viterbiDecoder; delete BPM_Filter; @@ -126,11 +131,11 @@ delete newFFT; } -int32_t pskDecoder::rateOut (void) { +int32_t pskDecoder::rateOut () { return theRate; } -int16_t pskDecoder::detectorOffset (void) { +int16_t pskDecoder::detectorOffset () { return psk_IF; } @@ -313,9 +318,9 @@ std::complex v [PSKRATE / 8]; audioOut -> putDataIntoBuffer (&z, 1); // we down-mix the signal to a zero-centered one, old_z = z; - z = BPM_Filter -> Pass (z); - z = localShifter. do_shift (z, psk_IF); z = newFilter -> Pass (z); + z = localShifter. do_shift (z, psk_IF); + z = BPM_Filter -> Pass (z); // // and resample to PSKRATE @@ -325,35 +330,29 @@ std::complex v [PSKRATE / 8]; #define NO_OFFSET_FOUND -500 std::complex outV [2000]; -static int fftTeller = 0; + // Now we are on PSKRATE for (i = 0; i < cnt; i ++) { int j; - std::complex res; - if (theFilter -> Pass (out [i], &res)) { - fftBuffer [fillP ++] = res; - newFFT -> do_FFT (res, outV); - if (fillP < screenwidth / 2) - continue; - for (int j = fillP; j < screenwidth; j ++) - fftBuffer [j] = std::complex< float> (0, 0); -// the_fft -> do_FFT (); - for (int j = 0; j < screenwidth; j ++) - y_values [j] = - abs (outV [(screenwidth / 2 + j) % screenwidth]); + newFFT -> do_FFT (out [i], outV); + fillP ++; + if (fillP < screenwidth / 2) + continue; + for (int j = 0; j < screenwidth; j ++) + y_values [j] = + abs (outV [(screenwidth / 2 + j) % screenwidth]); pskViewer -> display (x_axis, y_values, amplitudeSlider -> value (), 0, 0); fillP = 0; - fftTeller ++; - if (fftTeller >= 4) { - int offs = offset (outV); - fprintf (stderr, "offset = %d\n", offs); - if ((offs != NO_OFFSET_FOUND) && (abs (offs) >= 3)) + int offs = offset (outV); + if ((offs != NO_OFFSET_FOUND) && (abs (offs) >= 3)) { + if ((- searchRange / 2 < psk_IF + offs) && + (psk_IF + offs / 2 < searchRange)) { psk_IF += offs / 2; - fftTeller = 0; - newFFT -> reset (); - } - } + } + } + + newFFT -> reset (); } for (i = 0; i < cnt; i ++) { @@ -362,7 +361,6 @@ static int fftTeller = 0; doDecode (out [i]); } } - /* * now we are finally back on 16 samples per symbol * to apply the "standard" algorithm @@ -464,6 +462,8 @@ double error; void pskDecoder::bpsk_bit (uint16_t bit) { int16_t c; + if (pskReverse) + bit = !bit; pskShiftReg = (pskShiftReg << 1) | !!bit; if ((pskShiftReg & 03) == 0) { c = pskVaridecode (pskShiftReg >> 2); @@ -636,37 +636,35 @@ int k; } void pskDecoder::handleClick (int a) { - fprintf (stderr, "adjust %d\n", a); +// fprintf (stderr, "adjust %d\n", a); adjustFrequency (a); } -#define MAX_SIZE 50 +#define MAX_SIZE 20 int pskDecoder::offset (std::complex *v) { float avg = 0; float max = 0; float supermax = 0; int superIndex = 0; -// for (int i = 0; i < screenwidth; i ++) -// v [(screenwidth / 2 + i) % screenwidth] = -// std::complex (2 * sin ((float)i / (M_PI)), 0); for (int i = 0; i < screenwidth; i ++) avg += abs (v [i]); avg /= screenwidth; - int index = screenwidth - 200; + + int index = screenwidth - searchRange / 2; for (int i = 0; i < MAX_SIZE; i ++) max += abs (v [index + i]); supermax = max; - for (int i = MAX_SIZE; i < 400; i ++) { + for (int i = MAX_SIZE; i < searchRange; i ++) { max -= abs (v [(index + i - MAX_SIZE) % screenwidth]); max += abs (v [(index + i) % screenwidth]); if (max > supermax) { - superIndex = (index + i - MAX_SIZE / 2) % screenwidth; + superIndex = (index + i - MAX_SIZE / 2); supermax = max; } } - fprintf (stderr, "%f (%f) %d\n", supermax / MAX_SIZE, avg, superIndex); +// fprintf (stderr, "%f (%f) %d\n", supermax / MAX_SIZE, avg, superIndex); if (supermax / MAX_SIZE > 3 * avg) return superIndex > screenwidth / 2 ? superIndex - screenwidth : @@ -674,3 +672,9 @@ int superIndex = 0; else return NO_OFFSET_FOUND; } + +void pskDecoder::set_searchRange (int n) { + searchRange = n; + newFilter -> newKernel (n / 2); +} + diff --git a/decoders/psk-decoder-ok/psk-decoder.h b/decoders/psk-decoder/psk-decoder/psk-decoder.h similarity index 98% rename from decoders/psk-decoder-ok/psk-decoder.h rename to decoders/psk-decoder/psk-decoder/psk-decoder.h index 73ffa7e..2057db0 100644 --- a/decoders/psk-decoder-ok/psk-decoder.h +++ b/decoders/psk-decoder/psk-decoder/psk-decoder.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2010, 2011, 2012, 2013 * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Programming + * Lazy Chair Computing * * This file is part of swradio * @@ -61,6 +61,7 @@ private slots: void psk_setMode (const QString &); void psk_setFilterDegree (int); void handleClick (int); + void set_searchRange (int); private: enum PskMode { @@ -137,6 +138,8 @@ private slots: std::vector theTable; std::vector > inTable; int16_t tablePointer; + + int searchRange; // // former signals are now handled locally QString pskText; diff --git a/decoders/psk-decoder-ok/psk-decoder.ui b/decoders/psk-decoder/psk-decoder/psk-decoder.ui similarity index 93% rename from decoders/psk-decoder-ok/psk-decoder.ui rename to decoders/psk-decoder/psk-decoder/psk-decoder.ui index b52e0ab..61c8800 100644 --- a/decoders/psk-decoder-ok/psk-decoder.ui +++ b/decoders/psk-decoder/psk-decoder/psk-decoder.ui @@ -260,6 +260,28 @@ + + + + 10 + 130 + 121 + 31 + + + + 100 + + + 800 + + + 25 + + + 400 + + diff --git a/decoders/cw-new/viterbi.cpp b/decoders/psk-decoder/psk-decoder/viterbi.cpp similarity index 97% rename from decoders/cw-new/viterbi.cpp rename to decoders/psk-decoder/psk-decoder/viterbi.cpp index 3c92459..e035a52 100644 --- a/decoders/cw-new/viterbi.cpp +++ b/decoders/psk-decoder/psk-decoder/viterbi.cpp @@ -2,12 +2,9 @@ /* * Copyright (C) 2010, 2011, 2012 * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Programming + * 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 diff --git a/decoders/cw-new/viterbi.h b/decoders/psk-decoder/psk-decoder/viterbi.h similarity index 98% rename from decoders/cw-new/viterbi.h rename to decoders/psk-decoder/psk-decoder/viterbi.h index 907c294..12f5b45 100644 --- a/decoders/cw-new/viterbi.h +++ b/decoders/psk-decoder/psk-decoder/viterbi.h @@ -52,7 +52,8 @@ #include #include -#define PATHMEM 64 +#define PATHMEM 8 +//#define PATHMEM 64 class viterbi { public: diff --git a/decoders/ssb-decoder/ssb-decoder.cpp b/decoders/ssb-decoder/ssb-decoder.cpp index 32f81f7..cd1f090 100644 --- a/decoders/ssb-decoder/ssb-decoder.cpp +++ b/decoders/ssb-decoder/ssb-decoder.cpp @@ -30,8 +30,7 @@ ssbDecoder::ssbDecoder (int32_t inRate, RingBuffer *buffer, QSettings *settings): - virtualDecoder (inRate, buffer), - SSB_Filter (31, 0.25, inRate) { + virtualDecoder (inRate, buffer) { this -> inRate = inRate; (void)settings; myFrame = new QFrame; @@ -90,7 +89,7 @@ int32_t i; } void ssbDecoder::process (std::complex z) { - std::complex temp = SSB_Filter. Pass (z); + std::complex temp = z; if (mode == USB_MODE) temp = std::complex (real (temp) - imag (temp), real (temp) - imag (temp)); diff --git a/decoders/ssb-decoder/ssb-decoder.h b/decoders/ssb-decoder/ssb-decoder.h index c8b3f8c..611ad20 100644 --- a/decoders/ssb-decoder/ssb-decoder.h +++ b/decoders/ssb-decoder/ssb-decoder.h @@ -2,12 +2,9 @@ /* * Copyright (C) 2017 * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Programming + * 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 @@ -24,8 +21,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __SSB_DECODER__ -#define __SSB_DECODER__ +#ifndef __SSB_DECODER_H +#define __SSB_DECODER_H #include #include "virtual-decoder.h" #include "ui_ssb-decoder.h" @@ -52,7 +49,6 @@ Q_OBJECT adaptiveFilter *adaptive; bool adaptiveFiltering; int counter; - HilbertFilter SSB_Filter; uint8_t mode; private slots: void set_adaptiveFilter (void); diff --git a/decoders/test-decoder/test-decoder.cpp b/decoders/test-decoder/test-decoder.cpp index a6a5ac0..40fe8db 100644 --- a/decoders/test-decoder/test-decoder.cpp +++ b/decoders/test-decoder/test-decoder.cpp @@ -2,7 +2,7 @@ /* * Copyright (C) 2017 * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Programming + * Lazy Chair Computing * * This file is part of the swradio * swradio is free software; you can redistribute it and/or modify @@ -27,37 +27,33 @@ testDecoder::testDecoder (int32_t inRate, RingBuffer *buffer, QSettings *settings) : - virtualDecoder (inRate, buffer) { + virtualDecoder (inRate, buffer), + baseFilter (55, 4500, inRate), + s2Filter (8192), + s3Filter (8192), + usbFilter (8192, 511), + lsbFilter (8192, 511) { + myFrame = new QFrame; setupUi (myFrame); myFrame -> show (); this -> inputRate = inRate; - this -> outputRate = 600; - this -> samplesperSymbol = 60; - - x_axis = new double [samplesperSymbol]; - for (int i = 0; i < samplesperSymbol; i ++) - x_axis [i] = (i * 0.73 - samplesperSymbol / 2 * 0.73); - y_values = new double [samplesperSymbol]; - theFilter = new decimatingFIR (55, 100, inputRate, inputRate / 750); + this -> outputRate = 12000; + this -> audioBuffer = buffer; + for (int i = 0; i < 512; i ++) + x_axis [i] = i; the_fft = new common_fft (1024); fftBuffer = the_fft -> getVector (); - theCache = new Cache (samplesperSymbol, - 4 * 162); - Viewer = new waterfallScope (testSpectrum, - samplesperSymbol, 30); + Viewer = new spectrumScope (testSpectrum, 512); counter = 30; - cacheLineP = 0; - fillP = 0; - cacheSize = 4 * 162; - connect (Viewer, SIGNAL (clickedwithLeft (int)), this, SLOT (handleClick (int))); + usbFilter. setBand (40, 4000, inRate); + lsbFilter. setBand (-4000, -40, inRate); } testDecoder::~testDecoder (void) { delete myFrame; - delete theFilter; } void testDecoder::processBuffer (std::complex *buffer, @@ -68,68 +64,36 @@ int i; process (buffer [i]); } // -// The tone distance is 1.4648 Hz, the tone duration is -// 1/1.4648 = 0.68 seconds. -// we want to be able to separate half tones, i.e. two bins -// per tone. This means a bin-width of 0.732 Hz. -// If we take an FFT of 1024 bins, that means a samplerate -// of 750. In order to get 4 lines for each tone instance, we -// need 750 * 0.68 * 0.25 samples to create an FFT, i.e. 127/128 -// samples. // void testDecoder::process (std::complex z) { -int i, j; -std::complex res; -std::complex v [1024]; -static bool switcher = false; - - if (theFilter -> Pass (z, &res)) { - fftBuffer [fillP++] = cmul (res, 2); - if (fillP < (switcher ? 128 : 127)) - return; - - switcher = !switcher; - for (i = fillP; i < 1024; i ++) - fftBuffer [i] = std::complex (0, 0); - the_fft -> do_FFT (); - - for (i = 0; i < 1024 / 2; i ++) { - v [i] = fftBuffer [1024 / 2 + i]; - v [1024 / 2 + i] = fftBuffer [i]; - } +static int counter = 0; +static std::complex old_usb = std::complex (0, 0); +static std::complex old_lsb = std::complex (0, 0); - for (i = 0; i < samplesperSymbol; i ++) - (theCache -> cacheLine (cacheLineP)) [i] = - v [1024 / 2 - samplesperSymbol / 2 + i]; - for (i = 0; i < samplesperSymbol; i ++) - y_values [i] = abs (theCache -> cacheElement (cacheLineP, i)); + z = baseFilter. Pass (z); + z = std::complex (real (z) / abs (z), + imag (z) / abs (z)); + std::complex usbBand = usbFilter. Pass (z); + std::complex lsbBand = lsbFilter. Pass (z); + std::complex USB = s2Filter. Pass (real (usbBand) - imag (usbBand)); + std::complex LSB = s3Filter. Pass (real (lsbBand) + imag (lsbBand)); - Viewer -> display (x_axis, y_values, - amplitudeSlider -> value (), - 0, 0); - cacheLineP ++; + float plusSignal = arg (USB); + float minusSignal = arg (LSB); +// float plusSignal = arg (USB * conj (old_usb)); + old_usb = USB; + old_lsb = LSB; - if (cacheLineP % 20 == 0) { - int maxLine = -1; - float maxLineSum = 0; - for (i = 10; i < samplesperSymbol - 10; i ++) { - float sum = 0; - for (j = 0; j < 50; j ++) - for (int k = 0; k < 8; k ++) - sum += abs (theCache -> cacheElement (j, i + k)); - if (sum > maxLineSum) { - maxLineSum = sum; - maxLine = i; - } - } - fprintf (stderr, "maxLine = %d\n", maxLine); - } - - if (cacheLineP >= cacheSize) - cacheLineP = 0; - fillP = 0; - - } + std::complex combined = + std::complex (minusSignal, minusSignal); + audioBuffer -> putDataIntoBuffer (&combined, 1); + counter ++; + if (counter > inputRate / 10) { + setDetectorMarker (0); + counter = 0; + emit audioAvailable (audioOut -> GetRingBufferReadAvailable () / 10, + inputRate); + } } void testDecoder::handleClick (int a) { diff --git a/decoders/test-decoder/test-decoder.h b/decoders/test-decoder/test-decoder.h index 935b5bf..623a424 100644 --- a/decoders/test-decoder/test-decoder.h +++ b/decoders/test-decoder/test-decoder.h @@ -27,10 +27,11 @@ #include "virtual-decoder.h" #include "ui_test-decoder.h" #include "fir-filters.h" +#include "fft-filters.h" #include "fft.h" -#include "waterfall-scope.h" +#include "spectrum-scope.h" +#include "hilbertfilter.h" -class Cache; class QSettings; class testDecoder: public virtualDecoder, public Ui_test_decoder { @@ -43,23 +44,23 @@ Q_OBJECT void processBuffer (std::complex *, int32_t); void process (std::complex z); - private: + LowPassFIR baseFilter; + fftFilter usbFilter; + fftFilter lsbFilter; + hilbertFilter s2Filter; + hilbertFilter s3Filter; int fillP; QFrame *myFrame; - decimatingFIR *theFilter; int32_t inputRate; int32_t outputRate; - int32_t samplesperSymbol; - int32_t counter; common_fft *the_fft; std::complex *fftBuffer; - Cache *theCache; - int cacheLineP; - int cacheSize; - waterfallScope *Viewer; - double *x_axis; - double *y_values; + spectrumScope *Viewer; + int counter; + double x_axis [512]; + double y_values [512];; + RingBuffer> *audioBuffer; private slots: void handleClick (int); }; diff --git a/devices/rtlsdr-handler/rtlsdr-handler.cpp b/devices/rtlsdr-handler/rtlsdr-handler.cpp index 06842d3..2f17a07 100644 --- a/devices/rtlsdr-handler/rtlsdr-handler.cpp +++ b/devices/rtlsdr-handler/rtlsdr-handler.cpp @@ -127,11 +127,10 @@ QString temp; while (inputRate < Khz (1000)) inputRate += outputRate; libraryLoaded = false; - workerHandle = NULL; - d_filter = NULL; - workerHandle = NULL; + workerHandle = nullptr; + d_filter = nullptr; + workerHandle = nullptr; open = false; - gains = NULL; statusLabel -> setText ("setting up"); #ifdef __MINGW32__ @@ -202,18 +201,19 @@ QString temp; } gainsCount = rtlsdr_get_tuner_gains (device, NULL); - gains = new int [gainsCount]; - fprintf (stderr, "Supported gain values (%d): ", gainsCount); - gainsCount = rtlsdr_get_tuner_gains (device, gains); - for (i = gainsCount; i > 0; i--) { - fprintf (stderr, "%.1f ", gains [i - 1] / 10.0); - combo_gain -> addItem (QString::number (gains [i - 1])); + { + int gains [gainsCount]; + fprintf (stderr, "Supported gain values (%d): ", gainsCount); + gainsCount = rtlsdr_get_tuner_gains (device, gains); + for (i = gainsCount; i > 0; i--) { + fprintf (stderr, "%.1f ", gains [i - 1] / 10.0); + combo_gain -> addItem (QString::number (gains [i - 1])); + } + fprintf (stderr, "\n"); + temp = + rtlsdrSettings -> value ("externalGain", + gains [2]). toString (); } - - fprintf (stderr, "\n"); - - temp = - rtlsdrSettings -> value ("externalGain", "10"). toString (); k = combo_gain -> findText (temp); if (k != -1) { combo_gain -> setCurrentIndex (k); @@ -263,8 +263,6 @@ QString temp; open = false; if (d_filter != NULL) delete d_filter; - if (gains != NULL) - delete [] gains; delete myFrame; throw (22); } @@ -291,7 +289,6 @@ QString temp; dlclose (Handle); #endif delete d_filter; - delete[] gains; delete myFrame; } diff --git a/devices/rtlsdr-handler/rtlsdr-handler.h b/devices/rtlsdr-handler/rtlsdr-handler.h index 442f25e..3d6d8e7 100644 --- a/devices/rtlsdr-handler/rtlsdr-handler.h +++ b/devices/rtlsdr-handler/rtlsdr-handler.h @@ -2,12 +2,9 @@ /* * Copyright (C) 2010, 2011, 2012 * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair programming + * 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 @@ -98,14 +95,14 @@ Q_OBJECT RingBuffer *r, QSettings *s); - ~rtlsdrHandler (void); - int32_t getRate (void); + ~rtlsdrHandler (); + int32_t getRate (); void setVFOFrequency (quint64); - quint64 getVFOFrequency (void); + quint64 getVFOFrequency (); bool legalFrequency (int32_t); - bool restartReader (void); - void stopReader (void); - int16_t bitDepth (void); + bool restartReader (); + void stopReader (); + int16_t bitDepth (); // // I_Buffer needs to be visible for use within the callback RingBuffer> *_I_Buffer; @@ -132,11 +129,10 @@ private slots: int32_t vfoFrequency; bool open; int16_t gainsCount; - int *gains; int theGain; // // here we need to load functions from the dll - bool load_rtlFunctions (void); + bool load_rtlFunctions (); pfnrtlsdr_open rtlsdr_open; pfnrtlsdr_close rtlsdr_close; pfnrtlsdr_get_usb_strings rtlsdr_get_usb_strings; diff --git a/devices/sdrplay-handler-v3/Rsp-device.cpp b/devices/sdrplay-handler-v3/Rsp-device.cpp index eb9e97e..0e466ee 100644 --- a/devices/sdrplay-handler-v3/Rsp-device.cpp +++ b/devices/sdrplay-handler-v3/Rsp-device.cpp @@ -26,8 +26,6 @@ sdrplay_api_ErrT err; parent, SLOT (set_lnabounds (int, int))); connect (this, SIGNAL (set_deviceName_signal (const QString &)), parent, SLOT (set_deviceName (const QString &))); - connect (this, SIGNAL (set_antennaSelect_signal (int)), - parent, SLOT (set_antennaSelect (int))); connect (this, SIGNAL (set_nrBits_signal (int)), parent, SLOT (set_nrBits (int))); connect (this, SIGNAL (show_lnaGain (int)), diff --git a/devices/sdrplay-handler-v3/RspDuo-handler.cpp b/devices/sdrplay-handler-v3/RspDuo-handler.cpp index 56532e6..1f7dddb 100644 --- a/devices/sdrplay-handler-v3/RspDuo-handler.cpp +++ b/devices/sdrplay-handler-v3/RspDuo-handler.cpp @@ -9,6 +9,7 @@ bool agcMode, int lnaState, int GRdB, + int antennaValue, bool biasT) : Rsp_device (parent, chosenDevice, @@ -17,15 +18,13 @@ agcMode, lnaState, GRdB, biasT) { - + set_antenna (antennaValue); this -> lna_upperBound = 10; this -> deviceModel = "RSP-Duo"; this -> nrBits = 14; this -> antennaSelect = true; set_deviceName_signal (deviceModel); - set_antennaSelect_signal (1); set_lnabounds_signal (0, lna_upperBound); - set_nrBits_signal (nrBits); show_lnaGain (get_lnaGain (lnaState, freq)); if (biasT) diff --git a/devices/sdrplay-handler-v3/RspDuo-handler.h b/devices/sdrplay-handler-v3/RspDuo-handler.h index 1796eea..ecea35f 100644 --- a/devices/sdrplay-handler-v3/RspDuo-handler.h +++ b/devices/sdrplay-handler-v3/RspDuo-handler.h @@ -14,6 +14,7 @@ class RspDuo_handler: public Rsp_device { bool agcMode, int lnaState, int GRdB, + int antennaSelect, bool biasT); ~RspDuo_handler (); diff --git a/devices/sdrplay-handler-v3/RspDx-handler.cpp b/devices/sdrplay-handler-v3/RspDx-handler.cpp index 4543bf6..2147c6d 100644 --- a/devices/sdrplay-handler-v3/RspDx-handler.cpp +++ b/devices/sdrplay-handler-v3/RspDx-handler.cpp @@ -9,6 +9,7 @@ bool agcMode, int lnaState, int GRdB, + int antennaValue, bool biasT) : Rsp_device (parent, chosenDevice, @@ -19,17 +20,17 @@ GRdB, biasT) { + set_antenna (antennaValue); this -> deviceModel = "RSP-Dx"; this -> nrBits = 14; this -> antennaSelect = true; this -> lna_upperBound = lnaStates (freq); set_lnabounds_signal (0, lna_upperBound); set_deviceName_signal (deviceModel); - set_antennaSelect_signal (2); - set_nrBits_signal (nrBits); show_lnaGain (get_lnaGain (lnaState, freq)); if (biasT) set_biasT (true); + set_lna (this -> lnaState); } RspDx_handler::~RspDx_handler () {} diff --git a/devices/sdrplay-handler-v3/RspDx-handler.h b/devices/sdrplay-handler-v3/RspDx-handler.h index 38cce63..0252a71 100644 --- a/devices/sdrplay-handler-v3/RspDx-handler.h +++ b/devices/sdrplay-handler-v3/RspDx-handler.h @@ -15,6 +15,7 @@ class RspDx_handler: public Rsp_device { bool agcMode, int lnaState, int GRdB, + int antennaValue, bool biasT); ~RspDx_handler (); diff --git a/devices/sdrplay-handler-v3/RspII-handler.cpp b/devices/sdrplay-handler-v3/RspII-handler.cpp index 58089bd..86a5df4 100644 --- a/devices/sdrplay-handler-v3/RspII-handler.cpp +++ b/devices/sdrplay-handler-v3/RspII-handler.cpp @@ -9,6 +9,7 @@ bool agcMode, int lnaState, int GRdB, + int antennaValue, bool biasT) : Rsp_device (parent, chosenDevice, @@ -17,14 +18,12 @@ agcMode, lnaState, GRdB, biasT) { - + set_antenna (antennaValue); this -> lna_upperBound = 9; this -> deviceModel = "RSP-II"; this -> nrBits = 14; this -> antennaSelect = true; set_deviceName_signal (deviceModel); - set_antennaSelect_signal (1); - set_nrBits_signal (nrBits); if (freq < Mhz (420)) lna_upperBound = 9; else diff --git a/devices/sdrplay-handler-v3/RspII-handler.h b/devices/sdrplay-handler-v3/RspII-handler.h index 3dd9ad2..32347e1 100644 --- a/devices/sdrplay-handler-v3/RspII-handler.h +++ b/devices/sdrplay-handler-v3/RspII-handler.h @@ -15,6 +15,7 @@ class RspII_handler: public Rsp_device { bool agcMode, int lnaState, int GRdB, + int antennaValue, bool biasT); ~RspII_handler (); diff --git a/devices/sdrplay-handler-v3/sdrplay-handler-v3.cpp b/devices/sdrplay-handler-v3/sdrplay-handler-v3.cpp index 5dd08b5..05b7be3 100644 --- a/devices/sdrplay-handler-v3/sdrplay-handler-v3.cpp +++ b/devices/sdrplay-handler-v3/sdrplay-handler-v3.cpp @@ -46,6 +46,7 @@ #define SDRPLAY_RSP2_ 2 #define SDRPLAY_RSPduo_ 3 #define SDRPLAY_RSPdx_ 4 +#define SDRPLAY_RSP1B_ 6 sdrplayHandler_v3::sdrplayHandler_v3 (RadioInterface *mr, int32_t outputRate, @@ -68,7 +69,7 @@ // See if there are settings from previous incarnations // and config stuff - sdrplaySettings -> beginGroup ("sdrplaySettings"); + sdrplaySettings -> beginGroup ("sdrplaySettings_v3"); GRdBSelector -> setValue ( sdrplaySettings -> value ("sdrplay-ifgrdb", 20). toInt()); GRdBValue = GRdBSelector -> value (); @@ -102,8 +103,6 @@ this, SLOT (set_agcControl (int))); connect (ppmControl, SIGNAL (valueChanged (int)), this, SLOT (set_ppmControl (int))); - connect (antennaSelector, SIGNAL (activated (const QString &)), - this, SLOT (set_selectAntenna (const QString &))); connect (amPortSelector, SIGNAL (activated (const QString &)), this, SLOT (set_amPortSelect (const QString &))); connect (biasT_selector, SIGNAL (stateChanged (int)), @@ -265,9 +264,11 @@ ppmRequest r (ppm); } void sdrplayHandler_v3::set_selectAntenna (const QString &s) { -antennaRequest r (s == "Antenna A" ? 'A' : - s == "Antenna B" ? 'B' : 'C'); - messageHandler (&r); +messageHandler (new antennaRequest (s == "Antenna A" ? 'A' : + s == "Antenna B" ? 'B' : 'C')); + sdrplaySettings -> beginGroup ("sdrplaySettings_v3"); + sdrplaySettings -> setValue ("Antenna", s); + sdrplaySettings -> endGroup (); } void sdrplayHandler_v3::set_amPortSelect (const QString &s) { @@ -283,19 +284,28 @@ void sdrplayHandler_v3::report_dataAvailable (void) { //////////////////////////////////////////////////////////////////////// // showing data //////////////////////////////////////////////////////////////////////// -void sdrplayHandler_v3::set_antennaSelect (int n) { - if (n > 0) { +int sdrplayHandler_v3::set_antennaSelect (int sdrDevice) { + if ((sdrDevice == SDRPLAY_RSPdx_) || (sdrDevice == SDRPLAY_RSPduo_)) { + antennaSelector -> addItem ("Antenna B"); + antennaSelector -> addItem ("Antenna C"); + antennaSelector -> show (); + } + else + if (sdrDevice == SDRPLAY_RSP2_) { antennaSelector -> addItem ("Antenna B"); - if (n > 1) { // It is a "DX" - antennaSelector -> addItem ("Antenna C"); - amPortSelector -> show (); - } - antennaSelector -> show (); - } - else { - antennaSelector -> hide (); - amPortSelector -> hide (); + antennaSelector -> show (); } + + sdrplaySettings -> beginGroup ("sdrplaySettings_v3"); + QString setting = + sdrplaySettings -> value ("Antenna", "Antenna A"). toString (); + sdrplaySettings -> endGroup (); + int k = antennaSelector -> findText (setting); + if (k >= 0) + antennaSelector -> setCurrentIndex (k); + connect (antennaSelector, SIGNAL (activated (const QString &)), + this, SLOT (set_selectAntenna (const QString &))); + return k == 2 ? 'C' : k == 1 ? 'B' : 'A'; } void sdrplayHandler_v3::show_tunerSelector (bool b) { @@ -498,8 +508,11 @@ uint32_t ndev; serial = devs [0]. SerNo; hwVersion = devs [0]. hwVer; try { + int antennaValue; switch (hwVersion) { case SDRPLAY_RSPdx_ : + antennaValue = set_antennaSelect (SDRPLAY_RSPdx_); + nrBits = 14; theRsp = new RspDx_handler (this, chosenDevice, inputRate, @@ -507,10 +520,13 @@ uint32_t ndev; agcMode, lnaState, GRdBValue, + antennaValue, biasT); break; case SDRPLAY_RSP1A_ : + case SDRPLAY_RSP1B_ : + nrBits = 14; theRsp = new Rsp1A_handler (this, chosenDevice, inputRate, @@ -522,6 +538,8 @@ uint32_t ndev; break; case SDRPLAY_RSP2_ : + nrBits = 14; + antennaValue = set_antennaSelect (SDRPLAY_RSP2_); theRsp = new RspII_handler (this, chosenDevice, inputRate, @@ -529,10 +547,13 @@ uint32_t ndev; agcMode, lnaState, GRdBValue, + antennaValue, biasT); break; case SDRPLAY_RSPduo_ : + nrBits = 14; + antennaValue = set_antennaSelect (SDRPLAY_RSPdx_); theRsp = new RspDuo_handler (this, chosenDevice, inputRate, @@ -540,6 +561,7 @@ uint32_t ndev; agcMode, lnaState, GRdBValue, + antennaValue, biasT); break; diff --git a/devices/sdrplay-handler-v3/sdrplay-handler-v3.h b/devices/sdrplay-handler-v3/sdrplay-handler-v3.h index ec1c107..cb15bd6 100644 --- a/devices/sdrplay-handler-v3/sdrplay-handler-v3.h +++ b/devices/sdrplay-handler-v3/sdrplay-handler-v3.h @@ -124,6 +124,7 @@ Q_OBJECT HINSTANCE fetchLibrary (); void releaseLibrary (); bool loadFunctions (); + int set_antennaSelect (int); private slots: void set_ifgainReduction (int); @@ -139,7 +140,6 @@ public slots: void set_deviceName (const QString &); void set_serial (const QString &); void set_apiVersion (float); - void set_antennaSelect (int); void show_tunerSelector (bool); void show_lnaGain (int); signals: diff --git a/filters/hilbertfilter.cpp b/filters/hilbertfilter.cpp new file mode 100644 index 0000000..0e95dbf --- /dev/null +++ b/filters/hilbertfilter.cpp @@ -0,0 +1,91 @@ +#include +#include +#include +#include + +#include "hilbertfilter.h" +using namespace std; + +// length of complex array +//#define N 64 + + hilbertFilter::hilbertFilter (int size) { + this -> size = size; + fftBuffer_1 = new std::complex [size]; + fftBuffer_2 = new std::complex [size]; +// create a DFT plan and execute it + plan_in = fftwf_plan_dft_1d (size, + reinterpret_cast (fftBuffer_1), + reinterpret_cast (fftBuffer_2), + FFTW_FORWARD, FFTW_ESTIMATE); + plan_uit = fftwf_plan_dft_1d (size, + reinterpret_cast (fftBuffer_2), + reinterpret_cast (fftBuffer_2), + FFTW_BACKWARD, FFTW_ESTIMATE); + + for (int i = 0; i < size; i ++) { + fftBuffer_1 [i] = std::complex (0, 0); + fftBuffer_2 [i] = std::complex (0, 0); + } + inp = size / 4; +} + + hilbertFilter::~hilbertFilter () { + fftwf_destroy_plan (plan_in); + fftwf_destroy_plan (plan_uit); + fftwf_cleanup (); + delete [] fftBuffer_1; + delete [] fftBuffer_2; +} + +std::complex hilbertFilter::Pass (float v) { +std::complex res = fftBuffer_2 [inp - size / 4]; + + fftBuffer_1 [inp] = std::complex (v, 0); + inp = inp + 1; + if (inp < this -> size) + return res; +// +// OK, the buffer is full, transition starts + fftwf_execute (plan_in); + + int hN = size >> 1; // half of the length (N/2) + int numRem = hN; // the number of remaining elements + +// multiply the appropriate value by 2 +// (those should multiplied by 1 are left intact because +// they wouldn't change) + + for (int i = 1; i < hN; ++i) + fftBuffer_2 [i] = + std::complex (real (fftBuffer_2 [i]) * 2, + imag (fftBuffer_2 [i]) * 2); + +// if the length is even, the number of the remaining elements decrease by 1 + if (size % 2 == 0) + numRem--; + else + if (size > 1) { // odd and more than one element + fftBuffer_2 [hN] = + std::complex (real (fftBuffer_2 [hN]) * 2, + imag (fftBuffer_2 [hN]) * 2); + } + +// set the negative frequencuess to 0 + for (int i = hN + 1; i < size; i ++) + fftBuffer_2 [i] = std::complex (0, 0); + fftwf_execute (plan_uit); +// scale the IDFT output + + for (int i = 0; i < size; ++i) { + fftBuffer_2 [i] = + std::complex (real (fftBuffer_2 [i]) / size, + imag (fftBuffer_2 [i]) / size); + } + for (int i = 0; i < size / 4; i ++) + fftBuffer_1 [i] = fftBuffer_1 [size - size / 4 - 1 + i]; + inp = size / 4; + + return res; +} + diff --git a/filters/hilbertfilter.h b/filters/hilbertfilter.h new file mode 100644 index 0000000..e9e3fe8 --- /dev/null +++ b/filters/hilbertfilter.h @@ -0,0 +1,28 @@ + +#ifndef __HILBERT_TRANSFORM_H +#define __HILBERT_TRANSFORM_H +#include +#include +#include +#include + +using namespace std; + + +class hilbertFilter { +public: + hilbertFilter (int size); + ~hilbertFilter (); +std::complex Pass (float); + +private: + std::complex *fftBuffer_1; + std::complex *fftBuffer_2; + fftwf_plan plan_in; + fftwf_plan plan_uit; + int size; + int inp; +}; +#endif + + diff --git a/main.cpp b/main.cpp index 14fdc17..3f16750 100644 --- a/main.cpp +++ b/main.cpp @@ -100,8 +100,15 @@ QString bandplanFile = QDir::homePath (); #if QT_VERSION >= 0x050600 QGuiApplication::setAttribute (Qt::AA_EnableHighDpiScaling); #endif + QApplication a (argc, argv); + QFile file (":res/Combinear.qss"); + if (file .open (QFile::ReadOnly | QFile::Text)) { + a. setStyleSheet (file.readAll ()); + file.close (); + } + ISettings = new QSettings (iniFile, QSettings::IniFormat); /* * Before we connect control to the gui, we have to diff --git a/res/Adaptic.qss b/res/Adaptic.qss new file mode 100644 index 0000000..b1463fe --- /dev/null +++ b/res/Adaptic.qss @@ -0,0 +1,1249 @@ +/*Copyright (c) DevSec Studio. All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +/*-----QWidget-----*/ +QWidget +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(102, 115, 140, 255),stop:1 rgba(56, 63, 77, 255)); + color: #ffffff; + border-color: #051a39; + +} + + +/*-----QLabel-----*/ +QLabel +{ + background-color: transparent; + color: #ffffff; + font-weight: bold; + +} + + +QLabel::disabled +{ + background-color: transparent; + color: #898988; + +} + + +/*-----QMenuBar-----*/ +QMenuBar +{ + background-color: #484c58; + color: #ffffff; + border-color: #051a39; + font-weight: bold; + +} + + +QMenuBar::disabled +{ + background-color: #404040; + color: #898988; + border-color: #051a39; + +} + + +QMenuBar::item +{ + background-color: transparent; + +} + + +QMenuBar::item:selected +{ + background-color: #c4c5c3; + color: #000000; + border: 1px solid #000000; + +} + + +QMenuBar::item:pressed +{ + background-color: #979796; + border: 1px solid #000; + margin-bottom: -1px; + padding-bottom: 1px; + +} + + +/*-----QMenu-----*/ +QMenu +{ + background-color: #c4c5c3; + border: 1px solid; + color: #000000; + font-weight: bold; + +} + + +QMenu::separator +{ + height: 1px; + background-color: #363942; + color: #ffffff; + padding-left: 4px; + margin-left: 10px; + margin-right: 5px; + +} + + +QMenu::item +{ + min-width : 150px; + padding: 3px 20px 3px 20px; + +} + + +QMenu::item:selected +{ + background-color: #363942; + color: #ffffff; + +} + + +QMenu::item:disabled +{ + color: #898988; +} + + +/*-----QToolTip-----*/ +QToolTip +{ + background-color: #bbbcba; + color: #000000; + border-color: #051a39; + border : 1px solid #000000; + border-radius: 2px; + +} + + +/*-----QPushButton-----*/ +QPushButton +{ + background-color: qlineargradient(spread:repeat, x1:0.486, y1:0, x2:0.505, y2:1, stop:0.00480769 rgba(170, 0, 0, 255),stop:1 rgba(122, 0, 0, 255)); + color: #ffffff; + font-weight: bold; + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: #051a39; + padding: 5px; + +} + + +QPushButton::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QPushButton::hover +{ + background-color: #9c0000; + color: #ffffff; + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: #051a39; + padding: 5px; + +} + + +QPushButton::pressed +{ + background-color: #880000; + color: #ffffff; + border-style: solid; + border-width: 2px; + border-radius: 3px; + border-color: #000000; + padding: 5px; + +} + + +/*-----QToolButton-----*/ +QToolButton +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(177, 181, 193, 255),stop:1 rgba(159, 163, 174, 255)); + color: #ffffff; + font-weight: bold; + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: #051a39; + padding: 5px; + +} + + +QToolButton::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QToolButton::hover +{ + background-color: #9fa3ae; + color: #ffffff; + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: #051a39; + padding: 5px; + +} + + +QToolButton::pressed +{ + background-color: #7b7e86; + color: #ffffff; + border-style: solid; + border-width: 2px; + border-radius: 3px; + border-color: #000000; + padding: 5px; + +} + + +/*-----QComboBox-----*/ +QComboBox +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(118, 118, 118, 255),stop:1 rgba(70, 70, 70, 255)); + border: 1px solid #333333; + border-radius: 3px; + padding-left: 6px; + color: lightgray; + font-weight: bold; + height: 20px; + +} + + +QComboBox::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QComboBox:hover +{ + background-color: #646464; + +} + + +QComboBox:on +{ + background-color: #979796; + color: #000000; + +} + + +QComboBox QAbstractItemView +{ + background-color: #c4c5c3; + color: #000000; + border: 1px solid black; + selection-background-color: #363942; + selection-color: #ffffff; + outline: 0; + +} + + +QComboBox::drop-down +{ + subcontrol-origin: padding; + subcontrol-position: top right; + width: 15px; + border-left-width: 1px; + border-left-color: darkgray; + border-left-style: solid; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + +} + + +QComboBox::down-arrow +{ + image: url(://arrow-down.png); + width: 8px; + height: 8px; +} + + +/*-----QSpinBox & QDoubleSpinBox & QDateTimeEdit-----*/ +QSpinBox, +QDoubleSpinBox, +QDateTimeEdit +{ + background-color: #000000; + color: #00ff00; + font-weight: bold; + border: 1px solid #333333; + padding : 4px; + +} + + +QSpinBox::disabled, +QDoubleSpinBox::disabled, +QDateTimeEdit::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QSpinBox:hover, +QDoubleSpinBox::hover, +QDateTimeEdit::hover +{ + border: 1px solid #00ff00; + +} + + +QSpinBox::up-button, QSpinBox::down-button, +QDoubleSpinBox::up-button, QDoubleSpinBox::down-button, +QDateTimeEdit::up-button, QDateTimeEdit::down-button +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(118, 118, 118, 255),stop:1 rgba(70, 70, 70, 255)); + border: 0px solid #333333; + +} + + +QSpinBox::disabled, +QDoubleSpinBox::disabled, +QDateTimeEdit::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QSpinBox::up-button:hover, QSpinBox::down-button:hover, +QDoubleSpinBox::up-button:hover, QDoubleSpinBox::down-button:hover, +QDateTimeEdit::up-button:hover, QDateTimeEdit::down-button:hover +{ + background-color: #646464; + border: 1px solid #333333; + + +} + + +QSpinBox::up-button:disabled, QSpinBox::down-button:disabled, +QDoubleSpinBox::up-button:disabled, QDoubleSpinBox::down-button:disabled, +QDateTimeEdit::up-button:disabled, QDateTimeEdit::down-button:disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QSpinBox::up-button:pressed, QSpinBox::down-button:pressed, +QDoubleSpinBox::up-button:pressed, QDoubleSpinBox::down-button::pressed, +QDateTimeEdit::up-button:pressed, QDateTimeEdit::down-button::pressed +{ + background-color: #979796; + border: 1px solid #444444; + +} + + +QSpinBox::down-arrow, +QDoubleSpinBox::down-arrow, +QDateTimeEdit::down-arrow +{ + image: url(://arrow-down.png); + width: 7px; + +} + + +QSpinBox::up-arrow, +QDoubleSpinBox::up-arrow, +QDateTimeEdit::up-arrow +{ + image: url(://arrow-up.png); + width: 7px; + +} + + +/*-----QLineEdit-----*/ +QLineEdit +{ + background-color: #000000; + color: #00ff00; + font-weight: bold; + border: 1px solid #333333; + padding: 4px; + +} + + +QLineEdit:hover +{ + border: 1px solid #00ff00; + +} + + +QLineEdit::disabled +{ + background-color: #404040; + color: #656565; + border-width: 1px; + border-color: #051a39; + padding: 2px; + +} + + +/*-----QTextEdit-----*/ +QTextEdit +{ + background-color: #808080; + color: #fff; + border: 1px groove #333333; + +} + + +QTextEdit::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +/*-----QGroupBox-----*/ +QGroupBox +{ + border: 1px groove #333333; + border-radius: 2px; + margin-top: 20px; + +} + + +QGroupBox +{ + background-color: qlineargradient(spread:repeat, x1:0.486, y1:0, x2:0.505, y2:1, stop:0.00480769 rgba(170, 169, 169, 255),stop:1 rgba(122, 122, 122, 255)); + font-weight: bold; + +} + + +QGroupBox::title +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(71, 75, 87, 255),stop:1 rgba(35, 37, 43, 255)); + color: #ffffff; + border: 2px groove #333333; + subcontrol-origin: margin; + subcontrol-position: top left; + padding: 2px; + +} + + +QGroupBox::title::disabled +{ + background-color: #404040; + color: #656565; + subcontrol-origin: margin; + subcontrol-position: top left; + padding: 5px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + +} + + +/*-----QCheckBox-----*/ +QCheckBox{ + background-color: transparent; + font-weight: bold; + color: #fff; + +} + + +QCheckBox::indicator +{ + color: #b1b1b1; + background-color: #323232; + border: 2px solid #222222; + width: 12px; + height: 12px; + +} + + +QCheckBox::indicator:checked +{ + image:url(://checkbox.png); + border: 2px solid #00ff00; + +} + + +QCheckBox::indicator:unchecked:hover +{ + border: 2px solid #00ff00; + +} + + +QCheckBox::disabled +{ + color: #656565; + +} + + +QCheckBox::indicator:disabled +{ + background-color: #656565; + color: #656565; + border: 1px solid #656565; + +} + + +/*-----QRadioButton-----*/ +QRadioButton{ + background-color: transparent; + font-weight: bold; + color: #fff; + +} + + +QRadioButton::indicator::unchecked +{ + border: 2px inset #222222; + border-radius: 6px; + background-color: #323232; + width: 9px; + height: 9px; + +} + + +QRadioButton::indicator::unchecked:hover +{ + border: 2px solid #00ff00; + border-radius: 5px; + background-color: #323232; + width: 9px; + height: 9px; + +} + + +QRadioButton::indicator::checked +{ + border: 2px inset #222222; + border-radius: 5px; + background-color: #00ff00; + width: 9px; + height: 9px; + +} + + +QRadioButton::disabled +{ + color: #656565; + +} + + +QRadioButton::indicator:disabled +{ + background-color: #656565; + color: #656565; + border: 2px solid #656565; + +} + + +/*-----QTableView & QTableWidget-----*/ +QTableView +{ + background-color: #808080; + border: 1px groove #333333; + color: #f0f0f0; + font-weight: bold; + gridline-color: #333333; + outline : 0; + +} + + +QTableView::disabled +{ + background-color: #242526; + border: 1px solid #32414B; + color: #656565; + gridline-color: #656565; + outline : 0; + +} + + +QTableView::item:hover +{ + background-color: #484c58; + color: #f0f0f0; + +} + + +QTableView::item:selected +{ + background-color: #484c58; + border: 2px groove #00ff00; + color: #F0F0F0; + +} + + +QTableView::item:selected:disabled +{ + background-color: #1a1b1c; + border: 2px solid #525251; + color: #656565; + +} + + +QTableCornerButton::section +{ + background-color: #282830; + +} + + +QHeaderView::section +{ + background-color: #282830; + color: #fff; + font-weight: bold; + text-align: left; + padding: 4px; + +} + + +QHeaderView::section:disabled +{ + background-color: #525251; + color: #656565; + +} + + +QHeaderView::section:checked +{ + background-color: #00ff00; + +} + + +QHeaderView::section:checked:disabled +{ + color: #656565; + background-color: #525251; + +} + + +QHeaderView::section::vertical::first, +QHeaderView::section::vertical::only-one +{ + border-top: 0px; + +} + + +QHeaderView::section::vertical +{ + border-top: 0px; + +} + + +QHeaderView::section::horizontal::first, +QHeaderView::section::horizontal::only-one +{ + border-left: 0px; + +} + + +QHeaderView::section::horizontal +{ + border-left: 0px; + +} + + +/*-----QTabWidget-----*/ +QTabBar::tab +{ + background-color: transparent; + color: #ffffff; + font-weight: bold; + width: 80px; + height: 9px; + +} + + +QTabBar::tab:disabled +{ + background-color: #656565; + color: #656565; + +} + + +QTabWidget::pane +{ + background-color: transparent; + color: #ffffff; + border: 1px groove #333333; + +} + + +QTabBar::tab:selected +{ + background-color: #484c58; + color: #ffffff; + border: 1px groove #333333; + border-bottom: 0px; + +} + + +QTabBar::tab:selected:disabled +{ + background-color: #404040; + color: #656565; + +} + + +QTabBar::tab:!selected +{ + background-color: #a3a7b2; + +} + + +QTabBar::tab:!selected:hover +{ + background-color: #484c58; + +} + + +QTabBar::tab:top:!selected +{ + margin-top: 1px; + +} + + +QTabBar::tab:bottom:!selected +{ + margin-bottom: 3px; + +} + + +QTabBar::tab:top, QTabBar::tab:bottom +{ + min-width: 8ex; + margin-right: -1px; + padding: 5px 10px 5px 10px; + +} + + +QTabBar::tab:top:selected +{ + border-bottom-color: none; + +} + + +QTabBar::tab:bottom:selected +{ + border-top-color: none; + +} + + +QTabBar::tab:top:last, QTabBar::tab:bottom:last, +QTabBar::tab:top:only-one, QTabBar::tab:bottom:only-one +{ + margin-right: 0; + +} + + +QTabBar::tab:left:!selected +{ + margin-right: 2px; + +} + + +QTabBar::tab:right:!selected +{ + margin-left: 2px; + +} + + +QTabBar::tab:left, QTabBar::tab:right +{ + min-height: 15ex; + margin-bottom: -1px; + padding: 10px 5px 10px 5px; + +} + + +QTabBar::tab:left:selected +{ + border-left-color: none; + +} + + +QTabBar::tab:right:selected +{ + border-right-color: none; + +} + + +QTabBar::tab:left:last, QTabBar::tab:right:last, +QTabBar::tab:left:only-one, QTabBar::tab:right:only-one +{ + margin-bottom: 0; + +} + + +/*-----QSlider-----*/ +QSlider{ + background-color: transparent; + +} + + +QSlider::groove:horizontal +{ + background-color: transparent; + height: 6px; + +} + + +QSlider::sub-page:horizontal +{ + background-color: qlineargradient(spread:reflect, x1:1, y1:0, x2:1, y2:1, stop:0.00480769 rgba(201, 201, 201, 255),stop:1 rgba(72, 72, 72, 255)); + border: 1px solid #000; + +} + + +QSlider::add-page:horizontal +{ + background-color: #404040; + border: 1px solid #000; + +} + + +QSlider::handle:horizontal +{ + background-color: qlineargradient(spread:reflect, x1:1, y1:0, x2:1, y2:1, stop:0.00480769 rgba(201, 201, 201, 255),stop:1 rgba(72, 72, 72, 255)); + border: 1px solid #000; + width: 12px; + margin-top: -6px; + margin-bottom: -6px; + +} + + +QSlider::handle:horizontal:hover +{ + background-color: #808080; + +} + + +QSlider::sub-page:horizontal:disabled +{ + background-color: #bbb; + border-color: #999; + +} + + +QSlider::add-page:horizontal:disabled +{ + background-color: #eee; + border-color: #999; + +} + + +QSlider::handle:horizontal:disabled +{ + background-color: #eee; + border: 1px solid #aaa; + +} + + +QSlider::groove:vertical +{ + background-color: transparent; + width: 6px; + +} + + +QSlider::sub-page:vertical +{ + background-color: qlineargradient(spread:reflect, x1:0, y1:0.483, x2:1, y2:0.517, stop:0.00480769 rgba(201, 201, 201, 255),stop:1 rgba(72, 72, 72, 255)); + border: 1px solid #000; + +} + + +QSlider::add-page:vertical +{ + background-color: #404040; + border: 1px solid #000; + +} + + +QSlider::handle:vertical +{ + background-color: qlineargradient(spread:reflect, x1:0, y1:0.483, x2:1, y2:0.517, stop:0.00480769 rgba(201, 201, 201, 255),stop:1 rgba(72, 72, 72, 255)); + border: 1px solid #000; + height: 12px; + margin-left: -6px; + margin-right: -6px; + +} + + +QSlider::handle:vertical:hover +{ + background-color: #808080; + +} + + +QSlider::sub-page:vertical:disabled +{ + background-color: #bbb; + border-color: #999; + +} + + +QSlider::add-page:vertical:disabled +{ + background-color: #eee; + border-color: #999; + +} + + +QSlider::handle:vertical:disabled +{ + background-color: #eee; + border: 1px solid #aaa; + border-radius: 3px; + +} + + +/*-----QDial-----*/ +QDial +{ + background-color: #600000; + +} + + +QDial::disabled +{ + background-color: #404040; + +} + + +/*-----QScrollBar-----*/ +QScrollBar:horizontal +{ + border: 1px solid #222222; + background-color: #63676d; + height: 18px; + margin: 0px 18px 0 18px; + +} + + +QScrollBar::handle:horizontal +{ + background-color: #a6acb3; + border: 1px solid #656565; + border-radius: 2px; + min-height: 20px; + +} + + +QScrollBar::add-line:horizontal +{ + border: 1px solid #1b1b19; + background-color: #a6acb3; + width: 18px; + subcontrol-position: right; + subcontrol-origin: margin; + +} + + +QScrollBar::sub-line:horizontal +{ + border: 1px solid #1b1b19; + background-color: #a6acb3; + width: 18px; + subcontrol-position: left; + subcontrol-origin: margin; + +} + + +QScrollBar::right-arrow:horizontal +{ + image: url(://arrow-right.png); + width: 8px; + height: 8px; + +} + + +QScrollBar::left-arrow:horizontal +{ + image: url(://arrow-left.png); + width: 8px; + height: 8px; + +} + + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal +{ + background: none; + +} + + +QScrollBar:vertical +{ + background-color: #63676d; + width: 18px; + margin: 18px 0 18px 0; + border: 1px solid #222222; + +} + + +QScrollBar::handle:vertical +{ + background-color: #a6acb3; + border: 1px solid #656565; + border-radius: 2px; + min-height: 20px; + +} + + +QScrollBar::add-line:vertical +{ + border: 1px solid #1b1b19; + background-color: #a6acb3; + height: 18px; + subcontrol-position: bottom; + subcontrol-origin: margin; + +} + + +QScrollBar::sub-line:vertical +{ + border: 1px solid #1b1b19; + background-color: #a6acb3; + height: 18px; + subcontrol-position: top; + subcontrol-origin: margin; + +} + + +QScrollBar::up-arrow:vertical +{ + image: url(://arrow-up.png); + width: 8px; + height: 8px; + +} + + +QScrollBar::down-arrow:vertical +{ + image: url(://arrow-down.png); + width: 8px; + height: 8px; + +} + + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical +{ + background: none; + +} + + +/*-----QProgressBar-----*/ +QProgressBar +{ + background-color: #000; + color: #00ff00; + font-weight: bold; + border: 0px groove #000; + border-radius: 10px; + text-align: center; + +} + + +QProgressBar:disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + border: 1px solid #000; + border-radius: 10px; + text-align: center; + +} + + +QProgressBar::chunk { + background-color: #ffaf02; + border: 0px; + border-radius: 10px; + color: #000; + +} + + +QProgressBar::chunk:disabled { + background-color: #333; + border: 0px; + border-radius: 10px; + color: #656565; +} + + +/*-----QStatusBar-----*/ +QStatusBar +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(102, 115, 140, 255),stop:1 rgba(56, 63, 77, 255)); + color: #ffffff; + border-color: #051a39; + font-weight: bold; + +} + + diff --git a/res/Combinear.qss b/res/Combinear.qss new file mode 100644 index 0000000..1484e66 --- /dev/null +++ b/res/Combinear.qss @@ -0,0 +1,987 @@ +/*Copyright (c) DevSec Studio. All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +/*-----QWidget-----*/ +QWidget +{ + background-color: #3a3a3a; + color: #fff; + selection-background-color: #b78620; + selection-color: #000; + +} + + +/*-----QLabel-----*/ +QLabel +{ + background-color: transparent; + color: #fff; + +} + + +/*-----QMenuBar-----*/ +QMenuBar +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(57, 57, 57, 255),stop:1 rgba(50, 50, 50, 255)); + border: 1px solid #000; + color: #fff; + +} + + +QMenuBar::item +{ + background-color: transparent; + +} + + +QMenuBar::item:selected +{ + background-color: rgba(183, 134, 32, 20%); + border: 1px solid #b78620; + color: #fff; + +} + + +QMenuBar::item:pressed +{ + background-color: rgb(183, 134, 32); + border: 1px solid #b78620; + color: #fff; + +} + + +/*-----QMenu-----*/ +QMenu +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(57, 57, 57, 255),stop:1 rgba(50, 50, 50, 255)); + border: 1px solid #222; + padding: 4px; + color: #fff; + +} + + +QMenu::item +{ + background-color: transparent; + padding: 2px 20px 2px 20px; + +} + + +QMenu::separator +{ + background-color: rgb(183, 134, 32); + height: 1px; + +} + + +QMenu::item:disabled +{ + color: #555; + background-color: transparent; + padding: 2px 20px 2px 20px; + +} + + +QMenu::item:selected +{ + background-color: rgba(183, 134, 32, 20%); + border: 1px solid #b78620; + color: #fff; + +} + + +/*-----QToolBar-----*/ +QToolBar +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(69, 69, 69, 255),stop:1 rgba(58, 58, 58, 255)); + border-top: none; + border-bottom: 1px solid #4f4f4f; + border-left: 1px solid #4f4f4f; + border-right: 1px solid #4f4f4f; + +} + + +QToolBar::separator +{ + background-color: #2e2e2e; + width: 1px; + +} + + +/*-----QToolButton-----*/ +QToolButton +{ + background-color: transparent; + color: #fff; + padding: 5px; + padding-left: 8px; + padding-right: 8px; + margin-left: 1px; +} + + +QToolButton:hover +{ + background-color: rgba(183, 134, 32, 20%); + border: 1px solid #b78620; + color: #fff; + +} + + +QToolButton:pressed +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(57, 57, 57, 255),stop:1 rgba(50, 50, 50, 255)); + border: 1px solid #b78620; + +} + + +QToolButton:checked +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(57, 57, 57, 255),stop:1 rgba(50, 50, 50, 255)); + border: 1px solid #222; +} + + +/*-----QPushButton-----*/ +QPushButton +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(84, 84, 84, 255),stop:1 rgba(59, 59, 59, 255)); + color: #ffffff; + min-width: 80px; + border-style: solid; + border-width: 1px; + border-radius: 3px; + border-color: #051a39; + padding: 5px; + +} + + +QPushButton::flat +{ + background-color: transparent; + border: none; + color: #fff; + +} + + +QPushButton::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QPushButton::hover +{ + background-color: rgba(183, 134, 32, 20%); + border: 1px solid #b78620; + +} + + +QPushButton::pressed +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(74, 74, 74, 255),stop:1 rgba(49, 49, 49, 255)); + border: 1px solid #b78620; + +} + + +QPushButton::checked +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(74, 74, 74, 255),stop:1 rgba(49, 49, 49, 255)); + border: 1px solid #222; + +} + + +/*-----QLineEdit-----*/ +QLineEdit +{ + background-color: #131313; + color : #eee; + border: 1px solid #343434; + border-radius: 2px; + padding: 3px; + padding-left: 5px; + +} + + +/*-----QPlainTExtEdit-----*/ +QPlainTextEdit +{ + background-color: #131313; + color : #eee; + border: 1px solid #343434; + border-radius: 2px; + padding: 3px; + padding-left: 5px; + +} + + +/*-----QTabBar-----*/ +QTabBar::tab +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(84, 84, 84, 255),stop:1 rgba(59, 59, 59, 255)); + color: #ffffff; + border-style: solid; + border-width: 1px; + border-color: #666; + border-bottom: none; + padding: 5px; + padding-left: 15px; + padding-right: 15px; + +} + + +QTabWidget::pane +{ + background-color: red; + border: 1px solid #666; + top: 1px; + +} + + +QTabBar::tab:last +{ + margin-right: 0; + +} + + +QTabBar::tab:first:!selected +{ + background-color: #0c0c0d; + margin-left: 0px; + +} + + +QTabBar::tab:!selected +{ + color: #b1b1b1; + border-bottom-style: solid; + background-color: #0c0c0d; + +} + + +QTabBar::tab:selected +{ + margin-bottom: 0px; + +} + + +QTabBar::tab:!selected:hover +{ + border-top-color: #b78620; + +} + + +/*-----QComboBox-----*/ +QComboBox +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(84, 84, 84, 255),stop:1 rgba(59, 59, 59, 255)); + border: 1px solid #000; + padding-left: 6px; + color: #ffffff; + height: 20px; + +} + + +QComboBox::disabled +{ + background-color: #404040; + color: #656565; + border-color: #051a39; + +} + + +QComboBox:on +{ + background-color: #b78620; + color: #000; + +} + + +QComboBox QAbstractItemView +{ + background-color: #383838; + color: #ffffff; + border: 1px solid black; + selection-background-color: #b78620; + outline: 0; + +} + + +QComboBox::drop-down +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(57, 57, 57, 255),stop:1 rgba(50, 50, 50, 255)); + subcontrol-origin: padding; + subcontrol-position: top right; + width: 15px; + border-left-width: 1px; + border-left-color: black; + border-left-style: solid; + +} + + +QComboBox::down-arrow +{ + image: url(://arrow-down.png); + width: 8px; + height: 8px; +} + + +/*-----QSpinBox & QDateTimeEdit-----*/ +QSpinBox, +QDateTimeEdit +{ + background-color: #131313; + color : #eee; + border: 1px solid #343434; + padding: 3px; + padding-left: 5px; + border-radius : 2px; + +} + + +QSpinBox::up-button, +QDateTimeEdit::up-button +{ + border-top-right-radius:2px; + background-color: #777777; + width: 16px; + border-width: 1px; + +} + + +QSpinBox::up-button:hover, +QDateTimeEdit::up-button:hover +{ + background-color: #585858; + +} + + +QSpinBox::up-button:pressed, +QDateTimeEdit::up-button:pressed +{ + background-color: #252525; + width: 16px; + border-width: 1px; + +} + + +QSpinBox::up-arrow, +QDateTimeEdit::up-arrow +{ + image: url(://arrow-up.png); + width: 7px; + height: 7px; + +} + + +QSpinBox::down-button, +QDateTimeEdit::down-button +{ + border-bottom-right-radius:2px; + background-color: #777777; + width: 16px; + border-width: 1px; + +} + + +QSpinBox::down-button:hover, +QDateTimeEdit::down-button:hover +{ + background-color: #585858; + +} + + +QSpinBox::down-button:pressed, +QDateTimeEdit::down-button:pressed +{ + background-color: #252525; + width: 16px; + border-width: 1px; + +} + + +QSpinBox::down-arrow, +QDateTimeEdit::down-arrow +{ + image: url(://arrow-down.png); + width: 7px; + height: 7px; + +} + + +/*-----QGroupBox-----*/ +QGroupBox +{ + border: 1px solid; + border-color: #666666; + border-radius: 5px; + margin-top: 20px; + +} + + +QGroupBox::title +{ + background-color: transparent; + color: #eee; + subcontrol-origin: margin; + padding: 5px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + +} + + +/*-----QHeaderView-----*/ +QHeaderView::section +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(60, 60, 60, 255),stop:1 rgba(50, 50, 50, 255)); + border: 1px solid #000; + color: #fff; + text-align: left; + padding: 4px; + +} + + +QHeaderView::section:disabled +{ + background-color: #525251; + color: #656565; + +} + + +QHeaderView::section:checked +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(60, 60, 60, 255),stop:1 rgba(50, 50, 50, 255)); + color: #fff; + +} + + +QHeaderView::section::vertical::first, +QHeaderView::section::vertical::only-one +{ + border-top: 1px solid #353635; + +} + + +QHeaderView::section::vertical +{ + border-top: 1px solid #353635; + +} + + +QHeaderView::section::horizontal::first, +QHeaderView::section::horizontal::only-one +{ + border-left: 1px solid #353635; + +} + + +QHeaderView::section::horizontal +{ + border-left: 1px solid #353635; + +} + + +QTableCornerButton::section +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(60, 60, 60, 255),stop:1 rgba(50, 50, 50, 255)); + border: 1px solid #000; + color: #fff; + +} + + +/*-----QTreeWidget-----*/ +QTreeView +{ + show-decoration-selected: 1; + alternate-background-color: #3a3a3a; + selection-color: #fff; + background-color: #2d2d2d; + border: 1px solid gray; + padding-top : 5px; + color: #fff; + font: 8pt; + +} + + +QTreeView::item:selected +{ + color:#fff; + background-color: #b78620; + border-radius: 0px; + +} + + +QTreeView::item:!selected:hover +{ + background-color: #262626; + border: none; + color: white; + +} + + +QTreeView::branch:has-children:!has-siblings:closed, +QTreeView::branch:closed:has-children:has-siblings +{ + image: url(://tree-closed.png); + +} + + +QTreeView::branch:open:has-children:!has-siblings, +QTreeView::branch:open:has-children:has-siblings +{ + image: url(://tree-open.png); + +} + + +/*-----QListView-----*/ +QListView +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(83, 83, 83, 255),stop:0.293269 rgba(81, 81, 81, 255),stop:0.634615 rgba(79, 79, 79, 255),stop:1 rgba(83, 83, 83, 255)); + border : none; + color: white; + show-decoration-selected: 1; + outline: 0; + border: 1px solid gray; + +} + + +QListView::disabled +{ + background-color: #656565; + color: #1b1b1b; + border: 1px solid #656565; + +} + + +QListView::item +{ + background-color: #2d2d2d; + padding: 1px; + +} + + +QListView::item:alternate +{ + background-color: #3a3a3a; + +} + + +QListView::item:selected +{ + background-color: #b78620; + border: 1px solid #b78620; + color: #fff; + +} + + +QListView::item:selected:!active +{ + background-color: #b78620; + border: 1px solid #b78620; + color: #fff; + +} + + +QListView::item:selected:active +{ + background-color: #b78620; + border: 1px solid #b78620; + color: #fff; + +} + + +QListView::item:hover { + background-color: #262626; + border: none; + color: white; + +} + + +/*-----QCheckBox-----*/ +QCheckBox +{ + background-color: transparent; + color: lightgray; + border: none; + +} + + +QCheckBox::indicator +{ + background-color: #323232; + border: 1px solid darkgray; + width: 12px; + height: 12px; + +} + + +QCheckBox::indicator:checked +{ + image:url("./ressources/check.png"); + background-color: #b78620; + border: 1px solid #3a546e; + +} + + +QCheckBox::indicator:unchecked:hover +{ + border: 1px solid #b78620; + +} + + +QCheckBox::disabled +{ + color: #656565; + +} + + +QCheckBox::indicator:disabled +{ + background-color: #656565; + color: #656565; + border: 1px solid #656565; + +} + + +/*-----QRadioButton-----*/ +QRadioButton +{ + color: lightgray; + background-color: transparent; + +} + + +QRadioButton::indicator::unchecked:hover +{ + background-color: lightgray; + border: 2px solid #b78620; + border-radius: 6px; +} + + +QRadioButton::indicator::checked +{ + border: 2px solid #b78620; + border-radius: 6px; + background-color: rgba(183,134,32,20%); + width: 9px; + height: 9px; + +} + + +/*-----QSlider-----*/ +QSlider::groove:horizontal +{ + background-color: transparent; + height: 3px; + +} + + +QSlider::sub-page:horizontal +{ + background-color: #b78620; + +} + + +QSlider::add-page:horizontal +{ + background-color: #131313; + +} + + +QSlider::handle:horizontal +{ + background-color: #b78620; + width: 14px; + margin-top: -6px; + margin-bottom: -6px; + border-radius: 6px; + +} + + +QSlider::handle:horizontal:hover +{ + background-color: #d89e25; + border-radius: 6px; + +} + + +QSlider::sub-page:horizontal:disabled +{ + background-color: #bbb; + border-color: #999; + +} + + +QSlider::add-page:horizontal:disabled +{ + background-color: #eee; + border-color: #999; + +} + + +QSlider::handle:horizontal:disabled +{ + background-color: #eee; + border: 1px solid #aaa; + border-radius: 3px; + +} + + +/*-----QScrollBar-----*/ +QScrollBar:horizontal +{ + border: 1px solid #222222; + background-color: #3d3d3d; + height: 15px; + margin: 0px 16px 0 16px; + +} + + +QScrollBar::handle:horizontal +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(97, 97, 97, 255),stop:1 rgba(90, 90, 90, 255)); + border: 1px solid #2d2d2d; + min-height: 20px; + +} + + +QScrollBar::add-line:horizontal +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(97, 97, 97, 255),stop:1 rgba(90, 90, 90, 255)); + border: 1px solid #2d2d2d; + width: 15px; + subcontrol-position: right; + subcontrol-origin: margin; + +} + + +QScrollBar::sub-line:horizontal +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(97, 97, 97, 255),stop:1 rgba(90, 90, 90, 255)); + border: 1px solid #2d2d2d; + width: 15px; + subcontrol-position: left; + subcontrol-origin: margin; + +} + + +QScrollBar::right-arrow:horizontal +{ + image: url(://arrow-right.png); + width: 6px; + height: 6px; + +} + + +QScrollBar::left-arrow:horizontal +{ + image: url(://arrow-left.png); + width: 6px; + height: 6px; + +} + + +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal +{ + background: none; + +} + + +QScrollBar:vertical +{ + background-color: #3d3d3d; + width: 16px; + border: 1px solid #2d2d2d; + margin: 16px 0px 16px 0px; + +} + + +QScrollBar::handle:vertical +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(97, 97, 97, 255),stop:1 rgba(90, 90, 90, 255)); + border: 1px solid #2d2d2d; + min-height: 20px; + +} + + +QScrollBar::add-line:vertical +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(97, 97, 97, 255),stop:1 rgba(90, 90, 90, 255)); + border: 1px solid #2d2d2d; + height: 15px; + subcontrol-position: bottom; + subcontrol-origin: margin; + +} + + +QScrollBar::sub-line:vertical +{ + background-color: qlineargradient(spread:repeat, x1:1, y1:0, x2:1, y2:1, stop:0 rgba(97, 97, 97, 255),stop:1 rgba(90, 90, 90, 255)); + border: 1px solid #2d2d2d; + height: 15px; + subcontrol-position: top; + subcontrol-origin: margin; + +} + + +QScrollBar::up-arrow:vertical +{ + image: url(://arrow-up.png); + width: 6px; + height: 6px; + +} + + +QScrollBar::down-arrow:vertical +{ + image: url(://arrow-down.png); + width: 6px; + height: 6px; + +} + + +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical +{ + background: none; + +} + + +/*-----QProgressBar-----*/ +QProgressBar +{ + border: 1px solid #666666; + text-align: center; + color: #000; + font-weight: bold; + +} + + +QProgressBar::chunk +{ + background-color: #b78620; + width: 30px; + margin: 0.5px; + +} + diff --git a/res/swradio.ico b/res/swradio.ico new file mode 100644 index 0000000..d664a75 Binary files /dev/null and b/res/swradio.ico differ diff --git a/resources.qrc b/resources.qrc index 803943e..f63459d 100644 --- a/resources.qrc +++ b/resources.qrc @@ -2,5 +2,8 @@ AUTHORS COPYING + res/swradio.ico + res/Adaptic.qss + res/Combinear.qss diff --git a/scopes-qwt6/virtual-scope.h b/scopes-qwt6/virtual-scope.h index 75f8616..366d16d 100644 --- a/scopes-qwt6/virtual-scope.h +++ b/scopes-qwt6/virtual-scope.h @@ -2,27 +2,27 @@ /* * Copyright (C) 2017 * Jan van Katwijk (J.vanKatwijk@gmail.com) - * Lazy Chair Programming + * Lazy Chair Computing * - * This file is part of the SDR-J. + * This file is part of the sw receiver * - * SDR-J is free software; you can redistribute it and/or modify + * sw receiver 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, + * swreceiver 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 + * along with swreceiver; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __VIRTUAL_SCOPE__ -#define __VIRTUAL_SCOPE__ +#ifndef __VIRTUAL_SCOPE_H +#define __VIRTUAL_SCOPE_H #include "radio-constants.h" #include diff --git a/swradio-8.pro b/swradio-8.pro index 45d2fd2..13337d6 100644 --- a/swradio-8.pro +++ b/swradio-8.pro @@ -60,6 +60,7 @@ HEADERS += ./radio-constants.h \ ./filters/fir-filters.h \ ./filters/iir-filters.h \ ./filters/decimating_filter.h \ + ./filters/hilbertfilter.h \ ./scopes-qwt6/virtual-scope.h \ ./scopes-qwt6/spectrogramdata.h \ ./scopes-qwt6/waterfall-scope.h \ @@ -96,6 +97,7 @@ SOURCES += ./main.cpp \ ./filters/fir-filters.cpp \ ./filters/iir-filters.cpp \ ./filters/decimating_filter.cpp \ + ./filters/hilbertfilter.cpp \ ./scopes-qwt6/virtual-scope.cpp \ ./scopes-qwt6/waterfall-scope.cpp \ ./scopes-qwt6/spectrum-scope.cpp \ @@ -140,11 +142,11 @@ CONFIG += rtty-decoder CONFIG += fax-decoder CONFIG += drm-decoder-fdk CONFIG += acars-decoder -#CONFIG += test-decoder -INCLUDEPATH += /usr/local/include /usr/local/lib/qwt.framework/Headers +CONFIG += test-decoder +INCLUDEPATH += /usr/local/include /usr/local/lib/qwt.framework/Headers QMAKE_LFLAGS += -F/usr/local/opt/qwt-qt5/lib -L/usr/local/lib -#LIBS += -lqwt -lrt -lsndfile -lsamplerate -lportaudio -lusb-1.0 -lfftw3f -ldl -LIBS += -framework qwt -lsndfile -lsamplerate -lportaudio -lusb-1.0 -lfftw3f -ldl +#LIBS += -lqwt -lrt -lsndfile -lsamplerate -lportaudio -lusb-1.0 -lfftw3f -ldl +LIBS += -framework qwt -lsndfile -lsamplerate -lportaudio -lusb-1.0 -lfftw3f -ldl } unix { @@ -170,7 +172,6 @@ CONFIG += rtl_tcp CONFIG += am-decoder CONFIG += ssb-decoder CONFIG += cw-decoder -#CONFIG += new-cw CONFIG += amtor-decoder CONFIG += psk-decoder CONFIG += ft8-decoder @@ -178,7 +179,7 @@ CONFIG += rtty-decoder CONFIG += fax-decoder CONFIG += drm-decoder-fdk CONFIG += acars-decoder -#CONFIG += test-decoder +CONFIG += test-decoder LIBS += -L/usr/lib64 LIBS += -L/lib64 LIBS += -lrt -lsndfile -lsamplerate -lportaudio -lusb-1.0 -lfftw3f -ldl @@ -518,6 +519,7 @@ drm-decoder-fdk { LIBS += -lfdk-aac # LIBS += -lfdk-aac-2 INCLUDEPATH += ./fdk-aac + INCLUDEPATH += /usr/include/eigen3 DEPENDPATH += ./decoders/drm-decoder/ \ ./decoders/drm-decoder/ \ ./decoders/drm-decoder/fac \ @@ -569,8 +571,8 @@ drm-decoder-fdk { ./decoders/drm-decoder/ofdm/word-collector.h \ ./decoders/drm-decoder/equalizer/equalizer-1.h \ ./decoders/drm-decoder/equalizer/equalizer-base.h \ -# ./decoders/drm-decoder/equalizer/estimator-2.h \ ./decoders/drm-decoder/equalizer/estimator-1.h \ + ./decoders/drm-decoder/equalizer/estimator-eigen-2.h \ ./decoders/drm-decoder/equalizer/matrix2.h \ ./decoders/drm-decoder/equalizer/referenceframe.h \ ./decoders/drm-decoder/parameters/msc-config.h \ @@ -618,8 +620,8 @@ drm-decoder-fdk { ./decoders/drm-decoder/ofdm/word-collector.cpp \ ./decoders/drm-decoder/equalizer/equalizer-1.cpp \ ./decoders/drm-decoder/equalizer/equalizer-base.cpp \ -# ./decoders/drm-decoder/equalizer/estimator-2.cpp \ ./decoders/drm-decoder/equalizer/estimator-1.cpp \ + ./decoders/drm-decoder/equalizer/estimator-eigen-2.cpp \ ./decoders/drm-decoder/equalizer/matrix2.cpp \ ./decoders/drm-decoder/equalizer/referenceframe.cpp \ ./decoders/drm-decoder/parameters/msc-config.cpp \ diff --git a/swradio-cw-widget.png b/swradio-cw-widget.png index 5751854..b245204 100644 Binary files a/swradio-cw-widget.png and b/swradio-cw-widget.png differ diff --git a/swradio-device-selection.png b/swradio-device-selection.png index 163a206..825cd81 100644 Binary files a/swradio-device-selection.png and b/swradio-device-selection.png differ diff --git a/swradio-drm-widget-1.png b/swradio-drm-widget-1.png new file mode 100644 index 0000000..a34e906 Binary files /dev/null and b/swradio-drm-widget-1.png differ diff --git a/swradio-drm-widget-2.png b/swradio-drm-widget-2.png new file mode 100644 index 0000000..0ad6852 Binary files /dev/null and b/swradio-drm-widget-2.png differ diff --git a/swradio-ft8-widget.png b/swradio-ft8-widget.png index 75e9374..ee5f2e9 100644 Binary files a/swradio-ft8-widget.png and b/swradio-ft8-widget.png differ diff --git a/swradio-navtex-widget.png b/swradio-navtex-widget.png index 9b0046e..0ea5eb1 100644 Binary files a/swradio-navtex-widget.png and b/swradio-navtex-widget.png differ diff --git a/swradio-overview.png b/swradio-overview.png index 2a4caae..72131ba 100644 Binary files a/swradio-overview.png and b/swradio-overview.png differ diff --git a/swradio-psk-widget.png b/swradio-psk-widget.png index 0c866fa..29b4df6 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 6dae6a6..4ac0fb9 100644 Binary files a/swradio-rtty-widget.png and b/swradio-rtty-widget.png differ diff --git a/swradio-waterfall.png b/swradio-waterfall.png index d6c7b0f..5ce3e7d 100644 Binary files a/swradio-waterfall.png and b/swradio-waterfall.png differ diff --git a/swradio-wfax-widget.png b/swradio-wfax-widget.png index adbb205..72131ba 100644 Binary files a/swradio-wfax-widget.png and b/swradio-wfax-widget.png differ