diff --git a/.gitignore b/.gitignore index 9705193..0bbd302 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ build/ cmake_build/ -cmake_build_msvc/ dist/ diff --git a/CMakeLists.txt b/CMakeLists.txt index c3ce07b..18d7fea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,8 +17,14 @@ ADD_DEFINITIONS( -DCUBICSDR_VERSION="${CUBICSDR_VERSION}-${VERSION_SUFFIX}" ) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") +SET (ENABLE_DIGITAL_LAB OFF CACHE BOOL "Enable 'Digital Lab' testing features.") +IF(ENABLE_DIGITAL_LAB) +ADD_DEFINITIONS( + -DENABLE_DIGITAL_LAB=1 +) +ENDIF() +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") macro(configure_files srcDir destDir globStr) message(STATUS "Copying ${srcDir}/${globStr} to directory ${destDir}") diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 7296799..51f86ef 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -76,7 +76,36 @@ AppFrame::AppFrame() : demodModeSelector->setSelection(DEMOD_TYPE_FM); demodModeSelector->setHelpTip("Choose modulation type: Frequency Modulation, Amplitude Modulation and Lower, Upper or Double Side-Band."); demodTray->Add(demodModeSelector, 2, wxEXPAND | wxALL, 0); - + +#ifdef ENABLE_DIGITAL_LAB + demodModeSelectorAdv = new ModeSelectorCanvas(this, attribList); + demodModeSelectorAdv->addChoice(DEMOD_TYPE_ASK, "ASK"); + demodModeSelectorAdv->addChoice(DEMOD_TYPE_APSK, "APSK"); + demodModeSelectorAdv->addChoice(DEMOD_TYPE_BPSK, "BPSK"); + demodModeSelectorAdv->addChoice(DEMOD_TYPE_DPSK, "DPSK"); + demodModeSelectorAdv->addChoice(DEMOD_TYPE_PSK, "PSK"); + demodModeSelectorAdv->addChoice(DEMOD_TYPE_OOK, "OOK"); + demodModeSelectorAdv->addChoice(DEMOD_TYPE_ST, "ST"); + demodModeSelectorAdv->addChoice(DEMOD_TYPE_SQAM, "SQAM"); + demodModeSelectorAdv->addChoice(DEMOD_TYPE_QAM, "QAM"); + demodModeSelectorAdv->addChoice(DEMOD_TYPE_QPSK, "QPSK"); + demodModeSelectorAdv->setHelpTip("Choose advanced modulation types."); + demodTray->Add(demodModeSelectorAdv, 3, wxEXPAND | wxALL, 0); + + demodModeSelectorCons = new ModeSelectorCanvas(this, attribList); + demodModeSelectorCons->addChoice(1, "auto"); + demodModeSelectorCons->addChoice(2, "2"); + demodModeSelectorCons->addChoice(4, "4"); + demodModeSelectorCons->addChoice(8, "8"); + demodModeSelectorCons->addChoice(16, "16"); + demodModeSelectorCons->addChoice(32, "32"); + demodModeSelectorCons->addChoice(64, "64"); + demodModeSelectorCons->addChoice(128, "128"); + demodModeSelectorCons->addChoice(256, "256"); + demodModeSelectorCons->setHelpTip("Choose number of constallations types."); + demodTray->Add(demodModeSelectorCons, 2, wxEXPAND | wxALL, 0); +#endif + wxGetApp().getDemodSpectrumProcessor()->setup(1024); demodSpectrumCanvas = new SpectrumCanvas(demodPanel, attribList); demodSpectrumCanvas->setView(wxGetApp().getConfig()->getCenterFreq(), 300000); @@ -828,6 +857,11 @@ void AppFrame::OnIdle(wxIdleEvent& event) { outputDeviceMenuItems[outputDevice]->Check(true); int dType = demod->getDemodulatorType(); demodModeSelector->setSelection(dType); +#ifdef ENABLE_DIGITAL_LAB + int dCons = demod->getDemodulatorCons(); + demodModeSelectorAdv->setSelection(dType); + demodModeSelectorCons->setSelection(dCons); +#endif demodMuteButton->setSelection(demod->isMuted()?1:-1); } if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) { @@ -856,9 +890,31 @@ void AppFrame::OnIdle(wxIdleEvent& event) { demodSpectrumCanvas->setCenterFrequency(centerFreq); } int dSelection = demodModeSelector->getSelection(); +#ifdef ENABLE_DIGITAL_LAB + int dSelectionadv = demodModeSelectorAdv->getSelection(); + int dSelectionCons = demodModeSelectorCons->getSelection(); + + // basic demodulators + if (dSelection != -1 && dSelection != demod->getDemodulatorType()) { + demod->setDemodulatorType(dSelection); + demodModeSelectorAdv->setSelection(-1); + } + // advanced demodulators + else if (dSelectionadv != -1 && dSelectionadv != demod->getDemodulatorType()) { + demod->setDemodulatorType(dSelectionadv); + demodModeSelector->setSelection(-1); + } + + // set constellations + if (dSelectionCons != demod->getDemodulatorCons()) { + demod->setDemodulatorCons(dSelectionCons); + } +#else + // basic demodulators if (dSelection != -1 && dSelection != demod->getDemodulatorType()) { demod->setDemodulatorType(dSelection); } +#endif int muteMode = demodMuteButton->getSelection(); if (demodMuteButton->modeChanged()) { @@ -896,9 +952,31 @@ void AppFrame::OnIdle(wxIdleEvent& event) { DemodulatorMgr *mgr = &wxGetApp().getDemodMgr(); int dSelection = demodModeSelector->getSelection(); +#ifdef ENABLE_DIGITAL_LAB + int dSelectionadv = demodModeSelectorAdv->getSelection(); + int dSelectionCons = demodModeSelectorCons->getSelection(); + + // basic demodulators + if (dSelection != -1 && dSelection != mgr->getLastDemodulatorType()) { + mgr->setLastDemodulatorType(dSelection); + demodModeSelectorAdv->setSelection(-1); + } + // advanced demodulators + else if(dSelectionadv != -1 && dSelectionadv != mgr->getLastDemodulatorType()) { + mgr->setLastDemodulatorType(dSelectionadv); + demodModeSelector->setSelection(-1); + } + + // set constellations + if (dSelectionCons != mgr->getLastDemodulatorCons()) { + mgr->setLastDemodulatorCons(dSelectionCons); + } +#else + // basic demodulators if (dSelection != -1 && dSelection != mgr->getLastDemodulatorType()) { mgr->setLastDemodulatorType(dSelection); } +#endif demodGainMeter->setLevel(mgr->getLastGain()); if (demodSignalMeter->inputChanged()) { mgr->setLastSquelchLevel(demodSignalMeter->getInputValue()); diff --git a/src/AppFrame.h b/src/AppFrame.h index d174d57..694d8c7 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -79,6 +79,10 @@ private: SpectrumCanvas *spectrumCanvas; WaterfallCanvas *waterfallCanvas; ModeSelectorCanvas *demodModeSelector; +#ifdef ENABLE_DIGITAL_LAB + ModeSelectorCanvas *demodModeSelectorAdv; + ModeSelectorCanvas *demodModeSelectorCons; +#endif SpectrumCanvas *demodSpectrumCanvas; WaterfallCanvas *demodWaterfallCanvas; MeterCanvas *demodSignalMeter; diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 186f9a8..3081026 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -1,7 +1,6 @@ #define OPENGL #include "CubicSDRDefs.h" - #include "wx/wxprec.h" #ifndef WX_PRECOMP @@ -21,6 +20,21 @@ IMPLEMENT_APP(CubicSDR) +#ifdef ENABLE_DIGITAL_LAB +// console output buffer for windows +#ifdef _WINDOWS +class outbuf : public std::streambuf { + public: + outbuf() { + setp(0, 0); + } + virtual int_type overflow(int_type c = traits_type::eof()) { + return fputc(c, stdout) == EOF ? traits_type::eof() : c; + } +}; +#endif +#endif + #ifdef MINGW_PATCH FILE _iob[] = { *stdin, *stdout, *stderr }; @@ -118,7 +132,6 @@ CubicSDR::CubicSDR() : appframe(NULL), m_glContext(NULL), frequency(0), offset(0 agcMode.store(true); } - bool CubicSDR::OnInit() { #ifdef _OSX_APP_ CFBundleRef mainBundle = CFBundleGetMainBundle(); @@ -136,6 +149,19 @@ bool CubicSDR::OnInit() { return false; } +#ifdef ENABLE_DIGITAL_LAB + // console output for windows + #ifdef _WINDOWS + if (AllocConsole()) { + freopen("CONOUT$", "w", stdout); + SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED); + } + outbuf ob; + std::streambuf *sb = std::cout.rdbuf(&ob); + std::cout.rdbuf(sb); + #endif +#endif + wxApp::SetAppName("CubicSDR"); frequency = wxGetApp().getConfig()->getCenterFreq(); diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index 0f49ccd..a9a0d48 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -13,7 +13,17 @@ #define DEMOD_TYPE_LSB 3 #define DEMOD_TYPE_USB 4 #define DEMOD_TYPE_DSB 5 -#define DEMOD_TYPE_RAW 6 +#define DEMOD_TYPE_ASK 6 +#define DEMOD_TYPE_APSK 7 +#define DEMOD_TYPE_BPSK 8 +#define DEMOD_TYPE_DPSK 9 +#define DEMOD_TYPE_PSK 10 +#define DEMOD_TYPE_OOK 11 +#define DEMOD_TYPE_ST 12 +#define DEMOD_TYPE_SQAM 13 +#define DEMOD_TYPE_QAM 14 +#define DEMOD_TYPE_QPSK 15 +#define DEMOD_TYPE_RAW 16 #include "IOThread.h" diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index b03ece4..f5d285a 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -45,6 +45,7 @@ DemodulatorInstance::DemodulatorInstance() : audioThread->setOutputQueue("NotifyQueue", pipeDemodNotify); currentDemodType = demodulatorThread->getDemodulatorType(); + currentDemodCons = demodulatorThread->getDemodulatorCons(); } DemodulatorInstance::~DemodulatorInstance() { @@ -74,6 +75,7 @@ void DemodulatorInstance::run() { currentFrequency = demodulatorPreThread->getParams().frequency; currentDemodType = demodulatorThread->getDemodulatorType(); + currentDemodCons = demodulatorThread->getDemodulatorCons(); currentAudioSampleRate = AudioThread::deviceSampleRate[getOutputDevice()]; demodulatorPreThread->getParams().audioSampleRate = currentAudioSampleRate; @@ -302,6 +304,22 @@ int DemodulatorInstance::getDemodulatorType() { return currentDemodType; } +void DemodulatorInstance::setDemodulatorLock(bool demod_lock_in) { + demodulatorThread->setDemodulatorLock(demod_lock_in); +} + +int DemodulatorInstance::getDemodulatorLock() { + return demodulatorThread->getDemodulatorLock(); +} + +void DemodulatorInstance::setDemodulatorCons(int demod_cons_in) { + demodulatorThread->setDemodulatorCons(demod_cons_in); +} + +int DemodulatorInstance::getDemodulatorCons() { + return demodulatorThread->getDemodulatorCons(); +} + void DemodulatorInstance::setBandwidth(int bw) { if (currentDemodType == DEMOD_TYPE_RAW) { if (currentAudioSampleRate) { diff --git a/src/demod/DemodulatorInstance.h b/src/demod/DemodulatorInstance.h index cc9da67..19d3fb6 100644 --- a/src/demod/DemodulatorInstance.h +++ b/src/demod/DemodulatorInstance.h @@ -55,6 +55,12 @@ public: void setDemodulatorType(int demod_type_in); int getDemodulatorType(); + + void setDemodulatorLock(bool demod_lock_in); + int getDemodulatorLock(); + + void setDemodulatorCons(int demod_cons_in); + int getDemodulatorCons(); void setBandwidth(int bw); int getBandwidth(); @@ -106,6 +112,7 @@ private: std::atomic_llong currentFrequency; std::atomic_int currentBandwidth; std::atomic_int currentDemodType; + std::atomic_int currentDemodCons; std::atomic_int currentOutputDevice; std::atomic_int currentAudioSampleRate; std::atomic currentAudioGain; diff --git a/src/demod/DemodulatorMgr.cpp b/src/demod/DemodulatorMgr.cpp index 1931d3e..fcc2c1b 100644 --- a/src/demod/DemodulatorMgr.cpp +++ b/src/demod/DemodulatorMgr.cpp @@ -17,7 +17,6 @@ DemodulatorMgr::~DemodulatorMgr() { DemodulatorInstance *DemodulatorMgr::newThread() { DemodulatorInstance *newDemod = new DemodulatorInstance; - demods.push_back(newDemod); std::stringstream label; @@ -162,6 +161,8 @@ void DemodulatorMgr::updateLastState() { if (lastActiveDemodulator) { lastBandwidth = lastActiveDemodulator->getBandwidth(); lastDemodType = lastActiveDemodulator->getDemodulatorType(); + lastDemodLock = lastActiveDemodulator->getDemodulatorLock(); + lastDemodCons = lastActiveDemodulator->getDemodulatorCons(); lastSquelchEnabled = lastActiveDemodulator->isSquelchEnabled(); lastSquelch = lastActiveDemodulator->getSquelchLevel(); lastGain = lastActiveDemodulator->getGain(); @@ -191,6 +192,14 @@ void DemodulatorMgr::setLastDemodulatorType(int lastDemodType) { this->lastDemodType = lastDemodType; } +int DemodulatorMgr::getLastDemodulatorCons() const { + return lastDemodCons; +} + +void DemodulatorMgr::setLastDemodulatorCons(int lastDemodCons) { + this->lastDemodCons = lastDemodCons; +} + float DemodulatorMgr::getLastGain() const { return lastGain; } diff --git a/src/demod/DemodulatorMgr.h b/src/demod/DemodulatorMgr.h index 56f752f..0cfb4ed 100644 --- a/src/demod/DemodulatorMgr.h +++ b/src/demod/DemodulatorMgr.h @@ -27,6 +27,9 @@ public: int getLastDemodulatorType() const; void setLastDemodulatorType(int lastDemodType); + + int getLastDemodulatorCons() const; + void setLastDemodulatorCons(int lastDemodCons); float getLastGain() const; void setLastGain(float lastGain); @@ -55,6 +58,8 @@ private: int lastBandwidth; int lastDemodType; + bool lastDemodLock; + int lastDemodCons; bool lastSquelchEnabled; float lastSquelch; float lastGain; diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index 220560f..b46ff03 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -24,7 +24,74 @@ DemodulatorThread::DemodulatorThread() : IOThread(), iqAutoGain(NULL), amOutputC demodAM_DSB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 1); demodAM_DSB_CSP = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 0); demodAM = demodAM_DSB_CSP; + + // advanced demodulators + + demodulatorCons.store(2); + currentDemodCons = 0; + + demodASK = demodASK2; + demodASK2 = modem_create(LIQUID_MODEM_ASK2); + demodASK4 = modem_create(LIQUID_MODEM_ASK4); + demodASK8 = modem_create(LIQUID_MODEM_ASK8); + demodASK16 = modem_create(LIQUID_MODEM_ASK16); + demodASK32 = modem_create(LIQUID_MODEM_ASK32); + demodASK64 = modem_create(LIQUID_MODEM_ASK64); + demodASK128 = modem_create(LIQUID_MODEM_ASK128); + demodASK256 = modem_create(LIQUID_MODEM_ASK256); + demodAPSK = demodAPSK4; + demodAPSK4 = modem_create(LIQUID_MODEM_APSK4); + demodAPSK8 = modem_create(LIQUID_MODEM_APSK8); + demodAPSK16 = modem_create(LIQUID_MODEM_APSK16); + demodAPSK32 = modem_create(LIQUID_MODEM_APSK32); + demodAPSK64 = modem_create(LIQUID_MODEM_APSK64); + demodAPSK128 = modem_create(LIQUID_MODEM_APSK128); + demodAPSK256 = modem_create(LIQUID_MODEM_APSK256); + + demodBPSK = modem_create(LIQUID_MODEM_BPSK); + + demodDPSK = demodDPSK2; + demodDPSK2 = modem_create(LIQUID_MODEM_DPSK2); + demodDPSK4 = modem_create(LIQUID_MODEM_DPSK4); + demodDPSK8 = modem_create(LIQUID_MODEM_DPSK8); + demodDPSK16 = modem_create(LIQUID_MODEM_DPSK16); + demodDPSK32 = modem_create(LIQUID_MODEM_DPSK32); + demodDPSK64 = modem_create(LIQUID_MODEM_DPSK64); + demodDPSK128 = modem_create(LIQUID_MODEM_DPSK128); + demodDPSK256 = modem_create(LIQUID_MODEM_DPSK256); + + demodPSK = demodPSK2; + demodPSK2 = modem_create(LIQUID_MODEM_PSK2); + demodPSK4 = modem_create(LIQUID_MODEM_PSK4); + demodPSK8 = modem_create(LIQUID_MODEM_PSK8); + demodPSK16 = modem_create(LIQUID_MODEM_PSK16); + demodPSK32 = modem_create(LIQUID_MODEM_PSK32); + demodPSK64 = modem_create(LIQUID_MODEM_PSK64); + demodPSK128 = modem_create(LIQUID_MODEM_PSK128); + demodPSK256 = modem_create(LIQUID_MODEM_PSK256); + + demodOOK = modem_create(LIQUID_MODEM_OOK); + + demodSQAM = demodSQAM32; + demodSQAM32 = modem_create(LIQUID_MODEM_SQAM32); + demodSQAM128 = modem_create(LIQUID_MODEM_SQAM128); + + demodST = modem_create(LIQUID_MODEM_V29); + + demodQAM = demodQAM4; + demodQAM4 = modem_create(LIQUID_MODEM_QAM4); + demodQAM8 = modem_create(LIQUID_MODEM_QAM8); + demodQAM16 = modem_create(LIQUID_MODEM_QAM16); + demodQAM32 = modem_create(LIQUID_MODEM_QAM32); + demodQAM64 = modem_create(LIQUID_MODEM_QAM64); + demodQAM128 = modem_create(LIQUID_MODEM_QAM128); + demodQAM256 = modem_create(LIQUID_MODEM_QAM256); + + demodQPSK = modem_create(LIQUID_MODEM_QPSK); + + currentDemodLock = false; + } DemodulatorThread::~DemodulatorThread() { } @@ -156,12 +223,19 @@ void DemodulatorThread::run() { double audio_resample_ratio = inp->audioResampleRatio; - if (demodOutputData.size() != bufSize) { - if (demodOutputData.capacity() < bufSize) { - demodOutputData.reserve(bufSize); - } - demodOutputData.resize(bufSize); - } + if (demodOutputData.size() != bufSize) { + if (demodOutputData.capacity() < bufSize) { + demodOutputData.reserve(bufSize); + } + demodOutputData.resize(bufSize); + } + + if (demodOutputDataDigital.size() != bufSize) { + if (demodOutputDataDigital.capacity() < bufSize) { + demodOutputDataDigital.reserve(bufSize); + } + demodOutputDataDigital.resize(bufSize); + } int audio_out_size = ceil((double) (bufSize) * audio_resample_ratio) + 512; @@ -183,19 +257,25 @@ void DemodulatorThread::run() { inputData = &inp->data; } + // Reset demodulator Constellations & Lock + updateDemodulatorCons(0); + if (demodulatorType == DEMOD_TYPE_FM) { + currentDemodLock = false; freqdem_demodulate_block(demodFM, &(*inputData)[0], bufSize, &demodOutputData[0]); } else if (demodulatorType == DEMOD_TYPE_RAW) { // do nothing here.. } else { switch (demodulatorType.load()) { case DEMOD_TYPE_LSB: + currentDemodLock = false; for (int i = 0; i < bufSize; i++) { // Reject upper band resamp2_crcf_filter_execute(ssbFilt,(*inputData)[i],&x,&y); ampmodem_demodulate(demodAM, x, &demodOutputData[i]); } break; case DEMOD_TYPE_USB: + currentDemodLock = false; for (int i = 0; i < bufSize; i++) { // Reject lower band resamp2_crcf_filter_execute(ssbFilt,(*inputData)[i],&x,&y); ampmodem_demodulate(demodAM, y, &demodOutputData[i]); @@ -203,9 +283,305 @@ void DemodulatorThread::run() { break; case DEMOD_TYPE_AM: case DEMOD_TYPE_DSB: + currentDemodLock = false; for (int i = 0; i < bufSize; i++) { ampmodem_demodulate(demodAM, (*inputData)[i], &demodOutputData[i]); } + break; + // advanced demodulators + case DEMOD_TYPE_ASK: + + switch (demodulatorCons.load()) { + case 2: + demodASK = demodASK2; + updateDemodulatorCons(2); + break; + case 4: + demodASK = demodASK4; + updateDemodulatorCons(4); + break; + case 8: + demodASK = demodASK8; + updateDemodulatorCons(8); + break; + case 16: + demodASK = demodASK16; + updateDemodulatorCons(16); + break; + case 32: + demodASK = demodASK32; + updateDemodulatorCons(32); + break; + case 64: + demodASK = demodASK64; + updateDemodulatorCons(64); + break; + case 128: + demodASK = demodASK128; + updateDemodulatorCons(128); + break; + case 256: + demodASK = demodASK256; + updateDemodulatorCons(256); + break; + default: + demodASK = demodASK2; + break; + } + + for (int i = 0; i < bufSize; i++) { + modem_demodulate(demodASK, inp->data[i], &demodOutputDataDigital[i]); + } + updateDemodulatorLock(demodASK, 0.005f); + break; + case DEMOD_TYPE_APSK: + + switch (demodulatorCons.load()) { + case 2: + demodAPSK = demodAPSK4; + updateDemodulatorCons(4); + break; + case 4: + demodAPSK = demodAPSK4; + updateDemodulatorCons(4); + break; + case 8: + demodAPSK = demodAPSK8; + updateDemodulatorCons(8); + break; + case 16: + demodAPSK = demodAPSK16; + updateDemodulatorCons(16); + break; + case 32: + demodAPSK = demodAPSK32; + updateDemodulatorCons(32); + break; + case 64: + demodAPSK = demodAPSK64; + updateDemodulatorCons(64); + break; + case 128: + demodAPSK = demodAPSK128; + updateDemodulatorCons(128); + break; + case 256: + demodAPSK = demodAPSK256; + updateDemodulatorCons(256); + break; + default: + demodAPSK = demodAPSK4; + break; + } + + for (int i = 0; i < bufSize; i++) { + modem_demodulate(demodAPSK, inp->data[i], &demodOutputDataDigital[i]); + } + updateDemodulatorLock(demodAPSK, 0.005f); + break; + case DEMOD_TYPE_BPSK: + for (int i = 0; i < bufSize; i++) { + modem_demodulate(demodBPSK, inp->data[i], &demodOutputDataDigital[i]); + } + updateDemodulatorLock(demodBPSK, 0.005f); + break; + case DEMOD_TYPE_DPSK: + + switch (demodulatorCons.load()) { + case 2: + demodDPSK = demodDPSK2; + updateDemodulatorCons(2); + break; + case 4: + demodDPSK = demodDPSK4; + updateDemodulatorCons(4); + break; + case 8: + demodDPSK = demodDPSK8; + updateDemodulatorCons(8); + break; + case 16: + demodDPSK = demodDPSK16; + updateDemodulatorCons(16); + break; + case 32: + demodDPSK = demodDPSK32; + updateDemodulatorCons(32); + break; + case 64: + demodDPSK = demodDPSK64; + updateDemodulatorCons(64); + break; + case 128: + demodDPSK = demodDPSK128; + updateDemodulatorCons(128); + break; + case 256: + demodDPSK = demodDPSK256; + updateDemodulatorCons(256); + break; + default: + demodDPSK = demodDPSK2; + break; + } + + for (int i = 0; i < bufSize; i++) { + modem_demodulate(demodDPSK, inp->data[i], &demodOutputDataDigital[i]); + } + updateDemodulatorLock(demodDPSK, 0.005f); + break; + case DEMOD_TYPE_PSK: + + switch (demodulatorCons.load()) { + case 2: + demodPSK = demodPSK2; + updateDemodulatorCons(2); + break; + case 4: + demodPSK = demodPSK4; + updateDemodulatorCons(4); + break; + case 8: + demodPSK = demodPSK8; + updateDemodulatorCons(8); + break; + case 16: + demodPSK = demodPSK16; + updateDemodulatorCons(16); + break; + case 32: + demodPSK = demodPSK32; + updateDemodulatorCons(32); + break; + case 64: + demodPSK = demodPSK64; + updateDemodulatorCons(64); + break; + case 128: + demodPSK = demodPSK128; + updateDemodulatorCons(128); + break; + case 256: + demodPSK = demodPSK256; + updateDemodulatorCons(256); + break; + default: + demodPSK = demodPSK2; + break; + } + + for (int i = 0; i < bufSize; i++) { + modem_demodulate(demodPSK, inp->data[i], &demodOutputDataDigital[i]); + } + updateDemodulatorLock(demodPSK, 0.005f); + break; + case DEMOD_TYPE_OOK: + for (int i = 0; i < bufSize; i++) { + modem_demodulate(demodOOK, inp->data[i], &demodOutputDataDigital[i]); + } + updateDemodulatorLock(demodOOK, 0.005f); + break; + case DEMOD_TYPE_SQAM: + + switch (demodulatorCons.load()) { + case 2: + demodSQAM = demodSQAM32; + updateDemodulatorCons(32); + break; + case 4: + demodSQAM = demodSQAM32; + updateDemodulatorCons(32); + break; + case 8: + demodSQAM = demodSQAM32; + updateDemodulatorCons(32); + break; + case 16: + demodSQAM = demodSQAM32; + updateDemodulatorCons(32); + break; + case 32: + demodSQAM = demodSQAM32; + updateDemodulatorCons(32); + break; + case 64: + demodSQAM = demodSQAM32; + updateDemodulatorCons(32); + break; + case 128: + demodSQAM = demodSQAM128; + updateDemodulatorCons(128); + break; + case 256: + demodSQAM = demodSQAM128; + updateDemodulatorCons(128); + break; + default: + demodSQAM = demodSQAM32; + break; + } + + for (int i = 0; i < bufSize; i++) { + modem_demodulate(demodSQAM, inp->data[i], &demodOutputDataDigital[i]); + } + updateDemodulatorLock(demodSQAM, 0.005f); + break; + case DEMOD_TYPE_ST: + for (int i = 0; i < bufSize; i++) { + modem_demodulate(demodST, inp->data[i], &demodOutputDataDigital[i]); + } + updateDemodulatorLock(demodST, 0.005f); + break; + case DEMOD_TYPE_QAM: + + switch (demodulatorCons.load()) { + case 2: + demodQAM = demodQAM4; + updateDemodulatorCons(4); + break; + case 4: + demodQAM = demodQAM4; + updateDemodulatorCons(4); + break; + case 8: + demodQAM = demodQAM8; + updateDemodulatorCons(8); + break; + case 16: + demodQAM = demodQAM16; + updateDemodulatorCons(16); + break; + case 32: + demodQAM = demodQAM32; + updateDemodulatorCons(32); + break; + case 64: + demodQAM = demodQAM64; + updateDemodulatorCons(64); + break; + case 128: + demodQAM = demodQAM128; + updateDemodulatorCons(128); + break; + case 256: + demodQAM = demodQAM256; + updateDemodulatorCons(256); + break; + default: + demodQAM = demodQAM4; + break; + } + + for (int i = 0; i < bufSize; i++) { + modem_demodulate(demodQAM, inp->data[i], &demodOutputDataDigital[i]); + } + updateDemodulatorLock(demodQAM, 0.5f); + break; + case DEMOD_TYPE_QPSK: + for (int i = 0; i < bufSize; i++) { + modem_demodulate(demodQPSK, inp->data[i], &demodOutputDataDigital[i]); + } + updateDemodulatorLock(demodQPSK, 0.8f); break; } @@ -218,7 +594,7 @@ void DemodulatorThread::run() { if (demodOutputData[i] > amOutputCeil) { amOutputCeil = demodOutputData[i]; } - } + } float gain = 0.5 / amOutputCeilMAA; @@ -457,13 +833,49 @@ void DemodulatorThread::run() { demodAM = demodAM_DSB_CSP; ampmodem_reset(demodAM); break; + case DEMOD_TYPE_ASK: + //modem_reset(demodASK); + break; + case DEMOD_TYPE_APSK: + //modem_reset(demodAPSK); + break; + case DEMOD_TYPE_BPSK: + //modem_reset(demodBPSK); + break; + case DEMOD_TYPE_DPSK: + //modem_reset(demodDPSK); + break; + case DEMOD_TYPE_PSK: + //modem_reset(demodPSK); + break; + case DEMOD_TYPE_OOK: + //modem_reset(demodOOK); + break; + case DEMOD_TYPE_SQAM: + //modem_reset(demodSQAM); + break; + case DEMOD_TYPE_ST: + //modem_reset(demodST); + break; + case DEMOD_TYPE_QAM: + //modem_reset(demodQAM); + break; + case DEMOD_TYPE_QPSK: + //modem_reset(demodQPSK); + break; + default: + // empty default to prevent exceptions + break; } demodulatorType = newDemodType; } } + demodOutputDataDigital.empty(); + inp->decRefCount(); } + // end while !terminated if (audioResampler != NULL) { msresamp_rrrf_destroy(audioResampler); @@ -557,3 +969,28 @@ int DemodulatorThread::getDemodulatorType() { return demodulatorType; } +void DemodulatorThread::setDemodulatorLock(bool demod_lock_in) { + demod_lock_in ? currentDemodLock = true : currentDemodLock = false; +} + +int DemodulatorThread::getDemodulatorLock() { + return currentDemodLock; +} + +void DemodulatorThread::setDemodulatorCons(int demod_cons_in) { + demodulatorCons.store(demod_cons_in); +} + +int DemodulatorThread::getDemodulatorCons() { + return currentDemodCons; +} + +void DemodulatorThread::updateDemodulatorLock(modem demod, float sensitivity) { + modem_get_demodulator_evm(demod) <= sensitivity ? setDemodulatorLock(true) : setDemodulatorLock(false); +} + +void DemodulatorThread::updateDemodulatorCons(int Cons) { + if (currentDemodCons != Cons) { + currentDemodCons = Cons; + } +} diff --git a/src/demod/DemodulatorThread.h b/src/demod/DemodulatorThread.h index 91d6b0c..891849f 100644 --- a/src/demod/DemodulatorThread.h +++ b/src/demod/DemodulatorThread.h @@ -36,6 +36,12 @@ public: void setDemodulatorType(int demod_type_in); int getDemodulatorType(); + + void setDemodulatorLock(bool demod_lock_in); + int getDemodulatorLock(); + + void setDemodulatorCons(int demod_cons_in); + int getDemodulatorCons(); #ifdef __APPLE__ static void *pthread_helper(void *context) { @@ -52,6 +58,11 @@ protected: std::vector demodStereoData; std::vector resampledOutputData; std::vector resampledStereoData; + std::vector demodOutputDataDigital; + //std::vector demodOutputDataDigitalTest; + + //std::vector demodOutputSoftbits; + //std::vector demodOutputSoftbitsTest; freqdem demodFM; ampmodem demodAM; @@ -60,6 +71,66 @@ protected: ampmodem demodAM_LSB; ampmodem demodAM_USB; + modem demodASK; + modem demodASK2; + modem demodASK4; + modem demodASK8; + modem demodASK16; + modem demodASK32; + modem demodASK64; + modem demodASK128; + modem demodASK256; + + modem demodAPSK; + modem demodAPSK4; + modem demodAPSK8; + modem demodAPSK16; + modem demodAPSK32; + modem demodAPSK64; + modem demodAPSK128; + modem demodAPSK256; + + modem demodBPSK; + + modem demodDPSK; + modem demodDPSK2; + modem demodDPSK4; + modem demodDPSK8; + modem demodDPSK16; + modem demodDPSK32; + modem demodDPSK64; + modem demodDPSK128; + modem demodDPSK256; + + modem demodPSK; + modem demodPSK2; + modem demodPSK4; + modem demodPSK8; + modem demodPSK16; + modem demodPSK32; + modem demodPSK64; + modem demodPSK128; + modem demodPSK256; + + modem demodOOK; + + modem demodSQAM; + modem demodSQAM32; + modem demodSQAM128; + + modem demodST; + + modem demodQAM; + modem demodQAM4; + modem demodQAM8; + modem demodQAM16; + modem demodQAM32; + modem demodQAM64; + modem demodQAM128; + modem demodQAM256; + + modem demodQPSK; + agc_crcf iqAutoGain; float amOutputCeil; @@ -70,12 +141,19 @@ protected: std::atomic_bool muted; std::atomic_bool agcEnabled; std::atomic_int demodulatorType; + std::atomic_int demodulatorCons; int audioSampleRate; std::atomic squelchLevel; std::atomic signalLevel; bool squelchEnabled; + bool currentDemodLock; + int currentDemodCons; + + void updateDemodulatorCons(int Cons); + void updateDemodulatorLock(modem demod, float sensitivity); + DemodulatorThreadPostInputQueue* iqInputQueue; AudioThreadInputQueue *audioOutputQueue; DemodulatorThreadOutputQueue* audioVisOutputQueue; diff --git a/src/visual/PrimaryGLContext.cpp b/src/visual/PrimaryGLContext.cpp index 29d2391..f11fdac 100644 --- a/src/visual/PrimaryGLContext.cpp +++ b/src/visual/PrimaryGLContext.cpp @@ -236,8 +236,61 @@ void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, RGBA4f color, long demodAlign = GLFont::GLFONT_ALIGN_LEFT; uxPos += xOfs; break; + // advanced demodulators start here + case DEMOD_TYPE_ASK: + demodStr = "ASK"; + demodAlign = GLFont::GLFONT_ALIGN_CENTER; + break; + case DEMOD_TYPE_APSK: + demodStr = "APSK"; + demodAlign = GLFont::GLFONT_ALIGN_CENTER; + break; + case DEMOD_TYPE_BPSK: + demodStr = "BPSK"; + demodAlign = GLFont::GLFONT_ALIGN_CENTER; + break; + case DEMOD_TYPE_DPSK: + demodStr = "DPSK"; + demodAlign = GLFont::GLFONT_ALIGN_CENTER; + break; + case DEMOD_TYPE_PSK: + demodStr = "PSK"; + demodAlign = GLFont::GLFONT_ALIGN_CENTER; + break; + case DEMOD_TYPE_OOK: + demodStr = "OOK"; + demodAlign = GLFont::GLFONT_ALIGN_CENTER; + break; + case DEMOD_TYPE_SQAM: + demodStr = "SQAM"; + demodAlign = GLFont::GLFONT_ALIGN_CENTER; + break; + case DEMOD_TYPE_ST: + demodStr = "ST"; + demodAlign = GLFont::GLFONT_ALIGN_CENTER; + break; + case DEMOD_TYPE_QAM: + demodStr = "QAM"; + demodAlign = GLFont::GLFONT_ALIGN_CENTER; + break; + case DEMOD_TYPE_QPSK: + demodStr = "QPSK"; + demodAlign = GLFont::GLFONT_ALIGN_CENTER; + break; } + if (demod->getDemodulatorCons() != NULL && demod->getDemodulatorCons() > 0) { + demodStr = demodStr + std::to_string(demod->getDemodulatorCons()); + } + + // add lock to string if we have an lock + if(demod->getDemodulatorLock()) { + demodStr = demodStr + " Lock"; + } + // else { + // demodStr = demodStr + " UnLock"; + // } + glColor3f(0, 0, 0); GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodStr, 2.0 * (uxPos - 0.5) + xOfs, -1.0 + hPos - yOfs, 16, demodAlign, GLFont::GLFONT_ALIGN_CENTER);