From 76d69ffd78817a4781dca266d917a6efd3261f0d Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 30 Nov 2015 21:58:54 -0500 Subject: [PATCH] Add GMSK, fix modem bandwidth logic, cleanup. --- CMakeLists.txt | 2 + src/AppFrame.cpp | 48 ++++---- src/CubicSDR.cpp | 1 + src/CubicSDR.h | 1 + src/ModemProperties.cpp | 26 +++- src/ModemProperties.h | 5 + src/demod/DemodulatorInstance.cpp | 13 +- src/demod/DemodulatorInstance.h | 1 + src/demod/DemodulatorMgr.cpp | 15 --- src/demod/DemodulatorMgr.h | 4 - src/modules/modem/Modem.cpp | 14 +++ src/modules/modem/Modem.h | 2 + src/modules/modem/analog/ModemAM.cpp | 8 ++ src/modules/modem/analog/ModemAM.h | 6 + src/modules/modem/analog/ModemDSB.cpp | 8 ++ src/modules/modem/analog/ModemDSB.h | 6 + src/modules/modem/analog/ModemFM.cpp | 8 ++ src/modules/modem/analog/ModemFM.h | 7 +- src/modules/modem/analog/ModemFMStereo.cpp | 4 + src/modules/modem/analog/ModemFMStereo.h | 1 + src/modules/modem/analog/ModemIQ.cpp | 20 ++-- src/modules/modem/analog/ModemIQ.h | 9 +- src/modules/modem/analog/ModemLSB.cpp | 4 + src/modules/modem/analog/ModemLSB.h | 6 +- src/modules/modem/analog/ModemUSB.cpp | 4 + src/modules/modem/analog/ModemUSB.h | 5 + src/modules/modem/digital/ModemFSK.cpp | 4 + src/modules/modem/digital/ModemFSK.h | 1 + src/modules/modem/digital/ModemGMSK.cpp | 133 +++++++++++++++++++++ src/modules/modem/digital/ModemGMSK.h | 41 +++++++ src/modules/modem/digital/ModemOOK.cpp | 15 ++- src/modules/modem/digital/ModemOOK.h | 2 + src/visual/ModeSelectorCanvas.cpp | 5 + src/visual/ModeSelectorCanvas.h | 1 + src/visual/WaterfallCanvas.cpp | 12 +- 35 files changed, 365 insertions(+), 77 deletions(-) create mode 100644 src/modules/modem/digital/ModemGMSK.cpp create mode 100644 src/modules/modem/digital/ModemGMSK.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f07098..5c2c651 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -297,6 +297,7 @@ IF(ENABLE_DIGITAL_LAB) src/modules/modem/digital/ModemBPSK.cpp src/modules/modem/digital/ModemDPSK.cpp src/modules/modem/digital/ModemFSK.cpp + src/modules/modem/digital/ModemGMSK.cpp src/modules/modem/digital/ModemPSK.cpp src/modules/modem/digital/ModemOOK.cpp src/modules/modem/digital/ModemST.cpp @@ -402,6 +403,7 @@ SET (cubicsdr_headers src/modules/modem/digital/ModemBPSK.h src/modules/modem/digital/ModemDPSK.h src/modules/modem/digital/ModemFSK.h + src/modules/modem/digital/ModemGMSK.h src/modules/modem/digital/ModemPSK.h src/modules/modem/digital/ModemOOK.h src/modules/modem/digital/ModemST.h diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 7cc5339..82deeac 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -67,13 +67,13 @@ AppFrame::AppFrame() : gainSpacerItem->Show(false); demodModeSelector = new ModeSelectorCanvas(demodPanel, attribList); - demodModeSelector->addChoice(0, "FM"); - demodModeSelector->addChoice(1, "FMS"); - demodModeSelector->addChoice(2, "AM"); - demodModeSelector->addChoice(3, "LSB"); - demodModeSelector->addChoice(4, "USB"); - demodModeSelector->addChoice(5, "DSB"); - demodModeSelector->addChoice(6, "I/Q"); + demodModeSelector->addChoice("FM"); + demodModeSelector->addChoice("FMS"); + demodModeSelector->addChoice("AM"); + demodModeSelector->addChoice("LSB"); + demodModeSelector->addChoice("USB"); + demodModeSelector->addChoice("DSB"); + demodModeSelector->addChoice("I/Q"); demodModeSelector->setSelection("FM"); demodModeSelector->setHelpTip("Choose modulation type: Frequency Modulation, Amplitude Modulation and Lower, Upper or Double Side-Band."); demodModeSelector->SetMinSize(wxSize(40,-1)); @@ -82,17 +82,18 @@ AppFrame::AppFrame() : #ifdef ENABLE_DIGITAL_LAB demodModeSelectorAdv = new ModeSelectorCanvas(demodPanel, attribList); - demodModeSelectorAdv->addChoice(0, "ASK"); - demodModeSelectorAdv->addChoice(1, "APSK"); - demodModeSelectorAdv->addChoice(2, "BPSK"); - demodModeSelectorAdv->addChoice(3, "DPSK"); - demodModeSelectorAdv->addChoice(4, "PSK"); - demodModeSelectorAdv->addChoice(5, "FSK"); - demodModeSelectorAdv->addChoice(6, "OOK"); - demodModeSelectorAdv->addChoice(7, "ST"); - demodModeSelectorAdv->addChoice(8, "SQAM"); - demodModeSelectorAdv->addChoice(9, "QAM"); - demodModeSelectorAdv->addChoice(10, "QPSK"); + demodModeSelectorAdv->addChoice("ASK"); + demodModeSelectorAdv->addChoice("APSK"); + demodModeSelectorAdv->addChoice("BPSK"); + demodModeSelectorAdv->addChoice("DPSK"); + demodModeSelectorAdv->addChoice("PSK"); + demodModeSelectorAdv->addChoice("FSK"); + demodModeSelectorAdv->addChoice("GMSK"); + demodModeSelectorAdv->addChoice("OOK"); + demodModeSelectorAdv->addChoice("ST"); + demodModeSelectorAdv->addChoice("SQAM"); + demodModeSelectorAdv->addChoice("QAM"); + demodModeSelectorAdv->addChoice("QPSK"); demodModeSelectorAdv->setHelpTip("Choose advanced modulation types."); demodModeSelectorAdv->SetMinSize(wxSize(40,-1)); demodModeSelectorAdv->SetMaxSize(wxSize(40,-1)); @@ -906,25 +907,16 @@ void AppFrame::OnIdle(wxIdleEvent& event) { if (dSelection != "" && dSelection != demod->getDemodulatorType()) { demod->setDemodulatorType(dSelection); demodModeSelectorAdv->setSelection(-1); - if (int lastDemodBw = wxGetApp().getDemodMgr().getLastBandwidth(dSelection)) { - demod->setBandwidth(lastDemodBw); - } } // advanced demodulators else if (dSelectionadv != "" && dSelectionadv != demod->getDemodulatorType()) { demod->setDemodulatorType(dSelectionadv); demodModeSelector->setSelection(-1); - if (int lastDemodBw = wxGetApp().getDemodMgr().getLastBandwidth(dSelection)) { - demod->setBandwidth(lastDemodBw); - } } #else // basic demodulators if (dSelection != "" && dSelection != demod->getDemodulatorType()) { demod->setDemodulatorType(dSelection); - if (int lastDemodBw = wxGetApp().getDemodMgr().getLastBandwidth(dSelection)) { - demod->setBandwidth(lastDemodBw); - } } #endif @@ -1017,7 +1009,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) { if (!demodTuner->HasFocus()) { demodTuner->SetFocus(); } - } else if (!wxGetApp().isDeviceSelectorOpen()) { + } else if (!wxGetApp().isDeviceSelectorOpen() && (!modemProps || !modemProps->isMouseInView())) { if (!waterfallCanvas->HasFocus()) { waterfallCanvas->SetFocus(); } diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 2e917e6..e480765 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -178,6 +178,7 @@ bool CubicSDR::OnInit() { Modem::addModemFactory(new ModemBPSK); Modem::addModemFactory(new ModemDPSK); Modem::addModemFactory(new ModemFSK); + Modem::addModemFactory(new ModemGMSK); Modem::addModemFactory(new ModemOOK); Modem::addModemFactory(new ModemPSK); Modem::addModemFactory(new ModemQAM); diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 6de2843..381b308 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -43,6 +43,7 @@ #include "ModemBPSK.h" #include "ModemDPSK.h" #include "ModemFSK.h" +#include "ModemGMSK.h" #include "ModemOOK.h" #include "ModemPSK.h" #include "ModemQAM.h" diff --git a/src/ModemProperties.cpp b/src/ModemProperties.cpp index d8c2546..0472bff 100644 --- a/src/ModemProperties.cpp +++ b/src/ModemProperties.cpp @@ -14,10 +14,14 @@ ModemProperties::ModemProperties(wxWindow *parent, wxWindowID winid, m_propertyGrid->Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( ModemProperties::OnChange ), NULL, this ); this->Connect( wxEVT_SHOW, wxShowEventHandler( ModemProperties::OnShow ), NULL, this ); + + this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( ModemProperties::OnMouseEnter ), NULL, this); + this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( ModemProperties::OnMouseLeave ), NULL, this); + + mouseInView = false; } void ModemProperties::OnShow(wxShowEvent &event) { - m_propertyGrid->FitColumns(); } ModemProperties::~ModemProperties() { @@ -27,6 +31,7 @@ ModemProperties::~ModemProperties() { void ModemProperties::initProperties(ModemArgInfoList newArgs) { args = newArgs; + bSizer->Layout(); m_propertyGrid->Clear(); if (newArgs.size() == 0) { @@ -35,9 +40,6 @@ void ModemProperties::initProperties(ModemArgInfoList newArgs) { } else { Show(); } - - bSizer->Layout(); - Layout(); m_propertyGrid->Append(new wxPropertyCategory("Modem Settings")); @@ -149,6 +151,10 @@ std::string ModemProperties::readProperty(std::string key) { void ModemProperties::OnChange(wxPropertyGridEvent &event) { DemodulatorInstance *inst = wxGetApp().getDemodMgr().getLastActiveDemodulator(); + if (!inst) { + return; + } + std::map::const_iterator prop_i; for (prop_i = props.begin(); prop_i != props.end(); prop_i++) { if (prop_i->second == event.m_property) { @@ -159,3 +165,15 @@ void ModemProperties::OnChange(wxPropertyGridEvent &event) { } } } + +void ModemProperties::OnMouseEnter(wxMouseEvent &event) { + mouseInView = true; +} + +void ModemProperties::OnMouseLeave(wxMouseEvent &event) { + mouseInView = false; +} + +bool ModemProperties::isMouseInView() { + return mouseInView; +} diff --git a/src/ModemProperties.h b/src/ModemProperties.h index 5a101c0..326c947 100644 --- a/src/ModemProperties.h +++ b/src/ModemProperties.h @@ -20,15 +20,20 @@ public: ~ModemProperties(); void initProperties(ModemArgInfoList newArgs); + bool isMouseInView(); private: wxPGProperty *addArgInfoProperty(wxPropertyGrid *pg, ModemArgInfo arg); std::string readProperty(std::string); void OnChange(wxPropertyGridEvent &event); void OnShow(wxShowEvent &event); + + void OnMouseEnter(wxMouseEvent &event); + void OnMouseLeave(wxMouseEvent &event); wxBoxSizer* bSizer; wxPropertyGrid* m_propertyGrid; ModemArgInfoList args; std::map props; + bool mouseInView; }; \ No newline at end of file diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index 6a4badd..f3da7fb 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -264,13 +264,25 @@ void DemodulatorInstance::setDemodulatorType(std::string demod_type_in) { std::string currentDemodType = demodulatorPreThread->getDemodType(); if ((currentDemodType != "") && (currentDemodType != demod_type_in)) { lastModemSettings[currentDemodType] = demodulatorPreThread->readModemSettings(); + lastModemBandwidth[currentDemodType] = demodulatorPreThread->getBandwidth(); } #if ENABLE_DIGITAL_LAB if (activeOutput) { activeOutput->Hide(); } #endif + demodulatorPreThread->setDemodType(demod_type_in); + int lastbw = 0; + if (currentDemodType != "" && lastModemBandwidth.find(demod_type_in) != lastModemBandwidth.end()) { + lastbw = lastModemBandwidth[demod_type_in]; + } + if (!lastbw) { + lastbw = Modem::getModemDefaultSampleRate(demod_type_in); + } + if (lastbw) { + setBandwidth(lastbw); + } } } @@ -297,7 +309,6 @@ int DemodulatorInstance::getDemodulatorLock() { void DemodulatorInstance::setBandwidth(int bw) { demodulatorPreThread->setBandwidth(bw); - wxGetApp().getDemodMgr().setLastBandwidth(bw); } int DemodulatorInstance::getBandwidth() { diff --git a/src/demod/DemodulatorInstance.h b/src/demod/DemodulatorInstance.h index d3d3671..b03184e 100644 --- a/src/demod/DemodulatorInstance.h +++ b/src/demod/DemodulatorInstance.h @@ -127,6 +127,7 @@ private: std::atomic currentAudioGain; std::atomic_bool follow, tracking; std::map lastModemSettings; + std::map lastModemBandwidth; #if ENABLE_DIGITAL_LAB ModemDigitalOutput *activeOutput; #endif diff --git a/src/demod/DemodulatorMgr.cpp b/src/demod/DemodulatorMgr.cpp index 4d6f874..618c5d0 100644 --- a/src/demod/DemodulatorMgr.cpp +++ b/src/demod/DemodulatorMgr.cpp @@ -8,13 +8,6 @@ DemodulatorMgr::DemodulatorMgr() : activeDemodulator(NULL), lastActiveDemodulator(NULL), activeVisualDemodulator(NULL), lastBandwidth(DEFAULT_DEMOD_BW), lastDemodType( DEFAULT_DEMOD_TYPE), lastSquelchEnabled(false), lastSquelch(-100), lastGain(1.0), lastMuted(false) { - setLastBandwidth("FM",200000); - setLastBandwidth("FMS",200000); - setLastBandwidth("AM",6000); - setLastBandwidth("USB",5400); - setLastBandwidth("LSB",5400); - setLastBandwidth("DSB",5400); - setLastBandwidth("IQ",48000); } DemodulatorMgr::~DemodulatorMgr() { @@ -171,7 +164,6 @@ void DemodulatorMgr::updateLastState() { lastSquelch = lastActiveDemodulator->getSquelchLevel(); lastGain = lastActiveDemodulator->getGain(); lastModemSettings[lastDemodType] = lastActiveDemodulator->readModemSettings(); - lastBandwidthNamed[lastDemodType] = lastBandwidth; } } @@ -236,10 +228,3 @@ ModemSettings DemodulatorMgr::getLastModemSettings(std::string modemType) { void DemodulatorMgr::setLastModemSettings(std::string modemType, ModemSettings settings) { lastModemSettings[modemType] = settings; } - -int DemodulatorMgr::getLastBandwidth(std::string modemType) { - return lastBandwidthNamed[modemType]; -} -void DemodulatorMgr::setLastBandwidth(std::string modemType, int lastBandwidth_in) { - lastBandwidthNamed[modemType] = lastBandwidth_in; -} diff --git a/src/demod/DemodulatorMgr.h b/src/demod/DemodulatorMgr.h index 1b178d9..4e8f496 100644 --- a/src/demod/DemodulatorMgr.h +++ b/src/demod/DemodulatorMgr.h @@ -25,9 +25,6 @@ public: int getLastBandwidth() const; void setLastBandwidth(int lastBandwidth); - int getLastBandwidth(std::string modemType); - void setLastBandwidth(std::string modemType, int lastBandwidth); - std::string getLastDemodulatorType() const; void setLastDemodulatorType(std::string lastDemodType); @@ -57,7 +54,6 @@ private: DemodulatorInstance *lastActiveDemodulator; DemodulatorInstance *activeVisualDemodulator; - std::map lastBandwidthNamed; int lastBandwidth; std::string lastDemodType; bool lastDemodLock; diff --git a/src/modules/modem/Modem.cpp b/src/modules/modem/Modem.cpp index 6b14b58..c98e2be 100644 --- a/src/modules/modem/Modem.cpp +++ b/src/modules/modem/Modem.cpp @@ -1,4 +1,6 @@ #include "Modem.h" +#include "CubicSDR.h" + ModemFactoryList Modem::modemFactories; @@ -52,12 +54,24 @@ Modem *Modem::makeModem(std::string modemName) { return nullptr; } +int Modem::getModemDefaultSampleRate(std::string modemName) { + if (modemFactories.find(modemName) != modemFactories.end()) { + return modemFactories[modemName]->getDefaultSampleRate(); + } + + return 0; +} + ModemArgInfoList Modem::getSettings() { ModemArgInfoList args; return args; } +int Modem::getDefaultSampleRate() { + return 200000; +} + void Modem::writeSetting(std::string setting, std::string value) { // ... } diff --git a/src/modules/modem/Modem.h b/src/modules/modem/Modem.h index f87c4db..d9ffb4c 100644 --- a/src/modules/modem/Modem.h +++ b/src/modules/modem/Modem.h @@ -113,6 +113,7 @@ public: static ModemFactoryList getFactories(); static Modem *makeModem(std::string modemName); + static int getModemDefaultSampleRate(std::string modemName); virtual std::string getType() = 0; virtual std::string getName() = 0; @@ -123,6 +124,7 @@ public: virtual ~Modem(); virtual ModemArgInfoList getSettings(); + virtual int getDefaultSampleRate(); virtual void writeSetting(std::string setting, std::string value); virtual void writeSettings(ModemSettings settings); virtual std::string readSetting(std::string setting); diff --git a/src/modules/modem/analog/ModemAM.cpp b/src/modules/modem/analog/ModemAM.cpp index 114d81b..a4baa57 100644 --- a/src/modules/modem/analog/ModemAM.cpp +++ b/src/modules/modem/analog/ModemAM.cpp @@ -4,6 +4,10 @@ ModemAM::ModemAM() : ModemAnalog() { demodAM = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 0); } +ModemAM::~ModemAM() { + ampmodem_destroy(demodAM); +} + Modem *ModemAM::factory() { return new ModemAM; } @@ -12,6 +16,10 @@ std::string ModemAM::getName() { return "AM"; } +int ModemAM::getDefaultSampleRate() { + return 6000; +} + void ModemAM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) { ModemKitAnalog *amkit = (ModemKitAnalog *)kit; diff --git a/src/modules/modem/analog/ModemAM.h b/src/modules/modem/analog/ModemAM.h index 8a1d017..5adf75f 100644 --- a/src/modules/modem/analog/ModemAM.h +++ b/src/modules/modem/analog/ModemAM.h @@ -5,8 +5,14 @@ class ModemAM : public ModemAnalog { public: ModemAM(); + ~ModemAM(); + std::string getName(); + Modem *factory(); + + int getDefaultSampleRate(); + void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut); private: diff --git a/src/modules/modem/analog/ModemDSB.cpp b/src/modules/modem/analog/ModemDSB.cpp index b40b11f..b0de272 100644 --- a/src/modules/modem/analog/ModemDSB.cpp +++ b/src/modules/modem/analog/ModemDSB.cpp @@ -4,6 +4,10 @@ ModemDSB::ModemDSB() : ModemAnalog() { demodAM_DSB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 1); } +ModemDSB::~ModemDSB() { + ampmodem_destroy(demodAM_DSB); +} + Modem *ModemDSB::factory() { return new ModemDSB; } @@ -12,6 +16,10 @@ std::string ModemDSB::getName() { return "DSB"; } +int ModemDSB::getDefaultSampleRate() { + return 5400; +} + void ModemDSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) { ModemKitAnalog *amkit = (ModemKitAnalog *)kit; diff --git a/src/modules/modem/analog/ModemDSB.h b/src/modules/modem/analog/ModemDSB.h index fc0e550..8c99332 100644 --- a/src/modules/modem/analog/ModemDSB.h +++ b/src/modules/modem/analog/ModemDSB.h @@ -5,8 +5,14 @@ class ModemDSB : public ModemAnalog { public: ModemDSB(); + ~ModemDSB(); + std::string getName(); + Modem *factory(); + + int getDefaultSampleRate(); + void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut); private: diff --git a/src/modules/modem/analog/ModemFM.cpp b/src/modules/modem/analog/ModemFM.cpp index 1e90ea4..931eef6 100644 --- a/src/modules/modem/analog/ModemFM.cpp +++ b/src/modules/modem/analog/ModemFM.cpp @@ -4,6 +4,10 @@ ModemFM::ModemFM() : ModemAnalog() { demodFM = freqdem_create(0.5); } +ModemFM::~ModemFM() { + freqdem_destroy(demodFM); +} + Modem *ModemFM::factory() { return new ModemFM; } @@ -12,6 +16,10 @@ std::string ModemFM::getName() { return "FM"; } +int ModemFM::getDefaultSampleRate() { + return 200000; +} + void ModemFM::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) { ModemKitAnalog *fmkit = (ModemKitAnalog *)kit; diff --git a/src/modules/modem/analog/ModemFM.h b/src/modules/modem/analog/ModemFM.h index a763bc2..267114d 100644 --- a/src/modules/modem/analog/ModemFM.h +++ b/src/modules/modem/analog/ModemFM.h @@ -5,11 +5,16 @@ class ModemFM : public ModemAnalog { public: ModemFM(); + ~ModemFM(); + std::string getName(); + Modem *factory(); + + int getDefaultSampleRate(); + void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut); private: - freqdem demodFM; }; \ No newline at end of file diff --git a/src/modules/modem/analog/ModemFMStereo.cpp b/src/modules/modem/analog/ModemFMStereo.cpp index f871ac9..935fb4b 100644 --- a/src/modules/modem/analog/ModemFMStereo.cpp +++ b/src/modules/modem/analog/ModemFMStereo.cpp @@ -40,6 +40,10 @@ int ModemFMStereo::checkSampleRate(long long sampleRate, int audioSampleRate) { } } +int ModemFMStereo::getDefaultSampleRate() { + return 200000; +} + ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) { ModemKitFMStereo *kit = new ModemKitFMStereo; diff --git a/src/modules/modem/analog/ModemFMStereo.h b/src/modules/modem/analog/ModemFMStereo.h index 10808f8..21e41c1 100644 --- a/src/modules/modem/analog/ModemFMStereo.h +++ b/src/modules/modem/analog/ModemFMStereo.h @@ -27,6 +27,7 @@ public: Modem *factory(); int checkSampleRate(long long sampleRate, int audioSampleRate); + int getDefaultSampleRate(); ModemKit *buildKit(long long sampleRate, int audioSampleRate); void disposeKit(ModemKit *kit); diff --git a/src/modules/modem/analog/ModemIQ.cpp b/src/modules/modem/analog/ModemIQ.cpp index bcf7d97..7eda625 100644 --- a/src/modules/modem/analog/ModemIQ.cpp +++ b/src/modules/modem/analog/ModemIQ.cpp @@ -4,6 +4,14 @@ ModemIQ::ModemIQ() { } +std::string ModemIQ::getType() { + return "analog"; +} + +std::string ModemIQ::getName() { + return "I/Q"; +} + Modem *ModemIQ::factory() { return new ModemIQ; } @@ -15,14 +23,6 @@ ModemKit *ModemIQ::buildKit(long long sampleRate, int audioSampleRate) { return kit; } -std::string ModemIQ::getType() { - return "analog"; -} - -std::string ModemIQ::getName() { - return "I/Q"; -} - void ModemIQ::disposeKit(ModemKit *kit) { delete kit; } @@ -31,6 +31,10 @@ int ModemIQ::checkSampleRate(long long sampleRate, int audioSampleRate) { return audioSampleRate; } +int ModemIQ::getDefaultSampleRate() { + return 48000; +} + void ModemIQ::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) { int bufSize = input->data.size(); diff --git a/src/modules/modem/analog/ModemIQ.h b/src/modules/modem/analog/ModemIQ.h index ea0c614..ca9e5fa 100644 --- a/src/modules/modem/analog/ModemIQ.h +++ b/src/modules/modem/analog/ModemIQ.h @@ -4,12 +4,19 @@ class ModemIQ : public Modem { public: ModemIQ(); + std::string getType(); std::string getName(); + Modem *factory(); - ModemKit *buildKit(long long sampleRate, int audioSampleRate); + int checkSampleRate(long long sampleRate, int audioSampleRate); + int getDefaultSampleRate(); + + ModemKit *buildKit(long long sampleRate, int audioSampleRate); + void disposeKit(ModemKit *kit); + void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut); private: diff --git a/src/modules/modem/analog/ModemLSB.cpp b/src/modules/modem/analog/ModemLSB.cpp index 3838f1d..7e38f15 100644 --- a/src/modules/modem/analog/ModemLSB.cpp +++ b/src/modules/modem/analog/ModemLSB.cpp @@ -29,6 +29,10 @@ int ModemLSB::checkSampleRate(long long sampleRate, int audioSampleRate) { return sampleRate+1; } +int ModemLSB::getDefaultSampleRate() { + return 5400; +} + void ModemLSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) { ModemKitAnalog *akit = (ModemKitAnalog *)kit; diff --git a/src/modules/modem/analog/ModemLSB.h b/src/modules/modem/analog/ModemLSB.h index 9ea4c0e..04a462c 100644 --- a/src/modules/modem/analog/ModemLSB.h +++ b/src/modules/modem/analog/ModemLSB.h @@ -1,14 +1,18 @@ #pragma once -#include "Modem.h" #include "ModemAnalog.h" class ModemLSB : public ModemAnalog { public: ModemLSB(); ~ModemLSB(); + std::string getName(); + Modem *factory(); + int checkSampleRate(long long sampleRate, int audioSampleRate); + int getDefaultSampleRate(); + void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut); private: diff --git a/src/modules/modem/analog/ModemUSB.cpp b/src/modules/modem/analog/ModemUSB.cpp index 17392c5..be1c9bd 100644 --- a/src/modules/modem/analog/ModemUSB.cpp +++ b/src/modules/modem/analog/ModemUSB.cpp @@ -29,6 +29,10 @@ int ModemUSB::checkSampleRate(long long sampleRate, int audioSampleRate) { return sampleRate+1; } +int ModemUSB::getDefaultSampleRate() { + return 5400; +} + void ModemUSB::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) { ModemKitAnalog *akit = (ModemKitAnalog *)kit; diff --git a/src/modules/modem/analog/ModemUSB.h b/src/modules/modem/analog/ModemUSB.h index cff6ac4..44dd0f3 100644 --- a/src/modules/modem/analog/ModemUSB.h +++ b/src/modules/modem/analog/ModemUSB.h @@ -5,9 +5,14 @@ class ModemUSB : public ModemAnalog { public: ModemUSB(); ~ModemUSB(); + std::string getName(); + Modem *factory(); + int checkSampleRate(long long sampleRate, int audioSampleRate); + int getDefaultSampleRate(); + void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut); private: diff --git a/src/modules/modem/digital/ModemFSK.cpp b/src/modules/modem/digital/ModemFSK.cpp index 43b8180..f7f856e 100644 --- a/src/modules/modem/digital/ModemFSK.cpp +++ b/src/modules/modem/digital/ModemFSK.cpp @@ -22,6 +22,10 @@ int ModemFSK::checkSampleRate(long long sampleRate, int audioSampleRate) { } } +int ModemFSK::getDefaultSampleRate() { + return 19200; +} + ModemArgInfoList ModemFSK::getSettings() { ModemArgInfoList args; diff --git a/src/modules/modem/digital/ModemFSK.h b/src/modules/modem/digital/ModemFSK.h index 8f2e00b..03c1d24 100644 --- a/src/modules/modem/digital/ModemFSK.h +++ b/src/modules/modem/digital/ModemFSK.h @@ -21,6 +21,7 @@ public: Modem *factory(); int checkSampleRate(long long sampleRate, int audioSampleRate); + int getDefaultSampleRate(); ModemArgInfoList getSettings(); void writeSetting(std::string setting, std::string value); diff --git a/src/modules/modem/digital/ModemGMSK.cpp b/src/modules/modem/digital/ModemGMSK.cpp new file mode 100644 index 0000000..166641d --- /dev/null +++ b/src/modules/modem/digital/ModemGMSK.cpp @@ -0,0 +1,133 @@ +#include "ModemGMSK.h" +#include + +ModemGMSK::ModemGMSK() : ModemDigital() { + _sps = 4; + _fdelay = 3; + _ebf = 0.3; + outStream << std::hex; +} + +ModemGMSK::~ModemGMSK() { + +} + +std::string ModemGMSK::getName() { + return "GMSK"; +} + +Modem *ModemGMSK::factory() { + return new ModemGMSK; +} + +int ModemGMSK::checkSampleRate(long long sampleRate, int audioSampleRate) { + if (sampleRate < 1500) { + return 1500; + } + return sampleRate; +} + +int ModemGMSK::getDefaultSampleRate() { + return 19200; +} + +ModemArgInfoList ModemGMSK::getSettings() { + ModemArgInfoList args; + + ModemArgInfo fdelayArg; + fdelayArg.key = "fdelay"; + fdelayArg.name = "Filter delay"; + fdelayArg.value = std::to_string(_fdelay); + fdelayArg.description = "Filter delay in samples"; + fdelayArg.type = ModemArgInfo::INT; + fdelayArg.units = "samples"; + fdelayArg.range = ModemRange(1,128); + args.push_back(fdelayArg); + + ModemArgInfo spsArg; + spsArg.key = "sps"; + spsArg.name = "Samples / symbol"; + spsArg.value = std::to_string(_sps); + spsArg.description = "Modem samples-per-symbol"; + spsArg.type = ModemArgInfo::INT; + spsArg.units = "samples/symbol"; + spsArg.range = ModemRange(2,512); + args.push_back(spsArg); + + ModemArgInfo ebfArg; + ebfArg.key = "ebf"; + ebfArg.name = "Excess bandwidth"; + ebfArg.value = std::to_string(_ebf); + ebfArg.description = "Modem excess bandwidth factor"; + ebfArg.type = ModemArgInfo::FLOAT; + ebfArg.range = ModemRange(0.1,0.49); + args.push_back(ebfArg); + + return args; +} + +void ModemGMSK::writeSetting(std::string setting, std::string value) { + if (setting == "fdelay") { + _fdelay = std::stoi(value); + rebuildKit(); + } else if (setting == "sps") { + _sps = std::stoi(value); + rebuildKit(); + } else if (setting == "ebf") { + _ebf = std::stof(value); + rebuildKit(); + } +} + +std::string ModemGMSK::readSetting(std::string setting) { + if (setting == "fdelay") { + return std::to_string(_fdelay); + } else if (setting == "sps") { + return std::to_string(_sps); + } else if (setting == "ebf") { + return std::to_string(_ebf); + } + return ""; +} + +ModemKit *ModemGMSK::buildKit(long long sampleRate, int audioSampleRate) { + ModemKitGMSK *dkit = new ModemKitGMSK; + dkit->sps = _sps; + dkit->fdelay = _fdelay; + dkit->ebf = _ebf; + + dkit->demodGMSK = gmskdem_create(dkit->sps, dkit->fdelay, dkit->ebf); + + dkit->sampleRate = sampleRate; + dkit->audioSampleRate = audioSampleRate; + + return dkit; +} + +void ModemGMSK::disposeKit(ModemKit *kit) { + ModemKitGMSK *dkit = (ModemKitGMSK *)kit; + + gmskdem_destroy(dkit->demodGMSK); + + delete dkit; +} + +void ModemGMSK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) { + ModemKitGMSK *dkit = (ModemKitGMSK *)kit; + unsigned int sym_out; + + digitalStart(dkit, nullptr, input); + + dkit->inputBuffer.insert(dkit->inputBuffer.end(),input->data.begin(),input->data.end()); + + int numProcessed = 0; + for (int i = 0, iMax = dkit->inputBuffer.size()/dkit->sps; i < iMax; i+= dkit->sps) { + gmskdem_demodulate(dkit->demodGMSK, &input->data[i],&sym_out); + outStream << sym_out; + numProcessed += dkit->sps; + } + + dkit->inputBuffer.erase(dkit->inputBuffer.begin(),dkit->inputBuffer.begin()+numProcessed); + + digitalFinish(dkit, nullptr); +} \ No newline at end of file diff --git a/src/modules/modem/digital/ModemGMSK.h b/src/modules/modem/digital/ModemGMSK.h new file mode 100644 index 0000000..e2e0635 --- /dev/null +++ b/src/modules/modem/digital/ModemGMSK.h @@ -0,0 +1,41 @@ +#pragma once +#include "ModemDigital.h" +#include + +class ModemKitGMSK : public ModemKitDigital { +public: + unsigned int fdelay, sps; + float ebf; + + gmskdem demodGMSK; + std::vector inputBuffer; +}; + + +class ModemGMSK : public ModemDigital { +public: + ModemGMSK(); + ~ModemGMSK(); + + std::string getName(); + + Modem *factory(); + + int checkSampleRate(long long sampleRate, int audioSampleRate); + int getDefaultSampleRate(); + + ModemArgInfoList getSettings(); + void writeSetting(std::string setting, std::string value); + std::string readSetting(std::string setting); + + ModemKit *buildKit(long long sampleRate, int audioSampleRate); + void disposeKit(ModemKit *kit); + + void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut); + +private: + int _sps; // samples per symbol + int _fdelay; // filter delay + float _ebf; +}; + diff --git a/src/modules/modem/digital/ModemOOK.cpp b/src/modules/modem/digital/ModemOOK.cpp index 7b5d54f..faef9d2 100644 --- a/src/modules/modem/digital/ModemOOK.cpp +++ b/src/modules/modem/digital/ModemOOK.cpp @@ -4,10 +4,6 @@ ModemOOK::ModemOOK() : ModemDigital() { demodOOK = modem_create(LIQUID_MODEM_OOK); } -Modem *ModemOOK::factory() { - return new ModemOOK; -} - ModemOOK::~ModemOOK() { modem_destroy(demodOOK); } @@ -16,6 +12,17 @@ std::string ModemOOK::getName() { return "OOK"; } +Modem *ModemOOK::factory() { + return new ModemOOK; +} + +int ModemOOK::checkSampleRate(long long sampleRate, int audioSampleRate) { + if (sampleRate < 100) { + return 100; + } + return sampleRate; +} + void ModemOOK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) { ModemKitDigital *dkit = (ModemKitDigital *)kit; digitalStart(dkit, demodOOK, input); diff --git a/src/modules/modem/digital/ModemOOK.h b/src/modules/modem/digital/ModemOOK.h index 4266113..0c25001 100644 --- a/src/modules/modem/digital/ModemOOK.h +++ b/src/modules/modem/digital/ModemOOK.h @@ -10,6 +10,8 @@ public: Modem *factory(); + int checkSampleRate(long long sampleRate, int audioSampleRate); + void demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut); private: diff --git a/src/visual/ModeSelectorCanvas.cpp b/src/visual/ModeSelectorCanvas.cpp index 7f57c56..4d00f0a 100644 --- a/src/visual/ModeSelectorCanvas.cpp +++ b/src/visual/ModeSelectorCanvas.cpp @@ -155,6 +155,11 @@ void ModeSelectorCanvas::addChoice(int value, std::string label) { numChoices = selections.size(); } +void ModeSelectorCanvas::addChoice(std::string label) { + selections.push_back(ModeSelectorMode(selections.size()+1, label)); + numChoices = selections.size(); +} + void ModeSelectorCanvas::setSelection(std::string label) { for (int i = 0; i < numChoices; i++) { if (selections[i].label == label) { diff --git a/src/visual/ModeSelectorCanvas.h b/src/visual/ModeSelectorCanvas.h index ca2a524..bdbcc41 100644 --- a/src/visual/ModeSelectorCanvas.h +++ b/src/visual/ModeSelectorCanvas.h @@ -32,6 +32,7 @@ public: void setHelpTip(std::string tip); void addChoice(int value, std::string label); + void addChoice(std::string label); void setSelection(std::string label); std::string getSelectionLabel(); void setSelection(int value); diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index 4b3dec3..3594900 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -663,11 +663,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) { demod->setFrequency(freq); demod->setDemodulatorType(mgr->getLastDemodulatorType()); - if (int lastDemodBw = mgr->getLastBandwidth(mgr->getLastDemodulatorType())) { - demod->setBandwidth(lastDemodBw); - } else { - demod->setBandwidth(mgr->getLastBandwidth()); - } + demod->setBandwidth(mgr->getLastBandwidth()); demod->setSquelchLevel(mgr->getLastSquelchLevel()); demod->setSquelchEnabled(mgr->isLastSquelchEnabled()); demod->setGain(mgr->getLastGain()); @@ -756,11 +752,7 @@ void WaterfallCanvas::OnMouseReleased(wxMouseEvent& event) { demod = wxGetApp().getDemodMgr().newThread(); demod->setFrequency(freq); demod->setDemodulatorType(mgr->getLastDemodulatorType()); - if (int lastDemodBw = mgr->getLastBandwidth(mgr->getLastDemodulatorType())) { - demod->setBandwidth(lastDemodBw); - } else { - demod->setBandwidth(mgr->getLastBandwidth()); - } + demod->setBandwidth(bw); demod->setSquelchLevel(mgr->getLastSquelchLevel()); demod->setSquelchEnabled(mgr->isLastSquelchEnabled()); demod->setGain(mgr->getLastGain());